Browse Source

预约管理

fanzherong_v 3 tháng trước cách đây
mục cha
commit
953e48210f
17 tập tin đã thay đổi với 969 bổ sung73 xóa
  1. 11 1
      snowy-admin-web/src/api/biz/bizAppointmentRecordApi.js
  2. 116 0
      snowy-admin-web/src/views/biz/bizappointmentrecord/detail.vue
  3. 2 2
      snowy-admin-web/src/views/biz/bizappointmentrecord/form.vue
  4. 362 21
      snowy-admin-web/src/views/biz/bizappointmentrecord/index.vue
  5. 65 0
      snowy-admin-web/src/views/biz/bizappointmentrecord/review.vue
  6. 4 29
      snowy-admin-web/src/views/biz/bizorder/index.vue
  7. 32 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/controller/BizAppointmentRecordController.java
  8. 35 2
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/entity/BizAppointmentRecord.java
  9. 8 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/BizAppointmentRecordMapper.java
  10. 25 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/mapping/BizAppointmentRecordMapper.xml
  11. 61 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentExportResult.java
  12. 5 3
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentRecordEditParam.java
  13. 24 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentRecordPageParam.java
  14. 12 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/BizAppointmentRecordService.java
  15. 205 12
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/impl/BizAppointmentRecordServiceImpl.java
  16. 1 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmenttime/service/impl/BizAppointmentTimeServiceImpl.java
  17. 1 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/entity/BizOrder.java

+ 11 - 1
snowy-admin-web/src/api/biz/bizAppointmentRecordApi.js

@@ -24,5 +24,15 @@ export default {
 	// 获取预约记录详情
 	bizAppointmentRecordDetail(data) {
 		return request('detail', data, 'get')
-	}
+	},
+	//审核
+	auditRecord(data){
+		return request('auditRecord',data)
+	},
+	//导出
+	exportRecord(data){
+		return request('exportRecord', data, 'get', {
+			responseType: 'blob'
+		})
+	},
 }

+ 116 - 0
snowy-admin-web/src/views/biz/bizappointmentrecord/detail.vue

@@ -0,0 +1,116 @@
+<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.orderNumber }}</a-descriptions-item>
+				<a-descriptions-item label="订单名称" :span="2">{{ formData.orderName }}</a-descriptions-item>
+				<a-descriptions-item label="车牌号" :span="2">{{ formData.licenseNumber }}</a-descriptions-item>
+				<a-descriptions-item label="预约时段" :span="2">{{ formData.beginTime + '~' + formData.endTime }}</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.goodsModel }}</a-descriptions-item>
+				<a-descriptions-item label="司机姓名" :span="2">{{ formData.driverName }}</a-descriptions-item>
+				<a-descriptions-item label="司机电话" :span="2">{{ formData.driverPhone }}</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="2">{{ formData.appointmentReason }}</a-descriptions-item>
+			</a-descriptions>
+		</a-form>
+	</xn-form-container>
+</template>
+
+<script setup name="recordDoubleForm">
+	import { cloneDeep } from 'lodash-es'
+	// 默认是关闭状态
+	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 onOpen = (record) => {
+		visible.value = true
+		//getRecordDoubleDetail(record)
+		if(record){
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+
+	}
+	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>

+ 2 - 2
snowy-admin-web/src/views/biz/bizappointmentrecord/form.vue

@@ -91,9 +91,9 @@
 	}
 	// 默认要校验的
 	const formRules = {
-		orderId: [required('请输入订单id')],
+		orderId: [required('请选择订单信息')],
 		licenseNumber: [required('请输入车牌号')],
-		timeId: [required('请输入预约时段id')],
+		timeId: [required('请选择预约时段')],
 	}
 	// 验证并提交数据
 	const onSubmit = () => {

+ 362 - 21
snowy-admin-web/src/views/biz/bizappointmentrecord/index.vue

@@ -1,4 +1,63 @@
 <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="orderNumber">
+						<a-input v-model:value="searchFormState.orderNumber" placeholder="订单编号查询" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="订单名称" name="orderName">
+						<a-input v-model:value="searchFormState.orderName" 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>
+				<template v-if="advanced">
+					<a-col :span="6">
+						<a-form-item label="客户名称" name="customerName">
+							<a-input v-model:value="searchFormState.customerName" placeholder="客户名称查询" />
+						</a-form-item>
+					</a-col>
+					<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="driverPhone">
+							<a-input v-model:value="searchFormState.driverPhone" 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"
@@ -13,69 +72,222 @@
 						<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 === 'timeInfo'">
+					<span>{{record.beginTime + '~' + record.endTime}}</span>
+				</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.driverPhone }}</p>
+					</div>
+				</template>
+				<template v-if="column.dataIndex === 'goodsInfo'">
+					<div class="time-list">
+						<p>名称:{{ record.goodsName }}</p>
+						<p style="margin-bottom: 0">规格:{{ record.goodsModel }}</p>
+					</div>
+				</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'">二维码</a>
+
+					<a-divider type="vertical" v-if="record.status!='1'&& record.status!='2'"/>
+
 					<a-space>
