浏览代码

订单管理

fanzherong_v 1 月之前
父节点
当前提交
8889d41b79
共有 42 个文件被更改,包括 3516 次插入1 次删除
  1. 28 0
      snowy-admin-web/src/api/biz/bizAppointmentRecordApi.js
  2. 4 0
      snowy-admin-web/src/api/biz/bizAppointmentTimeApi.js
  3. 4 0
      snowy-admin-web/src/api/biz/bizGoodsApi.js
  4. 50 0
      snowy-admin-web/src/api/biz/bizOrderApi.js
  5. 587 0
      snowy-admin-web/src/components/XnCustomerSelector/index.vue
  6. 121 0
      snowy-admin-web/src/views/biz/bizappointmentrecord/form.vue
  7. 149 0
      snowy-admin-web/src/views/biz/bizappointmentrecord/index.vue
  8. 1 1
      snowy-admin-web/src/views/biz/bizappointmenttime/form.vue
  9. 104 0
      snowy-admin-web/src/views/biz/bizorder/detail.vue
  10. 111 0
      snowy-admin-web/src/views/biz/bizorder/form.vue
  11. 527 0
      snowy-admin-web/src/views/biz/bizorder/index.vue
  12. 119 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/controller/BizAppointmentRecordController.java
  13. 63 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/entity/BizAppointmentRecord.java
  14. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/enums/BizAppointmentRecordEnum.java
  15. 25 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/BizAppointmentRecordMapper.java
  16. 5 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/mapping/BizAppointmentRecordMapper.xml
  17. 61 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentRecordAddParam.java
  18. 66 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentRecordEditParam.java
  19. 35 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentRecordIdParam.java
  20. 51 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentRecordPageParam.java
  21. 80 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/BizAppointmentRecordService.java
  22. 94 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/impl/BizAppointmentRecordServiceImpl.java
  23. 12 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmenttime/controller/BizAppointmentTimeController.java
  24. 4 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmenttime/entity/BizAppointmentTime.java
  25. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmenttime/service/BizAppointmentTimeService.java
  26. 50 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmenttime/service/impl/BizAppointmentTimeServiceImpl.java
  27. 187 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/controller/BizOrderController.java
  28. 111 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/entity/BizOrder.java
  29. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/enums/BizOrderEnum.java
  30. 33 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/mapper/BizOrderMapper.java
  31. 28 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/mapper/mapping/BizOrderMapper.xml
  32. 72 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderAddParam.java
  33. 79 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderEditParam.java
  34. 51 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderExportResult.java
  35. 35 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderIdParam.java
  36. 69 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderPageParam.java
  37. 99 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/service/BizOrderService.java
  38. 198 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/service/impl/BizOrderServiceImpl.java
  39. 12 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/goods/controller/BizGoodsController.java
  40. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/goods/service/BizGoodsService.java
  41. 5 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/goods/service/impl/BizGoodsServiceImpl.java
  42. 112 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/CommonExportUtil.java

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

