fanzherong_v vor 2 Tagen
Ursprung
Commit
ab9e29fe74
18 geänderte Dateien mit 1421 neuen und 2 gelöschten Zeilen
  1. 8 0
      snowy-admin-web/src/api/biz/bizAppointmentRecordApi.js
  2. 8 0
      snowy-admin-web/src/api/biz/bizLoadDispatchApi.js
  3. 144 0
      snowy-admin-web/src/views/biz/bizappointload/detail.vue
  4. 202 0
      snowy-admin-web/src/views/biz/bizappointload/form.vue
  5. 623 0
      snowy-admin-web/src/views/biz/bizappointload/index.vue
  6. 2 2
      snowy-admin-web/src/views/biz/bizloadappoint/index.vue
  7. 43 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/controller/BizAppointmentRecordController.java
  8. 4 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/entity/BizAppointmentRecord.java
  9. 2 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/BizAppointmentRecordMapper.java
  10. 49 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/mapping/BizAppointmentRecordMapper.xml
  11. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentRecordPageParam.java
  12. 9 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/BizAppointmentRecordService.java
  13. 252 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/impl/BizAppointmentRecordServiceImpl.java
  14. 24 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/controller/BizLoadDispatchController.java
  15. 4 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/mapper/BizLoadDispatchMapper.java
  16. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/param/BizLoadDispatchPageParam.java
  17. 10 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/service/BizLoadDispatchService.java
  18. 31 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/service/impl/BizLoadDispatchServiceImpl.java

+ 8 - 0
snowy-admin-web/src/api/biz/bizAppointmentRecordApi.js