-						<a @click="formRef.onOpen(record)" v-if="hasPerm('bizAppointmentRecordEdit')">编辑</a>
-						<a-divider type="vertical" v-if="hasPerm(['bizAppointmentRecordEdit', 'bizAppointmentRecordDelete'], 'and')" />
-						<a-button type="link" danger size="small" v-if="hasPerm('bizAppointmentRecordDelete')"  @click="deleteConfig(record)">删除</a-button>
+						<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 == '1' || record.status == '2')">
+										<a style="color:blue" @click="formRef.onOpen(record)" >编辑</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizAppointmentRecordDelete') && (record.status == '1' || record.status == '2')">
+										<a style="color:red" type="link" danger size="small" @click="deleteConfig(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()" />
+
+
+	<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.orderNumber }}</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'
 
 	const submitLoading = ref(false)
 	const tableRef = ref()
 	const formRef = ref()
+	const reviewRef = ref()
+	const detailRef = ref()
 	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+
+	const nowRecord = 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: 'orderId'
+			dataIndex: 'orderInfo',
+			width:250
 		},
 		{
 			title: '车牌号',
-			dataIndex: 'licenseNumber'
+			dataIndex: 'licenseNumber',
+			width:160,
+			align: 'center'
 		},
 		{
-			title: '预约时段id',
-			dataIndex: 'timeId'
+			title: '预约时段',
+			dataIndex: 'timeInfo',
+			align:'center',
+			width:200
 		},
 		{
-			title: '司机姓名',
-			dataIndex: 'driverName'
+			title: '客户信息',
+			dataIndex: 'customerInfo',
+			align:'center',
+			width:200
 		},
 		{
-			title: '司机电话',
-			dataIndex: 'driverPhone'
+			title: '货品信息',
+			dataIndex: 'goodsInfo',
+			width:200
+		},
+		{
+			title: '司机信息',
+			dataIndex: 'driverInfo',
+			width: '200px'
 		},
 		{
 			title: '状态',
-			dataIndex: 'status'
+			dataIndex: 'status',
+			align: 'center',
+			width:120
 		},
 	]
 	// 操作栏通过权限判断是否显示
-	if (hasPerm(['bizAppointmentRecordEdit', 'bizAppointmentRecordDelete'])) {
-		columns.push({
-			title: '操作',
-			dataIndex: 'action',
-			align: 'center',
-			width: 150
-		})
-	}
+	columns.push({
+		title: '操作',
+		dataIndex: 'action',
+		align: 'center',
+		width: 150
+	})
+
 	const selectedRowKeys = ref([])
 	// 列表选择配置
 	const options = {
@@ -93,7 +305,8 @@
 		}
 	}
 	const loadData = (parameter) => {
-		return bizAppointmentRecordApi.bizAppointmentRecordPage(parameter).then((data) => {
+		const searchFormParam = cloneDeep(searchFormState.value)
+		return bizAppointmentRecordApi.bizAppointmentRecordPage(Object.assign(parameter, searchFormParam)).then((data) => {
 			return data
 		})
 	}
@@ -146,4 +359,132 @@
 			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
+		}
+		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)
+		})
+	}
 </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/bizappointmentrecord/review.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.appointmentReason" placeholder="请输入审核备注"
