Ver código fonte

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

shasha 1 mês atrás
pai
commit
3a2832b4e4
79 arquivos alterados com 3332 adições e 187 exclusões
  1. 1 0
      snowy-admin-web/package.json
  2. 4 0
      snowy-admin-web/src/api/biz/bizOrderApi.js
  3. 36 0
      snowy-admin-web/src/api/biz/bizSaleOrderApi.js
  4. 4 3
      snowy-admin-web/src/components/XnSignName/index.vue
  5. 7 0
      snowy-admin-web/src/views/biz/bizaccessrecord/detail.vue
  6. 24 2
      snowy-admin-web/src/views/biz/bizappointmentrecord/detail.vue
  7. 77 14
      snowy-admin-web/src/views/biz/bizappointmentrecord/index.vue
  8. 159 0
      snowy-admin-web/src/views/biz/bizappointmentrecord/sign.vue
  9. 4 0
      snowy-admin-web/src/views/biz/bizconfig/form.vue
  10. 8 0
      snowy-admin-web/src/views/biz/bizconfig/index.vue
  11. 2 0
      snowy-admin-web/src/views/biz/bizorder/detail.vue
  12. 64 0
      snowy-admin-web/src/views/biz/bizorder/end.vue
  13. 23 4
      snowy-admin-web/src/views/biz/bizorder/flow.vue
  14. 25 13
      snowy-admin-web/src/views/biz/bizorder/form.vue
  15. 66 14
      snowy-admin-web/src/views/biz/bizorder/index.vue
  16. 18 9
      snowy-admin-web/src/views/biz/bizqueuerecord/index.vue
  17. 136 0
      snowy-admin-web/src/views/biz/bizsaleorder/form.vue
  18. 237 0
      snowy-admin-web/src/views/biz/bizsaleorder/index.vue
  19. 52 8
      snowy-admin-web/src/views/biz/bizsendrecord/detail.vue
  20. 38 28
      snowy-admin-web/src/views/biz/bizsendrecord/index.vue
  21. 79 9
      snowy-admin-web/src/views/biz/record/detail.vue
  22. 14 14
      snowy-admin-web/src/views/biz/record/index.vue
  23. 6 0
      snowy-common/src/main/java/vip/xiaonuo/common/prop/CommonProperties.java
  24. 3 0
      snowy-plugin-api/snowy-plugin-auth-api/src/main/java/vip/xiaonuo/auth/core/pojo/SaBaseLoginUser.java
  25. 71 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/api/controller/ApiController.java
  26. 167 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/api/service/ApiService.java
  27. 1 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/controller/BizAppointmentRecordController.java
  28. 32 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/entity/BizAppointmentRecord.java
  29. 12 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/mapping/BizAppointmentRecordMapper.xml
  30. 11 2
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/param/BizAppointmentExportResult.java
  31. 39 13
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/impl/BizAppointmentRecordServiceImpl.java
  32. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizconfig/entity/BizConfig.java
  33. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizconfig/param/BizConfigAddParam.java
  34. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizconfig/param/BizConfigEditParam.java
  35. 15 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/controller/BizOrderController.java
  36. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/entity/BizOrder.java
  37. 3 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/mapper/mapping/BizOrderMapper.xml
  38. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderEditParam.java
  39. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/service/BizOrderService.java
  40. 102 6
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/service/impl/BizOrderServiceImpl.java
  41. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorderconfig/service/impl/BizOrderConfigServiceImpl.java
  42. 144 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/controller/BizSaleOrderController.java
  43. 73 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/entity/BizSaleOrder.java
  44. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/enums/BizSaleOrderEnum.java
  45. 30 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/mapper/BizSaleOrderMapper.java
  46. 21 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/mapper/mapping/BizSaleOrderMapper.xml
  47. 60 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/param/BizSaleOrderAddParam.java
  48. 65 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/param/BizSaleOrderEditParam.java
  49. 37 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/param/BizSaleOrderIdParam.java
  50. 63 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/param/BizSaleOrderPageParam.java
  51. 85 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/service/BizSaleOrderService.java
  52. 163 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/service/impl/BizSaleOrderServiceImpl.java
  53. 12 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/controller/BizVehicleController.java
  54. 5 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/service/BizVehicleService.java
  55. 19 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/service/impl/BizVehicleServiceImpl.java
  56. 123 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/controller/OfficialInfoController.java
  57. 63 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/entity/OfficialInfo.java
  58. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/enums/OfficialInfoEnum.java
  59. 25 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/mapper/OfficialInfoMapper.java
  60. 5 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/mapper/mapping/OfficialInfoMapper.xml
  61. 58 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoAddParam.java
  62. 63 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoEditParam.java
  63. 35 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoIdParam.java
  64. 51 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoPageParam.java
  65. 80 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/service/OfficialInfoService.java
  66. 94 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/service/impl/OfficialInfoServiceImpl.java
  67. 5 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/entity/BizRecord.java
  68. 52 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/mapper/mapping/BizRecordMapper.xml
  69. 1 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/param/BizRecordEditParam.java
  70. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/param/BizRecordPageParam.java
  71. 39 22
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/result/BizRecordExportResult.java
  72. 46 18
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/service/impl/BizRecordServiceImpl.java
  73. 45 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/MsgUtil.java
  74. 78 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/SignUtil.java
  75. 43 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/XmlUtil.java
  76. 3 0
      snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/entity/SysUser.java
  77. 6 1
      snowy-web-app/src/main/java/vip/xiaonuo/core/config/GlobalConfigure.java
  78. 2 2
      snowy-web-app/src/main/resources/application-dev.properties
  79. 6 0
      snowy-web-app/src/main/resources/application-local.properties

+ 1 - 0
snowy-admin-web/package.json

@@ -38,6 +38,7 @@
 		"fuse.js": "7.0.0",
 		"highlight.js": "11.10.0",
 		"hotkeys-js": "3.13.7",
+		"html2canvas": "^1.4.1",
 		"js-pinyin": "0.2.7",
 		"lodash-es": "4.17.21",
 		"moment": "^2.30.1",

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

@@ -58,5 +58,9 @@ export default {
 	//订单审核
 	auditOrder(data){
 		return request('auditOrder',data)
+	},
+	//提交
+	submit(data){
+		return request('submit',data)
 	}
 }

+ 36 - 0
snowy-admin-web/src/api/biz/bizSaleOrderApi.js