@@ -13,6 +13,10 @@ export default {
 	bizAppointmentRecordPage(data) {
 		return request('page', data, 'get')
 	},
+	//获取起卸预约列表
+	bizAppointmentLoadRecordPage(data) {
+		return request('getLoadPage', data, 'get')
+	},
 	// 提交预约记录表单 edit为true时为编辑,默认为新增
 	bizAppointmentRecordSubmitForm(data, edit = false) {
 		return request(edit ? 'edit' : 'add', data)
@@ -21,6 +25,10 @@ export default {
 	bizAppointmentTempSubmitForm(data, edit = false) {
 		return request(edit ? 'editTemp' : 'addTemp', data)
 	},
+	//起卸预约
+	bizAppointmentLoadSubmitForm(data, edit = false) {
+		return request(edit ? 'editLoad' : 'addLoad', data)
+	},
 	// 删除预约记录
 	bizAppointmentRecordDelete(data) {
 		return request('delete', data)

+ 8 - 0
snowy-admin-web/src/api/biz/bizLoadDispatchApi.js

@@ -40,5 +40,13 @@ export default {
 	// 获取起卸预约分配列表
 	getPageList(data){
 		return request('getPageList',data,'get')
+	},
+	//获取装卸点位列表
+	getList(data){
+		return request('getList',data,'get')
+	},
+	//获取装卸时间列表
+	getListTime(data){
+		return request('getListTime',data,'get')
 	}
 }

+ 144 - 0
snowy-admin-web/src/views/biz/bizappointload/detail.vue

@@ -0,0 +1,144 @@
+<template>
+	<xn-form-container title="详情" :width="900" :visible="visible" :destroy-on-close="true" @close="onClose">
+		<a-form ref="formRef" :model="formData" :label-col="labelCol4" :wrapper-col="wrapperCol20">
+			<a-descriptions :column="4" size="middle" bordered class="mb-2" :label-style="labelStyle" :contentStyle="contentStyle">
+				<a-descriptions-item label="起卸单号" :span="2">{{ formData.loadNumber }}</a-descriptions-item>
+				<a-descriptions-item label="车牌号" :span="2">{{ formData.licenseNumber }}</a-descriptions-item>
+				<a-descriptions-item label="车辆轴数" :span="2">{{ formData.axleNumber+'轴' }}</a-descriptions-item>
+				<a-descriptions-item label="客户名称" :span="2">{{ formData.customerName }}</a-descriptions-item>
+				<a-descriptions-item label="联系人" :span="2">{{ formData.customerContactName }}</a-descriptions-item>
+				<a-descriptions-item label="货品名称" :span="2">{{ formData.goodsName }}</a-descriptions-item>
+				<a-descriptions-item label="货品编码" :span="2">{{ formData.goodsCode }}</a-descriptions-item>
+				<a-descriptions-item label="司机姓名" :span="2">{{ formData.driverName }}</a-descriptions-item>
+				<a-descriptions-item label="司机电话" :span="2">{{ formData.driverMobile }}</a-descriptions-item>
+				<a-descriptions-item label="装卸点位" :span="2">{{ formData.loadPoint }}</a-descriptions-item>
+				<a-descriptions-item label="装卸开始时间" :span="2">{{ formData.loadBeginTime }}</a-descriptions-item>
+				<a-descriptions-item label="装卸结束时间" :span="2">{{ formData.loadEndTime }}</a-descriptions-item>
+				<a-descriptions-item label="创建人" :span="2">{{ formData.createUserName }}</a-descriptions-item>
+				<a-descriptions-item label="创建时间" :span="2">{{ formData.createTime }}</a-descriptions-item>
+
+				<a-descriptions-item label="预约状态" :span="2">
+					<a-tag
+						:color="
+							formData.status === '1'
+								? 'volcano'
+								: formData.status === '2'
+								  ? 'red'
+								  : formData.status === '3'
+								  ? 'processing'
+								  : formData.status === '4'
+								  ? 'warning'
+								  : formData.status === '5'
+								  ? 'magenta'
+								  : formData.status === '6'
+								  ? 'orange'
+								  : formData.status === '7'
+								  ? 'gold'
+								   : formData.status === '8'
+								  ? 'lime'
+								   : formData.status === '9'
+								  ? 'green'
+								  : formData.status === '10'
+								  ? 'cyan'
+								  : formData.status === '11'
+								  ? 'success'
+								  : formData.status === '12'
+								  ? 'blue'
+								  : formData.status === '13'
+								  ? 'geekblue'
+								  : 'error'
+						"
+					>
+						{{ $TOOL.dictTypeData('appointment_status', formData.status) }}
+					</a-tag>
+				</a-descriptions-item>
+				<a-descriptions-item label="完成装货时间" :span="2">{{ formData.completeSendTime }}</a-descriptions-item>
+				<a-descriptions-item label="审核备注" :span="4">{{ formData.appointmentReason }}</a-descriptions-item>
+				<a-descriptions-item label="司机确认" :span="4">
+					<a-image :width="200" :src="formData.driverSign" />
+				</a-descriptions-item>
+				<a-descriptions-item label="卸货重量(吨)" :span="4">{{ formData.unloadWeight }}</a-descriptions-item>
+				<a-descriptions-item label="司机回签" :span="4">
+					<div v-for="(item,index) in fileList " :key="item.value">
+						<a-image :width="200" :src="item.url" />
+					</div>
+				</a-descriptions-item>
+				<a-descriptions-item label="签收审核" :span="4" v-if="formData.auditSign!=null && formData.auditSign!=''">
+					<a-image :width="200" :src="formData.auditSign" />
+				</a-descriptions-item>
+			</a-descriptions>
+		</a-form>
+	</xn-form-container>
+</template>
+
+<script setup name="recordDoubleForm">
+	import { cloneDeep } from 'lodash-es'
+	import sysConfig from "@/config";
+	// 默认是关闭状态
+	const visible = ref(false)
+	const formData = ref({})
+	const table = ref()
+	const resultJson = ref()
+
+	const labelStyle = {
+		width: '20%'
+	}
+	const contentStyle = {
+		width: '30%'
+	}
+
+	const labelCol4 = ref({span: 4, style: 'width: 26%; line-height: 20px; white-space: normal',})
+	const labelCol8 = ref({span: 8, style: 'width: 26%; line-height: 20px; white-space: normal',})
+	const wrapperCol20 = ref({span: 20})
+
+	const fileList = ref([])
+	// 打开抽屉
+	const onOpen = (record) => {
+		visible.value = true
+		//getRecordDoubleDetail(record)
+		if(record){
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+			fileList.value = []
+			if(formData.value.unloadImg!=null){
+				for (var i=0;i<formData.value.unloadImg.split(',').length;i++){
+					fileList.value.push({
+						name: formData.value.unloadName.split(',')[i],
+						url:sysConfig.PREVIEW_PATH + formData.value.unloadImg.split(',')[i]
+					})
+				}
+			}
+		}
+
+	}
+	const getRecordDoubleDetail = (record) => {
+		const param = {
+			id: record.id
+		}
+		tbRecordDoubleApi.recordDoubleDetailPic(param).then((data) => {
+			Object.assign(record, data)
+			formData.value = record
+		})
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		resultJson.value = ''
+		visible.value = false
+	}
+
+	// 调用这个函数将子组件的一些数据和方法暴露出去
+	defineExpose({
+		onOpen
+	})
+</script>
+
+<style scoped>
+	.imgDiv ::v-deep .ant-image {
+		margin-left: 20px;
+		margin-top: 10px;
+	}
+	.imgDiv ::v-deep .ant-image-mask-info {
+		margin-left: 20px;
+		margin-top: 10px;
+	}
+</style>

+ 202 - 0
snowy-admin-web/src/views/biz/bizappointload/form.vue

@@ -0,0 +1,202 @@
+<template>
+	<xn-form-container
+		:title="formData.id ? '编辑预约记录' : '增加预约记录'"
+		:width="700"
+		v-model:open="open"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-form ref="formRef" :model="formData" :rules="formRules" :wrapper-col="wrapperCol" :label-col="labelCol">
+			<a-form-item label="起卸订单:" name="orderId">
+				<a-select v-model:value="formData.orderId" placeholder="请选择订单信息"
+						  :options="orderIdList" @change="onChangeOrder"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="装卸点位:" name="loadPointId">
+				<a-select v-model:value="formData.loadPointId" placeholder="请选择装卸点位"
+						  :options="loadPointIdList" @change="onChangePoint"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="装卸时间:" name="loadTimeId">
+				<a-select v-model:value="formData.loadTimeId" placeholder="请选择装卸时间"
+						  :options="loadTimeIdList"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="车牌号:" name="licenseNumber">
+				<a-input v-model:value="formData.licenseNumber" placeholder="请输入车牌号" allow-clear />
+			</a-form-item>
+<!--			<a-form-item label="预约时段:" name="timeId">
+				<a-select v-model:value="formData.timeId" placeholder="请选择预约时段"
+						  :options="timeIdList"
+				> </a-select>
+			</a-form-item>-->
+			<a-form-item label="车辆轴数:" name="overId">
+				<a-select v-model:value="formData.overId" placeholder="请选择车辆轴数"
+						  :options="overIdList"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="司机姓名:" name="driverName">
+				<a-input v-model:value="formData.driverName" placeholder="请输入司机姓名" allow-clear />
+			</a-form-item>
+			<a-form-item label="司机电话:" name="driverMobile">
+				<a-input v-model:value="formData.driverMobile" placeholder="请输入司机电话" allow-clear />
+			</a-form-item>
+		</a-form>
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="bizAppointmentRecordForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import bizAppointmentRecordApi from '@/api/biz/bizAppointmentRecordApi'
+	import bizAppointmentTimeApi from "@/api/biz/bizAppointmentTimeApi";
+	import bizOrderApi from '@/api/biz/bizOrderApi'
+	import bizExcessConfigApi from "@/api/biz/bizExcessConfigApi";
+	import bizOrderLoadApi from "@/api/biz/bizOrderLoadApi";
+	import bizLoadAppointApi from "@/api/biz/bizLoadAppointApi";
+	import bizLoadDispatchApi from "@/api/biz/bizLoadDispatchApi";
+
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+	const orderIdList = ref()
+	const timeIdList = ref()
+	const overIdList = ref()
+	const loadPointIdList = ref()
+	const loadTimeIdList = ref()
+
+	//设置表单样式
+	const labelCol = ref({ span: 5})
+	const wrapperCol = ref({ span: 16})
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+		//查询订单信息
+		bizLoadAppointApi.getList({status:'5,6'}).then((res)=>{
+			orderIdList.value = res.map((item)=>{
+				return{
+					value:item.id,
+					label:item.loadNumber
+				}
+			})
+		})
+
+		//查询车辆轴数
+		bizExcessConfigApi.getList().then((res)=>{
+			overIdList.value = res.map((item)=>{
+				return{
+					value:item.id,
+					label:item.vehicleAxleNumber+'轴'
+				}
+			})
+		})
+
+		//查询装卸点位信息
+		if(formData.value.orderId){
+			bizLoadDispatchApi.getList({appointId:formData.value.orderId,loadType:'2'}).then((res)=>{
+				loadPointIdList.value=res.map((item)=>{
+					return{
+						value:item.loadPointId,
+						label:item.loadPoint
+					}
+				})
+			})
+		}
+
+		//查询装卸时间信息
+		if(formData.value.orderId && formData.value.loadPointId){
+			bizLoadDispatchApi.getListTime({orderId:formData.value.orderId,loadPointId:formData.value.loadPointId,loadType:'2'}).then((res)=>{
+				loadTimeIdList.value = res.map((item)=>{
+					return{
+						value:item.loadTimeId,
+						label:item.beginTime+'~'+item.endTime
+					}
+				})
+			})
+		}
+	}
+
+
+	//订单点击事件
+	const onChangeOrder = (value) =>{
+		formData.value.loadTimeId = ''
+		formData.value.loadPointId = ''
+		loadTimeIdList.value = ''
+		console.log("value:"+JSON.stringify(value))
+		bizLoadDispatchApi.getList({appointId:value,loadType:'2'}).then((res)=>{
+			loadPointIdList.value=res.map((item)=>{
+				return{
+					value:item.loadPointId,
+					label:item.loadPoint
+				}
+			})
+		})
+	}
+
+	//装卸点位点击事件
+	const onChangePoint = (value) =>{
+		formData.value.loadTimeId = ''
+		bizLoadDispatchApi.getListTime({orderId:formData.value.orderId,loadPointId:value,loadType:'2'}).then((res)=>{
+			loadTimeIdList.value = res.map((item)=>{
+				return{
+					value:item.loadTimeId,
+					label:item.beginTime+'~'+item.endTime
+				}
+			})
+		})
+	}
+
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		orderId: [required('请选择订单信息')],
+		licenseNumber: [required('请输入车牌号')],
+		//timeId: [required('请选择预约时段')],
+		overId: [required('请选择车辆轴数')],
+		driverName:[required('请输入司机姓名')],
+		driverMobile:[required('请输入司机电话')],
+		loadPointId:[required('请选择装卸点位')],
+		loadTimeId:[required('请选择装卸时间')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				bizAppointmentRecordApi
+					.bizAppointmentLoadSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 623 - 0
snowy-admin-web/src/views/biz/bizappointload/index.vue

@@ -0,0 +1,623 @@
+<template>
+	<a-card :bordered="false" style="margin-bottom: 10px" class="mb-2">
+		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
+			<a-row :gutter="24">
+				<a-col :span="6">
+					<a-form-item label="起卸单号" name="loadNumber">
+						<a-input v-model:value="searchFormState.loadNumber" placeholder="起卸单号查询" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="车牌号" name="licenseNumber">
+						<a-input v-model:value="searchFormState.licenseNumber" placeholder="车牌号码查询" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="客户名称" name="customerName">
+						<a-input v-model:value="searchFormState.customerName" placeholder="客户名称查询" />
+					</a-form-item>
+				</a-col>
+				<template v-if="advanced">
+
+					<a-col :span="6">
+						<a-form-item label="货品名称" name="goodsName">
+							<a-input v-model:value="searchFormState.goodsName" placeholder="货品名称查询" />
+						</a-form-item>
+					</a-col>
+					<a-col :span="6">
+						<a-form-item label="司机名称" name="driverName">
+							<a-input v-model:value="searchFormState.driverName" placeholder="司机名称查询" />
+						</a-form-item>
+					</a-col>
+					<a-col :span="6">
+						<a-form-item label="司机电话" name="driverMobile">
+							<a-input v-model:value="searchFormState.driverMobile" placeholder="司机电话查询" />
+						</a-form-item>
+					</a-col>
+
+					<a-col :span="6">
+						<a-form-item label="预约状态" name="status">
+							<a-select v-model:value="searchFormState.status" placeholder="预约状态查询"
+									  :options="statusList"
+							> </a-select>
+						</a-form-item>
+					</a-col>
+				</template>
+				<a-col :span="6">
+					<a-button type="primary" @click="tableRef.refresh()">查询</a-button>
+					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
+					<a @click="toggleAdvanced" style="margin-left: 8px">
+						{{ advanced ? '收起' : '展开' }}
+						<component :is="advanced ? 'up-outlined' : 'down-outlined'" />
+					</a>
+				</a-col>
+			</a-row>
+		</a-form>
+	</a-card>
+	<a-card :bordered="false">
+		<s-table
+			ref="tableRef"
+			:columns="columns"
+			:data="loadData"
+			bordered
+			:row-key="(record) => record.id"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizAppointmentRecordAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<a-button @click="exportTotal" v-if="hasPerm('bizAppointmentExport')">
+						<template #icon>
+							<export-outlined/>
+						</template>
+						导出
+					</a-button>
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'orderInfo'">
+					<div class="time-list">
+						<p>名称:{{ record.orderName }}</p>
+						<p style="margin-bottom: 0">编号:{{ record.orderNumber }}</p>
+					</div>
+				</template>
+				<template v-if="column.dataIndex === 'carInfo'">
+					<div class="time-list">
+						<p>车牌号:{{ record.licenseNumber }}</p>
+						<p style="margin-bottom: 0">车轴数:{{ record.axleNumber + '轴' }}</p>
+					</div>
+				</template>
+				<template v-if="column.dataIndex === 'timeInfo'">
+<!--					<span>{{record.beginTime + '~' + record.endTime}}</span>-->
+					<div class="time-list">
+						<p>开始时间:{{ record.beginTime }}</p>
+						<p style="margin-bottom: 0">结束时间:{{ record.endTime }}</p>
+					</div>
+				</template>
+				<template v-if="column.dataIndex === 'customerInfo'">
+					<span>{{record.customerName}}</span>
+				</template>
+				<template v-if="column.dataIndex === 'driverInfo'">
+					<div class="time-list">
+						<p>姓名:{{ record.driverName }}</p>
+						<p style="margin-bottom: 0">电话:{{ record.driverMobile }}</p>
+					</div>
+				</template>
+				<template v-if="column.dataIndex === 'goodsInfo'">
+					<div class="time-list">
+						<p>名称:{{ record.goodsName }}</p>
+						<p style="margin-bottom: 0">编码:{{ record.goodsCode }}</p>
+					</div>
+				</template>
+				<template v-if="column.dataIndex === 'axleNumber'">
+					{{record.axleNumber+'轴'}}
+				</template>
+				<template v-if="column.dataIndex === 'status'">
+					<a-tag
+						:color="
+							record.status === '1'
+								? 'volcano'
+								: record.status === '2'
+								  ? 'red'
+								  : record.status === '3'
+								  ? 'processing'
+								  : record.status === '4'
+								  ? 'warning'
+								  : record.status === '5'
+								  ? 'magenta'
+								  : record.status === '6'
+								  ? 'orange'
+								  : record.status === '7'
+								  ? 'gold'
+								   : record.status === '8'
+								  ? 'lime'
+								   : record.status === '9'
+								  ? 'green'
+								  : record.status === '10'
+								  ? 'cyan'
+								  : record.status === '11'
+								  ? 'success'
+								  : record.status === '12'
+								  ? 'blue'
+								  : record.status === '13'
+								  ? 'geekblue'
+								  : 'error'
+						"
+					>
+						{{ $TOOL.dictTypeData('appointment_status', record.status) }}
+					</a-tag>
+				</template>
+				<template v-if="column.dataIndex === 'action'">
+					<a @click="showModal(record)" v-if="record.status!='1'&& record.status!='2' && record.status!='10' && record.status!='11'&&
+						record.status!='12' && record.status!='13' && record.status!='14' && record.status!='15'">二维码</a>
+
+					<a-divider type="vertical" v-if="record.status!='1'&& record.status!='2' && record.status!='10' && record.status!='11'&&
+						record.status!='12' && record.status!='13' && record.status!='14' && record.status!='15'"/>
+
+					<a-space>
+						<a-dropdown>
+							<a class="ant-dropdown-link">
+								更多
+								<DownOutlined />
+							</a>
+
+							<template #overlay>
+								<a-menu>
+									<a-menu-item>
+										<a @click="detailRef.onOpen(record)">详情</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizAppointmentAudit') && (record.status == '1')">
+										<a style="color: #ffaa00" @click="reviewRef.showModal(record.id)">审核</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizAppointmentRecordEdit') && (record.status == '2' || record.status == '4')">
+										<a style="color:blue" @click="formRef.onOpen(record)" >编辑</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizAppointmentRecordDelete') && (record.status == '2' || record.status == '4')">
+										<a style="color:red" type="link" danger size="small" @click="deleteConfig(record)">删除</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizAppointmentDriverConfim') && record.status == '8'">
+										<a @click="XnSignNameRef.show(record.recordId)" >确认</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizAppointmentDriverSign') && record.status=='10' && record.orderType=='1'">
+										<a  @click="signRef.onOpen(record)" >回签</a>
+									</a-menu-item>
+									<a-menu-item v-if="record.status=='4'">
+										<a style="color:green"  @click="cancel(record)" >取消</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizAppointmentDriverExit') && (record.status=='5' || record.status=='6' || record.status=='7' || record.status=='8')">
+										<a style="color:orange"  @click="exit(record)" >授权出场</a>
+									</a-menu-item>
+
+
+								</a-menu>
+							</template>
+						</a-dropdown>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="tableRef.refresh()" />
+	<Review ref="reviewRef" @successful="tableRef.refresh(true)" />
+	<Detail ref="detailRef" @successful="tableRef.refresh()" />
+	<Sign ref="signRef" @successful="tableRef.refresh(true)" />
+
+	<XnSignName ref="XnSignNameRef" :image="searchFormState.driverSign" @successful="signSuccess" />
+	<a-modal v-model:visible="open" title="二维码" width="600px" style="height: 700px">
+		<div id="qrcode" style="text-align: center; margin:  15px 5px 15px 5px">
+			<a-row>
+				<a-col :span="13" id="colFlag">
+					<div style="margin-top:10px;font-size:16px;">
+						<p id="projectCodeFlag">起卸单号:{{ nowRecord.loadNumber }}</p>
+						<p id="projectCodeFlag">客户名称:{{ nowRecord.customerName }}</p>
+						<p id="projectCodeFlag">货品名称:{{ nowRecord.goodsName }}</p>
+						<p id="projectCodeFlag">司机姓名:{{ nowRecord.driverName }}</p>
+						<p id="projectCodeFlag">预约状态:{{ $TOOL.dictTypeData('appointment_status', nowRecord.status) }}</p>
+					</div>
+				</a-col>
+				<a-col :span="11">
+					<a-image width="250"  height="100%" :src="qrCodeUrl.codeUrl"></a-image>
+				</a-col>
+			</a-row>
+		</div>
+		<template #footer>
+			<a-button @click="closeQrCode">关闭</a-button>
+			<a-button type="primary" @click="downloadFile">下载</a-button>
+		</template>
+	</a-modal>
+</template>
+
+<script setup name="bizappointmentrecord">
+	import { cloneDeep } from 'lodash-es'
+	import Form from './form.vue'
+	import Detail from './detail.vue'
+	import bizAppointmentRecordApi from '@/api/biz/bizAppointmentRecordApi'
+	import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
+	import {Modal} from 'ant-design-vue';
+	import {createVNode} from 'vue';
+	//import Review from './review.vue'
+	import tool from '@/utils/tool'
+	import QRCode from 'qrcode'
+	import html2canvas from 'html2canvas'
+	import downloadUtil from '@/utils/downloadUtil'
+	import bizRecordApi from '@/api/biz/bizRecordApi'
+	//import Sign from './sign.vue'
+	import bizOrderApi from "@/api/biz/bizOrderApi";
+
+	const submitLoading = ref(false)
+	const tableRef = ref()
+	const signRef = ref()
+	const formRef = ref()
+	const reviewRef = ref()
+	const detailRef = ref()
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+
+	const nowRecord = ref()
+	const XnSignNameRef = ref()
+
+	//查询数据
+	const searchFormState = ref({})
+	const searchFormRef = ref()
+	const statusList = tool.dictList('appointment_status')
+
+	// 查询区域显示更多控制
+	const advanced = ref(false)
+	const toggleAdvanced = () => {
+		advanced.value = !advanced.value
+	}
+
+	const columns = [
+		{
+			title: '起卸单号',
+			dataIndex: 'loadNumber',
+			align:'center',
+			width:150
+		},
+		{
+			title: '车牌号',
+			dataIndex: 'licenseNumber',
+			width:150,
+			align: 'center'
+		},
+		/*{
+			title: '提货时间',
+			dataIndex: 'timeInfo',
+			align:'center',
+			width:200
+		},*/
+		{
+			title: '客户名称',
+			dataIndex: 'customerInfo',
+			align:'center',
+			width:180
+		},
+		{
+			title: '货品信息',
+			dataIndex: 'goodsInfo',
+			width:160
+		},
+		{
+			title: '司机信息',
+			dataIndex: 'driverInfo',
+			width: 160
+		},
+		{
+			title: '车辆轴数',
+			dataIndex: 'axleNumber',
+			width: 110,
+			align:'center'
+		},
+		/*{
+			title: '供应商',
+			dataIndex: 'supplierName',
+			width: 110,
+			align:'center'
+		},*/
+		{
+			title: '状态',
+			dataIndex: 'status',
+			align: 'center',
+			width:130
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	columns.push({
+		title: '操作',
+		dataIndex: 'action',
+		align: 'center',
+		width: 150,
+
+	})
+
+	const selectedRowKeys = ref([])
+	// 列表选择配置
+	const options = {
+		// columns数字类型字段加入 needTotal: true 可以勾选自动算账
+		alert: {
+			show: true,
+			clear: () => {
+				selectedRowKeys.value = ref([])
+			}
+		},
+		rowSelection: {
+			onChange: (selectedRowKey, selectedRows) => {
+				selectedRowKeys.value = selectedRowKey
+			}
+		}
+	}
+	const loadData = (parameter) => {
+		const searchFormParam = cloneDeep(searchFormState.value)
+		searchFormParam.type = '3'
+		return bizAppointmentRecordApi.bizAppointmentLoadRecordPage(Object.assign(parameter, searchFormParam)).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		tableRef.value.refresh(true)
+	}
+	// 删除
+	const deleteBizAppointmentRecord = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		bizAppointmentRecordApi.bizAppointmentRecordDelete(params).then(() => {
+			tableRef.value.refresh(true)
+		})
+	}
+	// 删除
+	const deleteConfig = (record) => {
+
+		Modal.confirm({
+			title: '确定删除该数据吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				let params = [
+					{
+						id: record.id
+					}
+				]
+
+				bizAppointmentRecordApi
+					.bizAppointmentRecordDelete(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+
+	//取消预约
+	const cancel = (record) => {
+
+		Modal.confirm({
+			title: '确定要取消吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				let params =
+					{
+						id: record.id
+					}
+
+
+				bizAppointmentRecordApi
+					.bizAppointmentCancel(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+
+
+	//授权出场
+	const exit = (record) => {
+
+		Modal.confirm({
+			title: '确定要授权出场吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				let params =
+					{
+						id: record.id
+					}
+
+
+				bizAppointmentRecordApi
+					.bizAppointmentExit(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+
+	// 批量删除
+	const deleteBatchBizAppointmentRecord = (params) => {
+		bizAppointmentRecordApi.bizAppointmentRecordDelete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+
+	//二维码
+	const open = ref(false);
+	const qrCodeUrl = ref({})
+	const showModal = (record) => {
+		nowRecord.value = record
+		open.value = true;
+		getQrCode(record)
+
+	};
+
+	const getQrCode = (record) => {
+		//QRCode.toDataURL("id:"+record.id+"saleCode:"+record.saleCode, {
+		let param = {
+			id:record.id,
+			licenseNumber:record.licenseNumber
+		}
+		QRCode.toDataURL(JSON.stringify(param), {
+			errorCorrectionLevel: 'H',
+			margin: 1,
+			height: 206,
+			width: 206,
+			type: '10',
+			scal: 177,
+			color: {
+				dark: '#000' // 二维码背景颜色
+			},
+			rendererOpts: {
+				quality: 0.9
+			}
+		})
+			.then((url) => {
+				qrCodeUrl.value.codeUrl = url
+			})
+			.catch((err) => {
+				console.error(err)
+			})
+	}
+
+	const closeQrCode = () => {
+		open.value = false;
+	}
+
+	// 下载二维码
+	const downloadFile = () => {
+		const qrcodeDiv = document.getElementById('qrcode');
+		html2canvas(qrcodeDiv, {
+			logging: false,
+			allowTaint: true,
+			scale: window.devicePixelRatio,
+			scrollY: 0,
+			scrollX: 0,
+			useCORS: true,
+			backgroundColor: '#ffffff'
+		})
+			.then(function (canvas) {
+				const a = window.document.createElement('a')
+				a.href = canvas.toDataURL('image/png')
+				a.download = '二维码'
+				a.click()
+				this.$message.success('正在进行下载保存')
+			})
+			.catch((err) => {
+				console.log(err)
+			})
+	}
+
+
+	//导出
+	const exportTotal = () => {
+		/*const searchFormParam = cloneDeep(searchFormState.value)
+		bizAppointmentRecordApi.exportRecord(Object.assign(searchFormParam)).then((res)=>{
+			downloadUtil.resultDownload(res)
+		})*/
+		Modal.confirm({
+			title: '确定要导出记录吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				const searchFormParam = cloneDeep(searchFormState.value)
+
+				bizAppointmentRecordApi
+					.exportRecord(Object.assign(searchFormParam))
+					.then((res) => {
+						downloadUtil.resultDownload(res)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+
+	// 签名板组件回调
+	const signSuccess = (value) => {
+		const param = {
+			id:value.id,
+			driverSign: value.value
+		}
+		bizRecordApi.updateDriverSign(param).then(() => {
+			tableRef.value.refresh(true)
+		})
+	}
+</script>
+
+<style lang="less" scoped>
+/** 表头居中 */
+:deep .ant-table-thead > tr > th {
+	text-align: center;
+}
+
+.time-list {
+	-webkit-text-size-adjust: none;
+	font-size: 13px;
+	display: flex;
+	flex-direction: column;
+
+	p {
+		white-space: nowrap;
+		span {
+			display: inline-block;
+			font-weight: 600;
+			height: 16px;
+			line-height: 16px;
+			border-radius: 5px;
+			text-align: center;
+			margin-right: 2px;
+			padding: 0 5px;
+		}
+		.blueTag {
+			color: #1890ff;
+			background: rgba(24, 144, 255, 0.1);
+		}
+		.orangeTag {
+			color: #ff7c18;
+			background: rgba(24, 144, 255, 0.1);
+		}
+		.greenTag {
+			color: rgb(82, 196, 26);
+			background: rgba(82, 196, 26, 0.1);
+		}
+		.purpleTag {
+			color: rgb(77, 26, 196);
+			background: rgba(82, 196, 26, 0.1);
+		}
+		.showNum {
+			display: inline-block;
+			height: 16px;
+			line-height: 16px;
+			width: 45px;
+			border-radius: 5px;
+			text-align: center;
+			margin-right: 2px;
+			text-align: right;
+		}
+	}
+}
+</style>

+ 2 - 2
snowy-admin-web/src/views/biz/bizloadappoint/index.vue

@@ -98,10 +98,10 @@
 								<a-menu-item v-if="hasPerm('bizLoadAppointDelete') && (record.status == '0')">
 									<a style="color:red" size="small" type="link" @click="deleteConfig(record)">删除</a>
 								</a-menu-item>
-								<a-menu-item v-if="hasPerm('bizLoadDispatch') && (record.status == '4' || record.status=='5') && record.arriveStatus == '2'">
+								<a-menu-item v-if="hasPerm('bizLoadDispatch') && (record.status == '4' || record.status=='5' || record.status=='6') && record.arriveStatus == '2'">
 									<a style="color:blue" size="small" type="link" @click="dispatchRef.onOpen(record)">装货调度</a>
 								</a-menu-item>
-								<a-menu-item v-if="hasPerm('bizDispatchLoad') && (record.status == '4' || record.status=='5') && record.arriveStatus == '2'">
+								<a-menu-item v-if="hasPerm('bizDispatchLoad') && (record.status == '4' || record.status=='5' || record.status=='6') && record.arriveStatus == '2'">
 									<a style="color:green" size="small" type="link" @click="dispatchLoadRef.onOpen(record)">起卸调度</a>
 								</a-menu-item>
 							</a-menu>

+ 43 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/controller/BizAppointmentRecordController.java

@@ -285,4 +285,47 @@ public class BizAppointmentRecordController {
         bizAppointmentRecordService.exitTemp(bizAppointmentRecordIdParam);
         return CommonResult.ok();
     }
+
+
+    /**
+     * 添加起卸预约
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "添加起卸预约")
+    @CommonLog("添加起卸预约")
+    @CommonNoRepeat
+    @PostMapping("/biz/bizappointmentrecord/addLoad")
+    public CommonResult<String> addLoad(@RequestBody @Valid BizAppointmentRecordAddParam bizAppointmentRecordAddParam) {
+        bizAppointmentRecordService.addLoad(bizAppointmentRecordAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑起卸预约记录
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "编辑起卸预约记录")
+    @CommonLog("编辑起卸预约记录")
+    @PostMapping("/biz/bizappointmentrecord/editLoad")
+    public CommonResult<String> editLoad(@RequestBody @Valid BizAppointmentRecordEditParam bizAppointmentRecordEditParam) {
+        bizAppointmentRecordService.editLoad(bizAppointmentRecordEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取起卸预约列表
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "获取起卸预约列表")
+    @SaCheckPermission("/biz/bizappointmentrecord/getLoadPage")
+    @GetMapping("/biz/bizappointmentrecord/getLoadPage")
+    public CommonResult<Page<BizAppointmentRecord>> getLoadPage(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
+        return CommonResult.data(bizAppointmentRecordService.getLoadPage(bizAppointmentRecordPageParam));
+    }
 }

+ 4 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/entity/BizAppointmentRecord.java

@@ -199,4 +199,8 @@ public class BizAppointmentRecord extends CommonEntity {
     /**完成装货时间*/
     @TableField(exist = false)
     private Date completeSendTime;
+
+    /**起卸单号*/
+    @TableField(exist = false)
+    private String loadNumber;
 }

+ 2 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/BizAppointmentRecordMapper.java

@@ -37,4 +37,6 @@ public interface BizAppointmentRecordMapper extends BaseMapper<BizAppointmentRec
     List<Map<String,Object>> gerVehicleTotal(@Param("beginTime") String beginTime,@Param("endTime") String endTime);
 
     List<BizAppointmentRecord> getRecordList(@Param("ew") QueryWrapper<BizAppointmentRecord> ew);
+
+    Page<BizAppointmentRecord> getLoadPage(@Param("page") Page<BizAppointmentRecord> page,@Param("ew") QueryWrapper<BizAppointmentRecord> ew);
 }

+ 49 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/mapping/BizAppointmentRecordMapper.xml

@@ -129,4 +129,53 @@
                 left join biz_order bo on bo.id = bar.order_id
             ${ew.customSqlSegment}
     </select>
+    <select id="getLoadPage"
+            resultType="vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord">
+        SELECT
+            bar.id,
+            bar.order_id,
+            bar.license_number,
+            bla.load_number,
+            bla.order_type,
+            bc.NAME customerName,
+            bc.contact customerContactName,
+            bg.GOODS_NAME goodsName,
+            bg.GOODS_MODEL goodsModel,
+            bg.GOODS_CODE goodsCode,
+            bar.driver_name,
+            bar.driver_mobile,
+            bar.STATUS,
+            bar.appointment_reason,
+            bar.over_id,
+            bec.vehicle_axle_number axleNumber,
+            br.id recordId,
+            bar.queue_number,
+            br.driver_sign,
+            br.unload_weight / 1000 unload_weight,
+            br.unload_img,
+            br.unload_name,
+            br.audit_sign,
+            bar.appointment_type,
+            bar.appointment_classify,
+            bar.create_time,
+            bar.create_user,
+            bar.load_point_id,
+            bar.load_time_id,
+            blp.load_point,
+            blt.begin_time loadBeginTime,
+            blt.end_time loadEndTime,
+            blt.available_number,
+            blt.already_number,
+            br.complete_send_time
+        FROM
+            biz_appointment_record bar
+                LEFT JOIN biz_load_appoint bla ON bar.order_id = bla.id
+                LEFT JOIN biz_goods bg ON bg.id = bla.goods_id
+                LEFT JOIN biz_service_customer bc ON bc.id = bla.customer_id
+                LEFT JOIN biz_excess_config bec ON bec.id = bar.over_id
+                LEFT JOIN biz_record br ON bar.id = br.appointment_id
+                LEFT JOIN biz_load_point blp ON blp.id = bar.load_point_id
+                LEFT JOIN biz_load_time blt ON blt.id = bar.load_time_id
+            ${ew.customSqlSegment}
+    </select>
 </mapper>

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentRecordPageParam.java

@@ -85,4 +85,7 @@ public class BizAppointmentRecordPageParam {
 
     private String appointmentClassify;
 
+    /**起卸单号*/
+    private String loadNumber;
+
 }

+ 9 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/BizAppointmentRecordService.java

@@ -125,4 +125,13 @@ public interface BizAppointmentRecordService extends IService<BizAppointmentReco
     void exit(BizAppointmentRecordIdParam bizAppointmentRecordIdParam);
 
     void exitTemp(BizAppointmentRecordIdParam bizAppointmentRecordIdParam);
+
+    /**起卸预约列表**/
+    Page<BizAppointmentRecord> getLoadPage(BizAppointmentRecordPageParam bizAppointmentRecordPageParam);
+
+    /**起卸预约新增*/
+    void addLoad(BizAppointmentRecordAddParam bizAppointmentRecordAddParam);
+
+    /**起卸预约编辑*/
+    void editLoad(BizAppointmentRecordEditParam bizAppointmentRecordEditParam);
 }

+ 252 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/impl/BizAppointmentRecordServiceImpl.java

@@ -44,6 +44,10 @@ import vip.xiaonuo.biz.modular.bizconfig.entity.BizConfig;
 import vip.xiaonuo.biz.modular.bizconfig.service.BizConfigService;
 import vip.xiaonuo.biz.modular.bizexcessconfig.entity.BizExcessConfig;
 import vip.xiaonuo.biz.modular.bizexcessconfig.service.BizExcessConfigService;
+import vip.xiaonuo.biz.modular.bizloadappoint.entity.BizLoadAppoint;
+import vip.xiaonuo.biz.modular.bizloadappoint.service.BizLoadAppointService;
+import vip.xiaonuo.biz.modular.bizloadappointsupplier.entity.BizLoadAppointSupplier;
+import vip.xiaonuo.biz.modular.bizloadappointsupplier.service.BizLoadAppointSupplierService;
 import vip.xiaonuo.biz.modular.bizloadtime.entity.BizLoadTime;
 import vip.xiaonuo.biz.modular.bizloadtime.service.BizLoadTimeService;
 import vip.xiaonuo.biz.modular.bizorder.entity.BizOrder;
@@ -138,6 +142,12 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
     @Resource
     private BizOrderSupplierService bizOrderSupplierService;
 
+    @Resource
+    private BizLoadAppointService bizLoadAppointService;
+
+    @Resource
+    private BizLoadAppointSupplierService bizLoadAppointSupplierService;
+
     @Override
     public Page<BizAppointmentRecord> page(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
         QueryWrapper<BizAppointmentRecord> queryWrapper = getQueryWrapper(bizAppointmentRecordPageParam);
@@ -185,6 +195,9 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
         if(ObjectUtil.isEmpty(loginUserDataScope)) {
             queryWrapper.eq("bar.create_user", StpUtil.getLoginIdAsString());
         }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getLoadNumber())){
+            queryWrapper.like("bla.load_number",bizAppointmentRecordPageParam.getLoadNumber());
+        }
         queryWrapper.eq("bar.delete_flag","NOT_DELETE");
         queryWrapper.orderByDesc("bar.create_time");
         return queryWrapper;
@@ -1046,4 +1059,243 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
         bizAppointmentRecord.setStatus("10");
         this.updateById(bizAppointmentRecord);
     }
+
+    @Override
+    public Page<BizAppointmentRecord> getLoadPage(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
+        QueryWrapper<BizAppointmentRecord> queryWrapper = getQueryWrapper(bizAppointmentRecordPageParam);
+        Page<BizAppointmentRecord> loadPage = this.getBaseMapper().getLoadPage(CommonPageRequest.defaultPage(), queryWrapper);
+        return loadPage;
+    }
+
+    @Transactional
+    @Override
+    public void addLoad(BizAppointmentRecordAddParam bizAppointmentRecordAddParam) {
+        checkLoadParam(bizAppointmentRecordAddParam);
+        //获取流程配置判断预约是否需要审核
+        BizConfig bizConfig = bizConfigService.getOne(new QueryWrapper<BizConfig>().lambda().last("limit 1"));
+        BizAppointmentRecord bizAppointmentRecord = BeanUtil.toBean(bizAppointmentRecordAddParam, BizAppointmentRecord.class);
+        if(ObjectUtil.isNotNull(bizConfig)){
+            if(StringUtils.equals(bizConfig.getTemporaryAuditSwitch(),"1")){
+                //开启审核,设置待审核状态
+                bizAppointmentRecord.setStatus("1");
+            }else{
+                //未开启审核,设置待入场状态
+                bizAppointmentRecord.setStatus("4");
+            }
+        }
+        bizAppointmentRecord.setAppointmentType("3");
+        this.save(bizAppointmentRecord);
+
+        //修改起卸订单状态
+        BizLoadAppoint loadAppoint = bizLoadAppointService.getById(bizAppointmentRecordAddParam.getOrderId());
+        loadAppoint.setStatus("6");
+        bizLoadAppointService.updateById(loadAppoint);
+
+        //更新装卸时间段的已约次数
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getLoadTimeId())){
+            BizLoadTime bizLoadTime = bizLoadTimeService.getById(bizAppointmentRecordAddParam.getLoadTimeId());
+            if(ObjectUtil.isNotNull(bizLoadTime)){
+                bizLoadTime.setAlreadyNumber(bizLoadTime.getAlreadyNumber()+1);
+                bizLoadTimeService.updateById(bizLoadTime);
+            }
+        }
+    }
+
+
+
+    public void checkLoadParam(BizAppointmentRecordAddParam bizAppointmentRecordAddParam){
+        //校验车牌号
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getLicenseNumber())){
+            bizAppointmentRecordAddParam.setLicenseNumber(bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim());
+            //校验车牌号是否添加过预约,排除11:已签收、 13:销售已审核  、 14:已取消
+            long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
+                    eq(BizAppointmentRecord::getLicenseNumber,bizAppointmentRecordAddParam.getLicenseNumber()).
+                    notIn(BizAppointmentRecord::getStatus, "10","11","12", "13", "14","15"));
+            if(count>0){
+                throw new CommonException("车牌号:{}已经添加过预约!",bizAppointmentRecordAddParam.getLicenseNumber());
+            }
+
+            //查询是否存在没有回签的记录
+            QueryWrapper<BizAppointmentRecord> queryWrapper = new QueryWrapper<>();
+            queryWrapper.eq("bar.delete_flag","NOT_DELETE");
+            queryWrapper.isNull("br.unload_weight");
+            queryWrapper.eq("bo.order_type","1");
+            queryWrapper.eq("bar.`status`","10");
+            queryWrapper.eq("bar.license_number",bizAppointmentRecordAddParam.getLicenseNumber());
+            List<BizAppointmentRecord> recordList = this.getBaseMapper().getRecordList(queryWrapper);
+            if(ObjectUtil.isNotEmpty(recordList)){
+                throw new CommonException("请先填写回签信息,再进行预约!");
+            }
+        }
+        //校验手机号
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getDriverMobile())){
+            if(!PhoneUtil.isMobile(bizAppointmentRecordAddParam.getDriverMobile())) {
+                throw new CommonException("手机号码:{}格式错误", bizAppointmentRecordAddParam.getDriverMobile());
+            }
+        }
+        //校验订单
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getOrderId())){
+            BizLoadAppoint loadAppoint = bizLoadAppointService.getById(bizAppointmentRecordAddParam.getOrderId());
+            if(ObjectUtil.isNotNull(loadAppoint)){
+                if(!StringUtils.equals(loadAppoint.getStatus(),"5") && !StringUtils.equals(loadAppoint.getStatus(),"6")){
+                    throw new CommonException("当前订单不可预约!");
+                }
+
+                //查询订单下的供应商
+                List<BizLoadAppointSupplier> supplierList = bizLoadAppointSupplierService.list(new QueryWrapper<BizLoadAppointSupplier>().lambda().
+                        eq(BizLoadAppointSupplier::getAppointId, bizAppointmentRecordAddParam.getOrderId()));
+                List<String> supplierIdList = Lists.newArrayList();
+                supplierList.forEach(supplier->supplierIdList.add(supplier.getSupplierId()));
+                //查询车辆是否在供应商名下
+                BizSupplierTransport transport = bizSupplierTransportService.getOne(new QueryWrapper<BizSupplierTransport>().lambda().
+                        in(BizSupplierTransport::getSupplierId, supplierIdList).
+                        eq(BizSupplierTransport::getTransportNo, bizAppointmentRecordAddParam.getLicenseNumber()).
+                        eq(BizSupplierTransport::getAuditStatus,"2").
+                        last("limit 1"));
+                if(ObjectUtil.isNull(transport)){
+                    throw new CommonException("该车辆没有绑定在供应商下,不可预约!");
+                }
+            }
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getLoadTimeId())){
+            //查询预约时间段内可预约次数
+            getLoadTimeCount(bizAppointmentRecordAddParam);
+        }
+    }
+
+    public void getLoadTimeCount(BizAppointmentRecordAddParam bizAppointmentRecordAddParam){
+        lock.lock();
+        try{
+            //判断装卸预约次数是否满足
+            if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getLoadTimeId())){
+                BizLoadTime bizLoadTime = bizLoadTimeService.queryEntity(bizAppointmentRecordAddParam.getLoadTimeId());
+                if(bizLoadTime.getAvailableNumber()-bizLoadTime.getAlreadyNumber() <= 0){
+                    throw new CommonException("当前装卸时段预约已满,不可预约!");
+                }
+                if(new Date().getTime() > bizLoadTime.getEndTime().getTime()){
+                    throw new CommonException("装卸时间段已过,不可预约!");
+                }
+            }
+        }finally {
+            lock.unlock(); // 释放锁
+        }
+
+    }
+
+
+    @Transactional
+    @Override
+    public void editLoad(BizAppointmentRecordEditParam bizAppointmentRecordEditParam) {
+        BizAppointmentRecord bizAppointmentRecord = this.queryEntity(bizAppointmentRecordEditParam.getId());
+        checkLoadParam(bizAppointmentRecordEditParam,bizAppointmentRecord);
+        if(!StringUtils.equals(bizAppointmentRecord.getLoadTimeId(),bizAppointmentRecordEditParam.getLoadTimeId())){
+            //调整了装卸时段,释放之前的已约次数,更新新的时段已约次数
+            if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getLoadTimeId())){
+                BizLoadTime bizLoadTime = bizLoadTimeService.getById(bizAppointmentRecordEditParam.getLoadTimeId());
+                if(ObjectUtil.isNotNull(bizLoadTime)){
+                    bizLoadTime.setAlreadyNumber(bizLoadTime.getAlreadyNumber()+1);
+                    bizLoadTimeService.updateById(bizLoadTime);
+                }
+            }
+
+            if(ObjectUtil.isNotEmpty(bizAppointmentRecord.getLoadTimeId())){
+                BizLoadTime bizLoadTime = bizLoadTimeService.getById(bizAppointmentRecord.getLoadTimeId());
+                if(ObjectUtil.isNotNull(bizLoadTime)){
+                    bizLoadTime.setAlreadyNumber(bizLoadTime.getAlreadyNumber()-1);
+                    bizLoadTimeService.updateById(bizLoadTime);
+                }
+            }
+        }
+        BeanUtil.copyProperties(bizAppointmentRecordEditParam, bizAppointmentRecord);
+        if(StringUtils.equals(bizAppointmentRecord.getStatus(),"2")){
+            //如果当前状态是审核不通过的状态,修改后重新提交审核
+            bizAppointmentRecord.setStatus("1");
+        }
+        this.updateById(bizAppointmentRecord);
+    }
+
+    public void checkLoadParam(BizAppointmentRecordEditParam bizAppointmentRecordEditParam,BizAppointmentRecord bizAppointmentRecord){
+        //校验车牌号
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getLicenseNumber())){
+            bizAppointmentRecordEditParam.setLicenseNumber(bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim());
+            if(!StringUtils.equals(bizAppointmentRecord.getLicenseNumber(),bizAppointmentRecordEditParam.getLicenseNumber())){
+                //校验车牌号是否添加过预约,排除11:已签收、 13:销售已审核  、 14:已取消
+                long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
+                        eq(BizAppointmentRecord::getLicenseNumber,bizAppointmentRecordEditParam.getLicenseNumber()).
+                        notIn(BizAppointmentRecord::getStatus, "10","11","12", "13", "14","15"));
+                if(count>0){
+                    throw new CommonException("车牌号:{}已经添加过预约!",bizAppointmentRecordEditParam.getLicenseNumber());
+                }
+
+                //查询是否存在没有回签的记录
+                QueryWrapper<BizAppointmentRecord> queryWrapper = new QueryWrapper<>();
+                queryWrapper.eq("bar.delete_flag","NOT_DELETE");
+                queryWrapper.isNull("br.unload_weight");
+                queryWrapper.eq("bo.order_type","1");
+                queryWrapper.eq("bar.`status`","10");
+                queryWrapper.eq("bar.license_number",bizAppointmentRecordEditParam.getLicenseNumber());
+                List<BizAppointmentRecord> recordList = this.getBaseMapper().getRecordList(queryWrapper);
+                if(ObjectUtil.isNotEmpty(recordList)){
+                    throw new CommonException("请先填写回签信息,再进行预约!");
+                }
+            }
+        }
+        //校验手机号
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getDriverMobile())){
+            if(!PhoneUtil.isMobile(bizAppointmentRecordEditParam.getDriverMobile())) {
+                throw new CommonException("手机号码:{}格式错误", bizAppointmentRecordEditParam.getDriverMobile());
+            }
+        }
+        //校验订单
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getOrderId())){
+            BizLoadAppoint loadAppoint = bizLoadAppointService.getById(bizAppointmentRecordEditParam.getOrderId());
+            if(ObjectUtil.isNotNull(loadAppoint)){
+                if(!StringUtils.equals(loadAppoint.getStatus(),"5") && !StringUtils.equals(loadAppoint.getStatus(),"6")){
+                    throw new CommonException("当前订单不可预约!");
+                }
+
+                //查询订单下的供应商
+                List<BizLoadAppointSupplier> supplierList = bizLoadAppointSupplierService.list(new QueryWrapper<BizLoadAppointSupplier>().lambda().
+                        eq(BizLoadAppointSupplier::getAppointId, bizAppointmentRecordEditParam.getOrderId()));
+                List<String> supplierIdList = Lists.newArrayList();
+                supplierList.forEach(supplier->supplierIdList.add(supplier.getSupplierId()));
+                //查询车辆是否在供应商名下
+                BizSupplierTransport transport = bizSupplierTransportService.getOne(new QueryWrapper<BizSupplierTransport>().lambda().
+                        in(BizSupplierTransport::getSupplierId, supplierIdList).
+                        eq(BizSupplierTransport::getTransportNo, bizAppointmentRecordEditParam.getLicenseNumber()).
+                        eq(BizSupplierTransport::getAuditStatus,"2").
+                        last("limit 1"));
+                if(ObjectUtil.isNull(transport)){
+                    throw new CommonException("该车辆没有绑定在供应商下,不可预约!");
+                }
+            }
+
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getLoadTimeId())){
+            //查询预约时间段内可预约次数
+            getLoadTimeCount(bizAppointmentRecordEditParam,bizAppointmentRecord);
+        }
+    }
+
+    public void getLoadTimeCount(BizAppointmentRecordEditParam bizAppointmentRecordEditParam,BizAppointmentRecord bizAppointmentRecord){
+        lock.lock();
+        try{
+            //判断装卸预约次数是否满足
+            if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getLoadTimeId())){
+                if(!StringUtils.equals(bizAppointmentRecord.getLoadTimeId(),bizAppointmentRecordEditParam.getLoadTimeId())){
+                    BizLoadTime bizLoadTime = bizLoadTimeService.queryEntity(bizAppointmentRecordEditParam.getLoadTimeId());
+                    if(bizLoadTime.getAvailableNumber()-bizLoadTime.getAlreadyNumber() <= 0){
+                        throw new CommonException("当前装卸时段预约已满,不可预约!");
+                    }
+                    if(new Date().getTime() > bizLoadTime.getEndTime().getTime()){
+                        throw new CommonException("装卸时间段已过,不可预约!");
+                    }
+                }
+
+            }
+        }finally {
+            lock.unlock(); // 释放锁
+        }
+
+    }
 }

