Browse Source

充电桩预约代码提交

fanzherong 1 day ago
parent
commit
b703f96f89

+ 40 - 0
snowy-admin-web/src/api/biz/bizChargeStationReservationApi.js

@@ -0,0 +1,40 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/bizchargestationreservation/` + url, ...arg)
+
+/**
+ * 预约记录Api接口管理器
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+export default {
+	// 获取预约记录分页
+	bizChargeStationReservationPage(data) {
+		return request('page', data, 'get')
+	},
+	// 其他预约表单提交
+	bizChargeStationReservationSubmitForm(data, edit = false) {
+		return request(edit ? 'editChargeStationReservation' : 'addChargeStationReservation', data)
+	},
+	// 删除其他预约记录
+	bizChargeStationReservationDelete(data) {
+		return request('deleteChargeStationReservation', data)
+	},
+	//强制结束
+	bizChargeStationReservationExit(data){
+		return request('bizChargeStationReservationExit',data)
+	},
+
+	// 获取预约记录详情
+	bizAppointmentRecordDetail(data) {
+		return request('detail', data, 'get')
+	},
+
+	//导出
+	bizChargeStationReservationExport(data){
+		return request('bizChargeStationReservationExport', data, 'get', {
+			responseType: 'blob'
+		})
+	}
+}

+ 125 - 0
snowy-admin-web/src/views/biz/bizchargestationreservation/detail.vue

@@ -0,0 +1,125 @@
+<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.otherNumber }}</a-descriptions-item>
+				<a-descriptions-item label="车牌号" :span="2">{{ formData.licenseNumber }}</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="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>
+		</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>

+ 119 - 0
snowy-admin-web/src/views/biz/bizchargestationreservation/form.vue

@@ -0,0 +1,119 @@
+<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>
+		<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 bizChargeStationReservationApi from '@/api/biz/bizChargeStationReservationApi'
+	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) => {
+
+				return Promise.resolve(data)
+			})
+		}
+	}
+
+
+
+
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		licenseNumber: [required('请输入车牌号')],
+		driverId: [required('请选择司机')]
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+
+				bizChargeStationReservationApi
+					.bizChargeStationReservationSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 431 - 0
snowy-admin-web/src/views/biz/bizchargestationreservation/index.vue

@@ -0,0 +1,431 @@
+<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="otherNumber">
+						<a-input v-model:value="searchFormState.otherNumber" 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="driverName">
+						<a-input v-model:value="searchFormState.driverName" placeholder="司机名称" />
+					</a-form-item>
+				</a-col>
+
+				<template v-if="advanced">
+					<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('addChargeStationReservation')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<a-button @click="exportTotal" v-if="hasPerm('bizChargeStationReservationExport')">
+						<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('editChargeStationReservation') && ( record.status == '4')">
+										<a style="color:blue" @click="formRef.onOpen(record)" >编辑</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('deleteChargeStationReservation') && ( 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('bizChargeStationReservationExit') && (record.status=='4' || record.status=='5' || record.status=='6' || record.status=='7'
+									|| record.status=='8' || record.status=='9' || record.status=='16' || record.status=='18'  )">
+										<a style="color:green"  @click="cancel(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)" />
+
+</template>
+
+<script setup name="bizappointmentrecord">
+	import { cloneDeep } from 'lodash-es'
+	import Form from './form.vue'
+	import Detail from './detail.vue'
+	import bizChargeStationReservationApi from '@/api/biz/bizChargeStationReservationApi'
+	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: 'otherNumber',
+			width:150,
+			align: 'center'
+		},
+		{
+			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
+		},
+
+	]
+	// 操作栏通过权限判断是否显示
+	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 = '4'
+		return bizChargeStationReservationApi.bizChargeStationReservationPage(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
+			}
+		]
+		bizChargeStationReservationApi.bizChargeStationReservationDelete(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
+					}
+				]
+
+				bizChargeStationReservationApi
+					.bizChargeStationReservationDelete(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
+					}
+				bizChargeStationReservationApi
+					.bizChargeStationReservationExit(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+
+
+	// 批量删除
+	const deleteBatchBizAppointmentRecord = (params) => {
+		bizChargeStationReservationApi.bizChargeStationReservationDelete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+
+	//二维码
+	const open = ref(false);
+	const qrCodeUrl = ref({})
+	const showModal = (record) => {
+		nowRecord.value = record
+		open.value = true;
+		getQrCode(record)
+
+	};
+
+
+
+	const closeQrCode = () => {
+		open.value = false;
+	}
+
+
+
+	//导出
+	const exportTotal = () => {
+		Modal.confirm({
+			title: '确定要导出记录吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				const searchFormParam = cloneDeep(searchFormState.value)
+				bizChargeStationReservationApi
+					.bizChargeStationReservationExport(Object.assign(searchFormParam))
+					.then((res) => {
+						downloadUtil.resultDownload(res)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+
+</script>
+
+<style lang="less" scoped>
+/** 表头居中 */
+:deep .ant-table-thead > tr > th {
+	text-align: center;
+}
+
+.time-list {
+	-webkit-text-size-adjust: none;
+	font-size: 13px;
+	display: flex;
+	flex-direction: column;
+
+	p {
+		white-space: nowrap;
+		span {
+			display: inline-block;
+			font-weight: 600;
+			height: 16px;
+			line-height: 16px;
+			border-radius: 5px;
+			text-align: center;
+			margin-right: 2px;
+			padding: 0 5px;
+		}
+		.blueTag {
+			color: #1890ff;
+			background: rgba(24, 144, 255, 0.1);
+		}
+		.orangeTag {
+			color: #ff7c18;
+			background: rgba(24, 144, 255, 0.1);
+		}
+		.greenTag {
+			color: rgb(82, 196, 26);
+			background: rgba(82, 196, 26, 0.1);
+		}
+		.purpleTag {
+			color: rgb(77, 26, 196);
+			background: rgba(82, 196, 26, 0.1);
+		}
+		.showNum {
+			display: inline-block;
+			height: 16px;
+			line-height: 16px;
+			width: 45px;
+			border-radius: 5px;
+			text-align: center;
+			margin-right: 2px;
+			text-align: right;
+		}
+	}
+}
+</style>

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

@@ -86,7 +86,7 @@
 		userPageApi: (param) => {
 		userPageApi: (param) => {
 			param.roleName = '司机'
 			param.roleName = '司机'
 			return userApi.userSelectorByRole(param).then((data) => {
 			return userApi.userSelectorByRole(param).then((data) => {
-				debugger
+
 				return Promise.resolve(data)
 				return Promise.resolve(data)
 			})
 			})
 		}
 		}
@@ -114,7 +114,7 @@
 			.then(() => {
 			.then(() => {
 				submitLoading.value = true
 				submitLoading.value = true
 				const formDataParam = cloneDeep(formData.value)
 				const formDataParam = cloneDeep(formData.value)
-				debugger
+
 				bizOtherAppointmentApi
 				bizOtherAppointmentApi
 					.bizOtherAppointmentSubmitForm(formDataParam, formDataParam.id)
 					.bizOtherAppointmentSubmitForm(formDataParam, formDataParam.id)
 					.then(() => {
 					.then(() => {

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

@@ -493,4 +493,79 @@ public class BizAppointmentRecordController {
     public void bizOtherAppointmentExport(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException {
     public void bizOtherAppointmentExport(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException {
         bizAppointmentRecordService.bizOtherAppointmentExport(bizAppointmentRecordPageParam,response);
         bizAppointmentRecordService.bizOtherAppointmentExport(bizAppointmentRecordPageParam,response);
     }
     }
+
+
+
+
+    /**
+     * 充电预约_记录分页
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "充电预约_记录分页")
+    @SaCheckPermission("/biz/bizchargestationreservation/page")
+    @GetMapping("/biz/bizchargestationreservation/page")
+    public CommonResult<Page<BizAppointmentRecord>> bizchargestationreservationPage(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
+        return CommonResult.data(bizAppointmentRecordService.page(bizAppointmentRecordPageParam));
+    }
+
+
+    /**
+     * 充电预约__添加
+     *
+     * @author xumudong
+     * @date  2025/07/02 11:47
+     */
+    @Operation(summary = "充电预约__添加")
+    @CommonLog("充电预约__添加")
+    @CommonNoRepeat
+    @PostMapping("/biz/bizchargestationreservation/addChargeStationReservation")
+    public CommonResult<String> addChargeStationReservation(@RequestBody @Valid BizChargeStationReservationAddParam bizChargeStationReservationAddParam) {
+        bizAppointmentRecordService.addChargeStationReservation(bizChargeStationReservationAddParam);
+        return CommonResult.ok();
+    }
+
+
+    /**
+     * 充电预约_编辑
+     *
+     * @author xumudong
+     * @date  2025/07/02 11:47
+     */
+    @Operation(summary = "充电预约_编辑")
+    @CommonLog("充电预约_编辑")
+    @PostMapping("/biz/bizchargestationreservation/editChargeStationReservation")
+    public CommonResult<String> editChargeStationReservation(@RequestBody @Valid BizChargeStationReservationEditParam bizChargeStationReservationEditParam) {
+        bizAppointmentRecordService.editChargeStationReservation(bizChargeStationReservationEditParam);
+        return CommonResult.ok();
+    }
+    /**
+     * 充电预约_删除
+     *
+     * @author xumudong
+     * @date  2025/07/02 11:47
+     */
+    @Operation(summary = "充电预约_删除")
+    @CommonLog("充电预约_删除")
+    @PostMapping("/biz/bizchargestationreservation/deleteChargeStationReservation")
+    public CommonResult<String> deleteChargeStationReservation(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                               List<BizAppointmentRecordIdParam> bizAppointmentRecordIdParamList) {
+        bizAppointmentRecordService.deleteChargeStationReservation(bizAppointmentRecordIdParamList);
+        return CommonResult.ok();
+    }
+
+
+    /**
+     * 充电预约_强制结束
+     */
+    @Operation(summary = "充电预约_强制结束")
+    @CommonLog("充电预约_强制结束")
+    @PostMapping("/biz/bizchargestationreservation/bizChargeStationReservationExit")
+    public CommonResult<String> bizChargeStationReservationExit(@RequestBody BizAppointmentRecordIdParam bizAppointmentRecordIdParam){
+        bizAppointmentRecordService.bizChargeStationReservationExit(bizAppointmentRecordIdParam);
+        return CommonResult.ok();
+    }
+
+
 }
 }

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

@@ -158,6 +158,7 @@ public class BizAppointmentRecord extends CommonEntity {
     private String goodsCode;
     private String goodsCode;
 
 
     /**预约类型(1:订单预约   2:临时预约)*/
     /**预约类型(1:订单预约   2:临时预约)*/
+    @Trans(type = TransType.DICTIONARY, key = "appointment_type")
     private String appointmentType;
     private String appointmentType;
 
 
     /**预约分类(1、充电预约  2、管桩预约   3、其他预约)*/
     /**预约分类(1、充电预约  2、管桩预约   3、其他预约)*/

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

@@ -0,0 +1,60 @@
+/*
+ * 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 BizChargeStationReservationAddParam {
+
+
+    /**
+     * 车牌号
+     */
+    @Schema(description = "车牌号", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "licenseNumber不能为空")
+    private String licenseNumber;
+
+
+    /**
+     * 司机姓名
+     */
+    @Schema(description = "司机姓名")
+    private String driverName;
+
+    /**
+     * 司机电话
+     */
+    @Schema(description = "司机电话")
+    private String driverMobile;
+
+
+    /**
+     * 司机用户ID
+     */
+    @Schema(description = "司机用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "司机不能为空")
+    private String driverId;
+
+
+}

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

@@ -0,0 +1,63 @@
+/*
+ * 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 BizChargeStationReservationEditParam {
+
+    /** 主键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 = "司机姓名")
+    private String driverName;
+
+    /**
+     * 司机电话
+     */
+    @Schema(description = "司机电话")
+    private String driverMobile;
+
+
+    /**
+     * 司机用户ID
+     */
+    @Schema(description = "司机用户ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "司机不能为空")
+    private String driverId;
+
+
+}

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

@@ -183,4 +183,30 @@ public interface BizAppointmentRecordService extends IService<BizAppointmentReco
      */
      */
     void bizOtherAppointmentExport(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException;
     void bizOtherAppointmentExport(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException;
 
 
+
+
+    /**
+     * 充电预约_新增
+     * @param bizChargeStationReservationAddParam
+     */
+    void addChargeStationReservation(BizChargeStationReservationAddParam bizChargeStationReservationAddParam);
+    /**
+     * 充电预约_编辑
+     * @param bizChargeStationReservationEditParam
+     */
+    void editChargeStationReservation(BizChargeStationReservationEditParam bizChargeStationReservationEditParam);
+
+    /**
+     * 充电预约_删除
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    void deleteChargeStationReservation(List<BizAppointmentRecordIdParam> bizAppointmentRecordIdParamList);
+    /**
+     * 充电预约_强制结束
+     * @param bizAppointmentRecordIdParam
+     */
+    void bizChargeStationReservationExit(BizAppointmentRecordIdParam bizAppointmentRecordIdParam);
+
 }
 }

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

@@ -18,7 +18,6 @@ import cn.hutool.core.collection.CollStreamUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.PhoneUtil;
 import cn.hutool.core.util.PhoneUtil;
-import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -29,7 +28,6 @@ import com.google.common.collect.Maps;
 import jakarta.annotation.Resource;
 import jakarta.annotation.Resource;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.compress.utils.Lists;
 import org.apache.commons.compress.utils.Lists;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -39,8 +37,9 @@ import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
 import vip.xiaonuo.biz.modular.api.param.WxUserMsgParam;
 import vip.xiaonuo.biz.modular.api.param.WxUserMsgParam;
 import vip.xiaonuo.biz.modular.api.service.ApiService;
 import vip.xiaonuo.biz.modular.api.service.ApiService;
 import vip.xiaonuo.biz.modular.bizappointmentrecord.param.*;
 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.bizappointmenttime.service.BizAppointmentTimeService;
+import vip.xiaonuo.biz.modular.bizchargestation.entity.BizChargeStation;
+import vip.xiaonuo.biz.modular.bizchargestation.service.BizChargeStationService;
 import vip.xiaonuo.biz.modular.bizconfig.entity.BizConfig;
 import vip.xiaonuo.biz.modular.bizconfig.entity.BizConfig;
 import vip.xiaonuo.biz.modular.bizconfig.service.BizConfigService;
 import vip.xiaonuo.biz.modular.bizconfig.service.BizConfigService;
 import vip.xiaonuo.biz.modular.bizexcessconfig.entity.BizExcessConfig;
 import vip.xiaonuo.biz.modular.bizexcessconfig.entity.BizExcessConfig;
@@ -52,7 +51,6 @@ import vip.xiaonuo.biz.modular.bizloadappointsupplier.service.BizLoadAppointSupp
 import vip.xiaonuo.biz.modular.bizloadtime.entity.BizLoadTime;
 import vip.xiaonuo.biz.modular.bizloadtime.entity.BizLoadTime;
 import vip.xiaonuo.biz.modular.bizloadtime.service.BizLoadTimeService;
 import vip.xiaonuo.biz.modular.bizloadtime.service.BizLoadTimeService;
 import vip.xiaonuo.biz.modular.bizorder.entity.BizOrder;
 import vip.xiaonuo.biz.modular.bizorder.entity.BizOrder;
-import vip.xiaonuo.biz.modular.bizorder.param.BizOrderExportResult;
 import vip.xiaonuo.biz.modular.bizorder.service.BizOrderService;
 import vip.xiaonuo.biz.modular.bizorder.service.BizOrderService;
 import vip.xiaonuo.biz.modular.bizorderconfig.entity.BizOrderConfig;
 import vip.xiaonuo.biz.modular.bizorderconfig.entity.BizOrderConfig;
 import vip.xiaonuo.biz.modular.bizorderconfig.service.BizOrderConfigService;
 import vip.xiaonuo.biz.modular.bizorderconfig.service.BizOrderConfigService;
@@ -77,7 +75,6 @@ import vip.xiaonuo.biz.modular.record.service.BizRecordService;
 import vip.xiaonuo.biz.modular.user.entity.BizUser;
 import vip.xiaonuo.biz.modular.user.entity.BizUser;
 import vip.xiaonuo.biz.modular.user.service.BizUserService;
 import vip.xiaonuo.biz.modular.user.service.BizUserService;
 import vip.xiaonuo.biz.modular.utils.CommonExportUtil;
 import vip.xiaonuo.biz.modular.utils.CommonExportUtil;
-import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
 import vip.xiaonuo.common.page.CommonPageRequest;
 import vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord;
 import vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord;
@@ -156,6 +153,10 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
     @Resource
     @Resource
     private BizPipePlanService bizPipePlanService;
     private BizPipePlanService bizPipePlanService;
 
 
+
+    @Resource
+    private BizChargeStationService bizChargeStationService;
+
     @Override
     @Override
     public Page<BizAppointmentRecord> page(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
     public Page<BizAppointmentRecord> page(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
         QueryWrapper<BizAppointmentRecord> queryWrapper = getQueryWrapper(bizAppointmentRecordPageParam);
         QueryWrapper<BizAppointmentRecord> queryWrapper = getQueryWrapper(bizAppointmentRecordPageParam);
@@ -1526,7 +1527,7 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
 
 
     @Override
     @Override
     public void addOtherAppointment(BizOtherAppointmentAddParam bizOtherAppointmentAddParam) {
     public void addOtherAppointment(BizOtherAppointmentAddParam bizOtherAppointmentAddParam) {
-        checkOtherParam(bizOtherAppointmentAddParam.getLicenseNumber());
+        checkParam(bizOtherAppointmentAddParam.getLicenseNumber());
         //获取流程配置判断预约是否需要审核
         //获取流程配置判断预约是否需要审核
         BizAppointmentRecord bizAppointmentRecord = BeanUtil.toBean(bizOtherAppointmentAddParam, BizAppointmentRecord.class);
         BizAppointmentRecord bizAppointmentRecord = BeanUtil.toBean(bizOtherAppointmentAddParam, BizAppointmentRecord.class);
         BizUser bizUser = bizUserService.getById(bizOtherAppointmentAddParam.getDriverId());
         BizUser bizUser = bizUserService.getById(bizOtherAppointmentAddParam.getDriverId());
@@ -1545,7 +1546,7 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
     public void editOtherAppointment(BizOtherAppointmentEditParam bizOtherAppointmentEditParam) {
     public void editOtherAppointment(BizOtherAppointmentEditParam bizOtherAppointmentEditParam) {
         BizAppointmentRecord bizAppointmentRecord = this.queryEntity(bizOtherAppointmentEditParam.getId());
         BizAppointmentRecord bizAppointmentRecord = this.queryEntity(bizOtherAppointmentEditParam.getId());
         if (!bizAppointmentRecord.getLicenseNumber().equals(bizOtherAppointmentEditParam.getLicenseNumber())) {
         if (!bizAppointmentRecord.getLicenseNumber().equals(bizOtherAppointmentEditParam.getLicenseNumber())) {
-            checkOtherParam(bizOtherAppointmentEditParam.getLicenseNumber());
+            checkParam(bizOtherAppointmentEditParam.getLicenseNumber());
         }
         }
         BizAppointmentRecord bizAppointmentRecordUp = BeanUtil.toBean(bizOtherAppointmentEditParam, BizAppointmentRecord.class);
         BizAppointmentRecord bizAppointmentRecordUp = BeanUtil.toBean(bizOtherAppointmentEditParam, BizAppointmentRecord.class);
         BizUser bizUser = bizUserService.getById(bizOtherAppointmentEditParam.getDriverId());
         BizUser bizUser = bizUserService.getById(bizOtherAppointmentEditParam.getDriverId());
@@ -1557,17 +1558,19 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
     }
     }
 
 
 
 
-    //其他预约校验
-    public void checkOtherParam(String licenseNumber) {
+    //预约校验
+    public void checkParam(String licenseNumber) {
         //校验车牌号
         //校验车牌号
         if (ObjectUtil.isNotEmpty(licenseNumber)) {
         if (ObjectUtil.isNotEmpty(licenseNumber)) {
             licenseNumber = licenseNumber.toUpperCase().trim();
             licenseNumber = licenseNumber.toUpperCase().trim();
             //校验车牌号是否添加过预约,排除11:已签收、 13:销售已审核  、 14:已取消
             //校验车牌号是否添加过预约,排除11:已签收、 13:销售已审核  、 14:已取消
-            long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
+            BizAppointmentRecord bizAppointmentRecord = this.getOne(new QueryWrapper<BizAppointmentRecord>().lambda().
                     eq(BizAppointmentRecord::getLicenseNumber, licenseNumber).
                     eq(BizAppointmentRecord::getLicenseNumber, licenseNumber).
-                    notIn(BizAppointmentRecord::getStatus, "10", "11", "12", "13", "14", "15"));
-            if (count > 0) {
-                throw new CommonException("车牌号:{}已经添加过预约!", licenseNumber);
+                    notIn(BizAppointmentRecord::getStatus, "10", "11", "12", "13", "14", "15", "19")
+                    .last("limit 1"));
+            if (bizAppointmentRecord != null) {
+                transService.transOne(bizAppointmentRecord);
+                throw new CommonException("车牌号:{}已经存在【" + (String) bizAppointmentRecord.getTransMap().get("appointmentTypeName") + "】类型的有效预约记录!", licenseNumber);
             }
             }
         }
         }
 
 
@@ -1661,4 +1664,118 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
         return String.format("%03d", counter);
         return String.format("%03d", counter);
     }
     }
 
 
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void addChargeStationReservation(BizChargeStationReservationAddParam bizChargeStationReservationAddParam) {
+        //校验是否存在有效得预约信息
+        checkParam(bizChargeStationReservationAddParam.getLicenseNumber());
+        lock.lock();
+        try {
+            //校验一下充电桩剩余数量是否够扣减
+            //查询充电桩配置信息
+            BizChargeStation bizChargeStation = bizChargeStationService.getOne(new QueryWrapper<BizChargeStation>()
+                    .lambda().eq(BizChargeStation::getDeleteFlag, 0).last("limit 1"));
+            if (bizChargeStation != null && (bizChargeStation.getChargeStationTotalNumber() - bizChargeStation.getChargeStationUsedNumber()) < 1) {
+                throw new CommonException("充电桩已无剩余充电桩数量");
+            }
+
+            //获取流程配置判断预约是否需要审核
+            BizAppointmentRecord bizAppointmentRecord = BeanUtil.toBean(bizChargeStationReservationAddParam, BizAppointmentRecord.class);
+            BizUser bizUser = bizUserService.getById(bizChargeStationReservationAddParam.getDriverId());
+            if (bizUser != null) {
+                bizAppointmentRecord.setDriverName(bizUser.getName());
+                bizAppointmentRecord.setDriverMobile(bizUser.getPhone());
+            }
+            bizAppointmentRecord.setOtherNumber(getNumber("CD", "4"));
+            //默认赋值待入场状态
+            bizAppointmentRecord.setStatus("4");
+            bizAppointmentRecord.setAppointmentType("4");
+            //新增成功,并将充电桩已使用数量进行扣减
+            if (this.save(bizAppointmentRecord)) {
+                bizChargeStation.setChargeStationUsedNumber(bizChargeStation.getChargeStationUsedNumber() + 1);
+                bizChargeStationService.updateById(bizChargeStation);
+            }
+        } catch (Exception e) {
+
+        } finally {
+            lock.unlock();
+        }
+
+
+    }
+
+    @Override
+    public void editChargeStationReservation(BizChargeStationReservationEditParam bizChargeStationReservationEditParam) {
+        BizAppointmentRecord bizAppointmentRecord = this.queryEntity(bizChargeStationReservationEditParam.getId());
+        if (!bizAppointmentRecord.getLicenseNumber().equals(bizChargeStationReservationEditParam.getLicenseNumber())) {
+            //校验是否存在有效得预约信息
+            checkParam(bizChargeStationReservationEditParam.getLicenseNumber());
+        }
+        BizAppointmentRecord bizAppointmentRecordUp = BeanUtil.toBean(bizChargeStationReservationEditParam, BizAppointmentRecord.class);
+        BizUser bizUser = bizUserService.getById(bizChargeStationReservationEditParam.getDriverId());
+        if (bizUser != null) {
+            bizAppointmentRecordUp.setDriverName(bizUser.getName());
+            bizAppointmentRecordUp.setDriverMobile(bizUser.getPhone());
+        }
+        this.updateById(bizAppointmentRecordUp);
+    }
+
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void deleteChargeStationReservation(List<BizAppointmentRecordIdParam> bizAppointmentRecordIdParamList) {
+        lock.lock();
+        try {
+            //释放充电数量
+            //查询充电桩配置信息
+            BizChargeStation bizChargeStation = bizChargeStationService.getOne(new QueryWrapper<BizChargeStation>()
+                    .lambda().eq(BizChargeStation::getDeleteFlag, 0).last("limit 1"));
+            if (ObjectUtil.isNotNull(bizChargeStation)) {
+                bizChargeStation.setChargeStationUsedNumber(bizChargeStation.getChargeStationUsedNumber() - 1);
+                bizChargeStationService.updateById(bizChargeStation);
+            }
+            // 执行删除
+            this.removeByIds(CollStreamUtil.toList(bizAppointmentRecordIdParamList, BizAppointmentRecordIdParam::getId));
+        } catch (Exception e) {
+
+        } finally {
+            lock.unlock();
+        }
+
+    }
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void bizChargeStationReservationExit(BizAppointmentRecordIdParam bizAppointmentRecordIdParam) {
+        lock.lock();
+        try {
+            BizAppointmentRecord bizAppointmentRecord = this.queryEntity(bizAppointmentRecordIdParam.getId());
+            if ("10".equals(bizAppointmentRecord.getStatus())) {
+                throw new CommonException("当前流程已经强制结束,不可重复操作!");
+            }
+            //强制结束,将状态改成已出场,同时记录操作人以及操作时间
+            SaBaseLoginUser loginUser = StpLoginUserUtil.getLoginUser();
+            bizAppointmentRecord.setExitOperator(loginUser.getName());
+            bizAppointmentRecord.setExitTime(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
+                    .format(LocalDateTime.now()));
+            bizAppointmentRecord.setStatus("10");
+            if(this.updateById(bizAppointmentRecord)){
+                //释放充电数量
+                //查询充电桩配置信息
+                BizChargeStation bizChargeStation = bizChargeStationService.getOne(new QueryWrapper<BizChargeStation>()
+                        .lambda().eq(BizChargeStation::getDeleteFlag, 0).last("limit 1"));
+                if (ObjectUtil.isNotNull(bizChargeStation)) {
+                    bizChargeStation.setChargeStationUsedNumber(bizChargeStation.getChargeStationUsedNumber() - 1);
+                    bizChargeStationService.updateById(bizChargeStation);
+                }
+            }
+
+        } catch (Exception e) {
+
+        } finally {
+            lock.unlock();
+        }
+
+    }
+
+
 }
 }