index.vue 62 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899
  1. <template>
  2. <div class="compnent-price-calc">
  3. <exportQuota
  4. ref="compExportQuotaRef"
  5. :product-info="productInfo"
  6. :export-form="exportForm"
  7. :step3-form-list="step3FormList"
  8. :step2-form-list="formList"
  9. :creator-options="creatorOptions"
  10. :city2="formData.cal_city.local_city"
  11. :city="exportForm.pdf_city"
  12. ></exportQuota>
  13. <!-- :city="formData.cal_city.local_city" -->
  14. <el-dialog
  15. v-model="show"
  16. class="custom-calc-price-dialog"
  17. title="查看计价结果"
  18. :close-on-click-modal="false"
  19. :close-on-press-escape="false"
  20. :before-close="close"
  21. width="1800px"
  22. >
  23. <div
  24. v-loading="loading"
  25. class="flex items-start flex-wrap"
  26. >
  27. <step1
  28. :computed-box-number="computedBoxNumber"
  29. :computed-total-bulk="computedTotalBulk"
  30. :computed-total-weight="computedTotalWeight"
  31. :computed-total-weight-plus="computedTotalWeightPlus"
  32. :image-list="imageList"
  33. :product-info="productInfo"
  34. ></step1>
  35. <div class="step step-2">
  36. <common-title
  37. :title="$t(prefix + 'label_transport_info')"
  38. ></common-title>
  39. <p style="color: #ef4135; margin-bottom: 12px">
  40. 快速运输天数:2-3天 / 空+派运输天数:8天 /
  41. 海运运输天数:LCL30天、FCL25天
  42. </p>
  43. <div class="flex items-center">
  44. <el-select
  45. v-model="formData.cal_city.local_city"
  46. style="width: 120px; margin-right: 12px"
  47. size="small"
  48. @change="onCityChange"
  49. >
  50. <el-option
  51. v-for="city in cityList"
  52. :key="city"
  53. :label="city"
  54. :value="city"
  55. ></el-option>
  56. </el-select>
  57. <div class="flex items-center">
  58. <el-tooltip content="切换城市后点击">
  59. <el-button
  60. type="primary"
  61. size="small"
  62. @click="reGenerateFormAfterCityChange"
  63. >
  64. 生成运输信息
  65. </el-button>
  66. </el-tooltip>
  67. <el-button
  68. type="warning"
  69. size="small"
  70. @click="componentFreightVisible = true"
  71. >
  72. 设置运费参数
  73. </el-button>
  74. </div>
  75. </div>
  76. <div class="step2-form-area">
  77. <div
  78. v-for="(formItem, index) in formList"
  79. :key="index"
  80. class="step2-form-item"
  81. >
  82. <div class="qty-number">
  83. 采购数量:&nbsp;{{ formItem.number }} ({{ isHeavyGoods.label
  84. }}{{
  85. isHeavyGoodsPlus.flag !== isHeavyGoods.flag
  86. ? ` | ${isHeavyGoodsPlus.label}`
  87. : ''
  88. }})
  89. </div>
  90. <div class="flex items-center">
  91. <el-card
  92. v-for="v in 5"
  93. :key="v"
  94. class="form-item-card"
  95. :class="{
  96. on: formItem[`${v - 1}_${formItem.number}`] === 'on',
  97. }"
  98. >
  99. <template #header>
  100. <div
  101. @click.capture="
  102. ($e) => captureSwitchChange($e, formItem, v - 1)
  103. "
  104. >
  105. <!-- <el-tooltip
  106. placement="left"
  107. content="注意, 切换开关会导致右侧的成本数据 以(点过'保存按钮'后的 / 默认的)初始值 计算重置"
  108. > -->
  109. <el-switch
  110. v-model="formItem[`${v - 1}_${formItem.number}`]"
  111. size="small"
  112. active-color="#409eff"
  113. inactive-color="#ccc"
  114. active-value="on"
  115. inactive-value="off"
  116. @change="
  117. () => generateStep3Form({ y: v - 1, x: index })
  118. "
  119. />
  120. <!-- </el-tooltip> -->
  121. </div>
  122. </template>
  123. <div v-if="v === 1">
  124. <el-select
  125. v-model="formItem[`method_0_${formItem.number}`]"
  126. size="small"
  127. @change="
  128. reGenerateFormAfterMidwayTypeChange({
  129. x: index,
  130. y: 0,
  131. })
  132. "
  133. >
  134. <el-option
  135. v-for="option in airOption"
  136. :key="option.value"
  137. :label="option.label"
  138. :value="option.value"
  139. ></el-option>
  140. </el-select>
  141. <div class="price">
  142. $&nbsp;{{ formItem.midway_price_0.toFixed(2) }}
  143. </div>
  144. </div>
  145. <div v-if="v === 2">
  146. <div>空+派</div>
  147. <div class="price">
  148. $&nbsp;{{ formItem.midway_price_1.toFixed(2) }}
  149. </div>
  150. </div>
  151. <div v-if="v === 3">
  152. <el-select
  153. v-model="formItem[`method_2_${formItem.number}`]"
  154. size="small"
  155. @change="
  156. reGenerateFormAfterMidwayTypeChange({
  157. x: index,
  158. y: 2,
  159. })
  160. "
  161. >
  162. <el-option
  163. v-for="option in seaOption"
  164. :key="option.value"
  165. :label="option.label"
  166. :value="option.value"
  167. ></el-option>
  168. </el-select>
  169. <div class="price">
  170. $&nbsp;{{ formItem.midway_price_2.toFixed(2) }}
  171. </div>
  172. </div>
  173. <div v-if="v === 4">
  174. <div>DTD</div>
  175. <div
  176. v-if="formItem.freight_cost_3"
  177. class="price cursor-pointer"
  178. @click="openDTDDialog(3, index)"
  179. >
  180. $&nbsp;{{ Number(formItem.freight_cost_3).toFixed(2) }}
  181. </div>
  182. <div
  183. v-else
  184. class="edit cursor-pointer"
  185. @click="openDTDDialog(3, index)"
  186. >
  187. {{ $t('btn_edit') }}
  188. </div>
  189. </div>
  190. <div v-if="v === 5">
  191. <div>LCL散货</div>
  192. <div
  193. v-if="formItem.freight_cost_4"
  194. class="price cursor-pointer"
  195. @click="openLCLDialog(4, index)"
  196. >
  197. $&nbsp;{{ formItem.freight_cost_4.toFixed(2) }}
  198. </div>
  199. <div
  200. v-else
  201. class="edit cursor-pointer"
  202. @click="openLCLDialog(4, index)"
  203. >
  204. {{ $t('btn_edit') }}
  205. </div>
  206. </div>
  207. </el-card>
  208. </div>
  209. </div>
  210. </div>
  211. </div>
  212. <div class="step step-3">
  213. <div
  214. class="mb-4 border border-x-0 border-t-0 border-solid border-gray-200"
  215. >
  216. <el-check-tag
  217. v-for="(form, index) in step3FormList"
  218. :checked="index === currentTab"
  219. :key="index"
  220. class="border border-solid border-gray-200 bg-white"
  221. style="border-radius: 2px"
  222. @click="currentTab = index"
  223. >
  224. {{ form.tabLabel }}
  225. </el-check-tag>
  226. </div>
  227. <div
  228. data-desc="这层div没用的,只是移除原本的el-tab之后用来减少代码改动量,不然里面的内容全部要减少一个缩进单位了"
  229. >
  230. <div
  231. v-show="index === currentTab"
  232. v-for="(form, index) in step3FormList"
  233. :key="index"
  234. >
  235. <common-title
  236. :title="$t(prefix + 'label_cost_list')"
  237. ></common-title>
  238. <div class="horizontal-table">
  239. <div
  240. class="flex items-center tr"
  241. style="background-color: #ebeef5"
  242. >
  243. <div class="td">项目</div>
  244. <div class="td">总价</div>
  245. <div class="td">单价</div>
  246. </div>
  247. <div class="flex items-center tr">
  248. <div class="td column-label">产品成本(AUD)</div>
  249. <div class="td">
  250. {{ Number(form.product_cost).toFixed(2) }}
  251. </div>
  252. <div class="td">
  253. {{ (Number(form.product_cost) / form.number).toFixed(2) }}
  254. </div>
  255. </div>
  256. <div class="flex items-center tr">
  257. <div class="td column-label">制版及其它成本(AUD)</div>
  258. <div class="td">
  259. {{ Number(form.extend_cost).toFixed(2) }}
  260. </div>
  261. <div class="td">
  262. {{ (Number(form.extend_cost) / form.number).toFixed(2) }}
  263. </div>
  264. </div>
  265. <div class="flex items-center tr">
  266. <div class="td column-label">运费总成本(AUD)</div>
  267. <div class="td">
  268. {{ Number(form.freight_cost).toFixed(2) }}
  269. </div>
  270. <div class="td">
  271. {{ (Number(form.freight_cost) / form.number).toFixed(2) }}
  272. </div>
  273. </div>
  274. <div class="flex items-center tr">
  275. <div class="td column-label">税费(AUD)</div>
  276. <div class="td">
  277. {{ Number(form.tax_fee).toFixed(2) }}
  278. </div>
  279. <div class="td">
  280. {{ (Number(form.tax_fee) / form.number).toFixed(2) }}
  281. </div>
  282. </div>
  283. <div class="flex items-center tr">
  284. <div class="td column-label">入口报关费(AUD)</div>
  285. <div class="td">
  286. {{ Number(form.gatt_tax_fee).toFixed(2) }}
  287. </div>
  288. <div class="td">
  289. {{ (Number(form.gatt_tax_fee) / form.number).toFixed(2) }}
  290. </div>
  291. </div>
  292. <div class="flex items-center tr">
  293. <div class="td column-label">验货费(AUD)</div>
  294. <div class="td">
  295. {{ Number(form.review_cost).toFixed(2) }}
  296. </div>
  297. <div class="td">
  298. {{ (Number(form.review_cost) / form.number).toFixed(2) }}
  299. </div>
  300. </div>
  301. <div class="flex items-center tr">
  302. <div class="td column-label">总成本(AUD)</div>
  303. <div class="td">
  304. {{ Number(form.total_cost).toFixed(2) }}
  305. </div>
  306. <div class="td">
  307. {{ (Number(form.total_cost) / form.number).toFixed(2) }}
  308. </div>
  309. </div>
  310. </div>
  311. <el-form
  312. :model="form"
  313. label-width="105px"
  314. >
  315. <common-title
  316. :title="$t(prefix + 'label_other_cost')"
  317. ></common-title>
  318. <div class="">
  319. <el-form-item
  320. label="COO Certificate"
  321. label-width="120px"
  322. >
  323. <el-switch
  324. v-model="form.coo_certificate"
  325. active-color="#409eff"
  326. inactive-color="#ccc"
  327. active-text="是"
  328. inactive-text="否"
  329. active-value="on"
  330. inactive-value="off"
  331. size="small"
  332. @change="($e: any) => changeCOO(form, $e)"
  333. ></el-switch>
  334. </el-form-item>
  335. </div>
  336. <div class="flex justify-between flex-wrap items-center">
  337. <el-form-item label="税点">
  338. <el-input
  339. v-model="form.tax"
  340. :disabled="form.coo_certificate === 'on'"
  341. @input="() => onForm3ItemChange(form, 'tax')"
  342. >
  343. <template #append>%</template>
  344. </el-input>
  345. </el-form-item>
  346. <el-form-item label="税费">
  347. <el-input
  348. v-model="form.tax_fee"
  349. disabled
  350. >
  351. <template #append>AUD</template>
  352. </el-input>
  353. </el-form-item>
  354. <el-form-item label="入口报关费用">
  355. <el-input
  356. v-model="form.gatt_tax_fee"
  357. @input="() => onForm3ItemChange(form, 'gatt_tax_fee')"
  358. >
  359. <template #append>AUD</template>
  360. </el-input>
  361. </el-form-item>
  362. <el-form-item label="验货费">
  363. <el-input
  364. v-model="form.review_cost"
  365. @input="() => onForm3ItemChange(form, 'review_cost')"
  366. >
  367. <template #append>AUD</template>
  368. </el-input>
  369. </el-form-item>
  370. <el-form-item label="国内运费总价">
  371. <el-input
  372. v-model="form.cn_freight_cost"
  373. @input="() => onForm3ItemChange(form, 'cn_freight_cost')"
  374. >
  375. <template #append>RMB</template>
  376. </el-input>
  377. </el-form-item>
  378. <el-form-item label="国外本土运费">
  379. <el-input
  380. v-model="form.local_freight_cost"
  381. @input="
  382. () => onForm3ItemChange(form, 'local_freight_cost')
  383. "
  384. >
  385. <template #append>AUD</template>
  386. </el-input>
  387. </el-form-item>
  388. </div>
  389. <common-title
  390. :title="$t(prefix + 'label_charge')"
  391. ></common-title>
  392. <div class="flex justify-between flex-wrap items-center">
  393. <el-form-item label="Set Up Cost">
  394. <el-input
  395. v-model="form.setup_cost"
  396. @input="() => onForm3ItemChange(form, 'setup_cost')"
  397. >
  398. <template #append>AUD</template>
  399. </el-input>
  400. </el-form-item>
  401. <el-form-item label="本地收费">
  402. <el-input
  403. v-model="form.add_freight_cost"
  404. @input="() => onForm3ItemChange(form, 'add_freight_cost')"
  405. >
  406. <template #append>AUD</template>
  407. </el-input>
  408. </el-form-item>
  409. <el-form-item label="售卖单价">
  410. <el-input
  411. v-model="form.sold_unit"
  412. @input="() => onForm3ItemChange(form, 'sold_unit')"
  413. >
  414. <template #append>AUD</template>
  415. </el-input>
  416. </el-form-item>
  417. <el-form-item label="售卖总价">
  418. <el-input
  419. v-model="form.sold_price"
  420. disabled
  421. >
  422. <template #append>AUD</template>
  423. </el-input>
  424. </el-form-item>
  425. </div>
  426. <common-title
  427. :title="$t(prefix + 'label_analysis')"
  428. ></common-title>
  429. <div class="flex justify-between items-center">
  430. <el-form-item label="利润率">
  431. <el-input
  432. v-model="form.profit_margin"
  433. @input="() => onForm3ItemChange(form, 'profit_margin')"
  434. >
  435. <template #append>%</template>
  436. </el-input>
  437. </el-form-item>
  438. <el-form-item label="利润">
  439. <el-input
  440. v-model="form.profit"
  441. disabled
  442. >
  443. <template #append>AUD</template>
  444. </el-input>
  445. </el-form-item>
  446. </div>
  447. </el-form>
  448. <div class="flex justify-center items-center">
  449. <el-button
  450. type="primary"
  451. size="small"
  452. @click="
  453. () => {
  454. isExport = 0
  455. checkForm(1)
  456. }
  457. "
  458. >
  459. {{ $t('btn_save') }}
  460. </el-button>
  461. <el-button
  462. type="primary"
  463. size="small"
  464. plain
  465. @click="
  466. () => {
  467. isExport = 1
  468. checkForm(2)
  469. }
  470. "
  471. >
  472. 保存并导出
  473. </el-button>
  474. <!-- <el-button @click="generate">test</el-button> -->
  475. </div>
  476. </div>
  477. </div>
  478. </div>
  479. </div>
  480. <setDTD
  481. v-model:visible="dtdVisible"
  482. :form-data="dtdData"
  483. @save="dtdChange"
  484. ></setDTD>
  485. <setLCL
  486. v-model:visible="lclVisible"
  487. :form-data="lclData"
  488. @save="lclChange"
  489. ></setLCL>
  490. <freight
  491. v-model:visible="componentFreightVisible"
  492. @save="getCalcParam"
  493. ></freight>
  494. <CompExportForm
  495. v-model:visible="componentExportFormVisible"
  496. :step3-form-list="step3FormList"
  497. :creator-options="creatorOptions"
  498. :form-data="exportForm"
  499. :city-list="cityList"
  500. @save="onExportFormSave"
  501. ></CompExportForm>
  502. </el-dialog>
  503. </div>
  504. </template>
  505. <script lang="ts" setup>
  506. import { defineComponent, ref, watch, computed, nextTick, inject } from 'vue'
  507. import {
  508. ElButton,
  509. ElNotification,
  510. ElMessage,
  511. ElForm,
  512. ElFormItem,
  513. ElInput,
  514. ElSelect,
  515. ElDialog,
  516. ElOption,
  517. ElSwitch,
  518. ElCard,
  519. ElCheckTag,
  520. ElTooltip,
  521. } from 'element-plus'
  522. import cloneDeep from 'lodash.clonedeep'
  523. import commonTitle from './components/title.vue'
  524. import setDTD from './components/dialogDTD.vue'
  525. import setLCL from './components/dialogLCL.vue'
  526. import freight from '../freight.vue'
  527. import step1 from './components/step1.vue'
  528. import CompExportForm from '../exportForm.vue'
  529. import exportQuota from '../exportQuota2.vue'
  530. import mathjs, { savePrecision } from '@/utils/math.js'
  531. import Cookies from 'js-cookie'
  532. import { getCalcParams, saveCalcData } from '@/api/indent'
  533. import { $t } from '@/i18n/index'
  534. defineComponent({
  535. name: 'ComponentAaaa',
  536. })
  537. const {
  538. visible = false,
  539. dataForCalc = {} as any,
  540. creatorOptions = [],
  541. } = defineProps<{
  542. visible: boolean
  543. dataForCalc: object
  544. creatorOptions: any[]
  545. }>()
  546. const $emit = defineEmits([
  547. 'update:visible',
  548. 'save-price-calc',
  549. 'save-price-calc',
  550. ])
  551. const $mediaRegExp = inject('mediaRegExp') as RegExp
  552. const prefix = 'order.indent_calc.'
  553. const loading = ref(false)
  554. const componentFreightVisible = ref(false)
  555. const componentExportFormVisible = ref(false)
  556. const productInfo = ref({} as any)
  557. const setting = ref({} as any) // 运费设置数据
  558. // 用在step2界面上显示的表单
  559. const formList = ref([] as any[])
  560. // 用在step3界面上显示的表单
  561. const step3FormList = ref([] as any[])
  562. const currentTab = ref(0) // 当前显示的step3表单的tab索引
  563. // 提交的表单, 用来存真正提交的数据.
  564. const formData = ref({
  565. cal_city: {
  566. local_city: '',
  567. },
  568. cal_shipment_method: {},
  569. } as any)
  570. // 导出pdf那个表单
  571. let exportForm = ref({
  572. city: '', // 显示在导出pdf的城市地址, 不是step2的运费选择地址.
  573. exchange: '',
  574. days: '30',
  575. gst_name: '+GST',
  576. notes: '',
  577. other_notes: '',
  578. saleperson: '',
  579. } as any)
  580. const step3FormDemo = ref({
  581. coo_certificate: 'on', // coo 开关
  582. tax: 0, // 税点 coo打开则是0, 关闭默认是5
  583. tax_fee: 0, // 税费 coo打开则是0, 需要根据税点计算
  584. gatt_tax_fee: 60, // 入口报关费用
  585. review_cost: 0, // 验货费
  586. cn_freight_cost: 0, // 国内运费总价
  587. local_freight_cost: 0, // 国外本地运费
  588. add_freight_cost: 0, // 本地收费
  589. freight: 0, // 运费总成本
  590. setup_cost: 0, // Set Up Cost
  591. sold_unit: 0, // 售卖单价
  592. sold_price: 0, // 售卖总价
  593. profit_margin: 30, // mark up 利润率
  594. profit: 0, // 利润
  595. } as any)
  596. const imageList = ref([] as any[])
  597. const cityList = ref([] as any[])
  598. // 空运选项. 参考: https://www.tapd.cn/59388921/prong/stories/view/1159388921001001048
  599. const airOption = [
  600. { label: 'DHL', value: 'dhl' },
  601. { label: 'TNT', value: 'tnt' },
  602. { label: 'Fedex', value: 'fedex' },
  603. ]
  604. // 海运选项
  605. const seaOption = ref([
  606. { label: 'FCL', value: 'fcl' },
  607. { label: 'LCL', value: 'lcl' },
  608. ])
  609. const dtdData = ref({} as any)
  610. const lclData = ref({} as any)
  611. const dtdVisible = ref(false)
  612. const lclVisible = ref(false)
  613. const show = ref(false)
  614. watch(
  615. () => visible,
  616. () => {
  617. show.value = visible
  618. resetData()
  619. if (show.value) {
  620. getCalcParam()
  621. }
  622. },
  623. )
  624. let getCalcParam = () => {
  625. getCalcParams().then((response: any) => {
  626. const res = response.result
  627. if (response.code !== 1) return
  628. cityList.value = res.city_list
  629. if (cityList.value.length) {
  630. formData.value.cal_city.local_city = cityList.value[0]
  631. }
  632. setting.value = Object.assign({}, res.data)
  633. setting.value.dhl_airline = JSON.parse(setting.value.dhl_airline)
  634. if (!Array.isArray(setting.value.dhl_airline)) {
  635. setting.value.dhl_airline = []
  636. } else {
  637. setting.value.dhl_airline = setting.value.dhl_airline.map((i: any) => {
  638. const result: any = {}
  639. for (const key in i) {
  640. if (Object.prototype.hasOwnProperty.call(i, key)) {
  641. result[key] = Number(i[key])
  642. }
  643. }
  644. return result
  645. })
  646. }
  647. setting.value.tnt_airline = JSON.parse(setting.value.tnt_airline)
  648. if (!Array.isArray(setting.value.tnt_airline)) {
  649. setting.value.tnt_airline = []
  650. } else {
  651. setting.value.tnt_airline = setting.value.tnt_airline.map((i: any) => {
  652. const result: any = {}
  653. for (const key in i) {
  654. if (Object.prototype.hasOwnProperty.call(i, key)) {
  655. result[key] = Number(i[key])
  656. }
  657. }
  658. return result
  659. })
  660. }
  661. setting.value.fedex_airline = JSON.parse(setting.value.fedex_airline)
  662. if (!Array.isArray(setting.value.fedex_airline)) {
  663. setting.value.fedex_airline = []
  664. } else {
  665. setting.value.fedex_airline = setting.value.fedex_airline.map(
  666. (i: any) => {
  667. const result: any = {}
  668. for (const key in i) {
  669. if (Object.prototype.hasOwnProperty.call(i, key)) {
  670. result[key] = Number(i[key])
  671. }
  672. }
  673. return result
  674. },
  675. )
  676. }
  677. setting.value.airplus = JSON.parse(setting.value.airplus)
  678. if (!Array.isArray(setting.value.airplus)) {
  679. setting.value.airplus = []
  680. } else {
  681. setting.value.airplus = setting.value.airplus.map((i: any) => {
  682. const result: any = {}
  683. for (const key in i) {
  684. if (Object.prototype.hasOwnProperty.call(i, key)) {
  685. result[key] = Number(i[key])
  686. }
  687. }
  688. return result
  689. })
  690. }
  691. setting.value.cbm = JSON.parse(setting.value.cbm)
  692. if (!Array.isArray(setting.value.cbm)) {
  693. setting.value.cbm = []
  694. } else {
  695. setting.value.cbm = setting.value.cbm.map((i: any) => {
  696. const result: any = {}
  697. for (const key in i) {
  698. if (Object.prototype.hasOwnProperty.call(i, key)) {
  699. result[key] = Number(i[key])
  700. }
  701. }
  702. return result
  703. })
  704. }
  705. delete setting.value.admin_id
  706. delete setting.value.id
  707. delete setting.value.is_del
  708. delete setting.value.update_time
  709. delete setting.value.create_time
  710. delete setting.value.delete_time
  711. // 把浅层的几个属性全部转换成数字. 方便后续的计算
  712. for (const key in setting.value) {
  713. if (
  714. Object.prototype.hasOwnProperty.call(setting.value, key) &&
  715. typeof setting.value[key] === 'string'
  716. ) {
  717. setting.value[key] = Number(setting.value[key])
  718. }
  719. }
  720. initProductInfo()
  721. initForm([], true)
  722. })
  723. }
  724. let close = (done = {} as any) => {
  725. $emit('update:visible', false)
  726. imageList.value = []
  727. if (typeof done === 'function') done()
  728. }
  729. let resetData = () => {
  730. formData.value = {
  731. cal_city: {
  732. local_city: '',
  733. },
  734. cal_shipment_method: {},
  735. }
  736. exportForm.value = {
  737. pdf_city: '',
  738. cycle_name: '',
  739. exchange: '',
  740. days: '30',
  741. gst_name: '+GST',
  742. notes: '',
  743. other_notes: '',
  744. saleperson: '',
  745. }
  746. }
  747. // 总箱数. 购买数量/每箱数量.
  748. let computedBoxNumber = computed(() => {
  749. if (productInfo.value.number?.length) {
  750. return productInfo.value.number.map((i: any) =>
  751. mathjs.chain(i).divide(productInfo.value.in_package).done(),
  752. )
  753. } else {
  754. return []
  755. }
  756. })
  757. // 单箱体积. 立方厘米. 长*宽*高
  758. let computedBulk = computed(() => {
  759. return mathjs
  760. .chain(productInfo.value.package_size_length || 1)
  761. .multiply(productInfo.value.package_size_width || 1)
  762. .multiply(productInfo.value.package_size_height || 1)
  763. .done()
  764. })
  765. // 是否重货. 每箱毛重 大于等于 (每箱体积 / 5000) 则为重货.
  766. let isHeavyGoods = computed(() => {
  767. if (
  768. productInfo.value.package_weight >
  769. mathjs.chain(computedBulk.value).divide(5000).done()
  770. ) {
  771. return {
  772. flag: true,
  773. label: '重货',
  774. }
  775. } else {
  776. return {
  777. flag: false,
  778. label: '轻货',
  779. }
  780. }
  781. })
  782. // 是否重货. 空+派 配送方式专属的 轻重货计算逻辑, 与标准的计算区别在于一个除6000一个除5000
  783. let isHeavyGoodsPlus = computed(() => {
  784. if (
  785. productInfo.value.package_weight >
  786. mathjs.chain(computedBulk.value).divide(6000).done()
  787. ) {
  788. return {
  789. flag: true,
  790. label: '重货',
  791. }
  792. } else {
  793. return {
  794. flag: false,
  795. label: '轻货',
  796. }
  797. }
  798. })
  799. // 界面上写的是总重量, 实际上应该理解成负重系数, 即轻重货占不同体积, 货运得收不同费用维持利润.
  800. // 重货是货物重量本身, 即每箱毛重*箱数, 轻货则是每箱体积*箱数/5000
  801. let computedTotalWeight = computed(() => {
  802. if (!computedBoxNumber.value.length) return []
  803. if (isHeavyGoods.value.flag) {
  804. // 重货
  805. return computedBoxNumber.value.map((i: number) => {
  806. return mathjs
  807. .chain(
  808. // 重量浮动比. 在运费参数里面设置的.
  809. mathjs
  810. .chain(Number(setting.value.rate_weight || 0))
  811. .divide(100)
  812. .add(1)
  813. .done(),
  814. )
  815. .multiply(productInfo.value.package_weight)
  816. .multiply(i)
  817. .done()
  818. })
  819. } else {
  820. // 轻货
  821. return computedBoxNumber.value.map((i: number) => {
  822. return mathjs.chain(computedBulk.value).multiply(i).divide(5000).done()
  823. })
  824. }
  825. })
  826. // 空+派 方式的(总重量)负重系数.
  827. let computedTotalWeightPlus = computed(() => {
  828. if (!computedBoxNumber.value.length) return []
  829. if (isHeavyGoodsPlus.value.flag) {
  830. // 重货
  831. return computedBoxNumber.value.map((i: number) => {
  832. return mathjs
  833. .chain(
  834. // 重量浮动比. 在运费参数里面设置的.
  835. mathjs
  836. .chain(Number(setting.value.rate_weight || 0))
  837. .divide(100)
  838. .add(1)
  839. .done(),
  840. )
  841. .multiply(productInfo.value.package_weight)
  842. .multiply(i)
  843. .done()
  844. })
  845. } else {
  846. // 轻货
  847. return computedBoxNumber.value.map((i: number) => {
  848. return mathjs.chain(computedBulk.value).multiply(i).divide(6000).done()
  849. })
  850. }
  851. })
  852. // 总体积CBM. 单箱体积*箱数*浮动 / 一百万
  853. let computedTotalBulk = computed(() => {
  854. if (!computedBoxNumber.value.length) return []
  855. return computedBoxNumber.value.map((i: number) => {
  856. return mathjs
  857. .chain(
  858. // 体积浮动比. 在运费参数里面设置的.
  859. mathjs.chain(Number(setting.value.rate_bulk)).divide(100).add(1).done(),
  860. )
  861. .multiply(computedBulk.value)
  862. .multiply(i)
  863. .divide(1000000)
  864. .done()
  865. })
  866. })
  867. // 返回值会有两个子数组. 第一个是重货的, 第二个是轻货的,
  868. // 每个数组里有两项, 分别是计算公式的参数1和2.
  869. let computedCityFreightParams = computed(() => {
  870. if (formData.value.cal_city?.local_city) {
  871. return setting.value.city_list[formData.value.cal_city.local_city]
  872. }
  873. return []
  874. })
  875. // 国内运费
  876. // let computedLocalFreight = computed(() => {
  877. // if (isHeavyGoodsPlus.value.flag) {
  878. // return this.computedTotalWeight((i:number) => {
  879. // return mathjs.chain(setting.value.cn_price_heavy).multiply(i).done()
  880. // })
  881. // }
  882. // return computedTotalBulk.value.map((i:number) => {
  883. // return mathjs.chain(setting.value.cn_price).multiply(i).done()
  884. // })
  885. // })
  886. let initProductInfo = () => {
  887. const temp = cloneDeep(dataForCalc)
  888. if (Array.isArray(temp.product_image)) {
  889. imageList.value = temp.product_image.map((img: string) => {
  890. return $mediaRegExp.test(img)
  891. ? img
  892. : import.meta.env.VITE_APP_OSS_PREFIX + img
  893. })
  894. }
  895. temp.cost_name = []
  896. temp.cost_price = []
  897. if (temp.cost_list && temp.cost_list.length > 2) {
  898. const t = JSON.parse(temp.cost_list)
  899. t.forEach((item: any) => {
  900. temp.cost_name.push(item.cost_name)
  901. temp.cost_price.push(parseFloat(item.cost_price))
  902. })
  903. }
  904. temp.number = []
  905. temp.price = []
  906. temp.days = []
  907. if (temp.price_list && temp.price_list.length > 2) {
  908. const t = JSON.parse(temp.price_list)
  909. // temp.number 按数量从小到大排序
  910. t.sort(
  911. (a: any, b: any) => parseFloat(a.number) - parseFloat(b.number),
  912. ).forEach((item: any) => {
  913. temp.number.push(parseFloat(item.number))
  914. temp.price.push(parseFloat(item.price))
  915. temp.days.push(parseFloat(item.days))
  916. })
  917. }
  918. // 之前保存到数据库的计价信息
  919. if (typeof temp.save_cal === 'string' && temp.save_cal.length > 2) {
  920. temp.save_cal = JSON.parse(temp.save_cal)
  921. } else {
  922. temp.save_cal = {}
  923. }
  924. // 初始化之前选择的城市
  925. if (temp.save_cal.cal_city) {
  926. formData.value.cal_city.local_city = temp.save_cal.cal_city.local_city
  927. }
  928. productInfo.value = temp
  929. }
  930. /**
  931. * 根据 productInfo 生成表单, 包括step2的和部分step3的数据.
  932. */
  933. let initForm = (switchStatus = [] as any[], useOldFormData = true) => {
  934. formList.value = []
  935. step3FormList.value = []
  936. if (productInfo.value.number?.length) {
  937. // 保存的数据库里面的中途配送数据
  938. const oldMidWayData = productInfo.value.save_cal.cal_shipment_method || {}
  939. productInfo.value.number.forEach((item: any, index: number) => {
  940. const t: any = {}
  941. t[`method_0_${item}`] = 'dhl'
  942. t[`method_2_${item}`] = 'lcl'
  943. if (useOldFormData) {
  944. t[`method_0_${item}`] = oldMidWayData[`method_0_${item}`] || 'dhl'
  945. t[`method_2_${item}`] = oldMidWayData[`method_2_${item}`] || 'lcl'
  946. }
  947. t[`method_3_${item}`] = ''
  948. t[`method_4_${item}`] = ''
  949. // 这5个是开关
  950. t[`0_${item}`] = 'off'
  951. t[`1_${item}`] = 'off'
  952. t[`2_${item}`] = 'off'
  953. t[`3_${item}`] = 'off'
  954. t[`4_${item}`] = 'off'
  955. if (useOldFormData) {
  956. // 上一次编辑中, 保存到数据库的数据记录
  957. t[`0_${item}`] = oldMidWayData[`0_${item}`] || 'off'
  958. t[`1_${item}`] = oldMidWayData[`1_${item}`] || 'off'
  959. t[`2_${item}`] = oldMidWayData[`2_${item}`] || 'off'
  960. t[`3_${item}`] = oldMidWayData[`3_${item}`] || 'off'
  961. t[`4_${item}`] = oldMidWayData[`4_${item}`] || 'off'
  962. }
  963. if (switchStatus.length) {
  964. // 记录当前页面之前已经打开的开关状态, 用在切换城市后的重新初始化逻辑中.
  965. t[`0_${item}`] = switchStatus[index][`0_${item}`] || 'off'
  966. t[`1_${item}`] = switchStatus[index][`1_${item}`] || 'off'
  967. t[`2_${item}`] = switchStatus[index][`2_${item}`] || 'off'
  968. t[`3_${item}`] = switchStatus[index][`3_${item}`] || 'off'
  969. t[`4_${item}`] = switchStatus[index][`4_${item}`] || 'off'
  970. }
  971. // 目的城市运费
  972. t.city_price_0 = 0
  973. t.city_price_1 = 0
  974. t.city_price_2 = 0
  975. t.city_price_3 = 0
  976. t.city_price_4 = 0
  977. // 中途运费总额. 即海运和空运的.
  978. t.midway_price_0 = 0
  979. t.midway_price_1 = 0
  980. t.midway_price_2 = 0
  981. // 这两个是自行输入然后直接显示在step2的中途运费位置, 其他三个是计算出来的,
  982. // 同时也作为step3的运费总成本(AUD)
  983. t.freight_cost_3 = 0
  984. t.freight_cost_4 = 0
  985. // 国内本地运费
  986. t.cn_price_0 = 0
  987. t.cn_price_1 = 0
  988. t.cn_price_2 = 0
  989. // 成本清单
  990. t.product_cost = calcProductCost(index) // 产品成本(AUD)
  991. t.extend_cost = calcExtendCost() // 制版及其它成本(AUD)
  992. t.total_cost = 0 // 总成本(AUD)
  993. // 给html模版分辨是哪个表单的数据
  994. t.number = item
  995. // 计价步骤上貌似没有用到的数据, 但是保存到数据库, 并且该对话框界面回显.
  996. t.fclData = {}
  997. t.lclData = {}
  998. if (useOldFormData) {
  999. const oldData = productInfo.value.save_cal || {}
  1000. if (oldData[`cal_fcl_${item}`]) {
  1001. t.fclData = oldData[`cal_fcl_${item}`]
  1002. t.freight_cost_3 = oldData[`cal_fcl_${item}`].total_fcl
  1003. }
  1004. if (oldData[`cal_lcl_${item}`]) {
  1005. t.lclData = oldData[`cal_lcl_${item}`]
  1006. t.freight_cost_4 = oldData[`cal_lcl_${item}`].total_lcl
  1007. }
  1008. }
  1009. formList.value.push(t)
  1010. })
  1011. const indentUser = Cookies.get('indent-user')
  1012. let r = creatorOptions.filter((i) => i.label === indentUser)
  1013. exportForm.value = {
  1014. pdf_city: productInfo.value.save_cal.pdf_city || cityList.value[0],
  1015. exchange: productInfo.value.save_cal.exchange || '',
  1016. days: productInfo.value.save_cal.days || 30,
  1017. gst_name: productInfo.value.save_cal.gst_name || '+GST',
  1018. notes: productInfo.value.save_cal.notes || '',
  1019. other_notes: productInfo.value.save_cal.other_notes || '',
  1020. saleperson:
  1021. productInfo.value.save_cal.saleperson || (r.length ? r[0].value : ''),
  1022. }
  1023. }
  1024. setFreight()
  1025. if (useOldFormData) {
  1026. // 仅页面初始化时会执行到这里
  1027. generateStep3Form({ withOldData: true })
  1028. }
  1029. }
  1030. const onCityChange = (str: string) => {
  1031. // 没保存计价之前, 切换城市会改变pdf_city. 保存之后, 再怎么切换也用保存的数据做默认数据, 除非手动更改pdf_city
  1032. exportForm.value.pdf_city =
  1033. productInfo.value.save_cal.pdf_city || str || cityList.value[0]
  1034. }
  1035. let reGenerateFormAfterCityChange = () => {
  1036. const temp: any[] = formList.value.map((i, index) => {
  1037. const result: any = {}
  1038. result[`0_${productInfo.value.number[index]}`] =
  1039. i[`0_${productInfo.value.number[index]}`]
  1040. result[`1_${productInfo.value.number[index]}`] =
  1041. i[`1_${productInfo.value.number[index]}`]
  1042. result[`2_${productInfo.value.number[index]}`] =
  1043. i[`2_${productInfo.value.number[index]}`]
  1044. result[`3_${productInfo.value.number[index]}`] =
  1045. i[`3_${productInfo.value.number[index]}`]
  1046. result[`4_${productInfo.value.number[index]}`] =
  1047. i[`4_${productInfo.value.number[index]}`]
  1048. result[`method_0_${productInfo.value.number[index]}`] =
  1049. i[`method_0_${productInfo.value.number[index]}`]
  1050. result[`method_2_${productInfo.value.number[index]}`] =
  1051. i[`method_2_${productInfo.value.number[index]}`]
  1052. return result
  1053. })
  1054. initForm(temp)
  1055. // 切换城市后, 理论上所有数据都应该重置
  1056. generateStep3Form({ withOldData: false })
  1057. }
  1058. /**
  1059. * 切换运送方式之后, 重新计算中途运费和生成step3的表单内容.
  1060. */
  1061. let reGenerateFormAfterMidwayTypeChange = (p: any) => {
  1062. setFreight()
  1063. generateStep3Form(p || {})
  1064. }
  1065. let generateStep3Form = (p = {}) => {
  1066. const config = Object.assign({}, { withOldData: true, x: -1, y: -1 }, p || {})
  1067. const withOldData = config.withOldData
  1068. const labelList = ['快递', '空+派', '海运', 'DTD', 'LCL散货']
  1069. const result: any[] = []
  1070. const oldData = productInfo.value.save_cal
  1071. formList.value.forEach((i: any, formRow) => {
  1072. // console.log(i, '表单行数据')
  1073. for (let n = 0; n < 5; n++) {
  1074. if (i[`${n}_${i.number}`] === 'on') {
  1075. // console.log(config, 'config')
  1076. let temp = Object.assign({}, step3FormDemo.value, {
  1077. tabLabel: `${i.number} ${labelList[n]}`,
  1078. number: i.number,
  1079. typeNumber: n,
  1080. cn_freight_cost: 0,
  1081. product_cost: i.product_cost,
  1082. extend_cost: i.extend_cost,
  1083. total_cost: i.total_cost,
  1084. })
  1085. if (n <= 2) {
  1086. console.log(i, 'i')
  1087. temp.cn_freight_cost = savePrecision(i[`cn_price_${n}`]) // 这个是人民币
  1088. temp.local_freight_cost = savePrecision(i[`city_price_${n}`]).toFixed(
  1089. 2,
  1090. )
  1091. temp.add_freight_cost = savePrecision(i[`city_price_${n}`]).toFixed(2)
  1092. // 记录中途运费, 用在step3表单项变更后的重复计算
  1093. temp.midway_price = i[`midway_price_${n}`]
  1094. temp.freight_cost = mathjs
  1095. .chain(i[`midway_price_${n}`])
  1096. .add(i[`city_price_${n}`])
  1097. .add(
  1098. mathjs
  1099. .chain(i[`cn_price_${n}`])
  1100. .divide(setting.value.rate_rmb_aud)
  1101. .done(),
  1102. )
  1103. .done()
  1104. .toFixed(2)
  1105. // 用demo默认值是重新计算的数据. 如果是初始化时需要用保存到数据库的数据覆盖掉这个.
  1106. temp.total_cost = mathjs
  1107. .chain(i.product_cost)
  1108. .add(i.extend_cost)
  1109. .add(temp.freight_cost)
  1110. .add(
  1111. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1112. ? oldData[`cal_quote_${n}_${i.number}`].tax_fee ||
  1113. step3FormDemo.value.tax_fee
  1114. : step3FormDemo.value.tax_fee,
  1115. )
  1116. .add(
  1117. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1118. ? oldData[`cal_quote_${n}_${i.number}`].gatt_tax_fee ||
  1119. step3FormDemo.value.gatt_tax_fee
  1120. : step3FormDemo.value.gatt_tax_fee,
  1121. )
  1122. .add(
  1123. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1124. ? oldData[`cal_quote_${n}_${i.number}`].review_cost ||
  1125. step3FormDemo.value.review_cost
  1126. : step3FormDemo.value.review_cost,
  1127. )
  1128. .done()
  1129. .toFixed(2)
  1130. } else if (n === 3) {
  1131. temp.local_freight_cost = 0
  1132. temp.add_freight_cost = 0
  1133. // 记录中途运费, 用在step3表单项变更后的重复计算
  1134. temp.midway_price = mathjs
  1135. .chain(i[`freight_cost_${n}`])
  1136. .add(i[`city_price_${n}`])
  1137. .done()
  1138. .toFixed(2)
  1139. temp.freight_cost = mathjs
  1140. .chain(temp.midway_price)
  1141. .add(
  1142. mathjs
  1143. .chain(temp.cn_freight_cost)
  1144. .divide(setting.value.rate_rmb_aud)
  1145. .done(),
  1146. )
  1147. .done()
  1148. .toFixed(2)
  1149. temp.total_cost = mathjs
  1150. .chain(i.product_cost)
  1151. .add(i.extend_cost)
  1152. .add(temp.freight_cost)
  1153. // .add(
  1154. // mathjs
  1155. // .chain(temp.cn_freight_cost)
  1156. // .divide(setting.value.rate_rmb_aud)
  1157. // .done(),
  1158. // )
  1159. .add(
  1160. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1161. ? oldData[`cal_quote_${n}_${i.number}`].tax_fee ||
  1162. step3FormDemo.value.tax_fee
  1163. : step3FormDemo.value.tax_fee,
  1164. )
  1165. .add(
  1166. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1167. ? oldData[`cal_quote_${n}_${i.number}`].gatt_tax_fee ||
  1168. step3FormDemo.value.gatt_tax_fee
  1169. : step3FormDemo.value.gatt_tax_fee,
  1170. )
  1171. .add(
  1172. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1173. ? oldData[`cal_quote_${n}_${i.number}`].review_cost ||
  1174. step3FormDemo.value.review_cost
  1175. : step3FormDemo.value.review_cost,
  1176. )
  1177. .done()
  1178. .toFixed(2)
  1179. temp[`cn_price_${n}`] = 0 // 国内运费. 后两种配送方式默认是0
  1180. } else if (n === 4) {
  1181. temp.local_freight_cost = 0
  1182. temp.add_freight_cost = 0
  1183. temp.local_freight_cost = 0
  1184. temp.add_freight_cost = 0
  1185. // 记录中途运费, 用在step3表单项变更后的重复计算
  1186. temp.midway_price = mathjs
  1187. .chain(i[`freight_cost_${n}`])
  1188. .add(i[`city_price_${n}`])
  1189. .done()
  1190. .toFixed(2)
  1191. temp.freight_cost = mathjs
  1192. .chain(temp.midway_price)
  1193. .add(
  1194. mathjs
  1195. .chain(temp.cn_freight_cost)
  1196. .divide(setting.value.rate_rmb_aud)
  1197. .done(),
  1198. )
  1199. .done()
  1200. .toFixed(2)
  1201. // total_lcl 运费总成本
  1202. // price 国内总运费
  1203. temp.total_cost = mathjs
  1204. .chain(i.product_cost)
  1205. .add(i.extend_cost)
  1206. .add(temp.freight_cost)
  1207. // .add(
  1208. // mathjs
  1209. // .chain(temp.cn_freight_cost)
  1210. // .divide(setting.value.rate_rmb_aud)
  1211. // .done(),
  1212. // )
  1213. .add(
  1214. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1215. ? oldData[`cal_quote_${n}_${i.number}`].tax_fee ||
  1216. step3FormDemo.value.tax_fee
  1217. : step3FormDemo.value.tax_fee,
  1218. )
  1219. .add(
  1220. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1221. ? oldData[`cal_quote_${n}_${i.number}`].gatt_tax_fee ||
  1222. step3FormDemo.value.gatt_tax_fee
  1223. : step3FormDemo.value.gatt_tax_fee,
  1224. )
  1225. .add(
  1226. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1227. ? oldData[`cal_quote_${n}_${i.number}`].review_cost ||
  1228. step3FormDemo.value.review_cost
  1229. : step3FormDemo.value.review_cost,
  1230. )
  1231. .done()
  1232. .toFixed(2)
  1233. temp[`cn_price_${n}`] = 0 // 国内运费. 后两种配送方式默认是0
  1234. }
  1235. temp.profit = savePrecision(
  1236. // 利润率是整数, 除100算出百分数.
  1237. mathjs
  1238. .chain(
  1239. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1240. ? oldData[`cal_quote_${n}_${i.number}`].profit_margin ||
  1241. step3FormDemo.value.profit_margin
  1242. : step3FormDemo.value.profit_margin,
  1243. )
  1244. .divide(100)
  1245. .multiply(temp.total_cost)
  1246. .done(),
  1247. ).toFixed(2)
  1248. temp.sold_price = savePrecision(
  1249. mathjs
  1250. .chain(temp.total_cost)
  1251. .multiply(
  1252. mathjs
  1253. .chain(
  1254. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1255. ? oldData[`cal_quote_${n}_${i.number}`].profit_margin ||
  1256. step3FormDemo.value.profit_margin
  1257. : step3FormDemo.value.profit_margin,
  1258. )
  1259. .add(100)
  1260. .divide(100)
  1261. .done(),
  1262. )
  1263. .done(),
  1264. ).toFixed(2)
  1265. temp.sold_unit = mathjs
  1266. .chain(
  1267. Math.ceil(
  1268. Number(
  1269. mathjs
  1270. .chain(temp.sold_price)
  1271. .subtract(temp.add_freight_cost)
  1272. .subtract(
  1273. withOldData && oldData[`cal_quote_${n}_${i.number}`]
  1274. ? oldData[`cal_quote_${n}_${i.number}`].setup_cost
  1275. : step3FormDemo.value.setup_cost,
  1276. )
  1277. .divide(i.number)
  1278. .multiply(100)
  1279. .done(),
  1280. ),
  1281. ),
  1282. )
  1283. .divide(100)
  1284. .done()
  1285. .toFixed(2)
  1286. // exportForm.value[`zdy_date_${n}_${i.number}`] = ''
  1287. // exportForm.value[`cycle_name_${n}_${i.number}`] = 'weeks'
  1288. // 行和列只要有一项不等, 就不是点开关的那个, 就应该用已保存数据覆盖
  1289. // if (withOldData && (config.y !== n || config.x !== formRow)) {
  1290. // 出了切换城市, 全部用已保存的数据覆盖
  1291. if (withOldData) {
  1292. if (oldData[`cal_quote_${n}_${i.number}`]) {
  1293. const cloneData = cloneDeep(oldData[`cal_quote_${n}_${i.number}`])
  1294. cloneData.freight_cost = cloneData.freight
  1295. delete cloneData.freight
  1296. temp = Object.assign(temp, cloneData)
  1297. calcTotalCost(temp) // 如果运费总成本被覆盖, 那总成本会产生误差, 最好是重算一遍.
  1298. }
  1299. exportForm.value[`zdy_date_${n}_${i.number}`] = oldData[
  1300. `zdy_date_${n}_${i.number}`
  1301. ]
  1302. ? oldData[`zdy_date_${n}_${i.number}`]
  1303. : ''
  1304. exportForm.value[`cycle_name_${n}_${i.number}`] = oldData[
  1305. `cycle_name_${n}_${i.number}`
  1306. ]
  1307. ? oldData[`cycle_name_${n}_${i.number}`]
  1308. : 'weeks'
  1309. console.log('覆盖: 行:', formRow + 1, '列:', n)
  1310. } else {
  1311. console.log('重算, 没有覆盖: 行:', config.x + 1, '列:', config.y)
  1312. }
  1313. // console.log(temp, 'temp')
  1314. result.push(temp)
  1315. }
  1316. }
  1317. })
  1318. step3FormList.value = result
  1319. }
  1320. // 设置 中途运费 及 国外当地运费
  1321. let setFreight = () => {
  1322. productInfo.value.number.forEach((item: any, index: number) => {
  1323. // 早起的需求限制3个, 现在暂定放开了. 限制的话, 超过3个的货物数量的运费直接就跳过不计算了.
  1324. // if (index > 2) {
  1325. // return
  1326. // }
  1327. const cityPrice = calcCityPrice(
  1328. computedTotalWeight.value[index],
  1329. computedTotalBulk.value[index],
  1330. )
  1331. // 国外本地运费, dtd 和 lcl散货默认是0, 所以这里只给前三个填充了值.
  1332. formList.value[index].city_price_0 = cityPrice
  1333. formList.value[index].city_price_1 = cityPrice
  1334. formList.value[index].city_price_2 = cityPrice
  1335. // 航空:总重量*空运费单价(AUD) * (1+燃油附加)
  1336. formList.value[index].midway_price_0 = mathjs
  1337. .chain(
  1338. getCurrentPrice(
  1339. formList.value[index][`method_0_${item}`],
  1340. computedTotalWeight.value[index],
  1341. ),
  1342. )
  1343. .multiply(computedTotalWeight.value[index])
  1344. .multiply(mathjs.chain(setting.value.rate_fuel).divide(100).add(1).done())
  1345. .done()
  1346. // 空+派 与航空的计算方式基本一致。
  1347. // 差异点为,重轻货判断及负重系数计算时,除以6000, 燃油附加是另外的字段.
  1348. formList.value[index].midway_price_1 = mathjs
  1349. .chain(getCurrentPricePlus(computedTotalWeightPlus.value[index]))
  1350. .multiply(computedTotalWeightPlus.value[index])
  1351. .multiply(
  1352. mathjs.chain(setting.value.rate_fuelplus).divide(100).add(1).done(),
  1353. )
  1354. .done()
  1355. // 海运 CBM * 基础参数里面的海运费. 旧后台这一项的计算有误差, cbm用了约进两位数之后的值来计算.
  1356. formList.value[index].midway_price_2 = mathjs
  1357. .chain(computedTotalBulk.value[index])
  1358. .multiply(setting.value.sea_fee)
  1359. .done()
  1360. const cn_price = calcLocalPrice(index)
  1361. // 国内运费
  1362. formList.value[index].cn_price_0 = cn_price
  1363. formList.value[index].cn_price_1 = cn_price
  1364. formList.value[index].cn_price_2 = cn_price
  1365. })
  1366. }
  1367. // 目标城市的快递费用计算. 这个判断轻重货时不用区分 空+派 的 /6000
  1368. let calcCityPrice = (heavy: number, bulk: number) => {
  1369. const p = computedCityFreightParams.value
  1370. if (!p.length) return 0
  1371. if (isHeavyGoods.value.flag) {
  1372. return p[0][0] + (p[0][1] / 50) * heavy
  1373. } else {
  1374. return p[1][0] + p[1][1] * bulk
  1375. }
  1376. }
  1377. // 目标城市的快递费用计算. 空+派方式的, 这种方式轻重货判断计算公式不一样
  1378. // let calcCityPricePlus = (heavy: number, bulk: number) => {
  1379. // const p = computedCityFreightParams.value
  1380. // if (!p.length) return 0
  1381. // if (isHeavyGoodsPlus.value.flag) {
  1382. // return p[0][0] + (p[0][1] / 50) * heavy
  1383. // } else {
  1384. // return p[1][0] + p[1][1] * bulk
  1385. // }
  1386. // }
  1387. // 国内运费. 轻重货计算公式不同
  1388. let calcLocalPrice = (index: number) => {
  1389. if (isHeavyGoods.value.flag) {
  1390. return mathjs
  1391. .chain(setting.value.cn_price_heavy)
  1392. .multiply(computedTotalWeight.value[index])
  1393. .done()
  1394. } else {
  1395. return mathjs
  1396. .chain(setting.value.cn_price)
  1397. .multiply(computedTotalBulk.value[index])
  1398. .done()
  1399. }
  1400. }
  1401. // 打样费用 和 额外费用(报价信息里面的出厂价-额外费用), 再除以汇率
  1402. let calcExtendCost = () => {
  1403. const reduceCost = productInfo.value.cost_price.reduce(
  1404. (total: number, i: number) => {
  1405. total = total + i
  1406. return total
  1407. },
  1408. 0,
  1409. )
  1410. const extendCost = mathjs
  1411. .chain(reduceCost)
  1412. .add(Number(productInfo.value.demo_cost) || 0)
  1413. .divide(setting.value.rate_rmb_aud)
  1414. .done()
  1415. return extendCost
  1416. }
  1417. // 产品成本 = 单价 * 数量 / 汇率
  1418. let calcProductCost = (index: number) => {
  1419. return mathjs
  1420. .chain(productInfo.value.number[index])
  1421. .multiply(productInfo.value.price[index])
  1422. .divide(setting.value.rate_rmb_aud)
  1423. .done()
  1424. }
  1425. // 获取 当前重量的 运费单价
  1426. let getCurrentPrice = (key: string | number, heavy: number) => {
  1427. const target = setting.value[`${key}_airline`]
  1428. let result = 0
  1429. if (Array.isArray(target) && target.length) {
  1430. result = target.findIndex((i: any) => i.min <= heavy && i.max > heavy)
  1431. }
  1432. return target[result].price
  1433. }
  1434. // 空+ 派
  1435. let getCurrentPricePlus = (heavy: number) => {
  1436. const target = setting.value.airplus
  1437. let result = 0
  1438. if (Array.isArray(target) && target.length) {
  1439. result = target.findIndex((i: any) => i.min <= heavy && i.max > heavy)
  1440. }
  1441. return target[result].price
  1442. }
  1443. // 开关切换前的点击捕获, 检查前提数据是否已输入, 没有的话不允许打开开关. 旧后台的交互.
  1444. let captureSwitchChange = (e: any, obj: any, n: number) => {
  1445. if (n === 3) {
  1446. if (typeof obj.freight_cost_3 !== 'number' || obj.freight_cost_3 <= 0) {
  1447. ElMessage.warning('请先点击编辑, 填写相关数据, 再打开开关')
  1448. e.preventDefault()
  1449. e.stopPropagation()
  1450. }
  1451. } else if (n === 4) {
  1452. if (typeof obj.freight_cost_4 !== 'number' || obj.freight_cost_4 <= 0) {
  1453. ElMessage.warning('请先点击编辑, 填写相关数据, 再打开开关')
  1454. e.preventDefault()
  1455. e.stopPropagation()
  1456. }
  1457. }
  1458. }
  1459. let changeCOO = (form: any, value: any) => {
  1460. // 因为设置了active value, value变量不再是布尔值
  1461. if (value === 'on') {
  1462. form.tax = 0
  1463. onForm3ItemChange(form, 'tax')
  1464. } else {
  1465. form.tax = 5
  1466. onForm3ItemChange(form, 'tax')
  1467. }
  1468. }
  1469. let calcTaxFee = (form: any) => {
  1470. form.tax_fee = savePrecision(
  1471. mathjs.chain(form.product_cost).multiply(form.tax).divide(100).done(),
  1472. ).toFixed(2)
  1473. }
  1474. // 利润 = 售卖总价 - 总成本
  1475. let calcProfit = (form: any) => {
  1476. form.profit = savePrecision(
  1477. mathjs
  1478. .chain(form.sold_price)
  1479. // .subtract(form.setup_cost)
  1480. // .subtract(form.add_freight_cost)
  1481. .subtract(form.total_cost)
  1482. .done(),
  1483. ).toFixed(2)
  1484. }
  1485. let calcProfitMargin = (form: any) => {
  1486. form.profit_margin = savePrecision(
  1487. mathjs.chain(form.profit).divide(form.total_cost).multiply(100).done(),
  1488. ).toFixed(2)
  1489. }
  1490. let calcTotalCost = (form: any) => {
  1491. form.total_cost = mathjs
  1492. .chain(form.product_cost)
  1493. .add(form.extend_cost)
  1494. .add(form.freight_cost)
  1495. // .add(
  1496. // mathjs
  1497. // .chain(form.cn_freight_cost)
  1498. // .divide(setting.value.rate_rmb_aud)
  1499. // .done(),
  1500. // )
  1501. .add(form.tax_fee)
  1502. .add(form.gatt_tax_fee)
  1503. .add(form.review_cost)
  1504. .done()
  1505. .toFixed(2)
  1506. }
  1507. /**
  1508. * 用利润率计算售价总价. 总成本 * (利润率 + 100) / 100
  1509. **/
  1510. let calcSoldPriceByProfitMargin = (form: any) => {
  1511. form.sold_price = savePrecision(
  1512. mathjs
  1513. .chain(form.total_cost)
  1514. .multiply(mathjs.chain(form.profit_margin).add(100).divide(100).done())
  1515. // .add(form.setup_cost)
  1516. // .add(form.add_freight_cost)
  1517. .done(),
  1518. ).toFixed(2)
  1519. }
  1520. /**
  1521. * 用单价计算售价总价. 单价*数量 + setup cost + add freight cost
  1522. **/
  1523. let calcSoldPriceBySoldUnit = (form: any) => {
  1524. form.sold_price = savePrecision(
  1525. mathjs
  1526. .chain(form.sold_unit)
  1527. .multiply(form.number)
  1528. .add(form.setup_cost)
  1529. .add(form.add_freight_cost)
  1530. .done(),
  1531. ).toFixed(2)
  1532. }
  1533. let onForm3ItemChange = (form: any, key: string) => {
  1534. let dotFlag = false
  1535. if (typeof form[key] === 'string' && /\.$/.test(form[key])) {
  1536. // 处理小数点
  1537. form[key] = form[key].replace(/\.$/, '')
  1538. dotFlag = true
  1539. }
  1540. // 各输入框之间的输入值变动会有联动.
  1541. // 注意, 各 case 里面的调用顺序有影响, 改动之前务必保证你理解当前在做什么.
  1542. switch (key) {
  1543. case 'tax':
  1544. // 影响 税费、总成本、利润率、利润值
  1545. calcTaxFee(form)
  1546. calcTotalCost(form)
  1547. calcProfit(form)
  1548. calcProfitMargin(form)
  1549. break
  1550. case 'review_cost':
  1551. // 影响 总成本、利润率、利润值
  1552. calcTotalCost(form)
  1553. calcProfit(form)
  1554. calcProfitMargin(form)
  1555. break
  1556. case 'cn_freight_cost':
  1557. // 影响 运费总成本、总成本、利润率、利润值
  1558. form.freight_cost = mathjs
  1559. .chain(form.local_freight_cost)
  1560. .add(form.midway_price)
  1561. .add(
  1562. mathjs
  1563. .chain(form.cn_freight_cost)
  1564. .divide(setting.value.rate_rmb_aud)
  1565. .done(),
  1566. )
  1567. .done()
  1568. .toFixed(2)
  1569. calcTotalCost(form)
  1570. calcProfit(form)
  1571. calcProfitMargin(form)
  1572. break
  1573. case 'local_freight_cost':
  1574. // 影响 运费总成本、总成本、售卖总价、利润率. 利润值(不影响)
  1575. form.add_freight_cost = form.local_freight_cost
  1576. form.freight_cost = mathjs
  1577. .chain(form.local_freight_cost)
  1578. .add(form.midway_price)
  1579. .add(
  1580. mathjs
  1581. .chain(form.cn_freight_cost)
  1582. .divide(setting.value.rate_rmb_aud)
  1583. .done(),
  1584. )
  1585. .done()
  1586. .toFixed(2)
  1587. calcTotalCost(form)
  1588. calcProfitMargin(form)
  1589. calcSoldPriceByProfitMargin(form)
  1590. break
  1591. case 'add_freight_cost':
  1592. // 影响 售卖总价、利润率、利润值
  1593. // fallthrough
  1594. case 'setup_cost':
  1595. // 影响 售卖总价、利润值、利润率
  1596. // fallthrough
  1597. case 'sold_unit':
  1598. // 直接乘算出售卖总价, 更新利润率、利润值
  1599. calcSoldPriceBySoldUnit(form)
  1600. calcProfit(form)
  1601. calcProfitMargin(form)
  1602. break
  1603. case 'profit_margin':
  1604. // 影响 利润值、售卖总价、售卖单价
  1605. calcSoldPriceByProfitMargin(form)
  1606. calcProfit(form)
  1607. form.sold_unit = mathjs
  1608. .chain(
  1609. Math.ceil(
  1610. Number(
  1611. mathjs
  1612. .chain(form.sold_price)
  1613. .subtract(form.add_freight_cost)
  1614. .subtract(form.setup_cost)
  1615. .divide(form.number)
  1616. .multiply(100)
  1617. .done(),
  1618. ),
  1619. ),
  1620. )
  1621. .divide(100)
  1622. .done()
  1623. .toFixed(2)
  1624. break
  1625. case 'gatt_tax_fee':
  1626. calcTotalCost(form)
  1627. calcProfit(form)
  1628. calcProfitMargin(form)
  1629. break
  1630. default:
  1631. // 默认不做任何处理
  1632. break
  1633. }
  1634. if (dotFlag) {
  1635. form[key] = form[key] + '.'
  1636. }
  1637. }
  1638. let openDTDDialog = (columnNum: number, rowNum: number) => {
  1639. dtdData.value = {
  1640. rowNum,
  1641. columnNum,
  1642. freight_cost: formList.value[rowNum][`freight_cost_${columnNum}`] || '',
  1643. method_fcl: formList.value[rowNum].fclData.method_fcl || '',
  1644. }
  1645. dtdVisible.value = true
  1646. }
  1647. let dtdChange = (data: any) => {
  1648. formList.value[dtdData.value.rowNum][
  1649. `freight_cost_${dtdData.value.columnNum}`
  1650. ] = Number(data.freight_cost) || 0
  1651. formList.value[dtdData.value.rowNum].fclData.method_fcl =
  1652. data.method_fcl || ''
  1653. formList.value[dtdData.value.rowNum].fclData.total_fcl =
  1654. Number(data.freight_cost) || 0
  1655. generateStep3Form({ x: dtdData.value.rowNum, y: dtdData.value.columnNum })
  1656. }
  1657. let openLCLDialog = (columnNum: number, rowNum: number) => {
  1658. lclData.value = {
  1659. rowNum,
  1660. columnNum,
  1661. heavy: computedTotalWeight.value[rowNum],
  1662. freight_cost: formList.value[rowNum][`freight_cost_${columnNum}`] || '',
  1663. margin_lcl: formList.value[rowNum].lclData.margin_lcl || '',
  1664. unit_lcl: formList.value[rowNum].lclData.unit_lcl || '',
  1665. price: formList.value[rowNum].lclData.price || '',
  1666. }
  1667. lclVisible.value = true
  1668. }
  1669. let lclChange = (data: any) => {
  1670. // 这个是 运输总成本, 会添加到 step3form 里面用于计算
  1671. formList.value[lclData.value.rowNum][
  1672. `freight_cost_${lclData.value.columnNum}`
  1673. ] = Number(data.freight_cost) || 0
  1674. // 这四个保存到数据库的, total_lcl其实就是 运输总成本
  1675. formList.value[lclData.value.rowNum].lclData.unit_lcl =
  1676. Number(data.unit_lcl) || 0
  1677. formList.value[lclData.value.rowNum].lclData.price = Number(data.price) || 0
  1678. formList.value[lclData.value.rowNum].lclData.margin_lcl =
  1679. Number(data.margin_lcl) || 0
  1680. formList.value[lclData.value.rowNum].lclData.total_lcl =
  1681. Number(data.freight_cost) || 0
  1682. generateStep3Form({ x: lclData.value.rowNum, y: lclData.value.columnNum })
  1683. }
  1684. let isExport = ref(0)
  1685. let checkForm = (type = 1) => {
  1686. // 利用引用传值变更 formData 的内容
  1687. const method = formData.value.cal_shipment_method
  1688. formList.value.forEach((item) => {
  1689. for (let i = 0; i < 5; i++) {
  1690. if (item[`${i}_${item.number}`] === 'on') {
  1691. method[`${i}_${item.number}`] = 'on'
  1692. }
  1693. }
  1694. method[`method_0_${item.number}`] = item[`method_0_${item.number}`]
  1695. method[`method_2_${item.number}`] = item[`method_2_${item.number}`]
  1696. if (item.lclData && item.lclData.total_lcl) {
  1697. formData.value[`cal_lcl_${item.number}`] = cloneDeep(item.lclData)
  1698. }
  1699. if (item.fclData && item.fclData.total_fcl) {
  1700. formData.value[`cal_fcl_${item.number}`] = cloneDeep(item.fclData)
  1701. }
  1702. })
  1703. step3FormList.value.forEach((item) => {
  1704. formData.value[`cal_quote_${item.typeNumber}_${item.number}`] = {
  1705. coo_certificate: item.coo_certificate, // coo 开关
  1706. tax: item.tax, // 税点 coo打开则是0, 关闭默认是5
  1707. tax_fee: item.tax_fee, // 税费 coo打开则是0, 需要根据税点计算
  1708. gatt_tax_fee: item.gatt_tax_fee, // 入口报关费用
  1709. review_cost: item.review_cost, // 验货费
  1710. cn_freight_cost: item.cn_freight_cost, // 国内运费总价
  1711. local_freight_cost: item.local_freight_cost, // 国外本地运费
  1712. add_freight_cost: item.add_freight_cost, // 本地收费
  1713. freight: savePrecision(item.freight_cost), // 运费总成本
  1714. setup_cost: item.setup_cost, // Set Up Cost
  1715. sold_unit: item.sold_unit, // 售卖单价
  1716. sold_price: item.sold_price, // 售卖总价
  1717. profit_margin: item.profit_margin, // mark up 利润率
  1718. profit: item.profit, // 利润
  1719. }
  1720. })
  1721. const p = Object.assign(
  1722. {
  1723. id: dataForCalc.id || '',
  1724. },
  1725. cloneDeep(formData.value),
  1726. )
  1727. if (isExport.value === 1) p.is_export = 1 // 后端用来区分是否是点了导出
  1728. if (type === 1) {
  1729. saveCalc(Object.assign(p, exportForm.value))
  1730. } else if (type === 2) {
  1731. componentExportFormVisible.value = true
  1732. }
  1733. }
  1734. let saveCalc = (p: any) => {
  1735. loading.value = true
  1736. saveCalcData(p)
  1737. .then((res: any) => {
  1738. if (res.code !== 1) {
  1739. ElNotification({
  1740. type: 'error',
  1741. title: '保存出错了',
  1742. duration: 3000,
  1743. })
  1744. return
  1745. }
  1746. ElNotification({
  1747. type: 'success',
  1748. title: '保存成功',
  1749. duration: 3000,
  1750. })
  1751. $emit('save-price-calc')
  1752. })
  1753. .finally(() => {
  1754. setTimeout(() => {
  1755. loading.value = false
  1756. }, 300)
  1757. })
  1758. }
  1759. let onExportFormSave = (data: any) => {
  1760. exportForm.value = cloneDeep(data)
  1761. checkForm(1)
  1762. // 生成pdf涉及DOM操作, 故变更数据后需要等界面更新,
  1763. // 此处需要nextTick保证生成时数据已经更新到了界面上.
  1764. nextTick(() => {
  1765. generate()
  1766. })
  1767. }
  1768. const compExportQuotaRef = ref()
  1769. let generate = () => {
  1770. if (
  1771. compExportQuotaRef.value.generatePDF &&
  1772. typeof compExportQuotaRef.value.generatePDF === 'function'
  1773. ) {
  1774. compExportQuotaRef.value.generatePDF()
  1775. }
  1776. }
  1777. </script>
  1778. <style lang="scss">
  1779. .compnent-price-calc {
  1780. .custom-calc-price-dialog {
  1781. margin-top: 0 !important;
  1782. margin-bottom: 0 !important;
  1783. height: 100vh;
  1784. .el-dialog__body {
  1785. max-height: calc(100vh - 56px);
  1786. overflow-y: scroll;
  1787. overflow-x: auto;
  1788. padding: 4px 0 0;
  1789. }
  1790. }
  1791. .step-3 {
  1792. input[type='number'] {
  1793. -moz-appearance: textfield;
  1794. appearance: textfield;
  1795. &:hover {
  1796. -moz-appearance: textfield;
  1797. appearance: textfield;
  1798. &::-webkit-inner-spin-button,
  1799. &::-webkit-outer-spin-button {
  1800. -webkit-appearance: none;
  1801. margin: 0;
  1802. }
  1803. }
  1804. &::-webkit-inner-spin-button,
  1805. &::-webkit-outer-spin-button {
  1806. -webkit-appearance: none;
  1807. margin: 0;
  1808. }
  1809. }
  1810. }
  1811. }
  1812. </style>
  1813. <style lang="scss" scoped>
  1814. @use './styles/index.scss';
  1815. </style>