Files
art-design/src/views/crmpc/stocking/Add.vue
T

1278 lines
45 KiB
Vue
Raw Normal View History

2025-09-04 15:09:17 +08:00
<template>
<div class="stocking-add-page">
<div class="header boxshadow">
<div class="title">合塑实业·汽车事业部-备货单(客户下定)</div>
<div class="subtitle">业务员:{{ getUserInfo.user.name }}</div>
</div>
<div class="boxshadow">
<div class="form-title">
<span class="border"></span>
<span class="title">基础信息</span>
</div>
<ElForm :model="baseForm" class="base-form">
<ElRow :gutter="12">
<ElCol :span="4">
<ElFormItem label="阿里订单号/PN号">
<ElInput v-model="baseForm.pi_no" placeholder="请输入阿里订单号/PN号" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="日期">
<ElDatePicker
v-model="baseForm.biz_date"
type="date"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
placeholder="请选择日期"
style="width: 100%"
/>
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="清关目的国">
<el-select
v-model="baseForm.clearance_country_id"
filterable
placeholder="请选择国家"
@change="
(val) =>
(baseForm.clearance_country_snapshot =
(countryOptions || []).find((x: any) => x.id === val)?.cn_addr || '')
"
>
<el-option
v-for="item in countryOptions"
:key="item.id"
:label="item.cn_addr"
:value="item.id"
/>
</el-select>
<ElInput v-model="baseForm.clearance_country_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="客户来源">
<el-select
v-model="baseForm.customer_source_id"
filterable
placeholder="请选择客户渠道"
@change="
(val) =>
(baseForm.customer_source_snapshot =
(channelOptions || []).find((x: any) => x.id === val)?.name || '')
"
>
<el-option
v-for="item in channelOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<ElInput v-model="baseForm.customer_source_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="客户名称">
<ElInput
v-model="baseForm.customer_snapshot"
placeholder="请选择客户"
readonly
@click="openCustomerDialog"
>
<template #append>
<ElButton type="primary" text @click.stop="openCustomerDialog">选择</ElButton>
</template>
</ElInput>
<ElInput v-model="baseForm.customer_id" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="客户所在国">
<el-select
v-model="baseForm.customer_country_id"
filterable
placeholder="请选择国家"
@change="
(val) =>
(baseForm.customer_country_snapshot =
(countryOptions || []).find((x: any) => x.id === val)?.cn_addr || '')
"
>
<el-option
v-for="item in countryOptions"
:key="item.id"
:label="item.cn_addr"
:value="item.id"
/>
</el-select>
<ElInput v-model="baseForm.customer_country_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
</ElRow>
</ElForm>
</div>
<!-- 明细行 -->
<div class="boxshadow">
<div class="form-title">
<span class="border"></span>
<span class="title">订单详情</span>
</div>
<div class="items-wrap">
<div class="item-row" v-for="(item, idx) in items" :key="idx">
<ElRow :gutter="12">
<ElCol :span="8">
<ElFormItem label="车型" label-width="64px">
<ElInput
v-model="item.model_snapshot"
placeholder="请选择车型"
readonly
@click="openVehicleDialog(idx)"
>
<template #append>
<ElButton type="primary" text @click.stop="openVehicleDialog(idx)"
>选择</ElButton
>
</template>
</ElInput>
<ElInput v-model="item.sku_id" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="颜色/外饰" label-width="72px">
<el-select
v-model="item.color_interior_snapshot"
filterable
placeholder="请选择内容"
@change="
(val) =>
(item.color_interior_code =
(wcolorOptions || []).find((x: any) => x.color_text === val)?.color_code ||
'')
"
>
<ElOption
v-for="item in wcolorOptions"
:key="item.color_code"
:label="item.color_text"
:value="item.color_text"
/>
</el-select>
<ElInput v-model="item.color_interior_code" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="颜色/内饰" label-width="72px">
<el-select
v-model="item.color_exterior_snapshot"
filterable
placeholder="请选择内容"
@change="
(val) =>
(item.color_exterior_code =
(ncolorOptions || []).find((x: any) => x.color_text === val)?.color_code ||
'')
"
>
<ElOption
v-for="item in ncolorOptions"
:key="item.color_code"
:label="item.color_text"
:value="item.color_text"
/>
</el-select>
<ElInput v-model="item.color_exterior_code" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="8">
<ElFormItem label="改装" label-width="52px">
<el-select
v-model="item.modify_ids"
filterable
multiple
placeholder="请选择内容"
@change="
(vals) =>
(item.modify_list = (modificationOptions || [])
.filter((x: any) => (vals || []).includes(x.id))
.map((x: any) => ({ option_id: x.id, option_name_snapshot: x.name })))
"
>
<el-option
v-for="item in modificationOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
<ElInput v-model="item.modify_list" type="hidden" />
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="12">
<ElCol :span="4">
<ElFormItem label="改装费" label-width="60px">
<ElInput v-model.number="item.retrofit_fee" placeholder="请输入改装费">
<template #append>
<ElSelect v-model="item.modify_fee_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="item.modify_fee_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="FOB段运费" label-width="84px">
<ElInput v-model.number="item.fob_transport_fee" placeholder="请输入FOB段运费">
<template #append>
<ElSelect v-model="item.fob_fee_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="item.fob_fee_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="单价" label-width="52px">
<ElInput v-model.number="item.unit_price" placeholder="请输入单价">
<template #append>
<ElSelect v-model="item.unit_price_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="item.unit_price_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="总价" label-width="52px">
<ElInput v-model.number="item.total_price" placeholder="请输入总价">
<template #append>
<ElSelect v-model="item.total_price_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="item.total_price_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="官方指导价" label-width="85px">
<ElInput v-model.number="item.official_price" placeholder="请输入官方指导价">
<template #append>
<ElSelect v-model="item.guide_price_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="item.guide_price_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="优惠" label-width="52px">
<ElInput v-model.number="item.discount_price" placeholder="请输入优惠额">
<template #append>
<ElSelect v-model="item.discount_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="item.discount_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="12">
<ElCol :span="4">
<ElFormItem label="手续费" label-width="60px">
<ElInput v-model.number="item.handling_fee" placeholder="请输入手续费">
<template #append>
<ElSelect v-model="item.helper_fee_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="item.helper_fee_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<!-- <ElCol :span="4">
<ElFormItem label="国内运费" label-width="72px">
<ElInput v-model.number="item.domestic_freight" placeholder="请输入国内运费">
<template #append>
<ElSelect v-model="item.domestic_freight_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="item.domestic_freight_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol> -->
<ElCol :span="4">
<ElFormItem label="港杂费" label-width="60px">
<ElInput v-model.number="item.port_misc_fee" placeholder="请输入港杂费">
<template #append>
<ElSelect v-model="item.port_fee_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="item.port_fee_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="利润" label-width="52px">
<ElSelect v-model="item.profit_type" placeholder="请选择" style="width: 100%">
<ElOption label="正在计算利润" value="calc" />
<ElOption label="已确认" value="ok" />
</ElSelect>
<ElInput v-model="item.profit_type_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="12">
<ElCol :span="24" class="row-actions">
<el-tag effect="light" @click="copyRow(idx)"> 复制 </el-tag>
<el-tag effect="dark" @click="addRowAfter(idx)" v-if="idx == items.length - 1">
新增
</el-tag>
<el-tag type="danger" effect="light" @click="removeRow(idx)" v-if="items.length > 1">
删除
</el-tag>
</ElCol>
</ElRow>
</div>
<ElRow :gutter="12">
<ElCol :span="4">
<ElFormItem label="合计到岸价" label-width="85px">
<ElInput v-model.number="baseForm.total_cif" placeholder="请输入合计到岸价">
<template #append>
<ElSelect v-model="baseForm.total_cif_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
</template>
</ElInput>
<ElInput v-model="baseForm.total_cif_currency_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="合同汇率" label-width="70px">
<ElInput v-model="baseForm.contract_exchange_rate" placeholder="请输入" />
</ElFormItem>
</ElCol>
</ElRow>
</div>
</div>
<div class="boxshadow">
<div class="form-title">
<span class="border"></span>
<span class="title">运输详情</span>
</div>
<ElForm :model="baseForm" class="foot-form">
<ElRow :gutter="12">
<ElCol :span="4">
<ElFormItem label="清关人">
<ElInput v-model="baseForm.declarant_name" placeholder="请输入清关人" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="预计发送日">
<ElDatePicker
v-model="baseForm.eta_ship_date"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
type="date"
placeholder="请选择日期"
style="width: 100%"
/>
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="运输方式">
<ElSelect
v-model="baseForm.shipping_method_id"
placeholder="请选择运输方式"
@change="
(val) =>
(baseForm.shipping_method_snapshot =
(ncolorOptions || []).find((x: any) => x.id === val)?.item_label || '')
"
>
<ElOption
v-for="t in transportOptions"
:key="t.id"
:label="t.item_label"
:value="t.id"
/>
</ElSelect>
<ElInput v-model="baseForm.shipping_method_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="国内收货港">
<ElSelect
v-model="baseForm.domestic_port_id"
placeholder="请选择国内收货商"
@change="
(val) =>
(baseForm.domestic_port_snapshot =
(portOptions || []).find((x: any) => x.id === val)?.port_name || '')
"
>
<ElOption v-for="p in portOptions" :key="p.id" :label="p.port_name" :value="p.id" />
</ElSelect>
<ElInput v-model="baseForm.domestic_port_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="贸易条款">
<ElSelect
v-model="baseForm.trade_term_id"
placeholder="请选择"
@change="
(val) =>
(baseForm.trade_term_snapshot =
(trade_termsOptions || []).find((x: any) => x.id === val)?.item_label || '')
"
>
<ElOption
v-for="t in trade_termsOptions"
:key="t.id"
:label="t.item_label"
:value="t.id"
/>
</ElSelect>
<ElInput v-model="baseForm.trade_term_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="清关目的港">
<ElSelect
v-model="baseForm.clearance_port_id"
placeholder="请选择"
@change="
(val) =>
(baseForm.clearance_port_snapshot =
(portOptionsall || []).find((x: any) => x.id === val)?.port_name || '')
"
>
<ElOption
v-for="p in portOptionsall"
:key="p.id"
:label="p.port_name"
:value="p.id"
/>
</ElSelect>
<ElInput v-model="baseForm.clearance_port_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="12">
<ElCol :span="6">
<ElFormItem label="最迟到港时间">
<ElDatePicker
v-model="baseForm.latest_arrival_date"
type="date"
value-format="YYYY-MM-DD"
format="YYYY-MM-DD"
placeholder="请选择日期"
style="width: 100%"
/>
</ElFormItem>
</ElCol>
</ElRow>
</ElForm>
</div>
<div class="boxshadow">
<div class="form-title">
<span class="border"></span>
<span class="title">计划收款信息</span>
</div>
<div class="payment-section">
<div class="payment-items">
<div v-for="(payment, idx) in paymentItems" :key="idx" class="payment-item">
<ElForm :model="payment" label-width="55px" class="payment-form">
<ElRow :gutter="12">
<ElCol :span="4">
<ElFormItem label="汇款国">
<el-select v-model="payment.remit_country_id" filterable placeholder="请选择汇款国" @change="
(val) =>
(payment.remit_country_name_snapshot =
(countryOptions || []).find((x: any) => x.id === val)?.cn_addr || '')
">
<el-option
v-for="item in countryOptions"
:key="item.id"
:label="item.cn_addr"
:value="item.id"
/>
</el-select>
<ElInput v-model="payment.remit_country_name_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="日期">
<ElDatePicker
v-model="payment.remit_date"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="请选择日期"
style="width: 100%"
/>
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="币种">
<ElSelect v-model="payment.currency_code" placeholder="请选择币种" @change="
(val) => {
const found = (currencyOptions || []).find((x: any) => x.currency_code === val)
payment.currency_name_snapshot = found?.currency_name || ''
}
">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
/>
</ElSelect>
<ElInput v-model="payment.currency_name_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="账户">
<ElSelect v-model="payment.account_id" placeholder="请选择账户" @change="
(val) =>
(payment.account_name_snapshot =
(accountOptions || []).find((x: any) => x.id === val)?.account_number || '')
">
<ElOption
v-for="item in accountOptions"
:key="item.id"
:label="item.account_number"
:value="item.id"
/>
</ElSelect>
<ElInput v-model="payment.account_name_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="汇款人">
<ElInput v-model="payment.remitter_name" placeholder="请选择汇款人" />
</ElFormItem>
</ElCol>
<ElCol :span="4">
<ElFormItem label="金额">
<ElInput v-model.number="payment.amount" placeholder="请输入金额" />
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="12">
<ElCol :span="24" style="text-align: right;">
<ElButton type="danger" size="small" @click="removePaymentItem(idx)" :disabled="paymentItems.length === 1">删除</ElButton>
<ElButton type="primary" size="small" @click="addPaymentItem" v-if="idx === paymentItems.length - 1">添加收款信息</ElButton>
</ElCol>
</ElRow>
</ElForm>
</div>
</div>
</div>
</div>
<!-- 上传合同 -->
<div class="boxshadow">
<div class="form-title">
<span class="border"></span>
<span class="title">上传合同</span>
</div>
<ElUpload drag action="#" :auto-upload="false" :show-file-list="true" class="upload-box">
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">拖拽文件到此处,或点击上传</div>
</ElUpload>
</div>
<div class="form-card">
<!-- 底部信息 -->
<div class="submit-wrap">
<ElButton type="primary" size="large" class="submit-btn" @click="handleSubmit"
>提交</ElButton
>
</div>
</div>
<!-- 选择车型 弹框 -->
<ElDialog
v-model="vehicleDialog.visible"
title="选择车辆"
width="900px"
:close-on-click-modal="false"
top="40px"
>
<div
class="search-toolbar"
style="margin-bottom: 12px; display: flex; justify-content: flex-end; gap: 8px"
>
<el-input
v-model="vehicleDialog.search.keyword"
placeholder="请输入关键字"
clearable
style="width: 300px"
@keyup.enter="getVehicleList"
>
<template #suffix>
<el-icon class="clickable" @click="getVehicleList"><Search /></el-icon>
</template>
</el-input>
</div>
<ArtTable
:loading="vehicleDialog.loading"
:data="vehicleDialog.tableData"
:currentPage="vehicleDialog.pagination.currentPage"
:pageSize="vehicleDialog.pagination.pageSize"
:total="vehicleDialog.pagination.total"
@size-change="handleVehicleSizeChange"
@current-change="handleVehicleCurrentChange"
>
<template #default>
<ElTableColumn label="品牌" prop="brand_name" align="center" />
<ElTableColumn label="车系" prop="series_name" align="center" />
<ElTableColumn label="车型/配置" prop="model_name" min-width="160">
<template #default="scope">
<span class="primary">{{ scope.row.model_name }}</span>
</template>
</ElTableColumn>
<ElTableColumn label="年款" prop="model_year" width="80" align="center" />
<ElTableColumn label="指导价" prop="msrp" width="100" align="center" />
<ElTableColumn label="操作" width="100" align="center" fixed="right">
<template #default="scope">
<ElButton link type="primary" @click="chooseVehicle(scope.row)">选择</ElButton>
</template>
</ElTableColumn>
</template>
</ArtTable>
</ElDialog>
<!-- 选择客户 弹框 -->
<ElDialog
v-model="customerDialog.visible"
title="选择客户"
width="900px"
:close-on-click-modal="false"
top="40px"
>
<div
class="search-toolbar"
style="margin-bottom: 12px; display: flex; justify-content: flex-end; gap: 8px"
>
<el-input
v-model="customerDialog.search.keyword"
placeholder="请输入客户名称/电话"
clearable
style="width: 300px"
@keyup.enter="getCustomerList"
>
<template #suffix>
<el-icon class="clickable" @click="getCustomerList"><Search /></el-icon>
</template>
</el-input>
</div>
<ArtTable
:loading="customerDialog.loading"
:data="customerDialog.tableData"
:currentPage="customerDialog.pagination.currentPage"
:pageSize="customerDialog.pagination.pageSize"
:total="customerDialog.pagination.total"
@size-change="handleCustomerSizeChange"
@current-change="handleCustomerCurrentChange"
>
<template #default>
<ElTableColumn label="客户名称" prop="contacts" />
<ElTableColumn label="客户编码" prop="code" />
<ElTableColumn label="电话" prop="phone" />
<ElTableColumn label="公司" prop="company" />
<ElTableColumn label="操作" width="80" align="center" fixed="right">
<template #default="scope">
<ElButton link type="primary" @click="chooseCustomer(scope.row)">选择</ElButton>
</template>
</ElTableColumn>
</template>
</ArtTable>
</ElDialog>
</div>
</template>
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { Search } from '@element-plus/icons-vue'
import { CrmService } from '@/api/crmApi'
import { commonService } from '@/api/commonApi'
import { vehicleService } from '@/api/vehicleApi'
import { StringDecoder } from 'string_decoder'
import { useUserStore } from '@/store/modules/user'
import { watch } from 'vue'
const { getUserInfo } = useUserStore()
const channelOptions = ref<any>()
const countryOptions = ref<any>()
const modificationOptions = ref<any>()
const currencyOptions = ref<any>()
const accountOptions = ref<any>()
const customerOptions = ref<any>()
const portOptions = ref<any>()
const portOptionsall = ref<any>()
// 外观颜色
const wcolorOptions = ref<Array<any>>([])
// 内饰颜色
const ncolorOptions = ref<Array<any>>([])
//渠道
const getgetChannel = async () => {
const res = await CrmService.getChannel()
channelOptions.value = res || []
}
//客户下拉
const getcustomer = async () => {
const res = await commonService.getCustomerSelect()
customerOptions.value = res || []
}
//国家
const getarea = async () => {
const res = await CrmService.getCountry()
countryOptions.value = res || []
}
//改装项
const getmodification = async () => {
const res = await commonService.getModificationSelect()
modificationOptions.value = res || []
}
//颜色下拉列表
const loadColorOptions = async () => {
try {
const res = await commonService.getColorSelect({ type: 1 })
wcolorOptions.value = res
const response = await commonService.getColorSelect({ type: 2 })
ncolorOptions.value = response
} catch (error) {
console.error('获取颜色列表失败:', error)
ElMessage.error('获取颜色列表失败')
}
}
//账户
const loadAccountOptions = async () => {
try {
const res = await commonService.getAccountSelect()
accountOptions.value = res
} catch (error) {
console.error('获取账户列表失败:', error)
ElMessage.error('获取账户列表失败')
}
}
//币种
const loadCurrencyOptions = async () => {
try {
const res = await commonService.getCurrencySelect()
currencyOptions.value = res
} catch (error) {
console.error('获取币种列表失败:', error)
ElMessage.error('获取币种列表失败')
}
}
//港口
const loadPortOptions = async () => {
try {
const res = await commonService.getPortSelect({ scene: 'domestic' })
const resall = await commonService.getPortSelect({})
portOptions.value = res
portOptionsall.value = resall
} catch (error) {
console.error('获取港口列表失败:', error)
ElMessage.error('获取港口列表失败')
}
}
//字典下拉框
const transportOptions = ref<Array<any>>([])
const trade_termsOptions = ref<Array<any>>([])
const loadDictOptions = async () => {
const response = await commonService.getDictSelect({ scope: '2,15' })
transportOptions.value = response.transport
trade_termsOptions.value = response.trade_terms
}
onMounted(async () => {
getcustomer()
await loadCurrencyOptions()
getgetChannel()
getarea()
getmodification()
loadColorOptions()
loadAccountOptions()
loadPortOptions()
loadDictOptions()
// 设置默认汇率
baseForm.contract_exchange_rate = getCurrencyRate('USD')
})
const getCurrencyRate = (code: string): string => {
try {
const found = (currencyOptions?.value || []).find((c: any) => c.currency_code === code)
return found?.rate || found?.exchange_rate || ''
} catch (e) {
return ''
}
}
const baseForm = reactive({
pi_no: '',
biz_date: '',
clearance_country_id: '',
clearance_country_snapshot: '',
customer_source_id: '',
customer_source_snapshot: '',
customer_id: '',
customer_snapshot: '',
customer_country_id: '',
customer_country_snapshot: '',
declarant_name: '',
eta_ship_date: '',
shipping_method_id: '',
shipping_method_snapshot: '',
domestic_port_id: '',
domestic_port_snapshot: '',
trade_term_id: '',
trade_term_snapshot: '',
clearance_port_id: '',
clearance_port_snapshot: '',
latest_arrival_date: '',
contract_exchange_rate: '',
remark: '',
total_cif: undefined as number | undefined,
total_cif_currency: 'USD',
total_cif_currency_snapshot: '',
is_final: '0'
})
type ItemRow = {
sku_id: string
model_snapshot: string
color_interior_code: string
color_interior_snapshot: string
color_exterior_code: string
color_exterior_snapshot: string
unit_price: number | undefined
handling_fee: string
fob_transport_fee: number | undefined
port_misc_fee: string
retrofit_fee: string
total_price: number | undefined
official_price: number | undefined
discount_price: number | undefined
fob_fee: number | undefined
fob_fee_currency: string
fob_fee_currency_snapshot: string
helper_fee: number | undefined
helper_fee_currency: string
helper_fee_currency_snapshot: string
domestic_freight: number | undefined
domestic_freight_currency: string
domestic_freight_currency_snapshot: string
port_fee: number | undefined
port_fee_currency: string
port_fee_currency_snapshot: string
unit_price_currency: string
unit_price_currency_snapshot: string
total_price_currency: string
total_price_currency_snapshot: string
guide_price_currency: string
guide_price_currency_snapshot: string
discount: number | undefined
discount_currency: string
discount_currency_snapshot: string
contract_rate: number | undefined
profit_type: string
profit_type_snapshot: string
modify_ids: string[]
modify_list: Array<{ option_id: string; option_name_snapshot: string }>
modify_fee_currency: string
modify_fee_currency_snapshot: string
}
const newItem = (): ItemRow => ({
sku_id: '',
model_snapshot: '',
color_interior_code: '',
color_interior_snapshot: '',
color_exterior_code: '',
color_exterior_snapshot: '',
unit_price: undefined,
handling_fee: '',
fob_transport_fee: undefined,
port_misc_fee: '',
retrofit_fee: '',
total_price: undefined,
official_price: undefined,
discount_price: undefined,
fob_fee: undefined,
fob_fee_currency: 'USD',
fob_fee_currency_snapshot: '',
helper_fee: undefined,
helper_fee_currency: 'USD',
helper_fee_currency_snapshot: '',
domestic_freight: undefined,
domestic_freight_currency: 'USD',
domestic_freight_currency_snapshot: '',
port_fee: undefined,
port_fee_currency: 'USD',
port_fee_currency_snapshot: '',
unit_price_currency: 'USD',
unit_price_currency_snapshot: '',
total_price_currency: 'USD',
total_price_currency_snapshot: '',
guide_price_currency: 'USD',
guide_price_currency_snapshot: '',
discount: undefined,
discount_currency: 'USD',
discount_currency_snapshot: '',
contract_rate: 7.16,
profit_type: 'calc',
profit_type_snapshot: '',
modify_ids: [],
modify_list: [],
modify_fee_currency: 'USD',
modify_fee_currency_snapshot: ''
})
const items = ref<ItemRow[]>([newItem()])
const copyRow = (idx: number) => {
const copied = JSON.parse(JSON.stringify(items.value[idx])) as ItemRow
copied.uid = Math.random().toString(36).slice(2)
items.value.splice(idx + 1, 0, copied)
}
const addRowAfter = (idx: number) => {
items.value.splice(idx + 1, 0, newItem())
}
const removeRow = (idx: number) => {
items.value.splice(idx, 1)
}
// 监听币种变化,自动更新汇率
watch(
() => items.value[0].unit_price_currency,
(newCurrency) => {
if (newCurrency) {
baseForm.contract_exchange_rate = getCurrencyRate(newCurrency)
}
}
)
type PaymentItem = {
remit_country_id: string
remit_country_name_snapshot: string
remit_date: string
currency_code: string
currency_name_snapshot: string
account_id: string
account_name_snapshot: string
remitter_name: string
amount: number | undefined
}
const newPaymentItem = (): PaymentItem => ({
remit_country_id: '',
remit_country_name_snapshot: '',
remit_date: '',
currency_code: '',
currency_name_snapshot: '',
account_id: '',
account_name_snapshot: '',
remitter_name: '',
amount: undefined
})
const paymentItems = ref<PaymentItem[]>([newPaymentItem()])
const addPaymentItem = () => {
paymentItems.value.push(newPaymentItem())
}
const removePaymentItem = (idx: number) => {
if (paymentItems.value.length > 1) {
paymentItems.value.splice(idx, 1)
}
}
const wrapMoney = (amount: any, currency: string, remark: string) => ({
currency: currency || '',
amount: amount === undefined || amount === null ? '' : String(amount),
rate: getCurrencyRate(currency),
remark
})
const handleSubmit = async () => {
const mappedItems = items.value.map((it) => ({
sku_id: it.sku_id,
model_snapshot: it.model_snapshot,
color_interior_code: it.color_interior_code,
color_interior_snapshot: it.color_interior_snapshot,
color_exterior_code: it.color_exterior_code,
color_exterior_snapshot: it.color_exterior_snapshot,
unit_price: wrapMoney(it.unit_price, (it as any).unit_price_currency, '单价'),
handling_fee: wrapMoney(it.handling_fee, (it as any).helper_fee_currency, '手续费'),
fob_transport_fee: wrapMoney(
it.fob_transport_fee ?? (it as any).fob_fee,
(it as any).fob_fee_currency,
'FOB运输费'
),
port_misc_fee: wrapMoney(
it.port_misc_fee ?? (it as any).port_fee,
(it as any).port_fee_currency,
'港杂费'
),
retrofit_fee: wrapMoney((it as any).retrofit_fee, (it as any).modify_fee_currency, '单价'),
modify_list: it.modify_list,
total_price: wrapMoney(it.total_price, (it as any).total_price_currency, '总价'),
official_price: wrapMoney(
(it as any).official_price ?? (it as any).guide_price,
(it as any).guide_price_currency,
'官方指导价'
),
discount_price: wrapMoney(
(it as any).discount_price ?? (it as any).discount,
(it as any).discount_currency,
'优惠额'
)
}))
const payload = {
...baseForm,
veh_list: mappedItems,
account_list: paymentItems.value
}
console.log('submit payload', payload)
// const { message } = await CrmService.addStock(payload)
// ElMessage.success(message)
}
// 选择客户弹框逻辑
const customerDialog = reactive({
visible: false,
search: { keyword: '' },
loading: false,
tableData: [] as any[],
pagination: { currentPage: 1, pageSize: 10, total: 0 }
})
const openCustomerDialog = () => {
customerDialog.visible = true
customerDialog.pagination.currentPage = 1
getCustomerList()
}
const getCustomerList = async () => {
customerDialog.loading = true
try {
const { currentPage, pageSize } = customerDialog.pagination
const params = { current: currentPage, size: pageSize, keyword: customerDialog.search.keyword }
const { data, current, size, total } = await CrmService.getcustomerList(params as any)
customerDialog.tableData = data || []
Object.assign(customerDialog.pagination, { currentPage: current, pageSize: size, total })
} catch (e) {
} finally {
customerDialog.loading = false
}
}
const handleCustomerSizeChange = (size: number) => {
customerDialog.pagination.pageSize = size
getCustomerList()
}
const handleCustomerCurrentChange = (page: number) => {
customerDialog.pagination.currentPage = page
getCustomerList()
}
const chooseCustomer = (row: any) => {
baseForm.customer_id = row.id || ''
baseForm.customer_snapshot = row.contacts || row.name || ''
customerDialog.visible = false
}
// 选择车型弹框逻辑
const vehicleDialog = reactive({
visible: false,
targetIndex: -1,
search: { keyword: '' },
loading: false,
tableData: [] as any[],
pagination: { currentPage: 1, pageSize: 10, total: 0 }
})
const openVehicleDialog = (index: number) => {
vehicleDialog.targetIndex = index
vehicleDialog.visible = true
vehicleDialog.pagination.currentPage = 1
getVehicleList()
}
const getVehicleList = async () => {
vehicleDialog.loading = true
try {
const { currentPage, pageSize } = vehicleDialog.pagination
const params = { current: currentPage, size: pageSize, keyword: vehicleDialog.search.keyword }
const { records, current, size, total } = await vehicleService.getVehicleList(params)
vehicleDialog.tableData = records || []
Object.assign(vehicleDialog.pagination, { currentPage: current, pageSize: size, total })
} catch (e) {
ElMessage.error('获取车辆列表失败')
} finally {
vehicleDialog.loading = false
}
}
const handleVehicleSizeChange = (size: number) => {
vehicleDialog.pagination.pageSize = size
getVehicleList()
}
const handleVehicleCurrentChange = (page: number) => {
vehicleDialog.pagination.currentPage = page
getVehicleList()
}
const chooseVehicle = (row: any) => {
const idx = vehicleDialog.targetIndex
if (idx >= 0 && idx < items.value.length) {
const target = items.value[idx]
target.sku_id = row.id || ''
target.model_snapshot = row.model_name || row.name || ''
// 回显颜色与指导价
target.color_exterior_code = row.color_exterior_code || ''
target.color_exterior_snapshot = row.color_exterior_text || ''
target.color_interior_code = row.color_interior_code || ''
target.color_interior_snapshot = row.color_interior_text || ''
target.official_price = row.msrp ?? target.official_price
if (row.currency) {
target.official_price_currency = row.currency
}
// 可按需带出更多字段回显
}
vehicleDialog.visible = false
}
</script>
<style scoped lang="scss">
:deep(.el-input-group--append .el-input-group__append .el-select .el-select__wrapper) {
padding: 4px;
}
:deep(.el-select__selected-item span) {
font-size: 12px;
}
.form-title {
font-weight: bold;
color: #222;
margin-bottom: 15px;
}
.form-title .title {
margin-left: 6px;
}
.stocking-add-page {
// background: var(--art-main-bg-color);
min-height: 100vh;
}
.header {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px 20px;
margin-bottom: 12px;
.title {
font-size: 18px;
font-weight: 600;
margin-bottom: 15px;
}
.subtitle {
color: var(--el-text-color-secondary);
}
}
.items-wrap {
margin-top: 6px;
}
.item-row {
padding: 8px 0;
}
.row-actions {
display: flex;
align-items: center;
gap: 8px;
justify-content: flex-end;
}
.row-actions span {
font-size: 12px;
cursor: pointer;
}
.row-actions .primary {
color: var(--el-color-primary);
cursor: pointer;
}
.row-actions .danger {
color: var(--el-color-danger);
cursor: pointer;
}
.submit-wrap {
display: flex;
justify-content: center;
padding: 24px 0 8px;
}
.submit-btn {
width: 220px;
height: 44px;
font-size: 16px;
}
.payment-item {
margin-bottom: 12px;
}
.upload-box { width: 200px; }
</style>