Browse Source

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

xuchao 1 month ago
parent
commit
be633d2ab1
100 changed files with 4496 additions and 190 deletions
  1. 20 0
      .gitignore
  2. 1 1
      snowy-admin-web/.env.development
  3. 3 3
      snowy-admin-web/.env.production
  4. 4 0
      snowy-admin-web/src/api/biz/bizOrderApi.js
  5. 36 0
      snowy-admin-web/src/api/biz/bizSaleOrderApi.js
  6. 28 0
      snowy-admin-web/src/api/biz/bizVehicleApi.js
  7. 24 0
      snowy-admin-web/src/api/biz/customerAccountApi.js
  8. 2 1
      snowy-admin-web/src/components/HomeCard/SysUserInfoCard/index.vue
  9. 3 1
      snowy-admin-web/src/views/biz/bizappointmentrecord/detail.vue
  10. 25 9
      snowy-admin-web/src/views/biz/bizappointmentrecord/index.vue
  11. 4 0
      snowy-admin-web/src/views/biz/bizconfig/form.vue
  12. 8 0
      snowy-admin-web/src/views/biz/bizconfig/index.vue
  13. 2 2
      snowy-admin-web/src/views/biz/bizexcessconfig/form.vue
  14. 64 0
      snowy-admin-web/src/views/biz/bizorder/end.vue
  15. 24 12
      snowy-admin-web/src/views/biz/bizorder/form.vue
  16. 39 7
      snowy-admin-web/src/views/biz/bizorder/index.vue
  17. 9 3
      snowy-admin-web/src/views/biz/bizqueuerecord/index.vue
  18. 122 0
      snowy-admin-web/src/views/biz/bizsaleorder/form.vue
  19. 237 0
      snowy-admin-web/src/views/biz/bizsaleorder/index.vue
  20. 115 0
      snowy-admin-web/src/views/biz/bizvehicle/form.vue
  21. 188 0
      snowy-admin-web/src/views/biz/bizvehicle/index.vue
  22. 78 0
      snowy-admin-web/src/views/biz/customer/accountAdd.vue
  23. 107 0
      snowy-admin-web/src/views/biz/customer/accountIndex.vue
  24. 1 5
      snowy-admin-web/src/views/biz/customer/form.vue
  25. 11 15
      snowy-admin-web/src/views/biz/customer/index.vue
  26. 62 2
      snowy-admin-web/src/views/biz/record/detail.vue
  27. 6 0
      snowy-common/src/main/java/vip/xiaonuo/common/prop/CommonProperties.java
  28. 71 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/api/controller/ApiController.java
  29. 167 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/api/service/ApiService.java
  30. 4 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/entity/BizAppointmentRecord.java
  31. 3 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/mapper/mapping/BizAppointmentRecordMapper.xml
  32. 1 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizappointmentrecord/service/impl/BizAppointmentRecordServiceImpl.java
  33. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizconfig/entity/BizConfig.java
  34. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizconfig/param/BizConfigAddParam.java
  35. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizconfig/param/BizConfigEditParam.java
  36. 14 2
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizexcessconfig/service/impl/BizExcessConfigServiceImpl.java
  37. 14 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/controller/BizOrderController.java
  38. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/entity/BizOrder.java
  39. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/param/BizOrderEditParam.java
  40. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/service/BizOrderService.java
  41. 73 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizorder/service/impl/BizOrderServiceImpl.java
  42. 144 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/controller/BizSaleOrderController.java
  43. 70 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. 20 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/mapper/mapping/BizSaleOrderMapper.xml
  47. 62 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/param/BizSaleOrderAddParam.java
  48. 67 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. 144 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/service/impl/BizSaleOrderServiceImpl.java
  53. 131 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/controller/BizVehicleController.java
  54. 62 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/entity/BizVehicle.java
  55. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/enums/BizVehicleEnum.java
  56. 29 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/mapper/BizVehicleMapper.java
  57. 20 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/mapper/mapping/BizVehicleMapper.xml
  58. 54 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/param/BizVehicleAddParam.java
  59. 59 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/param/BizVehicleEditParam.java
  60. 35 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/param/BizVehicleIdParam.java
  61. 60 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/param/BizVehiclePageParam.java
  62. 85 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/service/BizVehicleService.java
  63. 230 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/service/impl/BizVehicleServiceImpl.java
  64. 94 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/controller/BizCustomerAccountController.java
  65. 0 14
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/controller/BizCustomerController.java
  66. 0 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/entity/BizCustomer.java
  67. 47 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/entity/BizCustomerAccount.java
  68. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/enums/BizCustomerAccountEnum.java
  69. 25 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/mapper/BizCustomerAccountMapper.java
  70. 5 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/mapper/mapping/BizCustomerAccountMapper.xml
  71. 37 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerAccountAddParam.java
  72. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerAccountIdParam.java
  73. 53 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerAccountPageParam.java
  74. 0 5
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerAddParam.java
  75. 0 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerEditParam.java
  76. 0 4
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerPageParam.java
  77. 63 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/service/BizCustomerAccountService.java
  78. 0 8
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/service/BizCustomerService.java
  79. 131 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/service/impl/BizCustomerAccountServiceImpl.java
  80. 0 71
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/service/impl/BizCustomerServiceImpl.java
  81. 123 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/controller/OfficialInfoController.java
  82. 63 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/entity/OfficialInfo.java
  83. 34 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/enums/OfficialInfoEnum.java
  84. 25 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/mapper/OfficialInfoMapper.java
  85. 5 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/mapper/mapping/OfficialInfoMapper.xml
  86. 58 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoAddParam.java
  87. 63 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoEditParam.java
  88. 35 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoIdParam.java
  89. 51 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/param/OfficialInfoPageParam.java
  90. 80 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/service/OfficialInfoService.java
  91. 94 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/officialinfo/service/impl/OfficialInfoServiceImpl.java
  92. 1 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/entity/BizRecord.java
  93. 1 1
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/param/BizRecordEditParam.java
  94. 19 9
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/record/service/impl/BizRecordServiceImpl.java
  95. 3 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/user/entity/BizUser.java
  96. 45 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/MsgUtil.java
  97. 78 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/SignUtil.java
  98. 43 0
      snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/utils/XmlUtil.java
  99. 3 0
      snowy-web-app/src/main/resources/application-dev.properties
  100. 6 0
      snowy-web-app/src/main/resources/application-local.properties

+ 20 - 0
.gitignore

@@ -0,0 +1,20 @@
+.idea/compiler.xml
+.idea/
+snowy-common/target/
+snowy-plugin/snowy-plugin-auth/target/
+snowy-plugin/snowy-plugin-biz/target/
+snowy-plugin/snowy-plugin-client/target/
+snowy-plugin/snowy-plugin-dev/target/
+snowy-plugin/snowy-plugin-gen/target/
+snowy-plugin/snowy-plugin-mobile/target/
+snowy-plugin/snowy-plugin-sys/target/
+snowy-plugin-api/snowy-plugin-auth-api/target/
+snowy-plugin-api/snowy-plugin-biz-api/target/
+snowy-plugin-api/snowy-plugin-dev-api/target/
+snowy-plugin-api/snowy-plugin-mobile-api/target/
+snowy-plugin-api/snowy-plugin-sys-api/target/
+snowy-web-app/target/
+snowy-admin-web/package.json
+snowy-web-app/src/main/resources/application.properties
+snowy-web-app/src/main/resources/application-local.properties
+snowy-web-app/src/main/resources/application-test.properties

+ 1 - 1
snowy-admin-web/.env.development

@@ -14,4 +14,4 @@ NODE_ENV = development
 VITE_VERSION_UPDATE = false
 
 #文件访问地址
-VITE_PREVIEW_PATH = http://db.js-whzl.com:8065/preview/
+VITE_PREVIEW_PATH = https://db.js-whzl.com:8055/preview/

+ 3 - 3
snowy-admin-web/.env.production

@@ -1,5 +1,5 @@
-# 接口地址
-VITE_API_BASEURL = http://127.0.0.1:83
+# 接口地址(测试环境)
+VITE_API_BASEURL = https://wx.js-whzl.com:10008/api
 
 # 本地端口
 VITE_PORT = 81
@@ -11,4 +11,4 @@ VITE_SET_DRAWER = false
 VITE_VERSION_UPDATE = true
 
 #文件访问地址
-VITE_PREVIEW_PATH = http://db.js-whzl.com:8065/preview/
+VITE_PREVIEW_PATH = https://db.js-whzl.com:8055/preview/

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

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

