qzyReal 3 years ago
parent
commit
58d8936e25
100 changed files with 8071 additions and 270 deletions
  1. 18 0
      app/apis/api.js
  2. 0 0
      app/common/js/jweixin-1.6.0.js
  3. 0 0
      app/components/jweixin-module/index.js
  4. 26 12
      app/manifest.json
  5. 16 0
      app/pages.json
  6. 2 2
      app/pages/business-order/business-order.vue
  7. 34 19
      app/pages/business-order/surePay.vue
  8. 3 0
      app/pages/index/index.vue
  9. 70 0
      app/pages/wx/index.vue
  10. 206 0
      app/pages/wx/pay.vue
  11. 32 0
      app/pages/wx/remote-js.vue
  12. 1 1
      app/utils/request.js
  13. 79 35
      sp-admin/login.html
  14. 4 1
      sp-admin/sa-frame/com/sa-item.vue
  15. 19 23
      sp-admin/sa-frame/menu-list.js
  16. 128 0
      sp-admin/sa-view/tb-business-car/tb-business-car-add.html
  17. 68 0
      sp-admin/sa-view/tb-business-car/tb-business-car-info.html
  18. 164 0
      sp-admin/sa-view/tb-business-car/tb-business-car-list.html
  19. 178 37
      sp-admin/sa-view/tb-business/tb-business-add.html
  20. 117 0
      sp-admin/sa-view/tb-business/tb-business-car-list.html
  21. 170 22
      sp-admin/sa-view/tb-business/tb-business-edit.html
  22. 6 1
      sp-admin/sa-view/tb-business/tb-business-list.html
  23. 67 0
      sp-admin/sa-view/tb-charge-record/tb-charge-record-info.html
  24. 88 0
      sp-admin/sa-view/tb-charge-record/tb-charge-record-list.html
  25. 132 0
      sp-admin/sa-view/tb-costomer/tb-account-manager.html
  26. 6 0
      sp-admin/sa-view/tb-costomer/tb-costomer-list.html
  27. 38 115
      sp-admin/sa-view/tb-item/tb-item-list.html
  28. 128 0
      sp-admin/sa-view/tb-pay-record/tb-pay-record-add.html
  29. 68 0
      sp-admin/sa-view/tb-pay-record/tb-pay-record-info.html
  30. 164 0
      sp-admin/sa-view/tb-pay-record/tb-pay-record-list.html
  31. 2 2
      sp-admin/static/sa.js
  32. 16 0
      sp-com/.gitignore
  33. 33 0
      sp-com/business/.gitignore
  34. 30 0
      sp-com/business/pom.xml
  35. 51 0
      sp-com/business/src/main/java/com/pj/api/bo/InOutRecordBO.java
  36. 90 0
      sp-com/business/src/main/java/com/pj/api/h5/ApiController.java
  37. 20 0
      sp-com/business/src/main/java/com/pj/api/open/OpenFilter.java
  38. 37 0
      sp-com/business/src/main/java/com/pj/api/open/ResultJson.java
  39. 63 0
      sp-com/business/src/main/java/com/pj/api/open/bo/CheckCarNumberBO.java
  40. 118 0
      sp-com/business/src/main/java/com/pj/api/open/service/OpenService.java
  41. 40 0
      sp-com/business/src/main/java/com/pj/api/open/web/OpenController.java
  42. 58 0
      sp-com/business/src/main/java/com/pj/api/service/ApiService.java
  43. 36 0
      sp-com/business/src/main/java/com/pj/constants/RoleEnum.java
  44. 14 0
      sp-com/business/src/main/java/com/pj/constants/UserTypeEnum.java
  45. 52 0
      sp-com/business/src/main/java/com/pj/current/SaPlusStartup.java
  46. 13 0
      sp-com/business/src/main/java/com/pj/current/config/CarConfig.java
  47. 19 0
      sp-com/business/src/main/java/com/pj/current/config/PartConfig.java
  48. 42 0
      sp-com/business/src/main/java/com/pj/current/satoken/AuthConst.java
  49. 69 0
      sp-com/business/src/main/java/com/pj/current/satoken/SaTokenConfigure.java
  50. 46 0
      sp-com/business/src/main/java/com/pj/current/satoken/StpInterfaceImpl.java
  51. 946 0
      sp-com/business/src/main/java/com/pj/current/satoken/StpUserUtil.java
  52. 6 0
      sp-com/business/src/main/java/com/pj/project/package-info.java
  53. 65 0
      sp-com/business/src/main/java/com/pj/project/sys_dict/SysDict.java
  54. 116 0
      sp-com/business/src/main/java/com/pj/project/sys_dict/SysDictController.java
  55. 55 0
      sp-com/business/src/main/java/com/pj/project/sys_dict/SysDictMapper.java
  56. 72 0
      sp-com/business/src/main/java/com/pj/project/sys_dict/SysDictMapper.xml
  57. 76 0
      sp-com/business/src/main/java/com/pj/project/sys_dict/SysDictService.java
  58. 80 0
      sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItem.java
  59. 112 0
      sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItemController.java
  60. 55 0
      sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItemMapper.java
  61. 92 0
      sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItemMapper.xml
  62. 54 0
      sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItemService.java
  63. 87 0
      sp-com/business/src/main/java/com/pj/project/tb_account/TbAccount.java
  64. 29 0
      sp-com/business/src/main/java/com/pj/project/tb_account/TbAccountController.java
  65. 28 0
      sp-com/business/src/main/java/com/pj/project/tb_account/TbAccountMapper.java
  66. 65 0
      sp-com/business/src/main/java/com/pj/project/tb_account/TbAccountMapper.xml
  67. 40 0
      sp-com/business/src/main/java/com/pj/project/tb_account/TbAccountService.java
  68. 29 0
      sp-com/business/src/main/java/com/pj/project/tb_business/BusinessMessageManager.java
  69. 217 0
      sp-com/business/src/main/java/com/pj/project/tb_business/TbBusiness.java
  70. 295 0
      sp-com/business/src/main/java/com/pj/project/tb_business/TbBusinessController.java
  71. 27 0
      sp-com/business/src/main/java/com/pj/project/tb_business/TbBusinessMapper.java
  72. 74 0
      sp-com/business/src/main/java/com/pj/project/tb_business/TbBusinessMapper.xml
  73. 364 0
      sp-com/business/src/main/java/com/pj/project/tb_business/TbBusinessService.java
  74. 97 0
      sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItem.java
  75. 53 0
      sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItemController.java
  76. 50 0
      sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItemMapper.java
  77. 92 0
      sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItemMapper.xml
  78. 66 0
      sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItemService.java
  79. 70 0
      sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeople.java
  80. 99 0
      sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeopleController.java
  81. 49 0
      sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeopleMapper.java
  82. 79 0
      sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeopleMapper.xml
  83. 51 0
      sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeopleService.java
  84. 92 0
      sp-com/business/src/main/java/com/pj/project/tb_car/TbCar.java
  85. 105 0
      sp-com/business/src/main/java/com/pj/project/tb_car/TbCarController.java
  86. 55 0
      sp-com/business/src/main/java/com/pj/project/tb_car/TbCarMapper.java
  87. 100 0
      sp-com/business/src/main/java/com/pj/project/tb_car/TbCarMapper.xml
  88. 54 0
      sp-com/business/src/main/java/com/pj/project/tb_car/TbCarService.java
  89. 109 0
      sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomer.java
  90. 126 0
      sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomerController.java
  91. 55 0
      sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomerMapper.java
  92. 113 0
      sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomerMapper.xml
  93. 150 0
      sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomerService.java
  94. 93 0
      sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrict.java
  95. 49 0
      sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrictController.java
  96. 55 0
      sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrictMapper.java
  97. 80 0
      sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrictMapper.xml
  98. 95 0
      sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrictService.java
  99. 70 0
      sp-com/business/src/main/java/com/pj/project/tb_driver/TbDriver.java
  100. 99 0
      sp-com/business/src/main/java/com/pj/project/tb_driver/TbDriverController.java

+ 18 - 0
app/apis/api.js

@@ -92,5 +92,23 @@ export default {
 	},
 	getUnitList(){
 		return ajax.get('/TbUnit/getList')
+	},
+	getPrePay(data){
+		return ajax.get('/wx/pre-pay',data)
+	},
+	getRedirectUrl(data){
+		return ajax.get('/wx/getRedirectUrl',data)
+	},
+	getOpenidByCode (data){
+		return ajax.get('/wx/getOpenidByCode',data)
+	},
+	searchPartCar(data){
+		return ajax.get('/api/searchPartCar',data)
+	},
+	getBusinessMoney(data){
+		return ajax.get('/api/getBusinessMoney',data)
+	},
+	getWxConfig(data){
+		return ajax.get('/wx/getWxConfig',data)
 	}
 }

File diff suppressed because it is too large
+ 0 - 0
app/common/js/jweixin-1.6.0.js


File diff suppressed because it is too large
+ 0 - 0
app/components/jweixin-module/index.js


+ 26 - 12
app/manifest.json

@@ -1,5 +1,5 @@
 {
-    "name" : "CZ-SYSTEM",
+    "name" : "场站管理系统",
     "appid" : "__UNI__8AC923A",
     "description" : "",
     "versionName" : "1.0.0",
@@ -17,33 +17,47 @@
             "delay" : 0
         },
         /* 模块配置 */
-        "modules" : {},
+        "modules" : {
+            "Payment" : {}
+        },
         /* 应用发布信息 */
         "distribute" : {
             /* android打包配置 */
             "android" : {
                 "permissions" : [
-                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
-                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
-                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
-                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                     "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
                     "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                     "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                     "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+                    "<uses-permission android:name=\"android.permission.INTERNET\"/>",
+                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                     "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
-                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                     "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
-                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
-                    "<uses-feature android:name=\"android.hardware.camera\"/>",
+                    "<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
                     "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                 ]
             },
             /* ios打包配置 */
             "ios" : {},
             /* SDK配置 */
-            "sdkConfigs" : {}
+            "sdkConfigs" : {
+                "payment" : {
+                    "weixin" : {
+                        "__platform__" : [ "ios", "android" ],
+                        "appid" : "",
+                        "UniversalLinks" : ""
+                    }
+                }
+            }
         }
     },
     /* 快应用特有相关 */
@@ -71,7 +85,7 @@
     "vueVersion" : "2",
     "h5" : {
         "router" : {
-            "base" : "./",
+            "base" : "/h5/",
             "mode" : "history"
         },
         "devServer" : {

+ 16 - 0
app/pages.json

@@ -156,6 +156,22 @@
 		    
 		},
 		{
+		    "path" : "pages/wx/index",
+		    "style" :                                                                                    
+		    {
+		        "navigationBarTitleText": ""
+		    }
+		    
+		},
+		{
+		    "path" : "pages/wx/pay",
+		    "style" :                                                                                    
+		    {
+		        "navigationBarTitleText": ""
+		    }
+		    
+		},
+		{
             "path" : "pages/business-entering/item-select",
             "style" :                                                                                    
             {

+ 2 - 2
app/pages/business-order/business-order.vue

@@ -70,9 +70,9 @@
 					<view class="btn b3" v-if="perList.indexOf('tb-business-pay')!=-1
 								&&businessItem.payStatus==1&&businessItem.confirmInput==1&&customemrId!='1'" @click="fkFn(businessItem)">
 						马上支付</view>
-					<view class="btn b3" v-if="perList.indexOf('tb-business-pay')!=-1&&
+					<!-- <view class="btn b3" v-if="perList.indexOf('tb-business-pay')!=-1&&
 									customemrId=='1'&&businessItem.payStatus<3&&businessItem.outDayTime!=null" @click="fkFn(businessItem)">
-						确认支付</view>
+						确认支付</view> -->
 					<view class="btn b1" v-if="customemrId=='1'&&(businessItem.realInTime==null||businessItem.chinaCarInTime==null)"
 						@click="rcFn(businessItem)">确认入场</view>
 					<view class="btn b1"

+ 34 - 19
app/pages/business-order/surePay.vue

@@ -16,7 +16,7 @@
 			<view class="item">
 				<view class="l">停车费用:</view>
 				<view class="r">
-					<text >{{form.partMoney+form.chinaPartMoney}}元</text>
+					<text>{{form.partMoney+form.chinaPartMoney}}元</text>
 				</view>
 			</view>
 			<view class="item">
@@ -26,6 +26,13 @@
 				</view>
 			</view>
 			<view class="item">
+				<u-radio-group v-model="form.payType" placement="column" @change="groupChange">
+					<u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in payTypeList" :key="index"
+						:label="item.name" :name="item.value" @change="radioChange">
+				 </u-radio>
+				</u-radio-group>
+			</view>
+			<!-- 	<view class="item">
 				<view class="l">支付凭据:</view>
 				<view class="r">
 					<view class="img">
@@ -34,9 +41,9 @@
 							@delete="form.payTicket=''" :image-styles="imageStyles" />
 					</view>
 				</view>
-			</view>
+			</view> -->
 		</view>
-		<u-button type="primary" @click="confirmFn">确认</u-button>
+		<u-button type="primary" @click="confirmFn">确认支付</u-button>
 	</view>
 </template>
 
@@ -57,8 +64,13 @@
 						radius: '5px'
 					}
 				},
+				payTypeList: [{
+					name: '微信支付',
+					value: 3
+				}],
 				form: {
-					partMoney: 0
+					partMoney: 0,
+					payType: 3
 				},
 				imgList: [],
 				uploadImageUrl: request.server + '/upload/image',
@@ -79,23 +91,23 @@
 					filePath: e.tempFilePaths[0],
 					name: 'file',
 					success: (resp => {
-						that.form.payTicket=JSON.parse(resp.data).data;
+						that.form.payTicket = JSON.parse(resp.data).data;
 					})
 				})
 			},
