Browse Source

Merge branch 'master' of http://218.2.6.10:3001/fanzherong/hunanzeyunew

shasha 1 week ago
parent
commit
16b09761b7
35 changed files with 2859 additions and 250 deletions
  1. 8 0
      snowy-admin-web/src/api/biz/bizAppointmentRecordApi.js
  2. 8 0
      snowy-admin-web/src/api/biz/bizLoadAppointApi.js
  3. 8 0
      snowy-admin-web/src/api/biz/bizLoadDispatchApi.js
  4. 44 0
      snowy-admin-web/src/api/biz/bizOtherAppointmentApi.js
  5. 144 0
      snowy-admin-web/src/views/biz/bizappointload/detail.vue
  6. 197 0
      snowy-admin-web/src/views/biz/bizappointload/form.vue
  7. 623 0
      snowy-admin-web/src/views/biz/bizappointload/index.vue
  8. 65 0
      snowy-admin-web/src/views/biz/bizloadappoint/end.vue
  9. 65 0
      snowy-admin-web/src/views/biz/bizloadappoint/fill.vue
  10. 18 5
      snowy-admin-web/src/views/biz/bizloadappoint/index.vue
  11. 2 2
      snowy-admin-web/src/views/biz/bizloaddispatch/index.vue
  12. 132 0
      snowy-admin-web/src/views/biz/bizotherappoint/detail.vue
  13. 134 0
      snowy-admin-web/src/views/biz/bizotherappoint/form.vue
  14. 516 0
      snowy-admin-web/src/views/biz/bizotherappoint/index.vue
  15. 136 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/controller/BizAppointmentRecordController.java
  16. 41 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/entity/BizAppointmentRecord.java
  17. 2 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/BizAppointmentRecordMapper.java
  18. 56 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/mapping/BizAppointmentRecordMapper.xml
  19. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentRecordPageParam.java
  20. 71 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizOtherAppointmentAddParam.java
  21. 74 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizOtherAppointmentEditParam.java
  22. 70 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizOtherAppointmentExportResult.java
  23. 45 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/BizAppointmentRecordService.java
  24. 248 233
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/impl/BizAppointmentRecordServiceImpl.java
  25. 28 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/controller/BizLoadAppointController.java
  26. 9 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/entity/BizLoadAppoint.java
  27. 9 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/param/BizLoadAppointEditParam.java
  28. 11 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/service/BizLoadAppointService.java
  29. 17 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/service/impl/BizLoadAppointServiceImpl.java
  30. 24 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/controller/BizLoadDispatchController.java
  31. 4 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/mapper/BizLoadDispatchMapper.java
  32. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/param/BizLoadDispatchPageParam.java
  33. 10 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/service/BizLoadDispatchService.java
  34. 33 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloaddispatch/service/impl/BizLoadDispatchServiceImpl.java
  35. 1 1
      snowy-web-app/src/main/resources/application-local.properties

+ 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/bizLoadAppointApi.js