@@ -0,0 +1,36 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/bizsaleorder/` + url, ...arg)
+
+/**
+ * 销售订单Api接口管理器
+ *
+ * @author fanzherong
+ * @date  2025/04/10 09:31
+ **/
+export default {
+	// 获取销售订单分页
+	bizSaleOrderPage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交销售订单表单 edit为true时为编辑,默认为新增
+	bizSaleOrderSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除销售订单
+	bizSaleOrderDelete(data) {
+		return request('delete', data)
+	},
+	// 获取销售订单详情
+	bizSaleOrderDetail(data) {
+		return request('detail', data, 'get')
+	},
+	//根据客户id查询销售订单信息
+	queryByCustomerId(data){
+		return request('queryByCustomerId',data,'get')
+	},
+	//详情
+	detailById(data){
+		return request('detailById',data,'get')
+	}
+}

+ 4 - 3
snowy-admin-web/src/components/XnSignName/index.vue

@@ -53,23 +53,24 @@
 	import VueEsign from './vueEsign.vue'
 	const visible = ref(false)
 	const esignRef = ref(false)
-	const resultImg = ref('')
+	const resultImg = ref('https://db.js-whzl.com:8055/preview/zhdbbucket/hnzy/20250412/plateName/17444643281127352.null')
 	const isCrop = ref(false)
 	const lineWidth = ref(10)
 	const lineColor = ref('#000000')
 	const bgColor = ref('')
 	const props = defineProps(['image'])
 	// eslint-disable-next-line vue/no-setup-props-destructure
-	resultImg.value = props.image
+	//resultImg.value = props.image
 	const emit = defineEmits({ successful: null })
 	const recordId = ref()
 	const show = (id) => {
 		visible.value = true
 		recordId.value = id
+		handleReset()
 	}
 	const handleReset = () => {
 		esignRef.value.reset()
-		resultImg.value = ''
+		resultImg.value = 'https://db.js-whzl.com:8055/preview/zhdbbucket/hnzy/20250412/plateName/17444643281127352.null'
 	}
 	const handleGenerate = () => {
 		esignRef.value

+ 7 - 0
snowy-admin-web/src/views/biz/bizaccessrecord/detail.vue

@@ -56,6 +56,7 @@
 
 <script setup name="recordDoubleForm">
 	import { cloneDeep } from 'lodash-es'
+	import sysConfig from "@/config";
 	// 默认是关闭状态
 	const visible = ref(false)
 	const formData = ref({})
@@ -80,6 +81,12 @@
 		if(record){
 			let recordData = cloneDeep(record)
 			formData.value = Object.assign({}, recordData)
+			if(formData.value.cloudPlateName.includes("http://db.js-whzl.com:8065")){
+				formData.value.cloudPlateName = formData.value.cloudPlateName.replace("http://db.js-whzl.com:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.cloudLicenseName.includes("http://db.js-whzl.com:8065")){
+				formData.value.cloudLicenseName = formData.value.cloudLicenseName.replace("http://db.js-whzl.com:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
 		}
 
 	}

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

@@ -5,7 +5,9 @@
 				<a-descriptions-item label="订单编号" :span="2">{{ formData.orderNumber }}</a-descriptions-item>
 				<a-descriptions-item label="订单名称" :span="2">{{ formData.orderName }}</a-descriptions-item>
 				<a-descriptions-item label="车牌号" :span="2">{{ formData.licenseNumber }}</a-descriptions-item>
-				<a-descriptions-item label="提货时段" :span="2">{{ formData.beginTime + '~' + formData.endTime }}</a-descriptions-item>
+				<a-descriptions-item label="车辆轴数" :span="2">{{ formData.axleNumber+'轴' }}</a-descriptions-item>
+				<a-descriptions-item label="提货开始时间" :span="2">{{ formData.beginTime }}</a-descriptions-item>
+				<a-descriptions-item label="提货结束时间" :span="2">{{formData.endTime }}</a-descriptions-item>
 				<a-descriptions-item label="客户名称" :span="2">{{ formData.customerName }}</a-descriptions-item>
 				<a-descriptions-item label="联系人" :span="2">{{ formData.customerContactName }}</a-descriptions-item>
 				<a-descriptions-item label="货品名称" :span="2">{{ formData.goodsName }}</a-descriptions-item>
@@ -48,7 +50,16 @@
 						{{ $TOOL.dictTypeData('appointment_status', formData.status) }}
 					</a-tag>
 				</a-descriptions-item>
-				<a-descriptions-item label="审核备注" :span="2">{{ formData.appointmentReason }}</a-descriptions-item>
+				<a-descriptions-item label="审核备注" :span="4">{{ formData.appointmentReason }}</a-descriptions-item>
+				<a-descriptions-item label="司机确认" :span="4">
+					<a-image :width="200" :src="formData.driverSign" />
+				</a-descriptions-item>
+				<a-descriptions-item label="卸货重量(吨)" :span="4">{{ formData.unloadWeight }}</a-descriptions-item>
+				<a-descriptions-item label="司机回签" :span="4">
+					<div v-for="(item,index) in fileList " :key="item.value">
+						<a-image :width="200" :src="item.url" />
+					</div>
+				</a-descriptions-item>
 			</a-descriptions>
 		</a-form>
 	</xn-form-container>
@@ -56,6 +67,7 @@
 
 <script setup name="recordDoubleForm">
 	import { cloneDeep } from 'lodash-es'
+	import sysConfig from "@/config";
 	// 默认是关闭状态
 	const visible = ref(false)
 	const formData = ref({})
@@ -73,6 +85,7 @@
 	const labelCol8 = ref({span: 8, style: 'width: 26%; line-height: 20px; white-space: normal',})
 	const wrapperCol20 = ref({span: 20})
 
+	const fileList = ref([])
 	// 打开抽屉
 	const onOpen = (record) => {
 		visible.value = true
@@ -80,6 +93,15 @@
 		if(record){
 			let recordData = cloneDeep(record)
 			formData.value = Object.assign({}, recordData)
+			fileList.value = []
+			if(formData.value.unloadImg!=null){
+				for (var i=0;i<formData.value.unloadImg.split(',').length;i++){
+					fileList.value.push({
+						name: formData.value.unloadName.split(',')[i],
+						url:sysConfig.PREVIEW_PATH + formData.value.unloadImg.split(',')[i]
+					})
+				}
+			}
 		}
 
 	}

+ 77 - 14
snowy-admin-web/src/views/biz/bizappointmentrecord/index.vue

@@ -87,8 +87,18 @@
 						<p style="margin-bottom: 0">编号:{{ record.orderNumber }}</p>
 					</div>
 				</template>
+				<template v-if="column.dataIndex === 'carInfo'">
+					<div class="time-list">
+						<p>车牌号:{{ record.licenseNumber }}</p>
+						<p style="margin-bottom: 0">车轴数:{{ record.axleNumber + '轴' }}</p>
+					</div>
+				</template>
 				<template v-if="column.dataIndex === 'timeInfo'">
-					<span>{{record.beginTime + '~' + record.endTime}}</span>
+<!--					<span>{{record.beginTime + '~' + record.endTime}}</span>-->
+					<div class="time-list">
+						<p>开始时间:{{ record.beginTime }}</p>
+						<p style="margin-bottom: 0">结束时间:{{ record.endTime }}</p>
+					</div>
 				</template>
 				<template v-if="column.dataIndex === 'customerInfo'">
 					<span>{{record.customerName}}</span>
@@ -105,6 +115,9 @@
 						<p style="margin-bottom: 0">规格:{{ record.goodsModel }}</p>
 					</div>
 				</template>
+				<template v-if="column.dataIndex === 'axleNumber'">
+					{{record.axleNumber+'轴'}}
+				</template>
 				<template v-if="column.dataIndex === 'status'">
 					<a-tag
 						:color="
@@ -160,12 +173,19 @@
 									<a-menu-item v-if="hasPerm('bizAppointmentAudit') && (record.status == '1')">
 										<a style="color: #ffaa00" @click="reviewRef.showModal(record.id)">审核</a>
 									</a-menu-item>
-									<a-menu-item v-if="hasPerm('bizAppointmentRecordEdit') && (record.status == '1' || record.status == '2')">
+									<a-menu-item v-if="hasPerm('bizAppointmentRecordEdit') && (record.status == '2')">
 										<a style="color:blue" @click="formRef.onOpen(record)" >编辑</a>
 									</a-menu-item>
-									<a-menu-item v-if="hasPerm('bizAppointmentRecordDelete') && (record.status == '1' || record.status == '2')">
+									<a-menu-item v-if="hasPerm('bizAppointmentRecordDelete') && (record.status == '2')">
 										<a style="color:red" type="link" danger size="small" @click="deleteConfig(record)">删除</a>
 									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizAppointmentDriverConfim') && record.status == '8'">
+										<a @click="XnSignNameRef.show(record.recordId)" >确认</a>
+									</a-menu-item>
+									<a-menu-item v-if="hasPerm('bizAppointmentDriverSign') && record.status=='10' && record.orderType=='1'">
+										<a  @click="signRef.onOpen(record)" >回签</a>
+									</a-menu-item>
+
 
 								</a-menu>
 							</template>
@@ -178,8 +198,9 @@
 	<Form ref="formRef" @successful="tableRef.refresh()" />
 	<Review ref="reviewRef" @successful="tableRef.refresh(true)" />
 	<Detail ref="detailRef" @successful="tableRef.refresh()" />
+	<Sign ref="signRef" @successful="tableRef.refresh(true)" />
 
-
+	<XnSignName ref="XnSignNameRef" :image="searchFormState.driverSign" @successful="signSuccess" />
 	<a-modal v-model:visible="open" title="二维码" width="600px" style="height: 700px">
 		<div id="qrcode" style="text-align: center; margin:  15px 5px 15px 5px">
 			<a-row>
@@ -218,15 +239,20 @@
 	import QRCode from 'qrcode'
 	import html2canvas from 'html2canvas'
 	import downloadUtil from '@/utils/downloadUtil'
+	import bizRecordApi from '@/api/biz/bizRecordApi'
+	import Sign from './sign.vue'
+	import bizOrderApi from "@/api/biz/bizOrderApi";
 
 	const submitLoading = ref(false)
 	const tableRef = ref()
+	const signRef = ref()
 	const formRef = ref()
 	const reviewRef = ref()
 	const detailRef = ref()
 	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
 
 	const nowRecord = ref()
+	const XnSignNameRef = ref()
 
 	//查询数据
 	const searchFormState = ref({})
@@ -243,7 +269,7 @@
 		{
 			title: '订单信息',
 			dataIndex: 'orderInfo',
-			width:230
+			width:200
 		},
 		{
 			title: '车牌号',
@@ -252,32 +278,38 @@
 			align: 'center'
 		},
 		{
-			title: '提货时',
+			title: '提货时',
 			dataIndex: 'timeInfo',
 			align:'center',
-			width:360
+			width:200
 		},
 		{
-			title: '客户信息',
+			title: '客户名称',
 			dataIndex: 'customerInfo',
 			align:'center',
-			width:200
+			width:180
 		},
 		{
 			title: '货品信息',
 			dataIndex: 'goodsInfo',
-			width:180
+			width:160
 		},
 		{
 			title: '司机信息',
 			dataIndex: 'driverInfo',
-			width: 180
+			width: 160
+		},
+		{
+			title: '车辆轴数',
+			dataIndex: 'axleNumber',
+			width: 110,
+			align:'center'
 		},
 		{
 			title: '状态',
 			dataIndex: 'status',
 			align: 'center',
-			width:120
+			width:130
 		},
 	]
 	// 操作栏通过权限判断是否显示
@@ -285,7 +317,8 @@
 		title: '操作',
 		dataIndex: 'action',
 		align: 'center',
-		width: 150
+		width: 150,
+
 	})
 
 	const selectedRowKeys = ref([])
@@ -429,9 +462,39 @@
 
 	//导出
 	const exportTotal = () => {
-		const searchFormParam = cloneDeep(searchFormState.value)
+		/*const searchFormParam = cloneDeep(searchFormState.value)
 		bizAppointmentRecordApi.exportRecord(Object.assign(searchFormParam)).then((res)=>{
 			downloadUtil.resultDownload(res)
+		})*/
+		Modal.confirm({
+			title: '确定要导出记录吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				const searchFormParam = cloneDeep(searchFormState.value)
+
+				bizAppointmentRecordApi
+					.exportRecord(Object.assign(searchFormParam))
+					.then((res) => {
+						downloadUtil.resultDownload(res)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+
+	// 签名板组件回调
+	const signSuccess = (value) => {
+		const param = {
+			id:value.id,
+			driverSign: value.value
+		}
+		bizRecordApi.updateDriverSign(param).then(() => {
+			tableRef.value.refresh(true)
 		})
 	}
 </script>

+ 159 - 0
snowy-admin-web/src/views/biz/bizappointmentrecord/sign.vue

@@ -0,0 +1,159 @@
+<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="unloadWeight">
+				<a-input-number v-model:value="formData.unloadWeight" style="width:90%"  :precision="2" :min="1" :max="999999"  placeholder="请输入卸货重量" allow-clear /><span style="margin-left:10px;">吨</span>
+			</a-form-item>
+<!--			<a-form-item label="单据图片:" name="licensePlate">
+				<a-input v-model:value="formData.licensePlate" placeholder="请输入车牌号码" allow-clear />
+			</a-form-item>-->
+			<a-form-item label="上传图片:" name="filePathList" :rules="[{ required: true, message: '请上传图片' }]">
+				<a-upload
+					v-model:file-list="fileList"
+					class="avatar-uploader"
+					list-type="picture"
+					:show-upload-list="true"
+					:custom-request="customRequest"
+					:remove="file => removeOtherFile(file,index)"
+					:before-upload="beforeUpload"
+					accept="image/png, image/jpeg, image/jpg"
+
+				>
+					<a-button>
+						<upload-outlined></upload-outlined>
+						upload
+					</a-button>
+				</a-upload>
+			</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="bizRecordForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import bizRecordApi from '@/api/biz/bizRecordApi'
+	import fileApi from '@/api/dev/fileApi'
+	import sysConfig from "@/config";
+	import {message, Modal, Upload } from 'ant-design-vue';
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({filePathList:[],fileNameList:[]})
+	const submitLoading = ref(false)
+
+	//设置表单样式
+	const labelCol = ref({ span: 5})
+	const wrapperCol = ref({ span: 16})
+
+	const fileList = ref([])
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+			formData.value.id = record.recordId
+			formData.value.filePathList = []
+			formData.value.fileNameList = []
+			fileList.value = []
+			if(formData.value.unloadImg!=null){
+				for (var i=0;i<formData.value.unloadImg.split(',').length;i++){
+					fileList.value.push({
+						name: formData.value.unloadName.split(',')[i],
+						url:sysConfig.PREVIEW_PATH + formData.value.unloadImg.split(',')[i]
+					})
+					formData.value.filePathList.push(formData.value.unloadImg.split(",")[i])
+					formData.value.fileNameList.push(formData.value.unloadName.split(",")[i])
+				}
+			}
+		}
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		formData.value.fileNameList = []
+		formData.value.filePathList = []
+		fileList.value = []
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		unloadWeight: [required('请输入卸货重量')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				console.log("formData:"+formDataParam.filePahList)
+				bizRecordApi
+					.updateWeight(formDataParam)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+
+	const customRequest = (data) => {
+		console.log("data:"+JSON.stringify(data.file.name))
+		//保存图片
+		const fileData = new FormData()
+		fileData.append('file', data.file)
+		fileApi
+			.uploadImgMap(fileData)
+			.then((result) => {
+				formData.value.filePathList.push(result.imageFile)
+				formData.value.fileNameList.push(data.file.name)
+			}).finally(()=>{
+			data.onSuccess()
+		})
+
+	}
+
+	//文件删除
+	const removeOtherFile = (file) => {
+		fileList.value.forEach((item,index)=>{
+			console.log(item.name+"======="+file.name)
+			if(item.name === file.name){
+
+				fileList.value.splice(index, 1);
+				formData.value.filePathList.splice(index,1)
+				formData.value.fileNameList.splice(index,1)
+			}
+		})
+	}
+
+	const beforeUpload = (file) => {
+		const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
+		if (!isJpgOrPng) {
+			message.error('请上传JPG/PNG格式的图片!')
+		}
+		return isJpgOrPng || Upload.LIST_IGNORE
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 4 - 0
snowy-admin-web/src/views/biz/bizconfig/form.vue

@@ -19,6 +19,9 @@
 			<a-form-item label="装卸损耗预警值:" name="lossWarn">
 				<a-input-number v-model:value="formData.lossWarn" style="width:90%"  :precision="0" :min="1" :max="99999" placeholder="请输入装卸损耗预警值" allow-clear /><span style="margin-left:10px;">%</span>
 			</a-form-item>
+			<a-form-item label="预约申请数量:" name="applyCount">
+				<a-input-number v-model:value="formData.applyCount" style="width:90%"  :precision="0" :min="1" :max="99999" placeholder="请输入预约申请数量" allow-clear /><span style="margin-left:10px;">个</span>
+			</a-form-item>
 			<a-form-item label="预约审核开关:" name="auditSwitch">
 				<a-radio-group button-style="solid" v-model:value="formData.auditSwitch">
 					<a-radio-button value="1">
@@ -100,6 +103,7 @@
 		orderWeightSwitch: [required('请输入订单重量校验开关(1:开启   2:关闭)')],
 		accessControlSwitch: [required('请输入门禁强制校验开关')],
 		lossWarn: [required('请输入装卸损耗预警值')],
+		applyCount: [required('请输入预约申请数量')],
 	}
 	// 验证并提交数据
 	const onSubmit = () => {

+ 8 - 0
snowy-admin-web/src/views/biz/bizconfig/index.vue

@@ -44,6 +44,9 @@
 				<template v-if="column.dataIndex === 'lossWarn'">
 					{{record.lossWarn}}%
 				</template>
+				<template v-if="column.dataIndex === 'applyCount'">
+					{{record.applyCount}}个
+				</template>
 			</template>
 		</s-table>
 	</a-card>
@@ -99,6 +102,11 @@
 			dataIndex: 'lossWarn',
 			align:'center'
 		},
+		{
+			title: '预约申请数量',
+			dataIndex: 'applyCount',
+			align:'center'
+		},
 	]
 	// 操作栏通过权限判断是否显示
 	columns.push({

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

@@ -53,6 +53,8 @@
 				<a-descriptions-item label="签名" :span="4">
 					<a-image v-if="formData.orderSign != null" :width="200" :src="formData.orderSign" />
 				</a-descriptions-item>
+				<a-descriptions-item label="结束备注" :span="4">{{ formData.endReason}}</a-descriptions-item>
+				<a-descriptions-item label="审核备注" :span="4">{{ formData.orderReason}}</a-descriptions-item>
 			</a-descriptions>
 		</a-form>
 	</xn-form-container>

+ 64 - 0
snowy-admin-web/src/views/biz/bizorder/end.vue

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

+ 23 - 4
snowy-admin-web/src/views/biz/bizorder/flow.vue

@@ -1,5 +1,5 @@
 <template>
-	<xn-form-container title="流水" :width="1200" :visible="visible" :destroy-on-close="true" @close="onClose">
+	<xn-form-container title="流水" :width="1300" :visible="visible" :destroy-on-close="true" @close="onClose">
 		<s-table
 			ref="tableRef"
 			:columns="columns"
@@ -81,19 +81,29 @@
 						<p style="margin-bottom: 0">编号:{{ record.orderNumber }}</p>
 					</div>
 				</template>
+
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a @click="detailRef.onOpen(record)">详情</a>
+					</a-space>
+				</template>
 			</template>
 		</s-table>
 	</xn-form-container>
+
+	<Detail ref="detailRef" />
 </template>
 
 <script setup name="recordDoubleForm">
 	import { cloneDeep } from 'lodash-es'
 	import bizRecordApi from "@/api/biz/bizRecordApi";
+	import Detail from "@/views/biz/record/detail.vue";
 	// 默认是关闭状态
 	const visible = ref(false)
 	const formData = ref({})
 	const table = ref()
 	const resultJson = ref()
+	const detailRef = ref()
 
 	const labelStyle = {
 		width: '20%'
@@ -125,7 +135,7 @@
 			width: '130px'
 		},
 		{
-			title: '重量(KG)',
+			title: '重量()',
 			dataIndex: 'weight',
 			align: 'center'
 		},
@@ -134,8 +144,9 @@
 			dataIndex: 'orderInfo'
 		},
 		{
-			title: '收发货单位',
-			dataIndex: 'company'
+			title: '客户名称',
+			dataIndex: 'customerName',
+			align:'center'
 		},
 		{
 			title: '货品',
@@ -148,6 +159,14 @@
 		}
 	]
 
+	// 操作栏通过权限判断是否显示
+	columns.push({
+		title: '操作',
+		dataIndex: 'action',
+		align: 'center',
+		width: 150
+	})
+
 	const orderId = ref()
 	// 打开抽屉
 	const onOpen = (record) => {

+ 25 - 13
snowy-admin-web/src/views/biz/bizorder/form.vue

@@ -21,7 +21,7 @@
 						  :options="customerIdList" @change="onChangeCustomer"
 				> </a-select>
 			</a-form-item>
-			<a-form-item label="订单信息:" name="saleOrderInfo">
+			<a-form-item label="销售订单信息:" name="saleOrderInfo">
 				<a-select v-model:value="formData.saleOrderInfo" placeholder="请选择订单信息"
 						  :options="saleOrderInfoList" @change="onChangeSaleOrder"
 				> </a-select>
@@ -37,7 +37,7 @@
 				> </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-input-number v-model:value="formData.orderWeight" style="width:90%"  :precision="2" :min="1" :max="999999"  placeholder="请输入订单重量" allow-clear /><span style="margin-left:10px;">吨</span>
 			</a-form-item>
 		</a-form>
 		<template #footer>
@@ -55,6 +55,7 @@
 	import bizGoodsApi from '@/api/biz/bizGoodsApi'
 	import customerApi from '@/api/biz/customerApi'
 	import goodsConfApi from '@/api/biz/goodsConfApi'
+	import bizSaleOrderApi from "@/api/biz/bizSaleOrderApi";
 	// 抽屉状态
 	const open = ref(false)
 	const emit = defineEmits({ successful: null })
@@ -91,7 +92,7 @@
 			})
 		})
 
-		if(formData.value.customerId){
+		/*if(formData.value.customerId){
 			customerApi.getOrderByCustomerId({id:formData.value.customerId}).then((res)=>{
 				saleOrderInfoList.value = res.orderList.map((item)=>{
 					return{
@@ -100,6 +101,16 @@
 					}
 				})
 			})
+		}*/
+		if(formData.value.customerId){
+			bizSaleOrderApi.queryByCustomerId({id:formData.value.customerId,flag:formData.value.id?"edit":"add"}).then((res)=>{
+				saleOrderInfoList.value = res.map((item)=>{
+					return{
+						value:item.id,
+						label:item.saleOrderName
+					}
+				})
+			})
 		}
 
 		if(formData.value.saleOrderInfo){
@@ -119,11 +130,11 @@
 	const onChangeCustomer =(value)=>{
 		formData.value.saleOrderInfo = ''
 		formData.value.deliveryTimeId = ''
-		customerApi.getOrderByCustomerId({id:value}).then((res)=>{
-			saleOrderInfoList.value = res.orderList.map((item)=>{
+		bizSaleOrderApi.queryByCustomerId({id:formData.value.customerId,flag:formData.value.id?"edit":"add"}).then((res)=>{
+			saleOrderInfoList.value = res.map((item)=>{
 				return{
-					value:item.orderName+'-'+item.orderNumber+'-'+item.goodsName+'-'+item.orderWeight+'-'+item.orderType,
-					label:item.orderName
+					value:item.id,
+					label:item.saleOrderName
 				}
 			})
 		})
@@ -131,12 +142,13 @@
 
 	//订单点击时间
 	const onChangeSaleOrder = (value) =>{
-		formData.value.orderName = value.split('-')[0]
-		formData.value.orderNumber= value.split('-')[1]
-		formData.value.goodsName = value.split('-')[2]
-		formData.value.orderWeight = value.split('-')[3]
-		formData.value.orderType = value.split('-')[4]
-
+		bizSaleOrderApi.detailById({id:value}).then((res)=>{
+			formData.value.orderName = res.saleOrderName
+			formData.value.orderNumber= res.saleOrderNumber
+			formData.value.goodsName = res.saleGoodsName
+			formData.value.orderWeight = res.saleOrderWeight
+			formData.value.orderType = res.saleOrderType
+		})
 		formData.value.deliveryTimeId = ''
 		//根据货品名称和重量查询提货时间段
 		goodsConfApi.getList({goodsName:value.split('-')[2],needWeight:value.split('-')[3]}).then((res)=>{

+ 66 - 14
snowy-admin-web/src/views/biz/bizorder/index.vue

@@ -133,8 +133,7 @@
 
 					<a-divider type="vertical" v-if="record.orderStatus == '3' || record.orderStatus == '4'"/>
 
-					<a-dropdown v-if="(hasPerm('bizOrderEdit')) || (hasPerm('bizOrderDelete'))
-						">
+					<a-dropdown>
 						<a class="ant-dropdown-link">
 							更多
 							<DownOutlined />
@@ -145,11 +144,14 @@
 								<a-menu-item>
 									<a size="small" type="link" @click="detailRef.onOpen(record)" >详情</a>
 								</a-menu-item>
-								<a-menu-item v-if="hasPerm('bizOrderEdit') && (record.orderStatus == '1' || record.orderStatus == '2')">
+								<a-menu-item  v-if="hasPerm('bizOrderSubmit') && record.orderStatus=='0'">
+									<a style="color:orangered" size="small" type="link" @click="submit(record.id)">提交</a>
+								</a-menu-item>
+								<a-menu-item v-if="hasPerm('bizOrderEdit') && (record.orderStatus == '0')">
 									<a style="color:blue" size="small" type="link" @click="formRef.onOpen(record)" >编辑</a>
 								</a-menu-item>
 
-								<a-menu-item v-if="hasPerm('bizOrderDelete') && (record.orderStatus == '1' || record.orderStatus == '2')">
+								<a-menu-item v-if="hasPerm('bizOrderDelete') && (record.orderStatus == '0')">
 									<a style="color:red" size="small" type="link" @click="deleteConfig(record)">删除</a>
 								</a-menu-item>
 
@@ -169,7 +171,7 @@
 									<a style="color:green" @click="reviewRef.showModal(record.id)">审核</a>
 								</a-menu-item>
 
-								<a-menu-item v-if="hasPerm('bizOrderFlow')">
+								<a-menu-item v-if="hasPerm('bizOrderFlow') && (record.orderStatus == '4' || record.orderStatus=='5' || record.orderStatus=='6' || record.orderStatus=='7')">
 									<a style="color:deepskyblue" @click="flowRef.onOpen(record)">流水</a>
 								</a-menu-item>
 
@@ -177,8 +179,8 @@
 									<a style="color:forestgreen" @click="showMore(record)">配置</a>
 								</a-menu-item>
 
-								<a-menu-item v-if="hasPerm('bizOrderEnd') && (record.orderStatus != '5' && record.orderStatus != '6' && record.orderStatus != '7')">
-									<a style="color:red" @click="endOrder(record)">结束</a>
+								<a-menu-item v-if="hasPerm('bizOrderEnd') && (record.orderStatus == '3' || record.orderStatus == '4')">
+									<a style="color:red" @click="endRef.showModal(record.id)">结束</a>
 								</a-menu-item>
 							</a-menu>
 						</template>
@@ -198,7 +200,8 @@
 	<Detail ref="detailRef" @successful="tableRef.refresh()" />
 	<Flow ref="flowRef" @successful="tableRef.refresh()" />
 	<Review ref="reviewRef" @successful="tableRef.refresh(true)" />
-	<XnSignName ref="XnSignNameRef" :image="searchFormState.orderSign" @successful="signSuccess" />
+	<End ref="endRef" @successful="tableRef.refresh(true)" />
+	<XnSignName ref="XnSignNameRef" @successful="signSuccess" />
 
 
 	<a-modal v-model:visible="open" title="二维码" width="600px" style="height: 700px">
@@ -246,18 +249,18 @@
 		@cancel="onCloseAccount"
 	>
 		<a-card :bordered="false">
-			<a-button type="primary" @click="addAccount()" style="margin-bottom:10px;">
+<!--			<a-button type="primary" @click="addAccount()" style="margin-bottom:10px;">
 				<template #icon><plus-outlined /></template>
 				新增
-			</a-button>
+			</a-button>-->
 			<a-table ref="tableRef" :columns="columns1" :data-source="data1" bordered :row-key="(record) => record.id">
 				<template #bodyCell="{ column, record }">
 					<template v-if="column.dataIndex === 'action'">
 						<a @click="editAccount(record)">编辑</a>
-						<a-divider type="vertical" />
+<!--						<a-divider type="vertical" />
 						<a-popconfirm title="确定要删除吗?" @confirm="removeUser(record)">
 							<a-button type="link" danger size="small">删除</a-button>
-						</a-popconfirm>
+						</a-popconfirm>-->
 					</template>
 					<template v-if="column.dataIndex === 'remain'">
 						{{record.applyNumber-record.applyNumberAlready}}
@@ -308,6 +311,7 @@
 	import Flow from './flow.vue'
 	import bizOrderConfigApi from "@/api/biz/bizOrderConfigApi";
 	import { required } from '@/utils/formRules'
+	import End from './end.vue'
 
 	const editAccountFlag = ref(false)
 	const moreFlag = ref(false)
@@ -319,6 +323,7 @@
 	const configRef = ref()
 	const flowRef = ref()
 	const reviewRef = ref()
+	const endRef = ref()
 	const detailRef = ref()
 	const XnSignNameRef = ref()
 	const submitLoading = ref(false)
@@ -467,6 +472,32 @@
 			onCancel() {}
 		})
 	}
+
+	//提交
+	const submit = (id) =>{
+		Modal.confirm({
+			title: '提示',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '是否提交该数据?',
+			onOk() {
+				submitLoading.value = true
+				let params =
+					{
+						id: id
+					}
+
+				bizOrderApi
+					.submit(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
 	// 删除
 	const deleteBizOrder = (record) => {
 		let params = [
@@ -525,7 +556,8 @@
 	const getQrCode = (record) => {
 		//QRCode.toDataURL("id:"+record.id+"saleCode:"+record.saleCode, {
 		let param = {
-			id:record.id
+			id:record.id,
+			orderName:record.orderName
 		}
 		QRCode.toDataURL(JSON.stringify(param), {
 			errorCorrectionLevel: 'H',
@@ -603,9 +635,29 @@
 
 	//导出
 	const exportTotal = () => {
-		const searchFormParam = cloneDeep(searchFormState.value)
+		/*const searchFormParam = cloneDeep(searchFormState.value)
 		bizOrderApi.exportRecord(Object.assign(searchFormParam)).then((res)=>{
 			downloadUtil.resultDownload(res)
+		})*/
+
+		Modal.confirm({
+			title: '确定要导出记录吗?',
+			icon: createVNode(ExclamationCircleOutlined),
+			content: '',
+			onOk() {
+				submitLoading.value = true
+				const searchFormParam = cloneDeep(searchFormState.value)
+
+				bizOrderApi
+					.exportRecord(Object.assign(searchFormParam))
+					.then((res) => {
+						downloadUtil.resultDownload(res)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
 		})
 	}
 

+ 18 - 9
snowy-admin-web/src/views/biz/bizqueuerecord/index.vue

@@ -88,7 +88,10 @@
 					</div>
 				</template>
 				<template v-if="column.dataIndex === 'timeInfo'">
-					<span>{{record.beginTime + '~' + record.endTime}}</span>
+					<div class="time-list">
+						<p>开始时间:{{ record.beginTime }}</p>
+						<p style="margin-bottom: 0">结束时间:{{ record.endTime }}</p>
+					</div>
 				</template>
 				<template v-if="column.dataIndex === 'customerInfo'">
 					<span>{{record.customerName}}</span>
@@ -181,7 +184,7 @@
 	//查询数据
 	const searchFormState = ref({appointmentFlag:'1'})
 	const searchFormRef = ref()
-	const statusList = tool.dictList('appointment_status')
+	const statusList = tool.dictList('queue_status')
 
 	// 查询区域显示更多控制
 	const advanced = ref(false)
@@ -193,7 +196,7 @@
 		{
 			title: '订单信息',
 			dataIndex: 'orderInfo',
-			width:230
+			width:200
 		},
 		{
 			title: '车牌号',
@@ -202,26 +205,32 @@
 			align: 'center'
 		},
 		{
-			title: '提货时',
+			title: '提货时',
 			dataIndex: 'timeInfo',
 			align:'center',
-			width:360
+			width:200
 		},
 		{
-			title: '客户信息',
+			title: '客户名称',
 			dataIndex: 'customerInfo',
 			align:'center',
-			width:200
+			width:180
 		},
 		{
 			title: '货品信息',
 			dataIndex: 'goodsInfo',
-			width:180
+			width:160
 		},
 		{
 			title: '司机信息',
 			dataIndex: 'driverInfo',
-			width: 180
+			width: 160
+		},
+		{
+			title: '排队号',
+			dataIndex: 'queueNumber',
+			width: 110,
+			align:'center'
 		},
 		{
 			title: '状态',

+ 136 - 0
snowy-admin-web/src/views/biz/bizsaleorder/form.vue

@@ -0,0 +1,136 @@
+<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="saleOrderNumber">
+				<a-input v-model:value="formData.saleOrderNumber" placeholder="请输入销售订单编号" allow-clear />
+			</a-form-item>
+			<a-form-item label="订单名称:" name="saleOrderName">
+				<a-input v-model:value="formData.saleOrderName" placeholder="请输入销售订单名称" allow-clear />
+			</a-form-item>
+			<a-form-item label="客户信息:" name="customerId">
+				<a-select v-model:value="formData.customerId" placeholder="请选择客户信息"
+						  :options="customerIdList"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="订单类型:" name="saleOrderType">
+				<a-radio-group button-style="solid" v-model:value="formData.saleOrderType">
+					<a-radio-button value="1">
+						常规订单
+					</a-radio-button>
+					<a-radio-button value="2">
+						服务订单
+					</a-radio-button>
+				</a-radio-group>
+			</a-form-item>
+			<a-form-item label="货品信息:" name="saleGoodsCode">
+<!--				<a-input v-model:value="formData.saleGoodsName" placeholder="请输入货品名称" allow-clear />-->
+				<a-select v-model:value="formData.saleGoodsCode" placeholder="请选择货品信息"
+						  :options="saleGoodsCodeList"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="订单重量:" name="saleOrderWeight">
+				<a-input-number v-model:value="formData.saleOrderWeight" 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="bizSaleOrderForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import bizSaleOrderApi from '@/api/biz/bizSaleOrderApi'
+	import customerApi from '@/api/biz/customerApi'
+	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 customerIdList = ref()
+	const saleGoodsCodeList = ref()
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}else{
+			formData.value.saleOrderType = '1'
+		}
+
+		//查询客户信息
+		customerApi.getList().then((res)=>{
+			customerIdList.value = res.map((item)=>{
+				return{
+					value:item.id,
+					label:item.name
+				}
+			})
+		})
+		//查询货品信息
+		bizGoodsApi.getList().then((res)=>{
+			saleGoodsCodeList.value = res.map((item)=>{
+				return{
+					value:item.goodsCode,
+					label:item.goodsName+'-'+item.goodsCode
+				}
+			})
+		})
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		saleOrderNumber: [required('请输入销售订单编号')],
+		saleOrderName: [required('请输入销售订单名称')],
+		saleOrderType: [required('请选择订单类型')],
+		saleGoodsCode: [required('请选择货品信息')],
+		saleOrderWeight: [required('请输入销售订单重量')],
+		customerId: [required('请选择客户信息')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				bizSaleOrderApi
+					.bizSaleOrderSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 237 - 0
snowy-admin-web/src/views/biz/bizsaleorder/index.vue

@@ -0,0 +1,237 @@
+<template>
+	<a-card :bordered="false" style="margin-bottom: 10px" class="mb-2">
+		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
+			<a-row :gutter="24">
+				<a-col :span="6">
+					<a-form-item label="订单编号" name="saleOrderNumber">
+						<a-input v-model:value="searchFormState.saleOrderNumber" placeholder="订单编号查询" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="订单名称" name="saleOrderName">
+						<a-input v-model:value="searchFormState.saleOrderName" placeholder="订单名称查询" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="订单类型" name="saleOrderType">
+						<a-select v-model:value="searchFormState.saleOrderType" placeholder="订单类型查询"
+								  :options="orderTypeList"
+						> </a-select>
+					</a-form-item>
+				</a-col>
+
+				<template v-if="advanced">
+					<a-col :span="6">
+						<a-form-item label="货品名称" name="saleGoodsName">
+							<a-input v-model:value="searchFormState.saleGoodsName" placeholder="货品名称查询" />
+						</a-form-item>
+					</a-col>
+				</template>
+				<a-col :span="6">
+					<a-button type="primary" @click="tableRef.refresh()">查询</a-button>
+					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
+					<a @click="toggleAdvanced" style="margin-left: 8px">
+						{{ advanced ? '收起' : '展开' }}
+						<component :is="advanced ? 'up-outlined' : 'down-outlined'" />
+					</a>
+				</a-col>
+			</a-row>
+		</a-form>
+	</a-card>
+	<a-card :bordered="false">
+		<s-table
+			ref="tableRef"
+			:columns="columns"
+			:data="loadData"
+			bordered
+			:row-key="(record) => record.id"
+		>
+			<template #operator class="table-operator">
+				<a-space>
+					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizSaleOrderAdd')">
+						<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('bizSaleOrderEdit') && record.saleStatus == '1'">编辑</a>
+						<a-divider type="vertical" v-if="hasPerm(['bizSaleOrderEdit', 'bizSaleOrderDelete'], 'and') && (record.saleStatus == '1' || record.saleStatus == '3')" />
+						<a-button style="color:red" type="link" danger size="small" v-if="hasPerm('bizSaleOrderDelete') && (record.saleStatus == '1' || record.saleStatus == '3')" @click="deleteConfig(record)">删除</a-button>
+					</a-space>
+				</template>
+				<template v-if="column.dataIndex === 'saleOrderType'">
+					<a-tag
+						:color="
+							record.saleOrderType === '1'
+								? 'orange'
+								: record.saleOrderType === '2'
+								  ? 'green'
+								  : 'purple'
+						"
+					>
+						{{ $TOOL.dictTypeData('order_type', record.saleOrderType) }}
+					</a-tag>
+				</template>
+				<template v-if="column.dataIndex === 'saleStatus'">
+					<a-tag
+						:color="
+							record.saleStatus === '1'
+								? 'processing'
+								: record.saleStatus === '2'
+								  ? 'volcano'
+								  : 'red'
+						"
+					>
+						{{ $TOOL.dictTypeData('sale_order_status', record.saleStatus) }}
+					</a-tag>
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="tableRef.refresh()" />
+</template>
+
+<script setup name="bizsaleorder">
+	import { cloneDeep } from 'lodash-es'
+	import Form from './form.vue'
+	import bizSaleOrderApi from '@/api/biz/bizSaleOrderApi'
+	import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
+	import {Modal} from 'ant-design-vue';
+	import {createVNode} from 'vue';
+	import tool from '@/utils/tool'
+
+	const tableRef = ref()
+	const formRef = ref()
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+	const submitLoading = ref(false)
+
+	//查询数据
+	const searchFormState = ref({})
+	const searchFormRef = ref()
+	// 查询区域显示更多控制
+	const advanced = ref(false)
+	const toggleAdvanced = () => {
+		advanced.value = !advanced.value
+	}
+	const orderTypeList = tool.dictList('order_type')
+
+	const columns = [
+		{
+			title: '订单编号',
+			dataIndex: 'saleOrderNumber',
+			align:'center'
+		},
+		{
+			title: '订单名称',
+			dataIndex: 'saleOrderName',
+			align:'center'
+		},
+		{
+			title: '订单类型',
+			dataIndex: 'saleOrderType',
+			align:'center'
+		},
+		{
+			title: '客户名称',
+			dataIndex: 'customerName',
+			align:'center'
+		},
+		{
+			title: '货品名称',
+			dataIndex: 'saleGoodsName',
+			align:'center'
+		},
+		{
+			title: '订单重量(吨)',
+			dataIndex: 'saleOrderWeight',
+			align:'center'
+		},
+		{
+			title: '状态',
+			dataIndex: 'saleStatus',
+			align:'center'
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	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 bizSaleOrderApi.bizSaleOrderPage(Object.assign(parameter, searchFormParam)).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		tableRef.value.refresh(true)
+	}
+	// 删除
+	const deleteBizSaleOrder = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		bizSaleOrderApi.bizSaleOrderDelete(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
+					}
+				]
+
+				bizSaleOrderApi
+					.bizSaleOrderDelete(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+	// 批量删除
+	const deleteBatchBizSaleOrder = (params) => {
+		bizSaleOrderApi.bizSaleOrderDelete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+</script>

+ 52 - 8
snowy-admin-web/src/views/biz/bizsendrecord/detail.vue

@@ -1,6 +1,6 @@
 <template>
 	<xn-form-container
-		:title="'过磅记录详情'"
+		:title="'详情'"
 		:width="1200"
 		v-model:open="open"
 		:destroy-on-close="true"
@@ -10,9 +10,9 @@
 			<a-descriptions-item span="3" label="车次编码">{{ formData.carNumber }}</a-descriptions-item>
 			<a-descriptions-item label="车牌号码">{{ formData.licensePlate }}</a-descriptions-item>
 			<a-descriptions-item span="2" label="车牌颜色">{{ formData.plateColor }}</a-descriptions-item>
-			<a-descriptions-item label="发货单位">{{ formData.shippingCompany }}</a-descriptions-item>
+<!--			<a-descriptions-item label="发货单位">{{ formData.shippingCompany }}</a-descriptions-item>
 			<a-descriptions-item label="收货单位">{{ formData.receiptCompany }}</a-descriptions-item>
-			<a-descriptions-item label="运输单位">{{ formData.transportCompany }}</a-descriptions-item>
+			<a-descriptions-item label="运输单位">{{ formData.transportCompany }}</a-descriptions-item>-->
 			<!-- <a-descriptions-item label="运输路线">{{ formData.transportRoute }}</a-descriptions-item> -->
 			<a-descriptions-item label="货品名称">{{ formData.goodsName }}</a-descriptions-item>
 			<a-descriptions-item label="货品规格">{{ formData.goodsModel }}</a-descriptions-item>
@@ -21,19 +21,19 @@
 			<a-descriptions-item label="订单编号">{{ formData.orderNumber }}</a-descriptions-item>
 			<a-descriptions-item label="客户名称">{{ formData.customerName }}</a-descriptions-item>
 			<a-descriptions-item label="司机电话">{{ formData.driverMobile }}</a-descriptions-item>
-			<a-descriptions-item label="过磅人">{{ formData.extKey1 }}</a-descriptions-item>
-			<a-descriptions-item label="打印时间">{{ formData.extKey2 }}</a-descriptions-item>
+<!--			<a-descriptions-item label="过磅人">{{ formData.extKey1 }}</a-descriptions-item>
+			<a-descriptions-item label="打印时间">{{ formData.extKey2 }}</a-descriptions-item>-->
 		</a-descriptions>
 		<a-divider></a-divider>
 		<a-descriptions>
 			<a-descriptions-item label="毛重"
-				><a-tag color="blue">{{ formData.grossWeight }} KG</a-tag></a-descriptions-item
+				><a-tag color="blue">{{ formData.grossWeight }} </a-tag></a-descriptions-item
 			>
 			<a-descriptions-item label="皮重"
-				><a-tag color="orange">{{ formData.tareWeight }} KG</a-tag></a-descriptions-item
+				><a-tag color="orange">{{ formData.tareWeight }} </a-tag></a-descriptions-item
 			>
 			<a-descriptions-item label="净重"
-				><a-tag color="green">{{ formData.netWeight }} KG</a-tag></a-descriptions-item
+				><a-tag color="green">{{ formData.netWeight }} </a-tag></a-descriptions-item
 			>
 		</a-descriptions>
 		<a-divider></a-divider>
@@ -80,6 +80,7 @@
 	import tool from '@/utils/tool'
 	import { cloneDeep } from 'lodash-es'
 	import bizRecordApi from '@/api/biz/bizRecordApi'
+	import sysConfig from "@/config";
 
 	// 抽屉状态
 	const open = ref(false)
@@ -103,6 +104,49 @@
 			})*/
 			let recordData = cloneDeep(record)
 			formData.value = Object.assign({}, recordData)
+			if(formData.value.grossPlateName.includes("http://218.2.6.74:8065")){
+				console.log("str:"+formData.value.grossPlateName.indexOf("preview/"))
+				formData.value.grossPlateName = formData.value.grossPlateName.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossLicenseName.includes("http://218.2.6.74:8065")){
+				formData.value.grossLicenseName = formData.value.grossLicenseName.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCaptureHead.includes("http://218.2.6.74:8065")){
+				formData.value.grossCaptureHead = formData.value.grossCaptureHead.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCaptureTail.includes("http://218.2.6.74:8065")){
+				formData.value.grossCaptureTail = formData.value.grossCaptureTail.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCaptureBody.includes("http://218.2.6.74:8065")){
+				formData.value.grossCaptureBody = formData.value.grossCaptureBody.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCaptureWare.includes("http://218.2.6.74:8065")){
+				formData.value.grossCaptureWare = formData.value.grossCaptureWare.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCapturePoundRoom.includes("http://218.2.6.74:8065")){
+				formData.value.grossCapturePoundRoom = formData.value.grossCapturePoundRoom.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tarePlateName.includes("http://218.2.6.74:8065")){
+				formData.value.tarePlateName = formData.value.tarePlateName.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareLicenseName.includes("http://218.2.6.74:8065")){
+				formData.value.tareLicenseName = formData.value.tareLicenseName.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCaptureHead.includes("http://218.2.6.74:8065")){
+				formData.value.tareCaptureHead = formData.value.tareCaptureHead.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCaptureTail.includes("http://218.2.6.74:8065")){
+				formData.value.tareCaptureTail = formData.value.tareCaptureTail.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCaptureBody.includes("http://218.2.6.74:8065")){
+				formData.value.tareCaptureBody = formData.value.tareCaptureBody.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCaptureWare.includes("http://218.2.6.74:8065")){
+				formData.value.tareCaptureWare = formData.value.tareCaptureWare.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCapturePoundRoom.includes("http://218.2.6.74:8065")){
+				formData.value.tareCapturePoundRoom = formData.value.tareCapturePoundRoom.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
 		}
 	}
 	// 关闭抽屉

+ 38 - 28
snowy-admin-web/src/views/biz/bizsendrecord/index.vue

@@ -2,6 +2,11 @@
 	<a-card :bordered="false" style="margin-bottom: 10px" class="mb-2">
 		<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
 			<a-row :gutter="24">
+				<a-col :span="6">
+					<a-form-item label="车次编码" name="carNumber">
+						<a-input v-model:value="searchFormState.carNumber" placeholder="请输入车次编码" />
+					</a-form-item>
+				</a-col>
 				<a-col :span="6">
 					<a-form-item label="车牌号码" name="licensePlate">
 						<a-input v-model:value="searchFormState.licensePlate" placeholder="请输入车牌号码" />
@@ -15,14 +20,6 @@
 						/>
 					</a-form-item>
 				</a-col>
-				<a-col :span="6">
-					<a-form-item label="过皮时间" name="tareTime">
-						<a-range-picker
-							v-model:value="searchFormState.tareTime"
-							value-format="YYYY-MM-DD"
-						/>
-					</a-form-item>
-				</a-col>
 				<a-col :span="6" v-show="advanced">
 					<a-form-item label="司机姓名" name="driverName">
 						<a-input v-model:value="searchFormState.driverName" placeholder="请输入司机姓名" />
@@ -43,7 +40,7 @@
 						<a-input v-model:value="searchFormState.goodsModel" placeholder="请输入规格型号" />
 					</a-form-item>
 				</a-col>
-				<a-col :span="6" v-show="advanced">
+<!--				<a-col :span="6" v-show="advanced">
 					<a-form-item label="收货单位" name="receiptCompany">
 						<a-input v-model:value="searchFormState.receiptCompany" placeholder="请输入收货单位" />
 					</a-form-item>
@@ -57,7 +54,7 @@
 					<a-form-item label="运输单位" name="transportCompany">
 						<a-input v-model:value="searchFormState.transportCompany" placeholder="请输入运输单位" />
 					</a-form-item>
-				</a-col>
+				</a-col>-->
 				<a-col :span="6" v-show="advanced">
 					<a-form-item label="订单编号" name="orderNumber">
 						<a-input v-model:value="searchFormState.orderNumber" placeholder="请输入订单编号" />
@@ -73,6 +70,13 @@
 						<a-input v-model:value="searchFormState.customerName" placeholder="请输入客户名称" />
 					</a-form-item>
 				</a-col>
+				<a-col :span="6" v-show="advanced">
+					<a-form-item label="确认状态" name="sendRecordStatus">
+						<a-select v-model:value="searchFormState.sendRecordStatus" placeholder="确认状态查询"
+								  :options="sendRecordStatusList"
+						> </a-select>
+					</a-form-item>
+				</a-col>
 				<a-col :span="6">
 					<a-button type="primary" @click="tableRef.refresh()">查询</a-button>
 					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
@@ -93,11 +97,14 @@
 			:row-key="(record) => record.id"
 		>
 			<template #operator class="table-operator">
-				<a-space>
-<!--					<a-button type="dashed" class="snowy-buttom-left" @click="exportData()" v-if="hasPerm('bizRecordBatchExport')"
-						><export-outlined />记录导出</a-button
-					>-->
-				</a-space>
+<!--				<a-space>
+					<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizRecordToConfirm')">
+						待确认
+					</a-button>
+					<a-button style="background-color: orange;" type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizRecordAlreadyConfirm')">
+						已确认
+					</a-button>
+				</a-space>-->
 			</template>
 			<template #bodyCell="{ column, record }">
 				<template v-if="column.dataIndex === 'licensePlate'">
@@ -169,8 +176,8 @@
 				<template v-if="column.dataIndex === 'action'">
 					<a-space>
 						<a @click="detailRef.onOpen(record)">详情</a>
-						<a-divider type="vertical"  v-if="hasPerm('bizRecordConfirm') && record.confirmUser==null " />
-						<a  @click="confirmRecord(record)" v-if="hasPerm('bizRecordConfirm') && record.confirmUser==null ">确认</a>
+						<a-divider type="vertical"  v-if="hasPerm('bizRecordConfirm') && record.status=='6' " />
+						<a  @click="confirmRecord(record)" v-if="hasPerm('bizRecordConfirm') && record.status=='6' ">确认</a>
 					</a-space>
 				</template>
 			</template>
@@ -190,6 +197,8 @@
 	import {createVNode} from "vue";
 	import {ExclamationCircleOutlined} from "@ant-design/icons-vue";
 	import bizAppointmentRecordApi from "@/api/biz/bizAppointmentRecordApi";
+	import tool from '@/utils/tool'
+
 	const searchFormState = ref({isFlag:1})
 	const searchFormRef = ref()
 	const tableRef = ref()
@@ -200,6 +209,7 @@
 	const advanced = ref(false)
 
 	const submitLoading = ref(false)
+	const sendRecordStatusList = tool.dictList('send_record_status')
 
 	const toggleAdvanced = () => {
 		advanced.value = !advanced.value
@@ -223,7 +233,7 @@
 			width: '130px'
 		},
 		{
-			title: '重量(KG)',
+			title: '重量()',
 			dataIndex: 'weight',
 			align: 'center'
 		},
@@ -232,8 +242,9 @@
 			dataIndex: 'orderInfo'
 		},
 		{
-			title: '收发货单位',
-			dataIndex: 'company'
+			title: '客户名称',
+			dataIndex: 'customerName',
+			align:'center'
 		},
 		{
 			title: '货品',
@@ -246,14 +257,13 @@
 		}
 	]
 	// 操作栏通过权限判断是否显示
-	if (hasPerm(['bizRecordEdit', 'bizRecordDelete', 'bizRecordDetail'])) {
-		columns.push({
-			title: '操作',
-			dataIndex: 'action',
-			align: 'center',
-			width: 150
-		})
-	}
+	columns.push({
+		title: '操作',
+		dataIndex: 'action',
+		align: 'center',
+		width: 150
+	})
+
 
 	const loadData = (parameter) => {
 		const searchFormParam = cloneDeep(searchFormState.value)

+ 79 - 9
snowy-admin-web/src/views/biz/record/detail.vue

@@ -1,6 +1,6 @@
 <template>
 	<xn-form-container
-		:title="'过磅记录详情'"
+		:title="'详情'"
 		:width="1200"
 		v-model:open="open"
 		:destroy-on-close="true"
@@ -10,9 +10,9 @@
 			<a-descriptions-item span="3" label="车次编码">{{ formData.carNumber }}</a-descriptions-item>
 			<a-descriptions-item label="车牌号码">{{ formData.licensePlate }}</a-descriptions-item>
 			<a-descriptions-item span="2" label="车牌颜色">{{ formData.plateColor }}</a-descriptions-item>
-			<a-descriptions-item label="发货单位">{{ formData.shippingCompany }}</a-descriptions-item>
+<!--			<a-descriptions-item label="发货单位">{{ formData.shippingCompany }}</a-descriptions-item>
 			<a-descriptions-item label="收货单位">{{ formData.receiptCompany }}</a-descriptions-item>
-			<a-descriptions-item label="运输单位">{{ formData.transportCompany }}</a-descriptions-item>
+			<a-descriptions-item label="运输单位">{{ formData.transportCompany }}</a-descriptions-item>-->
 			<!-- <a-descriptions-item label="运输路线">{{ formData.transportRoute }}</a-descriptions-item> -->
 			<a-descriptions-item label="货品名称">{{ formData.goodsName }}</a-descriptions-item>
 			<a-descriptions-item label="货品规格">{{ formData.goodsModel }}</a-descriptions-item>
@@ -21,19 +21,19 @@
 			<a-descriptions-item label="订单编号">{{ formData.orderNumber }}</a-descriptions-item>
 			<a-descriptions-item label="客户名称">{{ formData.customerName }}</a-descriptions-item>
 			<a-descriptions-item label="司机电话">{{ formData.driverMobile }}</a-descriptions-item>
-			<a-descriptions-item label="过磅人">{{ formData.extKey1 }}</a-descriptions-item>
-			<a-descriptions-item label="打印时间">{{ formData.extKey2 }}</a-descriptions-item>
+<!--			<a-descriptions-item label="过磅人">{{ formData.extKey1 }}</a-descriptions-item>
+			<a-descriptions-item label="打印时间">{{ formData.extKey2 }}</a-descriptions-item>-->
 		</a-descriptions>
 		<a-divider></a-divider>
 		<a-descriptions>
 			<a-descriptions-item label="毛重"
-				><a-tag color="blue">{{ formData.grossWeight }} KG</a-tag></a-descriptions-item
+				><a-tag color="blue">{{ formData.grossWeight }} </a-tag></a-descriptions-item
 			>
 			<a-descriptions-item label="皮重"
-				><a-tag color="orange">{{ formData.tareWeight }} KG</a-tag></a-descriptions-item
+				><a-tag color="orange">{{ formData.tareWeight }} </a-tag></a-descriptions-item
 			>
 			<a-descriptions-item label="净重"
-				><a-tag color="green">{{ formData.netWeight }} KG</a-tag></a-descriptions-item
+				><a-tag color="green">{{ formData.netWeight }} </a-tag></a-descriptions-item
 			>
 		</a-descriptions>
 		<a-divider></a-divider>
@@ -71,11 +71,27 @@
 			<a-image v-if="formData.tareCapturePoundRoom != null" :width="200" :src="formData.tareCapturePoundRoom" />
 		</a-space>
 		<a-divider></a-divider>
-		<a-descriptions title="司机签名" style="margin-top: 15px">
+		<a-descriptions title="司机确认" style="margin-top: 15px">
 		</a-descriptions>
 		<a-space>
 			<a-image :width="200" :src="formData.driverSign" />
 		</a-space>
+		<a-divider v-if="formData.orderType == '1'"></a-divider>
+		<a-descriptions title="司机回签" style="margin-top: 15px" v-if="formData.orderType == '1'">
+			<a-descriptions-item label="卸货重量"><a-tag color="green">{{ formData.unloadWeight }} 吨</a-tag></a-descriptions-item>
+		</a-descriptions>
+		<a-space v-if="formData.orderType == '1'">
+			<div v-for="(item,index) in fileList " :key="item.value">
+				<a-image :width="200" :src="item.url" />
+			</div>
+
+		</a-space>
+		<a-divider v-if="formData.orderType == '1'"></a-divider>
+		<a-descriptions title="签收审核" style="margin-top: 15px" v-if="formData.orderType == '1'">
+		</a-descriptions>
+		<a-space v-if="formData.orderType == '1'">
+			<a-image :width="200" :src="formData.auditSign" />
+		</a-space>
 		<template #footer>
 			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
 		</template>
@@ -86,6 +102,7 @@
 	import tool from '@/utils/tool'
 	import { cloneDeep } from 'lodash-es'
 	import bizRecordApi from '@/api/biz/bizRecordApi'
+	import sysConfig from '@/config/index'
 
 	// 抽屉状态
 	const open = ref(false)
@@ -96,6 +113,7 @@
 	// const submitLoading = ref(false)
 	const tareTypeOptions = ref([])
 
+	const fileList = ref([])
 	// 打开抽屉
 	const onOpen = (record) => {
 		open.value = true
@@ -109,6 +127,58 @@
 			})*/
 			let recordData = cloneDeep(record)
 			formData.value = Object.assign({}, recordData)
+			fileList.value = []
+			if(formData.value.unloadImg!=null){
+				for (var i=0;i<formData.value.unloadImg.split(',').length;i++){
+					fileList.value.push({
+						name: formData.value.unloadName.split(',')[i],
+						url:sysConfig.PREVIEW_PATH + formData.value.unloadImg.split(',')[i]
+					})
+				}
+			}
+			if(formData.value.grossPlateName.includes("http://218.2.6.74:8065")){
+				console.log("str:"+formData.value.grossPlateName.indexOf("preview/"))
+				formData.value.grossPlateName = formData.value.grossPlateName.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossLicenseName.includes("http://218.2.6.74:8065")){
+				formData.value.grossLicenseName = formData.value.grossLicenseName.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCaptureHead.includes("http://218.2.6.74:8065")){
+				formData.value.grossCaptureHead = formData.value.grossCaptureHead.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCaptureTail.includes("http://218.2.6.74:8065")){
+				formData.value.grossCaptureTail = formData.value.grossCaptureTail.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCaptureBody.includes("http://218.2.6.74:8065")){
+				formData.value.grossCaptureBody = formData.value.grossCaptureBody.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCaptureWare.includes("http://218.2.6.74:8065")){
+				formData.value.grossCaptureWare = formData.value.grossCaptureWare.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.grossCapturePoundRoom.includes("http://218.2.6.74:8065")){
+				formData.value.grossCapturePoundRoom = formData.value.grossCapturePoundRoom.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tarePlateName.includes("http://218.2.6.74:8065")){
+				formData.value.tarePlateName = formData.value.tarePlateName.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareLicenseName.includes("http://218.2.6.74:8065")){
+				formData.value.tareLicenseName = formData.value.tareLicenseName.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCaptureHead.includes("http://218.2.6.74:8065")){
+				formData.value.tareCaptureHead = formData.value.tareCaptureHead.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCaptureTail.includes("http://218.2.6.74:8065")){
+				formData.value.tareCaptureTail = formData.value.tareCaptureTail.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCaptureBody.includes("http://218.2.6.74:8065")){
+				formData.value.tareCaptureBody = formData.value.tareCaptureBody.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCaptureWare.includes("http://218.2.6.74:8065")){
+				formData.value.tareCaptureWare = formData.value.tareCaptureWare.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
+			if(formData.value.tareCapturePoundRoom.includes("http://218.2.6.74:8065")){
+				formData.value.tareCapturePoundRoom = formData.value.tareCapturePoundRoom.replace("http://218.2.6.74:8065/preview/",sysConfig.PREVIEW_PATH)
+			}
 		}
 	}
 	// 关闭抽屉

+ 14 - 14
snowy-admin-web/src/views/biz/record/index.vue

@@ -49,7 +49,7 @@
 							<a-input v-model:value="searchFormState.goodsModel" placeholder="请输入规格型号" />
 						</a-form-item>
 					</a-col>
-					<a-col :span="6" v-show="advanced">
+<!--					<a-col :span="6" v-show="advanced">
 						<a-form-item label="收货单位" name="receiptCompany">
 							<a-input v-model:value="searchFormState.receiptCompany" placeholder="请输入收货单位" />
 						</a-form-item>
@@ -63,7 +63,7 @@
 						<a-form-item label="运输单位" name="transportCompany">
 							<a-input v-model:value="searchFormState.transportCompany" placeholder="请输入运输单位" />
 						</a-form-item>
-					</a-col>
+					</a-col>-->
 					<a-col :span="6" v-show="advanced">
 						<a-form-item label="订单编号" name="orderNumber">
 							<a-input v-model:value="searchFormState.orderNumber" placeholder="请输入订单编号" />
@@ -177,7 +177,7 @@
 					<a-space>
 						<a @click="detailRef.onOpen(record)">详情</a>
 						<a-divider type="vertical" v-if="hasPerm('bizRecordDriverConfirm')" />
-						<a @click="XnSignNameRef.show(record.id)" v-if="hasPerm('bizRecordDriverConfirm') && record.status == '8'">司机确认</a>
+<!--						<a @click="XnSignNameRef.show(record.id)" v-if="hasPerm('bizRecordDriverConfirm') && record.status == '8'">司机确认</a>-->
 						<XnSignName ref="XnSignNameRef" :image="searchFormState.driverSign" @successful="signSuccess" />
 						<a-divider type="vertical" v-if="hasPerm(['bizGoodsEdit', 'bizGoodsDelete'], 'and')" />
 						<a-popconfirm title="确定要删除吗?" @confirm="cancellationBizRecord(record)">
@@ -230,7 +230,7 @@
 			width: '130px'
 		},
 		{
-			title: '重量(KG)',
+			title: '重量()',
 			dataIndex: 'weight',
 			align: 'center'
 		},
@@ -239,8 +239,9 @@
 			dataIndex: 'orderInfo'
 		},
 		{
-			title: '收发货单位',
-			dataIndex: 'company'
+			title: '客户名称',
+			dataIndex: 'customerName',
+			align:'center'
 		},
 		{
 			title: '货品',
@@ -253,14 +254,13 @@
 		}
 	]
 	// 操作栏通过权限判断是否显示
-	if (hasPerm(['bizRecordEdit', 'bizRecordDelete', 'bizRecordDetail'])) {
-		columns.push({
-			title: '操作',
-			dataIndex: 'action',
-			align: 'center',
-			width: 150
-		})
-	}
+	columns.push({
+		title: '操作',
+		dataIndex: 'action',
+		align: 'center',
+		width: 150
+	})
+
 
 	const loadData = (parameter) => {
 		const searchFormParam = cloneDeep(searchFormState.value)

+ 6 - 0
snowy-common/src/main/java/vip/xiaonuo/common/prop/CommonProperties.java

@@ -42,5 +42,11 @@ public class CommonProperties {
 
     private String mqttPassword;
 
+    /**微信公众号*/
+    private String officialToken;
+    private String officialAppId;
+    private String officialAeskey;
+    private String officialSecret;
+
 
 }

+ 3 - 0
snowy-plugin-api/snowy-plugin-auth-api/src/main/java/vip/xiaonuo/auth/core/pojo/SaBaseLoginUser.java

@@ -247,6 +247,9 @@ public abstract class SaBaseLoginUser {
     @Schema(description = "用户密码hash值")
     private String password;
 
+    /**客户id*/
+    private String customerId;
+
     /** 是否可登录,由继承类实现 */
     public abstract Boolean getEnabled();
 

+ 71 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/api/controller/ApiController.java

@@ -0,0 +1,71 @@
+package vip.xiaonuo.biz.modular.api.controller;
+
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+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.RestController;
+import vip.xiaonuo.biz.modular.api.service.ApiService;
+import vip.xiaonuo.biz.modular.utils.SignUtil;
+import vip.xiaonuo.common.prop.CommonProperties;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+@Tag(name = "微信公众号")
+@RestController
+@Validated
+public class ApiController {
+
+    @Resource
+    private CommonProperties commonProperties;
+
+    @Resource
+    private ApiService apiService;
+
+    /***
+     * 微信公众号验证接口
+     * @param request
+     * @param response
+     */
+    @GetMapping("/api/wxOpen")
+    public void get(HttpServletRequest request, HttpServletResponse response) {
+        // 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
+        String signature = request.getParameter("signature");
+        // 时间戳
+        String timestamp = request.getParameter("timestamp");
+        // 随机数
+        String nonce = request.getParameter("nonce");
+        // 随机字符串
+        String echostr = request.getParameter("echostr");
+        PrintWriter out = null;
+        try {
+            out = response.getWriter();
+            // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,否则接入失败
+            if (SignUtil.checkSignature(commonProperties.getOfficialToken(), signature, timestamp, nonce)) {
+                out.print(echostr);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+
+    /**
+     * 微信公众号操作事件(包括关注和取消动作操作)
+     *
+     * @param request
+     * @param response
+     */
+    @PostMapping("/api/wxOpen")
+    public void officialCallback(HttpServletRequest request, HttpServletResponse response) {
+        apiService.officialCallback(request, response);
+    }
+}

+ 167 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/api/service/ApiService.java

@@ -0,0 +1,167 @@
+package vip.xiaonuo.biz.modular.api.service;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import vip.xiaonuo.biz.modular.officialinfo.entity.OfficialInfo;
+import vip.xiaonuo.biz.modular.officialinfo.service.OfficialInfoService;
+import vip.xiaonuo.biz.modular.utils.MsgUtil;
+import vip.xiaonuo.biz.modular.utils.XmlUtil;
+import vip.xiaonuo.common.exception.CommonException;
+import vip.xiaonuo.common.prop.CommonProperties;
+
+import java.io.PrintWriter;
+import java.util.Date;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class ApiService {
+
+    @Resource
+    private OfficialInfoService officialInfoService;
+
+    @Resource
+    private CommonProperties commonProperties;
+
+    public static JSONObject wx_token_map = new JSONObject();
+
+    public void officialCallback(HttpServletRequest request, HttpServletResponse response) {
+        // 响应消息
+        PrintWriter out = null;
+        String resMessage = "";
+        try {
+            request.setCharacterEncoding("UTF-8");
+            response.setCharacterEncoding("UTF-8");
+            //把微信返回的xml信息转义成map
+            Map<String, Object> map = XmlUtil.parseXML(request.getInputStream());
+            //消息来源用户标识
+            String fromUserName = (String) map.get("FromUserName");
+            //消息目的用户标识
+            String toUserName = (String) map.get("ToUserName");
+            //消息创建时间(整型)
+            String createTime = (String) map.get("CreateTime");
+            //消息类型
+            String msgType = (String) map.get("MsgType");
+            //事件类型:subscribe/unsubscribe
+            String eventType = (String) map.get("Event");
+            //如果为事件类型
+            if (MsgUtil.MSGTYPE_EVENT.equals(msgType)) {
+                //查询是否存在公众号表记录
+                QueryWrapper<OfficialInfo> queryWrapper = new QueryWrapper<>();
+                queryWrapper.lambda().eq(OfficialInfo::getOfficialOpenId, fromUserName)
+                        .last("limit 1");
+                OfficialInfo officialInfo = officialInfoService.getOne(queryWrapper);
+                if (officialInfo == null) {
+                    officialInfo = new OfficialInfo();
+                    JSONObject jsonObject = this.getUserInfo(fromUserName);
+                    if (jsonObject != null) {
+                        officialInfo.setWxAddress(jsonObject.getString("country")
+                                + jsonObject.getString("province")
+                                + jsonObject.getString("city"));
+                        officialInfo.setCreateTime(new Date());
+                        officialInfo.setNickName(jsonObject.getString("nickname"));
+                        officialInfo.setOfficialOpenId(jsonObject.getString("openid"));
+                        officialInfo.setUnionId(jsonObject.getString("unionid"));
+                        officialInfo.setWxHead(jsonObject.getString("headimgurl"));
+                        officialInfoService.save(officialInfo);
+                    }
+                }
+                //处理订阅事件-关注与取消关注
+                if (MsgUtil.MESSAGE_SUBSCIBE.equals(eventType)) {
+                    officialInfo.setStatus(1);
+                    System.out.println("您好,谢谢您的关注!!");
+                    if (ObjectUtil.isEmpty(officialInfo.getUnionId())) {
+                        JSONObject jsonObject = this.getUserInfo(fromUserName);
+                        if (jsonObject != null) {
+                            officialInfo.setUnionId(jsonObject.getString("unionid"));
+                        }
+                    }
+                    resMessage = MsgUtil.subscribeForText(toUserName, fromUserName, "您好,谢谢您的关注!!");
+                } else if (MsgUtil.MESSAGE_UNSUBSCIBE.equals(eventType)) {//取消订阅
+                    officialInfo.setStatus(0);
+                    resMessage = MsgUtil.unsubscribeForText(toUserName, fromUserName, "取消关注~");
+                }
+                officialInfoService.updateById(officialInfo);
+                log.info("eventType:" + eventType + ",fromUserName:" + fromUserName + ",toUserName:" + toUserName + ",msgType:" + msgType + ",createTime:" + createTime);
+            }
+            out = response.getWriter();
+            out.println(resMessage);
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.info("公众号回调异常------", e.getMessage());
+            //itemErrorInfoService.errorAdd(e);
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+
+    /**
+     * 微信公众号的appid以及sercet
+     *
+     * @param openId
+     * @return
+     */
+    private JSONObject getUserInfo(String openId) {
+        JSONObject jsonObject = null;
+        String accessToken = getAccessToken(commonProperties.getOfficialAppId(), commonProperties.getOfficialSecret());
+        log.info("-------openId:" + openId + "-------");
+        log.info("-------accessToken:" + accessToken + "-------");
+        StringBuffer url = new StringBuffer("https://api.weixin.qq.com/cgi-bin/user/info");
+        url.append("?access_token=").append(accessToken);
+        url.append("&openid=").append(openId);
+        url.append("&lang=zh_CN");
+
+        String content = HttpUtil.get(url.toString());
+        if (ObjectUtil.isNotEmpty(content)) {
+            jsonObject = JSONObject.parseObject(content);
+        }
+        log.info("-------微信用户信息:" + content + "-------");
+        return jsonObject;
+    }
+
+
+    private String getAccessToken(String sAppid, String sSecret) {
+        // 因为微信有限制次数跟有效期,所以需要存在redis中
+        if (wx_token_map.size() == 0) {
+            wx_token_map.put("token", null);
+        }
+        String token = wx_token_map.getString("token");
+        // token失效或者为空
+        if (StrUtil.isEmpty(token) || "null".equals(token)) {
+            StringBuffer url = new StringBuffer("https://api.weixin.qq.com/cgi-bin/token");
+            url.append("?grant_type=client_credential");
+            url.append("&appid=").append(sAppid);
+            url.append("&secret=").append(sSecret);
+            log.info(url.toString());
+            String content = HttpUtil.get(url.toString());
+            if (StrUtil.isEmpty(content) || !content.contains("access_token")) {
+                log.info(content);
+                throw new CommonException("获取公众号accessToken失败");
+            }
+            token = JSONObject.parseObject(content).getString("access_token");
+            // 设置为1.9h(有效期2h)
+            wx_token_map.put("token", token);
+            wx_token_map.put("time", System.currentTimeMillis());
+        } else {
+            Long time = wx_token_map.getLong("time");
+            long l = System.currentTimeMillis();
+            if ((l - time) >= 1.9 * 3600 * 1000) {
+                wx_token_map.clear();
+                getAccessToken(sAppid, sSecret);
+            }
+
+        }
+        return token;
+    }
+}

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

@@ -145,6 +145,7 @@ public class BizAppointmentRecordController {
      * 导出预约报表
      */
     @Operation(summary = "导出预约报表")
+    @SaCheckPermission("/biz/bizappointmentrecord/exportRecord")
     @GetMapping(value = "/biz/bizappointmentrecord/exportRecord", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
     public void exportRecord(BizAppointmentRecordPageParam bizAppointmentRecordPageParam, HttpServletResponse response) throws IOException {
         bizAppointmentRecordService.exportRecord(bizAppointmentRecordPageParam,response);

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

@@ -112,4 +112,36 @@ public class BizAppointmentRecord extends CommonEntity {
     /**订单重量校验*/
     @TableField(exist = false)
     private String orderWeightSwitch;
+
+    @TableField(exist = false)
+    /**车辆轴数*/
+    private Integer axleNumber;
+
+    /**过磅记录id*/
+    @TableField(exist = false)
+    private String recordId;
+
+    /**排队号*/
+    private Integer queueNumber;
+
+    @TableField(exist = false)
+    /**司机签名*/
+    private String driverSign;
+
+    @TableField(exist = false)
+    /**订单类型*/
+    private String orderType;
+
+    @TableField(exist = false)
+    /**卸货重量*/
+    private BigDecimal unloadWeight;
+
+    /**单据图片*/
+    @TableField(exist = false)
+    private String unloadImg;
+    @TableField(exist = false)
+    private String unloadName;
+
+    @TableField(exist = false)
+    private String customerContactName;
 }

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

@@ -9,7 +9,9 @@
             bar.license_number,
             bo.order_number,
             bo.order_name,
+            bo.order_type,
             bc.name customerName,
+            bc.contact customerContactName,
             bg.GOODS_NAME goodsName,
             bg.GOODS_MODEL goodsModel,
             bar.time_id,
@@ -19,12 +21,21 @@
             bar.driver_mobile,
             bar.status,
             bar.appointment_reason,
-            bar.over_id
+            bar.over_id,
+            bec.vehicle_axle_number axleNumber,
+            br.id recordId,
+            bar.queue_number,
+            br.driver_sign,
+            br.unload_weight/1000 unload_weight,
+            br.unload_img,
+            br.unload_name
         from biz_appointment_record bar
          left join biz_order bo on bar.order_id = bo.id
          left join biz_goods bg on bg.id = bo.good_id
          left join biz_goods_conf bgc on bgc.id = bar.time_id
          left join biz_customer bc on bc.id = bo.customer_id
+         left join biz_excess_config bec on bec.id = bar.over_id
+         left join biz_record br on bar.id = br.appointment_id
         ${ew.customSqlSegment}
     </select>
     <select id="getRecord"

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

@@ -26,8 +26,12 @@ public class BizAppointmentExportResult {
 
     /** 预约时段 */
     @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
-    @ExcelProperty({"预约报表", "提货时段"})
-    private String timeInfo;
+    @ExcelProperty({"预约报表", "提货开始时间"})
+    private String beginTime;
+    /** 预约时段 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "提货结束时间"})
+    private String endTime;
 
     /** 客户名称 */
     @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
@@ -54,6 +58,11 @@ public class BizAppointmentExportResult {
     @ExcelProperty({"预约报表", "司机电话"})
     private String driverMobile;
 
+    /** 司机电话 */
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
+    @ExcelProperty({"预约报表", "车辆轴数"})
+    private String axleNumber;
+
     /** 预约状态*/
     @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 120)
     @ExcelProperty({"预约报表", "预约状态"})

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

@@ -15,6 +15,7 @@ package vip.xiaonuo.biz.modular.bizappointmentrecord.service.impl;
 import cn.dev33.satoken.stp.StpUtil;
 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.PhoneUtil;
 import cn.hutool.core.util.StrUtil;
@@ -58,6 +59,7 @@ import vip.xiaonuo.biz.modular.bizappointmentrecord.service.BizAppointmentRecord
 import java.io.IOException;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.locks.ReentrantLock;
 import java.util.regex.Pattern;
 
 /**
@@ -69,6 +71,7 @@ import java.util.regex.Pattern;
 @Service
 public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentRecordMapper, BizAppointmentRecord> implements BizAppointmentRecordService {
 
+    private final ReentrantLock lock = new ReentrantLock();
     @Resource
     private BizConfigService bizConfigService;
     @Resource
@@ -103,7 +106,7 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
             queryWrapper.like("bo.order_number",bizAppointmentRecordPageParam.getOrderNumber());
         }
         if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getCustomerName())){
-            queryWrapper.like("bc.customer_name",bizAppointmentRecordPageParam.getCustomerName());
+            queryWrapper.like("bc.name",bizAppointmentRecordPageParam.getCustomerName());
         }
         if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getDriverName())){
             queryWrapper.like("bar.driver_name",bizAppointmentRecordPageParam.getDriverName());
@@ -112,7 +115,7 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
             queryWrapper.like("bar.driver_mobile",bizAppointmentRecordPageParam.getDriverMobile());
         }
         if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getGoodsName())){
-            queryWrapper.like("bg.NAME",bizAppointmentRecordPageParam.getGoodsName());
+            queryWrapper.like("bg.GOODS_NAME",bizAppointmentRecordPageParam.getGoodsName());
         }
         if(ObjectUtil.isNotEmpty(bizAppointmentRecordPageParam.getLicenseNumber())){
             queryWrapper.like("bar.license_number",bizAppointmentRecordPageParam.getLicenseNumber());
@@ -151,7 +154,8 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
                 bizAppointmentRecord.setStatus("3");
             }
         }
-        this.save(bizAppointmentRecord);
+        //this.save(bizAppointmentRecord);
+        saveRecord(bizAppointmentRecord);
 
         BizOrder bizOrder = bizOrderService.getById(bizAppointmentRecordAddParam.getOrderId());
         bizOrder.setOrderStatus("4");
@@ -167,18 +171,39 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
         }
     }
 
+    public void saveRecord(BizAppointmentRecord bizAppointmentRecord){
+        //排队中
+        lock.lock();
+        try {
+            //查询当天预约记录条数
+            String format = DateUtil.format(DateUtil.date(), "yyyy-MM-dd");
+            BizGoodsConf bizGoodsConf = bizGoodsConfService.getById(bizAppointmentRecord.getTimeId());
+            if(ObjectUtil.isNotNull(bizGoodsConf)){
+                format = DateUtil.format(bizGoodsConf.getConfStartTime(),"yyyy-MM-dd");
+            }
+            long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
+                    between(BizAppointmentRecord::getCreateTime, format + " 00:00:00", format + " 23:59:59"));
+            bizAppointmentRecord.setQueueNumber((int) (count+1));
+            this.save(bizAppointmentRecord);
+        } finally {
+            lock.unlock(); // 释放锁
+        }
+
+    }
+
     public void checkParam(BizAppointmentRecordAddParam bizAppointmentRecordAddParam){
         //校验车牌号
         if(ObjectUtil.isNotEmpty(bizAppointmentRecordAddParam.getLicenseNumber())){
-            if(!isCarNumber(bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim())){
-                throw new CommonException("车牌号:{}格式错误",bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim());
+            bizAppointmentRecordAddParam.setLicenseNumber(bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim());
+            if(!isCarNumber(bizAppointmentRecordAddParam.getLicenseNumber())){
+                //throw new CommonException("车牌号:{}格式错误",bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim());
             }
             //校验车牌号是否添加过预约,排除11:已签收、 13:销售已审核  、 14:已取消
             long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
-                    eq(BizAppointmentRecord::getLicenseNumber,bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim()).
+                    eq(BizAppointmentRecord::getLicenseNumber,bizAppointmentRecordAddParam.getLicenseNumber()).
                     notIn(BizAppointmentRecord::getStatus, "11", "13", "14","15"));
             if(count>0){
-                throw new CommonException("车牌号:{}已经添加过预约!",bizAppointmentRecordAddParam.getLicenseNumber().toUpperCase().trim());
+                throw new CommonException("车牌号:{}已经添加过预约!",bizAppointmentRecordAddParam.getLicenseNumber());
             }
         }
         //校验手机号
@@ -225,17 +250,18 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
     public void checkParam(BizAppointmentRecordEditParam bizAppointmentRecordEditParam,BizAppointmentRecord bizAppointmentRecord){
         //校验车牌号
         if(ObjectUtil.isNotEmpty(bizAppointmentRecordEditParam.getLicenseNumber())){
-            if(!StringUtils.equals(bizAppointmentRecord.getLicenseNumber(),bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim())){
+            bizAppointmentRecordEditParam.setLicenseNumber(bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim());
+            if(!StringUtils.equals(bizAppointmentRecord.getLicenseNumber(),bizAppointmentRecordEditParam.getLicenseNumber())){
                 //车牌号修改过
-                if(!isCarNumber(bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim())){
-                    throw new CommonException("车牌号:{}格式错误",bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim());
+                if(!isCarNumber(bizAppointmentRecordEditParam.getLicenseNumber())){
+                    //throw new CommonException("车牌号:{}格式错误",bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim());
                 }
                 //校验车牌号是否添加过预约,排除11:已签收、 13:销售已审核  、 14:已取消
                 long count = this.count(new QueryWrapper<BizAppointmentRecord>().lambda().
-                        eq(BizAppointmentRecord::getLicenseNumber,bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim()).
+                        eq(BizAppointmentRecord::getLicenseNumber,bizAppointmentRecordEditParam.getLicenseNumber()).
                         notIn(BizAppointmentRecord::getStatus, "11", "13", "14","15"));
                 if(count>0){
-                    throw new CommonException("车牌号:{}已经添加过预约!",bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim());
+                    throw new CommonException("车牌号:{}已经添加过预约!",bizAppointmentRecordEditParam.getLicenseNumber());
                 }
             }
         }
@@ -375,7 +401,7 @@ public class BizAppointmentRecordServiceImpl extends ServiceImpl<BizAppointmentR
             BizAppointmentExportResult bizAppointmentExportResult = new BizAppointmentExportResult();
             BeanUtil.copyProperties(bizAppointmentRecord, bizAppointmentExportResult);
             bizAppointmentExportResult.setStatusName((String) bizAppointmentRecord.getTransMap().get("statusName"));
-            bizAppointmentExportResult.setTimeInfo(bizAppointmentRecord.getBeginTime()+"~"+bizAppointmentRecord.getEndTime());
+            bizAppointmentExportResult.setAxleNumber(bizAppointmentRecord.getAxleNumber()+"轴");
             list.add(bizAppointmentExportResult);
         }
         CommonExportUtil.export(fileName, BizAppointmentExportResult.class,list,response,"预约报表");

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizconfig/entity/BizConfig.java

@@ -63,4 +63,7 @@ public class BizConfig extends CommonEntity {
 
     /**装卸损耗预警值配置(百分比)*/
     private BigDecimal lossWarn;
+
+    /**预约申请次数*/
+    private Integer applyCount;
 }

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

@@ -64,4 +64,7 @@ public class BizConfigAddParam {
     /**装卸损耗预警值配置(百分比)*/
     private Integer lossWarn;
 
+    /**预约申请次数*/
+    private Integer applyCount;
+
 }

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

@@ -69,4 +69,7 @@ public class BizConfigEditParam {
     /**装卸损耗预警值配置(百分比)*/
     private Integer lossWarn;
 
+    /**预约申请次数*/
+    private Integer applyCount;
+
 }

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

@@ -154,6 +154,7 @@ public class BizOrderController {
      * 导出订单报表
      */
     @Operation(summary = "导出订单报表")
+    @SaCheckPermission("/biz/bizorder/exportRecord")
     @GetMapping(value = "/biz/bizorder/exportRecord", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
     public void exportRecord(BizOrderPageParam bizOrderPageParam, HttpServletResponse response) throws IOException {
         bizOrderService.exportRecord(bizOrderPageParam,response);
@@ -243,4 +244,18 @@ public class BizOrderController {
         bizOrderService.auditOrder(bizOrderEditParam);
         return CommonResult.ok();
     }
+
+    /**
+     * 订单提交
+     *
+     * @author fanzherong
+     * @date  2025/03/21 17:16
+     */
+    @Operation(summary = "订单提交")
+    @CommonLog("订单提交")
+    @PostMapping("/biz/bizorder/submit")
+    public CommonResult<String> submit(@RequestBody @Valid BizOrderEditParam bizOrderEditParam) {
+        bizOrderService.submit(bizOrderEditParam);
+        return CommonResult.ok();
+    }
 }

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

@@ -128,4 +128,7 @@ public class BizOrder extends CommonEntity{
     /**审核备注*/
     private String orderReason;
 
+    /**结束备注**/
+    private String endReason;
+
 }

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

@@ -24,7 +24,9 @@
             bgc.CONF_END_TIME,
             bo.sale_order_info,
             bo.delivery_time_id,
-            bo.order_sign
+            bo.order_sign,
+            bo.order_reason,
+            bo.end_reason
         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

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

@@ -91,4 +91,7 @@ public class BizOrderEditParam {
     /**审核标识*/
     private String auditFlag;
 
+    /**结束备注**/
+    private String endReason;
+
 }

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

@@ -108,4 +108,7 @@ public interface BizOrderService extends IService<BizOrder> {
 
     /**审核**/
     void auditOrder(BizOrderEditParam bizOrderEditParam);
+
+    /**提交*/
+    void submit(BizOrderEditParam bizOrderEditParam);
 }

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

@@ -12,11 +12,13 @@
  */
 package vip.xiaonuo.biz.modular.bizorder.service.impl;
 
+import cn.dev33.satoken.stp.StpUtil;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollStreamUtil;
 import cn.hutool.core.img.ImgUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -27,6 +29,14 @@ 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.auth.api.SaBaseLoginUserApi;
+import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
+import vip.xiaonuo.biz.modular.bizconfig.entity.BizConfig;
+import vip.xiaonuo.biz.modular.bizconfig.service.BizConfigService;
+import vip.xiaonuo.biz.modular.bizorderconfig.entity.BizOrderConfig;
+import vip.xiaonuo.biz.modular.bizorderconfig.service.BizOrderConfigService;
+import vip.xiaonuo.biz.modular.bizsaleorder.entity.BizSaleOrder;
+import vip.xiaonuo.biz.modular.bizsaleorder.service.BizSaleOrderService;
 import vip.xiaonuo.biz.modular.customer.entity.BizCustomer;
 import vip.xiaonuo.biz.modular.customer.service.BizCustomerService;
 import vip.xiaonuo.biz.modular.bizorder.param.*;
@@ -45,6 +55,7 @@ import java.math.BigDecimal;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 订单管理Service接口实现类
@@ -64,6 +75,18 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
     @Resource
     private BizGoodsConfService bizGoodsConfService;
 
+    @Resource
+    private BizOrderConfigService orderConfigService;
+
+    @Resource
+    private BizConfigService bizConfigService;
+
+    @Resource
+    private BizSaleOrderService bizSaleOrderService;
+
+    @Resource(name = "loginUserApi")
+    private SaBaseLoginUserApi loginUserApi;
+
     @Override
     public Page<BizOrder> page(BizOrderPageParam bizOrderPageParam) {
         QueryWrapper<BizOrder> queryWrapper = getQueryWrapper(bizOrderPageParam);
@@ -82,11 +105,11 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
         }
         //客户名称查询
         if(ObjectUtil.isNotEmpty(bizOrderPageParam.getCustomerName())){
-            queryWrapper.like("bc.customer_name",bizOrderPageParam.getCustomerName());
+            queryWrapper.like("bc.name",bizOrderPageParam.getCustomerName());
         }
         //货品名称查询
         if(ObjectUtil.isNotEmpty(bizOrderPageParam.getGoodsName())){
-            queryWrapper.like("bg.`NAME`",bizOrderPageParam.getGoodsName());
+            queryWrapper.like("bg.`GOODS_NAME`",bizOrderPageParam.getGoodsName());
         }
         //状态查询
         if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderStatus())){
@@ -96,6 +119,11 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
         if(ObjectUtil.isNotEmpty(bizOrderPageParam.getOrderSource())){
             queryWrapper.eq("bo.order_source",bizOrderPageParam.getOrderSource());
         }
+        // 校验数据范围
+        List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
+        if(ObjectUtil.isEmpty(loginUserDataScope)) {
+            queryWrapper.eq("bo.customer_id", StpLoginUserUtil.getLoginUser().getCustomerId());
+        }
         queryWrapper.eq("bo.delete_flag","NOT_DELETE");
         queryWrapper.orderByDesc("bo.create_time");
         return queryWrapper;
@@ -118,11 +146,20 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
         bizOrder.setOrderWeight(bizOrder.getOrderWeight().multiply(new BigDecimal(1000)));
         //来源,手动新增
         bizOrder.setOrderSource("2");
-        bizOrder.setOrderStatus("1");
+        bizOrder.setOrderStatus("0");
         this.save(bizOrder);
 
         //修改时段配置内物品重量
         bizGoodsConfService.editUsedWeight(bizGoodsConf.getId(),bizOrderAddParam.getOrderWeight().multiply(new BigDecimal(1000)).doubleValue());
+
+        //修改销售订单状态
+        if(ObjectUtil.isNotEmpty(bizOrderAddParam.getSaleOrderInfo())){
+            BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrderAddParam.getSaleOrderInfo());
+            if(ObjectUtil.isNotNull(bizSaleOrder)){
+                bizSaleOrder.setSaleStatus("2");
+                bizSaleOrderService.updateById(bizSaleOrder);
+            }
+        }
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -161,6 +198,26 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
                 bizGoodsConfService.editUsedWeight(bizGoodsConf.getId(),bizOrderEditParam.getOrderWeight().multiply(new BigDecimal(1000)).doubleValue());
             }
         }
+        //判断是否修改订单
+        if(!StringUtils.equals(bizOrder.getSaleOrderInfo(),bizOrderEditParam.getSaleOrderInfo())){
+            long count = this.count(new QueryWrapper<BizOrder>().lambda().eq(BizOrder::getSaleOrderInfo, bizOrderEditParam.getSaleOrderInfo()));
+            if(count>0){
+                throw new CommonException("销售订单已经添加过!");
+            }
+            //修改之前订单状态
+            BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrder.getSaleOrderInfo());
+            if(ObjectUtil.isNotNull(bizSaleOrder)){
+                bizSaleOrder.setSaleStatus("1");
+                bizSaleOrderService.updateById(bizSaleOrder);
+            }
+
+            //修改现在订单状态
+            BizSaleOrder saleOrder = bizSaleOrderService.getById(bizOrderEditParam.getSaleOrderInfo());
+            if(ObjectUtil.isNotNull(saleOrder)){
+                saleOrder.setSaleStatus("2");
+                bizSaleOrderService.updateById(saleOrder);
+            }
+        }
         BeanUtil.copyProperties(bizOrderEditParam, bizOrder);
         bizOrder.setGoodId(bizGoodsConf.getGoodsId());
         //设置订单重量
@@ -183,6 +240,13 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
                 //修改时段配置内物品重量
                 bizGoodsConfService.editUsedWeight(bizGoodsConf.getId(),bizOrder.getOrderWeight().negate().doubleValue());
             }
+
+            //查询销售订单信息
+            BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrder.getSaleOrderInfo());
+            if(ObjectUtil.isNotNull(bizSaleOrder)){
+                bizSaleOrder.setSaleStatus("1");
+                bizSaleOrderService.updateById(bizSaleOrder);
+            }
         }
         // 执行删除
         this.removeByIds(CollStreamUtil.toList(bizOrderIdParamList, BizOrderIdParam::getId));
@@ -267,11 +331,21 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
         this.updateById(bizOrder);
     }
 
+    @Transactional
     @Override
     public void orderConfirm(BizOrderEditParam bizOrderEditParam) {
         BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
         bizOrder.setOrderStatus("3");
         this.updateById(bizOrder);
+
+        //存取预约次数配置
+        BizOrderConfig bizOrderConfig = new BizOrderConfig();
+        bizOrderConfig.setOrderId(bizOrder.getId());
+        BizConfig bizConfig = bizConfigService.getOne(new QueryWrapper<BizConfig>().lambda().last("limit 1"));
+        if(ObjectUtil.isNotNull(bizConfig)){
+            bizOrderConfig.setApplyNumber(bizConfig.getApplyCount());
+        }
+        orderConfigService.save(bizOrderConfig);
     }
 
     @Override
@@ -280,15 +354,23 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
         if(bizOrder.getNetWeight().compareTo(BigDecimal.ZERO) != 0){
             BigDecimal orderBalance = bizOrder.getOrderWeight().subtract(bizOrder.getNetWeight());
             BigDecimal result = orderBalance.divide(bizOrder.getOrderWeight()).multiply(new BigDecimal(100));
-            if(result.compareTo(new BigDecimal(80)) >= 0){
+            if(result.compareTo(new BigDecimal(20)) <= 0){
                 //大于80%不需要审核
                 bizOrder.setOrderStatus("7");
+
+                //销售订单结束
+                BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrder.getSaleOrderInfo());
+                if(ObjectUtil.isNotNull(bizSaleOrder)){
+                    bizSaleOrder.setSaleStatus("3");
+                    bizSaleOrderService.updateById(bizSaleOrder);
+                }
             }else{
                 bizOrder.setOrderStatus("5");
             }
         }else{
-            bizOrder.setOrderStatus("7");
+            bizOrder.setOrderStatus("5");
         }
+        bizOrder.setEndReason(bizOrderEditParam.getEndReason());
         this.updateById(bizOrder);
     }
 
@@ -298,15 +380,29 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
         if(ObjectUtil.isNotEmpty(bizOrderEditParam.getAuditFlag())){
             if(StringUtils.equals(bizOrderEditParam.getAuditFlag(),"true")){
                 //驳回
-                bizOrder.setOrderStatus("6");
+                bizOrder.setOrderStatus("4");
                 bizOrder.setOrderReason(bizOrderEditParam.getOrderReason());
             }else{
                 bizOrder.setOrderStatus("7");
+
+                //销售订单结束
+                BizSaleOrder bizSaleOrder = bizSaleOrderService.getById(bizOrder.getSaleOrderInfo());
+                if(ObjectUtil.isNotNull(bizSaleOrder)){
+                    bizSaleOrder.setSaleStatus("3");
+                    bizSaleOrderService.updateById(bizSaleOrder);
+                }
             }
             this.updateById(bizOrder);
         }
     }
 
+    @Override
+    public void submit(BizOrderEditParam bizOrderEditParam) {
+        BizOrder bizOrder = this.queryEntity(bizOrderEditParam.getId());
+        bizOrder.setOrderStatus("1");
+        this.updateById(bizOrder);
+    }
+
     public static void main(String[] args) {
         String result = "";
         try {

+ 3 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorderconfig/service/impl/BizOrderConfigServiceImpl.java

@@ -70,6 +70,9 @@ public class BizOrderConfigServiceImpl extends ServiceImpl<BizOrderConfigMapper,
     @Override
     public void edit(BizOrderConfigEditParam bizOrderConfigEditParam) {
         BizOrderConfig bizOrderConfig = this.queryEntity(bizOrderConfigEditParam.getId());
+        if(bizOrderConfigEditParam.getApplyNumber()<=bizOrderConfig.getApplyNumberAlready()){
+            throw new CommonException("申请数量必须大于已约数量!");
+        }
         BeanUtil.copyProperties(bizOrderConfigEditParam, bizOrderConfig);
         this.updateById(bizOrderConfig);
     }

+ 144 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/controller/BizSaleOrderController.java

@@ -0,0 +1,144 @@
+/*
+ * 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.bizsaleorder.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.bizsaleorder.entity.BizSaleOrder;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderAddParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderEditParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderIdParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderPageParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.service.BizSaleOrderService;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 销售订单控制器
+ *
+ * @author fanzherong
+ * @date  2025/04/10 09:31
+ */
+@Tag(name = "销售订单控制器")
+@RestController
+@Validated
+public class BizSaleOrderController {
+
+    @Resource
+    private BizSaleOrderService bizSaleOrderService;
+
+    /**
+     * 获取销售订单分页
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    @Operation(summary = "获取销售订单分页")
+    @SaCheckPermission("/biz/bizsaleorder/page")
+    @GetMapping("/biz/bizsaleorder/page")
+    public CommonResult<Page<BizSaleOrder>> page(BizSaleOrderPageParam bizSaleOrderPageParam) {
+        return CommonResult.data(bizSaleOrderService.page(bizSaleOrderPageParam));
+    }
+
+    /**
+     * 添加销售订单
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    @Operation(summary = "添加销售订单")
+    @CommonLog("添加销售订单")
+    @PostMapping("/biz/bizsaleorder/add")
+    public CommonResult<String> add(@RequestBody @Valid BizSaleOrderAddParam bizSaleOrderAddParam) {
+        bizSaleOrderService.add(bizSaleOrderAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑销售订单
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    @Operation(summary = "编辑销售订单")
+    @CommonLog("编辑销售订单")
+    @PostMapping("/biz/bizsaleorder/edit")
+    public CommonResult<String> edit(@RequestBody @Valid BizSaleOrderEditParam bizSaleOrderEditParam) {
+        bizSaleOrderService.edit(bizSaleOrderEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除销售订单
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    @Operation(summary = "删除销售订单")
+    @CommonLog("删除销售订单")
+    @PostMapping("/biz/bizsaleorder/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   List<BizSaleOrderIdParam> bizSaleOrderIdParamList) {
+        bizSaleOrderService.delete(bizSaleOrderIdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取销售订单详情
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    @Operation(summary = "获取销售订单详情")
+    @GetMapping("/biz/bizsaleorder/detail")
+    public CommonResult<BizSaleOrder> detail(@Valid BizSaleOrderIdParam bizSaleOrderIdParam) {
+        return CommonResult.data(bizSaleOrderService.detail(bizSaleOrderIdParam));
+    }
+
+
+    /**
+     * 根据客户id查询销售订单信息
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    @Operation(summary = "根据客户id查询销售订单信息")
+    @GetMapping("/biz/bizsaleorder/queryByCustomerId")
+    public CommonResult<List<BizSaleOrder>> queryByCustomerId(@Valid BizSaleOrderIdParam bizSaleOrderIdParam) {
+        return CommonResult.data(bizSaleOrderService.queryByCustomerId(bizSaleOrderIdParam));
+    }
+
+    /**
+     * 详情(重量转换)
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    @Operation(summary = "详情(重量转换)")
+    @GetMapping("/biz/bizsaleorder/detailById")
+    public CommonResult<BizSaleOrder> detailById(@Valid BizSaleOrderIdParam bizSaleOrderIdParam) {
+        return CommonResult.data(bizSaleOrderService.detailById(bizSaleOrderIdParam));
+    }
+}

+ 73 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/entity/BizSaleOrder.java

@@ -0,0 +1,73 @@
+/*
+ * 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.bizsaleorder.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/04/10 09:31
+ **/
+@Getter
+@Setter
+@TableName("biz_sale_order")
+public class BizSaleOrder extends CommonEntity {
+
+    /** 主键ID */
+    @TableId
+    @Schema(description = "主键ID")
+    private String id;
+
+    /** 销售订单编号 */
+    @Schema(description = "销售订单编号")
+    private String saleOrderNumber;
+
+    /** 销售订单名称 */
+    @Schema(description = "销售订单名称")
+    private String saleOrderName;
+
+    /** 订单类型(1:常规订单   2:服务订单) */
+    @Schema(description = "订单类型(1:常规订单   2:服务订单)")
+    private String saleOrderType;
+
+    /** 货品名称 */
+    @Schema(description = "货品名称")
+    private String saleGoodsName;
+
+    /** 销售订单重量 */
+    @Schema(description = "销售订单重量")
+    private BigDecimal saleOrderWeight;
+
+    /**状态(1:待执行  2:执行中   3:结束)*/
+    private String saleStatus;
+
+    /***客户id*/
+    private String customerId;
+
+    @TableField(exist = false)
+    /**客户名称*/
+    private String customerName;
+
+    /**货品编码*/
+    private String saleGoodsCode;
+
+}

+ 34 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/enums/BizSaleOrderEnum.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.bizsaleorder.enums;
+
+import lombok.Getter;
+
+/**
+ * 销售订单枚举
+ *
+ * @author fanzherong
+ * @date  2025/04/10 09:31
+ **/
+@Getter
+public enum BizSaleOrderEnum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    BizSaleOrderEnum(String value) {
+        this.value = value;
+    }
+}

+ 30 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/mapper/BizSaleOrderMapper.java

@@ -0,0 +1,30 @@
+/*
+ * 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.bizsaleorder.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.bizsaleorder.entity.BizSaleOrder;
+
+/**
+ * 销售订单Mapper接口
+ *
+ * @author fanzherong
+ * @date  2025/04/10 09:31
+ **/
+public interface BizSaleOrderMapper extends BaseMapper<BizSaleOrder> {
+
+    Page<BizSaleOrder> getPage(@Param("page") Page page, @Param("ew") QueryWrapper<BizSaleOrder> ew);
+}

+ 21 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/mapper/mapping/BizSaleOrderMapper.xml

@@ -0,0 +1,21 @@
+<?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.bizsaleorder.mapper.BizSaleOrderMapper">
+
+    <select id="getPage" resultType="vip.xiaonuo.biz.modular.bizsaleorder.entity.BizSaleOrder">
+        select
+            bso.id,
+            bso.sale_order_number,
+            bso.sale_order_name,
+            bso.sale_order_type,
+            bso.sale_goods_name,
+            bso.sale_order_weight/1000 sale_order_weight,
+            bso.sale_status,
+            bso.customer_id,
+            bc.name customerName,
+            bso.sale_goods_code
+        from biz_sale_order bso
+        left join biz_customer bc on bc.id = bso.customer_id
+        ${ew.customSqlSegment}
+    </select>
+</mapper>

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

@@ -0,0 +1,60 @@
+/*
+ * Copyright [2022] [https://www.xiaonuo.vip]
+ *
+ * Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
+ *
+ * 1.请不要删除和修改根目录下的LICENSE文件。
+ * 2.请不要删除和修改Snowy源码头部的版权声明。
+ * 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
+ * 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
+ * 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
+ * 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
+ */
+package vip.xiaonuo.biz.modular.bizsaleorder.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/04/10 09:31
+ **/
+@Getter
+@Setter
+public class BizSaleOrderAddParam {
+
+    /** 销售订单编号 */
+    @Schema(description = "销售订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String saleOrderNumber;
+
+    /** 销售订单名称 */
+    @Schema(description = "销售订单名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String saleOrderName;
+
+    /** 订单类型(1:常规订单   2:服务订单) */
+    @Schema(description = "订单类型(1:常规订单   2:服务订单)", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String saleOrderType;
+
+    /** 货品名称 */
+    @Schema(description = "货品名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String saleGoodsName;
+
+    /** 销售订单重量 */
+    @Schema(description = "销售订单重量", requiredMode = Schema.RequiredMode.REQUIRED)
+    private BigDecimal saleOrderWeight;
+
+    /***客户id*/
+    private String customerId;
+
+    /**货品编码*/
+    private String saleGoodsCode;
+
+}

+ 65 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/param/BizSaleOrderEditParam.java

@@ -0,0 +1,65 @@
+/*
+ * 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.bizsaleorder.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/04/10 09:31
+ **/
+@Getter
+@Setter
+public class BizSaleOrderEditParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 销售订单编号 */
+    @Schema(description = "销售订单编号", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String saleOrderNumber;
+
+    /** 销售订单名称 */
+    @Schema(description = "销售订单名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String saleOrderName;
+
+    /** 订单类型(1:常规订单   2:服务订单) */
+    @Schema(description = "订单类型(1:常规订单   2:服务订单)", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String saleOrderType;
+
+    /** 货品名称 */
+    @Schema(description = "货品名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    private String saleGoodsName;
+
+    /** 销售订单重量 */
+    @Schema(description = "销售订单重量", requiredMode = Schema.RequiredMode.REQUIRED)
+    private BigDecimal saleOrderWeight;
+
+    /***客户id*/
+    private String customerId;
+
+    /**货品编码*/
+    private String saleGoodsCode;
+
+}

+ 37 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/param/BizSaleOrderIdParam.java

@@ -0,0 +1,37 @@
+/*
+ * 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.bizsaleorder.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/04/10 09:31
+ **/
+@Getter
+@Setter
+public class BizSaleOrderIdParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    private String flag;
+}

+ 63 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/param/BizSaleOrderPageParam.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.bizsaleorder.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/04/10 09:31
+ **/
+@Getter
+@Setter
+public class BizSaleOrderPageParam {
+
+    /** 当前页 */
+    @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 saleOrderNumber;
+
+    /**订单名称*/
+    private String saleOrderName;
+
+    /**订单类型**/
+    private String saleOrderType;
+
+    /**货品名称*/
+    private String saleGoodsName;
+
+}

+ 85 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/service/BizSaleOrderService.java

@@ -0,0 +1,85 @@
+/*
+ * 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.bizsaleorder.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import vip.xiaonuo.biz.modular.bizsaleorder.entity.BizSaleOrder;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderAddParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderEditParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderIdParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderPageParam;
+
+import java.util.List;
+
+/**
+ * 销售订单Service接口
+ *
+ * @author fanzherong
+ * @date  2025/04/10 09:31
+ **/
+public interface BizSaleOrderService extends IService<BizSaleOrder> {
+
+    /**
+     * 获取销售订单分页
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    Page<BizSaleOrder> page(BizSaleOrderPageParam bizSaleOrderPageParam);
+
+    /**
+     * 添加销售订单
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    void add(BizSaleOrderAddParam bizSaleOrderAddParam);
+
+    /**
+     * 编辑销售订单
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    void edit(BizSaleOrderEditParam bizSaleOrderEditParam);
+
+    /**
+     * 删除销售订单
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    void delete(List<BizSaleOrderIdParam> bizSaleOrderIdParamList);
+
+    /**
+     * 获取销售订单详情
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     */
+    BizSaleOrder detail(BizSaleOrderIdParam bizSaleOrderIdParam);
+
+    /**
+     * 获取销售订单详情
+     *
+     * @author fanzherong
+     * @date  2025/04/10 09:31
+     **/
+    BizSaleOrder queryEntity(String id);
+
+    /**根据客户id查询销售订单信息*/
+    List<BizSaleOrder> queryByCustomerId(BizSaleOrderIdParam bizSaleOrderIdParam);
+
+    BizSaleOrder detailById(BizSaleOrderIdParam bizSaleOrderIdParam);
+}

+ 163 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/service/impl/BizSaleOrderServiceImpl.java

@@ -0,0 +1,163 @@
+/*
+ * 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.bizsaleorder.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.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.biz.modular.goods.entity.BizGoods;
+import vip.xiaonuo.biz.modular.goods.service.BizGoodsService;
+import vip.xiaonuo.common.enums.CommonSortOrderEnum;
+import vip.xiaonuo.common.exception.CommonException;
+import vip.xiaonuo.common.page.CommonPageRequest;
+import vip.xiaonuo.biz.modular.bizsaleorder.entity.BizSaleOrder;
+import vip.xiaonuo.biz.modular.bizsaleorder.mapper.BizSaleOrderMapper;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderAddParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderEditParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderIdParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.param.BizSaleOrderPageParam;
+import vip.xiaonuo.biz.modular.bizsaleorder.service.BizSaleOrderService;
+
+import javax.annotation.RegEx;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 销售订单Service接口实现类
+ *
+ * @author fanzherong
+ * @date  2025/04/10 09:31
+ **/
+@Service
+public class BizSaleOrderServiceImpl extends ServiceImpl<BizSaleOrderMapper, BizSaleOrder> implements BizSaleOrderService {
+
+    @Resource
+    private BizGoodsService goodsService;
+
+    @Override
+    public Page<BizSaleOrder> page(BizSaleOrderPageParam bizSaleOrderPageParam) {
+        QueryWrapper<BizSaleOrder> queryWrapper = new QueryWrapper<BizSaleOrder>().checkSqlInjection();
+        //订单编号查询
+        if(ObjectUtil.isNotEmpty(bizSaleOrderPageParam.getSaleOrderNumber())){
+            queryWrapper.like("bso.sale_order_number",bizSaleOrderPageParam.getSaleOrderNumber());
+        }
+        //订单名称查询
+        if(ObjectUtil.isNotEmpty(bizSaleOrderPageParam.getSaleOrderName())){
+            queryWrapper.like("bso.sale_order_name",bizSaleOrderPageParam.getSaleOrderName());
+        }
+        //订单类型查询
+        if(ObjectUtil.isNotEmpty(bizSaleOrderPageParam.getSaleOrderType())){
+            queryWrapper.eq("bso.sale_order_type",bizSaleOrderPageParam.getSaleOrderType());
+        }
+        //货品名称查询
+        if(ObjectUtil.isNotEmpty(bizSaleOrderPageParam.getSaleGoodsName())){
+            queryWrapper.like("bso.sale_goods_name",bizSaleOrderPageParam.getSaleGoodsName());
+        }
+        queryWrapper.eq("bso.delete_flag","NOT_DELETE");
+        queryWrapper.orderByDesc("bso.create_time");
+        return this.getBaseMapper().getPage(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(BizSaleOrderAddParam bizSaleOrderAddParam) {
+        long count = this.count(new QueryWrapper<BizSaleOrder>().lambda().
+                eq(BizSaleOrder::getSaleOrderNumber, bizSaleOrderAddParam.getSaleOrderNumber()));
+        if(count>0){
+            throw new CommonException("订单编号已经存在!");
+        }
+        BizSaleOrder bizSaleOrder = BeanUtil.toBean(bizSaleOrderAddParam, BizSaleOrder.class);
+        BizGoods bizGoods = goodsService.getOne(new QueryWrapper<BizGoods>().lambda()
+                .eq(BizGoods::getGoodsCode, bizSaleOrderAddParam.getSaleGoodsCode()).
+                last("limit 1"));
+        if(ObjectUtil.isNotNull(bizGoods)){
+            bizSaleOrder.setSaleGoodsName(bizGoods.getGoodsName());
+        }
+        bizSaleOrder.setSaleOrderWeight(bizSaleOrderAddParam.getSaleOrderWeight().multiply(new BigDecimal(1000)));
+        this.save(bizSaleOrder);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(BizSaleOrderEditParam bizSaleOrderEditParam) {
+        BizSaleOrder bizSaleOrder = this.queryEntity(bizSaleOrderEditParam.getId());
+        if(!StringUtils.equals(bizSaleOrder.getSaleOrderNumber(),bizSaleOrderEditParam.getSaleOrderNumber())){
+            long count = this.count(new QueryWrapper<BizSaleOrder>().lambda().
+                    eq(BizSaleOrder::getSaleOrderNumber, bizSaleOrderEditParam.getSaleOrderNumber()));
+            if(count>0){
+                throw new CommonException("订单编号已经存在!");
+            }
+        }
+        BeanUtil.copyProperties(bizSaleOrderEditParam, bizSaleOrder);
+        bizSaleOrder.setSaleOrderWeight(bizSaleOrderEditParam.getSaleOrderWeight().multiply(new BigDecimal(1000)));
+        BizGoods bizGoods = goodsService.getOne(new QueryWrapper<BizGoods>().lambda()
+                .eq(BizGoods::getGoodsCode, bizSaleOrderEditParam.getSaleGoodsCode()).
+                last("limit 1"));
+        if(ObjectUtil.isNotNull(bizGoods)){
+            bizSaleOrder.setSaleGoodsName(bizGoods.getGoodsName());
+        }
+        this.updateById(bizSaleOrder);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<BizSaleOrderIdParam> bizSaleOrderIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(bizSaleOrderIdParamList, BizSaleOrderIdParam::getId));
+    }
+
+    @Override
+    public BizSaleOrder detail(BizSaleOrderIdParam bizSaleOrderIdParam) {
+        BizSaleOrder bizSaleOrder = this.queryEntity(bizSaleOrderIdParam.getId());
+        return bizSaleOrder;
+    }
+
+    @Override
+    public BizSaleOrder queryEntity(String id) {
+        BizSaleOrder bizSaleOrder = this.getById(id);
+        if(ObjectUtil.isEmpty(bizSaleOrder)) {
+            throw new CommonException("销售订单不存在,id值为:{}", id);
+        }
+        return bizSaleOrder;
+    }
+
+    @Override
+    public List<BizSaleOrder> queryByCustomerId(BizSaleOrderIdParam bizSaleOrderIdParam) {
+        QueryWrapper<BizSaleOrder> queryWrapper = new QueryWrapper<>();
+        queryWrapper.lambda().eq(BizSaleOrder::getCustomerId, bizSaleOrderIdParam.getId());
+        if(StringUtils.equals(bizSaleOrderIdParam.getFlag(),"add")){
+            queryWrapper.lambda().eq(BizSaleOrder::getSaleStatus, "1");
+        }
+        //根据客户id查询待执行状态的销售订单
+        List<BizSaleOrder> list = this.list(queryWrapper);
+        for(BizSaleOrder bizSaleOrder : list){
+            bizSaleOrder.setSaleOrderWeight(bizSaleOrder.getSaleOrderWeight().divide(new BigDecimal(1000)));
+        }
+        return list;
+    }
+
+    @Override
+    public BizSaleOrder detailById(BizSaleOrderIdParam bizSaleOrderIdParam) {
+        BizSaleOrder bizSaleOrder = this.queryEntity(bizSaleOrderIdParam.getId());
+        bizSaleOrder.setSaleOrderWeight(bizSaleOrder.getSaleOrderWeight().divide(new BigDecimal(1000)));
+        return bizSaleOrder;
+    }
+}

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

@@ -116,4 +116,16 @@ public class BizVehicleController {
     public CommonResult<BizVehicle> detail(@Valid BizVehicleIdParam bizVehicleIdParam) {
         return CommonResult.data(bizVehicleService.detail(bizVehicleIdParam));
     }
+
+    /**
+     * 获取个人长期车辆
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    @Operation(summary = "获取个人长期车辆")
+    @GetMapping("/biz/bizvehicle/queryByUserId")
+    public CommonResult<BizVehicle> queryByUserId() {
+        return CommonResult.data(bizVehicleService.queryByUserId());
+    }
 }

+ 5 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/service/BizVehicleService.java

@@ -77,4 +77,9 @@ public interface BizVehicleService extends IService<BizVehicle> {
      * @date  2025/04/08 09:26
      **/
     BizVehicle queryEntity(String id);
+
+    /**
+     * 个人长期车辆接口
+     */
+    BizVehicle queryByUserId();
 }

+ 19 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/service/impl/BizVehicleServiceImpl.java

@@ -22,9 +22,12 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import jakarta.annotation.Resource;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import vip.xiaonuo.auth.core.util.StpLoginUserUtil;
+import vip.xiaonuo.biz.modular.bizexcessconfig.entity.BizExcessConfig;
+import vip.xiaonuo.biz.modular.bizexcessconfig.service.BizExcessConfigService;
 import vip.xiaonuo.common.enums.CommonSortOrderEnum;
 import vip.xiaonuo.common.exception.CommonException;
 import vip.xiaonuo.common.page.CommonPageRequest;
@@ -49,6 +52,9 @@ import java.util.regex.Pattern;
 @Service
 public class BizVehicleServiceImpl extends ServiceImpl<BizVehicleMapper, BizVehicle> implements BizVehicleService {
 
+    @Resource
+    private BizExcessConfigService bizExcessConfigService;
+
     @Override
     public Page<BizVehicle> page(BizVehiclePageParam bizVehiclePageParam) {
         QueryWrapper<BizVehicle> queryWrapper = new QueryWrapper<BizVehicle>().checkSqlInjection();
@@ -199,6 +205,19 @@ public class BizVehicleServiceImpl extends ServiceImpl<BizVehicleMapper, BizVehi
         return bizVehicle;
     }
 
+    @Override
+    public BizVehicle queryByUserId() {
+        BizVehicle bizVehicle = this.getOne(new QueryWrapper<BizVehicle>().lambda().
+                eq(BizVehicle::getStatus, "1").
+                eq(BizVehicle::getCreateUser, StpLoginUserUtil.getLoginUser().getId()).
+                last("limit 1"));
+        BizExcessConfig excessConfig = bizExcessConfigService.getById(bizVehicle.getVehicleAxles());
+        if(ObjectUtil.isNotNull(excessConfig)){
+            bizVehicle.setVehicleAxleNumber(excessConfig.getVehicleAxleNumber().toString());
+        }
+        return bizVehicle;
+    }
+
     /**
      * 车牌号校验
      * @param carNumber

+ 123 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/controller/OfficialInfoController.java

@@ -0,0 +1,123 @@
+/*
+ * 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.officialinfo.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.officialinfo.entity.OfficialInfo;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoAddParam;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoEditParam;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoIdParam;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoPageParam;
+import vip.xiaonuo.biz.modular.officialinfo.service.OfficialInfoService;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 微信公众号关注表控制器
+ *
+ * @author fanzherong
+ * @date  2025/04/10 17:31
+ */
+@Tag(name = "微信公众号关注表控制器")
+@RestController
+@Validated
+public class OfficialInfoController {
+
+    @Resource
+    private OfficialInfoService officialInfoService;
+
+    /**
+     * 获取微信公众号关注表分页
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    @Operation(summary = "获取微信公众号关注表分页")
+    @SaCheckPermission("/biz/officialinfo/page")
+    @GetMapping("/biz/officialinfo/page")
+    public CommonResult<Page<OfficialInfo>> page(OfficialInfoPageParam officialInfoPageParam) {
+        return CommonResult.data(officialInfoService.page(officialInfoPageParam));
+    }
+
+    /**
+     * 添加微信公众号关注表
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    @Operation(summary = "添加微信公众号关注表")
+    @CommonLog("添加微信公众号关注表")
+    @SaCheckPermission("/biz/officialinfo/add")
+    @PostMapping("/biz/officialinfo/add")
+    public CommonResult<String> add(@RequestBody @Valid OfficialInfoAddParam officialInfoAddParam) {
+        officialInfoService.add(officialInfoAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑微信公众号关注表
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    @Operation(summary = "编辑微信公众号关注表")
+    @CommonLog("编辑微信公众号关注表")
+    @SaCheckPermission("/biz/officialinfo/edit")
+    @PostMapping("/biz/officialinfo/edit")
+    public CommonResult<String> edit(@RequestBody @Valid OfficialInfoEditParam officialInfoEditParam) {
+        officialInfoService.edit(officialInfoEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除微信公众号关注表
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    @Operation(summary = "删除微信公众号关注表")
+    @CommonLog("删除微信公众号关注表")
+    @SaCheckPermission("/biz/officialinfo/delete")
+    @PostMapping("/biz/officialinfo/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   List<OfficialInfoIdParam> officialInfoIdParamList) {
+        officialInfoService.delete(officialInfoIdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取微信公众号关注表详情
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    @Operation(summary = "获取微信公众号关注表详情")
+    @SaCheckPermission("/biz/officialinfo/detail")
+    @GetMapping("/biz/officialinfo/detail")
+    public CommonResult<OfficialInfo> detail(@Valid OfficialInfoIdParam officialInfoIdParam) {
+        return CommonResult.data(officialInfoService.detail(officialInfoIdParam));
+    }
+}

+ 63 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/entity/OfficialInfo.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.officialinfo.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/04/10 17:31
+ **/
+@Getter
+@Setter
+@TableName("biz_official_info")
+public class OfficialInfo extends CommonEntity {
+
+    /** 主键Id */
+    @TableId
+    @Schema(description = "主键Id")
+    private String id;
+
+    /** 公众号ID */
+    @Schema(description = "公众号ID")
+    private String officialOpenId;
+
+    /** union_id */
+    @Schema(description = "union_id")
+    private String unionId;
+
+    /** 关注状态 0.取消关注  1. 已关注 */
+    @Schema(description = "关注状态 0.取消关注  1. 已关注")
+    private Integer status;
+
+    /** 微信名 */
+    @Schema(description = "微信名")
+    private String nickName;
+
+    /** 微信头像 */
+    @Schema(description = "微信头像")
+    private String wxHead;
+
+    /** 微信地址 */
+    @Schema(description = "微信地址")
+    private String wxAddress;
+}

+ 34 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/enums/OfficialInfoEnum.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.officialinfo.enums;
+
+import lombok.Getter;
+
+/**
+ * 微信公众号关注表枚举
+ *
+ * @author fanzherong
+ * @date  2025/04/10 17:31
+ **/
+@Getter
+public enum OfficialInfoEnum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    OfficialInfoEnum(String value) {
+        this.value = value;
+    }
+}

+ 25 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/mapper/OfficialInfoMapper.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.officialinfo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import vip.xiaonuo.biz.modular.officialinfo.entity.OfficialInfo;
+
+/**
+ * 微信公众号关注表Mapper接口
+ *
+ * @author fanzherong
+ * @date  2025/04/10 17:31
+ **/
+public interface OfficialInfoMapper extends BaseMapper<OfficialInfo> {
+}

+ 5 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/mapper/mapping/OfficialInfoMapper.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.officialinfo.mapper.OfficialInfoMapper">
+
+</mapper>

+ 58 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoAddParam.java

@@ -0,0 +1,58 @@
+/*
+ * 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.officialinfo.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/04/10 17:31
+ **/
+@Getter
+@Setter
+public class OfficialInfoAddParam {
+
+    /** 公众号ID */
+    @Schema(description = "公众号ID")
+    private String officialOpenId;
+
+    /** union_id */
+    @Schema(description = "union_id")
+    private String unionId;
+
+    /** 关注状态 0.取消关注  1. 已关注 */
+    @Schema(description = "关注状态 0.取消关注  1. 已关注")
+    private Integer status;
+
+    /** 微信名 */
+    @Schema(description = "微信名")
+    private String nickName;
+
+    /** 微信头像 */
+    @Schema(description = "微信头像")
+    private String wxHead;
+
+    /** 微信地址 */
+    @Schema(description = "微信地址")
+    private String wxAddress;
+
+}

+ 63 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoEditParam.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.officialinfo.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/04/10 17:31
+ **/
+@Getter
+@Setter
+public class OfficialInfoEditParam {
+
+    /** 主键Id */
+    @Schema(description = "主键Id", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 公众号ID */
+    @Schema(description = "公众号ID")
+    private String officialOpenId;
+
+    /** union_id */
+    @Schema(description = "union_id")
+    private String unionId;
+
+    /** 关注状态 0.取消关注  1. 已关注 */
+    @Schema(description = "关注状态 0.取消关注  1. 已关注")
+    private Integer status;
+
+    /** 微信名 */
+    @Schema(description = "微信名")
+    private String nickName;
+
+    /** 微信头像 */
+    @Schema(description = "微信头像")
+    private String wxHead;
+
+    /** 微信地址 */
+    @Schema(description = "微信地址")
+    private String wxAddress;
+
+}

+ 35 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoIdParam.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.officialinfo.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/04/10 17:31
+ **/
+@Getter
+@Setter
+public class OfficialInfoIdParam {
+
+    /** 主键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/officialinfo/param/OfficialInfoPageParam.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.officialinfo.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/04/10 17:31
+ **/
+@Getter
+@Setter
+public class OfficialInfoPageParam {
+
+    /** 当前页 */
+    @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/officialinfo/service/OfficialInfoService.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.officialinfo.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import vip.xiaonuo.biz.modular.officialinfo.entity.OfficialInfo;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoAddParam;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoEditParam;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoIdParam;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoPageParam;
+
+import java.util.List;
+
+/**
+ * 微信公众号关注表Service接口
+ *
+ * @author fanzherong
+ * @date  2025/04/10 17:31
+ **/
+public interface OfficialInfoService extends IService<OfficialInfo> {
+
+    /**
+     * 获取微信公众号关注表分页
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    Page<OfficialInfo> page(OfficialInfoPageParam officialInfoPageParam);
+
+    /**
+     * 添加微信公众号关注表
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    void add(OfficialInfoAddParam officialInfoAddParam);
+
+    /**
+     * 编辑微信公众号关注表
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    void edit(OfficialInfoEditParam officialInfoEditParam);
+
+    /**
+     * 删除微信公众号关注表
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    void delete(List<OfficialInfoIdParam> officialInfoIdParamList);
+
+    /**
+     * 获取微信公众号关注表详情
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     */
+    OfficialInfo detail(OfficialInfoIdParam officialInfoIdParam);
+
+    /**
+     * 获取微信公众号关注表详情
+     *
+     * @author fanzherong
+     * @date  2025/04/10 17:31
+     **/
+    OfficialInfo queryEntity(String id);
+}

+ 94 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/service/impl/OfficialInfoServiceImpl.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.officialinfo.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.officialinfo.entity.OfficialInfo;
+import vip.xiaonuo.biz.modular.officialinfo.mapper.OfficialInfoMapper;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoAddParam;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoEditParam;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoIdParam;
+import vip.xiaonuo.biz.modular.officialinfo.param.OfficialInfoPageParam;
+import vip.xiaonuo.biz.modular.officialinfo.service.OfficialInfoService;
+
+import java.util.List;
+
+/**
+ * 微信公众号关注表Service接口实现类
+ *
+ * @author fanzherong
+ * @date  2025/04/10 17:31
+ **/
+@Service
+public class OfficialInfoServiceImpl extends ServiceImpl<OfficialInfoMapper, OfficialInfo> implements OfficialInfoService {
+
+    @Override
+    public Page<OfficialInfo> page(OfficialInfoPageParam officialInfoPageParam) {
+        QueryWrapper<OfficialInfo> queryWrapper = new QueryWrapper<OfficialInfo>().checkSqlInjection();
+        if(ObjectUtil.isAllNotEmpty(officialInfoPageParam.getSortField(), officialInfoPageParam.getSortOrder())) {
+            CommonSortOrderEnum.validate(officialInfoPageParam.getSortOrder());
+            queryWrapper.orderBy(true, officialInfoPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
+                    StrUtil.toUnderlineCase(officialInfoPageParam.getSortField()));
+        } else {
+            queryWrapper.lambda().orderByAsc(OfficialInfo::getId);
+        }
+        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(OfficialInfoAddParam officialInfoAddParam) {
+        OfficialInfo officialInfo = BeanUtil.toBean(officialInfoAddParam, OfficialInfo.class);
+        this.save(officialInfo);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(OfficialInfoEditParam officialInfoEditParam) {
+        OfficialInfo officialInfo = this.queryEntity(officialInfoEditParam.getId());
+        BeanUtil.copyProperties(officialInfoEditParam, officialInfo);
+        this.updateById(officialInfo);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<OfficialInfoIdParam> officialInfoIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(officialInfoIdParamList, OfficialInfoIdParam::getId));
+    }
+
+    @Override
+    public OfficialInfo detail(OfficialInfoIdParam officialInfoIdParam) {
+        return this.queryEntity(officialInfoIdParam.getId());
+    }
+
+    @Override
+    public OfficialInfo queryEntity(String id) {
+        OfficialInfo officialInfo = this.getById(id);
+        if(ObjectUtil.isEmpty(officialInfo)) {
+            throw new CommonException("微信公众号关注表不存在,id值为:{}", id);
+        }
+        return officialInfo;
+    }
+}

+ 5 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/entity/BizRecord.java

@@ -219,5 +219,9 @@ public class BizRecord extends CommonEntity {
     private String unloadImg;
     private String unloadName;
 
-    private String auditReason;
+    private String auditSign;
+
+    @TableField(exist = false)
+    /**订单类型*/
+    private String orderType;
 }

+ 52 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/mapper/mapping/BizRecordMapper.xml

@@ -267,9 +267,60 @@
 
     <select id="getPage" resultType="vip.xiaonuo.biz.modular.record.entity.BizRecord">
         select
-            br.*,
+            br.ID,
+            br.RELATION_ID,
+            br.LICENSE_PLATE,
+            br.PLATE_COLOR,
+            br.CAR_NUMBER,
+            br.GROSS_TIME,
+            br.TARE_TIME,
+            br.TARE_TYPE,
+            br.GROSS_WEIGHT/1000 GROSS_WEIGHT,
+            br.TARE_WEIGHT/1000 TARE_WEIGHT,
+            br.NET_WEIGHT/1000 NET_WEIGHT,
+            br.KF_WEIGHT/1000 KF_WEIGHT,
+            br.DRIVER_NAME,
+            br.DRIVER_MOBILE,
+            br.GOODS_NAME,
+            br.GOODS_MODEL,
+            br.RECEIPT_COMPANY,
+            br.SHIPPING_COMPANY,
+            br.TRANSPORT_COMPANY,
+            br.TRANSPORT_ROUTE,
+            br.GROSS_PLATE_NAME,
+            br.GROSS_LICENSE_NAME,
+            br.GROSS_CAPTURE_HEAD,
+            br.GROSS_CAPTURE_TAIL,
+            br.GROSS_CAPTURE_WARE,
+            br.GROSS_CAPTURE_BODY,
+            br.GROSS_CAPTURE_POUND_ROOM,
+            br.TARE_PLATE_NAME,
+            br.TARE_LICENSE_NAME,
+            br.TARE_CAPTURE_HEAD,
+            br.TARE_CAPTURE_TAIL,
+            br.TARE_CAPTURE_WARE,
+            br.TARE_CAPTURE_BODY,
+            br.TARE_CAPTURE_POUND_ROOM,
+            br.EXT_KEY1,
+            br.EXT_KEY2,
+            br.DELETE_FLAG,
+            br.CREATE_TIME,
+            br.CREATE_USER,
+            br.UPDATE_TIME,
+            br.UPDATE_USER,
+            br.weighing_type,
+            br.appointment_id,
+            br.order_id,
+            br.confirm_user,
+            br.appointment_user,
+            br.driver_sign,
+            br.unload_weight/1000 unload_weight,
+            br.unload_img,
+            br.unload_name,
+            br.audit_sign,
             bo.order_name,
             bo.order_number,
+            bo.order_type,
             bc.name customerName,
             bar.status
         from biz_record br

+ 1 - 1
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/param/BizRecordEditParam.java

@@ -198,6 +198,6 @@ public class BizRecordEditParam {
 
     private String auditFlag;
 
-    private String auditReason;
+    private String auditSign;
 
 }

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

@@ -118,4 +118,7 @@ public class BizRecordPageParam {
     /**签收审核标识*/
     private String signFlag;
 
+    /**发货确认状态*/
+    private String sendRecordStatus;
+
 }

+ 39 - 22
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/result/BizRecordExportResult.java

@@ -41,30 +41,17 @@ public class BizRecordExportResult {
     private String carNumber;
 
     /** 车牌号码 */
+    @ColumnWidth(20)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "车牌号码"})
     private String licensePlate;
 
     /** 车牌颜色 */
+    @ColumnWidth(20)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "车牌颜色"})
     private String plateColor;
 
-    /** 毛重 */
-    @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
-    @ExcelProperty({"过磅记录", "称重信息", "毛重(KG)"})
-    private BigDecimal grossWeight;
-
-    /** 皮重 */
-    @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
-    @ExcelProperty({"过磅记录", "称重信息", "皮重(KG)"})
-    private BigDecimal tareWeight;
-
-    /** 净重 */
-    @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
-    @ExcelProperty({"过磅记录", "称重信息", "净重(KG)"})
-    private BigDecimal netWeight;
-
     /** 过毛时间 */
     @ColumnWidth(30)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
@@ -79,62 +66,92 @@ public class BizRecordExportResult {
     @ExcelProperty({"过磅记录", "称重信息", "过皮时间"})
     private Date tareTime;
 
+    /** 毛重 */
+    @ColumnWidth(20)
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
+    @ExcelProperty({"过磅记录", "称重信息", "毛重(吨)"})
+    private BigDecimal grossWeight;
+
+    /** 皮重 */
+    @ColumnWidth(20)
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
+    @ExcelProperty({"过磅记录", "称重信息", "皮重(吨)"})
+    private BigDecimal tareWeight;
+
+    /** 净重 */
+    @ColumnWidth(20)
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
+    @ExcelProperty({"过磅记录", "称重信息", "净重(吨)"})
+    private BigDecimal netWeight;
+
 
     /** 订单名称 */
+    @ColumnWidth(20)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "订单信息", "订单名称"})
     private String orderName;
 
     /** 订单编号 */
+    @ColumnWidth(20)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "订单信息", "订单编号"})
     private String orderNumber;
 
+    /** 客户名称 */
+    @ColumnWidth(20)
+    @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
+    @ExcelProperty({"过磅记录", "客户名称"})
+    private String customerName;
+
     /** 货品名称 */
+    @ColumnWidth(20)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "货品信息", "货品名称"})
     private String goodsName;
 
     /** 货品规格 */
+    @ColumnWidth(20)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "货品信息", "货品规格"})
     private String goodsModel;
 
-    /** 收货单位 */
+    /** 收货单位 *//*
     @ColumnWidth(50)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "货品信息", "收货单位"})
     private String receiptCompany;
 
-    /** 发货单位 */
+    *//** 发货单位 *//*
     @ColumnWidth(50)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "货品信息", "发货单位"})
     private String shippingCompany;
 
-    /** 运输单位 */
+    *//** 运输单位 *//*
     @ColumnWidth(50)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "货品信息", "运输单位"})
-    private String transportCompany;
+    private String transportCompany;*/
 
     /** 司机姓名 */
+    @ColumnWidth(20)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "司机信息", "司机姓名"})
     private String driverName;
 
     /** 司机电话 */
+    @ColumnWidth(20)
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "司机信息", "司机电话"})
     private String driverMobile;
 
-    /** 人员状态 */
+   /* *//** 人员状态 *//*
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "备注1"})
     private String extKey1;
 
-    /** 人员状态 */
+    *//** 人员状态 *//*
     @HeadStyle(fillPatternType = FillPatternTypeEnum.NO_FILL)
     @ExcelProperty({"过磅记录", "备注2"})
-    private String extKey2;
+    private String extKey2;*/
 }

+ 46 - 18
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/service/impl/BizRecordServiceImpl.java

@@ -143,12 +143,22 @@ public class BizRecordServiceImpl extends ServiceImpl<BizRecordMapper, BizRecord
             queryWrapper.like("br.TRANSPORT_COMPANY",bizRecordPageParam.getTransportCompany());
         }
         if (ObjectUtil.isNotEmpty(bizRecordPageParam.getIsFlag())){
-            queryWrapper.eq("br.weighing_type","1");
+            //queryWrapper.eq("br.weighing_type","1");
         }
         if (ObjectUtil.isNotEmpty(bizRecordPageParam.getSignFlag())){
             queryWrapper.in("bar.status","10","11","12","13");
             queryWrapper.eq("bo.order_type","1");
         }
+        //发货确认状态查询
+        if (ObjectUtil.isNotEmpty(bizRecordPageParam.getSendRecordStatus())){
+            if(StringUtils.equals(bizRecordPageParam.getSendRecordStatus(),"1")){
+                //待确认
+                queryWrapper.isNull("br.confirm_user");
+            }else{
+                //已确认
+                queryWrapper.isNotNull("br.confirm_user");
+            }
+        }
         if (ObjectUtil.isNotEmpty(bizRecordPageParam.getOrderName())){
             queryWrapper.like("bo.order_name",bizRecordPageParam.getOrderName());
         }
@@ -156,7 +166,7 @@ public class BizRecordServiceImpl extends ServiceImpl<BizRecordMapper, BizRecord
             queryWrapper.like("bo.order_number",bizRecordPageParam.getOrderNumber());
         }
         if (ObjectUtil.isNotEmpty(bizRecordPageParam.getCustomerName())){
-            queryWrapper.like("bc.customer_name",bizRecordPageParam.getCustomerName());
+            queryWrapper.like("bc.name",bizRecordPageParam.getCustomerName());
         }
         if (ObjectUtil.isNotEmpty(bizRecordPageParam.getOrderId())){
             queryWrapper.eq("br.order_id",bizRecordPageParam.getOrderId());
@@ -615,21 +625,16 @@ public class BizRecordServiceImpl extends ServiceImpl<BizRecordMapper, BizRecord
         this.updateById(bizRecord);
 
         //净重和卸货重量进行对比
-        BigDecimal weight = new BigDecimal(0);
-        if(bizRecord.getNetWeight().compareTo(bizRecordEditParam.getUnloadWeight()) > 0){
-            weight = bizRecord.getNetWeight().subtract(bizRecordEditParam.getUnloadWeight());
-        }else{
-            weight = bizRecordEditParam.getUnloadWeight().subtract(bizRecord.getNetWeight());
-        }
+        BigDecimal weight = bizRecord.getNetWeight().subtract(bizRecordEditParam.getUnloadWeight().multiply(new BigDecimal(1000))).negate();
         //如果差值等于0说明没有误差,预约状态修改为11,已签收
-        //查询预约记录
+        //查询预约记录run
         BizAppointmentRecord appointmentRecord = bizAppointmentRecordService.getById(bizRecord.getAppointmentId());
         if(ObjectUtil.isNotNull(appointmentRecord)){
             if(weight.compareTo(BigDecimal.ZERO) == 0){
                 appointmentRecord.setStatus("11");
             }else{
                 //计算差值百分比
-                BigDecimal decimal = weight.divide(bizRecord.getNetWeight()).multiply(new BigDecimal(100));
+                BigDecimal decimal = weight.divide(bizRecord.getNetWeight(),2,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
                 BizConfig bizConfig = bizConfigService.getOne(new QueryWrapper<BizConfig>().lambda().last("limit 1"));
                 if(decimal.compareTo(bizConfig.getLossWarn()) > 0){
                     appointmentRecord.setStatus("12");
@@ -641,18 +646,41 @@ public class BizRecordServiceImpl extends ServiceImpl<BizRecordMapper, BizRecord
         }
     }
 
+    public static void main(String[] args) {
+        BigDecimal subtract = new BigDecimal(15400).subtract(new BigDecimal(15).multiply(new BigDecimal(1000)));
+        BigDecimal decimal = subtract.divide(new BigDecimal(15000), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100));
+        if(decimal.compareTo(new BigDecimal(2)) > 0){
+            System.out.printf("大于2");
+        }else{
+            System.out.printf("小于等于2");
+        }
+
+        BigDecimal subtract1 = new BigDecimal(15000).subtract(new BigDecimal(15.3).multiply(new BigDecimal(1000))).negate();
+        System.out.printf("sbu:"+subtract1);
+
+    }
+
     @Override
     public void auditRecord(BizRecordEditParam bizRecordEditParam) {
         BizRecord bizRecord = this.queryEntity(bizRecordEditParam.getId());
-        bizRecord.setAuditReason(bizRecordEditParam.getAuditReason());
+        if(ObjectUtil.isEmpty(bizRecordEditParam.getAuditSign())){
+            throw new CommonException("签名不能为空!");
+        }
+        String auditSign = bizRecordEditParam.getAuditSign();
+        if(bizRecordEditParam.getAuditSign().contains(StrUtil.COMMA)) {
+            auditSign = StrUtil.split(auditSign, StrUtil.COMMA).get(1);
+        }
+        String base64 = ImgUtil.toBase64DataUri(ImgUtil.scale(ImgUtil.toImage(auditSign),
+                100, 50, null), ImgUtil.IMAGE_TYPE_PNG);
+
+        bizRecord.setAuditSign(base64);
         this.updateById(bizRecord);
-        if(ObjectUtil.isNotEmpty(bizRecordEditParam.getAuditFlag())){
-            //查询预约记录
-            BizAppointmentRecord appointmentRecord = bizAppointmentRecordService.getById(bizRecord.getAppointmentId());
-            if(ObjectUtil.isNotNull(appointmentRecord)){
-                appointmentRecord.setStatus("13");
-                bizAppointmentRecordService.updateById(appointmentRecord);
-            }
+
+        //查询预约记录
+        BizAppointmentRecord appointmentRecord = bizAppointmentRecordService.getById(bizRecord.getAppointmentId());
+        if(ObjectUtil.isNotNull(appointmentRecord)){
+            appointmentRecord.setStatus("13");
+            bizAppointmentRecordService.updateById(appointmentRecord);
         }
     }
 }

+ 45 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/MsgUtil.java

@@ -0,0 +1,45 @@
+package vip.xiaonuo.biz.modular.utils;
+
+/**
+ * @author liuqh
+ * @date 2020-02-20 10:10
+ * @description
+ */
+public class MsgUtil {
+
+    public static final String MSGTYPE_EVENT = "event";//消息类型--事件
+    public static final String MESSAGE_SUBSCIBE = "subscribe";//消息事件类型--订阅事件
+    public static final String MESSAGE_UNSUBSCIBE = "unsubscribe";//消息事件类型--取消订阅事件
+    public static final String MESSAGE_TEXT = "text";//消息类型--文本消息
+
+    /**
+     * 组装文本消息
+     */
+    public static String textMsg(String toUserName,String fromUserName,String content){
+//        TextMsg text = new TextMsg();
+//        text.setFromUserName(toUserName);
+//        text.setToUserName(fromUserName);
+//        text.setMsgType(MESSAGE_TEXT);
+//        text.setCreateTime(new Date().getTime());
+//        text.setContent(content);
+//        return XmlUtil.textMsgToxml(text);
+        return null;
+    }
+
+    /**
+     * 响应订阅事件--回复文本消息
+     */
+    public static String subscribeForText(String toUserName,String fromUserName,String content){
+        return textMsg(toUserName, fromUserName, content);
+    }
+
+    /**
+     * 响应取消订阅事件
+     */
+    public static String unsubscribeForText(String toUserName,String fromUserName,String content){
+        System.out.println("用户:"+ fromUserName +"取消关注~");
+        return "";
+    }
+}
+
+

+ 78 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/SignUtil.java

@@ -0,0 +1,78 @@
+package vip.xiaonuo.biz.modular.utils;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+
+/**
+ * @author liuqh
+ * @date 2019-08-13 16:20
+ * @description
+ */
+public class SignUtil {
+
+    /**
+     * 验证签名
+     * @param token
+     * @param signature 签名用来核实最后的结果是否一致
+     * @param timestamp 时间标记
+     * @param nonce 随机数字标记
+     * @return 一个布尔值确定最后加密得到的是否与signature一致
+     */
+    public static boolean checkSignature(String token, String signature, String timestamp, String nonce) {
+        //将传入参数变成一个String数组然后进行字典排序
+        String[] arr = new String[] { token, timestamp, nonce };
+        // 将token、timestamp、nonce三个参数进行字典排序
+        Arrays.sort(arr);
+        //创建一个对象储存排序后三个String的结合体
+        StringBuilder content = new StringBuilder();
+        for (int i = 0; i < arr.length; i++) {
+            content.append(arr[i]);
+        }
+        MessageDigest md = null;
+        String tmpStr = null;
+
+        try {
+            md = MessageDigest.getInstance("SHA-1");
+            byte[] digest = md.digest(content.toString().getBytes());
+            tmpStr = byteToStr(digest);
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+
+        content = null;
+        // 将sha1加密后的字符串可与signature对比
+        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     * @param byteArray
+     * @return
+     */
+    private static String byteToStr(byte[] byteArray) {
+        String strDigest = "";
+        for (int i = 0; i < byteArray.length; i++) {
+            strDigest += byteToHexStr(byteArray[i]);
+        }
+        return strDigest;
+    }
+
+    /**
+     * 将每一个字节转换为十六进制字符串
+     * @param mByte
+     * @return
+     */
+    private static String byteToHexStr(byte mByte) {
+        //转位数参照表
+        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+        char[] tempArr = new char[2];
+        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
+        tempArr[1] = Digit[mByte & 0X0F];
+        //得到进制码的字符串
+        String s = new String(tempArr);
+        return s;
+    }
+}
+
+

+ 43 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/XmlUtil.java

@@ -0,0 +1,43 @@
+package vip.xiaonuo.biz.modular.utils;
+
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class XmlUtil {
+
+
+    /**
+     * 简单解析xml
+     * @param in
+     * @return
+     */
+    public static Map<String,Object> parseXML(InputStream in){
+
+
+        Map<String,Object> map=new HashMap<>();
+        try {
+            SAXReader saxReader = new SAXReader();
+            Document document = saxReader.read(in);
+            Element root = document.getRootElement();
+            Iterator iterator = root.elementIterator();
+            while (iterator.hasNext()){
+
+                Element element = (Element) iterator.next();
+                map.put(element.getName(),element.getStringValue());
+
+            }
+        } catch (DocumentException e) {
+            e.printStackTrace();
+        }
+
+        return map;
+    }
+
+}

+ 3 - 0
snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/user/entity/SysUser.java

@@ -288,4 +288,7 @@ public class SysUser extends CommonEntity {
 
     @Schema(description = "用户类型 1:客户账号   2:司机账号")
     private String userType;
+
+    /**客户id*/
+    private String customerId;
 }

+ 6 - 1
snowy-web-app/src/main/java/vip/xiaonuo/core/config/GlobalConfigure.java

@@ -199,7 +199,12 @@ public class GlobalConfigure implements WebMvcConfigurer {
             "/biz/user/miniAdd",
 
             /*用友推送客户接口*/
-            "/biz/customer/yongAdd"
+            "/biz/customer/yongAdd",
+
+            //微信公众号接口
+            "/api/**"
+
+
     };
 
     /**

+ 2 - 2
snowy-web-app/src/main/resources/application-dev.properties

@@ -20,7 +20,7 @@ spring.servlet.multipart.max-file-size=100MB
 
 # mysql
 spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
-spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/hnzy?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&useInformationSchema=true&rewriteBatchedStatements=true
+spring.datasource.dynamic.datasource.master.url=jdbc:mysql://192.168.25.72:3306/hnzy?useUnicode=true&characterEncoding=utf-8&useSSL=false&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&useInformationSchema=true&rewriteBatchedStatements=true
 spring.datasource.dynamic.datasource.master.username=hnzy
 spring.datasource.dynamic.datasource.master.password=MRXPibTNd6FNLRSp
 spring.datasource.dynamic.strict=true
@@ -93,7 +93,7 @@ spring.jackson.serialization.write-dates-as-timestamps=false
 # redis configuration
 #########################################
 spring.data.redis.database=1
-spring.data.redis.host=127.0.0.1
+spring.data.redis.host=192.168.25.72
 spring.data.redis.port=6379
 spring.data.redis.password=4008809192
 spring.data.redis.timeout=10s

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

@@ -204,3 +204,9 @@ snowy.config.common.mqtt-url=tcp://218.2.6.74:13883
 snowy.config.common.mqtt-name=bydz-smt
 snowy.config.common.mqtt-password=bydzsmt123!@#
 snowy.config.common.mqtt-clientId=my-mqtt-client-id
+
+#?????
+snowy.config.common.official-token=jswhzl
+snowy.config.common.official-aeskey=YFalph4k6OpXoSnBdV5Z3qpJC6MpGJ3KKgN3sRCPuqk
+snowy.config.common.official-appId=wx0b5b039f123f51d9
+snowy.config.common.official-secret=b724494616d4e1ca74cd4f71c2f6cfee