This commit is contained in:
zlwu committed 2026-06-21 12:41:39 +08:00
1 parent 299609706c
commit e46c0480d4
87 files changed
+11975 -15543

No files matched your search

+3 -8
View File
@@ -455,7 +455,7 @@
/>
</el-form-item>
<el-form-item label="车牌号" prop="vehicleNo">
<DbVehicleSelect ref="vehicleSelectRef" v-model="formData.vehicleNo" />
<PlVehicleSelect v-model="formData.vehicleNo" />
</el-form-item>
<el-form-item label="计划号" prop="planNo" class="form-col-span-2">
<el-input v-model="formData.planNo" placeholder="请输入计划号" :readonly="isPlanNoReadonly" />
@@ -511,7 +511,7 @@
import DbCrmProductSelect from '@/components/business/db/DbCrmProductSelect.vue'
import DbInventoryRelatedViewDialog from '@/components/business/db/DbInventoryRelatedViewDialog.vue'
import DbPoundSlipQrcodeDialog from '@/components/business/db/DbPoundSlipQrcodeDialog.vue'
import DbVehicleSelect from '@/components/business/db/DbVehicleSelect.vue'
import PlVehicleSelect from '@/components/business/pl/PlVehicleSelect.vue'
import { useDbInstantSearch } from '@/composables/useDbInstantSearch'
import { $modal } from '@/utils/modal'
import {
@@ -549,7 +549,6 @@
const modalOpen = ref(false)
const editingRecord = ref<InventoryRecord | null>(null)
const vehicleSelectRef = ref<InstanceType<typeof DbVehicleSelect> | null>(null)
const relatedModalOpen = ref(false)
const loadingRelated = ref(false)
const relatedData = ref<InventoryRelatedData>({ plan: null, weighing: null })
@@ -597,7 +596,7 @@
partnerCompany: [{ required: true, message: '请输入往来单位', trigger: 'blur' }],
productId: [{ required: true, message: '请选择 CRM 产品', trigger: 'change' }],
quantity: [{ required: true, message: '请输入数量', trigger: 'blur' }],
vehicleNo: [{ required: true, message: '请输入车牌号', trigger: 'blur' }]
vehicleNo: [{ required: true, message: '请选择车牌号', trigger: 'change' }]
}
const formatKgToTon = (kg: number | undefined | null) => {
@@ -926,10 +925,6 @@
if (!valid) return
saving.value = true
try {
if (formData.vehicleNo?.trim()) {
await vehicleSelectRef.value?.ensureVehicleExists()
}
const cleanData = (data: Record<string, unknown>) => {
const cleaned: Record<string, unknown> = {}
for (const key in data) {
-289
View File
@@ -1,289 +0,0 @@
<template>
<div class="page-container">
<section class="panel">
<div class="panel-top">
<h2 class="title-bar-heading">车牌管理</h2>
</div>
<div class="list-toolbar">
<div class="list-toolbar-row db-list-toolbar-row">
<div class="list-toolbar-selected">
已选 <span class="sel-num">{{ selectedRows.length }}</span> 项
</div>
<el-input
v-model="searchKeyword"
class="db-toolbar-quick-search-input"
placeholder="车牌号 / 备注"
clearable
@keyup.enter="handleQuickSearch"
@clear="handleQuickSearchClear"
>
<template #suffix>
<el-icon class="db-quick-search-icon" @click="handleQuickSearch"><Search /></el-icon>
</template>
</el-input>
<el-button class="btn-main" type="primary" @click="handleAdd">
<el-icon><Plus /></el-icon>
新增车牌号
</el-button>
<el-button class="btn-ghost" :loading="loading" @click="loadData">
<el-icon><Refresh /></el-icon>
刷新
</el-button>
</div>
</div>
<div class="list-body list-wrap">
<el-table
class="list-table"
:data="tableData"
v-loading="loading"
stripe
row-key="id"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" min-width="55" align="center" />
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column
prop="vehicleNo"
label="车牌号"
min-width="160"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column
prop="remarks"
label="备注"
min-width="240"
align="center"
header-align="center"
show-overflow-tooltip
/>
<el-table-column
label="操作"
min-width="200"
align="center"
header-align="center"
fixed="right"
>
<template #default="{ row }">
<div class="db-op-actions">
<el-button class="btn-op-item primary" @click="handleEdit(row)">
<el-icon><Edit /></el-icon>
编辑
</el-button>
<el-button class="btn-op-item danger" @click="handleDelete(row.id)">
<el-icon><Delete /></el-icon>
删除
</el-button>
</div>
</template>
</el-table-column>
</el-table>
<div class="pagination list-pager-bar">
<el-pagination
v-show="total > 0"
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
:page-sizes="[10, 20, 50, 100]"
layout="total, sizes, prev, pager, next, jumper"
@current-change="applyPagination"
@size-change="handleSizeChange"
/>
</div>
</div>
</section>
<el-dialog
v-model="modalOpen"
:title="editingVehicle ? '修改车牌号' : '新增车牌号'"
width="520px"
align-center
destroy-on-close
:close-on-click-modal="false"
class="dialog-form-layout"
modal-class="order-module-dialog-mask"
@close="handleModalClose"
>
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-position="top"
class="form-grid-2"
scroll-to-error
>
<el-form-item label="车牌号" prop="vehicleNo">
<el-input v-model="formData.vehicleNo" placeholder="请输入车牌号" clearable />
</el-form-item>
<el-form-item label="备注" prop="remarks" class="form-col-span-2">
<el-input v-model="formData.remarks" type="textarea" :rows="3" placeholder="选填" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleModalClose">
<el-icon><Close /></el-icon>
取消
</el-button>
<el-button type="primary" :loading="saving" @click="handleSubmit">
<el-icon><Check /></el-icon>
确定
</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts">
/**
* UI 模式 P01 · 标准列表 CRUD
* 参考:/#/crm/quote · src/views/crm/quote/index.vue
*/
import { Check, Close, Delete, Edit, Plus, Refresh, Search } from '@element-plus/icons-vue'
import { vehicleApi, type Vehicle, type VehicleCreate } from '@/api/db/vehicles'
import { useDbInstantSearch } from '@/composables/useDbInstantSearch'
import { $modal } from '@/utils/modal'
defineOptions({ name: 'DbVehicles' })
const loading = ref(false)
const saving = ref(false)
const allRecords = ref<Vehicle[]>([])
const tableData = ref<Vehicle[]>([])
const total = ref(0)
const currentPage = ref(1)
const pageSize = ref(10)
const searchKeyword = ref('')
const selectedRows = ref<Vehicle[]>([])
const modalOpen = ref(false)
const editingVehicle = ref<Vehicle | null>(null)
const formRef = ref()
const formData = reactive<VehicleCreate>({
vehicleNo: '',
remarks: ''
})
const formRules = {
vehicleNo: [{ required: true, message: '请输入车牌号', trigger: 'blur' }]
}
const applyPagination = () => {
total.value = allRecords.value.length
const start = (currentPage.value - 1) * pageSize.value
const end = start + pageSize.value
tableData.value = allRecords.value.slice(start, end)
}
const loadData = async () => {
loading.value = true
try {
const keyword = searchKeyword.value.trim()
allRecords.value = await vehicleApi.list(keyword || undefined)
const maxPage = Math.ceil(allRecords.value.length / pageSize.value) || 1
if (currentPage.value > maxPage) {
currentPage.value = 1
}
applyPagination()
} catch (error) {
console.error('加载车牌列表失败', error)
} finally {
loading.value = false
}
}
const handleQuickSearch = () => {
currentPage.value = 1
loadData()
}
const handleQuickSearchClear = () => {
searchKeyword.value = ''
handleQuickSearch()
}
const handleSelectionChange = (selection: Vehicle[]) => {
selectedRows.value = selection
}
const handleSizeChange = (size: number) => {
pageSize.value = size
currentPage.value = 1
applyPagination()
}
const handleAdd = () => {
editingVehicle.value = null
Object.assign(formData, { vehicleNo: '', remarks: '' })
modalOpen.value = true
}
const handleEdit = (record: Vehicle) => {
editingVehicle.value = record
Object.assign(formData, {
vehicleNo: record.vehicleNo,
remarks: record.remarks || ''
})
modalOpen.value = true
}
const handleDelete = async (id: string) => {
try {
await $modal.confirm('确定要删除该车牌号吗?')
await vehicleApi.delete(id)
$modal.msgSuccess('删除成功')
loadData()
} catch {
// 用户取消或请求失败
}
}
const handleSubmit = async () => {
if (!formRef.value) return
await formRef.value.validate(async (valid: boolean) => {
if (!valid) return
saving.value = true
try {
const payload: VehicleCreate = {
vehicleNo: formData.vehicleNo.trim(),
remarks: formData.remarks?.trim() || null
}
if (editingVehicle.value) {
await vehicleApi.update(editingVehicle.value.id, payload)
$modal.msgSuccess('修改成功')
} else {
await vehicleApi.create(payload)
$modal.msgSuccess('新增成功')
}
modalOpen.value = false
loadData()
} catch (error) {
console.error('保存车牌失败', error)
} finally {
saving.value = false
}
})
}
const handleModalClose = () => {
modalOpen.value = false
editingVehicle.value = null
formRef.value?.resetFields()
}
useDbInstantSearch(() => searchKeyword.value, handleQuickSearch)
onMounted(() => {
loadData()
})
</script>
+3 -7
View File
@@ -357,7 +357,7 @@
scroll-to-error
>
<el-form-item label="车牌号" prop="vehicleNo">
<DbVehicleSelect ref="vehicleSelectRef" v-model="formData.vehicleNo" />
<PlVehicleSelect v-model="formData.vehicleNo" />
</el-form-item>
<el-form-item label="产品" prop="productId">
<DbCrmProductSelect
@@ -504,7 +504,7 @@
import DbCrmProductSelect from '@/components/business/db/DbCrmProductSelect.vue'
import DbRelatedViewDialog from '@/components/business/db/DbRelatedViewDialog.vue'
import { buildWeighingRelatedSections } from '@/components/business/db/db-related-view'
import DbVehicleSelect from '@/components/business/db/DbVehicleSelect.vue'
import PlVehicleSelect from '@/components/business/pl/PlVehicleSelect.vue'
import { useDbInstantSearch } from '@/composables/useDbInstantSearch'
import { $modal } from '@/utils/modal'
import { inventoryApi } from '@/api/db/inventory'
@@ -552,7 +552,6 @@
const timeRange = ref<[string, string] | null>([formatYmd(new Date()), formatYmd(new Date())])
const modalOpen = ref(false)
const vehicleSelectRef = ref<InstanceType<typeof DbVehicleSelect> | null>(null)
const editingRecord = ref<WeighingRecord | null>(null)
const relatedModalOpen = ref(false)
const loadingRelated = ref(false)
@@ -592,7 +591,7 @@
})
const formRules = {
vehicleNo: [{ required: true, message: '请输入车牌号', trigger: 'blur' }],
vehicleNo: [{ required: true, message: '请选择车牌号', trigger: 'change' }],
productId: [{ required: true, message: '请选择 CRM 产品', trigger: 'change' }],
supplier: [{ required: true, message: '请输入供货单位', trigger: 'blur' }],
consignee: [{ required: true, message: '请输入收货单位', trigger: 'blur' }]
@@ -903,9 +902,6 @@
if (!valid) return
saving.value = true
try {
if (formData.vehicleNo?.trim()) {
await vehicleSelectRef.value?.ensureVehicleExists()
}
const hasGrossWeight = formData.grossWeight && formData.grossWeight > 0
const hasTareWeight = formData.tareWeight && formData.tareWeight > 0
if (hasGrossWeight && hasTareWeight) {