-			deleteFn(v){
+			deleteFn(v) {
 				console.log(v)
 			},
 			// 获取上传进度
 			progress(e) {
 				console.log('上传进度:', e)
 			},
-			
+
 			// 上传成功
 			success(e) {
 				console.log('上传成功')
 			},
-			
+
 			// 上传失败
 			fail(e) {
 				console.log('上传失败:', e)
@@ -105,21 +117,24 @@
 					id: this.id
 				}).then(resp => {
 					this.form = resp.data;
-					if(this.form.payTicket){
-						this.imageValue=[{
-							'name':'payTicket.png',
-							'extname':'.png',
-							'url':this.form.payTicket
+					this.form.payType = 3
+					if (this.form.payTicket) {
+						this.imageValue = [{
+							'name': 'payTicket.png',
+							'extname': '.png',
+							'url': this.form.payTicket
 						}]
 					}
 				})
 			},
-			confirmFn(){
-				this.$api.confirmPay(this.$common.removeNull(this.form)).then(Resp=>{
-					this.$common.toast('已支付');
-					setTimeout(()=>{
-						this.$common.back()
-					},500)
+			confirmFn() {
+				this.$api.getPrePay({
+					no: this.form.no
+				}).then(resp => {
+					if (resp.code != 200) {
+						this.$common.toast('支付异常');
+					}
+					window.location.href = resp.data.payUrl;
 				})
 			}
 		}

+ 3 - 0
app/pages/index/index.vue

@@ -38,6 +38,9 @@
 			<image class="qrcode" :src="qrcoderlc"></image>
 			<text class="text">长按二维码保存分享</text>
 		</view>
+		<view style="text-align: center;font-size: 23rpx;">
+			<a href="https://beian.miit.gov.cn/" target="_blank">桂ICP备12007573号-1</a>
+		</view>
 	</view>
 </template>
 

+ 70 - 0
app/pages/wx/index.vue

@@ -0,0 +1,70 @@
+<template>
+	<view class="box">
+
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				timestamp: 3,
+				param:''
+			}
+		},
+		onLoad(options) {
+			this.param=options.p;
+		},
+		created() {
+			this.$common.showLoading('正在加载...')
+		},
+		mounted() {
+			this.getRedirectUri();
+		},
+		beforeDestroy() {
+			this.$common.hidingLoading()
+		},
+		methods: {
+			getRedirectUri() {
+				this.$api.getRedirectUrl({path:'/pages/wx/pay',state:this.param}).then(resp => {
+					console.log(resp);
+					window.location.href = resp.data;
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #fff;
+	}
+
+	.box {
+		display: flex;
+		flex: 1;
+		align-items: center;
+		justify-content: center;
+		flex-direction: column;
+		padding: 100rpx 0;
+
+		.text {
+			color: #191919;
+			font-size: 36rpx;
+			font-weight: bold;
+			margin-top: 40rpx;
+		}
+
+		.count-down-box {
+			display: flex;
+			flex: 1;
+			align-items: center;
+			justify-content: center;
+			margin-top: 30rpx;
+
+			text {
+				margin-left: 20rpx;
+			}
+		}
+	}
+</style>

+ 206 - 0
app/pages/wx/pay.vue

@@ -0,0 +1,206 @@
+<template>
+	<view>
+		<view class="box">
+			<u-search placeholder="输入车牌号查询" shape="square" v-model="p.carNo" @search="searchFn()" @change="searchFn"
+				:height="80">
+			</u-search>
+		</view>
+		<view class="list" v-show="list.length>0">
+			<u-radio-group placement="column" @change="groupChange">
+				<u-radio :customStyle="{marginBottom: '6px',borderBottom: '1px solid #e5e5e5',paddingBottom:'5px'}"
+					v-for="(item, index) in list" :key="index" :label="item.carNo" :name="item.businessId">
+				</u-radio>
+			</u-radio-group>
+		</view>
+		<view class="car-list" v-show="cars.length>0">
+			<view>停车费:</view>
+			<view class="item" v-for="item in cars" style="margin: 20rpx 0 0 40rpx;">
+				<view class="l">{{item.carNo}}:{{item.price}}元</view>
+			</view>
+		</view>
+		<view class="car-list" v-show="item.itemsPrice" style="margin-top:40rpx;">
+			<view>业务费:{{item.itemsPrice}}元</view>
+			<view class="item" v-for="item in item.list" style="margin: 20rpx 0 0 40rpx;">
+				<view class="l">{{item.name}}:{{item.price}}元</view>
+			</view>
+		</view>
+		<view class="item" v-if="total">
+			<view>
+				合计费用:{{total}}元
+			</view>
+			<u-radio-group style="margin: 50rpx 0 20rpx 30rpx;" v-model="form.payType" placement="column"
+				@change="payTypeChange">
+				<u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in payTypeList" :key="index"
+					:label="item.name" :name="item.value">
+				</u-radio>
+			</u-radio-group>
+			<u-button type="primary" @click="confirmPayFn">立即支付</u-button>
+		</view>
+	</view>
+
+</template>
+
+<script>
+	var jweixin = require('@/components/jweixin-module/index.js');
+	export default {
+		data() {
+			return {
+				p: {
+					carNo: ''
+				},
+				code: '',
+				selectNo: '',
+				openid: '',
+				businessId:'',
+				state:'',
+				list: [],
+				cars: [],
+				item: {
+					itemsPrice: '',
+					businessId: '',
+					list: []
+				},
+				total:0,
+				payTypeList: [{
+					name: '微信支付',
+					value: 3
+				}],
+				form: {
+					partMoney: 0,
+					payType: 3
+				},
+				
+			}
+		},
+		onLoad(options) {
+			this.code = options.code;
+			this.state=options.state;
+			this.getOpenidByCode();
+		},
+		created() {},
+		mounted() {
+			this.getWxConfig();
+		},
+		beforeDestroy() {
+			this.$common.hidingLoading()
+		},
+		methods: {
+			getWxConfig() {
+				let url = window.location.href;
+				this.$api.getWxConfig({
+					url: url
+				}).then(resp => {
+					jweixin.config({
+						//debug: true,
+						appId: resp.data.appId,
+						timestamp: resp.data.timestamp, // 必填,生成签名的时间戳
+						nonceStr: resp.data.noncestr, // 必填,生成签名的随机串
+						signature: resp.data.sign, // 必填,签名
+						jsApiList: ['chooseWXPay'] // 必填,需要使用的JS接口列表
+					});
+					jweixin.ready(function() {
+						console.log('111')
+
+					});
+					jweixin.error(function(res) {
+						console.log(res)
+					});
+				})
+			},
+			confirmPayFn() {
+				let p = {
+					businessId: this.businessId,
+					carId: this.cars.map(obj=>obj.id).join(','),
+					money: this.total,
+					tradeType: "JSAPI",
+					openid: this.openid
+				}
+				this.$api.getPrePay(p).then(resp => {
+					let data = resp.data;
+					let that=this;
+					jweixin.chooseWXPay({
+						timestamp: data.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
+						nonceStr: data.nonceStr, // 支付签名随机串,不长于 32 位
+						package: data.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
+						signType: data.signType, // 微信支付V3的传入RSA,微信支付V2的传入格式与V2统一下单的签名格式保持一致
+						paySign: data.paySign, // 支付签名
+						success: function(res) {
+							if (res.errMsg === "chooseWXPay:ok") {
+								that.$common.toast('支付成功')
+								// wx.closeWindow();
+							}
+						}
+					});
+				})
+			},
+			payTypeChange(value) {
+
+			},
+			getOpenidByCode() {
+				let storeOpenid = uni.getStorageSync('openid');
+				this.$api.getOpenidByCode({
+					code: this.code,
+					openid: storeOpenid
+				}).then(resp => {
+					let openid = resp.data;
+					this.openid = openid;
+					if (openid) {
+						uni.setStorageSync('openid', openid)
+					}
+
+				})
+			},
+			groupChange(value) {
+				this.list = [];
+				this.businessId=value;
+				this.$api.getBusinessMoney({
+					businessId: value,
+					state:this.state
+				}).then(resp => {
+					let data = resp.data;
+					this.cars = data.carList;
+					this.total=data.total;
+					Object.assign(this.item, {
+						itemsPrice: data.itemsPrice,
+						businessId: value,
+						list: data.itemList
+					})
+				})
+			},
+			searchFn() {
+				if (!this.p.carNo) {
+					this.list = [];
+				} else {
+					this.$api.searchPartCar(this.p).then(resp => {
+						this.list = resp.data;
+					})
+				}
+			}
+
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #fff;
+	}
+
+	.box {
+		display: flex;
+		flex: 1;
+		align-items: center;
+		justify-content: center;
+		flex-direction: column;
+		padding: 40rpx 0;
+	}
+
+	.list {
+		margin-left: 120rpx;
+		width: 380rpx;
+		border-radius: 5rpx;
+		//background-color: rgb(242, 242, 242);
+		margin-top: -35rpx;
+		padding: 20rpx;
+	}
+</style>

+ 32 - 0
app/pages/wx/remote-js.vue

@@ -0,0 +1,32 @@
+<template>
+	<view>
+
+	</view>
+</template>
+
+<script>
+	export default {
+		components: {
+			'remote-js': {
+				render(createElement) {
+					return createElement('script', {
+						attrs: {
+							type: 'text/javascript',
+							src: this.src
+						}
+					});
+				},
+				props: {
+					src: {
+						type: String,
+						required: true
+					},
+				},
+			},
+		},
+	}
+</script>
+
+<style>
+
+</style>

+ 1 - 1
app/utils/request.js

@@ -1,6 +1,6 @@
 // const server = 'http://127.0.0.1:8099/pro';
 // const server = 'http://47.101.143.145/pro';
- const server = 'http://116.252.74.16:8099/pro';
+ const server = 'https://dxkaa1.bgigc.com/pro';
 
 import common from '../common/js/common.js';
 

+ 79 - 35
sp-admin/login.html

@@ -5,29 +5,74 @@
 		<title>登录</title>
 		<meta name="description" content="particles.js is a lightweight JavaScript library for creating particles.">
 		<meta name="author" content="Vincent Garreau" />
-		<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
+		<meta name="viewport"
+			content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
 		<link rel="stylesheet" media="screen" href="sa-frame/login/style.css">
 		<link rel="stylesheet" href="static/sa.css">
 		<style type="text/css">
 			/* 背景图片 */
-			#particles-js{
+			#particles-js {
 				background-image: url(sa-frame/login/bg.jpg);
 			}
-			
+
 			/* 样式调整 */
-			.login-box{display: flex; justify-content: center; align-items: center; position: fixed; width: inherit; height: 100%; pointer-events: none;}
-			.login{height: auto; padding: 50px 50px; position: static; margin: 0 auto !important; pointer-events: all; border-radius: 0px;}
-			.login-top{margin-top: 0px; margin-bottom: 30px;}
-			.logo-img{width: 50px; height: 50px; vertical-align: middle; position: relative; top: -3px; border-radius: 50%; margin-left: -10px; margin-right: 10px;}
-			.logo-img{display: none;}
-			.login-button{width: 270px; border-radius: 0px; transition: all 0.2s;}
-			.login-button:hover{background-color: #0E80eF;}
+			.login-box {
+				display: flex;
+				justify-content: center;
+				align-items: center;
+				position: fixed;
+				width: inherit;
+				height: 100%;
+				pointer-events: none;
+			}
+
+			.login {
+				height: auto;
+				padding: 50px 50px;
+				position: static;
+				margin: 0 auto !important;
+				pointer-events: all;
+				border-radius: 0px;
+			}
+
+			.login-top {
+				margin-top: 0px;
+				margin-bottom: 30px;
+			}
+
+			.logo-img {
+				width: 50px;
+				height: 50px;
+				vertical-align: middle;
+				position: relative;
+				top: -3px;
+				border-radius: 50%;
+				margin-left: -10px;
+				margin-right: 10px;
+			}
+
+			.logo-img {
+				display: none;
+			}
+
+			.login-button {
+				width: 270px;
+				border-radius: 0px;
+				transition: all 0.2s;
+			}
+
+			.login-button:hover {
+				background-color: #0E80eF;
+			}
+
 			/* .page-title{line-height: 50px;} */
-			.sk-rotating-plane{}
+			.sk-rotating-plane {}
+
 			/* 动画相关 */
 			/* .login{background-color: rgba(0,0,0,0); } */
-			.login{opacity: 0;}
-			
+			.login {
+				opacity: 0;
+			}
 		</style>
 	</head>
 	<body>
@@ -58,6 +103,9 @@
 			</div>
 			<div class="sk-rotating-plane"></div>
 		</div>
+		<div style="text-align: center;position: relative;bottom: 20px;background-color: #000000;padding: 5px;">
+			<a href="https://beian.miit.gov.cn/" target="_blank" style="color: #FFFFFF;">桂ICP备12007573号-1</a>
+		</div>
 
 		<!-- scripts -->
 		<script src="sa-frame/login/particles.min.js"></script>
@@ -66,15 +114,14 @@
 		<script src="static/kj/layer/layer.js"></script>
 		<script src="static/sa.js"></script>
 		<script type="text/javascript">
-			
 			// 你所有要改的代码全在这里   ↓↓↓↓↓ 
-			
+
 			// 所有参考属性  
-			var page_title = '场站管理系统 后台登录';		// 页面标题
-			var key = 'sa';							// 默认的账号
-			var password = '123456';				// 默认的password  
-			var logo = '';	// logo地址,为空字符串则不显示
-			
+			var page_title = '场站管理系统 后台登录'; // 页面标题
+			var key = 'sa'; // 默认的账号
+			var password = '123456'; // 默认的password  
+			var logo = ''; // logo地址,为空字符串则不显示
+
 			// 点击登录按钮 
 			document.querySelector(".login-button").onclick = function() {
 				// 1、取值 
@@ -83,24 +130,24 @@
 					password: $('[name=password]').val()
 				}
 				// 2、判断
-				if(p.key == '' || p.password == ''){
+				if (p.key == '' || p.password == '') {
 					return layer.msg('请输入账号密码');
 				}
 				// 3、请求后台
-				sa.ajax('/AccAdmin/doLogin', p, function(res){
+				sa.ajax('/AccAdmin/doLogin', p, function(res) {
 					// 写入token
-					if(res.data.tokenInfo) {
-						localStorage.tokenName = res.data.tokenInfo.tokenName; 
-						localStorage.tokenValue = res.data.tokenInfo.tokenValue; 
+					if (res.data.tokenInfo) {
+						localStorage.tokenName = res.data.tokenInfo.tokenName;
+						localStorage.tokenValue = res.data.tokenInfo.tokenValue;
 					}
 					// 写入权限码 
-					sa.setAuth(res.data.per_list);		
+					sa.setAuth(res.data.per_list);
 					// 打个招呼,进入 index.html 
 					sa.msg('登录成功,欢迎你:' + p.key);
-					setTimeout(function () {
-						if(parent == window){
+					setTimeout(function() {
+						if (parent == window) {
 							location.href = "index.html";
-						}else{
+						} else {
 							sa.closeCurrIframe();
 							parent.location.reload();
 						}
@@ -108,7 +155,6 @@
 				})
 			}
 			// 你所有要改的代码全在这里   ↑↑↑↑↑	
-			
 		</script>
 		<script type="text/javascript">
 			// 替换属性 
@@ -116,13 +162,13 @@
 			$('title').html(page_title);
 			$('[name=key]').val(key);
 			$('[name=password]').val(password);
-			if(logo != null && logo != '') {
+			if (logo != null && logo != '') {
 				$('.logo-img').attr('src', logo);
 				$('.logo-img').show();
 			}
 			// 绑定回车事件
-			$('[name=password]').bind('keypress', function(event){
-				if(event.keyCode == "13") {
+			$('[name=password]').bind('keypress', function(event) {
+				if (event.keyCode == "13") {
 					$('.login-button').click();
 				}
 			});
@@ -131,8 +177,6 @@
 				// document.querySelector('.login').style.backgroundColor = 'rgba(256,256,256,1)';
 				document.querySelector('.login').style.opacity = '1';
 			}, 0)
-			
-			console.log('本页面参考于jq22,原作者:http://www.jq22.com/jquery-info20074');
 		</script>
 	</body>
 </html>

+ 4 - 1
sp-admin/sa-frame/com/sa-item.vue

@@ -221,6 +221,10 @@
 			// 是否禁用
 			disabled: {},
 			// 是否换行 
+			need:{
+				type:Boolean,
+				defalut:true
+			},
 			br: {
 				type: Boolean,
 				default: false
@@ -282,7 +286,6 @@
 			},
 			// 日期范围选择时触发 
 			dateRangeOnChange: function(value) {
-				console.log(value);
 				this.dateRangeValue = value;
 				this.start = value[0];
 				this.end = value[1];

+ 19 - 23
sp-admin/sa-frame/menu-list.js

@@ -27,16 +27,6 @@ var menuList =	[
 			{id: 'tb-costomer-maintain', name: '信息维护', url: 'sa-view/tb-costomer/tb-costomer-maintain.html'},
 		]
 	},
-	// {
-	// 	id: 'tb-goods',
-	// 	name: '商品管理',
-	// 	icon: 'el-icon-folder-opened',
-	// 	info: '商品管理表数据的维护',
-	// 	childList: [
-	// 		{id: 'tb-goods-list', name: '商品管理-列表', url: 'sa-view/tb-goods/tb-goods-list.html'},
-	// 		{id: 'tb-goods-add', name: '商品管理-添加', url: 'sa-view/tb-goods/tb-goods-add.html'},
-	// 	]
-	// },
 	{
 		id: 'tb-business',
 		name: '业务录入',
@@ -49,7 +39,7 @@ var menuList =	[
 			{id: 'tb-business-pay', name: '业务支付', url: 'sa-view/tb-business/tb-business-list.html', isShow: false},
 		]
 	},
-
+	
 	{
 		id: 'tb-car',
 		name: '车辆管理',
@@ -95,17 +85,23 @@ var menuList =	[
 			{id: 'tb-notices-list', name: '消息列表', url: 'sa-view/tb-notices/tb-notices-list.html'},
 		]
 	},
+	{
+		id: 'tb-charge-record',
+		name: '充值记录',
+		icon: 'el-icon-folder-opened',
+		info: '充值记录表数据的维护',
+		childList: [
+			{id: 'tb-charge-record-list', name: '充值记录', url: 'sa-view/tb-charge-record/tb-charge-record-list.html'},
+		]
+	},
+	{
+		id: 'tb-pay-record',
+		name: '支付记录',
+		icon: 'el-icon-folder-opened',
+		info: '支付记录表数据的维护',
+		childList: [
+			{id: 'tb-pay-record-list', name: '支付记录', url: 'sa-view/tb-pay-record/tb-pay-record-list.html'},
+		]
+	},
 
-	// {
-	// 	id: 'tb-driver',
-	// 	name: '司机管理',
-	// 	icon: 'el-icon-folder-opened',
-	// 	info: '司机表数据的维护',
-	// 	childList: [
-	// 		{id: 'tb-driver-list', name: '司机-列表', url: 'sa-view/tb-driver/tb-driver-list.html'},
-	// 		{id: 'tb-driver-add', name: '司机-添加', url: 'sa-view/tb-driver/tb-driver-add.html'},
-	// 	]
-	// },
-	
-	
 ]

+ 128 - 0
sp-admin/sa-view/tb-business-car/tb-business-car-add.html

@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>-添加/修改</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/httpVueLoader.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+		<style type="text/css">
+			.c-panel .el-form .c-label{width: 7em !important;}
+			.c-panel .el-form .el-input, .c-panel .el-form .el-textarea__inner{width: 250px;}
+		</style>
+	</head>
+	<body>
+		<div class="vue-box" :class="{sbot: id}" style="display: none;" :style="'display: block;'">
+			<!-- ------- 内容部分 ------- -->
+			<div class="s-body">
+				<div class="c-panel">
+                    <div class="c-title" v-if="id == 0">数据添加</div>
+					<div class="c-title" v-else>数据修改</div>
+					<el-form v-if="m">
+						<sa-item type="text" name="" v-model="m.id" br></sa-item>
+						<sa-item type="text" name="" v-model="m.businessId" br></sa-item>
+						<sa-item type="text" name="" v-model="m.carNo" br></sa-item>
+						<sa-item type="text" name="" v-model="m.preInTime" br></sa-item>
+						<sa-item type="text" name="" v-model="m.preOutTime" br></sa-item>
+						<sa-item type="text" name="" v-model="m.realInTime" br></sa-item>
+						<sa-item type="text" name="" v-model="m.realOutTime" br></sa-item>
+						<sa-item type="text" name="" v-model="m.money" br></sa-item>
+						<sa-item type="text" name="" v-model="m.driverPhone" br></sa-item>
+						<sa-item name="" class="s-ok" br>
+							<el-button type="primary" icon="el-icon-plus" @click="ok()">保存</el-button>
+						</sa-item>
+					</el-form>
+				</div>
+			</div>
+			<!-- ------- 底部按钮 ------- -->
+			<div class="s-foot">
+				<el-button type="primary" @click="ok()">确定</el-button>
+				<el-button @click="sa.closeCurrIframe()">取消</el-button>
+			</div>
+		</div>
+        <script>
+			
+			var app = new Vue({
+				components: {
+					"sa-item": httpVueLoader('../../sa-frame/com/sa-item.vue')
+				},
+				el: '.vue-box',
+				data: {
+					id: sa.p('id', 0),		// 获取超链接中的id参数(0=添加,非0=修改) 
+					m: null,		// 实体对象 
+				},
+				methods: {
+					// 创建一个 默认Model 
+					createModel: function() {
+						return {
+							id: '',		//  
+							businessId: '',		//  
+							carNo: '',		//  
+							preInTime: '',		//  
+							preOutTime: '',		//  
+							realInTime: '',		//  
+							realOutTime: '',		//  
+							money: '',		//  
+							driverPhone: '',		//  
+						}
+					},
+					// 提交数据 
+					ok: function(){
+						// 表单校验 
+						let m = this.m;
+						sa.checkNull(m.id, '请输入 []');
+						sa.checkNull(m.businessId, '请输入 []');
+						sa.checkNull(m.carNo, '请输入 []');
+						sa.checkNull(m.preInTime, '请输入 []');
+						sa.checkNull(m.preOutTime, '请输入 []');
+						sa.checkNull(m.realInTime, '请输入 []');
+						sa.checkNull(m.realOutTime, '请输入 []');
+						sa.checkNull(m.money, '请输入 []');
+						sa.checkNull(m.driverPhone, '请输入 []');
+				
+						// 开始增加或修改
+						if(this.id <= 0) {	// 添加
+							sa.ajax('/TbBusinessCar/add', m, function(res){
+								sa.alert('增加成功', this.clean); 
+							}.bind(this));
+						} else {	// 修改
+							sa.ajax('/TbBusinessCar/update', m, function(res){
+								sa.alert('修改成功', this.clean);
+							}.bind(this));
+						}
+					},
+					// 添加/修改 完成后的动作
+					clean: function() {
+						if(this.id == 0) {
+							this.m = this.createModel();
+						} else {
+							parent.app.f5();		// 刷新父页面列表
+							sa.closeCurrIframe();	// 关闭本页 
+						}
+					}
+				},
+				mounted: function(){
+					// 初始化数据 
+					if(this.id <= 0) {	
+						this.m = this.createModel();
+					} else {	
+						sa.ajax('/TbBusinessCar/getById?id=' + this.id, function(res) {
+							this.m = res.data;
+							if(res.data == null) {
+								sa.alert('未能查找到 id=' + this.id + " 详细数据");
+							}
+						}.bind(this))
+					}
+				}
+			})
+			
+		</script>
+	</body>
+</html>

+ 68 - 0
sp-admin/sa-view/tb-business-car/tb-business-car-info.html

@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>-详情</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/httpVueLoader.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+		<style type="text/css">
+			.c-panel .c-label{width: 8em;}
+		</style>
+	</head>
+	<body>
+		<div class="vue-box sbot" style="display: none;" :style="'display: block;'">
+			<!-- ------- 内容部分 ------- -->
+			<div class="s-body">
+				<div class="c-panel">
+					<el-form v-if="m">
+						<sa-info name="" br>{{m.id}}</sa-info>
+						<sa-info name="" br>{{m.businessId}}</sa-info>
+						<sa-info name="" br>{{m.carNo}}</sa-info>
+						<sa-info name="" br>{{m.preInTime}}</sa-info>
+						<sa-info name="" br>{{m.preOutTime}}</sa-info>
+						<sa-info name="" br>{{m.realInTime}}</sa-info>
+						<sa-info name="" br>{{m.realOutTime}}</sa-info>
+						<sa-info name="" br>{{m.money}}</sa-info>
+						<sa-info name="" br>{{m.driverPhone}}</sa-info>
+					</el-form>
+				</div>
+			</div>
+			<!-- ------- 底部按钮 ------- -->
+			<div class="s-foot">
+				<el-button type="success" @click="sa.closeCurrIframe()">确定</el-button>
+				<el-button @click="sa.closeCurrIframe()">取消</el-button>
+			</div>
+		</div>
+		<script>
+			var app = new Vue({
+				components: {
+					"sa-info": httpVueLoader('../../sa-frame/com/sa-info.vue')
+				},
+				el: '.vue-box',
+				data: {
+					id: sa.p('id', 0),	// 获取数据ID 
+					m: null
+				},
+				methods: {
+				},
+				mounted: function() {
+					sa.ajax('/TbBusinessCar/getById?id=' + this.id, function(res) {
+						this.m = res.data;
+						if(res.data == null) {
+							sa.alert('未能查找到 id=' + this.id + " 详细数据");
+						}
+					}.bind(this))
+				}
+			})
+			
+		</script>
+	</body>
+</html>

+ 164 - 0
sp-admin/sa-view/tb-business-car/tb-business-car-list.html

@@ -0,0 +1,164 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>-列表</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css & js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/httpVueLoader.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+	</head>
+	<body>
+		<div class="vue-box" style="display: none;" :style="'display: block;'">
+			<div class="c-panel">
+				<!-- ------------- 检索参数 ------------- -->
+				<div class="c-title">检索参数</div>
+				<el-form ref="form" :model='p' @submit.native.prevent>
+					<sa-item type="text" name="" v-model="p.id"></sa-item>
+					<sa-item type="text" name="" v-model="p.businessId"></sa-item>
+					<sa-item type="text" name="" v-model="p.carNo"></sa-item>
+					<sa-item type="text" name="" v-model="p.preInTime"></sa-item>
+					<sa-item type="text" name="" v-model="p.preOutTime"></sa-item>
+					<sa-item type="text" name="" v-model="p.realInTime"></sa-item>
+					<sa-item type="text" name="" v-model="p.realOutTime"></sa-item>
+					<sa-item type="text" name="" v-model="p.money"></sa-item>
+					<sa-item type="text" name="" v-model="p.driverPhone"></sa-item>
+					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
+					<br />
+					<sa-item name="综合排序">
+						<el-radio-group v-model="p.sortType" class="s-radio-text">
+							<el-radio :label="0">默认</el-radio>
+							<el-radio :label="1"></el-radio>
+							<el-radio :label="2"></el-radio>
+							<el-radio :label="3"></el-radio>
+							<el-radio :label="4"></el-radio>
+							<el-radio :label="5"></el-radio>
+							<el-radio :label="6"></el-radio>
+							<el-radio :label="7"></el-radio>
+							<el-radio :label="8"></el-radio>
+							<el-radio :label="9"></el-radio>
+						</el-radio-group>
+					</sa-item>
+				</el-form>
+				<!-- ------------- 快捷按钮 ------------- -->
+				<sa-item type="fast-btn" show="add,get,delete,export,reset"></sa-item>
+				<!-- ------------- 数据列表 ------------- -->
+				<el-table class="data-table" ref="data-table" :data="dataList" >
+					<sa-td type="selection"></sa-td>
+					<sa-td name="" prop="id" ></sa-td>
+					<sa-td name="" prop="businessId" ></sa-td>
+					<sa-td name="" prop="carNo" ></sa-td>
+					<sa-td name="" prop="preInTime" ></sa-td>
+					<sa-td name="" prop="preOutTime" ></sa-td>
+					<sa-td name="" prop="realInTime" ></sa-td>
+					<sa-td name="" prop="realOutTime" ></sa-td>
+					<sa-td name="" prop="money" ></sa-td>
+					<sa-td name="" prop="driverPhone" ></sa-td>
+					<el-table-column label="操作" fixed="right"  width="240px">
+						<template slot-scope="s">
+							<el-button class="c-btn" type="success" icon="el-icon-view" @click="get(s.row)">查看</el-button>
+							<el-button class="c-btn" type="primary" icon="el-icon-edit" @click="update(s.row)">修改</el-button>
+							<el-button class="c-btn" type="danger" icon="el-icon-delete" @click="del(s.row)">删除</el-button>
+						</template>
+					</el-table-column>
+				</el-table>
+				<!-- ------------- 分页 ------------- -->
+				<sa-item type="page" :curr.sync="p.pageNo" :size.sync="p.pageSize" :total="dataCount" @change="f5()"></sa-item>
+			</div>
+		</div>
+		<script>
+			var app = new Vue({
+				components: {
+					"sa-item": httpVueLoader('../../sa-frame/com/sa-item.vue'),  
+					"sa-td": httpVueLoader('../../sa-frame/com/sa-td.vue'),		
+				},
+				el: '.vue-box',
+				data: {
+					p: { // 查询参数  
+						id: '',		//  
+						businessId: '',		//  
+						carNo: '',		//  
+						preInTime: '',		//  
+						preOutTime: '',		//  
+						realInTime: '',		//  
+						realOutTime: '',		//  
+						money: '',		//  
+						driverPhone: '',		//  
+						pageNo: 1,		// 当前页 
+						pageSize: 10,	// 页大小 
+						sortType: 0		// 排序方式 
+					},
+					dataCount: 0,
+					dataList: [], // 数据集合 
+				},
+				methods: {
+					// 刷新
+					f5: function() {
+						sa.ajax('/TbBusinessCar/getList', sa.removeNull(this.p), function(res) {
+							this.dataList = res.data; // 数据
+							this.dataCount = res.dataCount; // 数据总数 
+							sa.f5TableHeight();		// 刷新表格高度 
+						}.bind(this));
+					},
+					// 查看
+					get: function(data) {
+						sa.showIframe('数据详情', 'tb-business-car-info.html?id=' + data.id, '1050px', '90%');
+					},
+					// 查看 - 根据选中的
+					getBySelect: function(data) {
+						var selection = this.$refs['data-table'].selection;
+						if(selection.length == 0) {
+							return sa.msg('请选择一条数据')
+						}
+						this.get(selection[0]);
+					},
+					// 修改
+					update: function(data) {
+						sa.showIframe('修改数据', 'tb-business-car-add.html?id=' + data.id, '1000px', '90%');
+					},
+					// 新增
+					add: function(data) {
+						sa.showIframe('新增数据', 'tb-business-car-add.html?id=-1', '1000px', '90%');
+					},
+					// 删除
+					del: function(data) {
+						sa.confirm('是否删除,此操作不可撤销', function() {
+							sa.ajax('/TbBusinessCar/delete?id=' + data.id, function(res) {
+								sa.arrayDelete(this.dataList, data);
+								sa.ok('删除成功');
+								sa.f5TableHeight();		// 刷新表格高度 
+							}.bind(this))
+						}.bind(this));
+					},
+					// 批量删除
+					deleteByIds: function() {
+						// 获取选中元素的id列表 
+						let selection = this.$refs['data-table'].selection;
+						let ids = sa.getArrayField(selection, 'id');
+						if(selection.length == 0) {
+							return sa.msg('请至少选择一条数据')
+						}
+						// 提交删除 
+						sa.confirm('是否批量删除选中数据?此操作不可撤销', function() {
+							sa.ajax('/TbBusinessCar/deleteByIds', {ids: ids.join(',')}, function(res) {
+								sa.arrayDelete(this.dataList, selection);
+								sa.ok('删除成功');
+								sa.f5TableHeight();		// 刷新表格高度 
+							}.bind(this))
+						}.bind(this));
+					},
+				},
+				created: function() {
+					this.f5();
+					sa.onInputEnter();
+				}
+			})
+		</script>
+	</body>
+</html>

+ 178 - 37
sp-admin/sa-view/tb-business/tb-business-add.html

@@ -41,6 +41,10 @@
 				font-weight: bold;
 
 			}
+
+			.china-car-size .el-input__inner {
+				width: 130px;
+			}
 		</style>
 	</head>
 	<body>
@@ -74,8 +78,7 @@
 												</el-option>
 											</el-select>
 										</div>
-										<sa-item type="num" name="载重(吨)"  placeholder="请输入车辆载重"
-											v-model="m.netWeight" br>
+										<sa-item type="num" name="载重(吨)" placeholder="请输入车辆载重" v-model="m.netWeight" br>
 										</sa-item>
 										<sa-item type="text" name="境外车牌号" placeholder="请输入境外车牌号" v-model="m.cardNo" br>
 										</sa-item>
@@ -87,15 +90,16 @@
 												:fetch-suggestions="queryCaSizerAsync">
 											</el-autocomplete>
 										</div>
-
-										<sa-item type="text" name="中国车牌" placeholder="请输入中国车牌" v-model="m.chinaCarNo"
-											br></sa-item>
-										<sa-item type="text" name="中国司机" placeholder="请输入中国车司机" v-model="m.driverName"
-											br></sa-item>
-										<sa-item type="text" name="联系号码" placeholder="请输入联系号码" v-model="m.driverPhone"
-											br></sa-item>
-										<sa-item type="datetime" name="预计入场" placeholder="请选择" v-model="m.expectInDay"
-											br></sa-item>
+										<div class="c-item">
+											<label class="c-label">中国车:</label>
+											<el-input v-model="china.list.map(obj=>obj.carNo).join('、')"
+												placeholder="添加中国车" readonly>
+												<div slot="suffix" style="cursor: pointer;color: blue;" @click="addCar">
+													<i class="el-icon-folder-add"></i>
+												</div>
+											</el-input>
+											</el-autocomplete>
+										</div>
 									</div>
 								</el-card>
 							</el-col>
@@ -108,11 +112,13 @@
 									<div>
 										<el-form-item v-for="(type,index) in filterTypeList" style="display: flex;"
 											v-if="filterTypeList.length>0">
-											<label slot="label"><label v-if="needTypeId.indexOf(type.id)!==-1"
+											<label slot="label">
+												<label v-if="needTypeId.indexOf(type.id)!==-1"
 													style="color: red;">*</label>{{type.name}}</label>
-											<el-select v-model="type.itemId" style="width: 120px;" placeholder="请选择">
-												<el-option v-for="item in type.items" :key="item.id" :label="item.itemName" :value="item.id"
-												v-if="m.netWeight >= item.minWeight && m.netWeight < item.maxWeight
+											<el-select v-model="type.itemId" style="width: 120px;" @change="itemChange"
+												placeholder="请选择">
+												<el-option v-for="item in type.items" :key="item.id"
+													:label="item.itemName" :value="item.id" v-if="m.netWeight >= item.minWeight && m.netWeight < item.maxWeight
 												&&m.cardSize<=item.carLength&&m.cardSize>=item.minLength">
 												</el-option>
 											</el-select>
@@ -121,7 +127,7 @@
 												:disabled="type.inc==0"></el-input-number>
 											<div class="xj" v-if="type.itemId">
 												{{type.items.filter(obj=>obj.id==type.itemId)[0].price*type.num}}元
-												<label @click="type.itemId=''"
+												<label @click="cleanItem(type)"
 													style="margin-left: 5px;cursor: pointer">(<i
 														class="el-icon-delete"></i>)</label>
 											</div>
@@ -138,10 +144,8 @@
 								</el-card>
 							</el-col>
 						</el-row>
-
 					</el-form>
 				</div>
-
 			</div>
 			<!-- ------- 底部按钮 ------- -->
 			<div class="s-foot">
@@ -188,6 +192,65 @@
 					<el-button type="primary" @click="confirmAdd">确 定</el-button>
 				</span>
 			</el-dialog>
+			<el-dialog title="添加中国车" :visible.sync="china.visible" width="80%">
+				<el-card class="box-card">
+					<div slot="header">
+						<span>列表</span>
+						<el-button style="float: right;" icon="el-icon-plus" type="primary" @click="addChinaCarFn">添加
+						</el-button>
+					</div>
+					<el-table :data="china.list">
+						<el-table-column prop="carNo" label="车牌号">
+						</el-table-column>
+						<el-table-column prop="driverName" label="联系人">
+						</el-table-column>
+						<el-table-column prop="driverPhone" label="联系号码">
+						</el-table-column>
+						<el-table-column prop="carSize" label="车辆规格">
+						</el-table-column>
+						<el-table-column label="操作">
+							<template slot-scope="s">
+								<el-button class="c-btn" type="info" @click="editChinaCarFn(s.row)">修改</el-button>
+								<el-button class="c-btn" type="danger" @click="deleteChinaCarFn(s.row)">删除</el-button>
+							</template>
+						</el-table-column>
+					</el-table>
+				</el-card>
+				<span slot="footer" class="dialog-footer">
+					<el-button @click="china.visible=false">关 闭</el-button>
+					<el-button type="primary" @click="china.visible=false">确 定</el-button>
+				</span>
+			</el-dialog>
+			<el-dialog title="添加中国车" :visible.sync="car.visible" width="300">
+				<span>
+					<el-form label-position="left">
+						<div class="c-item">
+							<label class="c-label"><span style="color: red;">*</span>车牌号:</label>
+							<el-input v-model="car.form.carNo" placeholder="车牌号">
+							</el-input>
+						</div>
+						<div class="c-item">
+							<label class="c-label"><span style="color: red;">*</span>车辆规格:</label>
+							<el-input-number class="china-car-size" v-model="car.form.carSize" controls-position="right"
+								:min="1" :max="50"></el-input-number>
+						</div>
+						<div class="c-item">
+							<label class="c-label">联系人:</label>
+							<el-input v-model="car.form.driverName" placeholder="联系人">
+							</el-input>
+						</div>
+						<div class="c-item">
+							<label class="c-label">联系号码:</label>
+							<el-input v-model="car.form.driverPhone" placeholder="联系号码">
+							</el-input>
+						</div>
+					</el-form>
+				</span>
+				<span slot="footer" class="dialog-footer">
+					<el-button @click="car.visible = false">取 消</el-button>
+					<el-button type="primary" @click="confirmAddCar">确 定</el-button>
+				</span>
+			</el-dialog>
 		</div>
 		<script>
 			var app = new Vue({
@@ -215,6 +278,7 @@
 						driverIdCard: '', // 司机身份证 
 						payTicket: '', // 支付凭证 
 					}, // 实体对象 
+					checkItem:'',
 					customerList: [],
 					cardList: [],
 					driverList: [],
@@ -244,7 +308,20 @@
 						}
 					},
 					unitList: [],
-					needTypeId: []
+					needTypeId: [],
+					china: {
+						visible: false,
+						list: []
+					},
+					car: {
+						visible: false,
+						form: {
+							carNo: '',
+							driverName: '',
+							driverPhone: '',
+							carSize: ''
+						}
+					}
 				},
 				computed: {
 					totalPrice() {
@@ -266,6 +343,75 @@
 					}
 				},
 				methods: {
+					cleanItem(type) {
+						type.itemId = '';
+						let typeName=type.name;
+						if (typeName == '干杂货人工装卸' ||typeName == '特殊车辆') {
+							this.checkItem='';
+						}
+					},
+					itemChange(itemId) {
+						let items = this.itemTypeList.flatMap(obj => obj.items);
+						let item = items.filter(obj => obj.id == itemId)[0];
+						let typeName = item.typeName;
+						let checkItem = this.checkItem;
+						if ((typeName == '干杂货人工装卸' && checkItem=='特殊车辆') ||
+							(typeName == '特殊车辆' && checkItem=='干杂货人工装卸')) {
+							this.itemTypeList.filter(obj => obj.id == item.typeId)[0].itemId = ''
+							sa.error('不能同时选择干杂货人工装卸和特殊车辆')
+							return false;
+						}
+						if (typeName == '干杂货人工装卸' ||typeName == '特殊车辆') {
+							this.checkItem=typeName;
+						}
+					},
+					addCar() {
+						this.china.visible = true;
+					},
+					addChinaCarFn() {
+						Object.assign(this.car, {
+							visible: true,
+							form: {
+								carNo: '',
+								driverName: '',
+								driverPhone: '',
+								carSize: ''
+							}
+						})
+					},
+					confirmAddCar() {
+						let carNo = this.car.form.carNo;
+						if (!carNo) {
+							sa.error('请填入车牌号')
+							return false;
+						}
+						if (!this.car.form.carSize) {
+							sa.error('请填入车辆规格')
+							return false;
+						}
+						let phone = this.car.form.phone;
+						if (phone && !sa.isPhone(phone)) {
+							sa.error('联系号码不正确')
+							return false;
+						}
+						let list = this.china.list;
+						let index = list.map(obj => obj.carNo).indexOf(carNo);
+						if (index > -1) {
+							list.splice(index, 1);
+						}
+						this.china.list.push(this.car.form);
+						this.car.visible = false;
+
+					},
+					editChinaCarFn(data) {
+						Object.assign(this.car, {
+							visible: true,
+							form: data
+						})
+					},
+					deleteChinaCarFn(data) {
+						this.china.list.splice(this.china.list.indexOf(data), 1)
+					},
 					goodsChange(value) {
 						let goods = this.goodsList.filter(obj => obj.name === value).pop();
 						let noNeedIds = goods.noNeedIds.split(',');
@@ -424,19 +570,19 @@
 							sa.error('载重只能输入数字')
 							return;
 						}
-						sa.checkNull(m.driverName, '请输入 [中国司机名称]');
-						if (!sa.isPhone(m.driverPhone)) {
-							sa.error('司机联系号码不正确')
-							return false;
-						}
-						sa.checkNull(m.chinaCarNo, '请输入 [中国车牌号]');
 						let checkList = this.itemTypeList;
+						let chechItem=this.checkItem;
 						for (let j in this.needTypeId) {
 							let id = this.needTypeId[j];
 							for (let i in checkList) {
 								let type = checkList[i];
-								if (id == type.id && !type.itemId) {
-									sa.error('选择[' + this.m.goodsName + ']时,[' + type.name + ']必选')
+								let typeName = type.name;
+								if (id == type.id && !type.itemId&&typeName!=='特殊车辆'&&typeName!=='干杂货人工装卸') {
+									sa.error('选择[' + this.m.goodsName + ']时,[' + typeName + ']必选')
+									return;
+								}
+								if(!chechItem&&this.m.goodsName=='干杂货'){
+									sa.error('请选择特殊车辆或干杂货人工装卸之一')
 									return;
 								}
 							}
@@ -464,17 +610,12 @@
 
 						m.itemJson = JSON.stringify(list);
 						m.peopleJson = JSON.stringify(this.modal.list);
+						m.carJson = JSON.stringify(this.china.list);
 						m.items = [];
-
-						if (this.id <= 0) { // 添加
-							sa.ajax('/TbBusiness/add', m, function(res) {
-								sa.alert('增加成功', this.clean);
-							}.bind(this));
-						} else { // 修改
-							sa.ajax('/TbBusiness/update', m, function(res) {
-								sa.alert('修改成功', this.clean);
-							}.bind(this));
-						}
+						m.cars = [];
+						sa.ajax('/TbBusiness/add', m, function(res) {
+							sa.alert('增加成功', this.clean);
+						}.bind(this));
 					},
 					// 添加/修改 完成后的动作
 					clean: function() {

+ 117 - 0
sp-admin/sa-view/tb-business/tb-business-car-list.html

@@ -0,0 +1,117 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>-列表</title>
+		<meta charset="utf-8">
+		<meta name="viewport"
+			content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css & js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/httpVueLoader.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+	</head>
+	<body>
+		<div class="vue-box" style="display: none;" :style="'display: block;'">
+			<div class="c-panel">
+				<!-- ------------- 数据列表 ------------- -->
+				<el-table class="data-table" ref="data-table" :data="dataList">
+					<sa-td type="selection"></sa-td>
+					<sa-td name="车牌号" prop="carNo"></sa-td>
+					<sa-td name="车辆规格" prop="carSize"></sa-td>
+					<sa-td name="联系人" prop="driverName"></sa-td>
+					<sa-td name="联系号码" prop="driverPhone"></sa-td>
+					<sa-td name="入场时间" prop="realInTime"></sa-td>
+					<sa-td name="离场时间" prop="realOutTime"></sa-td>
+					<el-table-column label="停车费">
+						<template slot-scope="s">
+							<label v-if="s.row.money">{{s.row.money}}</label>
+							<label v-else>{{s.row.basePartMoney}}</label>
+						</template>
+					</el-table-column>
+					<sa-td width="130" name="支付状态" prop="pay" type="enum" :jv="{0: '未支付[#ff0000]', 1: '已支付[#005500]'}">
+					</sa-td>
+					<sa-td name="状态" prop="isLock" type="switch" :jv="{1: '锁定[#ff0000]', 0: '正常[#005500]'}"
+						@change="s => updateStatus(s.row)"></sa-td>
+					<!-- 	<el-table-column label="操作" fixed="right" width="240px">
+						<template slot-scope="s">
+							<el-button class="c-btn" type="success" icon="el-icon-view" @click="get(s.row)">查看
+							</el-button>
+							<el-button class="c-btn" type="primary" icon="el-icon-edit" @click="update(s.row)">修改
+							</el-button>
+							<el-button class="c-btn" type="danger" icon="el-icon-delete" @click="del(s.row)">删除
+							</el-button>
+						</template>
+					</el-table-column> -->
+				</el-table>
+				<!-- ------------- 分页 ------------- -->
+				<sa-item type="page" :curr.sync="p.pageNo" :size.sync="p.pageSize" :total="dataCount" @change="f5()">
+				</sa-item>
+			</div>
+		</div>
+		<script>
+			var app = new Vue({
+				components: {
+					"sa-item": httpVueLoader('../../sa-frame/com/sa-item.vue'),
+					"sa-td": httpVueLoader('../../sa-frame/com/sa-td.vue'),
+				},
+				el: '.vue-box',
+				data: {
+					p: { // 查询参数  
+						id: '', //  
+						businessId: sa.p('id', '-1'), //  
+						carNo: '', //  
+						preInTime: '', //  
+						preOutTime: '', //  
+						realInTime: '', //  
+						realOutTime: '', //  
+						money: '', //  
+						driverPhone: '', //  
+						pageNo: 1, // 当前页 
+						pageSize: 10, // 页大小 
+						sortType: 0 // 排序方式 
+					},
+					dataCount: 0,
+					dataList: [], // 数据集合 
+				},
+				methods: {
+					// 刷新
+					f5: function() {
+						sa.ajax('/TbBusinessCar/getList', sa.removeNull(this.p), function(res) {
+							this.dataList = res.data; // 数据
+							this.dataCount = res.dataCount; // 数据总数 
+							sa.f5TableHeight(); // 刷新表格高度 
+						}.bind(this));
+					},
+					// 改 - 状态(0=否,1=是)
+					updateStatus: function(data) {
+						// 声明变量记录是否成功 
+						var isOk = false;
+						var oldValue = data.isLock;
+						var ajax = sa.ajax('/TbBusinessCar/updateStatus', {
+							id: data.id,
+							value: data.isLock
+						}, function(res) {
+							isOk = true;
+							sa.msg('修改成功');
+						}.bind(this));
+						// 如果未能修改成功, 则回滚 
+						$.when(ajax).done(function() {
+							if (isOk == false) {
+								data.isLock = oldValue;
+							}
+						})
+					},
+				},
+				created: function() {
+					this.f5();
+					sa.onInputEnter();
+				}
+			})
+		</script>
+	</body>
+</html>

+ 170 - 22
sp-admin/sa-view/tb-business/tb-business-edit.html

@@ -86,15 +86,16 @@
 												:fetch-suggestions="queryCaSizerAsync">
 											</el-autocomplete>
 										</div>
-
-										<sa-item type="text" name="中国车牌" placeholder="请输入中国车牌" v-model="m.chinaCarNo"
-											br></sa-item>
-										<sa-item type="text" name="中国司机" placeholder="请输入中国车司机" v-model="m.driverName"
-											br></sa-item>
-										<sa-item type="text" name="联系号码" placeholder="请输入联系号码" v-model="m.driverPhone"
-											br></sa-item>
-										<sa-item type="datetime" name="预计入场" placeholder="请选择" v-model="m.expectInDay"
-											br></sa-item>
+										<div class="c-item">
+											<label class="c-label">中国车:</label>
+											<el-input v-model="china.list.map(obj=>obj.carNo).join('、')"
+												placeholder="添加中国车" readonly>
+												<div slot="suffix" style="cursor: pointer;color: blue;" @click="addCar">
+													<i class="el-icon-folder-add"></i>
+												</div>
+											</el-input>
+											</el-autocomplete>
+										</div>
 									</div>
 								</el-card>
 							</el-col>
@@ -109,7 +110,8 @@
 											v-if="filterTypeList.length>0">
 											<label slot="label"><label v-if="needTypeId.indexOf(type.id)!==-1"
 													style="color: red;">*</label>{{type.name}}</label>
-											<el-select v-model="type.itemId" style="width: 120px;" placeholder="请选择">
+											<el-select v-model="type.itemId" style="width: 120px;" @change="itemChange"
+												placeholder="请选择">
 												<el-option v-for="item in type.items" v-if="m.netWeight >= item.minWeight && m.netWeight < item.maxWeight
 													&&m.cardSize<=item.carLength&&m.cardSize>=item.minLength" :key="item.id" :label="item.itemName"
 													:value="item.id">
@@ -120,7 +122,7 @@
 												:disabled="type.inc==0"></el-input-number>
 											<div class="xj" v-if="type.itemId">
 												{{type.items.filter(obj=>obj.id==type.itemId)[0].price*type.num}}元
-												<label @click="type.itemId=''"
+												<label @click="cleanItem(type)"
 													style="margin-left: 5px;cursor: pointer">(<i
 														class="el-icon-delete"></i>)</label>
 											</div>
@@ -187,6 +189,65 @@
 					<el-button type="primary" @click="confirmAdd">确 定</el-button>
 				</span>
 			</el-dialog>
+			<el-dialog title="添加中国车" :visible.sync="china.visible" width="80%">
+				<el-card class="box-card">
+					<div slot="header">
+						<span>列表</span>
+						<el-button style="float: right;" icon="el-icon-plus" type="primary" @click="addChinaCarFn">添加
+						</el-button>
+					</div>
+					<el-table :data="china.list">
+						<el-table-column prop="carNo" label="车牌号">
+						</el-table-column>
+						<el-table-column prop="driverName" label="联系人">
+						</el-table-column>
+						<el-table-column prop="driverPhone" label="联系号码">
+						</el-table-column>
+						<el-table-column prop="carSize" label="车辆规格">
+						</el-table-column>
+						<el-table-column label="操作">
+							<template slot-scope="s">
+								<el-button class="c-btn" type="info" @click="editChinaCarFn(s.row)">修改</el-button>
+								<el-button class="c-btn" type="danger" @click="deleteChinaCarFn(s.row)">删除</el-button>
+							</template>
+						</el-table-column>
+					</el-table>
+				</el-card>
+				<span slot="footer" class="dialog-footer">
+					<el-button @click="china.visible=false">关 闭</el-button>
+					<el-button type="primary" @click="china.visible=false">确 定</el-button>
+				</span>
+			</el-dialog>
+			<el-dialog title="添加中国车" :visible.sync="car.visible" width="300">
+				<span>
+					<el-form label-position="left">
+						<div class="c-item">
+							<label class="c-label"><span style="color: red;">*</span>车牌号:</label>
+							<el-input v-model="car.form.carNo" placeholder="车牌号">
+							</el-input>
+						</div>
+						<div class="c-item">
+							<label class="c-label"><span style="color: red;">*</span>车辆规格:</label>
+							<el-input-number class="china-car-size" v-model="car.form.carSize" controls-position="right"
+								:min="1" :max="50"></el-input-number>
+						</div>
+						<div class="c-item">
+							<label class="c-label">联系人:</label>
+							<el-input v-model="car.form.driverName" placeholder="联系人">
+							</el-input>
+						</div>
+						<div class="c-item">
+							<label class="c-label">联系号码:</label>
+							<el-input v-model="car.form.driverPhone" placeholder="联系号码">
+							</el-input>
+						</div>
+					</el-form>
+				</span>
+				<span slot="footer" class="dialog-footer">
+					<el-button @click="car.visible = false">取 消</el-button>
+					<el-button type="primary" @click="confirmAddCar">确 定</el-button>
+				</span>
+			</el-dialog>
 		</div>
 		<script>
 			var app = new Vue({
@@ -214,6 +275,7 @@
 						driverIdCard: '', // 司机身份证 
 						payTicket: '', // 支付凭证 
 					}, // 实体对象 
+					checkItem: '',
 					customerList: [],
 					cardList: [],
 					driverList: [],
@@ -243,7 +305,20 @@
 						}
 					},
 					unitList: [],
-					needTypeId: []
+					needTypeId: [],
+					china: {
+						visible: false,
+						list: []
+					},
+					car: {
+						visible: false,
+						form: {
+							carNo: '',
+							driverName: '',
+							driverPhone: '',
+							carSize: ''
+						}
+					}
 				},
 				computed: {
 					totalPrice() {
@@ -265,6 +340,75 @@
 					}
 				},
 				methods: {
+					cleanItem(type) {
+						type.itemId = '';
+						let typeName = type.name;
+						if (typeName == '干杂货人工装卸' || typeName == '特殊车辆') {
+							this.checkItem = '';
+						}
+					},
+					itemChange(itemId) {
+						let items = this.itemTypeList.flatMap(obj => obj.items);
+						let item = items.filter(obj => obj.id == itemId)[0];
+						let typeName = item.typeName;
+						let checkItem = this.checkItem;
+						if ((typeName == '干杂货人工装卸' && checkItem == '特殊车辆') ||
+							(typeName == '特殊车辆' && checkItem == '干杂货人工装卸')) {
+							this.itemTypeList.filter(obj => obj.id == item.typeId)[0].itemId = ''
+							sa.error('不能同时选择干杂货人工装卸和特殊车辆')
+							return false;
+						}
+						if (typeName == '干杂货人工装卸' || typeName == '特殊车辆') {
+							this.checkItem = typeName;
+						}
+					},
+					addCar() {
+						this.china.visible = true;
+					},
+					addChinaCarFn() {
+						Object.assign(this.car, {
+							visible: true,
+							form: {
+								carNo: '',
+								driverName: '',
+								driverPhone: '',
+								carSize: ''
+							}
+						})
+					},
+					confirmAddCar() {
+						let carNo = this.car.form.carNo;
+						if (!carNo) {
+							sa.error('请填入车牌号')
+							return false;
+						}
+						if (!this.car.form.carSize) {
+							sa.error('请填入车辆规格')
+							return false;
+						}
+						let phone = this.car.form.phone;
+						if (phone && !sa.isPhone(phone)) {
+							sa.error('联系号码不正确')
+							return false;
+						}
+						let list = this.china.list;
+						let index = list.map(obj => obj.carNo).indexOf(carNo);
+						if (index > -1) {
+							list.splice(index, 1);
+						}
+						this.china.list.push(this.car.form);
+						this.car.visible = false;
+
+					},
+					editChinaCarFn(data) {
+						Object.assign(this.car, {
+							visible: true,
+							form: data
+						})
+					},
+					deleteChinaCarFn(data) {
+						this.china.list.splice(this.china.list.indexOf(data), 1)
+					},
 					goodsChange(value) {
 						let goods = this.goodsList.filter(obj => obj.name === value).pop();
 						let noNeedIds = goods.noNeedIds.split(',');
@@ -371,6 +515,7 @@
 							sa.ajax('/TbBusiness/getById?id=' + this.id, function(res) {
 								let m = res.data;
 								let items = m.items;
+								this.china.list = m.cars;
 								let hsItem = items.filter(obj => obj.itemTypeName.indexOf('人') !== -1 &&
 									obj.itemTypeName.indexOf('核酸') !== -1);
 								if (hsItem.length > 0) {
@@ -378,6 +523,9 @@
 								}
 								for (let i in items) {
 									let item = items[i];
+									if (item.itemTypeName == '特殊车辆' || item.itemTypeName == '干杂货人工装卸') {
+										this.checkItem = item.itemTypeName
+									}
 									for (let j in typeList) {
 										let type = typeList[j];
 										if (item.itemTypeId == type.id) {
@@ -445,19 +593,19 @@
 							sa.error('载重只能输入数字')
 							return;
 						}
-						sa.checkNull(m.driverName, '请输入 [中国司机名称]');
-						if (!sa.isPhone(m.driverPhone)) {
-							sa.error('司机联系号码不正确')
-							return false;
-						}
-						sa.checkNull(m.chinaCarNo, '请输入 [中国车牌号]');
 						let checkList = this.itemTypeList;
+						let chechItem = this.checkItem;
 						for (let j in this.needTypeId) {
 							let id = this.needTypeId[j];
 							for (let i in checkList) {
 								let type = checkList[i];
-								if (id == type.id && !type.itemId) {
-									sa.error('选择[' + this.m.goodsName + ']时,[' + type.name + ']必选')
+								let typeName = type.name;
+								if (id == type.id && !type.itemId && typeName !== '特殊车辆' && typeName !== '干杂货人工装卸') {
+									sa.error('选择[' + this.m.goodsName + ']时,[' + typeName + ']必选')
+									return;
+								}
+								if (!chechItem && this.m.goodsName == '干杂货') {
+									sa.error('请选择特殊车辆或干杂货人工装卸之一')
 									return;
 								}
 							}
@@ -485,8 +633,9 @@
 
 						m.itemJson = JSON.stringify(list);
 						m.peopleJson = JSON.stringify(this.modal.list);
+						m.carJson = JSON.stringify(this.china.list);
 						m.items = [];
-
+						m.cars = [];
 						if (this.id <= 0) { // 添加
 							sa.ajax('/TbBusiness/add', m, function(res) {
 								sa.alert('增加成功', this.clean);
@@ -516,7 +665,6 @@
 					this.getUnitList();
 				},
 				beforeDestroy() {
-					console.log(111)
 					parent.app.f5();
 				}
 			})

+ 6 - 1
sp-admin/sa-view/tb-business/tb-business-list.html

@@ -89,6 +89,8 @@
 							<el-button class="c-btn" type="success" v-if="perCode.indexOf('tb-business-pay')!=-1
 								&&s.row.payStatus==1&&s.row.confirmInput==1&&currentCustomerId!='1'" @click="payFn(s.row)">
 								马上支付</el-button>
+							<el-button class="c-btn" type="primary" @click="carFn(s.row)">司机
+							</el-button>
 							<el-button class="c-btn" type="primary"
 								v-if="currentCustomerId=='1'&&(s.row.realInTime==null||s.row.chinaCarInTime==null)"
 								@click="inFn(s.row)">确认入场
@@ -283,10 +285,13 @@
 					},
 					timmer: null,
 					fresh: {
-						value: 10
+						value: 60
 					}
 				},
 				methods: {
+					carFn(data) {
+						sa.showIframe('车辆司机', 'tb-business-car-list.html?id=' + data.id, '1050px', '90%');
+					},
 					blurFn() {
 						console.log(123)
 					},

+ 67 - 0
sp-admin/sa-view/tb-charge-record/tb-charge-record-info.html

@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>充值记录-详情</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/httpVueLoader.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+		<style type="text/css">
+			.c-panel .c-label{width: 8em;}
+		</style>
+	</head>
+	<body>
+		<div class="vue-box sbot" style="display: none;" :style="'display: block;'">
+			<!-- ------- 内容部分 ------- -->
+			<div class="s-body">
+				<div class="c-panel">
+					<el-form v-if="m">
+						<sa-info name="主键" br>{{m.id}}</sa-info>
+						<sa-info name="客户id" br>{{m.customerId}}</sa-info>
+						<sa-info name="客户名称" br>{{m.customerName}}</sa-info>
+						<sa-info name="充值金额" br>{{m.money}}</sa-info>
+						<sa-info name="充值渠道" br>{{m.chargeChannel}}</sa-info>
+						<sa-info name="充值时间" br>{{m.createTime}}</sa-info>
+						<sa-info name="充值人" br>{{m.chargePeople}}</sa-info>
+						<sa-info name="订单号" br>{{m.no}}</sa-info>
+					</el-form>
+				</div>
+			</div>
+			<!-- ------- 底部按钮 ------- -->
+			<div class="s-foot">
+				<el-button type="success" @click="sa.closeCurrIframe()">确定</el-button>
+				<el-button @click="sa.closeCurrIframe()">取消</el-button>
+			</div>
+		</div>
+		<script>
+			var app = new Vue({
+				components: {
+					"sa-info": httpVueLoader('../../sa-frame/com/sa-info.vue')
+				},
+				el: '.vue-box',
+				data: {
+					id: sa.p('id', 0),	// 获取数据ID 
+					m: null
+				},
+				methods: {
+				},
+				mounted: function() {
+					sa.ajax('/TbChargeRecord/getById?id=' + this.id, function(res) {
+						this.m = res.data;
+						if(res.data == null) {
+							sa.alert('未能查找到 id=' + this.id + " 详细数据");
+						}
+					}.bind(this))
+				}
+			})
+			
+		</script>
+	</body>
+</html>

+ 88 - 0
sp-admin/sa-view/tb-charge-record/tb-charge-record-list.html

@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>充值记录-列表</title>
+		<meta charset="utf-8">
+		<meta name="viewport"
+			content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css & js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/httpVueLoader.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+	</head>
+	<body>
+		<div class="vue-box" style="display: none;" :style="'display: block;'">
+			<div class="c-panel">
+				<!-- ------------- 检索参数 ------------- -->
+				<div class="c-title">检索参数</div>
+				<el-form ref="form" :model='p' @submit.native.prevent>
+					<sa-item type="text" name="客户名称" v-model="p.customerName"></sa-item>
+					<sa-item type="text" name="充值渠道" v-model="p.chargeChannel"></sa-item>
+					<sa-item type="text" name="订单号" v-model="p.no"></sa-item>
+					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
+					<sa-item type="fast-btn" show="reset" style="display: inline;"></sa-item>
+				</el-form>
+				<!-- ------------- 快捷按钮 ------------- -->
+
+				<!-- ------------- 数据列表 ------------- -->
+				<el-table class="data-table" ref="data-table" :data="dataList">
+					<sa-td type="selection"></sa-td>
+					<sa-td name="订单号" prop="no"></sa-td>
+					<sa-td name="客户名称" prop="customerName"></sa-td>
+					<sa-td name="充值金额" prop="money"></sa-td>
+					<sa-td name="充值渠道" prop="chargeChannel"></sa-td>
+					<sa-td name="充值时间" prop="createTime"></sa-td>
+					<sa-td name="充值人" prop="chargePeople"></sa-td>
+				</el-table>
+				<!-- ------------- 分页 ------------- -->
+				<sa-item type="page" :curr.sync="p.pageNo" :size.sync="p.pageSize" :total="dataCount" @change="f5()">
+				</sa-item>
+			</div>
+			
+		</div>
+		<script>
+			var app = new Vue({
+				components: {
+					"sa-item": httpVueLoader('../../sa-frame/com/sa-item.vue'),
+					"sa-td": httpVueLoader('../../sa-frame/com/sa-td.vue'),
+				},
+				el: '.vue-box',
+				data: {
+					p: { // 查询参数  
+						customerName: '', // 客户名称 
+						money: '', // 充值金额 
+						chargeChannel: '', // 充值渠道 
+						createTime: '', // 充值时间 
+						chargePeople: '', // 充值人 
+						no: '', // 订单号 
+						pageNo: 1, // 当前页 
+						pageSize: 10, // 页大小 
+						sortType: 0 // 排序方式 
+					},
+					dataCount: 0,
+					dataList: [], // 数据集合 
+				
+				},
+				methods: {
+					// 刷新
+					f5: function() {
+						sa.ajax('/TbChargeRecord/getList', sa.removeNull(this.p), function(res) {
+							this.dataList = res.data; // 数据
+							this.dataCount = res.dataCount; // 数据总数 
+							sa.f5TableHeight(); // 刷新表格高度 
+						}.bind(this));
+					},
+				},
+				created: function() {
+					this.f5();
+					sa.onInputEnter();
+				}
+			})
+		</script>
+	</body>
+</html>

+ 132 - 0
sp-admin/sa-view/tb-costomer/tb-account-manager.html

@@ -0,0 +1,132 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta name="viewport"
+			content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+
+	</head>
+	<body>
+		<div id='account' style="padding: 10px;">
+			<el-row :gutter="15">
+				<el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
+					<el-col :span="24">
+						<el-form-item label="账户:" prop="accountNo">
+							{{formData.accountNo}}
+						</el-form-item>
+					</el-col>
+					<el-col :span="24">
+						<el-form-item label="总金额:" prop="totalMoney">
+							{{formData.totalMoney}}元
+						</el-form-item>
+					</el-col>
+				<!-- 	<el-col :span="12">
+						<el-form-item label="冻结金额" prop="lockMoney">
+							<el-input v-model="formData.lockMoney" placeholder="请输入冻结金额" :disabled='true' clearable
+								:style="{width: '100%'}"></el-input>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="可用余额" prop="actMoney">
+							<el-input v-model="formData.actMoney" placeholder="请输入可用余额" :disabled='true' clearable
+								:style="{width: '100%'}"></el-input>
+						</el-form-item>
+					</el-col> -->
+					<el-col :span="24">
+						<el-form-item label="充值(元):" prop="money">
+							<el-input-number v-model="money" placeholder="请输入充值金额" :step='1' step-strictly
+								:precision='1' controls-position=right :min='0'></el-input-number>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="" prop="field108">
+							<el-button type="primary" icon="el-icon-check" size="medium" @click="submitForm"> 确认充值
+							</el-button>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="" prop="field109">
+							<el-button type="info" icon="el-icon-close" size="medium" @click="sa.closeCurrIframe()"> 关闭
+							</el-button>
+						</el-form-item>
+					</el-col>
+				</el-form>
+			</el-row>
+			<el-dialog title="核验身份" :visible="modal.visible" width="500px">
+				<el-form size="mini">
+					<div class="c-item br">
+						<label class="c-label"><label style="color: red">*</label>登录密码:</label>
+						<el-input placeholder="请输入登录密码" v-model="modal.form.password"></el-input>
+					</div>
+				</el-form>
+				<span slot="footer" class="dialog-footer">
+					<el-button @click="modal.visible=false">关闭</el-button>
+					<el-button type="primary" @click="subFn">确定</el-button>
+				</span>
+			</el-dialog>
+		</div>
+		<script>
+			var app = new Vue({
+				el: '#account',
+				data: {
+					customerId: sa.p('customerId', 0), // 获取超链接中的id参数(0=添加,非0=修改) 
+					formData: {
+						accountNo: '',
+						totalMoney: '',
+						lockMoney: '',
+						actMoney: '',
+					},
+					money: '',
+					rules: {
+						money: [{
+							required: true,
+							message: '请输入充值金额',
+							trigger: 'blur'
+						}],
+					},
+					modal:{
+						visible:false,
+						form:{
+							password:''
+						}
+					}
+				},
+				methods: {
+					subFn(){
+						
+					},
+					submitForm() {
+						if (!this.money || this.money < 0) {
+							sa.alert('请输入充值金额')
+							return;
+						}
+						sa.ajax('/TbAccount/recharge', {
+							customerId: this.customerId,
+							money: this.money
+						}, function(resp) {
+							this.getCustomerAccount()
+						}.bind(this))
+					},
+					getCustomerAccount() {
+						sa.ajax('/TbAccount/getCustomerAccount', {
+							customerId: this.customerId
+						}, function(resp) {
+							this.formData = resp.data;
+						}.bind(this))
+					}
+				},
+				mounted: function() {
+					this.getCustomerAccount()
+				}
+			})
+		</script>
+	</body>
+</html>

+ 6 - 0
sp-admin/sa-view/tb-costomer/tb-costomer-list.html

@@ -69,6 +69,8 @@
 							</el-button>
 							<el-button class="c-btn" type="primary" icon="el-icon-user-solid" @click="userFn(s.row)">用户
 							</el-button>
+							<el-button class="c-btn" type="primary" icon="el-icon-user-solid" v-if="s.row.judgeStatus==2" @click="accountFn(s.row)">账户
+							</el-button>
 							<el-button v=if="currentCustomerId==1" class="c-btn" type="danger" icon="el-icon-delete"
 								@click="del(s.row)">删除</el-button>
 						</template>
@@ -128,7 +130,11 @@
 					currentCustomerId: '1',
 				},
 				methods: {
+					accountFn(data){
+						sa.showIframe('企业账户', 'tb-account-manager.html?customerId=' + data.id, '450px', '60%');
+					},
 					judgeFn(data) {
+						
 						Object.assign(this.modal, {
 							visible: true,
 							form: {

+ 38 - 115
sp-admin/sa-view/tb-item/tb-item-list.html

@@ -3,7 +3,8 @@
 	<head>
 		<title>作业配置项-列表</title>
 		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<meta name="viewport"
+			content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
 		<!-- 所有的 css & js 资源 -->
 		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
 		<link rel="stylesheet" href="../../static/sa.css">
@@ -20,63 +21,57 @@
 				<!-- ------------- 检索参数 ------------- -->
 				<div class="c-title">检索参数</div>
 				<el-form ref="form" :model='p' @submit.native.prevent>
-					<sa-item type="text" name="项目编号" v-model="p.itemCode"></sa-item>
-					<sa-item type="text" name="项目名称" v-model="p.itemName"></sa-item>
-					<div class="c-item">
-						<label class="c-label">项目类型:</label>
-						<el-select v-model="p.typeId" style="width: 120px;"  placeholder="请选择">
-							<el-option
-									v-for="type in itemTypeList"
-									:key="type.id"
-									:label="type.name"
-									:value="type.id">
-							</el-option>
-						</el-select>
-					</div>
+					<sa-item type="text" name="项目名称" v-model="p.name"></sa-item>
 					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
+					<sa-item type="fast-btn" show="reset" style="display: inline;"></sa-item>
 					<br />
 				</el-form>
-				<!-- ------------- 快捷按钮 ------------- -->
-				<sa-item type="fast-btn" show="add,delete,reset"></sa-item>
 				<!-- ------------- 数据列表 ------------- -->
-				<el-table class="data-table" ref="data-table" :data="dataList" >
-					<sa-td type="selection"></sa-td>
-					<sa-td name="项目编号" prop="itemCode" ></sa-td>
-					<sa-td name="项目类型" prop="typeName" ></sa-td>
-					<sa-td name="项目名称" prop="itemName" width="300px" ></sa-td>
-					<sa-td name="项目金额(元)" prop="price" ></sa-td>
-					<sa-td name="单位" prop="unit" ></sa-td>
-<!--					<sa-td name="状态" prop="status" type="switch" :jv="{0: '禁用[#ff0000]', 1: '启用[#005500]'}"-->
-<!--						   @change="s => updateStatus(s.row)"></sa-td>-->
-					<el-table-column label="操作" fixed="right"  width="240px">
+				<el-table class="data-table" ref="data-table" :data="dataList">
+					<sa-td name="项目名称" prop="name" width="300px"></sa-td>
+					<sa-td name="项目编号" prop="code"></sa-td>
+					<sa-td name="收费项" prop="code">
 						<template slot-scope="s">
-							<el-button class="c-btn" type="success" icon="el-icon-view" @click="get(s.row)">查看</el-button>
-							<el-button class="c-btn" type="primary" icon="el-icon-edit" @click="update(s.row)">修改</el-button>
-							<el-button class="c-btn" type="danger" icon="el-icon-delete" @click="del(s.row)">删除</el-button>
+							  <el-select v-model="s.row.items[0].id" placeholder="收费项">
+							    <el-option
+							      v-for="item in s.row.items"
+							      :key="item.id"
+								  :value="item.id"
+							      :label="item.itemName+' '+item.price+item.unit">
+							    </el-option>
+							  </el-select>
 						</template>
-					</el-table-column>
+					</sa-td>
+				<!-- 	<el-table-column label="操作" fixed="right" width="240px">
+						<template slot-scope="s">
+							<el-button class="c-btn" type="success" icon="el-icon-view" @click="get(s.row)">查看
+							</el-button>
+							<el-button class="c-btn" type="primary" icon="el-icon-edit" @click="update(s.row)">修改
+							</el-button>
+							<el-button class="c-btn" type="danger" icon="el-icon-delete" @click="del(s.row)">删除
+							</el-button>
+						</template>
+					</el-table-column> -->
 				</el-table>
 				<!-- ------------- 分页 ------------- -->
-				<sa-item type="page" :curr.sync="p.pageNo" :size.sync="p.pageSize" :total="dataCount" @change="f5()"></sa-item>
+				<sa-item type="page" :curr.sync="p.pageNo" :size.sync="p.pageSize" :total="dataCount" @change="f5()">
+				</sa-item>
 			</div>
 		</div>
 		<script>
 			var app = new Vue({
 				components: {
-					"sa-item": httpVueLoader('../../sa-frame/com/sa-item.vue'),  
-					"sa-td": httpVueLoader('../../sa-frame/com/sa-td.vue'),		
+					"sa-item": httpVueLoader('../../sa-frame/com/sa-item.vue'),
+					"sa-td": httpVueLoader('../../sa-frame/com/sa-td.vue'),
 				},
 				el: '.vue-box',
 				data: {
 					p: { // 查询参数  
-						id: '',		// 主键
-						typeId: '',	//类型id
-						itemCode: '',		// 项目编号 
-						itemName: '',		// 项目名称 
-						price: '',		// 项目金额(元)
-						pageNo: 1,		// 当前页 
-						pageSize: 10,	// 页大小 
-						sortType: 0		// 排序方式 
+						id: '', // 主键
+						name: '', // 项目名称 
+						pageNo: 1, // 当前页 
+						pageSize: 10, // 页大小 
+						sortType: 0 // 排序方式 
 					},
 					dataCount: 0,
 					dataList: [], // 数据集合
@@ -85,87 +80,15 @@
 				methods: {
 					// 刷新
 					f5: function() {
-						sa.ajax('/TbItem/getList', sa.removeNull(this.p), function(res) {
+						sa.ajax('/TbItemType/getList', sa.removeNull(this.p), function(res) {
 							this.dataList = res.data; // 数据
 							this.dataCount = res.dataCount; // 数据总数 
-							sa.f5TableHeight();		// 刷新表格高度 
-						}.bind(this));
-					},
-					getItemTypeList(){
-						sa.ajax('/TbItemType/getList', function(resp) {
-							this.itemTypeList = resp.data;
-						}.bind(this));
-					},
-					// 查看
-					get: function(data) {
-						sa.showIframe('数据详情', 'tb-item-info.html?id=' + data.id, '600px', '60%');
-					},
-					// 查看 - 根据选中的
-					getBySelect: function(data) {
-						var selection = this.$refs['data-table'].selection;
-						if(selection.length == 0) {
-							return sa.msg('请选择一条数据')
-						}
-						this.get(selection[0]);
-					},
-					// 修改
-					update: function(data) {
-						sa.showIframe('修改数据', 'tb-item-add.html?id=' + data.id, '800px', '70%');
-					},
-					// 新增
-					add: function(data) {
-						sa.showIframe('新增数据', 'tb-item-add.html?id=-1', '800px', '70%');
-					},
-					// 删除
-					del: function(data) {
-						sa.confirm('是否删除,此操作不可撤销', function() {
-							sa.ajax('/TbItem/delete?id=' + data.id, function(res) {
-								sa.arrayDelete(this.dataList, data);
-								sa.ok('删除成功');
-								sa.f5TableHeight();		// 刷新表格高度 
-							}.bind(this))
-						}.bind(this));
-					},
-					// 批量删除
-					deleteByIds: function() {
-						// 获取选中元素的id列表 
-						let selection = this.$refs['data-table'].selection;
-						let ids = sa.getArrayField(selection, 'id');
-						if(selection.length == 0) {
-							return sa.msg('请至少选择一条数据')
-						}
-						// 提交删除 
-						sa.confirm('是否批量删除选中数据?此操作不可撤销', function() {
-							sa.ajax('/TbItem/deleteByIds', {ids: ids.join(',')}, function(res) {
-								sa.arrayDelete(this.dataList, selection);
-								sa.ok('删除成功');
-								sa.f5TableHeight();		// 刷新表格高度 
-							}.bind(this))
-						}.bind(this));
-					},
-					// 改 - 状态(0=否,1=是)
-					updateStatus: function(data) {
-						// 声明变量记录是否成功
-						var isOk = false;
-						var oldValue = data.status;
-						var ajax = sa.ajax('/TbItem/updateStatus', {
-							id: data.id,
-							value: data.status
-						}, function(res) {
-							isOk = true;
-							sa.msg('修改成功');
+							sa.f5TableHeight(); // 刷新表格高度 
 						}.bind(this));
-						// 如果未能修改成功, 则回滚
-						$.when(ajax).done(function() {
-							if (isOk == false) {
-								data.status = oldValue;
-							}
-						})
 					},
 				},
 				created: function() {
 					this.f5();
-					this.getItemTypeList();
 					sa.onInputEnter();
 				}
 			})

+ 128 - 0
sp-admin/sa-view/tb-pay-record/tb-pay-record-add.html

@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>支付记录-添加/修改</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/httpVueLoader.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+		<style type="text/css">
+			.c-panel .el-form .c-label{width: 7em !important;}
+			.c-panel .el-form .el-input, .c-panel .el-form .el-textarea__inner{width: 250px;}
+		</style>
+	</head>
+	<body>
+		<div class="vue-box" :class="{sbot: id}" style="display: none;" :style="'display: block;'">
+			<!-- ------- 内容部分 ------- -->
+			<div class="s-body">
+				<div class="c-panel">
+                    <div class="c-title" v-if="id == 0">数据添加</div>
+					<div class="c-title" v-else>数据修改</div>
+					<el-form v-if="m">
+						<sa-item type="text" name="主键" v-model="m.id" br></sa-item>
+						<sa-item type="text" name="客户id" v-model="m.customerId" br></sa-item>
+						<sa-item type="text" name="客户名称" v-model="m.customerName" br></sa-item>
+						<sa-item type="text" name="业务订单号" v-model="m.outTradeNo" br></sa-item>
+						<sa-item type="text" name="支付金额" v-model="m.payMoney" br></sa-item>
+						<sa-item type="text" name="支付时间" v-model="m.payTime" br></sa-item>
+						<sa-item type="text" name="微信订单号" v-model="m.transactionId" br></sa-item>
+						<sa-item type="text" name="支付结束时间" v-model="m.timeEnd" br></sa-item>
+						<sa-item type="text" name="创建时间" v-model="m.createTime" br></sa-item>
+						<sa-item name="" class="s-ok" br>
+							<el-button type="primary" icon="el-icon-plus" @click="ok()">保存</el-button>
+						</sa-item>
+					</el-form>
+				</div>
+			</div>
+			<!-- ------- 底部按钮 ------- -->
+			<div class="s-foot">
+				<el-button type="primary" @click="ok()">确定</el-button>
+				<el-button @click="sa.closeCurrIframe()">取消</el-button>
+			</div>
+		</div>
+        <script>
+			
+			var app = new Vue({
+				components: {
+					"sa-item": httpVueLoader('../../sa-frame/com/sa-item.vue')
+				},
+				el: '.vue-box',
+				data: {
+					id: sa.p('id', 0),		// 获取超链接中的id参数(0=添加,非0=修改) 
+					m: null,		// 实体对象 
+				},
+				methods: {
+					// 创建一个 默认Model 
+					createModel: function() {
+						return {
+							id: '',		// 主键 
+							customerId: '',		// 客户id 
+							customerName: '',		// 客户名称 
+							outTradeNo: '',		// 业务订单号 
+							payMoney: '',		// 支付金额 
+							payTime: '',		// 支付时间 
+							transactionId: '',		// 微信订单号 
+							timeEnd: '',		// 支付结束时间 
+							createTime: '',		// 创建时间 
+						}
+					},
+					// 提交数据 
+					ok: function(){
+						// 表单校验 
+						let m = this.m;
+						sa.checkNull(m.id, '请输入 [主键]');
+						sa.checkNull(m.customerId, '请输入 [客户id]');
+						sa.checkNull(m.customerName, '请输入 [客户名称]');
+						sa.checkNull(m.outTradeNo, '请输入 [业务订单号]');
+						sa.checkNull(m.payMoney, '请输入 [支付金额]');
+						sa.checkNull(m.payTime, '请输入 [支付时间]');
+						sa.checkNull(m.transactionId, '请输入 [微信订单号]');
+						sa.checkNull(m.timeEnd, '请输入 [支付结束时间]');
+						sa.checkNull(m.createTime, '请输入 [创建时间]');
+				
+						// 开始增加或修改
+						if(this.id <= 0) {	// 添加
+							sa.ajax('/TbPayRecord/add', m, function(res){
+								sa.alert('增加成功', this.clean); 
+							}.bind(this));
+						} else {	// 修改
+							sa.ajax('/TbPayRecord/update', m, function(res){
+								sa.alert('修改成功', this.clean);
+							}.bind(this));
+						}
+					},
+					// 添加/修改 完成后的动作
+					clean: function() {
+						if(this.id == 0) {
+							this.m = this.createModel();
+						} else {
+							parent.app.f5();		// 刷新父页面列表
+							sa.closeCurrIframe();	// 关闭本页 
+						}
+					}
+				},
+				mounted: function(){
+					// 初始化数据 
+					if(this.id <= 0) {	
+						this.m = this.createModel();
+					} else {	
+						sa.ajax('/TbPayRecord/getById?id=' + this.id, function(res) {
+							this.m = res.data;
+							if(res.data == null) {
+								sa.alert('未能查找到 id=' + this.id + " 详细数据");
+							}
+						}.bind(this))
+					}
+				}
+			})
+			
+		</script>
+	</body>
+</html>

+ 68 - 0
sp-admin/sa-view/tb-pay-record/tb-pay-record-info.html

@@ -0,0 +1,68 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>支付记录-详情</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/httpVueLoader.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+		<style type="text/css">
+			.c-panel .c-label{width: 8em;}
+		</style>
+	</head>
+	<body>
+		<div class="vue-box sbot" style="display: none;" :style="'display: block;'">
+			<!-- ------- 内容部分 ------- -->
+			<div class="s-body">
+				<div class="c-panel">
+					<el-form v-if="m">
+						<sa-info name="主键" br>{{m.id}}</sa-info>
+						<sa-info name="客户id" br>{{m.customerId}}</sa-info>
+						<sa-info name="客户名称" br>{{m.customerName}}</sa-info>
+						<sa-info name="业务订单号" br>{{m.outTradeNo}}</sa-info>
+						<sa-info name="支付金额" br>{{m.payMoney}}</sa-info>
+						<sa-info name="支付时间" br>{{m.payTime}}</sa-info>
+						<sa-info name="微信订单号" br>{{m.transactionId}}</sa-info>
+						<sa-info name="支付结束时间" br>{{m.timeEnd}}</sa-info>
+						<sa-info name="创建时间" br>{{m.createTime}}</sa-info>
+					</el-form>
+				</div>
+			</div>
+			<!-- ------- 底部按钮 ------- -->
+			<div class="s-foot">
+				<el-button type="success" @click="sa.closeCurrIframe()">确定</el-button>
+				<el-button @click="sa.closeCurrIframe()">取消</el-button>
+			</div>
+		</div>
+		<script>
+			var app = new Vue({
+				components: {
+					"sa-info": httpVueLoader('../../sa-frame/com/sa-info.vue')
+				},
+				el: '.vue-box',
+				data: {
+					id: sa.p('id', 0),	// 获取数据ID 
+					m: null
+				},
+				methods: {
+				},
+				mounted: function() {
+					sa.ajax('/TbPayRecord/getById?id=' + this.id, function(res) {
+						this.m = res.data;
+						if(res.data == null) {
+							sa.alert('未能查找到 id=' + this.id + " 详细数据");
+						}
+					}.bind(this))
+				}
+			})
+			
+		</script>
+	</body>
+</html>

+ 164 - 0
sp-admin/sa-view/tb-pay-record/tb-pay-record-list.html

@@ -0,0 +1,164 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<title>支付记录-列表</title>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
+		<!-- 所有的 css & js 资源 -->
+		<link rel="stylesheet" href="../../static/kj/element-ui/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="../../static/kj/vue.min.js"></script>
+		<script src="../../static/kj/element-ui/index.js"></script>
+		<script src="../../static/kj/httpVueLoader.js"></script>
+		<script src="../../static/kj/jquery.min.js"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+	</head>
+	<body>
+		<div class="vue-box" style="display: none;" :style="'display: block;'">
+			<div class="c-panel">
+				<!-- ------------- 检索参数 ------------- -->
+				<div class="c-title">检索参数</div>
+				<el-form ref="form" :model='p' @submit.native.prevent>
+					<sa-item type="text" name="主键" v-model="p.id"></sa-item>
+					<sa-item type="text" name="客户id" v-model="p.customerId"></sa-item>
+					<sa-item type="text" name="客户名称" v-model="p.customerName"></sa-item>
+					<sa-item type="text" name="业务订单号" v-model="p.outTradeNo"></sa-item>
+					<sa-item type="text" name="支付金额" v-model="p.payMoney"></sa-item>
+					<sa-item type="text" name="支付时间" v-model="p.payTime"></sa-item>
+					<sa-item type="text" name="微信订单号" v-model="p.transactionId"></sa-item>
+					<sa-item type="text" name="支付结束时间" v-model="p.timeEnd"></sa-item>
+					<sa-item type="text" name="创建时间" v-model="p.createTime"></sa-item>
+					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
+					<br />
+					<sa-item name="综合排序">
+						<el-radio-group v-model="p.sortType" class="s-radio-text">
+							<el-radio :label="0">默认</el-radio>
+							<el-radio :label="1">主键</el-radio>
+							<el-radio :label="2">客户id</el-radio>
+							<el-radio :label="3">客户名称</el-radio>
+							<el-radio :label="4">业务订单号</el-radio>
+							<el-radio :label="5">支付金额</el-radio>
+							<el-radio :label="6">支付时间</el-radio>
+							<el-radio :label="7">微信订单号</el-radio>
+							<el-radio :label="8">支付结束时间</el-radio>
+							<el-radio :label="9">创建时间</el-radio>
+						</el-radio-group>
+					</sa-item>
+				</el-form>
+				<!-- ------------- 快捷按钮 ------------- -->
+				<sa-item type="fast-btn" show="add,get,delete,export,reset"></sa-item>
+				<!-- ------------- 数据列表 ------------- -->
+				<el-table class="data-table" ref="data-table" :data="dataList" >
+					<sa-td type="selection"></sa-td>
+					<sa-td name="主键" prop="id" ></sa-td>
+					<sa-td name="客户id" prop="customerId" ></sa-td>
+					<sa-td name="客户名称" prop="customerName" ></sa-td>
+					<sa-td name="业务订单号" prop="outTradeNo" ></sa-td>
+					<sa-td name="支付金额" prop="payMoney" ></sa-td>
+					<sa-td name="支付时间" prop="payTime" ></sa-td>
+					<sa-td name="微信订单号" prop="transactionId" ></sa-td>
+					<sa-td name="支付结束时间" prop="timeEnd" ></sa-td>
+					<sa-td name="创建时间" prop="createTime" ></sa-td>
+					<el-table-column label="操作" fixed="right"  width="240px">
+						<template slot-scope="s">
+							<el-button class="c-btn" type="success" icon="el-icon-view" @click="get(s.row)">查看</el-button>
+							<el-button class="c-btn" type="primary" icon="el-icon-edit" @click="update(s.row)">修改</el-button>
+							<el-button class="c-btn" type="danger" icon="el-icon-delete" @click="del(s.row)">删除</el-button>
+						</template>
+					</el-table-column>
+				</el-table>
+				<!-- ------------- 分页 ------------- -->
+				<sa-item type="page" :curr.sync="p.pageNo" :size.sync="p.pageSize" :total="dataCount" @change="f5()"></sa-item>
+			</div>
+		</div>
+		<script>
+			var app = new Vue({
+				components: {
+					"sa-item": httpVueLoader('../../sa-frame/com/sa-item.vue'),  
+					"sa-td": httpVueLoader('../../sa-frame/com/sa-td.vue'),		
+				},
+				el: '.vue-box',
+				data: {
+					p: { // 查询参数  
+						id: '',		// 主键 
+						customerId: '',		// 客户id 
+						customerName: '',		// 客户名称 
+						outTradeNo: '',		// 业务订单号 
+						payMoney: '',		// 支付金额 
+						payTime: '',		// 支付时间 
+						transactionId: '',		// 微信订单号 
+						timeEnd: '',		// 支付结束时间 
+						createTime: '',		// 创建时间 
+						pageNo: 1,		// 当前页 
+						pageSize: 10,	// 页大小 
+						sortType: 0		// 排序方式 
+					},
+					dataCount: 0,
+					dataList: [], // 数据集合 
+				},
+				methods: {
+					// 刷新
+					f5: function() {
+						sa.ajax('/TbPayRecord/getList', sa.removeNull(this.p), function(res) {
+							this.dataList = res.data; // 数据
+							this.dataCount = res.dataCount; // 数据总数 
+							sa.f5TableHeight();		// 刷新表格高度 
+						}.bind(this));
+					},
+					// 查看
+					get: function(data) {
+						sa.showIframe('数据详情', 'tb-pay-record-info.html?id=' + data.id, '1050px', '90%');
+					},
+					// 查看 - 根据选中的
+					getBySelect: function(data) {
+						var selection = this.$refs['data-table'].selection;
+						if(selection.length == 0) {
+							return sa.msg('请选择一条数据')
+						}
+						this.get(selection[0]);
+					},
+					// 修改
+					update: function(data) {
+						sa.showIframe('修改数据', 'tb-pay-record-add.html?id=' + data.id, '1000px', '90%');
+					},
+					// 新增
+					add: function(data) {
+						sa.showIframe('新增数据', 'tb-pay-record-add.html?id=-1', '1000px', '90%');
+					},
+					// 删除
+					del: function(data) {
+						sa.confirm('是否删除,此操作不可撤销', function() {
+							sa.ajax('/TbPayRecord/delete?id=' + data.id, function(res) {
+								sa.arrayDelete(this.dataList, data);
+								sa.ok('删除成功');
+								sa.f5TableHeight();		// 刷新表格高度 
+							}.bind(this))
+						}.bind(this));
+					},
+					// 批量删除
+					deleteByIds: function() {
+						// 获取选中元素的id列表 
+						let selection = this.$refs['data-table'].selection;
+						let ids = sa.getArrayField(selection, 'id');
+						if(selection.length == 0) {
+							return sa.msg('请至少选择一条数据')
+						}
+						// 提交删除 
+						sa.confirm('是否批量删除选中数据?此操作不可撤销', function() {
+							sa.ajax('/TbPayRecord/deleteByIds', {ids: ids.join(',')}, function(res) {
+								sa.arrayDelete(this.dataList, selection);
+								sa.ok('删除成功');
+								sa.f5TableHeight();		// 刷新表格高度 
+							}.bind(this))
+						}.bind(this));
+					},
+				},
+				created: function() {
+					this.f5();
+					sa.onInputEnter();
+				}
+			})
+		</script>
+	</body>
+</html>

+ 2 - 2
sp-admin/static/sa.js

@@ -9,7 +9,7 @@ var sa = {
 (function(){
 	// 公司开发环境
 	var cfg_dev = {
-		api_url: 'http://192.168.3.217:8099/pro',	// 所有ajax请求接口父地址
+		api_url: 'http://192.168.3.53:8099/pro',	// 所有ajax请求接口父地址
 		web_url: 'http://www.baidu.com'		// 此项目前台地址 (此配置项非必须)
 	}
 	// 服务器测试环境
@@ -19,7 +19,7 @@ var sa = {
 	}
 	// 正式生产环境
 	var cfg_prod = {
-		api_url: 'http://116.252.74.16:8099/pro',
+		api_url: 'https://dxkaa1.bgigc.com/pro',
 		web_url: 'http://www.baidu.com'
 	}
 	sa.cfg = cfg_prod; // 最终环境 , 上线前请选择正确的环境

+ 16 - 0
sp-com/.gitignore

@@ -0,0 +1,16 @@
+target/
+.project
+.classpath
+.settings
+
+.factorypath
+
+/.idea/
+
+node_modules/
+bin/
+.settings/
+unpackage/
+*.iml
+
+

+ 33 - 0
sp-com/business/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 30 - 0
sp-com/business/pom.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>sp-com</artifactId>
+        <groupId>com.pj</groupId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>business</artifactId>
+    <packaging>jar</packaging>
+
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.pj</groupId>
+            <artifactId>sp-core</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+
+
+    </dependencies>
+
+
+
+</project>

+ 51 - 0
sp-com/business/src/main/java/com/pj/api/bo/InOutRecordBO.java

@@ -0,0 +1,51 @@
+package com.pj.api.bo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 出入记录
+ */
+@Data
+@Accessors(chain = true)
+public class InOutRecordBO {
+
+    private String businessId;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    private String customerContact;
+
+    private String dutyPeople;
+
+    /**
+     * 车牌号
+     */
+    private String cardNo;
+
+    /**
+     * 车牌国籍
+     */
+    private String carCountryName;
+
+    /**
+     * 实际进境时间
+     */
+    private Date inTime;
+
+    /**
+     * 离境时间
+     */
+    private Date outTime;
+
+    /**
+     * 状态(1=未入场, 2=已入场, 3=已出场)
+     */
+    private int status;
+
+}

+ 90 - 0
sp-com/business/src/main/java/com/pj/api/h5/ApiController.java

@@ -0,0 +1,90 @@
+package com.pj.api.h5;
+
+
+import com.pj.api.bo.InOutRecordBO;
+import com.pj.api.service.ApiService;
+import com.pj.constants.UserTypeEnum;
+import com.pj.current.satoken.StpUserUtil;
+import com.pj.project.tb_business.TbBusinessService;
+import com.pj.project.tb_costomer.TbCostomer;
+import com.pj.project.tb_costomer.TbCostomerService;
+import com.pj.project4sp.admin4login.SpAccAdminService;
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.sg.NbUtil;
+import com.pj.utils.so.SoMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.Collections;
+import java.util.List;
+
+@RequestMapping(value = "/api")
+@RestController
+@Slf4j
+public class ApiController {
+
+    @Resource
+    ApiService apiService;
+    @Resource
+    SpAccAdminService spAccAdminService;
+    @Resource
+    TbCostomerService tbCostomerService;
+    @Resource
+    TbBusinessService tbBusinessService;
+
+    /** 账号、密码登录  */
+    @RequestMapping("doLogin")
+    AjaxJson doLogin(String key, String password) {
+        // 1、验证参数
+        if(NbUtil.isOneNull(key, password)) {
+            return AjaxJson.getError("请提供key与password参数");
+        }
+        return spAccAdminService.doLogin(key, password);
+    }
+
+    @PostMapping(value = "register")
+    public AjaxJson register(TbCostomer costomer){
+        tbCostomerService.register(costomer);
+        return AjaxJson.getSuccess();
+    }
+
+    @RequestMapping(value = "getInOutRecord")
+    public AjaxJson getInOutRecord(){
+        SoMap so = SoMap.getRequestSoMap();
+        String currentCustomerId = StpUserUtil.getCustomerId();
+        if (!currentCustomerId.equals(UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            so.put("customerId",currentCustomerId);
+        }
+        List<InOutRecordBO> recordList = apiService.getInOutRecord(so.startPage());
+        return AjaxJson.getPageData(so.getDataCount(), recordList);
+    }
+
+    @RequestMapping(value = "getCustomerList")
+    public AjaxJson getCustomerList(){
+        SoMap so = SoMap.getRequestSoMap();
+        String currentCustomerId = StpUserUtil.getCustomerId();
+        if (!currentCustomerId.equals(UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            so.put("id",currentCustomerId);
+        }
+        List<TbCostomer> list = apiService.getCustomerList(so.startPage());
+        return AjaxJson.getPageData(so.getDataCount(), list);
+    }
+
+    @PostMapping(value = "confirmCustomer")
+    public AjaxJson confirmCustomer(Long customerId, String judgeContent){
+        apiService.confirmCustomer(customerId, judgeContent);
+        return AjaxJson.getSuccess();
+    }
+    @PostMapping(value = "confirm")
+    public AjaxJson confirmPay(){
+        SoMap so = SoMap.getRequestSoMap();
+      String id=  so.getString("id");
+      tbBusinessService.confirm(Collections.singletonList(id));
+        return AjaxJson.getSuccess();
+    }
+
+
+}

+ 20 - 0
sp-com/business/src/main/java/com/pj/api/open/OpenFilter.java

@@ -0,0 +1,20 @@
+package com.pj.api.open;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+//@Slf4j
+//@WebFilter(filterName = "openFilter", urlPatterns = "/open/*")
+public class OpenFilter implements Filter {
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+        HttpServletRequest request = (HttpServletRequest) servletRequest;
+        HttpServletResponse response = (HttpServletResponse) servletResponse;
+        response.setContentType("application/json;charset=utf-8");
+        response.setHeader("Access-Control-Allow-Origin", "*");
+        String dataType = request.getHeader("DataType");
+        request.getRequestDispatcher("/open/"+dataType).forward(request,response);
+    }
+}

+ 37 - 0
sp-com/business/src/main/java/com/pj/api/open/ResultJson.java

@@ -0,0 +1,37 @@
+package com.pj.api.open;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+@Data
+@Accessors(chain = true)
+@AllArgsConstructor
+@NoArgsConstructor
+public class ResultJson {
+    /**
+     * 操作状态,大于等于0 为成功
+     */
+    private int status;
+    /**
+     * 状态描述
+     */
+    private String message;
+    /**
+     * 0 不允许,1 允许
+     */
+    private int canpass;
+    /**
+     * 不允许放行的原因
+     */
+    private String reason;
+
+    public static ResultJson success(){
+        return new ResultJson(1,"ok",1,"");
+    }
+    public static ResultJson error(String reason){
+        return new ResultJson(1,"ok",0,reason);
+    }
+
+}

+ 63 - 0
sp-com/business/src/main/java/com/pj/api/open/bo/CheckCarNumberBO.java

@@ -0,0 +1,63 @@
+package com.pj.api.open.bo;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import java.io.Serializable;
+
+
+public class CheckCarNumberBO implements Serializable {
+    /**
+     * 当前设别车牌的通道名称
+     */
+   private String ChannelName;
+    private String     CarNumber;
+    /**
+     * 1 入场 2 出场
+     */
+    private int  InOrOut;
+    private String     ImageData;
+    /**
+     * 操作员
+     */
+    private String OperationUserName;
+    @JsonProperty("ChannelName")
+    public String getChannelName() {
+        return ChannelName;
+    }
+
+    public void setChannelName(String channelName) {
+        ChannelName = channelName;
+    }
+    @JsonProperty("CarNumber")
+    public String getCarNumber() {
+        return CarNumber;
+    }
+
+    public void setCarNumber(String carNumber) {
+        CarNumber = carNumber;
+    }
+    @JsonProperty("InOrOut")
+    public int getInOrOut() {
+        return InOrOut;
+    }
+
+    public void setInOrOut(int inOrOut) {
+        InOrOut = inOrOut;
+    }
+    @JsonProperty("ImageData")
+    public String getImageData() {
+        return ImageData;
+    }
+
+    public void setImageData(String imageData) {
+        ImageData = imageData;
+    }
+
+    public String getOperationUserName() {
+        return OperationUserName;
+    }
+
+    public void setOperationUserName(String operationUserName) {
+        OperationUserName = operationUserName;
+    }
+}

+ 118 - 0
sp-com/business/src/main/java/com/pj/api/open/service/OpenService.java

@@ -0,0 +1,118 @@
+package com.pj.api.open.service;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.pj.api.open.ResultJson;
+import com.pj.api.open.bo.CheckCarNumberBO;
+import com.pj.constants.UserTypeEnum;
+import com.pj.project.tb_business.BusinessMessageManager;
+import com.pj.project.tb_business.TbBusiness;
+import com.pj.project.tb_business.TbBusinessService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+
+@Service
+@Transactional
+public class OpenService {
+    @Resource
+    private TbBusinessService tbBusinessService;
+
+    private final List<String> CAR_LIST = StrUtil.splitTrim("浙,粤,京,津,冀,晋,蒙,辽,黑,沪,吉,苏,皖,赣,鲁,豫,鄂,湘,桂,琼,渝,川,贵,云,藏, 陕, 甘, 青, 宁", ",");
+
+
+    public ResultJson checkCarNumber(CheckCarNumberBO checkCarNumberBO) {
+        String carNo = checkCarNumberBO.getCarNumber();
+        String start = carNo.substring(0, 1);
+        if (CAR_LIST.contains(start)) {
+            return handlerChinaCar(checkCarNumberBO);
+        } else {
+            return handlerOutCar(checkCarNumberBO);
+        }
+
+    }
+
+    private ResultJson handlerOutCar(CheckCarNumberBO checkCarNumberBO) {
+        int inOrOut = checkCarNumberBO.getInOrOut();
+        String carNo = checkCarNumberBO.getCarNumber();
+        TbBusiness tbBusiness = tbBusinessService.findCarTheNewRecord(carNo,inOrOut);
+        if (tbBusiness == null) {
+            return ResultJson.error("无业务登记记录");
+        }
+        Date now=new Date();
+        String channel=checkCarNumberBO.getChannelName();
+        if (inOrOut==1){
+            tbBusiness.setRealInTime(now).setInChannel(channel);
+            if (StrUtil.isNotEmpty(tbBusiness.getChinaCarInChannel())||tbBusiness.getChinaCarInTime()!=null){
+                tbBusiness.setAdminConfirmIn(1);
+            }
+            tbBusinessService.updateById(tbBusiness);
+            BusinessMessageManager.set(UserTypeEnum.PLATFORM_ADMIN.getCustomerId(),"订单号【"+tbBusiness.getNo()+"】,车辆【"+tbBusiness.getChinaCarNo()+"】已入场。"+ DateUtil.now()+"。");
+            BusinessMessageManager.set(tbBusiness.getCustomerId(),"您的订单号【"+tbBusiness.getNo()+"】,车辆【"+tbBusiness.getChinaCarNo()+"】已入场。"+ DateUtil.now()+"。");
+            return ResultJson.success();
+        }else {
+            if (tbBusiness.getAdminConfirmPay() ==0&&tbBusiness.getCustomerType()==1) {
+                return ResultJson.error("账单未确认支付");
+            }
+            if (tbBusiness.getConfirmInput()==0&&tbBusiness.getCustomerType()==2){
+                return ResultJson.error("账单未确认");
+            }
+            tbBusiness.setOutDayTime(now).setOutChannel(channel);
+            if (StrUtil.isNotEmpty(tbBusiness.getChinaCarOutChannel())){
+                tbBusiness.setAdminConfirmOut(1);
+            }
+            tbBusinessService.calculationPartMoney("越南车", tbBusiness);
+            tbBusinessService.updateById(tbBusiness);
+            BusinessMessageManager.set(UserTypeEnum.PLATFORM_ADMIN.getCustomerId(),"订单号【"+tbBusiness.getNo()+"】,车辆【"+tbBusiness.getChinaCarNo()+"】已完成业务离场。"+ DateUtil.now()+"。");
+            BusinessMessageManager.set(tbBusiness.getCustomerId(),"您的订单号【"+tbBusiness.getNo()+"】,车辆"+tbBusiness.getChinaCarNo()+"已完成业务离场。"+ DateUtil.now()+"。");
+            return ResultJson.success();
+        }
+    }
+
+    private ResultJson handlerChinaCar(CheckCarNumberBO checkCarNumberBO) {
+        String carNo = checkCarNumberBO.getCarNumber();
+        int inOrOut=checkCarNumberBO.getInOrOut();
+        TbBusiness cb = tbBusinessService.findByChinaCarNo(carNo,inOrOut);
+        if (cb==null){
+            return ResultJson.error("未查询到相应业务");
+        }
+        Date now = new Date();
+        String channel = checkCarNumberBO.getChannelName();
+        if (checkCarNumberBO.getInOrOut() == 1) {
+            cb.setChinaCarInTime(now).setChinaCarInChannel(channel);
+            if (StrUtil.isNotEmpty(cb.getInChannel())||cb.getRealInTime()!=null){
+                cb.setAdminConfirmIn(1);
+            }
+            BusinessMessageManager.set(UserTypeEnum.PLATFORM_ADMIN.getCustomerId(),"订单号【"+cb.getNo()+"】,车辆【"+cb.getChinaCarNo()+"】已入场。"+DateUtil.now()+"。");
+            BusinessMessageManager.set(cb.getCustomerId(),"您的订单号【"+cb.getNo()+"】,车辆【"+cb.getChinaCarNo()+"】已入场。"+DateUtil.now()+"。");
+            tbBusinessService.updateById(cb);
+            return ResultJson.success();
+        }else  {
+            //现结
+            if (cb.getCustomerType()==1&&cb.getAdminConfirmPay()==0){
+                return ResultJson.error("账单未确认支付");
+            }
+            if (cb.getConfirmInput()==0&&cb.getCustomerType()==2){
+                return ResultJson.error("账单未确认");
+            }
+            cb.setChinaCarOutTime(now).setChinaCarOutChannel(channel);
+            if (StrUtil.isNotEmpty(cb.getOutChannel())){
+                cb.setAdminConfirmOut(1);
+            }
+            tbBusinessService.calculationPartMoney("中国车", cb);
+            tbBusinessService.updateById(cb);
+            BusinessMessageManager.set(cb.getCustomerId(),"您的订单号【"+cb.getNo()+"】,车辆【"+cb.getChinaCarNo()+"】已完成业务离场");
+            BusinessMessageManager.set(UserTypeEnum.PLATFORM_ADMIN.getCustomerId(),"业务订单号【"+cb.getNo()+"】,车辆【"+cb.getChinaCarNo()+"】已完成业务离场");
+            return ResultJson.success();
+        }
+    }
+
+    private void handlerOut(TbBusiness tbBusiness) {
+        tbBusiness.setOutDayTime(new Date());
+        tbBusinessService.calculationPartMoney("越南车", tbBusiness);
+        tbBusinessService.updateById(tbBusiness);
+    }
+}

+ 40 - 0
sp-com/business/src/main/java/com/pj/api/open/web/OpenController.java

@@ -0,0 +1,40 @@
+package com.pj.api.open.web;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.json.JSONUtil;
+import com.pj.api.open.ResultJson;
+import com.pj.api.open.bo.CheckCarNumberBO;
+import com.pj.api.open.service.OpenService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.Map;
+
+@RequestMapping(value = "open")
+@RestController
+@Slf4j
+public class OpenController {
+    @Resource
+    OpenService openService;
+
+    @PostMapping(value = "req")
+    public ResultJson req(@RequestBody Map<String, Object> params, HttpServletRequest request, HttpServletResponse response) {
+        String dataType = request.getHeader("DataType");
+        if ("CheckCarNumber".equals(dataType)) {
+            CheckCarNumberBO checkCarNumberBO = BeanUtil.toBean(params, CheckCarNumberBO.class);
+            return checkCarNumber(checkCarNumberBO);
+        }
+        return ResultJson.error("未知异常");
+    }
+
+    private ResultJson checkCarNumber(CheckCarNumberBO checkCarNumberBO) {
+        log.info("check car number:{}", JSONUtil.toJsonStr(checkCarNumberBO));
+        return openService.checkCarNumber(checkCarNumberBO);
+    }
+}

+ 58 - 0
sp-com/business/src/main/java/com/pj/api/service/ApiService.java

@@ -0,0 +1,58 @@
+package com.pj.api.service;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.pj.api.bo.InOutRecordBO;
+import com.pj.project.tb_business.TbBusinessService;
+import com.pj.project.tb_costomer.TbCostomer;
+import com.pj.project.tb_costomer.TbCostomerService;
+import com.pj.project.tb_pass_record.TbPassRecord;
+import com.pj.project.tb_pass_record.TbPassRecordService;
+import com.pj.utils.so.SoMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ */
+
+@Service
+@Transactional(rollbackFor = Exception.class)
+@Slf4j
+public class ApiService {
+
+    @Resource
+    TbCostomerService tbCostomerService;
+    @Resource
+    TbBusinessService tbBusinessService;
+    @Resource
+    TbPassRecordService tbPassRecordService;
+
+    public List<InOutRecordBO> getInOutRecord(SoMap so){
+        List<TbPassRecord> passRecords = tbPassRecordService.getList(so);
+        List<InOutRecordBO> recordList = new ArrayList<>();
+        for (TbPassRecord passRecord : passRecords) {
+            InOutRecordBO record = new InOutRecordBO();
+            BeanUtil.copyProperties(passRecord, record);
+            TbCostomer costomer = tbCostomerService.getById(passRecord.getCustomerId());
+            record.setCustomerContact(costomer.getPhone()).setDutyPeople(costomer.getDutyPeople());
+            recordList.add(record);
+        }
+        return recordList;
+    }
+
+    public List<TbCostomer> getCustomerList(SoMap so) {
+        List<TbCostomer> list = tbCostomerService.getList(so);
+        return list;
+    }
+
+    public void confirmCustomer(Long customerId, String judgeContent) {
+        TbCostomer costomer = tbCostomerService.getById(customerId);
+        if(costomer != null && costomer.getJudgeStatus() == 1){
+            tbCostomerService.judge(customerId + "", 2, judgeContent);
+        }
+    }
+}

+ 36 - 0
sp-com/business/src/main/java/com/pj/constants/RoleEnum.java

@@ -0,0 +1,36 @@
+package com.pj.constants;
+
+import com.pj.current.satoken.AuthConst;
+import com.pj.project.tb_business.TbBusiness;
+import com.pj.project.tb_costomer.TbCostomer;
+import com.pj.project.tb_notices.TbNotices;
+import com.pj.project.tb_pass_record.TbPassRecord;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+
+@Getter
+@AllArgsConstructor
+public enum RoleEnum {
+    INPUT_ROLE("input","业务录入",
+            Arrays.asList(AuthConst.ADMIN_LIST, TbCostomer.PERMISSION_CODE, TbCostomer.PERMISSION_INFO, TbBusiness.PERMISSION_CODE, TbBusiness.PERMISSION_LIST, TbBusiness.PERMISSION_INPUT)),
+    CONFIRM_ROLE("confirm","业务确认",
+            Arrays.asList(AuthConst.ADMIN_LIST, TbCostomer.PERMISSION_CODE, TbCostomer.PERMISSION_INFO, TbBusiness.PERMISSION_CODE, TbBusiness.PERMISSION_LIST, TbBusiness.PERMISSION_CONFIRM)),
+    PAY_ROLE("pay","业务支付",
+            Arrays.asList(AuthConst.ADMIN_LIST, TbCostomer.PERMISSION_CODE, TbCostomer.PERMISSION_INFO, TbBusiness.PERMISSION_CODE, TbBusiness.PERMISSION_LIST, TbBusiness.PERMISSION_PAY)),
+    ADMIN_ROLE("admin","管理员", Collections.emptyList()),
+    SUPER_ROLE("super","超级管理员", Collections.emptyList()),
+    COMMON_ROLE_PER("common","共同",Arrays.asList(TbPassRecord.PERMISSION_CODE, TbPassRecord.PERMISSION_LIST, TbNotices.PERMISSION_CODE, TbNotices.PERMISSION_LIST))
+    ;
+    private String type;
+    private String name;
+    private List<String>perCode;
+
+    public static List<RoleEnum>getCustomerInitRoleList(){
+        return Arrays.asList(INPUT_ROLE,CONFIRM_ROLE, PAY_ROLE);
+    }
+}

+ 14 - 0
sp-com/business/src/main/java/com/pj/constants/UserTypeEnum.java

@@ -0,0 +1,14 @@
+package com.pj.constants;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+@Getter
+@AllArgsConstructor
+public enum  UserTypeEnum {
+    SUPER_ADMIN("-1","超级管理员"),
+    PLATFORM_ADMIN("1","平台管理员");
+    private String customerId;
+    private String desc;
+}

+ 52 - 0
sp-com/business/src/main/java/com/pj/current/SaPlusStartup.java

@@ -0,0 +1,52 @@
+package com.pj.current;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+import java.net.InetAddress;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * springboot启动之后 
+ * @author kong
+ *
+ */
+@Component
+public class SaPlusStartup implements CommandLineRunner {
+
+	@Value("${spring.application.name:sa-plus}")
+    private String applicationName;
+	
+	@Value("${server.port:8080}")
+    private String port;
+
+    @Value("${server.servlet.context-path:}")
+    private String path;
+
+    @Value("${spring.profiles.active:}")
+    private String active;
+   
+    @Override
+    public void run(String... args) throws Exception {
+    	 String ip = InetAddress.getLocalHost().getHostAddress();
+         String str = "\n------------- " + applicationName + " (" + active + ") 启动成功 --by " + getNow() + " -------------\n" + 
+                 "\t- Local:   http://localhost:" + port + path + "\n" +
+                 "\t- Local2:  http://127.0.0.1:" + port + path + "\n" +
+                 "\t- Network: http://" + ip + ":" + port + path + "\n";
+         System.out.println(str);
+    }
+
+    
+	
+	/**
+	 * 返回系统当前时间的YYYY-MM-dd hh:mm:ss 字符串格式
+	 */
+	private static String getNow(){
+		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
+	}
+    
+
+}
+

+ 13 - 0
sp-com/business/src/main/java/com/pj/current/config/CarConfig.java

@@ -0,0 +1,13 @@
+package com.pj.current.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "car")
+@Data
+public class CarConfig {
+    private double maxLength;
+    private double maxWeight;
+}

+ 19 - 0
sp-com/business/src/main/java/com/pj/current/config/PartConfig.java

@@ -0,0 +1,19 @@
+package com.pj.current.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.math.BigDecimal;
+
+@Data
+@Component
+@ConfigurationProperties(prefix = "part-config")
+public class PartConfig {
+    private Double freeCarLength;
+    private BigDecimal basePrice;
+    private BigDecimal extraPrice;
+    private String  nightEnd;
+    private long freeMinutes;
+
+}

+ 42 - 0
sp-com/business/src/main/java/com/pj/current/satoken/AuthConst.java

@@ -0,0 +1,42 @@
+package com.pj.current.satoken;
+
+/**
+ * 权限码常量  
+ * @author kong
+ *
+ */
+public final class AuthConst {
+
+	/**
+	 *  私有构造方法 
+	 */
+	private AuthConst() {
+	}
+	
+	
+	// --------------- 代表身份的权限 --------------- 
+	
+	public static final String R1 = "1"; 			 // 角色_id_超级管理员 最高权限,超管身份的代表
+	public static final String R11 = "11"; 		 // 
+	public static final String R99 = "99";		  // 进入后台权限,没有此权限无法进入后台管理
+	
+	
+	// --------------- 所有权限码 --------------- 
+
+	public static final String AUTH = "auth";		   // 权限管理
+	public static final String ROLE_LIST = "role-list";		    // 权限管理 - 角色管理
+	public static final String MENU_LIST = "menu-list";		   // 权限管理 - 菜单列表
+	public static final String ADMIN_LIST = "admin-list";		   // 权限管理 - 管理员列表
+	public static final String ADMIN_ADD = "admin-add";		   // 权限管理 - 管理员添加
+
+	public static final String CONSOLE = "console";		   // 监控中心
+	public static final String SQL_CONSOLE = "sql-console";		      // 监控中心 - SQL监控
+	public static final String REDIS_CONSOLE = "redis-console";		   // 监控中心 - Redis 控制台
+	public static final String APILOG_LIST = "apilog-list";		   // 监控中心 - API 请求日志
+
+	public static final String SP_CFG = "sp-cfg";		  	 // 系统配置
+	public static final String SP_CFG_APP = "sp-cfg-app";		  	 // 系统配置 - 系统对公配置
+	public static final String SP_CFG_SERVER = "sp-cfg-server";		   // 系统配置 - 服务器私有配置
+	
+	
+}

+ 69 - 0
sp-com/business/src/main/java/com/pj/current/satoken/SaTokenConfigure.java

@@ -0,0 +1,69 @@
+package com.pj.current.satoken;
+
+import cn.dev33.satoken.context.SaHolder;
+import cn.dev33.satoken.filter.SaServletFilter;
+import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
+import cn.dev33.satoken.router.SaHttpMethod;
+import cn.dev33.satoken.router.SaRouter;
+import com.pj.utils.sg.AjaxJson;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * Sa-Token 代码方式进行配置 
+ * @author kong 
+ */
+@Configuration
+public class SaTokenConfigure implements WebMvcConfigurer {
+
+	/**
+	 * 注册 Sa-Token 的拦截器,打开注解式鉴权功能 
+	 */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
+    }
+    
+    /**
+     * 注册 Sa-Token全局过滤器,解决跨域问题 
+     */
+    @Bean
+    public SaServletFilter getSaServletFilter() {
+        return new SaServletFilter()
+        		// 拦截与排除 path 
+        		.addInclude("/**").addExclude("/favicon.ico")
+        		
+        		// 全局认证函数 
+        		.setAuth(obj -> {
+        			// ... 
+        		})
+        		
+        		// 异常处理函数  
+        		.setError(e -> {
+        			return AjaxJson.getError(e.getMessage());
+        		})
+        		
+        		// 前置函数:在每次认证函数之前执行
+        		.setBeforeAuth(obj -> {
+        			// ---------- 设置跨域响应头 ----------
+        			SaHolder.getResponse()
+        			// 允许指定域访问跨域资源
+        			.setHeader("Access-Control-Allow-Origin", "*")
+        			// 允许所有请求方式
+        			.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
+        			// 有效时间
+        			.setHeader("Access-Control-Max-Age", "3600")
+        			// 允许的header参数
+        			.setHeader("Access-Control-Allow-Headers", "*");
+        			
+        			// 如果是预检请求,则立即返回到前端 
+        			SaRouter.match(SaHttpMethod.OPTIONS)
+        				.free(r -> System.out.println("--------OPTIONS预检请求,不做处理"))
+        				.back();
+        		})
+        		;
+    }
+	
+}

+ 46 - 0
sp-com/business/src/main/java/com/pj/current/satoken/StpInterfaceImpl.java

@@ -0,0 +1,46 @@
+package com.pj.current.satoken;
+
+import cn.dev33.satoken.stp.StpInterface;
+import cn.dev33.satoken.stp.StpUtil;
+import com.pj.project4sp.admin.SpAdmin;
+import com.pj.project4sp.admin.SpAdminMapper;
+import com.pj.project4sp.role4permission.SpRolePermissionService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 自定义Sa-Token权限认证接口扩展 
+ * 
+ * @author kong
+ *
+ */
+@Component	
+public class StpInterfaceImpl implements StpInterface {
+
+	@Resource
+    SpAdminMapper spAdminMapper;
+	
+	@Autowired
+    SpRolePermissionService spRolePermissionService;
+	
+	/** 返回一个账号所拥有的权限码集合  */
+	@Override
+	public List<String> getPermissionList(Object loginId, String loginType) {
+		if(loginType.equals(StpUtil.TYPE)) {
+			SpAdmin spAdmin= spAdminMapper.getById(Long.valueOf( loginId.toString()));
+			String roleIds=spAdmin.getRoleId();
+			return spRolePermissionService.getPcodeByRid(roleIds);
+		}
+		return null;
+	}
+	
+	/** 返回一个账号所拥有的角色标识集合  */
+	@Override
+	public List<String> getRoleList(Object loginId, String loginType) {
+		return null;
+	}
+
+}

+ 946 - 0
sp-com/business/src/main/java/com/pj/current/satoken/StpUserUtil.java

@@ -0,0 +1,946 @@
+package com.pj.current.satoken;
+
+import cn.dev33.satoken.SaManager;
+import cn.dev33.satoken.fun.SaFunction;
+import cn.dev33.satoken.session.SaSession;
+import cn.dev33.satoken.stp.SaLoginModel;
+import cn.dev33.satoken.stp.SaTokenInfo;
+import cn.dev33.satoken.stp.StpLogic;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.json.JSONUtil;
+import com.pj.project4sp.admin.SpAdmin;
+import com.pj.utils.cache.RedisUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * Sa-Token 权限认证工具类 (User版本)
+ *
+ * @author kong
+ */
+@Component
+public class StpUserUtil {
+
+    /**
+     * 账号类型标识
+     */
+    public static final String TYPE = "user";
+
+    /**
+     * 底层的 StpLogic 对象
+     */
+    public static StpLogic stpLogic = new StpLogic(TYPE);
+
+    /**
+     * 获取当前 StpLogic 的账号类型
+     *
+     * @return See Note
+     */
+    public static String getLoginType() {
+        return stpLogic.getLoginType();
+    }
+
+    public static void saveAdmin(Long loginId, SpAdmin spAdmin) {
+        String key = "admin:" + loginId;
+        RedisUtil.set(key, JSONUtil.toJsonStr(spAdmin));
+    }
+
+    public static SpAdmin getAdmin() {
+        String key = "admin:" + StpUtil.getLoginIdAsLong();
+        String adminJson = RedisUtil.get(key);
+        return JSONUtil.toBean(adminJson, SpAdmin.class);
+    }
+
+    public static String getCustomerId(){
+        return getAdmin().getCustomerId();
+    }
+
+    /**
+     * 重置 StpLogic 对象
+     *
+     * @param stpLogic /
+     */
+    public static void setStpLogic(StpLogic stpLogic) {
+        StpUtil.stpLogic = stpLogic;
+        // 防止自定义 stpLogic 被覆盖
+        SaManager.putStpLogic(stpLogic);
+    }
+
+
+    // =================== 获取token 相关 ===================
+
+    /**
+     * 返回token名称
+     *
+     * @return 此StpLogic的token名称
+     */
+    public static String getTokenName() {
+        return stpLogic.getTokenName();
+    }
+
+    /**
+     * 在当前会话写入当前TokenValue
+     *
+     * @param tokenValue    token值
+     * @param cookieTimeout Cookie存活时间(秒)
+     */
+    public static void setTokenValue(String tokenValue, int cookieTimeout) {
+        stpLogic.setTokenValue(tokenValue, cookieTimeout);
+    }
+
+    /**
+     * 获取当前TokenValue
+     *
+     * @return 当前tokenValue
+     */
+    public static String getTokenValue() {
+        return stpLogic.getTokenValue();
+    }
+
+    /**
+     * 获取当前会话的Token信息
+     *
+     * @return token信息
+     */
+    public static SaTokenInfo getTokenInfo() {
+        return stpLogic.getTokenInfo();
+    }
+
+
+    // =================== 登录相关操作 ===================
+
+    // --- 登录
+
+    /**
+     * 会话登录
+     *
+     * @param id 账号id,建议的类型:(long | int | String)
+     */
+    public static void login(Object id) {
+        stpLogic.login(id);
+    }
+
+    /**
+     * 会话登录,并指定登录设备
+     *
+     * @param id     账号id,建议的类型:(long | int | String)
+     * @param device 设备标识
+     */
+    public static void login(Object id, String device) {
+        stpLogic.login(id, device);
+    }
+
+    /**
+     * 会话登录,并指定是否 [记住我]
+     *
+     * @param id              账号id,建议的类型:(long | int | String)
+     * @param isLastingCookie 是否为持久Cookie
+     */
+    public static void login(Object id, boolean isLastingCookie) {
+        stpLogic.login(id, isLastingCookie);
+    }
+
+    /**
+     * 会话登录,并指定所有登录参数Model
+     *
+     * @param id         登录id,建议的类型:(long | int | String)
+     * @param loginModel 此次登录的参数Model
+     */
+    public static void login(Object id, SaLoginModel loginModel) {
+        stpLogic.login(id, loginModel);
+    }
+
+    // --- 注销
+
+    /**
+     * 会话注销
+     */
+    public static void logout() {
+        stpLogic.logout();
+    }
+
+    /**
+     * 会话注销,根据账号id
+     *
+     * @param loginId 账号id
+     */
+    public static void logout(Object loginId) {
+        stpLogic.logout(loginId);
+    }
+
+    /**
+     * 会话注销,根据账号id 和 设备标识
+     *
+     * @param loginId 账号id
+     * @param device  设备标识 (填null代表所有注销设备)
+     */
+    public static void logout(Object loginId, String device) {
+        stpLogic.logout(loginId, device);
+    }
+
+    /**
+     * 会话注销,根据指定 Token
+     *
+     * @param tokenValue 指定token
+     */
+    public static void logoutByTokenValue(String tokenValue) {
+        stpLogic.logoutByTokenValue(tokenValue);
+    }
+
+    /**
+     * 踢人下线,根据账号id
+     * <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-5 </p>
+     *
+     * @param loginId 账号id
+     */
+    public static void kickout(Object loginId) {
+        stpLogic.kickout(loginId);
+    }
+
+    /**
+     * 踢人下线,根据账号id 和 设备标识
+     * <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-5 </p>
+     *
+     * @param loginId 账号id
+     * @param device  设备标识 (填null代表踢出所有设备)
+     */
+    public static void kickout(Object loginId, String device) {
+        stpLogic.kickout(loginId, device);
+    }
+
+    /**
+     * 踢人下线,根据指定 Token
+     * <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-5 </p>
+     *
+     * @param tokenValue 指定token
+     */
+    public static void kickoutByTokenValue(String tokenValue) {
+        stpLogic.kickoutByTokenValue(tokenValue);
+    }
+
+    /**
+     * 顶人下线,根据账号id 和 设备标识
+     * <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-4 </p>
+     *
+     * @param loginId 账号id
+     * @param device  设备标识 (填null代表顶替所有设备)
+     */
+    public static void replaced(Object loginId, String device) {
+        stpLogic.replaced(loginId, device);
+    }
+
+
+    // 查询相关
+
+    /**
+     * 当前会话是否已经登录
+     *
+     * @return 是否已登录
+     */
+    public static boolean isLogin() {
+        return stpLogic.isLogin();
+    }
+
+    /**
+     * 检验当前会话是否已经登录,如未登录,则抛出异常
+     */
+    public static void checkLogin() {
+        stpLogic.checkLogin();
+    }
+
+    /**
+     * 获取当前会话账号id, 如果未登录,则抛出异常
+     *
+     * @return 账号id
+     */
+    public static Object getLoginId() {
+        return stpLogic.getLoginId();
+    }
+
+    /**
+     * 获取当前会话账号id, 如果未登录,则返回默认值
+     *
+     * @param <T>          返回类型
+     * @param defaultValue 默认值
+     * @return 登录id
+     */
+    public static <T> T getLoginId(T defaultValue) {
+        return stpLogic.getLoginId(defaultValue);
+    }
+
+    /**
+     * 获取当前会话账号id, 如果未登录,则返回null
+     *
+     * @return 账号id
+     */
+    public static Object getLoginIdDefaultNull() {
+        return stpLogic.getLoginIdDefaultNull();
+    }
+
+    /**
+     * 获取当前会话账号id, 并转换为String类型
+     *
+     * @return 账号id
+     */
+    public static String getLoginIdAsString() {
+        return stpLogic.getLoginIdAsString();
+    }
+
+    /**
+     * 获取当前会话账号id, 并转换为int类型
+     *
+     * @return 账号id
+     */
+    public static int getLoginIdAsInt() {
+        return stpLogic.getLoginIdAsInt();
+    }
+
+    /**
+     * 获取当前会话账号id, 并转换为long类型
+     *
+     * @return 账号id
+     */
+    public static long getLoginIdAsLong() {
+        return stpLogic.getLoginIdAsLong();
+    }
+
+    /**
+     * 获取指定Token对应的账号id,如果未登录,则返回 null
+     *
+     * @param tokenValue token
+     * @return 账号id
+     */
+    public static Object getLoginIdByToken(String tokenValue) {
+        return stpLogic.getLoginIdByToken(tokenValue);
+    }
+
+
+    // =================== User-Session 相关 ===================
+
+    /**
+     * 获取指定账号id的Session, 如果Session尚未创建,isCreate=是否新建并返回
+     *
+     * @param loginId  账号id
+     * @param isCreate 是否新建
+     * @return Session对象
+     */
+    public static SaSession getSessionByLoginId(Object loginId, boolean isCreate) {
+        return stpLogic.getSessionByLoginId(loginId, isCreate);
+    }
+
+    /**
+     * 获取指定key的Session, 如果Session尚未创建,则返回null
+     *
+     * @param sessionId SessionId
+     * @return Session对象
+     */
+    public static SaSession getSessionBySessionId(String sessionId) {
+        return stpLogic.getSessionBySessionId(sessionId);
+    }
+
+    /**
+     * 获取指定账号id的Session,如果Session尚未创建,则新建并返回
+     *
+     * @param loginId 账号id
+     * @return Session对象
+     */
+    public static SaSession getSessionByLoginId(Object loginId) {
+        return stpLogic.getSessionByLoginId(loginId);
+    }
+
+    /**
+     * 获取当前会话的Session, 如果Session尚未创建,isCreate=是否新建并返回
+     *
+     * @param isCreate 是否新建
+     * @return Session对象
+     */
+    public static SaSession getSession(boolean isCreate) {
+        return stpLogic.getSession(isCreate);
+    }
+
+    /**
+     * 获取当前会话的Session,如果Session尚未创建,则新建并返回
+     *
+     * @return Session对象
+     */
+    public static SaSession getSession() {
+        return stpLogic.getSession();
+    }
+
+
+    // =================== Token-Session 相关 ===================
+
+    /**
+     * 获取指定Token-Session,如果Session尚未创建,则新建并返回
+     *
+     * @param tokenValue Token值
+     * @return Session对象
+     */
+    public static SaSession getTokenSessionByToken(String tokenValue) {
+        return stpLogic.getTokenSessionByToken(tokenValue);
+    }
+
+    /**
+     * 获取当前Token-Session,如果Session尚未创建,则新建并返回
+     *
+     * @return Session对象
+     */
+    public static SaSession getTokenSession() {
+        return stpLogic.getTokenSession();
+    }
+
+
+    // =================== [临时过期] 验证相关 ===================
+
+    /**
+     * 检查当前token 是否已经[临时过期],如果已经过期则抛出异常
+     */
+    public static void checkActivityTimeout() {
+        stpLogic.checkActivityTimeout();
+    }
+
+    /**
+     * 续签当前token:(将 [最后操作时间] 更新为当前时间戳)
+     * <h1>请注意: 即时token已经 [临时过期] 也可续签成功,
+     * 如果此场景下需要提示续签失败,可在此之前调用 checkActivityTimeout() 强制检查是否过期即可 </h1>
+     */
+    public static void updateLastActivityToNow() {
+        stpLogic.updateLastActivityToNow();
+    }
+
+
+    // =================== 过期时间相关 ===================
+
+    /**
+     * 获取当前登录者的 token 剩余有效时间 (单位: 秒)
+     *
+     * @return token剩余有效时间
+     */
+    public static long getTokenTimeout() {
+        return stpLogic.getTokenTimeout();
+    }
+
+    /**
+     * 获取当前登录者的 User-Session 剩余有效时间 (单位: 秒)
+     *
+     * @return token剩余有效时间
+     */
+    public static long getSessionTimeout() {
+        return stpLogic.getSessionTimeout();
+    }
+
+    /**
+     * 获取当前 Token-Session 剩余有效时间 (单位: 秒)
+     *
+     * @return token剩余有效时间
+     */
+    public static long getTokenSessionTimeout() {
+        return stpLogic.getTokenSessionTimeout();
+    }
+
+    /**
+     * 获取当前 token [临时过期] 剩余有效时间 (单位: 秒)
+     *
+     * @return token [临时过期] 剩余有效时间
+     */
+    public static long getTokenActivityTimeout() {
+        return stpLogic.getTokenActivityTimeout();
+    }
+
+
+    // =================== 角色验证操作 ===================
+
+    /**
+     * 获取:当前账号的角色集合
+     *
+     * @return /
+     */
+    public static List<String> getRoleList() {
+        return stpLogic.getRoleList();
+    }
+
+    /**
+     * 获取:指定账号的角色集合
+     *
+     * @param loginId 指定账号id
+     * @return /
+     */
+    public static List<String> getRoleList(Object loginId) {
+        return stpLogic.getRoleList(loginId);
+    }
+
+    /**
+     * 判断:当前账号是否拥有指定角色, 返回true或false
+     *
+     * @param role 角色标识
+     * @return 是否含有指定角色标识
+     */
+    public static boolean hasRole(String role) {
+        return stpLogic.hasRole(role);
+    }
+
+    /**
+     * 判断:指定账号是否含有指定角色标识, 返回true或false
+     *
+     * @param loginId 账号id
+     * @param role    角色标识
+     * @return 是否含有指定角色标识
+     */
+    public static boolean hasRole(Object loginId, String role) {
+        return stpLogic.hasRole(loginId, role);
+    }
+
+    /**
+     * 判断:当前账号是否含有指定角色标识 [指定多个,必须全部验证通过]
+     *
+     * @param roleArray 角色标识数组
+     * @return true或false
+     */
+    public static boolean hasRoleAnd(String... roleArray) {
+        return stpLogic.hasRoleAnd(roleArray);
+    }
+
+    /**
+     * 判断:当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可]
+     *
+     * @param roleArray 角色标识数组
+     * @return true或false
+     */
+    public static boolean hasRoleOr(String... roleArray) {
+        return stpLogic.hasRoleOr(roleArray);
+    }
+
+    /**
+     * 校验:当前账号是否含有指定角色标识, 如果验证未通过,则抛出异常: NotRoleException
+     *
+     * @param role 角色标识
+     */
+    public static void checkRole(String role) {
+        stpLogic.checkRole(role);
+    }
+
+    /**
+     * 校验:当前账号是否含有指定角色标识 [指定多个,必须全部验证通过]
+     *
+     * @param roleArray 角色标识数组
+     */
+    public static void checkRoleAnd(String... roleArray) {
+        stpLogic.checkRoleAnd(roleArray);
+    }
+
+    /**
+     * 校验:当前账号是否含有指定角色标识 [指定多个,只要其一验证通过即可]
+     *
+     * @param roleArray 角色标识数组
+     */
+    public static void checkRoleOr(String... roleArray) {
+        stpLogic.checkRoleOr(roleArray);
+    }
+
+
+    // =================== 权限验证操作 ===================
+
+    /**
+     * 获取:当前账号的权限码集合
+     *
+     * @return /
+     */
+    public static List<String> getPermissionList() {
+        return stpLogic.getPermissionList();
+    }
+
+    /**
+     * 获取:指定账号的权限码集合
+     *
+     * @param loginId 指定账号id
+     * @return /
+     */
+    public static List<String> getPermissionList(Object loginId) {
+        return stpLogic.getPermissionList(loginId);
+    }
+
+    /**
+     * 判断:当前账号是否含有指定权限, 返回true或false
+     *
+     * @param permission 权限码
+     * @return 是否含有指定权限
+     */
+    public static boolean hasPermission(String permission) {
+        return stpLogic.hasPermission(permission);
+    }
+
+    /**
+     * 判断:指定账号id是否含有指定权限, 返回true或false
+     *
+     * @param loginId    账号id
+     * @param permission 权限码
+     * @return 是否含有指定权限
+     */
+    public static boolean hasPermission(Object loginId, String permission) {
+        return stpLogic.hasPermission(loginId, permission);
+    }
+
+    /**
+     * 判断:当前账号是否含有指定权限, [指定多个,必须全部具有]
+     *
+     * @param permissionArray 权限码数组
+     * @return true 或 false
+     */
+    public static boolean hasPermissionAnd(String... permissionArray) {
+        return stpLogic.hasPermissionAnd(permissionArray);
+    }
+
+    /**
+     * 判断:当前账号是否含有指定权限 [指定多个,只要其一验证通过即可]
+     *
+     * @param permissionArray 权限码数组
+     * @return true 或 false
+     */
+    public static boolean hasPermissionOr(String... permissionArray) {
+        return stpLogic.hasPermissionOr(permissionArray);
+    }
+
+    /**
+     * 校验:当前账号是否含有指定权限, 如果验证未通过,则抛出异常: NotPermissionException
+     *
+     * @param permission 权限码
+     */
+    public static void checkPermission(String permission) {
+        stpLogic.checkPermission(permission);
+    }
+
+    /**
+     * 校验:当前账号是否含有指定权限 [指定多个,必须全部验证通过]
+     *
+     * @param permissionArray 权限码数组
+     */
+    public static void checkPermissionAnd(String... permissionArray) {
+        stpLogic.checkPermissionAnd(permissionArray);
+    }
+
+    /**
+     * 校验:当前账号是否含有指定权限 [指定多个,只要其一验证通过即可]
+     *
+     * @param permissionArray 权限码数组
+     */
+    public static void checkPermissionOr(String... permissionArray) {
+        stpLogic.checkPermissionOr(permissionArray);
+    }
+
+
+    // =================== id 反查token 相关操作 ===================
+
+    /**
+     * 获取指定账号id的tokenValue
+     * <p> 在配置为允许并发登录时,此方法只会返回队列的最后一个token,
+     * 如果你需要返回此账号id的所有token,请调用 getTokenValueListByLoginId
+     *
+     * @param loginId 账号id
+     * @return token值
+     */
+    public static String getTokenValueByLoginId(Object loginId) {
+        return stpLogic.getTokenValueByLoginId(loginId);
+    }
+
+    /**
+     * 获取指定账号id指定设备端的tokenValue
+     * <p> 在配置为允许并发登录时,此方法只会返回队列的最后一个token,
+     * 如果你需要返回此账号id的所有token,请调用 getTokenValueListByLoginId
+     *
+     * @param loginId 账号id
+     * @param device  设备标识
+     * @return token值
+     */
+    public static String getTokenValueByLoginId(Object loginId, String device) {
+        return stpLogic.getTokenValueByLoginId(loginId, device);
+    }
+
+    /**
+     * 获取指定账号id的tokenValue集合
+     *
+     * @param loginId 账号id
+     * @return 此loginId的所有相关token
+     */
+    public static List<String> getTokenValueListByLoginId(Object loginId) {
+        return stpLogic.getTokenValueListByLoginId(loginId);
+    }
+
+    /**
+     * 获取指定账号id指定设备端的tokenValue 集合
+     *
+     * @param loginId 账号id
+     * @param device  设备标识
+     * @return 此loginId的所有相关token
+     */
+    public static List<String> getTokenValueListByLoginId(Object loginId, String device) {
+        return stpLogic.getTokenValueListByLoginId(loginId, device);
+    }
+
+    /**
+     * 返回当前会话的登录设备
+     *
+     * @return 当前令牌的登录设备
+     */
+    public static String getLoginDevice() {
+        return stpLogic.getLoginDevice();
+    }
+
+
+    // =================== 会话管理 ===================
+
+    /**
+     * 根据条件查询Token
+     *
+     * @param keyword 关键字
+     * @param start   开始处索引 (-1代表查询所有)
+     * @param size    获取数量
+     * @return token集合
+     */
+    public static List<String> searchTokenValue(String keyword, int start, int size) {
+        return stpLogic.searchTokenValue(keyword, start, size);
+    }
+
+    /**
+     * 根据条件查询SessionId
+     *
+     * @param keyword 关键字
+     * @param start   开始处索引 (-1代表查询所有)
+     * @param size    获取数量
+     * @return sessionId集合
+     */
+    public static List<String> searchSessionId(String keyword, int start, int size) {
+        return stpLogic.searchSessionId(keyword, start, size);
+    }
+
+    /**
+     * 根据条件查询Token专属Session的Id
+     *
+     * @param keyword 关键字
+     * @param start   开始处索引 (-1代表查询所有)
+     * @param size    获取数量
+     * @return sessionId集合
+     */
+    public static List<String> searchTokenSessionId(String keyword, int start, int size) {
+        return stpLogic.searchTokenSessionId(keyword, start, size);
+    }
+
+
+    // ------------------- 账号封禁 -------------------
+
+    /**
+     * 封禁指定账号
+     * <p> 此方法不会直接将此账号id踢下线,而是在对方再次登录时抛出`DisableLoginException`异常
+     *
+     * @param loginId     指定账号id
+     * @param disableTime 封禁时间, 单位: 秒 (-1=永久封禁)
+     */
+    public static void disable(Object loginId, long disableTime) {
+        stpLogic.disable(loginId, disableTime);
+    }
+
+    /**
+     * 指定账号是否已被封禁 (true=已被封禁, false=未被封禁)
+     *
+     * @param loginId 账号id
+     * @return see note
+     */
+    public static boolean isDisable(Object loginId) {
+        return stpLogic.isDisable(loginId);
+    }
+
+    /**
+     * 获取指定账号剩余封禁时间,单位:秒(-1=永久封禁,-2=未被封禁)
+     *
+     * @param loginId 账号id
+     * @return see note
+     */
+    public static long getDisableTime(Object loginId) {
+        return stpLogic.getDisableTime(loginId);
+    }
+
+    /**
+     * 解封指定账号
+     *
+     * @param loginId 账号id
+     */
+    public static void untieDisable(Object loginId) {
+        stpLogic.untieDisable(loginId);
+    }
+
+
+    // =================== 身份切换 ===================
+
+    /**
+     * 临时切换身份为指定账号id
+     *
+     * @param loginId 指定loginId
+     */
+    public static void switchTo(Object loginId) {
+        stpLogic.switchTo(loginId);
+    }
+
+    /**
+     * 结束临时切换身份
+     */
+    public static void endSwitch() {
+        stpLogic.endSwitch();
+    }
+
+    /**
+     * 当前是否正处于[身份临时切换]中
+     *
+     * @return 是否正处于[身份临时切换]中
+     */
+    public static boolean isSwitch() {
+        return stpLogic.isSwitch();
+    }
+
+    /**
+     * 在一个代码段里方法内,临时切换身份为指定账号id
+     *
+     * @param loginId  指定账号id
+     * @param function 要执行的方法
+     */
+    public static void switchTo(Object loginId, SaFunction function) {
+        stpLogic.switchTo(loginId, function);
+    }
+
+
+    // ------------------- 二级认证 -------------------
+
+    /**
+     * 在当前会话 开启二级认证
+     *
+     * @param safeTime 维持时间 (单位: 秒)
+     */
+    public static void openSafe(long safeTime) {
+        stpLogic.openSafe(safeTime);
+    }
+
+    /**
+     * 当前会话 是否处于二级认证时间内
+     *
+     * @return true=二级认证已通过, false=尚未进行二级认证或认证已超时
+     */
+    public static boolean isSafe() {
+        return stpLogic.isSafe();
+    }
+
+    /**
+     * 检查当前会话是否已通过二级认证,如未通过则抛出异常
+     */
+    public static void checkSafe() {
+        stpLogic.checkSafe();
+    }
+
+    /**
+     * 获取当前会话的二级认证剩余有效时间 (单位: 秒, 返回-2代表尚未通过二级认证)
+     *
+     * @return 剩余有效时间
+     */
+    public static long getSafeTime() {
+        return stpLogic.getSafeTime();
+    }
+
+    /**
+     * 在当前会话 结束二级认证
+     */
+    public static void closeSafe() {
+        stpLogic.closeSafe();
+    }
+
+
+    // =================== 历史API,兼容旧版本 ===================
+
+    /**
+     * <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.getLoginType() ,使用方式保持不变 </h1>
+     * <p>
+     * 获取当前StpLogin的loginKey
+     *
+     * @return 当前StpLogin的loginKey
+     */
+    @Deprecated
+    public static String getLoginKey() {
+        return stpLogic.getLoginType();
+    }
+
+    /**
+     * <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.login() ,使用方式保持不变 </h1>
+     * <p>
+     * 在当前会话上登录id
+     *
+     * @param loginId 登录id,建议的类型:(long | int | String)
+     */
+    @Deprecated
+    public static void setLoginId(Object loginId) {
+        stpLogic.login(loginId);
+    }
+
+    /**
+     * <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.login() ,使用方式保持不变 </h1>
+     * <p>
+     * 在当前会话上登录id, 并指定登录设备
+     *
+     * @param loginId 登录id,建议的类型:(long | int | String)
+     * @param device  设备标识
+     */
+    @Deprecated
+    public static void setLoginId(Object loginId, String device) {
+        stpLogic.login(loginId, device);
+    }
+
+    /**
+     * <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.login() ,使用方式保持不变 </h1>
+     * <p>
+     * 在当前会话上登录id, 并指定登录设备
+     *
+     * @param loginId         登录id,建议的类型:(long | int | String)
+     * @param isLastingCookie 是否为持久Cookie
+     */
+    @Deprecated
+    public static void setLoginId(Object loginId, boolean isLastingCookie) {
+        stpLogic.login(loginId, isLastingCookie);
+    }
+
+    /**
+     * <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.login() ,使用方式保持不变 </h1>
+     * <p>
+     * 在当前会话上登录id, 并指定所有登录参数Model
+     *
+     * @param loginId    登录id,建议的类型:(long | int | String)
+     * @param loginModel 此次登录的参数Model
+     */
+    @Deprecated
+    public static void setLoginId(Object loginId, SaLoginModel loginModel) {
+        stpLogic.login(loginId, loginModel);
+    }
+
+    /**
+     * <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.kickout() ,使用方式保持不变 </h1>
+     * <p>
+     * 会话注销,根据账号id (踢人下线)
+     * <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2
+     *
+     * @param loginId 账号id
+     */
+    @Deprecated
+    public static void logoutByLoginId(Object loginId) {
+        stpLogic.kickout(loginId);
+    }
+
+    /**
+     * <h1> 本函数设计已过时,未来版本可能移除此函数,请及时更换为 StpUtil.kickout() ,使用方式保持不变 </h1>
+     * <p>
+     * 会话注销,根据账号id and 设备标识 (踢人下线)
+     * <p> 当对方再次访问系统时,会抛出NotLoginException异常,场景值=-2 </p>
+     *
+     * @param loginId 账号id
+     * @param device  设备标识 (填null代表所有注销设备)
+     */
+    @Deprecated
+    public static void logoutByLoginId(Object loginId, String device) {
+        stpLogic.kickout(loginId, device);
+    }
+
+}

+ 6 - 0
sp-com/business/src/main/java/com/pj/project/package-info.java

@@ -0,0 +1,6 @@
+
+
+/**
+ * 此包下放你的模块代码
+ */
+package com.pj.project;

+ 65 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict/SysDict.java

@@ -0,0 +1,65 @@
+package com.pj.project.sys_dict;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * Model: sys_dict -- 字典表
+ * @author qzyReal 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(SysDict.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class SysDict extends Model<SysDict> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "sys_dict";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "sys-dict";	
+
+
+	// ---------- 表中字段 ----------
+	/**
+	 * 主键 
+	 */
+
+	private String id;
+
+	/**
+	 * 字典名称 
+	 */
+	private String name;
+
+	/**
+	 * 编号 
+	 */
+	private String code;
+
+	/**
+	 * 描述 
+	 */
+	private String des;
+
+
+
+
+
+	
+
+
+}

+ 116 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict/SysDictController.java

@@ -0,0 +1,116 @@
+package com.pj.project.sys_dict;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.pj.current.satoken.StpUserUtil;
+import com.pj.project4sp.SP;
+import com.pj.utils.sg.AjaxError;
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * Controller: sys_dict -- 字典表
+ *
+ * @author qzyReal
+ */
+@RestController
+@RequestMapping("/SysDict/")
+public class SysDictController {
+
+    /**
+     * 底层 Service 对象
+     */
+    @Autowired
+    SysDictService sysDictService;
+
+    /**
+     * 增
+     */
+    @RequestMapping("add")
+    @SaCheckPermission(SysDict.PERMISSION_CODE)
+    @Transactional(rollbackFor = Exception.class)
+    public AjaxJson add(SysDict s) {
+        sysDictService.add(s);
+        return AjaxJson.getSuccessData(s);
+    }
+
+    /**
+     * 删
+     */
+    @RequestMapping("delete")
+    @SaCheckPermission(SysDict.PERMISSION_CODE)
+    public AjaxJson delete(Long id) {
+        int line = sysDictService.delete(id);
+        return AjaxJson.getByLine(line);
+    }
+
+    /**
+     * 删 - 根据id列表
+     */
+    @RequestMapping("deleteByIds")
+    @SaCheckPermission(SysDict.PERMISSION_CODE)
+    public AjaxJson deleteByIds() {
+        List<Long> ids = SoMap.getRequestSoMap().getListByComma("ids", long.class);
+        int line = SP.publicMapper.deleteByIds(SysDict.TABLE_NAME, ids);
+        return AjaxJson.getByLine(line);
+    }
+
+    /**
+     * 改
+     */
+    @RequestMapping("update")
+    @SaCheckPermission(SysDict.PERMISSION_CODE)
+    public AjaxJson update(SysDict s) {
+        int line = sysDictService.update(s);
+        return AjaxJson.getByLine(line);
+    }
+
+    /**
+     * 查 - 根据id
+     */
+    @RequestMapping("getById")
+    public AjaxJson getById(Long id) {
+        SysDict s = sysDictService.getById(id);
+        return AjaxJson.getSuccessData(s);
+    }
+
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
+    @RequestMapping("getList")
+    public AjaxJson getList() {
+        SoMap so = SoMap.getRequestSoMap();
+        List<SysDict> list = sysDictService.getList(so.startPage());
+        return AjaxJson.getPageData(so.getDataCount(), list);
+    }
+
+
+
+
+    // ------------------------- 前端接口 -------------------------
+
+
+    /**
+     * 改 - 不传不改 [G]
+     */
+    @RequestMapping("updateByNotNull")
+    public AjaxJson updateByNotNull(Long id) {
+        AjaxError.throwBy(true, "如需正常调用此接口,请删除此行代码");
+        // 鉴别身份,是否为数据创建者
+        long userId = SP.publicMapper.getColumnByIdToLong(SysDict.TABLE_NAME, "user_id", id);
+        AjaxError.throwBy(userId != StpUserUtil.getLoginIdAsLong(), "此数据您无权限修改");
+        // 开始修改 (请只保留需要修改的字段)
+        SoMap so = SoMap.getRequestSoMap();
+        so.clearNotIn("id", "name", "code", "desc").clearNull().humpToLineCase();
+        int line = SP.publicMapper.updateBySoMapById(SysDict.TABLE_NAME, so, id);
+        return AjaxJson.getByLine(line);
+    }
+
+
+}

+ 55 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict/SysDictMapper.java

@@ -0,0 +1,55 @@
+package com.pj.project.sys_dict;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pj.utils.so.SoMap;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Mapper: sys_dict -- 字典表
+ * @author qzyReal 
+ */
+
+@Mapper
+@Repository
+public interface SysDictMapper extends BaseMapper <SysDict> {
+
+	/**
+	 * 增  
+	 * @param s 实体对象 
+	 * @return 受影响行数 
+	 */
+	int add(SysDict s);
+
+	/**
+	 * 删  
+	 * @param id 要删除的数据id  
+	 * @return 受影响行数 
+	 */
+	int delete(Long id);	 
+
+	/** 
+	 * 改  
+	 * @param s 实体对象 
+	 * @return 受影响行数 
+	 */
+	int update(SysDict s);
+
+	/** 
+	 * 查 - 根据id  
+	 * @param id 要查询的数据id 
+	 * @return 实体对象 
+	 */
+	SysDict getById(Long id);
+
+	/**
+	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+	 * @param so 参数集合 
+	 * @return 数据列表 
+	 */
+	List<SysDict> getList(SoMap so);
+
+
+}

+ 72 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict/SysDictMapper.xml

@@ -0,0 +1,72 @@
+<?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="com.pj.project.sys_dict.SysDictMapper">
+
+    <!-- 增 [G] -->
+    <insert id="add">
+		insert into 
+		sys_dict (id, name, code, `des`)
+		values (#{id}, #{name}, #{code}, #{des})
+	</insert>
+
+    <!-- 删 -->
+    <delete id="delete">
+		delete from sys_dict 
+		where id = #{id}
+	</delete>
+
+    <!-- 改 [G] -->
+    <update id="update">
+		update sys_dict set
+		id = #{id}, 
+		name = #{name}, 
+		code = #{code}, 
+		`des` = #{des}
+		where id = #{id}
+	</update>
+
+
+    <!-- ================================== 查询相关 ================================== -->
+    <!-- select id, name, code, desc from sys_dict  -->
+
+    <!-- 通用映射:手动模式 -->
+    <resultMap id="model" type="com.pj.project.sys_dict.SysDict">
+        <result property="id" column="id"/>
+        <result property="name" column="name"/>
+        <result property="code" column="code"/>
+        <result property="des" column="des"/>
+    </resultMap>
+
+    <!-- 公共查询sql片段 -->
+    <sql id="select_sql">
+		select * 
+		from sys_dict 
+	</sql>
+
+    <!-- 查 - 根据id -->
+    <select id="getById" resultMap="model">
+        <include refid="select_sql"></include>
+        where id = #{id}
+    </select>
+
+    <!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+    <select id="getList" resultMap="model">
+        <include refid="select_sql"></include>
+        <where>
+            <if test=' this.isNotNull("id") '>and id = #{id}</if>
+            <if test=' this.isNotNull("name") '>and name like concat('%',#{name},'%')</if>
+            <if test=' this.isNotNull("code") '>and code = #{code}</if>
+            <if test=' this.isNotNull("des") '>and `des` like concat('%',#{des},'%')</if>
+        </where>
+        order by
+        <choose>
+            <when test='sortType == 1'>id desc</when>
+            <when test='sortType == 2'>name desc</when>
+            <when test='sortType == 3'>code desc</when>
+            <when test='sortType == 4'>`des` desc</when>
+            <otherwise>id desc</otherwise>
+        </choose>
+    </select>
+
+
+</mapper>

+ 76 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict/SysDictService.java

@@ -0,0 +1,76 @@
+package com.pj.project.sys_dict;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+
+/**
+ * Service: sys_dict -- 字典表
+ *
+ * @author qzyReal
+ */
+@Service
+public class SysDictService extends ServiceImpl<SysDictMapper, SysDict> implements IService<SysDict> {
+
+    /**
+     * 底层 Mapper 对象
+     */
+    @Autowired
+    SysDictMapper sysDictMapper;
+
+    /**
+     * 增
+     */
+    int add(SysDict s) {
+        return sysDictMapper.add(s);
+    }
+
+    /**
+     * 删
+     */
+    int delete(Long id) {
+        return sysDictMapper.delete(id);
+    }
+
+    /**
+     * 改
+     */
+    int update(SysDict s) {
+        return sysDictMapper.update(s);
+    }
+
+    /**
+     * 查
+     */
+    SysDict getById(Long id) {
+        return sysDictMapper.getById(id);
+    }
+
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
+    List<SysDict> getList(SoMap so) {
+        return sysDictMapper.getList(so);
+    }
+
+    /**
+     * 根据编号查询
+     * @param code
+     * @return
+     */
+    SysDict findByCode(String code) {
+        QueryWrapper<SysDict> ew = new QueryWrapper<>();
+        ew.eq("code", code);
+        return this.getOne(ew);
+    }
+
+
+
+}

+ 80 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItem.java

@@ -0,0 +1,80 @@
+package com.pj.project.sys_dict_item;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * Model: sys_dict_item -- 
+ * @author qzyReal 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(SysDictItem.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class SysDictItem extends Model<SysDictItem> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "sys_dict_item";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "sys-dict-item";	
+
+
+	// ---------- 表中字段 ----------
+	/**
+	 * 主键 
+	 */
+
+	private String id;
+
+	/**
+	 * 字典ID 
+	 */
+	private String dictId;
+
+	/**
+	 * 字典值 
+	 */
+	private String itemValue;
+
+	/**
+	 * 字典文本 
+	 */
+	private String itemText;
+
+	/**
+	 * 描述 
+	 */
+	private String des;
+
+	/**
+	 * 排序 
+	 */
+	private int sort;
+
+	/**
+	 * 状态(0=禁用,1=启用) 
+	 */
+	private int status;
+
+
+
+
+
+	
+
+
+}

+ 112 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItemController.java

@@ -0,0 +1,112 @@
+package com.pj.project.sys_dict_item;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.pj.current.satoken.StpUserUtil;
+import com.pj.project.sys_dict.SysDict;
+import com.pj.project4sp.SP;
+import com.pj.utils.sg.AjaxError;
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * Controller: sys_dict_item -- 
+ * @author qzyReal 
+ */
+@RestController
+@RequestMapping("/SysDictItem/")
+public class SysDictItemController {
+
+	/** 底层 Service 对象 */
+	@Autowired
+    SysDictItemService sysDictItemService;
+
+	/** 增 */  
+	@RequestMapping("add")
+	@SaCheckPermission(SysDict.PERMISSION_CODE)
+	@Transactional(rollbackFor = Exception.class)
+	public AjaxJson add(SysDictItem s){
+		sysDictItemService.add(s);
+		return AjaxJson.getSuccessData(s);
+	}
+
+	/** 删 */  
+	@RequestMapping("delete")
+	@SaCheckPermission(SysDict.PERMISSION_CODE)
+	public AjaxJson delete(String id){
+		int line = sysDictItemService.delete(id);
+		return AjaxJson.getByLine(line);
+	}
+	
+	/** 删 - 根据id列表 */  
+	@RequestMapping("deleteByIds")
+	@SaCheckPermission(SysDict.PERMISSION_CODE)
+	public AjaxJson deleteByIds(){
+		List<Long> ids = SoMap.getRequestSoMap().getListByComma("ids", long.class);
+		int line = SP.publicMapper.deleteByIds(SysDictItem.TABLE_NAME, ids);
+		return AjaxJson.getByLine(line);
+	}
+	
+	/** 改 */  
+	@RequestMapping("update")
+	@SaCheckPermission(SysDict.PERMISSION_CODE)
+	public AjaxJson update(SysDictItem s){
+		int line = sysDictItemService.update(s);
+		return AjaxJson.getByLine(line);
+	}
+
+	/** 查 - 根据id */  
+	@RequestMapping("getById")
+	public AjaxJson getById(String id){
+		SysDictItem s = sysDictItemService.getById(id);
+		return AjaxJson.getSuccessData(s);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	@RequestMapping("getList")
+	public AjaxJson getList() {
+		SoMap so = SoMap.getRequestSoMap();
+		List<SysDictItem> list = sysDictItemService.getList(so.startPage());
+		return AjaxJson.getPageData(so.getDataCount(), list);
+	}
+
+	/** 改 - 是否可用(0=可用,1=不可用) */
+	@RequestMapping("updateStatus")
+	@SaCheckPermission(SysDict.PERMISSION_CODE)
+	public AjaxJson updateStatus(Long id, int value){
+		SP.publicMapper.updateColumnById(SysDictItem.TABLE_NAME, "status", value, id);
+		return AjaxJson.getSuccess();
+	}
+	
+	
+	
+	// ------------------------- 前端接口 -------------------------
+	
+	
+	/** 改 - 不传不改 [G] */
+	@RequestMapping("updateByNotNull")
+	public AjaxJson updateByNotNull(String id){
+		AjaxError.throwBy(true, "如需正常调用此接口,请删除此行代码");
+		// 鉴别身份,是否为数据创建者 
+		long userId = SP.publicMapper.getColumnByIdToLong(SysDictItem.TABLE_NAME, "user_id", id);
+		AjaxError.throwBy(userId != StpUserUtil.getLoginIdAsLong(), "此数据您无权限修改");
+		// 开始修改 (请只保留需要修改的字段)
+		SoMap so = SoMap.getRequestSoMap();
+		so.clearNotIn("id", "dictId", "itemValue", "itemText", "desc", "sort", "status").clearNull().humpToLineCase();	
+		int line = SP.publicMapper.updateBySoMapById(SysDictItem.TABLE_NAME, so, id);
+		return AjaxJson.getByLine(line);
+	}
+	
+	
+	
+	
+	
+	
+
+}

+ 55 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItemMapper.java

@@ -0,0 +1,55 @@
+package com.pj.project.sys_dict_item;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pj.utils.so.SoMap;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Mapper: sys_dict_item -- 
+ * @author qzyReal 
+ */
+
+@Mapper
+@Repository
+public interface SysDictItemMapper extends BaseMapper <SysDictItem> {
+
+	/**
+	 * 增  
+	 * @param s 实体对象 
+	 * @return 受影响行数 
+	 */
+	int add(SysDictItem s);
+
+	/**
+	 * 删  
+	 * @param id 要删除的数据id  
+	 * @return 受影响行数 
+	 */
+	int delete(String id);	 
+
+	/** 
+	 * 改  
+	 * @param s 实体对象 
+	 * @return 受影响行数 
+	 */
+	int update(SysDictItem s);
+
+	/** 
+	 * 查 - 根据id  
+	 * @param id 要查询的数据id 
+	 * @return 实体对象 
+	 */
+	SysDictItem getById(String id);	 
+
+	/**
+	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+	 * @param so 参数集合 
+	 * @return 数据列表 
+	 */
+	List<SysDictItem> getList(SoMap so);
+
+
+}

+ 92 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItemMapper.xml

@@ -0,0 +1,92 @@
+<?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="com.pj.project.sys_dict_item.SysDictItemMapper">
+
+	<!-- 增 [G] -->
+	<insert id="add">
+		insert into 
+		sys_dict_item (id, dict_id, item_value, item_text, des, sort, status)
+		values (#{id}, #{dictId}, #{itemValue}, #{itemText}, #{des}, #{sort}, #{status})
+	</insert>
+
+	<!-- 删 -->
+	<delete id="delete">
+		delete from sys_dict_item 
+		where id = #{id}
+	</delete>
+
+	<!-- 改 [G] -->
+	<update id="update">
+		update sys_dict_item set
+		id = #{id}, 
+		dict_id = #{dictId}, 
+		item_value = #{itemValue}, 
+		item_text = #{itemText}, 
+		des = #{des},
+		sort = #{sort}, 
+		status = #{status}
+		where id = #{id}
+	</update>
+
+
+	<!-- ================================== 查询相关 ================================== -->
+	<!-- select id, dict_id, item_value, item_text, desc, sort, status from sys_dict_item  -->
+	
+	<!-- 通用映射:手动模式 -->
+	<resultMap id="model" type="com.pj.project.sys_dict_item.SysDictItem">
+		<result property="id" column="id" />
+		<result property="dictId" column="dict_id" />
+		<result property="itemValue" column="item_value" />
+		<result property="itemText" column="item_text" />
+		<result property="des" column="des" />
+		<result property="sort" column="sort" />
+		<result property="status" column="status" />
+	</resultMap>
+	
+	<!-- 公共查询sql片段 -->
+	<sql id="select_sql">
+		select * 
+		from sys_dict_item 
+	</sql>
+	
+	<!-- 查 - 根据id -->
+	<select id="getById" resultMap="model">
+		<include refid="select_sql"></include>
+		where id = #{id}
+	</select>
+	
+	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+	<select id="getList" resultMap="model">
+		<include refid="select_sql"></include>
+		<where>
+			<if test=' this.isNotNull("id") '> and id = #{id} </if>
+			<if test=' this.isNotNull("dictId") '> and dict_id = #{dictId} </if>
+			<if test=' this.isNotNull("itemValue") '> and item_value = #{itemValue} </if>
+			<if test=' this.isNotNull("itemText") '> and item_text = #{itemText} </if>
+			<if test=' this.isNotNull("des") '> and desc= #{des} </if>
+			<if test=' this.isNotNull("sort") '> and sort = #{sort} </if>
+			<if test=' this.isNotNull("status") '> and status = #{status} </if>
+		</where>
+		order by
+		<choose>
+			<when test='sortType == 1'> id desc </when>
+			<when test='sortType == 2'> dict_id desc </when>
+			<when test='sortType == 3'> item_value desc </when>
+			<when test='sortType == 4'> item_text desc </when>
+			<when test='sortType == 5'> des desc </when>
+			<when test='sortType == 6'> sort desc </when>
+			<when test='sortType == 7'> status desc </when>
+			<otherwise> id desc </otherwise>
+		</choose>
+	</select>
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+</mapper>

+ 54 - 0
sp-com/business/src/main/java/com/pj/project/sys_dict_item/SysDictItemService.java

@@ -0,0 +1,54 @@
+package com.pj.project.sys_dict_item;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Service: sys_dict_item -- 
+ * @author qzyReal 
+ */
+@Service
+public class SysDictItemService  extends ServiceImpl <SysDictItemMapper,SysDictItem> implements IService<SysDictItem>  {
+
+	/** 底层 Mapper 对象 */
+	@Autowired
+	SysDictItemMapper sysDictItemMapper;
+
+	/** 增 */
+	int add(SysDictItem s){
+		return sysDictItemMapper.add(s);
+	}
+
+	/** 删 */
+	int delete(String id){
+		return sysDictItemMapper.delete(id);
+	}
+
+	/** 改 */
+	int update(SysDictItem s){
+		return sysDictItemMapper.update(s);
+	}
+
+	/** 查 */
+	SysDictItem getById(String id){
+		return sysDictItemMapper.getById(id);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	List<SysDictItem> getList(SoMap so) {
+		return sysDictItemMapper.getList(so);	
+	}
+	
+
+	public List<SysDictItem> findByDictId(Long dictId){
+		QueryWrapper<SysDictItem>ew=new QueryWrapper<>();
+		ew.eq("dict_id",dictId);
+		return this.list(ew);
+	}
+}

+ 87 - 0
sp-com/business/src/main/java/com/pj/project/tb_account/TbAccount.java

@@ -0,0 +1,87 @@
+package com.pj.project.tb_account;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * Model: tb_account -- 客户账户
+ * @author qzy 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(TbAccount.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class TbAccount extends Model<TbAccount> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "tb_account";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "tb-account";	
+
+
+	// ---------- 表中字段 ----------
+	/**
+	 * 主键 
+	 */
+	@TableId(type = IdType.AUTO)
+	private Long id;	
+
+	/**
+	 * 客户id 
+	 */
+	private Long customerId;	
+
+	/**
+	 * 账户 
+	 */
+	private String accountNo;	
+
+	/**
+	 * 冻结金额 
+	 */
+	private String lockMoney;	
+
+	/**
+	 * 可用金额 
+	 */
+	private String actMoney;	
+
+	/**
+	 * 总金额 
+	 */
+	private String totalMoney;	
+
+	/**
+	 * 状态(0=禁用,1=启用) 
+	 */
+	private String status;	
+
+	/**
+	 * 创建时间 
+	 */
+	private String createTime;	
+
+
+
+
+
+	
+
+
+}

+ 29 - 0
sp-com/business/src/main/java/com/pj/project/tb_account/TbAccountController.java

@@ -0,0 +1,29 @@
+package com.pj.project.tb_account;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * Controller: tb_account -- 客户账户
+ * @author qzy 
+ */
+@RestController
+@RequestMapping("/TbAccount/")
+public class TbAccountController {
+
+	/** 底层 Service 对象 */
+	@Autowired
+	TbAccountService tbAccountService;
+
+
+
+	
+	
+	
+	
+	
+	
+
+}

+ 28 - 0
sp-com/business/src/main/java/com/pj/project/tb_account/TbAccountMapper.java

@@ -0,0 +1,28 @@
+package com.pj.project.tb_account;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pj.utils.so.SoMap;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Mapper: tb_account -- 客户账户
+ * @author qzy 
+ */
+
+@Mapper
+@Repository
+public interface TbAccountMapper extends BaseMapper <TbAccount> {
+
+
+	/**
+	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+	 * @param so 参数集合 
+	 * @return 数据列表 
+	 */
+	List<TbAccount> getList(SoMap so);
+
+
+}

+ 65 - 0
sp-com/business/src/main/java/com/pj/project/tb_account/TbAccountMapper.xml

@@ -0,0 +1,65 @@
+<?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="com.pj.project.tb_account.TbAccountMapper">
+
+
+
+	<!-- ================================== 查询相关 ================================== -->
+	<!-- select id, customer_id, account_no, lock_money, act_money, total_money, status, create_time from tb_account  -->
+	
+	<!-- 通用映射:手动模式 -->
+	<resultMap id="model" type="com.pj.project.tb_account.TbAccount">
+		<result property="id" column="id" />
+		<result property="customerId" column="customer_id" />
+		<result property="accountNo" column="account_no" />
+		<result property="lockMoney" column="lock_money" />
+		<result property="actMoney" column="act_money" />
+		<result property="totalMoney" column="total_money" />
+		<result property="status" column="status" />
+		<result property="createTime" column="create_time" />
+	</resultMap>
+	
+	<!-- 公共查询sql片段 -->
+	<sql id="select_sql">
+		select * 
+		from tb_account 
+	</sql>
+
+	
+	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+	<select id="getList" resultMap="model">
+		<include refid="select_sql"></include>
+		<where>
+			<if test=' this.has("id") '> and id = #{id} </if>
+			<if test=' this.has("customerId") '> and customer_id = #{customerId} </if>
+			<if test=' this.has("accountNo") '> and account_no = #{accountNo} </if>
+			<if test=' this.has("lockMoney") '> and lock_money = #{lockMoney} </if>
+			<if test=' this.has("actMoney") '> and act_money = #{actMoney} </if>
+			<if test=' this.has("totalMoney") '> and total_money = #{totalMoney} </if>
+			<if test=' this.has("status") '> and status = #{status} </if>
+			<if test=' this.has("createTime") '> and create_time = #{createTime} </if>
+		</where>
+		order by
+		<choose>
+			<when test='sortType == 1'> id desc </when>
+			<when test='sortType == 2'> customer_id desc </when>
+			<when test='sortType == 3'> account_no desc </when>
+			<when test='sortType == 4'> lock_money desc </when>
+			<when test='sortType == 5'> act_money desc </when>
+			<when test='sortType == 6'> total_money desc </when>
+			<when test='sortType == 7'> status desc </when>
+			<when test='sortType == 8'> create_time desc </when>
+			<otherwise> id desc </otherwise>
+		</choose>
+	</select>
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+</mapper>

+ 40 - 0
sp-com/business/src/main/java/com/pj/project/tb_account/TbAccountService.java

@@ -0,0 +1,40 @@
+package com.pj.project.tb_account;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Service: tb_account -- 客户账户
+ *
+ * @author qzy
+ */
+@Service
+public class TbAccountService extends ServiceImpl<TbAccountMapper, TbAccount> implements IService<TbAccount> {
+
+    /**
+     * 底层 Mapper 对象
+     */
+    @Autowired
+    TbAccountMapper tbAccountMapper;
+
+    TbAccount getByCustomerId(String customerId) {
+        QueryWrapper<TbAccount>ew=new QueryWrapper<>();
+        ew.eq("customer_id",customerId);
+        return getOne(ew);
+    }
+
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
+    List<TbAccount> getList(SoMap so) {
+        return tbAccountMapper.getList(so);
+    }
+
+
+}

+ 29 - 0
sp-com/business/src/main/java/com/pj/project/tb_business/BusinessMessageManager.java

@@ -0,0 +1,29 @@
+package com.pj.project.tb_business;
+
+import com.pj.utils.cache.RedisUtil;
+import org.springframework.stereotype.Component;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Component
+public class BusinessMessageManager {
+    private static String MES_PREFIX = "b_m:";
+    private static long EXP_TIME_SECOND = 24 * 60;
+
+    public static void set(String customerId, String content) {
+        List<Object> list = RedisUtil.forListGet(MES_PREFIX + customerId);
+        List<String>checkList=list.stream().map(Object::toString).collect(Collectors.toList());
+        if (checkList.contains(content)) {
+            return;
+        }
+        RedisUtil.forListAdd(MES_PREFIX + customerId, content);
+    }
+
+    public static List<String> get(String customerId) {
+        List<Object> list = RedisUtil.forListGet(MES_PREFIX + customerId);
+        RedisUtil.forListRemove(MES_PREFIX+customerId);
+        return list == null ? Collections.emptyList() : list.stream().map(Object::toString).collect(Collectors.toList());
+    }
+}

+ 217 - 0
sp-com/business/src/main/java/com/pj/project/tb_business/TbBusiness.java

@@ -0,0 +1,217 @@
+package com.pj.project.tb_business;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.pj.project.tb_business_item.TbBusinessItem;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Model: tb_business -- 入境登记
+ *
+ * @author qzy
+ */
+@Data
+@Accessors(chain = true)
+@TableName(TbBusiness.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class TbBusiness extends Model<TbBusiness> implements Serializable {
+
+    // ---------- 模块常量 ----------
+    /**
+     * 序列化版本id
+     */
+    private static final long serialVersionUID = 1L;
+    /**
+     * 此模块对应的表名
+     */
+    public static final String TABLE_NAME = "tb_business";
+    /**
+     * 此模块对应的权限码
+     */
+    public static final String PERMISSION_CODE = "tb-business";
+    public static final String PERMISSION_LIST = "tb-business-list";
+    public static final String PERMISSION_CONFIRM = "tb-business-confirm";
+    public static final String PERMISSION_PAY = "tb-business-pay";
+    public static final String PERMISSION_INPUT = "tb-business-add";
+
+
+    // ---------- 表中字段 ----------
+    /**
+     * 主键
+     */
+    private String id;
+
+    /**
+     * 客户id
+     */
+    private String customerId;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    /**
+     * 编号
+     */
+    private String no;
+
+    /**
+     * 车牌号
+     */
+    private String cardNo;
+    private String countryName;
+
+    /**
+     * 车规格
+     */
+    private Double cardSize;
+
+    /**
+     * 载重(kg)
+     */
+    private Double netWeight;
+
+    /**
+     * 商品
+     */
+    private String goodsName;
+
+    /**
+     * 商品编号
+     */
+    private String goodsCode;
+
+    /**
+     * 司机名称
+     */
+    private String driverName;
+
+    /**
+     * 司机id
+     */
+    private String driverId;
+
+    /**
+     * 司机联系号码
+     */
+    private String driverPhone;
+
+    /**
+     * 司机身份证
+     */
+    private String driverIdCard;
+
+    /**
+     * 支付凭证
+     */
+    private String payTicket;
+
+    /**
+     * 预计进边境日期
+     */
+    private String expectInDay;
+
+    /**
+     * 实际进边境日期
+     */
+    private Date realInDay;
+
+    /**
+     * 实际进境时间
+     */
+    private Date realInTime;
+    /**
+     * 入场通道
+     */
+    private String inChannel;
+
+
+    /**
+     * 支付状态(1=未支付,2=已支付,3=运营人员确认支付)
+     */
+    private Integer payStatus = 1;
+
+    /**
+     * 支付时间
+     */
+    private Date payTime;
+
+    /**
+     * 支付方式(1=线下支付,2现金支付,3=第三方支付)
+     */
+    private Integer payType = 1;
+    private String payBy;
+
+    /**
+     * 离境时间
+     */
+    private Date outDayTime;
+    /**
+     * 出场通道
+     */
+    private String outChannel;
+
+
+    /**
+     * 停车费用
+     */
+    private BigDecimal partMoney=new BigDecimal(0);
+
+    private BigDecimal chinaPartMoney=new BigDecimal(0);
+
+    /**
+     * 停车时常(分)
+     */
+    private Long partTime;
+    private Long chinaCarPartTime;
+    private BigDecimal itemPrice=new BigDecimal(0);
+    private BigDecimal totalMoney=new BigDecimal(0);
+    private Date createTime;
+    private String createBy;
+    private Integer confirmInput;
+    private Date confirmInputTime;
+    private String confirmInputBy;
+
+
+    private Integer adminConfirmPay;
+    private Date adminConfirmPayTime;
+    private String adminConfirmPayBy;
+    private int adminConfirmOut=0;
+    private int adminConfirmIn=0;
+    //结账方式(1=现结,2=月结)[j]
+    private int customerType;
+    private String chinaCarNo;
+    private String chinaCarInChannel;
+    private String chinaCarOutChannel;
+    private Date chinaCarInTime;
+    private Date chinaCarOutTime;
+    /**
+     * 是否完成 0 1
+     */
+    private Integer complete=0;
+    private transient String itemJson;
+    private transient String peopleJson;
+    @TableField(exist = false)
+    private List<TbBusinessItem> items = new ArrayList<>();
+
+
+
+    public void setCardNo(String cardNo) {
+        this.cardNo = cardNo.toUpperCase().trim();
+    }
+
+
+    public void setChinaCarNo(String chinaCarNo) {
+        this.chinaCarNo = chinaCarNo.toUpperCase().trim();
+    }
+}

+ 295 - 0
sp-com/business/src/main/java/com/pj/project/tb_business/TbBusinessController.java

@@ -0,0 +1,295 @@
+package com.pj.project.tb_business;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.pj.constants.UserTypeEnum;
+import com.pj.current.satoken.StpUserUtil;
+import com.pj.project.tb_business_item.TbBusinessItem;
+import com.pj.project.tb_business_item.TbBusinessItemService;
+import com.pj.project.tb_notices.TbNoticesService;
+import com.pj.project.tb_pass_record.TbPassRecordService;
+import com.pj.project4sp.SP;
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * Controller: tb_business -- 入境登记
+ *
+ * @author qzy
+ */
+@RestController
+@RequestMapping("/TbBusiness/")
+public class TbBusinessController {
+
+    /**
+     * 底层 Service 对象
+     */
+    @Autowired
+    TbBusinessService tbBusinessService;
+    @Resource
+    private TbBusinessItemService tbBusinessItemService;
+    @Resource
+    private TbPassRecordService tbPassRecordService;
+    @Resource
+    private TbNoticesService tbNoticesService;
+
+
+    @RequestMapping(value = "getMsg")
+    public AjaxJson getMsg(){
+        return AjaxJson.getSuccessData(BusinessMessageManager.get(StpUserUtil.getCustomerId()));
+    }
+
+    /**
+     * 增
+     */
+    @RequestMapping("add")
+    @SaCheckPermission(TbBusiness.PERMISSION_CODE)
+    @Transactional(rollbackFor = Exception.class)
+    public AjaxJson add(TbBusiness t) {
+        return tbBusinessService.addOrUpdate(t);
+    }
+
+    /**
+     * 删
+     */
+    @RequestMapping("delete")
+    @SaCheckPermission(TbBusiness.PERMISSION_INPUT)
+    @Transactional(rollbackFor = Exception.class)
+    public AjaxJson delete(String id) {
+      TbBusiness db=  tbBusinessService.getById(id);
+      if (db!=null){
+          tbBusinessService.storeMsg(db.getCustomerId(),"业务订单【"+db.getNo()+"】已删除。"+ DateUtil.now()+"。");
+      }
+        tbBusinessService.removeById(id);
+        tbBusinessItemService.removeByBusinessId(id);
+        tbPassRecordService.removeByBusinessId(id);
+        return AjaxJson.getSuccess();
+    }
+
+    /**
+     * 删 - 根据id列表
+     */
+    @RequestMapping("deleteByIds")
+    @SaCheckPermission(TbBusiness.PERMISSION_CODE)
+    @Transactional(rollbackFor = Exception.class)
+    public AjaxJson deleteByIds() {
+        List<Long> ids = SoMap.getRequestSoMap().getListByComma("ids", long.class);
+        ids.forEach(id -> {
+            tbBusinessItemService.removeByBusinessId(id + "");
+        });
+        int line = SP.publicMapper.deleteByIds(TbBusiness.TABLE_NAME, ids);
+        return AjaxJson.getByLine(line);
+    }
+
+    /**
+     * 改
+     */
+    @RequestMapping("update")
+    @SaCheckPermission(TbBusiness.PERMISSION_CODE)
+    public AjaxJson update(TbBusiness t) {
+        tbBusinessService.addOrUpdate(t);
+        return AjaxJson.getSuccess();
+    }
+
+    /**
+     * 确认业务
+     */
+    @RequestMapping("confirm")
+    @Transactional(rollbackFor = Exception.class)
+    public AjaxJson confirm() {
+        if (!StpUtil.hasPermissionAnd(TbBusiness.PERMISSION_CONFIRM) && !
+                StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            return AjaxJson.getError("无确认业务权限");
+        }
+        SoMap so = SoMap.getRequestSoMap();
+        List<String> ids = so.getListByComma("ids", String.class);
+        tbBusinessService.confirm(ids);
+        return AjaxJson.getSuccess();
+    }
+
+    /**
+     * 确认业务
+     */
+    @RequestMapping("adminConfirmPay")
+    @Transactional(rollbackFor = Exception.class)
+    public AjaxJson adminConfirmPay() {
+        if (!StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            return AjaxJson.getError("无确认支付权限");
+        }
+        SoMap so = SoMap.getRequestSoMap();
+        List<String> ids = so.getListByComma("ids", String.class);
+        String ticket = so.getString("payTicket");
+        tbBusinessService.adminConfirmPay(ids, ticket);
+        return AjaxJson.getSuccess();
+    }
+
+    /**
+     * 手动入场确认 see adminSetIn
+     */
+    @RequestMapping("adminConfirmIn")
+    @Transactional(rollbackFor = Exception.class)
+    @Deprecated
+    public AjaxJson adminConfirmIn() {
+        if (!StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            return AjaxJson.getError("无确认入场权限");
+        }
+        SoMap so = SoMap.getRequestSoMap();
+        String id = so.getString("id");
+        String inChannel = so.getString("inChannel");
+        tbBusinessService.adminConfirmIn(id, inChannel);
+        return AjaxJson.getSuccess();
+    }
+
+
+    /**
+     * 查 - 根据id
+     */
+    @RequestMapping("getById")
+    public AjaxJson getById(String id) {
+        TbBusiness t = tbBusinessService.getById(id);
+        List<TbBusinessItem> items = tbBusinessItemService.findByBusinessId(id);
+        t.setItems(items);
+        return AjaxJson.getSuccessData(t);
+    }
+
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
+    @RequestMapping("getList")
+    public AjaxJson getList() {
+        SoMap so = SoMap.getRequestSoMap();
+        String currentCustomerId = StpUserUtil.getCustomerId();
+        if (!currentCustomerId.equals(UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            so.put("customerId", currentCustomerId);
+        }
+        List<TbBusiness> list = tbBusinessService.getList(so.startPage());
+        return AjaxJson.getPageData(so.getDataCount(), list);
+    }
+
+    /**
+     * 改
+     */
+    @RequestMapping("pay")
+    public AjaxJson pay() {
+        if (!StpUtil.hasPermissionAnd("tb-business-pay") && !
+                StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            return AjaxJson.getError("无支付权限");
+        }
+        SoMap so = SoMap.getRequestSoMap();
+        String id = so.getString("id");
+        String payTicket = so.getString("payTicket");
+        tbBusinessService.pay(id, payTicket);
+        return AjaxJson.getSuccess();
+    }
+
+    @RequestMapping("adminSetIn")
+    public AjaxJson adminSetIn() {
+        if (!StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            return AjaxJson.getError("无入场权限");
+        }
+        SoMap so = SoMap.getRequestSoMap();
+        String id = so.getString("id");
+        Date inTime = so.getDateTime("realInTime");
+        Date chinaCarInTime = so.getDateTime("chinaCarInTime");
+        TbBusiness tbBusiness = tbBusinessService.getById(id);
+        tbBusiness.setChinaCarInTime(chinaCarInTime).setRealInTime(inTime).setAdminConfirmIn(1);
+        tbBusinessService.updateById(tbBusiness);
+
+        //更新境外车入场记录
+        tbPassRecordService.addOrUpdate(tbBusiness.getId(), tbBusiness.getCustomerId(), tbBusiness.getCustomerName(),
+                tbBusiness.getCardNo(), 2, tbBusiness.getRealInTime(), null, tbBusiness.getCountryName());
+        //更新中国车入场记录
+        tbPassRecordService.addOrUpdate(tbBusiness.getId(), tbBusiness.getCustomerId(), tbBusiness.getCustomerName(),
+                tbBusiness.getChinaCarNo(), 2, tbBusiness.getChinaCarInTime(), null, "中国车");
+        //发送消息
+        String text = "您的车辆已入场,业务单号["+ tbBusiness.getNo() + "]";
+        tbNoticesService.sendNotice(tbBusiness.getId(), tbBusiness.getNo(), tbBusiness.getCustomerId(), text);
+
+        return AjaxJson.getSuccess();
+    }
+
+    @RequestMapping("adminOut")
+    public AjaxJson adminOut(){
+        if (!StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            return AjaxJson.getError("无离场权限");
+        }
+        SoMap so = SoMap.getRequestSoMap();
+        String id = so.getString("id");
+       TbBusiness business= tbBusinessService.getById(id);
+       Date outTime=so.getDateTime("outDayTime");
+        if (business.getRealInTime().getTime()>outTime.getTime()) {
+            return AjaxJson.getError("离场时间须大于出场时间");
+        }
+        business.setOutDayTime(outTime);
+        tbBusinessService. calculationPartMoney("越南车",business);
+        tbBusinessService.updateById(business);
+        Date chinaCarOutTime=so.getDateTime("chinaCarOutTime");
+        if (chinaCarOutTime.getTime()<business.getChinaCarInTime().getTime()){
+            return AjaxJson.getError("离场时间须大于出场时间");
+        }
+        business.setChinaCarOutTime(chinaCarOutTime);
+        tbBusinessService. calculationPartMoney("中国车",business);
+        business.setAdminConfirmOut(1);
+        tbBusinessService.updateById(business);
+        //更新境外车出场记录
+        tbPassRecordService.addOrUpdate(business.getId(), business.getCustomerId(), business.getCustomerName(),
+                business.getCardNo(), 3,
+                business.getRealInTime(), business.getOutDayTime(), business.getCountryName());
+        //更新中国车出场记录
+        tbPassRecordService.addOrUpdate(business.getId(), business.getCustomerId(), business.getCustomerName(),
+                business.getChinaCarNo(), 3,
+                business.getChinaCarInTime(), business.getChinaCarOutTime(), "中国车");
+        tbBusinessService.storeMsg(business.getCustomerId(), "业务订单【"+business.getNo()+"】已完成作业离场"+ DateUtil.now()+"。");
+        //发送消息
+        String text = "您的车辆已离场,业务单号["+ business.getNo() + "]";
+        tbNoticesService.sendNotice(business.getId(), business.getNo(), business.getCustomerId(), text);
+        return AjaxJson.getSuccess();
+    }
+
+    @RequestMapping("calJwPartMoney")
+    public AjaxJson calJwPartMoney(TbBusiness business) {
+        if (!StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            return AjaxJson.getError("无生成账单权限");
+        }
+        tbBusinessService.calculationPartMoney("越南车", business);
+        return AjaxJson.getSuccessData(business);
+    }
+
+    @RequestMapping("calChinaPartMoney")
+    public AjaxJson calChinaPartMoney(TbBusiness business) {
+        if (!StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            return AjaxJson.getError("无生成账单权限");
+        }
+        tbBusinessService.calculationPartMoney("中国车", business);
+        return AjaxJson.getSuccessData(business);
+    }
+    @RequestMapping("complete")
+    public AjaxJson complete(TbBusiness business) {
+        if (!StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            return AjaxJson.getError("无生成账单权限");
+        }
+        business.setComplete(1);
+        tbBusinessService.updateById(business);
+        tbBusinessService.storeMsg(business.getCustomerId(), "业务订单【"+business.getNo()+"】账单已生成!"+ DateUtil.now()+"。");
+        //发送消息
+        String text = "您的账单已生成,业务单号["+ business.getNo() + "]";
+        tbNoticesService.sendNotice(business.getId(), business.getNo(), business.getCustomerId(), text);
+        return AjaxJson.getSuccessData(business);
+    }
+
+
+    // ------------------------- 前端接口 -------------------------
+
+
+}

+ 27 - 0
sp-com/business/src/main/java/com/pj/project/tb_business/TbBusinessMapper.java

@@ -0,0 +1,27 @@
+package com.pj.project.tb_business;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pj.utils.so.SoMap;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Mapper: tb_business -- 入境登记
+ * @author qzy 
+ */
+
+@Mapper
+@Repository
+public interface TbBusinessMapper extends BaseMapper <TbBusiness> {
+
+	/**
+	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+	 * @param so 参数集合 
+	 * @return 数据列表 
+	 */
+	List<TbBusiness> getList(SoMap so);
+
+
+}

+ 74 - 0
sp-com/business/src/main/java/com/pj/project/tb_business/TbBusinessMapper.xml

@@ -0,0 +1,74 @@
+<?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="com.pj.project.tb_business.TbBusinessMapper">
+
+	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+	<select id="getList" resultType="com.pj.project.tb_business.TbBusiness">
+		select * from tb_business
+		<where>
+			<if test=' this.has("id") '> and id = #{id} </if>
+			<if test=' this.has("customerId") '> and customer_id = #{customerId} </if>
+			<if test=' this.has("customerName") '> and customer_name like concat('%', #{customerName} ,'%')</if>
+			<if test=' this.has("no") '> and no = #{no} </if>
+			<if test=' this.has("cardNo") '> and card_no  like concat('%', #{cardNo} ,'%')</if>
+			<if test=' this.has("cardSize") '> and card_size = #{cardSize} </if>
+			<if test=' this.has("netWeight") '> and net_weight = #{netWeight} </if>
+			<if test=' this.has("goodsName") '> and goods_name = #{goodsName} </if>
+			<if test=' this.has("goodsCode") '> and goods_code = #{goodsCode} </if>
+			<if test=' this.has("driverName") '> and driver_name  like concat('%', #{driverName} ,'%')</if>
+			<if test=' this.has("driverId") '> and driver_id = #{driverId} </if>
+			<if test=' this.has("driverPhone") '> and driver_phone = #{driverPhone} </if>
+			<if test=' this.has("driverIdCard") '> and driver_id_card  like concat('%', #{driverIdCard} ,'%')</if>
+			<if test=' this.has("expectInDay") '> and expect_in_day = #{expectInDay} </if>
+			<if test=' this.has("realInDay") '> and real_in_day = #{realInDay} </if>
+			<if test=' this.has("realInTime") '> and real_in_time = #{realInTime} </if>
+			<if test=' this.has("payStatus") '> and pay_status = #{payStatus} </if>
+			<if test=' this.has("payTime") '> and pay_time = #{payTime} </if>
+			<if test=' this.has("payType") '> and pay_type = #{payType} </if>
+			<if test=' this.has("outDayTime") '> and out_day_time = #{outDayTime} </if>
+			<if test=' this.has("partMoney") '> and part_money = #{partMoney} </if>
+			<if test=' this.has("partTime") '> and part_time = #{partTime} </if>
+            <if test=' this.has("current") '>
+                <if test=' current == 3 '>and real_in_time is not null and out_day_time is not null</if>
+                <if test=' current == 2 '>and real_in_time is not null and out_day_time is null</if>
+                <if test=' current == 1 '>and real_in_time is null and out_day_time is null</if>
+            </if>
+		</where>
+		order by
+		<choose>
+			<when test='sortType == 1'> id desc </when>
+			<when test='sortType == 2'> customer_id desc </when>
+			<when test='sortType == 3'> customer_name desc </when>
+			<when test='sortType == 4'> no desc </when>
+			<when test='sortType == 5'> card_no desc </when>
+			<when test='sortType == 6'> card_size desc </when>
+			<when test='sortType == 7'> net_weight desc </when>
+			<when test='sortType == 8'> goods_name desc </when>
+			<when test='sortType == 9'> goods_code desc </when>
+			<when test='sortType == 10'> driver_name desc </when>
+			<when test='sortType == 11'> driver_id desc </when>
+			<when test='sortType == 12'> driver_phone desc </when>
+			<when test='sortType == 13'> driver_id_card desc </when>
+			<when test='sortType == 14'> expect_in_day desc </when>
+			<when test='sortType == 15'> real_in_day desc </when>
+			<when test='sortType == 16'> real_in_time desc </when>
+			<when test='sortType == 17'> pay_status desc </when>
+			<when test='sortType == 18'> pay_time desc </when>
+			<when test='sortType == 19'> pay_type desc </when>
+			<when test='sortType == 20'> out_day_time desc </when>
+			<when test='sortType == 21'> part_money desc </when>
+			<when test='sortType == 22'> part_time desc </when>
+			<otherwise> id desc </otherwise>
+		</choose>
+	</select>
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+</mapper>

+ 364 - 0
sp-com/business/src/main/java/com/pj/project/tb_business/TbBusinessService.java

@@ -0,0 +1,364 @@
+package com.pj.project.tb_business;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.constants.UserTypeEnum;
+import com.pj.current.config.CarConfig;
+import com.pj.current.config.PartConfig;
+import com.pj.current.satoken.StpUserUtil;
+import com.pj.project.tb_business_item.TbBusinessItem;
+import com.pj.project.tb_business_item.TbBusinessItemService;
+import com.pj.project.tb_business_people.TbBusinessPeople;
+import com.pj.project.tb_business_people.TbBusinessPeopleService;
+import com.pj.project.tb_car.TbCar;
+import com.pj.project.tb_car.TbCarService;
+import com.pj.project.tb_costomer.TbCostomer;
+import com.pj.project.tb_costomer.TbCostomerService;
+import com.pj.project.tb_driver.TbDriver;
+import com.pj.project.tb_driver.TbDriverService;
+import com.pj.project.tb_item.TbItem;
+import com.pj.project.tb_item.TbItemService;
+import com.pj.project.tb_item_type.TbItemType;
+import com.pj.project.tb_item_type.TbItemTypeService;
+import com.pj.project.tb_notices.TbNoticesService;
+import com.pj.project.tb_pass_record.TbPassRecordService;
+import com.pj.project.tb_unit.TbUnit;
+import com.pj.project.tb_unit.TbUnitService;
+import com.pj.project4sp.admin.SpAdmin;
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Service: tb_business -- 入境登记
+ *
+ * @author qzy
+ */
+@Service
+public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness> implements IService<TbBusiness> {
+
+    /**
+     * 底层 Mapper 对象
+     */
+    @Autowired
+    TbBusinessMapper tbBusinessMapper;
+    @Resource
+    private TbCarService tbCarService;
+    @Resource
+    private TbDriverService tbDriverService;
+    @Resource
+    private TbCostomerService tbCostomerService;
+
+    @Resource
+    private TbItemService tbItemService;
+    @Resource
+    private TbItemTypeService tbItemTypeService;
+    @Resource
+    private TbBusinessItemService tbBusinessItemService;
+
+    @Resource
+    TbUnitService tbUnitService;
+    @Resource
+    TbBusinessPeopleService tbBusinessPeopleService;
+    @Resource
+    private PartConfig partConfig;
+    @Resource
+    private CarConfig carConfig;
+
+    @Resource
+    private TbPassRecordService tbPassRecordService;
+    @Resource
+    private TbNoticesService tbNoticesService;
+
+
+    public TbBusiness checkCarNo(String carNo) {
+        QueryWrapper<TbBusiness> ew = new QueryWrapper<>();
+        ew.eq("card_no", carNo)
+                .eq("admin_confirm_out", 0);
+        return this.getOne(ew);
+    }
+
+    /**
+     * 增
+     */
+    public AjaxJson addOrUpdate(TbBusiness t) {
+        if (checkCarNo(t.getCardNo()) != null && StrUtil.isEmpty(t.getId())) {
+            return AjaxJson.getError("该车辆【" + t.getCardNo() + "】有未完成业务");
+        }
+        if (checkCarNo(t.getChinaCarNo()) != null && StrUtil.isEmpty(t.getId())) {
+            return AjaxJson.getError("该车辆【" + t.getChinaCarNo() + "】有未完成业务");
+        }
+        double carSize = t.getCardSize();
+        if (carSize > carConfig.getMaxLength()) {
+            return AjaxJson.getError("车辆规格不能大于" + carConfig.getMaxLength());
+        }
+        double netWeight = t.getNetWeight();
+        if (netWeight > carConfig.getMaxWeight()) {
+            return AjaxJson.getError("车辆载重不能大于" + carConfig.getMaxWeight());
+        }
+        t.setCreateBy(StpUserUtil.getAdmin().getName());
+        createCarUnit(t);
+        String customerId = t.getCustomerId();
+        TbCostomer tbCostomer = tbCostomerService.getById(customerId);
+        t.setCustomerName(tbCostomer.getName()).setCustomerType(tbCostomer.getPayType());
+        if (StrUtil.equals(customerId, UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            t.setConfirmInputBy(StpUserUtil.getAdmin().getName())
+                    .setConfirmInput(1)
+                    .setConfirmInputTime(new Date());
+        }
+        if (StrUtil.isEmpty(t.getId())) {
+            t.setCreateTime(new Date());
+            t.setNo(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")) + RandomUtil.randomNumbers(4));
+            storeMsg(t.getCustomerId(), "新增一条业务数据:【" + t.getNo() + "】" + DateUtil.now() + "。");
+        } else {
+            storeMsg(t.getCustomerId(), "业务订单:【" + t.getNo() + "】数据发生更改," + DateUtil.now() + "。");
+        }
+        List<TbBusinessItem> items = JSONUtil.toList(t.getItemJson(), TbBusinessItem.class);
+        saveOrUpdate(t);
+        createBusinessPeople(t);
+        tbBusinessItemService.removeByBusinessId(t.getId());
+        BigDecimal price = new BigDecimal(0);
+        for (TbBusinessItem item : items) {
+            Double num = NumberUtil.parseDouble(item.getNum());
+            TbItem tbItem = tbItemService.getById(item.getItemId());
+            price = price.add(NumberUtil.mul(num, tbItem.getPrice()));
+            TbItemType tbItemType = tbItemTypeService.getById(tbItem.getTypeId());
+            item.setBusinessId(t.getId()).setItemCode(tbItem.getItemCode())
+                    .setItemName(tbItem.getItemName()).setItemPrice(tbItem.getPrice())
+                    .setItemTypeId(tbItem.getTypeId()).setItemTypeName(tbItemType.getName())
+                    .setUnit(tbItem.getUnit()).setTotal(NumberUtil.mul(num, tbItem.getPrice()));
+        }
+        t.setItemPrice(price).setTotalMoney(price);
+        this.saveOrUpdate(t);
+        tbBusinessItemService.saveBatch(items);
+
+        //增加或修改一条境外车未入场记录
+        tbPassRecordService.addOrUpdate(t.getId(), t.getCustomerId(), t.getCustomerName(),
+                t.getCardNo(), 1, null, null, t.getCountryName());
+        //增加或修改一条中国车未入场记录
+        tbPassRecordService.addOrUpdate(t.getId(), t.getCustomerId(), t.getCustomerName(),
+                t.getChinaCarNo(), 1, null, null, "中国车");
+
+        return AjaxJson.getSuccess();
+    }
+
+    public void storeMsg(String businessCustomerId, String content) {
+        String currentCustomerId = StpUserUtil.getCustomerId();
+        if (StrUtil.equals(currentCustomerId, UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            BusinessMessageManager.set(businessCustomerId, content);
+        } else {
+            BusinessMessageManager.set(UserTypeEnum.PLATFORM_ADMIN.getCustomerId(), content);
+        }
+    }
+
+    private void createBusinessPeople(TbBusiness t) {
+        tbBusinessPeopleService.removeByBusinessId(t.getId());
+        List<TbBusinessPeople> peopleList = JSONUtil.toList(t.getPeopleJson(), TbBusinessPeople.class);
+        peopleList.forEach(tbBusinessPeople -> tbBusinessPeople.setBusinessId(t.getId()).setCreateTime(new Date()));
+        tbBusinessPeopleService.saveBatch(peopleList);
+    }
+
+    private void createCarUnit(TbBusiness t) {
+        TbUnit tbUnit = tbUnitService.findByUnit(t.getCardSize());
+        if (tbUnit == null) {
+            tbUnit = new TbUnit();
+            tbUnit.setUnit(t.getCardSize() + "");
+            tbUnitService.save(tbUnit);
+        }
+    }
+
+
+    private TbDriver createDriver(TbBusiness business) {
+        TbDriver tbDriver = tbDriverService.findByIdCardNo(business.getCardNo());
+        if (tbDriver == null) {
+            tbDriver = new TbDriver();
+            tbDriver.setCreateTime(new Date()).setIdCard(business.getCardNo())
+                    .setName(business.getDriverName()).setPhone(business.getDriverPhone());
+            tbDriverService.save(tbDriver);
+        }
+        return tbDriver;
+
+    }
+
+    private TbCar createCar(TbBusiness business) {
+        String cardNo = business.getCardNo();
+        TbCar tbCar = tbCarService.findByCardNo(cardNo);
+        if (tbCar == null) {
+            tbCar = new TbCar();
+        }
+        tbCar.setCardNo(cardNo)
+                .setCardSize(business.getCardSize())
+                .setCountryName(business.getCountryName())
+                .setLastGoodsName(business.getGoodsName())
+                .setLastNetWeight(business.getNetWeight());
+        tbCarService.saveOrUpdate(tbCar);
+        return tbCar;
+    }
+
+
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
+    public List<TbBusiness> getList(SoMap so) {
+
+        return tbBusinessMapper.getList(so);
+    }
+
+
+    public void pay(String id, String payTicket) {
+        TbBusiness tbBusiness = this.getById(id);
+        SpAdmin admin = StpUserUtil.getAdmin();
+        tbBusiness.setPayStatus(2).setPayBy(admin.getName())
+                .setPayBy(StpUserUtil.getAdmin().getName())
+                .setPayTicket(payTicket)
+                .setPayTime(new Date());
+        if (StrUtil.equals(admin.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
+            tbBusiness.setAdminConfirmPay(1).setPayStatus(3)
+                    .setAdminConfirmPayBy(admin.getName()).setAdminConfirmPayTime(new Date());
+        }
+        this.updateById(tbBusiness);
+        storeMsg(tbBusiness.getCustomerId(), "业务订单【" + tbBusiness.getNo() + "】已支付" + DateUtil.now() + "。");
+        //发送消息
+        String text = "您的费用已支付,业务单号["+ tbBusiness.getNo() + "]";
+        tbNoticesService.sendNotice(tbBusiness.getId(), tbBusiness.getNo(), tbBusiness.getCustomerId(), text);
+    }
+
+    public void confirm(List<String> ids) {
+        ids.forEach(id -> {
+            TbBusiness business = this.getById(id);
+            business.setConfirmInput(1).setConfirmInputTime(new Date()).setConfirmInputBy(StpUserUtil.getAdmin().getName());
+            this.updateById(business);
+            storeMsg(business.getCustomerId(), "业务订单【" + business.getNo() + "】已确认" + DateUtil.now() + "。");
+        });
+    }
+
+    public void adminConfirmPay(List<String> ids, String ticket) {
+        ids.forEach(id -> {
+            TbBusiness business = this.getById(id);
+            business.setAdminConfirmPayTime(new Date()).setAdminConfirmPay(1).setAdminConfirmPayBy(StpUserUtil.getAdmin().getName())
+                    .setPayStatus(3).setPayTicket(ticket);
+            this.updateById(business);
+            storeMsg(business.getCustomerId(), "业务订单【" + business.getNo() + "】已确认支付" + DateUtil.now() + "。");
+            //发送消息
+            String text = "您的费用已支付,业务单号["+ business.getNo() + "]";
+            tbNoticesService.sendNotice(business.getId(), business.getNo(), business.getCustomerId(), text);
+        });
+    }
+
+    public TbBusiness findCarTheNewRecord(String carNo, int inOrOut) {
+        QueryWrapper<TbBusiness> ew = new QueryWrapper<>();
+        ew.eq("card_no", carNo);
+        if (inOrOut == 1) {
+            ew.eq("admin_confirm_in", 0).isNull("in_channel");
+        } else {
+            ew.eq("admin_confirm_out", 0).isNull("out_channel").isNotNull("real_in_time");
+        }
+        return getOne(ew);
+    }
+
+    @Deprecated
+    public void adminConfirmIn(String id, String inChannel) {
+        TbBusiness tbBusiness = this.getById(id);
+        tbBusiness.setRealInTime(new Date()).setInChannel(inChannel);
+        this.updateById(tbBusiness);
+
+        //更新境外车入场记录
+        tbPassRecordService.addOrUpdate(tbBusiness.getId(), tbBusiness.getCustomerId(), tbBusiness.getCustomerName(),
+                tbBusiness.getCardNo(), 2, tbBusiness.getRealInTime(), null, tbBusiness.getCountryName());
+        //更新中国车入场记录
+        tbPassRecordService.addOrUpdate(tbBusiness.getId(), tbBusiness.getCustomerId(), tbBusiness.getCustomerName(),
+                tbBusiness.getChinaCarNo(), 2, tbBusiness.getChinaCarInTime(), null, "中国车");
+        //发送消息
+        String text = "您的车辆已入场,业务单号["+ tbBusiness.getNo() + "]";
+        tbNoticesService.sendNotice(tbBusiness.getId(), tbBusiness.getNo(), tbBusiness.getCustomerId(), text);
+
+    }
+
+    public void adminOut(String id, Date outDayTime, String outChannel, String carType) {
+        TbBusiness tbBusiness = this.getById(id);
+        tbBusiness.setOutDayTime(outDayTime).setOutChannel(outChannel);
+        calculationPartMoney(carType, tbBusiness);
+        this.updateById(tbBusiness);
+
+        //更新境外车出场记录
+        tbPassRecordService.addOrUpdate(tbBusiness.getId(), tbBusiness.getCustomerId(), tbBusiness.getCustomerName(),
+                tbBusiness.getCardNo(), 3,
+                tbBusiness.getRealInTime(), tbBusiness.getOutDayTime(), tbBusiness.getCountryName());
+        //更新中国车出场记录
+        tbPassRecordService.addOrUpdate(tbBusiness.getId(), tbBusiness.getCustomerId(), tbBusiness.getCustomerName(),
+                tbBusiness.getChinaCarNo(), 3,
+                tbBusiness.getChinaCarInTime(), tbBusiness.getChinaCarOutTime(), "中国车");
+        //发送消息
+        String text = "您的车辆已离场,业务单号["+ tbBusiness.getNo() + "]";
+        tbNoticesService.sendNotice(tbBusiness.getId(), tbBusiness.getNo(), tbBusiness.getCustomerId(), text);
+
+    }
+
+    @Async
+    public void calculationPartMoney(String itemType, TbBusiness tbBusiness) {
+        Date iTime = tbBusiness.getRealInTime();
+        Date oTime = tbBusiness.getOutDayTime();
+        if (itemType.contains("中国")) {
+            iTime = tbBusiness.getChinaCarInTime();
+            oTime = tbBusiness.getChinaCarOutTime();
+        }
+        LocalDateTime inDayTime = iTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+        LocalDateTime outDayTime = oTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+        long minutes = ChronoUnit.MINUTES.between(inDayTime, outDayTime);
+        if (minutes < 0) {
+            return;
+        }
+        double carSize = tbBusiness.getCardSize();
+        if (carSize < partConfig.getFreeCarLength() || minutes <= partConfig.getFreeMinutes()) {
+            return;
+        }
+        long days = ChronoUnit.DAYS.between(inDayTime.toLocalDate(), outDayTime.toLocalDate());
+        long hour = ChronoUnit.HOURS.between(inDayTime, outDayTime);
+        BigDecimal basePrice = partConfig.getBasePrice();
+        BigDecimal extraPrice = partConfig.getExtraPrice();
+        BigDecimal price = basePrice.add(basePrice.multiply(new BigDecimal(hour / 24))).add(new BigDecimal(days).multiply(extraPrice));
+        if (itemType.contains("中国")) {
+            tbBusiness.setChinaPartMoney(price).setChinaCarPartTime(minutes);
+        } else {
+            tbBusiness.setPartMoney(price).setPartTime(minutes);
+        }
+        tbBusiness.setTotalMoney(tbBusiness.getItemPrice().add(tbBusiness.getChinaPartMoney()).add(tbBusiness.getPartMoney()));
+    }
+
+    /**
+     * @param carNo
+     * @param inOrOut 1入 2出
+     * @return
+     */
+    public TbBusiness findByChinaCarNo(String carNo, int inOrOut) {
+        QueryWrapper<TbBusiness> ew = new QueryWrapper<>();
+        ew.eq("china_car_no", carNo);
+        if (inOrOut == 1) {
+            ew.eq("admin_confirm_in", 0).isNull("china_car_in_channel");
+        } else {
+            ew.eq("admin_confirm_out", 0)
+                    .isNull("china_car_out_channel")
+                    .isNotNull("china_car_in_time");
+        }
+        return this.getOne(ew);
+    }
+
+
+}

+ 97 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItem.java

@@ -0,0 +1,97 @@
+package com.pj.project.tb_business_item;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * Model: tb_business_item -- 业务作业项
+ * @author qzy 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(TbBusinessItem.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class TbBusinessItem extends Model<TbBusinessItem> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "tb_business_item";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "tb-business-item";	
+
+
+	// ---------- 表中字段 ----------
+	/**
+	 * 主键 
+	 */
+	private String id;
+
+	/**
+	 * 等级表id 
+	 */
+	private String businessId;
+
+	/**
+	 * 项目编号 
+	 */
+	private String itemCode;
+	private String itemId;
+
+	/**
+	 * 项目金额(元) 
+	 */
+	private BigDecimal itemPrice;
+
+	/**
+	 * 项目名称 
+	 */
+	private String itemName;	
+
+	/**
+	 * 状态(1=未完成,2=已完成) 
+	 */
+	private int status;
+
+	/**
+	 * 操作时间 
+	 */
+	private Date operateTime;
+
+	private String itemTypeId;
+
+	private String itemTypeName;
+
+	/**
+	 * 操作人员 
+	 */
+	private String operaror;
+	/**
+	 * 数量
+	 */
+	private String num;
+	private String unit;
+	private BigDecimal total;
+	private String ticket;
+
+
+
+
+	
+
+
+}

+ 53 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItemController.java

@@ -0,0 +1,53 @@
+package com.pj.project.tb_business_item;
+
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * Controller: tb_business_item -- 业务作业项
+ * @author qzy 
+ */
+@RestController
+@RequestMapping("/TbBusinessItem/")
+public class TbBusinessItemController {
+
+	/** 底层 Service 对象 */
+	@Autowired
+    TbBusinessItemService tbBusinessItemService;
+
+	/** 改 */  
+	@RequestMapping("update")
+	public AjaxJson update(TbBusinessItem t){
+		tbBusinessItemService.updateById(t);
+		return AjaxJson.getSuccess();
+	}
+
+	/** 查 - 根据id */  
+	@RequestMapping("getById")
+	public AjaxJson getById(String id){
+		TbBusinessItem t = tbBusinessItemService.getById(id);
+		return AjaxJson.getSuccessData(t);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	@RequestMapping("getList")
+	public AjaxJson getList() {
+		SoMap so = SoMap.getRequestSoMap();
+		List<TbBusinessItem> list = tbBusinessItemService.getList(so.startPage());
+		return AjaxJson.getPageData(so.getDataCount(), list);
+	}
+	
+
+	
+	
+	
+	
+	
+
+}

+ 50 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItemMapper.java

@@ -0,0 +1,50 @@
+package com.pj.project.tb_business_item;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pj.utils.so.SoMap;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Mapper: tb_business_item -- 业务作业项
+ * @author qzy 
+ */
+
+@Mapper
+@Repository
+public interface TbBusinessItemMapper extends BaseMapper <TbBusinessItem> {
+
+	/**
+	 * 增  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int add(TbBusinessItem t);
+
+
+
+	/** 
+	 * 改  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int update(TbBusinessItem t);
+
+	/** 
+	 * 查 - 根据id  
+	 * @param id 要查询的数据id 
+	 * @return 实体对象 
+	 */
+	TbBusinessItem getById(String id);	 
+
+	/**
+	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+	 * @param so 参数集合 
+	 * @return 数据列表 
+	 */
+	List<TbBusinessItem> getList(SoMap so);
+
+
+}

+ 92 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItemMapper.xml

@@ -0,0 +1,92 @@
+<?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="com.pj.project.tb_business_item.TbBusinessItemMapper">
+
+	<!-- 增 [G] -->
+	<insert id="add">
+		insert into 
+		tb_business_item (id, business_id, item_code, item_price, item_name, status, operate_time, operaror) 
+		values (#{id}, #{businessId}, #{itemCode}, #{itemPrice}, #{itemName}, #{status}, #{operateTime}, #{operaror}) 
+	</insert>
+
+
+
+	<!-- 改 [G] -->
+	<update id="update">
+		update tb_business_item set
+		id = #{id}, 
+		business_id = #{businessId}, 
+		item_code = #{itemCode}, 
+		item_price = #{itemPrice}, 
+		item_name = #{itemName}, 
+		status = #{status}, 
+		operate_time = #{operateTime}, 
+		operaror = #{operaror}
+		where id = #{id}
+	</update>
+
+
+	<!-- ================================== 查询相关 ================================== -->
+
+	
+	<!-- 通用映射:手动模式 -->
+	<resultMap id="model" type="com.pj.project.tb_business_item.TbBusinessItem">
+		<result property="id" column="id" />
+		<result property="businessId" column="business_id" />
+		<result property="itemCode" column="item_code" />
+		<result property="itemPrice" column="item_price" />
+		<result property="itemName" column="item_name" />
+		<result property="status" column="status" />
+		<result property="operateTime" column="operate_time" />
+		<result property="operaror" column="operaror" />
+	</resultMap>
+	
+	<!-- 公共查询sql片段 -->
+	<sql id="select_sql">
+		select *
+		from tb_business_item 
+	</sql>
+	
+	<!-- 查 - 根据id -->
+	<select id="getById" resultMap="model">
+		<include refid="select_sql"></include>
+		where id = #{id}
+	</select>
+	
+	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+	<select id="getList" resultMap="model">
+		<include refid="select_sql"></include>
+		<where>
+			<if test=' this.has("id") '> and id = #{id} </if>
+			<if test=' this.has("businessId") '> and business_id = #{businessId} </if>
+			<if test=' this.has("itemCode") '> and item_code = #{itemCode} </if>
+			<if test=' this.has("itemPrice") '> and item_price = #{itemPrice} </if>
+			<if test=' this.has("itemName") '> and item_name = #{itemName} </if>
+			<if test=' this.has("status") '> and status = #{status} </if>
+			<if test=' this.has("operateTime") '> and operate_time = #{operateTime} </if>
+			<if test=' this.has("operaror") '> and operaror = #{operaror} </if>
+		</where>
+		order by
+		<choose>
+			<when test='sortType == 1'> id desc </when>
+			<when test='sortType == 2'> business_id desc </when>
+			<when test='sortType == 3'> item_code desc </when>
+			<when test='sortType == 4'> item_price desc </when>
+			<when test='sortType == 5'> item_name desc </when>
+			<when test='sortType == 6'> status desc </when>
+			<when test='sortType == 7'> operate_time desc </when>
+			<when test='sortType == 8'> operaror desc </when>
+			<otherwise> id desc </otherwise>
+		</choose>
+	</select>
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+</mapper>

+ 66 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_item/TbBusinessItemService.java

@@ -0,0 +1,66 @@
+package com.pj.project.tb_business_item;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * Service: tb_business_item -- 业务作业项
+ * @author qzy 
+ */
+@Service
+@Transactional
+public class TbBusinessItemService extends ServiceImpl<TbBusinessItemMapper,TbBusinessItem> implements IService<TbBusinessItem> {
+
+	/** 底层 Mapper 对象 */
+	@Autowired
+    TbBusinessItemMapper tbBusinessItemMapper;
+
+	/** 增 */
+	int add(TbBusinessItem t){
+		return tbBusinessItemMapper.add(t);
+	}
+
+
+
+	/** 改 */
+	int update(TbBusinessItem t){
+		return tbBusinessItemMapper.update(t);
+	}
+
+	/** 查 */
+	TbBusinessItem getById(String id){
+		return tbBusinessItemMapper.getById(id);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	List<TbBusinessItem> getList(SoMap so) {
+		return tbBusinessItemMapper.getList(so);	
+	}
+
+
+	public void removeByBusinessId(String businessId) {
+		QueryWrapper<TbBusinessItem>ew=new QueryWrapper<>();
+		ew.eq("business_id",businessId);
+		this.remove(ew);
+	}
+
+    public List<TbBusinessItem> findByBusinessId(String businessId) {
+		QueryWrapper<TbBusinessItem>ew=new QueryWrapper<>();
+		ew.eq("business_id",businessId);
+		return list(ew);
+    }
+
+	public TbBusinessItem findByBusinessIdAndTypeName(String businessId, String itemTypeName) {
+		QueryWrapper<TbBusinessItem>ew=new QueryWrapper<>();
+		ew.eq("business_id",businessId);
+		ew.eq("item_type_name",itemTypeName);
+		return getOne(ew);
+	}
+}

+ 70 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeople.java

@@ -0,0 +1,70 @@
+package com.pj.project.tb_business_people;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Model: tb_business_people -- 核酸检测人员
+ * @author qzy 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(TbBusinessPeople.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class TbBusinessPeople extends Model<TbBusinessPeople> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "tb_business_people";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "tb-business-people";	
+
+
+	// ---------- 表中字段 ----------
+	/**
+	 *  
+	 */
+	private String id;
+
+	/**
+	 *  
+	 */
+	private String name;	
+
+	/**
+	 *  
+	 */
+	private String phone;	
+
+	/**
+	 *  
+	 */
+	private String businessId;
+
+	/**
+	 *  
+	 */
+	private Date createTime;
+
+
+
+
+
+	
+
+
+}

+ 99 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeopleController.java

@@ -0,0 +1,99 @@
+package com.pj.project.tb_business_people;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.pj.current.satoken.StpUserUtil;
+import com.pj.project4sp.SP;
+import com.pj.utils.sg.AjaxError;
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * Controller: tb_business_people -- 核酸检测人员
+ * @author qzy 
+ */
+@RestController
+@RequestMapping("/TbBusinessPeople/")
+public class TbBusinessPeopleController {
+
+	/** 底层 Service 对象 */
+	@Autowired
+	TbBusinessPeopleService tbBusinessPeopleService;
+
+	/** 增 */
+	@RequestMapping("deleteById")
+	@Transactional(rollbackFor = Exception.class)
+	public AjaxJson deleteById(){
+		SoMap so = SoMap.getRequestSoMap();
+		String id=so.getString("id");
+		tbBusinessPeopleService.removeById(id);
+		return AjaxJson.getSuccess();
+	}
+
+
+
+	/** 删 - 根据id列表 */
+	@RequestMapping("deleteByIds")
+	@SaCheckPermission(TbBusinessPeople.PERMISSION_CODE)
+	public AjaxJson deleteByIds(){
+		List<Long> ids = SoMap.getRequestSoMap().getListByComma("ids", long.class);
+		int line = SP.publicMapper.deleteByIds(TbBusinessPeople.TABLE_NAME, ids);
+		return AjaxJson.getByLine(line);
+	}
+
+	/** 改 */
+	@RequestMapping("update")
+	@SaCheckPermission(TbBusinessPeople.PERMISSION_CODE)
+	public AjaxJson update(TbBusinessPeople t){
+		int line = tbBusinessPeopleService.update(t);
+		return AjaxJson.getByLine(line);
+	}
+
+	/** 查 - 根据id */
+	@RequestMapping("getById")
+	public AjaxJson getById(Long id){
+		TbBusinessPeople t = tbBusinessPeopleService.getById(id);
+		return AjaxJson.getSuccessData(t);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */
+	@RequestMapping("getList")
+	public AjaxJson getList() {
+		SoMap so = SoMap.getRequestSoMap();
+		List<TbBusinessPeople> list = tbBusinessPeopleService.getList(so.startPage());
+		return AjaxJson.getPageData(so.getDataCount(), list);
+	}
+
+
+
+
+	// ------------------------- 前端接口 -------------------------
+
+
+	/** 改 - 不传不改 [G] */
+	@RequestMapping("updateByNotNull")
+	public AjaxJson updateByNotNull(Long id){
+		AjaxError.throwBy(true, "如需正常调用此接口,请删除此行代码");
+		// 鉴别身份,是否为数据创建者
+		long userId = SP.publicMapper.getColumnByIdToLong(TbBusinessPeople.TABLE_NAME, "user_id", id);
+		AjaxError.throwBy(userId != StpUserUtil.getLoginIdAsLong(), "此数据您无权限修改");
+		// 开始修改 (请只保留需要修改的字段)
+		SoMap so = SoMap.getRequestSoMap();
+		so.clearNotIn("id", "name", "phone", "businessId", "createTime").clearNull().humpToLineCase();
+		int line = SP.publicMapper.updateBySoMapById(TbBusinessPeople.TABLE_NAME, so, id);
+		return AjaxJson.getByLine(line);
+	}
+	
+	
+	
+	
+	
+	
+
+}

+ 49 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeopleMapper.java

@@ -0,0 +1,49 @@
+package com.pj.project.tb_business_people;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pj.utils.so.SoMap;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Mapper: tb_business_people -- 核酸检测人员
+ * @author qzy 
+ */
+
+@Mapper
+@Repository
+public interface TbBusinessPeopleMapper extends BaseMapper <TbBusinessPeople> {
+
+	/**
+	 * 增  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int add(TbBusinessPeople t);
+
+
+	/** 
+	 * 改  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int update(TbBusinessPeople t);
+
+	/** 
+	 * 查 - 根据id  
+	 * @param id 要查询的数据id 
+	 * @return 实体对象 
+	 */
+	TbBusinessPeople getById(Long id);	 
+
+	/**
+	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+	 * @param so 参数集合 
+	 * @return 数据列表 
+	 */
+	List<TbBusinessPeople> getList(SoMap so);
+
+
+}

+ 79 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeopleMapper.xml

@@ -0,0 +1,79 @@
+<?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="com.pj.project.tb_business_people.TbBusinessPeopleMapper">
+
+	<!-- 增 [G] -->
+	<insert id="add">
+		insert into 
+		tb_business_people (id, name, phone, business_id, create_time) 
+		values (#{id}, #{name}, #{phone}, #{businessId}, #{createTime}) 
+	</insert>
+
+
+	<!-- 改 [G] -->
+	<update id="update">
+		update tb_business_people set
+		id = #{id}, 
+		name = #{name}, 
+		phone = #{phone}, 
+		business_id = #{businessId}, 
+		create_time = #{createTime}
+		where id = #{id}
+	</update>
+
+
+	<!-- ================================== 查询相关 ================================== -->
+	<!-- select id, name, phone, business_id, create_time from tb_business_people  -->
+	
+	<!-- 通用映射:手动模式 -->
+	<resultMap id="model" type="com.pj.project.tb_business_people.TbBusinessPeople">
+		<result property="id" column="id" />
+		<result property="name" column="name" />
+		<result property="phone" column="phone" />
+		<result property="businessId" column="business_id" />
+		<result property="createTime" column="create_time" />
+	</resultMap>
+	
+	<!-- 公共查询sql片段 -->
+	<sql id="select_sql">
+		select * 
+		from tb_business_people 
+	</sql>
+	
+	<!-- 查 - 根据id -->
+	<select id="getById" resultMap="model">
+		<include refid="select_sql"></include>
+		where id = #{id}
+	</select>
+	
+	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+	<select id="getList" resultMap="model">
+		<include refid="select_sql"></include>
+		<where>
+			<if test=' this.has("id") '> and id = #{id} </if>
+			<if test=' this.has("name") '> and name = #{name} </if>
+			<if test=' this.has("phone") '> and phone = #{phone} </if>
+			<if test=' this.has("businessId") '> and business_id = #{businessId} </if>
+			<if test=' this.has("createTime") '> and create_time = #{createTime} </if>
+		</where>
+		order by
+		<choose>
+			<when test='sortType == 1'> id desc </when>
+			<when test='sortType == 2'> name desc </when>
+			<when test='sortType == 3'> phone desc </when>
+			<when test='sortType == 4'> business_id desc </when>
+			<when test='sortType == 5'> create_time desc </when>
+			<otherwise> id desc </otherwise>
+		</choose>
+	</select>
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+</mapper>

+ 51 - 0
sp-com/business/src/main/java/com/pj/project/tb_business_people/TbBusinessPeopleService.java

@@ -0,0 +1,51 @@
+package com.pj.project.tb_business_people;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Service: tb_business_people -- 核酸检测人员
+ * @author qzy 
+ */
+@Service
+public class TbBusinessPeopleService extends ServiceImpl<TbBusinessPeopleMapper, TbBusinessPeople>  implements IService<TbBusinessPeople> {
+
+	/** 底层 Mapper 对象 */
+	@Autowired
+    TbBusinessPeopleMapper tbBusinessPeopleMapper;
+
+	/** 增 */
+	int add(TbBusinessPeople t){
+		return tbBusinessPeopleMapper.add(t);
+	}
+
+
+
+	/** 改 */
+	int update(TbBusinessPeople t){
+		return tbBusinessPeopleMapper.update(t);
+	}
+
+	/** 查 */
+	TbBusinessPeople getById(Long id){
+		return tbBusinessPeopleMapper.getById(id);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	List<TbBusinessPeople> getList(SoMap so) {
+		return tbBusinessPeopleMapper.getList(so);	
+	}
+
+
+	public void removeByBusinessId(String businessId) {
+		QueryWrapper<TbBusinessPeople>ew=new QueryWrapper<>();
+		ew.eq("business_id",businessId);
+		this.remove(ew);
+	}
+}

+ 92 - 0
sp-com/business/src/main/java/com/pj/project/tb_car/TbCar.java

@@ -0,0 +1,92 @@
+package com.pj.project.tb_car;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Model: tb_car -- 
+ * @author qzy 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(TbCar.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class TbCar extends Model<TbCar> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "tb_car";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "tb-car";	
+
+
+	// ---------- 表中字段 ----------
+	/**
+	 * 主键 
+	 */
+	private String id;
+
+	/**
+	 * 名称 
+	 */
+	private String cardNo;
+
+
+	/**
+	 * 规格 
+	 */
+	private Double cardSize;
+	private String countryName;
+
+	/**
+	 * 最后一次运输商品 
+	 */
+	private String lastGoodsName;	
+
+	/**
+	 * 最后一次运输商品编号 
+	 */
+	private String lastGoodsCode;	
+
+	/**
+	 * 最后一次载重 
+	 */
+	private Double lastNetWeight;	
+
+	/**
+	 * 最后一次入境时间 
+	 */
+	private Date lastInTime;
+
+	/**
+	 * 最后一次出境时间 
+	 */
+	private Date lastOutTime;
+
+	/**
+	 * 当前状态(1=境外,2=境内) 
+	 */
+	private int status;
+
+
+
+
+
+	
+
+
+}

+ 105 - 0
sp-com/business/src/main/java/com/pj/project/tb_car/TbCarController.java

@@ -0,0 +1,105 @@
+package com.pj.project.tb_car;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.pj.current.satoken.StpUserUtil;
+import com.pj.project4sp.SP;
+import com.pj.utils.sg.AjaxError;
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * Controller: tb_car -- 
+ * @author qzy 
+ */
+@RestController
+@RequestMapping("/TbCar/")
+public class TbCarController {
+
+	/** 底层 Service 对象 */
+	@Autowired
+	TbCarService tbCarService;
+
+	/** 增 */  
+	@RequestMapping("add")
+	@SaCheckPermission(TbCar.PERMISSION_CODE)
+	@Transactional(rollbackFor = Exception.class)
+	public AjaxJson add(TbCar t){
+		tbCarService.add(t);
+		t = tbCarService.getById(SP.publicMapper.getPrimarykey());
+		return AjaxJson.getSuccessData(t);
+	}
+
+	/** 删 */  
+	@RequestMapping("delete")
+	@SaCheckPermission(TbCar.PERMISSION_CODE)
+	public AjaxJson delete(Long id){
+		int line = tbCarService.delete(id);
+		return AjaxJson.getByLine(line);
+	}
+	
+	/** 删 - 根据id列表 */  
+	@RequestMapping("deleteByIds")
+	@SaCheckPermission(TbCar.PERMISSION_CODE)
+	public AjaxJson deleteByIds(){
+		List<Long> ids = SoMap.getRequestSoMap().getListByComma("ids", long.class);
+		int line = SP.publicMapper.deleteByIds(TbCar.TABLE_NAME, ids);
+		return AjaxJson.getByLine(line);
+	}
+	
+	/** 改 */  
+	@RequestMapping("update")
+	@SaCheckPermission(TbCar.PERMISSION_CODE)
+	public AjaxJson update(TbCar t){
+		int line = tbCarService.update(t);
+		return AjaxJson.getByLine(line);
+	}
+
+	/** 查 - 根据id */  
+	@RequestMapping("getById")
+	public AjaxJson getById(Long id){
+		TbCar t = tbCarService.getById(id);
+		return AjaxJson.getSuccessData(t);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	@RequestMapping("getList")
+	public AjaxJson getList() {
+		SoMap so = SoMap.getRequestSoMap();
+		List<TbCar> list = tbCarService.getList(so.startPage());
+		return AjaxJson.getPageData(so.getDataCount(), list);
+	}
+	
+	
+	
+	
+	// ------------------------- 前端接口 -------------------------
+	
+	
+	/** 改 - 不传不改 [G] */
+	@RequestMapping("updateByNotNull")
+	public AjaxJson updateByNotNull(Long id){
+		AjaxError.throwBy(true, "如需正常调用此接口,请删除此行代码");
+		// 鉴别身份,是否为数据创建者 
+		long userId = SP.publicMapper.getColumnByIdToLong(TbCar.TABLE_NAME, "user_id", id);
+		AjaxError.throwBy(userId != StpUserUtil.getLoginIdAsLong(), "此数据您无权限修改");
+		// 开始修改 (请只保留需要修改的字段)
+		SoMap so = SoMap.getRequestSoMap();
+		so.clearNotIn("id", "cardNo", "cardSize", "lastGoodsName", "lastGoodsCode", "lastNetWeight", "lastInTime", "lastOutTime", "status").clearNull().humpToLineCase();	
+		int line = SP.publicMapper.updateBySoMapById(TbCar.TABLE_NAME, so, id);
+		return AjaxJson.getByLine(line);
+	}
+	
+	
+	
+	
+	
+	
+
+}

+ 55 - 0
sp-com/business/src/main/java/com/pj/project/tb_car/TbCarMapper.java

@@ -0,0 +1,55 @@
+package com.pj.project.tb_car;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pj.utils.so.SoMap;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Mapper: tb_car -- 
+ * @author qzy 
+ */
+
+@Mapper
+@Repository
+public interface TbCarMapper extends BaseMapper <TbCar> {
+
+	/**
+	 * 增  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int add(TbCar t);
+
+	/**
+	 * 删  
+	 * @param id 要删除的数据id  
+	 * @return 受影响行数 
+	 */
+	int delete(Long id);	 
+
+	/** 
+	 * 改  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int update(TbCar t);
+
+	/** 
+	 * 查 - 根据id  
+	 * @param id 要查询的数据id 
+	 * @return 实体对象 
+	 */
+	TbCar getById(Long id);
+
+	/**
+	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+	 * @param so 参数集合 
+	 * @return 数据列表 
+	 */
+	List<TbCar> getList(SoMap so);
+
+
+}

+ 100 - 0
sp-com/business/src/main/java/com/pj/project/tb_car/TbCarMapper.xml

@@ -0,0 +1,100 @@
+<?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="com.pj.project.tb_car.TbCarMapper">
+
+	<!-- 增 [G] -->
+	<insert id="add">
+		insert into 
+		tb_car (id, card_no, card_size, last_goods_name, last_goods_code, last_net_weight, last_in_time, last_out_time, status) 
+		values (#{id}, #{cardNo}, #{cardSize}, #{lastGoodsName}, #{lastGoodsCode}, #{lastNetWeight}, #{lastInTime}, #{lastOutTime}, #{status}) 
+	</insert>
+
+	<!-- 删 -->
+	<delete id="delete">
+		delete from tb_car 
+		where id = #{id}
+	</delete>
+
+	<!-- 改 [G] -->
+	<update id="update">
+		update tb_car set
+		id = #{id}, 
+		card_no = #{cardNo}, 
+		card_size = #{cardSize}, 
+		last_goods_name = #{lastGoodsName}, 
+		last_goods_code = #{lastGoodsCode}, 
+		last_net_weight = #{lastNetWeight}, 
+		last_in_time = #{lastInTime}, 
+		last_out_time = #{lastOutTime}, 
+		status = #{status}
+		where id = #{id}
+	</update>
+
+
+	<!-- ================================== 查询相关 ================================== -->
+
+	
+	<!-- 通用映射:手动模式 -->
+	<resultMap id="model" type="com.pj.project.tb_car.TbCar">
+		<result property="id" column="id" />
+		<result property="cardNo" column="card_no" />
+		<result property="cardSize" column="card_size" />
+		<result property="lastGoodsName" column="last_goods_name" />
+		<result property="lastGoodsCode" column="last_goods_code" />
+		<result property="lastNetWeight" column="last_net_weight" />
+		<result property="lastInTime" column="last_in_time" />
+		<result property="lastOutTime" column="last_out_time" />
+		<result property="status" column="status" />
+	</resultMap>
+	
+	<!-- 公共查询sql片段 -->
+	<sql id="select_sql">
+		select *
+		from tb_car 
+	</sql>
+	
+	<!-- 查 - 根据id -->
+	<select id="getById" resultMap="model">
+		<include refid="select_sql"></include>
+		where id = #{id}
+	</select>
+	
+	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+	<select id="getList" resultMap="model">
+		<include refid="select_sql"></include>
+		<where>
+			<if test=' this.has("id") '> and id = #{id} </if>
+			<if test=' this.has("cardNo") '> and card_no = #{cardNo} </if>
+			<if test=' this.has("cardSize") '> and card_size = #{cardSize} </if>
+			<if test=' this.has("lastGoodsName") '> and last_goods_name = #{lastGoodsName} </if>
+			<if test=' this.has("lastGoodsCode") '> and last_goods_code = #{lastGoodsCode} </if>
+			<if test=' this.has("lastNetWeight") '> and last_net_weight = #{lastNetWeight} </if>
+			<if test=' this.has("lastInTime") '> and last_in_time = #{lastInTime} </if>
+			<if test=' this.has("lastOutTime") '> and last_out_time = #{lastOutTime} </if>
+			<if test=' this.has("status") '> and status = #{status} </if>
+		</where>
+		order by
+		<choose>
+			<when test='sortType == 1'> id desc </when>
+			<when test='sortType == 2'> card_no desc </when>
+			<when test='sortType == 3'> card_size desc </when>
+			<when test='sortType == 4'> last_goods_name desc </when>
+			<when test='sortType == 5'> last_goods_code desc </when>
+			<when test='sortType == 6'> last_net_weight desc </when>
+			<when test='sortType == 7'> last_in_time desc </when>
+			<when test='sortType == 8'> last_out_time desc </when>
+			<when test='sortType == 9'> status desc </when>
+			<otherwise> id desc </otherwise>
+		</choose>
+	</select>
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+</mapper>

+ 54 - 0
sp-com/business/src/main/java/com/pj/project/tb_car/TbCarService.java

@@ -0,0 +1,54 @@
+package com.pj.project.tb_car;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Service: tb_car -- 
+ * @author qzy 
+ */
+@Service
+public class TbCarService extends ServiceImpl<TbCarMapper, TbCar>implements IService<TbCar> {
+
+	/** 底层 Mapper 对象 */
+	@Autowired
+    TbCarMapper tbCarMapper;
+
+	/** 增 */
+	int add(TbCar t){
+		return tbCarMapper.add(t);
+	}
+
+	/** 删 */
+	int delete(Long id){
+		return tbCarMapper.delete(id);
+	}
+
+	/** 改 */
+	int update(TbCar t){
+		return tbCarMapper.update(t);
+	}
+
+	/** 查 */
+	TbCar getById(Long id){
+		return tbCarMapper.getById(id);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	List<TbCar> getList(SoMap so) {
+		return tbCarMapper.getList(so);	
+	}
+
+
+	public TbCar findByCardNo(String cardNo) {
+		QueryWrapper<TbCar>ew=new QueryWrapper<>();
+		ew.eq("card_no",cardNo);
+		return getOne(ew);
+	}
+}

+ 109 - 0
sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomer.java

@@ -0,0 +1,109 @@
+package com.pj.project.tb_costomer;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Model: tb_costomer -- 客户管理
+ * @author qzy 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(TbCostomer.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class TbCostomer extends Model<TbCostomer> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "tb_costomer";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "tb-costomer";
+	public static final String PERMISSION_INFO = "tb-costomer-maintain";
+
+	// ---------- 表中字段 ----------
+	/**
+	 * 主键 
+	 */
+	private String id;
+
+	/**
+	 * 名称 
+	 */
+	private String name;	
+
+	/**
+	 * 联系号码 
+	 */
+	private String phone;	
+
+	/**
+	 * 负责人 
+	 */
+	private String dutyPeople;	
+
+	/**
+	 * 地址id 
+	 */
+	private String addressIds;	
+
+	/**
+	 * 地址 
+	 */
+	private String addressStr;	
+
+	/**
+	 * 营业执照 
+	 */
+	private String businessLicence;	
+
+	/**
+	 * 状态(0=否,1=是) 
+	 */
+	private Integer status;
+
+	/**
+	 * 创建时间 
+	 */
+	private Date creareTime=null;
+
+	/**
+	 * 审核状态(1=未审核,2审核通过,3审核不通过) 
+	 */
+	private Integer judgeStatus=1;
+
+	/**
+	 * 审核时间 
+	 */
+	private Date judgeTime=null;
+
+	/**
+	 * 审核意见 
+	 */
+	private String judgeContent;
+	/**
+	 * 结账方式(1=现结,2=月结)[j]
+	 */
+	private int payType;
+
+
+
+
+
+	
+
+
+}

+ 126 - 0
sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomerController.java

@@ -0,0 +1,126 @@
+package com.pj.project.tb_costomer;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import com.pj.current.satoken.StpUserUtil;
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * Controller: tb_costomer -- 客户管理
+ * @author qzy 
+ */
+@RestController
+@RequestMapping("/TbCostomer/")
+public class TbCostomerController {
+
+	/** 底层 Service 对象 */
+	@Autowired
+	TbCostomerService tbCostomerService;
+
+	/** 增 */  
+	@RequestMapping("add")
+	@SaCheckPermission(TbCostomer.PERMISSION_CODE)
+	@Transactional(rollbackFor = Exception.class)
+	public AjaxJson add(TbCostomer t){
+		tbCostomerService.add(t);
+		return AjaxJson.getSuccessData(t);
+	}
+
+	/** 删 */  
+	@RequestMapping("delete")
+	@SaCheckPermission(TbCostomer.PERMISSION_CODE)
+	public AjaxJson delete(String id){
+		int line = tbCostomerService.delete(id);
+		return AjaxJson.getByLine(line);
+	}
+	
+	/** 删 - 根据id列表 */  
+	@RequestMapping("deleteByIds")
+	@SaCheckPermission(TbCostomer.PERMISSION_CODE)
+	public AjaxJson deleteByIds(){
+		List<Long> ids = SoMap.getRequestSoMap().getListByComma("ids", long.class);
+		ids.forEach(id->tbCostomerService.delete(id+""));
+		return AjaxJson.getByLine(1);
+	}
+	
+	/** 改 */  
+	@RequestMapping("update")
+	@SaCheckPermission(TbCostomer.PERMISSION_CODE)
+	public AjaxJson update(TbCostomer t){
+		int line = tbCostomerService.update(t);
+		return AjaxJson.getByLine(line);
+	}
+
+	/** 查 - 根据id */  
+	@RequestMapping("getById")
+	public AjaxJson getById(String id){
+		TbCostomer t = tbCostomerService.getById(id);
+		return AjaxJson.getSuccessData(t);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	@RequestMapping("getList")
+	public AjaxJson getList() {
+		SoMap so = SoMap.getRequestSoMap();
+		List<TbCostomer> list = tbCostomerService.getList(so.startPage());
+		return AjaxJson.getPageData(so.getDataCount(), list);
+	}
+
+    /** 查集合 - 客户登录时查询自己 */
+    @RequestMapping("getOwnList")
+    public AjaxJson getOwnList() {
+        SoMap so = SoMap.getRequestSoMap();
+        so.put("id", StpUserUtil.getCustomerId());
+        List<TbCostomer> list = tbCostomerService.getList(so.startPage());
+        return AjaxJson.getPageData(so.getDataCount(), list);
+    }
+
+    @RequestMapping("getAll")
+    public AjaxJson getAll(){
+        SoMap so = SoMap.getRequestSoMap();
+        so.put("status", 1);
+        so.put("judgeStatus", 2);
+        List<TbCostomer> list = tbCostomerService.getList(so);
+        return AjaxJson.getSuccessData(list);
+    }
+	
+	/** 改 - 状态(0=否,1=是) */  
+	@RequestMapping("updateStatus")
+	@SaCheckPermission(TbCostomer.PERMISSION_CODE)
+	public AjaxJson updateStatus(String id, int value){
+		tbCostomerService.updateStatus(id,value);
+
+		return AjaxJson.getByLine(1);
+	}
+
+
+	@RequestMapping("getCurrentCustomerId")
+	@SaCheckPermission(TbCostomer.PERMISSION_CODE)
+	public AjaxJson getCurrentCustomer(){
+		String id= StpUserUtil.getCustomerId();
+		return AjaxJson.getSuccessData(id);
+	}
+
+	@RequestMapping("judge")
+	@SaCheckPermission(TbCostomer.PERMISSION_CODE)
+	public AjaxJson judge(){
+		SoMap so = SoMap.getRequestSoMap();
+		tbCostomerService.judge(so.getString("id"),so.getInt("judgeStatus"),so.getString("judgeContent"));
+		return AjaxJson.getSuccess();
+	}
+
+
+	
+	
+	
+	
+	
+
+}

+ 55 - 0
sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomerMapper.java

@@ -0,0 +1,55 @@
+package com.pj.project.tb_costomer;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pj.utils.so.SoMap;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Mapper: tb_costomer -- 客户管理
+ * @author qzy 
+ */
+
+@Mapper
+@Repository
+public interface TbCostomerMapper extends BaseMapper <TbCostomer> {
+
+	/**
+	 * 增  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int add(TbCostomer t);
+
+	/**
+	 * 删  
+	 * @param id 要删除的数据id  
+	 * @return 受影响行数 
+	 */
+	int delete(String id);	 
+
+	/** 
+	 * 改  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int update(TbCostomer t);
+
+	/** 
+	 * 查 - 根据id  
+	 * @param id 要查询的数据id 
+	 * @return 实体对象 
+	 */
+	TbCostomer getById(String id);	 
+
+	/**
+	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+	 * @param so 参数集合 
+	 * @return 数据列表 
+	 */
+	List<TbCostomer> getList(SoMap so);
+
+
+}

+ 113 - 0
sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomerMapper.xml

@@ -0,0 +1,113 @@
+<?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="com.pj.project.tb_costomer.TbCostomerMapper">
+
+	<!-- 增 [G] -->
+	<insert id="add">
+		insert into 
+		tb_costomer (id, name, phone, duty_people, address_ids, address_str, business_licence, status, creare_time, judge_status, judge_time, judge_content) 
+		values (#{id}, #{name}, #{phone}, #{dutyPeople}, #{addressIds}, #{addressStr}, #{businessLicence}, #{status}, #{creareTime}, #{judgeStatus}, #{judgeTime}, #{judgeContent}) 
+	</insert>
+
+	<!-- 删 -->
+	<delete id="delete">
+		delete from tb_costomer 
+		where id = #{id}
+	</delete>
+
+	<!-- 改 [G] -->
+	<update id="update">
+		update tb_costomer set
+		id = #{id}, 
+		name = #{name}, 
+		phone = #{phone}, 
+		duty_people = #{dutyPeople}, 
+		address_ids = #{addressIds}, 
+		address_str = #{addressStr}, 
+		business_licence = #{businessLicence}, 
+		status = #{status}, 
+		creare_time = #{creareTime}, 
+		judge_status = #{judgeStatus}, 
+		judge_time = #{judgeTime}, 
+		judge_content = #{judgeContent}
+		where id = #{id}
+	</update>
+
+
+	<!-- ================================== 查询相关 ================================== -->
+
+	
+	<!-- 通用映射:手动模式 -->
+	<resultMap id="model" type="com.pj.project.tb_costomer.TbCostomer">
+		<result property="id" column="id" />
+		<result property="name" column="name" />
+		<result property="phone" column="phone" />
+		<result property="dutyPeople" column="duty_people" />
+		<result property="addressIds" column="address_ids" />
+		<result property="addressStr" column="address_str" />
+		<result property="businessLicence" column="business_licence" />
+		<result property="status" column="status" />
+		<result property="creareTime" column="creare_time" />
+		<result property="judgeStatus" column="judge_status" />
+		<result property="judgeTime" column="judge_time" />
+		<result property="judgeContent" column="judge_content" />
+	</resultMap>
+	
+	<!-- 公共查询sql片段 -->
+	<sql id="select_sql">
+		select 	*
+		from tb_costomer
+	</sql>
+	
+	<!-- 查 - 根据id -->
+	<select id="getById" resultMap="model">
+		<include refid="select_sql"></include>
+		where id = #{id}
+	</select>
+	
+	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+	<select id="getList" resultMap="model">
+		<include refid="select_sql"></include>
+		<where>
+			<if test=' this.has("id") '> and id = #{id} </if>
+			<if test=' this.has("name") '> and name like concat('%',#{name},'%')  </if>
+			<if test=' this.has("phone") '> and phone like concat('%',#{phone},'%')  </if>
+			<if test=' this.has("dutyPeople") '> and duty_people  like concat('%',#{dutyPeople},'%') </if>
+			<if test=' this.has("addressIds") '> and address_ids = #{addressIds} </if>
+			<if test=' this.has("addressStr") '> and address_str = #{addressStr} </if>
+			<if test=' this.has("status") '> and status = #{status} </if>
+			<if test=' this.has("creareTime") '> and creare_time = #{creareTime} </if>
+			<if test=' this.has("judgeStatus") '> and judge_status = #{judgeStatus} </if>
+			<if test=' this.has("judgeTime") '> and judge_time = #{judgeTime} </if>
+			<if test=' this.has("judgeContent") '> and judge_content = #{judgeContent} </if>
+            <if test=' this.has("current") '>
+                <if test=' current != 0 '>and judge_status = #{current}</if>
+            </if>
+		</where>
+		order by
+		<choose>
+			<when test='sortType == 1'> id desc </when>
+			<when test='sortType == 2'> name desc </when>
+			<when test='sortType == 3'> phone desc </when>
+			<when test='sortType == 4'> duty_people desc </when>
+			<when test='sortType == 5'> address_ids desc </when>
+			<when test='sortType == 6'> address_str desc </when>
+			<when test='sortType == 7'> status desc </when>
+			<when test='sortType == 8'> creare_time desc </when>
+			<when test='sortType == 9'> judge_status desc </when>
+			<when test='sortType == 10'> judge_time desc </when>
+			<when test='sortType == 11'> judge_content desc </when>
+			<otherwise> id desc </otherwise>
+		</choose>
+	</select>
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+</mapper>

+ 150 - 0
sp-com/business/src/main/java/com/pj/project/tb_costomer/TbCostomerService.java

@@ -0,0 +1,150 @@
+package com.pj.project.tb_costomer;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.constants.RoleEnum;
+import com.pj.project.tb_district.TbDistrictService;
+import com.pj.project4sp.SP;
+import com.pj.project4sp.admin.SpAdmin;
+import com.pj.project4sp.admin.SpAdminMapper;
+import com.pj.project4sp.role.SpRole;
+import com.pj.project4sp.role.SpRoleMapper;
+import com.pj.project4sp.role4permission.SpRolePermissionMapper;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Service: tb_costomer -- 客户管理
+ *
+ * @author qzy
+ */
+@Service
+public class TbCostomerService extends ServiceImpl<TbCostomerMapper, TbCostomer> implements IService<TbCostomer> {
+
+    /**
+     * 底层 Mapper 对象
+     */
+    @Autowired
+    TbCostomerMapper tbCostomerMapper;
+    @Resource
+    private SpRoleMapper spRoleMapper;
+    @Resource
+    private SpRolePermissionMapper spRolePermissionMapper;
+    @Resource
+    private TbDistrictService tbDistrictService;
+    @Resource
+    private SpAdminMapper spAdminMapper;
+
+    /**
+     * 增
+     */
+    int add(TbCostomer t) {
+        if (!validateName(t)) {
+            throw new RuntimeException("该企业名称已存在");
+        }
+        t.setCreareTime(new Date()).setJudgeContent("平台创建,直接通过").setJudgeTime(new Date());
+        this.save(t);
+        List<RoleEnum> roleEnums = RoleEnum.getCustomerInitRoleList();
+        List<String>commonPer=RoleEnum.COMMON_ROLE_PER.getPerCode();
+        roleEnums.forEach(roleEnum -> {
+            SpRole spRole = new SpRole();
+            spRole.setCustomerId(t.getId()).setInfo(roleEnum.getName())
+                    .setName(roleEnum.getName()).setType(roleEnum.getType());
+            spRoleMapper.add(spRole);
+            long roleId = SP.publicMapper.getPrimarykey();
+            spRolePermissionMapper.saveRolePer(roleId, roleEnum.getPerCode());
+            spRolePermissionMapper.saveRolePer(roleId,commonPer);
+        });
+        return 1;
+    }
+
+    private boolean validateName(TbCostomer t) {
+        String costomerName = t.getName();
+        TbCostomer db = this.findByName(costomerName);
+        if (db == null) {
+            return true;
+        }
+        return StrUtil.equals(db.getId(), t.getId());
+    }
+
+    TbCostomer findByName(String name){
+        QueryWrapper<TbCostomer> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("name", name);
+        return this.getOne(queryWrapper);
+    }
+
+    /**
+     * 删
+     */
+    int delete(String id) {
+        this.removeById(id);
+        SoMap soMap = SoMap.getRequestSoMap();
+        soMap.put("customerId", id);
+        List<SpRole> roles = spRoleMapper.getList(soMap);
+        if (roles.isEmpty()){
+            return 1;
+        }
+        spRoleMapper.removeByCustomerId(id);
+        spRolePermissionMapper.removeByRoleIds(roles.stream().map(SpRole::getId).collect(Collectors.toList()));
+        spAdminMapper.removeByCustomerId(id);
+        return 1;
+    }
+
+    /**
+     * 改
+     */
+    int update(TbCostomer t) {
+        if (!validateName(t)) {
+            throw new RuntimeException("该企业名称已存在");
+        }
+        this.updateById(t);
+        return 1;
+    }
+
+
+
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
+    public List<TbCostomer> getList(SoMap so) {
+
+        return tbCostomerMapper.getList(so);
+    }
+
+
+    public int updateStatus(String id, int value) {
+        int line = SP.publicMapper.updateColumnById(TbCostomer.TABLE_NAME, "status", value, id);
+        int status=value==1?1:2;
+        spAdminMapper.updateCustomerAdmin(id,status);
+        return line;
+    }
+
+    public void judge(String id, int status,String judgeContent) {
+        TbCostomer costomer=  this.getById(id);
+        costomer.setJudgeContent(judgeContent)
+            .setJudgeStatus(status).setJudgeTime(new Date());
+        this.updateById(costomer);
+
+        //审核不通过禁用用户
+        int isBan = status == 3 ? 2 : 1;//账号状态(1=正常, 2=禁用)
+        SpAdmin spAdmin = spAdminMapper.getByCostomerId(costomer.getId());
+        if(spAdmin != null) {
+            spAdmin.setStatus(isBan);
+            spAdminMapper.updateCustomerAdmin(costomer.getId(), isBan);
+        }
+
+    }
+
+    public void register(TbCostomer costomer) {
+        costomer.setJudgeStatus(1).setStatus(1);
+        this.add(costomer);
+    }
+}

+ 93 - 0
sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrict.java

@@ -0,0 +1,93 @@
+package com.pj.project.tb_district;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Model: tb_district -- 全国地区表
+ * @author qzyReal 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(TbDistrict.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class TbDistrict extends Model<TbDistrict> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "tb_district";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "tb-district";	
+
+
+	// ---------- 表中字段 ----------
+	/**
+	 * 主键 
+	 */
+	private Long id;
+
+	/**
+	 * 父及地区关系 
+	 */
+	private Long pid;
+
+	/**
+	 * 地区名称 
+	 */
+	private String district;
+
+	/**
+	 * 子属级别关系 
+	 */
+	private String level;
+
+	@TableField(exist = false)
+	private List<TbDistrict> children;
+
+
+	@TableField(exist = false)
+	private Long AreaId;
+	@TableField(exist = false)
+	private String AreaName;
+	@TableField(exist = false)
+	private Long ParentId;
+	@TableField(exist = false)
+	private String Layer;
+
+
+	public Long getAreaId() {
+		return this.id;
+	}
+
+	public String getAreaName() {
+		return this.district;
+	}
+
+	public Long getParentId() {
+		return this.pid;
+	}
+
+	public String getLayer() {
+		return this.Layer;
+	}
+
+
+	
+
+
+}

+ 49 - 0
sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrictController.java

@@ -0,0 +1,49 @@
+package com.pj.project.tb_district;
+
+
+import com.pj.utils.sg.AjaxJson;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * Controller: tb_district -- 全国地区表
+ *
+ * @author qzyReal
+ */
+@RestController
+@RequestMapping("/TbDistrict/")
+public class TbDistrictController {
+
+    /**
+     * 底层 Service 对象
+     */
+    @Autowired
+    TbDistrictService tbDistrictService;
+
+
+    /**
+     * 查 - 根据id
+     */
+    @RequestMapping("getById")
+    public AjaxJson getById(Integer id) {
+        TbDistrict t = tbDistrictService.getById(id);
+        return AjaxJson.getSuccessData(t);
+    }
+
+    @RequestMapping(value = "getTreeData")
+    public AjaxJson getTreeData() {
+        List<TbDistrict> list = tbDistrictService.getTreeData();
+        return AjaxJson.getSuccessData(list);
+    }
+
+    // ------------------------- 前端接口 -------------------------
+
+
+
+
+
+}

+ 55 - 0
sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrictMapper.java

@@ -0,0 +1,55 @@
+package com.pj.project.tb_district;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.pj.utils.so.SoMap;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * Mapper: tb_district -- 全国地区表
+ * @author qzyReal 
+ */
+
+@Mapper
+@Repository
+public interface TbDistrictMapper extends BaseMapper <TbDistrict> {
+
+	/**
+	 * 增  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int add(TbDistrict t);
+
+	/**
+	 * 删  
+	 * @param id 要删除的数据id  
+	 * @return 受影响行数 
+	 */
+	int delete(Integer id);	 
+
+	/** 
+	 * 改  
+	 * @param t 实体对象 
+	 * @return 受影响行数 
+	 */
+	int update(TbDistrict t);
+
+	/** 
+	 * 查 - 根据id  
+	 * @param id 要查询的数据id 
+	 * @return 实体对象 
+	 */
+	TbDistrict getById(Integer id);
+
+	/**
+	 * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+	 * @param so 参数集合 
+	 * @return 数据列表 
+	 */
+	List<TbDistrict> getList(SoMap so);
+
+
+}

+ 80 - 0
sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrictMapper.xml

@@ -0,0 +1,80 @@
+<?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="com.pj.project.tb_district.TbDistrictMapper">
+
+	<!-- 增 [G] -->
+	<insert id="add">
+		insert into 
+		tb_district (id, pid, district, level) 
+		values (#{id}, #{pid}, #{district}, #{level}) 
+	</insert>
+
+	<!-- 删 -->
+	<delete id="delete">
+		delete from tb_district 
+		where id = #{id}
+	</delete>
+
+	<!-- 改 [G] -->
+	<update id="update">
+		update tb_district set
+		id = #{id}, 
+		pid = #{pid}, 
+		district = #{district}, 
+		level = #{level}
+		where id = #{id}
+	</update>
+
+
+	<!-- ================================== 查询相关 ================================== -->
+	<!-- select id, pid, district, level from tb_district  -->
+	
+	<!-- 通用映射:手动模式 -->
+	<resultMap id="model" type="com.pj.project.tb_district.TbDistrict">
+		<result property="id" column="id" />
+		<result property="pid" column="pid" />
+		<result property="district" column="district" />
+		<result property="level" column="level" />
+	</resultMap>
+	
+	<!-- 公共查询sql片段 -->
+	<sql id="select_sql">
+		select * 
+		from tb_district 
+	</sql>
+	
+	<!-- 查 - 根据id -->
+	<select id="getById" resultMap="model">
+		<include refid="select_sql"></include>
+		where id = #{id}
+	</select>
+	
+	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+	<select id="getList" resultMap="model">
+		<include refid="select_sql"></include>
+		<where>
+			<if test=' this.isNotNull("id") '> and id = #{id} </if>
+			<if test=' this.isNotNull("pid") '> and pid = #{pid} </if>
+			<if test=' this.isNotNull("district") '> and district = #{district} </if>
+			<if test=' this.isNotNull("level") '> and level = #{level} </if>
+		</where>
+		order by
+		<choose>
+			<when test='sortType == 1'> id desc </when>
+			<when test='sortType == 2'> pid desc </when>
+			<when test='sortType == 3'> district desc </when>
+			<when test='sortType == 4'> level desc </when>
+			<otherwise> id desc </otherwise>
+		</choose>
+	</select>
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+</mapper>

+ 95 - 0
sp-com/business/src/main/java/com/pj/project/tb_district/TbDistrictService.java

@@ -0,0 +1,95 @@
+package com.pj.project.tb_district;
+
+import cn.hutool.cache.CacheUtil;
+import cn.hutool.cache.impl.TimedCache;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * Service: tb_district -- 全国地区表
+ *
+ * @author qzyReal
+ */
+@Service
+public class TbDistrictService extends ServiceImpl<TbDistrictMapper, TbDistrict> implements IService<TbDistrict> {
+
+    /**
+     * 底层 Mapper 对象
+     */
+    @Autowired
+    TbDistrictMapper tbDistrictMapper;
+
+    /**
+     * 增
+     */
+    int add(TbDistrict t) {
+        return tbDistrictMapper.add(t);
+    }
+
+    /**
+     * 删
+     */
+    int delete(Integer id) {
+        return tbDistrictMapper.delete(id);
+    }
+
+    /**
+     * 改
+     */
+    int update(TbDistrict t) {
+        return tbDistrictMapper.update(t);
+    }
+
+    /**
+     * 查
+     */
+    TbDistrict getById(Integer id) {
+        return tbDistrictMapper.getById(id);
+    }
+
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
+    List<TbDistrict> getList(SoMap so) {
+        return tbDistrictMapper.getList(so);
+    }
+
+
+    public List<TbDistrict> GetListProvince() {
+        QueryWrapper<TbDistrict> ew = new QueryWrapper<>();
+        ew.eq("pid", 1);
+        return this.list(ew);
+    }
+
+    public List<TbDistrict> GetListCity(Long areaId) {
+        QueryWrapper<TbDistrict> ew = new QueryWrapper<>();
+        ew.eq("pid", areaId);
+        return this.list(ew);
+    }
+
+    TimedCache<String, List<TbDistrict>> timedCache = CacheUtil.newTimedCache(999999999);
+
+    public List<TbDistrict> getTreeData() {
+        List<TbDistrict> cacheList = timedCache.get("address");
+        if (cacheList != null && cacheList.size() > 0) {
+            return cacheList;
+        }
+        List<TbDistrict> list = this.GetListProvince();
+        list.forEach(tbDistrict -> {
+            List<TbDistrict> cityList = this.GetListCity(tbDistrict.getId());
+            tbDistrict.setChildren(cityList);
+            cityList.forEach(city -> {
+                List<TbDistrict> areaList = this.GetListCity(city.getId());
+                city.setChildren(areaList);
+            });
+        });
+        timedCache.put("address", list);
+        return list;
+    }
+}

+ 70 - 0
sp-com/business/src/main/java/com/pj/project/tb_driver/TbDriver.java

@@ -0,0 +1,70 @@
+package com.pj.project.tb_driver;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Model: tb_driver -- 司机
+ * @author qzy 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(TbDriver.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class TbDriver extends Model<TbDriver> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "tb_driver";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "tb-driver";	
+
+
+	// ---------- 表中字段 ----------
+	/**
+	 * 主键 
+	 */
+	private String id;
+
+	/**
+	 * 名称 
+	 */
+	private String name;	
+
+	/**
+	 * 手机号码 
+	 */
+	private String phone;	
+
+	/**
+	 * 身份证 
+	 */
+	private String idCard;	
+
+	/**
+	 * 创建时间 
+	 */
+	private Date createTime;
+
+
+
+
+
+	
+
+
+}

+ 99 - 0
sp-com/business/src/main/java/com/pj/project/tb_driver/TbDriverController.java

@@ -0,0 +1,99 @@
+package com.pj.project.tb_driver;
+
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.util.IdcardUtil;
+import cn.hutool.core.util.StrUtil;
+import com.pj.project4sp.SP;
+import com.pj.utils.sg.AjaxJson;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+/**
+ * Controller: tb_driver -- 司机
+ * @author qzy 
+ */
+@RestController
+@RequestMapping("/TbDriver/")
+public class TbDriverController {
+
+	/** 底层 Service 对象 */
+	@Autowired
+	TbDriverService tbDriverService;
+
+	/** 增 */  
+	@RequestMapping("add")
+	@SaCheckPermission(TbDriver.PERMISSION_CODE)
+	@Transactional(rollbackFor = Exception.class)
+	public AjaxJson add(TbDriver t){
+		tbDriverService.add(t);
+		t = tbDriverService.getById(SP.publicMapper.getPrimarykey());
+		return AjaxJson.getSuccessData(t);
+	}
+
+	/** 删 */  
+	@RequestMapping("delete")
+	@SaCheckPermission(TbDriver.PERMISSION_CODE)
+	public AjaxJson delete(Long id){
+		int line = tbDriverService.delete(id);
+		return AjaxJson.getByLine(line);
+	}
+	
+	/** 删 - 根据id列表 */  
+	@RequestMapping("deleteByIds")
+	@SaCheckPermission(TbDriver.PERMISSION_CODE)
+	public AjaxJson deleteByIds(){
+		List<Long> ids = SoMap.getRequestSoMap().getListByComma("ids", long.class);
+		int line = SP.publicMapper.deleteByIds(TbDriver.TABLE_NAME, ids);
+		return AjaxJson.getByLine(line);
+	}
+	
+	/** 改 */  
+	@RequestMapping("update")
+	@SaCheckPermission(TbDriver.PERMISSION_CODE)
+	public AjaxJson update(TbDriver t){
+		int line = tbDriverService.update(t);
+		return AjaxJson.getByLine(line);
+	}
+
+	/** 查 - 根据id */  
+	@RequestMapping("getById")
+	public AjaxJson getById(Long id){
+		TbDriver t = tbDriverService.getById(id);
+		return AjaxJson.getSuccessData(t);
+	}
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	@RequestMapping("getList")
+	public AjaxJson getList() {
+		SoMap so = SoMap.getRequestSoMap();
+		List<TbDriver> list = tbDriverService.getList(so.startPage());
+		list.forEach(tbDriver -> {
+			String idCard=tbDriver.getIdCard();
+			String b=IdcardUtil.getBirthByIdCard(idCard);
+			if (StrUtil.isNotEmpty(b)){
+				tbDriver.setIdCard(idCard.replace(b,"******"));
+			}
+		});
+		return AjaxJson.getPageData(so.getDataCount(), list);
+	}
+	
+	
+	
+	
+	// ------------------------- 前端接口 -------------------------
+	
+	
+
+	
+	
+	
+	
+	
+
+}

Some files were not shown because too many files changed in this diff