@@ -0,0 +1,28 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/bizvehicle/` + url, ...arg)
+
+/**
+ * 车辆信息Api接口管理器
+ *
+ * @author fanzherong
+ * @date  2025/04/08 09:26
+ **/
+export default {
+	// 获取车辆信息分页
+	bizVehiclePage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交车辆信息表单 edit为true时为编辑,默认为新增
+	bizVehicleSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除车辆信息
+	bizVehicleDelete(data) {
+		return request('delete', data)
+	},
+	// 获取车辆信息详情
+	bizVehicleDetail(data) {
+		return request('detail', data, 'get')
+	}
+}

+ 24 - 0
snowy-admin-web/src/api/biz/customerAccountApi.js

@@ -0,0 +1,24 @@
+import { baseRequest } from '@/utils/request'
+
+const request = (url, ...arg) => baseRequest(`/biz/customerAccount/` + url, ...arg)
+
+/**
+ * 客户账号Api接口管理器
+ *
+ * @author sandy
+ * @date  2025/04/09 17:00
+ **/
+export default {
+	// 获取客户账号分页
+	customerAccountPage(data) {
+		return request('page', data, 'get')
+	},
+	// 提交客户账号表单 edit为true时为编辑,默认为新增
+	customerAccountSubmitForm(data, edit = false) {
+		return request(edit ? 'edit' : 'add', data)
+	},
+	// 删除客户账号
+	customerAccountDelete(data) {
+		return request('delete', data)
+	},
+}

+ 2 - 1
snowy-admin-web/src/components/HomeCard/SysUserInfoCard/index.vue

@@ -26,7 +26,8 @@
 	import tool from '@/utils/tool'
 	const userInfo = tool.data.get('USER_INFO')
 
-	const pic = ref('../../../../public/img/logo.png')
+	//const pic = ref('../../../../public/img/logo.png')
+	const pic = ref('../img/logo.png')
 
 	const currentTime = ref(dayjs().format('YYYY年MM月DD日 HH时mm分ss秒'))
 	// 运行定时器,一秒获取一次

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

+ 25 - 9
snowy-admin-web/src/views/biz/bizappointmentrecord/index.vue

@@ -87,6 +87,12 @@
 						<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>
 				</template>
@@ -105,6 +111,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="
@@ -243,7 +252,7 @@
 		{
 			title: '订单信息',
 			dataIndex: 'orderInfo',
-			width:230
+			width:200
 		},
 		{
 			title: '车牌号',
@@ -252,32 +261,38 @@
 			align: 'center'
 		},
 		{
-			title: '提货时段',
-			dataIndex: 'timeInfo',
+			title: '提货开始时间',
+			dataIndex: 'beginTime',
+			align:'center',
+			width:180
+		},
+		{
+			title: '提货结束时间',
+			dataIndex: 'endTime',
 			align:'center',
-			width:360
+			width:180
 		},
 		{
 			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: 'status',
 			align: 'center',
-			width:120
+			width:150
 		},
 	]
 	// 操作栏通过权限判断是否显示
@@ -285,7 +300,8 @@
 		title: '操作',
 		dataIndex: 'action',
 		align: 'center',
-		width: 150
+		width: 150,
+
 	})
 
 	const selectedRowKeys = ref([])

+ 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 - 2
snowy-admin-web/src/views/biz/bizexcessconfig/form.vue

@@ -13,7 +13,7 @@
 			<a-form-item label="超限重量:" name="excessWeight">
 				<a-input-number v-model:value="formData.excessWeight" style="width:90%"  :precision="0" :min="1" :max="999999" placeholder="请输入超限重量" allow-clear /><span style="margin-left:10px;">KG</span>
 			</a-form-item>
-			<a-form-item label="是否启用:" name="status">
+			<a-form-item label="是否启用:" name="status" v-if="formData.id!=null && formData.id!=''">
 				<a-radio-group button-style="solid" v-model:value="formData.status">
 					<a-radio-button value="1">
 						启用
@@ -54,7 +54,7 @@
 			let recordData = cloneDeep(record)
 			formData.value = Object.assign({}, recordData)
 		}else{
-			formData.value.status = '2'
+			formData.value.status = '1'
 		}
 	}
 	// 关闭抽屉

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

+ 24 - 12
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>
@@ -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)=>{

+ 39 - 7
snowy-admin-web/src/views/biz/bizorder/index.vue

@@ -145,11 +145,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' || record.orderStatus == '1')">
 									<a style="color:red" size="small" type="link" @click="deleteConfig(record)">删除</a>
 								</a-menu-item>
 
@@ -178,7 +181,7 @@
 								</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 style="color:red" @click="endRef.showModal(record.id)">结束</a>
 								</a-menu-item>
 							</a-menu>
 						</template>
@@ -198,6 +201,7 @@
 	<Detail ref="detailRef" @successful="tableRef.refresh()" />
 	<Flow ref="flowRef" @successful="tableRef.refresh()" />
 	<Review ref="reviewRef" @successful="tableRef.refresh(true)" />
+	<End ref="endRef" @successful="tableRef.refresh(true)" />
 	<XnSignName ref="XnSignNameRef" :image="searchFormState.orderSign" @successful="signSuccess" />
 
 
@@ -246,18 +250,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 +312,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 +324,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 +473,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 = [

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

@@ -202,10 +202,16 @@
 			align: 'center'
 		},
 		{
-			title: '提货时段',
-			dataIndex: 'timeInfo',
+			title: '提货开始时间',
+			dataIndex: 'beginTime',
 			align:'center',
-			width:360
+			width:180
+		},
+		{
+			title: '提货结束时间',
+			dataIndex: 'endTime',
+			align:'center',
+			width:180
 		},
 		{
 			title: '客户信息',

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

@@ -0,0 +1,122 @@
+<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" @change="onChangeCustomer"
+				> </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="saleGoodsName">
+				<a-input v-model:value="formData.saleGoodsName" placeholder="请输入货品名称" allow-clear />
+			</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'
+	// 抽屉状态
+	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 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
+				}
+			})
+		})
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		saleOrderNumber: [required('请输入销售订单编号')],
+		saleOrderName: [required('请输入销售订单名称')],
+		saleOrderType: [required('请选择订单类型')],
+		saleGoodsName: [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')">编辑</a>
+						<a-divider type="vertical" v-if="hasPerm(['bizSaleOrderEdit', 'bizSaleOrderDelete'], 'and')" />
+						<a-button style="color:red" type="link" danger size="small" v-if="hasPerm('bizSaleOrderDelete')" @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>

+ 115 - 0
snowy-admin-web/src/views/biz/bizvehicle/form.vue

@@ -0,0 +1,115 @@
+<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="licensePlate">
+				<a-input v-model:value="formData.licensePlate" placeholder="请输入车牌号" allow-clear />
+			</a-form-item>
+			<a-form-item label="车辆轴数:" name="vehicleAxles">
+				<a-select v-model:value="formData.vehicleAxles" placeholder="请选择车辆轴数"
+						  :options="overIdList"
+				> </a-select>
+			</a-form-item>
+			<a-form-item label="司机姓名:" name="driverName">
+				<a-input v-model:value="formData.driverName" placeholder="请输入司机姓名" allow-clear />
+			</a-form-item>
+			<a-form-item label="司机电话:" name="driverMobile">
+				<a-input v-model:value="formData.driverMobile" placeholder="请输入司机电话" allow-clear />
+			</a-form-item>
+			<a-form-item label="是否启用:" name="status" v-if="formData.id!=null && formData.id!=''">
+				<a-radio-group button-style="solid" v-model:value="formData.status">
+					<a-radio-button value="1">
+						启用
+					</a-radio-button>
+					<a-radio-button value="2">
+						关闭
+					</a-radio-button>
+				</a-radio-group>
+			</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="bizVehicleForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import bizVehicleApi from '@/api/biz/bizVehicleApi'
+	import bizExcessConfigApi from "@/api/biz/bizExcessConfigApi";
+	// 抽屉状态
+	const open = ref(false)
+	const emit = defineEmits({ successful: null })
+	const formRef = ref()
+	// 表单数据
+	const formData = ref({})
+	const submitLoading = ref(false)
+	const overIdList = ref()
+
+	//设置表单样式
+	const labelCol = ref({ span: 5})
+	const wrapperCol = ref({ span: 16})
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		open.value = true
+		if (record) {
+			let recordData = cloneDeep(record)
+			formData.value = Object.assign({}, recordData)
+		}else{
+			formData.value.status = '1'
+		}
+		//查询车辆轴数
+		bizExcessConfigApi.getList().then((res)=>{
+			overIdList.value = res.map((item)=>{
+				return{
+					value:item.id,
+					label:item.vehicleAxleNumber+'轴'
+				}
+			})
+		})
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		licensePlate: [required('请输入车牌号')],
+		vehicleAxles: [required('请选择车辆轴数')],
+		//driverName: [required('请输入司机姓名')],
+		//driverMobile: [required('请输入司机电话')],
+	}
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				bizVehicleApi
+					.bizVehicleSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 188 - 0
snowy-admin-web/src/views/biz/bizvehicle/index.vue

@@ -0,0 +1,188 @@
+<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="licensePlate">
+						<a-input v-model:value="searchFormState.licensePlate" placeholder="请输入车牌号" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="司机姓名" name="driverName">
+						<a-input v-model:value="searchFormState.driverName" placeholder="请输入司机姓名" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-form-item label="司机电话" name="driverMobile">
+						<a-input v-model:value="searchFormState.driverMobile" placeholder="请输入司机电话" />
+					</a-form-item>
+				</a-col>
+				<a-col :span="6">
+					<a-button type="primary" @click="tableRef.refresh()">查询</a-button>
+					<a-button style="margin: 0 8px" @click="reset">重置</a-button>
+				</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('bizVehicleAdd')">
+						<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('bizVehicleEdit')">编辑</a>
+						<a-divider type="vertical" v-if="hasPerm(['bizVehicleEdit', 'bizVehicleDelete'], 'and')" />
+						<a-button type="link" danger size="small" v-if="hasPerm('bizVehicleDelete')" @click="deleteConfig(record)">删除</a-button>
+					</a-space>
+				</template>
+				<template v-if="column.dataIndex === 'status'">
+					<span v-if="record.status=='1'">启用</span>
+					<span v-else>关闭</span>
+				</template>
+				<template v-if="column.dataIndex === 'vehicleAxleNumber'">
+					{{record.vehicleAxleNumber + '轴'}}
+				</template>
+			</template>
+		</s-table>
+	</a-card>
+	<Form ref="formRef" @successful="tableRef.refresh()" />
+</template>
+
+<script setup name="bizvehicle">
+	import { cloneDeep } from 'lodash-es'
+	import Form from './form.vue'
+	import bizVehicleApi from '@/api/biz/bizVehicleApi'
+	import {ExclamationCircleOutlined} from '@ant-design/icons-vue';
+	import {Modal} from 'ant-design-vue';
+	import {createVNode} from 'vue';
+
+	const submitLoading = ref(false)
+	const tableRef = ref()
+	const formRef = ref()
+	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
+
+	//查询数据
+	const searchFormState = ref({})
+	const searchFormRef = ref()
+
+	const columns = [
+		{
+			title: '车牌号',
+			dataIndex: 'licensePlate',
+			align:'center'
+		},
+		{
+			title: '车辆轴数',
+			dataIndex: 'vehicleAxleNumber',
+			align:'center'
+		},
+		{
+			title: '司机姓名',
+			dataIndex: 'driverName',
+			align:'center'
+		},
+		{
+			title: '司机电话',
+			dataIndex: 'driverMobile',
+			align:'center'
+		},
+		{
+			title: '状态',
+			dataIndex: 'status',
+			align:'center'
+		},
+	]
+	// 操作栏通过权限判断是否显示
+	if (hasPerm(['bizVehicleEdit', 'bizVehicleDelete'])) {
+		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 bizVehicleApi.bizVehiclePage(Object.assign(parameter, searchFormParam)).then((data) => {
+			return data
+		})
+	}
+	// 重置
+	const reset = () => {
+		searchFormRef.value.resetFields()
+		tableRef.value.refresh(true)
+	}
+	// 删除
+	const deleteBizVehicle = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		bizVehicleApi.bizVehicleDelete(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
+					}
+				]
+
+				bizVehicleApi
+					.bizVehicleDelete(params)
+					.then(() => {
+						tableRef.value.refresh(true)
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			},
+			onCancel() {}
+		})
+	}
+	// 批量删除
+	const deleteBatchBizVehicle = (params) => {
+		bizVehicleApi.bizVehicleDelete(params).then(() => {
+			tableRef.value.clearRefreshSelected()
+		})
+	}
+</script>

+ 78 - 0
snowy-admin-web/src/views/biz/customer/accountAdd.vue

@@ -0,0 +1,78 @@
+<template>
+	<xn-form-container
+		:title="'增加客户账号'"
+		: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="loginAccount">
+				<a-input v-model:value="formData.loginAccount" placeholder="请输入客户账号" allow-clear />
+			</a-form-item>
+		</a-form>
+		<template #footer>
+			<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
+			<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
+		</template>
+	</xn-form-container>
+</template>
+
+<script setup name="customerForm">
+	import { cloneDeep } from 'lodash-es'
+	import { required } from '@/utils/formRules'
+	import customerAccountApi from '@/api/biz/customerAccountApi'
+	// 抽屉状态
+	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 onOpen = (recordData) => {
+		open.value = true
+		if (recordData) {
+			formData.value.customerId = recordData.id
+		}
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		formRef.value.resetFields()
+		formData.value = {}
+		open.value = false
+	}
+	// 默认要校验的
+	const formRules = {
+		loginAccount: [required("客户账号")],
+	}
+
+	// 验证并提交数据
+	const onSubmit = () => {
+		formRef.value
+			.validate()
+			.then(() => {
+				submitLoading.value = true
+				const formDataParam = cloneDeep(formData.value)
+				customerAccountApi
+					.customerAccountSubmitForm(formDataParam, formDataParam.id)
+					.then(() => {
+						onClose()
+						emit('successful')
+					})
+					.finally(() => {
+						submitLoading.value = false
+					})
+			})
+			.catch(() => {})
+	}
+	// 抛出函数
+	defineExpose({
+		onOpen
+	})
+</script>

+ 107 - 0
snowy-admin-web/src/views/biz/customer/accountIndex.vue

@@ -0,0 +1,107 @@
+<template>
+	<a-drawer title="客户账号管理" :width="650" :open="visible" :destroy-on-close="true" @close="onClose">
+		<s-table
+			ref="tableRef"
+			:columns="columns"
+			:data="loadData"
+			:alert="false"
+			:row-key="(record) => record.id"
+			:tool-config="toolConfig"
+		>
+			<template #operator class="table-operator">
+				<a-button type="primary" v-if="hasPerm('customerAccountAdd')" @click="accountAddForm.onOpen(recordData)">
+					<template #icon>
+						<plus-outlined />
+					</template>
+					<span>新增账号</span>
+				</a-button>
+			</template>
+			<template #bodyCell="{ column, record, index }">
+				<template v-if="column.dataIndex === 'serial'">
+					{{ index + 1 }}
+				</template>
+				<template v-if="column.dataIndex === 'action'">
+					<a-space>
+						<a-popconfirm title="确定要删除此账号吗?" v-if="hasPerm('customerAccountDelete')" @confirm="deleteCustomerAccount(record)">
+							<a-button type="link" danger size="small">删除</a-button>
+						</a-popconfirm>
+					</a-space>
+				</template>
+			</template>
+		</s-table>
+	</a-drawer>
+	<AccountAddForm ref="accountAddForm" @successful="tableRef.refresh(true)" />
+</template>
+
+<script setup name="accountForm">
+	import customerAccountApi from '@/api/biz/customerAccountApi'
+	import AccountAddForm from './accountAdd.vue'
+
+	const columns = [
+		{
+			title: '序号',
+			width: 50,
+			dataIndex: 'serial',
+			align:'center'
+		},
+		{
+			title: '账号',
+			align:'center',
+			dataIndex: 'loginAccount'
+		},
+	]
+	const toolConfig = { refresh: true, height: false, columnSetting: false, striped: false }
+	// 默认是关闭状态
+	const visible = ref(false)
+	const searchFormState = ref()
+	const accountAddForm = ref()
+	const recordData = ref()
+	const tableRef = ref()
+
+	// 操作栏通过权限判断是否显示
+	if (hasPerm(['customerAccountDelete'])) {
+		columns.push({
+			title: '操作',
+			dataIndex: 'action',
+			align: 'center',
+			width: 150
+		})
+	}
+
+	// 打开抽屉
+	const onOpen = (record) => {
+		recordData.value = record
+		searchFormState.value = {
+			customerId: record.id
+		}
+		visible.value = true
+	}
+	// 加载字段数据
+	const loadData = (parameter) => {
+		return customerAccountApi.customerAccountPage(Object.assign(parameter, searchFormState.value)).then((res) => {
+			return res
+		})
+	}
+	// 关闭抽屉
+	const onClose = () => {
+		visible.value = false
+	}
+	// 删除
+	const deleteCustomerAccount = (record) => {
+		let params = [
+			{
+				id: record.id
+			}
+		]
+		customerAccountApi.customerAccountDelete(params).then(() => {
+			tableRef.value.refresh(true)
+		})
+	}
+	// 调用这个函数将子组件的一些数据和方法暴露出去
+	defineExpose({
+		onOpen
+	})
+</script>
+
+<style scoped>
+</style>

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

@@ -10,9 +10,6 @@
 			<a-form-item label="关联用友平台的ID:" name="yongId">
 				<a-input v-model:value="formData.yongId" placeholder="请输入关联用友平台的ID" allow-clear />
 			</a-form-item>
-			<a-form-item label="客户登录账号:" name="loginAccount">
-				<a-input v-model:value="formData.loginAccount" placeholder="请输入客户登录账号" allow-clear />
-			</a-form-item>
 			<a-form-item label="客户名称:" name="name">
 				<a-input v-model:value="formData.name" placeholder="请输入客户名称" allow-clear />
 			</a-form-item>
@@ -68,8 +65,7 @@
 	}
 	// 默认要校验的
 	const formRules = {
-		yongId: [required("关联用友平台的ID")],
-		loginAccount: [required("客户登录账号")],
+		// yongId: [required("关联用友平台的ID")],
 		name: [required("客户名称")],
 		contact: [required("联系人")],
 		phone: [required("手机号")],

+ 11 - 15
snowy-admin-web/src/views/biz/customer/index.vue

@@ -2,11 +2,6 @@
 	<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="loginAccount">
-						<a-input v-model:value="searchFormState.loginAccount" placeholder="请输入客户登录账号" />
-					</a-form-item>
-				</a-col>
 				<a-col :span="6">
 					<a-form-item label="客户名称" name="name">
 						<a-input v-model:value="searchFormState.name" placeholder="请输入客户名称" />
@@ -48,22 +43,27 @@
 						<a-popconfirm title="确定要删除吗?" @confirm="deleteCustomer(record)">
 							<a-button type="link" danger size="small" v-if="hasPerm('customerDelete')">删除</a-button>
 						</a-popconfirm>
+						<a-divider type="vertical" v-if="hasPerm(['customerEdit', 'customerDelete'], 'or') && hasPerm('customerAccount')" />
+						<a @click="accountFormRef.onOpen(record)" v-if="hasPerm('customerAccount')">账号管理</a>
 					</a-space>
 				</template>
 			</template>
 		</s-table>
 	</a-card>
 	<Form ref="formRef" @successful="tableRef.refresh()" />
+	<AccountForm ref="accountFormRef" @successful="tableRef.refresh()" />
 </template>
 
 <script setup name="customer">
 	import { cloneDeep } from 'lodash-es'
 	import Form from './form.vue'
+	import AccountForm from './accountIndex.vue'
 	import customerApi from '@/api/biz/customerApi'
 	const searchFormState = ref({})
 	const searchFormRef = ref()
 	const tableRef = ref()
 	const formRef = ref()
+	const accountFormRef = ref()	
 	const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
 	const columns = [
 		{
@@ -72,42 +72,38 @@
 			dataIndex: 'serial',
 			align:'center'
 		},
-		{
-			title: '登录账号',
-			dataIndex: 'loginAccount'
-		},
 		{
 			title: '客户名称',
+			width: 180,
 			dataIndex: 'name'
 		},
 		{
 			title: '联系人',
+			width: 80,
 			dataIndex: 'contact'
 		},
 		{
 			title: '手机号',
+			width: 80,
 			dataIndex: 'phone'
 		},
 		{
 			title: '客户地址',
+			width: 250,
 			dataIndex: 'address'
 		},
 		{
 			title: '备注',
 			dataIndex: 'remark'
 		},
-		{
-			title: '关联用友平台的ID',
-			dataIndex: 'yongId'
-		},
 	]
 	// 操作栏通过权限判断是否显示
-	if (hasPerm(['customerEdit', 'customerDelete'])) {
+	if (hasPerm(['customerEdit', 'customerDelete', 'customerAccount'])) {
 		columns.push({
 			title: '操作',
 			dataIndex: 'action',
 			align: 'center',
-			width: 150
+			width: 220
 		})
 	}
 	const selectedRowKeys = ref([])

+ 62 - 2
snowy-admin-web/src/views/biz/record/detail.vue

@@ -21,8 +21,8 @@
 			<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>
@@ -76,6 +76,22 @@
 		<a-space>
 			<a-image :width="200" :src="formData.driverSign" />
 		</a-space>
+		<a-divider></a-divider>
+		<a-descriptions title="司机回签" style="margin-top: 15px">
+			<a-descriptions-item label="卸货重量"><a-tag color="green">{{ formData.unloadWeight }} KG</a-tag></a-descriptions-item>
+		</a-descriptions>
+		<a-space>
+			<div v-for="(item,index) in fileList " :key="item.value">
+				<a-image :width="200" :src="item.url" />
+			</div>
+
+		</a-space>
+		<a-divider></a-divider>
+		<a-descriptions title="平台手签" style="margin-top: 15px">
+		</a-descriptions>
+		<a-space>
+			<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)
@@ -109,6 +126,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)
+			}
 		}
 	}
 	// 关闭抽屉

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

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

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

@@ -112,4 +112,8 @@ public class BizAppointmentRecord extends CommonEntity {
     /**订单重量校验*/
     @TableField(exist = false)
     private String orderWeightSwitch;
+
+    @TableField(exist = false)
+    /**车辆轴数*/
+    private Integer axleNumber;
 }

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

@@ -19,12 +19,14 @@
             bar.driver_mobile,
             bar.status,
             bar.appointment_reason,
-            bar.over_id
+            bar.over_id,
+            bec.vehicle_axle_number axleNumber
         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
         ${ew.customSqlSegment}
     </select>
     <select id="getRecord"

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

@@ -225,7 +225,7 @@ 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())){
+            if(!StringUtils.equals(bizAppointmentRecord.getLicenseNumber(),bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim())){
                 //车牌号修改过
                 if(!isCarNumber(bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim())){
                     throw new CommonException("车牌号:{}格式错误",bizAppointmentRecordEditParam.getLicenseNumber().toUpperCase().trim());

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

+ 14 - 2
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizexcessconfig/service/impl/BizExcessConfigServiceImpl.java

@@ -56,7 +56,8 @@ public class BizExcessConfigServiceImpl extends ServiceImpl<BizExcessConfigMappe
     public void add(BizExcessConfigAddParam bizExcessConfigAddParam) {
         //根据车辆轴数查询,相同的轴数不能重复创建
         long count = this.count(new QueryWrapper<BizExcessConfig>().lambda().
-                eq(BizExcessConfig::getVehicleAxleNumber, bizExcessConfigAddParam.getVehicleAxleNumber()));
+                eq(BizExcessConfig::getVehicleAxleNumber, bizExcessConfigAddParam.getVehicleAxleNumber()).
+                eq(BizExcessConfig::getStatus,"1"));
         if(count>0){
             throw new CommonException("该轴数已经添加过超限重量!");
         }
@@ -71,11 +72,22 @@ public class BizExcessConfigServiceImpl extends ServiceImpl<BizExcessConfigMappe
         //判断是否修改过轴数,如果修改过,则校验该轴数是否添加过超限配置
         if(bizExcessConfig.getVehicleAxleNumber()!=bizExcessConfigEditParam.getVehicleAxleNumber()){
             long count = this.count(new QueryWrapper<BizExcessConfig>().lambda().
-                    eq(BizExcessConfig::getVehicleAxleNumber, bizExcessConfigEditParam.getVehicleAxleNumber()));
+                    eq(BizExcessConfig::getVehicleAxleNumber, bizExcessConfigEditParam.getVehicleAxleNumber()).
+                    eq(BizExcessConfig::getStatus,"1"));
             if(count>0){
                 throw new CommonException("该轴数已经添加过超限重量!");
             }
         }
+        if(!StringUtils.equals(bizExcessConfig.getStatus(),bizExcessConfigEditParam.getStatus())){
+            if(StringUtils.equals(bizExcessConfigEditParam.getStatus(),"1")){
+                long count = this.count(new QueryWrapper<BizExcessConfig>().lambda().
+                        eq(BizExcessConfig::getVehicleAxleNumber, bizExcessConfigEditParam.getVehicleAxleNumber()).
+                        eq(BizExcessConfig::getStatus,"1"));
+                if(count>0){
+                    throw new CommonException("该轴数已经添加过超限重量!");
+                }
+            }
+        }
         BeanUtil.copyProperties(bizExcessConfigEditParam, bizExcessConfig);
         this.updateById(bizExcessConfig);
     }

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

@@ -243,4 +243,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 - 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);
 }

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

@@ -27,6 +27,12 @@ import org.apache.commons.compress.utils.Lists;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.biz.modular.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.*;
@@ -64,6 +70,15 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
     @Resource
     private BizGoodsConfService bizGoodsConfService;
 
+    @Resource
+    private BizOrderConfigService orderConfigService;
+
+    @Resource
+    private BizConfigService bizConfigService;
+
+    @Resource
+    private BizSaleOrderService bizSaleOrderService;
+
     @Override
     public Page<BizOrder> page(BizOrderPageParam bizOrderPageParam) {
         QueryWrapper<BizOrder> queryWrapper = getQueryWrapper(bizOrderPageParam);
@@ -118,11 +133,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 +185,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 +227,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 +318,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 +341,16 @@ 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");
             }else{
                 bizOrder.setOrderStatus("5");
             }
         }else{
-            bizOrder.setOrderStatus("7");
+            bizOrder.setOrderStatus("5");
         }
+        bizOrder.setEndReason(bizOrderEditParam.getEndReason());
         this.updateById(bizOrder);
     }
 
@@ -298,7 +360,7 @@ 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");
@@ -307,6 +369,13 @@ public class BizOrderServiceImpl extends ServiceImpl<BizOrderMapper, BizOrder> i
         }
     }
 
+    @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 {

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

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

@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+}

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

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

@@ -0,0 +1,20 @@
+<?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
+        from biz_sale_order bso
+        left join biz_customer bc on bc.id = bso.customer_id
+        ${ew.customSqlSegment}
+    </select>
+</mapper>

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

@@ -0,0 +1,62 @@
+/*
+ * 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)
+    @NotBlank(message = "saleOrderNumber不能为空")
+    private String saleOrderNumber;
+
+    /** 销售订单名称 */
+    @Schema(description = "销售订单名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "saleOrderName不能为空")
+    private String saleOrderName;
+
+    /** 订单类型(1:常规订单   2:服务订单) */
+    @Schema(description = "订单类型(1:常规订单   2:服务订单)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "saleOrderType不能为空")
+    private String saleOrderType;
+
+    /** 货品名称 */
+    @Schema(description = "货品名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "saleGoodsName不能为空")
+    private String saleGoodsName;
+
+    /** 销售订单重量 */
+    @Schema(description = "销售订单重量", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "saleOrderWeight不能为空")
+    private BigDecimal saleOrderWeight;
+
+    /***客户id*/
+    private String customerId;
+
+}

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

@@ -0,0 +1,67 @@
+/*
+ * 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)
+    @NotBlank(message = "saleOrderNumber不能为空")
+    private String saleOrderNumber;
+
+    /** 销售订单名称 */
+    @Schema(description = "销售订单名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "saleOrderName不能为空")
+    private String saleOrderName;
+
+    /** 订单类型(1:常规订单   2:服务订单) */
+    @Schema(description = "订单类型(1:常规订单   2:服务订单)", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "saleOrderType不能为空")
+    private String saleOrderType;
+
+    /** 货品名称 */
+    @Schema(description = "货品名称", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "saleGoodsName不能为空")
+    private String saleGoodsName;
+
+    /** 销售订单重量 */
+    @Schema(description = "销售订单重量", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "saleOrderWeight不能为空")
+    private BigDecimal saleOrderWeight;
+
+    /***客户id*/
+    private String customerId;
+
+}

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

+ 144 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizsaleorder/service/impl/BizSaleOrderServiceImpl.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.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 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.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 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 {
+
+    @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);
+        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)));
+        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;
+    }
+}

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

@@ -0,0 +1,131 @@
+/*
+ * 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.bizvehicle.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.bizvehicle.entity.BizVehicle;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehicleAddParam;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehicleEditParam;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehicleIdParam;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehiclePageParam;
+import vip.xiaonuo.biz.modular.bizvehicle.service.BizVehicleService;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 车辆信息控制器
+ *
+ * @author fanzherong
+ * @date  2025/04/08 09:26
+ */
+@Tag(name = "车辆信息控制器")
+@RestController
+@Validated
+public class BizVehicleController {
+
+    @Resource
+    private BizVehicleService bizVehicleService;
+
+    /**
+     * 获取车辆信息分页
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    @Operation(summary = "获取车辆信息分页")
+    @SaCheckPermission("/biz/bizvehicle/page")
+    @GetMapping("/biz/bizvehicle/page")
+    public CommonResult<Page<BizVehicle>> page(BizVehiclePageParam bizVehiclePageParam) {
+        return CommonResult.data(bizVehicleService.page(bizVehiclePageParam));
+    }
+
+    /**
+     * 添加车辆信息
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    @Operation(summary = "添加车辆信息")
+    @CommonLog("添加车辆信息")
+    @PostMapping("/biz/bizvehicle/add")
+    public CommonResult<String> add(@RequestBody @Valid BizVehicleAddParam bizVehicleAddParam) {
+        bizVehicleService.add(bizVehicleAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 编辑车辆信息
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    @Operation(summary = "编辑车辆信息")
+    @CommonLog("编辑车辆信息")
+    @PostMapping("/biz/bizvehicle/edit")
+    public CommonResult<String> edit(@RequestBody @Valid BizVehicleEditParam bizVehicleEditParam) {
+        bizVehicleService.edit(bizVehicleEditParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除车辆信息
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    @Operation(summary = "删除车辆信息")
+    @CommonLog("删除车辆信息")
+    @PostMapping("/biz/bizvehicle/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   List<BizVehicleIdParam> bizVehicleIdParamList) {
+        bizVehicleService.delete(bizVehicleIdParamList);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 获取车辆信息详情
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    @Operation(summary = "获取车辆信息详情")
+    @GetMapping("/biz/bizvehicle/detail")
+    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());
+    }
+}

+ 62 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/entity/BizVehicle.java

@@ -0,0 +1,62 @@
+/*
+ * 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.bizvehicle.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/08 09:26
+ **/
+@Getter
+@Setter
+@TableName("biz_vehicle")
+public class BizVehicle extends CommonEntity {
+
+    /** 主键ID */
+    @TableId
+    @Schema(description = "主键ID")
+    private String id;
+
+    /** 车牌号 */
+    @Schema(description = "车牌号")
+    private String licensePlate;
+
+    /** 车辆轴数 */
+    @Schema(description = "车辆轴数")
+    private String vehicleAxles;
+
+    /** 司机姓名 */
+    @Schema(description = "司机姓名")
+    private String driverName;
+
+    /** 司机电话 */
+    @Schema(description = "司机电话")
+    private String driverMobile;
+
+    /** 状态 (1:启用   2:停用) */
+    @Schema(description = "状态 (1:启用   2:停用)")
+    private String status;
+
+    @TableField(exist = false)
+    private String vehicleAxleNumber;
+}

+ 34 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/enums/BizVehicleEnum.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.bizvehicle.enums;
+
+import lombok.Getter;
+
+/**
+ * 车辆信息枚举
+ *
+ * @author fanzherong
+ * @date  2025/04/08 09:26
+ **/
+@Getter
+public enum BizVehicleEnum {
+
+    /** 测试 */
+    TEST("TEST");
+
+    private final String value;
+
+    BizVehicleEnum(String value) {
+        this.value = value;
+    }
+}

+ 29 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/mapper/BizVehicleMapper.java

@@ -0,0 +1,29 @@
+/*
+ * 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.bizvehicle.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.bizvehicle.entity.BizVehicle;
+
+/**
+ * 车辆信息Mapper接口
+ *
+ * @author fanzherong
+ * @date  2025/04/08 09:26
+ **/
+public interface BizVehicleMapper extends BaseMapper<BizVehicle> {
+    Page<BizVehicle> getPage(@Param("page") Page page, @Param("ew") QueryWrapper<BizVehicle> ew);
+}

+ 20 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/mapper/mapping/BizVehicleMapper.xml

@@ -0,0 +1,20 @@
+<?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.bizvehicle.mapper.BizVehicleMapper">
+
+    <select id="getPage" resultType="vip.xiaonuo.biz.modular.bizvehicle.entity.BizVehicle">
+        select
+            bc.id,
+            bc.license_plate,
+            bc.vehicle_axles,
+            bec.vehicle_axle_number,
+            bc.driver_name,
+            bc.driver_mobile,
+            bc.status,
+            bc.create_user,
+            bc.create_time
+        from biz_vehicle bc
+        left join biz_excess_config bec on bec.id = bc.vehicle_axles
+        ${ew.customSqlSegment}
+    </select>
+</mapper>

+ 54 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/param/BizVehicleAddParam.java

@@ -0,0 +1,54 @@
+/*
+ * 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.bizvehicle.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/08 09:26
+ **/
+@Getter
+@Setter
+public class BizVehicleAddParam {
+
+    /** 车牌号 */
+    @Schema(description = "车牌号")
+    private String licensePlate;
+
+    /** 车辆轴数 */
+    @Schema(description = "车辆轴数")
+    private String vehicleAxles;
+
+    /** 司机姓名 */
+    @Schema(description = "司机姓名")
+    private String driverName;
+
+    /** 司机电话 */
+    @Schema(description = "司机电话")
+    private String driverMobile;
+
+    /** 状态 (1:启用   2:停用) */
+    @Schema(description = "状态 (1:启用   2:停用)")
+    private String status;
+
+}

+ 59 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/param/BizVehicleEditParam.java

@@ -0,0 +1,59 @@
+/*
+ * 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.bizvehicle.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/08 09:26
+ **/
+@Getter
+@Setter
+public class BizVehicleEditParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+
+    /** 车牌号 */
+    @Schema(description = "车牌号")
+    private String licensePlate;
+
+    /** 车辆轴数 */
+    @Schema(description = "车辆轴数")
+    private String vehicleAxles;
+
+    /** 司机姓名 */
+    @Schema(description = "司机姓名")
+    private String driverName;
+
+    /** 司机电话 */
+    @Schema(description = "司机电话")
+    private String driverMobile;
+
+    /** 状态 (1:启用   2:停用) */
+    @Schema(description = "状态 (1:启用   2:停用)")
+    private String status;
+
+}

+ 35 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/param/BizVehicleIdParam.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.bizvehicle.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/08 09:26
+ **/
+@Getter
+@Setter
+public class BizVehicleIdParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+}

+ 60 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/param/BizVehiclePageParam.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.bizvehicle.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/08 09:26
+ **/
+@Getter
+@Setter
+public class BizVehiclePageParam {
+
+    /** 当前页 */
+    @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 licensePlate;
+
+    /**司机姓名**/
+    private String driverName;
+
+    /**司机电话*/
+    private String driverMobile;
+
+}

+ 85 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/bizvehicle/service/BizVehicleService.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.bizvehicle.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import vip.xiaonuo.biz.modular.bizvehicle.entity.BizVehicle;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehicleAddParam;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehicleEditParam;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehicleIdParam;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehiclePageParam;
+
+import java.util.List;
+
+/**
+ * 车辆信息Service接口
+ *
+ * @author fanzherong
+ * @date  2025/04/08 09:26
+ **/
+public interface BizVehicleService extends IService<BizVehicle> {
+
+    /**
+     * 获取车辆信息分页
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    Page<BizVehicle> page(BizVehiclePageParam bizVehiclePageParam);
+
+    /**
+     * 添加车辆信息
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    void add(BizVehicleAddParam bizVehicleAddParam);
+
+    /**
+     * 编辑车辆信息
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    void edit(BizVehicleEditParam bizVehicleEditParam);
+
+    /**
+     * 删除车辆信息
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    void delete(List<BizVehicleIdParam> bizVehicleIdParamList);
+
+    /**
+     * 获取车辆信息详情
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     */
+    BizVehicle detail(BizVehicleIdParam bizVehicleIdParam);
+
+    /**
+     * 获取车辆信息详情
+     *
+     * @author fanzherong
+     * @date  2025/04/08 09:26
+     **/
+    BizVehicle queryEntity(String id);
+
+    /**
+     * 个人长期车辆接口
+     */
+    BizVehicle queryByUserId();
+}

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

@@ -0,0 +1,230 @@
+/*
+ * 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.bizvehicle.service.impl;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollStreamUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.PhoneUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.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;
+import vip.xiaonuo.biz.modular.bizvehicle.entity.BizVehicle;
+import vip.xiaonuo.biz.modular.bizvehicle.mapper.BizVehicleMapper;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehicleAddParam;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehicleEditParam;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehicleIdParam;
+import vip.xiaonuo.biz.modular.bizvehicle.param.BizVehiclePageParam;
+import vip.xiaonuo.biz.modular.bizvehicle.service.BizVehicleService;
+import vip.xiaonuo.common.util.CommonCryptogramUtil;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * 车辆信息Service接口实现类
+ *
+ * @author fanzherong
+ * @date  2025/04/08 09:26
+ **/
+@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();
+        if(ObjectUtil.isNotEmpty(bizVehiclePageParam.getLicensePlate())){
+            queryWrapper.like("bc.license_plate",bizVehiclePageParam.getLicensePlate());
+        }
+        if(ObjectUtil.isNotEmpty(bizVehiclePageParam.getDriverName())){
+            queryWrapper.like("bc.driver_name",bizVehiclePageParam.getDriverName());
+        }
+        if(ObjectUtil.isNotEmpty(bizVehiclePageParam.getDriverMobile())){
+            queryWrapper.like("bc.driver_mobile",bizVehiclePageParam.getDriverMobile());
+        }
+        // 校验数据范围
+        List<String> loginUserDataScope = StpLoginUserUtil.getLoginUserDataScope();
+        if(ObjectUtil.isEmpty(loginUserDataScope)) {
+            queryWrapper.eq("bc.create_user", StpUtil.getLoginIdAsString());
+        }
+        queryWrapper.eq("bc.delete_flag","NOT_DELETE");
+        queryWrapper.orderByDesc("bc.create_time");
+        return this.getBaseMapper().getPage(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(BizVehicleAddParam bizVehicleAddParam) {
+        checkParam(bizVehicleAddParam);
+        BizVehicle bizVehicle = BeanUtil.toBean(bizVehicleAddParam, BizVehicle.class);
+        if(ObjectUtil.isEmpty(bizVehicleAddParam.getDriverName())){
+            bizVehicle.setDriverName(StpLoginUserUtil.getLoginUser().getName());
+        }
+        if(ObjectUtil.isEmpty(bizVehicleAddParam.getDriverMobile())){
+            bizVehicle.setDriverMobile(CommonCryptogramUtil.doSm4CbcDecrypt(StpLoginUserUtil.getLoginUser().getPhone()));
+        }
+        this.save(bizVehicle);
+    }
+
+    public void checkParam(BizVehicleAddParam bizVehicleAddParam){
+        if(ObjectUtil.isNotEmpty(bizVehicleAddParam.getLicensePlate())){
+            bizVehicleAddParam.setLicensePlate(bizVehicleAddParam.getLicensePlate().toUpperCase().trim());
+            //校验车牌号
+            if(!isCarNumber(bizVehicleAddParam.getLicensePlate())){
+                throw new CommonException("车牌号:{}格式错误",bizVehicleAddParam.getLicensePlate());
+            }
+            //判断车牌号是否添加过
+            long count = this.count(new QueryWrapper<BizVehicle>().lambda().
+                    eq(BizVehicle::getLicensePlate, bizVehicleAddParam.getLicensePlate()).
+                    eq(BizVehicle::getStatus, "1"));
+            if(count>0){
+                throw new CommonException("车牌号:{}已经添加过!",bizVehicleAddParam.getLicensePlate());
+            }
+        }
+        //校验司机电话
+        if(ObjectUtil.isNotEmpty(bizVehicleAddParam.getDriverMobile())){
+            if(!PhoneUtil.isMobile(bizVehicleAddParam.getDriverMobile())) {
+                throw new CommonException("手机号码:{}格式错误", bizVehicleAddParam.getDriverMobile());
+            }
+        }
+        long count = this.count(new QueryWrapper<BizVehicle>().lambda().
+                eq(BizVehicle::getCreateUser, StpLoginUserUtil.getLoginUser().getId()).
+                eq(BizVehicle::getStatus, "1"));
+        if(count>0){
+            throw new CommonException("已添加过启用得车辆信息");
+        }
+    }
+
+    public void checkParam(BizVehicleEditParam bizVehicleEditParam,BizVehicle bizVehicle){
+        if(ObjectUtil.isNotEmpty(bizVehicleEditParam.getLicensePlate())){
+            bizVehicleEditParam.setLicensePlate(bizVehicleEditParam.getLicensePlate().toUpperCase().trim());
+            //判断车牌号是否添加过
+            if(!StringUtils.equals(bizVehicle.getLicensePlate(),bizVehicleEditParam.getLicensePlate())){
+                //校验车牌号
+                if(!isCarNumber(bizVehicleEditParam.getLicensePlate())){
+                    throw new CommonException("车牌号:{}格式错误",bizVehicleEditParam.getLicensePlate());
+                }
+                long count = this.count(new QueryWrapper<BizVehicle>().lambda().
+                        eq(BizVehicle::getLicensePlate, bizVehicleEditParam.getLicensePlate()).
+                        eq(BizVehicle::getStatus, "1"));
+                if(count>0){
+                    throw new CommonException("车牌号:{}已经添加过!",bizVehicleEditParam.getLicensePlate());
+                }
+                long sum = this.count(new QueryWrapper<BizVehicle>().lambda().
+                        eq(BizVehicle::getCreateUser, StpLoginUserUtil.getLoginUser().getId()).
+                        eq(BizVehicle::getStatus, "1").
+                        ne(BizVehicle::getLicensePlate,bizVehicle.getLicensePlate()));
+                if(sum>0){
+                    throw new CommonException("已添加过启用得车辆信息");
+                }
+            }
+        }
+        //校验司机电话
+        if(ObjectUtil.isNotEmpty(bizVehicleEditParam.getDriverMobile())){
+            if(!PhoneUtil.isMobile(bizVehicleEditParam.getDriverMobile())) {
+                throw new CommonException("手机号码:{}格式错误", bizVehicleEditParam.getDriverMobile());
+            }
+        }
+        //启用时校验修改状态
+        if(!StringUtils.equals(bizVehicle.getStatus(),bizVehicleEditParam.getStatus())){
+            if(StringUtils.equals(bizVehicleEditParam.getStatus(),"1")){
+                long count = this.count(new QueryWrapper<BizVehicle>().lambda().
+                        eq(BizVehicle::getLicensePlate, bizVehicleEditParam.getLicensePlate()).
+                        eq(BizVehicle::getStatus, "1"));
+                if(count>0){
+                    throw new CommonException("车牌号:{}已经添加过!",bizVehicleEditParam.getLicensePlate());
+                }
+                long sum = this.count(new QueryWrapper<BizVehicle>().lambda().
+                        eq(BizVehicle::getCreateUser, StpLoginUserUtil.getLoginUser().getId()).
+                        eq(BizVehicle::getStatus, "1"));
+                if(sum>0){
+                    throw new CommonException("已添加过启用得车辆信息");
+                }
+            }
+        }
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void edit(BizVehicleEditParam bizVehicleEditParam) {
+        BizVehicle bizVehicle = this.queryEntity(bizVehicleEditParam.getId());
+        checkParam(bizVehicleEditParam,bizVehicle);
+        BeanUtil.copyProperties(bizVehicleEditParam, bizVehicle);
+        if(ObjectUtil.isEmpty(bizVehicleEditParam.getDriverName())){
+            bizVehicle.setDriverName(StpLoginUserUtil.getLoginUser().getName());
+        }
+        if(ObjectUtil.isEmpty(bizVehicleEditParam.getDriverMobile())){
+            bizVehicle.setDriverMobile(CommonCryptogramUtil.doSm4CbcDecrypt(StpLoginUserUtil.getLoginUser().getPhone()));
+        }
+        this.updateById(bizVehicle);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<BizVehicleIdParam> bizVehicleIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(bizVehicleIdParamList, BizVehicleIdParam::getId));
+    }
+
+    @Override
+    public BizVehicle detail(BizVehicleIdParam bizVehicleIdParam) {
+        return this.queryEntity(bizVehicleIdParam.getId());
+    }
+
+    @Override
+    public BizVehicle queryEntity(String id) {
+        BizVehicle bizVehicle = this.getById(id);
+        if(ObjectUtil.isEmpty(bizVehicle)) {
+            throw new CommonException("车辆信息不存在,id值为:{}", id);
+        }
+        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
+     * @return
+     */
+    public boolean isCarNumber(String carNumber){
+        String carNumberPattern = "([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼]{1}(([A-HJ-Z]{1}[A-HJ-NP-Z0-9]{5})|([A-HJ-Z]{1}(([DF]{1}[A-HJ-NP-Z0-9]{1}[0-9]{4})|([0-9]{5}[DF]{1})))|([A-HJ-Z]{1}[A-D0-9]{1}[0-9]{3}警)))|([0-9]{6}使)|((([沪粤川云桂鄂陕蒙藏黑辽渝]{1}A)|鲁B|闽D|蒙E|蒙H)[0-9]{4}领)|(WJ[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼·•]{1}[0-9]{4}[TDSHBXJ0-9]{1})|([VKHBSLJNGCE]{1}[A-DJ-PR-TVY]{1}[0-9]{5})";
+        return Pattern.matches(carNumberPattern, carNumber);
+    }
+}

+ 94 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/controller/BizCustomerAccountController.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.customer.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.customer.entity.BizCustomerAccount;
+import vip.xiaonuo.biz.modular.customer.param.BizCustomerAccountAddParam;
+import vip.xiaonuo.biz.modular.customer.param.BizCustomerAccountIdParam;
+import vip.xiaonuo.biz.modular.customer.param.BizCustomerAccountPageParam;
+import vip.xiaonuo.biz.modular.customer.service.BizCustomerAccountService;
+
+import jakarta.annotation.Resource;
+import jakarta.validation.Valid;
+import jakarta.validation.constraints.NotEmpty;
+import java.util.List;
+
+/**
+ * 客户账号控制器
+ *
+ * @author sandy
+ * @date  2025/04/09 17:00
+ */
+@Tag(name = "客户账号控制器")
+@RestController
+@Validated
+public class BizCustomerAccountController {
+
+    @Resource
+    private BizCustomerAccountService bizCustomerAccountService;
+
+    /**
+     * 获取客户账号分页
+     *
+     * @author sandy
+     * @date  2025/04/09 17:00
+     */
+    @Operation(summary = "获取客户账号分页")
+    @GetMapping("/biz/customerAccount/page")
+    public CommonResult<Page<BizCustomerAccount>> page(BizCustomerAccountPageParam bizCustomerAccountPageParam) {
+        return CommonResult.data(bizCustomerAccountService.page(bizCustomerAccountPageParam));
+    }
+
+    /**
+     * 添加客户账号
+     *
+     * @author sandy
+     * @date  2025/04/09 17:00
+     */
+    @Operation(summary = "添加客户账号")
+    @CommonLog("添加客户账号")
+    @SaCheckPermission("/biz/customerAccount/add")
+    @PostMapping("/biz/customerAccount/add")
+    public CommonResult<String> add(@RequestBody @Valid BizCustomerAccountAddParam bizCustomerAccountAddParam) {
+        bizCustomerAccountService.add(bizCustomerAccountAddParam);
+        return CommonResult.ok();
+    }
+
+    /**
+     * 删除客户账号
+     *
+     * @author sandy
+     * @date  2025/04/09 17:00
+     */
+    @Operation(summary = "删除客户账号")
+    @CommonLog("删除客户账号")
+    @SaCheckPermission("/biz/customerAccount/delete")
+    @PostMapping("/biz/customerAccount/delete")
+    public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空")
+                                                   List<BizCustomerAccountIdParam> bizCustomerAccountIdParamList) {
+        bizCustomerAccountService.delete(bizCustomerAccountIdParamList);
+        return CommonResult.ok();
+    }
+
+}

+ 0 - 14
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/controller/BizCustomerController.java

@@ -130,20 +130,6 @@ public class BizCustomerController {
         return CommonResult.data(bizCustomerService.detail(bizCustomerIdParam));
     }
 
-    /**
-     * 重置用户密码
-     *
-     * @author sandy
-     * @date  2025/03/26 10:00
-     **/
-    @Operation(summary = "重置用户密码")
-    @CommonLog("重置用户密码")
-    @PostMapping("/biz/customer/resetPassword")
-    public CommonResult<String> resetPassword(@RequestBody @Valid BizCustomerIdParam bizCustomerIdParam) {
-        bizCustomerService.resetPassword(bizCustomerIdParam);
-        return CommonResult.ok();
-    }
-
     /**
      * 用友推送客户接口
      *

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

@@ -37,10 +37,6 @@ public class BizCustomer extends CommonEntity {
     @Schema(description = "主键ID")
     private String id;
 
-    /** 客户登录账号 */
-    @Schema(description = "客户登录账号")
-    private String loginAccount;
-
     /** 客户名称 */
     @Schema(description = "客户名称")
     private String name;

+ 47 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/entity/BizCustomerAccount.java

@@ -0,0 +1,47 @@
+/*
+ * 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.customer.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.util.Date;
+
+/**
+ * 客户账号实体
+ *
+ * @author sandy
+ * @date  2025/04/09 17:00
+ **/
+@Getter
+@Setter
+@TableName("biz_customer_account")
+public class BizCustomerAccount extends CommonEntity {
+
+    /** 主键ID */
+    @TableId
+    @Schema(description = "主键ID")
+    private String id;
+
+    /** 客户ID */
+    @Schema(description = "客户ID")
+    private String customerId;
+
+    /** 账号 */
+    @Schema(description = "账号")
+    private String loginAccount;
+
+}

+ 34 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/enums/BizCustomerAccountEnum.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.customer.enums;
+
+import lombok.Getter;
+
+/**
+ * 客户账号枚举
+ *
+ * @author sandy
+ * @date  2025/04/09 17:00
+ **/
+@Getter
+public enum BizCustomerAccountEnum {
+
+    /** 未删除 */
+    NOT_DELETE("NOT_DELETE");
+
+    private final String value;
+
+    BizCustomerAccountEnum(String value) {
+        this.value = value;
+    }
+}

+ 25 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/mapper/BizCustomerAccountMapper.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.customer.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import vip.xiaonuo.biz.modular.customer.entity.BizCustomerAccount;
+
+/**
+ * 客户账号Mapper接口
+ *
+ * @author sandy
+ * @date  2025/04/09 17:00
+ **/
+public interface BizCustomerAccountMapper extends BaseMapper<BizCustomerAccount> {
+}

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

+ 37 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerAccountAddParam.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.customer.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 客户账号添加参数
+ *
+ * @author sandy
+ * @date  2025/04/09 17:00
+ **/
+@Getter
+@Setter
+public class BizCustomerAccountAddParam {
+
+    /** 客户ID */
+    @Schema(description = "客户ID")
+    private String customerId;
+
+    /** 账号 */
+    @Schema(description = "账号")
+    private String loginAccount;
+
+}

+ 34 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerAccountIdParam.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.customer.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 客户Id参数
+ *
+ * @author sandy
+ * @date  2025/03/25 15:30
+ **/
+@Getter
+@Setter
+public class BizCustomerAccountIdParam {
+
+    /** 主键ID */
+    @Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotBlank(message = "id不能为空")
+    private String id;
+}

+ 53 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerAccountPageParam.java

@@ -0,0 +1,53 @@
+/*
+ * 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.customer.param;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * 客户账号查询参数
+ *
+ * @author sandy
+ * @date  2025/04/09 17:00
+ **/
+@Getter
+@Setter
+public class BizCustomerAccountPageParam {
+
+    /** 当前页 */
+    @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;
+
+    /** 客户ID */
+    @Schema(description = "客户ID")
+    private String customerId;
+
+}

+ 0 - 5
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerAddParam.java

@@ -31,11 +31,6 @@ import java.util.Date;
 @Setter
 public class BizCustomerAddParam {
 
-    /** 客户登录账号 */
-    @Schema(description = "客户登录账号", requiredMode = Schema.RequiredMode.REQUIRED)
-    @NotBlank(message = "客户登录账号不能为空")
-    private String loginAccount;
-
     /** 客户名称 */
     @Schema(description = "客户名称")
     private String name;

+ 0 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerEditParam.java

@@ -36,10 +36,6 @@ public class BizCustomerEditParam {
     @NotBlank(message = "id不能为空")
     private String id;
 
-    /** 客户登录账号 */
-    @Schema(description = "客户登录账号")
-    private String loginAccount;
-
     /** 客户名称 */
     @Schema(description = "客户名称")
     private String name;

+ 0 - 4
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/param/BizCustomerPageParam.java

@@ -48,10 +48,6 @@ public class BizCustomerPageParam {
     @Schema(description = "关键词")
     private String searchKey;
 
-    /** 客户登录账号 */
-    @Schema(description = "客户登录账号")
-    private String loginAccount;
-
     /** 客户名称 */
     @Schema(description = "客户名称")
     private String name;

+ 63 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/service/BizCustomerAccountService.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.customer.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import vip.xiaonuo.biz.modular.customer.entity.BizCustomerAccount;
+import vip.xiaonuo.biz.modular.customer.param.BizCustomerAccountAddParam;
+import vip.xiaonuo.biz.modular.customer.param.BizCustomerAccountIdParam;
+import vip.xiaonuo.biz.modular.customer.param.BizCustomerAccountPageParam;
+
+import java.util.List;
+
+/**
+ * 客户账号Service接口
+ *
+ * @author sandy
+ * @date  2025/04/09 17:00
+ **/
+public interface BizCustomerAccountService extends IService<BizCustomerAccount> {
+
+    /**
+     * 获取客户账号分页
+     *
+     * @author sandy
+     * @date  2025/04/09 17:00
+     */
+    Page<BizCustomerAccount> page(BizCustomerAccountPageParam bizBizCustomerAccountPageParam);
+
+    /**
+     * 添加客户账号
+     *
+     * @author sandy
+     * @date  2025/04/09 17:00
+     */
+    void add(BizCustomerAccountAddParam bizBizCustomerAccountAddParam);
+
+    /**
+     * 删除客户账号
+     *
+     * @author sandy
+     * @date  2025/04/09 17:00
+     */
+    void delete(List<BizCustomerAccountIdParam> bizBizCustomerAccountIdParamList);
+
+    /**
+     * 获取客户账号详情
+     *
+     * @author sandy
+     * @date  2025/04/09 17:00
+     **/
+    BizCustomerAccount queryEntity(String id);
+}

+ 0 - 8
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/service/BizCustomerService.java

@@ -80,14 +80,6 @@ public interface BizCustomerService extends IService<BizCustomer> {
      */
     BizCustomer detail(BizCustomerIdParam bizCustomerIdParam);
 
-    /**
-     * 重置用户密码
-     *
-     * @author sandy
-     * @date  2025/03/26 10:00
-     **/
-    void resetPassword(BizCustomerIdParam bizCustomerIdParam);
-
     /**
      * 获取客户详情
      *

+ 131 - 0
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/service/impl/BizCustomerAccountServiceImpl.java

@@ -0,0 +1,131 @@
+/*
+ * 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.customer.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 jakarta.annotation.Resource;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import vip.xiaonuo.biz.modular.customer.entity.BizCustomer;
+import vip.xiaonuo.biz.modular.customer.enums.BizCustomerAccountEnum;
+import vip.xiaonuo.biz.modular.customer.enums.BizCustomerEnum;
+import vip.xiaonuo.biz.modular.customer.param.BizCustomerAccountIdParam;
+import vip.xiaonuo.biz.modular.goods.entity.BizGoods;
+import vip.xiaonuo.biz.modular.user.entity.BizUser;
+import vip.xiaonuo.biz.modular.user.enums.BizUserStatusEnum;
+import vip.xiaonuo.biz.modular.user.mapper.BizUserMapper;
+import vip.xiaonuo.common.enums.CommonSortOrderEnum;
+import vip.xiaonuo.common.exception.CommonException;
+import vip.xiaonuo.common.page.CommonPageRequest;
+import vip.xiaonuo.biz.modular.customer.entity.BizCustomerAccount;
+import vip.xiaonuo.biz.modular.customer.mapper.BizCustomerAccountMapper;
+import vip.xiaonuo.biz.modular.customer.param.BizCustomerAccountAddParam;
+import vip.xiaonuo.biz.modular.customer.param.BizCustomerAccountPageParam;
+import vip.xiaonuo.biz.modular.customer.service.BizCustomerAccountService;
+import vip.xiaonuo.common.util.CommonCryptogramUtil;
+import vip.xiaonuo.dev.api.DevConfigApi;
+import vip.xiaonuo.sys.api.SysUserApi;
+
+import java.util.List;
+
+/**
+ * 客户账号Service接口实现类
+ *
+ * @author sandy
+ * @date  2025/04/09 17:00
+ **/
+@Service
+public class BizCustomerAccountServiceImpl extends ServiceImpl<BizCustomerAccountMapper, BizCustomerAccount> implements BizCustomerAccountService {
+
+    @Resource
+    private DevConfigApi devConfigApi;
+
+    @Resource
+    private BizUserMapper bizUserMapper;
+
+    @Resource
+    private SysUserApi sysUserApi;
+
+    private static final String SNOWY_SYS_DEFAULT_PASSWORD_KEY = "SNOWY_SYS_DEFAULT_PASSWORD";
+
+    @Override
+    public Page<BizCustomerAccount> page(BizCustomerAccountPageParam bizCustomerAccountPageParam) {
+        QueryWrapper<BizCustomerAccount> queryWrapper = new QueryWrapper<BizCustomerAccount>().checkSqlInjection();
+        if(ObjectUtil.isNotEmpty(bizCustomerAccountPageParam.getCustomerId())) {
+            queryWrapper.lambda().like(BizCustomerAccount::getCustomerId, bizCustomerAccountPageParam.getCustomerId());
+        }
+        queryWrapper.lambda().eq(BizCustomerAccount::getDeleteFlag, BizCustomerAccountEnum.NOT_DELETE.getValue());
+        if(ObjectUtil.isAllNotEmpty(bizCustomerAccountPageParam.getSortField(), bizCustomerAccountPageParam.getSortOrder())) {
+            CommonSortOrderEnum.validate(bizCustomerAccountPageParam.getSortOrder());
+            queryWrapper.orderBy(true, bizCustomerAccountPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
+                    StrUtil.toUnderlineCase(bizCustomerAccountPageParam.getSortField()));
+        } else {
+            queryWrapper.lambda().orderByAsc(BizCustomerAccount::getId);
+        }
+        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(BizCustomerAccountAddParam bizCustomerAccountAddParam) {
+        QueryWrapper<BizCustomerAccount> queryWrapper = new QueryWrapper<>();
+        if(ObjectUtil.isNotEmpty(bizCustomerAccountAddParam.getLoginAccount())){
+            queryWrapper.lambda().eq(BizCustomerAccount::getLoginAccount,bizCustomerAccountAddParam.getLoginAccount());
+        }
+        queryWrapper.lambda().eq(BizCustomerAccount::getDeleteFlag, BizCustomerAccountEnum.NOT_DELETE.getValue());
+        long count = this.count(queryWrapper);
+        if(count>0){
+            throw new CommonException("该客户账号已经存在!");
+        }
+
+        BizCustomerAccount bizCustomerAccount = BeanUtil.toBean(bizCustomerAccountAddParam, BizCustomerAccount.class);
+        this.save(bizCustomerAccount);
+
+        // 添加客户登录账号
+        BizUser bizUser = new BizUser();
+        bizUser.setCustomerId(bizCustomerAccountAddParam.getCustomerId());
+        bizUser.setName(bizCustomerAccountAddParam.getLoginAccount());
+        bizUser.setAccount(bizCustomerAccountAddParam.getLoginAccount());
+        bizUser.setUserType("1");
+        // 设置密码
+        bizUser.setPassword(CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY)));
+        // 设置状态
+        bizUser.setUserStatus(BizUserStatusEnum.ENABLE.getValue());
+        this.bizUserMapper.insert(bizUser);
+
+        // 添加客户角色
+        this.sysUserApi.grantRoleType(bizUser.getId(), "客户");
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void delete(List<BizCustomerAccountIdParam> bizCustomerAccountIdParamList) {
+        // 执行删除
+        this.removeByIds(CollStreamUtil.toList(bizCustomerAccountIdParamList, BizCustomerAccountIdParam::getId));
+    }
+
+    @Override
+    public BizCustomerAccount queryEntity(String id) {
+        BizCustomerAccount bizCustomerAccount = this.getById(id);
+        if(ObjectUtil.isEmpty(bizCustomerAccount)) {
+            throw new CommonException("客户账号不存在,id值为:{}", id);
+        }
+        return bizCustomerAccount;
+    }
+}

+ 0 - 71
snowy-plugin/snowy-plugin-biz/src/main/java/vip/xiaonuo/biz/modular/customer/service/impl/BizCustomerServiceImpl.java

@@ -57,23 +57,9 @@ import java.util.Map;
 @Service
 public class BizCustomerServiceImpl extends ServiceImpl<BizCustomerMapper, BizCustomer> implements BizCustomerService {
 
-    private static final String SNOWY_SYS_DEFAULT_PASSWORD_KEY = "SNOWY_SYS_DEFAULT_PASSWORD";
-
-    @Resource
-    private DevConfigApi devConfigApi;
-
-    @Resource
-    private BizUserMapper bizUserMapper;
-
-    @Resource
-    private SysUserApi sysUserApi;
-
     @Override
     public Page<BizCustomer> page(BizCustomerPageParam bizCustomerPageParam) {
         QueryWrapper<BizCustomer> queryWrapper = new QueryWrapper<BizCustomer>().checkSqlInjection();
-        if(ObjectUtil.isNotEmpty(bizCustomerPageParam.getLoginAccount())) {
-            queryWrapper.lambda().like(BizCustomer::getLoginAccount, bizCustomerPageParam.getLoginAccount());
-        }
         if(ObjectUtil.isNotEmpty(bizCustomerPageParam.getName())) {
             queryWrapper.lambda().like(BizCustomer::getName, bizCustomerPageParam.getName());
         }
@@ -94,9 +80,6 @@ public class BizCustomerServiceImpl extends ServiceImpl<BizCustomerMapper, BizCu
     @Override
     public List<BizCustomer> getList(BizCustomerPageParam bizCustomerPageParam) {
         QueryWrapper<BizCustomer> queryWrapper = new QueryWrapper<BizCustomer>().checkSqlInjection();
-        if(ObjectUtil.isNotEmpty(bizCustomerPageParam.getLoginAccount())) {
-            queryWrapper.lambda().like(BizCustomer::getLoginAccount, bizCustomerPageParam.getLoginAccount());
-        }
         if(ObjectUtil.isNotEmpty(bizCustomerPageParam.getName())) {
             queryWrapper.lambda().like(BizCustomer::getName, bizCustomerPageParam.getName());
         }
@@ -122,11 +105,6 @@ public class BizCustomerServiceImpl extends ServiceImpl<BizCustomerMapper, BizCu
         if(countYong>0){
             throw new CommonException("客户关联的用友平台ID已存在!");
         }
-        //查询客户账号是否添加过
-        long countLogin = this.count(new QueryWrapper<BizCustomer>().lambda().eq(BizCustomer::getLoginAccount, bizCustomerAddParam.getLoginAccount()));
-        if(countLogin>0){
-            throw new CommonException("客户账号已存在!");
-        }
         //查询客户名称是否添加过
         long countName = this.count(new QueryWrapper<BizCustomer>().lambda().eq(BizCustomer::getName, bizCustomerAddParam.getName()));
         if(countName>0){
@@ -134,22 +112,6 @@ public class BizCustomerServiceImpl extends ServiceImpl<BizCustomerMapper, BizCu
         }
         BizCustomer bizCustomer = BeanUtil.toBean(bizCustomerAddParam, BizCustomer.class);
         this.save(bizCustomer);
-
-        // 添加客户登录账号
-        BizUser bizUser = new BizUser();
-        bizUser.setCustomerId(bizCustomer.getId());
-        bizUser.setAccount(bizCustomer.getLoginAccount());
-        bizUser.setName(bizCustomer.getName());
-        bizUser.setPhone(bizCustomer.getPhone());
-        bizUser.setUserType("1");
-        // 设置密码
-        bizUser.setPassword(CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY)));
-        // 设置状态
-        bizUser.setUserStatus(BizUserStatusEnum.ENABLE.getValue());
-        this.bizUserMapper.insert(bizUser);
-
-        // 添加客户角色
-        this.sysUserApi.grantRoleType(bizUser.getId(), "客户");
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -169,13 +131,6 @@ public class BizCustomerServiceImpl extends ServiceImpl<BizCustomerMapper, BizCu
                 throw new CommonException("客户关联的用友平台ID已存在!");
             }
         }
-        if(!StringUtils.equals(bizCustomer.getLoginAccount(),bizCustomerEditParam.getLoginAccount())){
-            //查询客户账号是否添加过
-            long countLogin = this.count(new QueryWrapper<BizCustomer>().lambda().eq(BizCustomer::getLoginAccount, bizCustomerEditParam.getLoginAccount()));
-            if(countLogin>0){
-                throw new CommonException("客户账号已存在!");
-            }
-        }
         if(!StringUtils.equals(bizCustomer.getName(),bizCustomerEditParam.getName())){
             //查询客户名称是否添加过
             long count = this.count(new QueryWrapper<BizCustomer>().lambda().eq(BizCustomer::getName, bizCustomerEditParam.getName()));
@@ -185,25 +140,6 @@ public class BizCustomerServiceImpl extends ServiceImpl<BizCustomerMapper, BizCu
         }
         BeanUtil.copyProperties(bizCustomerEditParam, bizCustomer);
         this.updateById(bizCustomer);
-
-        // 检查是否存在账号
-        long count = this.bizUserMapper.selectCount(new QueryWrapper<BizUser>().lambda().eq(BizUser::getCustomerId, bizCustomer.getId()));
-        if(count == 0){
-            BizUser bizUser = new BizUser();
-            bizUser.setCustomerId(bizCustomer.getId());
-            bizUser.setAccount(bizCustomer.getLoginAccount());
-            bizUser.setName(bizCustomer.getName());
-            bizUser.setPhone(bizCustomer.getPhone());
-            bizUser.setUserType("1");
-            // 设置密码
-            bizUser.setPassword(CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY)));
-            // 设置状态
-            bizUser.setUserStatus(BizUserStatusEnum.ENABLE.getValue());
-            this.bizUserMapper.insert(bizUser);
-
-            // 添加客户角色
-            this.sysUserApi.grantRoleType(bizUser.getId(), "客户");
-        }
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -218,13 +154,6 @@ public class BizCustomerServiceImpl extends ServiceImpl<BizCustomerMapper, BizCu
         return this.queryEntity(bizCustomerIdParam.getId());
     }
 
-    @Override
-    public void resetPassword(BizCustomerIdParam bizCustomerIdParam) {
-        this.bizUserMapper.update(new LambdaUpdateWrapper<BizUser>().eq(BizUser::getCustomerId,
-                bizCustomerIdParam.getId()).set(BizUser::getPassword,
-                CommonCryptogramUtil.doHashValue(devConfigApi.getValueByKey(SNOWY_SYS_DEFAULT_PASSWORD_KEY))));
-    }
-
     @Override
     public BizCustomer queryEntity(String id) {
         BizCustomer bizCustomer = this.getById(id);

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

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

@@ -219,5 +219,5 @@ public class BizRecord extends CommonEntity {
     private String unloadImg;
     private String unloadName;
 
-    private String auditReason;
+    private String auditSign;
 }

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

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

@@ -143,7 +143,7 @@ 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");
@@ -555,6 +555,7 @@ public class BizRecordServiceImpl extends ServiceImpl<BizRecordMapper, BizRecord
         if(ObjectUtil.isNotNull(appointmentRecord)){
             appointmentRecord.setStatus("7");
             bizAppointmentRecordService.updateById(appointmentRecord);
+
         }
     }
 
@@ -643,15 +644,24 @@ public class BizRecordServiceImpl extends ServiceImpl<BizRecordMapper, BizRecord
     @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);
         }
     }
 }

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

@@ -288,4 +288,7 @@ public class BizUser extends CommonEntity {
 
     @Schema(description = "客户ID")
     private String customerId;
+
+    @Schema(description = "客户账号ID")
+    private String customerAccountId;
 }

+ 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-web-app/src/main/resources/application-dev.properties

@@ -201,3 +201,6 @@ 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
+
+open-sign.interceptor.sign.enable=true
+open-sign.interceptor.sign.include-paths=/thirdPart/v1/**

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

@@ -204,3 +204,9 @@ snowy.config.common.mqtt-url=tcp://127.0.0.1:1883
 snowy.config.common.mqtt-name=admin
 snowy.config.common.mqtt-password=public
 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