+                            :auto-size="{ minRows: 3, maxRows: 5 }"/>
+            </a-form-item>
+        </a-form>
+        <template #footer>
+            <a-spin :spinning="submitLoading">
+                <a-button style="margin-right: 8px" @click="onsubmit(true)" type="primary" danger>审核驳回</a-button>
+                <a-button type="primary" @click="onsubmit(false)">审核通过</a-button>
+            </a-spin>
+        </template>
+    </a-modal>
+</template>
+<script setup>
+import {message} from 'ant-design-vue';
+import bizAppointmentRecordApi from '@/api/biz/bizAppointmentRecordApi'
+
+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.appointmentReason) {
+            message.error('审核驳回时,备注信息不能为空')
+            return
+        }
+    }
+    submitLoading.value = true
+	formData.value.auditFlag = flag
+	bizAppointmentRecordApi.auditRecord(formData.value).then(() => {
+        onClose()
+        emit('successful', null)
+    }).finally(() => {
+        submitLoading.value = false
+    })
+}
+// 抛出函数
+defineExpose({
+    showModal
+})
+</script>
+<style scoped>
+
+</style>

+ 4 - 29
snowy-admin-web/src/views/biz/bizorder/index.vue

@@ -1,5 +1,5 @@
 <template>
-	<a-card :bordered="false">
+	<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">
@@ -48,6 +48,8 @@
 				</a-col>
 			</a-row>
 		</a-form>
+	</a-card>
+	<a-card :bordered="false">
 		<s-table
 			ref="tableRef"
 			:columns="columns"
