1 line
16 KiB
Plaintext
1 line
16 KiB
Plaintext
{"version":3,"file":"s-select-seckill-sku.js","sources":["../../../../../../src/sheep/components/s-select-seckill-sku/s-select-seckill-sku.vue","../../../../../../uniComponent:/RDovQXBwL1dvcmsvYWRkci9hY2RyLXVpL3NyYy9zaGVlcC9jb21wb25lbnRzL3Mtc2VsZWN0LXNlY2tpbGwtc2t1L3Mtc2VsZWN0LXNlY2tpbGwtc2t1LnZ1ZQ"],"sourcesContent":["<!-- 秒杀商品的 SKU 选择,和 s-select-sku.vue 类似 -->\r\n<template>\r\n <!-- 规格弹窗 -->\r\n <su-popup :show=\"show\" round=\"10\" @close=\"emits('close')\">\r\n <!-- SKU 信息 -->\r\n <view class=\"ss-modal-box bg-white ss-flex-col\">\r\n <view class=\"modal-header ss-flex ss-col-center\">\r\n <!-- 规格图 -->\r\n <view class=\"header-left ss-m-r-30\">\r\n <image\r\n class=\"sku-image\"\r\n :src=\"sheep.$url.cdn(state.selectedSku.picUrl || state.goodsInfo.picUrl)\"\r\n mode=\"aspectFill\"\r\n ></image>\r\n </view>\r\n <view class=\"header-right ss-flex-col ss-row-between ss-flex-1\">\r\n <!-- 名称 -->\r\n <view class=\"goods-title ss-line-2\">{{ state.goodsInfo.name }}</view>\r\n <view class=\"header-right-bottom ss-flex ss-col-center ss-row-between\">\r\n <!-- 价格 -->\r\n <view class=\"price-text\">\r\n {{ fen2yuan(state.selectedSku.price || state.goodsInfo.price) }}\r\n </view>\r\n <!-- 秒杀价格标签 -->\r\n <view class=\"tig ss-flex ss-col-center\">\r\n <view class=\"tig-icon ss-flex ss-col-center ss-row-center\">\r\n <text class=\"cicon-alarm\"></text>\r\n </view>\r\n <view class=\"tig-title\">秒杀价</view>\r\n </view>\r\n <!-- 库存 -->\r\n <view class=\"stock-text ss-m-l-20\">\r\n 库存{{ state.selectedSku.stock || state.goodsInfo.stock }}件\r\n </view>\r\n </view>\r\n </view>\r\n </view>\r\n <view class=\"modal-content ss-flex-1\">\r\n <scroll-view scroll-y=\"true\" class=\"modal-content-scroll\">\r\n <view class=\"sku-item ss-m-b-20\" v-for=\"property in propertyList\" :key=\"property.id\">\r\n <view class=\"label-text ss-m-b-20\">{{ property.name }}</view>\r\n <view class=\"ss-flex ss-col-center ss-flex-wrap\">\r\n <button\r\n class=\"ss-reset-button spec-btn\"\r\n v-for=\"value in property.values\"\r\n :class=\"[\r\n {\r\n 'checked-btn': state.currentPropertyArray[property.id] === value.id,\r\n },\r\n {\r\n 'disabled-btn': value.disabled === true,\r\n },\r\n ]\"\r\n :key=\"value.id\"\r\n :disabled=\"value.disabled === true\"\r\n @tap=\"onSelectSku(property.id, value.id)\"\r\n >\r\n {{ value.name }}\r\n </button>\r\n </view>\r\n </view>\r\n <view class=\"buy-num-box ss-flex ss-col-center ss-row-between\">\r\n <view class=\"label-text\">购买数量</view>\r\n <su-number-box\r\n :min=\"1\"\r\n :max=\"min([singleLimitCount, state.selectedSku.stock])\"\r\n :step=\"1\"\r\n v-model=\"state.selectedSku.count\"\r\n @change=\"onBuyCountChange($event)\"\r\n activity=\"seckill\"\r\n ></su-number-box>\r\n </view>\r\n </scroll-view>\r\n </view>\r\n <view class=\"modal-footer\">\r\n <view class=\"buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center\">\r\n <button class=\"ss-reset-button buy-btn\" @tap=\"onBuy\">确认</button>\r\n </view>\r\n </view>\r\n </view>\r\n </su-popup>\r\n</template>\r\n\r\n<script setup>\r\n/**\r\n * 秒杀活动SKU选择,\r\n * 与s-select-sku的区别:多一个秒杀价的标签、没有加入购物车按钮、立即购买按钮叫确认、秒杀有最大购买数量限制\r\n * 差别不大,可以考虑合并 todo @芋艿\r\n */\r\n// 按钮状态: active,nostock\r\nimport { computed, reactive, watch } from 'vue'\r\nimport sheep from '@/sheep'\r\nimport { convertProductPropertyList, fen2yuan } from '@/sheep/hooks/useGoods'\r\nimport { min } from 'lodash-es'\r\nconst emits = defineEmits(['change', 'addCart', 'buy', 'close'])\r\nconst props = defineProps({\r\n modelValue: {\r\n type: Object,\r\n default() {},\r\n },\r\n show: {\r\n type: Boolean,\r\n default: false,\r\n },\r\n // 单次限购数量\r\n singleLimitCount: {\r\n type: Number,\r\n default: 1,\r\n },\r\n})\r\nconst state = reactive({\r\n goodsInfo: computed(() => props.modelValue),\r\n selectedSku: {},\r\n currentPropertyArray: [],\r\n})\r\n\r\nconst propertyList = convertProductPropertyList(state.goodsInfo.skus)\r\n// SKU 列表\r\nconst skuList = computed(() => {\r\n const skuPrices = state.goodsInfo.skus\r\n for (const price of skuPrices) {\r\n price.value_id_array = price.properties.map((item) => item.valueId)\r\n }\r\n return skuPrices\r\n})\r\n\r\nif (!state.goodsInfo.is_sku) {\r\n state.selectedSku = state.goodsInfo.skus[0]\r\n}\r\n\r\nwatch(\r\n () => state.selectedSku,\r\n (newVal) => {\r\n emits('change', newVal)\r\n },\r\n {\r\n immediate: true, // 立即执行\r\n deep: true, // 深度监听\r\n },\r\n)\r\n\r\nconst onBuy = () => {\r\n if (state.selectedSku.id) {\r\n if (state.selectedSku.stock <= 0) {\r\n sheep.$helper.toast('库存不足')\r\n } else {\r\n emits('buy', state.selectedSku)\r\n }\r\n } else {\r\n sheep.$helper.toast('请选择规格')\r\n }\r\n}\r\n\r\n// 购买数量改变\r\nfunction onBuyCountChange(buyCount) {\r\n if (buyCount > 0 && state.selectedSku.count !== buyCount) {\r\n state.selectedSku.count = buyCount\r\n }\r\n}\r\n\r\n// 改变禁用状态\r\nconst changeDisabled = (isChecked = false, propertyId = 0, valueId = 0) => {\r\n let newSkus = [] // 所有可以选择的 sku 数组\r\n if (isChecked) {\r\n // 情况一:选中 property\r\n // 获得当前点击选中 property 的、所有可用 SKU\r\n for (const price of skuList.value) {\r\n if (price.stock <= 0) {\r\n continue\r\n }\r\n if (price.value_id_array.indexOf(valueId) >= 0) {\r\n newSkus.push(price)\r\n }\r\n }\r\n } else {\r\n // 情况二:取消选中 property\r\n // 当前所选 property 下,所有可以选择的 SKU\r\n newSkus = getCanUseSkuList()\r\n }\r\n\r\n // 所有存在并且有库存未选择的 SKU 的 value 属性值 id\r\n let noChooseValueIds = []\r\n for (const price of newSkus) {\r\n noChooseValueIds = noChooseValueIds.concat(price.value_id_array)\r\n }\r\n noChooseValueIds = Array.from(new Set(noChooseValueIds)) // 去重\r\n\r\n if (isChecked) {\r\n // 去除当前选中的 value 属性值 id\r\n const index = noChooseValueIds.indexOf(valueId)\r\n noChooseValueIds.splice(index, 1)\r\n } else {\r\n // 循环去除当前已选择的 value 属性值 id\r\n state.currentPropertyArray.forEach((currentPropertyId) => {\r\n if (currentPropertyId.toString() !== '') {\r\n return\r\n }\r\n // currentPropertyId 为空是反选 填充的\r\n const index = noChooseValueIds.indexOf(currentPropertyId)\r\n if (index >= 0) {\r\n // currentPropertyId 存在于 noChooseValueIds\r\n noChooseValueIds.splice(index, 1)\r\n }\r\n })\r\n }\r\n\r\n // 当前已选择的 property 数组\r\n let choosePropertyIds = []\r\n if (!isChecked) {\r\n // 当前已选择的 property\r\n state.currentPropertyArray.forEach((currentPropertyId, currentValueId) => {\r\n if (currentPropertyId !== '') {\r\n // currentPropertyId 为空是反选 填充的\r\n choosePropertyIds.push(currentValueId)\r\n }\r\n })\r\n } else {\r\n // 当前点击选择的 property\r\n choosePropertyIds = [propertyId]\r\n }\r\n\r\n for (const propertyIndex in propertyList) {\r\n // 当前点击的 property、或者取消选择时候,已选中的 property 不进行处理\r\n if (choosePropertyIds.indexOf(propertyList[propertyIndex].id) >= 0) {\r\n continue\r\n }\r\n // 如果当前 property id 不存在于有库存的 SKU 中,则禁用\r\n for (const valueIndex in propertyList[propertyIndex].values) {\r\n propertyList[propertyIndex].values[valueIndex].disabled =\r\n noChooseValueIds.indexOf(propertyList[propertyIndex].values[valueIndex].id) < 0 // true 禁用 or false 不禁用\r\n }\r\n }\r\n}\r\n\r\n// 获取可用的(有库存的)SKU 列表\r\nconst getCanUseSkuList = () => {\r\n const newSkus = []\r\n for (const sku of skuList.value) {\r\n if (sku.stock <= 0) {\r\n continue\r\n }\r\n let isOk = true\r\n state.currentPropertyArray.forEach((propertyId) => {\r\n // propertyId 不为空,并且,这个 条 sku 没有被选中,则排除\r\n if (propertyId.toString() !== '' && sku.value_id_array.indexOf(propertyId) < 0) {\r\n isOk = false\r\n }\r\n })\r\n if (isOk) {\r\n newSkus.push(sku)\r\n }\r\n }\r\n return newSkus\r\n}\r\n\r\n// 选择规格\r\nconst onSelectSku = (propertyId, valueId) => {\r\n // 清空已选择\r\n let isChecked = true // 选中 or 取消选中\r\n if (\r\n state.currentPropertyArray[propertyId] !== undefined &&\r\n state.currentPropertyArray[propertyId] === valueId\r\n ) {\r\n // 点击已被选中的,删除并填充 ''\r\n isChecked = false\r\n state.currentPropertyArray.splice(propertyId, 1, '')\r\n } else {\r\n // 选中\r\n state.currentPropertyArray[propertyId] = valueId\r\n }\r\n\r\n // 选中的 property 大类\r\n const choosePropertyId = []\r\n state.currentPropertyArray.forEach((currentPropertyId) => {\r\n if (currentPropertyId !== '') {\r\n // currentPropertyId 为空是反选 填充的\r\n choosePropertyId.push(currentPropertyId)\r\n }\r\n })\r\n\r\n // 当前所选 property 下,所有可以选择的 SKU 们\r\n const newSkuList = getCanUseSkuList()\r\n\r\n // 判断所有 property 大类是否选择完成\r\n if (choosePropertyId.length === propertyList.length && newSkuList.length) {\r\n newSkuList[0].count = state.selectedSku.count || 1\r\n state.selectedSku = newSkuList[0]\r\n } else {\r\n state.selectedSku = {}\r\n }\r\n\r\n // 改变 property 禁用状态\r\n changeDisabled(isChecked, propertyId, valueId)\r\n}\r\n\r\nchangeDisabled(false)\r\n</script>\r\n\r\n<style lang=\"scss\" scoped>\r\n \r\n// 购买\r\n.buy-box {\r\n padding: 10rpx 20rpx;\r\n\r\n .buy-btn {\r\n width: 100%;\r\n height: 80rpx;\r\n color: #fff;\r\n background: linear-gradient(90deg, #ff5854, #ff2621);\r\n border-radius: 40rpx;\r\n }\r\n}\r\n\r\n.ss-modal-box {\r\n max-height: 1000rpx;\r\n border-radius: 30rpx 30rpx 0 0;\r\n\r\n .modal-header {\r\n position: relative;\r\n padding: 80rpx 20rpx 40rpx;\r\n\r\n .sku-image {\r\n width: 160rpx;\r\n height: 160rpx;\r\n border-radius: 10rpx;\r\n }\r\n\r\n .header-right {\r\n height: 160rpx;\r\n }\r\n\r\n .close-icon {\r\n position: absolute;\r\n top: 10rpx;\r\n right: 20rpx;\r\n font-size: 46rpx;\r\n opacity: 0.2;\r\n }\r\n\r\n .goods-title {\r\n font-size: 28rpx;\r\n font-weight: 500;\r\n line-height: 42rpx;\r\n }\r\n\r\n .price-text {\r\n font-family: OPPOSANS;\r\n font-size: 30rpx;\r\n font-weight: 500;\r\n color: $red;\r\n\r\n &::before {\r\n font-size: 24rpx;\r\n content: '¥';\r\n }\r\n }\r\n\r\n .stock-text {\r\n font-size: 26rpx;\r\n color: #999999;\r\n }\r\n }\r\n\r\n .modal-content {\r\n padding: 0 20rpx;\r\n\r\n .modal-content-scroll {\r\n max-height: 600rpx;\r\n\r\n .label-text {\r\n font-size: 26rpx;\r\n font-weight: 500;\r\n }\r\n\r\n .buy-num-box {\r\n height: 100rpx;\r\n }\r\n\r\n .spec-btn {\r\n min-width: 100rpx;\r\n height: 60rpx;\r\n padding: 0 30rpx;\r\n margin-right: 10rpx;\r\n margin-bottom: 10rpx;\r\n font-size: 26rpx;\r\n color: #434343;\r\n background: #f4f4f4;\r\n border-radius: 30rpx;\r\n }\r\n\r\n .checked-btn {\r\n font-weight: 500;\r\n color: #ffffff;\r\n background: linear-gradient(90deg, #ff5854, #ff2621);\r\n }\r\n\r\n .disabled-btn {\r\n font-weight: 400;\r\n color: #c6c6c6;\r\n background: #f8f8f8;\r\n }\r\n }\r\n }\r\n}\r\n\r\n.tig {\r\n width: 126rpx;\r\n height: 38rpx;\r\n border: 2rpx solid #ff5854;\r\n border-radius: 4rpx;\r\n\r\n .tig-icon {\r\n width: 40rpx;\r\n height: 40rpx;\r\n background: #ff5854;\r\n border-radius: 4rpx 0 0 4rpx;\r\n\r\n .cicon-alarm {\r\n font-size: 32rpx;\r\n color: #fff;\r\n }\r\n }\r\n\r\n .tig-title {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 86rpx;\r\n font-size: 24rpx;\r\n font-weight: 500;\r\n line-height: normal;\r\n color: #ff6000;\r\n }\r\n}\r\n</style>\r\n","import Component from 'D:/App/Work/addr/acdr-ui/src/sheep/components/s-select-seckill-sku/s-select-seckill-sku.vue'\nwx.createComponent(Component)"],"names":["reactive","computed","convertProductPropertyList","watch","sheep"],"mappings":"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"} |