|
@@ -0,0 +1,1724 @@
|
|
|
+<template>
|
|
|
+ <div class="compnent-price-calc">
|
|
|
+ <exportQuota
|
|
|
+ ref="compExportQuota"
|
|
|
+ :product-info="productInfo"
|
|
|
+ :export-form="exportForm"
|
|
|
+ :step3-form-list="step3FormList"
|
|
|
+ :step2-form-list="formList"
|
|
|
+ :creator-options="creatorOptions"
|
|
|
+ :city="formData.cal_city.local_city"
|
|
|
+ ></exportQuota>
|
|
|
+ <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"
|
|
|
+ >
|
|
|
+ <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
|
|
|
+ class=""
|
|
|
+ @click.capture="
|
|
|
+ ($e) => captureSwitchChange($e, formItem, v - 1)
|
|
|
+ "
|
|
|
+ >
|
|
|
+ <el-tooltip
|
|
|
+ placement="left"
|
|
|
+ :disabled="
|
|
|
+ formItem[`${v - 1}_${formItem.number}`] === 'off'
|
|
|
+ "
|
|
|
+ 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"
|
|
|
+ class=""
|
|
|
+ >
|
|
|
+ <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"
|
|
|
+ class=""
|
|
|
+ >
|
|
|
+ <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"
|
|
|
+ class=""
|
|
|
+ >
|
|
|
+ <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">
|
|
|
+ <el-tabs type="card">
|
|
|
+ <el-tab-pane
|
|
|
+ v-for="(form, index) in step3FormList"
|
|
|
+ :key="index"
|
|
|
+ :label="`${form.tabLabel}`"
|
|
|
+ >
|
|
|
+ <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'"
|
|
|
+ type="number"
|
|
|
+ @blur="() => onForm3ItemChange(form, 'tax')"
|
|
|
+ >
|
|
|
+ <template #append>%</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="税费">
|
|
|
+ <el-input
|
|
|
+ v-model="form.tax_fee"
|
|
|
+ disabled
|
|
|
+ type="number"
|
|
|
+ >
|
|
|
+ <template #append>AUD</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="入口报关费用">
|
|
|
+ <el-input
|
|
|
+ v-model="form.gatt_tax_fee"
|
|
|
+ type="number"
|
|
|
+ @blur="() => 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"
|
|
|
+ type="number"
|
|
|
+ @blur="() => 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"
|
|
|
+ type="number"
|
|
|
+ @blur="() => 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"
|
|
|
+ type="number"
|
|
|
+ @blur="
|
|
|
+ () => 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"
|
|
|
+ type="number"
|
|
|
+ @blur="() => 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"
|
|
|
+ type="number"
|
|
|
+ @blur="() => 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"
|
|
|
+ type="number"
|
|
|
+ @blur="() => 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
|
|
|
+ type="number"
|
|
|
+ >
|
|
|
+ <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"
|
|
|
+ type="number"
|
|
|
+ @blur="() => onForm3ItemChange(form, 'profit_margin')"
|
|
|
+ >
|
|
|
+ <template #append>%</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="利润">
|
|
|
+ <el-input
|
|
|
+ v-model="form.profit"
|
|
|
+ disabled
|
|
|
+ type="number"
|
|
|
+ >
|
|
|
+ <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>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </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"
|
|
|
+ @save="onExportFormSave"
|
|
|
+ ></CompExportForm>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<script lang="ts" setup>
|
|
|
+import {
|
|
|
+ defineComponent,
|
|
|
+ ref,
|
|
|
+ watch,
|
|
|
+ computed,
|
|
|
+ defineProps,
|
|
|
+ defineEmits,
|
|
|
+ nextTick,
|
|
|
+ useTemplateRef,
|
|
|
+ ShallowRef,
|
|
|
+} from 'vue'
|
|
|
+import {
|
|
|
+ ElButton,
|
|
|
+ ElNotification,
|
|
|
+ ElMessage,
|
|
|
+ ElForm,
|
|
|
+ ElFormItem,
|
|
|
+ ElInput,
|
|
|
+ ElSelect,
|
|
|
+ ElDialog,
|
|
|
+ ElOption,
|
|
|
+ ElSwitch,
|
|
|
+ ElCard,
|
|
|
+ ElTabs,
|
|
|
+ ElTabPane,
|
|
|
+ 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 '../exportQuota.vue'
|
|
|
+import mathjs, { savePrecision } from '@/utils/math.js'
|
|
|
+import { getCalcParams, saveCalcData } from '@/api/indent'
|
|
|
+import { $t } from '@/i18n/index'
|
|
|
+defineComponent({
|
|
|
+ name: 'ComponentAaaa',
|
|
|
+})
|
|
|
+const props = defineProps({
|
|
|
+ visible: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ dataForCalc: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return {}
|
|
|
+ },
|
|
|
+ },
|
|
|
+ creatorOptions: {
|
|
|
+ type: Array,
|
|
|
+ default: () => [],
|
|
|
+ },
|
|
|
+})
|
|
|
+const $emit = defineEmits([
|
|
|
+ 'update:visible',
|
|
|
+ 'save-price-calc',
|
|
|
+ 'save-price-calc',
|
|
|
+])
|
|
|
+// 用来对oss的图片、视频等媒体数据的url进行匹配替换
|
|
|
+const $mediaRegExp = /^(https?:)?\/\/.+(.com.au\/|.com\/)/
|
|
|
+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 formData = ref({
|
|
|
+ cal_city: {
|
|
|
+ local_city: '',
|
|
|
+ },
|
|
|
+ cal_shipment_method: {},
|
|
|
+} as any)
|
|
|
+
|
|
|
+// 导出pdf那个表单
|
|
|
+let exportForm = ref({
|
|
|
+ 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(
|
|
|
+ () => props.visible,
|
|
|
+ () => {
|
|
|
+ show.value = props.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)
|
|
|
+ if (typeof done === 'function') done()
|
|
|
+}
|
|
|
+let resetData = () => {
|
|
|
+ formData.value = {
|
|
|
+ cal_city: {
|
|
|
+ local_city: '',
|
|
|
+ },
|
|
|
+ cal_shipment_method: {},
|
|
|
+ }
|
|
|
+ exportForm.value = {
|
|
|
+ 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(props.dataForCalc)
|
|
|
+
|
|
|
+ if (Array.isArray(temp.product_image) && temp.product_image.length) {
|
|
|
+ imageList.value = temp.product_image.map((img) => {
|
|
|
+ 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的数据.
|
|
|
+ * @useOldFormData 仅刚打开界面初始化数据时为 true, 后续的调用都为 false
|
|
|
+ */
|
|
|
+let initForm = (switchStatus = [] as any[], useOldFormData = false) => {
|
|
|
+ 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)
|
|
|
+ })
|
|
|
+ exportForm.value = {
|
|
|
+ exchange: productInfo.value.save_cal.exchange || '',
|
|
|
+ days: productInfo.value.save_cal.days || '',
|
|
|
+ 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 || '',
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ setFreight()
|
|
|
+ if (useOldFormData) {
|
|
|
+ // 仅页面初始化时会执行到这里
|
|
|
+ generateStep3Form(true)
|
|
|
+ }
|
|
|
+}
|
|
|
+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 = false) => {
|
|
|
+ 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) => {
|
|
|
+ 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 convertIntoNumber = (value: string | number) => {
|
|
|
+ const result = Number(value)
|
|
|
+ return typeof result === 'number' ? result : 0
|
|
|
+}
|
|
|
+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) => {
|
|
|
+ // form3 的项除了开关, 其他输入框变动首先将对应之转换为数字.
|
|
|
+ form[key] = convertIntoNumber(form[key])
|
|
|
+
|
|
|
+ // 各输入框之间的输入值变动会有联动.
|
|
|
+ // 注意, 各 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
|
|
|
+ default:
|
|
|
+ // 默认不做任何处理
|
|
|
+ break
|
|
|
+ }
|
|
|
+}
|
|
|
+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) => {
|
|
|
+ console.log(columnNum, rowNum)
|
|
|
+ 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: props.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 = useTemplateRef('compExportQuota')
|
|
|
+let generate = () => {
|
|
|
+ const target: ShallowRef = compExportQuotaRef
|
|
|
+ if (
|
|
|
+ target.value.generatePDF &&
|
|
|
+ typeof target.value.generatePDF === 'function'
|
|
|
+ ) {
|
|
|
+ target.value.generatePDF()
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.compnent-price-calc {
|
|
|
+ .custom-calc-price-dialog {
|
|
|
+ margin-top: 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>
|
|
|
+@import './styles/index.scss';
|
|
|
+</style>
|