@@ -42,5 +42,13 @@ export default {
 	//获取待报港的起卸预约列表
 	getList(data){
 		return request('getList',data,'get')
+	},
+	// 结束起卸订单
+	endLoad(data){
+		return request('endLoad',data)
+	},
+	// 填报起卸订单
+	fillLoad(data){
+		return request('fillLoad',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')
 	}
 }

+ 44 - 0
snowy-admin-web/src/api/biz/bizOtherAppointmentApi.js

@@ -0,0 +1,44 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/bizotherappointment/` + url, ...arg)
+
+/**
+ * 预约记录Api接口管理器
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+export default {
+	// 获取预约记录分页
+	bizOtherAppointmentPage(data) {
+		return request('page', data, 'get')
+	},
+	// 其他预约表单提交
+	bizOtherAppointmentSubmitForm(data, edit = false) {
+		return request(edit ? 'editOtherAppointment' : 'addOtherAppointment', data)
+	},
+	// 删除其他预约记录
+	bizOtherAppointmentDelete(data) {
+		return request('deleteOtherAppointment', data)
+	},
+	//强制结束
+	bizOtherAppointmentExit(data){
+		return request('bizOtherAppointmentExit',data)
+	},
+	//授权出场
+	bizOtherAppointmentAuthorize(data){
+		return request('bizOtherAppointmentAuthorize',data)
+	},
+
+	// 获取预约记录详情
+	bizAppointmentRecordDetail(data) {
+		return request('detail', data, 'get')
+	},
+
+	//导出
+	bizOtherAppointmentExport(data){
+		return request('bizOtherAppointmentExport', data, 'get', {
+			responseType: 'blob'
+		})
+	}
+}

+ 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>

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

@@ -0,0 +1,197 @@
+<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="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>

+ 65 - 0
snowy-admin-web/src/views/biz/bizloadappoint/end.vue

@@ -0,0 +1,65 @@
+<template>
+    <a-modal v-model:visible="visible" title="结束">
+
+        <a-form ref="formRef" :label-col="labelCol" :model="formData" layout="horizontal">
+            <a-form-item v-show="false">
+                <a-input v-model:value="formData.id"></a-input>
+            </a-form-item>
+            <a-form-item
+                    label="结束说明"
+                    name="auditingRemark"
+            >
+                <a-textarea v-model:value="formData.endReason" placeholder="请输入结束说明"
+                            :auto-size="{ minRows: 3, maxRows: 5 }"/>
+            </a-form-item>
+        </a-form>
+        <template #footer>
+            <a-spin :spinning="submitLoading">
+                <a-button type="primary" @click="onsubmit(true)">结束</a-button>
+            </a-spin>
+        </template>
+    </a-modal>
+</template>
+<script setup>
+import {message} from 'ant-design-vue';
+import bizOrderApi from '@/api/biz/bizOrderApi'
+import bizLoadAppointApi from "@/api/biz/bizLoadAppointApi";
+
+const emit = defineEmits({successful: null})
+const visible = ref(false);
+const submitLoading = ref(false)
+const labelCol = ref({span: 4})
+// 表单数据
+const formData = ref({})
+const showModal = (id) => {
+    formData.value.id = id
+    visible.value = true;
+};
+const onClose = () => {
+    formData.value = {}
+    visible.value = false
+};
+const onsubmit = (flag) => {
+    if (flag === true) {
+        if (!formData.value.endReason) {
+            message.error('结束时,说明信息不能为空')
+            return
+        }
+    }
+    submitLoading.value = true
+	formData.value.auditFlag = flag
+	bizLoadAppointApi.endLoad(formData.value).then(() => {
+        onClose()
+        emit('successful', null)
+    }).finally(() => {
+        submitLoading.value = false
+    })
+}
+// 抛出函数
+defineExpose({
+    showModal
+})
+</script>
+<style scoped>
+
+</style>

+ 65 - 0
snowy-admin-web/src/views/biz/bizloadappoint/fill.vue

@@ -0,0 +1,65 @@
+<template>
+    <a-modal v-model:visible="visible" title="填报">
+
+        <a-form ref="formRef" :label-col="labelCol" :model="formData" layout="horizontal">
+            <a-form-item v-show="false">
+                <a-input v-model:value="formData.id"></a-input>
+            </a-form-item>
+            <a-form-item
+                    label="起卸数量"
+                    name="fillWeight"
+            >
+<!--                <a-textarea v-model:value="formData.endReason" placeholder="请输入结束说明"
+                            :auto-size="{ minRows: 3, maxRows: 5 }"/>-->
+				<a-input-number v-model:value="formData.fillWeight" style="width:90%"  :precision="2" :min="0.01" :max="9999999"  placeholder="请输入起卸数量" allow-clear/><span style="margin-left:10px;">吨</span>
+            </a-form-item>
+        </a-form>
+        <template #footer>
+            <a-spin :spinning="submitLoading">
+                <a-button type="primary" @click="onsubmit(true)">确认</a-button>
+            </a-spin>
+        </template>
+    </a-modal>
+</template>
+<script setup>
+import {message} from 'ant-design-vue';
+import bizOrderApi from '@/api/biz/bizOrderApi'
+import bizLoadAppointApi from "@/api/biz/bizLoadAppointApi";
+
+const emit = defineEmits({successful: null})
+const visible = ref(false);
+const submitLoading = ref(false)
+const labelCol = ref({span: 4})
+// 表单数据
+const formData = ref({})
+const showModal = (id) => {
+    formData.value.id = id
+    visible.value = true;
+};
+const onClose = () => {
+    formData.value = {}
+    visible.value = false
+};
+const onsubmit = (flag) => {
+    if (flag === true) {
+        if (!formData.value.fillWeight) {
+            message.error('起卸数量不能为空')
+            return
+        }
+    }
+    submitLoading.value = true
+	bizLoadAppointApi.fillLoad(formData.value).then(() => {
+        onClose()
+        emit('successful', null)
+    }).finally(() => {
+        submitLoading.value = false
+    })
+}
+// 抛出函数
+defineExpose({
+    showModal
+})
+</script>
+<style scoped>
+
+</style>

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

@@ -72,9 +72,9 @@
 			<template #bodyCell="{ column, record }">
 				<template v-if="column.dataIndex === 'action'">
 
-					<a @click="showModal(record)" v-if="record.status == '5'">二维码</a>
+					<a @click="showModal(record)" v-if="(record.status == '5' || record.status == '6')">二维码</a>
 
-					<a-divider type="vertical" v-if="record.status == '5' "/>
+					<a-divider type="vertical" v-if="(record.status == '5' || record.status == '6') "/>
 
 					<a-dropdown>
 						<a class="ant-dropdown-link">
@@ -98,12 +98,18 @@
 								<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-item v-if="hasPerm('bizLoadAppointEnd') && (record.status=='5' || record.status=='6')">
+									<a style="color:red" @click="endRef.showModal(record.id)">结束</a>
+								</a-menu-item>
+								<a-menu-item v-if="hasPerm('bizLoadAppointFill') && (record.status=='7' )">
+									<a style="color:orange" @click="fillRef.showModal(record.id)">填报</a>
+								</a-menu-item>
 							</a-menu>
 						</template>
 					</a-dropdown>
@@ -140,6 +146,8 @@
 	<Detail ref="detailRef" @successful="tableRef.refresh()" />
 	<Dispatch ref="dispatchRef" @successful="tableRef.refresh()" />
 	<DispatchLoad ref="dispatchLoadRef" @successful="tableRef.refresh()" />
+	<End ref="endRef" @successful="tableRef.refresh(true)" />
+	<Fill ref="fillRef" @successful="tableRef.refresh(true)" />
 	<XnSignName ref="XnSignNameRef" @successful="signSuccess" />
 
 	<a-modal v-model:visible="open" title="二维码" width="600px" style="height: 700px">
@@ -180,6 +188,8 @@
 	import downloadUtil from '@/utils/downloadUtil'
 	import Dispatch from './dispatch.vue'
 	import DispatchLoad from './dispatchload.vue'
+	import End from "./end.vue";
+	import Fill from './fill.vue'
 
 
 	const tableRef = ref()
@@ -189,6 +199,8 @@
 	const detailRef = ref()
 	const XnSignNameRef = ref()
 	const nowRecord = ref()
+	const endRef = ref()
+	const fillRef = ref()
 	const submitLoading = ref(false)
 	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
 
@@ -370,7 +382,8 @@
 		//QRCode.toDataURL("id:"+record.id+"saleCode:"+record.saleCode, {
 		let param = {
 			id:record.id,
-			loadNumber:record.loadNumber
+			loadNumber:record.loadNumber,
+			type:'3'
 		}
 		QRCode.toDataURL(JSON.stringify(param), {
 			errorCorrectionLevel: 'H',

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

@@ -37,8 +37,8 @@
 						<a-divider type="vertical" v-if="hasPerm(['bizLoadPointEdit', 'bizLoadPointDelete'], 'and')" />
 						<a-button type="link" danger size="small" v-if="hasPerm('bizLoadPointDelete')" @click="deleteConfig(record)">删除</a-button>
 
-						<a-divider type="vertical" v-if="hasPerm(['bizLoadPointEdit', 'bizLoadPointDelete'], 'or') && hasPerm('bizLoadUser')" />
-						<a @click="userIndexRef.onOpen(record)" v-if="hasPerm('bizLoadUser')">起卸员</a>
+<!--						<a-divider type="vertical" v-if="hasPerm(['bizLoadPointEdit', 'bizLoadPointDelete'], 'or') && hasPerm('bizLoadUser')" />
+						<a @click="userIndexRef.onOpen(record)" v-if="hasPerm('bizLoadUser')">起卸员</a>-->
 
 						<a-divider type="vertical" v-if="hasPerm(['bizLoadPointEdit', 'bizLoadPointDelete', 'bizLoadUser'], 'or') && hasPerm('bizLoadTime')" />
 						<a @click="timeIndexRef.onOpen(record)" v-if="hasPerm('bizLoadTime')">起卸时间</a>

+ 132 - 0
snowy-admin-web/src/views/biz/bizotherappoint/detail.vue

@@ -0,0 +1,132 @@
+<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.licenseNumber }}</a-descriptions-item>
+<!--				<a-descriptions-item label="订单名称" :span="2">{{ formData.orderName }}</a-descriptions-item>-->
+				<a-descriptions-item label="是否过磅" :span="2">{{ $TOOL.dictTypeData('is_weigh', formData.isWeigh) }}</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.createUserName }}</a-descriptions-item>
+				<a-descriptions-item label="创建时间" :span="2">{{ formData.createTime }}</a-descriptions-item>
+
+				<a-descriptions-item label="强制结束操作人" :span="2">{{ formData.exitOperator }}</a-descriptions-item>
+				<a-descriptions-item label="强制结束操作时间" :span="2">{{ formData.exitTime }}</a-descriptions-item>
+
+				<a-descriptions-item label="授权离场操作人" :span="2">{{ formData.authorizeOperator }}</a-descriptions-item>
+				<a-descriptions-item label="授权离场操作时间" :span="2">{{ formData.authorizeTime }}</a-descriptions-item>
+
+
+				<a-descriptions-item label="预约状态" :span="4">
+					<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="4">{{ formData.remark }}</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>

+ 134 - 0
snowy-admin-web/src/views/biz/bizotherappoint/form.vue

@@ -0,0 +1,134 @@
+<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="licenseNumber">
+				<a-input v-model:value="formData.licenseNumber" placeholder="请输入车牌号" allow-clear />
+			</a-form-item>
+
+			<a-form-item label="司机信息:" name="driverId">
+				<xn-user-selector
+					:org-tree-api="selectorApiFunction.orgTreeApi"
+					:user-page-api="selectorApiFunction.userPageApi"
+					:radio-model="true"
+					placeholder="请选择司机"
+					v-model:value="formData.driverId"
+				/>
+			</a-form-item>
+
+			<a-form-item label="是否过磅:" name="isWeigh">
+				<a-radio-group button-style="solid" v-model:value="formData.isWeigh">
+					<a-radio-button value="1">
+						是
+					</a-radio-button>
+					<a-radio-button value="2">
+						否
+					</a-radio-button>
+				</a-radio-group>
+			</a-form-item>
+
+			<a-form-item label="备注:" name="remark">
+				<a-textarea v-model:value="formData.remark" 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 bizOtherAppointmentApi from '@/api/biz/bizOtherAppointmentApi'
+	import userApi from '@/api/biz/bizUserApi'
+	// 抽屉状态
+	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)
+		}
+
+
+	}
+
+	// 传递设计器需要的API
+	const selectorApiFunction = {
+		orgTreeApi: (param) => {
+			return userApi.userOrgTreeSelector(param).then((data) => {
+				return Promise.resolve(data)
+			})
+		},
+		userPageApi: (param) => {
+			param.roleName = '司机'
+			return userApi.userSelectorByRole(param).then((data) => {
+				debugger
+				return Promise.resolve(data)
+			})
+		}
+	}
+
+
+
+
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		licenseNumber: [required('请输入车牌号')],
+		driverId: [required('请选择司机')],
+		isWeigh: [required('请选择是否过磅')]
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				debugger
+				bizOtherAppointmentApi
+					.bizOtherAppointmentSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 516 - 0
snowy-admin-web/src/views/biz/bizotherappoint/index.vue

@@ -0,0 +1,516 @@
+<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="licenseNumber">
+						<a-input v-model:value="searchFormState.licenseNumber" 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>
+				<template v-if="advanced">
+					<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('bizOtherAppointmentAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<a-button @click="exportTotal" v-if="hasPerm('bizOtherAppointmentExport')">
+						<template #icon>
+							<export-outlined/>
+						</template>
+						导出
+					</a-button>
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+
+				<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 === 'isWeigh'">
+					{{ $TOOL.dictTypeData('is_weigh', record.isWeigh) }}
+				</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-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('bizOtherAppointmentEdit') && ( record.status == '4')">
+										<a style="color:blue" @click="formRef.onOpen(record)" >编辑</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizOtherAppointmentDelete') && ( 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('bizOtherAppointmentExit') && (record.status=='5' || record.status=='6' || record.status=='7'
+									|| record.status=='8' || record.status=='9' || record.status=='16' || record.status=='17'  )">
+										<a style="color:green"  @click="cancel(record)" >强制结束</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizOtherAppointmentAuthorize') && (record.status=='17' )">
+										<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="projectNameFlag">订单名称:{{nowRecord.orderName}}</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 bizOtherAppointmentApi from '@/api/biz/bizOtherAppointmentApi'
+	import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
+	import {Modal} from 'ant-design-vue';
+	import {createVNode} from 'vue';
+	import tool from '@/utils/tool'
+	import downloadUtil from '@/utils/downloadUtil'
+	import bizRecordApi from '@/api/biz/bizRecordApi'
+
+	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: 'licenseNumber',
+			width:150,
+			align: 'center'
+		},
+
+
+		{
+			title: '司机信息',
+			dataIndex: 'driverInfo',
+			width: 160
+		},
+
+		{
+			title: '是否过磅',
+			dataIndex: 'isWeigh',
+			width: 110,
+			align:'center'
+		},
+		{
+			title: '状态',
+			dataIndex: 'status',
+			align: 'center',
+			width:130
+		},
+		{
+			title: '备注',
+			dataIndex: 'remark',
+			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 = '6'
+		return bizOtherAppointmentApi.bizOtherAppointmentPage(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
+			}
+		]
+		bizOtherAppointmentApi.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
+					}
+				]
+
+				bizOtherAppointmentApi
+					.bizOtherAppointmentDelete(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
+					}
+				bizOtherAppointmentApi
+					.bizOtherAppointmentExit(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
+					}
+				bizOtherAppointmentApi
+					.bizOtherAppointmentAuthorize(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+
+	// 批量删除
+	const deleteBatchBizAppointmentRecord = (params) => {
+		bizOtherAppointmentApi.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 exportTotal = () => {
+		/*const searchFormParam = cloneDeep(searchFormState.value)
+		bizOtherAppointmentApi.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)
+
+				bizOtherAppointmentApi
+					.bizOtherAppointmentExport(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>

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

@@ -24,15 +24,12 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RestController;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.param.*;
 import vip.xiaonuo.biz.modular.bizorder.param.BizOrderPageParam;
 import vip.xiaonuo.common.annotation.CommonLog;
 import vip.xiaonuo.common.annotation.CommonNoRepeat;
 import vip.xiaonuo.common.pojo.CommonResult;
 import vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord;
-import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordAddParam;
-import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordEditParam;
-import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordIdParam;
-import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordPageParam;
 import vip.xiaonuo.biz.modular.bizappointmentrecord.service.BizAppointmentRecordService;
 
 import jakarta.annotation.Resource;
@@ -285,4 +282,139 @@ 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));
+    }
+
+    /**
+     * 其他预约_记录分页
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "其他预约_记录分页")
+    @SaCheckPermission("/biz/bizotherappointment/page")
+    @GetMapping("/biz/bizotherappointment/page")
+    public CommonResult<Page<BizAppointmentRecord>> bizOtherAppointmentPage(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
+        return CommonResult.data(bizAppointmentRecordService.page(bizAppointmentRecordPageParam));
+    }
+
+
+    /**
+     * 其他预约_添加
+     *
+     * @author xumudong
+     * @date  2025/07/02 11:47
+     */
+    @Operation(summary = "其他预约_添加")
+    @CommonLog("其他预约_添加")
+    @CommonNoRepeat
+    @PostMapping("/biz/bizotherappointment/addOtherAppointment")
+    public CommonResult<String> addOtherAppointment(@RequestBody @Valid BizOtherAppointmentAddParam bizOtherAppointmentAddParam) {
+        bizAppointmentRecordService.addOtherAppointment(bizOtherAppointmentAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 其他预约_编辑
+     *
+     * @author xumudong
+     * @date  2025/07/02 11:47
+     */
+    @Operation(summary = "其他预约_编辑")
+    @CommonLog("其他预约_编辑")
+    @PostMapping("/biz/bizotherappointment/editOtherAppointment")
+    public CommonResult<String> editOtherAppointment(@RequestBody @Valid BizOtherAppointmentEditParam bizOtherAppointmentEditParam) {
+        bizAppointmentRecordService.editOtherAppointment(bizOtherAppointmentEditParam);
+        return CommonResult.ok();
+    }
+    /**
+     * 其他预约_删除
+     *
+     * @author xumudong
+     * @date  2025/07/02 11:47
+     */
+    @Operation(summary = "其他预约_删除")
+    @CommonLog("其他预约_删除")
+    @PostMapping("/biz/bizotherappointment/deleteOtherAppointment")
+    public CommonResult<String> deleteOtherAppointment(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                               List<BizAppointmentRecordIdParam> bizAppointmentRecordIdParamList) {
+        bizAppointmentRecordService.delete(bizAppointmentRecordIdParamList);
+        return CommonResult.ok();
+    }
+
+
+    /**
+     * 其他预约_强制结束
+     */
+    @Operation(summary = "其他预约_强制结束")
+    @CommonLog("其他预约_强制结束")
+    @PostMapping("/biz/bizotherappointment/bizOtherAppointmentExit")
+    public CommonResult<String> bizOtherAppointmentExit(@RequestBody BizAppointmentRecordIdParam bizAppointmentRecordIdParam){
+        bizAppointmentRecordService.bizOtherAppointmentExit(bizAppointmentRecordIdParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 其他预约_授权离场
+     */
+    @Operation(summary = "其他预约_授权离场")
+    @CommonLog("其他预约_授权离场")
+    @PostMapping("/biz/bizotherappointment/bizOtherAppointmentAuthorize")
+    public CommonResult<String> bizOtherAppointmentAuthorize(@RequestBody BizAppointmentRecordIdParam bizAppointmentRecordIdParam){
+        bizAppointmentRecordService.bizOtherAppointmentAuthorize(bizAppointmentRecordIdParam);
+        return CommonResult.ok();
+    }
+
+
+
+    /**
+     * 临时预约_导出
+     */
+    @Operation(summary = "临时预约_导出")
+    @SaCheckPermission("/biz/bizotherappointment/bizOtherAppointmentExport")
+    @GetMapping(value = "/biz/bizotherappointment/bizOtherAppointmentExport", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+    public void bizOtherAppointmentExport(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException {
+        bizAppointmentRecordService.bizOtherAppointmentExport(bizAppointmentRecordPageParam,response);
+    }
 }

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

@@ -16,6 +16,7 @@ import com.baomidou.mybatisplus.annotation.*;
 import com.fhs.core.trans.anno.Trans;
 import com.fhs.core.trans.constant.TransType;
 import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
 import lombok.Getter;
 import lombok.Setter;
 import vip.xiaonuo.common.pojo.CommonEntity;
@@ -58,6 +59,11 @@ public class BizAppointmentRecord extends CommonEntity {
     /** 司机电话 */
     @Schema(description = "司机电话")
     private String driverMobile;
+    /**
+     * 司机用户ID
+     */
+    @Schema(description = "司机用户ID")
+    private String driverId;
 
     /** 状态(1:待审核  2:审核不通过   3:排队中  4:可入场  5:已入场  6:一次过磅  7:完成装货   8:二次过磅   9:待出场  10:已出场   11:已签收   12:自动审核   13:销售已审核   14:已取消) */
     @Trans(type = TransType.DICTIONARY, key = "appointment_status")
@@ -172,6 +178,13 @@ public class BizAppointmentRecord extends CommonEntity {
     /**装卸时间ID**/
     private String loadTimeId;
 
+    /**是否过磅 1-是 2-否**/
+    @Trans(type = TransType.DICTIONARY, key = "is_weigh")
+    private String isWeigh;
+
+    /**备注**/
+    private String remark;
+
     /**装卸点位*/
     @TableField(exist = false)
     private String loadPoint;
@@ -199,4 +212,32 @@ public class BizAppointmentRecord extends CommonEntity {
     /**完成装货时间*/
     @TableField(exist = false)
     private Date completeSendTime;
+
+    /**起卸单号*/
+    @TableField(exist = false)
+    private String loadNumber;
+
+
+    /**
+     * 其他预约_强制结束操作人
+     */
+    @Schema(description = "操作人")
+    private String exitOperator;
+    /**
+     * 其他预约_强制结束操作时间
+     */
+    @Schema(description = "操作时间")
+    private String exitTime;
+
+    /**
+     * 其他预约_授权离场操作人
+     */
+    @Schema(description = "操作人")
+    private String authorizeOperator;
+    /**
+     * 其他预约_授权离场操作时间
+     */
+    @Schema(description = "操作时间")
+    private String authorizeTime;
+
 }

+ 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);
 }

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

@@ -5,7 +5,13 @@
     <select id="getPage" resultType="vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord">
         select
             bar.id,
-            bar.order_id,
+            bar.is_weigh,
+            bar.remark,
+            bar.driver_id,
+            bar.exit_operator,
+            bar.exit_time,
+            bar.authorize_operator,
+            bar.authorize_time,
             bar.license_number,
             bo.order_number,
             bo.order_name,
@@ -129,4 +135,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;
+
 }

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

@@ -0,0 +1,71 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.bizappointmentrecord.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 其他预约记录添加参数
+ *
+ * @author xumudong
+ * @date 2025/07/02 09:50
+ **/
+@Getter
+@Setter
+public class BizOtherAppointmentAddParam {
+
+
+    /**
+     * 车牌号
+     */
+    @Schema(description = "车牌号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "licenseNumber不能为空")
+    private String licenseNumber;
+
+    /**
+     * 是否过磅
+     */
+    @Schema(description = "是否过磅", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "isWeigh不能为空")
+    private String isWeigh;
+
+    /**
+     * 司机姓名
+     */
+    @Schema(description = "司机姓名")
+    private String driverName;
+
+    /**
+     * 司机电话
+     */
+    @Schema(description = "司机电话")
+    private String driverMobile;
+
+
+    /**
+     * 司机用户ID
+     */
+    @Schema(description = "司机用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "司机不能为空")
+    private String driverId;
+    /**
+     * 备注
+     */
+    @Schema(description = "备注")
+    private String remark;
+
+
+}

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

@@ -0,0 +1,74 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.bizappointmentrecord.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 其他预约记录添加参数
+ *
+ * @author xumudong
+ * @date 2025/07/02 09:50
+ **/
+@Getter
+@Setter
+public class BizOtherAppointmentEditParam {
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /**
+     * 车牌号
+     */
+    @Schema(description = "车牌号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "licenseNumber不能为空")
+    private String licenseNumber;
+
+    /**
+     * 是否过磅
+     */
+    @Schema(description = "是否过磅", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "isWeigh不能为空")
+    private String isWeigh;
+
+    /**
+     * 司机姓名
+     */
+    @Schema(description = "司机姓名")
+    private String driverName;
+
+    /**
+     * 司机电话
+     */
+    @Schema(description = "司机电话")
+    private String driverMobile;
+
+
+    /**
+     * 司机用户ID
+     */
+    @Schema(description = "司机用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "司机不能为空")
+    private String driverId;
+    /**
+     * 备注
+     */
+    @Schema(description = "备注")
+    private String remark;
+
+
+}

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

@@ -0,0 +1,70 @@
+package vip.xiaonuo.biz.modular.bizappointmentrecord.param;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.HeadStyle;
+import com.alibaba.excel.enums.poi.FillPatternTypeEnum;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+public class BizOtherAppointmentExportResult {
+
+
+    /** 车牌号 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "车牌号"})
+    private String licenseNumber;
+    /** 司机姓名 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "司机姓名"})
+    private String driverName;
+    /** 司机电话 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "司机电话"})
+    private String driverMobile;
+    /** 预约状态*/
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "预约状态"})
+    private String statusName;
+
+
+    /** 是否过磅 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "是否过磅"})
+    private String isWeigh;
+
+
+    /** 备注 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "备注"})
+    private String remark;
+
+
+    /**
+     * 其他预约_强制结束操作人
+     */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "其他预约_强制结束操作人"})
+    private String exitOperator;
+    /**
+     * 其他预约_强制结束操作时间
+     */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "其他预约_强制结束操作时间"})
+    private String exitTime;
+
+    /**
+     * 其他预约_授权离场操作人
+     */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "其他预约_授权离场操作人"})
+    private String authorizeOperator;
+    /**
+     * 其他预约_授权离场操作时间
+     */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"其他预约报表", "其他预约_授权离场操作时间"})
+    private String authorizeTime;
+
+
+}

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

@@ -16,10 +16,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import jakarta.servlet.http.HttpServletResponse;
 import vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord;
-import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordAddParam;
-import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordEditParam;
-import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordIdParam;
-import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordPageParam;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.param.*;
 import vip.xiaonuo.biz.modular.bizorder.param.BizOrderPageParam;
 
 import java.io.IOException;
@@ -125,4 +122,48 @@ 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);
+
+
+
+    /**
+     * 其他预约_新增
+     * @param bizOtherAppointmentAddParam
+     */
+    void addOtherAppointment(BizOtherAppointmentAddParam bizOtherAppointmentAddParam);
+    /**
+     * 其他预约_编辑
+     * @param bizOtherAppointmentEditParam
+     */
+    void editOtherAppointment(BizOtherAppointmentEditParam bizOtherAppointmentEditParam);
+
+
+    /**
+     * 其他预约_强制结束
+     * @param bizAppointmentRecordIdParam
+     */
+    void bizOtherAppointmentExit(BizAppointmentRecordIdParam bizAppointmentRecordIdParam);
+    /**
+     * 其他预约_授权离场
+     * @param bizAppointmentRecordIdParam
+     */
+    void bizOtherAppointmentAuthorize(BizAppointmentRecordIdParam bizAppointmentRecordIdParam);
+
+
+    /**
+     * 其他预约_导出
+     * @param bizAppointmentRecordPageParam
+     * @param response
+     * @throws IOException
+     */
+    void bizOtherAppointmentExport(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException;
+
 }

File diff suppressed because it is too large
+ 248 - 233
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/impl/BizAppointmentRecordServiceImpl.java


+ 28 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/controller/BizLoadAppointController.java

@@ -173,4 +173,32 @@ public class BizLoadAppointController {
     public CommonResult<List<BizLoadAppoint>> getList(BizLoadAppointPageParam bizLoadAppointPageParam) {
         return CommonResult.data(bizLoadAppointService.getList(bizLoadAppointPageParam));
     }
+
+    /**
+     * 结束起卸预约
+     *
+     * @author fanzherong
+     * @date  2025/06/25 14:51
+     */
+    @Operation(summary = "结束起卸预约")
+    @CommonLog("结束起卸预约")
+    @PostMapping("/biz/bizloadappoint/endLoad")
+    public CommonResult<String> endLoad(@RequestBody @Valid BizLoadAppointEditParam bizLoadAppointEditParam) {
+        bizLoadAppointService.endLoad(bizLoadAppointEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 填报起卸订单
+     *
+     * @author fanzherong
+     * @date  2025/06/25 14:51
+     */
+    @Operation(summary = "填报起卸订单")
+    @CommonLog("填报起卸订单")
+    @PostMapping("/biz/bizloadappoint/fillLoad")
+    public CommonResult<String> fillLoad(@RequestBody @Valid BizLoadAppointEditParam bizLoadAppointEditParam) {
+        bizLoadAppointService.fillLoad(bizLoadAppointEditParam);
+        return CommonResult.ok();
+    }
 }

+ 9 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/entity/BizLoadAppoint.java

@@ -126,4 +126,13 @@ public class BizLoadAppoint extends CommonEntity {
     /**报港预约状态**/
     @TableField(exist = false)
     private String arriveStatus;
+
+    /**结束说明*/
+    private String endReason;
+
+    /**起卸重量*/
+    private BigDecimal fillWeight;
+
+    /**填报时间*/
+    private Date fillTime;
 }

+ 9 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/param/BizLoadAppointEditParam.java

@@ -83,4 +83,13 @@ public class BizLoadAppointEditParam {
     /**客户签名*/
     private String customerSign;
 
+    /**结束说明*/
+    private String endReason;
+
+    /**起卸重量*/
+    private BigDecimal fillWeight;
+
+    /**填报时间*/
+    private Date fillTime;
+
 }

+ 11 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/service/BizLoadAppointService.java

@@ -99,4 +99,15 @@ public interface BizLoadAppointService extends IService<BizLoadAppoint> {
      * 获取起卸预约待报港列表
      */
     List<BizLoadAppoint> getList(BizLoadAppointPageParam bizLoadAppointPageParam);
+
+    /**
+     * 结束起卸订单
+     * @param bizLoadAppointEditParam
+     */
+    void endLoad(BizLoadAppointEditParam bizLoadAppointEditParam);
+
+    /**
+     * 填报起卸数量
+     */
+    void fillLoad(BizLoadAppointEditParam bizLoadAppointEditParam);
 }

+ 17 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizloadappoint/service/impl/BizLoadAppointServiceImpl.java

@@ -251,6 +251,23 @@ public class BizLoadAppointServiceImpl extends ServiceImpl<BizLoadAppointMapper,
         return list;
     }
 
+    @Override
+    public void endLoad(BizLoadAppointEditParam bizLoadAppointEditParam) {
+        BizLoadAppoint bizLoadAppoint = this.queryEntity(bizLoadAppointEditParam.getId());
+        bizLoadAppoint.setEndReason(bizLoadAppointEditParam.getEndReason());
+        bizLoadAppoint.setStatus("7");
+        this.updateById(bizLoadAppoint);
+    }
+
+    @Override
+    public void fillLoad(BizLoadAppointEditParam bizLoadAppointEditParam) {
+        BizLoadAppoint bizLoadAppoint = this.queryEntity(bizLoadAppointEditParam.getId());
+        bizLoadAppoint.setStatus("8");
+        bizLoadAppoint.setFillWeight(bizLoadAppointEditParam.getFillWeight().multiply(new BigDecimal(1000)));
+        bizLoadAppoint.setFillTime(new Date());
+        this.updateById(bizLoadAppoint);
+    }
+
 
     public String getNumber(){
         lock.lock();

+ 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);
 }

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

@@ -38,6 +38,7 @@ import vip.xiaonuo.biz.modular.bizloaddispatch.param.BizLoadDispatchIdParam;
 import vip.xiaonuo.biz.modular.bizloaddispatch.param.BizLoadDispatchPageParam;
 import vip.xiaonuo.biz.modular.bizloaddispatch.service.BizLoadDispatchService;
 
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -213,4 +214,36 @@ 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.gt("blt.end_time",new Date());
+        queryWrapper.eq("bld.delete_flag","NOT_DELETE");
+        queryWrapper.groupBy("bld.load_time_id");
+        return this.getBaseMapper().getPageList(queryWrapper);
+    }
 }

+ 1 - 1
snowy-web-app/src/main/resources/application-local.properties

@@ -102,7 +102,7 @@ spring.jackson.serialization.write-dates-as-timestamps=false
 spring.data.redis.database=9
 spring.data.redis.host=127.0.0.1
 spring.data.redis.port=6379
-spring.data.redis.password=lease
+spring.data.redis.password=
 spring.data.redis.timeout=10s
 
 spring.data.redis.lettuce.pool.max-active=200

Some files were not shown because too many files changed in this diff