feat(商品属性): 多 sku

This commit is contained in:
unknown 2024-06-07 02:05:33 +08:00
parent c188d92c11
commit 900936db56
8 changed files with 198 additions and 158 deletions

View File

@ -1,48 +1,72 @@
<template> <template>
<div class="sku-item"> <div class="sku-item">
<uni-forms label-width="160" label-position="top"> <uni-forms label-width="176rpx" label-position="left">
<uni-forms-item label="商品封面图" name="picUrl">
<p-uploader <template v-if="specType">
v-model:url="formData.picUrl" <template v-for="item in formData.properties">
fileMediatype="image" <uni-forms-item :label="item.propertyName">
limit="1" <uni-easyinput type="text" :value="item.valueName" disabled />
mode="grid" </uni-forms-item>
:imageStyles="{ width: '168rpx', height: '168rpx' }" </template>
/> </template>
</uni-forms-item>
<uni-forms-item label="商品条码" name="barCode"> <uni-forms-item label="商品封面图" name="picUrl" label-position="top">
<uni-easyinput type="text" trim="all" v-model="formData.barCode" placeholder="请输入商品条码" /> <p-uploader v-model:url="formData.picUrl" fileMediatype="image" limit="1" mode="grid"
</uni-forms-item> :imageStyles="{ width: '168rpx', height: '168rpx' }" />
<uni-forms-item label="销售价" name="price"> </uni-forms-item>
<uni-easyinput type="number" trim="all" v-model="formData.price" placeholder="请输入商品销售价" /> <uni-forms-item label="商品条码" name="barCode">
</uni-forms-item> <uni-easyinput type="text" trim="all" v-model="formData.barCode" placeholder="请输入商品条码" />
<uni-forms-item label="市场价" name="marketPrice"> </uni-forms-item>
<uni-easyinput type="number" trim="all" v-model="formData.marketPrice" placeholder="请输入商品销售价" /> <uni-forms-item label="销售价" name="price">
</uni-forms-item> <uni-easyinput type="number" trim="all" v-model="formData.price" placeholder="请输入商品销售价" />
<uni-forms-item label="成本价" name="costPrice"> </uni-forms-item>
<uni-easyinput type="number" trim="all" v-model="formData.costPrice" placeholder="请输入商品销售价" /> <uni-forms-item label="市场价" name="marketPrice">
</uni-forms-item> <uni-easyinput type="number" trim="all" v-model="formData.marketPrice" placeholder="请输入商品销售价" />
<uni-forms-item label="库存" name="stock"> </uni-forms-item>
<uni-easyinput type="number" trim="all" v-model="formData.stock" placeholder="请输入商品库存" /> <uni-forms-item label="成本价" name="costPrice">
</uni-forms-item> <uni-easyinput type="number" trim="all" v-model="formData.costPrice" placeholder="请输入商品销售价" />
<uni-forms-item label="重量kg" name="weight"> </uni-forms-item>
<uni-easyinput type="number" trim="all" v-model="formData.weight" placeholder="请输入商品重量" /> <uni-forms-item label="库存" name="stock">
</uni-forms-item> <uni-easyinput type="number" trim="all" v-model="formData.stock" placeholder="请输入商品库存" />
<uni-forms-item label="体积" name="volume"> </uni-forms-item>
<uni-easyinput type="number" trim="all" v-model="formData.volume" placeholder="请输入商品体积" /> <uni-forms-item label="重量kg" name="weight">
</uni-forms-item> <uni-easyinput type="number" trim="all" v-model="formData.weight" placeholder="请输入商品重量" />
</uni-forms> </uni-forms-item>
</div> <uni-forms-item label="体积" name="volume">
<uni-easyinput type="number" trim="all" v-model="formData.volume" placeholder="请输入商品体积" />
</uni-forms-item>
</uni-forms>
</div>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref, watch, computed, defineProps } from 'vue'
import peach from '@/peach'
const props = defineProps({
skus: {
type: Array,
default: () => []
}
})
const formData = ref({}) const formData = ref({})
const specType = computed(() => peach.$store("trade").goodsInfo.specType);
watch(() => props.skus, (newVal) => {
console.log(newVal)
formData.value = newVal ?? {}
}, { immediate: true })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.sku-item { .sku-item {
margin: 40rpx; margin: 40rpx;
padding-top: 40rpx;
}
.sku-item:first-child {
border-top: 1px solid var(--ui-BG-Main);
} }
</style> </style>

