feat(sku):sku 合并
This commit is contained in:
parent
900936db56
commit
b10f8458af
|
@ -1,77 +1,84 @@
|
|||
<template>
|
||||
<view class="property-detail">
|
||||
<template v-for="item in goodsPropertyList" :key="item.id">
|
||||
<view class="property-item ss-p-40 ss-gap-40" v-if="item.checked">
|
||||
<view class="property-name ss-flex ss-gap-40 ss-m-b-20">
|
||||
<view class="property-name-text">规格名</view>
|
||||
<view class="property-name-value">{{ item.name }}</view>
|
||||
</view>
|
||||
<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', sitem.checked ? 'active' : '']">{{ sitem.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<view class="property-detail">
|
||||
<template v-for="item in goodsPropertyList" :key="item.id">
|
||||
<view class="property-item ss-p-40 ss-gap-40" v-if="item.checked">
|
||||
<view class="property-name ss-flex ss-gap-40 ss-m-b-20">
|
||||
<view class="property-name-text">规格名</view>
|
||||
<view class="property-name-value">{{ item.name }}</view>
|
||||
</view>
|
||||
<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(sitem)"
|
||||
:class="['item', sitem.checked ? 'active' : '']"
|
||||
>{{ sitem.name }}</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps, ref, computed } from 'vue'
|
||||
import { goodsPropertyList } from '../js/sku';
|
||||
import { defineProps, defineEmits, ref, computed } from 'vue'
|
||||
import { goodsPropertyList } from '../js/sku'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
goodsPropertyList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
modelValue: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
goodsPropertyList: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits(['changeSubProperty'])
|
||||
|
||||
function chooseProperty(item) {
|
||||
item.checked = !item.checked
|
||||
item.checked = !item.checked
|
||||
emit('changeSubProperty')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.property-detail {
|
||||
.property-item {
|
||||
margin: 0 40rpx 20rpx;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 10px;
|
||||
.property-item {
|
||||
margin: 0 40rpx 20rpx;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 10px;
|
||||
|
||||
.property-name {
|
||||
.property-name-text {
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
|
||||
.property-value {
|
||||
.property-value-text {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.property-value-value {
|
||||
.item {
|
||||
text-align: center;
|
||||
line-height: 60rpx;
|
||||
height: 60rpx;
|
||||
padding: 0 10px;
|
||||
border-radius: 10px;
|
||||
background-color: var(--ui-BG-4);
|
||||
.property-name {
|
||||
.property-name-text {
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #fff;
|
||||
background-color: var(--ui-BG-Main);
|
||||
.property-value {
|
||||
.property-value-text {
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.property-value-value {
|
||||
.item {
|
||||
text-align: center;
|
||||
line-height: 60rpx;
|
||||
height: 60rpx;
|
||||
padding: 0 10px;
|
||||
border-radius: 10px;
|
||||
background-color: var(--ui-BG-4);
|
||||
}
|
||||
|
||||
.active {
|
||||
color: #fff;
|
||||
background-color: var(--ui-BG-Main);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,101 +1,163 @@
|
|||
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)
|
||||
|
||||
// 多属性商品 sku 列表
|
||||
const skus = ref([]);
|
||||
const skus = ref([])
|
||||
|
||||
const propertyList = ref([]);
|
||||
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,
|
||||
});
|
||||
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.value ? 1 : 0;
|
||||
pickerRef.value.onOpen([index]);
|
||||
let index = specType.value ? 1 : 0
|
||||
pickerRef.value.onOpen([index])
|
||||
}
|
||||
|
||||
async function onPropertyConfirm(e) {
|
||||
await getGoodsProperty();
|
||||
console.log(e);
|
||||
await getGoodsProperty()
|
||||
console.log(e)
|
||||
}
|
||||
|
||||
async function getGoodsProperty() {
|
||||
let { data } = await GoodsApi.getHistoryProperty();
|
||||
let { data } = await GoodsApi.getHistoryProperty()
|
||||
|
||||
// 把 propertyList 中 id 相同的属性合并,并去重
|
||||
propertyList.value = peach.$store("trade").selectedProperty;
|
||||
// 把 propertyList 中 id 相同的属性合并,并去重
|
||||
propertyList.value = peach.$store('trade').selectedProperty
|
||||
|
||||
console.log(propertyList.value);
|
||||
console.log(propertyList.value)
|
||||
|
||||
// 根据已经选择数据,设置默认选中
|
||||
data.forEach((item) => {
|
||||
// 判断属性是否已经选中
|
||||
let propertyParent = propertyList.value.find(
|
||||
(sitem) => sitem?.id === item.id
|
||||
);
|
||||
// 根据已经选择数据,设置默认选中
|
||||
data.forEach((item) => {
|
||||
// 判断属性是否已经选中
|
||||
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 === child.id
|
||||
);
|
||||
console.log(childResult);
|
||||
child.checked = childResult ? true : false;
|
||||
});
|
||||
}
|
||||
});
|
||||
// 如果属性已经选中,查询子类中是否有选中
|
||||
if (item.checked) {
|
||||
item.propertyValues.forEach((child) => {
|
||||
let childResult = propertyParent?.children.some((schild) => schild === child.id)
|
||||
child.checked = childResult ? true : false
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
goodsPropertyList.value = data;
|
||||
goodsPropertyList.value = data
|
||||
console.log(goodsPropertyList.value)
|
||||
}
|
||||
|
||||
const specType = computed(() => peach.$store("trade").goodsInfo.specType);
|
||||
function changeSubProperty() {
|
||||
// 修改子属性状态,需要同步更新 skus 的显示
|
||||
console.log(goodsPropertyList.value)
|
||||
// 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容
|
||||
let temp = JSON.parse(JSON.stringify(goodsPropertyList.value.filter((item) => item.checked)))
|
||||
temp.forEach((item) => {
|
||||
item.propertyValues = item.propertyValues.filter((child) => child.checked)
|
||||
})
|
||||
|
||||
let result = temp.map((item) => {
|
||||
return item.propertyValues.map((child) => ({
|
||||
propertyId: item.id,
|
||||
propertyName: item.name,
|
||||
valueId: child.id,
|
||||
valueName: child.name,
|
||||
}))
|
||||
})
|
||||
|
||||
let tempSkus = []
|
||||
|
||||
for (let item of reduceArr(result)) {
|
||||
let obj = {
|
||||
picUrl: '',
|
||||
barCode: '',
|
||||
price: 0,
|
||||
marketPrice: 0,
|
||||
costPrice: 0,
|
||||
stock: 0,
|
||||
weight: 0,
|
||||
volume: 0,
|
||||
properties: item,
|
||||
}
|
||||
tempSkus.push(obj)
|
||||
}
|
||||
|
||||
skus.value = tempSkus
|
||||
}
|
||||
|
||||
function reduceArr(arr) {
|
||||
return arr.reduce((acc, cur) => {
|
||||
let tempAcc = []
|
||||
|
||||
if (acc.length < 1) {
|
||||
cur.forEach((item, index) => {
|
||||
if (tempAcc[index]) {
|
||||
tempAcc[index].push(item)
|
||||
} else {
|
||||
tempAcc[index] = [item]
|
||||
}
|
||||
})
|
||||
} else {
|
||||
acc.forEach((item, index) => {
|
||||
cur.forEach((sitem, sindex) => {
|
||||
tempAcc.push([...item, sitem])
|
||||
})
|
||||
})
|
||||
|
||||
if (cur.length < 1) {
|
||||
tempAcc = acc
|
||||
}
|
||||
}
|
||||
return tempAcc
|
||||
}, [])
|
||||
}
|
||||
|
||||
const specType = computed(() => peach.$store('trade').goodsInfo.specType)
|
||||
|
||||
function initial() {
|
||||
onLoad(() => {
|
||||
formData.value.specType = specType.value ? true : false;
|
||||
formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label;
|
||||
skus.value = peach.$store("trade").skus;
|
||||
if (specType.value) {
|
||||
getGoodsProperty();
|
||||
}
|
||||
});
|
||||
onLoad(() => {
|
||||
formData.value.specType = specType.value ? true : false
|
||||
formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label
|
||||
skus.value = peach.$store('trade').skus
|
||||
if (specType.value) {
|
||||
getGoodsProperty()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
initial,
|
||||
skus,
|
||||
pickerRef,
|
||||
pickerProperty,
|
||||
propertyListRef,
|
||||
formData,
|
||||
onRDPickerConfirm,
|
||||
onPropertyConfirm,
|
||||
propertyList,
|
||||
showPropertyList,
|
||||
goodsPropertyList,
|
||||
};
|
||||
initial,
|
||||
skus,
|
||||
pickerRef,
|
||||
pickerProperty,
|
||||
propertyListRef,
|
||||
formData,
|
||||
onRDPickerConfirm,
|
||||
onPropertyConfirm,
|
||||
propertyList,
|
||||
showPropertyList,
|
||||
goodsPropertyList,
|
||||
changeSubProperty,
|
||||
}
|
||||
|
|
|
@ -1,34 +1,57 @@
|
|||
<template>
|
||||
<pb-layout class="goods-property" title="商品属性" leftIcon="leftIcon" navbar="normal" :bgStyle="bgStyle"
|
||||
opacityBgUi="bg-white" color="black">
|
||||
<view class="property">
|
||||
<uni-forms ref="formRef" v-model="formData" :rules="rules" label-position="top" label-width="160">
|
||||
<uni-forms-item label="商品规格" @tap="pickerProperty" name="specType" label-position="left" required>
|
||||
<uni-easyinput type="text" :clearable="false" :styles="selfStyles" placeholderStyle="color:#8a8a8a"
|
||||
:inputBorder="false" v-model="formData.specText" placeholder="请选择商品规格" disabled>
|
||||
<template v-slot:right>
|
||||
<uni-icons type="right" />
|
||||
</template>
|
||||
</uni-easyinput>
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<template v-if="formData.specType">
|
||||
<button class="ss-reset-button add-property" @tap="showPropertyList">+添加规格</button>
|
||||
<property-detail v-if="propertyList.length > 0" v-model="propertyList"
|
||||
:goodsPropertyList="goodsPropertyList"></property-detail>
|
||||
<mutiple-sku :skus="skus"></mutiple-sku>
|
||||
</template>
|
||||
<pb-layout
|
||||
class="goods-property"
|
||||
title="商品属性"
|
||||
leftIcon="leftIcon"
|
||||
navbar="normal"
|
||||
:bgStyle="bgStyle"
|
||||
opacityBgUi="bg-white"
|
||||
color="black"
|
||||
>
|
||||
<view class="property">
|
||||
<uni-forms ref="formRef" v-model="formData" :rules="rules" label-position="top" label-width="160">
|
||||
<uni-forms-item label="商品规格" @tap="pickerProperty" name="specType" label-position="left" required>
|
||||
<uni-easyinput
|
||||
type="text"
|
||||
:clearable="false"
|
||||
:styles="selfStyles"
|
||||
placeholderStyle="color:#8a8a8a"
|
||||
:inputBorder="false"
|
||||
v-model="formData.specText"
|
||||
placeholder="请选择商品规格"
|
||||
disabled
|
||||
>
|
||||
<template v-slot:right>
|
||||
<uni-icons type="right" />
|
||||
</template>
|
||||
</uni-easyinput>
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<template v-if="formData.specType">
|
||||
<button class="ss-reset-button add-property" @tap="showPropertyList">+添加规格</button>
|
||||
<property-detail
|
||||
v-if="propertyList.length > 0"
|
||||
v-model="propertyList"
|
||||
:goodsPropertyList="goodsPropertyList"
|
||||
@changeSubProperty="changeSubProperty"
|
||||
></property-detail>
|
||||
<mutiple-sku :skus="skus"></mutiple-sku>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<SkuItem :skus="skus" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<SkuItem :skus="skus" />
|
||||
</template>
|
||||
|
||||
<p-picker ref="pickerRef" mode="single" :options-cols="SPEC_TYPE" @confirm="onRDPickerConfirm"></p-picker>
|
||||
<p-picker ref="pickerRef" mode="single" :options-cols="SPEC_TYPE" @confirm="onRDPickerConfirm"></p-picker>
|
||||
|
||||
<PropertyList ref="propertyListRef" v-model="propertyList" :goodsPropertyList="goodsPropertyList"
|
||||
@confirm="onPropertyConfirm" />
|
||||
</pb-layout>
|
||||
<PropertyList
|
||||
ref="propertyListRef"
|
||||
v-model="propertyList"
|
||||
:goodsPropertyList="goodsPropertyList"
|
||||
@confirm="onPropertyConfirm"
|
||||
/>
|
||||
</pb-layout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
@ -38,23 +61,24 @@ import PropertyList from './components/propertyList'
|
|||
import PropertyDetail from './components/propertyDetail'
|
||||
import { SPEC_TYPE } from './js/config'
|
||||
import {
|
||||
initial,
|
||||
pickerRef,
|
||||
propertyListRef,
|
||||
onRDPickerConfirm,
|
||||
formData,
|
||||
propertyList,
|
||||
onPropertyConfirm,
|
||||
showPropertyList,
|
||||
goodsPropertyList,
|
||||
pickerProperty,
|
||||
skus
|
||||
initial,
|
||||
pickerRef,
|
||||
propertyListRef,
|
||||
onRDPickerConfirm,
|
||||
formData,
|
||||
propertyList,
|
||||
onPropertyConfirm,
|
||||
showPropertyList,
|
||||
goodsPropertyList,
|
||||
pickerProperty,
|
||||
skus,
|
||||
changeSubProperty,
|
||||
} from './js/sku'
|
||||
|
||||
const bgStyle = {
|
||||
backgroundImage: '',
|
||||
backgroundColor: '#fff',
|
||||
description: '',
|
||||
backgroundImage: '',
|
||||
backgroundColor: '#fff',
|
||||
description: '',
|
||||
}
|
||||
|
||||
initial()
|
||||
|
@ -62,49 +86,49 @@ initial()
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.goods-property {
|
||||
.property {
|
||||
margin: 40rpx;
|
||||
.property {
|
||||
margin: 40rpx;
|
||||
|
||||
:deep() {
|
||||
.uni-easyinput__content-input {
|
||||
font-size: 28rpx !important;
|
||||
color: #333333 !important;
|
||||
line-height: normal !important;
|
||||
}
|
||||
:deep() {
|
||||
.uni-easyinput__content-input {
|
||||
font-size: 28rpx !important;
|
||||
color: #333333 !important;
|
||||
line-height: normal !important;
|
||||
}
|
||||
|
||||
.uni-easyinput__placeholder-class {
|
||||
font-size: 14px;
|
||||
}
|
||||
.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;
|
||||
.is-direction-left {
|
||||
.uni-forms-item__label {
|
||||
padding-left: 10px;
|
||||
background-color: #f9f9f9;
|
||||
border-radius: 10px 0 0 10px;
|
||||
}
|
||||
|
||||
uni-icons {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.uni-easyinput__content {
|
||||
border-radius: 0 10px 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.is-disabled {
|
||||
color: #333333;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
uni-icons {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.uni-easyinput__content {
|
||||
border-radius: 0 10px 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.is-disabled {
|
||||
color: #333333;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.add-property {
|
||||
margin: 40rpx;
|
||||
border: 1px dotted var(--ui-BG-Main);
|
||||
color: var(--ui-BG-Main);
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
.add-property {
|
||||
margin: 40rpx;
|
||||
border: 1px dotted var(--ui-BG-Main);
|
||||
color: var(--ui-BG-Main);
|
||||
border-radius: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
Loading…
Reference in New Issue