@@ -0,0 +1,28 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/bizappointmentrecord/` + url, ...arg)
+
+/**
+ * 预约记录Api接口管理器
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+export default {
+	// 获取预约记录分页
+	bizAppointmentRecordPage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交预约记录表单 edit为true时为编辑,默认为新增
+	bizAppointmentRecordSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除预约记录
+	bizAppointmentRecordDelete(data) {
+		return request('delete', data)
+	},
+	// 获取预约记录详情
+	bizAppointmentRecordDetail(data) {
+		return request('detail', data, 'get')
+	}
+}

+ 4 - 0
snowy-admin-web/src/api/biz/bizAppointmentTimeApi.js

@@ -24,5 +24,9 @@ export default {
 	// 获取预约时段配置详情
 	bizAppointmentTimeDetail(data) {
 		return request('detail', data, 'get')
+	},
+	//获取预约时段下拉列表
+	getDownList(data){
+		return request('getDownList',data,'get')
 	}
 }

+ 4 - 0
snowy-admin-web/src/api/biz/bizGoodsApi.js

@@ -24,5 +24,9 @@ export default {
 	// 获取货品管理详情
 	bizGoodsDetail(data) {
 		return request('detail', data, 'get')
+	},
+	// 获取货品列表
+	getList(data){
+		return request('getList',data,'get')
 	}
 }

+ 50 - 0
snowy-admin-web/src/api/biz/bizOrderApi.js

@@ -0,0 +1,50 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/bizorder/` + url, ...arg)
+
+/**
+ * 订单管理Api接口管理器
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+export default {
+	// 获取订单管理分页
+	bizOrderPage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交订单管理表单 edit为true时为编辑,默认为新增
+	bizOrderSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除订单管理
+	bizOrderDelete(data) {
+		return request('delete', data)
+	},
+	// 获取订单管理详情
+	bizOrderDetail(data) {
+		return request('detail', data, 'get')
+	},
+	// 获取客户信息
+	getCustomerById(data){
+		return request('getCustomerById',data,'get')
+	},
+	// 绑定客户ID
+	bindCustomerId(data){
+		return request('bindCustomerId',data)
+	},
+	//导出
+	exportRecord(data){
+		return request('exportRecord', data, 'get', {
+			responseType: 'blob'
+		})
+	},
+	//结束订单
+	endOrder(data){
+		return request('endOrder',data)
+	},
+	//订单列表
+	getList(data){
+		return request('getList',data,'get')
+	}
+}

+ 587 - 0
snowy-admin-web/src/components/XnCustomerSelector/index.vue

@@ -0,0 +1,587 @@
+<template>
+	<!-- 这是引入后展示的样式 -->
+	<div v-if="props.show">
+		<!-- <a-tag v-for="data in dataArray" closable @close="deleteObj(data)" :key="data.id" class="mb-1">{{
+			data.name
+		}}</a-tag> -->
+		<a-button
+			type="primary"
+			size="small"
+			@click="openModal"
+			v-if="(props.radioModel ? dataArray.length !== 1 : true) && addShow"
+		>
+			<slot name="button"></slot>
+			<span v-if="!hasContent('button')">
+				<plus-outlined />
+				选择
+			</span>
+		</a-button>
+	</div>
+	<!-- 以下是弹窗内容 -->
+	<a-modal
+		v-model:open="visible"
+		title="客户选择"
+		:width="1000"
+		:mask-closable="false"
+		:destroy-on-close="true"
+		@ok="handleOk"
+		@cancel="handleClose"
+	>
+		<a-row :gutter="10">
+			<!-- <a-col :span="7">
+				<a-card size="small" :loading="cardLoading" class="selectorTreeDiv">
+					<a-tree
+						v-if="treeData"
+						v-model:expandedKeys="defaultExpandedKeys"
+						:tree-data="treeData"
+						:field-names="treeFieldNames"
+						@select="treeSelect"
+					>
+					</a-tree>
+				</a-card>
+			</a-col> -->
+			<a-col :span="18">
+				<div class="table-operator xn-mb10">
+					<a-form ref="searchFormRef" name="advanced_search" class="ant-advanced-search-form" :model="searchFormState">
+						<a-row :gutter="24">
+							<a-col :span="12">
+								<a-form-item name="searchKey">
+									<a-input v-model:value="searchFormState.searchKey" placeholder="请输入客户名称" />
+								</a-form-item>
+							</a-col>
+							<a-col :span="12">
+								<a-button type="primary" class="xn-mr-10" @click="loadData()"> 查询 </a-button>
+								<a-button @click="reset()"> 重置 </a-button>
+							</a-col>
+						</a-row>
+					</a-form>
+				</div>
+				<div class="selector-table">
+					<a-table
+						ref="tableRef"
+						size="small"
+						:columns="commons"
+						:data-source="tableData"
+						:expand-row-by-click="true"
+						:loading="pageLoading"
+						bordered
+						:pagination="false"
+					>
+						<template #title>
+							<span>待选择列表 {{ tableRecordNum }} 条</span>
+<!--							<div v-if="!radioModel" class="xn-fdr">
+								<a-button type="dashed" size="small" @click="addAllPageRecord">添加当前数据</a-button>
+							</div>-->
+						</template>
+						<template #bodyCell="{ column, record }">
+							<template v-if="column.dataIndex === 'action'">
+								<a-button type="dashed" size="small" @click="addRecord(record)"><PlusOutlined /></a-button>
+							</template>
+						</template>
+					</a-table>
+					<div class="mt-2">
+						<a-pagination
+							v-if="!isEmpty(tableData)"
+							v-model:current="current"
+							v-model:page-size="pageSize"
+							:total="total"
+							size="small"
+							showSizeChanger
+							@change="paginationChange"
+						/>
+					</div>
+				</div>
+			</a-col>
+			<a-col :span="6">
+				<div class="selector-table">
+					<a-table
+						ref="selectedTable"
+						size="small"
+						:columns="selectedCommons"
+						:data-source="selectedData"
+						:expand-row-by-click="true"
+						:loading="selectedTableListLoading"
+						bordered
+					>
+						<template #title>
+							<span>已选择: {{ selectedData.length }}</span>
+							<div v-if="!radioModel" class="xn-fdr">
+								<a-button type="dashed" danger size="small" @click="delAllRecord">全部移除</a-button>
+							</div>
+						</template>
+						<template #bodyCell="{ column, record }">
+							<template v-if="column.dataIndex === 'action'">
+								<a-button type="dashed" danger size="small" @click="delRecord(record)"><MinusOutlined /></a-button>
+							</template>
+						</template>
+					</a-table>
+				</div>
+			</a-col>
+		</a-row>
+	</a-modal>
+</template>
+
+<script setup name="roleSelector">
+	import { message } from 'ant-design-vue'
+	import { remove, isEmpty, cloneDeep } from 'lodash-es'
+	import userCenterApi from '@/api/sys/userCenterApi'
+	import bizCustomerApi from '@/api/biz/bizCustomerApi'
+	import bizOrderApi from '@/api/biz/bizOrderApi'
+	import { useSlots } from 'vue'
+	// 弹窗是否打开
+	const visible = ref(false)
+	// 主表格common
+	const commons = [
+		{
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: 50
+		},
+		{
+			title: '客户名称',
+			dataIndex: 'customerName',
+			ellipsis: true
+		},
+		{
+			title: '联系人',
+			dataIndex: 'customerContactName'
+		},
+		{
+			title: '手机号',
+			dataIndex: 'customerPhone'
+		}
+	]
+	// 选中表格的表格common
+	const selectedCommons = [
+		{
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: 50
+		},
+		{
+			title: '客户名称',
+			dataIndex: 'customerName',
+			ellipsis: true
+		}
+	]
+	const props = defineProps({
+		radioModel: {
+			type: Boolean,
+			default: () => false
+		},
+		dataIsConverterFlw: {
+			type: Boolean,
+			default: () => false
+		},
+		orgTreeApi: {
+			type: Function
+		},
+		rolePageApi: {
+			type: Function
+		},
+		roleListByIdListApi: {
+			type: Function
+		},
+		value: {
+			default: () => ''
+		},
+		dataType: {
+			type: String,
+			default: () => 'array'
+		},
+		show: {
+			type: Boolean,
+			default: () => true
+		},
+		addShow: {
+			type: Boolean,
+			default: () => true
+		},
+		// 是否展示‘全局’这个节点
+		roleGlobal: {
+			type: Boolean,
+			default: true,
+			required: false
+		}
+	})
+	// 主表格的ref 名称
+	const tableRef = ref()
+	// 选中表格的ref 名称
+	const selectedTable = ref()
+	const tableRecordNum = ref()
+	const searchFormState = ref({})
+	const searchFormRef = ref()
+	const cardLoading = ref(true)
+	const pageLoading = ref(false)
+	const selectedTableListLoading = ref(false)
+	const slots = useSlots()
+	// 替换treeNode 中 title,key,children
+	const treeFieldNames = { children: 'children', title: 'name', key: 'id' }
+	// 获取职位树数据
+	const treeData = ref()
+	//  默认展开二级树的节点id
+	const defaultExpandedKeys = ref([])
+	const emit = defineEmits(['update:value', 'onBack'])
+	const tableData = ref([])
+	const selectedData = ref([])
+	const recordIds = ref([])
+	// 分页相关
+	const current = ref(0) // 当前页数
+	const pageSize = ref(10) // 每页条数
+	const total = ref(0) // 数据总数
+	const hasContent = (slotName) => {
+		return !!(slots[slotName] && slots[slotName]().length > 0)
+	}
+	// 打开弹框
+	const showModel = (ids = []) => {
+		const data = goDataConverter(ids)
+		console.log("data:"+data)
+		recordIds.value = data
+		//getDataNameById(data)
+		openModal()
+	}
+	// 获取机构树的api
+	const orgTree = (param) => {
+		if (typeof props.orgTreeApi === 'function') {
+			return props.orgTreeApi(param)
+		} else {
+			message.warning('未配置机构树API')
+			return Promise.resolve([])
+		}
+	}
+	// 获取列表的api
+	const rolePage = (param) => {
+		if (typeof props.rolePageApi === 'function') {
+			return props.rolePageApi(param)
+		} else {
+			message.warning('未配置角色选择器API')
+			return Promise.resolve([])
+		}
+	}
+	// 获取选中列表的api
+	const roleListByIdList = (param) => {
+		if (typeof props.roleListByIdListApi === 'function') {
+			return props.roleListByIdListApi(param)
+		} else {
+			return userCenterApi.userCenterGetRoleListByIdList(param).then((data) => {
+				return Promise.resolve(data)
+			})
+		}
+	}
+	const openModal = () => {
+		visible.value = true
+		searchFormState.value.size = pageSize.value
+		loadData()
+		if (isEmpty(recordIds.value)) {
+			return
+		}
+		const param = {
+			id: recordIds.value
+		}
+		selectedTableListLoading.value = true
+		/*roleListByIdList(param)
+			.then((data) => {
+				selectedData.value = data
+			})
+			.finally(() => {
+				selectedTableListLoading.value = false
+			})*/
+		bizOrderApi.getCustomerById(param).then((data)=>{
+			selectedData.value = data
+		}).finally(() => {
+			selectedTableListLoading.value = false
+		})
+	}
+	// 点击删除
+	const deleteObj = (obj) => {
+		// 删除显示的
+		remove(dataArray.value, (item) => item.id === obj.id)
+		// 删除缓存的
+		remove(recordIds.value, (item) => item === obj.id)
+		const value = []
+		const showData = []
+		dataArray.value.forEach((item) => {
+			const obj = {
+				id: item.id,
+				name: item.name
+			}
+			value.push(item.id)
+			// 拷贝一份obj数据
+			const objClone = cloneDeep(obj)
+			showData.push(objClone)
+		})
+		dataArray.value = showData
+		// 判断是否做数据的转换为工作流需要的
+		const resultData = outDataConverter(value)
+		emit('update:value', resultData)
+		emit('onBack', resultData)
+	}
+	// 查询主表格数据
+	const loadData = () => {
+		// 如果不是用全局的,我们每次查询加上这个条件
+		// if (!props.roleGlobal) {
+		// 	searchFormState.value.category = 'ORG'
+		// }
+		pageLoading.value = true
+		bizCustomerApi.bizCustomerPage(searchFormState.value).then((data) => {
+			current.value = data.current
+			total.value = data.total
+			// 重置、赋值
+			tableData.value = []
+			tableRecordNum.value = 0
+			tableData.value = data.records
+			if (data.records) {
+				tableRecordNum.value = data.records.length
+			} else {
+				tableRecordNum.value = 0
+			}
+		}).finally(() => {
+			pageLoading.value = false
+		})
+	}
+	// pageSize改变回调分页事件
+	const paginationChange = (page, pageSize) => {
+		searchFormState.value.current = page
+		searchFormState.value.size = pageSize
+		loadData()
+	}
+	const judge = () => {
+		return !(props.radioModel && selectedData.value.length > 0)
+	}
+	// 添加记录
+	const addRecord = (record) => {
+		if (!judge()) {
+			message.warning('只可选择一条')
+			return
+		}
+		if(selectedData.value.length>=1){
+			message.warning('只可选择一条')
+			return
+		}
+		const selectedRecord = selectedData.value.filter((item) => item.id === record.id)
+		if (selectedRecord.length === 0) {
+			selectedData.value.push(record)
+		} else {
+			message.warning('该记录已存在')
+		}
+	}
+	// 添加全部
+	const addAllPageRecord = () => {
+		let newArray = selectedData.value.concat(tableData.value)
+		let list = []
+		for (let item1 of newArray) {
+			let flag = true
+			for (let item2 of list) {
+				if (item1.id === item2.id) {
+					flag = false
+				}
+			}
+			if (flag) {
+				list.push(item1)
+			}
+		}
+		selectedData.value = list
+	}
+	// 删减记录
+	const delRecord = (record) => {
+		remove(selectedData.value, (item) => item.id === record.id)
+	}
+	// 删减记录
+	const delAllRecord = () => {
+		selectedData.value = []
+	}
+	// 点击树查询
+	// const treeSelect = (selectedKeys) => {
+	// 	searchFormState.value.current = 0
+	// 	if (selectedKeys.length > 0) {
+	// 		if (selectedKeys[0] === 'GLOBAL') {
+	// 			searchFormState.value.category = selectedKeys[0]
+	// 			delete searchFormState.value.orgId
+	// 		} else {
+	// 			searchFormState.value.orgId = selectedKeys.toString()
+	// 			delete searchFormState.value.category
+	// 		}
+	// 	} else {
+	// 		delete searchFormState.value.category
+	// 		delete searchFormState.value.orgId
+	// 	}
+	// 	loadData()
+	// }
+	const dataArray = ref([])
+	// 确定
+	const handleOk = () => {
+		dataArray.value = []
+		const value = []
+		const showData = []
+		if(selectedData.value.length == 0){
+			message.warning('请选择需要绑定的客户!')
+			return
+		}
+		selectedData.value.forEach((item) => {
+			const obj = {
+				id: item.id,
+				name: item.name
+			}
+			value.push(item.id)
+			// 拷贝一份obj数据
+			const objClone = cloneDeep(obj)
+			showData.push(objClone)
+		})
+		dataArray.value = showData
+		// 判断是否做数据的转换为工作流需要的
+		const resultData = outDataConverter(value)
+		emit('update:value', resultData)
+		emit('onBack', resultData)
+		handleClose()
+	}
+	// 重置
+	const reset = () => {
+		delete searchFormState.value.searchKey
+		loadData()
+	}
+	const handleClose = () => {
+		searchFormState.value = {}
+		tableRecordNum.value = 0
+		tableData.value = []
+		current.value = 0
+		pageSize.value = 20
+		total.value = 0
+		selectedData.value = []
+		// dataArray.value = []
+		visible.value = false
+	}
+	// 数据进入后转换
+	const goDataConverter = (data) => {
+		if (props.dataIsConverterFlw) {
+			const resultData = []
+			// 处理对象
+			if (!isEmpty(data.value)) {
+				const values = data.value.split(',')
+				if (values.length > 0) {
+					values.forEach((id) => {
+						resultData.push(id)
+					})
+				} else {
+					resultData.push(data.value)
+				}
+			} else {
+				// 处理数组
+				if (!isEmpty(data) && !isEmpty(data[0]) && !isEmpty(data[0].value)) {
+					const values = data[0].value.split(',')
+					for (let i = 0; i < values.length; i++) {
+						resultData.push(values[i])
+					}
+				}
+			}
+			return resultData
+		} else {
+			if (getValueType() !== 'string') {
+				return data
+			}
+			if (data.length > 1) {
+				const resultData = []
+				data.split(',').forEach((id) => {
+					resultData.push(id)
+				})
+				return resultData
+			} else {
+				return data
+			}
+		}
+	}
+	// 数据出口转换器
+	const outDataConverter = (data) => {
+		if (props.dataIsConverterFlw) {
+			data = dataArray.value
+			const obj = {}
+			let label = ''
+			let value = ''
+			for (let i = 0; i < data.length; i++) {
+				if (data.length === i + 1) {
+					label = label + data[i].name
+					value = value + data[i].id
+				} else {
+					label = label + data[i].name + ','
+					value = value + data[i].id + ','
+				}
+			}
+			obj.key = 'ROLE'
+			obj.label = label
+			obj.value = value
+			obj.extJson = ''
+			return obj
+		} else {
+			if (getValueType() !== 'string') {
+				return data
+			}
+			let resultData = ''
+			data.forEach((id) => {
+				resultData = resultData + ',' + id
+			})
+			resultData = resultData.substring(1, resultData.length)
+			return resultData
+		}
+	}
+	// 获取数据类型
+	const getValueType = () => {
+		if (props.dataType) {
+			return props.dataType
+		} else {
+			if (props.radioModel) {
+				return 'string'
+			}
+			return typeof typeof props.value
+		}
+	}
+	const getDataNameById = (ids) => {
+		if (isEmpty(dataArray.value) && !isEmpty(ids)) {
+			const param = {
+				idList: recordIds.value
+			}
+			// 这里必须转为数组类型的
+			roleListByIdList(param).then((data) => {
+				dataArray.value = data
+			})
+		}
+	}
+	watch(
+		() => props.value,
+		(newValue) => {
+			if (!isEmpty(props.value)) {
+				const ids = goDataConverter(newValue)
+				recordIds.value = ids
+				getDataNameById(ids)
+			} else {
+				dataArray.value = []
+				selectedData.value = []
+			}
+		},
+		{
+			immediate: true // 立即执行
+		}
+	)
+	defineExpose({
+		showModel
+	})
+</script>
+<style lang="less" scoped>
+	.xn-mr-5 {
+		margin-right: 5px;
+	}
+	.xn-mr-10 {
+		margin-right: 10px;
+	}
+	.selectorTreeDiv {
+		max-height: 500px;
+		overflow: auto;
+	}
+	.ant-form-item {
+		margin-bottom: 0 !important;
+	}
+	.selector-table {
+		overflow: auto;
+		max-height: 450px;
+	}
+</style>

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

