mall-app-t/pages/product/components/propertyList.vue

205 lines
5.0 KiB
Vue

<template>
<view class="property-list">
<uni-popup type="bottom" ref="propertyListPopupRef" background-color="#fff">
<view class="popup-header">
<view class="button-cancel" @click="onClosePopup">取消</view>
<view style="color: #c0c0c0; font-size: 12px">长按规格修改/删除</view>
<view class="button-link" @click="onConfirmPopup">确定</view>
</view>
<view class="popup-content">
<view
v-for="item in nowGoodsPropertyList"
:key="item.id"
:class="['property-item', item.checked ? 'active' : '']"
@tap="chooseProperty(item)"
@longpress="longPress(item)"
>
{{ item.name }}
</view>
<view
v-if="canEdit"
style="height: 60rpx; position: relative; top: 5px; display: inline-block"
@click="addPropertyClick"
>
<text style="color: #ff3300; font-size: 30px" class="cicon-add-round-o"></text>
</view>
</view>
</uni-popup>
<uni-popup ref="inputDialogRef" type="dialog">
<uni-popup-dialog
mode="input"
:title="propertyTitle"
v-model="inputFormdata.name"
placeholder="请输入商品规格"
:before-close="true"
@confirm="dialogInputConfirm"
@close="inputDialogRef.close()"
></uni-popup-dialog>
</uni-popup>
</view>
</template>
<script setup>
import { ref, computed, defineEmits, defineProps, defineExpose } from 'vue'
import peach from '@/peach'
import GoodsApi from '@/peach/api/trade/goods'
import { getGoodsProperty, canEdit } from '../js/sku'
import { cloneDeep } from 'lodash'
/**
* todo 底部高度配置
*/
const props = defineProps({
modelValue: {
default: () => [],
required: true,
type: Array,
},
goodsPropertyList: {
default: () => [],
required: true,
type: Array,
},
})
const nowGoodsPropertyList = ref([])
const emit = defineEmits(['update:modelValue', 'confirm'])
const propertyListPopupRef = ref()
const onClosePopup = () => {
propertyListPopupRef.value.close()
}
function chooseProperty(item) {
item.checked = !item.checked
}
function longPress(item) {
if (canEdit) {
// 震动提示
uni.vibrateShort()
uni.showActionSheet({
itemList: ['编辑', '删除'],
success: async (res) => {
if (res.tapIndex === 0) {
propertyTitle.value = '编辑'
inputFormdata.value.id = item.id
inputFormdata.value.name = item.name
inputDialogRef.value.open()
}
if (res.tapIndex === 1) {
await GoodsApi.delProperty({ id: item.id })
await getGoodsProperty()
nowGoodsPropertyList.value = cloneDeep(props.goodsPropertyList)
}
},
})
}
}
function onConfirmPopup() {
let result = nowGoodsPropertyList.value
.filter((item) => {
if (item.checked) {
return item.propertyValues.filter((sitem) => sitem.checked)
}
})
.map((item) => {
let children = item.propertyValues.filter((sitem) => sitem.checked).map((titem) => titem.id)
return {
id: item.id,
children: children,
}
})
peach.$store('trade').selectedProperty = result
emit('confirm')
emit('update:modelValue', result)
onClosePopup()
}
const propertyTitle = ref('新增')
const inputDialogRef = ref()
const inputFormdata = ref({
id: '',
name: '',
remark: '',
})
function addPropertyClick() {
propertyTitle.value = '新增'
inputFormdata.value.name = ''
inputFormdata.value.id = ''
inputDialogRef.value.open()
}
async function dialogInputConfirm(value) {
if (!value) {
peach.$helper.toast('请输入商品属性')
return
}
if (inputFormdata.value.id) {
await GoodsApi.editProperty(inputFormdata.value)
} else {
await GoodsApi.createProperty(inputFormdata.value)
}
await getGoodsProperty()
inputDialogRef.value.close()
nowGoodsPropertyList.value = cloneDeep(props.goodsPropertyList)
}
function onOpen() {
nowGoodsPropertyList.value = cloneDeep(props.goodsPropertyList)
propertyListPopupRef.value.open('bottom')
}
defineExpose({
onOpen,
})
</script>
<style lang="scss" scoped>
.property-list {
.popup-content {
height: 500rpx;
padding: 40rpx;
.property-item {
display: inline-block;
margin-right: 10px;
margin-bottom: 10px;
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);
}
}
.button-link {
color: #1892ea;
font-size: 28rpx;
}
.button-cancel {
color: #888;
font-size: 28rpx;
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 38rpx 0;
}
}
</style>