Quote.vue 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491
  1. <template>
  2. <div>
  3. <div
  4. v-if="quoteLoadState == 0"
  5. v-loading="true"
  6. class="com-loading"></div>
  7. <div v-else-if="quoteLoadState == 1">
  8. <tab-nav
  9. :borderType="'allBorder'"
  10. :liWidth="100"
  11. :liHeight="40"
  12. :marginRight="5"
  13. :currTab.sync="curWeek"
  14. :tabList="priceList" />
  15. <div
  16. v-for="(items, indexs) in priceList"
  17. :key="items.name"
  18. v-show="curWeek == indexs">
  19. <div>
  20. <tab-nav
  21. :borderType="'incompleteBorder'"
  22. :currTab.sync="items.curPrint"
  23. :tabList="items.basePrice"
  24. :allPrintTab="allPrintTab"
  25. :marginTop="0"
  26. :marginRight="5"
  27. :marginBottom="items.basePrice?.length > 1 ? 7 : 0"
  28. @handle="sortBy(items)" />
  29. <!-- <el-popover
  30. placement="bottom-start"
  31. trigger="hover">
  32. <div
  33. class="exclamation-icon"
  34. slot="reference">!</div>
  35. <div class="popover">
  36. <p class="title">Print Price Comparison</p>
  37. <div
  38. v-for="(item,index) in items.basePrice"
  39. :key="item.name">
  40. <total-table
  41. :tableColumns="[...undecorated_columns, ...items.part_columns]"
  42. :tableData="item.data"
  43. :tableType="'Comparison'"
  44. :title="item.name"
  45. :curDecoration="items.decorationOrign[items.curPrint]" :indexDecoration="items.decorationOrign[index]"></total-table>
  46. </div>
  47. </div>
  48. </el-popover> -->
  49. </div>
  50. <div
  51. v-for="(item, index) in items.basePrice"
  52. :key="item.name"
  53. v-show="items.curPrint == index">
  54. <new-price-table
  55. :tableColumns="[...undecorated_columns, ...item.part_columns]"
  56. :tableData="item.data"
  57. :tableType="'Undecorated'"
  58. :curPrint="item.name"
  59. :curModel="items.decorationOrign[index]?.model"
  60. :data="items"
  61. :selectRow.sync="item.selectBaseRow"></new-price-table>
  62. </div>
  63. <!-- decoration_multiple is_more_print 打印开关,ID1001092需求 ;additional_print 颜色数量开关
  64. 以上需求作废,改版为多色多面的需求-->
  65. <new-price-table
  66. v-if="
  67. items.decoration?.length ||
  68. items.basePrice?.[items.curPrint]?.decoration_addition?.length
  69. "
  70. :tableData="items.decoration"
  71. :tableColumns="[...decoration_columns, ...comCurBaseColumns]"
  72. :tableType="'Decoration'"
  73. :marginBottom="0"
  74. :hasDecAdd="
  75. items.basePrice?.[items.curPrint]?.decoration_addition?.length
  76. "></new-price-table>
  77. <div
  78. v-for="(item, index) in items.basePrice"
  79. :key="item.name + index"
  80. v-show="items.curPrint == index && item.decoration_addition.length">
  81. <new-price-table
  82. :tableData="item.decoration_addition"
  83. :tableColumns="[...addon_columns, ...item.part_columns]"
  84. :isCheckBox="true"
  85. :tableType="'Addon'"
  86. :multipleSelection.sync="items.selectAdditionRow"></new-price-table>
  87. </div>
  88. </div>
  89. <!-- <section>
  90. <p class="title1">
  91. <span></span>
  92. <span>Currency GBP(£)</span>
  93. </p>
  94. <total-table
  95. :comLocationNum="comLocationNum"
  96. :tableData="comBuyData"
  97. :tableColumns="[
  98. ...buy_columns,
  99. ...comCurBaseTotalColumns
  100. ]"
  101. :curOrder="`${curWeek}-${comCurPrint}`"
  102. :min="comCurBaseColumns[0]?.label"
  103. :title="'Buy Price'" @send-idx="getChildIdx"></total-table>
  104. <p class="text-red">Price is ex- gst</p>
  105. <ul>
  106. <li class="entry">
  107. <div class="entry-l">Delivery Locations</div>
  108. <el-input
  109. placeholder="Enter Num"
  110. v-model="comCurBasePrice.locationNum"
  111. size="small" max="7" min="1"
  112. style="width: 130px;"
  113. type="number" @input="setMaxNum"></el-input>
  114. </li>
  115. <li
  116. class="entry"
  117. v-if="comLocationNum > 1">
  118. <div class="entry-text">Qty / Location</div>
  119. </li>
  120. <li class="entry" v-for="(i,k) in comCurBaseTotalColumns" :key="i.prop" v-show="comLocationNum > k">
  121. <div class="entry-l">Delivery Postcode</div>
  122. <el-input
  123. clearable
  124. placeholder="Enter Postcode"
  125. v-model="
  126. i.postcode"
  127. size="small"
  128. style="width: 130px; margin-right: 20px;"
  129. @input="getDebFreight(k)"></el-input>
  130. <el-input
  131. v-if="comLocationNum > 1"
  132. placeholder="Enter Qty"
  133. type="number"
  134. :min="comCurBaseColumns[0]?.label"
  135. @blur="getNumber($event, comCurBaseTotalColumns[k],comCurBaseColumns[0]?.label)"
  136. v-model="i.label"
  137. size="small"
  138. style="width: 130px; margin-right: 20px;"></el-input>
  139. <div class="entry-r">
  140. <span>Freight Method</span>
  141. <el-radio-group
  142. v-model="i.freight_type"
  143. @change="getFreight(k)">
  144. <el-radio :label="1">Road Express</el-radio>
  145. <el-radio :label="2">Air Freight</el-radio>
  146. </el-radio-group>
  147. </div>
  148. </li>
  149. </ul>
  150. <div class="entry">
  151. <div class="entry-l">Setup</div>
  152. <div class="entry-l">include in unit price</div>
  153. <pc-switch v-model="setup_switch"></pc-switch>
  154. </div>
  155. <div class="entry">
  156. <div class="entry-l">Freight</div>
  157. <div class="entry-l">include in unit price</div>
  158. <div>
  159. <pc-switch v-model="freight_switch"></pc-switch>
  160. </div>
  161. </div>
  162. </section> -->
  163. <el-button
  164. size="medium"
  165. class="button-black"
  166. style="margin-top: 12px"
  167. @click="openMailDialog">
  168. Enquiry
  169. </el-button>
  170. <!-- <section>
  171. <unit-table
  172. :tableData="unitData"
  173. :tableColumns="[
  174. ...unit_columns,
  175. ...comCurBaseTotalColumns
  176. ]"></unit-table>
  177. 直接用comMergeColumns会出现summary数值问题,改用v-show="comLocationNum"控制
  178. <total-table
  179. v-show="comLocationNum == 1"
  180. :tableData="comSellData"
  181. :tableColumns="comNoSumCol"
  182. :comLocationNum="comLocationNum"
  183. :title="'Sell Price'"></total-table>
  184. <total-table
  185. v-show="comLocationNum != 1"
  186. :tableData="comSellData"
  187. :tableColumns="comHasSumCol"
  188. :comLocationNum="comLocationNum"
  189. :title="'Sell Price'"></total-table>
  190. <el-button
  191. class="button-black button-margin"
  192. size="medium"
  193. @click="openDownloadDialog(0)"
  194. >View Quote</el-button>
  195. <el-button
  196. class="button-black button-margin"
  197. size="medium"
  198. @click="openDownloadDialog(1)"
  199. >Send Order Enquiry</el-button>
  200. </section> -->
  201. </div>
  202. <div
  203. v-else
  204. class="quote-tips">
  205. Current item prices are missing, please contact<a
  206. href="mailto:Info@promocollection.uk">
  207. info@promocollection.uk</a
  208. >
  209. </div>
  210. <no-ssr>
  211. <div v-if="quoteLoadState == 1">
  212. <!-- Enquiry按钮 -->
  213. <form-dialog
  214. :emailForm="enquiryForm"
  215. :enquiryConfig="enquiryConfig"
  216. :visible.sync="enquiryFormVisible"
  217. @handleSend="sendPriceMail"
  218. :rules="rules"
  219. :labelWidth="
  220. enquiryConfig[3].selectlist?.length ? 140 : 82
  221. "></form-dialog>
  222. <mail-table
  223. ref="mailtable"
  224. :mailData="mailData"
  225. v-show="false">
  226. <price-to-img
  227. :pageData="pageData"
  228. :specificationsObj="specificationsObj"
  229. :tableData="comFilterSwitchSellData"
  230. :tableColumns="comMergeColumns"
  231. :comLocationNum="comLocationNum"
  232. :emailForm="commentObj"></price-to-img>
  233. </mail-table>
  234. <el-dialog
  235. ref="dialogRef"
  236. :lock-scroll="false"
  237. title="Customer Quote"
  238. :visible.sync="priceToImgVisible"
  239. custom-class="price-to-img-dialog">
  240. <price-to-img
  241. :isImgSrc="false"
  242. ref="priceToImgRef"
  243. :loading.sync="pdfLoading"
  244. :pageData="pageData"
  245. :specificationsObj="specificationsObj"
  246. :tableData="comFilterSwitchSellData"
  247. :tableColumns="comMergeColumns"
  248. :comLocationNum="comLocationNum"
  249. :emailForm="commentObj"></price-to-img>
  250. <p class="tips">Change default standard comment:</p>
  251. <el-input v-model="commentObj.Comments"></el-input>
  252. <div class="btn-wrap">
  253. <el-button
  254. class="button-black button-margin"
  255. size="medium"
  256. @click="handleDownloadPdf"
  257. :loading="pdfLoading"
  258. >Download</el-button
  259. >
  260. </div>
  261. </el-dialog>
  262. <!-- <form-dialog
  263. :emailForm="commentObj"
  264. :enquiryConfig="enquiryConfig1"
  265. :visible.sync="downloadDialogVisible"
  266. @handleSend="sendPdfMail"
  267. :rules="rules1"
  268. :labelWidth="120"
  269. :isSendPdf="true"></form-dialog> -->
  270. <price-to-img
  271. ref="pdf"
  272. v-show="false"
  273. :loading.sync="pdfLoading"
  274. :pageData="pageData"
  275. :specificationsObj="specificationsObj"
  276. :tableData="comFilterSwitchSellData"
  277. :tableColumns="comMergeColumns"
  278. :comLocationNum="comLocationNum"
  279. :emailForm="commentObj"></price-to-img>
  280. <!-- 报价图片弹框 -->
  281. <dialog-XX-success
  282. :visible.sync="xxContentVisible"
  283. :imgType="false"
  284. :content="'This quantity is below the MOQ for this product'"></dialog-XX-success>
  285. </div>
  286. </no-ssr>
  287. </div>
  288. </template>
  289. <script>
  290. import { mapState, mapMutations, mapActions } from 'vuex'
  291. import _ from 'lodash'
  292. import {
  293. times as npTimes,
  294. plus as npPlus,
  295. minus as npMinus,
  296. divide as npDivide,
  297. } from 'number-precision'
  298. import NewPriceTable from '@/components/table/NewPriceTable'
  299. import TotalTable from '@/components/table/TotalTable'
  300. import UnitTable from '@/components/table/UnitTable'
  301. import MailTable from '@/components/table/MailTable'
  302. import dialogXXSuccess from '@/components/DIalogXXSuccess.vue'
  303. export default {
  304. components: {
  305. NewPriceTable,
  306. TotalTable,
  307. UnitTable,
  308. MailTable,
  309. 'dialog-XX-success': dialogXXSuccess,
  310. },
  311. props: {
  312. pageData: {
  313. type: Object,
  314. default: () => {
  315. return {}
  316. },
  317. },
  318. id: {
  319. type: Number,
  320. default: null,
  321. },
  322. },
  323. data() {
  324. return {
  325. quoteLoadState: 0,
  326. curWeek: 0,
  327. allPrintTab: [],
  328. priceList: [],
  329. initZeroObj: {},
  330. initSetupObj: {},
  331. initUnitObj: {},
  332. initChangeUnitObj: {},
  333. initFrightObj: {},
  334. initTotalObj: {},
  335. xxContentVisible: false,
  336. setup_switch: false,
  337. freight_switch: false,
  338. weight: {},
  339. undecorated_columns: [
  340. {
  341. label: 'MODEL',
  342. prop: 'model',
  343. type: 'text',
  344. align: 'left',
  345. width: 150,
  346. extraWidth: 50, // 配合组件 (820-tableColumns[0].width-tableColumns[0].extraWidth)/(tableColumns.length-1)
  347. isFirstColumn: true, // 去掉$符号
  348. },
  349. {
  350. label: 'SETUP',
  351. prop: 'website_setup',
  352. },
  353. ],
  354. decoration_columns: [
  355. {
  356. label: 'PRINT OPTION',
  357. prop: 'dec_code',
  358. type: 'radioInput',
  359. align: 'left',
  360. width: 150,
  361. extraWidth: 50,
  362. },
  363. {
  364. label: 'SETUP',
  365. prop: 'website_setup',
  366. },
  367. ],
  368. addon_columns: [
  369. {
  370. label: 'Addon',
  371. prop: 'name',
  372. type: 'text',
  373. width: 150,
  374. extraWidth: 50,
  375. isFirstColumn: true, // 去掉$符号
  376. },
  377. {
  378. label: 'Setup',
  379. prop: 'website_setup',
  380. },
  381. ],
  382. buy_columns: [
  383. {
  384. label: 'QTY',
  385. prop: 'project',
  386. isFirstColumn: true, // 去掉$符号
  387. },
  388. ],
  389. unit_columns: [
  390. {
  391. label: 'QTY',
  392. prop: 'total',
  393. align: 'left',
  394. isText: true,
  395. },
  396. ],
  397. buyData: [
  398. { project: 'Setup' },
  399. { project: 'Unit' },
  400. { project: 'Freight' },
  401. { project: 'Total' },
  402. ],
  403. unitData: [
  404. { total: 'Unit Rate %' },
  405. { total: 'Setup %' },
  406. { total: 'Freight %' },
  407. ],
  408. sellData: [
  409. { project: 'Postcode', summary: '-' },
  410. { project: 'Setup', summary: 0.0 },
  411. { project: 'Unit', summary: 0.0 },
  412. { project: 'Freight', summary: 0.0 },
  413. { project: 'Total', summary: 0.0 },
  414. ],
  415. POA_Config: ['111', '111.00', '999', '999.00'],
  416. enquiryFormVisible: false,
  417. enquiryForm: {
  418. Name: '',
  419. Email: '',
  420. Phone: '',
  421. 'Customer manager': null,
  422. Comments: '',
  423. },
  424. enquiryConfig: [
  425. { prop: 'Name', type: 'input' },
  426. { prop: 'Email', type: 'input' },
  427. { prop: 'Phone', type: 'input' },
  428. {
  429. prop: 'Customer manager',
  430. type: 'select',
  431. selectlist: [],
  432. isShow: true,
  433. },
  434. { prop: 'Comments', type: 'textarea' },
  435. ],
  436. rules: {
  437. Name: [{ required: true, message: 'Please enter', trigger: 'blur' }],
  438. Email: [
  439. {
  440. required: true,
  441. message: 'Please enter the correct format',
  442. pattern:
  443. /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/,
  444. trigger: 'blur',
  445. },
  446. ],
  447. Phone: [
  448. {
  449. required: true,
  450. message: 'Please enter the correct format',
  451. // pattern: /^1[0-9]{10}$/,
  452. trigger: 'blur',
  453. },
  454. ],
  455. 'Customer manager': [
  456. { required: true, message: 'Please select', trigger: 'change' },
  457. ],
  458. },
  459. mailData: {
  460. Url: '',
  461. },
  462. priceToImgVisible: false,
  463. downloadDialogVisible: false,
  464. commentObj: {
  465. 'Email Address': '',
  466. Comments: '',
  467. },
  468. enquiryConfig1: [
  469. { prop: 'Email Address', type: 'input' },
  470. { prop: 'Comments', type: 'input' },
  471. ],
  472. rules1: {
  473. 'Email Address': [
  474. {
  475. required: true,
  476. message: 'Please enter the correct format',
  477. pattern:
  478. /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/,
  479. trigger: 'blur',
  480. },
  481. ],
  482. },
  483. specificationsObj: {
  484. time: null,
  485. model: null,
  486. decoration: null,
  487. addonArr: null,
  488. },
  489. pdfLoading: false,
  490. }
  491. },
  492. computed: {
  493. ...mapState('config', { configInfo: state => state.configInfo }),
  494. userInfo() {
  495. return this.$store.state.userInfo
  496. },
  497. comCurWeekPrice() {
  498. return this.priceList[this.curWeek] || {}
  499. },
  500. comCurPrint() {
  501. return this.comCurWeekPrice.curPrint
  502. },
  503. comCurBasePrice() {
  504. return this.comCurWeekPrice.basePrice[this.comCurPrint]
  505. },
  506. comLocationNum() {
  507. return +this.comCurWeekPrice.basePrice[this.comCurPrint].locationNum
  508. },
  509. comCurBaseColumns() {
  510. return this.comCurBasePrice.part_columns
  511. },
  512. comCurBaseTotalColumns() {
  513. const d =
  514. this.comCurWeekPrice.basePrice[this.comCurPrint].total_part_columns
  515. const n = this.comLocationNum
  516. if (n === 1) {
  517. return d
  518. } else {
  519. const concatAdd = [
  520. ...d,
  521. ...this.comCurWeekPrice.basePrice[this.comCurPrint].remainingAttr,
  522. ].slice(0, n)
  523. return concatAdd
  524. }
  525. },
  526. comTotalLabel() {
  527. // 计算所有元素label的和
  528. return this.comCurBaseTotalColumns.reduce(
  529. (sum, item) => sum + Number(item.label),
  530. 0
  531. )
  532. },
  533. comSummaryColumns() {
  534. return [{ label: this.comTotalLabel.toString(), prop: 'summary' }]
  535. },
  536. comAttributeList() {
  537. const obj = {}
  538. this.comCurBaseTotalColumns?.forEach(item => {
  539. obj[item.prop] = item.label
  540. })
  541. obj.summary = this.comTotalLabel
  542. return obj
  543. },
  544. // 当前已选基础价
  545. comBasePrice() {
  546. return this.comCurBasePrice.selectBaseRow
  547. },
  548. // 当前累加打印价
  549. comDecoPrice() {
  550. if (!this.comCurWeekPrice.decoration?.length) {
  551. return []
  552. }
  553. const arr = this.comCurWeekPrice.decoration
  554. .map((item, idx) => {
  555. const obj = {}
  556. if (+item.num > 0) {
  557. for (const i in this.initUnitObj) {
  558. if (idx === 0) {
  559. // 首个打印价要取附加价计算
  560. const keyArr = i.split('_')
  561. const supplier_val = item[`supplier_${keyArr[1]}`]
  562. if (this.POA_Config.includes(supplier_val)) {
  563. obj[`${i}`] = supplier_val
  564. } else {
  565. obj[`${i}`] = npTimes(+supplier_val, item.num)
  566. }
  567. } else {
  568. obj[`${i}`] = this.POA_Config.includes(item[i])
  569. ? item[i]
  570. : npTimes(+item[i], item.num)
  571. }
  572. }
  573. }
  574. return obj
  575. })
  576. .filter(obj => Object.keys(obj).length !== 0)
  577. return arr
  578. },
  579. comBuyData() {
  580. this.calculateBuyData()
  581. return this.buyData
  582. },
  583. comNoSumCol() {
  584. return [...this.buy_columns, ...this.comCurBaseTotalColumns]
  585. },
  586. comHasSumCol() {
  587. return [
  588. ...this.buy_columns,
  589. ...this.comCurBaseTotalColumns,
  590. ...this.comSummaryColumns,
  591. ]
  592. },
  593. comMergeColumns() {
  594. return this.comLocationNum == 1 ? this.comNoSumCol : this.comHasSumCol
  595. },
  596. comSellData() {
  597. if (Object.keys(this.comAttributeList).length !== 0) {
  598. this.calculateSellData()
  599. }
  600. return this.sellData
  601. },
  602. comFilterSwitchSellData() {
  603. return this.comSellData?.filter((item, i) => {
  604. if (i === 1 && this.setup_switch) {
  605. return false
  606. } else if (i === 3 && this.freight_switch) {
  607. return false
  608. } else {
  609. return item
  610. }
  611. })
  612. },
  613. },
  614. methods: {
  615. ...mapActions(['getUserInfo']),
  616. getQuote() {
  617. this.$axios
  618. .post('/uk-api/quote/pricequote', { id: this.id })
  619. .then(res => {
  620. if (localStorage.getItem('unit')) {
  621. this.unitData = JSON.parse(localStorage.getItem('unit'))
  622. }
  623. const { attributeList, priceList, default: defaultID } = res.result
  624. if (
  625. !Object.keys(attributeList).length ||
  626. !Object.keys(priceList).length
  627. ) {
  628. this.quoteLoadState = 2
  629. return
  630. }
  631. for (const a in attributeList) {
  632. // 过滤掉website_qty标签无数量
  633. if (attributeList[a]) {
  634. this.initZeroObj[a] = 0
  635. } else {
  636. delete attributeList[a]
  637. }
  638. for (const unit of this.unitData) {
  639. // 如果对象中缺少 attributeList 的 key,则设置为 40
  640. if (!(a in unit) || unit[a] === '') {
  641. this.$set(unit, a, 40)
  642. }
  643. }
  644. }
  645. // 格式化数据,对象改成数组
  646. for (const keys in priceList) {
  647. const vals = {}
  648. const { decoration, additionlist, ...remaining } = priceList[keys]
  649. vals.basePrice = []
  650. vals.selectAdditionRow = []
  651. vals.curPrint = 0
  652. vals.name = this.formatDurationString(keys)
  653. vals.nameOrigin = keys
  654. vals.decorationOrign = [...decoration]
  655. vals.decorationID = decoration.map(i => i.id)
  656. vals.decoration = [...decoration].flatMap(item => {
  657. const result = []
  658. if (item.max_color > 0) {
  659. result.push({
  660. ...item,
  661. max_num: item.max_color,
  662. id: `${item.id}-1`,
  663. decName: item.max_color_name,
  664. })
  665. }
  666. if (item.max_point > 0) {
  667. result.push({
  668. ...item,
  669. max_num: item.max_point,
  670. id: `${item.id}-2`,
  671. decName: item.max_point_name,
  672. })
  673. }
  674. return result
  675. })
  676. vals.additionlist = additionlist
  677. for (const k in remaining) {
  678. const o = {}
  679. o.attributeList = this.copyData(attributeList)
  680. if (remaining[k]?.length > 1) {
  681. // 检查数组中各元素的 website_qtyN 是否都等于 "-" or "POA",则删除key
  682. for (const a in attributeList) {
  683. const is111Poa = remaining[k].every(item =>
  684. this.POA_Config.includes(item[a])
  685. )
  686. if (is111Poa) {
  687. delete o.attributeList[a]
  688. }
  689. }
  690. } else if (remaining[k]?.length === 1) {
  691. // 判断 remaining[k][0] 中是否包含 vals.attributeList 的键,并且对应的值都等于 "-" or "POA",则不删除key
  692. const obj = remaining[k][0]
  693. const attributeKeys = Object.keys(o.attributeList)
  694. const areAllKeysInPOAConfig = attributeKeys.every(key => {
  695. return (
  696. Object.prototype.hasOwnProperty.call(obj, key) &&
  697. this.POA_Config.includes(obj[key])
  698. )
  699. })
  700. if (!areAllKeysInPOAConfig) {
  701. attributeKeys.forEach(key => {
  702. if (
  703. Object.prototype.hasOwnProperty.call(obj, key) &&
  704. this.POA_Config.includes(obj[key])
  705. ) {
  706. delete o.attributeList[key]
  707. }
  708. })
  709. }
  710. }
  711. o.name = k
  712. o.data = remaining[k]
  713. o.locationNum = 1
  714. o.part_columns = Object.keys(o.attributeList).map(e => {
  715. return { label: o.attributeList[e].toString(), prop: e }
  716. })
  717. const freightParam = {
  718. postcode: '',
  719. freight_type: 1,
  720. freight: {},
  721. }
  722. o.total_part_columns = this.copyData(o.part_columns).map(obj => ({
  723. ...obj,
  724. ...freightParam,
  725. }))
  726. o.remainingAttr = []
  727. const firstColumns = { ...o.part_columns[0], ...freightParam }
  728. for (let i = 1; i < 9; i++) {
  729. if (!Object.keys(o.attributeList).includes(`website_qty${i}`)) {
  730. const newColumn = { ...firstColumns }
  731. this.$set(newColumn, 'prop', `website_qty${i}`)
  732. o.remainingAttr.push(newColumn)
  733. }
  734. }
  735. vals.basePrice.push(o)
  736. if (!this.allPrintTab.includes(k)) {
  737. this.allPrintTab.push(k)
  738. }
  739. }
  740. this.priceList.push(vals)
  741. }
  742. this.priceList.forEach((options, index) => {
  743. // 原始数据name没空格,需要映射到
  744. if (options.nameOrigin === defaultID?.name) {
  745. this.curWeek = index
  746. options.decorationOrign.forEach((opt, idx) => {
  747. if (opt.id === defaultID?.decoration?.id) {
  748. this.$set(options, 'curPrint', idx)
  749. }
  750. })
  751. }
  752. // 所有周期的所有打印,进来页面时默认勾选第一条价格
  753. options.basePrice.forEach((opt, idx) => {
  754. this.$set(opt, 'selectBaseRow', opt.data[0] || {})
  755. opt.decoration_addition = [
  756. ...(options.decorationOrign?.[idx]?.decoration_addition || []),
  757. ...(options.additionlist || []),
  758. ]
  759. })
  760. options.decoration.forEach(opt => {
  761. this.$set(opt, 'num', 0)
  762. })
  763. })
  764. this.initSetupObj = Object.assign({}, this.initZeroObj)
  765. this.initUnitObj = Object.assign({}, this.initZeroObj, {
  766. website_setup: 0,
  767. })
  768. this.initFrightObj = Object.assign({}, this.initZeroObj)
  769. this.buyData = this.buyData.map(item => {
  770. return { ...item, ...this.initSetupObj }
  771. })
  772. this.sellData = this.sellData.map(item => {
  773. return { ...item, ...this.initSetupObj }
  774. })
  775. this.quoteLoadState = 1
  776. })
  777. .catch(e => {
  778. console.log('this.quoteLoadState1: ', e)
  779. this.quoteLoadState = 2
  780. })
  781. },
  782. formatDurationString(input) {
  783. // 匹配数字和字符串的正则表达式
  784. const regex = /(\d+)([a-zA-Z]+)/g
  785. const result = input.replace(regex, '$1 $2')
  786. return result
  787. },
  788. // getWeight() {
  789. // this.$axios
  790. // .post('/api/quote/weight', { id: this.id })
  791. // .then(res => {
  792. // this.weight = res.result
  793. // })
  794. // .catch(() => {})
  795. // },
  796. // getFreight(k) {
  797. // const postcode = this.comCurBaseTotalColumns[k].postcode
  798. // const type = this.comCurBaseTotalColumns[k].freight_type
  799. // const init = { basic:0,pickup:0,minimum:0 }
  800. // if (postcode.length < 3) {
  801. // this.comCurBaseTotalColumns[k].freight = init
  802. // return
  803. // }
  804. // this.$axios
  805. // .post('/api/quote/freight', {
  806. // postcode,
  807. // type
  808. // })
  809. // .then(res => {
  810. // this.comCurBaseTotalColumns[k].freight = Array.isArray(res.result)?init:res.result
  811. // })
  812. // },
  813. getDebFreight: _.debounce(function (k) {
  814. this.getFreight(k)
  815. }, 200),
  816. getNumber(e, row, min) {
  817. if (parseInt(e.target.value) < min) {
  818. this.xxContentVisible = true
  819. row.label = min
  820. } else {
  821. this.xxContentVisible = false
  822. }
  823. },
  824. sortBy(items) {
  825. // items.decoration.sort(this.customSort(items.decorationID))
  826. // const targetElement = items.decoration.splice(items.curPrint, 1)[0]
  827. // items.decoration.unshift(targetElement)
  828. },
  829. // 按原打印数组的id字段排序
  830. customSort(decorationID) {
  831. return (a, b) => {
  832. return decorationID.indexOf(a.id) - decorationID.indexOf(b.id)
  833. }
  834. },
  835. dividePrice(a) {
  836. return npDivide(+a, 100)
  837. },
  838. openMailDialog() {
  839. if (this.$utils.checkLogin()) {
  840. this.getUserInfo()
  841. const {
  842. contacts,
  843. email,
  844. phone,
  845. crm_users_id: crmUsersId,
  846. } = this.userInfo
  847. this.enquiryForm.Name = contacts
  848. this.enquiryForm.Email = email
  849. this.enquiryForm.Phone = phone
  850. if (crmUsersId?.length) {
  851. this.enquiryConfig[3].selectlist = crmUsersId
  852. if (crmUsersId?.length === 1) {
  853. this.enquiryForm['Customer manager'] = crmUsersId[0].name
  854. }
  855. } else {
  856. this.enquiryConfig[3].isShow = false
  857. this.$delete(this.enquiryForm, 'Customer manager')
  858. }
  859. this.enquiryFormVisible = true
  860. } else {
  861. this.openDialog()
  862. }
  863. },
  864. getMailData() {
  865. this.mailData.Url = window.location.href
  866. const { Name, Email, Phone, Comments } = this.enquiryForm
  867. this.mailData['Customer Name'] = Name
  868. this.mailData['Customer Email'] = Email
  869. this.mailData['Customer Phone'] = Phone
  870. this.mailData.Comments = Comments
  871. const { email, level, createTime } = this.userInfo
  872. this.mailData['Member Account'] = email
  873. this.mailData['Member Grade'] = level.name
  874. this.mailData['Member Registration time'] = createTime
  875. this.mailData['Quote time'] = this.$utils.formatTime(new Date())
  876. },
  877. // 发送价格邮件 Enquiry按钮
  878. async sendPriceMail() {
  879. await this.getMailData()
  880. await this.getCustomerQuoteData()
  881. const {
  882. Name,
  883. Email,
  884. Phone,
  885. Comments,
  886. 'Customer manager': customerManager,
  887. } = this.enquiryForm
  888. this.$axios
  889. .post('/uk-api/quote/sendenquiry', {
  890. content: this.$refs.mailtable.$el.innerHTML,
  891. name: Name,
  892. email: Email,
  893. phone: Phone,
  894. customer_manager: customerManager || '',
  895. url: this.mailData.Url,
  896. product_code: this.pageData.product_code,
  897. comments: Comments,
  898. member_id: this.userInfo.id,
  899. })
  900. .then(res => {
  901. this.setLoading(false)
  902. this.enquiryFormVisible = false
  903. this.$confirm('Enquiry Sent', {
  904. confirmButtonText: 'OK',
  905. showCancelButton: false,
  906. type: 'success',
  907. center: true,
  908. showClose: false,
  909. confirmButtonClass: 'com-btnblack',
  910. }).then(() => {})
  911. })
  912. .catch(() => {
  913. this.setLoading(false)
  914. })
  915. },
  916. getCustomerQuoteData() {
  917. const { name, selectAdditionRow } = this.comCurWeekPrice
  918. this.specificationsObj.time = name
  919. this.specificationsObj.model = this.comBasePrice.model
  920. this.specificationsObj.decoration = this.comCurBasePrice.name
  921. if (selectAdditionRow.length) {
  922. this.specificationsObj.addonArr = selectAdditionRow.map(
  923. item => item.name
  924. )
  925. } else {
  926. this.specificationsObj.addonArr = null
  927. }
  928. },
  929. // openDownloadDialog(type) {
  930. // this.getCustomerQuoteData()
  931. // type
  932. // ? (this.downloadDialogVisible = true)
  933. // : (this.priceToImgVisible = true)
  934. // },
  935. handleDownloadPdf() {
  936. this.pdfLoading = true
  937. this.$nextTick(() => {
  938. this.$refs.priceToImgRef.htmlToPdf(this.pageData.product_code)
  939. })
  940. },
  941. // 发送PDF邮件
  942. // sendPdfMail() {
  943. // this.$axios
  944. // .post('/api/quote/sendpdf', {
  945. // content: this.$refs.pdf.$el.innerHTML,
  946. // product_code: this.pageData.product_code,
  947. // email: this.commentObj['Email Address'],
  948. // })
  949. // .then(res => {
  950. // this.setLoading(false)
  951. // this.downloadDialogVisible = false
  952. // this.$confirm('Enquiry Sent', {
  953. // confirmButtonText: 'OK',
  954. // showCancelButton: false,
  955. // type: 'success',
  956. // center: true,
  957. // showClose: false,
  958. // confirmButtonClass: 'com-btnblack',
  959. // })
  960. // })
  961. // .catch(() => {
  962. // this.setLoading(false)
  963. // })
  964. // },
  965. copyData(data) {
  966. return JSON.parse(JSON.stringify(data))
  967. },
  968. calculateBuyData() {
  969. const selPriceArr = []
  970. if (JSON.stringify(this.comBasePrice) !== '{}') {
  971. selPriceArr.push(this.comBasePrice)
  972. }
  973. selPriceArr.push(
  974. ...this.comDecoPrice,
  975. ...this.comCurWeekPrice.selectAdditionRow
  976. )
  977. if (selPriceArr.length === 0) {
  978. this.buyData = this.buyData.map(item => ({
  979. ...item,
  980. ...this.initZeroObj,
  981. }))
  982. return
  983. }
  984. // 累加所选,初始数量对应的单价。赋值给this.initUnitObj
  985. for (const i in this.initUnitObj) {
  986. const columnSum = this.copyData(selPriceArr).reduce(function (
  987. prev,
  988. cur
  989. ) {
  990. if (cur[i] === '111' || cur[i] === '111.00') {
  991. return (cur[i] = '-')
  992. } else if (cur[i] === '999' || cur[i] === '999.00') {
  993. return (cur[i] = 'POA')
  994. } else {
  995. // 当基础价格是-POA,后续累加价格是正常数字价,依然返回-POA
  996. if (prev === '-' || prev === 'POA') {
  997. return prev
  998. }
  999. return npPlus(+cur[i], prev).toFixed(2)
  1000. }
  1001. },
  1002. 0)
  1003. this.$set(this.initUnitObj, i, columnSum)
  1004. }
  1005. for (const a in this.comAttributeList) {
  1006. // 每次更改选择价格,必须遍历整个comAttributeList
  1007. const tempIdx = this.comCurBaseColumns.findIndex(
  1008. items => +this.comAttributeList[a] < +items.label
  1009. )
  1010. if (tempIdx > 0) {
  1011. const key = this.comCurBaseColumns[tempIdx - 1].prop
  1012. this.$set(this.initChangeUnitObj, a, this.initUnitObj[key])
  1013. } else {
  1014. const length = this.comCurBaseColumns.length
  1015. const key = this.comCurBaseColumns[length - 1].prop
  1016. this.$set(this.initChangeUnitObj, a, this.initUnitObj[key])
  1017. }
  1018. if (
  1019. this.initChangeUnitObj[a] === 'POA' ||
  1020. this.initChangeUnitObj[a] === '-'
  1021. ) {
  1022. this.$set(this.initSetupObj, a, this.initChangeUnitObj[a])
  1023. this.$set(this.initFrightObj, a, this.initChangeUnitObj[a])
  1024. } else {
  1025. this.$set(this.initSetupObj, a, this.initUnitObj.website_setup)
  1026. // 计算运费
  1027. // 单独批次数量的总重
  1028. // weight定义是{},后端没数据传回[]
  1029. const unitWLocal = this.weight.unit_w_local
  1030. ? +this.weight.unit_w_local
  1031. : 0
  1032. const totalWeight = Math.ceil(
  1033. npTimes(unitWLocal, this.comAttributeList[a])
  1034. )
  1035. // Road express 1 AAE:AAEFactor 2
  1036. const setupFuel = this.dividePrice(this.configInfo.fuel)
  1037. const setupBagFreight = this.dividePrice(this.configInfo.bag_freight)
  1038. const setupExpressFreight = this.dividePrice(
  1039. this.configInfo.express_freight
  1040. )
  1041. const AAEFactor = npPlus(1, setupBagFreight, setupFuel)
  1042. const expressFactor = npPlus(1, setupExpressFreight, setupFuel)
  1043. let frightCost = 0
  1044. let freightType
  1045. let postcode
  1046. let freight = {}
  1047. const matchIndex = this.comCurBaseTotalColumns.findIndex(
  1048. item => item.prop === a
  1049. )
  1050. // 1,所有按第一个运费统计;不为1,则只计算 comCurBaseTotalColumns的[地址数]长度
  1051. if (
  1052. +this.comLocationNum === 1 ||
  1053. this.comLocationNum >= matchIndex + 1
  1054. ) {
  1055. ;({
  1056. freight,
  1057. freight_type: freightType,
  1058. postcode,
  1059. } = this.comCurBaseTotalColumns[
  1060. +this.comLocationNum === 1 ? 0 : matchIndex
  1061. ] || {})
  1062. }
  1063. if (freightType === 1 && postcode >= 3) {
  1064. if (totalWeight > 20) {
  1065. const a1 = npMinus(totalWeight, 20)
  1066. const a2 = npTimes(a1, +freight.basic)
  1067. const a3 = npPlus(+freight.pickup, a2)
  1068. frightCost = npTimes(a3, expressFactor)
  1069. } else {
  1070. frightCost = npTimes(+freight.pickup, expressFactor)
  1071. }
  1072. } else if (freightType === 2 && postcode >= 3) {
  1073. const a1 = npDivide(totalWeight, 5)
  1074. const a2 = npTimes(+freight.minimum, Math.ceil(a1))
  1075. frightCost = npTimes(a2, AAEFactor)
  1076. } else {
  1077. frightCost = 0
  1078. }
  1079. this.$set(this.initFrightObj, a, Math.ceil(frightCost).toFixed(2))
  1080. }
  1081. if (
  1082. this.initChangeUnitObj[a] === '-' ||
  1083. this.initChangeUnitObj[a] === 'POA'
  1084. ) {
  1085. this.$set(this.initTotalObj, a, this.initChangeUnitObj[a])
  1086. } else {
  1087. const unitQTY = npTimes(
  1088. this.initChangeUnitObj[a],
  1089. this.comAttributeList[a]
  1090. )
  1091. this.$set(
  1092. this.initTotalObj,
  1093. a,
  1094. npPlus(
  1095. this.initUnitObj.website_setup,
  1096. unitQTY,
  1097. this.initFrightObj[a]
  1098. ).toFixed(2)
  1099. )
  1100. }
  1101. if (this.setup_switch) {
  1102. // 业务:Setup价格/对应数量后向上取整
  1103. if (
  1104. this.initChangeUnitObj[a] === '-' ||
  1105. this.initChangeUnitObj[a] === 'POA'
  1106. ) {
  1107. this.$set(this.initChangeUnitObj, a, this.initChangeUnitObj[a])
  1108. } else {
  1109. const num =
  1110. Math.ceil(
  1111. (this.initSetupObj[a] / this.comAttributeList[a]) * 100
  1112. ) / 100
  1113. this.$set(
  1114. this.initChangeUnitObj,
  1115. a,
  1116. npPlus(this.initChangeUnitObj[a], num).toFixed(2)
  1117. )
  1118. }
  1119. }
  1120. if (this.freight_switch) {
  1121. if (
  1122. this.initChangeUnitObj[a] === '-' ||
  1123. this.initChangeUnitObj[a] === 'POA'
  1124. ) {
  1125. this.$set(this.initChangeUnitObj, a, this.initChangeUnitObj[a])
  1126. } else {
  1127. const num =
  1128. Math.ceil(
  1129. (this.initFrightObj[a] / this.comAttributeList[a]) * 100
  1130. ) / 100
  1131. this.$set(
  1132. this.initChangeUnitObj,
  1133. a,
  1134. npPlus(this.initChangeUnitObj[a], num).toFixed(2)
  1135. )
  1136. }
  1137. }
  1138. }
  1139. if (this.setup_switch) {
  1140. this.$set(this.buyData, 0, {
  1141. ...this.buyData[0],
  1142. ...this.initZeroObj,
  1143. ...{ summary: 0.0 },
  1144. })
  1145. } else {
  1146. this.$set(this.buyData, 0, { ...this.buyData[0], ...this.initSetupObj })
  1147. }
  1148. this.$set(this.buyData, 1, {
  1149. ...this.buyData[1],
  1150. ...this.initChangeUnitObj,
  1151. })
  1152. if (this.freight_switch) {
  1153. this.$set(this.buyData, 2, { ...this.buyData[2], ...this.initZeroObj })
  1154. } else {
  1155. this.$set(this.buyData, 2, {
  1156. ...this.buyData[2],
  1157. ...this.initFrightObj,
  1158. })
  1159. }
  1160. this.$set(this.buyData, 3, { ...this.buyData[3], ...this.initTotalObj })
  1161. },
  1162. calculateSellData() {
  1163. // 放置comSellData计算和副作用的代码
  1164. const buySetup = this.comBuyData[0]
  1165. const buyUnit = this.comBuyData[1]
  1166. const buyFright = this.comBuyData[2]
  1167. let frightSummary = 0
  1168. for (const i in this.comAttributeList) {
  1169. if (buyUnit[i] === '-' || buyUnit[i] === 'POA') {
  1170. this.sellData[0][i] = '-'
  1171. this.sellData[1][i] = buyUnit[i]
  1172. this.sellData[2][i] = buyUnit[i]
  1173. this.sellData[3][i] = buyUnit[i]
  1174. this.sellData[4][i] = buyUnit[i]
  1175. } else {
  1176. const item =
  1177. this.comLocationNum === 1
  1178. ? this.comCurBaseTotalColumns[0]
  1179. : this.comCurBaseTotalColumns.find(element => element.prop === i)
  1180. this.sellData[0][i] =
  1181. item && item.postcode !== '' ? item.postcode : '-'
  1182. // 分别乘以Markup %表格
  1183. const key = this.comCurBaseTotalColumns[0]?.prop
  1184. if (this.unitData[1] && this.unitData[1][key]) {
  1185. const a = npPlus(this.unitData[1][key] / 100, 1)
  1186. this.sellData[1][i] = npTimes(buySetup[i], a).toFixed(2)
  1187. } else {
  1188. this.sellData[1][i] = buySetup[i]
  1189. }
  1190. if (this.unitData[0][i]) {
  1191. const a = npPlus(this.unitData[0][i] / 100, 1)
  1192. this.sellData[2][i] = npTimes(buyUnit[i], a).toFixed(2)
  1193. } else {
  1194. this.sellData[2][i] = buyUnit[i]
  1195. }
  1196. if (this.unitData[2] && this.unitData[2][key]) {
  1197. const a = npPlus(this.unitData[2][key] / 100, 1)
  1198. this.sellData[3][i] = npTimes(buyFright[i], a).toFixed(2)
  1199. // freight_switch会使qty的运费=0无法计算,故用了initFrightObj
  1200. const fa = npTimes(this.initFrightObj[i], a)
  1201. frightSummary = npPlus(frightSummary, fa).toFixed(2)
  1202. } else {
  1203. this.sellData[3][i] = buyFright[i]
  1204. frightSummary = npPlus(
  1205. frightSummary,
  1206. this.initFrightObj[i]
  1207. ).toFixed(2)
  1208. }
  1209. const unitQTY = npTimes(this.sellData[2][i], this.comAttributeList[i])
  1210. this.$set(
  1211. this.sellData[4],
  1212. i,
  1213. npPlus(this.sellData[1][i], unitQTY, this.sellData[3][i]).toFixed(2)
  1214. )
  1215. }
  1216. }
  1217. // 迭代加了Total列,需要统计qty的运费后才能合计运费
  1218. if (
  1219. this.sellData[2].summary !== '-' &&
  1220. this.sellData[2].summary !== 'POA'
  1221. ) {
  1222. if (this.freight_switch) {
  1223. const num =
  1224. Math.ceil((frightSummary / this.comAttributeList.summary) * 100) /
  1225. 100
  1226. this.sellData[2].summary = npPlus(
  1227. this.sellData[2].summary,
  1228. num
  1229. ).toFixed(2)
  1230. this.sellData[3].summary = 0.0
  1231. const a = npTimes(
  1232. this.sellData[2].summary,
  1233. this.comAttributeList.summary
  1234. )
  1235. this.sellData[4].summary = npPlus(
  1236. this.sellData[1].summary,
  1237. a
  1238. ).toFixed(2)
  1239. } else {
  1240. this.sellData[3].summary = frightSummary
  1241. this.sellData[4].summary = npPlus(
  1242. frightSummary,
  1243. this.sellData[4].summary
  1244. ).toFixed(2)
  1245. }
  1246. }
  1247. },
  1248. // 低于最小起订量 把该栏的数值重置到最小起订量
  1249. getChildIdx(idx) {
  1250. this.xxContentVisible = true
  1251. this.$set(
  1252. this.comCurBaseTotalColumns[idx - 1],
  1253. 'label',
  1254. this.comCurBaseColumns[0]?.label
  1255. )
  1256. },
  1257. setMaxNum(val) {
  1258. if (val > 7) {
  1259. this.comCurBasePrice.locationNum = 7
  1260. } else if (val < 1) {
  1261. this.comCurBasePrice.locationNum = 1
  1262. }
  1263. },
  1264. ...mapMutations({
  1265. openDialog: 'openDialog',
  1266. setLoading: 'product/setLoading',
  1267. }),
  1268. },
  1269. }
  1270. </script>
  1271. <style lang="scss" scoped>
  1272. $deep-blue: #004a97;
  1273. .exclamation-icon {
  1274. width: 18px;
  1275. height: 18px;
  1276. line-height: 18px;
  1277. display: inline-block;
  1278. text-align: center;
  1279. color: #000;
  1280. border-radius: 100%;
  1281. border: 1px solid #000;
  1282. font-size: 18px;
  1283. font-weight: 550;
  1284. }
  1285. .popover {
  1286. border: 1px solid #eee;
  1287. padding: 20px;
  1288. .title {
  1289. text-align: center;
  1290. font-weight: bold;
  1291. font-size: 20px;
  1292. }
  1293. }
  1294. .title1 {
  1295. margin: 30px 0 0;
  1296. padding: 20px 0 0;
  1297. font-size: 16px;
  1298. color: #15263d;
  1299. display: flex;
  1300. font-family: ProximaNova-Regular;
  1301. font-weight: 600;
  1302. justify-content: space-between;
  1303. border-top: 1px solid #eee;
  1304. span {
  1305. &:nth-child(2) {
  1306. font-size: 14px;
  1307. color: #50596b;
  1308. }
  1309. }
  1310. }
  1311. .text-red {
  1312. text-align: right;
  1313. color: #e90000;
  1314. padding: 10px 10px 0 0;
  1315. font-size: 16px;
  1316. font-weight: bold;
  1317. }
  1318. .entry {
  1319. color: #50596b;
  1320. margin: 15px 10px;
  1321. display: flex;
  1322. flex-direction: row;
  1323. align-items: center;
  1324. .entry-l {
  1325. width: 120px;
  1326. margin-right: 10px;
  1327. }
  1328. .entry-text {
  1329. margin-left: 280px;
  1330. width: 130px;
  1331. text-align: center;
  1332. font-weight: bold;
  1333. }
  1334. :deep(.el-input__inner) {
  1335. text-align: center;
  1336. padding: 0;
  1337. }
  1338. .entry-r {
  1339. flex: 1;
  1340. text-align: right;
  1341. span {
  1342. margin-right: 10px;
  1343. }
  1344. //修改radio选中为✔样式
  1345. :deep(.el-radio__inner) {
  1346. border-radius: 0;
  1347. width: 18px;
  1348. height: 18px;
  1349. }
  1350. :deep(.el-radio__input.is-checked .el-radio__inner) {
  1351. background: $deep-blue;
  1352. border: 1px solid $deep-blue;
  1353. }
  1354. :deep(.el-radio__input.is-checked + .el-radio__label) {
  1355. color: $deep-blue;
  1356. }
  1357. :deep(.el-radio__input.is-checked .el-radio__inner::after) {
  1358. content: '';
  1359. width: 10px;
  1360. height: 5px;
  1361. border: 1px solid white;
  1362. border-top: transparent;
  1363. border-right: transparent;
  1364. text-align: center;
  1365. display: block;
  1366. position: absolute;
  1367. top: 3px;
  1368. left: 2px;
  1369. transform: rotate(-45deg);
  1370. border-radius: 0px;
  1371. background: none;
  1372. }
  1373. }
  1374. }
  1375. .button-margin {
  1376. margin: 20px 0 0;
  1377. }
  1378. .quote-tips {
  1379. font-size: 16px;
  1380. a {
  1381. color: #6495ed;
  1382. text-decoration: underline;
  1383. margin-left: 5px;
  1384. }
  1385. }
  1386. button {
  1387. font-size: 12px;
  1388. width: 200px;
  1389. height: 30px;
  1390. border-radius: 5px;
  1391. margin-right: 20px;
  1392. cursor: pointer;
  1393. border: none;
  1394. box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.2);
  1395. }
  1396. .button-black {
  1397. background-color: $deep-blue;
  1398. color: #ffffff;
  1399. &:hover {
  1400. background-color: #013269;
  1401. }
  1402. }
  1403. .button-white {
  1404. background-color: #fff;
  1405. color: #50596b;
  1406. img,
  1407. span {
  1408. vertical-align: middle;
  1409. }
  1410. }
  1411. // 报价图片弹框样式
  1412. :deep(.price-to-img-dialog) {
  1413. min-width: 840px;
  1414. margin-top: 2vh !important;
  1415. .el-dialog__header {
  1416. background-color: #00213b;
  1417. padding: 10px 20px;
  1418. .el-dialog__title {
  1419. color: #fff;
  1420. }
  1421. .el-dialog__headerbtn {
  1422. top: 15px;
  1423. }
  1424. }
  1425. .el-dialog__body {
  1426. background-color: #f1f4f9;
  1427. padding: 13px 20px;
  1428. }
  1429. .tips {
  1430. font-size: 16px;
  1431. color: #00213b;
  1432. margin: 12px 0;
  1433. }
  1434. .btn-wrap {
  1435. text-align: left;
  1436. .button-black {
  1437. margin-top: 20px;
  1438. }
  1439. }
  1440. }
  1441. :deep(.el-switch) {
  1442. .el-switch__label {
  1443. position: absolute;
  1444. display: none;
  1445. color: #fff !important;
  1446. }
  1447. /*打开时文字位置设置*/
  1448. .el-switch__label--right {
  1449. z-index: 1;
  1450. right: -3px;
  1451. }
  1452. /*关闭时文字位置设置*/
  1453. .el-switch__label--left {
  1454. z-index: 1;
  1455. left: 20px;
  1456. }
  1457. /*显示文字*/
  1458. .el-switch__label.is-active {
  1459. display: block;
  1460. }
  1461. .el-switch .el-switch__core,
  1462. .el-switch .el-switch__label {
  1463. width: 50px !important;
  1464. }
  1465. .el-switch__label * {
  1466. font-size: 13px !important;
  1467. }
  1468. }
  1469. </style>