@@ -0,0 +1,121 @@
+<template>
+	<xn-form-container
+		:title="formData.id ? '编辑预约记录' : '增加预约记录'"
+		:width="700"
+		v-model:open="open"
+		:destroy-on-close="true"
+		@close="onClose"
+	>
+		<a-form ref="formRef" :model="formData" :rules="formRules" :wrapper-col="wrapperCol" :label-col="labelCol">
+			<a-form-item label="订单信息:" name="orderId">
+				<a-select v-model:value="formData.orderId" placeholder="请选择订单信息"
+						  :options="orderIdList"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="车牌号:" name="licenseNumber">
+				<a-input v-model:value="formData.licenseNumber" placeholder="请输入车牌号" allow-clear />
+			</a-form-item>
+			<a-form-item label="预约时段:" name="timeId">
+				<a-select v-model:value="formData.timeId" placeholder="请选择预约时段"
+						  :options="timeIdList"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="司机姓名:" name="driverName">
+				<a-input v-model:value="formData.driverName" placeholder="请输入司机姓名" allow-clear />
+			</a-form-item>
+			<a-form-item label="司机电话:" name="driverPhone">
+				<a-input v-model:value="formData.driverPhone" placeholder="请输入司机电话" allow-clear />
+			</a-form-item>
+		</a-form>
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="bizAppointmentRecordForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import bizAppointmentRecordApi from '@/api/biz/bizAppointmentRecordApi'
+	import bizAppointmentTimeApi from "@/api/biz/bizAppointmentTimeApi";
+	import bizOrderApi from '@/api/biz/bizOrderApi'
+
+	// 抽屉状态
+	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 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)
+		}
+
+		//查询订单信息
+		bizOrderApi.getList().then((res)=>{
+			orderIdList.value = res.map((item)=>{
+				return{
+					value:item.id,
+					label:item.orderName + '-' + item.orderNumber
+				}
+			})
+		})
+
+		//查询预约时段下拉
+		bizAppointmentTimeApi.getDownList().then((res)=>{
+			timeIdList.value = res.map((item)=>{
+				return{
+					value:item.id,
+					label:item.beginTime + '-' + item.endTime
+				}
+			})
+		})
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		orderId: [required('请输入订单id')],
+		licenseNumber: [required('请输入车牌号')],
+		timeId: [required('请输入预约时段id')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				bizAppointmentRecordApi
+					.bizAppointmentRecordSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 149 - 0
snowy-admin-web/src/views/biz/bizappointmentrecord/index.vue

@@ -0,0 +1,149 @@
+<template>
+	<a-card :bordered="false">
+		<s-table
+			ref="tableRef"
+			:columns="columns"
+			:data="loadData"
+			bordered
+			:row-key="(record) => record.id"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizAppointmentRecordAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'action'">
+					<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-space>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="tableRef.refresh()" />
+</template>
+
+<script setup name="bizappointmentrecord">
+	import { cloneDeep } from 'lodash-es'
+	import Form from './form.vue'
+	import bizAppointmentRecordApi from '@/api/biz/bizAppointmentRecordApi'
+	import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
+	import {Modal} from 'ant-design-vue';
+	import {createVNode} from 'vue';
+
+	const submitLoading = ref(false)
+	const tableRef = ref()
+	const formRef = ref()
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const columns = [
+		{
+			title: '订单信息',
+			dataIndex: 'orderId'
+		},
+		{
+			title: '车牌号',
+			dataIndex: 'licenseNumber'
+		},
+		{
+			title: '预约时段id',
+			dataIndex: 'timeId'
+		},
+		{
+			title: '司机姓名',
+			dataIndex: 'driverName'
+		},
+		{
+			title: '司机电话',
+			dataIndex: 'driverPhone'
+		},
+		{
+			title: '状态',
+			dataIndex: 'status'
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	if (hasPerm(['bizAppointmentRecordEdit', 'bizAppointmentRecordDelete'])) {
+		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) => {
+		return bizAppointmentRecordApi.bizAppointmentRecordPage(parameter).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		tableRef.value.refresh(true)
+	}
+	// 删除
+	const deleteBizAppointmentRecord = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		bizAppointmentRecordApi.bizAppointmentRecordDelete(params).then(() => {
+			tableRef.value.refresh(true)
+		})
+	}
+	// 删除
+	const deleteConfig = (record) => {
+
+		Modal.confirm({
+			title: '确定删除该数据吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				let params = [
+					{
+						id: record.id
+					}
+				]
+
+				bizAppointmentRecordApi
+					.bizAppointmentRecordDelete(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+	// 批量删除
+	const deleteBatchBizAppointmentRecord = (params) => {
+		bizAppointmentRecordApi.bizAppointmentRecordDelete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+</script>

+ 1 - 1
snowy-admin-web/src/views/biz/bizappointmenttime/form.vue

@@ -15,7 +15,7 @@
 				<a-time-picker v-model:value="formData.endTime" valueFormat="HH:mm" format = "HH:mm"  placeholder="请选择预约结束时间段" style="width: 100%" />
 			</a-form-item>
 			<a-form-item label="申请数量:" name="applyNumber">
-				<a-input v-model:value="formData.applyNumber" placeholder="请输入申请数量" allow-clear />
+				<a-input-number v-model:value="formData.applyNumber" style="width:90%"  :precision="0" :min="1" :max="99999" placeholder="请输入申请数量" allow-clear /><span style="margin-left:10px;">次</span>
 			</a-form-item>
 		</a-form>
 		<template #footer>

+ 104 - 0
snowy-admin-web/src/views/biz/bizorder/detail.vue

@@ -0,0 +1,104 @@
+<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.customerName }}</a-descriptions-item>
+				<a-descriptions-item label="联系人" :span="2">{{ formData.customerContactName }}</a-descriptions-item>
+				<a-descriptions-item label="手机号" :span="2">{{ formData.customerPhone }}</a-descriptions-item>
+				<a-descriptions-item label="客户地址" :span="2">{{ formData.customerAddress }}</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">
+					<a-tag
+						:color="
+							formData.orderSource === '1'
+								? 'orange'
+								: formData.orderSource === '2'
+								  ? 'green'
+								  : 'purple'
+						"
+					>
+						{{ $TOOL.dictTypeData('order_source', formData.orderSource) }}
+					</a-tag>
+				</a-descriptions-item>
+				<a-descriptions-item label="订单状态" :span="2">
+					<a-tag
+						:color="
+							formData.orderStatus === '1'
+								? '#2db7f5'
+								: formData.orderStatus === '2'
+								  ? '#f50'
+								  : '#f50'
+						"
+					>
+						{{ $TOOL.dictTypeData('order_status', formData.orderStatus) }}
+					</a-tag>
+				</a-descriptions-item>
+				<a-descriptions-item label="订单重量" :span="2">{{ formData.orderWeight }}</a-descriptions-item>
+				<a-descriptions-item label="过磅重量" :span="2">{{ formData.netWeight }}</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>

+ 111 - 0
snowy-admin-web/src/views/biz/bizorder/form.vue

@@ -0,0 +1,111 @@
+<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="orderNumber">
+				<a-input v-model:value="formData.orderNumber" placeholder="请输入订单编号" allow-clear />
+			</a-form-item>
+			<a-form-item label="订单名称:" name="orderName">
+				<a-input v-model:value="formData.orderName" placeholder="请输入订单名称" allow-clear />
+			</a-form-item>
+			<a-form-item label="货品信息:" name="goodId">
+				<a-select v-model:value="formData.goodId" placeholder="请选择货品信息"
+						  :options="goodIdList"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="订单类型:" name="orderType">
+				<a-select v-model:value="formData.orderType" placeholder="请选择订单类型"
+						  :options="orderTypeList"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="订单重量:" name="orderWeight">
+				<a-input-number v-model:value="formData.orderWeight" style="width:90%"  :precision="0" :min="1" :max="999999"  placeholder="请输入订单重量" allow-clear /><span style="margin-left:10px;">吨</span>
+			</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="bizOrderForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import bizOrderApi from '@/api/biz/bizOrderApi'
+	import tool from '@/utils/tool'
+	import bizGoodsApi from '@/api/biz/bizGoodsApi'
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+
+	//设置表单样式
+	const labelCol = ref({ span: 5})
+	const wrapperCol = ref({ span: 16})
+
+	//订单类型
+	const orderTypeList = tool.dictList('order_type')
+	const goodIdList = ref()
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}
+		bizGoodsApi.getList().then((res)=>{
+			goodIdList.value = res.map((item)=>{
+				return{
+					value:item.id,
+					label:item.model? (item.name+'-'+item.model):item.name
+				}
+			})
+		})
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		orderNumber: [required('请输入订单编号')],
+		orderName: [required('请输入订单名称')],
+		goodId: [required('请选择货品信息')],
+		orderWeight: [required('请输入订单重量')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				bizOrderApi
+					.bizOrderSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 527 - 0
snowy-admin-web/src/views/biz/bizorder/index.vue

@@ -0,0 +1,527 @@
+<template>
+	<a-card :bordered="false">
+		<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="customerName">
+						<a-input v-model:value="searchFormState.customerName" placeholder="客户名称查询" />
+					</a-form-item>
+				</a-col>
+				<template v-if="advanced">
+					<a-col :span="6">
+						<a-form-item label="货品名称" name="goodsName">
+							<a-input v-model:value="searchFormState.goodsName" placeholder="货品名称查询" />
+						</a-form-item>
+					</a-col>
+					<a-col :span="6">
+						<a-form-item label="订单状态" name="orderStatus">
+							<a-select v-model:value="searchFormState.orderStatus" placeholder="订单状态查询"
+									  :options="orderStatusList"
+							> </a-select>
+						</a-form-item>
+					</a-col>
+					<a-col :span="6">
+						<a-form-item label="订单来源" name="orderSource">
+							<a-select v-model:value="searchFormState.orderSource" placeholder="订单状态查询"
+									  :options="orderSourceList"
+							> </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>
+		<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('bizOrderAdd')">
+						<template #icon><plus-outlined /></template>
+						新增
+					</a-button>
+					<a-button @click="exportTotal" v-if="hasPerm('bizOrderExport')">
+						<template #icon>
+							<export-outlined/>
+						</template>
+						导出
+					</a-button>
+				</a-space>
+			</template>
+			<template #bodyCell="{ column, record }">
+				<template v-if="column.dataIndex === 'orderType'">
+					<a-tag
+						:color="
+							record.orderType === '1'
+								? 'orange'
+								: record.orderType === '2'
+								  ? 'green'
+								  : 'purple'
+						"
+					>
+						{{ $TOOL.dictTypeData('order_type', record.orderType) }}
+					</a-tag>
+				</template>
+				<template v-if="column.dataIndex === 'orderSource'">
+					<a-tag
+						:color="
+							record.orderSource === '1'
+								? 'orange'
+								: record.orderSource === '2'
+								  ? 'green'
+								  : 'purple'
+						"
+					>
+						{{ $TOOL.dictTypeData('order_source', record.orderSource) }}
+					</a-tag>
+				</template>
+				<template v-if="column.dataIndex === 'orderStatus'">
+					<a-tag
+						:color="
+							record.orderStatus === '1'
+								? '#2db7f5'
+								: record.orderStatus === '2'
+								  ? '#f50'
+								  : '#f50'
+						"
+					>
+						{{ $TOOL.dictTypeData('order_status', record.orderStatus) }}
+					</a-tag>
+				</template>
+				<template v-if="column.dataIndex === 'orderWeight'">
+					{{record.orderWeight + '吨'}}
+				</template>
+				<template v-if="column.dataIndex === 'netWeight'">
+					{{record.netWeight + '吨'}}
+				</template>
+				<template v-if="column.dataIndex === 'action'">
+
+					<a @click="showModal(record)" v-if="record.customerId!=''&& record.customerId!=null">二维码</a>
+
+					<a-divider type="vertical" v-if="record.customerId!=''&& record.customerId!=null"/>
+
+					<a-dropdown v-if="(hasPerm('bizOrderEdit')) || (hasPerm('bizOrderDelete'))
+						">
+						<a class="ant-dropdown-link">
+							更多
+							<DownOutlined />
+						</a>
+
+						<template #overlay>
+							<a-menu>
+								<a-menu-item>
+									<a size="small" type="link" @click="detailRef.onOpen(record)" >详情</a>
+								</a-menu-item>
+								<a-menu-item v-if="hasPerm('bizOrderEdit') && record.orderSource == '2' && record.orderStatus == '1'">
+									<a style="color:blue" size="small" type="link" @click="formRef.onOpen(record)" >编辑</a>
+								</a-menu-item>
+
+								<a-menu-item v-if="hasPerm('bizOrderDelete') && record.orderSource == '2'">
+									<a style="color:red" size="small" type="link" @click="deleteConfig(record)">删除</a>
+								</a-menu-item>
+
+								<a-menu-item v-if="record.orderStatus == '1'">
+									<a style="color:orange" @click="selectCustomer(record)">绑定</a>
+								</a-menu-item>
+
+								<a-menu-item v-if="record.orderStatus == '1'">
+									<a style="color:red" @click="endOrder(record)">结束</a>
+								</a-menu-item>
+							</a-menu>
+						</template>
+					</a-dropdown>
+
+<!--					<a-space>
+						<a @click="formRef.onOpen(record)" v-if="hasPerm('bizOrderEdit')">编辑</a>
+						<a-divider type="vertical" v-if="hasPerm(['bizOrderEdit', 'bizOrderDelete'], 'and')" />
+						<a-button type="link" danger size="small" v-if="hasPerm('bizOrderDelete')" @click="deleteConfig(record)">删除</a-button>
+					</a-space>-->
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="tableRef.refresh()" />
+
+	<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">订单来源:{{ $TOOL.dictTypeData('order_source', nowRecord.orderSource) }}</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>
+
+
+	<xn-customer-selector
+		ref="CustomerSelectorPlusRef"
+		:add-show="false"
+		:show="false"
+		:role-global="true"
+		@onBack="customerBack"
+	/>
+</template>
+
+<script setup name="bizorder">
+	import { cloneDeep } from 'lodash-es'
+	import Form from './form.vue'
+	import Detail from './detail.vue'
+	import bizOrderApi from '@/api/biz/bizOrderApi'
+	import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
+	import {Modal} from 'ant-design-vue';
+	import {createVNode} from 'vue';
+	import QRCode from 'qrcode'
+	import html2canvas from 'html2canvas'
+	import userApi from '@/api/sys/userApi'
+	import downloadUtil from '@/utils/downloadUtil'
+	import tool from '@/utils/tool'
+
+	const selectedRecord = ref({})
+	const CustomerSelectorPlusRef = ref()
+	const nowRecord = ref()
+	const tableRef = ref()
+	const formRef = ref()
+	const detailRef = ref()
+	const submitLoading = ref(false)
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+
+	//查询数据
+	const searchFormState = ref({})
+	const searchFormRef = ref()
+	const orderStatusList = tool.dictList('order_status')
+	const orderSourceList = tool.dictList('order_source')
+
+	// 查询区域显示更多控制
+	const advanced = ref(false)
+	const toggleAdvanced = () => {
+		advanced.value = !advanced.value
+	}
+
+	const columns = [
+		{
+			title: '订单编号',
+			dataIndex: 'orderNumber',
+			align:'center',
+			width: 150
+		},
+		{
+			title: '订单名称',
+			dataIndex: 'orderName',
+			align:'center',
+			width: 150
+		},
+		{
+			title: '客户名称',
+			dataIndex: 'customerName',
+			align:'center',
+			width: 150
+		},
+		{
+			title: '货品名称',
+			dataIndex: 'goodsName',
+			align:'center',
+			width: 150
+		},
+		/*{
+			title: '订单类型',
+			dataIndex: 'orderType',
+			align:'center'
+		},*/
+		{
+			title: '订单来源',
+			dataIndex: 'orderSource',
+			align:'center',
+			width: 100
+		},
+		{
+			title: '订单状态',
+			dataIndex: 'orderStatus',
+			align:'center',
+			width: 100
+		},
+		{
+			title: '订单重量',
+			dataIndex: 'orderWeight',
+			align:'center',
+			width: 100
+		},
+		{
+			title: '过磅重量',
+			dataIndex: 'netWeight',
+			align:'center',
+			width: 100
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	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)
+		return bizOrderApi.bizOrderPage(Object.assign(parameter, searchFormParam)).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		tableRef.value.refresh(true)
+	}
+	// 删除
+	const deleteBizOrder = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		bizOrderApi.bizOrderDelete(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
+					}
+				]
+
+				bizOrderApi
+					.bizOrderDelete(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+	// 批量删除
+	const deleteBatchBizOrder = (params) => {
+		bizOrderApi.bizOrderDelete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+
+	//二维码
+	const open = ref(false);
+	const qrCodeUrl = ref({})
+	const showModal = (record) => {
+		nowRecord.value = record
+		open.value = true;
+		getQrCode(record)
+
+	};
+
+	const getQrCode = (record) => {
+		//QRCode.toDataURL("id:"+record.id+"saleCode:"+record.saleCode, {
+		let param = {
+			id:record.id,
+			projectCode:record.projectCode,
+			projectName:record.projectName
+		}
+		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 = () => {
+		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,
+			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 selectCustomer = (record) => {
+		selectedRecord.value = record
+		// 查询到已有角色,并转为ids的格式,给角色选择器
+		CustomerSelectorPlusRef.value.showModel(record.customerId)
+	}
+	// 角色选择回调
+	const customerBack = (value) => {
+		let params = {
+			id: selectedRecord.value.id,
+			customerIdList: []
+		}
+		if (value.length > 0) {
+			value.forEach((item) => {
+				params.customerIdList.push(item)
+			})
+		}
+		bizOrderApi.bindCustomerId(params).then(() => {
+			tableRef.value.refresh()
+		})
+	}
+
+
+	//导出
+	const exportTotal = () => {
+		const searchFormParam = cloneDeep(searchFormState.value)
+		bizOrderApi.exportRecord(Object.assign(searchFormParam)).then((res)=>{
+			downloadUtil.resultDownload(res)
+		})
+	}
+
+	//结束订单
+	const endOrder = (record) => {
+		/*let param = {
+			id:record.id
+		}
+		bizOrderApi.endOrder(param).then((res)=>{
+			tableRef.value.refresh()
+		})*/
+
+		Modal.confirm({
+			title: '确定结束该订单吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				let param = {
+					id:record.id
+				}
+
+				bizOrderApi
+					.endOrder(param)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+</script>

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

@@ -0,0 +1,119 @@
+/*
+ * 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.controller;
+
+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 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.common.annotation.CommonLog;
+import vip.xiaonuo.common.pojo.CommonResult;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordAddParam;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordEditParam;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordIdParam;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.param.BizAppointmentRecordPageParam;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.service.BizAppointmentRecordService;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 预约记录控制器
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ */
+@Tag(name = "预约记录控制器")
+@RestController
+@Validated
+public class BizAppointmentRecordController {
+
+    @Resource
+    private BizAppointmentRecordService bizAppointmentRecordService;
+
+    /**
+     * 获取预约记录分页
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "获取预约记录分页")
+    @SaCheckPermission("/biz/bizappointmentrecord/page")
+    @GetMapping("/biz/bizappointmentrecord/page")
+    public CommonResult<Page<BizAppointmentRecord>> page(BizAppointmentRecordPageParam bizAppointmentRecordPageParam) {
+        return CommonResult.data(bizAppointmentRecordService.page(bizAppointmentRecordPageParam));
+    }
+
+    /**
+     * 添加预约记录
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "添加预约记录")
+    @CommonLog("添加预约记录")
+    @PostMapping("/biz/bizappointmentrecord/add")
+    public CommonResult<String> add(@RequestBody @Valid BizAppointmentRecordAddParam bizAppointmentRecordAddParam) {
+        bizAppointmentRecordService.add(bizAppointmentRecordAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑预约记录
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "编辑预约记录")
+    @CommonLog("编辑预约记录")
+    @PostMapping("/biz/bizappointmentrecord/edit")
+    public CommonResult<String> edit(@RequestBody @Valid BizAppointmentRecordEditParam bizAppointmentRecordEditParam) {
+        bizAppointmentRecordService.edit(bizAppointmentRecordEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除预约记录
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "删除预约记录")
+    @CommonLog("删除预约记录")
+    @PostMapping("/biz/bizappointmentrecord/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   List<BizAppointmentRecordIdParam> bizAppointmentRecordIdParamList) {
+        bizAppointmentRecordService.delete(bizAppointmentRecordIdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取预约记录详情
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    @Operation(summary = "获取预约记录详情")
+    @GetMapping("/biz/bizappointmentrecord/detail")
+    public CommonResult<BizAppointmentRecord> detail(@Valid BizAppointmentRecordIdParam bizAppointmentRecordIdParam) {
+        return CommonResult.data(bizAppointmentRecordService.detail(bizAppointmentRecordIdParam));
+    }
+}

+ 63 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/entity/BizAppointmentRecord.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.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import vip.xiaonuo.common.pojo.CommonEntity;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 预约记录实体
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+@Getter
+@Setter
+@TableName("biz_appointment_record")
+public class BizAppointmentRecord extends CommonEntity {
+
+    /** 主键ID */
+    @TableId
+    @Schema(description = "主键ID")
+    private String id;
+
+    /** 订单id */
+    @Schema(description = "订单id")
+    private String orderId;
+
+    /** 车牌号 */
+    @Schema(description = "车牌号")
+    private String licenseNumber;
+
+    /** 预约时段id */
+    @Schema(description = "预约时段id")
+    private String timeId;
+
+    /** 司机姓名 */
+    @Schema(description = "司机姓名")
+    private String driverName;
+
+    /** 司机电话 */
+    @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:已取消)")
+    private String status;
+}

+ 34 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/enums/BizAppointmentRecordEnum.java

@@ -0,0 +1,34 @@
+/*
+ * 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.enums;
+
+import lombok.Getter;
+
+/**
+ * 预约记录枚举
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+@Getter
+public enum BizAppointmentRecordEnum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    BizAppointmentRecordEnum(String value) {
+        this.value = value;
+    }
+}

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

@@ -0,0 +1,25 @@
+/*
+ * 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.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import vip.xiaonuo.biz.modular.bizappointmentrecord.entity.BizAppointmentRecord;
+
+/**
+ * 预约记录Mapper接口
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+public interface BizAppointmentRecordMapper extends BaseMapper<BizAppointmentRecord> {
+}

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

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!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>

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

@@ -0,0 +1,61 @@
+/*
+ * 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 lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 预约记录添加参数
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+@Getter
+@Setter
+public class BizAppointmentRecordAddParam {
+
+    /** 订单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;
+
+    /** 司机姓名 */
+    @Schema(description = "司机姓名")
+    private String driverName;
+
+    /** 司机电话 */
+    @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:已取消)")
+    private String status;
+
+}

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

@@ -0,0 +1,66 @@
+/*
+ * 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 lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 预约记录编辑参数
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+@Getter
+@Setter
+public class BizAppointmentRecordEditParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 订单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;
+
+    /** 司机姓名 */
+    @Schema(description = "司机姓名")
+    private String driverName;
+
+    /** 司机电话 */
+    @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:已取消)")
+    private String status;
+
+}

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

@@ -0,0 +1,35 @@
+/*
+ * 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 lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+
+/**
+ * 预约记录Id参数
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+@Getter
+@Setter
+public class BizAppointmentRecordIdParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+}

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

@@ -0,0 +1,51 @@
+/*
+ * 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 lombok.Getter;
+import lombok.Setter;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 预约记录查询参数
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+@Getter
+@Setter
+public class BizAppointmentRecordPageParam {
+
+    /** 当前页 */
+    @Schema(description = "当前页码")
+    private Integer current;
+
+    /** 每页条数 */
+    @Schema(description = "每页条数")
+    private Integer size;
+
+    /** 排序字段 */
+    @Schema(description = "排序字段,字段驼峰名称,如:userName")
+    private String sortField;
+
+    /** 排序方式 */
+    @Schema(description = "排序方式,升序:ASCEND;降序:DESCEND")
+    private String sortOrder;
+
+    /** 关键词 */
+    @Schema(description = "关键词")
+    private String searchKey;
+
+}

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

@@ -0,0 +1,80 @@
+/*
+ * 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.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+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 java.util.List;
+
+/**
+ * 预约记录Service接口
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+public interface BizAppointmentRecordService extends IService<BizAppointmentRecord> {
+
+    /**
+     * 获取预约记录分页
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    Page<BizAppointmentRecord> page(BizAppointmentRecordPageParam bizAppointmentRecordPageParam);
+
+    /**
+     * 添加预约记录
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    void add(BizAppointmentRecordAddParam bizAppointmentRecordAddParam);
+
+    /**
+     * 编辑预约记录
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    void edit(BizAppointmentRecordEditParam bizAppointmentRecordEditParam);
+
+    /**
+     * 删除预约记录
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    void delete(List<BizAppointmentRecordIdParam> bizAppointmentRecordIdParamList);
+
+    /**
+     * 获取预约记录详情
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     */
+    BizAppointmentRecord detail(BizAppointmentRecordIdParam bizAppointmentRecordIdParam);
+
+    /**
+     * 获取预约记录详情
+     *
+     * @author fanzherong
+     * @date  2025/03/24 14:47
+     **/
+    BizAppointmentRecord queryEntity(String id);
+}

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

@@ -0,0 +1,94 @@
+/*
+ * 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.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.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 org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+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.util.List;
+
+/**
+ * 预约记录Service接口实现类
+ *
+ * @author fanzherong
+ * @date  2025/03/24 14:47
+ **/
+@Service
+public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentRecordMapper, BizAppointmentRecord> implements BizAppointmentRecordService {
+
+    @Override
+    public Page<BizAppointmentRecord> page(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);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(BizAppointmentRecordAddParam bizAppointmentRecordAddParam) {
+        BizAppointmentRecord bizAppointmentRecord = BeanUtil.toBean(bizAppointmentRecordAddParam, BizAppointmentRecord.class);
+        this.save(bizAppointmentRecord);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(BizAppointmentRecordEditParam bizAppointmentRecordEditParam) {
+        BizAppointmentRecord bizAppointmentRecord = this.queryEntity(bizAppointmentRecordEditParam.getId());
+        BeanUtil.copyProperties(bizAppointmentRecordEditParam, bizAppointmentRecord);
+        this.updateById(bizAppointmentRecord);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<BizAppointmentRecordIdParam> bizAppointmentRecordIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(bizAppointmentRecordIdParamList, BizAppointmentRecordIdParam::getId));
+    }
+
+    @Override
+    public BizAppointmentRecord detail(BizAppointmentRecordIdParam bizAppointmentRecordIdParam) {
+        return this.queryEntity(bizAppointmentRecordIdParam.getId());
+    }
+
+    @Override
+    public BizAppointmentRecord queryEntity(String id) {
+        BizAppointmentRecord bizAppointmentRecord = this.getById(id);
+        if(ObjectUtil.isEmpty(bizAppointmentRecord)) {
+            throw new CommonException("预约记录不存在,id值为:{}", id);
+        }
+        return bizAppointmentRecord;
+    }
+}

+ 12 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmenttime/controller/BizAppointmentTimeController.java

@@ -116,4 +116,16 @@ public class BizAppointmentTimeController {
     public CommonResult<BizAppointmentTime> detail(@Valid BizAppointmentTimeIdParam bizAppointmentTimeIdParam) {
         return CommonResult.data(bizAppointmentTimeService.detail(bizAppointmentTimeIdParam));
     }
+
+    /**
+     * 获取下拉预约时段列表
+     *
+     * @author fanzherong
+     * @date  2025/03/20 17:46
+     */
+    @Operation(summary = "获取下拉预约时段列表")
+    @GetMapping("/biz/bizappointmenttime/getDownList")
+    public CommonResult<List<BizAppointmentTime>> getDownList() {
+        return CommonResult.data(bizAppointmentTimeService.getDownList());
+    }
 }

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

@@ -45,6 +45,10 @@ public class BizAppointmentTime extends CommonEntity {
     @Schema(description = "结束时段")
     private String endTime;
 
+    /** 结束时段 */
+    @Schema(description = "结束时段")
+    private String finishTime;
+
     /** 申请数量 */
     @Schema(description = "申请数量")
     private Integer applyNumber;

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmenttime/service/BizAppointmentTimeService.java

@@ -77,4 +77,7 @@ public interface BizAppointmentTimeService extends IService<BizAppointmentTime>
      * @date  2025/03/20 17:46
      **/
     BizAppointmentTime queryEntity(String id);
+
+    /** 获取预约时段下拉列表*/
+    List<BizAppointmentTime> getDownList();
 }

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

@@ -14,15 +14,21 @@ package vip.xiaonuo.biz.modular.bizappointmenttime.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
 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.google.common.collect.Lists;
+import jakarta.annotation.Resource;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.checkerframework.framework.qual.QualifierArgument;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.biz.modular.bizconfig.entity.BizConfig;
+import vip.xiaonuo.biz.modular.bizconfig.service.BizConfigService;
 import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
@@ -47,6 +53,9 @@ import java.util.List;
 @Slf4j
 public class BizAppointmentTimeServiceImpl extends ServiceImpl<BizAppointmentTimeMapper, BizAppointmentTime> implements BizAppointmentTimeService {
 
+    @Resource
+    private BizConfigService bizConfigService;
+
     @Override
     public Page<BizAppointmentTime> page(BizAppointmentTimePageParam bizAppointmentTimePageParam) {
         QueryWrapper<BizAppointmentTime> queryWrapper = new QueryWrapper<BizAppointmentTime>().checkSqlInjection();
@@ -59,6 +68,11 @@ public class BizAppointmentTimeServiceImpl extends ServiceImpl<BizAppointmentTim
     public void add(BizAppointmentTimeAddParam bizAppointmentTimeAddParam) {
         checkAddParam(bizAppointmentTimeAddParam);
         BizAppointmentTime bizAppointmentTime = BeanUtil.toBean(bizAppointmentTimeAddParam, BizAppointmentTime.class);
+        if(StringUtils.equals(bizAppointmentTime.getEndTime(),"00:00")){
+            bizAppointmentTime.setFinishTime("24:00");
+        }else{
+            bizAppointmentTime.setFinishTime(bizAppointmentTime.getEndTime());
+        }
         this.save(bizAppointmentTime);
     }
 
@@ -147,6 +161,11 @@ public class BizAppointmentTimeServiceImpl extends ServiceImpl<BizAppointmentTim
             checkEditParam(bizAppointmentTimeEditParam);
         }
         BeanUtil.copyProperties(bizAppointmentTimeEditParam, bizAppointmentTime);
+        if(StringUtils.equals(bizAppointmentTime.getEndTime(),"00:00")){
+            bizAppointmentTime.setFinishTime("24:00");
+        }else{
+            bizAppointmentTime.setFinishTime(bizAppointmentTime.getEndTime());
+        }
         this.updateById(bizAppointmentTime);
     }
 
@@ -171,6 +190,37 @@ public class BizAppointmentTimeServiceImpl extends ServiceImpl<BizAppointmentTim
         return bizAppointmentTime;
     }
 
+    @Override
+    public List<BizAppointmentTime> getDownList() {
+        List<BizAppointmentTime> timeList = Lists.newArrayList();
+        //获取配置的时段下拉个数
+        BizConfig bizConfig = bizConfigService.getOne(new QueryWrapper<BizConfig>().lambda().last("limit 1"));
+        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")).
+                orderByAsc(BizAppointmentTime::getBeginTime));
+        //如果查询到的时段个数大于等于配置的下拉个数,直接返回,反之,从前面查询补上
+        if(list.size()>= bizConfig.getPullNumber()){
+            timeList.addAll(list.subList(0,bizConfig.getPullNumber()));
+        }else{
+            //差额
+            timeList.addAll(list);
+            int count = bizConfig.getPullNumber() - list.size();
+            List<BizAppointmentTime> bizAppointmentTimeList = this.list(new QueryWrapper<BizAppointmentTime>().lambda().
+                    ge(BizAppointmentTime::getBeginTime,  "00:00").
+                    orderByAsc(BizAppointmentTime::getBeginTime).
+                    last("limit "+count));
+            timeList.addAll(bizAppointmentTimeList);
+        }
+        return timeList;
+    }
+
+    public static void main(String[] args) {
+        String format = DateUtil.format(DateUtil.date(), "HH");
+        System.out.printf("format:"+format);
+    }
+
 
     public static boolean checkAddTime(LocalTime startA, LocalTime endA){
         if(startA.isAfter(endA)){

+ 187 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/controller/BizOrderController.java

@@ -0,0 +1,187 @@
+/*
+ * 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.bizorder.controller;
+
+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.bizcustomer.entity.BizCustomer;
+import vip.xiaonuo.common.annotation.CommonLog;
+import vip.xiaonuo.common.pojo.CommonResult;
+import vip.xiaonuo.biz.modular.bizorder.entity.BizOrder;
+import vip.xiaonuo.biz.modular.bizorder.param.BizOrderAddParam;
+import vip.xiaonuo.biz.modular.bizorder.param.BizOrderEditParam;
+import vip.xiaonuo.biz.modular.bizorder.param.BizOrderIdParam;
+import vip.xiaonuo.biz.modular.bizorder.param.BizOrderPageParam;
+import vip.xiaonuo.biz.modular.bizorder.service.BizOrderService;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 订单管理控制器
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ */
+@Tag(name = "订单管理控制器")
+@RestController
+@Validated
+public class BizOrderController {
+
+    @Resource
+    private BizOrderService bizOrderService;
+
+    /**
+     * 获取订单管理分页
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "获取订单管理分页")
+    @SaCheckPermission("/biz/bizorder/page")
+    @GetMapping("/biz/bizorder/page")
+    public CommonResult<Page<BizOrder>> page(BizOrderPageParam bizOrderPageParam) {
+        return CommonResult.data(bizOrderService.page(bizOrderPageParam));
+    }
+
+    /**
+     * 添加订单管理
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "添加订单管理")
+    @CommonLog("添加订单管理")
+    @PostMapping("/biz/bizorder/add")
+    public CommonResult<String> add(@RequestBody @Valid BizOrderAddParam bizOrderAddParam) {
+        bizOrderService.add(bizOrderAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑订单管理
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "编辑订单管理")
+    @CommonLog("编辑订单管理")
+    @PostMapping("/biz/bizorder/edit")
+    public CommonResult<String> edit(@RequestBody @Valid BizOrderEditParam bizOrderEditParam) {
+        bizOrderService.edit(bizOrderEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除订单管理
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "删除订单管理")
+    @CommonLog("删除订单管理")
+    @PostMapping("/biz/bizorder/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   List<BizOrderIdParam> bizOrderIdParamList) {
+        bizOrderService.delete(bizOrderIdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取订单管理详情
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "获取订单管理详情")
+    @GetMapping("/biz/bizorder/detail")
+    public CommonResult<BizOrder> detail(@Valid BizOrderIdParam bizOrderIdParam) {
+        return CommonResult.data(bizOrderService.detail(bizOrderIdParam));
+    }
+
+    /**
+     * 获取客户信息
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "获取客户信息")
+    @GetMapping("/biz/bizorder/getCustomerById")
+    public CommonResult<List<BizCustomer>> getCustomerById(@Valid BizOrderIdParam bizOrderIdParam) {
+        return CommonResult.data(bizOrderService.getCustomerById(bizOrderIdParam));
+    }
+
+    /**
+     * 绑定客户ID
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "绑定客户ID")
+    @CommonLog("绑定客户ID")
+    @PostMapping("/biz/bizorder/bindCustomerId")
+    public CommonResult<String> bindCustomerId(@RequestBody @Valid BizOrderEditParam bizOrderEditParam) {
+        bizOrderService.bindCustomerId(bizOrderEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 导出订单报表
+     */
+    @Operation(summary = "导出订单报表")
+    @GetMapping(value = "/biz/bizorder/exportRecord", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
+    public void exportRecord(BizOrderPageParam bizOrderPageParam, HttpServletResponse response) throws IOException {
+        bizOrderService.exportRecord(bizOrderPageParam,response);
+    }
+
+
+    /**
+     * 结束订单
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "结束订单")
+    @CommonLog("结束订单")
+    @PostMapping("/biz/bizorder/endOrder")
+    public CommonResult<String> endOrder(@RequestBody @Valid BizOrderIdParam bizOrderIdParam) {
+        bizOrderService.endOrder(bizOrderIdParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 订单列表
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "订单列表")
+    @CommonLog("订单列表")
+    @GetMapping("/biz/bizorder/getList")
+    public CommonResult<List<BizOrder>> getList() {
+        return CommonResult.data(bizOrderService.getList());
+    }
+}

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

@@ -0,0 +1,111 @@
+/*
+ * 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.bizorder.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fhs.core.trans.anno.Trans;
+import com.fhs.core.trans.constant.TransType;
+import com.fhs.core.trans.vo.TransPojo;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import vip.xiaonuo.common.pojo.CommonEntity;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 订单管理实体
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+@Getter
+@Setter
+@TableName("biz_order")
+public class BizOrder extends CommonEntity implements TransPojo {
+
+    /** 主键ID */
+    @TableId
+    @Schema(description = "主键ID")
+    private String id;
+
+    /** 订单编号 */
+    @Schema(description = "订单编号")
+    private String orderNumber;
+
+    /** 订单名称 */
+    @Schema(description = "订单名称")
+    private String orderName;
+
+    /** 客户id */
+    @Schema(description = "客户id")
+    private String customerId;
+
+    /** 货品id */
+    @Schema(description = "货品id")
+    private String goodId;
+
+    /** 订单类型(1:采购   2:销售) */
+    @Trans(type = TransType.DICTIONARY, key = "order_type")
+    private String orderType;
+
+    /** 订单来源(1:oa推送   2:手动新增) */
+    @Trans(type = TransType.DICTIONARY, key = "order_source")
+    private String orderSource;
+
+    /** 订单状态(1:正常  2:终止) */
+    @Trans(type = TransType.DICTIONARY, key = "order_status")
+    private String orderStatus;
+
+    /** 订单重量 */
+    @Schema(description = "订单重量")
+    private BigDecimal orderWeight;
+
+    /** 过磅重量 */
+    @Schema(description = "过磅重量")
+    private BigDecimal netWeight;
+
+    /** 订单备注*/
+    @Schema(description = "订单备注")
+    private String orderRemark;
+
+
+    @TableField(exist = false)
+    /**客户名称*/
+    private String customerName;
+
+    @TableField(exist = false)
+    /**货品名称*/
+    private String goodsName;
+
+    /**货品规格*/
+    @TableField(exist = false)
+    private String goodsModel;
+
+    /** 联系人 */
+    @TableField(exist = false)
+    @Schema(description = "联系人")
+    private String customerContactName;
+
+    /** 手机号 */
+    @TableField(exist = false)
+    @Schema(description = "手机号")
+    private String customerPhone;
+
+    /** 客户地址 */
+    @TableField(exist = false)
+    @Schema(description = "客户地址")
+    private String customerAddress;
+
+}

+ 34 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/enums/BizOrderEnum.java

@@ -0,0 +1,34 @@
+/*
+ * 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.bizorder.enums;
+
+import lombok.Getter;
+
+/**
+ * 订单管理枚举
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+@Getter
+public enum BizOrderEnum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    BizOrderEnum(String value) {
+        this.value = value;
+    }
+}

+ 33 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/mapper/BizOrderMapper.java

@@ -0,0 +1,33 @@
+/*
+ * 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.bizorder.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.bizorder.entity.BizOrder;
+
+import java.util.List;
+
+/**
+ * 订单管理Mapper接口
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+public interface BizOrderMapper extends BaseMapper<BizOrder> {
+    Page<BizOrder> getPage(@Param("page")Page<BizOrder> page, @Param("ew") QueryWrapper<BizOrder> ew);
+
+    List<BizOrder> getPage(@Param("ew") QueryWrapper<BizOrder> ew);
+}

+ 28 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/mapper/mapping/BizOrderMapper.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="vip.xiaonuo.biz.modular.bizorder.mapper.BizOrderMapper">
+
+    <select id="getPage" resultType="vip.xiaonuo.biz.modular.bizorder.entity.BizOrder">
+        select
+            bo.id,
+            bo.order_number,
+            bo.order_name,
+            bo.customer_id,
+            bc.customer_name,
+            bc.customer_contact_name,
+            bc.customer_phone,
+            bc.customer_address,
+            bo.good_id,
+            bg.`NAME` goodsName,
+            bg.MODEL goodsModel,
+            bo.order_type,
+            bo.order_source,
+            bo.order_status,
+            bo.order_weight/1000 order_weight,
+            bo.net_weight/1000 net_weight
+        from biz_order bo
+        left join biz_customer bc on bo.customer_id = bc.id
+        left join biz_goods bg on bg.id = bo.good_id
+        ${ew.customSqlSegment}
+    </select>
+</mapper>

+ 72 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderAddParam.java

@@ -0,0 +1,72 @@
+/*
+ * 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.bizorder.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 订单管理添加参数
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+@Getter
+@Setter
+public class BizOrderAddParam {
+
+    /** 订单编号 */
+    @Schema(description = "订单编号")
+    private String orderNumber;
+
+    /** 订单名称 */
+    @Schema(description = "订单名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "orderName不能为空")
+    private String orderName;
+
+    /** 客户id */
+    @Schema(description = "客户id", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String customerId;
+
+    /** 货品id */
+    @Schema(description = "货品id", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String goodId;
+
+    /** 订单类型(1:采购   2:销售) */
+    @Schema(description = "订单类型(1:采购   2:销售)")
+    private String orderType;
+
+    /** 订单来源(1:oa推送   2:手动新增) */
+    @Schema(description = "订单来源(1:oa推送   2:手动新增)")
+    private String orderSource;
+
+    /** 订单状态(1:正常  2:终止) */
+    @Schema(description = "订单状态(1:正常  2:终止)")
+    private String orderStatus;
+
+    /** 订单重量 */
+    @Schema(description = "订单重量", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "orderWeight不能为空")
+    private BigDecimal orderWeight;
+
+    /** 过磅重量 */
+    @Schema(description = "过磅重量")
+    private BigDecimal netWeight;
+
+}

+ 79 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderEditParam.java

@@ -0,0 +1,79 @@
+/*
+ * 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.bizorder.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 订单管理编辑参数
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+@Getter
+@Setter
+public class BizOrderEditParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 订单编号 */
+    @Schema(description = "订单编号")
+    private String orderNumber;
+
+    /** 订单名称 */
+    @Schema(description = "订单名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String orderName;
+
+    /** 客户id */
+    @Schema(description = "客户id", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String customerId;
+
+    /** 货品id */
+    @Schema(description = "货品id", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String goodId;
+
+    /** 订单类型(1:采购   2:销售) */
+    @Schema(description = "订单类型(1:采购   2:销售)")
+    private String orderType;
+
+    /** 订单来源(1:oa推送   2:手动新增) */
+    @Schema(description = "订单来源(1:oa推送   2:手动新增)")
+    private String orderSource;
+
+    /** 订单状态(1:正常  2:终止) */
+    @Schema(description = "订单状态(1:正常  2:终止)")
+    private String orderStatus;
+
+    /** 订单重量 */
+    @Schema(description = "订单重量", requiredMode = Schema.RequiredMode.REQUIRED)
+    private BigDecimal orderWeight;
+
+    /** 过磅重量 */
+    @Schema(description = "过磅重量")
+    private BigDecimal netWeight;
+
+    /**客户id集合*/
+    private List<String> customerIdList;
+
+}

+ 51 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderExportResult.java

@@ -0,0 +1,51 @@
+package vip.xiaonuo.biz.modular.bizorder.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 BizOrderExportResult {
+    /** 订单编号 */
+    @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 customerName;
+
+    /** 货品名称*/
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"订单报表", "货品名称"})
+    private String goodsName;
+
+    /** 订单来源(1:oa推送   2:手动新增) */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"订单报表", "订单来源"})
+    private String orderSourceName;
+
+    /** 订单状态(1:正常  2:终止) */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"订单报表", "订单状态"})
+    private String orderStatusName;
+
+    /** 订单重量 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"订单报表", "订单重量(吨)"})
+    private BigDecimal orderWeight;
+
+    /** 过磅重量 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"订单报表", "过磅重量(吨)"})
+    private BigDecimal netWeight;
+}

+ 35 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderIdParam.java

@@ -0,0 +1,35 @@
+/*
+ * 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.bizorder.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+import jakarta.validation.constraints.NotBlank;
+
+/**
+ * 订单管理Id参数
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+@Getter
+@Setter
+public class BizOrderIdParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+}

+ 69 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderPageParam.java

@@ -0,0 +1,69 @@
+/*
+ * 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.bizorder.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 订单管理查询参数
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+@Getter
+@Setter
+public class BizOrderPageParam {
+
+    /** 当前页 */
+    @Schema(description = "当前页码")
+    private Integer current;
+
+    /** 每页条数 */
+    @Schema(description = "每页条数")
+    private Integer size;
+
+    /** 排序字段 */
+    @Schema(description = "排序字段,字段驼峰名称,如:userName")
+    private String sortField;
+
+    /** 排序方式 */
+    @Schema(description = "排序方式,升序:ASCEND;降序:DESCEND")
+    private String sortOrder;
+
+    /** 关键词 */
+    @Schema(description = "关键词")
+    private String searchKey;
+
+    /**订单名称*/
+    private String orderName;
+
+    /**订单编号*/
+    private String orderNumber;
+
+    /**客户名称*/
+    private String customerName;
+
+    /**货品名称*/
+    private String goodsName;
+
+    /**订单状态*/
+    private String orderStatus;
+
+    /**订单来源*/
+    private String orderSource;
+
+}

+ 99 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/service/BizOrderService.java

@@ -0,0 +1,99 @@
+/*
+ * 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.bizorder.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.bizcustomer.entity.BizCustomer;
+import vip.xiaonuo.biz.modular.bizorder.entity.BizOrder;
+import vip.xiaonuo.biz.modular.bizorder.param.BizOrderAddParam;
+import vip.xiaonuo.biz.modular.bizorder.param.BizOrderEditParam;
+import vip.xiaonuo.biz.modular.bizorder.param.BizOrderIdParam;
+import vip.xiaonuo.biz.modular.bizorder.param.BizOrderPageParam;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 订单管理Service接口
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+public interface BizOrderService extends IService<BizOrder> {
+
+    /**
+     * 获取订单管理分页
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    Page<BizOrder> page(BizOrderPageParam bizOrderPageParam);
+
+    /**
+     * 添加订单管理
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    void add(BizOrderAddParam bizOrderAddParam);
+
+    /**
+     * 编辑订单管理
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    void edit(BizOrderEditParam bizOrderEditParam);
+
+    /**
+     * 删除订单管理
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    void delete(List<BizOrderIdParam> bizOrderIdParamList);
+
+    /**
+     * 获取订单管理详情
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    BizOrder detail(BizOrderIdParam bizOrderIdParam);
+
+    /**
+     * 获取订单管理详情
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     **/
+    BizOrder queryEntity(String id);
+
+    /**获取客户id*/
+    List<BizCustomer> getCustomerById(BizOrderIdParam bizOrderIdParam);
+
+    /**绑定客户id*/
+    void bindCustomerId(BizOrderEditParam bizOrderEditParam);
+
+
+    /**导出报表*/
+    void exportRecord(BizOrderPageParam bizOrderPageParam, HttpServletResponse response) throws IOException;
+
+    /**结束订单*/
+    void endOrder(BizOrderIdParam bizOrderIdParam);
+
+    /**查询订单列表*/
+    List<BizOrder> getList();
+}

