| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- <template>
- <div>
- <el-popover
- placement="bottom-start"
- width="325"
- trigger="click"
- v-model="visible"
- @show="show"
- >
- <div class="popover-sku-box">
- <div class="sku-item" v-for="(skuLine, key) in skuGroup" :key="key">
- <div class="sku-name">{{ key }}</div>
- <div class="sku-value">
- <div
- class="item"
- @click="toChooseItem(skuLineItem, key, $event)"
- :class="[
- selectedProp.find(
- el => el.key === key && el.value === skuLineItem
- )
- ? 'active'
- : '',
- isSkuLineItemNotOptional(
- allProperties,
- selectedPropObj,
- key,
- skuLineItem,
- propKeys
- )
- ? 'not-optional'
- : ''
- ]"
- v-for="(skuLineItem, index) in skuLine"
- :key="index">
- {{ skuLineItem }}
- </div>
- </div>
- </div>
- <div class="footer">
- <div class="red btn" :class="{gary: !findSku}" @click="submit">{{ $t("determine") }}</div>
- <div class="cancal btn" @click="close">{{ $t("cancel") }}</div>
- </div>
- </div>
- <div class="prod-sku" slot="reference">
- {{ skuName }}
- <img src="../assets/images/down.png" alt="" />
- </div>
- </el-popover>
- </div>
- </template>
- <script>
- export default {
- props: {
- skuName: {
- type: String,
- default: ''
- },
- skuList: {
- type: Array,
- default() {
- return []
- }
- },
- skuId: {
- type: Number,
- default: 0
- },
- prodId: {
- type: Number,
- default: 0
- },
- comboId: {
- type: Number,
- default: 0
- }
- },
- data () {
- return {
- visible: false,
- defaultSku: '',
- // 购物车中修改的sku列表
- cartChangeSkuList: [],
- propKeys: [],
- selectedPropObj: {},
- skuGroup: {},
- allProperties: [],
- findSku: false
- }
- },
- methods: {
- handleVisible() {
- this.visible = true
- },
- isSelect(specVal, specName) {
- let list = this.defaultSku.properties.split(";")
- for(let i = 0;i< list.length;i++) {
- let spec = list[i].split(":")
- if(spec[0] === specName && spec[1] === specVal) {
- return true
- }
- }
- return false
- },
- skuSelect(specVal, specName) {
- const skuList = this.cartChangeSkuList.length ? this.cartChangeSkuList : this.skuList
- let list = this.defaultSku.properties.split(";")
- for(let i = 0;i< list.length;i++) {
- let spec = list[i].split(":")
- if(spec[0] === specName) {
- spec[1] = specVal
- spec = spec.join(":")
- list[i] = spec
- break
- }
- }
- const sku = list.join(";")
- for(let i = 0; i<skuList.length; i++) {
- if(skuList[i].properties === sku) {
- this.defaultSku = skuList[i]
- break;
- }
- }
- },
- close() {
- this.visible = false
- },
- show() {
- if (!this.skuList.length) {
- this.getSkuListByProdId()
- return
- }
- this.groupSkuProp()
- },
- /**
- * 组装SKU
- */
- groupSkuProp: function() {
- const skuList = this.skuList.length ? this.skuList : this.cartChangeSkuList
- if (skuList.length == 1 && !skuList[0].properties) {
- this.defaultSku = skuList[0]
- return
- }
- var skuGroup = {}
- var allProperties = []
- var propKeys = []
- var selectedPropObj = {}
- var defaultSku = null
- for (var i = 0; i < skuList.length; i++) {
- var isDefault = false
- if (!defaultSku && skuList[i].skuId == this.skuId) {
- defaultSku = skuList[i]
- isDefault = true
- }
- var properties = skuList[i].properties //版本:公开版;颜色:金色;内存:64GB
- allProperties.push(properties)
- var propList = properties.split(';') // ["版本:公开版","颜色:金色","内存:64GB"]
- for (var j = 0; j < propList.length; j++) {
- var propval = propList[j].split(':') //["版本","公开版"]
- var props = skuGroup[propval[0]] //先取出 版本对应的值数组
- //如果当前是默认选中的sku,把对应的属性值 组装到selectedProp
- if (isDefault) {
- propKeys.push(propval[0])
- selectedPropObj[propval[0]] = propval[1]
- }
- if (props == undefined) {
- props = [] //假设还没有版本,新建个新的空数组
- props.push(propval[1]) //把 "公开版" 放进空数组
- } else {
- if (props.indexOf(propval[1]) === -1) {
- //如果数组里面没有"公开版"
- props.push(propval[1]) //把 "公开版" 放进数组
- }
- }
- skuGroup[propval[0]] = props //最后把数据 放回版本对应的值
- }
- }
-
- this.defaultSku = defaultSku
- this.propKeys = propKeys
- this.selectedPropObj = selectedPropObj
- this.parseSelectedObjToVals(skuList)
- this.skuGroup = skuGroup
- this.allProperties = allProperties
- },
- /**
- * 将已选的 {key:val,key2:val2}转换成 [val,val2]
- */
- parseSelectedObjToVals: function() {
- const skuList = this.cartChangeSkuList.length ? this.cartChangeSkuList : this.skuList
- var selectedPropObj = this.selectedPropObj
- var selectedProperties = ''
- var selectedProp = []
- for (var key in selectedPropObj) {
- // selectedProp.push(selectedPropObj[key]);
- selectedProp.push({ key: key, value: selectedPropObj[key] })
- selectedProperties += key + ':' + selectedPropObj[key] + ';'
- }
- selectedProperties = selectedProperties.substring(
- 0,
- selectedProperties.length - 1
- )
- this.selectedProp = selectedProp
- this.selectedProperties = selectedProperties
- this.selectedPropObj = selectedPropObj
- var findSku = false
- for (var i = 0; i < skuList.length; i++) {
- // 解决排序问题导致无法匹配
- if (
- this.compareArray(
- selectedProperties.split(';').sort(),
- skuList[i].properties.split(';').sort()
- )
- ) {
- findSku = true
- this.defaultSku = skuList[i]
- break
- }
- }
- this.findSku = findSku
- },
- /**
- * 比较两个数组中的元素是否相等
- * @param a1 第一个数组
- * @param a2 第二个数组
- * @return boolean 两个数组中的元素都相等则返回 true,反之返回 false
- */
- compareArray(a1, a2) {
- if (!a1 || !a2) {
- return false
- }
- if (a1.length !== a2.length) {
- return false
- }
- for (var i = 0, n = a1.length; i < n; i++) {
- if (a1[i] !== a2[i]) {
- return false
- }
- }
- return true
- },
- /**
- * 判断当前的规格值 是否可以选
- */
- isSkuLineItemNotOptional(
- allProperties,
- selectedPropObj,
- key,
- item,
- propKeys
- ) {
- var selectedPropObj = Object.assign({}, selectedPropObj)
- var properties = ''
- selectedPropObj[key] = item
- for (var j = 0; j < propKeys.length; j++) {
- properties += propKeys[j] + ':' + selectedPropObj[propKeys[j]] + ';'
- }
- properties = properties.substring(0, properties.length - 1)
- for (var i = 0; i < allProperties.length; i++) {
- if (properties == allProperties[i]) {
- return false
- }
- }
- for (var i = 0; i < allProperties.length; i++) {
- if (allProperties[i].indexOf(item) >= 0) {
- return true
- }
- }
- return false
- },
- /**
- * 规格点击事件
- */
- toChooseItem(skuLineItem, key, event) {
- this.selectedPropObj[key] = skuLineItem
- this.parseSelectedObjToVals()
- },
- submit() {
- if (!this.findSku) return
- if(!this.defaultSku.stocks) {
- this.$message({
- message: this.$t('prodDetail.insufficientInventory'),
- type: 'warning',
- duration: 1000
- })
- return
- }
- this.close()
- this.$emit('getSku', this.defaultSku)
- },
- /**
- * 根据商品id获取skuList
- */
- getSkuListByProdId() {
- this.$axios.get(this.comboId ? '/combo/skuList' : '/prod/skuList', {
- params: {
- comboId: this.comboId,
- prodId: this.prodId
- }
- }).then(({ data }) => {
- this.cartChangeSkuList = data
- this.groupSkuProp()
- })
- }
- }
- }
- </script>
- <style scoped>
- .prod-sku {
- display: inline-block;
- font-size: 12px;
- color: #999999;
- cursor: pointer;
- }
- .prod-sku img {
- width: 8px;
- height: 4px;
- margin-left: 5px;
- margin-bottom: 2px;
- }
- .popover-sku-box {
- width: 311px;
- }
- .popover-sku-box .sku-item .sku-name{
- font-size: 12px;
- line-height: 12px;
- color: #999999;
- margin-bottom: 5px;
- }
- .popover-sku-box .sku-item .sku-value {
- margin-bottom: 10px;
- }
- .popover-sku-box .sku-item .sku-value .item {
- box-sizing: border-box;
- display: inline-block;
- font-size: 12px;
- color: #333333;
- min-width: 50px;
- height: 22px;
- line-height: 22px;
- padding: 0 8px;
- background: #FFFFFF;
- border: 1px solid #DDDDDD;
- cursor: pointer;
- margin-right: 10px;
- margin-bottom: 5px;
- user-select:none;
- }
- .popover-sku-box .sku-item .sku-value .item:last-child{
- margin-bottom: 0;
- }
- .popover-sku-box .sku-item .sku-value .item.active {
- border: 1px solid #E43130;
- }
- .popover-sku-box .sku-item .sku-value .item.not-optional {
- border: 1px dashed #bbb;
- color: #bbb;
- }
- .popover-sku-box .sku-item .sku-value .item.active.not-optional {
- border: 1px dashed #E43130;
- }
- .popover-sku-box .footer {
- margin-top: 15px;
- display: flex;
- }
- .popover-sku-box .footer .btn {
- box-sizing: border-box;
- width: 50px;
- height: 22px;
- border-radius: 11px;
- font-size: 12px;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- }
- .popover-sku-box .footer .btn.red {
- color: #fff;
- background: #E1251B;
- margin-right: 10px;
- }
- .popover-sku-box .footer .btn.gary {
- color: #999;
- background: #eee;
- }
- .popover-sku-box .footer .btn.gary:hover {
- cursor: not-allowed;
- }
- .popover-sku-box .footer .btn.cancal {
- background: #FFFFFF;
- border: 1px solid #DDDDDD;
- }
- </style>
|