123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- /* eslint-disable no-param-reassign */
- /* eslint-disable no-nested-ternary */
- //@ts-ignore
- import Toast from 'tdesign-miniprogram/toast/index'
- Component<
- {
- buyNum: number
- isAllSelectedSku: boolean
- },
- {
- src: ComponentPropertyStringType
- title: ComponentPropertyStringType
- show: ComponentPropertyBooleanType
- limitBuyInfo: ComponentPropertyStringType
- isStock: ComponentPropertyBooleanType
- limitMaxCount: ComponentPropertyNumberType
- limitMinCount: ComponentPropertyNumberType
- skuList: ComponentPropertyArrayType
- specList: ComponentPropertyArrayType
- outOperateStatus: ComponentPropertyBooleanType
- outEditStatus: ComponentPropertyBooleanType
- hasAuth: ComponentPropertyBooleanType
- count: ComponentPropertyNumberType
- },
- {
- initData(): void
- checkSkuStockQuantity(specValueId: number, skuList: any[]): void
- chooseSpecValueId(specValueId: number, specId: number): void
- flatten(input: any[]): any[]
- getIntersection(array: any[], nextArray: any[]): any[]
- toChooseItem(e: any): void
- isAllSelected(skuTree: any[], selectedSku: any[]): void
- handlePopupHide(): void
- specsConfirm(): void
- addCart(): void
- buyNow(): void
- handleBuyNumPlus(): void
- handleBuyNumMinus(): void
- setBuyNum(buyNum: number): void
- handleBuyNumChange(e: WechatMiniprogram.CustomEvent<{ value: string }>): void
- },
- {
- initStatus: boolean
- selectedSku: any
- selectSpecObj: any
- }
- >({
- options: {
- multipleSlots: true,
- addGlobalClass: true,
- },
- properties: {
- src: {
- type: String,
- },
- title: {
- type: String,
- },
- show: {
- type: Boolean,
- value: false,
- },
- limitBuyInfo: {
- type: String,
- value: '',
- },
- isStock: {
- type: Boolean,
- value: true,
- },
- limitMaxCount: {
- type: Number,
- value: 999,
- },
- limitMinCount: {
- type: Number,
- value: 1,
- },
- skuList: {
- type: Array,
- value: [],
- observer(skuList) {
- if (skuList && skuList.length > 0) {
- if (this.initStatus) {
- this.initData()
- }
- }
- },
- },
- specList: {
- type: Array,
- value: [],
- observer(specList) {
- if (specList && specList.length > 0) {
- this.initData()
- }
- },
- },
- outOperateStatus: {
- type: Boolean,
- value: false,
- },
- outEditStatus: {
- type: Boolean,
- value: false,
- },
- hasAuth: {
- type: Boolean,
- value: false,
- },
- count: {
- type: Number,
- value: 1,
- observer(count) {
- this.setData({
- buyNum: count,
- })
- },
- },
- },
- data: {
- buyNum: 1,
- isAllSelectedSku: false,
- },
- observers: {
- limitMinCount(limitMinCount) {
- this.setBuyNum(limitMinCount)
- },
- },
- lifetimes: {
- created() {
- this.initStatus = false
- this.selectedSku = {}
- this.selectSpecObj = {}
- },
- ready() {
- console.log(this.data.skuList, this.data.specList)
- },
- },
- methods: {
- initData() {
- const { skuList } = this.properties
- const { specList } = this.properties
- specList.forEach((item) => {
- if (item.specValueList.length > 0) {
- item.specValueList.forEach((subItem) => {
- const obj = this.checkSkuStockQuantity(subItem.specValueId, skuList)
- subItem.hasStockObj = obj
- })
- }
- })
- const selectedSku = {}
- specList.forEach((item) => {
- selectedSku[item.specId] = ''
- })
- this.setData({
- specList,
- })
- this.selectSpecObj = {}
- this.selectedSku = {}
- this.initStatus = true
- },
- checkSkuStockQuantity(specValueId, skuList) {
- let hasStock = false
- const array = []
- skuList.forEach((item) => {
- ;(item.specInfo || []).forEach((subItem) => {
- if (subItem.specValueId === specValueId && item.quantity > 0) {
- const subArray = []
- ;(item.specInfo || []).forEach((specItem) => {
- subArray.push(specItem.specValueId)
- })
- array.push(subArray)
- hasStock = true
- }
- })
- })
- return {
- hasStock,
- specsArray: array,
- }
- },
- chooseSpecValueId(specValueId, specId) {
- const { selectSpecObj } = this
- const { skuList, specList } = this.properties
- if (selectSpecObj[specId]) {
- selectSpecObj[specId] = []
- this.selectSpecObj = selectSpecObj
- } else {
- selectSpecObj[specId] = []
- }
- const itemAllSpecArray = []
- const itemUnSelectArray = []
- const itemSelectArray = []
- specList.forEach((item) => {
- if (item.specId === specId) {
- const subSpecValueItem = item.specValueList.find(
- (subItem) => subItem.specValueId === specValueId,
- )
- let specSelectStatus = false
- item.specValueList.forEach((n) => {
- itemAllSpecArray.push(n.hasStockObj.specsArray)
- if (n.isChoosed) {
- specSelectStatus = true
- }
- if (n.hasStockObj.hasStock) {
- itemSelectArray.push(n.specValueId)
- } else {
- itemUnSelectArray.push(n.specValueId)
- }
- })
- if (specSelectStatus) {
- selectSpecObj[specId] = this.flatten(
- subSpecValueItem?.hasStockObj.specsArray.concat(itemSelectArray),
- )
- } else {
- const subSet = function (arr1, arr2) {
- const set2 = new Set(arr2)
- const subset = []
- arr1.forEach((val) => {
- if (!set2.has(val)) {
- subset.push(val)
- }
- })
- return subset
- }
- selectSpecObj[specId] = subSet(
- this.flatten(itemAllSpecArray),
- this.flatten(itemUnSelectArray),
- )
- }
- } else {
- // 未点击规格的逻辑
- const itemSelectArray = []
- let specSelectStatus = false
- item.specValueList.map(
- // 找到有库存的规格数组
- (n) => {
- itemSelectArray.push(n.hasStockObj.specsArray)
- if (n.isChoosed) {
- specSelectStatus = true
- }
- n.hasStockObj.hasStock = true
- return n
- },
- )
- if (specSelectStatus) {
- selectSpecObj[item.specId] = this.flatten(itemSelectArray)
- } else {
- delete selectSpecObj[item.specId]
- }
- }
- this.selectSpecObj = selectSpecObj
- })
- const combatArray = Object.values(selectSpecObj)
- if (combatArray.length > 0) {
- const showArray = combatArray.reduce((x, y) => this.getIntersection(x, y))
- const lastResult = Array.from(new Set(showArray))
- specList.forEach((item) => {
- item.specValueList.forEach((subItem) => {
- if (lastResult.includes(subItem.specValueId)) {
- subItem.hasStockObj.hasStock = true
- } else {
- subItem.hasStockObj.hasStock = false
- }
- })
- })
- } else {
- specList.forEach((item) => {
- if (item.specValueList.length > 0) {
- item.specValueList.forEach((subItem) => {
- const obj = this.checkSkuStockQuantity(subItem.specValueId, skuList)
- subItem.hasStockObj = obj
- })
- }
- })
- }
- this.setData({
- specList,
- })
- },
- flatten(input) {
- const stack = [...input]
- const res = []
- while (stack.length) {
- const next = stack.pop()
- if (Array.isArray(next)) {
- stack.push(...next)
- } else {
- res.push(next)
- }
- }
- return res.reverse()
- },
- getIntersection(array, nextArray) {
- return array.filter((item) => nextArray.includes(item))
- },
- toChooseItem(e) {
- const { isStock } = this.properties
- if (!isStock) return
- const { id } = e.currentTarget.dataset
- const specId = e.currentTarget.dataset.specid
- const hasStock = e.currentTarget.dataset.hasstock
- if (!hasStock) {
- Toast({
- context: this,
- selector: '#t-toast',
- message: '该规格已售罄',
- icon: '',
- duration: 1000,
- })
- return
- }
- let { selectedSku } = this
- const { specList } = this.properties
- selectedSku =
- selectedSku[specId] === id
- ? { ...this.selectedSku, [specId]: '' }
- : { ...this.selectedSku, [specId]: id }
- specList.forEach((item) => {
- item.specValueList.forEach((valuesItem) => {
- if (item.specId === specId) {
- valuesItem.isChoosed = valuesItem.specValueId === selectedSku[specId]
- }
- })
- })
- this.chooseSpecValueId(id, specId)
- const isAllSelectedSku = this.isAllSelected(specList, selectedSku)
- if (!isAllSelectedSku) {
- this.setData({
- selectSkuSellsPrice: 0,
- selectSkuImg: '',
- })
- }
- this.setData({
- specList,
- isAllSelectedSku,
- })
- this.selectedSku = selectedSku
- this.triggerEvent('change', {
- specList,
- selectedSku,
- isAllSelectedSku,
- })
- },
- // 判断是否所有的sku都已经选中
- isAllSelected(skuTree, selectedSku) {
- const selected = Object.keys(selectedSku).filter((skuKeyStr) => selectedSku[skuKeyStr] !== '')
- return skuTree.length === selected.length
- },
- handlePopupHide() {
- this.triggerEvent('closeSpecsPopup', {
- show: false,
- })
- },
- specsConfirm() {
- const { isStock, isAllSelectedSku, buyNum } = this.properties
- if (!isStock) {
- return
- }
- if (!isAllSelectedSku) {
- Toast({
- context: this,
- selector: '#t-toast',
- message: '请选择规格',
- icon: '',
- duration: 1000,
- })
- return
- }
- this.triggerEvent('specsConfirm', {
- buy: buyNum,
- })
- },
- addCart() {
- const { isStock } = this.properties
- if (!isStock) return
- this.triggerEvent('addCart')
- },
- buyNow() {
- const { isAllSelectedSku } = this.data
- const { isStock } = this.properties
- if (!isStock) return
- this.triggerEvent('buyNow', {
- isAllSelectedSku,
- })
- },
- // 加
- handleBuyNumPlus() {
- const { buyNum } = this.data
- const { isStock, limitMaxCount } = this.properties
- if (!isStock) return
- const nextBuyNum = Number(buyNum) + 1
- this.setBuyNum(Math.min(limitMaxCount, nextBuyNum > 999 ? buyNum : nextBuyNum))
- },
- // 减
- handleBuyNumMinus() {
- const { buyNum } = this.data
- const { limitMinCount } = this.properties
- const { isStock } = this.properties
- if (!isStock) return
- const nextBuyNum = Number(buyNum) - 1
- this.setBuyNum(Math.max(limitMinCount, nextBuyNum < 1 ? buyNum : nextBuyNum))
- },
- // 总处理
- setBuyNum(buyNum) {
- this.setData({
- buyNum,
- })
- this.triggerEvent('changeNum', {
- buyNum,
- })
- },
- // 输入框
- handleBuyNumChange(e) {
- const {
- detail: { value },
- } = e
- const valInNum = Number(value)
- const { limitMaxCount, limitMinCount } = this.properties
- const nextData = {
- buyNum:
- valInNum < limitMinCount
- ? limitMinCount
- : valInNum > limitMaxCount
- ? limitMaxCount
- : valInNum,
- }
- this.setData(nextData)
- },
- },
- })
|