+ 198 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/service/impl/BizOrderServiceImpl.java

@@ -0,0 +1,198 @@
+/*
+ * 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.bizorder.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.util.ObjectUtil;
+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.bizcustomer.entity.BizCustomer;
+import vip.xiaonuo.biz.modular.bizcustomer.service.BizCustomerService;
+import vip.xiaonuo.biz.modular.bizorder.param.*;
+import vip.xiaonuo.biz.modular.utils.CommonExportUtil;
+import vip.xiaonuo.common.exception.CommonException;
+import vip.xiaonuo.common.page.CommonPageRequest;
+import vip.xiaonuo.biz.modular.bizorder.entity.BizOrder;
+import vip.xiaonuo.biz.modular.bizorder.mapper.BizOrderMapper;
+import vip.xiaonuo.biz.modular.bizorder.service.BizOrderService;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 订单管理Service接口实现类
+ *
+ * @author fanzherong
+ * @date  2025/03/21 17:16
+ **/
+@Service
+public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> implements BizOrderService {
+
+    @Resource
+    private BizCustomerService bizCustomerService;
+
+    @Resource
+    private TransService transService;
+
+    @Override
+    public Page<BizOrder> page(BizOrderPageParam bizOrderPageParam) {
+        QueryWrapper<BizOrder> queryWrapper = getQueryWrapper(bizOrderPageParam);
+        return this.getBaseMapper().getPage(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    public QueryWrapper<BizOrder> getQueryWrapper(BizOrderPageParam bizOrderPageParam){
+        QueryWrapper<BizOrder> queryWrapper = new QueryWrapper<BizOrder>().checkSqlInjection();
+        //订单名称查询
+        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderName())){
+            queryWrapper.like("bo.order_name",bizOrderPageParam.getOrderName());
+        }
+        //订单编号查询
+        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderNumber())){
+            queryWrapper.like("bo.order_number",bizOrderPageParam.getOrderNumber());
+        }
+        //客户名称查询
+        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getCustomerName())){
+            queryWrapper.like("bc.customer_name",bizOrderPageParam.getCustomerName());
+        }
+        //货品名称查询
+        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getGoodsName())){
+            queryWrapper.like("bg.`NAME`",bizOrderPageParam.getGoodsName());
+        }
+        //状态查询
+        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderStatus())){
+            queryWrapper.eq("bo.order_status",bizOrderPageParam.getOrderStatus());
+        }
+        //订单来源
+        if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderSource())){
+            queryWrapper.eq("bo.order_source",bizOrderPageParam.getOrderSource());
+        }
+        queryWrapper.eq("bo.delete_flag","NOT_DELETE");
+        queryWrapper.orderByDesc("bo.create_time");
+        return queryWrapper;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(BizOrderAddParam bizOrderAddParam) {
+        //判断订单编号是否存在
+        long count = this.count(new QueryWrapper<BizOrder>().lambda().eq(BizOrder::getOrderNumber, bizOrderAddParam.getOrderNumber()));
+        if(count>0){
+            throw new CommonException("订单编号已存在!");
+        }
+        BizOrder bizOrder = BeanUtil.toBean(bizOrderAddParam, BizOrder.class);
+        //数据库默认存KG,页面展示用吨
+        bizOrder.setOrderWeight(bizOrder.getOrderWeight().multiply(new BigDecimal(1000)));
+        //来源,手动新增
+        bizOrder.setOrderSource("2");
+        this.save(bizOrder);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(BizOrderEditParam bizOrderEditParam) {
+        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
+        if(!StringUtils.equals(bizOrder.getOrderNumber(),bizOrderEditParam.getOrderNumber())){
+            //订单编号修改,判断订单编号是否存在
+            long count = this.count(new QueryWrapper<BizOrder>().lambda().eq(BizOrder::getOrderNumber, bizOrderEditParam.getOrderNumber()));
+            if(count>0){
+                throw new CommonException("订单编号已存在!");
+            }
+        }
+        BeanUtil.copyProperties(bizOrderEditParam, bizOrder);
+        //设置订单重量
+        if(bizOrder.getOrderWeight().compareTo(bizOrderEditParam.getOrderWeight()) != 0){
+            bizOrder.setOrderWeight(bizOrderEditParam.getOrderWeight().multiply(new BigDecimal(1000)));
+        }else{
+            bizOrder.setOrderWeight(bizOrder.getOrderWeight().multiply(new BigDecimal(1000)));
+        }
+        this.updateById(bizOrder);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<BizOrderIdParam> bizOrderIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(bizOrderIdParamList, BizOrderIdParam::getId));
+    }
+
+    @Override
+    public BizOrder detail(BizOrderIdParam bizOrderIdParam) {
+        return this.queryEntity(bizOrderIdParam.getId());
+    }
+
+    @Override
+    public BizOrder queryEntity(String id) {
+        BizOrder bizOrder = this.getById(id);
+        if(ObjectUtil.isEmpty(bizOrder)) {
+            throw new CommonException("订单管理不存在,id值为:{}", id);
+        }
+        return bizOrder;
+    }
+
+    @Override
+    public List<BizCustomer> getCustomerById(BizOrderIdParam bizOrderIdParam) {
+        if(ObjectUtil.isNotEmpty(bizOrderIdParam.getId())){
+            List<BizCustomer> customerList = bizCustomerService.list(new QueryWrapper<BizCustomer>().lambda().eq(BizCustomer::getId, bizOrderIdParam.getId()));
+            return customerList;
+        }
+        return null;
+    }
+
+    @Override
+    public void bindCustomerId(BizOrderEditParam bizOrderEditParam) {
+        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
+        if(ObjectUtil.isNotEmpty(bizOrderEditParam.getCustomerIdList())){
+            bizOrder.setCustomerId(bizOrderEditParam.getCustomerIdList().get(0));
+        }
+        this.updateById(bizOrder);
+    }
+
+    @Override
+    public void exportRecord(BizOrderPageParam bizOrderPageParam, HttpServletResponse response) throws IOException {
+        QueryWrapper<BizOrder> queryWrapper = getQueryWrapper(bizOrderPageParam);
+        List<BizOrder> orderList = this.getBaseMapper().getPage(queryWrapper);
+        String fileName = "订单报表.xlsx";
+        List<BizOrderExportResult> list = Lists.newArrayList();
+        transService.transBatch(orderList);
+        for(BizOrder bizOrder : orderList){
+            BizOrderExportResult bizOrderExportResult = new BizOrderExportResult();
+            BeanUtil.copyProperties(bizOrder, bizOrderExportResult);
+            bizOrderExportResult.setOrderSourceName((String) bizOrder.getTransMap().get("orderSourceName"));
+            bizOrderExportResult.setOrderStatusName((String) bizOrder.getTransMap().get("orderStatusName"));
+            list.add(bizOrderExportResult);
+        }
+        CommonExportUtil.export(fileName, BizOrderExportResult.class,list,response,"订单报表");
+    }
+
+    @Override
+    public void endOrder(BizOrderIdParam bizOrderIdParam) {
+        BizOrder bizOrder = this.queryEntity(bizOrderIdParam.getId());
+        bizOrder.setOrderStatus("2");
+        this.updateById(bizOrder);
+    }
+
+    @Override
+    public List<BizOrder> getList() {
+        return this.list();
+    }
+}

