<template> <el-card class="step-card"> <div slot="header" class="flex between"> <div class="step-card-title">Step2 Choose options</div> <div>>></div> </div> <div v-loading="loading"> <div v-if="computedPrintPriceData.length"> <div class="card-sub-title">Decoration</div> <el-form :model="form" :rules="rules" label-width="0" ref="form"> <div v-for="item in computedPrintPriceData" :key="item.id"> <div class="divider"></div> <el-form-item> <div class="flex"> <el-switch v-model="form[`${item.id}`].enable" active-color="#13ce66" inactive-color="#ff4949"></el-switch> <div class="form-item-label" style="margin-left: 12px"> {{ item.point }} </div> </div> </el-form-item> <el-form-item> <div class="custom-checkbox-wrap"> <div class="custom-checkbox" :class="{ active: form[`${item.id}`].printService === decoration.id, disable: !form[`${item.id}`].enable, }" v-for="decoration in item.decorationList" @click="printServiceClick(decoration, item)" :key="decoration.id"> {{ decoration.dec_code }} </div> </div> <el-radio-group style="display: none" v-model="form[`${item.id}`].printService" :disabled="!form[`${item.id}`].enable"> <el-radio v-for="(decoration, index) in item.decorationList" :key="index" :label="decoration.id" >{{ decoration.dec_code }} </el-radio> </el-radio-group> </el-form-item> <div class="flex start" v-for="(decoration, index) in item.decorationList" v-show="decoration.id === form[`${item.id}`].printService" :key="index"> <div class="flex-auto" v-show="decoration.max_color_count"> <div class="form-item-label">Numbers of colours</div> <div style="height: 35px" class="flex"> <el-radio-group :disabled="!form[`${item.id}`].enable" v-model="form[`${item.id}`].colorForm[index].colorNumber"> <el-radio v-for="n in decoration.max_color_count" :key="n" :label="n"></el-radio> </el-radio-group> </div> </div> <div class="flex-auto" style="max-width: 50%"> <div class="form-item-label">PMS Colours</div> <el-form-item prop="pmsColor" label-width="0"> <el-input :disabled="!form[`${item.id}`].enable" v-model="form[`${item.id}`].colorForm[index].pmsColorText" size="small" placeholder="PMS"></el-input> </el-form-item> </div> </div> </div> </el-form> </div> <div v-if="hasAddition"> <div class="divider"></div> <br /> <div class="addition-title">Centre Back</div> <div class="flex" v-for="(addition, keyName, index) in priceData.additionList" :key="index"> <div class="addition-title flex">{{ keyName }}</div> <div class="flex-auto flex wrap"> <div @click="selectAddition(item, keyName)" class="addition-item" :class="[ { selected: additionForm[`${keyName}`].includes(item.id) }, ]" v-for="item in addition" :key="item.id"> <div class="background"></div> <div class="name">{{ item.name }}</div> </div> </div> </div> </div> </div> </el-card> </template> <script> import stepMixin from './stepMixin' export default { name: 'Step2', mixins: [stepMixin], props: { // 步骤1中选中的周期. 不能直接拿form1来取form1.cycle, 否则步骤1变更时, 涉及到form1的computed会全部重新计算, 可能会导致其他异常 cycle: { type: Number, default: function () { return 0 }, }, }, data() { return { form: {}, additionForm: {}, rules: {}, // 标志符,用于控制监听是否启用 loaded: false, } }, computed: { // 商品 当前选中周期的 基础价格和打印价格数据 computedPriceData() { return this.priceData.priceList.filter( item => item.cycle_id === this.cycle ) }, /** * 当前选中周期下, 商品对应的各型号打印价格. */ computedPrintPriceData() { const model = this.computedPriceData.length ? this.computedPriceData[0] : {} // 属性‘1’里面是基础价格数据, 属性 ’2‘是打印价格数据 if (model['2']) { return model['2'].slice() } else { return [] } }, // 计算是否存在附加项 hasAddition() { if (!this.loaded) return false let result = false const target = this.priceData.additionList for (const key in target) { if (Array.isArray(target[key]) && target[key].length) { result = true } } return result }, }, watch: { computedPrintPriceData: { deep: true, handler: function () { if (!this.loaded) return const temp = {} for (const item of this.computedPrintPriceData) { let pId = 0 // 从 product 页面来的用户选过的打印服务数据 if ( this.preData.printService && this.preData.printService[`${item.id}`] && this.preData.printService[`${item.id}`].id ) { pId = this.preData.printService[`${item.id}`].id } temp[`${item.id}`] = { // ...item直接把所有数据一起堆进去, 方便后续的价格计算, 不然计算需要各种遍历, 逻辑会非常难懂. ...item, enable: pId !== 0, // 打印服务. 如果选过的打印服务在这个周期的商品里面有, 则选上. 否则选当前打印服务项的第一个 printService: item.decorationList.map(i => i.id).includes(pId) ? pId : item.decorationList[0].id, colorForm: item.decorationList.map(decoration => { return { id: decoration.id, // 默认是1, 后台数据允许留空成0, 但既然计算打印价格, 肯定会是1, 不然怎么打印、怎么计算价格 colorNumber: pId === decoration.id ? Number(this.preData.printService[`${item.id}`].num) : 1, pmsColorText: '', } }), } } this.form = Object.assign(temp, this.additionForm) }, }, additionForm: { deep: true, handler: function () { if (!this.loaded) return Object.assign(this.form, this.additionForm) }, }, }, mounted() { for (const key in this.priceData.additionList) { this.$set( this.additionForm, `${key}`, this.preData[`${key}`] ? this.preData[`${key}`].slice() : [] ) } this.loaded = true }, methods: { checkForm() { return new Promise((resolve, reject) => { this.$refs.form.validate(valid => { if (valid) { resolve(JSON.parse(JSON.stringify(this.form))) } else { reject(new Error('validate step2 form error')) } }) }) }, selectAddition(item, key) { if (this.additionForm[`${key}`].includes(item.id)) { // 选中清除 this.$set( this.additionForm, `${key}`, this.additionForm[`${key}`].filter(i => i !== item.id) ) } else { this.$set( this.additionForm, `${key}`, this.additionForm[`${key}`].concat([item.id]) ) } }, printServiceClick(decoration, item) { if (!this.form[`${item.id}`].enable) return this.form[`${item.id}`].printService = decoration.id }, }, } </script> <style lang="scss" scoped> @import './step.scss'; div { box-sizing: border-box; } .addition-title { font-size: 14px; font-family: Proxima Nova, sans-serif; color: #000; min-width: 104px; } .addition-item { border: 1px solid #dbdbdb; max-width: 108px; margin-bottom: 12px; margin-right: 12px; cursor: pointer; .name { word-break: break-all; height: 32px; line-height: 16px; padding: 0 4px; overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } .background { border-bottom: 1px solid #dbdbdb; width: 108px; height: 108px; } &:hover, &.selected { border-color: #409eff; } } .custom-checkbox { &.disable { cursor: not-allowed; } } </style>