+ 24 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/controller/BizLoadDispatchController.java

@@ -171,4 +171,28 @@ public class BizLoadDispatchController {
     public CommonResult<Page<BizLoadDispatch>> getPageList(BizLoadDispatchPageParam bizLoadDispatchPageParam) {
         return CommonResult.data(bizLoadDispatchService.getPageList(bizLoadDispatchPageParam));
     }
+
+    /**
+     * 获取装货点位列表
+     *
+     * @author fanzherong
+     * @date  2025/07/01 09:47
+     */
+    @Operation(summary = "获取装货点位列表")
+    @GetMapping("/biz/bizloaddispatch/getList")
+    public CommonResult<List<BizLoadDispatch>> getList(BizLoadDispatchPageParam bizLoadDispatchPageParam) {
+        return CommonResult.data(bizLoadDispatchService.getList(bizLoadDispatchPageParam));
+    }
+
+    /**
+     * 获取装货时间列表
+     *
+     * @author fanzherong
+     * @date  2025/07/01 09:47
+     */
+    @Operation(summary = "获取装货时间列表")
+    @GetMapping("/biz/bizloaddispatch/getListTime")
+    public CommonResult<List<BizLoadDispatch>> getListTime(BizLoadDispatchPageParam bizLoadDispatchPageParam) {
+        return CommonResult.data(bizLoadDispatchService.getListTime(bizLoadDispatchPageParam));
+    }
 }

