判断是否有签名换到长链接推送 然后添加 报关价 预估退税计算

This commit is contained in:
浅念
2025-10-14 14:43:09 +08:00
parent 153bb37d10
commit 16abb6364c
10 changed files with 829 additions and 236 deletions
-29
View File
@@ -196,35 +196,6 @@
if (userStore.isLogin) {
try {
const data = await UserService.getUserInfo()
const { systemsid } = useUserStore()
// 排除移动端电子签名页,不做签名校验
const currentPath = router.currentRoute.value?.path || ''
const isOnMobileSignature = currentPath.startsWith('/auth/signature/mobile')
if (!isOnMobileSignature) {
if (data.user.sign_img == null || data.user.sign_img == '') {
ElMessageBox.alert('请前往个人中心完成签名操作!', '提醒', {
confirmButtonText: '确定',
callback: () => {
if (systemsid == '1') {
router.push('/admin/user/user_info')
} else {
router.push('/system/user-center')
}
}
})
} else if (data.user.email == null || data.user.email == '') {
ElMessageBox.alert('邮箱没有填写!请前往个人中心补充邮箱!', '提醒', {
confirmButtonText: '确定',
callback: () => {
if (systemsid == '1') {
router.push('/admin/user/user_info')
} else {
router.push('/system/user-center')
}
}
})
}
}
userStore.setUserInfo(data)
} catch (error) {
console.error('获取用户信息失败', error)
+7
View File
@@ -132,6 +132,13 @@ export class commonService {
url: '/common/preset/users'
})
}
//用户下拉框
static getUserSelectparams(params: any) {
return request.get<any>({
url: '/common/preset/users',
params
})
}
//签名 编辑
static signatureEdit(params: any) {
return request.post<any>({
@@ -206,6 +206,14 @@
'—'
}}</template>
</ElTableColumn>
<ElTableColumn label="报关价" min-width="120" align="center">
<template #default="scope">{{
scope.row.clearance_price?.currency_info ||
scope.row.clearance_price?.amount ||
scope.row.clearance_price ||
'—'
}}</template>
</ElTableColumn>
<ElTableColumn fixed="right" label="利润" min-width="120" align="center">
<template #default="scope">{{
scope.row.profit?.currency_info ||
+86 -23
View File
@@ -1,4 +1,4 @@
import { ref, reactive, watch, onMounted } from 'vue'
import { ref, reactive, watch, onMounted, nextTick } from 'vue'
import { componentSizeMap, ElMessage } from 'element-plus'
import { CrmService } from '@/api/crmApi'
import { commonService } from '@/api/commonApi'
@@ -75,6 +75,9 @@ export interface ItemRow {
tax_refund: string
tax_refund_currency: string
tax_refund_currency_snapshot: string
clearance_price: number | undefined
clearance_price_currency: string
clearance_price_currency_snapshot: string
retrofit_fee: string
total_price: number | undefined
official_price: number | undefined
@@ -133,6 +136,8 @@ export interface DialogState {
export function useStockingForm(isFinal = false, stockingId?: string | number) {
const { uploadHeaders } = useUploadHeaders()
const actionImageUplode = `${import.meta.env.VITE_API_URL}/ticket/upload?scene=stock_orders`
// 回显填充抑制标记:为 true 时不触发自动计算覆盖接口值
const isPopulating = ref(false)
// 选项数据
const channelOptions = ref<any>()
@@ -218,6 +223,9 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
tax_refund: '',
tax_refund_currency: 'CNY',
tax_refund_currency_snapshot: '人民币',
clearance_price: undefined,
clearance_price_currency: 'CNY',
clearance_price_currency_snapshot: '人民币',
retrofit_fee: '',
total_price: undefined,
official_price: undefined,
@@ -484,16 +492,9 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
)
return (
unit -
(retrofit +
fob +
listing +
reduction +
handling +
port +
ocean +
commission +
purchaseTax) +
taxRefund
(retrofit + fob + listing + handling + port + ocean + commission + purchaseTax) +
taxRefund +
reduction
)
}
@@ -510,11 +511,42 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
)
return (
unit -
(retrofit + fob + guide + discount + handling + port + ocean + commission + purchaseTax) +
taxRefund
(retrofit + fob + guide + handling + port + ocean + commission + purchaseTax) +
taxRefund +
discount
)
}
const calcClearanceFee = (it: any): number => {
const targetCurrency = baseForm.settlement_currency || 'USD'
const unit = convertCurrency(it.unit_price, it.unit_price_currency, targetCurrency)
const commission = convertCurrency(
it.commission ?? (it as any).commission,
(it as any).commission_currency,
targetCurrency
)
return unit - commission
}
const calcTaxRefund = (it: any): number => {
const mileageVal = Number(it.mileage ?? 0)
if (mileageVal > 0) return 0
const targetCurrency = baseForm.settlement_currency || 'USD'
const official = convertCurrency(
it.official_price ?? (it as any).guide_price,
(it as any).guide_price_currency,
targetCurrency
)
const discount = convertCurrency(
it.discount_price ?? (it as any).discount,
(it as any).discount_currency,
targetCurrency
)
const base = official - discount
const refund = base * 0.115
return refund < 0 ? 0 : refund
}
// 合同文件相关方法
const isImageFile = (file: { name: string; url: string; file_name: string }) => {
return /\.(jpg|jpeg|png|gif)$/i.test(file.name) || file.file_name.startsWith('image/')
@@ -675,6 +707,7 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
// 数据回显方法
const populateFromDetail = (res: any) => {
if (!res) return
isPopulating.value = true
// 基础信息
baseForm.pick_up_date = res.pick_up_date || ''
baseForm.collect_all_date = res.collect_all_date || ''
@@ -703,7 +736,7 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
baseForm.remark = res.remark || ''
baseForm.settlement_currency = res.settlement_currency || 'CNY'
// 合计与汇率
baseForm.total_cif = res.cif_total_amount ? Number(res.cif_total_amount) : undefined
baseForm.total_cif = res.cif_total_amount.amount ? Number(res.cif_total_amount.amount) : undefined
baseForm.total_cif_currency = res.settlement_currency || baseForm.total_cif_currency
baseForm.contract_exchange_rate =
res.contract_exchange_rate || getCurrencyRate(baseForm.total_cif_currency)
@@ -739,9 +772,6 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
purchase_tax: it.purchase_tax?.amount ?? '',
purchase_tax_currency: it.purchase_tax?.currency || 'CNY',
purchase_tax_currency_snapshot: '',
tax_refund: it.tax_refund?.amount ?? '',
tax_refund_currency: it.tax_refund?.currency || 'CNY',
tax_refund_currency_snapshot: '',
retrofit_fee: it.retrofit_fee?.amount ?? '',
total_price: it.total_price?.amount ? Number(it.total_price.amount) : undefined,
official_price: it.official_price?.amount ? Number(it.official_price.amount) : undefined,
@@ -768,14 +798,20 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
discount_currency: it.discount_price?.currency || 'CNY',
discount_currency_snapshot: '',
contract_rate: baseForm.contract_exchange_rate ? Number(baseForm.contract_exchange_rate) : undefined,
profit: undefined,
profit: it.profit?.amount ? Number(it.profit.amount) : undefined,
profit_type_snapshot: '',
clearance_price: it.clearance_price?.amount ? Number(it.clearance_price.amount) : undefined,
clearance_price_currency: it.clearance_price?.currency || 'CNY',
clearance_price_currency_snapshot: '',
modify_ids: Array.isArray(it.modify_list) ? it.modify_list.map((m: any) => Number(m.option_id)) : [],
modify_list: Array.isArray(it.modify_list)
? it.modify_list.map((m: any) => ({ option_id: String(m.option_id), option_name_snapshot: m.option_name_snapshot }))
: [],
modify_fee_currency: it.retrofit_fee?.currency || 'CNY',
modify_fee_currency_snapshot: ''
modify_fee_currency_snapshot: '',
tax_refund: it.tax_refund?.amount ?? '',
tax_refund_currency: it.tax_refund?.currency || 'CNY',
tax_refund_currency_snapshot: ''
}))
// 计划收款
const pays = Array.isArray(res.account_list) ? res.account_list : []
@@ -798,6 +834,8 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
file_name: res.contract
}
}
// 等待本轮变更完成后,再恢复自动计算
nextTick(() => { isPopulating.value = false })
}
// 提交方法
@@ -836,7 +874,8 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
ocean_freight: wrapMoney(it.ocean_freight, (it as any).ocean_freight_currency, '海运费'),
commission: wrapMoney(it.commission, (it as any).commission_currency, '佣金'),
purchase_tax: wrapMoney(it.purchase_tax, (it as any).purchase_tax_currency, '购置税'),
tax_refund: wrapMoney(it.tax_refund, (it as any).tax_refund_currency, '退税'),
// tax_refund: wrapMoney(it.tax_refund, (it as any).tax_refund_currency, '退税'),
tax_refund: wrapMoney(it.tax_refund, baseForm.settlement_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, '总价'),
@@ -851,8 +890,14 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
(it as any).discount_currency,
'优惠额'
),
profit: wrapMoney(it.profit, baseForm.settlement_currency, '利润'),
listing_price: wrapMoney(it.listing_price, (it as any).listing_price_currency, '挂牌价'),
reduction_price: wrapMoney(it.reduction_price, (it as any).reduction_price_currency, '二手减价')
reduction_price: wrapMoney(
it.reduction_price,
(it as any).reduction_price_currency,
'二手减价'
),
clearance_price: wrapMoney(it.clearance_price, baseForm.settlement_currency, '报关价')
}))
// 从提交参数中移除 settlement_currency
@@ -867,6 +912,7 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
account_list: paymentItems.value,
approval_status: type
}
console.log(payload)
try {
if (edit) {
@@ -887,7 +933,7 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
}
}, 1000)
} catch (e) {
ElMessage.error('保存失败')
// ElMessage.error('保存失败')
}
}
@@ -895,6 +941,7 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
watch(
() => baseForm.settlement_currency,
(newCurrency) => {
if (isPopulating.value) return
if (newCurrency) {
baseForm.contract_exchange_rate = getCurrencyRate(newCurrency)
if (typeof validateContractRate === 'function') {
@@ -904,6 +951,13 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
(items.value || []).forEach((it: any, index: number) => {
const profit = calcProfit(it)
if (items.value[index]) items.value[index].profit = isNaN(profit) ? 0 : Number(profit.toFixed(2))
const clearance = calcClearanceFee(it)
if (items.value[index]) items.value[index].clearance_price = isNaN(clearance) ? 0 : Number(clearance.toFixed(2))
const refund = calcTaxRefund(it)
if (items.value[index]) {
items.value[index].tax_refund = isNaN(refund) ? 0 : Number(refund.toFixed(2)) as any
;(items.value[index] as any).tax_refund_currency = baseForm.settlement_currency || 'USD'
}
})
}
}
@@ -923,11 +977,18 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
watch(
items,
(val) => {
if (isPopulating.value) return
val.forEach((it: any, index: number) => {
const profit = calcProfit(it)
if (items.value[index]) items.value[index].profit = isNaN(profit) ? 0 : Number(profit.toFixed(2))
const clearance = calcClearanceFee(it)
if (items.value[index]) items.value[index].clearance_price = isNaN(clearance) ? 0 : Number(clearance.toFixed(2))
const refund = calcTaxRefund(it)
if (items.value[index]) {
items.value[index].tax_refund = isNaN(refund) ? 0 : Number(refund.toFixed(2)) as any
;(items.value[index] as any).tax_refund_currency = baseForm.settlement_currency || 'USD'
}
})
// 合计到岸价 = 所有单价相加
const sum = (val || []).reduce((acc: number, cur: any) => {
const n = cur?.unit_price === undefined || cur?.unit_price === null || cur?.unit_price === '' ? 0 : Number(cur.unit_price)
@@ -1004,6 +1065,8 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
validateContractRate,
wrapMoney,
calcProfit,
calcClearanceFee,
calcTaxRefund,
// 合同文件方法
isImageFile,
+137 -3
View File
@@ -1,6 +1,8 @@
import mittBus from './mittBus'
import { useUserStore } from '@/store/modules/user'
import { ElNotification } from 'element-plus'
import { ElNotification, ElMessageBox } from 'element-plus'
import { useRouter } from 'vue-router'
import { ref } from 'vue'
type JsonValue = Record<string, any> | any[]
@@ -18,6 +20,7 @@ let isConnecting = false
let lastInitToken: string | null = null
let lastInitAt = 0
const INIT_DEBOUNCE_MS = 1200
let isAlertShowing = false
// 生成唯一ID
const generateTraceId = (): string => {
@@ -94,12 +97,143 @@ const handleMessage = (event: MessageEvent) => {
let data: any = event.data
try {
data = JSON.parse(event.data)
} catch (error) {
} catch {
// console.warn('WebSocket消息解析失败:', error, '原始数据:', event.data)
// 对于无法解析的消息,仍然尝试处理原始数据
data = { event: 'unknown', data: event.data }
}
console.log('WebSocket message:', data)
// console.log('WebSocket message:', data)
// 判断系统初始化检查
if (data.event == 'system.init.check') {
const { systemsid } = useUserStore()
// 检查页面是否已加载完成
if (document.readyState !== 'complete') {
console.warn('页面未完全加载,延迟处理系统检查消息')
// 延迟处理,等待页面加载完成
setTimeout(() => {
handleMessage(event)
}, 1000)
return
}
// 检查 router 是否可用
let router: any = null
let currentPath = ''
let isOnMobileSignature = false
let isOnUserInfo = false
let isOnUserCenter = false
try {
router = useRouter()
// 检查 router.currentRoute 是否可用
if (router.currentRoute) {
currentPath = router.currentRoute.value?.path || ''
isOnMobileSignature = currentPath.startsWith('/auth/signature/mobile')
isOnUserInfo = currentPath.startsWith('/system/user-center')
isOnUserCenter = currentPath.startsWith('/admin/user/user_info')
} else {
// Router currentRoute 未初始化,使用 window.location 作为备选方案
currentPath = window.location.pathname || ''
isOnMobileSignature = currentPath.startsWith('/auth/signature/mobile')
isOnUserInfo = currentPath.startsWith('/system/user-center')
isOnUserCenter = currentPath.startsWith('/admin/user/user_info')
// console.warn('Router currentRoute 未初始化,使用 window.location 作为备选方案')
}
} catch (error) {
// Router 完全未初始化,使用 window.location 作为备选方案
currentPath = window.location.pathname || ''
isOnMobileSignature = currentPath.startsWith('/auth/signature/mobile')
isOnUserInfo = currentPath.startsWith('/system/user-center')
isOnUserCenter = currentPath.startsWith('/admin/user/user_info')
// console.warn('Router 未初始化,使用 window.location 作为备选方案:', error)
}
// 排除移动端电子签名页,不弹出提示框
if (isOnMobileSignature || isOnUserInfo || isOnUserCenter) {
return
}
// 接收到消息就弹出提示框(排除移动端电子签名页)
if (data.data) {
const { is_sign } = data.data
const msgs = ref('尚未设置【签名】,请前往个人中心完成操作!')
// 根据检查结果确定提示信息
let alertMessage = ''
let shouldShowAlert = false
// 构建状态标识
// const statusKey = `${is_report_to}-${is_office_clerk}-${is_sign}`
// switch (statusKey) {
// case 'false-false-false':
// alertMessage = msgs.value
// shouldShowAlert = true
// break
// case 'true-false-true':
// alertMessage = '尚未操作【绑定直属上级、签名】,请前往个人中心完成操作!'
// shouldShowAlert = true
// break
// case 'true-false-false':
// alertMessage = '尚未操作【绑定内勤、签名】】,请前往个人中心完成操作!'
// shouldShowAlert = true
// break
// case 'true-true-false':
// alertMessage = '尚未操作【签名】,请前往个人中心完成操作!'
// shouldShowAlert = true
// break
// case 'false-true-true':
// alertMessage = '尚未操作【直属上级】,请前往个人中心完成操作!'
// shouldShowAlert = true
// break
// case 'false-true-false':
// alertMessage = '尚未操作【直属上级,签名】,请前往个人中心完成操作!'
// shouldShowAlert = true
// break
// case 'false-false-true':
// alertMessage = '尚未操作【直属上级,内勤】,请前往个人中心完成操作!'
// shouldShowAlert = true
// break
// default:
// // 其他情况不弹出提示
// shouldShowAlert = false
// break
// }
if (is_sign == false) {
alertMessage = msgs.value
shouldShowAlert = true
}
// 只有在需要显示提示且当前没有弹出框的情况下才弹出提示框
if (shouldShowAlert && !isAlertShowing) {
isAlertShowing = true
ElMessageBox.alert(alertMessage, '提醒', {
confirmButtonText: '确定',
callback: () => {
isAlertShowing = false
// 如果 router 可用,使用 router 跳转
if (router && router.push) {
if (systemsid == '1') {
router.push('/admin/user/user_info')
} else {
router.push('/system/user-center')
}
} else {
// Router 不可用,使用 window.location 跳转
const targetPath = systemsid == '1' ? '/admin/user/user_info' : '/system/user-center'
window.location.href = targetPath
}
}
}).catch(() => {
// 如果弹出框被意外关闭,重置状态
isAlertShowing = false
})
} else if (shouldShowAlert && isAlertShowing) {
console.log('当前已有弹出框显示,跳过新的提示框')
}
}
}
// 处理通知消息
if (data.event == 'notify.receive') {
+28 -2
View File
@@ -62,7 +62,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="客户来源" label-width="114px">
<ElFormItem label="客户来源" label-width="124px">
<el-tooltip class="box-item" content="如需修改客户来源,请先编辑修改客户资料">
<el-select
v-model="baseForm.customer_source_id"
@@ -388,7 +388,7 @@
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="预估退税额" label-width="85px">
<ElInput v-model="item.tax_refund" placeholder="请输入预估退税额">
<template #suffix>
<!-- <template #suffix>
<ElSelect v-model="item.tax_refund_currency" style="width: 74px">
<ElOption
v-for="c in currencyOptions"
@@ -397,6 +397,14 @@
:value="c.currency_code"
/>
</ElSelect>
</template> -->
<template #suffix>
<span style="font-size: 11px">
{{
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)?.currency_name) ||
baseForm.settlement_currency
}}
</span>
</template>
</ElInput>
<ElInput v-model="item.tax_refund_currency_snapshot" type="hidden" />
@@ -457,6 +465,24 @@
</ElInput>
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="报关价" label-width="85px">
<ElInput
v-model="item.clearance_price"
placeholder="正在计算报关价"
:class="Number(item.clearance_price) < 0 ? 'customs-fee-negative' : ''"
>
<template #suffix>
<span style="font-size: 11px">
{{
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)?.currency_name) ||
baseForm.settlement_currency
}}
</span>
</template>
</ElInput>
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="24" :md="24" :lg="24" :xl="24">
+122 -24
View File
@@ -9,7 +9,7 @@
<span class="border"></span>
<span class="title">基础信息</span>
</div>
<ElForm :model="baseForm" class="base-form" label-position="right">
<ElForm :model="baseForm" :rules="baseFormRules" ref="baseFormRef" class="base-form" label-position="right">
<ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="阿里订单号/PI号" label-width="114px">
@@ -17,7 +17,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="日期" label-width="114px">
<ElFormItem label="日期" label-width="114px" prop="biz_date" required>
<ElDatePicker
v-model="baseForm.biz_date"
type="date"
@@ -29,7 +29,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="清关目的国" label-width="114px">
<ElFormItem label="清关目的国" label-width="114px" prop="clearance_country_id" required>
<el-select
v-model="baseForm.clearance_country_id"
filterable
@@ -51,7 +51,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="客户名称" label-width="114px">
<ElFormItem label="客户名称" label-width="114px" prop="customer_id" required>
<ElInput
v-model="baseForm.customer_snapshot"
placeholder="请选择客户"
@@ -124,11 +124,11 @@
<span class="border"></span>
<span class="title">订单详情</span>
</div>
<ElForm class="items-wrap" label-position="right">
<ElForm :model="formModel" :rules="itemRules" ref="itemsFormRef" class="items-wrap" label-position="right">
<div class="item-row form-box" v-for="(item, idx) in items" :key="idx">
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="车型" label-width="85px">
<ElFormItem label="车型" label-width="85px" :prop="'items.' + idx + '.sku_id'" required>
<ElInput
v-model="item.model_snapshot"
placeholder="请选择车型"
@@ -144,7 +144,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="颜色/外饰" label-width="85px">
<ElFormItem label="颜色/外饰" label-width="85px" :prop="'items.' + idx + '.color_exterior_snapshot'" required>
<el-select
v-model="item.color_exterior_snapshot"
filterable
@@ -167,7 +167,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="颜色/内饰" label-width="85px">
<ElFormItem label="颜色/内饰" label-width="85px" :prop="'items.' + idx + '.color_interior_snapshot'" required>
<el-select
v-model="item.color_interior_snapshot"
filterable
@@ -220,7 +220,7 @@
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="4" v-if="(item.mileage ?? 0) <= 0">
<ElFormItem label="官方指导价" label-width="85px">
<ElFormItem label="官方指导价" label-width="85px" :prop="'items.' + idx + '.official_price'" required>
<ElInput v-model="item.official_price" placeholder="请输入官方指导价">
<template #suffix>
<ElSelect v-model="item.guide_price_currency" style="width: 64px;border: none;">
@@ -237,7 +237,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4" v-else>
<ElFormItem label="二手挂牌价" label-width="85px">
<ElFormItem label="二手挂牌价" label-width="85px" :prop="'items.' + idx + '.listing_price'" required>
<ElInput v-model="item.listing_price" placeholder="请输入二手挂牌价">
<template #suffix>
<ElSelect v-model="item.listing_price_currency" style="width: 64px">
@@ -411,7 +411,7 @@
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="预估退税额" label-width="85px">
<ElInput v-model="item.tax_refund" placeholder="请输入预估退税额">
<template #suffix>
<!-- <template #suffix>
<ElSelect v-model="item.tax_refund_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
@@ -420,6 +420,14 @@
:value="c.currency_code"
/>
</ElSelect>
</template> -->
<template #suffix>
<span style="font-size: 11px">
{{
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)?.currency_name) ||
baseForm.settlement_currency
}}
</span>
</template>
</ElInput>
<ElInput v-model="item.tax_refund_currency_snapshot" type="hidden" />
@@ -428,7 +436,7 @@
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="成交价" label-width="85px">
<ElFormItem label="成交价" label-width="85px" :prop="'items.' + idx + '.unit_price'" required>
<ElInput v-model="item.unit_price" placeholder="请输入成交价">
<template #suffix>
<ElSelect v-model="item.unit_price_currency" style="width: 64px">
@@ -480,6 +488,24 @@
</ElInput>
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="报关价" label-width="85px">
<ElInput
v-model="item.clearance_price"
placeholder="正在计算报关价"
:class="Number(item.clearance_price) < 0 ? 'profit-negative' : ''"
>
<template #suffix>
<span style="font-size: 11px">
{{
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)?.currency_name) ||
baseForm.settlement_currency
}}
</span>
</template>
</ElInput>
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="车架号" label-width="85px">
<ElInput v-model="item.vin" placeholder="请输入车架号"></ElInput>
@@ -537,15 +563,15 @@
<span class="border"></span>
<span class="title">运输详情</span>
</div>
<ElForm :model="baseForm" class="foot-form">
<ElForm :model="baseForm" :rules="transportFormRules" ref="transportFormRef" class="foot-form">
<ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="清关人" label-width="98px">
<ElFormItem label="清关人" label-width="98px" prop="declarant_name" required>
<ElInput v-model="baseForm.declarant_name" placeholder="请输入清关人" />
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="全款收齐日" label-width="98px">
<ElFormItem label="全款收齐日" label-width="98px" prop="collect_all_date" required>
<ElDatePicker
v-model="baseForm.collect_all_date"
value-format="YYYY-MM-DD"
@@ -557,7 +583,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="国内收货港" label-width="98px">
<ElFormItem label="国内收货港" label-width="98px" prop="domestic_port_id" required>
<ElSelect
v-model="baseForm.domestic_port_id"
placeholder="请选择国内收货商"
@@ -578,7 +604,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="运输方式" label-width="98px">
<ElFormItem label="运输方式" label-width="98px" prop="shipping_method_id" required>
<ElSelect
v-model="baseForm.shipping_method_id"
placeholder="请选择运输方式"
@@ -600,7 +626,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="贸易条款" label-width="98px">
<ElFormItem label="贸易条款" label-width="98px" prop="trade_term_id" required>
<ElSelect
v-model="baseForm.trade_term_id"
placeholder="请选择"
@@ -621,7 +647,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="清关目的港" label-width="98px">
<ElFormItem label="清关目的港" label-width="98px" prop="clearance_port_id" required>
<ElSelect
v-model="baseForm.clearance_port_id"
placeholder="请选择"
@@ -642,7 +668,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="提车日期" label-width="98px">
<ElFormItem label="提车日期" label-width="98px" prop="pick_up_date" required>
<ElDatePicker
v-model="baseForm.pick_up_date"
type="date"
@@ -664,7 +690,7 @@
<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">
<ElForm :model="payment" :rules="paymentFormRules" :ref="(el) => setPaymentFormRef(el, idx)" label-width="55px" class="payment-form">
<ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="汇款人" label-width="55px">
@@ -807,14 +833,14 @@
plain
size="large"
class="submit-btn"
@click="handleSubmit(0, undefined, '1')"
@click="handleSubmitWithValidation(0)"
>保存</ElButton
>
<ElButton
type="primary"
size="large"
class="submit-btn"
@click="handleSubmit(1, undefined, '1')"
@click="handleSubmitWithValidation(1)"
>提交</ElButton
>
</div>
@@ -930,13 +956,70 @@
import { CrmService } from '@/api/crmApi'
import { useUserStore } from '@/store/modules/user'
import { useStockingForm } from '@/composables/useStockingForm'
import { onMounted } from 'vue'
import { onMounted, ref, computed } from 'vue'
defineOptions({ name: 'CrmStockingFinalAdd' }) // 定义组件名称,用于 KeepAlive 缓存控制
const route = useRoute()
const stocking_id = route.query.id
const { getUserInfo } = useUserStore()
// 表单引用
const baseFormRef = ref()
const itemsFormRef = ref()
const transportFormRef = ref()
const paymentFormRefs = ref<any[]>([])
const setPaymentFormRef = (el: any, idx: number) => {
if (el) paymentFormRefs.value[idx] = el
}
// 表单模型
const formModel = computed(() => ({ items: items.value }))
// 基础表单校验
const baseFormRules = {
biz_date: [{ required: true, message: '请选择日期', trigger: 'change' }],
clearance_country_id: [{ required: true, message: '请选择清关目的国', trigger: 'change' }],
customer_id: [{ required: true, message: '请选择客户', trigger: 'change' }]
}
// 明细动态校验
const itemRules = computed(() => {
const rules: any = {}
items.value.forEach((_, idx) => {
rules[`items.${idx}.sku_id`] = [{ required: true, message: '请选择车型', trigger: 'change' }]
rules[`items.${idx}.color_exterior_snapshot`] = [
{ required: true, message: '请选择颜色/外饰', trigger: 'change' }
]
rules[`items.${idx}.color_interior_snapshot`] = [
{ required: true, message: '请选择颜色/内饰', trigger: 'change' }
]
rules[`items.${idx}.official_price`] = [
{ required: true, message: '请输入官方指导价', trigger: 'blur' }
]
rules[`items.${idx}.listing_price`] = [
{ required: true, message: '请输入二手挂牌价', trigger: 'blur' }
]
rules[`items.${idx}.unit_price`] = [
{ required: true, message: '请输入成交价', trigger: 'blur' }
]
})
return rules
})
// 运输详情校验
const transportFormRules = {
declarant_name: [{ required: true, message: '请输入清关人', trigger: 'blur' }],
collect_all_date: [{ required: true, message: '请选择全款收齐日', trigger: 'change' }],
domestic_port_id: [{ required: true, message: '请选择国内收货港', trigger: 'change' }],
shipping_method_id: [{ required: true, message: '请选择运输方式', trigger: 'change' }],
trade_term_id: [{ required: true, message: '请选择贸易条款', trigger: 'change' }],
clearance_port_id: [{ required: true, message: '请选择清关目的港', trigger: 'change' }],
pick_up_date: [{ required: true, message: '请选择提车日期', trigger: 'change' }]
}
// 收款信息校验(最终页为回显,不强校验;保留以便需要时启用)
const paymentFormRules = {
remitter_name: [{ required: true, message: '请输入汇款人', trigger: 'blur' }],
remit_country_id: [{ required: true, message: '请选择汇款国', trigger: 'change' }],
remit_date: [{ required: true, message: '请选择汇款日期', trigger: 'change' }],
account_id: [{ required: true, message: '请选择账户', trigger: 'change' }],
amount: [{ required: true, message: '请输入金额', trigger: 'blur' }]
}
// 使用公共的备货单表单逻辑
const {
// 数据
@@ -1005,6 +1088,21 @@
await getdetilfn()
}
})
// 提交前统一校验
const handleSubmitWithValidation = async (type: number) => {
try {
await baseFormRef.value?.validate()
await itemsFormRef.value?.validate()
await transportFormRef.value?.validate()
for (let i = 0; i < paymentItems.value.length; i++) {
const refForm = paymentFormRefs.value[i]
if (refForm) await refForm.validate()
}
await handleSubmit(type, undefined, '1')
} catch (e) {
// 校验失败不提交
}
}
</script>
<style scoped lang="scss">
+143 -49
View File
@@ -9,15 +9,15 @@
<span class="border"></span>
<span class="title">基础信息</span>
</div>
<ElForm :model="baseForm" class="base-form" label-position="right">
<ElForm :model="baseForm" :rules="baseFormRules" ref="baseFormRef" class="base-form" label-position="right">
<ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="阿里订单号/PI号" label-width="114px">
<ElInput v-model="baseForm.pi_no" placeholder="请输入阿里订单号/PI号" />
<ElInput v-model="baseForm.pi_no" placeholder="请输入阿里订单号/PI号" disabled />
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="日期" label-width="114px">
<ElFormItem label="日期" label-width="114px" prop="biz_date" required>
<ElDatePicker
v-model="baseForm.biz_date"
type="date"
@@ -29,7 +29,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="清关目的国" label-width="114px">
<ElFormItem label="清关目的国" label-width="114px" prop="clearance_country_id" required>
<el-select
v-model="baseForm.clearance_country_id"
filterable
@@ -51,7 +51,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="客户名称" label-width="114px">
<ElFormItem label="客户名称" label-width="114px" prop="customer_id" required>
<ElInput
v-model="baseForm.customer_snapshot"
placeholder="请选择客户"
@@ -124,11 +124,11 @@
<span class="border"></span>
<span class="title">订单详情</span>
</div>
<ElForm class="items-wrap" label-position="right">
<ElForm :model="formModel" :rules="itemRules" ref="itemsFormRef" class="items-wrap" label-position="right">
<div class="item-row form-box" v-for="(item, idx) in items" :key="idx">
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="车型" label-width="85px">
<ElFormItem label="车型" label-width="95px" :prop="'items.' + idx + '.sku_id'" required>
<ElInput
v-model="item.model_snapshot"
placeholder="请选择车型"
@@ -144,7 +144,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="颜色/外饰" label-width="85px">
<ElFormItem label="颜色/外饰" label-width="95px" :prop="'items.' + idx + '.color_exterior_snapshot'" required>
<el-select
v-model="item.color_exterior_snapshot"
filterable
@@ -168,7 +168,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="颜色/内饰" label-width="85px">
<ElFormItem label="颜色/内饰" label-width="95px" :prop="'items.' + idx + '.color_interior_snapshot'" required>
<el-select
v-model="item.color_interior_snapshot"
filterable
@@ -192,7 +192,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="改装" label-width="85px">
<ElFormItem label="改装" label-width="95px">
<el-select
v-model="item.modify_ids"
filterable
@@ -216,7 +216,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="里程" label-width="85px">
<ElFormItem label="里程" label-width="95px">
<ElInput
v-model="item.mileage"
:disabled="item._echo_vin === true"
@@ -227,7 +227,7 @@
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-if="(item.mileage ?? 0) <= 0">
<ElFormItem label="官方指导价" label-width="85px">
<ElFormItem label="官方指导价" label-width="95px" :prop="'items.' + idx + '.official_price'" required>
<ElInput
:disabled="item._echo_vin === true"
v-model="item.official_price"
@@ -252,7 +252,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-else>
<ElFormItem label="二手挂牌价" label-width="85px">
<ElFormItem label="二手挂牌价" label-width="95px" :prop="'items.' + idx + '.listing_price'" required>
<ElInput
:disabled="item._echo_vin === true"
v-model="item.listing_price"
@@ -277,7 +277,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-if="(item.mileage ?? 0) <= 0">
<ElFormItem label="优惠" label-width="85px">
<ElFormItem label="优惠" label-width="95px">
<ElInput
:disabled="item._echo_vin === true"
v-model="item.discount_price"
@@ -302,7 +302,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-else>
<ElFormItem label="优惠" label-width="85px">
<ElFormItem label="优惠" label-width="95px">
<ElInput
:disabled="item._echo_vin === true"
v-model="item.reduction_price"
@@ -329,7 +329,7 @@
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="手续费" label-width="85px">
<ElFormItem label="手续费" label-width="95px">
<ElInput
:disabled="item._echo_vin === true"
v-model="item.handling_fee"
@@ -354,7 +354,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="改装费" label-width="85px">
<ElFormItem label="改装费" label-width="95px">
<ElInput
:disabled="item._echo_vin === true"
v-model="item.retrofit_fee"
@@ -379,7 +379,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="FOB段运费" label-width="85px">
<ElFormItem label="FOB段运费" label-width="95px">
<ElInput
:disabled="item._echo_vin === true"
v-model="item.fob_transport_fee"
@@ -404,7 +404,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="港杂费" label-width="85px">
<ElFormItem label="港杂费" label-width="95px">
<ElInput
:disabled="item._echo_vin === true"
v-model="item.port_misc_fee"
@@ -429,7 +429,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="海运费" label-width="85px">
<ElFormItem label="海运费" label-width="95px">
<ElInput
:disabled="item._echo_vin === true"
v-model="item.ocean_freight"
@@ -454,10 +454,10 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="佣金" label-width="85px">
<ElInput v-model="item.commission" placeholder="请输入佣金">
<ElFormItem label="佣金" label-width="95px">
<ElInput :disabled="item._echo_vin === true" v-model="item.commission" placeholder="请输入佣金">
<template #suffix>
<ElSelect v-model="item.commission_currency" style="width: 64px">
<ElSelect :disabled="item._echo_vin === true" v-model="item.commission_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
@@ -471,10 +471,10 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="购置税" label-width="85px">
<ElInput v-model="item.purchase_tax" placeholder="请输入购置税">
<ElFormItem label="购置税" label-width="95px">
<ElInput :disabled="item._echo_vin === true" v-model="item.purchase_tax" placeholder="请输入购置税">
<template #suffix>
<ElSelect v-model="item.purchase_tax_currency" style="width: 64px">
<ElSelect :disabled="item._echo_vin === true" v-model="item.purchase_tax_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
@@ -488,10 +488,10 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="预估退税额" label-width="85px">
<ElInput v-model="item.tax_refund" placeholder="请输入预估退税额">
<template #suffix>
<ElSelect v-model="item.tax_refund_currency" style="width: 64px">
<ElFormItem label="预估退税额" label-width="95px">
<ElInput :disabled="item._echo_vin === true" v-model="item.tax_refund" placeholder="请输入预估退税额">
<!-- <template #suffix>
<ElSelect :disabled="item._echo_vin === true" v-model="item.tax_refund_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
@@ -499,6 +499,14 @@
:value="c.currency_code"
/>
</ElSelect>
</template> -->
<template #suffix>
<span style="font-size: 11px">
{{
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)?.currency_name) ||
baseForm.settlement_currency
}}
</span>
</template>
</ElInput>
<ElInput v-model="item.tax_refund_currency_snapshot" type="hidden" />
@@ -507,7 +515,7 @@
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="成交价" label-width="85px">
<ElFormItem label="成交价" label-width="95px" :prop="'items.' + idx + '.unit_price'" required>
<ElInput
:disabled="item._echo_vin === true"
v-model="item.unit_price"
@@ -532,7 +540,7 @@
</ElFormItem>
</ElCol>
<!-- <ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="总价" label-width="85px">
<ElFormItem label="总价" label-width="95px">
<ElInput v-model="item.total_price" placeholder="请输入总价">
<template #suffix>
<ElSelect v-model="item.total_price_currency" style="width: 64px">
@@ -549,7 +557,7 @@
</ElFormItem>
</ElCol> -->
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="利润" label-width="85px">
<ElFormItem label="利润" label-width="95px">
<ElInput
v-model="item.profit"
placeholder="正在计算利润"
@@ -568,7 +576,25 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="车架号" label-width="85px">
<ElFormItem label="报关价" label-width="95px">
<ElInput
v-model="item.clearance_price"
placeholder="正在计算报关价"
:class="Number(item.clearance_price) < 0 ? 'profit-negative' : ''"
>
<template #suffix>
<span style="font-size: 11px">
{{
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)?.currency_name) ||
baseForm.settlement_currency
}}
</span>
</template>
</ElInput>
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="车架号" label-width="95px">
<ElInput
:disabled="item._echo_vin === true"
v-model="item.vin"
@@ -579,7 +605,7 @@
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="24" :md="24" :lg="24" :xl="24">
<ElFormItem label="备注" label-width="85px">
<ElFormItem label="备注" label-width="95px">
<ElInput type="textarea" :rows="2" v-model="item.remark" placeholder="请输入备注" />
</ElFormItem>
</ElCol>
@@ -628,15 +654,15 @@
<span class="border"></span>
<span class="title">运输详情</span>
</div>
<ElForm :model="baseForm" class="foot-form">
<ElForm :model="baseForm" :rules="transportFormRules" ref="transportFormRef" class="foot-form">
<ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="清关人" label-width="98px">
<ElFormItem label="清关人" label-width="108px" prop="declarant_name" required>
<ElInput v-model="baseForm.declarant_name" placeholder="请输入清关人" />
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="预计发送日" label-width="98px">
<ElFormItem label="预计发送日" label-width="108px" prop="eta_ship_date" required>
<ElDatePicker
v-model="baseForm.eta_ship_date"
value-format="YYYY-MM-DD"
@@ -648,7 +674,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="国内收货港" label-width="98px">
<ElFormItem label="国内收货港" label-width="108px" prop="domestic_port_id" required>
<ElSelect
v-model="baseForm.domestic_port_id"
placeholder="请选择国内收货商"
@@ -669,7 +695,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="运输方式" label-width="98px">
<ElFormItem label="运输方式" label-width="108px" prop="shipping_method_id" required>
<ElSelect
v-model="baseForm.shipping_method_id"
placeholder="请选择运输方式"
@@ -690,7 +716,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="贸易条款" label-width="98px">
<ElFormItem label="贸易条款" label-width="108px" prop="trade_term_id" required>
<ElSelect
v-model="baseForm.trade_term_id"
placeholder="请选择"
@@ -711,7 +737,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="清关目的港" label-width="98px">
<ElFormItem label="清关目的港" label-width="108px" prop="clearance_port_id" required>
<ElSelect
v-model="baseForm.clearance_port_id"
placeholder="请选择"
@@ -732,7 +758,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="最迟到港时间" label-width="98px">
<ElFormItem label="最迟到港时间" label-width="108px" prop="latest_arrival_date" required>
<ElDatePicker
v-model="baseForm.latest_arrival_date"
type="date"
@@ -892,10 +918,10 @@
<div class="form-card">
<!-- 底部信息 -->
<div class="submit-wrap">
<ElButton type="primary" plain size="large" class="submit-btn" @click="handleSubmit1(0)"
<ElButton type="primary" plain size="large" class="submit-btn" @click="handleSubmitWithValidation(0)"
>保存</ElButton
>
<ElButton type="primary" size="large" class="submit-btn" @click="handleSubmit1(1)"
<ElButton type="primary" size="large" class="submit-btn" @click="handleSubmitWithValidation(1)"
>提交</ElButton
>
</div>
@@ -1012,14 +1038,65 @@
import { CrmService } from '@/api/crmApi'
import { useUserStore } from '@/store/modules/user'
import { useStockingForm } from '@/composables/useStockingForm'
import { onMounted } from 'vue'
import { onMounted, ref, computed } from 'vue'
defineOptions({ name: 'CrmStockingEdit' })
const route = useRoute()
const stocking_id = route.query.id
const { getUserInfo } = useUserStore()
const handleSubmit1 = async (status: number) => {
const id = Array.isArray(stocking_id) ? stocking_id[0] : stocking_id
await handleSubmit(status, typeof id === 'string' ? id : undefined, '1')
// 表单引用
const baseFormRef = ref()
const itemsFormRef = ref()
const transportFormRef = ref()
const paymentFormRefs = ref<any[]>([])
const setPaymentFormRef = (el: any, idx: number) => { if (el) paymentFormRefs.value[idx] = el }
// 表单模型
const formModel = computed(() => ({ items: items.value }))
// 基础表单校验
const baseFormRules = {
biz_date: [{ required: true, message: '请选择日期', trigger: 'change' }],
clearance_country_id: [{ required: true, message: '请选择清关目的国', trigger: 'change' }],
customer_id: [{ required: true, message: '请选择客户', trigger: 'change' }]
}
// 明细动态校验
const itemRules = computed(() => {
const rules: any = {}
items.value.forEach((_, idx) => {
rules[`items.${idx}.sku_id`] = [{ required: true, message: '请选择车型', trigger: 'change' }]
rules[`items.${idx}.color_exterior_snapshot`] = [
{ required: true, message: '请选择颜色/外饰', trigger: 'change' }
]
rules[`items.${idx}.color_interior_snapshot`] = [
{ required: true, message: '请选择颜色/内饰', trigger: 'change' }
]
rules[`items.${idx}.official_price`] = [
{ required: true, message: '请输入官方指导价', trigger: 'blur' }
]
rules[`items.${idx}.listing_price`] = [
{ required: true, message: '请输入二手挂牌价', trigger: 'blur' }
]
rules[`items.${idx}.unit_price`] = [
{ required: true, message: '请输入成交价', trigger: 'blur' }
]
})
return rules
})
// 运输详情校验
const transportFormRules = {
declarant_name: [{ required: true, message: '请输入清关人', trigger: 'blur' }],
eta_ship_date: [{ required: true, message: '请选择预计发送日', trigger: 'change' }],
domestic_port_id: [{ required: true, message: '请选择国内收货港', trigger: 'change' }],
shipping_method_id: [{ required: true, message: '请选择运输方式', trigger: 'change' }],
trade_term_id: [{ required: true, message: '请选择贸易条款', trigger: 'change' }],
clearance_port_id: [{ required: true, message: '请选择清关目的港', trigger: 'change' }],
latest_arrival_date: [{ required: true, message: '请选择最迟到港时间', trigger: 'change' }]
}
// 收款信息校验(编辑页多为回显,规则保留以备需要)
const paymentFormRules = {
remitter_name: [{ required: true, message: '请输入汇款人', trigger: 'blur' }],
remit_country_id: [{ required: true, message: '请选择汇款国', trigger: 'change' }],
remit_date: [{ required: true, message: '请选择汇款日期', trigger: 'change' }],
account_id: [{ required: true, message: '请选择账户', trigger: 'change' }],
amount: [{ required: true, message: '请输入金额', trigger: 'blur' }]
}
// 使用公共的备货单表单逻辑
const {
@@ -1087,6 +1164,23 @@
chooseVehicle
} = useStockingForm(true, stocking_id as string) // isFinal = true, stocking_id
// 提交前统一校验
const handleSubmitWithValidation = async (status: number) => {
try {
await baseFormRef.value?.validate()
await itemsFormRef.value?.validate()
await transportFormRef.value?.validate()
for (let i = 0; i < paymentItems.value.length; i++) {
const refForm = paymentFormRefs.value[i]
if (refForm) await refForm.validate()
}
const id = Array.isArray(stocking_id) ? stocking_id[0] : stocking_id
await handleSubmit(status, typeof id === 'string' ? id : undefined, '1')
} catch (e) {
// 校验失败不提交
}
}
// 获取详情数据
const getdetilfn = async () => {
const res = await CrmService.getStockDetail({ id: stocking_id })
+157 -58
View File
@@ -9,15 +9,15 @@
<span class="border"></span>
<span class="title">基础信息</span>
</div>
<ElForm :model="baseForm" class="base-form" label-position="right">
<ElForm :model="baseForm" :rules="baseFormRules" ref="baseFormRef" class="base-form" label-position="right">
<ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="阿里订单号/PI号" label-width="114px">
<ElFormItem label="阿里订单号/PI号" label-width="124px" prop="pi_no" required>
<ElInput v-model="baseForm.pi_no" placeholder="请输入阿里订单号/PI号" />
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="日期" label-width="114px">
<ElFormItem label="日期" label-width="114px" prop="biz_date" required>
<ElDatePicker
v-model="baseForm.biz_date"
type="date"
@@ -29,7 +29,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="清关目的国" label-width="114px">
<ElFormItem label="清关目的国" label-width="114px" prop="clearance_country_id" required>
<el-select
v-model="baseForm.clearance_country_id"
filterable
@@ -51,7 +51,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="客户名称" label-width="114px">
<ElFormItem label="客户名称" label-width="114px" prop="customer_id" required>
<ElInput
v-model="baseForm.customer_snapshot"
placeholder="请选择客户"
@@ -66,7 +66,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="客户来源" label-width="114px">
<ElFormItem label="客户来源" label-width="124px">
<el-tooltip class="box-item" content="如需修改客户来源,请先编辑修改客户资料">
<el-select
v-model="baseForm.customer_source_id"
@@ -124,11 +124,11 @@
<span class="border"></span>
<span class="title">订单详情</span>
</div>
<ElForm class="items-wrap" label-position="right">
<ElForm :model="formModel" :rules="itemRules" ref="itemsFormRef" class="items-wrap" label-position="right">
<div class="item-row form-box" v-for="(item, idx) in items" :key="idx">
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="车型" label-width="85px">
<ElFormItem label="车型" label-width="95px" :prop="'items.' + idx + '.sku_id'" required>
<ElInput
v-model="item.model_snapshot"
placeholder="请选择车型"
@@ -143,7 +143,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="颜色/外饰" label-width="85px">
<ElFormItem label="颜色/外饰" label-width="95px" :prop="'items.' + idx + '.color_exterior_snapshot'" required>
<el-select
v-model="item.color_exterior_snapshot"
filterable
@@ -166,7 +166,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="颜色/内饰" label-width="85px">
<ElFormItem label="颜色/内饰" label-width="95px" :prop="'items.' + idx + '.color_interior_snapshot'" required>
<el-select
v-model="item.color_interior_snapshot"
filterable
@@ -189,7 +189,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="改装" label-width="85px">
<ElFormItem label="改装" label-width="95px">
<el-select
v-model="item.modify_ids"
filterable
@@ -212,17 +212,17 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="里程" label-width="85px">
<ElFormItem label="里程" label-width="95px">
<ElInput v-model="item.mileage" placeholder="请输入里程" />
</ElFormItem>
</ElCol>
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-if="(item.mileage ?? 0) <= 0">
<ElFormItem label="官方指导价" label-width="85px">
<ElFormItem label="官方指导价" label-width="95px" :prop="'items.' + idx + '.official_price'" required>
<ElInput v-model="item.official_price" placeholder="请输入官方指导价">
<template #suffix>
<ElSelect v-model="item.guide_price_currency" style="width: 64px;border: none;">
<ElSelect v-model="item.guide_price_currency" style="width: 64px; border: none">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
@@ -236,7 +236,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-else>
<ElFormItem label="二手挂牌价" label-width="85px">
<ElFormItem label="二手挂牌价" label-width="95px" :prop="'items.' + idx + '.listing_price'" required>
<ElInput v-model="item.listing_price" placeholder="请输入二手挂牌价">
<template #suffix>
<ElSelect v-model="item.listing_price_currency" style="width: 64px">
@@ -253,7 +253,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-if="(item.mileage ?? 0) <= 0">
<ElFormItem label="优惠" label-width="85px">
<ElFormItem label="优惠" label-width="95px">
<ElInput v-model="item.discount_price" placeholder="请输入优惠额">
<template #suffix>
<ElSelect v-model="item.discount_currency" style="width: 64px">
@@ -270,7 +270,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-else>
<ElFormItem label="优惠" label-width="85px">
<ElFormItem label="优惠" label-width="95px">
<ElInput v-model="item.reduction_price" placeholder="请输入优惠">
<template #suffix>
<ElSelect v-model="item.reduction_price_currency" style="width: 64px">
@@ -289,7 +289,7 @@
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="手续费" label-width="85px">
<ElFormItem label="手续费" label-width="95px">
<ElInput v-model="item.handling_fee" placeholder="请输入手续费">
<template #suffix>
<ElSelect v-model="item.helper_fee_currency" style="width: 64px">
@@ -306,7 +306,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="改装费" label-width="85px">
<ElFormItem label="改装费" label-width="95px">
<ElInput v-model="item.retrofit_fee" placeholder="请输入改装费">
<template #suffix>
<ElSelect v-model="item.modify_fee_currency" style="width: 64px">
@@ -323,7 +323,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="FOB段运费" label-width="85px">
<ElFormItem label="FOB段运费" label-width="95px">
<ElInput v-model="item.fob_transport_fee" placeholder="请输入FOB段运费">
<template #suffix>
<ElSelect v-model="item.fob_fee_currency" style="width: 64px">
@@ -340,7 +340,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="港杂费" label-width="85px">
<ElFormItem label="港杂费" label-width="95px">
<ElInput v-model="item.port_misc_fee" placeholder="请输入港杂费">
<template #suffix>
<ElSelect v-model="item.port_fee_currency" style="width: 64px">
@@ -357,7 +357,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="海运费" label-width="85px">
<ElFormItem label="海运费" label-width="95px">
<ElInput v-model="item.ocean_freight" placeholder="请输入海运费">
<template #suffix>
<ElSelect v-model="item.ocean_freight_currency" style="width: 64px">
@@ -374,7 +374,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="佣金" label-width="85px">
<ElFormItem label="佣金" label-width="95px">
<ElInput v-model="item.commission" placeholder="请输入佣金">
<template #suffix>
<ElSelect v-model="item.commission_currency" style="width: 64px">
@@ -391,7 +391,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="购置税" label-width="85px">
<ElFormItem label="购置税" label-width="95px">
<ElInput v-model="item.purchase_tax" placeholder="请输入购置税">
<template #suffix>
<ElSelect v-model="item.purchase_tax_currency" style="width: 64px">
@@ -408,9 +408,9 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="预估退税额" label-width="85px">
<ElFormItem label="预估退税额" label-width="95px">
<ElInput v-model="item.tax_refund" placeholder="请输入预估退税额">
<template #suffix>
<!-- <template #suffix>
<ElSelect v-model="item.tax_refund_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
@@ -419,6 +419,14 @@
:value="c.currency_code"
/>
</ElSelect>
</template> -->
<template #suffix>
<span style="font-size: 11px">
{{
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)?.currency_name) ||
baseForm.settlement_currency
}}
</span>
</template>
</ElInput>
<ElInput v-model="item.tax_refund_currency_snapshot" type="hidden" />
@@ -427,7 +435,7 @@
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="成交价" label-width="85px">
<ElFormItem label="成交价" label-width="95px" :prop="'items.' + idx + '.unit_price'" required>
<ElInput v-model="item.unit_price" placeholder="请输入成交价">
<template #suffix>
<ElSelect v-model="item.unit_price_currency" style="width: 64px">
@@ -444,7 +452,7 @@
</ElFormItem>
</ElCol>
<!-- <ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="总价" label-width="85px">
<ElFormItem label="总价" label-width="95px">
<ElInput v-model="item.total_price" placeholder="请输入总价">
<template #suffix>
<ElSelect v-model="item.total_price_currency" style="width: 64px">
@@ -461,7 +469,7 @@
</ElFormItem>
</ElCol> -->
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="利润" label-width="85px">
<ElFormItem label="利润" label-width="95px">
<ElInput
v-model="item.profit"
placeholder="正在计算利润"
@@ -471,7 +479,27 @@
<template #suffix>
<span style="font-size: 11px">
{{
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)?.currency_name) ||
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)
?.currency_name) ||
baseForm.settlement_currency
}}
</span>
</template>
</ElInput>
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="报关价" label-width="95px">
<ElInput
v-model="item.clearance_price"
placeholder="正在计算报关价"
:class="Number(item.clearance_price) < 0 ? 'profit-negative' : ''"
>
<template #suffix>
<span style="font-size: 11px">
{{
((currencyOptions || []).find((c: any) => c.currency_code === baseForm.settlement_currency)
?.currency_name) ||
baseForm.settlement_currency
}}
</span>
@@ -482,7 +510,7 @@
</ElRow>
<ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="24" :md="24" :lg="24" :xl="24">
<ElFormItem label="备注" label-width="85px">
<ElFormItem label="备注" label-width="95px">
<ElInput type="textarea" :rows="2" v-model="item.remark" placeholder="请输入备注" />
</ElFormItem>
</ElCol>
@@ -532,13 +560,12 @@
<ElFormItem label="合同汇率" label-width="105px">
<ElInput v-model="baseForm.contract_exchange_rate" placeholder="请输入">
<template #suffix>
<ElSelect v-model="baseForm.settlement_currency" style="width: 64px">
<ElSelect v-model="baseForm.settlement_currency" style="width: 64px">
<ElOption
v-for="c in currencyOptions"
:key="c.currency_code"
:label="c.currency_name"
:value="c.currency_code"
@change="(val) =>(baseForm.contract_exchange_rate =(currencyOptions || []).find((x: any) => x.currency_code === val)?.exchange_rate || '') "
/>
</ElSelect>
</template>
@@ -553,15 +580,15 @@
<span class="border"></span>
<span class="title">运输详情</span>
</div>
<ElForm :model="baseForm" class="foot-form">
<ElForm :model="baseForm" :rules="transportFormRules" ref="transportFormRef" class="foot-form">
<ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="清关人" label-width="98px">
<ElFormItem label="清关人" label-width="108px" prop="declarant_name" required>
<ElInput v-model="baseForm.declarant_name" placeholder="请输入清关人" />
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="预计发送日" label-width="98px">
<ElFormItem label="预计发送日" label-width="108px" prop="eta_ship_date" required>
<ElDatePicker
v-model="baseForm.eta_ship_date"
value-format="YYYY-MM-DD"
@@ -573,7 +600,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="国内收货港" label-width="98px">
<ElFormItem label="国内收货港" label-width="108px" prop="domestic_port_id" required>
<ElSelect
v-model="baseForm.domestic_port_id"
placeholder="请选择国内收货商"
@@ -594,7 +621,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="运输方式" label-width="98px">
<ElFormItem label="运输方式" label-width="108px" prop="shipping_method_id" required>
<ElSelect
v-model="baseForm.shipping_method_id"
placeholder="请选择运输方式"
@@ -615,7 +642,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="贸易条款" label-width="98px">
<ElFormItem label="贸易条款" label-width="108px" prop="trade_term_id" required>
<ElSelect
v-model="baseForm.trade_term_id"
placeholder="请选择"
@@ -636,7 +663,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="清关目的港" label-width="98px">
<ElFormItem label="清关目的港" label-width="108px" prop="clearance_port_id" required>
<ElSelect
v-model="baseForm.clearance_port_id"
placeholder="请选择"
@@ -657,7 +684,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="最迟到港时间" label-width="98px">
<ElFormItem label="最迟到港时间" label-width="108px" prop="latest_arrival_date" required>
<ElDatePicker
v-model="baseForm.latest_arrival_date"
type="date"
@@ -679,15 +706,15 @@
<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">
<ElForm :model="payment" :rules="paymentFormRules" :ref="(el) => setPaymentFormRef(el, idx)" label-width="65px" class="payment-form">
<ElRow :gutter="12">
<ElCol :span="4">
<ElFormItem label="汇款人">
<ElFormItem label="汇款人" prop="remitter_name" required>
<ElInput v-model="payment.remitter_name" placeholder="请选择汇款人" />
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="汇款国">
<ElFormItem label="汇款国" prop="remit_country_id" required>
<el-select v-model="payment.remit_country_id" filterable placeholder="请选择汇款国" @change="
(val) =>
(payment.remit_country_name_snapshot =
@@ -704,7 +731,7 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="4" :xl="4">
<ElFormItem label="日期">
<ElFormItem label="日期" prop="remit_date" required>
<ElDatePicker
v-model="payment.remit_date"
type="date"
@@ -716,11 +743,11 @@
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="5" :xl="5">
<ElFormItem label="账户">
<ElSelect v-model="payment.account_name_snapshot" placeholder="请选择账户" @change="
<ElFormItem label="账户" prop="account_id" required>
<ElSelect v-model="payment.account_id" placeholder="请选择账户" @change="
(val) =>
(payment.account_id =
(accountOptions || []).find((x: any) => x.short_desc === val)?.id || '')
(payment.account_name_snapshot =
(accountOptions || []).find((x: any) => x.id === val)?.short_desc || '')
">
<ElOption
v-for="item in accountOptions"
@@ -729,11 +756,11 @@
:value="item.id"
/>
</ElSelect>
<ElInput v-model="payment.account_id" type="hidden" />
<ElInput v-model="payment.account_name_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="5" :xl="5">
<ElFormItem label="金额">
<ElFormItem label="金额" prop="amount" required>
<ElInput v-model="payment.amount" placeholder="请输入金额">
<template #suffix>
<ElSelect
@@ -741,7 +768,9 @@
style="width: 64px"
@change="
(val) => {
const found = (currencyOptions || []).find((x: any) => x.currency_code === val)
const found = (currencyOptions || []).find(
(x: any) => x.currency_code === val
)
payment.currency_name_snapshot = found?.currency_name || ''
}
"
@@ -809,14 +838,14 @@
plain
size="large"
class="submit-btn"
@click="handleSubmit1(0)"
@click="handleSubmitWithValidation(0)"
>保存</ElButton
>
<ElButton
type="primary"
size="large"
class="submit-btn"
@click="handleSubmit1(1)"
@click="handleSubmitWithValidation(1)"
>提交</ElButton
>
</div>
@@ -933,14 +962,84 @@
import { CrmService } from '@/api/crmApi'
import { useUserStore } from '@/store/modules/user'
import { useStockingForm } from '@/composables/useStockingForm'
import { onMounted } from 'vue'
import { onMounted, ref, computed } from 'vue'
defineOptions({ name: 'CrmStockingEdit' })
const route = useRoute()
const stocking_id = route.query.id
const { getUserInfo } = useUserStore()
const handleSubmit1 = async (status: number) => {
const id = Array.isArray(stocking_id) ? stocking_id[0] : stocking_id
await handleSubmit(status, typeof id === 'string' ? id : undefined)
// 表单引用
const baseFormRef = ref()
const itemsFormRef = ref()
const transportFormRef = ref()
const paymentFormRefs = ref<any[]>([])
const setPaymentFormRef = (el: any, idx: number) => {
if (el) paymentFormRefs.value[idx] = el
}
// 表单模型(用于明细动态校验)
const formModel = computed(() => ({ items: items.value }))
// 基础表单校验
const baseFormRules = {
pi_no: [{ required: true, message: '请输入阿里订单号/PI号', trigger: 'blur' }],
biz_date: [{ required: true, message: '请选择日期', trigger: 'change' }],
clearance_country_id: [{ required: true, message: '请选择清关目的国', trigger: 'change' }],
customer_id: [{ required: true, message: '请选择客户', trigger: 'change' }]
}
// 明细动态校验
const itemRules = computed(() => {
const rules: any = {}
items.value.forEach((_, idx) => {
rules[`items.${idx}.sku_id`] = [{ required: true, message: '请选择车型', trigger: 'change' }]
rules[`items.${idx}.color_exterior_snapshot`] = [
{ required: true, message: '请选择颜色/外饰', trigger: 'change' }
]
rules[`items.${idx}.color_interior_snapshot`] = [
{ required: true, message: '请选择颜色/内饰', trigger: 'change' }
]
rules[`items.${idx}.official_price`] = [
{ required: true, message: '请输入官方指导价', trigger: 'blur' }
]
rules[`items.${idx}.listing_price`] = [
{ required: true, message: '请输入二手挂牌价', trigger: 'blur' }
]
rules[`items.${idx}.unit_price`] = [
{ required: true, message: '请输入成交价', trigger: 'blur' }
]
})
return rules
})
// 运输详情校验
const transportFormRules = {
declarant_name: [{ required: true, message: '请输入清关人', trigger: 'blur' }],
eta_ship_date: [{ required: true, message: '请选择预计发送日', trigger: 'change' }],
domestic_port_id: [{ required: true, message: '请选择国内收货港', trigger: 'change' }],
shipping_method_id: [{ required: true, message: '请选择运输方式', trigger: 'change' }],
trade_term_id: [{ required: true, message: '请选择贸易条款', trigger: 'change' }],
clearance_port_id: [{ required: true, message: '请选择清关目的港', trigger: 'change' }],
latest_arrival_date: [{ required: true, message: '请选择最迟到港时间', trigger: 'change' }]
}
// 收款信息校验
const paymentFormRules = {
remitter_name: [{ required: true, message: '请输入汇款人', trigger: 'blur' }],
remit_country_id: [{ required: true, message: '请选择汇款国', trigger: 'change' }],
remit_date: [{ required: true, message: '请选择汇款日期', trigger: 'change' }],
account_id: [{ required: true, message: '请选择账户', trigger: 'change' }],
amount: [{ required: true, message: '请输入金额', trigger: 'blur' }]
}
// 带校验的提交
const handleSubmitWithValidation = async (status: number) => {
try {
await baseFormRef.value?.validate()
await itemsFormRef.value?.validate()
await transportFormRef.value?.validate()
for (let i = 0; i < paymentItems.value.length; i++) {
const refForm = paymentFormRefs.value[i]
if (refForm) await refForm.validate()
}
const id = Array.isArray(stocking_id) ? stocking_id[0] : stocking_id
await handleSubmit(status, typeof id === 'string' ? id : undefined)
} catch (e) {
// 校验失败不提交
}
}
// 使用公共的备货单表单逻辑
const {
+141 -48
View File
@@ -29,6 +29,14 @@
<span class="info-label">国 家:</span>
<span class="info-value">{{ userInfo.country_txt }}</span>
</div>
<div class="info-row">
<span class="info-label">上 级:</span>
<span class="info-value">{{ userInfo.report_to_info?.name || '' }}</span>
</div>
<div class="info-row">
<span class="info-label">内 勤:</span>
<span class="info-value">{{ userInfo.office_clerk_info?.name || '' }}</span>
</div>
</div>
</div>
</div>
@@ -111,48 +119,6 @@
<ElFormItem label="邮箱" prop="email">
<ElInput v-model="form.email" :disabled="!isEdit" />
</ElFormItem>
<ElFormItem label="签名" prop="signature" class="right-input">
<template v-if="form.sign_img">
<img :src="sign_img_url" class="signature-img" />
<el-button
v-if="isEdit"
style="margin-left: 12px"
@click="showReSignQR = !showReSignQR"
>
重新签名
</el-button>
<div
v-if="isEdit && showReSignQR"
class="signature-qrcode"
style="margin-top: 20px; margin-left: 20px"
>
<qrcode-vue
:value="qrcodeUrl"
:size="200"
level="M"
render-as="svg"
:include-margin="true"
background="#ffffff"
foreground="#000000"
/>
<div class="qrcode-tip">手机扫码重新签名</div>
</div>
</template>
<template v-else>
<div class="signature-qrcode">
<qrcode-vue
:value="qrcodeUrl"
:size="200"
level="M"
render-as="svg"
:include-margin="true"
background="#ffffff"
foreground="#000000"
/>
<div class="qrcode-tip">手机扫码进行签名</div>
</div>
</template>
</ElFormItem>
</ElRow>
<ElRow>
<ElFormItem
@@ -203,8 +169,100 @@
</div>
</ElForm>
</div>
<div class="info box-style">
<h1 class="title"><span class="border" style="margin-right: 5px"></span>绑定信息</h1>
<ElForm
:model="formbd"
class="form"
ref="ruleFormbdRef"
:rules="rulesbd"
label-width="86px"
label-position="left"
>
<ElRow>
<ElFormItem label="直属上级" prop="report_to" required>
<ElSelect
v-model="formbd.report_to"
placeholder="请选择直属上级"
:disabled="!isEditbd"
>
<ElOption
v-for="item in userOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</ElSelect>
</ElFormItem>
<ElFormItem label="所属内勤" prop="office_clerk_id" class="right-input" required>
<ElSelect
v-model="formbd.office_clerk_id"
placeholder="请选择所属内勤"
:disabled="!isEditbd"
>
<ElOption
v-for="item in usernqOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</ElSelect>
</ElFormItem>
</ElRow>
<div class="info box-style" style="margin-top: 20px">
<ElRow>
<ElFormItem label="签名" prop="signature" class="right-input">
<template v-if="formbd.sign_img">
<img :src="sign_img_url" class="signature-img" />
<el-button
v-if="isEditbd"
style="margin-left: 12px"
@click="showReSignQR = !showReSignQR"
>
重新签名
</el-button>
<div
v-if="isEditbd && showReSignQR"
class="signature-qrcode"
style="margin-top: 20px; margin-left: 20px"
>
<qrcode-vue
:value="qrcodeUrl"
:size="200"
level="M"
render-as="svg"
:include-margin="true"
background="#ffffff"
foreground="#000000"
/>
<div class="qrcode-tip">手机扫码重新签名</div>
</div>
</template>
<template v-else>
<div class="signature-qrcode">
<qrcode-vue
:value="qrcodeUrl"
:size="200"
level="M"
render-as="svg"
:include-margin="true"
background="#ffffff"
foreground="#000000"
/>
<div class="qrcode-tip">手机扫码进行签名</div>
</div>
</template>
</ElFormItem>
</ElRow>
<div class="el-form-item-right">
<ElButton type="primary" style="width: 90px" v-ripple @click="editbd(ruleFormbdRef)">
<i v-if="!isEditbd" class="iconfont-sys"> &#xe6bf;</i>
{{ isEditbd ? '保存' : '编辑' }}
</ElButton>
</div>
</ElForm>
</div>
<div class="info box-style">
<h1 class="title">更改密码</h1>
<ElForm :model="pwdForm" class="form" label-width="86px" label-position="left">
@@ -249,9 +307,10 @@
</template>
<script setup lang="ts">
import { ElForm, FormInstance } from 'element-plus'
import { ElForm, FormInstance, FormRules } from 'element-plus'
import imageUrl from '@/assets/img/crm/upimg.png'
import { CrmService } from '@/api/crmApi'
import { commonService } from '@/api/commonApi'
import { useUserStore } from '@/store/modules/user'
import QrcodeVue from 'qrcode.vue'
import { useUploadHeaders } from '@/composables/useUploadHeaders'
@@ -268,6 +327,7 @@
const sign_img_url = ref('')
const countryOptions = ref<any>()
const form = ref<CustomerInfo>({})
const formbd = ref<CustomerInfo>({})
//获取公司 getCompanyList
// const companyList = ref<any>()
//国家
@@ -280,17 +340,30 @@
countryOptions.value = []
}
}
//用户下拉
const userOptions = ref<any>()
const usernqOptions = ref<any>()
const getuserOptions = async () => {
const res = await commonService.getUserSelect()
const resparams = await commonService.getUserSelectparams({ role_id: '5' })
userOptions.value = res
usernqOptions.value = resparams
}
const userInfo = ref<CustomerInfo>({})
const getuserInfo = async () => {
const data = await CrmService.userget()
userInfo.value = data
form.value = data
formbd.value = data
formbd.value.office_clerk_id = data.office_clerk_info?.id || ''
formbd.value.report_to = data.report_to_info?.id || ''
imageUrlavatar.value = data.avatar_full
socialize_pic_full.value = data.socialize_pic_full
sign_img_url.value = data.sign_img_url
}
const isEdit = ref(false)
const isEditbd = ref(false)
const showReSignQR = ref(false)
const isEditPwd = ref(false)
const pwdForm = reactive({
@@ -315,22 +388,27 @@
// address: [{ required: true, message: '请输入地址', trigger: 'blur' }],
// sex: [{ type: 'array', required: true, message: '请选择性别', trigger: 'blur' }]
// })
const ruleFormbdRef = ref<FormInstance>()
const rulesbd = reactive<FormRules>({
report_to: [{ required: true, message: '请选择直属上级', trigger: 'blur' }],
office_clerk_id: [{ required: true, message: '请选择所属内勤', trigger: 'blur' }]
})
const options = [
{
value: '',
label: '未知'
},
{
value: '1',
value: 1,
label: '男'
},
{
value: '2',
value: 2,
label: '女'
}
]
onMounted(async () => {
await getuserOptions()
await getarea()
await getuserInfo()
})
@@ -343,7 +421,21 @@
getuserInfo()
}
isEdit.value = !isEdit.value
if (!isEdit.value) {
}
const editbd = async (formEl: FormInstance | undefined) => {
if (isEditbd.value) {
if (formbd.value.report_to == '' || formbd.value.office_clerk_id == '') {
ElMessage.error('直属上级或所属内勤不能为空')
return
}
const payload: any = { ...(formbd.value as any) }
delete payload.sign_img_url
const res = await CrmService.crmuseredit(payload)
ElMessage.success(res?.message || '操作成功')
getuserInfo()
}
isEditbd.value = !isEditbd.value
if (!isEditbd.value) {
showReSignQR.value = false
}
}
@@ -434,6 +526,7 @@
.box-style {
border: 1px solid var(--art-border-color);
margin-bottom: 20px;
}
.content {