+ 12 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/goods/controller/BizGoodsController.java

@@ -120,4 +120,16 @@ public class BizGoodsController {
     public CommonResult<BizGoods> detail(@Valid BizGoodsIdParam bizGoodsIdParam) {
         return CommonResult.data(bizGoodsService.detail(bizGoodsIdParam));
     }
+
+    /**
+     * 获取货品列表
+     *
+     * @author 徐超
+     * @date  2025/01/02 17:44
+     */
+    @Operation(summary = "获取货品管理详情")
+    @GetMapping("/biz/goods/getList")
+    public CommonResult<List<BizGoods>> getList() {
+        return CommonResult.data(bizGoodsService.getList());
+    }
 }

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/goods/service/BizGoodsService.java

@@ -77,4 +77,7 @@ public interface BizGoodsService extends IService<BizGoods> {
      * @date  2025/01/02 17:44
      **/
     BizGoods queryEntity(String id);
+
+    /** 获取货品列表*/
+    List<BizGoods> getList();
 }

+ 5 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/goods/service/impl/BizGoodsServiceImpl.java

@@ -116,4 +116,9 @@ public class BizGoodsServiceImpl extends ServiceImpl<BizGoodsMapper, BizGoods> i
         }
         return bizGoods;
     }
+
+    @Override
+    public List<BizGoods> getList() {
+        return this.list();
+    }
 }