+ 4 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/mapper/BizLoadDispatchMapper.java

@@ -18,6 +18,8 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Param;
 import vip.xiaonuo.biz.modular.bizloaddispatch.entity.BizLoadDispatch;
 
+import java.util.List;
+
 /**
  * 起卸预约分配Mapper接口
  *
@@ -27,4 +29,6 @@ import vip.xiaonuo.biz.modular.bizloaddispatch.entity.BizLoadDispatch;
 public interface BizLoadDispatchMapper extends BaseMapper<BizLoadDispatch> {
 
     Page<BizLoadDispatch> getPageList(@Param("page") Page<BizLoadDispatch> page, @Param("ew") QueryWrapper<BizLoadDispatch> ew);
+
+    List<BizLoadDispatch> getPageList(@Param("ew") QueryWrapper<BizLoadDispatch> ew);
 }

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/param/BizLoadDispatchPageParam.java

@@ -54,4 +54,7 @@ public class BizLoadDispatchPageParam {
     /**类型*/
     private String loadType;
 
+    /**点位id*/
+    private String loadPointId;
+
 }

+ 10 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/service/BizLoadDispatchService.java

@@ -109,4 +109,14 @@ public interface BizLoadDispatchService extends IService<BizLoadDispatch> {
      * @param bizLoadDispatchEditParam
      */
     void replaceDispatch(BizLoadDispatchEditParam bizLoadDispatchEditParam);
+
+    /**
+     * 查询装货点位列表
+     */
+    List<BizLoadDispatch> getList(BizLoadDispatchPageParam bizLoadDispatchPageParam);
+
+    /**
+     * 查询装卸时间列表
+     */
+    List<BizLoadDispatch> getListTime(BizLoadDispatchPageParam bizLoadDispatchPageParam);
 }

