修改备货单 等页面

This commit is contained in:
浅念
2025-09-12 17:49:07 +08:00
parent da690dfa06
commit 045d13eb7b
23 changed files with 2226 additions and 234 deletions
+2 -6
View File
@@ -258,11 +258,7 @@
top: 50%; top: 50%;
transform: translateY(-50%); transform: translateY(-50%);
} }
:deep(.el-table__empty-block) { .item-row-wrap {
height: 100% !important; margin-bottom: 12px;
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
} }
</style> </style>
+67
View File
@@ -0,0 +1,67 @@
import request from '@/utils/http'
export class vehicleService {
// 颜色管理
static getColorList(params: Api.Common.PaginatingParams & any) {
return request.get<Api.Common.CommonListData>({
url: '/crm/color/list',
params
})
}
static colorAdd(params: any) {
return request.post<Api.Common.AddResponse>({
url: '/crm/color/store',
params
})
}
static colorDetail(params: any) {
return request.get<any>({
url: '/crm/color/show',
params
})
}
static colorEdit(params: any) {
return request.post<Api.Common.AddResponse>({
url: '/crm/color/update',
params
})
}
static colorDelete(params: any) {
return request.post<Api.Common.AddResponse>({
url: '/crm/color/destroy',
params
})
}
// 车辆列表
static getVehicleList(params: Api.Common.PaginatingParams & any) {
return request.get<Api.Common.CommonListData>({
url: '/crm/vehicle/sku/list',
params
})
}
static vehicleAdd(params: any) {
return request.post<Api.Common.AddResponse>({
url: '/crm/vehicle/sku/store',
params
})
}
static vehicleDetail(params: any) {
return request.get<any>({
url: '/crm/vehicle/sku/show',
params
})
}
static vehicleEdit(params: any) {
return request.post<Api.Common.AddResponse>({
url: '/crm/vehicle/sku/update',
params
})
}
static vehicleDelete(params: any) {
return request.post<Api.Common.AddResponse>({
url: '/crm/vehicle/sku/destroy',
params
})
}
}
+9
View File
@@ -400,3 +400,12 @@
position: relative; position: relative;
z-index: 10; z-index: 10;
} }
// 修复 el-table 空数据块样式
.el-table__empty-block {
height: 100% !important;
min-height: 200px !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
@@ -16,6 +16,7 @@
<!-- 路由动画 --> <!-- 路由动画 -->
<Transition :name="pageTransition" mode="out-in" appear> <Transition :name="pageTransition" mode="out-in" appear>
<!-- <KeepAlive :max="10" :include="['StockingAdd', 'StockingFinalAdd']"> -->
<KeepAlive :max="10" :exclude="keepAliveExclude"> <KeepAlive :max="10" :exclude="keepAliveExclude">
<component :is="Component" v-if="route.meta.keepAlive" /> <component :is="Component" v-if="route.meta.keepAlive" />
</KeepAlive> </KeepAlive>
@@ -37,6 +38,7 @@
const { pageTransition, containerWidth, refresh } = storeToRefs(useSettingStore()) const { pageTransition, containerWidth, refresh } = storeToRefs(useSettingStore())
const { keepAliveExclude } = storeToRefs(useWorktabStore()) const { keepAliveExclude } = storeToRefs(useWorktabStore())
const { containerMinHeight } = useCommon() const { containerMinHeight } = useCommon()
const containerStyle = computed(() => { const containerStyle = computed(() => {
+40 -44
View File
@@ -56,28 +56,53 @@
<th class="col-color">颜色/外</th> <th class="col-color">颜色/外</th>
<th class="col-interior">内饰</th> <th class="col-interior">内饰</th>
<th class="col-modify">改装</th> <th class="col-modify">改装</th>
<th class="col-price">单价(美金)</th> <th class="col-official">官方指导价/二手挂牌价</th>
<th class="col-total">总价(美金)</th>
<th class="col-official">官方指导价</th>
<th class="col-discount">优惠</th> <th class="col-discount">优惠</th>
<th class="col-discount">手续费</th>
<th class="col-discount">改装费</th>
<th class="col-discount">FOB运费</th>
<th class="col-discount">港杂费</th>
<th class="col-discount">海运费</th>
<th class="col-discount">单价(美金)</th>
<th class="col-discount">总价(美金)</th>
<th class="col-discount">利润(美金)</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="(item, index) in (orderData.veh_list || orderData.items || [])" :key="index"> <tr v-for="(item, index) in (orderData.veh_list || orderData.items || [])" :key="index">
<td class="col-no">{{ index + 1 }}</td> <td class="col-no">{{ index + 1 }}</td>
<td class="col-model">{{ item.model_snapshot || item.model || '—' }}</td> <td class="col-model">{{ item.model_snapshot || item.model || '—' }} <span v-if="item.mileage>0">({{ item.mileage }}km)</span> </td>
<td class="col-qty">{{ item.num ?? item.quantity ?? 1 }}</td> <td class="col-qty">{{ item.num ?? item.quantity ?? 1 }}</td>
<td class="col-color">{{ item.color_exterior_snapshot || item.exteriorColor || '—' }}</td> <td class="col-color">{{ item.color_exterior_snapshot || item.exteriorColor || '—' }}</td>
<td class="col-interior">{{ item.color_interior_snapshot || item.interiorColor || '—' }}</td> <td class="col-interior">{{ item.color_interior_snapshot || item.interiorColor || '—' }}</td>
<td class="col-modify">{{ item.modify || item.modification || '—' }}</td> <td class="col-modify">{{ item.modify || item.modification || '—' }}</td>
<td class="col-price">${{ formatPrice(Number(item.unit_price?.amount ?? item.unitPrice ?? 0)) }}</td> <!-- <td class="col-official">{{ formatPrice(Number(item.official_price?.amount ?? item.officialPrice ?? 0)) }}</td> -->
<td class="col-total">${{ formatPrice(Number(item.total_price?.amount ?? item.totalPrice ?? 0)) }}</td> <td class="col-official">
<td class="col-official">{{ formatPrice(Number(item.official_price?.amount ?? item.officialPrice ?? 0)) }}</td> <span v-if="item.mileage > 0">
<td class="col-discount">{{ item.discount_price?.currency_info || item.discount_price?.amount || item.discount || '—' }}</td> {{ item.listing_price?.currency_info || item.listing_price?.amount || item.discount || '—' }}
</span>
<span v-else>{{ item.official_price?.currency_info || item.official_price?.amount || item.discount || '—' }}</span>
</td>
<td class="col-discount">
<span v-if="item.mileage > 0">
{{ item.reduction_price?.currency_info || item.reduction_price?.amount || item.discount || '—' }}
</span>
<span v-else>{{ item.discount_price?.currency_info || item.discount_price?.amount || item.discount || '—' }}</span>
</td>
<td class="col-discount">{{ item.handling_fee?.currency_info || item.handling_fee?.amount || item.discount || '—' }}</td>
<td class="col-discount">{{ item.retrofit_fee?.currency_info || item.retrofit_fee?.amount || item.discount || '—' }}</td>
<td class="col-discount">{{ item.fob_transport_fee?.currency_info || item.fob_transport_fee?.amount || item.discount || '—' }}</td>
<td class="col-discount">{{ item.port_misc_fee?.currency_info || item.port_misc_fee?.amount || item.discount || '—' }}</td>
<td class="col-discount">{{ item.ocean_freight?.currency_info || item.ocean_freight?.amount || item.discount || '—' }}</td>
<!-- <td class="col-discount">${{ formatPrice(Number(item.unit_price?.amount ?? item.unitPrice ?? 0)) }}</td> -->
<td class="col-discount">{{ item.unit_price?.currency_info || item.unit_price?.amount || item.discount || '—'}}</td>
<!-- <td class="col-discount">${{ formatPrice(Number(item.total_price?.amount ?? item.totalPrice ?? 0)) }}</td> -->
<td class="col-discount">{{ item.total_price?.currency_info || item.total_price?.amount || item.discount || '—' }}</td>
<td class="col-discount">{{ item.profit?.currency_info || item.profit?.amount || item.discount || '—' }}</td>
</tr> </tr>
<tr> <tr>
<td colspan="7"></td> <td colspan="10"></td>
<td> <td colspan="2">
<span class="label">合同汇率:</span> <span class="label">合同汇率:</span>
<span class="value">{{ orderData.contract_exchange_rate || orderData.contractRate || '—' }}</span> <span class="value">{{ orderData.contract_exchange_rate || orderData.contractRate || '—' }}</span>
</td> </td>
@@ -85,6 +110,10 @@
<span class="label">合计到岸价:</span> <span class="label">合计到岸价:</span>
<span class="value">${{ formatPrice(Number(orderData.cif_total_amount?.amount ?? orderData.totalCif ?? 0)) }}</span> <span class="value">${{ formatPrice(Number(orderData.cif_total_amount?.amount ?? orderData.totalCif ?? 0)) }}</span>
</td> </td>
<td colspan="2">
<span class="label">利润:</span>
<span class="value">{{ orderData.profit_total?.currency_info || orderData.profit_total?.amount || '—' }}</span>
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@@ -293,42 +322,9 @@
width: 60px; width: 60px;
} }
.col-model { .col-model {
width: 200px; max-width: 160px;
text-align: left;
}
.col-qty {
width: 80px;
}
.col-color {
width: 80px;
}
.col-interior {
width: 80px;
}
.col-modify {
width: 120px;
text-align: left;
}
.col-price {
width: 100px;
text-align: right;
}
.col-total {
width: 100px;
text-align: right;
}
.col-official {
width: 100px;
text-align: right;
}
.col-discount {
width: 120px;
// text-align: left; // text-align: left;
} }
tbody tr:nth-child(even) {
background: #fafafa;
}
tbody tr:hover { tbody tr:hover {
background: #e6f7ff; background: #e6f7ff;
} }
+14 -1
View File
@@ -234,7 +234,7 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
remit_country_id: '', remit_country_id: '',
remit_country_name_snapshot: '', remit_country_name_snapshot: '',
remit_date: '', remit_date: '',
currency_code: '', currency_code: 'USD',
currency_name_snapshot: '', currency_name_snapshot: '',
account_id: '', account_id: '',
account_name_snapshot: '', account_name_snapshot: '',
@@ -277,6 +277,10 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
const getarea = async () => { const getarea = async () => {
const res = await CrmService.getCountry() const res = await CrmService.getCountry()
res.forEach((item: any) => {
item.cn_addrs = item.cn_addr + '(' + item.en_addr + ')'
})
console.log(res)
countryOptions.value = res || [] countryOptions.value = res || []
} }
@@ -518,6 +522,8 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
baseForm.customer_snapshot = row.contacts || row.name || '' baseForm.customer_snapshot = row.contacts || row.name || ''
baseForm.customer_country_id = row.country_id || '' baseForm.customer_country_id = row.country_id || ''
baseForm.customer_country_snapshot = row.country_name || '' baseForm.customer_country_snapshot = row.country_name || ''
baseForm.customer_source_id = row.channel_id || ''
baseForm.customer_source_snapshot = row.channel_name || ''
customerDialog.visible = false customerDialog.visible = false
} }
@@ -822,6 +828,13 @@ export function useStockingForm(isFinal = false, stockingId?: string | number) {
// 设置默认汇率 // 设置默认汇率
baseForm.contract_exchange_rate = getCurrencyRate('USD') baseForm.contract_exchange_rate = getCurrencyRate('USD')
// 设置预计发送日默认为当天
const today = new Date()
const year = today.getFullYear()
const month = String(today.getMonth() + 1).padStart(2, '0')
const day = String(today.getDate()).padStart(2, '0')
baseForm.biz_date = `${year}-${month}-${day}`
} }
return { return {
+6 -2
View File
@@ -84,7 +84,9 @@ export const asyncRoutes: AppRouteRecord[] = [
component: 'crmpc/stocking/Add', component: 'crmpc/stocking/Add',
meta: { meta: {
title: '创建备货单', title: '创建备货单',
isHide: true isHide: true,
isHideTab: false,
keepAlive: true
} }
}, },
{ {
@@ -102,7 +104,9 @@ export const asyncRoutes: AppRouteRecord[] = [
component: 'crmpc/stocking/final_add', component: 'crmpc/stocking/final_add',
meta: { meta: {
title: '最终备货单', title: '最终备货单',
isHide: true isHide: true,
isHideTab: false,
keepAlive: true
} }
}, },
{ {
+4 -4
View File
@@ -183,8 +183,8 @@
<ElFormItem label="页面缓存" prop="keep_alive"> <ElFormItem label="页面缓存" prop="keep_alive">
<ElSwitch <ElSwitch
v-model="form.keep_alive" v-model="form.keep_alive"
:active-value="1" :active-value="true"
:inactive-value="0" :inactive-value="false"
></ElSwitch> ></ElSwitch>
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
@@ -197,8 +197,8 @@
<ElFormItem label="标签页是否隐藏" prop="is_hide_tab" label-width="120px"> <ElFormItem label="标签页是否隐藏" prop="is_hide_tab" label-width="120px">
<ElSwitch <ElSwitch
v-model="form.is_hide_tab" v-model="form.is_hide_tab"
:active-value="1" :active-value="true"
:inactive-value="0" :inactive-value="false"
></ElSwitch> ></ElSwitch>
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
+8 -8
View File
@@ -98,6 +98,14 @@
>当前品牌:{{ activeBrand.brand_name }}({{ activeBrand.brand_code }})</span >当前品牌:{{ activeBrand.brand_name }}({{ activeBrand.brand_code }})</span
> >
<span v-else class="muted">请选择左侧车辆品牌</span> <span v-else class="muted">请选择左侧车辆品牌</span>
<ElButton
type="primary"
style="margin-left: 8px"
@click="showSeriesDialog('add')"
:disabled="!activeBrand"
v-if="hasAuth('series@add')"
>新增系列</ElButton
>
</div> </div>
<div class="right"> <div class="right">
<ElInput <ElInput
@@ -108,14 +116,6 @@
@keyup.enter="getSeriesList" @keyup.enter="getSeriesList"
/> />
<ElButton style="margin-left: 8px" @click="getSeriesList" v-ripple>搜索</ElButton> <ElButton style="margin-left: 8px" @click="getSeriesList" v-ripple>搜索</ElButton>
<ElButton
type="primary"
style="margin-left: 8px"
@click="showSeriesDialog('add')"
:disabled="!activeBrand"
v-if="hasAuth('series@add')"
>新增系列</ElButton
>
</div> </div>
</div> </div>
<ArtTable <ArtTable
+3
View File
@@ -135,6 +135,9 @@
import { router } from '@/router' import { router } from '@/router'
import OrderDetailContent from '@/components/custom/OrderDetailContent.vue' import OrderDetailContent from '@/components/custom/OrderDetailContent.vue'
import type { OrderData } from '@/composables/useOrderDetailDialog' import type { OrderData } from '@/composables/useOrderDetailDialog'
defineOptions({ name: 'ApprovalDetail' }) // 定义组件名称,用于 KeepAlive 缓存控制
const { pdf, frameRef, download } = usePdfPreview() const { pdf, frameRef, download } = usePdfPreview()
const route = useRoute() const route = useRoute()
const orderDialog = reactive({ const orderDialog = reactive({
@@ -116,6 +116,9 @@
import { commonService } from '@/api/commonApi' import { commonService } from '@/api/commonApi'
import OrderDetailContent from '@/components/custom/OrderDetailContent.vue' import OrderDetailContent from '@/components/custom/OrderDetailContent.vue'
import type { OrderData } from '@/composables/useOrderDetailDialog' import type { OrderData } from '@/composables/useOrderDetailDialog'
defineOptions({ name: 'StockingAuth' }) // 定义组件名称,用于 KeepAlive 缓存控制
const { hasAuth } = useAuth() const { hasAuth } = useAuth()
const orderDialog = reactive({ const orderDialog = reactive({
orderData: {} as OrderData orderData: {} as OrderData
@@ -213,6 +216,13 @@
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
:deep(.el-table__empty-block) {
height: 100% !important;
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
}
.stocking-page { .stocking-page {
background: var(--art-main-bg-color); background: var(--art-main-bg-color);
min-height: 100vh; min-height: 100vh;
+1
View File
@@ -122,6 +122,7 @@
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { CrmService } from '@/api/crmApi' import { CrmService } from '@/api/crmApi'
defineOptions({ name: 'CustomerAdd' })
const warningMsg = ref('') const warningMsg = ref('')
const centerDialogVisible = ref(false) const centerDialogVisible = ref(false)
const router = useRouter() const router = useRouter()
+1
View File
@@ -104,6 +104,7 @@
const customerId = route.query.id const customerId = route.query.id
const router = useRouter() const router = useRouter()
const formRef = ref() const formRef = ref()
defineOptions({ name: 'CustomerEdit' })
const rules = { const rules = {
channel: [{ required: true, message: '请选择客户渠道', trigger: 'change' }], channel: [{ required: true, message: '请选择客户渠道', trigger: 'change' }],
+1
View File
@@ -243,6 +243,7 @@
const levelOptions = ref<any>() const levelOptions = ref<any>()
const followDesc = ref('') const followDesc = ref('')
const activecolor = '#3471FF' const activecolor = '#3471FF'
defineOptions({ name: 'CustomerFollowAdd' })
const successDialogVisible = ref(false) // 控制弹窗显示 const successDialogVisible = ref(false) // 控制弹窗显示
const remindValue = ref('1') const remindValue = ref('1')
+1
View File
@@ -159,6 +159,7 @@
import emptyimg from '@/assets/img/crm/empty.png' import emptyimg from '@/assets/img/crm/empty.png'
import { CrmService } from '@/api/crmApi' import { CrmService } from '@/api/crmApi'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
defineOptions({ name: 'CustomerShow' })
// 常量配置 // 常量配置
const TIMELINE_PLACEMENT = 'top' const TIMELINE_PLACEMENT = 'top'
const router = useRouter() const router = useRouter()
+1
View File
@@ -387,6 +387,7 @@
import { CrmService } from '@/api/crmApi' import { CrmService } from '@/api/crmApi'
import { useAuth } from '@/composables/useAuth' import { useAuth } from '@/composables/useAuth'
import { useUploadHeaders } from '@/composables/useUploadHeaders' import { useUploadHeaders } from '@/composables/useUploadHeaders'
defineOptions({ name: 'Customer_index' })
const { hasAuth } = useAuth() const { hasAuth } = useAuth()
const searchValue = ref('') const searchValue = ref('')
const selectValue = ref('') const selectValue = ref('')
+5 -9
View File
@@ -1,21 +1,17 @@
<template> <template>
<div class="console"> <div class="console">
<CardList></CardList> <CardList></CardList>
<!-- <AboutProject /> -->
</div> </div>
</template> </template>
<script setup lang="ts">
<script setup lang="ts">
import CardList from './widget/CardList.vue' import CardList from './widget/CardList.vue'
import { useCommon } from '@/composables/useCommon' import { useCommon } from '@/composables/useCommon'
defineOptions({ name: 'Console' }) defineOptions({ name: 'Console' })
useCommon().scrollToTop() useCommon().scrollToTop()
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@use './style'; @use './style';
</style> </style>
+115 -82
View File
@@ -37,41 +37,19 @@
@change=" @change="
(val) => (val) =>
(baseForm.clearance_country_snapshot = (baseForm.clearance_country_snapshot =
(countryOptions || []).find((x: any) => x.id === val)?.cn_addr || '') (countryOptions || []).find((x: any) => x.id === val)?.cn_addrs || '')
" "
> >
<el-option <el-option
v-for="item in countryOptions" v-for="item in countryOptions"
:key="item.id" :key="item.id"
:label="item.cn_addr" :label="item.cn_addrs"
:value="item.id" :value="item.id"
/> />
</el-select> </el-select>
<ElInput v-model="baseForm.clearance_country_snapshot" type="hidden" /> <ElInput v-model="baseForm.clearance_country_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="客户来源" label-width="114px">
<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 :sm="12" :md="12" :lg="6" :xl="4"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="客户名称" label-width="114px"> <ElFormItem label="客户名称" label-width="114px">
<ElInput <ElInput
@@ -87,25 +65,53 @@
<ElInput v-model="baseForm.customer_id" type="hidden" /> <ElInput v-model="baseForm.customer_id" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="客户来源" label-width="114px">
<el-tooltip class="box-item" content="如需修改客户来源,请先编辑修改客户资料">
<el-select
v-model="baseForm.customer_source_id"
filterable
disabled
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>
</el-tooltip>
<ElInput v-model="baseForm.customer_source_snapshot" type="hidden" />
</ElFormItem>
</ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="4"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="客户所在国" label-width="114px"> <ElFormItem label="客户所在国" label-width="114px">
<el-tooltip class="box-item" content="如需修改客户所在国,请先编辑修改客户资料">
<el-select <el-select
v-model="baseForm.customer_country_id" v-model="baseForm.customer_country_id"
filterable filterable
placeholder="请选择国家" placeholder="请选择国家"
disabled
@change=" @change="
(val) => (val) =>
(baseForm.customer_country_snapshot = (baseForm.customer_country_snapshot =
(countryOptions || []).find((x: any) => x.id === val)?.cn_addr || '') (countryOptions || []).find((x: any) => x.id === val)?.cn_addrs || '')
" "
> >
<el-option <el-option
v-for="item in countryOptions" v-for="item in countryOptions"
:key="item.id" :key="item.id"
:label="item.cn_addr" :label="item.cn_addrs"
:value="item.id" :value="item.id"
/> />
</el-select> </el-select>
</el-tooltip>
<ElInput v-model="baseForm.customer_country_snapshot" type="hidden" /> <ElInput v-model="baseForm.customer_country_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
@@ -120,7 +126,7 @@
</div> </div>
<ElForm class="items-wrap" label-position="right"> <ElForm class="items-wrap" label-position="right">
<div class="item-row form-box" v-for="(item, idx) in items" :key="idx"> <div class="item-row form-box" v-for="(item, idx) in items" :key="idx">
<ElRow :gutter="12"> <ElRow :gutter="12" class="item-row-wrap">
<ElCol :sm="12" :md="12" :lg="6" :xl="4"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="车型" label-width="85px"> <ElFormItem label="车型" label-width="85px">
<ElInput <ElInput
@@ -205,18 +211,18 @@
</el-select> </el-select>
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
</ElRow> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="里程" label-width="85px"> <ElFormItem label="里程" label-width="85px">
<ElInput v-model="item.mileage" placeholder="请输入里程" /> <ElInput v-model="item.mileage" placeholder="请输入里程" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-if="(item.mileage ?? 0) <= 0"> </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">
<ElInput v-model="item.official_price" placeholder="请输入官方指导价"> <ElInput v-model="item.official_price" placeholder="请输入官方指导价">
<template #suffix> <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 <ElOption
v-for="c in currencyOptions" v-for="c in currencyOptions"
:key="c.currency_code" :key="c.currency_code"
@@ -229,7 +235,7 @@
<ElInput v-model="item.guide_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.guide_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-else> <ElCol :sm="12" :md="12" :lg="6" :xl="4" v-else>
<ElFormItem label="二手挂牌价" label-width="85px"> <ElFormItem label="二手挂牌价" label-width="85px">
<ElInput v-model="item.listing_price" placeholder="请输入二手挂牌价"> <ElInput v-model="item.listing_price" placeholder="请输入二手挂牌价">
<template #suffix> <template #suffix>
@@ -246,7 +252,7 @@
<ElInput v-model="item.listing_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.listing_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-if="(item.mileage ?? 0) <= 0"> <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">
<ElInput v-model="item.discount_price" placeholder="请输入优惠额"> <ElInput v-model="item.discount_price" placeholder="请输入优惠额">
<template #suffix> <template #suffix>
@@ -263,7 +269,7 @@
<ElInput v-model="item.discount_currency_snapshot" type="hidden" /> <ElInput v-model="item.discount_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-else> <ElCol :sm="12" :md="12" :lg="6" :xl="4" v-else>
<ElFormItem label="优惠" label-width="85px"> <ElFormItem label="优惠" label-width="85px">
<ElInput v-model="item.reduction_price" placeholder="请输入优惠"> <ElInput v-model="item.reduction_price" placeholder="请输入优惠">
<template #suffix> <template #suffix>
@@ -280,7 +286,9 @@
<ElInput v-model="item.reduction_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.reduction_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> </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">
<ElInput v-model="item.handling_fee" placeholder="请输入手续费"> <ElInput v-model="item.handling_fee" placeholder="请输入手续费">
<template #suffix> <template #suffix>
@@ -297,7 +305,7 @@
<ElInput v-model="item.helper_fee_currency_snapshot" type="hidden" /> <ElInput v-model="item.helper_fee_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="改装费" label-width="85px"> <ElFormItem label="改装费" label-width="85px">
<ElInput v-model="item.retrofit_fee" placeholder="请输入改装费"> <ElInput v-model="item.retrofit_fee" placeholder="请输入改装费">
<template #suffix> <template #suffix>
@@ -314,7 +322,7 @@
<ElInput v-model="item.modify_fee_currency_snapshot" type="hidden" /> <ElInput v-model="item.modify_fee_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="FOB段运费" label-width="85px"> <ElFormItem label="FOB段运费" label-width="85px">
<ElInput v-model="item.fob_transport_fee" placeholder="请输入FOB段运费"> <ElInput v-model="item.fob_transport_fee" placeholder="请输入FOB段运费">
<template #suffix> <template #suffix>
@@ -331,7 +339,7 @@
<ElInput v-model="item.fob_fee_currency_snapshot" type="hidden" /> <ElInput v-model="item.fob_fee_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="港杂费" label-width="85px"> <ElFormItem label="港杂费" label-width="85px">
<ElInput v-model="item.port_misc_fee" placeholder="请输入港杂费"> <ElInput v-model="item.port_misc_fee" placeholder="请输入港杂费">
<template #suffix> <template #suffix>
@@ -348,7 +356,7 @@
<ElInput v-model="item.port_fee_currency_snapshot" type="hidden" /> <ElInput v-model="item.port_fee_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="海运费" label-width="85px"> <ElFormItem label="海运费" label-width="85px">
<ElInput v-model="item.ocean_freight" placeholder="请输入海运费"> <ElInput v-model="item.ocean_freight" placeholder="请输入海运费">
<template #suffix> <template #suffix>
@@ -365,7 +373,9 @@
<ElInput v-model="item.ocean_freight_currency_snapshot" type="hidden" /> <ElInput v-model="item.ocean_freight_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> </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">
<ElInput v-model="item.unit_price" placeholder="请输入成交价"> <ElInput v-model="item.unit_price" placeholder="请输入成交价">
<template #suffix> <template #suffix>
@@ -382,7 +392,7 @@
<ElInput v-model="item.unit_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.unit_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="总价" label-width="85px"> <ElFormItem label="总价" label-width="85px">
<ElInput v-model="item.total_price" placeholder="请输入总价"> <ElInput v-model="item.total_price" placeholder="请输入总价">
<template #suffix> <template #suffix>
@@ -399,7 +409,7 @@
<ElInput v-model="item.total_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.total_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="利润" label-width="85px"> <ElFormItem label="利润" label-width="85px">
<ElInput <ElInput
v-model="item.profit" v-model="item.profit"
@@ -413,9 +423,9 @@
</ElCol> </ElCol>
</ElRow> </ElRow>
<ElRow :gutter="12"> <ElRow :gutter="12">
<ElCol :span="24" class="row-actions"> <ElCol :span="24" style="text-align: right">
<el-tag effect="light" type="success" @click="copyRow(idx)"> 复制 </el-tag> <el-tag effect="light" type="success" @click="copyRow(idx)" class="row-actions"> 复制 </el-tag>
<el-tag effect="light" @click="addRowAfter(idx)" v-if="idx == items.length - 1"> <el-tag effect="light" @click="addRowAfter(idx)" v-if="idx == items.length - 1" class="row-actions">
新增 新增
</el-tag> </el-tag>
<el-tag type="danger" effect="light" @click="removeRow(idx)" v-if="items.length > 1"> <el-tag type="danger" effect="light" @click="removeRow(idx)" v-if="items.length > 1">
@@ -423,7 +433,6 @@
</el-tag> </el-tag>
</ElCol> </ElCol>
</ElRow> </ElRow>
</div> </div>
<ElRow :gutter="12"> <ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="6">
@@ -510,7 +519,8 @@
@change=" @change="
(val) => (val) =>
(baseForm.shipping_method_snapshot = (baseForm.shipping_method_snapshot =
(transportOptions || []).find((x: any) => x.item_value === val)?.item_label || '') (transportOptions || []).find((x: any) => x.item_value === val)?.item_label ||
'')
" "
> >
<ElOption <ElOption
@@ -591,21 +601,26 @@
<ElForm :model="payment" label-width="55px" class="payment-form" label-position="right"> <ElForm :model="payment" label-width="55px" class="payment-form" label-position="right">
<ElRow :gutter="12"> <ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="汇款人"> <ElFormItem label="汇款人" label-width="55px">
<ElInput v-model="payment.remitter_name" placeholder="请选择汇款人" /> <ElInput v-model="payment.remitter_name" placeholder="请选择汇款人" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="4" :xl="4"> <ElCol :sm="12" :md="12" :lg="4" :xl="4">
<ElFormItem label="汇款国"> <ElFormItem label="汇款国" label-width="55px">
<el-select v-model="payment.remit_country_id" filterable placeholder="请选择汇款国" @change=" <el-select
v-model="payment.remit_country_id"
filterable
placeholder="请选择汇款国"
@change="
(val) => (val) =>
(payment.remit_country_name_snapshot = (payment.remit_country_name_snapshot =
(countryOptions || []).find((x: any) => x.id === val)?.cn_addr || '') (countryOptions || []).find((x: any) => x.id === val)?.cn_addrs || '')
"> "
>
<el-option <el-option
v-for="item in countryOptions" v-for="item in countryOptions"
:key="item.id" :key="item.id"
:label="item.cn_addr" :label="item.cn_addrs"
:value="item.id" :value="item.id"
/> />
</el-select> </el-select>
@@ -613,7 +628,7 @@
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="4" :xl="4"> <ElCol :sm="12" :md="12" :lg="4" :xl="4">
<ElFormItem label="日期"> <ElFormItem label="日期" label-width="55px">
<ElDatePicker <ElDatePicker
v-model="payment.remit_date" v-model="payment.remit_date"
type="date" type="date"
@@ -625,12 +640,17 @@
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="5" :xl="5"> <ElCol :sm="12" :md="12" :lg="5" :xl="5">
<ElFormItem label="账户"> <ElFormItem label="账户" label-width="55px">
<ElSelect v-model="payment.account_id" placeholder="请选择账户" @change=" <ElSelect
v-model="payment.account_id"
placeholder="请选择账户"
@change="
(val) => (val) =>
(payment.account_name_snapshot = (payment.account_name_snapshot =
(accountOptions || []).find((x: any) => x.id === val)?.account_number || '') (accountOptions || []).find((x: any) => x.id === val)?.account_number ||
"> '')
"
>
<ElOption <ElOption
v-for="item in accountOptions" v-for="item in accountOptions"
:key="item.id" :key="item.id"
@@ -642,7 +662,7 @@
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="5" :xl="5"> <ElCol :sm="12" :md="12" :lg="5" :xl="5">
<ElFormItem label="金额"> <ElFormItem label="金额" label-width="55px">
<ElInput v-model="payment.amount" placeholder="请输入金额"> <ElInput v-model="payment.amount" placeholder="请输入金额">
<template #suffix> <template #suffix>
<ElSelect <ElSelect
@@ -650,7 +670,9 @@
style="width: 64px" style="width: 64px"
@change=" @change="
(val) => { (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 || '' payment.currency_name_snapshot = found?.currency_name || ''
} }
" "
@@ -669,9 +691,21 @@
</ElCol> </ElCol>
</ElRow> </ElRow>
<ElRow :gutter="12"> <ElRow :gutter="12">
<ElCol :span="24" style="text-align: right;"> <ElCol :span="24" style="text-align: right">
<ElButton type="danger" size="small" @click="removePaymentItem(idx)" :disabled="paymentItems.length === 1">删除</ElButton> <ElButton
<ElButton type="primary" size="small" @click="addPaymentItem" v-if="idx === paymentItems.length - 1">添加收款信息</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> </ElCol>
</ElRow> </ElRow>
</ElForm> </ElForm>
@@ -821,11 +855,15 @@
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { Search } from '@element-plus/icons-vue' import { Search } from '@element-plus/icons-vue'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import { CrmService } from '@/api/crmApi'
import { useStockingForm } from '@/composables/useStockingForm' import { useStockingForm } from '@/composables/useStockingForm'
import { onMounted } from 'vue' import { onMounted } from 'vue'
const { getUserInfo } = useUserStore() defineOptions({ name: 'StockingAdd' }) // 定义组件名称,用于 KeepAlive 缓存控制
const { getUserInfo } = useUserStore()
const route = useRoute()
const stocking_id = route.query.id
// 使用公共的备货单表单逻辑 // 使用公共的备货单表单逻辑
const { const {
// 数据 // 数据
@@ -856,6 +894,7 @@
// 方法 // 方法
initializeForm, initializeForm,
populateFromDetail,
handleSubmit, handleSubmit,
getCurrencyRate, getCurrencyRate,
validateContractRate, validateContractRate,
@@ -891,10 +930,19 @@
handleVehicleCurrentChange, handleVehicleCurrentChange,
chooseVehicle chooseVehicle
} = useStockingForm(false) // isFinal = false } = useStockingForm(false) // isFinal = false
// 获取详情数据
const getdetilfn = async () => {
const res = await CrmService.getStockDetail({ id: stocking_id })
populateFromDetail(res)
}
// 初始化表单 // 初始化表单
onMounted(async () => { onMounted(async () => {
await initializeForm() await initializeForm()
// 如果有ID,代表复制 加载详情数据
if (stocking_id) {
await getdetilfn()
}
}) })
</script> </script>
@@ -944,10 +992,7 @@
} }
.row-actions { .row-actions {
display: flex; margin-left: 8px;
align-items: center;
gap: 8px;
justify-content: flex-end;
} }
/* 利润为负数时,输入文字变红(兼容 Element Plus disabled 样式) */ /* 利润为负数时,输入文字变红(兼容 Element Plus disabled 样式) */
@@ -962,18 +1007,6 @@
background-color: var(--el-fill-color-blank) !important; background-color: var(--el-fill-color-blank) !important;
box-shadow: 0 0 0 1px var(--el-input-border-color, #dcdfe6) inset !important; box-shadow: 0 0 0 1px var(--el-input-border-color, #dcdfe6) inset !important;
} }
.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 { .submit-wrap {
display: flex; display: flex;
@@ -1042,7 +1075,7 @@
text-align: right; text-align: right;
} }
.form-box { .form-box {
border-bottom: 1px solid #F2F4F6; border-bottom: 1px solid #f2f4f6;
margin-bottom: 20px; margin-bottom: 20px;
padding: 8px 0px 20px; padding: 8px 0px 20px;
} }
+32 -31
View File
@@ -37,13 +37,13 @@
@change=" @change="
(val) => (val) =>
(baseForm.clearance_country_snapshot = (baseForm.clearance_country_snapshot =
(countryOptions || []).find((x: any) => x.id === val)?.cn_addr || '') (countryOptions || []).find((x: any) => x.id === val)?.cn_addrs || '')
" "
> >
<el-option <el-option
v-for="item in countryOptions" v-for="item in countryOptions"
:key="item.id" :key="item.id"
:label="item.cn_addr" :label="item.cn_addrs"
:value="item.id" :value="item.id"
/> />
</el-select> </el-select>
@@ -96,13 +96,13 @@
@change=" @change="
(val) => (val) =>
(baseForm.customer_country_snapshot = (baseForm.customer_country_snapshot =
(countryOptions || []).find((x: any) => x.id === val)?.cn_addr || '') (countryOptions || []).find((x: any) => x.id === val)?.cn_addrs || '')
" "
> >
<el-option <el-option
v-for="item in countryOptions" v-for="item in countryOptions"
:key="item.id" :key="item.id"
:label="item.cn_addr" :label="item.cn_addrs"
:value="item.id" :value="item.id"
/> />
</el-select> </el-select>
@@ -206,14 +206,12 @@
</el-select> </el-select>
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
</ElRow> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElRow :gutter="12">
<ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="里程" label-width="85px"> <ElFormItem label="里程" label-width="85px">
<ElInput v-model="item.mileage" placeholder="请输入里程" /> <ElInput v-model="item.mileage" placeholder="请输入里程" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-if="(item.mileage ?? 0) <= 0"> <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">
<ElInput v-model="item.official_price" placeholder="请输入官方指导价"> <ElInput v-model="item.official_price" placeholder="请输入官方指导价">
<template #suffix> <template #suffix>
@@ -230,7 +228,7 @@
<ElInput v-model="item.guide_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.guide_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-else> <ElCol :sm="12" :md="12" :lg="6" :xl="4" v-else>
<ElFormItem label="二手挂牌价" label-width="85px"> <ElFormItem label="二手挂牌价" label-width="85px">
<ElInput v-model="item.listing_price" placeholder="请输入二手挂牌价"> <ElInput v-model="item.listing_price" placeholder="请输入二手挂牌价">
<template #suffix> <template #suffix>
@@ -247,7 +245,7 @@
<ElInput v-model="item.listing_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.listing_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-if="(item.mileage ?? 0) <= 0"> <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">
<ElInput v-model="item.discount_price" placeholder="请输入优惠额"> <ElInput v-model="item.discount_price" placeholder="请输入优惠额">
<template #suffix> <template #suffix>
@@ -264,7 +262,7 @@
<ElInput v-model="item.discount_currency_snapshot" type="hidden" /> <ElInput v-model="item.discount_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6" v-else> <ElCol :sm="12" :md="12" :lg="6" :xl="4" v-else>
<ElFormItem label="优惠" label-width="85px"> <ElFormItem label="优惠" label-width="85px">
<ElInput v-model="item.reduction_price" placeholder="请输入优惠"> <ElInput v-model="item.reduction_price" placeholder="请输入优惠">
<template #suffix> <template #suffix>
@@ -281,7 +279,7 @@
<ElInput v-model="item.reduction_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.reduction_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="手续费" label-width="85px"> <ElFormItem label="手续费" label-width="85px">
<ElInput v-model="item.handling_fee" placeholder="请输入手续费"> <ElInput v-model="item.handling_fee" placeholder="请输入手续费">
<template #suffix> <template #suffix>
@@ -298,7 +296,7 @@
<ElInput v-model="item.helper_fee_currency_snapshot" type="hidden" /> <ElInput v-model="item.helper_fee_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="改装费" label-width="85px"> <ElFormItem label="改装费" label-width="85px">
<ElInput v-model="item.retrofit_fee" placeholder="请输入改装费"> <ElInput v-model="item.retrofit_fee" placeholder="请输入改装费">
<template #suffix> <template #suffix>
@@ -315,7 +313,7 @@
<ElInput v-model="item.modify_fee_currency_snapshot" type="hidden" /> <ElInput v-model="item.modify_fee_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="FOB段运费" label-width="85px"> <ElFormItem label="FOB段运费" label-width="85px">
<ElInput v-model="item.fob_transport_fee" placeholder="请输入FOB段运费"> <ElInput v-model="item.fob_transport_fee" placeholder="请输入FOB段运费">
<template #suffix> <template #suffix>
@@ -332,7 +330,7 @@
<ElInput v-model="item.fob_fee_currency_snapshot" type="hidden" /> <ElInput v-model="item.fob_fee_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="港杂费" label-width="85px"> <ElFormItem label="港杂费" label-width="85px">
<ElInput v-model="item.port_misc_fee" placeholder="请输入港杂费"> <ElInput v-model="item.port_misc_fee" placeholder="请输入港杂费">
<template #suffix> <template #suffix>
@@ -349,7 +347,7 @@
<ElInput v-model="item.port_fee_currency_snapshot" type="hidden" /> <ElInput v-model="item.port_fee_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="海运费" label-width="85px"> <ElFormItem label="海运费" label-width="85px">
<ElInput v-model="item.ocean_freight" placeholder="请输入海运费"> <ElInput v-model="item.ocean_freight" placeholder="请输入海运费">
<template #suffix> <template #suffix>
@@ -366,7 +364,7 @@
<ElInput v-model="item.ocean_freight_currency_snapshot" type="hidden" /> <ElInput v-model="item.ocean_freight_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="成交价" label-width="85px"> <ElFormItem label="成交价" label-width="85px">
<ElInput v-model="item.unit_price" placeholder="请输入成交价"> <ElInput v-model="item.unit_price" placeholder="请输入成交价">
<template #suffix> <template #suffix>
@@ -383,7 +381,7 @@
<ElInput v-model="item.unit_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.unit_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="总价" label-width="85px"> <ElFormItem label="总价" label-width="85px">
<ElInput v-model="item.total_price" placeholder="请输入总价"> <ElInput v-model="item.total_price" placeholder="请输入总价">
<template #suffix> <template #suffix>
@@ -400,7 +398,7 @@
<ElInput v-model="item.total_price_currency_snapshot" type="hidden" /> <ElInput v-model="item.total_price_currency_snapshot" type="hidden" />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="利润" label-width="85px"> <ElFormItem label="利润" label-width="85px">
<ElInput <ElInput
v-model="item.profit" v-model="item.profit"
@@ -412,7 +410,7 @@
</ElInput> </ElInput>
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="6" :xl="4">
<ElFormItem label="车架号" label-width="85px"> <ElFormItem label="车架号" label-width="85px">
<ElInput v-model="item.vin" placeholder="请输入车架号"></ElInput> <ElInput v-model="item.vin" placeholder="请输入车架号"></ElInput>
</ElFormItem> </ElFormItem>
@@ -584,22 +582,22 @@
<div v-for="(payment, idx) in paymentItems" :key="idx" class="payment-item"> <div v-for="(payment, idx) in paymentItems" :key="idx" class="payment-item">
<ElForm :model="payment" label-width="55px" class="payment-form"> <ElForm :model="payment" label-width="55px" class="payment-form">
<ElRow :gutter="12"> <ElRow :gutter="12">
<ElCol :span="4"> <ElCol :sm="12" :md="12" :lg="6" :xl="6">
<ElFormItem label="汇款人"> <ElFormItem label="汇款人" label-width="55px">
<ElInput v-model="payment.remitter_name" placeholder="请选择汇款人" disabled /> <ElInput v-model="payment.remitter_name" placeholder="请选择汇款人" disabled />
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="6" :xl="6"> <ElCol :sm="12" :md="12" :lg="4" :xl="4">
<ElFormItem label="汇款国"> <ElFormItem label="汇款国" label-width="55px">
<el-select disabled v-model="payment.remit_country_id" filterable placeholder="请选择汇款国" @change=" <el-select disabled v-model="payment.remit_country_id" filterable placeholder="请选择汇款国" @change="
(val) => (val) =>
(payment.remit_country_name_snapshot = (payment.remit_country_name_snapshot =
(countryOptions || []).find((x: any) => x.id === val)?.cn_addr || '') (countryOptions || []).find((x: any) => x.id === val)?.cn_addrs || '')
"> ">
<el-option <el-option
v-for="item in countryOptions" v-for="item in countryOptions"
:key="item.id" :key="item.id"
:label="item.cn_addr" :label="item.cn_addrs"
:value="item.id" :value="item.id"
/> />
</el-select> </el-select>
@@ -607,7 +605,7 @@
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="4" :xl="4"> <ElCol :sm="12" :md="12" :lg="4" :xl="4">
<ElFormItem label="日期"> <ElFormItem label="日期" label-width="55px">
<ElDatePicker <ElDatePicker
disabled disabled
v-model="payment.remit_date" v-model="payment.remit_date"
@@ -620,7 +618,7 @@
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="5" :xl="5"> <ElCol :sm="12" :md="12" :lg="5" :xl="5">
<ElFormItem label="账户"> <ElFormItem label="账户" label-width="55px">
<ElSelect disabled v-model="payment.account_name_snapshot" placeholder="请选择账户" @change=" <ElSelect disabled v-model="payment.account_name_snapshot" placeholder="请选择账户" @change="
(val) => (val) =>
(payment.account_id = (payment.account_id =
@@ -637,7 +635,7 @@
</ElFormItem> </ElFormItem>
</ElCol> </ElCol>
<ElCol :sm="12" :md="12" :lg="5" :xl="5"> <ElCol :sm="12" :md="12" :lg="5" :xl="5">
<ElFormItem label="金额"> <ElFormItem label="金额" label-width="55px">
<ElInput disabled v-model="payment.amount" placeholder="请输入金额"> <ElInput disabled v-model="payment.amount" placeholder="请输入金额">
<template #suffix> <template #suffix>
<ElSelect <ElSelect
@@ -821,6 +819,9 @@
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
import { useStockingForm } from '@/composables/useStockingForm' import { useStockingForm } from '@/composables/useStockingForm'
import { onMounted } from 'vue' import { onMounted } from 'vue'
defineOptions({ name: 'StockingFinalAdd' }) // 定义组件名称,用于 KeepAlive 缓存控制
const route = useRoute() const route = useRoute()
const stocking_id = route.query.id const stocking_id = route.query.id
const { getUserInfo } = useUserStore() const { getUserInfo } = useUserStore()
@@ -1064,7 +1065,7 @@
} }
.form-box { .form-box {
border-bottom: 1px solid #F2F4F6; border-bottom: 1px solid #F2F4F6;
margin-bottom: 20px; margin-bottom: 25px;
padding: 8px 0px 20px; padding: 8px 0px 25px;
} }
</style> </style>
+70 -5
View File
@@ -1,9 +1,9 @@
<template> <template>
<div class="stocking-page"> <div class="stocking-page">
<div class="stocking-toolbar boxshadow"> <div class="stocking-toolbar boxshadow">
<div class="toolbar-left"> <!-- <div class="toolbar-left">
<ElButton type="primary" v-ripple @click="handleCreate">创建备货单</ElButton> <ElButton type="primary" v-ripple @click="handleCreate">创建备货单</ElButton>
</div> </div> -->
<div class="toolbar-right"> <div class="toolbar-right">
<el-input <el-input
v-model="keyword" v-model="keyword"
@@ -55,9 +55,18 @@
</ElTableColumn> </ElTableColumn>
<ElTableColumn label="操作" fixed="right" min-width="120" align="center"> <ElTableColumn label="操作" fixed="right" min-width="120" align="center">
<template #default="scope"> <template #default="scope">
<ElRow :gutter="10" justify="center"> <el-link
<el-button link type="primary" @click="handleView1(scope.row)">查看终版</el-button> v-if="scope.row.file_url != null && scope.row.file_url != ''"
</ElRow> type="warning"
underline="never"
@click="printfn(scope.row)"
style="margin-right: 8px"
>
<i class="iconfont-sys">&#xe782;</i> 打印预览
</el-link>
<el-link type="primary" underline="never" @click="handleView1(scope.row)">
<i class="iconfont-sys">&#xe76c;</i> 查看终版
</el-link>
</template> </template>
</ElTableColumn> </ElTableColumn>
</template> </template>
@@ -116,6 +125,37 @@
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
<!-- PDF 预览弹窗 -->
<el-dialog
v-model="pdf.visible"
title="打印预览"
width="80%"
top="40px"
:close-on-click-modal="false"
>
<div style="max-height: 70vh; display: flex; flex-direction: column; gap: 12px">
<div style="display: flex; justify-content: flex-end; gap: 8px">
<el-button @click="download">下载</el-button>
</div>
<div
v-if="pdf.images.length"
style="overflow: auto; border: 1px solid #eee; border-radius: 6px; padding: 8px"
>
<img
v-for="(img, idx) in pdf.images"
:key="idx"
:src="img"
style="display: block; width: 100%; margin-bottom: 8px; background: #fff"
/>
</div>
<iframe
v-else-if="pdf.blobUrl || pdf.url"
ref="frameRef"
:src="pdf.blobUrl || pdf.url"
style="flex: 1; width: 100%; border: 1px solid #eee; border-radius: 6px"
/>
</div>
</el-dialog>
</div> </div>
</template> </template>
@@ -123,6 +163,7 @@
import { router } from '@/router' import { router } from '@/router'
import { CrmService } from '@/api/crmApi' import { CrmService } from '@/api/crmApi'
import { useAuth } from '@/composables/useAuth' import { useAuth } from '@/composables/useAuth'
import { usePdfPreview } from '@/composables/usePdfPreview'
import OrderDetailContent from '@/components/custom/OrderDetailContent.vue' import OrderDetailContent from '@/components/custom/OrderDetailContent.vue'
import type { OrderData } from '@/composables/useOrderDetailDialog' import type { OrderData } from '@/composables/useOrderDetailDialog'
// 订单详情弹窗 // 订单详情弹窗
@@ -187,6 +228,23 @@
// TODO: 跳转到创建备货单页面 // TODO: 跳转到创建备货单页面
router.push('/crmpc/stocking/Add') router.push('/crmpc/stocking/Add')
} }
// PDF 预览/打印(公共)
const { pdf, frameRef, openWithResponse, download, preparePreview, prepareImages } =
usePdfPreview()
//打印
const printfn = (row: any) => {
CrmService.printStock({ id: row.id })
.then((res) => {
openWithResponse(res)
// 优先转成图片以适配不带插件的环境
prepareImages()
// 同时保留 blob 预览作为兜底
preparePreview()
})
.catch((err) => {
console.log(err)
})
}
const contractFile = ref<{ name: string; url: string; file_name: string } | null>(null) const contractFile = ref<{ name: string; url: string; file_name: string } | null>(null)
const handleView1 = async (row: any) => { const handleView1 = async (row: any) => {
const res = await CrmService.checkStock({ id: row.id }) const res = await CrmService.checkStock({ id: row.id })
@@ -324,6 +382,13 @@
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
:deep(.el-table__empty-block) {
height: 100% !important;
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
}
.stocking-page { .stocking-page {
background: var(--art-main-bg-color); background: var(--art-main-bg-color);
min-height: 100vh; min-height: 100vh;
+13 -6
View File
@@ -108,13 +108,9 @@
> >
<i class="iconfont-sys">&#xe76c;</i> 查看终版 <i class="iconfont-sys">&#xe76c;</i> 查看终版
</el-link> </el-link>
<!-- <el-link <el-link type="success" underline="never" @click="copys(scope.row)">
type="success"
underline="never"
@click="copys(scope.row)"
>
<i class="iconfont-sys">&#xe8b7;</i> 复制 <i class="iconfont-sys">&#xe8b7;</i> 复制
</el-link> --> </el-link>
</ElRow> </ElRow>
</template> </template>
</ElTableColumn> </ElTableColumn>
@@ -220,6 +216,8 @@
// import { useAuth } from '@/composables/useAuth' // import { useAuth } from '@/composables/useAuth'
// const { hasAuth } = useAuth() // const { hasAuth } = useAuth()
defineOptions({ name: 'StockingList' }) // 定义组件名称,用于 KeepAlive 缓存控制
const loading = ref(false) const loading = ref(false)
const keyword = ref('') const keyword = ref('')
const tableRef = ref() const tableRef = ref()
@@ -479,6 +477,15 @@
// 可以在这里添加具体的打印逻辑 // 可以在这里添加具体的打印逻辑
window.print() window.print()
} }
//复制订单
const copys = (row: any) => {
console.log('复制订单:', row.id)
router.push({
path: '/crmpc/stocking/Add',
query: { id: row.id } // 可带客户名等参数
})
// 添加具体的复制逻辑
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
+359
View File
@@ -0,0 +1,359 @@
<template>
<div class="color-page">
<div class="color-toolbar boxshadow">
<div class="color-search-group">
<el-form-item label="关键字:" label-width="70px">
<el-input
style="min-width: 120px"
v-model="keyword"
placeholder="请输入颜色编码或名称"
clearable
@keyup.enter="getColorList"
/>
</el-form-item>
<el-form-item label="类型:" label-width="50px">
<el-select v-model="typeFilter" placeholder="全部类型" clearable style="min-width: 120px">
<el-option label="外观颜色" :value="1" />
<el-option label="内饰颜色" :value="2" />
</el-select>
</el-form-item>
<el-form-item label="状态:" label-width="50px">
<el-select
v-model="statusFilter"
placeholder="全部状态"
clearable
style="min-width: 120px"
>
<el-option label="启用" :value="1" />
<el-option label="停用" :value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getColorList" v-ripple>搜索</el-button>
<el-button @click="resetSearch" v-ripple>重置</el-button>
</el-form-item>
</div>
</div>
<div class="boxshadow">
<ElRow>
<div style="width: 12px"></div>
<ElCol :xs="24" :sm="12" :lg="6" class="el-col2">
<ElButton @click="showDialog('add')" v-ripple v-if="hasAuth('color@add')" type="primary">
新增颜色
</ElButton>
</ElCol>
</ElRow>
<ArtTable
ref="tableRef"
row-key="id"
:loading="loading"
:data="tableData"
:currentPage="pagination.currentPage"
:pageSize="pagination.pageSize"
:total="pagination.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
<template #default>
<ElTableColumn label="颜色编码" prop="color_code" min-width="120" />
<ElTableColumn label="颜色名称" prop="color_text" min-width="150" />
<ElTableColumn label="类型" prop="type" width="120">
<template #default="scope">
<ElTag :type="scope.row.type === 1 ? 'primary' : 'success'">
{{ scope.row.type === 1 ? '外观颜色' : '内饰颜色' }}
</ElTag>
</template>
</ElTableColumn>
<ElTableColumn label="排序" prop="sort" width="80" />
<ElTableColumn label="状态" prop="status" width="100">
<template #default="scope">
<ElTag :type="scope.row.status ? 'success' : 'info'">
{{ scope.row.status ? '启用' : '停用' }}
</ElTag>
</template>
</ElTableColumn>
<ElTableColumn label="创建时间" prop="created_at" min-width="160" />
<ElTableColumn fixed="right" label="操作" width="200px">
<template #default="scope">
<ElRow>
<el-button
link
@click="showDialog('edit', scope.row)"
v-if="hasAuth('color@update')"
>编辑</el-button
>
<el-button
type="danger"
link
@click="deleteColor(scope.row)"
v-if="hasAuth('color@destroy')"
>
删除
</el-button>
</ElRow>
</template>
</ElTableColumn>
</template>
</ArtTable>
</div>
<!-- 新增/编辑对话框 -->
<ElDialog
v-model="dialogVisible"
:title="dialogType === 'add' ? '新增颜色' : '编辑颜色'"
align-center
width="600px"
>
<ElForm ref="formRef" :model="form" :rules="rules" label-width="100px" class="form">
<ElFormItem label="颜色编码" prop="color_code">
<ElInput v-model="form.color_code" placeholder="请输入颜色编码" />
</ElFormItem>
<ElFormItem label="颜色名称" prop="color_text">
<ElInput v-model="form.color_text" placeholder="请输入颜色名称" />
</ElFormItem>
<ElFormItem label="类型" prop="type">
<el-select v-model="form.type" placeholder="请选择颜色类型" style="width: 100%">
<el-option label="外观颜色" :value="1" />
<el-option label="内饰颜色" :value="2" />
</el-select>
</ElFormItem>
<ElFormItem label="排序" prop="sort">
<ElInputNumber v-model="form.sort" :min="0" :max="999" style="width: 100%" />
</ElFormItem>
<ElFormItem label="状态">
<ElSwitch v-model="form.status" :active-value="1" :inactive-value="0" />
</ElFormItem>
</ElForm>
<template #footer>
<div class="dialog-footer">
<ElButton @click="dialogVisible = false">取消</ElButton>
<ElButton type="primary" @click="handleSubmit(formRef)">提交</ElButton>
</div>
</template>
</ElDialog>
</div>
</template>
<script setup lang="ts">
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules } from 'element-plus'
import { vehicleService } from '@/api/crmpc/vehicleApi'
import { useAuth } from '@/composables/useAuth'
const { hasAuth } = useAuth()
defineOptions({ name: 'VehicleColor' })
// 响应式数据
const loading = ref(false)
const dialogVisible = ref(false)
const dialogType = ref('add')
const formRef = ref<FormInstance>()
const keyword = ref<string>('')
const typeFilter = ref<number | undefined>(undefined)
const statusFilter = ref<number | undefined>(undefined)
// 表单数据
const form = reactive<any>({
id: '',
color_code: '',
color_text: '',
type: 1,
status: 1,
sort: 0
})
// 表单验证规则
const rules = reactive<FormRules>({
color_code: [{ required: true, message: '请输入颜色编码', trigger: 'blur' }],
color_text: [{ required: true, message: '请输入颜色名称', trigger: 'blur' }],
type: [{ required: true, message: '请选择颜色类型', trigger: 'change' }]
})
// 分页数据
const pagination = reactive({
currentPage: 1,
pageSize: 10,
total: 0
})
// 表格数据
const tableData = ref<any[]>([])
const tableRef = ref()
// 生命周期
onMounted(() => {
getColorList()
})
// 监听搜索条件变化
watch([keyword, typeFilter, statusFilter], () => {
pagination.currentPage = 1
getColorList()
})
// 获取颜色列表
const getColorList = async () => {
loading.value = true
try {
const { currentPage, pageSize } = pagination
const params = {
current: currentPage,
size: pageSize,
keyword: keyword.value
}
const { records, current, size, total } = await vehicleService.getColorList(params)
tableData.value = records || []
Object.assign(pagination, { currentPage: current, pageSize: size, total })
} catch (error) {
console.error('获取颜色列表失败:', error)
ElMessage.error('获取颜色列表失败')
} finally {
loading.value = false
}
}
// 重置搜索条件
const resetSearch = () => {
keyword.value = ''
typeFilter.value = undefined
statusFilter.value = undefined
pagination.currentPage = 1
getColorList()
}
// 处理分页变化
const handleSizeChange = (newPageSize: number) => {
pagination.pageSize = newPageSize
getColorList()
}
const handleCurrentChange = (newCurrentPage: number) => {
pagination.currentPage = newCurrentPage
getColorList()
}
// 显示对话框
const showDialog = (type: string, row?: any) => {
dialogVisible.value = true
dialogType.value = type
if (type === 'edit' && row) {
// 编辑模式
Object.assign(form, {
id: row.id,
color_code: row.color_code,
color_text: row.color_text,
type: row.type,
status: row.status,
sort: row.sort || 0
})
} else {
// 新增模式
Object.assign(form, {
id: '',
color_code: '',
color_text: '',
type: 1,
status: 1,
sort: 0
})
}
}
// 删除颜色
const deleteColor = (row: any) => {
ElMessageBox.confirm('确定删除该颜色吗?', '删除确认', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'error'
}).then(async () => {
try {
const { message } = await vehicleService.colorDelete({ id: row.id })
ElMessage.success(message)
getColorList()
} catch (error) {
console.error('删除失败:', error)
ElMessage.error('删除失败')
}
})
}
// 提交表单
const handleSubmit = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate(async (valid) => {
if (!valid) return
try {
if (dialogType.value === 'add') {
// 新增
const { message } = await vehicleService.colorAdd({
color_code: form.color_code,
color_text: form.color_text,
type: form.type,
status: form.status,
sort: form.sort
})
ElMessage.success(message)
} else {
// 编辑
const { message } = await vehicleService.colorEdit({
id: form.id,
color_code: form.color_code,
color_text: form.color_text,
type: form.type,
status: form.status,
sort: form.sort
})
ElMessage.success(message)
}
dialogVisible.value = false
getColorList()
} catch (error) {
console.error('操作失败:', error)
ElMessage.error('操作失败')
}
})
}
</script>
<style lang="scss" scoped>
:deep(.el-table__empty-block) {
height: 100% !important;
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
}
.color-page {
background: var(--art-main-bg-color);
min-height: 100vh;
}
.color-toolbar {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
padding: 20px 20px;
background: var(--art-main-bg-color);
}
.color-search-group {
display: flex;
gap: 12px;
align-items: center;
}
.form {
padding: 20px 0;
}
.dialog-footer {
text-align: right;
}
.el-col2 {
margin-bottom: 16px;
}
</style>
File diff suppressed because it is too large Load Diff