123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722 |
- <template>
- <div class="compnent-price-calc">
- <exportQuota
- ref="compExportQuotaRef"
- :product-info="productInfo"
- :export-form="exportForm"
- :step3-form-list="step3FormList"
- :step2-form-list="formList"
- :creator-options="creatorOptions"
- :city2="formData.cal_city.local_city"
- :city="exportForm.pdf_city"
- ></exportQuota>
- <!-- :city="formData.cal_city.local_city" -->
- <el-dialog
- v-model="show"
- class="custom-calc-price-dialog"
- title="查看计价结果"
- :close-on-click-modal="false"
- :close-on-press-escape="false"
- :before-close="close"
- width="1800px"
- >
- <div
- v-loading="loading"
- class="flex items-start flex-wrap"
- >
- <step1
- :computed-box-number="computedBoxNumber"
- :computed-total-bulk="computedTotalBulk"
- :computed-total-weight="computedTotalWeight"
- :computed-total-weight-plus="computedTotalWeightPlus"
- :image-list="imageList"
- :product-info="productInfo"
- ></step1>
- <div class="step step-2">
- <common-title
- :title="$t(prefix + 'label_transport_info')"
- ></common-title>
- <p style="color: #ef4135; margin-bottom: 12px">
- 快速运输天数:2-3天 / 空+派运输天数:8天 /
- 海运运输天数:LCL30天、FCL25天
- </p>
- <div class="flex items-center">
- <el-select
- v-model="formData.cal_city.local_city"
- style="width: 120px; margin-right: 12px"
- size="small"
- @change="onCityChange"
- >
- <el-option
- v-for="city in cityList"
- :key="city"
- :label="city"
- :value="city"
- ></el-option>
- </el-select>
- <div class="flex items-center">
- <el-tooltip content="切换城市后点击">
- <el-button
- type="primary"
- size="small"
- @click="reGenerateFormAfterCityChange"
- >
- 生成运输信息
- </el-button>
- </el-tooltip>
- <el-button
- type="warning"
- size="small"
- @click="componentFreightVisible = true"
- >
- 设置运费参数
- </el-button>
- </div>
- </div>
- <div class="step2-form-area">
- <div
- v-for="(formItem, index) in formList"
- :key="index"
- class="step2-form-item"
- >
- <div class="qty-number">
- 采购数量: {{ formItem.number }} ({{ isHeavyGoods.label
- }}{{
- isHeavyGoodsPlus.flag !== isHeavyGoods.flag
- ? ` | ${isHeavyGoodsPlus.label}`
- : ''
- }})
- </div>
- <div class="flex items-center">
- <el-card
- v-for="v in 5"
- :key="v"
- class="form-item-card"
- :class="{
- on: formItem[`${v - 1}_${formItem.number}`] === 'on',
- }"
- >
- <template #header>
- <div
- @click.capture="
- ($e) => captureSwitchChange($e, formItem, v - 1)
- "
- >
- <el-tooltip
- placement="left"
- content="注意, 切换开关会导致右侧的成本数据 以(点过'保存按钮'后的 / 默认的)初始值 计算重置"
- >
- <el-switch
- v-model="formItem[`${v - 1}_${formItem.number}`]"
- size="small"
- active-color="#409eff"
- inactive-color="#ccc"
- active-value="on"
- inactive-value="off"
- @change="() => generateStep3Form()"
- />
- </el-tooltip>
- </div>
- </template>
- <div v-if="v === 1">
- <el-select
- v-model="formItem[`method_0_${formItem.number}`]"
- size="small"
- @change="reGenerateFormAfterMidwayTypeChange"
- >
- <el-option
- v-for="option in airOption"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- ></el-option>
- </el-select>
- <div class="price">
- $ {{ formItem.midway_price_0.toFixed(2) }}
- </div>
- </div>
- <div v-if="v === 2">
- <div>空+派</div>
- <div class="price">
- $ {{ formItem.midway_price_1.toFixed(2) }}
- </div>
- </div>
- <div v-if="v === 3">
- <el-select
- v-model="formItem[`method_2_${formItem.number}`]"
- size="small"
- @change="reGenerateFormAfterMidwayTypeChange"
- >
- <el-option
- v-for="option in seaOption"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- ></el-option>
- </el-select>
- <div class="price">
- $ {{ formItem.midway_price_2.toFixed(2) }}
- </div>
- </div>
- <div v-if="v === 4">
- <div>DTD</div>
- <div
- v-if="formItem.freight_cost_3"
- class="price cursor-pointer"
- @click="openDTDDialog(3, index)"
- >
- $ {{ formItem.freight_cost_3.toFixed(2) }}
- </div>
- <div
- v-else
- class="edit cursor-pointer"
- @click="openDTDDialog(3, index)"
- >
- {{ $t('btn_edit') }}
- </div>
- </div>
- <div v-if="v === 5">
- <div>LCL散货</div>
- <div
- v-if="formItem.freight_cost_4"
- class="price cursor-pointer"
- @click="openLCLDialog(4, index)"
- >
- $ {{ formItem.freight_cost_4.toFixed(2) }}
- </div>
- <div
- v-else
- class="edit cursor-pointer"
- @click="openLCLDialog(4, index)"
- >
- {{ $t('btn_edit') }}
- </div>
- </div>
- </el-card>
- </div>
- </div>
- </div>
- </div>
- <div class="step step-3">
- <div
- class="mb-4 border border-x-0 border-t-0 border-solid border-gray-200"
- >
- <el-check-tag
- v-for="(form, index) in step3FormList"
- :checked="index === currentTab"
- :key="index"
- class="border border-solid border-gray-200 bg-white"
- style="border-radius: 2px"
- @click="currentTab = index"
- >
- {{ form.tabLabel }}
- </el-check-tag>
- </div>
- <div
- data-desc="这层div没用的,只是移除原本的el-tab之后用来减少代码改动量,不然里面的内容全部要减少一个缩进单位了"
- >
- <div
- v-show="index === currentTab"
- v-for="(form, index) in step3FormList"
- :key="index"
- >
- <common-title
- :title="$t(prefix + 'label_cost_list')"
- ></common-title>
- <div class="horizontal-table">
- <div
- class="flex items-center tr"
- style="background-color: #ebeef5"
- >
- <div class="td">项目</div>
- <div class="td">总价</div>
- <div class="td">单价</div>
- </div>
- <div class="flex items-center tr">
- <div class="td column-label">产品成本(AUD)</div>
- <div class="td">
- {{ form.product_cost.toFixed(2) }}
- </div>
- <div class="td">
- {{ (form.product_cost / form.number).toFixed(2) }}
- </div>
- </div>
- <div class="flex items-center tr">
- <div class="td column-label">制版及其它成本(AUD)</div>
- <div class="td">
- {{ form.extend_cost.toFixed(2) }}
- </div>
- <div class="td">
- {{ (form.extend_cost / form.number).toFixed(2) }}
- </div>
- </div>
- <div class="flex items-center tr">
- <div class="td column-label">运费总成本(AUD)</div>
- <div class="td">
- {{ form.freight_cost.toFixed(2) }}
- </div>
- <div class="td">
- {{ (form.freight_cost / form.number).toFixed(2) }}
- </div>
- </div>
- <div class="flex items-center tr">
- <div class="td column-label">税费(AUD)</div>
- <div class="td">
- {{ form.tax_fee.toFixed(2) }}
- </div>
- <div class="td">
- {{ (form.tax_fee / form.number).toFixed(2) }}
- </div>
- </div>
- <div class="flex items-center tr">
- <div class="td column-label">总成本(AUD)</div>
- <div class="td">
- {{ form.total_cost.toFixed(2) }}
- </div>
- <div class="td">
- {{ (form.total_cost / form.number).toFixed(2) }}
- </div>
- </div>
- </div>
- <el-form
- :model="form"
- label-width="105px"
- >
- <common-title
- :title="$t(prefix + 'label_other_cost')"
- ></common-title>
- <div class="">
- <el-form-item
- label="COO Certificate"
- label-width="120px"
- >
- <el-switch
- v-model="form.coo_certificate"
- active-color="#409eff"
- inactive-color="#ccc"
- active-text="是"
- inactive-text="否"
- active-value="on"
- inactive-value="off"
- size="small"
- @change="($e: any) => changeCOO(form, $e)"
- ></el-switch>
- </el-form-item>
- </div>
- <div class="flex justify-between flex-wrap items-center">
- <el-form-item label="税点">
- <el-input
- v-model="form.tax"
- :disabled="form.coo_certificate === 'on'"
- @input="() => onForm3ItemChange(form, 'tax')"
- >
- <template #append>%</template>
- </el-input>
- </el-form-item>
- <el-form-item label="税费">
- <el-input
- v-model="form.tax_fee"
- disabled
- >
- <template #append>AUD</template>
- </el-input>
- </el-form-item>
- <el-form-item label="入口报关费用">
- <el-input
- v-model="form.gatt_tax_fee"
- @input="() => onForm3ItemChange(form, 'gatt_tax_fee')"
- >
- <template #append>AUD</template>
- </el-input>
- </el-form-item>
- <el-form-item label="验货费">
- <el-input
- v-model="form.review_cost"
- @input="() => onForm3ItemChange(form, 'review_cost')"
- >
- <template #append>AUD</template>
- </el-input>
- </el-form-item>
- <el-form-item label="国内运费总价">
- <el-input
- v-model="form.cn_freight_cost"
- @input="() => onForm3ItemChange(form, 'cn_freight_cost')"
- >
- <template #append>RMB</template>
- </el-input>
- </el-form-item>
- <el-form-item label="国外本土运费">
- <el-input
- v-model="form.local_freight_cost"
- @input="
- () => onForm3ItemChange(form, 'local_freight_cost')
- "
- >
- <template #append>AUD</template>
- </el-input>
- </el-form-item>
- </div>
- <common-title
- :title="$t(prefix + 'label_charge')"
- ></common-title>
- <div class="flex justify-between flex-wrap items-center">
- <el-form-item label="Set Up Cost">
- <el-input
- v-model="form.setup_cost"
- @input="() => onForm3ItemChange(form, 'setup_cost')"
- >
- <template #append>AUD</template>
- </el-input>
- </el-form-item>
- <el-form-item label="本地收费">
- <el-input
- v-model="form.add_freight_cost"
- @input="() => onForm3ItemChange(form, 'add_freight_cost')"
- >
- <template #append>AUD</template>
- </el-input>
- </el-form-item>
- <el-form-item label="售卖单价">
- <el-input
- v-model="form.sold_unit"
- @input="() => onForm3ItemChange(form, 'sold_unit')"
- >
- <template #append>AUD</template>
- </el-input>
- </el-form-item>
- <el-form-item label="售卖总价">
- <el-input
- v-model="form.sold_price"
- disabled
- >
- <template #append>AUD</template>
- </el-input>
- </el-form-item>
- </div>
- <common-title
- :title="$t(prefix + 'label_analysis')"
- ></common-title>
- <div class="flex justify-between items-center">
- <el-form-item label="利润率">
- <el-input
- v-model="form.profit_margin"
- @input="() => onForm3ItemChange(form, 'profit_margin')"
- >
- <template #append>%</template>
- </el-input>
- </el-form-item>
- <el-form-item label="利润">
- <el-input
- v-model="form.profit"
- disabled
- >
- <template #append>AUD</template>
- </el-input>
- </el-form-item>
- </div>
- </el-form>
- <div class="flex justify-center items-center">
- <el-button
- type="primary"
- size="small"
- @click="
- () => {
- isExport = 0
- checkForm(1)
- }
- "
- >
- {{ $t('btn_save') }}
- </el-button>
- <el-button
- type="primary"
- size="small"
- plain
- @click="
- () => {
- isExport = 1
- checkForm(2)
- }
- "
- >
- 保存并导出
- </el-button>
- <!-- <el-button @click="generate">test</el-button> -->
- </div>
- </div>
- </div>
- </div>
- </div>
- <setDTD
- v-model:visible="dtdVisible"
- :form-data="dtdData"
- @save="dtdChange"
- ></setDTD>
- <setLCL
- v-model:visible="lclVisible"
- :form-data="lclData"
- @save="lclChange"
- ></setLCL>
- <freight
- v-model:visible="componentFreightVisible"
- @save="getCalcParam"
- ></freight>
- <CompExportForm
- v-model:visible="componentExportFormVisible"
- :step3-form-list="step3FormList"
- :creator-options="creatorOptions"
- :form-data="exportForm"
- :city-list="cityList"
- @save="onExportFormSave"
- ></CompExportForm>
- </el-dialog>
- </div>
- </template>
- <script lang="ts" setup>
- import { defineComponent, ref, watch, computed, nextTick, inject } from 'vue'
- import {
- ElButton,
- ElNotification,
- ElMessage,
- ElForm,
- ElFormItem,
- ElInput,
- ElSelect,
- ElDialog,
- ElOption,
- ElSwitch,
- ElCard,
- ElCheckTag,
- ElTooltip,
- } from 'element-plus'
- import cloneDeep from 'lodash.clonedeep'
- import commonTitle from './components/title.vue'
- import setDTD from './components/dialogDTD.vue'
- import setLCL from './components/dialogLCL.vue'
- import freight from '../freight.vue'
- import step1 from './components/step1.vue'
- import CompExportForm from '../exportForm.vue'
- import exportQuota from '../exportQuota2.vue'
- import mathjs, { savePrecision } from '@/utils/math.js'
- import Cookies from 'js-cookie'
- import { getCalcParams, saveCalcData } from '@/api/indent'
- import { $t } from '@/i18n/index'
- defineComponent({
- name: 'ComponentAaaa',
- })
- const {
- visible = false,
- dataForCalc = {} as any,
- creatorOptions = [],
- } = defineProps<{
- visible: boolean
- dataForCalc: object
- creatorOptions: any[]
- }>()
- const $emit = defineEmits([
- 'update:visible',
- 'save-price-calc',
- 'save-price-calc',
- ])
- const $mediaRegExp = inject('mediaRegExp') as RegExp
- const prefix = 'order.indent_calc.'
- const loading = ref(false)
- const componentFreightVisible = ref(false)
- const componentExportFormVisible = ref(false)
- const productInfo = ref({} as any)
- const setting = ref({} as any) // 运费设置数据
- // 用在step2界面上显示的表单
- const formList = ref([] as any[])
- // 用在step3界面上显示的表单
- const step3FormList = ref([] as any[])
- const currentTab = ref(0) // 当前显示的step3表单的tab索引
- // 提交的表单, 用来存真正提交的数据.
- const formData = ref({
- cal_city: {
- local_city: '',
- },
- cal_shipment_method: {},
- } as any)
- // 导出pdf那个表单
- let exportForm = ref({
- city: '', // 显示在导出pdf的城市地址, 不是step2的运费选择地址.
- exchange: '',
- days: '30',
- gst_name: '+GST',
- notes: '',
- other_notes: '',
- saleperson: '',
- } as any)
- const step3FormDemo = ref({
- coo_certificate: 'on', // coo 开关
- tax: 0, // 税点 coo打开则是0, 关闭默认是5
- tax_fee: 0, // 税费 coo打开则是0, 需要根据税点计算
- gatt_tax_fee: 60, // 入口报关费用
- review_cost: 0, // 验货费
- cn_freight_cost: 0, // 国内运费总价
- local_freight_cost: 0, // 国外本地运费
- add_freight_cost: 0, // 本地收费
- freight: 0, // 运费总成本
- setup_cost: 0, // Set Up Cost
- sold_unit: 0, // 售卖单价
- sold_price: 0, // 售卖总价
- profit_margin: 30, // mark up 利润率
- profit: 0, // 利润
- } as any)
- const imageList = ref([] as any[])
- const cityList = ref([] as any[])
- // 空运选项. 参考: https://www.tapd.cn/59388921/prong/stories/view/1159388921001001048
- const airOption = [
- { label: 'DHL', value: 'dhl' },
- { label: 'TNT', value: 'tnt' },
- { label: 'Fedex', value: 'fedex' },
- ]
- // 海运选项
- const seaOption = ref([
- { label: 'FCL', value: 'fcl' },
- { label: 'LCL', value: 'lcl' },
- ])
- const dtdData = ref({} as any)
- const lclData = ref({} as any)
- const dtdVisible = ref(false)
- const lclVisible = ref(false)
- const show = ref(false)
- watch(
- () => visible,
- () => {
- show.value = visible
- resetData()
- if (show.value) {
- getCalcParam()
- }
- },
- )
- let getCalcParam = () => {
- getCalcParams().then((response: any) => {
- const res = response.result
- if (response.code !== 1) return
- cityList.value = res.city_list
- if (cityList.value.length) {
- formData.value.cal_city.local_city = cityList.value[0]
- }
- setting.value = Object.assign({}, res.data)
- setting.value.dhl_airline = JSON.parse(setting.value.dhl_airline)
- if (!Array.isArray(setting.value.dhl_airline)) {
- setting.value.dhl_airline = []
- } else {
- setting.value.dhl_airline = setting.value.dhl_airline.map((i: any) => {
- const result: any = {}
- for (const key in i) {
- if (Object.prototype.hasOwnProperty.call(i, key)) {
- result[key] = Number(i[key])
- }
- }
- return result
- })
- }
- setting.value.tnt_airline = JSON.parse(setting.value.tnt_airline)
- if (!Array.isArray(setting.value.tnt_airline)) {
- setting.value.tnt_airline = []
- } else {
- setting.value.tnt_airline = setting.value.tnt_airline.map((i: any) => {
- const result: any = {}
- for (const key in i) {
- if (Object.prototype.hasOwnProperty.call(i, key)) {
- result[key] = Number(i[key])
- }
- }
- return result
- })
- }
- setting.value.fedex_airline = JSON.parse(setting.value.fedex_airline)
- if (!Array.isArray(setting.value.fedex_airline)) {
- setting.value.fedex_airline = []
- } else {
- setting.value.fedex_airline = setting.value.fedex_airline.map(
- (i: any) => {
- const result: any = {}
- for (const key in i) {
- if (Object.prototype.hasOwnProperty.call(i, key)) {
- result[key] = Number(i[key])
- }
- }
- return result
- },
- )
- }
- setting.value.airplus = JSON.parse(setting.value.airplus)
- if (!Array.isArray(setting.value.airplus)) {
- setting.value.airplus = []
- } else {
- setting.value.airplus = setting.value.airplus.map((i: any) => {
- const result: any = {}
- for (const key in i) {
- if (Object.prototype.hasOwnProperty.call(i, key)) {
- result[key] = Number(i[key])
- }
- }
- return result
- })
- }
- setting.value.cbm = JSON.parse(setting.value.cbm)
- if (!Array.isArray(setting.value.cbm)) {
- setting.value.cbm = []
- } else {
- setting.value.cbm = setting.value.cbm.map((i: any) => {
- const result: any = {}
- for (const key in i) {
- if (Object.prototype.hasOwnProperty.call(i, key)) {
- result[key] = Number(i[key])
- }
- }
- return result
- })
- }
- delete setting.value.admin_id
- delete setting.value.id
- delete setting.value.is_del
- delete setting.value.update_time
- delete setting.value.create_time
- delete setting.value.delete_time
- // 把浅层的几个属性全部转换成数字. 方便后续的计算
- for (const key in setting.value) {
- if (
- Object.prototype.hasOwnProperty.call(setting.value, key) &&
- typeof setting.value[key] === 'string'
- ) {
- setting.value[key] = Number(setting.value[key])
- }
- }
- initProductInfo()
- initForm([], true)
- })
- }
- let close = (done = {} as any) => {
- $emit('update:visible', false)
- imageList.value = []
- if (typeof done === 'function') done()
- }
- let resetData = () => {
- formData.value = {
- cal_city: {
- local_city: '',
- },
- cal_shipment_method: {},
- }
- exportForm.value = {
- pdf_city: '',
- cycle_name: '',
- exchange: '',
- days: '30',
- gst_name: '+GST',
- notes: '',
- other_notes: '',
- saleperson: '',
- }
- }
- // 总箱数. 购买数量/每箱数量.
- let computedBoxNumber = computed(() => {
- if (productInfo.value.number?.length) {
- return productInfo.value.number.map((i: any) =>
- mathjs.chain(i).divide(productInfo.value.in_package).done(),
- )
- } else {
- return []
- }
- })
- // 单箱体积. 立方厘米. 长*宽*高
- let computedBulk = computed(() => {
- return mathjs
- .chain(productInfo.value.package_size_length || 1)
- .multiply(productInfo.value.package_size_width || 1)
- .multiply(productInfo.value.package_size_height || 1)
- .done()
- })
- // 是否重货. 每箱毛重 大于等于 (每箱体积 / 5000) 则为重货.
- let isHeavyGoods = computed(() => {
- if (
- productInfo.value.package_weight >
- mathjs.chain(computedBulk.value).divide(5000).done()
- ) {
- return {
- flag: true,
- label: '重货',
- }
- } else {
- return {
- flag: false,
- label: '轻货',
- }
- }
- })
- // 是否重货. 空+派 配送方式专属的 轻重货计算逻辑, 与标准的计算区别在于一个除6000一个除5000
- let isHeavyGoodsPlus = computed(() => {
- if (
- productInfo.value.package_weight >
- mathjs.chain(computedBulk.value).divide(6000).done()
- ) {
- return {
- flag: true,
- label: '重货',
- }
- } else {
- return {
- flag: false,
- label: '轻货',
- }
- }
- })
- // 界面上写的是总重量, 实际上应该理解成负重系数, 即轻重货占不同体积, 货运得收不同费用维持利润.
- // 重货是货物重量本身, 即每箱毛重*箱数, 轻货则是每箱体积*箱数/5000
- let computedTotalWeight = computed(() => {
- if (!computedBoxNumber.value.length) return []
- if (isHeavyGoods.value.flag) {
- // 重货
- return computedBoxNumber.value.map((i: number) => {
- return mathjs
- .chain(
- // 重量浮动比. 在运费参数里面设置的.
- mathjs
- .chain(Number(setting.value.rate_weight || 0))
- .divide(100)
- .add(1)
- .done(),
- )
- .multiply(productInfo.value.package_weight)
- .multiply(i)
- .done()
- })
- } else {
- // 轻货
- return computedBoxNumber.value.map((i: number) => {
- return mathjs.chain(computedBulk.value).multiply(i).divide(5000).done()
- })
- }
- })
- // 空+派 方式的(总重量)负重系数.
- let computedTotalWeightPlus = computed(() => {
- if (!computedBoxNumber.value.length) return []
- if (isHeavyGoodsPlus.value.flag) {
- // 重货
- return computedBoxNumber.value.map((i: number) => {
- return mathjs
- .chain(
- // 重量浮动比. 在运费参数里面设置的.
- mathjs
- .chain(Number(setting.value.rate_weight || 0))
- .divide(100)
- .add(1)
- .done(),
- )
- .multiply(productInfo.value.package_weight)
- .multiply(i)
- .done()
- })
- } else {
- // 轻货
- return computedBoxNumber.value.map((i: number) => {
- return mathjs.chain(computedBulk.value).multiply(i).divide(6000).done()
- })
- }
- })
- // 总体积CBM. 单箱体积*箱数*浮动 / 一百万
- let computedTotalBulk = computed(() => {
- if (!computedBoxNumber.value.length) return []
- return computedBoxNumber.value.map((i: number) => {
- return mathjs
- .chain(
- // 体积浮动比. 在运费参数里面设置的.
- mathjs.chain(Number(setting.value.rate_bulk)).divide(100).add(1).done(),
- )
- .multiply(computedBulk.value)
- .multiply(i)
- .divide(1000000)
- .done()
- })
- })
- // 返回值会有两个子数组. 第一个是重货的, 第二个是轻货的,
- // 每个数组里有两项, 分别是计算公式的参数1和2.
- let computedCityFreightParams = computed(() => {
- if (formData.value.cal_city?.local_city) {
- return setting.value.city_list[formData.value.cal_city.local_city]
- }
- return []
- })
- // 国内运费
- // let computedLocalFreight = computed(() => {
- // if (isHeavyGoodsPlus.value.flag) {
- // return this.computedTotalWeight((i:number) => {
- // return mathjs.chain(setting.value.cn_price_heavy).multiply(i).done()
- // })
- // }
- // return computedTotalBulk.value.map((i:number) => {
- // return mathjs.chain(setting.value.cn_price).multiply(i).done()
- // })
- // })
- let initProductInfo = () => {
- const temp = cloneDeep(dataForCalc)
- if (Array.isArray(temp.product_image)) {
- imageList.value = temp.product_image.map((img: string) => {
- return $mediaRegExp.test(img)
- ? img
- : import.meta.env.VITE_APP_OSS_PREFIX + img
- })
- }
- temp.cost_name = []
- temp.cost_price = []
- if (temp.cost_list && temp.cost_list.length > 2) {
- const t = JSON.parse(temp.cost_list)
- t.forEach((item: any) => {
- temp.cost_name.push(item.cost_name)
- temp.cost_price.push(parseFloat(item.cost_price))
- })
- }
- temp.number = []
- temp.price = []
- temp.days = []
- if (temp.price_list && temp.price_list.length > 2) {
- const t = JSON.parse(temp.price_list)
- t.forEach((item: any) => {
- temp.number.push(parseFloat(item.number))
- temp.price.push(parseFloat(item.price))
- temp.days.push(parseFloat(item.days))
- })
- }
- // 之前保存到数据库的计价信息
- if (typeof temp.save_cal === 'string' && temp.save_cal.length > 2) {
- temp.save_cal = JSON.parse(temp.save_cal)
- } else {
- temp.save_cal = {}
- }
- // 初始化之前选择的城市
- if (temp.save_cal.cal_city) {
- formData.value.cal_city.local_city = temp.save_cal.cal_city.local_city
- }
- productInfo.value = temp
- }
- /**
- * 根据 productInfo 生成表单, 包括step2的和部分step3的数据.
- */
- let initForm = (switchStatus = [] as any[], useOldFormData = true) => {
- formList.value = []
- step3FormList.value = []
- if (productInfo.value.number?.length) {
- // 保存的数据库里面的中途配送数据
- const oldMidWayData = productInfo.value.save_cal.cal_shipment_method || {}
- productInfo.value.number.forEach((item: any, index: number) => {
- const t: any = {}
- t[`method_0_${item}`] = 'dhl'
- t[`method_2_${item}`] = 'lcl'
- if (useOldFormData) {
- t[`method_0_${item}`] = oldMidWayData[`method_0_${item}`] || 'dhl'
- t[`method_2_${item}`] = oldMidWayData[`method_2_${item}`] || 'lcl'
- }
- t[`method_3_${item}`] = ''
- t[`method_4_${item}`] = ''
- // 这5个是开关
- t[`0_${item}`] = 'off'
- t[`1_${item}`] = 'off'
- t[`2_${item}`] = 'off'
- t[`3_${item}`] = 'off'
- t[`4_${item}`] = 'off'
- if (useOldFormData) {
- // 上一次编辑中, 保存到数据库的数据记录
- t[`0_${item}`] = oldMidWayData[`0_${item}`] || 'off'
- t[`1_${item}`] = oldMidWayData[`1_${item}`] || 'off'
- t[`2_${item}`] = oldMidWayData[`2_${item}`] || 'off'
- t[`3_${item}`] = oldMidWayData[`3_${item}`] || 'off'
- t[`4_${item}`] = oldMidWayData[`4_${item}`] || 'off'
- }
- if (switchStatus.length) {
- // 记录当前页面之前已经打开的开关状态, 用在切换城市后的重新初始化逻辑中.
- t[`0_${item}`] = switchStatus[index][`0_${item}`] || 'off'
- t[`1_${item}`] = switchStatus[index][`1_${item}`] || 'off'
- t[`2_${item}`] = switchStatus[index][`2_${item}`] || 'off'
- t[`3_${item}`] = switchStatus[index][`3_${item}`] || 'off'
- t[`4_${item}`] = switchStatus[index][`4_${item}`] || 'off'
- }
- // 目的城市运费
- t.city_price_0 = 0
- t.city_price_1 = 0
- t.city_price_2 = 0
- t.city_price_3 = 0
- t.city_price_4 = 0
- // 中途运费总额. 即海运和空运的.
- t.midway_price_0 = 0
- t.midway_price_1 = 0
- t.midway_price_2 = 0
- // 这两个是自行输入然后直接显示在step2的中途运费位置, 其他三个是计算出来的,
- // 同时也作为step3的运费总成本(AUD)
- t.freight_cost_3 = 0
- t.freight_cost_4 = 0
- // 国内本地运费
- t.cn_price_0 = 0
- t.cn_price_1 = 0
- t.cn_price_2 = 0
- // 成本清单
- t.product_cost = calcProductCost(index) // 产品成本(AUD)
- t.extend_cost = calcExtendCost() // 制版及其它成本(AUD)
- t.total_cost = 0 // 总成本(AUD)
- // 给html模版分辨是哪个表单的数据
- t.number = item
- // 计价步骤上貌似没有用到的数据, 但是保存到数据库, 并且该对话框界面回显.
- t.fclData = {}
- t.lclData = {}
- if (useOldFormData) {
- const oldData = productInfo.value.save_cal || {}
- if (oldData[`cal_fcl_${item}`]) {
- t.fclData = oldData[`cal_fcl_${item}`]
- t.freight_cost_3 = oldData[`cal_fcl_${item}`].total_fcl
- }
- if (oldData[`cal_lcl_${item}`]) {
- t.lclData = oldData[`cal_lcl_${item}`]
- t.freight_cost_4 = oldData[`cal_lcl_${item}`].total_lcl
- }
- }
- formList.value.push(t)
- })
- const indentUser = Cookies.get('indent-user')
- let r = creatorOptions.filter((i) => i.label === indentUser)
- exportForm.value = {
- pdf_city: productInfo.value.save_cal.pdf_city || cityList.value[0],
- exchange: productInfo.value.save_cal.exchange || '',
- days: productInfo.value.save_cal.days || 30,
- gst_name: productInfo.value.save_cal.gst_name || '+GST',
- notes: productInfo.value.save_cal.notes || '',
- other_notes: productInfo.value.save_cal.other_notes || '',
- saleperson:
- productInfo.value.save_cal.saleperson || (r.length ? r[0].value : ''),
- }
- }
- setFreight()
- if (useOldFormData) {
- // 仅页面初始化时会执行到这里
- generateStep3Form(true)
- }
- }
- const onCityChange = (str: string) => {
- // 没保存计价之前, 切换城市会改变pdf_city. 保存之后, 再怎么切换也用保存的数据做默认数据, 除非手动更改pdf_city
- exportForm.value.pdf_city =
- productInfo.value.save_cal.pdf_city || str || cityList.value[0]
- }
- let reGenerateFormAfterCityChange = () => {
- const temp: any[] = formList.value.map((i, index) => {
- const result: any = {}
- result[`0_${productInfo.value.number[index]}`] =
- i[`0_${productInfo.value.number[index]}`]
- result[`1_${productInfo.value.number[index]}`] =
- i[`1_${productInfo.value.number[index]}`]
- result[`2_${productInfo.value.number[index]}`] =
- i[`2_${productInfo.value.number[index]}`]
- result[`3_${productInfo.value.number[index]}`] =
- i[`3_${productInfo.value.number[index]}`]
- result[`4_${productInfo.value.number[index]}`] =
- i[`4_${productInfo.value.number[index]}`]
- result[`method_0_${productInfo.value.number[index]}`] =
- i[`method_0_${productInfo.value.number[index]}`]
- result[`method_2_${productInfo.value.number[index]}`] =
- i[`method_2_${productInfo.value.number[index]}`]
- return result
- })
- initForm(temp)
- generateStep3Form()
- }
- /**
- * 切换运送方式之后, 重新计算中途运费和生成step3的表单内容. 开关属于开启状态才有必要重算
- */
- let reGenerateFormAfterMidwayTypeChange = () => {
- setFreight()
- generateStep3Form()
- }
- let generateStep3Form = (withOldData = true) => {
- const labelList = ['快递', '空+派', '海运', 'DTD', 'LCL散货']
- const result: any[] = []
- formList.value.forEach((i: any) => {
- for (let n = 0; n < 5; n++) {
- if (i[`${n}_${i.number}`] === 'on') {
- let temp = Object.assign({}, step3FormDemo.value, {
- tabLabel: `${i.number} ${labelList[n]}`,
- number: i.number,
- typeNumber: n,
- cn_freight_cost: 0,
- product_cost: i.product_cost,
- extend_cost: i.extend_cost,
- total_cost: i.total_cost,
- })
- if (n <= 2) {
- temp.cn_freight_cost = savePrecision(i[`cn_price_${n}`])
- temp.local_freight_cost = savePrecision(i[`city_price_${n}`])
- temp.add_freight_cost = savePrecision(i[`city_price_${n}`])
- // 记录中途运费, 用在step3表单项变更后的重复计算
- temp.midway_price = i[`midway_price_${n}`]
- temp.freight_cost = mathjs
- .chain(i[`midway_price_${n}`])
- .add(i[`city_price_${n}`])
- .done()
- temp.total_cost = mathjs
- .chain(i.product_cost)
- .add(i.extend_cost)
- .add(temp.freight_cost)
- .add(
- mathjs
- .chain(temp.cn_freight_cost)
- .divide(setting.value.rate_rmb_aud)
- .done(),
- )
- .add(step3FormDemo.value.tax_fee)
- .add(step3FormDemo.value.gatt_tax_fee)
- .add(step3FormDemo.value.review_cost)
- .done()
- } else if (n === 3) {
- temp.local_freight_cost = 0
- temp.add_freight_cost = 0
- temp.freight_cost = mathjs
- .chain(i[`freight_cost_${n}`])
- .add(i[`city_price_${n}`])
- .done()
- temp.total_cost = mathjs
- .chain(i.product_cost)
- .add(i.extend_cost)
- .add(temp.freight_cost)
- .add(
- mathjs
- .chain(temp.cn_freight_cost)
- .divide(setting.value.rate_rmb_aud)
- .done(),
- )
- .add(step3FormDemo.value.tax_fee)
- .add(step3FormDemo.value.gatt_tax_fee)
- .add(step3FormDemo.value.review_cost)
- .done()
- temp[`cn_price_${n}`] = 0 // 国内运费. 后两种配送方式默认是0
- } else if (n === 4) {
- temp.local_freight_cost = 0
- temp.add_freight_cost = 0
- temp.freight_cost = mathjs
- .chain(i[`freight_cost_${n}`])
- .add(i[`city_price_${n}`])
- .done()
- // total_lcl 运费总成本
- // price 国内总运费
- temp.total_cost = mathjs
- .chain(i.product_cost)
- .add(i.extend_cost)
- .add(temp.freight_cost)
- .add(
- mathjs
- .chain(temp.cn_freight_cost)
- .divide(setting.value.rate_rmb_aud)
- .done(),
- )
- .add(step3FormDemo.value.tax_fee)
- .add(step3FormDemo.value.gatt_tax_fee)
- .add(step3FormDemo.value.review_cost)
- .done()
- temp[`cn_price_${n}`] = 0 // 国内运费. 后两种配送方式默认是0
- }
- temp.profit = savePrecision(
- // 利润率是整数, 除100算出百分数.
- mathjs
- .chain(step3FormDemo.value.profit_margin)
- .divide(100)
- .multiply(temp.total_cost)
- .done(),
- )
- temp.sold_price = savePrecision(
- mathjs
- .chain(temp.total_cost)
- .multiply(
- mathjs
- .chain(step3FormDemo.value.profit_margin)
- .add(100)
- .divide(100)
- .done(),
- )
- .done(),
- )
- temp.sold_unit = mathjs
- .chain(
- Math.ceil(
- Number(
- mathjs
- .chain(temp.sold_price)
- .subtract(temp.add_freight_cost)
- .subtract(step3FormDemo.value.setup_cost)
- .divide(i.number)
- .multiply(100)
- .done(),
- ),
- ),
- )
- .divide(100)
- .done()
- exportForm.value[`zdy_date_${n}_${i.number}`] = ''
- exportForm.value[`cycle_name_${n}_${i.number}`] = 'weeks'
- if (withOldData === true) {
- const oldData = productInfo.value.save_cal
- if (oldData[`cal_quote_${n}_${i.number}`]) {
- const cloneData = cloneDeep(oldData[`cal_quote_${n}_${i.number}`])
- cloneData.freight_cost = cloneData.freight
- delete cloneData.freight
- temp = Object.assign(temp, cloneData)
- }
- exportForm.value[`zdy_date_${n}_${i.number}`] =
- oldData[`zdy_date_${n}_${i.number}`] || ''
- exportForm.value[`cycle_name_${n}_${i.number}`] =
- oldData[`cycle_name_${n}_${i.number}`] || 'weeks'
- }
- result.push(temp)
- }
- }
- })
- step3FormList.value = result
- }
- // 设置 中途运费 及 国外当地运费
- let setFreight = () => {
- productInfo.value.number.forEach((item: any, index: number) => {
- // 早起的需求限制3个, 现在暂定放开了. 限制的话, 超过3个的货物数量的运费直接就跳过不计算了.
- // if (index > 2) {
- // return
- // }
- const cityPrice = calcCityPrice(
- computedTotalWeight.value[index],
- computedTotalBulk.value[index],
- )
- // 国外本地运费, dtd 和 lcl散货默认是0, 所以这里只给前三个填充了值.
- formList.value[index].city_price_0 = cityPrice
- formList.value[index].city_price_1 = cityPrice
- formList.value[index].city_price_2 = cityPrice
- // 航空:总重量*空运费单价(AUD) * (1+燃油附加)
- formList.value[index].midway_price_0 = mathjs
- .chain(
- getCurrentPrice(
- formList.value[index][`method_0_${item}`],
- computedTotalWeight.value[index],
- ),
- )
- .multiply(computedTotalWeight.value[index])
- .multiply(mathjs.chain(setting.value.rate_fuel).divide(100).add(1).done())
- .done()
- // 空+派 与航空的计算方式基本一致。
- // 差异点为,重轻货判断及负重系数计算时,除以6000, 燃油附加是另外的字段.
- formList.value[index].midway_price_1 = mathjs
- .chain(getCurrentPricePlus(computedTotalWeightPlus.value[index]))
- .multiply(computedTotalWeightPlus.value[index])
- .multiply(
- mathjs.chain(setting.value.rate_fuelplus).divide(100).add(1).done(),
- )
- .done()
- // 海运 CBM * 基础参数里面的海运费. 旧后台这一项的计算有误差, cbm用了约进两位数之后的值来计算.
- formList.value[index].midway_price_2 = mathjs
- .chain(computedTotalBulk.value[index])
- .multiply(setting.value.sea_fee)
- .done()
- const cn_price = calcLocalPrice(index)
- // 国内运费
- formList.value[index].cn_price_0 = cn_price
- formList.value[index].cn_price_1 = cn_price
- formList.value[index].cn_price_2 = cn_price
- })
- }
- // 目标城市的快递费用计算. 这个判断轻重货时不用区分 空+派 的 /6000
- let calcCityPrice = (heavy: number, bulk: number) => {
- const p = computedCityFreightParams.value
- if (!p.length) return 0
- if (isHeavyGoods.value.flag) {
- return p[0][0] + (p[0][1] / 50) * heavy
- } else {
- return p[1][0] + p[1][1] * bulk
- }
- }
- // 目标城市的快递费用计算. 空+派方式的, 这种方式轻重货判断计算公式不一样
- // let calcCityPricePlus = (heavy: number, bulk: number) => {
- // const p = computedCityFreightParams.value
- // if (!p.length) return 0
- // if (isHeavyGoodsPlus.value.flag) {
- // return p[0][0] + (p[0][1] / 50) * heavy
- // } else {
- // return p[1][0] + p[1][1] * bulk
- // }
- // }
- // 国内运费. 轻重货计算公式不同
- let calcLocalPrice = (index: number) => {
- if (isHeavyGoods.value.flag) {
- return mathjs
- .chain(setting.value.cn_price_heavy)
- .multiply(computedTotalWeight.value[index])
- .done()
- } else {
- return mathjs
- .chain(setting.value.cn_price)
- .multiply(computedTotalBulk.value[index])
- .done()
- }
- }
- // 打样费用 和 额外费用(报价信息里面的出厂价-额外费用), 再除以汇率
- let calcExtendCost = () => {
- const reduceCost = productInfo.value.cost_price.reduce(
- (total: number, i: number) => {
- total = total + i
- return total
- },
- 0,
- )
- const extendCost = mathjs
- .chain(reduceCost)
- .add(Number(productInfo.value.demo_cost) || 0)
- .divide(setting.value.rate_rmb_aud)
- .done()
- return extendCost
- }
- // 产品成本 = 单价 * 数量 / 汇率
- let calcProductCost = (index: number) => {
- return mathjs
- .chain(productInfo.value.number[index])
- .multiply(productInfo.value.price[index])
- .divide(setting.value.rate_rmb_aud)
- .done()
- }
- // 获取 当前重量的 运费单价
- let getCurrentPrice = (key: string | number, heavy: number) => {
- const target = setting.value[`${key}_airline`]
- let result = 0
- if (Array.isArray(target) && target.length) {
- result = target.findIndex((i: any) => i.min <= heavy && i.max > heavy)
- }
- return target[result].price
- }
- // 空+ 派
- let getCurrentPricePlus = (heavy: number) => {
- const target = setting.value.airplus
- let result = 0
- if (Array.isArray(target) && target.length) {
- result = target.findIndex((i: any) => i.min <= heavy && i.max > heavy)
- }
- return target[result].price
- }
- // 开关切换前的点击捕获, 检查前提数据是否已输入, 没有的话不允许打开开关. 旧后台的交互.
- let captureSwitchChange = (e: any, obj: any, n: number) => {
- if (n === 3) {
- if (typeof obj.freight_cost_3 !== 'number' || obj.freight_cost_3 <= 0) {
- ElMessage.warning('请先点击编辑, 填写相关数据, 再打开开关')
- e.preventDefault()
- e.stopPropagation()
- }
- } else if (n === 4) {
- if (typeof obj.freight_cost_4 !== 'number' || obj.freight_cost_4 <= 0) {
- ElMessage.warning('请先点击编辑, 填写相关数据, 再打开开关')
- e.preventDefault()
- e.stopPropagation()
- }
- }
- }
- let changeCOO = (form: any, value: any) => {
- // 因为设置了active value, value变量不再是布尔值
- if (value === 'on') {
- form.tax = 0
- onForm3ItemChange(form, 'tax')
- } else {
- form.tax = 5
- onForm3ItemChange(form, 'tax')
- }
- }
- let calcTaxFee = (form: any) => {
- form.tax_fee = savePrecision(
- mathjs.chain(form.product_cost).multiply(form.tax).divide(100).done(),
- )
- }
- let calcProfit = (form: any) => {
- form.profit = savePrecision(
- mathjs.chain(form.sold_price).subtract(form.total_cost).done(),
- )
- }
- let calcProfitMargin = (form: any) => {
- form.profit_margin = savePrecision(
- mathjs.chain(form.profit).divide(form.total_cost).multiply(100).done(),
- )
- }
- let calcTotalCost = (form: any) => {
- form.total_cost = mathjs
- .chain(form.product_cost)
- .add(form.extend_cost)
- .add(form.freight_cost)
- .add(
- mathjs
- .chain(form.cn_freight_cost)
- .divide(setting.value.rate_rmb_aud)
- .done(),
- )
- .add(form.tax_fee)
- .add(form.gatt_tax_fee)
- .add(form.review_cost)
- .done()
- }
- /**
- * 用利润率计算售价总价
- **/
- let calcSoldPriceByProfitMargin = (form: any) => {
- form.sold_price = savePrecision(
- mathjs
- .chain(form.total_cost)
- .multiply(mathjs.chain(form.profit_margin).add(100).divide(100).done())
- .done(),
- )
- }
- /**
- * 用单价计算售价总价. 单价*数量 + setup cost + add freight cost
- **/
- let calcSoldPriceBySoldUnit = (form: any) => {
- form.sold_price = savePrecision(
- mathjs
- .chain(form.sold_unit)
- .multiply(form.number)
- .add(form.setup_cost)
- .add(form.add_freight_cost)
- .done(),
- )
- }
- let onForm3ItemChange = (form: any, key: string) => {
- let dotFlag = false
- if (typeof form[key] === 'string' && /\.$/.test(form[key])) {
- // 处理小数点
- form[key] = form[key].replace(/\.$/, '')
- dotFlag = true
- }
- // 各输入框之间的输入值变动会有联动.
- // 注意, 各 case 里面的调用顺序有影响, 改动之前务必保证你理解当前在做什么.
- switch (key) {
- case 'tax':
- // 影响 税费、总成本、利润率、利润值
- calcTaxFee(form)
- calcTotalCost(form)
- calcProfit(form)
- calcProfitMargin(form)
- break
- case 'review_cost':
- // 影响 总成本、利润率、利润值
- calcTotalCost(form)
- calcProfit(form)
- calcProfitMargin(form)
- break
- case 'cn_freight_cost':
- // 影响 总成本、利润率、利润值
- calcTotalCost(form)
- calcProfit(form)
- calcProfitMargin(form)
- break
- case 'local_freight_cost':
- // 影响 运费总成本、总成本、售卖总价、利润率. 利润值(不影响)
- form.add_freight_cost = form.local_freight_cost
- form.freight_cost = mathjs
- .chain(form.local_freight_cost)
- .add(form.midway_price)
- .done()
- calcTotalCost(form)
- calcProfitMargin(form)
- calcSoldPriceByProfitMargin(form)
- break
- case 'add_freight_cost':
- // 影响 售卖总价、利润率、利润值
- // fallthrough
- case 'setup_cost':
- // 影响 售卖总价、利润值、利润率
- // fallthrough
- case 'sold_unit':
- // 直接乘算出售卖总价, 更新利润率、利润值
- calcSoldPriceBySoldUnit(form)
- calcProfit(form)
- calcProfitMargin(form)
- break
- case 'profit_margin':
- // 影响 利润值、售卖总价、售卖单价
- calcSoldPriceByProfitMargin(form)
- calcProfit(form)
- form.sold_unit = mathjs
- .chain(
- Math.ceil(
- Number(
- mathjs
- .chain(form.sold_price)
- .subtract(form.add_freight_cost)
- .subtract(form.setup_cost)
- .divide(form.number)
- .multiply(100)
- .done(),
- ),
- ),
- )
- .divide(100)
- .done()
- break
- case 'gatt_tax_fee':
- calcTotalCost(form)
- calcProfit(form)
- calcProfitMargin(form)
- break
- default:
- // 默认不做任何处理
- break
- }
- if (dotFlag) {
- form[key] = form[key] + '.'
- }
- }
- let openDTDDialog = (columnNum: number, rowNum: number) => {
- dtdData.value = {
- rowNum,
- columnNum,
- freight_cost: formList.value[rowNum][`freight_cost_${columnNum}`] || '',
- method_fcl: formList.value[rowNum].fclData.method_fcl || '',
- }
- dtdVisible.value = true
- }
- let dtdChange = (data: any) => {
- formList.value[dtdData.value.rowNum][
- `freight_cost_${dtdData.value.columnNum}`
- ] = Number(data.freight_cost) || 0
- formList.value[dtdData.value.rowNum].fclData.method_fcl =
- data.method_fcl || ''
- formList.value[dtdData.value.rowNum].fclData.total_fcl =
- Number(data.freight_cost) || 0
- generateStep3Form()
- }
- let openLCLDialog = (columnNum: number, rowNum: number) => {
- lclData.value = {
- rowNum,
- columnNum,
- heavy: computedTotalWeight.value[rowNum],
- freight_cost: formList.value[rowNum][`freight_cost_${columnNum}`] || '',
- margin_lcl: formList.value[rowNum].lclData.margin_lcl || '',
- unit_lcl: formList.value[rowNum].lclData.unit_lcl || '',
- price: formList.value[rowNum].lclData.price || '',
- }
- lclVisible.value = true
- }
- let lclChange = (data: any) => {
- // 这个是 运输总成本, 会添加到 step3form 里面用于计算
- formList.value[lclData.value.rowNum][
- `freight_cost_${lclData.value.columnNum}`
- ] = Number(data.freight_cost) || 0
- // 这四个保存到数据库的, total_lcl其实就是 运输总成本
- formList.value[lclData.value.rowNum].lclData.unit_lcl =
- Number(data.unit_lcl) || 0
- formList.value[lclData.value.rowNum].lclData.price = Number(data.price) || 0
- formList.value[lclData.value.rowNum].lclData.margin_lcl =
- Number(data.margin_lcl) || 0
- formList.value[lclData.value.rowNum].lclData.total_lcl =
- Number(data.freight_cost) || 0
- generateStep3Form()
- }
- let isExport = ref(0)
- let checkForm = (type = 1) => {
- // 利用引用传值变更 formData 的内容
- const method = formData.value.cal_shipment_method
- formList.value.forEach((item) => {
- for (let i = 0; i < 5; i++) {
- if (item[`${i}_${item.number}`] === 'on') {
- method[`${i}_${item.number}`] = 'on'
- }
- }
- method[`method_0_${item.number}`] = item[`method_0_${item.number}`]
- method[`method_2_${item.number}`] = item[`method_2_${item.number}`]
- if (item.lclData && item.lclData.total_lcl) {
- formData.value[`cal_lcl_${item.number}`] = cloneDeep(item.lclData)
- }
- if (item.fclData && item.fclData.total_fcl) {
- formData.value[`cal_fcl_${item.number}`] = cloneDeep(item.fclData)
- }
- })
- step3FormList.value.forEach((item) => {
- formData.value[`cal_quote_${item.typeNumber}_${item.number}`] = {
- coo_certificate: item.coo_certificate, // coo 开关
- tax: item.tax, // 税点 coo打开则是0, 关闭默认是5
- tax_fee: item.tax_fee, // 税费 coo打开则是0, 需要根据税点计算
- gatt_tax_fee: item.gatt_tax_fee, // 入口报关费用
- review_cost: item.review_cost, // 验货费
- cn_freight_cost: item.cn_freight_cost, // 国内运费总价
- local_freight_cost: item.local_freight_cost, // 国外本地运费
- add_freight_cost: item.add_freight_cost, // 本地收费
- freight: savePrecision(item.freight_cost), // 运费总成本
- setup_cost: item.setup_cost, // Set Up Cost
- sold_unit: item.sold_unit, // 售卖单价
- sold_price: item.sold_price, // 售卖总价
- profit_margin: item.profit_margin, // mark up 利润率
- profit: item.profit, // 利润
- }
- })
- const p = Object.assign(
- {
- id: dataForCalc.id || '',
- },
- cloneDeep(formData.value),
- )
- if (isExport.value === 1) p.is_export = 1 // 后端用来区分是否是点了导出
- if (type === 1) {
- saveCalc(Object.assign(p, exportForm.value))
- } else if (type === 2) {
- componentExportFormVisible.value = true
- }
- }
- let saveCalc = (p: any) => {
- loading.value = true
- saveCalcData(p)
- .then((res: any) => {
- if (res.code !== 1) {
- ElNotification({
- type: 'error',
- title: '保存出错了',
- duration: 3000,
- })
- return
- }
- ElNotification({
- type: 'success',
- title: '保存成功',
- duration: 3000,
- })
- $emit('save-price-calc')
- })
- .finally(() => {
- setTimeout(() => {
- loading.value = false
- }, 300)
- })
- }
- let onExportFormSave = (data: any) => {
- exportForm.value = cloneDeep(data)
- checkForm(1)
- // 生成pdf涉及DOM操作, 故变更数据后需要等界面更新,
- // 此处需要nextTick保证生成时数据已经更新到了界面上.
- nextTick(() => {
- generate()
- })
- }
- const compExportQuotaRef = ref()
- let generate = () => {
- if (
- compExportQuotaRef.value.generatePDF &&
- typeof compExportQuotaRef.value.generatePDF === 'function'
- ) {
- compExportQuotaRef.value.generatePDF()
- }
- }
- </script>
- <style lang="scss">
- .compnent-price-calc {
- .custom-calc-price-dialog {
- margin-top: 0 !important;
- margin-bottom: 0 !important;
- height: 100vh;
- .el-dialog__body {
- max-height: calc(100vh - 56px);
- overflow-y: scroll;
- overflow-x: auto;
- padding: 4px 0 0;
- }
- }
- .step-3 {
- input[type='number'] {
- -moz-appearance: textfield;
- appearance: textfield;
- &:hover {
- -moz-appearance: textfield;
- appearance: textfield;
- &::-webkit-inner-spin-button,
- &::-webkit-outer-spin-button {
- -webkit-appearance: none;
- margin: 0;
- }
- }
- &::-webkit-inner-spin-button,
- &::-webkit-outer-spin-button {
- -webkit-appearance: none;
- margin: 0;
- }
- }
- }
- }
- </style>
- <style lang="scss" scoped>
- @use './styles/index.scss';
- </style>
|