+ 112 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/CommonExportUtil.java

@@ -0,0 +1,112 @@
+package vip.xiaonuo.biz.modular.utils;
+
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.metadata.data.WriteCellData;
+import com.alibaba.excel.write.handler.CellWriteHandler;
+import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
+import com.alibaba.excel.write.metadata.style.WriteCellStyle;
+import com.alibaba.excel.write.metadata.style.WriteFont;
+import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
+import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
+import com.alibaba.excel.write.style.row.AbstractRowHeightStyleStrategy;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.poi.ss.usermodel.*;
+import vip.xiaonuo.common.util.CommonDownloadUtil;
+
+import java.io.File;
+import java.util.List;
+
+public class CommonExportUtil {
+
+    public static void export(String fileName, Class c, List list, HttpServletResponse response , String sheetName){
+        File tempFile = null;
+        try {
+            // 创建临时文件
+            tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
+
+            // 头的策略
+            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
+            WriteFont headWriteFont = new WriteFont();
+            headWriteFont.setFontHeightInPoints((short) 14);
+            headWriteCellStyle.setWriteFont(headWriteFont);
+            // 水平垂直居中
+            headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
+            headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+            // 内容的策略
+            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
+            // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
+            contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
+            // 内容背景白色
+            contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
+            WriteFont contentWriteFont = new WriteFont();
+
+            // 内容字体大小
+            contentWriteFont.setFontHeightInPoints((short) 12);
+            contentWriteCellStyle.setWriteFont(contentWriteFont);
+
+            //设置边框样式,细实线
+            contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
+            contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
+            contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
+            contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
+
+            // 水平垂直居中
+            contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
+            contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
+
+            // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
+            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle,
+                    contentWriteCellStyle);
+
+            // 写excel
+            EasyExcel.write(tempFile.getPath(), c)
+                    // 自定义样式
+                    .registerWriteHandler(horizontalCellStyleStrategy)
+                    // 自动列宽
+                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
+                    // 设置第一行字体
+                    .registerWriteHandler(new CellWriteHandler() {
+                        @Override
+                        public void afterCellDispose(CellWriteHandlerContext context) {
+                            WriteCellData<?> cellData = context.getFirstCellData();
+                            WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();
+                            Integer rowIndex = context.getRowIndex();
+                            if(rowIndex == 0) {
+                                WriteFont headWriteFont = new WriteFont();
+                                headWriteFont.setFontName("宋体");
+                                headWriteFont.setBold(true);
+                                headWriteFont.setFontHeightInPoints((short) 16);
+                                writeCellStyle.setWriteFont(headWriteFont);
+                            }
+                        }
+                    })
+                    // 设置表头行高
+                    .registerWriteHandler(new AbstractRowHeightStyleStrategy() {
+                        @Override
+                        protected void setHeadColumnHeight(Row row, int relativeRowIndex) {
+                            if(relativeRowIndex == 0) {
+                                // 表头第一行
+                                row.setHeightInPoints(34);
+                            } else {
+                                // 表头其他行
+                                row.setHeightInPoints(30);
+                            }
+                        }
+                        @Override
+                        protected void setContentColumnHeight(Row row, int relativeRowIndex) {
+                            // 内容行
+                            row.setHeightInPoints(20);
+                        }
+                    })
+                    .sheet(sheetName)
+                    .doWrite(list);
+            CommonDownloadUtil.download(tempFile, response);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            FileUtil.del(tempFile);
+        }
+    }
+}