@@ -382,9 +384,7 @@
 	const getQrCode = (record) => {
 		//QRCode.toDataURL("id:"+record.id+"saleCode:"+record.saleCode, {
 		let param = {
-			id:record.id,
-			projectCode:record.projectCode,
-			projectName:record.projectName
+			id:record.id
 		}
 		QRCode.toDataURL(JSON.stringify(param), {
 			errorCorrectionLevel: 'H',
@@ -414,33 +414,8 @@
 
 	// 下载二维码
 	const downloadFile = () => {
-		console.log("projectNameChecked:"+projectNameChecked.value)
-		console.log("projectCodeChecked:"+projectCodeChecked.value)
-		debugger;
 		const qrcodeDiv = document.getElementById('qrcode');
 		html2canvas(qrcodeDiv, {
-			onclone: (clonedDoc) => {
-				debugger
-				if(!projectNameChecked.value){
-					const projectNameFlag = clonedDoc.getElementById("projectNameFlag")
-					projectNameFlag.style.display = 'none'
-				}else{
-					const checkboxes = clonedDoc.querySelectorAll('.ant-checkbox-wrapper');
-					checkboxes.forEach((checkbox) => {
-						checkbox.style.display = 'none';
-					})
-				}
-				if(!projectCodeChecked.value){
-					const projectCodeFlag = clonedDoc.getElementById("projectCodeFlag")
-					projectCodeFlag.style.display = 'none'
-				}else{
-					const checkboxes = clonedDoc.querySelectorAll('.ant-checkbox-wrapper');
-					checkboxes.forEach((checkbox) => {
-						checkbox.style.display = 'none';
-					})
-				}
-
-			},
 			logging: false,
 			allowTaint: true,
 			scale: window.devicePixelRatio,

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

@@ -16,12 +16,16 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import io.swagger.v3.oas.annotations.Operation;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.http.MediaType;
 import org.springframework.validation.annotation.Validated;
 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.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;
@@ -33,6 +37,8 @@ import vip.xiaonuo.biz.modular.bizappointmentrecord.service.BizAppointmentRecord
 import jakarta.annotation.Resource;
 import jakarta.validation.Valid;
 import jakarta.validation.constraints.NotEmpty;
+
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -70,6 +76,7 @@ public class BizAppointmentRecordController {
      */
     @Operation(summary = "添加预约记录")
     @CommonLog("添加预约记录")
+    @CommonNoRepeat
     @PostMapping("/biz/bizappointmentrecord/add")
     public CommonResult<String> add(@RequestBody @Valid BizAppointmentRecordAddParam bizAppointmentRecordAddParam) {
         bizAppointmentRecordService.add(bizAppointmentRecordAddParam);
@@ -116,4 +123,29 @@ public class BizAppointmentRecordController {
     public CommonResult<BizAppointmentRecord> detail(@Valid BizAppointmentRecordIdParam bizAppointmentRecordIdParam) {
         return CommonResult.data(bizAppointmentRecordService.detail(bizAppointmentRecordIdParam));
     }
+
+
+    /**
+     * 审核
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "审核")
+    @CommonLog("审核")
+    @PostMapping("/biz/bizappointmentrecord/auditRecord")
+    public CommonResult<String> auditRecord(@RequestBody @Valid BizAppointmentRecordEditParam bizAppointmentRecordEditParam) {
+        bizAppointmentRecordService.auditRecord(bizAppointmentRecordEditParam);
+        return CommonResult.ok();
+    }
+
+
+    /**
+     * 导出预约报表
+     */
+    @Operation(summary = "导出预约报表")
+    @GetMapping(value = "/biz/bizappointmentrecord/exportRecord", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+    public void exportRecord(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException {
+        bizAppointmentRecordService.exportRecord(bizAppointmentRecordPageParam,response);
+    }
 }

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

@@ -13,6 +13,8 @@
 package vip.xiaonuo.biz.modular.bizappointmentrecord.entity;
 
 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 lombok.Getter;
 import lombok.Setter;
@@ -57,7 +59,38 @@ public class BizAppointmentRecord extends CommonEntity {
     @Schema(description = "司机电话")
     private String driverPhone;
 
-    /** 状态(1:待审核  2:审核不通过   3:排队中  4:可入场  5:已入场  6:一次过磅  7:完成装货   8:二次过磅   9:已出场  10:已签收   11:已审核   12:已取消) */
-    @Schema(description = "状态(1:待审核  2:审核不通过   3:排队中  4:可入场  5:已入场  6:一次过磅  7:完成装货   8:二次过磅   9:已出场  10:已签收   11:已审核   12:已取消)")
+    /** 状态(1:待审核  2:审核不通过   3:排队中  4:可入场  5:已入场  6:一次过磅  7:完成装货   8:二次过磅   9:待出场  10:已出场   11:已签收   12:自动审核   13:销售已审核   14:已取消) */
+    @Trans(type = TransType.DICTIONARY, key = "appointment_status")
     private String status;
+
+    /**审核备注*/
+    private String appointmentReason;
+
+    /**订单编号*/
+    @TableField(exist = false)
+    private String orderNumber;
+
+    /**订单名称*/
+    @TableField(exist = false)
+    private String orderName;
+
+    /**客户名称*/
+    @TableField(exist = false)
+    private String customerName;
+
+    /**货品名称*/
+    @TableField(exist = false)
+    private String goodsName;
+
+    /**货品规格*/
+    @TableField(exist = false)
+    private String goodsModel;
+
+    /**开始时间段*/
+    @TableField(exist = false)
+    private String beginTime;
+
+    /**结束时间段*/
+    @TableField(exist = false)
+    private String endTime;
 }

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

@@ -12,9 +12,14 @@
  */
 package vip.xiaonuo.biz.modular.bizappointmentrecord.mapper;
 
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
 import vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord;
 
+import java.util.List;
+
 /**
  * 预约记录Mapper接口
  *
@@ -22,4 +27,7 @@ import vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord;
  * @date  2025/03/24 14:47
  **/
 public interface BizAppointmentRecordMapper extends BaseMapper<BizAppointmentRecord> {
+    Page<BizAppointmentRecord> getPage(@Param("page") Page<BizAppointmentRecord> page, @Param("ew") QueryWrapper<BizAppointmentRecord> ew);
+
+    List<BizAppointmentRecord> getPage(@Param("ew") QueryWrapper<BizAppointmentRecord> ew);
 }

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

@@ -2,4 +2,28 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="vip.xiaonuo.biz.modular.bizappointmentrecord.mapper.BizAppointmentRecordMapper">
 
-</mapper>
+    <select id="getPage" resultType="vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord">
+        select
+            bar.id,
+            bar.order_id,
+            bar.license_number,
+            bo.order_number,
+            bo.order_name,
+            bc.customer_name,
+            bg.NAME goodsName,
+            bg.MODEL goodsModel,
+            bar.time_id,
+            bat.begin_time,
+            bat.end_time,
+            bar.driver_name,
+            bar.driver_phone,
+            bar.status,
+            bar.appointment_reason
+        from biz_appointment_record bar
+         left join biz_order bo on bar.order_id = bo.id
+         left join biz_goods bg on bg.id = bo.good_id
+         left join biz_appointment_time bat on bat.id = bar.time_id
+         left join biz_customer bc on bc.id = bo.customer_id
+        ${ew.customSqlSegment}
+    </select>
+</mapper>

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

@@ -0,0 +1,61 @@
+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 lombok.Data;
+
+import java.math.BigDecimal;
+
+@Data
+public class BizAppointmentExportResult {
+    /** 订单编号 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "订单编号"})
+    private String orderNumber;
+
+    /** 订单名称 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "订单名称"})
+    private String orderName;
+
+    /** 车牌号 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "车牌号"})
+    private String licenseNumber;
+
+    /** 预约时段 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "预约时段"})
+    private String timeInfo;
+
+    /** 客户名称 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "客户名称"})
+    private String customerName;
+
+    /** 货品名称*/
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "货品名称"})
+    private String goodsName;
+
+    /** 货品规格*/
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "货品规格"})
+    private String goodsModel;
+
+    /** 司机姓名 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "司机姓名"})
+    private String driverName;
+
+    /** 司机电话 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "司机电话"})
+    private String driverPhone;
+
+    /** 预约状态*/
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "预约状态"})
+    private String statusName;
+}

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

@@ -38,17 +38,14 @@ public class BizAppointmentRecordEditParam {
 
     /** 订单id */
     @Schema(description = "订单id", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "orderId不能为空")
     private String orderId;
 
     /** 车牌号 */
     @Schema(description = "车牌号", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "licenseNumber不能为空")
     private String licenseNumber;
 
     /** 预约时段id */
     @Schema(description = "预约时段id", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "timeId不能为空")
     private String timeId;
 
     /** 司机姓名 */
@@ -63,4 +60,9 @@ public class BizAppointmentRecordEditParam {
     @Schema(description = "状态(1:待审核  2:审核不通过   3:排队中  4:可入场  5:已入场  6:一次过磅  7:完成装货   8:二次过磅   9:已出场  10:已签收   11:已审核   12:已取消)")
     private String status;
 
+
+    private String auditFlag;
+
+    private String appointmentReason;
+
 }

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

@@ -48,4 +48,28 @@ public class BizAppointmentRecordPageParam {
     @Schema(description = "关键词")
     private String searchKey;
 
+    /**订单编号*/
+    private String orderNumber;
+
+    /**订单名称*/
+    private String orderName;
+
+    /***客户名称*/
+    private String customerName;
+
+    /***司机名称*/
+    private String driverName;
+
+    /**司机电话*/
+    private String driverPhone;
+
+    /***货品名称*/
+    private String goodsName;
+
+    /**车牌号码*/
+    private String licenseNumber;
+
+    /**状态*/
+    private String status;
+
 }

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

@@ -14,12 +14,15 @@ package vip.xiaonuo.biz.modular.bizappointmentrecord.service;
 
 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.bizorder.param.BizOrderPageParam;
 
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -77,4 +80,13 @@ public interface BizAppointmentRecordService extends IService<BizAppointmentReco
      * @date  2025/03/24 14:47
      **/
     BizAppointmentRecord queryEntity(String id);
+
+    /**审核*/
+    void auditRecord(BizAppointmentRecordEditParam bizAppointmentRecordEditParam);
+
+    /**导出报表*/
+    void exportRecord(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException;
+
+    /**地磅端门禁和过磅校验*/
+    BizAppointmentRecord checkAppointmentRecord(BizAppointmentRecordPageParam bizAppointmentRecordPageParam);
 }

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

@@ -15,24 +15,35 @@ package vip.xiaonuo.biz.modular.bizappointmentrecord.service.impl;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollStreamUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.PhoneUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fhs.trans.service.impl.TransService;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.commons.compress.utils.Lists;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.param.*;
+import vip.xiaonuo.biz.modular.bizappointmenttime.entity.BizAppointmentTime;
+import vip.xiaonuo.biz.modular.bizappointmenttime.service.BizAppointmentTimeService;
+import vip.xiaonuo.biz.modular.bizconfig.entity.BizConfig;
+import vip.xiaonuo.biz.modular.bizconfig.service.BizConfigService;
+import vip.xiaonuo.biz.modular.bizorder.param.BizOrderExportResult;
+import vip.xiaonuo.biz.modular.utils.CommonExportUtil;
 import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
 import vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord;
 import vip.xiaonuo.biz.modular.bizappointmentrecord.mapper.BizAppointmentRecordMapper;
-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 java.io.IOException;
 import java.util.List;
+import java.util.regex.Pattern;
 
 /**
  * 预约记录Service接口实现类
@@ -43,37 +54,173 @@ import java.util.List;
 @Service
 public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentRecordMapper, BizAppointmentRecord> implements BizAppointmentRecordService {
 
+    @Resource
+    private BizConfigService bizConfigService;
+    @Resource
+    private BizAppointmentTimeService bizAppointmentTimeService;
+    @Resource
+    private TransService transService;
+
     @Override
     public Page<BizAppointmentRecord> page(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
+        QueryWrapper<BizAppointmentRecord> queryWrapper = getQueryWrapper(bizAppointmentRecordPageParam);
+        return this.getBaseMapper().getPage(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    public QueryWrapper<BizAppointmentRecord> getQueryWrapper(BizAppointmentRecordPageParam bizAppointmentRecordPageParam){
         QueryWrapper<BizAppointmentRecord> queryWrapper = new QueryWrapper<BizAppointmentRecord>().checkSqlInjection();
-        if(ObjectUtil.isAllNotEmpty(bizAppointmentRecordPageParam.getSortField(), bizAppointmentRecordPageParam.getSortOrder())) {
-            CommonSortOrderEnum.validate(bizAppointmentRecordPageParam.getSortOrder());
-            queryWrapper.orderBy(true, bizAppointmentRecordPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
-                    StrUtil.toUnderlineCase(bizAppointmentRecordPageParam.getSortField()));
-        } else {
-            queryWrapper.lambda().orderByAsc(BizAppointmentRecord::getId);
-        }
-        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getOrderName())){
+            queryWrapper.like("bo.order_name",bizAppointmentRecordPageParam.getOrderName());
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getOrderNumber())){
+            queryWrapper.like("bo.order_number",bizAppointmentRecordPageParam.getOrderNumber());
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getCustomerName())){
+            queryWrapper.like("bc.customer_name",bizAppointmentRecordPageParam.getCustomerName());
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getDriverName())){
+            queryWrapper.like("bar.driver_name",bizAppointmentRecordPageParam.getDriverName());
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getDriverPhone())){
+            queryWrapper.like("bar.driver_phone",bizAppointmentRecordPageParam.getDriverPhone());
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getGoodsName())){
+            queryWrapper.like("bg.NAME",bizAppointmentRecordPageParam.getGoodsName());
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getLicenseNumber())){
+            queryWrapper.like("bar.license_number",bizAppointmentRecordPageParam.getLicenseNumber());
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getStatus())){
+            queryWrapper.eq("bar.status",bizAppointmentRecordPageParam.getStatus());
+        }
+        queryWrapper.eq("bar.delete_flag","NOT_DELETE");
+        queryWrapper.orderByDesc("bar.create_time");
+        return queryWrapper;
     }
 
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void add(BizAppointmentRecordAddParam bizAppointmentRecordAddParam) {
+        checkParam(bizAppointmentRecordAddParam);
+        //获取流程配置判断预约是否需要审核
+        BizConfig bizConfig = bizConfigService.getOne(new QueryWrapper<BizConfig>().lambda().last("limit 1"));
         BizAppointmentRecord bizAppointmentRecord = BeanUtil.toBean(bizAppointmentRecordAddParam, BizAppointmentRecord.class);
+        if(ObjectUtil.isNotNull(bizConfig)){
+            if(StringUtils.equals(bizConfig.getAuditSwitch(),"1")){
+                //开启审核,设置待审核状态
+                bizAppointmentRecord.setStatus("1");
+            }else{
+                //未开启审核,设置排队中状态
+                bizAppointmentRecord.setStatus("3");
+            }
+        }
         this.save(bizAppointmentRecord);
+
+        //更新时间段内已预约数
+        BizAppointmentTime bizAppointmentTime = bizAppointmentTimeService.getById(bizAppointmentRecordAddParam.getTimeId());
+        bizAppointmentTime.setApplyNumberAlready(bizAppointmentTime.getApplyNumberAlready()+1);
+        bizAppointmentTimeService.updateById(bizAppointmentTime);
+    }
+
+    public void checkParam(BizAppointmentRecordAddParam bizAppointmentRecordAddParam){
+        //校验车牌号
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getLicenseNumber())){
+            if(!isCarNumber(bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim())){
+                throw new CommonException("车牌号:{}格式错误",bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim());
+            }
+            //校验车牌号是否添加过预约,排除11:已签收、 13:销售已审核  、 14:已取消
+            long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
+                    eq(BizAppointmentRecord::getLicenseNumber,bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim()).
+                    notIn(BizAppointmentRecord::getStatus, "11", "13", "14"));
+            if(count>0){
+                throw new CommonException("车牌号:{}已经添加过预约!",bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim());
+            }
+        }
+        //校验手机号
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getDriverPhone())){
+            if(!PhoneUtil.isMobile(bizAppointmentRecordAddParam.getDriverPhone())) {
+                throw new CommonException("手机号码:{}格式错误", bizAppointmentRecordAddParam.getDriverPhone());
+            }
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getTimeId())){
+            //校验预约时间段是否预约满
+            //查询预约时间段内的预约记录,10:已出场   11:已签收   12:自动审核  13:销售已审核   14:已取消这些状态都占用预约名额
+            long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
+                    eq(BizAppointmentRecord::getTimeId, bizAppointmentRecordAddParam.getTimeId()).
+                    notIn(BizAppointmentRecord::getStatus, "10", "11", "12", "13", "14"));
+            //查询预约时间段内可预约次数
+            BizAppointmentTime bizAppointmentTime = bizAppointmentTimeService.getById(bizAppointmentRecordAddParam.getTimeId());
+            if(count>=bizAppointmentTime.getApplyNumber()){
+                throw new CommonException("该时间段已经预约满!");
+            }
+        }
+
+    }
+
+    public void checkParam(BizAppointmentRecordEditParam bizAppointmentRecordEditParam,BizAppointmentRecord bizAppointmentRecord){
+        //校验车牌号
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getLicenseNumber())){
+            if(!StringUtils.equals(bizAppointmentRecord.getLicenseNumber(),bizAppointmentRecordEditParam.getLicenseNumber())){
+                //车牌号修改过
+                if(!isCarNumber(bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim())){
+                    throw new CommonException("车牌号:{}格式错误",bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim());
+                }
+                //校验车牌号是否添加过预约,排除11:已签收、 13:销售已审核  、 14:已取消
+                long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
+                        eq(BizAppointmentRecord::getLicenseNumber,bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim()).
+                        notIn(BizAppointmentRecord::getStatus, "11", "13", "14"));
+                if(count>0){
+                    throw new CommonException("车牌号:{}已经添加过预约!",bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim());
+                }
+            }
+        }
+        //校验手机号
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getDriverPhone())){
+            if(!PhoneUtil.isMobile(bizAppointmentRecordEditParam.getDriverPhone())) {
+                throw new CommonException("手机号码:{}格式错误", bizAppointmentRecordEditParam.getDriverPhone());
+            }
+        }
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getTimeId())){
+            if(!StringUtils.equals(bizAppointmentRecord.getTimeId(),bizAppointmentRecordEditParam.getTimeId())){
+                //校验预约时间段是否预约满
+                //查询预约时间段内的预约记录,10:已出场   11:已签收   12:自动审核  13:销售已审核   14:已取消这些状态都占用预约名额
+                long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
+                        eq(BizAppointmentRecord::getTimeId, bizAppointmentRecordEditParam.getTimeId()).
+                        notIn(BizAppointmentRecord::getStatus, "10", "11", "12", "13", "14"));
+                //查询预约时间段内可预约次数
+                BizAppointmentTime bizAppointmentTime = bizAppointmentTimeService.getById(bizAppointmentRecordEditParam.getTimeId());
+                if(count>=bizAppointmentTime.getApplyNumber()){
+                    throw new CommonException("该时间段已经预约满!");
+                }
+            }
+
+        }
+
     }
 
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void edit(BizAppointmentRecordEditParam bizAppointmentRecordEditParam) {
         BizAppointmentRecord bizAppointmentRecord = this.queryEntity(bizAppointmentRecordEditParam.getId());
+        checkParam(bizAppointmentRecordEditParam,bizAppointmentRecord);
         BeanUtil.copyProperties(bizAppointmentRecordEditParam, bizAppointmentRecord);
+        if(StringUtils.equals(bizAppointmentRecord.getStatus(),"2")){
+            //如果当前状态是审核不通过的状态,修改后重新提交审核
+            bizAppointmentRecord.setStatus("1");
+        }
         this.updateById(bizAppointmentRecord);
     }
 
     @Transactional(rollbackFor = Exception.class)
     @Override
     public void delete(List<BizAppointmentRecordIdParam> bizAppointmentRecordIdParamList) {
+        //释放预约数
+        for(BizAppointmentRecordIdParam bizAppointmentRecordIdParam : bizAppointmentRecordIdParamList){
+            BizAppointmentRecord bizAppointmentRecord = this.queryEntity(bizAppointmentRecordIdParam.getId());
+            BizAppointmentTime bizAppointmentTime = bizAppointmentTimeService.getById(bizAppointmentRecord.getTimeId());
+            bizAppointmentTime.setApplyNumberAlready(bizAppointmentTime.getApplyNumberAlready()-1);
+            bizAppointmentTimeService.updateById(bizAppointmentTime);
+        }
         // 执行删除
         this.removeByIds(CollStreamUtil.toList(bizAppointmentRecordIdParamList, BizAppointmentRecordIdParam::getId));
     }
@@ -91,4 +238,50 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
         }
         return bizAppointmentRecord;
     }
+
+    @Override
+    public void auditRecord(BizAppointmentRecordEditParam bizAppointmentRecordEditParam) {
+        BizAppointmentRecord bizAppointmentRecord = this.queryEntity(bizAppointmentRecordEditParam.getId());
+        if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getAuditFlag())){
+            if(StringUtils.equals(bizAppointmentRecordEditParam.getAuditFlag(),"true")){
+                bizAppointmentRecord.setStatus("2");
+            }else{
+                bizAppointmentRecord.setStatus("3");
+            }
+            bizAppointmentRecord.setAppointmentReason(bizAppointmentRecordEditParam.getAppointmentReason());
+            this.updateById(bizAppointmentRecord);
+        }
+    }
+
+    @Override
+    public void exportRecord(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException {
+        QueryWrapper<BizAppointmentRecord> queryWrapper = getQueryWrapper(bizAppointmentRecordPageParam);
+        List<BizAppointmentRecord> recordList = this.getBaseMapper().getPage(queryWrapper);
+        String fileName = "预约报表.xlsx";
+        List<BizAppointmentExportResult> list = Lists.newArrayList();
+        transService.transBatch(recordList);
+        for(BizAppointmentRecord bizAppointmentRecord : recordList){
+            BizAppointmentExportResult bizAppointmentExportResult = new BizAppointmentExportResult();
+            BeanUtil.copyProperties(bizAppointmentRecord, bizAppointmentExportResult);
+            bizAppointmentExportResult.setStatusName((String) bizAppointmentRecord.getTransMap().get("statusName"));
+            bizAppointmentExportResult.setTimeInfo(bizAppointmentRecord.getBeginTime()+"~"+bizAppointmentRecord.getEndTime());
+            list.add(bizAppointmentExportResult);
+        }
+        CommonExportUtil.export(fileName, BizAppointmentExportResult.class,list,response,"预约报表");
+    }
+
+    @Override
+    public BizAppointmentRecord checkAppointmentRecord(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
+        return null;
+    }
+
+    /**
+     * 车牌号校验
+     * @param carNumber
+     * @return
+     */
+    public boolean isCarNumber(String carNumber){
+        String carNumberPattern = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))|([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})";
+        return Pattern.matches(carNumberPattern, carNumber);
+    }
 }

+ 1 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmenttime/service/impl/BizAppointmentTimeServiceImpl.java

@@ -198,7 +198,7 @@ public class BizAppointmentTimeServiceImpl extends ServiceImpl<BizAppointmentTim
         String format = DateUtil.format(DateUtil.date(), "HH");
         //查询大于等于当前时间的时间段个数
         List<BizAppointmentTime> list = this.list(new QueryWrapper<BizAppointmentTime>().lambda().
-                and(wrapper->wrapper.ge(BizAppointmentTime::getBeginTime, format + ":00").or().gt(BizAppointmentTime::getEndTime,format + ":00")).
+                and(wrapper->wrapper.ge(BizAppointmentTime::getBeginTime, format + ":00").or().gt(BizAppointmentTime::getFinishTime,format + ":00")).
                 orderByAsc(BizAppointmentTime::getBeginTime));
         //如果查询到的时段个数大于等于配置的下拉个数,直接返回,反之,从前面查询补上
         if(list.size()>= bizConfig.getPullNumber()){

+ 1 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/entity/BizOrder.java

@@ -33,7 +33,7 @@ import java.util.Date;
 @Getter
 @Setter
 @TableName("biz_order")
-public class BizOrder extends CommonEntity implements TransPojo {
+public class BizOrder extends CommonEntity{
 
     /** 主键ID */
     @TableId