+ 31 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/service/impl/BizLoadDispatchServiceImpl.java

@@ -213,4 +213,35 @@ public class BizLoadDispatchServiceImpl extends ServiceImpl<BizLoadDispatchMappe
         //装卸分配替换
         BizLoadDispatch bizLoadDispatch = this.queryEntity(bizLoadDispatchEditParam.getId());
     }
+
+    @Override
+    public List<BizLoadDispatch> getList(BizLoadDispatchPageParam bizLoadDispatchPageParam) {
+        QueryWrapper<BizLoadDispatch> queryWrapper = new QueryWrapper<>();
+        if(ObjectUtil.isNotEmpty(bizLoadDispatchPageParam.getLoadType())){
+            queryWrapper.eq("bld.load_type",bizLoadDispatchPageParam.getLoadType());
+        }
+        if(ObjectUtil.isNotEmpty(bizLoadDispatchPageParam.getAppointId())){
+            queryWrapper.eq("bld.appoint_id",bizLoadDispatchPageParam.getAppointId());
+        }
+        queryWrapper.eq("bld.delete_flag","NOT_DELETE");
+        queryWrapper.groupBy("bld.load_point_id");
+        return this.getBaseMapper().getPageList(queryWrapper);
+    }
+
+    @Override
+    public List<BizLoadDispatch> getListTime(BizLoadDispatchPageParam bizLoadDispatchPageParam) {
+        QueryWrapper<BizLoadDispatch> queryWrapper = new QueryWrapper<>();
+        if(ObjectUtil.isNotEmpty(bizLoadDispatchPageParam.getLoadType())){
+            queryWrapper.eq("bld.load_type",bizLoadDispatchPageParam.getLoadType());
+        }
+        if(ObjectUtil.isNotEmpty(bizLoadDispatchPageParam.getAppointId())){
+            queryWrapper.eq("bld.appoint_id",bizLoadDispatchPageParam.getAppointId());
+        }
+        if(ObjectUtil.isNotEmpty(bizLoadDispatchPageParam.getLoadPointId())){
+            queryWrapper.eq("bld.load_point_id",bizLoadDispatchPageParam.getLoadPointId());
+        }
+        queryWrapper.eq("bld.delete_flag","NOT_DELETE");
+        queryWrapper.groupBy("bld.load_time_id");
+        return this.getBaseMapper().getPageList(queryWrapper);
+    }
 }