View File

@ -0,0 +1,22 @@
<template>
<view class="mutiple-sku">
<template v-for="item in props.skus">
<sku-item :skus="item">
</sku-item>
</template>
</view>
</template>
<script setup>
import SkuItem from './item'
import { defineProps } from 'vue'
const props = defineProps({
skus: {
type: Array,
default: () => []
}
})
</script>

View File

@ -6,6 +6,9 @@ import { SPEC_TYPE } from "./config";
const pickerRef = ref(null); const pickerRef = ref(null);
// 多属性商品 sku 列表
const skus = ref([]);
const propertyList = ref([]); const propertyList = ref([]);
const goodsPropertyList = ref([]); const goodsPropertyList = ref([]);
@ -29,22 +32,23 @@ function onRDPickerConfirm(e) {
} }
function pickerProperty() { function pickerProperty() {
let index = specType ? 1 : 0; let index = specType.value ? 1 : 0;
pickerRef.value.onOpen([index]); pickerRef.value.onOpen([index]);
} }
function onPropertyConfirm(e) { async function onPropertyConfirm(e) {
getGoodsProperty(); await getGoodsProperty();
console.log(e); console.log(e);
} }
async function getGoodsProperty() { async function getGoodsProperty() {
let { data } = await GoodsApi.getHistoryProperty(); let { data } = await GoodsApi.getHistoryProperty();
propertyList.value = [];
// 把 propertyList 中 id 相同的属性合并,并去重 // 把 propertyList 中 id 相同的属性合并,并去重
propertyList.value = peach.$store("trade").selectedProperty; propertyList.value = peach.$store("trade").selectedProperty;
console.log(propertyList.value);
// 根据已经选择数据,设置默认选中 // 根据已经选择数据,设置默认选中
data.forEach((item) => { data.forEach((item) => {
// 判断属性是否已经选中 // 判断属性是否已经选中
@ -58,7 +62,7 @@ async function getGoodsProperty() {
if (item.checked) { if (item.checked) {
item.propertyValues.forEach((child) => { item.propertyValues.forEach((child) => {
let childResult = propertyParent?.children.some( let childResult = propertyParent?.children.some(
(schild) => schild?.id === child.id (schild) => schild === child.id
); );
console.log(childResult); console.log(childResult);
child.checked = childResult ? true : false; child.checked = childResult ? true : false;
@ -69,18 +73,22 @@ async function getGoodsProperty() {
goodsPropertyList.value = data; goodsPropertyList.value = data;
} }
const specType = computed(() => peach.$store("trade").specType); const specType = computed(() => peach.$store("trade").goodsInfo.specType);
function initial() { function initial() {
onLoad(() => { onLoad(() => {
formData.value.specType = specType ? true : false; formData.value.specType = specType.value ? true : false;
formData.value.specText = SPEC_TYPE[specType ? 1 : 0].label; formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label;
getGoodsProperty(); skus.value = peach.$store("trade").skus;
if (specType.value) {
getGoodsProperty();
}
}); });
} }
export { export {
initial, initial,
skus,
pickerRef, pickerRef,
pickerProperty, pickerProperty,
propertyListRef, propertyListRef,

View File

@ -245,6 +245,7 @@ function clickSetProperty() {
peach.$store('trade').$patch({ peach.$store('trade').$patch({
selectedProperty: result, selectedProperty: result,
goodsInfo: formData.value, goodsInfo: formData.value,
skus: formData.value.skus
}) })
peach.$router.go('/pages/product/sku') peach.$router.go('/pages/product/sku')
} }

View File

@ -1,79 +1,60 @@
<template> <template>
<pb-layout <pb-layout class="goods-property" title="商品属性" leftIcon="leftIcon" navbar="normal" :bgStyle="bgStyle"
class="goods-property" opacityBgUi="bg-white" color="black">
title="商品属性" <view class="property">
leftIcon="leftIcon" <uni-forms ref="formRef" v-model="formData" :rules="rules" label-position="top" label-width="160">
navbar="normal" <uni-forms-item label="商品规格" @tap="pickerProperty" name="specType" label-position="left" required>
:bgStyle="bgStyle" <uni-easyinput type="text" :clearable="false" :styles="selfStyles" placeholderStyle="color:#8a8a8a"
opacityBgUi="bg-white" :inputBorder="false" v-model="formData.specText" placeholder="请选择商品规格" disabled>
color="black" <template v-slot:right>
> <uni-icons type="right" />
<view class="property"> </template>
<uni-forms ref="formRef" v-model="formData" :rules="rules" label-position="top" label-width="160"> </uni-easyinput>
<uni-forms-item label="商品规格" @tap="pickerProperty" name="specType" label-position="left" required> </uni-forms-item>
<uni-easyinput </uni-forms>
type="text" </view>
:clearable="false" <template v-if="formData.specType">
:styles="selfStyles" <button class="ss-reset-button add-property" @tap="showPropertyList">+添加规格</button>
placeholderStyle="color:#8a8a8a" <property-detail v-if="propertyList.length > 0" v-model="propertyList"
:inputBorder="false" :goodsPropertyList="goodsPropertyList"></property-detail>
v-model="formData.specText" <mutiple-sku :skus="skus"></mutiple-sku>
placeholder="请选择商品规格" </template>
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>
</template>
<template v-else> <template v-else>
<SkuItem /> <SkuItem :skus="skus" />
</template> </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 <PropertyList ref="propertyListRef" v-model="propertyList" :goodsPropertyList="goodsPropertyList"
ref="propertyListRef" @confirm="onPropertyConfirm" />
v-model="propertyList" </pb-layout>
:goodsPropertyList="goodsPropertyList"
@confirm="onPropertyConfirm"
/>
</pb-layout>
</template> </template>
<script setup> <script setup>
import SkuItem from './components/item' import SkuItem from './components/item'
import MutipleSku from './components/mutipleSku'
import PropertyList from './components/propertyList' import PropertyList from './components/propertyList'
import PropertyDetail from './components/propertyDetail' import PropertyDetail from './components/propertyDetail'
import { SPEC_TYPE } from './js/config' import { SPEC_TYPE } from './js/config'
import { import {
initial, initial,
pickerRef, pickerRef,
propertyListRef, propertyListRef,
onRDPickerConfirm, onRDPickerConfirm,
formData, formData,
propertyList, propertyList,
onPropertyConfirm, onPropertyConfirm,
showPropertyList, showPropertyList,
goodsPropertyList, goodsPropertyList,
pickerProperty, pickerProperty,
skus
} from './js/sku' } from './js/sku'
const bgStyle = { const bgStyle = {
backgroundImage: '', backgroundImage: '',
backgroundColor: '#fff', backgroundColor: '#fff',
description: '', description: '',
} }
initial() initial()
@ -81,49 +62,49 @@ initial()
<style lang="scss" scoped> <style lang="scss" scoped>
.goods-property { .goods-property {
.property { .property {
margin: 40rpx; margin: 40rpx;
:deep() { :deep() {
.uni-easyinput__content-input { .uni-easyinput__content-input {
font-size: 28rpx !important; font-size: 28rpx !important;
color: #333333 !important; color: #333333 !important;
line-height: normal !important; line-height: normal !important;
} }
.uni-easyinput__placeholder-class { .uni-easyinput__placeholder-class {
font-size: 14px; font-size: 14px;
} }
.is-direction-left { .is-direction-left {
.uni-forms-item__label { .uni-forms-item__label {
padding-left: 10px; padding-left: 10px;
background-color: #f9f9f9; background-color: #f9f9f9;
border-radius: 10px 0 0 10px; 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;
}
} }
}
.add-property { uni-icons {
margin: 40rpx; margin-right: 10px;
border: 1px dotted var(--ui-BG-Main); }
color: var(--ui-BG-Main);
border-radius: 10px; .uni-easyinput__content {
text-align: center; 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;
}
} }
</style> </style>

View File

@ -1,17 +1,21 @@
import { ref } from 'vue' import { ref } from "vue";
import { defineStore } from 'pinia' import { defineStore } from "pinia";
const useTradeStore = defineStore('trade', () => { const useTradeStore = defineStore("trade", () => {
// 已选择规格类型 // 已选择规格类型
const selectedProperty = ref(null) const selectedProperty = ref(null);
// 商品信息 // 商品信息
const goodsInfo = ref(null) const goodsInfo = ref(null);
return { // 商品属性
selectedProperty, const skus = ref(null);
goodsInfo,
}
})
export default useTradeStore return {
selectedProperty,
goodsInfo,
skus,
};
});
export default useTradeStore;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB