| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385 | <template>  <div>    <div      v-if="quoteLoadState == 0"      v-loading="true"      class="com-loading"></div>    <div v-else-if="quoteLoadState == 1">      <tab-nav        :borderType="'allBorder'" :liWidth="100" :liHeight="40" :marginRight="5"        :currTab.sync="curWeek"        :tabList="priceList" />      <div        v-for="(items, indexs) in priceList"        :key="items.name"        v-show="curWeek == indexs">        <div>          <tab-nav            :borderType="'incompleteBorder'"            :currTab.sync="items.curPrint"            :tabList="items.basePrice"            :allPrintTab="allPrintTab"            :marginTop="0"            :marginRight="5"            :marginBottom="items.basePrice?.length>1?7:0"            @handle="sortBy(items)" />          <!-- <el-popover            placement="bottom-start"            trigger="hover">            <div              class="exclamation-icon"              slot="reference">!</div>            <div class="popover">              <p class="title">Print Price Comparison</p>              <div                v-for="(item,index) in items.basePrice"                :key="item.name">                <total-table                    :tableColumns="[...undecorated_columns, ...items.part_columns]"                  :tableData="item.data"                  :tableType="'Comparison'"                  :title="item.name"                  :curDecoration="items.decorationOrign[items.curPrint]" :indexDecoration="items.decorationOrign[index]"></total-table>              </div>            </div>          </el-popover> -->        </div>        <div          v-for="(item, index) in items.basePrice"          :key="item.name"          v-show="items.curPrint == index">          <new-price-table            :tableColumns="[...undecorated_columns, ...item.part_columns]"            :tableData="item.data"            :tableType="'Undecorated'"            :curPrint="item.name"            :curModel="items.decorationOrign[index]?.model"            :data="items"            :selectRow.sync="item.selectBaseRow"></new-price-table>        </div>        <!-- decoration_multiple is_more_print 打印开关,ID1001092需求 ;additional_print 颜色数量开关        以上需求作废,改版为多色多面的需求-->        <new-price-table          v-if="items.decoration?.length || items.basePrice?.[items.curPrint]?.decoration_addition?.length"          :tableData="items.decoration"          :tableColumns="[...decoration_columns, ...comCurBaseColumns]"          :tableType="'Decoration'"          :marginBottom="0"          :hasDecAdd="items.basePrice?.[items.curPrint]?.decoration_addition?.length"></new-price-table>                  <div          v-for="(item, index) in items.basePrice"          :key="item.name + index"          v-show="items.curPrint == index && item.decoration_addition.length">          <new-price-table            :tableData="item.decoration_addition"            :tableColumns="[...addon_columns, ...item.part_columns]"            :isCheckBox="true"            :tableType="'Addon'"            :multipleSelection.sync="items.selectAdditionRow"></new-price-table>        </div>      </div>      <!-- <section>        <p class="title1">          <span></span>          <span>Currency GBP(£)</span>        </p>        <total-table          :comLocationNum="comLocationNum"          :tableData="comBuyData"          :tableColumns="[            ...buy_columns,            ...comCurBaseTotalColumns          ]"          :curOrder="`${curWeek}-${comCurPrint}`"          :min="comCurBaseColumns[0]?.label"          :title="'Buy Price'" @send-idx="getChildIdx"></total-table>        <p class="text-red">Price is ex- gst</p>        <ul>          <li class="entry">            <div class="entry-l">Delivery Locations</div>            <el-input              placeholder="Enter Num"              v-model="comCurBasePrice.locationNum"              size="small" max="7" min="1"              style="width: 130px;"              type="number" @input="setMaxNum"></el-input>          </li>          <li              class="entry"               v-if="comLocationNum > 1">            <div class="entry-text">Qty / Location</div>          </li>          <li class="entry" v-for="(i,k) in comCurBaseTotalColumns" :key="i.prop" v-show="comLocationNum > k">            <div class="entry-l">Delivery Postcode</div>            <el-input              clearable              placeholder="Enter Postcode"              v-model="              i.postcode"              size="small"              style="width: 130px; margin-right: 20px;"              @input="getDebFreight(k)"></el-input>            <el-input               v-if="comLocationNum > 1"              placeholder="Enter Qty"              type="number"              :min="comCurBaseColumns[0]?.label"              @blur="getNumber($event, comCurBaseTotalColumns[k],comCurBaseColumns[0]?.label)"              v-model="i.label"              size="small"              style="width: 130px; margin-right: 20px;"></el-input>            <div class="entry-r">              <span>Freight Method</span>              <el-radio-group                v-model="i.freight_type"                @change="getFreight(k)">                <el-radio :label="1">Road Express</el-radio>                <el-radio :label="2">Air Freight</el-radio>              </el-radio-group>            </div>          </li>        </ul>        <div class="entry">          <div class="entry-l">Setup</div>          <div class="entry-l">include in unit price</div>          <pc-switch v-model="setup_switch"></pc-switch>        </div>        <div class="entry">          <div class="entry-l">Freight</div>          <div class="entry-l">include in unit price</div>          <div>            <pc-switch v-model="freight_switch"></pc-switch>          </div>        </div>        <el-button          size="medium"          class="button-black"          @click="openMailDialog">          Enquiry        </el-button>      </section> -->      <!-- <section>        <unit-table          :tableData="unitData"          :tableColumns="[            ...unit_columns,            ...comCurBaseTotalColumns          ]"></unit-table>          直接用comMergeColumns会出现summary数值问题,改用v-show="comLocationNum"控制        <total-table          v-show="comLocationNum == 1"          :tableData="comSellData"          :tableColumns="comNoSumCol"          :comLocationNum="comLocationNum"          :title="'Sell Price'"></total-table>        <total-table          v-show="comLocationNum != 1"          :tableData="comSellData"          :tableColumns="comHasSumCol"          :comLocationNum="comLocationNum"          :title="'Sell Price'"></total-table>        <el-button          class="button-black button-margin"          size="medium"          @click="openDownloadDialog(0)"          >View Quote</el-button>        <el-button          class="button-black button-margin"          size="medium"          @click="openDownloadDialog(1)"          >Send Order Enquiry</el-button>      </section> -->    </div>    <div      v-else      class="quote-tips">      Current item prices are missing, please contact<a        href="mailto:Info@promocollection.uk">        info@promocollection.uk</a>    </div>    <no-ssr>      <div v-if="quoteLoadState == 1">        <!-- Enquiry按钮 -->        <form-dialog          :emailForm="enquiryForm"          :enquiryConfig="enquiryConfig"          :visible.sync="enquiryFormVisible"          @handleSend="sendPriceMail"          :rules="rules"          :labelWidth="            enquiryConfig[3].selectlist?.length ? 140 : 82          "></form-dialog>        <mail-table          ref="mailtable"          :mailData="mailData"          v-show="false">          <price-to-img            :pageData="pageData"            :specificationsObj="specificationsObj"            :tableData="comFilterSwitchSellData"            :tableColumns="comMergeColumns"            :comLocationNum="comLocationNum"            :emailForm="commentObj"></price-to-img>        </mail-table>        <el-dialog          ref="dialogRef"          :lock-scroll="false"          title="Customer Quote"          :visible.sync="priceToImgVisible"          custom-class="price-to-img-dialog">          <price-to-img            :isImgSrc="false"            ref="priceToImgRef"            :loading.sync="pdfLoading"            :pageData="pageData"            :specificationsObj="specificationsObj"            :tableData="comFilterSwitchSellData"            :tableColumns="comMergeColumns"            :comLocationNum="comLocationNum"            :emailForm="commentObj"></price-to-img>          <p class="tips">Change default standard comment:</p>          <el-input v-model="commentObj.Comments"></el-input>          <div class="btn-wrap">            <el-button              class="button-black button-margin"              size="medium"              @click="handleDownloadPdf"              :loading="pdfLoading"              >Download</el-button>          </div>        </el-dialog>        <!-- <form-dialog          :emailForm="commentObj"          :enquiryConfig="enquiryConfig1"          :visible.sync="downloadDialogVisible"          @handleSend="sendPdfMail"          :rules="rules1"          :labelWidth="120"          :isSendPdf="true"></form-dialog> -->        <price-to-img          ref="pdf"          v-show="false"          :loading.sync="pdfLoading"          :pageData="pageData"          :specificationsObj="specificationsObj"          :tableData="comFilterSwitchSellData"          :tableColumns="comMergeColumns"          :comLocationNum="comLocationNum"          :emailForm="commentObj"></price-to-img>        <!-- 报价图片弹框 -->        <dialog-XX-success          :visible.sync="xxContentVisible" :imgType="false"          :content="'This quantity is below the MOQ for this product'"></dialog-XX-success>      </div>    </no-ssr>  </div></template><script>import { mapState, mapMutations, mapActions } from 'vuex'import _ from 'lodash'import { times as npTimes,plus as npPlus, minus as npMinus, divide as npDivide } from 'number-precision';import NewPriceTable from '@/components/table/NewPriceTable'import TotalTable from '@/components/table/TotalTable'import UnitTable from '@/components/table/UnitTable'import MailTable from '@/components/table/MailTable'import dialogXXSuccess from '@/components/DIalogXXSuccess.vue'export default {  components: {    NewPriceTable,    TotalTable,    UnitTable,    MailTable,    'dialog-XX-success': dialogXXSuccess  },  props: {    pageData: {      type: Object,      default: () => {        return {}      },    },    id: {      type: Number,      default: null    },  },  data() {    return {      quoteLoadState: 0,      curWeek: 0,      allPrintTab: [],      priceList: [],      initZeroObj: {},      initSetupObj: {},      initUnitObj: {},      initChangeUnitObj: {},      initFrightObj: {},      initTotalObj: {},      xxContentVisible: false,      setup_switch: false,      freight_switch: false,      weight: {},      undecorated_columns: [        {          label: 'MODEL',          prop: 'model',          type: 'text',          align: 'left',          width: 150,          extraWidth: 50, // 配合组件 (820-tableColumns[0].width-tableColumns[0].extraWidth)/(tableColumns.length-1)          isFirstColumn: true, // 去掉$符号        },        {          label: 'SETUP',          prop: 'website_setup',        },      ],      decoration_columns: [        {          label: 'PRINT OPTION',          prop: 'dec_code',          type: 'radioInput',          align: 'left',          width: 150,          extraWidth: 50,        },        {          label: 'SETUP',          prop: 'website_setup',        },      ],      addon_columns: [        {          label: 'Addon',          prop: 'name',          type: 'text',          width: 150,          extraWidth: 50,          isFirstColumn: true, // 去掉$符号        },        {          label: 'Setup',          prop: 'website_setup',        },      ],      buy_columns: [        {          label: 'QTY',          prop: 'project',          isFirstColumn: true, // 去掉$符号        },      ],      unit_columns: [        {          label: 'QTY',          prop: 'total',          align: 'left',          isText: true,        },      ],      buyData: [        { project: 'Setup' },        { project: 'Unit' },        { project: 'Freight' },        { project: 'Total' }      ],      unitData: [        { total: 'Unit Rate %' },        { total: 'Setup %' },        { total: 'Freight %' },      ],      sellData: [        { project: 'Postcode',summary: '-' },        { project: 'Setup',summary: 0.00 },        { project: 'Unit',summary: 0.00 },        { project: 'Freight',summary: 0.00 },        { project: 'Total',summary: 0.00 },      ],      POA_Config: ['111', '111.00', '999', '999.00'],      enquiryFormVisible: false,      enquiryForm: {        Name: '',        Email: '',        Phone: '',        'Customer manager': null,        Comments: '',      },      enquiryConfig: [        { prop: 'Name', type: 'input' },        { prop: 'Email', type: 'input' },        { prop: 'Phone', type: 'input' },        {          prop: 'Customer manager',          type: 'select',          selectlist: [],          isShow: true,        },        { prop: 'Comments', type: 'textarea' },      ],      rules: {        Name: [{ required: true, message: 'Please enter', trigger: 'blur' }],        Email: [          {            required: true,            message: 'Please enter the correct format',            pattern:              /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/,            trigger: 'blur',          },        ],        Phone: [          {            required: true,            message: 'Please enter the correct format',            // pattern: /^1[0-9]{10}$/,            trigger: 'blur',          },        ],        'Customer manager': [          { required: true, message: 'Please select', trigger: 'change' },        ],      },      mailData: {        Url: '',      },      priceToImgVisible: false,      downloadDialogVisible: false,      commentObj: {        'Email Address': '',        Comments: '',      },      enquiryConfig1: [        { prop: 'Email Address', type: 'input' },        { prop: 'Comments', type: 'input' },      ],      rules1: {        'Email Address': [          {            required: true,            message: 'Please enter the correct format',            pattern:              /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/,            trigger: 'blur',          },        ],      },      specificationsObj: {        time: null,        model: null,        decoration: null,        addonArr: null,      },      pdfLoading: false,    }  },  computed: {    ...mapState('config', { configInfo: state => state.configInfo }),    userInfo() {      return this.$store.state.userInfo    },    comCurWeekPrice() {      return this.priceList[this.curWeek] || {}    },    comCurPrint() {      return this.comCurWeekPrice.curPrint    },    comCurBasePrice() {      return this.comCurWeekPrice.basePrice[this.comCurPrint]    },    comLocationNum() {      return +(this.comCurWeekPrice.basePrice[this.comCurPrint].locationNum)    },    comCurBaseColumns() {      return this.comCurBasePrice.part_columns    },    comCurBaseTotalColumns() {      const d = this.comCurWeekPrice.basePrice[this.comCurPrint].total_part_columns      const n = this.comLocationNum      if (n === 1) {        return d      }else{        const concatAdd = [...d,...this.comCurWeekPrice.basePrice[this.comCurPrint].remainingAttr].slice(0, n);        return concatAdd      }    },    comTotalLabel(){      // 计算所有元素label的和      return this.comCurBaseTotalColumns.reduce((sum, item) => sum + Number(item.label), 0);    },    comSummaryColumns(){      return [{ label: this.comTotalLabel.toString(), prop: 'summary' }];    },    comAttributeList() {      const obj = {}      this.comCurBaseTotalColumns?.forEach(item => {        obj[item.prop] = item.label      })        obj.summary = this.comTotalLabel;      return obj    },    // 当前已选基础价    comBasePrice() {      return this.comCurBasePrice.selectBaseRow    },    // 当前累加打印价    comDecoPrice() {      if (!this.comCurWeekPrice.decoration?.length) {        return []      }      const arr = this.comCurWeekPrice.decoration        .map((item, idx) => {          const obj = {}          if (+item.num > 0) {            for (const i in this.initUnitObj) {              if (idx === 0) {                // 首个打印价要取附加价计算                const keyArr = i.split('_')                const supplier_val = item[`supplier_${keyArr[1]}`]                if (this.POA_Config.includes(supplier_val)) {                  obj[`${i}`] = supplier_val                } else {                  obj[`${i}`] = npTimes(+supplier_val, item.num)                }              } else {                obj[`${i}`] = this.POA_Config.includes(item[i]) ? item[i] : npTimes(+item[i], item.num);              }            }          }          return obj        })        .filter(obj => Object.keys(obj).length !== 0)      return arr    },    comBuyData() {      this.calculateBuyData();      return this.buyData    },    comNoSumCol(){      return [          ...this.buy_columns,          ...this.comCurBaseTotalColumns        ]    },    comHasSumCol(){      return [          ...this.buy_columns,          ...this.comCurBaseTotalColumns,          ...this.comSummaryColumns        ];    },    comMergeColumns(){      return this.comLocationNum == 1 ? this.comNoSumCol:this.comHasSumCol    },    comSellData() {      if (Object.keys(this.comAttributeList).length !== 0) {        this.calculateSellData();      }      return this.sellData    },    comFilterSwitchSellData() {      return this.comSellData?.filter((item, i) => {        if (i === 1 && this.setup_switch) {          return false;        } else if (i === 3 && this.freight_switch) {          return false;        } else {          return item        }      })    },  },  methods: {    ...mapActions(['getUserInfo']),    getQuote() {      this.$axios        .post('/uk-api/quote/pricequote', { id: this.id })        .then(res => {          if (localStorage.getItem('unit')) {            this.unitData = JSON.parse(localStorage.getItem('unit'))          }          const { attributeList, priceList, default: defaultID } = res.result          if (            !Object.keys(attributeList).length ||            !Object.keys(priceList).length          ) {            this.quoteLoadState = 2            return          }          for (const a in attributeList) {            // 过滤掉website_qty标签无数量            if (attributeList[a]) {              this.initZeroObj[a] = 0            }else{              delete attributeList[a]            }            for (const unit of this.unitData) {              // 如果对象中缺少 attributeList 的 key,则设置为 40              if (!(a in unit) || unit[a] === '') {                this.$set(unit,a,40)              }            }          }          // 格式化数据,对象改成数组          for (const keys in priceList) {            const vals = {}            const { decoration, additionlist, ...remaining } = priceList[keys]            vals.basePrice = []            vals.selectAdditionRow = []            vals.curPrint = 0            vals.name = this.formatDurationString(keys)            vals.nameOrigin = keys            vals.decorationOrign = [...decoration]            vals.decorationID = decoration.map(i => i.id)            vals.decoration = [...decoration].flatMap(item => {              const result = [];              if (item.max_color > 0) {                  result.push({ ...item, max_num: item.max_color,id:`${item.id}-1`,decName:item.max_color_name });              }              if (item.max_point > 0) {                  result.push({ ...item, max_num: item.max_point,id:`${item.id}-2`,decName:item.max_point_name  });              }              return result;            });            vals.additionlist = additionlist            for (const k in remaining) {              const o = {}              o.attributeList = this.copyData(attributeList)              if (remaining[k]?.length>1) {                // 检查数组中各元素的 website_qtyN 是否都等于 "-" or "POA",则删除key                for (const a in attributeList) {                  const is111Poa = remaining[k].every(item => this.POA_Config.includes(item[a]));                  if (is111Poa) {                    delete o.attributeList[a]                  }                }              }else if (remaining[k]?.length === 1) {                // 判断 remaining[k][0] 中是否包含 vals.attributeList 的键,并且对应的值都等于 "-" or "POA",则不删除key                  const obj = remaining[k][0];                  const attributeKeys = Object.keys(o.attributeList);                  const areAllKeysInPOAConfig = attributeKeys.every(key => {                    return Object.prototype.hasOwnProperty.call(obj, key) && this.POA_Config.includes(obj[key]);                  });                  if (!areAllKeysInPOAConfig) {                    attributeKeys.forEach(key => {                      if (Object.prototype.hasOwnProperty.call(obj, key) && this.POA_Config.includes(obj[key])) {                        delete o.attributeList[key];                      }                    });                  }              }              o.name = k              o.data = remaining[k]              o.locationNum = 1              o.part_columns = Object.keys(o.attributeList).map(e => {                return { label: o.attributeList[e].toString(), prop: e }              })              const freightParam = {                postcode: '',                freight_type: 1,                freight: {}              }              o.total_part_columns = this.copyData(o.part_columns).map(obj => ({                ...obj,                ...freightParam              }));              o.remainingAttr = []              const firstColumns = { ...o.part_columns[0],...freightParam}              for(let i = 1; i < 9; i++){                if(!Object.keys(o.attributeList).includes(`website_qty${i}`)){                  const newColumn = {...firstColumns}                  this.$set(newColumn,'prop',`website_qty${i}`)                  o.remainingAttr.push(newColumn)                }              };              vals.basePrice.push(o)              if (!this.allPrintTab.includes(k)) {                this.allPrintTab.push(k)              }            }            this.priceList.push(vals)          }          this.priceList.forEach((options, index) => {            // 原始数据name没空格,需要映射到            if (options.nameOrigin === defaultID?.name) {              this.curWeek = index              options.decorationOrign.forEach((opt, idx) => {                if (opt.id === defaultID?.decoration?.id) {                  this.$set(options, 'curPrint', idx)                }              })            }            // 所有周期的所有打印,进来页面时默认勾选第一条价格            options.basePrice.forEach((opt,idx) => {              this.$set(opt, 'selectBaseRow', opt.data[0] ||{})              opt.decoration_addition = [...(options.decorationOrign?.[idx]?.decoration_addition || []),...(options.additionlist || [])]            })            options.decoration.forEach(opt => {              this.$set(opt, 'num', 0)            })          })          this.initSetupObj = Object.assign({}, this.initZeroObj)          this.initUnitObj = Object.assign({}, this.initZeroObj, {            website_setup: 0,          })          this.initFrightObj = Object.assign({}, this.initZeroObj)          this.buyData = this.buyData.map(item => {            return { ...item, ...this.initSetupObj }          })          this.sellData = this.sellData.map(item => {            return { ...item, ...this.initSetupObj }          })          this.quoteLoadState = 1        })        .catch((e) => {          console.log('this.quoteLoadState1: ', e);          this.quoteLoadState = 2        })    },    formatDurationString(input) {      // 匹配数字和字符串的正则表达式      const regex = /(\d+)([a-zA-Z]+)/g;      const result = input.replace(regex, '$1 $2');      return result;    },    // getWeight() {    //   this.$axios    //     .post('/api/quote/weight', { id: this.id })    //     .then(res => {    //       this.weight = res.result    //     })    //     .catch(() => {})    // },    // getFreight(k) {    //   const postcode = this.comCurBaseTotalColumns[k].postcode    //   const type = this.comCurBaseTotalColumns[k].freight_type    //   const init = { basic:0,pickup:0,minimum:0 }    //   if (postcode.length < 3) {    //     this.comCurBaseTotalColumns[k].freight = init    //     return    //   }    //   this.$axios    //     .post('/api/quote/freight', {    //       postcode,    //       type    //     })    //     .then(res => {    //       this.comCurBaseTotalColumns[k].freight = Array.isArray(res.result)?init:res.result    //     })    // },    getDebFreight: _.debounce(function (k) {      this.getFreight(k)    }, 200),      getNumber(e, row, min) {        if (parseInt(e.target.value) < min) {            this.xxContentVisible = true;            row.label = min        } else {            this.xxContentVisible = false;        }    },    sortBy(items) {      // items.decoration.sort(this.customSort(items.decorationID))      // const targetElement = items.decoration.splice(items.curPrint, 1)[0]      // items.decoration.unshift(targetElement)    },    // 按原打印数组的id字段排序    customSort(decorationID) {      return (a, b) => {        return decorationID.indexOf(a.id) - decorationID.indexOf(b.id)      }    },    dividePrice(a) {      return npDivide(+a, 100)    },    // openMailDialog() {    //   if (this.$utils.checkLogin()) {    //     this.getUserInfo()    //     const { contacts, email, phone, crm_users_id:crmUsersId } = this.userInfo    //     this.enquiryForm.Name = contacts    //     this.enquiryForm.Email = email    //     this.enquiryForm.Phone = phone    //     if (crmUsersId?.length) {    //       this.enquiryConfig[3].selectlist = crmUsersId    //       if (crmUsersId?.length === 1) {    //         this.enquiryForm['Customer manager'] = crmUsersId[0].name    //       }    //     } else {    //       this.enquiryConfig[3].isShow = false    //       this.$delete(this.enquiryForm, 'Customer manager')    //     }    //     this.enquiryFormVisible = true    //   } else {    //     this.openDialog()    //   }    // },    getMailData() {      this.mailData.Url = window.location.href      const { Name, Email, Phone, Comments } = this.enquiryForm      this.mailData['Customer Name'] = Name      this.mailData['Customer Email'] = Email      this.mailData['Customer Phone'] = Phone      this.mailData.Comments = Comments      const { email, level, createTime } = this.userInfo      this.mailData['Member Account'] = email      this.mailData['Member Grade'] = level.name      this.mailData['Member Registration time'] = createTime      this.mailData['Quote time'] = this.$utils.formatTime(new Date())    },    // 发送价格邮件 Enquiry按钮    // async sendPriceMail() {    //   await this.getMailData()    //   await this.getCustomerQuoteData()    //   const {    //     Name,    //     Email,    //     Phone,    //     Comments,    //     'Customer manager': customerManager,    //   } = this.enquiryForm    //   this.$axios    //     .post('/uk-api/quote/sendenquiry', {    //       content: this.$refs.mailtable.$el.innerHTML,    //       name: Name,    //       email: Email,    //       phone: Phone,    //       customer_manager: customerManager || '',    //       url: this.mailData.Url,    //       product_code: this.pageData.product_code,    //       comments: Comments,    //       member_id: this.userInfo.id,    //     })    //     .then(res => {    //       this.setLoading(false)    //       this.enquiryFormVisible = false    //       this.$confirm('Enquiry Sent', {    //         confirmButtonText: 'OK',    //         showCancelButton: false,    //         type: 'success',    //         center: true,    //         showClose: false,    //         confirmButtonClass: 'com-btnblack',    //       }).then(() => {})    //     })    //     .catch(() => {    //       this.setLoading(false)    //     })    // },    // getCustomerQuoteData() {    //   const { name, selectAdditionRow } = this.comCurWeekPrice    //   this.specificationsObj.time = name    //   this.specificationsObj.model = this.comBasePrice.model    //   this.specificationsObj.decoration = this.comCurBasePrice.name    //   if (selectAdditionRow.length) {    //     this.specificationsObj.addonArr = selectAdditionRow.map(    //       item => item.name    //     )    //   } else {    //     this.specificationsObj.addonArr = null    //   }    // },    // openDownloadDialog(type) {    //   this.getCustomerQuoteData()    //   type    //     ? (this.downloadDialogVisible = true)    //     : (this.priceToImgVisible = true)    // },    handleDownloadPdf() {      this.pdfLoading = true      this.$nextTick(() => {        this.$refs.priceToImgRef.htmlToPdf(this.pageData.product_code)      })    },    // 发送PDF邮件    // sendPdfMail() {    //   this.$axios    //     .post('/api/quote/sendpdf', {    //       content: this.$refs.pdf.$el.innerHTML,    //       product_code: this.pageData.product_code,    //       email: this.commentObj['Email Address'],    //     })    //     .then(res => {    //       this.setLoading(false)    //       this.downloadDialogVisible = false    //       this.$confirm('Enquiry Sent', {    //         confirmButtonText: 'OK',    //         showCancelButton: false,    //         type: 'success',    //         center: true,    //         showClose: false,    //         confirmButtonClass: 'com-btnblack',    //       })    //     })    //     .catch(() => {    //       this.setLoading(false)    //     })    // },    copyData(data) {      return JSON.parse(JSON.stringify(data))    },    calculateBuyData(){      const selPriceArr = []      if (JSON.stringify(this.comBasePrice) !== '{}') {        selPriceArr.push(this.comBasePrice)      }      selPriceArr.push(...this.comDecoPrice, ...this.comCurWeekPrice.selectAdditionRow);      if(selPriceArr.length === 0){        this.buyData = this.buyData.map(item => ({ ...item, ...this.initZeroObj }));        return      }      // 累加所选,初始数量对应的单价。赋值给this.initUnitObj      for (const i in this.initUnitObj) {        const columnSum = this.copyData(selPriceArr).reduce(function (prev, cur) {          if (cur[i] === '111' || cur[i] === '111.00') {            return (cur[i] = '-')          } else if (cur[i] === '999' || cur[i] === '999.00') {            return (cur[i] = 'POA')          } else {            // 当基础价格是-POA,后续累加价格是正常数字价,依然返回-POA            if (prev === '-' || prev === 'POA') {              return prev            }            return npPlus(+cur[i], prev).toFixed(2)          }        }, 0)        this.$set(this.initUnitObj, i, columnSum)      }      for (const a in this.comAttributeList) {        // 每次更改选择价格,必须遍历整个comAttributeList        const tempIdx = this.comCurBaseColumns.findIndex(          items => +this.comAttributeList[a] < +items.label        )        if (tempIdx > 0) {          const key = this.comCurBaseColumns[tempIdx - 1].prop          this.$set(this.initChangeUnitObj, a, this.initUnitObj[key])        } else {          const length = this.comCurBaseColumns.length          const key = this.comCurBaseColumns[length - 1].prop          this.$set(this.initChangeUnitObj, a, this.initUnitObj[key])        }        if (          this.initChangeUnitObj[a] === 'POA' ||          this.initChangeUnitObj[a] === '-'        ) {          this.$set(this.initSetupObj, a, this.initChangeUnitObj[a])          this.$set(this.initFrightObj, a, this.initChangeUnitObj[a])        } else {          this.$set(this.initSetupObj, a, this.initUnitObj.website_setup)          // 计算运费          // 单独批次数量的总重          // weight定义是{},后端没数据传回[]          const unitWLocal = this.weight.unit_w_local ? +this.weight.unit_w_local : 0;          const totalWeight = Math.ceil(            npTimes(unitWLocal, this.comAttributeList[a])          )          // Road express  1    AAE:AAEFactor  2          const setupFuel = this.dividePrice(this.configInfo.fuel)          const setupBagFreight = this.dividePrice(this.configInfo.bag_freight)          const setupExpressFreight = this.dividePrice(            this.configInfo.express_freight          )          const AAEFactor = npPlus(1, setupBagFreight, setupFuel)          const expressFactor = npPlus(1, setupExpressFreight, setupFuel)          let frightCost = 0          let freightType          let postcode          let freight = {}          const matchIndex = this.comCurBaseTotalColumns.findIndex(item => item.prop === a)          // 1,所有按第一个运费统计;不为1,则只计算 comCurBaseTotalColumns的[地址数]长度          if (+this.comLocationNum === 1 || this.comLocationNum >= matchIndex + 1) {              ({ freight, freight_type: freightType, postcode } = this.comCurBaseTotalColumns[+this.comLocationNum === 1 ? 0 : matchIndex] || {});          }          if (freightType === 1 && postcode >= 3) {            if (totalWeight > 20) {              const a1 = npMinus(totalWeight, 20)              const a2 = npTimes(a1, +freight.basic)              const a3 = npPlus(+freight.pickup, a2)              frightCost = npTimes(a3, expressFactor)            } else {              frightCost = npTimes(+freight.pickup, expressFactor)            }          } else if (freightType === 2 && postcode >= 3) {            const a1 = npDivide(totalWeight, 5)            const a2 = npTimes(+freight.minimum, Math.ceil(a1))            frightCost = npTimes(a2, AAEFactor)          } else {            frightCost = 0          }          this.$set(this.initFrightObj, a, Math.ceil(frightCost).toFixed(2))        }        if (          this.initChangeUnitObj[a] === '-' ||          this.initChangeUnitObj[a] === 'POA'        ) {          this.$set(this.initTotalObj, a, this.initChangeUnitObj[a])        } else {          const unitQTY = npTimes(            this.initChangeUnitObj[a],            this.comAttributeList[a]          )          this.$set(            this.initTotalObj,            a,            npPlus(              this.initUnitObj.website_setup,              unitQTY,              this.initFrightObj[a]            ).toFixed(2)          )        }        if (this.setup_switch) {          // 业务:Setup价格/对应数量后向上取整          if (            this.initChangeUnitObj[a] === '-' ||            this.initChangeUnitObj[a] === 'POA'          ) {            this.$set(this.initChangeUnitObj, a, this.initChangeUnitObj[a])          } else {            const num =              Math.ceil(                (this.initSetupObj[a] / this.comAttributeList[a]) * 100              ) / 100            this.$set(              this.initChangeUnitObj,              a,              npPlus(this.initChangeUnitObj[a], num).toFixed(2)            )          }        }        if (this.freight_switch) {          if (            this.initChangeUnitObj[a] === '-' ||            this.initChangeUnitObj[a] === 'POA'          ) {            this.$set(this.initChangeUnitObj, a, this.initChangeUnitObj[a])          } else {            const num =              Math.ceil(                (this.initFrightObj[a] / this.comAttributeList[a]) * 100              ) / 100            this.$set(              this.initChangeUnitObj,              a,              npPlus(this.initChangeUnitObj[a], num).toFixed(2)            )          }        }      }      if (this.setup_switch) {        this.$set(this.buyData, 0, { ...this.buyData[0], ...this.initZeroObj, ...{'summary':0.00} })      } else {        this.$set(this.buyData, 0, { ...this.buyData[0], ...this.initSetupObj })      }      this.$set(this.buyData, 1, {        ...this.buyData[1],        ...this.initChangeUnitObj,      })      if (this.freight_switch) {        this.$set(this.buyData, 2, { ...this.buyData[2], ...this.initZeroObj })      } else {        this.$set(this.buyData, 2, {          ...this.buyData[2],          ...this.initFrightObj,        })      }      this.$set(this.buyData, 3, { ...this.buyData[3], ...this.initTotalObj })    },    calculateSellData() {    // 放置comSellData计算和副作用的代码      const buySetup = this.comBuyData[0]      const buyUnit = this.comBuyData[1]      const buyFright = this.comBuyData[2]      let frightSummary = 0      for (const i in this.comAttributeList) {        if (buyUnit[i] === '-' || buyUnit[i] === 'POA') {          this.sellData[0][i] = '-'          this.sellData[1][i] = buyUnit[i]          this.sellData[2][i] = buyUnit[i]          this.sellData[3][i] = buyUnit[i]          this.sellData[4][i] = buyUnit[i]        } else {          const item = this.comLocationNum === 1 ? this.comCurBaseTotalColumns[0] : this.comCurBaseTotalColumns.find(element => element.prop === i);          this.sellData[0][i] = item && item.postcode !== '' ? item.postcode : '-';          // 分别乘以Markup %表格          const key = this.comCurBaseTotalColumns[0]?.prop          if (this.unitData[1] && this.unitData[1][key]) {            const a = npPlus(this.unitData[1][key] / 100, 1)            this.sellData[1][i] = npTimes(buySetup[i], a).toFixed(2)          } else {            this.sellData[1][i] = buySetup[i]          }          if (this.unitData[0][i]) {            const a = npPlus(this.unitData[0][i] / 100, 1)            this.sellData[2][i] = npTimes(buyUnit[i], a).toFixed(2)          } else {            this.sellData[2][i] = buyUnit[i]          }          if (this.unitData[2] && this.unitData[2][key]) {            const a = npPlus(this.unitData[2][key] / 100, 1)            this.sellData[3][i] = npTimes(buyFright[i], a).toFixed(2)            // freight_switch会使qty的运费=0无法计算,故用了initFrightObj            const fa = npTimes(this.initFrightObj[i], a)            frightSummary = npPlus(frightSummary,fa).toFixed(2)          } else {            this.sellData[3][i] = buyFright[i]            frightSummary = npPlus(frightSummary,this.initFrightObj[i]).toFixed(2)          }          const unitQTY = npTimes(this.sellData[2][i], this.comAttributeList[i])          this.$set(            this.sellData[4],            i,            npPlus(this.sellData[1][i], unitQTY, this.sellData[3][i]).toFixed(2)          )        }      }      // 迭代加了Total列,需要统计qty的运费后才能合计运费      if (this.sellData[2].summary !== '-' && this.sellData[2].summary !== 'POA') {        if (this.freight_switch) {          const num = Math.ceil((frightSummary / this.comAttributeList.summary) * 100) / 100          this.sellData[2].summary = npPlus(this.sellData[2].summary, num).toFixed(2)          this.sellData[3].summary = 0.00          const a = npTimes(this.sellData[2].summary,this.comAttributeList.summary)          this.sellData[4].summary = npPlus(this.sellData[1].summary,a).toFixed(2)        } else {          this.sellData[3].summary = frightSummary          this.sellData[4].summary = npPlus(frightSummary,this.sellData[4].summary).toFixed(2)        }      }    },    // 低于最小起订量 把该栏的数值重置到最小起订量    getChildIdx(idx){      this.xxContentVisible = true;      this.$set(this.comCurBaseTotalColumns[idx-1],'label',this.comCurBaseColumns[0]?.label)    },    setMaxNum(val){      if(val > 7){        this.comCurBasePrice.locationNum = 7      }else if(val < 1){        this.comCurBasePrice.locationNum = 1      }    },    ...mapMutations({ openDialog: 'openDialog', setLoading: 'product/setLoading' })  },}</script><style lang='scss' scoped>$deep-blue: #004a97;.exclamation-icon {  width: 18px;  height: 18px;  line-height: 18px;  display: inline-block;  text-align: center;  color: #000;  border-radius: 100%;  border: 1px solid #000;  font-size: 18px;  font-weight: 550;}.popover {  border: 1px solid #eee;  padding: 20px;  .title {    text-align: center;    font-weight: bold;    font-size: 20px;  }}.title1 {  margin: 30px 0 0;  padding: 20px 0 0;  font-size: 16px;  color: #15263d;  display: flex;  font-family: ProximaNova-Regular;  font-weight: 600;  justify-content: space-between;  border-top: 1px solid #eee;  span {    &:nth-child(2) {      font-size: 14px;      color: #50596b;    }  }}.text-red {  text-align: right;  color: #e90000;  padding: 10px 10px 0 0;  font-size: 16px;  font-weight: bold;}.entry {  color: #50596b;  margin: 15px 10px;  display: flex;  flex-direction: row;  align-items: center;  .entry-l {    width: 120px;    margin-right: 10px;  }  .entry-text{    margin-left: 280px;    width: 130px;    text-align: center;    font-weight: bold;  }  :deep(.el-input__inner) {    text-align: center;    padding: 0;  }  .entry-r {    flex: 1;    text-align: right;    span {      margin-right: 10px;    }    //修改radio选中为✔样式    :deep(.el-radio__inner) {      border-radius: 0;      width: 18px;      height: 18px;    }    :deep(.el-radio__input.is-checked .el-radio__inner) {      background: $deep-blue;      border: 1px solid $deep-blue;    }    :deep(.el-radio__input.is-checked + .el-radio__label) {      color: $deep-blue;    }    :deep(.el-radio__input.is-checked .el-radio__inner::after) {      content: '';      width: 10px;      height: 5px;      border: 1px solid white;      border-top: transparent;      border-right: transparent;      text-align: center;      display: block;      position: absolute;      top: 3px;      left: 2px;      transform: rotate(-45deg);      border-radius: 0px;      background: none;    }  }}.button-margin {  margin: 20px 0 0;}.quote-tips {  font-size: 16px;  a {    color: #6495ed;    text-decoration: underline;    margin-left: 5px;  }}button {  font-size: 12px;  width: 200px;  height: 30px;  border-radius: 5px;  margin-right: 20px;  cursor: pointer;  border: none;  box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.2);}.button-black {  background-color: $deep-blue;  color: #ffffff;  &:hover {    background-color: #013269;  }}.button-white {  background-color: #fff;  color: #50596b;  img,  span {    vertical-align: middle;  }}// 报价图片弹框样式:deep(.price-to-img-dialog) {  min-width: 840px;  margin-top: 2vh !important;  .el-dialog__header {    background-color: #00213b;    padding: 10px 20px;    .el-dialog__title {      color: #fff;    }    .el-dialog__headerbtn {      top: 15px;    }  }  .el-dialog__body {    background-color: #f1f4f9;    padding: 13px 20px;  }  .tips {    font-size: 16px;    color: #00213b;    margin: 12px 0;  }  .btn-wrap {    text-align: left;    .button-black {      margin-top: 20px;    }  }}:deep(.el-switch) {  .el-switch__label {    position: absolute;    display: none;    color: #fff !important;  }  /*打开时文字位置设置*/  .el-switch__label--right {    z-index: 1;    right: -3px;  }  /*关闭时文字位置设置*/  .el-switch__label--left {    z-index: 1;    left: 20px;  }  /*显示文字*/  .el-switch__label.is-active {    display: block;  }  .el-switch .el-switch__core,  .el-switch .el-switch__label {    width: 50px !important;  }  .el-switch__label * {    font-size: 13px !important;  }}</style>
 |