Browse Source

余额扣款

qzyReal 2 years ago
parent
commit
d945fcdba1
86 changed files with 4879 additions and 2072 deletions
  1. 32 5
      app-ui/pages/onely-disinfect/type-business-edit.vue
  2. 30 0
      app-ui/pages/onely-disinfect/type-business.vue
  3. 7 7
      app-ui/pages/wx/pay.vue
  4. 2 2
      app-ui/utils/request.js
  5. 71 33
      sp-admin/sa-frame/menu-list-sp.js
  6. 1 10
      sp-admin/sa-frame/menu-list.js
  7. 70 127
      sp-admin/sa-view/car/tb-business-car-list.html
  8. 209 0
      sp-admin/sa-view/tb-account/balance-print.html
  9. 49 165
      sp-admin/sa-view/tb-account/tb-account-add.html
  10. 127 0
      sp-admin/sa-view/tb-account/tb-account-balance-list.html
  11. 260 154
      sp-admin/sa-view/tb-account/tb-account-list.html
  12. 3 6
      sp-admin/sa-view/tb-account/tb-account-update.html
  13. 41 23
      sp-admin/sa-view/tb-business-car/tb-business-car-info.html
  14. 5 5
      sp-admin/sa-view/tb-business/tb-business-item-supplement.html
  15. 51 18
      sp-admin/sa-view/tb-business/tb-car-disincle-add.html
  16. 63 22
      sp-admin/sa-view/tb-business/tb-car-disincle-edit.html
  17. 223 0
      sp-admin/sa-view/tb-business/tb-car-disincle-error-add.html
  18. 36 19
      sp-admin/sa-view/tb-business/tb-car-disincle-info.html
  19. 74 19
      sp-admin/sa-view/tb-business/tb-car-disincle-list.html
  20. 0 5
      sp-admin/sa-view/tb-charge-record/tb-charge-record-add.html
  21. 140 85
      sp-admin/sa-view/tb-charge-record/tb-charge-record-list.html
  22. 351 0
      sp-admin/sa-view/tb-deduction-record/tb-deduction-record-error-list.html
  23. 158 108
      sp-admin/sa-view/tb-deduction-record/tb-deduction-record-list.html
  24. 1 1
      sp-admin/sa-view/tb-fee-statistics/tb-fee-statistics-list.html
  25. 386 378
      sp-admin/sa-view/tb-goods/tb-goods-list.html
  26. 4 4
      sp-admin/sa-view/tb-item-type/tb-item-list.html
  27. 4 4
      sp-admin/sa-view/tb-item-type/tb-item-type-list.html
  28. 134 0
      sp-admin/sa-view/tb-refund-record/tb-refund-record-add.html
  29. 70 0
      sp-admin/sa-view/tb-refund-record/tb-refund-record-info.html
  30. 167 0
      sp-admin/sa-view/tb-refund-record/tb-refund-record-list.html
  31. 1 1
      sp-admin/static/sa.js
  32. 55 98
      sp-server/src/main/java/com/pj/api/open/service/OpenService.java
  33. 10 2
      sp-server/src/main/java/com/pj/api/pushfee/task/FeeDetailSyncTask.java
  34. 2 1
      sp-server/src/main/java/com/pj/api/service/ApiService.java
  35. 4 1
      sp-server/src/main/java/com/pj/api/wx/bo/ManagerBO.java
  36. 1 0
      sp-server/src/main/java/com/pj/api/wx/bo/PriceBO.java
  37. 5 19
      sp-server/src/main/java/com/pj/api/wx/service/WxService.java
  38. 12 6
      sp-server/src/main/java/com/pj/constants/business/FeeTypeEnum.java
  39. 2 2
      sp-server/src/main/java/com/pj/constants/business/GoodsEnum.java
  40. 1 1
      sp-server/src/main/java/com/pj/constants/business/PayEnum.java
  41. 8 0
      sp-server/src/main/java/com/pj/current/config/MyConfig.java
  42. 110 104
      sp-server/src/main/java/com/pj/project/tb_account/AutomaticPay.java
  43. 35 0
      sp-server/src/main/java/com/pj/project/tb_account/ChargeBO.java
  44. 24 5
      sp-server/src/main/java/com/pj/project/tb_account/TbAccount.java
  45. 2 1
      sp-server/src/main/java/com/pj/project/tb_account/TbAccountBO.java
  46. 59 18
      sp-server/src/main/java/com/pj/project/tb_account/TbAccountController.java
  47. 6 0
      sp-server/src/main/java/com/pj/project/tb_account/TbAccountMapper.java
  48. 79 68
      sp-server/src/main/java/com/pj/project/tb_account/TbAccountMapper.xml
  49. 281 92
      sp-server/src/main/java/com/pj/project/tb_account/TbAccountService.java
  50. 52 0
      sp-server/src/main/java/com/pj/project/tb_account/TbBalanceBO.java
  51. 2 0
      sp-server/src/main/java/com/pj/project/tb_business/OtherBusinessBO.java
  52. 10 5
      sp-server/src/main/java/com/pj/project/tb_business/TbBusiness.java
  53. 20 24
      sp-server/src/main/java/com/pj/project/tb_business/TbBusinessController.java
  54. 4 0
      sp-server/src/main/java/com/pj/project/tb_business/TbBusinessMapper.xml
  55. 147 202
      sp-server/src/main/java/com/pj/project/tb_business/TbBusinessService.java
  56. 8 1
      sp-server/src/main/java/com/pj/project/tb_business_car/TbBusinessCar.java
  57. 4 3
      sp-server/src/main/java/com/pj/project/tb_business_car/TbBusinessCarController.java
  58. 123 14
      sp-server/src/main/java/com/pj/project/tb_business_car/TbBusinessCarService.java
  59. 14 1
      sp-server/src/main/java/com/pj/project/tb_business_item/TbBusinessItem.java
  60. 3 1
      sp-server/src/main/java/com/pj/project/tb_business_item/TbBusinessItemService.java
  61. 17 0
      sp-server/src/main/java/com/pj/project/tb_charge_record/BalanceDTO.java
  62. 45 7
      sp-server/src/main/java/com/pj/project/tb_charge_record/TbChargeRecord.java
  63. 7 0
      sp-server/src/main/java/com/pj/project/tb_charge_record/TbChargeRecordMapper.java
  64. 32 0
      sp-server/src/main/java/com/pj/project/tb_charge_record/TbChargeRecordMapper.xml
  65. 67 7
      sp-server/src/main/java/com/pj/project/tb_charge_record/TbChargeRecordService.java
  66. 6 0
      sp-server/src/main/java/com/pj/project/tb_costomer/TbCostomerController.java
  67. 18 0
      sp-server/src/main/java/com/pj/project/tb_costomer/TbCostomerService.java
  68. 92 19
      sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecord.java
  69. 36 16
      sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecordController.java
  70. 3 0
      sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecordMapper.java
  71. 17 2
      sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecordMapper.xml
  72. 192 18
      sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecordService.java
  73. 1 1
      sp-server/src/main/java/com/pj/project/tb_fee_details/TbFeeDetails.java
  74. 133 125
      sp-server/src/main/java/com/pj/project/tb_fee_details/TbFeeDetailsService.java
  75. 1 1
      sp-server/src/main/java/com/pj/project/tb_fee_details/dto/ExportFeeDetailDTO.java
  76. 2 2
      sp-server/src/main/java/com/pj/project/tb_fee_statistics/TbFeeStatisticsService.java
  77. 6 2
      sp-server/src/main/java/com/pj/project/tb_goods/TbGoods.java
  78. 6 1
      sp-server/src/main/java/com/pj/project/tb_goods/TbGoodsController.java
  79. 3 0
      sp-server/src/main/java/com/pj/project/tb_item/TbItem.java
  80. 3 1
      sp-server/src/main/java/com/pj/project/tb_item_type/TbItemTypeService.java
  81. 127 0
      sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecord.java
  82. 51 0
      sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecordController.java
  83. 24 0
      sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecordMapper.java
  84. 53 0
      sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecordMapper.xml
  85. 82 0
      sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecordService.java
  86. 2 0
      sp-server/src/main/resources/application-dev.yml

+ 32 - 5
app-ui/pages/onely-disinfect/type-business-edit.vue

@@ -13,6 +13,15 @@
 					</picker>
 				</view>
 			</view>
+			<view class="item" v-if="goods.needPartner==1">
+				<view class="l">合作伙伴:</view>
+				<view class="r" style="flex: 12;">
+					<picker v-if="partner.partnerList.length>0" class="p-picker" @change="partnerChange($event)"
+						:value="partner.index" :range="partner.partnerList" range-key="name">
+						<text class="p-text">{{ partner.partnerList[partner.index].name }}</text>
+					</picker>
+				</view>
+			</view>
 			<view class="item" v-if="goods.needOwner==1">
 				<view class="l">
 					<text style="color: red;">*</text>
@@ -120,6 +129,10 @@
 					index: 0,
 					customerList: [],
 				},
+				partner: {
+					index: 0,
+					partnerList: [],
+				},
 				goods: {
 					id: '',
 					name: '',
@@ -259,7 +272,7 @@
 					let items = data.items;
 					this.form = data;
 					this.getTypeByGoodsId(items);
-					this.getCustomerList(data.customerId);
+					this.getCustomerList(data.customerId, data.pickCustomerId);
 				})
 			},
 			showSelect(item) {
@@ -269,7 +282,10 @@
 					this.show = true;
 				}
 			},
-
+			partnerChange(e) {
+				var value = e.detail.value; //当前picker选中的值
+				this.partner.index = value;
+			},
 			confirmFn(e) {
 				let selects = e.value;
 				if (selects.length > 0) {
@@ -315,16 +331,16 @@
 					this.typeList = list;
 				})
 			},
-			getCustomerList(customerId) {
+			getCustomerList(customerId, pickCustomerId) {
 				this.$api.getCustomerList({
 					pageNo: 1,
 					pageSize: 100
 				}).then(resp => {
 					let list = resp.data;
-					console.log(list.map(obj => obj.id).indexOf(customerId))
 					this.customer.index = list.map(obj => obj.id).indexOf(customerId);
 					this.customer.customerList = list;
-					console.log(this.customer)
+					this.partner.index = list.map(obj => obj.id).indexOf(pickCustomerId);
+					this.partner.partnerList = list;
 				})
 			},
 			customerChange(e) {
@@ -472,6 +488,17 @@
 					this.form.customerId = '';
 					this.form.customerName = '';
 				}
+				let needPartner = goods.needPartner;
+				if (needPartner == 1) {
+					let partnerList = this.partner.partnerList;
+					let index = this.partner.index;
+					let partner = partnerList[index];
+					this.form.pickCustomerId = partner.id;
+					this.form.pickCustomerName = partner.name;
+				} else {
+					this.form.pickCustomerId = '';
+					this.form.pickCustomerName = '';
+				}
 				this.form.goodsId = this.goods.id;
 				this.form.goodsName = this.goods.name;
 				let chinaCarNo = carList

+ 30 - 0
app-ui/pages/onely-disinfect/type-business.vue

@@ -14,6 +14,16 @@
 					</picker>
 				</view>
 			</view>
+			<view class="item" v-if="goods.needPartner==1">
+				<view class="l">合作伙伴:</view>
+				<view class="r" style="flex: 12;">
+					<picker  v-if="partner.partnerList.length>0" class="p-picker"
+						@change="partnerChange($event)" :value="partner.index" :range="partner.partnerList"
+						range-key="name">
+						<text class="p-text">{{ partner.partnerList[partner.index].name }}</text>
+					</picker>
+				</view>
+			</view>
 			<view class="item" v-if="goods.needOwner==1">
 				<view class="l">
 					<text style="color: red;">*</text>
@@ -121,6 +131,10 @@
 					index: 0,
 					customerList: [],
 				},
+				partner: {
+					index: 0,
+					partnerList: [],
+				},
 				goods: {
 					id: '',
 					name: '',
@@ -291,12 +305,17 @@
 						this.customer.index = list.map(obj => obj.id).indexOf(customerId);
 					}
 					this.customer.customerList = list;
+					this.partner.partnerList = list.filter(obj=>obj.type!=0);
 				})
 			},
 			customerChange(e) {
 				var value = e.detail.value; //当前picker选中的值
 				this.customer.index = value;
 			},
+			partnerChange(e) {
+				var value = e.detail.value; //当前picker选中的值
+				this.partner.index = value;
+			},
 			handlerCar(car) {
 				let list = this.car.list;
 				let check = list.filter(obj => obj.carNo == car.carNo).pop();
@@ -440,6 +459,17 @@
 					this.form.customerId = '';
 					this.form.customerName = '';
 				}
+					let needPartner = goods.needPartner;
+				if (needPartner == 1) {
+					let partnerList = this.partner.partnerList;
+					let index = this.partner.index;
+					let partner = partnerList[index];
+					this.form.pickCustomerId = partner.id;
+					this.form.pickCustomerName = partner.name;
+				} else {
+					this.form.pickCustomerId = '';
+					this.form.pickCustomerName = '';
+				}
 				this.form.goodsId = this.goods.id;
 				this.form.goodsName = this.goods.name;
 				let chinaCarNo = carList

+ 7 - 7
app-ui/pages/wx/pay.vue

@@ -34,7 +34,7 @@
 					</view>
 				</u-checkbox-group>
 			</view>
-			<view class="card" v-if="manager">
+			<!-- <view class="card" v-if="manager">
 				<view class="title">
 					入场管理费:
 				</view>
@@ -49,7 +49,7 @@
 							<view class="r">{{ manager.price }}元</view>
 						</label>
 					</view>
-			</view>
+			</view> -->
 			<view class="card" v-if="item.itemsPrice">
 				<view class="title">
 					<u-checkbox-group placement="column" v-model="businessSelect" @change="businessChange">
@@ -192,10 +192,10 @@
 					.map(obj => obj.price).reduce(function(pre, cur) {
 						return pre + cur;
 					}, 0) : 0;
-					let manager=this.manager;
-					if(manager){
-						itemMoney=manager.price+itemMoney;
-					}
+					// let manager=this.manager;
+					// if(manager){
+					// 	itemMoney=manager.price+itemMoney;
+					// }
 				return (carMoney + itemMoney).toFixed(2);
 			}
 		},
@@ -353,7 +353,7 @@
 					}
 					let data = resp.data;
 					let cars = data.carList;
-					this.manager=data.manager;
+					// this.manager=data.manager;
 					
 					this.cars = cars;
 					this.goodsName = data.goodsName;

+ 2 - 2
app-ui/utils/request.js

@@ -1,8 +1,8 @@
-// const server = 'http://127.0.0.1:8099/pro';
+const server = 'http://127.0.0.1:8099/pro';
 // const server = 'https://pco.aseanbusiness.cn/pro';
 
 
-const server = 'https://dxkaa1.gxbtka.com/pro';
+// const server = 'https://dxkaa1.gxbtka.com/pro';
 
 
 import common from '../common/js/common.js';

+ 71 - 33
sp-admin/sa-frame/menu-list-sp.js

@@ -657,17 +657,7 @@ window.menuList.unshift({
 			},
 
 		]
-	}, {
-		id: 'tb-charge-record',
-		name: '充值记录',
-		icon: 'el-icon-folder-opened',
-		parent: true,
-		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',
@@ -798,16 +788,23 @@ window.menuList.unshift({
 		name: '预存款管理',
 		icon: 'el-icon-folder-opened',
 		parent: true,
-		childList: [{
+		childList: [
+			{
 				id: 'tb-account-list',
-				name: '客户充值',
+				name: '企业充值',
 				url: 'sa-view/tb-account/tb-account-list.html',
-				childList: [{
+				childList: [
+					{
 						id: 'tb-account-list-add',
 						name: '充值',
 						isShow: false,
 					},
 					{
+						id: 'tb-account-list-refund',
+						name: '退款',
+						isShow: false,
+					},
+					{
 						id: 'tb-account-list-update',
 						name: '修改',
 						isShow: false,
@@ -815,6 +812,23 @@ window.menuList.unshift({
 				]
 			},
 			{
+				id: 'tb-account-balance-list',
+				name: '企业余额',
+				url: 'sa-view/tb-account/tb-account-balance-list.html',
+				childList: [
+					{
+						id: 'tb-account-balance-list-export',
+						name: '导出',
+						isShow: false,
+					},
+					{
+						id: 'tb-account-balance-list-print',
+						name: '打印',
+						isShow: false,
+					}
+				]
+			},
+			{
 				id: 'tb-charge-record-list',
 				name: '充值记录',
 				url: 'sa-view/tb-charge-record/tb-charge-record-list.html',
@@ -834,31 +848,55 @@ window.menuList.unshift({
 						isShow: false,
 					}
 				]
-			}, {
-				id: 'tb-deduction-bind-list',
-				name: '扣费绑定',
-				url: 'sa-view/tb-deduction-bind/tb-deduction-bind-list.html',
-				childList: [{
-						id: 'tb-deduction-bind-list-bind',
-						name: '绑定车辆',
-						isShow: false,
-					},
-					{
-						id: 'tb-deduction-bind-list-unbind',
-						name: '手动解绑',
-						isShow: false,
-					}
-				]
-			}, {
+			}, 
+		
+			{
 				id: 'tb-deduction-record-list',
 				name: '扣费记录',
 				url: 'sa-view/tb-deduction-record/tb-deduction-record-list.html',
-				childList: [{
+				childList: [
+					{
 					id: 'tb-deduction-record-list-review',
 					name: '复审',
 					isShow: false,
-				}]
-			}
+				},
+				{
+					id: 'tb-deduction-record-export',
+					name: '导出',
+					isShow: false,
+				},
+				{
+					id: 'tb-deduction-record-set-error',
+					name: '设为异常单',
+					isShow: false,
+				},
+				]
+			},
+			{
+				id: 'tb-deduction-record-error-list',
+				name: '异常订单',
+				url: 'sa-view/tb-deduction-record/tb-deduction-record-error-list.html',
+				childList: [
+					{
+					id: 'tb-deduction-record-list-refund',
+					name: '退款',
+					isShow: false,
+				},
+				]
+			},
+			{
+				id: 'tb-refund-record',
+				name: '退款记录',
+				url: 'sa-view/tb-refund-record/tb-refund-record-list.html',
+				childList: [
+					{
+						id: 'tb-refund-record-export',
+						name: '导出',
+						isShow: false,
+					},
+				]
+			}, 
+		
 		],
 
 	}

+ 1 - 10
sp-admin/sa-frame/menu-list.js

@@ -16,14 +16,5 @@
 
 // 定义菜单列表 
 var menuList =	[
-	{
-		id: 'tb-mild-car',
-		name: '4.2~9.6车辆管理',
-		icon: 'el-icon-folder-opened',
-		info: '4.2~9.6车辆管理表数据的维护',
-		childList: [
-			{id: 'tb-mild-car-list', name: '4.2~9.6车辆管理-列表', url: 'sa-view/tb-mild-car/tb-mild-car-list.html'},
-			{id: 'tb-mild-car-add', name: '4.2~9.6车辆管理-添加', url: 'sa-view/tb-mild-car/tb-mild-car-add.html'},
-		]
-	},
+	
 ]

+ 70 - 127
sp-admin/sa-view/car/tb-business-car-list.html

@@ -14,13 +14,18 @@
     <script src="../../static/kj/jquery.min.js"></script>
     <script src="../../static/kj/layer/layer.js"></script>
     <script src="../../static/sa.js"></script>
+	<style>
+		.car-size .el-input__inner {
+		    width: 130px;
+		}
+	</style>
 </head>
 <body>
 <div class="vue-box" style="display: none;" :style="'display: block;'">
     <div class="c-panel">
         <div class="fast-btn">
             <el-button size="mini" type="primary" @click="add()"
-                       v-if="confirm==0&&sa.isAuth('tb-business-edit')">
+                       v-if="sa.isAuth('tb-flex-business-edit')">
                 新增
             </el-button>
             <el-button size="mini" type="info" @click="sa.f5()">刷新</el-button>
@@ -28,16 +33,8 @@
         <!-- ------------- 数据列表 ------------- -->
         <el-table class="data-table" ref="data-table" :data="dataList">
             <sa-td name="车牌号" prop="carNo" width=120></sa-td>
-            <sa-td name="车辆规格" prop="carSize"></sa-td>
             <sa-td width="130" name="支付状态" prop="payType">
             </sa-td>
-            <sa-td width=100 name="车辆状态" prop="isLock" type="switch" :jv="{1: '锁定[#ff0000]', 0: '正常[#005500]'}"
-                   @change="s => updateStatus(s.row)"></sa-td>
-            <el-table-column label="证明">
-                <template slot-scope="s">
-                    <el-button type="primary" @click="checkFn(s.row)">查看</el-button>
-                </template>
-            </el-table-column>
             <el-table-column label="停车费">
                 <template slot-scope="s">
                     <label v-if="s.row.money">{{s.row.money}}</label>
@@ -48,73 +45,44 @@
             <sa-td name="入场通道" prop="inChannel" width=180></sa-td>
             <sa-td name="离场时间" prop="realOutTime" width=160></sa-td>
             <sa-td name="离场通道" prop="outChannel" width=180></sa-td>
-            <el-table-column label="操作" width="120px" fixed="right">
+            <el-table-column label="操作" width="100px" fixed="right">
                 <template slot-scope="s">
-                    <el-button v-if="sa.isAuth('tb-business-car-change')&&s.row.realInTime==null" class="c-btn"
-                               type="primary" @click="inFn(s.row)">确认入场
-                    </el-button>
                     <el-button
-                            v-if="sa.isAuth('tb-business-car-change')&&s.row.realInTime!=null&&s.row.realOutTime==null"
-                            class="c-btn" type="primary" @click="outFn(s.row)">确认离场
+                            v-if="sa.isAuth('tb-flex-business-edit')&&s.row.pay==0&&s.row.confirmJudge==0"
+                            class="c-btn" type="danger" @click="del(s.row)">删除
                     </el-button>
                 </template>
             </el-table-column>
         </el-table>
     </div>
-    <el-dialog title="确认入场" :visible.sync="rc.visible" width="400px">
-        <el-form label-position="left">
-            <div class="confirm-in">
-                <sa-item type="datetime" name="入场时间" v-model="rc.form.realInTime" br></sa-item>
-                <div class="c-item">
-                    <label class="c-label"><span style="color: red;">*</span>入场通道:</label>
-                    <el-input v-model="rc.form.inChannel" placeholder="入场通道">
-                    </el-input>
-                </div>
-            </div>
+    <el-dialog title="添加车辆" :visible.sync="modal.visible" width="400px">
+        <el-form >
+            <sa-item type="text" name="车牌号" v-model="modal.form.carNo" br need></sa-item>
+			<div class="c-item">
+				<label class="c-label">车辆类型:</label>
+				<el-select v-model="modal.form.carType" placeholder="请选择">
+					<el-option :label="item.name" :value="item.name" v-for="(item,index) in carTypeList">
+					</el-option>
+				</el-select>
+			</div>
+			<div class="c-item">
+			    <label class="c-label"><span style="color: red;">*</span>车辆规格:</label>
+			    <el-input-number class="car-size" v-model="modal.form.carSize" controls-position="right"
+			                     :min="4.2" :max="50"></el-input-number>
+			</div>
+			<div class="c-item" v-if="modal.form.carType.indexOf('空')==-1">
+				<label class="c-label">
+					<span ></span>
+					载重(kg):</label>
+				<el-input-number class="car-size" v-model="modal.form.netWeight" :min="1" :max="999999">
+				</el-input-number>
+			</div>
         </el-form>
         <span slot="footer" class="dialog-footer">
-					<el-button @click="rc.visible = false">取 消</el-button>
-					<el-button type="primary" @click="sureInFn">确 认</el-button>
+					<el-button @click="modal.visible = false">取 消</el-button>
+					<el-button type="primary" @click="sureAddFn">确 认</el-button>
 				</span>
     </el-dialog>
-    <el-dialog title="确认离场" :visible.sync="out.visible" width="400px">
-        <el-form label-position="left">
-            <div class="confirm-in">
-                <sa-item type="datetime" name="离场时间" v-model="out.form.realOutTime" br></sa-item>
-                <div class="c-item">
-                    <label class="c-label"><span style="color: red;">*</span>离场通道:</label>
-                    <el-input v-model="out.form.outChannel" placeholder="离场通道">
-                    </el-input>
-                </div>
-            </div>
-        </el-form>
-        <span slot="footer" class="dialog-footer">
-					<el-button @click="out.visible = false">取 消</el-button>
-					<el-button type="primary" @click="sureOutFn">确 认</el-button>
-				</span>
-    </el-dialog>
-    <el-dialog title="证明" :visible.sync="report.visible" width="500px">
-        <div>
-            <el-form>
-                <el-row>
-                    <el-col span="12">
-                        <sa-info name="核酸报告" :value="report.business.nucleicReport" type="img"></sa-info>
-                    </el-col>
-                    <el-col span="12">
-                        <sa-info name="出仓证明" :value="report.business.outReport" type="img"></sa-info>
-                    </el-col>
-                </el-row>
-                <el-row style="margin-top: 20px;">
-                    <el-col span="12">
-                        <sa-info name="消杀证明" :value="report.business.disinfectReport" type="img"></sa-info>
-                    </el-col>
-                    <el-col span="12">
-                        <sa-info name="检验检疫证" :value="report.business.checkReport" type="img"></sa-info>
-                    </el-col>
-                </el-row>
-            </el-form>
-        </div>
-    </el-dialog>
 </div>
 <script>
     var app = new Vue({
@@ -137,71 +105,38 @@
             },
             dataCount: 0,
             dataList: [], // 数据集合
-            rc: {
+			carTypeList:[],
+            modal: {
                 visible: false,
                 form: {
-                    realInTime: '',
-                    inChannel: ''
+                    carNo: '',
+                    carSize: 13,
+					carType:'载重',
+					netWeight:0
                 }
             },
-            out: {
-                visible: false,
-                form: {
-                    realOutTime: '',
-                    outChannel: ''
-                }
-            }
         },
         methods: {
-            checkFn(data) {
-                sa.ajax('/TbBusiness/getById?id=' + this.p.businessId, function (resp) {
-                    let business = resp.data;
-                    if (!business.outReport) {
-                        //sa.error('未上传')
-                    }
-                    this.report.visible = true;
-                    this.report.business = business;
-                }.bind(this))
-            },
-            inFn(data) {
-                Object.assign(this.rc, {
-                    visible: true,
-                    form: data
-                })
-            },
-            sureInFn() {
-                if (!this.rc.form.realInTime) {
-                    sa.error('请填写入场时间')
-                    return;
-                }
-                if (!this.rc.form.inChannel) {
-                    sa.error('请填写入场通道')
-                    return;
-                }
-                sa.ajax('/TbBusinessCar/inCar', this.rc.form, function (res) {
-                    sa.alert('操作成功');
-                    this.rc.visible = false;
-                    this.f5();
-                }.bind(this));
-            },
-            outFn(data) {
-                Object.assign(this.out, {
-                    visible: true,
-                    form: data
-                })
-            },
-            sureOutFn() {
-                if (!this.out.form.realOutTime) {
-                    sa.error('请填写离场时间')
-                    return;
-                }
-                if (!this.out.form.outChannel) {
-                    sa.error('请填写离场通道')
-                    return;
-                }
-                sa.ajax('/TbBusinessCar/outCar', this.out.form, function (res) {
-                    sa.alert('操作成功');
-                    this.out.visible = false;
+			getItemType() {
+				sa.ajax('/TbItem/getItemType', function(resp) {
+					let list = resp.data;
+					if (list.length > 0) {
+						this.modal.form.carType = list[0].name;
+					}
+					this.carTypeList = list;
+				}.bind(this))
+			},
+         
+            sureAddFn() {
+				let data=this.modal.form;
+				if(!data.carNo){
+					  sa.error('请填写车牌号')
+					return;
+				}
+				data.businessId=this.p.businessId;
+                sa.ajax('/TbBusiness/addCar',data, function (res) {
+                    sa.alert('添加成功');
+                    this.modal.visible = false;
                     this.f5();
                 }.bind(this));
             },
@@ -225,13 +160,20 @@
             },
             // 新增
             add: function (data) {
-                sa.showIframe('新增数据', 'tb-business-car-add.html?id=-1' + '&businessId=' + this.p.businessId,
-                    '550px', '80%');
+                Object.assign(this.modal,{
+					visible:true,
+					form:{
+						carNo:'',
+						carSize:13,
+						carType:'重车',
+						netWeight:0
+					}
+				})
             },
             // 删除
             del: function (data) {
                 sa.confirm('是否删除,此操作不可撤销', function () {
-                    sa.ajax('/TbBusinessCar/delete?id=' + data.id, function (res) {
+                    sa.ajax('/TbBusiness/deleteBusinessCar?id=' + data.id+'&businessId='+this.p.businessId, function (res) {
                         sa.arrayDelete(this.dataList, data);
                         sa.ok('删除成功');
                         sa.f5TableHeight(); // 刷新表格高度
@@ -264,6 +206,7 @@
         },
         created: function () {
             this.f5();
+			this.getItemType();
             sa.onInputEnter();
         }
     })

+ 209 - 0
sp-admin/sa-view/tb-account/balance-print.html

@@ -0,0 +1,209 @@
+<!DOCTYPE html
+	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+		<title>打印收费明细</title>
+		<style type="text/css">
+			@page {
+				size: A4 portrait;
+				margin: 19mm 25mm 15mm 25mm;
+			}
+
+			.print-btn {
+				color: white;
+				background: #2D8CF0;
+				border: none;
+				border-radius: 3px;
+				padding: 5px 10px;
+				font-size: 10px;
+				margin: 10px 20px;
+				cursor: pointer;
+			}
+
+			.content-box {
+				text-align: center;
+				height: 1123px;
+				width: 794px;
+				margin: 0 auto;
+			}
+
+			table {
+				border-collapse: collapse;
+				border-spacing: 0;
+				border-left: 1px solid #888;
+				border-top: 1px solid #888;
+			}
+
+			th,
+			td {
+				border-right: 1px solid #888;
+				border-bottom: 1px solid #888;
+				word-break: break-all;
+				padding: 0 2px;
+			}
+
+			th {
+				/* font-weight: bold; */
+			}
+
+			.title-top {
+				margin-top: 248px;
+			}
+		</style>
+		<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/print/jquery-2.0.3.js" type="text/javascript"></script>
+		<script src="../../static/print/print2.js" type="text/javascript"></script>
+		<script src="../../static/kj/layer/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+
+	</head>
+
+	<body>
+		<div>
+			<div class="box">
+				<button class="print-btn" @click="printFn">打印</button>
+				<div id="myPrintArea" style="position: relative;">
+					<div class="content-box" style="position: relative;" v-for="(item,index) in dataList"
+						:key="index" :class="index>0?'title-top':''" >
+						<div class="header-title" style="text-align: center;" v-if="index==0">
+							<span
+								style="font-size: 20px;font-weight: 500;font-family: 黑体;">东兴口岸(二桥)进口货物集散区(A1地块)预存款余额表</span>
+						
+						</div>
+						<table style="margin: 0 auto;text-align: center;width: 790px;" >
+							<div
+								style="text-align: left;width: 790px;margin: auto;padding: 5px 0;font-family: 黑体;font-weight: 500;">
+								<span colspan="9">单位:广西东兴北投口岸投资有限公司
+								<span style="margin-left: 10px;">期间:{{item.time}}</span>
+								<span style="margin-left: 10px;">金额单位:元</span></span>
+								
+							</div>
+							<tr style="height: 60px;font-size:10px;">
+								<th style="min-width: 30px;">序号</th>
+								<th style="width: 180px;">企业名称</th>
+								<th style="min-width: 60px;"> 期初余额</th>
+								<th style="min-width: 60px;">本期充值</th>
+								<th style="min-width: 60px;">本期扣除</th>
+								<th style="min-width: 60px;">余额退款</th>
+								<th style="min-width: 60px;">异常退款</th>
+								<th style="width: 70px;">期末余额</th>
+								<th style="width: 110px;">统计稽核员</th>
+								<th style="width: 100px;">复核员</th>
+								<th style="width: 100px;">开单员</th>
+							</tr>
+							<tr v-for="(cel,i) in item.list" :key="cel.index" style="height:60px;font-size: 10px;">
+								<td>{{i+1}}</td>
+								<td>{{cel.customerName}}</td>
+								<td>{{cel.beginMoney}}</td>
+								<td>{{cel.chargeMoney}}</td>
+								<td>{{cel.deuctionMoney}}</td>
+								<td>{{cel.balanceRefundMoney}}</td>
+								<td>{{cel.errorRefundMoney}}</td>
+								<td>{{cel.endMoney}}</td>
+								<td></td>
+								<td></td>
+								<td></td>
+							</tr>
+							<tr style="height: 60px;padding: 0 0.5px;" v-if="index==dataList.length-1">
+								<td></td>
+								<td>合计</td>
+								<td>{{totalInit}}</td>
+								<td>{{totalCharge}}</td>
+								<td>{{totalDeuctionMoney}}</td>
+								<td>{{totalRefundMoney}}</td>
+								<td>{{totalErrorRefund}}</td>
+								<td>{{totalEnd}}</td>
+								<td></td>
+								<td></td>
+								<td></td>
+							</tr>
+						</table>
+						<span style="position: absolute;top: 1250px;left: 750px">{{index+1}}/{{dataList.length}}</span>
+					</div>
+				</div>
+			</div>
+		</div>
+		<script type="text/javascript">
+			var app = new Vue({
+				el: '.box',
+				data: {
+					p: {
+						"beginTime": sa.p('bDay', ''),
+						"endTime": sa.p('eDay', ''),
+						"customerName": sa.p('customerName', '')
+					},
+					dataList: [],
+					allDayFee: 0,
+					allDayTaxes: 0,
+					allDayNoTaxFee: 0,
+					totalCharge:0,
+					totalInit:0,
+					totalDeuctionMoney:0,
+					totalRefundMoney:0,
+					totalErrorRefund:0,
+					totalEnd:0
+				},
+				methods: {
+					getDataList() {
+						sa.ajax('/TbAccount/getBalance/list', this.p, function(resp) {
+							var list = resp.data;
+							let len = list.length;
+							let child = [];
+							let dataList = [];
+							let totalCharge=0;
+							let totalInit=0;
+							let totalDeuctionMoney=0;
+							let totalRefundMoney=0;
+							let totalErrorRefund=0;
+							let totalEnd=0;
+							for (i = 0; i < len; i++) {
+								let item = list[i];
+								child.push(item);
+								totalInit+=item.beginMoney;
+								totalCharge+=item.chargeMoney;
+								totalDeuctionMoney+=item.deuctionMoney;
+								totalRefundMoney+=item.balanceRefundMoney;
+								totalErrorRefund+=item.errorRefundMoney;
+								totalEnd+=item.endMoney;
+								if (child.length == 18 || i == len - 1) {
+									let title = {
+										time: this.p.beginTime + '至' + this.p.endTime,
+										list: child
+									}
+									dataList.push(title);
+									child = [];
+								}
+							
+							}
+							this.dataList = dataList;
+							this.totalCharge=totalCharge;
+							this.totalInit=totalInit;
+							this.totalDeuctionMoney=totalDeuctionMoney;
+							this.totalErrorRefund=totalErrorRefund;
+							this.totalRefundMoney=totalRefundMoney;
+							this.totalEnd=totalEnd;
+							// sa.loading("准备打印...");
+							// setTimeout(() => {
+							// 	this.printFn();
+							// 	sa.hideLoading();
+							// }, 2000)
+						}.bind(this))
+					},
+					printFn() {
+						Print('#myPrintArea', {
+							noPrint: '.noPrint'
+						});
+					}
+				},
+				mounted() {
+					this.getDataList();
+				}
+			})
+		</script>
+
+
+	</body>
+</html>

+ 49 - 165
sp-admin/sa-view/tb-account/tb-account-add.html

@@ -39,25 +39,15 @@
 				<div class="c-panel" style="text-align:center; ">
 					<div class="c-title">充值</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" :disabled="true" br></sa-item>
 						<sa-item type="text" name="客户余额" v-model="m.totalMoney" :disabled="true" br></sa-item>
-						<sa-item id="ast" type="text" name="充值金额" br>
-							<el-input v-model="m.preTopupMoney" placeholder="请输入金额" @change="computeChange">
-								<template slot="suffix">元</template>
-							</el-input>
-						</sa-item>
-						<sa-item type="text" name="优惠金额" br>
-							<el-input type="text" v-model="m.discountMoney" placeholder="请输入金额" @change="computeChange">
-								<template slot="suffix">元</template>
-							</el-input>
-						</sa-item>
-						<sa-item type="text" name="实收金额" br>
-							<el-input ref="totalTopupInp" type="text" v-model="m.totalTopup" :disabled="true">
+						<sa-item name="实际收款" br>
+							<el-input type="number" v-model="m.totalTopup" >
 								<template slot="suffix">元</template>
 							</el-input>
 						</sa-item>
+						<sa-item type="num" name="优惠金额" v-model="m.discountMoney"  br></sa-item>
+						<sa-item type="num" name="本次充值金额" v-model="preTopupMoney" disabled br></sa-item>
 						<sa-item type="enum" name="付款方式" br>
 							<el-select v-model="m.payingType">
 								<el-option label="请选择" v-for="(item,index) in payingTypeList" :key="item.id"
@@ -84,56 +74,36 @@
 				data: {
 					id: sa.p('id', ''),
 					customerId: sa.p('customerId', 0), // 获取超链接中的id参数(0=添加,非0=修改)
-					m: null, // 实体对象
+					m: {
+						id: '', 
+						customerId: sa.p('customerId', ''), 
+						customerName: '',
+						totalMoney: 0, 
+						preTopupMoney: 0, 
+						discountMoney: 0, 
+						totalTopup: 0, 
+						payingType: '',
+						salt: '',
+						remark: '', 
+					}, 
 					payingTypeList: [], //付款方式集合
 				},
-
-				methods: {
-					// 创建一个 默认Model
-					createModel: function() {
-						return {
-							id: '', // 主键
-							customerId: sa.p('customerId', ''), // 客户id
-							customerName: '',
-							totalMoney: '', // 总金额
-							preTopupMoney: '', //预充值金额
-							discountMoney: '', //优惠金额
-							totalTopup: '', //总计充值
-							payingType: '',
-							salt: '',
-							remark: '', // 备注
+				computed: {
+					preTopupMoney() {
+						let money= parseInt(this.m.totalTopup) + parseInt(this.m.discountMoney);
+						if(money<0){
+							money=0;
+							sa.error('金额不正确');
 						}
-					},
+						return money;
+					}
+				},
+				methods: {
 					// 提交数据
 					ok: function() {
-						let that = this;
-						let m = {
-							...this.m
-						};
-						sa.checkNull(m.preTopupMoney, '充值金额不能为空!');
-						if (!this.computeChange()) {
-							return;
-						}
-						const key = 'h!f78tr#L3D$2Z0q';
-						m.salt = key.split("").reverse().join("");
-						m.totalTopup = this.encrypt(m.totalTopup, key);
-						m.discountMoney = this.encrypt(m.discountMoney, key);
-						m.preTopupMoney = this.encrypt(m.preTopupMoney, key);
-						m.id = sa.p('id', 0);
-						sa.ajax('/TbAccount/recharge2', sa.removeNull(m), function(res) {
-							layer.open({
-								content: '充值成功!', //内容区域
-								move: false, //是否可以拖动,默认可以拖动
-								btn: ['确定'],
-								btn1: function(index) {
-									//    layer.close(index);//关闭弹框
-									that.clean();
-								},
-								cancel: function() {
-									that.clean();
-								}
-							});
-
+						this.m.preTopupMoney=this.preTopupMoney;
+						sa.ajax('/TbAccount/recharge', sa.removeNull(this.m), function(res) {
+							sa.alert('充值成功', this.clean);
 						}.bind(this));
 
 					},
@@ -149,121 +119,35 @@
 					},
 					computeChange(value) {
 						let preMoney = this.m.preTopupMoney;
-						let disMoney = this.m.discountMoney;
-						if (!disMoney) {
-							disMoney = 0;
-						}
-						if (isNaN(preMoney)) {
-							throw {
-								type: 'sa-error',
-								msg: "预充值金额必须是数字!"
-							};
-							return false;
-						}
-						if (isNaN(disMoney)) {
-							throw {
-								type: 'sa-error',
-								msg: "优惠金额必须是数字!"
-							};
-							return false;
-						}
-						if (preMoney.length > 1 && preMoney.substring(0, 1) == 0) {
-							throw {
-								type: 'sa-error',
-								msg: "请输入规范的数字,前面不要带零!"
-							};
-							return false;
-						}
-						if (disMoney.length > 1 && disMoney.substring(0, 1) == 0) {
-							throw {
-								type: 'sa-error',
-								msg: "请输入规范的数字,前面不要带零!"
-							};
-							return false;
-						}
-						if (!preMoney) {
-							return false;
-						}
-						preMoney = Number(preMoney);
-						disMoney = Number(disMoney);
 						if (preMoney <= 0) {
-							throw {
-								type: 'sa-error',
-								msg: "预存金额需大于零元!"
-							};
-							return false;
-						}
-						if (disMoney < 0) {
-							throw {
-								type: 'sa-error',
-								msg: "优惠金额不得低于零元!"
-							};
-							return false;
-						}
-						let totalM = preMoney - disMoney;
-						delete this.m.totalTopup;
-						this.$set(this.m, "totalTopup", totalM)
-						return true;
-					},
-					encrypt(word, keyStr) { // word, keyStr第一个参数是加密的字段名字  第二个是key值(16位)
-						if (!word) {
+							sa.error('充值金额须大于0');
 							return;
 						}
-						if (typeof word === 'object') {
-							// 如果传入的data是json对象,先转义为json字符串
-							try {
-								word = JSON.stringify(word);
-							} catch (error) {
-								console.log('error:', error);
-							}
-						}
-						keyStr = keyStr || 'h!f78tr#L3D$2Z0q'; // 密文(密钥)
-						let key = CryptoJS.enc.Utf8.parse(keyStr);
-						let src = CryptoJS.enc.Utf8.parse(word);
-						let encrypted = CryptoJS.AES.encrypt(src, key, {
-							mode: CryptoJS.mode.ECB,
-							padding: CryptoJS.pad.Pkcs7
-						});
-						//  console.log(encrypted.toString())
-						return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
-					},
-					decrypt(word, keyStr) {
-						if (!word) {
+						let disMoney = this.m.discountMoney;
+						if (disMoney < 0) {
+							sa.error('优惠金额须不能为负数');
 							return;
 						}
-						keyStr = keyStr || 'h!f78tr#L3D$2Z0q';
-						let base64 = CryptoJS.enc.Base64.parse(word);
-						let src = CryptoJS.enc.Base64.stringify(base64);
-						let key = CryptoJS.enc.Utf8.parse(keyStr);
-						let decrypt = CryptoJS.AES.decrypt(src, key, {
-							mode: CryptoJS.mode.ECB,
-							padding: CryptoJS.pad.Pkcs7
-						});
-						//  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
-						return CryptoJS.enc.Utf8.stringify(decrypt).toString();
 					},
 				},
 				mounted: function() {
-					// 初始化数据
-					this.m = this.createModel();
-					this.m.customerId = this.customerId;
+					let customerId=this.customerId;
 					this.getPayingType();
-					sa.ajax('/TbAccount/getList', sa.removeNull(this.m), function(res) {
-						if (res.data && res.data.length == 1) {
-							this.m = res.data[0];
-							if (this.m.totalMoney) {
-								this.m.totalMoney = this.decrypt(this.m.totalMoney, this.m.salt);
-							} else {
-								this.m.totalMoney = 0;
-							}
-							this.$set(this.m, "discountMoney", 0);
-							this.$set(this.m, "payingType", 1);
-						} else {
-							sa.alert('未能查找到客户详细数据,窗口将在5秒后关闭!');
-							setTimeout(function() {
-								sa.closeCurrIframe()
-							}, 5000)
-						}
+					sa.ajax('/TbAccount/getCustomerAccount', {
+						customerId: customerId
+					}, function(res) {
+						let data=res.data;
+						this.m={
+						id: data.id, 
+						customerId: customerId, 
+						customerName: data.customerName,
+						totalMoney: data.totalMoney, 
+						preTopupMoney: 0, 
+						discountMoney: 0, 
+						totalTopup: 0, 
+						payingType: 1,
+						remark: '',
+					}
 					}.bind(this))
 				}
 			})

+ 127 - 0
sp-admin/sa-view/tb-account/tb-account-balance-list.html

@@ -0,0 +1,127 @@
+<!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="https://unpkg.com/element-ui@2.13.0/lib/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>
+		<script src="../../static/node_modules/crypto-js/crypto-js.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="daterange" name="期间">
+						<el-date-picker v-model="p.createTime" type="daterange" align="right" unlink-panels
+							value-format="yyyy-MM-dd" range-separator="至" start-placeholder="开始日期"
+							end-placeholder="结束日期">
+						</el-date-picker>
+					</sa-item>
+					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
+					<el-button type="primary" icon="el-icon-download" @click="exportExcel">导出</el-button>
+					<el-button type="primary" @click="printFn">打印</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="index" name="序号"></sa-td>
+					<sa-td name="企业名称" prop="customerName" width="260"></sa-td>
+					<sa-td name="期初余额" prop="beginMoney" not="0"></sa-td>
+					<sa-td name="本期充值" prop="chargeMoney" not="0"></sa-td>
+					<sa-td name="本期扣除" prop="deuctionMoney" not="0"></sa-td>
+					<sa-td name="本期余额退款" prop="balanceRefundMoney" not="0"></sa-td>
+					<sa-td name="本期异常退款" prop="errorRefundMoney" not="0"></sa-td>
+					<sa-td name="期末余额" prop="endMoney" not="0"></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>
+
+		</script>
+		<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: { // 查询参数
+						//		accountNo: '',		// 账户
+						customerName: '',
+						createTime: [],
+						pageNo: 1, // 当前页
+						pageSize: 10, // 页大小
+						sortType: 0 // 排序方式
+					},
+					dataCount: 0,
+					dataList: [], // 数据集合
+				},
+				methods: {
+					exportExcel() {
+						let p = this.p;
+						let createTime = p.createTime;
+						if (!createTime || createTime.length == 0) {
+							sa.error('请选择导出期间')
+							return;
+						}
+						sa.confirm('是否导出符合筛选条件的记录', function() {
+							sa.ajax('/TbAccount/export', sa.removeNull(this.p),
+								function(res) {
+									window.location.href=res.data;
+								}.bind(this))
+						}.bind(this));
+					},
+					printFn() {
+						let p = this.p;
+						let createTime = p.createTime;
+						if (!createTime || createTime.length == 0) {
+							sa.error('请选择导出期间')
+							return;
+						}
+						sa.showIframe('打印', 'balance-print.html?customerName='+this.p.customerName+'&bDay='+createTime[0]+'&eDay='+createTime[1], '1080px', '90%');
+					},
+					// 刷新
+					f5: function() {
+						let p = this.p;
+						let createTime = p.createTime;
+						if (!createTime || createTime.length == 0) {
+							this.dataList = [];
+							this.dataCount = 0;
+							return;
+						} else {
+							p.beginTime = createTime[0];
+							p.endTime = createTime[1];
+						}
+						sa.ajax('/TbAccount/getBalance', 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>

+ 260 - 154
sp-admin/sa-view/tb-account/tb-account-list.html

@@ -1,160 +1,266 @@
 <!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="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css">
-    <link rel="stylesheet" href="../../static/sa.css">
-    <script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
-    <script src="https://unpkg.com/element-ui@2.13.0/lib/index.js"></script>
-    <script src="https://unpkg.com/http-vue-loader@1.4.2/src/httpVueLoader.js"></script>
-    <script src="https://unpkg.com/jquery@3.4.1/dist/jquery.js"></script>
-    <script src="https://www.layuicdn.com/layer-v3.1.1/layer.js"></script>
-    <script src="../../static/sa.js"></script>
-    <script src="../../static/node_modules/crypto-js/crypto-js.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.dutyPeople"></sa-item>
-            <sa-item type="text" name="联系电话" v-model="p.phone"></sa-item>
-            <sa-item type="text" name="操作员" v-model="p.updateBy"></sa-item>
-            <!--					<sa-item type="text" name="更新人" v-model="p.updateBy"></sa-item>-->
-            <el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
-            <br/>
-        </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="index" name="序号"></sa-td>
-            <sa-td name="客户名称" prop="customerName"></sa-td>
-            <sa-td name="联系人" prop="dutyPeople"></sa-td>
-            <sa-td name="联系电话" prop="phone"></sa-td>
-            <sa-td name="纳税识别号" prop="taxNum"></sa-td>
-            <sa-td name="开户银行" prop="bank"></sa-td>
-            <sa-td name="银行账户" prop="bankAccount"></sa-td>
-            <sa-td name="地址" prop="address"></sa-td>
-            <sa-td name="余额(元)" prop="totalMoney"></sa-td>
-           <el-table-column label="操作" fixed="right" width="140px">
-              <template slot-scope="s">
-                  <el-button class="c-btn" type="success" icon="el-icon-view" 
-                             @click="add(s.row)" v-if="sa.isAuth('tb-account-list-add')">充值</el-button>
-                  <!-- <el-button class="c-btn" type="primary" icon="el-icon-edit" v-if="sa.isAuth('tb-account-list-update')"
-                             @click="update(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>
+	<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="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
+		<script src="https://unpkg.com/element-ui@2.13.0/lib/index.js"></script>
+		<script src="https://unpkg.com/http-vue-loader@1.4.2/src/httpVueLoader.js"></script>
+		<script src="https://unpkg.com/jquery@3.4.1/dist/jquery.js"></script>
+		<script src="https://www.layuicdn.com/layer-v3.1.1/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+		<script src="../../static/node_modules/crypto-js/crypto-js.js"></script>
+		<style>
+			.sum-div {
+				text-align: right;
+				padding: 10px 150px 10px;
+				font-weight: bold;
+			}
+		
+			.sum-title {
+				color: darkred;
+				font-weight: bold;
+			}
+		</style>
+	</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.dutyPeople"></sa-item>
+					<sa-item type="text" name="联系电话" v-model="p.phone"></sa-item>
+					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
+					<el-button  type="info" icon="el-icon-refresh" @click="p.customerName = '';p.dutyPeople='';p.phone=''; f5()">查询</el-button>
+					<br />
+				</el-form>
+				<!-- ------------- 快捷按钮 ------------- -->
+				<!--        <sa-item type="fast-btn" show="add,get,delete,export,reset"></sa-item>-->
+				<!-- ------------- 数据列表 ------------- -->
+				<div class="sum-div">总共 <span
+						class="sum-title">{{dataCount}}</span>条;总金额:<span class="sum-title">¥{{totalMoney}}</span>元</div>
+				<el-table class="data-table" ref="data-table" :data="dataList">
+					<sa-td type="index" name="序号"></sa-td>
+					<sa-td name="企业名称" prop="customerName" width="260"></sa-td>
+					<sa-td name="联系人" prop="dutyPeople"></sa-td>
+					<sa-td name="联系电话" prop="phone"></sa-td>
+					<sa-td name="纳税识别号" prop="taxNum"></sa-td>
+					<sa-td name="开户银行" prop="bank"></sa-td>
+					<sa-td name="银行账户" prop="bankAccount"></sa-td>
+					<sa-td name="余额(元)" prop="totalMoney" not="0" width="120"></sa-td>
+					<el-table-column label="操作" fixed="right" width="180px">
+						<template slot-scope="s">
+							<el-button class="c-btn" type="success" @click="add(s.row)"
+								v-if="sa.isAuth('tb-account-list-add')">充值</el-button>
+							<el-button class="c-btn" type="warning" @click="refundFn(s.row)"
+								v-if="sa.isAuth('tb-account-list-refund')&&s.row.totalMoney>0">退款</el-button>
+							<el-button class="c-btn" type="primary" v-if="sa.isAuth('tb-account-list-update')"
+								@click="update(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>
+				<el-dialog title="退款操作" :visible.sync="refund.visible" :modal="false" width="400px">
+					<div>
+						<el-form>
+							<sa-item type="text" name="企业名称" v-model="refund.form.customerName" :disabled="true" br>
+							</sa-item>
+							<sa-item type="text" name="可退款金额" v-model="refund.form.totalMoney" :disabled="true" br>
+							</sa-item>
+							<sa-item type="num" name="退款金额" v-model="refund.form.refundMoney" br></sa-item>
+							<sa-item type="enum" name="退款方式" br>
+								<el-select v-model="refund.form.payingType">
+									<el-option label="请选择" v-for="(item,index) in payingTypeList" :key="item.id"
+										:label="item.name" :value="item.id">
+									</el-option>
+								</el-select>
+							</sa-item>
+							<sa-item type="textarea" name="退款原因" v-model="refund.form.refundReason" :rows="2" br>
+							</sa-item>
+						</el-form>
+					</div>
+					<span slot="footer" class="dialog-footer">
+						<el-button @click="refund.visible = false">取 消</el-button>
+						<el-button type="primary" @click="sureRefund">确 定</el-button>
+					</span>
+				</el-dialog>
+			</div>
+		</div>
+		<script>
 
-</script>
-<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
-                //		accountNo: '',		// 账户
-                customerName:'',
-                dutyPeople:'',
-                phone:'',
-                taxNum:'',
-                bank:'',
-                bankAccount:'',
-                address:'',
-                totalMoney: '',		// 总金额
-                lastTopupMoney: '',		// 最后充值金额
-                //		status: '',		// 状态(0=禁用,1=启用)
-                createTime: '',		// 创建时间
-                createBy: '',		// 创建人
-                updateTime: '',		// 更新时间
-                updateBy: '',		// 更新人
-                pageNo: 1,		// 当前页
-                pageSize: 10,	// 页大小
-                sortType: 0		// 排序方式
-            },
-            dataCount: 0,
-            dataList: [], // 数据集合
-        },
-        methods: {
-            // 刷新
-            f5: function () {
+		</script>
+		<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: {
+					refund: {
+						visible: false,
+						form: {
+							id: '',
+							money: '',
+							refundMoney: 0,
+							refundReason: '',
+							payingType: 1
+						}
+					},
+					payingTypeList: [],
+					totalMoney:0,
+					p: { // 查询参数
+						id: '', // 主键
+						customerId: '', // 客户id
+						//		accountNo: '',		// 账户
+						customerName: '',
+						dutyPeople: '',
+						phone: '',
+						taxNum: '',
+						bank: '',
+						bankAccount: '',
+						address: '',
+						totalMoney: '', // 总金额
+						lastTopupMoney: '', // 最后充值金额
+						//		status: '',		// 状态(0=禁用,1=启用)
+						createTime: '', // 创建时间
+						createBy: '', // 创建人
+						updateTime: '', // 更新时间
+						updateBy: '', // 更新人
+						pageNo: 1, // 当前页
+						pageSize: 10, // 页大小
+						sortType: 0 // 排序方式
+					},
+					dataCount: 0,
+					dataList: [], // 数据集合
+				},
+				
+				methods: {
+					getSum(){
+						sa.ajax('/TbAccount/getSum', sa.removeNull(this.p), function(res) {
+							this.totalMoney=res.data;
+						}.bind(this));
+					},
+					refundFn(data) {
+						Object.assign(this.refund, {
+							visible: true,
+							form: {
+								id: data.id,
+								customerId: data.customerId,
+								customerName: data.customerName,
+								totalMoney: data.totalMoney,
+								refundMoney: 0,
+								payingType: 1,
+								refundReason: ''
+							}
+						})
+					},
+					sureRefund() {
+						let form = this.refund.form;
+						let refundMoney = form.refundMoney;
+						if (refundMoney <= 0) {
+							sa.error('退款金额须大于0')
+							return;
+						}
+						if (refundMoney > form.totalMoney) {
+							sa.error('退款金额不能大于余额')
+							return;
+						}
+						if (!form.refundReason) {
+							sa.error('请输入退款原因')
+							return;
+						}
+						sa.ajax('/TbAccount/refund/account', form, function(res) {
+							this.refund.visible = false;
+							sa.alert('已退款');
+							this.f5();
+						}.bind(this))
+					},
+					getPayingType() {
+						sa.ajax('/TbAccount/getPayingType', function(res) {
+							this.payingTypeList = res.data;
+						}.bind(this))
+					},
+					printFn() {
+						let p = this.p;
+						sa.showIframe('打印', 'balance-print.html', '1080px', '90%');
+					},
+					// 刷新
+					f5: function() {
+						sa.ajax('/TbAccount/getList', sa.removeNull(this.p), function(res) {
+							this.dataList = res.data; // 数据
+							this.dataCount = res.dataCount; // 数据总数
+							sa.f5TableHeight(); // 刷新表格高度
+							this.getSum();
+						}.bind(this));
+					},
 
-                sa.ajax('/TbAccount/getList', sa.removeNull(this.p), function (res) {
-                    this.dataList = res.data; // 数据
-                    this.dataList.forEach((itm,index) =>{
-                        if(itm.totalMoney){
-                            itm.totalMoney = this.decrypt(itm.totalMoney,itm.salt);
-                        }
-                    })
-                    this.dataCount = res.dataCount; // 数据总数
-                    sa.f5TableHeight();		// 刷新表格高度
-                }.bind(this));
-            },
-           
-            update: function (data) {
-                sa.showIframe('修改数据', 'tb-account-update.html?customerId=' + data.customerId +
-                    '&id='+data.id, '1000px', '90%');
-            },
-            // 新增
-            add: function (data) {
-                sa.showIframe('充值账户', 'tb-account-add.html?customerId=' + data.customerId +
-                    '&id='+data.id, '700px', '70%');
-            },
-            encrypt(word, keyStr) { // word, keyStr第一个参数是加密的字段名字  第二个是key值(16位)
-                if(!word){
-                    return;
-                }
-                if (typeof word === 'object') {
-                    // 如果传入的data是json对象,先转义为json字符串
-                    try {
-                        word = JSON.stringify(word);
-                    } catch (error) {
-                        console.log('error:', error);
-                    }
-                }
-                keyStr = keyStr || 'h!f78tr#L3D$2Z0q'; // 密文(密钥)
-                let key = CryptoJS.enc.Utf8.parse(keyStr);
-                let src = CryptoJS.enc.Utf8.parse(word);
-                let encrypted = CryptoJS.AES.encrypt(src, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7});
-              //  console.log(encrypted.toString())
-                 return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
-            },
-            decrypt(word, keyStr) {
-                if(!word){
-                    return;
-                }
-                keyStr = keyStr || 'h!f78tr#L3D$2Z0q';
-                let base64 = CryptoJS.enc.Base64.parse(word);
-                let src = CryptoJS.enc.Base64.stringify(base64);
-                let key = CryptoJS.enc.Utf8.parse(keyStr);
-                let decrypt = CryptoJS.AES.decrypt(src, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7});
-              //  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
-                return CryptoJS.enc.Utf8.stringify(decrypt).toString();
-            },
+					update: function(data) {
+						sa.showIframe('修改数据', 'tb-account-update.html?customerId=' + data.customerId +
+							'&id=' + data.id, '1000px', '90%');
+					},
+					// 新增
+					add: function(data) {
+						sa.showIframe('充值账户', 'tb-account-add.html?customerId=' + data.customerId +
+							'&id=' + data.id, '700px', '70%');
+					},
+					encrypt(word, keyStr) { // word, keyStr第一个参数是加密的字段名字  第二个是key值(16位)
+						if (!word) {
+							return;
+						}
+						if (typeof word === 'object') {
+							// 如果传入的data是json对象,先转义为json字符串
+							try {
+								word = JSON.stringify(word);
+							} catch (error) {
+								console.log('error:', error);
+							}
+						}
+						keyStr = keyStr || 'h!f78tr#L3D$2Z0q'; // 密文(密钥)
+						let key = CryptoJS.enc.Utf8.parse(keyStr);
+						let src = CryptoJS.enc.Utf8.parse(word);
+						let encrypted = CryptoJS.AES.encrypt(src, key, {
+							mode: CryptoJS.mode.ECB,
+							padding: CryptoJS.pad.Pkcs7
+						});
+						//  console.log(encrypted.toString())
+						return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
+					},
+					decrypt(word, keyStr) {
+						if (!word) {
+							return;
+						}
+						keyStr = keyStr || 'h!f78tr#L3D$2Z0q';
+						let base64 = CryptoJS.enc.Base64.parse(word);
+						let src = CryptoJS.enc.Base64.stringify(base64);
+						let key = CryptoJS.enc.Utf8.parse(keyStr);
+						let decrypt = CryptoJS.AES.decrypt(src, key, {
+							mode: CryptoJS.mode.ECB,
+							padding: CryptoJS.pad.Pkcs7
+						});
+						//  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
+						return CryptoJS.enc.Utf8.stringify(decrypt).toString();
+					},
 
-        },
-        created: function () {
-            this.f5();
-            sa.onInputEnter();
-        }
-    })
-</script>
-</body>
+				},
+				created: function() {
+					this.f5();
+					sa.onInputEnter();
+					this.getPayingType();
+					
+				}
+			})
+		</script>
+	</body>
 </html>

+ 3 - 6
sp-admin/sa-view/tb-account/tb-account-update.html

@@ -36,9 +36,9 @@
                 <sa-item id="ast" type="text" name="纳税识别号" v-model="m.taxNum" br></sa-item>
                 <sa-item id="ast" type="text" name="客户负责人" v-model="m.dutyPeople" br></sa-item>
                 <sa-item id="ast" type="text" name="联系电话" v-model="m.phone" br></sa-item>
-                <sa-item id="ast" type="text" name="开户行" v-model="m.bank" br></sa-item>
-                <sa-item id="ast" type="text" name="银行账号" v-model="m.bankAccount" br></sa-item>
-                <sa-item id="ast" type="text" name="地址" v-model="m.address" br></sa-item>
+                <sa-item  type="text" name="开户行" v-model="m.bank" br></sa-item>
+                <sa-item  type="text" name="银行账号" v-model="m.bankAccount" br></sa-item>
+                <sa-item  type="text" name="地址" v-model="m.address" br></sa-item>
                 <sa-item name="" class="s-ok" br>
                     <el-button type="primary" icon="el-icon-plus" @click="ok()">保存</el-button>
                 </sa-item>
@@ -88,9 +88,6 @@
                 sa.checkNull(m.taxNum, '纳税识别号不能为空!');
                 sa.checkNull(m.phone, '联系电话不能为空!');
                 sa.checkNull(m.dutyPeople, '负责人不能为空!');
-                sa.checkNull(m.bank, '开户行不能为空!');
-                sa.checkNull(m.bankAccount, '银行账户不能为空!');
-                sa.checkNull(m.address, '地址不能为空!');
                 if (!sa.isPhone(m.phone)) {
                     sa.error('请输入正确手机号');
                     return;

+ 41 - 23
sp-admin/sa-view/tb-business-car/tb-business-car-info.html

@@ -62,13 +62,14 @@
 								<sa-info type="img" name="离场图片" :value="m.outImage" br></sa-info>
 							</el-col>
 							<el-col span=8 v-if="m.businessType==1">
-								<sa-info  style="margin-top: 0;" type="enum" name="审核状态"
-									:value="m.confirmJudge" :jv="{0: '未审核', 1: '审核通过', 2: '审核驳回'}" br>
+								<sa-info style="margin-top: 0;" type="enum" name="审核状态" :value="m.confirmJudge"
+									:jv="{0: '未审核', 1: '审核通过', 2: '审核驳回'}" br>
 								</sa-info>
-								<sa-info  style="margin-top: 0;" name="审核人" br>
-									{{m.confirmJudgeBy}}</sa-info>
-								<sa-info  name="审核时间" br>{{m.confirmJudgeTime}}</sa-info>
-								<sa-info  name="审核意见" br v-if="m.confirmJudgeContent">
+								<sa-info style="margin-top: 0;" name="审核人" br>
+									{{m.confirmJudgeBy}}
+								</sa-info>
+								<sa-info name="审核时间" br>{{m.confirmJudgeTime}}</sa-info>
+								<sa-info name="审核意见" br v-if="m.confirmJudgeContent">
 									{{m.confirmJudgeContent}}
 								</sa-info>
 							</el-col>
@@ -82,10 +83,9 @@
 									<el-table :data="businessList" style="width: 100%">
 										<sa-td name="业务单号" prop="no" width="180"></sa-td>
 										<sa-td name="客户名称" prop="customerName" width="200"></sa-td>
-										<sa-td name="货主" prop="owner" width="170"></sa-td>
+										<sa-td name="企业" prop="pickCustomerName" width="170"></sa-td>
 										<sa-td name="业务项" prop="goodsName" width="160"></sa-td>
-										<sa-td name="作业时间" prop="operateTime" width="160"></sa-td>
-										<sa-td name="业务费用(元)" prop="itemPrice" width="120"></sa-td>
+										<sa-td name="费用(元)" prop="itemPrice" width="120"></sa-td>
 										<sa-td name="确认" prop="adminConfirmInput" type="enum" :jv="{1: '已确认', 0: '未确认'}"
 											width="130"></sa-td>
 										<sa-td name="已支付(元)" prop="payMoney" width="140"></sa-td>
@@ -113,9 +113,21 @@
 										</el-table-column>
 										<el-table-column prop="total" label="合计" width="120">
 										</el-table-column>
-										<sa-td width="120" name="支付状态" prop="payStatus" type="enum"
-											:jv="{0: '未支付[#ff0000]', 1: '已支付[#005500]'}" width="130">
-										</sa-td>
+										<el-table-column prop="payStatus" label="支付状态" width="100">
+											<template slot-scope="s">
+												<span v-if="s.row.itemName=='人工、机械装卸车辆'">
+													<span v-if="m.payUnloadMoney==0">未支付</span>
+													<span v-else>已支付</span>
+												</span>
+												<span v-else>
+													<span v-if="s.row.payStatus==1">已支付</span>
+													<span v-else>未支付</span>
+												</span>
+											</template>
+										</el-table-column>
+									
+										<el-table-column prop="refundMoney" label="退款金额">
+										</el-table-column>
 										<el-table-column prop="payTime" label="支付时间" width="140">
 										</el-table-column>
 										<el-table-column prop="remark" label="备注" width="140">
@@ -129,11 +141,12 @@
 			</div>
 			<!-- ------- 底部按钮 ------- -->
 			<div class="s-foot">
-				<el-button v-if="sa.isAuth('tb-business-car-judge')&&m.businessType===1&&m.confirmJudge!=1" class="c-btn"
-					type="success" icon="el-icon" @click="pass()">审核通过</el-button>
-				<el-button v-if="sa.isAuth('tb-business-car-judge')&&m.businessType===1&&m.confirmJudge==1" class="c-btn"
-					type="warning" icon="el-icon" @click="callback()">审核驳回</el-button>
-				<el-button v-if="sa.isAuth('tb-business-car-print')&&m.pay===1&&m.businessType===1" type="success" @click="printFn()">打印</el-button>
+				<el-button v-if="sa.isAuth('tb-business-car-judge')&&m.businessType===1&&m.confirmJudge!=1"
+					class="c-btn" type="success" icon="el-icon" @click="pass()">审核通过</el-button>
+				<el-button v-if="sa.isAuth('tb-business-car-judge')&&m.businessType===1&&m.confirmJudge==1"
+					class="c-btn" type="warning" icon="el-icon" @click="callback()">审核驳回</el-button>
+				<el-button v-if="sa.isAuth('tb-business-car-print')&&m.pay===1&&m.businessType===1" type="success"
+					@click="printFn()">打印</el-button>
 				<el-button type="success" @click="sa.closeCurrIframe()">关闭</el-button>
 			</div>
 		</div>
@@ -150,12 +163,12 @@
 					id: sa.p('id', 0), // 获取数据ID
 					m: {}
 				},
-				computed:{
-					totalMoney(){
-						let businessList=this.businessList;
-						let money=0;
-						for(let i in businessList){
-							money+=parseFloat(businessList[i].itemPrice);
+				computed: {
+					totalMoney() {
+						let businessList = this.businessList;
+						let money = 0;
+						for (let i in businessList) {
+							money += parseFloat(businessList[i].itemPrice);
 						}
 						return money;
 					}
@@ -165,6 +178,11 @@
 						sa.ajax('/TbBusinessCar/confirmJudgePass', {
 							id: this.id
 						}, function(res) {
+							let msg = res.msg;
+							if (msg) {
+								sa.alert(msg, this.clean);
+								return;
+							}
 							sa.alert('审核通过', this.clean);
 						}.bind(this))
 					},

+ 5 - 5
sp-admin/sa-view/tb-business/tb-business-item-supplement.html

@@ -38,14 +38,14 @@
 						<div style="margin-top: 20px;">
 							<div>
 								<div class="c-item">
-									<label class="c-label"><span style="color: red;">*</span>收费项:</label>
+									<label class="c-label"><span style="color: red;">*</span>业务类型:</label>
 									<el-select v-model="m.itemTypeId" placeholder="请选择" filterable @change="itemTypeChange">
 										<el-option :label="type.name" :value="type.id"
 											v-for="(type,index) in businessTypeList">
 										</el-option>
 									</el-select>
 									<div>
-										<label class="c-label"><span style="color: red;">*</span>收费明细:</label>
+										<label class="c-label"><span style="color: red;">*</span>车型:</label>
 										<el-select v-model="m.itemId" placeholder="请选择">
 											<el-option :label="detail.itemName+'('+detail.price+'/'+detail.unit+')'" :value="detail.id"
 												v-for="(detail,i) in items">
@@ -125,16 +125,16 @@
 						// 表单校验
 						let m = this.m;
 						if(!m.itemTypeId){
-							sa.error('请选择收费项')
+							sa.error('请选择业务类型')
 							return;
 						}
 						if(!m.itemId){
-							sa.error('请选择收费明细')
+							sa.error('请选择车型')
 							return;
 						}
 						sa.confirm('是否确认添加该缴费补录?', function () {
 						   sa.ajax('/TbBusinessItem/add', m, function(res) {
-						   	sa.alert('增加成功', this.clean);
+						   	sa.alert('补录成功', this.clean);
 						   }.bind(this));
 						}.bind(this));
 						

+ 51 - 18
sp-admin/sa-view/tb-business/tb-car-disincle-add.html

@@ -81,8 +81,7 @@
 										<el-col span=8>
 											<div class="c-item" v-if="goods.needCustomer">
 												<label class="c-label"><span style="color: red;">*</span>客户:</label>
-												<el-select 
-													v-model="m.customerId" placeholder="请选择" filterable>
+												<el-select v-model="m.customerId" placeholder="请选择" filterable>
 													<el-option v-for="item in customerList" :key="item.id"
 														:label="item.name" :value="item.id">
 													</el-option>
@@ -90,18 +89,26 @@
 											</div>
 											<div class="c-item" v-if="goods.needOperateTime==1">
 												<label class="c-label"><span style="color: red;">*</span>数量(件):</label>
-												<el-input-number class="item-num" v-model="m.businessGoodsNum"
-													:min="1" :max="99999" size="mini">
+												<el-input-number class="item-num" v-model="m.businessGoodsNum" :min="1"
+													:max="99999" size="mini">
 												</el-input-number>
 											</div>
 										</el-col>
 										<el-col span=8>
+											<div class="c-item" v-if="goods.needPartner">
+												<label class="c-label"><span style="color: red;">*</span>合作伙伴:</label>
+												<el-select v-model="m.pickCustomerId" placeholder="请选择" filterable :disabled="partnerDis">
+													<el-option v-for="item in partnerList" :key="item.id"
+														:label="item.name" :value="item.id">
+													</el-option>
+												</el-select>
+											</div>
 											<div class="c-item">
 												<label class="c-label">作业人员:</label>
 												<el-input v-model="m.operator" placeholder="作业人员" clearable>
 												</el-input>
 											</div>
-											
+
 										</el-col>
 									</el-row>
 								</div>
@@ -144,7 +151,7 @@
 								<div>
 									<el-form-item v-for="(type,index) in itemTypeList">
 										<el-row justify="center">
-											<el-col span="16">
+											<el-col span="8">
 												<label style="color: red;"
 													v-if="type.need==1">*</label><label>{{type.name}}:</label>
 												<el-select v-model="type.itemId" style="width: 120px;"
@@ -156,8 +163,7 @@
 											</el-col>
 											<el-col span="8">
 												<el-input-number style="margin-left: 60px;" class="item-num"
-													v-model="type.num" :min="1" :max="10" size="mini"
-													></el-input-number>
+													v-model="type.num" :min="1" :disabled="type.disabled" :max="100" size="mini"></el-input-number>
 												<div class="xj" v-if="type.itemId">
 													{{type.price * type.num}}元
 													<label @click="cleanItem(type)"
@@ -165,6 +171,16 @@
 															class="el-icon-delete"></i>)</label>
 												</div>
 											</el-col>
+											<el-col span="8">
+												<div v-if="(type.itemName&&type.itemName.indexOf('集装箱')!==-1)
+												||(type.itemName&&type.itemName.indexOf('堆存')!==-1)">
+													<label class="c-label">
+														<span style="color: red;">*</span>
+														柜号:</label>
+													<el-input v-model="type.cabinetNo"  placeholder="柜号" clearable>
+													</el-input>
+												</div>
+											</el-col>
 										</el-row>
 										<el-divider></el-divider>
 									</el-form-item>
@@ -275,15 +291,18 @@
 					m: {
 						id: '', // 主键
 						customerId: '', // 客户id
+						pickCustomerId:'',
 						customerName: '', // 客户名称
 						operateTime: '',
 						no: '', // 编号
 						goodsId: '',
 						goodsName: '', // 商品
-						businessGoodsNum:1,
-						businessGoodsName:''
+						businessGoodsNum: 1,
+						businessGoodsName: ''
 					}, // 实体对象
+					partnerDis:false,
 					customerList: [],
+					partnerList: [],
 					carList: [],
 					currentCustomerId: 1,
 					itemTypeList: [],
@@ -438,13 +457,18 @@
 						type.price = '';
 					},
 					itemChange(type) {
-						if(this.validBefore()){
+						if (this.validBefore()) {
 							let itemId = type.itemId;
 							let item = type.items.filter(obj => obj.id == itemId).pop();
 							if (item) {
 								type.inc = item.inc;
 								type.price = item.price;
-								type.needRemark = item.needRemark
+								type.needRemark = item.needRemark;
+								type.disabled=false;
+								type.itemName=item.itemName;
+								if(item.itemName=='人工、机械装卸车辆'){
+									type.disabled=true;
+								}
 							}
 						}
 					},
@@ -570,7 +594,7 @@
 							goodsId: this.m.goodsId
 						}, function(resp) {
 							let list = resp.data;
-							this.itemTypeList = list.filter(type=>type.status==1);
+							this.itemTypeList = list.filter(type => type.status == 1);
 							console.log(this.itemTypeList);
 							this.filterTypeList = JSON.parse(JSON.stringify(this.itemTypeList));
 							this.filterItems();
@@ -597,6 +621,8 @@
 						}, function(res) {
 							let list = res.data;
 							this.customerList = list;
+							this.partnerList = list.filter(obj => obj.type != 0);
+							this.getCurrentCustomer();
 						}.bind(this));
 					},
 					queryCarAsync(queryStr, cb) {
@@ -618,7 +644,7 @@
 							sa.error('请选择客户');
 							return false;
 						}
-						if (goods.needOperateTime == 1 &&(!m.businessGoodsNum||m.businessGoodsNum<=0) ) {
+						if (goods.needOperateTime == 1 && (!m.businessGoodsNum || m.businessGoodsNum <= 0)) {
 							sa.error('请输入件数');
 							return false;
 						}
@@ -650,12 +676,12 @@
 							sa.error('请选择客户');
 							return false;
 						}
-						
+
 						if (!m.businessGoodsName && goods.needOwner == 1) {
 							sa.error('请填写货物');
 							return false;
 						}
-						if (goods.needOperateTime == 1 && (!m.businessGoodsNum||m.businessGoodsNum<=0)) {
+						if (goods.needOperateTime == 1 && (!m.businessGoodsNum || m.businessGoodsNum <= 0)) {
 							sa.error('请填写货物件数');
 							return false;
 						}
@@ -692,7 +718,8 @@
 									id: type.itemId,
 									num: type.num,
 									price: type.price,
-									remark: type.remark
+									remark: type.remark,
+									cabinetNo:type.cabinetNo
 								}
 								selectList.push(obj);
 							}
@@ -725,11 +752,17 @@
 						sa.ajax('/TbCostomer/getCurrentCustomerId', function(resp) {
 							let id = resp.data;
 							this.currentCustomerId = id;
+							let partnerList = this.partnerList;
+							let arr = partnerList.filter(obj => obj.id == id);
+							if(arr.length>0){
+								this.m.pickCustomerId=id;
+								this.partnerDis=true;
+								this.m.customerId=id;
+							}
 						}.bind(this));
 					},
 				},
 				mounted: function() {
-					this.getCurrentCustomer();
 					this.getGoods();
 					this.getItemType();
 					this.getCustomerList();

+ 63 - 22
sp-admin/sa-view/tb-business/tb-car-disincle-edit.html

@@ -66,38 +66,49 @@
 													</el-option>
 												</el-select>
 											</div>
+											<div class="c-item" v-if="goods.needOwner==1">
+												<label class="c-label">
+													<span style="color: red;">*</span>
+													货物名称:</label>
+												<el-input v-model="m.businessGoodsName" placeholder="填写货物" clearable>
+												</el-input>
+											</div>
 										</el-col>
 										<el-col span=8>
 											<div class="c-item" v-if="goods.needCustomer">
 												<label class="c-label"><span style="color: red;">*</span>客户:</label>
-												<el-select
-													:disabled="currentCustomerId!='1'"
-													v-model="m.customerId" placeholder="请选择" filterable>
+												<el-select :disabled="currentCustomerId!='1'" v-model="m.customerId"
+													placeholder="请选择" filterable>
 													<el-option v-for="item in customerList" :key="item.id"
 														:label="item.name" :value="item.id">
 													</el-option>
 												</el-select>
 											</div>
-											<div class="c-item" v-if="goods.needOwner==1">
-												<label class="c-label">
-													<span style="color: red;">*</span>
-													货物名称:</label>
-												<el-input v-model="m.businessGoodsName" placeholder="填写货物" clearable>
-												</el-input>
+
+											<div class="c-item" v-if="goods.needOperateTime==1">
+												<label class="c-label"><span style="color: red;">*</span>数量(件):</label>
+												<el-input-number class="item-num" v-model="m.businessGoodsNum" :min="1"
+													:max="99999" size="mini">
+												</el-input-number>
 											</div>
+
 										</el-col>
 										<el-col span=8>
+											<div class="c-item" v-if="goods.needPartner">
+												<label class="c-label"><span style="color: red;">*</span>合作伙伴:</label>
+												<el-select v-model="m.pickCustomerId" placeholder="请选择" filterable
+													:disabled="partnerDis">
+													<el-option v-for="item in partnerList" :key="item.id"
+														:label="item.name" :value="item.id">
+													</el-option>
+												</el-select>
+											</div>
 											<div class="c-item">
 												<label class="c-label">作业人员:</label>
 												<el-input v-model="m.operator" placeholder="作业人员" clearable>
 												</el-input>
 											</div>
-											<div class="c-item" v-if="goods.needOperateTime==1">
-												<label class="c-label"><span style="color: red;">*</span>数量(件):</label>
-												<el-input-number class="item-num" v-model="m.businessGoodsNum" :min="1"
-													:max="99999" size="mini">
-												</el-input-number>
-											</div>
+
 										</el-col>
 									</el-row>
 								</div>
@@ -140,7 +151,7 @@
 								<div>
 									<el-form-item v-for="(type,index) in itemTypeList">
 										<el-row justify="center">
-											<el-col span="16">
+											<el-col span="8">
 												<label style="color: red;"
 													v-if="type.need==1">*</label><label>{{type.name}}:</label>
 												<el-select v-model="type.itemId" style="width: 120px;"
@@ -152,7 +163,8 @@
 											</el-col>
 											<el-col span="8">
 												<el-input-number style="margin-left: 60px;" class="item-num"
-													v-model="type.num" :min="1" :max="10" size="mini"></el-input-number>
+													v-model="type.num" :min="1" :max="100" size="mini"
+													:disabled="type.disabled"></el-input-number>
 												<div class="xj" v-if="type.itemId">
 													{{type.price * type.num}}元
 													<label @click="cleanItem(type)"
@@ -160,6 +172,16 @@
 															class="el-icon-delete"></i>)</label>
 												</div>
 											</el-col>
+											<el-col span="8">
+												<div v-if="(type.itemName&&type.itemName.indexOf('集装箱')!==-1)
+												||(type.itemName&&type.itemName.indexOf('堆存')!==-1)">
+													<label class="c-label">
+														<span style="color: red;">*</span>
+														柜号:</label>
+													<el-input v-model="type.cabinetNo" placeholder="柜号" clearable>
+													</el-input>
+												</div>
+											</el-col>
 										</el-row>
 										<el-divider></el-divider>
 									</el-form-item>
@@ -276,7 +298,9 @@
 						goodsId: '',
 						goodsName: '', // 商品
 					}, // 实体对象
+					partnerDis: false,
 					customerList: [],
+					partnerList: [],
 					carList: [],
 					currentCustomerId: 1,
 					itemTypeList: [],
@@ -420,7 +444,7 @@
 									}
 								})
 							}
-							this.filterItems();
+							// this.filterItems();
 						}
 						this.declare.visible = false;
 					},
@@ -435,7 +459,13 @@
 						if (item) {
 							type.inc = item.inc;
 							type.price = item.price;
+							type.disabled = false;
+							type.itemName = item.itemName;
+							if (item.itemName == '人工、机械装卸车辆') {
+								type.disabled = true;
+							}
 						}
+						console.log(type);
 						this.validBefore();
 					},
 					confirmAdd() {
@@ -480,7 +510,7 @@
 							}
 						}
 
-						this.filterItems();
+						// this.filterItems();
 					},
 					filterItems() {
 						let carList = this.car.list;
@@ -582,6 +612,8 @@
 										type.price = initItem.itemPrice;
 										type.itemId = initItem.itemId;
 										type.remark = initItem.remark;
+										type.itemName= initItem.itemName;
+										type.cabinetNo=initItem.cabinetNo
 									}
 								}
 							}
@@ -611,6 +643,8 @@
 						}, function(res) {
 							let list = res.data;
 							this.customerList = list;
+							this.partnerList = list.filter(obj => obj.type != 0);
+							this.getCurrentCustomer();
 						}.bind(this));
 					},
 					queryCarAsync(queryStr, cb) {
@@ -663,7 +697,7 @@
 							sa.error('请填写货物');
 							return false;
 						}
-						if (goods.needOperateTime == 1 && (!m.businessGoodsNum||m.businessGoodsNum<=0)) {
+						if (goods.needOperateTime == 1 && (!m.businessGoodsNum || m.businessGoodsNum <= 0)) {
 							sa.error('请填写货物件数');
 							return false;
 						}
@@ -696,7 +730,8 @@
 									id: type.itemId,
 									num: type.num,
 									price: type.price,
-									remark: type.remark
+									remark: type.remark,
+									cabinetNo:type.cabinetNo
 								}
 								selectList.push(obj);
 							}
@@ -729,6 +764,12 @@
 						sa.ajax('/TbCostomer/getCurrentCustomerId', function(resp) {
 							let id = resp.data;
 							this.currentCustomerId = id;
+							let partnerList = this.partnerList;
+							let arr = partnerList.filter(obj => obj.id == id);
+							if (arr.length > 0) {
+								this.m.pickCustomerId = id;
+								this.partnerDis = true;
+							}
 						}.bind(this));
 					},
 					getOtherBusinessById() {
@@ -742,7 +783,7 @@
 					},
 				},
 				mounted: function() {
-					this.getCurrentCustomer();
+
 					this.getOtherBusinessById();
 					this.getCustomerList();
 					this.getItemType();

+ 223 - 0
sp-admin/sa-view/tb-business/tb-car-disincle-error-add.html

@@ -0,0 +1,223 @@
+<!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>
+		<script src="../../static/sa.js"></script>
+		<script src="../../static/kj/upload-util.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">
+						<el-row>
+							<el-collapse value='1'>
+								<el-collapse-item name="1">
+									<div slot="title">
+										基础资料
+									</div>
+									<div>
+										<el-row>
+											<el-col span="12">
+												<sa-info name="客户名称" br v-if="m.customerName">{{m.customerName}}
+												</sa-info>
+												<sa-info name="业务项目" br>{{m.goodsName}}</sa-info>
+												<!-- <sa-info name="作业时间" br>{{m.operateTime}}</sa-info> -->
+												<sa-info name="业务费用" br>{{m.itemPrice}}(元)</sa-info>
+												<sa-info name="货物名称" br v-if="m.businessGoodsName">{{m.businessGoodsName}}</sa-info>
+												<sa-info name="数量(件)" br v-if="m.businessGoodsNum">{{m.businessGoodsNum}}</sa-info>
+												<sa-info name="补录人" br v-if="m.supplementBy">{{m.supplementBy}}
+												</sa-info>
+												<sa-info name="补录时间" br v-if="m.supplementTime">{{m.supplementTime}}
+												</sa-info>
+												<sa-info name="补录原因" br v-if="m.supplementReason">{{m.supplementReason}}
+												</sa-info>
+												<sa-info type="enum" name="OA流程" :value="m.sendOa"
+													:jv="{0: '未发起', 1: '已发起'}" br v-if="m.supplementTime">
+												</sa-info>
+
+											</el-col>
+											<el-col span="12">
+												<sa-info name="企业" br v-if="m.pickCustomerName">{{m.pickCustomerName}}</sa-info>
+												<sa-info name="业务编号" br>{{m.no}}</sa-info>
+												<sa-info name="录入时间" br>{{m.createTime}}</sa-info>
+												<!-- <sa-info name="录入人" br>{{m.createBy}}</sa-info> -->
+												<sa-info style="margin-top: 0;" type="enum" name="支付状态"
+													:value="m.payStatus" :jv="{1: '未支付', 2: '已支付未确认', 3: '已支付'}">
+												</sa-info>
+												<sa-info name="已支付金额(元)" br>{{m.payMoney}}</sa-info>
+												<sa-info name="支付时间" br>{{m.payTime}}</sa-info>
+												<sa-info name="发起人" br v-if="m.sendBy">{{m.sendBy}}</sa-info>
+												<sa-info name="发起时间" br v-if="m.sendTime">{{m.sendTime}}</sa-info>
+												<sa-info name="审批结果" br v-if="m.oaResult">{{m.oaResult}}</sa-info>
+												<sa-info name="审批意见" br v-if="m.oaContent">{{m.oaContent}}</sa-info>
+											</el-col>
+										</el-row>
+									</div>
+								</el-collapse-item>
+							</el-collapse>
+
+						</el-row>
+						<el-row>
+							<el-collapse value='1'>
+								<el-collapse-item name="1">
+									<div slot="title">
+										车辆信息
+									</div>
+									<el-table :data="m.cars" style="width: 100%">
+										<sa-td name="车牌号" prop="carNo"></sa-td>
+										<sa-td name="类型" prop="carType"></sa-td>
+										<sa-td name="载重(kg)" prop="netWeight"></sa-td>
+										<sa-td name="规格(米)" prop="carSize"></sa-td>
+
+										<sa-td width="120" name="车辆状态" prop="isLock" type="enum"
+											:jv="{1: '锁定[#ff0000]', 0: '正常[#005500]'}">
+										</sa-td>
+										<sa-td name="入场时间" prop="realInTime" width=180></sa-td>
+										<sa-td name="离场时间" prop="realOutTime" width=180></sa-td>
+										<el-table-column label="停车费">
+											<template slot-scope="s">
+												<label v-if="s.row.money">{{s.row.money}}</label>
+												<label v-else>-</label>
+											</template>
+										</el-table-column>
+										<sa-td width="130" name="支付状态" prop="payType">
+										</sa-td>
+										<el-table-column prop="payTime" label="支付时间" width="150">
+										</el-table-column>
+									</el-table>
+								</el-collapse-item>
+							</el-collapse>
+						</el-row>
+						<el-row>
+							<div style="display: flex;margin-top: 10px;">
+								<div>
+									具体业务项
+									<label
+										style="color: red; font-weight: bold;margin-left: 20px;">合计:({{m.itemPrice}}元)
+									</label>
+								</div>
+								<div>
+									<el-button v-if="sa.isAuth('tb-business-item-supplement')" type="primary"
+										style="position: absolute;right: 40px;" @click="supplementFn">补交费
+									</el-button>
+								</div>
+							</div>
+							<el-table :data="tableData" style="width: 100%;margin-top: 20px;">
+								<el-table-column prop="itemTypeName" label="业务类型" width="180">
+								</el-table-column>
+								<el-table-column prop="itemName" label="车型" width="180">
+								</el-table-column>
+								<el-table-column prop="itemPrice" label="单价">
+								</el-table-column>
+								<el-table-column prop="unit" label="计费标准">
+								</el-table-column>
+								<el-table-column prop="num" label="数量">
+								</el-table-column>
+								<el-table-column prop="total" label="合计">
+								</el-table-column>
+								<sa-td width="120" name="支付状态" prop="payStatus" type="enum"
+									:jv="{0: '未支付[#ff0000]', 1: '已支付[#005500]'}">
+								</sa-td>
+								<el-table-column prop="payTime" label="支付时间" width="150">
+								</el-table-column>
+								<sa-td width="120" name="订单状态" prop="hasError" type="enum"
+									:jv="{0: '正常[#005500]', 1: '异常[#ff0000]'}">
+								</sa-td>
+								
+							</el-table>
+						</el-row>
+					</el-form>
+				</div>
+			</div>
+			<!-- ------- 底部按钮 ------- -->
+			<div class="s-foot">
+				<!-- <el-button class="c-btn" type="success" icon="el-icon" @click="print()">打印单据</el-button> -->
+				<el-button type="success" @click="sa.closeCurrIframe()">关闭</el-button>
+			</div>
+
+			<el-dialog title="上传凭据" :visible.sync="upload.visible" width="400">
+				<el-form>
+					<sa-item type="img-list" name="凭据图片" v-model="upload.form.ticket" br></sa-item>
+				</el-form>
+				<span slot="footer" class="dialog-footer">
+					<el-button @click="upload.visible=false">取 消</el-button>
+					<el-button type="primary" @click="ok()">确 定</el-button>
+				</span>
+			</el-dialog>
+
+		</div>
+		<script>
+			var app = new Vue({
+				components: {
+					"sa-info": httpVueLoader('../../sa-frame/com/sa-info.vue'),
+					"sa-item": httpVueLoader('../../sa-frame/com/sa-item.vue'),
+					"sa-td": httpVueLoader('../../sa-frame/com/sa-td.vue'),
+				},
+				el: '.vue-box',
+				data: {
+					id: sa.p('id', 0), // 获取数据ID
+					m: null,
+					tableData: [],
+					upload: {
+						visible: false,
+						form: {
+							id: '',
+							ticket: ''
+						}
+					}
+				},
+				methods: {
+					print: function() {
+						sa.showIframe('打印收费单据', 'print.html?id=' + this.id, '1000px', '100%');
+					},
+					uploadFn(data) {
+						Object.assign(this.upload, {
+							visible: true,
+							form: data
+						})
+					},
+					del(data) {
+						sa.confirm('是否确认删除该收费项?', function() {
+							sa.ajax('/TbBusinessItem/del', {
+								id: data.id
+							}, function(res) {
+								sa.alert('已删除', this.getInfo());
+							}.bind(this));
+						}.bind(this));
+					},
+					supplementFn() {
+						sa.showIframe('补交费', 'tb-business-item-supplement.html?id=' + this.m.id, '600px', '70%');
+					},
+					getInfo() {
+						sa.ajax('/TbBusiness/getOtherBusinessById?id=' + this.id, function(res) {
+							this.m = res.data;
+							this.tableData = res.data.items;
+						}.bind(this))
+					}
+				},
+				mounted: function() {
+					this.getInfo()
+				}
+			})
+		</script>
+	</body>
+</html>

+ 36 - 19
sp-admin/sa-view/tb-business/tb-car-disincle-info.html

@@ -42,8 +42,12 @@
 												<sa-info name="业务项目" br>{{m.goodsName}}</sa-info>
 												<!-- <sa-info name="作业时间" br>{{m.operateTime}}</sa-info> -->
 												<sa-info name="业务费用" br>{{m.itemPrice}}(元)</sa-info>
-												<sa-info name="货物名称" br v-if="m.businessGoodsName">{{m.businessGoodsName}}</sa-info>
-												<sa-info name="数量(件)" br v-if="m.businessGoodsNum">{{m.businessGoodsNum}}</sa-info>
+												<sa-info name="货物名称" br v-if="m.businessGoodsName">
+													{{m.businessGoodsName}}
+												</sa-info>
+												<sa-info name="数量(件)" br v-if="m.businessGoodsNum">
+													{{m.businessGoodsNum}}
+												</sa-info>
 												<sa-info name="补录人" br v-if="m.supplementBy">{{m.supplementBy}}
 												</sa-info>
 												<sa-info name="补录时间" br v-if="m.supplementTime">{{m.supplementTime}}
@@ -56,13 +60,15 @@
 
 											</el-col>
 											<el-col span="12">
-												<!-- <sa-info name="货主" br>{{m.owner}}</sa-info> -->
+												<sa-info name="企业" br v-if="m.pickCustomerName">{{m.pickCustomerName}}
+												</sa-info>
 												<sa-info name="业务编号" br>{{m.no}}</sa-info>
 												<sa-info name="录入时间" br>{{m.createTime}}</sa-info>
 												<!-- <sa-info name="录入人" br>{{m.createBy}}</sa-info> -->
 												<sa-info style="margin-top: 0;" type="enum" name="支付状态"
-													:value="m.payStatus" :jv="{1: '未支付', 2: '已支付未确认', 3: '已支付'}" br>
+													:value="m.payStatus" :jv="{1: '未支付', 2: '已支付未确认', 3: '已支付'}">
 												</sa-info>
+												<sa-info name="已支付金额(元)" br>{{m.payMoney}}</sa-info>
 												<sa-info name="支付时间" br>{{m.payTime}}</sa-info>
 												<sa-info name="发起人" br v-if="m.sendBy">{{m.sendBy}}</sa-info>
 												<sa-info name="发起时间" br v-if="m.sendTime">{{m.sendTime}}</sa-info>
@@ -86,10 +92,6 @@
 										<sa-td name="类型" prop="carType"></sa-td>
 										<sa-td name="载重(kg)" prop="netWeight"></sa-td>
 										<sa-td name="规格(米)" prop="carSize"></sa-td>
-
-										<sa-td width="120" name="车辆状态" prop="isLock" type="enum"
-											:jv="{1: '锁定[#ff0000]', 0: '正常[#005500]'}">
-										</sa-td>
 										<sa-td name="入场时间" prop="realInTime" width=180></sa-td>
 										<sa-td name="离场时间" prop="realOutTime" width=180></sa-td>
 										<el-table-column label="停车费">
@@ -115,36 +117,42 @@
 									</label>
 								</div>
 								<div>
-									<el-button v-if="sa.isAuth('tb-business-item-supplement')" type="primary"
-										style="position: absolute;right: 40px;" @click="supplementFn">补交费
+									<el-button v-if="sa.isAuth('tb-business-item-supplement&&m.hasError==1')" type="primary"
+										style="position: absolute;right: 40px;" @click="supplementFn">补录单
 									</el-button>
 								</div>
 							</div>
 							<el-table :data="tableData" style="width: 100%;margin-top: 20px;">
-								<el-table-column prop="itemTypeName" label="收费项" width="180">
+								<el-table-column prop="itemTypeName" label="业务类型" width="180">
 								</el-table-column>
-								<el-table-column prop="itemName" label="收费明细" width="180">
+								<el-table-column prop="itemName" label="车型" width="180">
 								</el-table-column>
 								<el-table-column prop="itemPrice" label="单价">
 								</el-table-column>
 								<el-table-column prop="unit" label="计费标准">
 								</el-table-column>
+								<el-table-column prop="cabinetNo" label="柜号">
+									
+								</el-table-column>
 								<el-table-column prop="num" label="数量">
 								</el-table-column>
 								<el-table-column prop="total" label="合计">
 								</el-table-column>
 								<sa-td width="120" name="支付状态" prop="payStatus" type="enum"
-									:jv="{0: '未支付[#ff0000]', 1: '已支付[#005500]'}">
+									:jv="{0: '未支付[#ff0000]', 1: '已支付[#005500]', 4: '已退款[#ff0000]'}">
 								</sa-td>
-								<el-table-column prop="payTime" label="支付时间" width="150">
+								<el-table-column prop="refundMoney" label="退款金额">
 								</el-table-column>
-								<el-table-column prop="remark" label="备注" width="150">
+								<el-table-column prop="payTime" label="支付时间" width="150">
 								</el-table-column>
-								<el-table-column label="操作" width="100px" fixed="right">
+								<sa-td width="120" name="订单状态" prop="hasError" type="enum"
+									:jv="{0: '正常[#005500]', 1: '异常[#ff0000]'}">
+								</sa-td>
+								<el-table-column label="操作" width="60px" fixed="right">
 									<template slot-scope="s">
-										<el-button class="c-btn" type="danger"
-											v-if="sa.isAuth('tb-business-item-supplement')&&s.row.payStatus==0"
-											@click="del(s.row)">删除
+										<el-button class="c-btn" type="warning" v-if="s.row.payStatus==0"
+											@click="delFn(s.row)">
+											删除
 										</el-button>
 									</template>
 								</el-table-column>
@@ -191,6 +199,15 @@
 					}
 				},
 				methods: {
+					delFn(data) {
+						sa.confirm('是否确认删除该收费项?', function() {
+							sa.ajax('/TbBusinessItem/del', {
+								id: data.id
+							}, function(res) {
+								sa.alert('已删除', this.getInfo());
+							}.bind(this));
+						}.bind(this));
+					},
 					print: function() {
 						sa.showIframe('打印收费单据', 'print.html?id=' + this.id, '1000px', '100%');
 					},

+ 74 - 19
sp-admin/sa-view/tb-business/tb-car-disincle-list.html

@@ -42,6 +42,7 @@
 					<sa-item type="text" name="业务单号" placeholder="业务单号" v-model="p.no"></sa-item>
 					<sa-item type="text" name="车牌号" placeholder="车牌号" v-model="p.carNo"></sa-item>
 					<sa-item type="text" name="客户" placeholder="客户" v-model="p.customerName"></sa-item>
+					<sa-item type="text" name="合作伙伴" placeholder="合作伙伴" v-model="p.pickCustomerName"></sa-item>
 					<div class="c-item">
 						<label class="c-label">确认状态:</label>
 						<el-select v-model="p.adminConfirmInput" placeholder="请选择" @change="f5()">
@@ -51,27 +52,36 @@
 						</el-select>
 					</div>
 					<div class="c-item">
+						<label class="c-label">状态:</label>
+						<el-select v-model="p.hasError" placeholder="请选择" @change="f5()">
+							<el-option label="全部" :value="-1"></el-option>
+							<el-option label="正常" :value="0"></el-option>
+							<el-option label="异常" :value="1"></el-option>
+						</el-select>
+					</div>
+					<div class="c-item">
 						<label class="c-label">业务项:</label>
 						<el-select v-model="p.goodsId">
 							<el-option v-for="good in goodsList" :key="good.id" :label="good.name" :value="good.id">
 							</el-option>
 						</el-select>
 					</div>
-			
-					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
-					<el-button type="info" icon="el-icon-search"
-						@click="p.carNo = '';p.adminConfirmInput=-1;p.customerName='';p.owner='';p.no=''; f5()">重置
-					</el-button>
-					<el-button v-if="sa.isAuth('tb-flex-business-add')" size="mini" type="primary" @click="add()">
-						新增
-					</el-button>
-					<br />
+					<div>
+						<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
+						<el-button type="info" icon="el-icon-search"
+							@click="p.carNo = '';p.adminConfirmInput=-1;p.customerName='';p.pickCustomerName='';p.owner='';p.no=''; f5()">重置
+						</el-button>
+						<el-button v-if="sa.isAuth('tb-flex-business-add')" size="mini" type="primary" @click="add()">
+							新增
+						</el-button>
+					</div>
 				</el-form>
 				<!-- ------------- 数据列表 ------------- -->
 				<el-table class="data-table" ref="data-table" :data="dataList" style="margin-top: 20px;">
-					<el-table-column type="index" width="50"></el-table-column>
+					<el-table-column type="index" name="序号" width="50"></el-table-column>
 					<sa-td name="业务单号" prop="no" width="160"></sa-td>
 					<sa-td name="客户名称" prop="customerName" width="190"></sa-td>
+					<sa-td name="合作伙伴" prop="pickCustomerName" width="190"></sa-td>
 					<sa-td name="货物名称" prop="businessGoodsName" width="160"></sa-td>
 					<sa-td name="业务项" prop="goodsName" width="160"></sa-td>
 					<el-table-column label="车牌号" width="160">
@@ -80,13 +90,14 @@
 						</template>
 					</el-table-column>
 					<sa-td name="支付时间" prop="payTime" width="160"></sa-td>
-					
+
 					<sa-td name="确认" prop="adminConfirmInput" type="enum" :jv="{1: '已确认', 0: '未确认'}"></sa-td>
 					<sa-td name="已支付(元)" prop="payMoney" width="140"></sa-td>
 					<sa-td name="业务费用(元)" prop="itemPrice" width="120"></sa-td>
+					<sa-td name="业务状态" prop="hasError" type="enum" :jv="{1: '异常[#ff0000]', 0: '正常[#005500]'}"></sa-td>
 					<sa-td width="160" name="创建时间" prop="createTime"></sa-td>
 					</sa-td>
-					<el-table-column label="操作" width="415px" fixed="right">
+					<el-table-column label="操作" width="300px" fixed="right">
 						<template slot-scope="s">
 							<el-button class="c-btn" type="primary" v-if="sa.isAuth('tb-flex-business-confirm')
 								&&currentCustomerId=='1'&&s.row.adminConfirmInput==0" @click="confirmFn(s.row)">账单确认
@@ -101,15 +112,12 @@
 								修改
 							</el-button>
 							<el-button v-if="sa.isAuth('tb-flex-business-edit')" class="c-btn" type="primary"
-								@click="carFn(s.row)">车辆管理
-							</el-button>
-							<el-button class="c-btn" type="primary" v-if="(currentCustomerId=='1'||(sa.isAuth('tb-flex-business-pay')))
-								&&s.row.payStatus!=3" @click="handlerPay(s.row)">
-								线下收费
+								@click="carFn(s.row)">业务车辆
 							</el-button>
+							<!-- 
 							<el-button v-if="sa.isAuth('tb-business-car-bind')" class="c-btn" type="primary"
 								@click="businessFn(s.row)">绑定车辆
-							</el-button>
+							</el-button> -->
 							<el-button v-if="sa.isAuth('tb-business-zx-print')&&zxShow(s.row.goodsName)" class="c-btn"
 								type="success" @click="zxPrint(s.row.id)">装卸打印
 							</el-button>
@@ -117,6 +125,9 @@
 								v-if="sa.isAuth('tb-flex-business-del')&&s.row.adminConfirmInput==0&&s.row.payMoney==0"
 								@click="del(s.row)">删除
 							</el-button>
+							<el-button class="c-btn" type="warning" v-if="s.row.hasError==1" @click="addErrorFn(s.row)">
+								补录单
+							</el-button>
 						</template>
 					</el-table-column>
 				</el-table>
@@ -145,6 +156,29 @@
 					</div>
 				</span>
 			</el-dialog>
+			<el-dialog title="补录异常单" :visible.sync="error.visible" width="500px">
+				<div class="confirm-info">
+					<el-form label-position="left">
+						<sa-info name="订单号" br>{{error.form.no}}</sa-info>
+						<div class="c-item">
+							<label class="c-label"><span style="color: red;">*</span>补录业务:</label>
+							<el-select v-model="error.form.itemId" placeholder="请选择" filterable>
+								<el-option v-for="item in itemList" :key="item.id" :label="item.itemName"
+									:value="item.id">
+								</el-option>
+							</el-select>
+						</div>
+					</el-form>
+				</div>
+				<span slot="footer" class="dialog-footer">
+					<div>
+						<el-button @click="error.visible = false">取 消</el-button>
+						<el-button type="primary" @click="sureAddFn">保 存</el-button>
+					</div>
+
+				</span>
+			</el-dialog>
+
 		</div>
 		<script>
 			var app = new Vue({
@@ -157,6 +191,12 @@
 				data: {
 					value: '',
 					currentCustomerId: '1',
+					error: {
+						visible: false,
+						form: {
+
+						}
+					},
 					confirm: {
 						visible: false,
 						title: '',
@@ -165,8 +205,10 @@
 						}
 					},
 					p: { // 查询参数
+						hasError: -1,
 						adminConfirmInput: -1,
-						confirmJudge:'',
+						pickCustomerName:'',
+						confirmJudge: '',
 						customerName: '',
 						supplement: 0,
 						owner: '',
@@ -178,6 +220,7 @@
 						sortType: 0 // 排序方式
 					},
 					dataCount: 0,
+					itemList: [],
 					dataList: [], // 数据集合
 					timmer: null,
 					fresh: {
@@ -186,6 +229,17 @@
 					goodsList: [],
 				},
 				methods: {
+					sureAddFn() {
+
+					},
+					addErrorFn(data) {
+						sa.showIframe('补录单', 'tb-business-item-supplement.html?id=' + data.id, '600px', '60%');
+					},
+					getItemList() {
+						sa.ajax('/TbItem/getList', function(resp) {
+							this.itemList = resp.data;
+						}.bind(this));
+					},
 					judgeFn(data) {
 						this.stopTimmer();
 						sa.showIframe('业务审核', 'tb-business-judge.html?id=' + data.id, '1050px', '90%');
@@ -324,6 +378,7 @@
 				mounted() {
 					this.getCurrendCustomer();
 					this.getGoodsList();
+					this.getItemList();
 					this.f5();
 				},
 				beforeDestroy() {

+ 0 - 5
sp-admin/sa-view/tb-charge-record/tb-charge-record-add.html

@@ -43,8 +43,6 @@
 						<sa-item type="text" name="付款方式" v-model="m.payingType" br></sa-item>
 						<sa-item type="text" name="充值说明" v-model="m.remark" br></sa-item>
 						<sa-item type="text" name="复核时间" v-model="m.reviewTime" br></sa-item>
-						<sa-item type="text" name="有效状态,0-无效已删除、1-有效" v-model="m.status" br></sa-item>
-						<sa-item type="text" name="盐" v-model="m.salt" br></sa-item>
 						<sa-item name="" class="s-ok" br>
 							<el-button type="primary" icon="el-icon-plus" @click="ok()">保存</el-button>
 						</sa-item>
@@ -97,9 +95,6 @@
 					ok: function(){
 						// 表单校验 
 						let m = this.m;
-						sa.checkNull(m.id, '请输入 [主键]');
-						sa.checkNull(m.accountId, '请输入 [客户账户id]');
-						sa.checkNull(m.customerId, '请输入 [客户id]');
 						sa.checkNull(m.customerName, '请输入 [客户名称]');
 						sa.checkNull(m.money, '请输入 [充值金额]');
 						sa.checkNull(m.payMoney, '请输入 [支付金额]');

+ 140 - 85
sp-admin/sa-view/tb-charge-record/tb-charge-record-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="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css">
 		<link rel="stylesheet" href="../../static/sa.css">
@@ -24,97 +25,140 @@
 
 					<sa-item type="text" name="客户名称" v-model="p.customerName"></sa-item>
 					<sa-item type="daterange" name="充值时间">
-						<el-date-picker
-								v-model="p.createTime"
-								type="daterange"
-								align="right"
-								unlink-panels
-								value-format="yyyy-MM-dd"
-								range-separator="至"
-								start-placeholder="开始日期"
-								end-placeholder="结束日期"
-								:picker-options="pickerOptions">
+						<el-date-picker v-model="p.createTime" type="daterange" align="right" unlink-panels
+							value-format="yyyy-MM-dd" range-separator="至" start-placeholder="开始日期"
+							end-placeholder="结束日期" :picker-options="pickerOptions">
 						</el-date-picker>
 					</sa-item>
-					<sa-item  name="复核状态" >
+					<sa-item name="复核状态">
 						<el-select v-model="p.reviewStatus" clearable placeholder="请选择">
-							<el-option
-									v-for="item in reviewStatusList"
-									:key="item.id"
-									:label="item.name"
-									:value="item.id">
+							<el-option v-for="item in reviewStatusList" :key="item.id" :label="item.name"
+								:value="item.id">
+							</el-option>
+						</el-select>
+					</sa-item>
+					<sa-item name="类型">
+						<el-select v-model="p.type" clearable placeholder="请选择">
+							<el-option v-for="item in typeList" :key="item.id" :label="item.name" :value="item.id">
 							</el-option>
 						</el-select>
 					</sa-item>
-<!--					<sa-item type="text" name="有效状态,0-无效已删除、1-有效" v-model="p.status"></sa-item>-->
-<!--					<sa-item type="text" name="盐" v-model="p.salt"></sa-item>-->
 					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
-					<br />
+					<sa-item type="fast-btn" show="reset" style="display: inline;"></sa-item>
 				</el-form>
 				<!-- ------------- 快捷按钮 ------------- -->
-<!--				<sa-item type="fast-btn" show="add,get,delete,export,reset"></sa-item>-->
+				<!--				<sa-item type="fast-btn" show="add,get,delete,export,reset"></sa-item>-->
 				<!-- ------------- 数据列表 ------------- -->
-				<el-table class="data-table" ref="data-table" :data="dataList" >
+				<el-table class="data-table" ref="data-table" :data="dataList">
 					<sa-td type="index" name="序号"></sa-td>
-					<sa-td name="客户名称" prop="customerName" ></sa-td>
-					<sa-td name="充值金额(元)" prop="preTopupMoney" ></sa-td>
-					<sa-td name="优惠金额(元)" prop="discountMoney" ></sa-td>
-<!--					<sa-td name="充值渠道" prop="chargeChannel" ></sa-td>-->
-					<sa-td name="余额" prop="totalMoney" ></sa-td>
+					<sa-td name="客户名称" prop="customerName" width="220"></sa-td>
+					<sa-td name="原金额(元)" prop="beforeMoney" not="0"></sa-td>
+					<sa-td name="实际收款(元)" prop="totalTopupMoney" not="0" width="120"></sa-td>
+					<sa-td name="优惠金额(元)" prop="discountMoney" not="0" width="120"></sa-td>
+					<sa-td name="本次充值金额(元)" prop="preTopupMoney" not="0" width="140"></sa-td>
+					<sa-td name="退款金额(元)"  width="120">
+						<template slot-scope="s">
+							<span v-if="s.row.refundMoney==0">0</span>
+							<span v-else style="color: blue;cursor: pointer;text-decoration: underline;" @click="getDetail(s.row)">{{s.row.refundMoney}}</span>
+						</template>
+					</sa-td>
+					<sa-td name="余额(元)" prop="totalMoney" not="0"></sa-td>
+					<sa-td name="类型" type="enum" prop="type" :jv="{1: '账户充值', 2: '余额退款',3:'异常单退款'}"></sa-td>
 					<sa-td name="付款方式" prop="payingType" type="enum" :jv="payingTypeObj"></sa-td>
-					<sa-td name="经办人" prop="chargePeople" ></sa-td>
-					<sa-td name="充值时间" prop="createTime" ></sa-td>
-					<sa-td name="复核人员" prop="reviewBy" ></sa-td>
-					<sa-td name="充值说明" prop="remark" ></sa-td>
-					<el-table-column label="操作" fixed="right"  width="240px">
+					<sa-td name="经办人" prop="chargePeople"></sa-td>
+					<sa-td name="充值时间" prop="createTime" width="160"></sa-td>
+					<sa-td name="复核人员" prop="reviewBy"></sa-td>
+					<sa-td name="说明" prop="remark"></sa-td>
+					<el-table-column label="操作" fixed="right" width="140px">
 						<template slot-scope="s">
-							<el-button class="c-btn" type="success" icon="el-icon-view" v-if="sa.isAuth('tb-charge-record-list-print')"
-									   @click="print(s.row)">打印单据</el-button>
-							<el-button class="c-btn" type="primary" icon="el-icon-edit"
-									   v-if="s.row.reviewStatus!=1 && sa.isAuth('tb-charge-record-list-review')"
-									   @click="toReview(s.row)">复审</el-button>
-							<el-button class="c-btn" type="danger" icon="el-icon-delete"
-									   v-if="sa.isAuth('tb-charge-record-list-del')" @click="del(s.row)">删除</el-button>
+							<el-button class="c-btn" type="success" v-if="sa.isAuth('tb-charge-record-list-print')"
+								@click="print(s.row)">打印单据</el-button>
+							<el-button class="c-btn" type="primary"
+								v-if="s.row.reviewStatus!=1 && sa.isAuth('tb-charge-record-list-review')"
+								@click="toReview(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>
+			<el-dialog title="退款明细" :visible.sync="refund.visible" width="900">
+				
+					<el-table :data="refund.list" ref="refundTable" height="100">
+						<el-table-column prop="customerName" label="企业名称" width=200>
+						</el-table-column>
+						<el-table-column prop="no" label="业务单号" width=160>
+						</el-table-column>
+						<sa-td name="类型" type="enum" prop="type" :jv="{1: '账户充值', 2: '余额退款',3:'异常单退款'}"></sa-td>
+						<el-table-column prop="refundMoney"  label="金额(元)">
+						</el-table-column>
+						<el-table-column prop="refundTime" width="140" label="退款时间">
+						</el-table-column>
+						<el-table-column prop="refundBy" label="退款人">
+						</el-table-column>
+						<el-table-column prop="remark" label="退款原因">
+						</el-table-column>
+					</el-table>
+				<span slot="footer" class="dialog-footer">
+					<el-button @click="refund.visible = false">关 闭</el-button>
+				</span>
+			</el-dialog>
 		</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: {
+					refund:{
+						visible:false,
+						list:[],
+					},
+					
+					typeList: [
+						{
+							id: 0,
+							name: '全部'
+						},
+						{
+						id: 1,
+						name: '账户充值'
+					}, {
+						id: 2,
+						name: '余额退款'
+					} ,{
+						id: 3,
+						name: '异常单退款'
+					}],
 					p: { // 查询参数  
-						id: '',		// 主键 
-						accountId: '',		// 客户账户id 
-						customerId: '',		// 客户id 
-						customerName: '',		// 客户名称 
-						money: '',		// 充值金额 
-						payMoney: '',		// 支付金额 
-						chargeChannel: '',		// 充值渠道 
-						createTime: '',		// 充值时间 
-						chargePeople: '',		// 充值人 
-						no: '',		// 订单号 
-						beforeBalance: '',		// 充值前余额
-						discountMoney: '',		// 优惠金额
-						totalMoney:'',
-						payingType: '',		// 付款方式 
-						remark: '',		// 充值说明
-						preTopupMoney:'',
-						reviewBy:'',
-						reviewTime: '',		// 复核时间 
-						status: '',		// 有效状态,0-无效已删除、1-有效
-						reviewStatus:'',
-						salt: '',		// 盐 
-						pageNo: 1,		// 当前页 
-						pageSize: 10,	// 页大小 
-						sortType: 0		// 排序方式 
+						type: 0,
+						id: '', // 主键 
+						accountId: '', // 客户账户id 
+						customerId: '', // 客户id 
+						customerName: '', // 客户名称 
+						money: '', // 充值金额 
+						payMoney: '', // 支付金额 
+						chargeChannel: '', // 充值渠道 
+						createTime: '', // 充值时间 
+						chargePeople: '', // 充值人 
+						no: '', // 订单号 
+						beforeBalance: '', // 充值前余额
+						discountMoney: '', // 优惠金额
+						totalMoney: '',
+						payingType: '', // 付款方式 
+						remark: '', // 充值说明
+						preTopupMoney: '',
+						reviewBy: '',
+						reviewTime: '', // 复核时间 
+						status: '', // 有效状态,0-无效已删除、1-有效
+						reviewStatus: '',
+						salt: '', // 盐 
+						pageNo: 1, // 当前页 
+						pageSize: 10, // 页大小 
+						sortType: 0 // 排序方式 
 					},
 					pickerOptions: {
 						shortcuts: [{
@@ -143,10 +187,18 @@
 							}
 						}]
 					},
-					reviewStatusList:[
-						{id:2,name:'全部'},
-						{id:0,name:'未复核'},
-						{id:1,name:'已复核'}
+					reviewStatusList: [{
+							id: 2,
+							name: '全部'
+						},
+						{
+							id: 0,
+							name: '未复核'
+						},
+						{
+							id: 1,
+							name: '已复核'
+						}
 					],
 					dataCount: 0,
 					dataList: [], // 数据集合
@@ -159,18 +211,18 @@
 
 				},
 				methods: {
+					getDetail(data){
+						Object.assign(this.refund,{
+							visible:true,
+							list:[data]
+						})
+					},
 					// 刷新
 					f5: function() {
 						sa.ajax('/TbChargeRecord/getList', sa.removeNull(this.p), function(res) {
 							this.dataList = res.data; // 数据
-							this.dataList.forEach((itm)=>{
-								itm.preTopupMoney = this.decrypt(itm.preTopupMoney);
-								itm.beforeBalance = this.decrypt(itm.beforeBalance);
-								itm.totalMoney = this.decrypt(itm.totalMoney);
-								itm.discountMoney = this.decrypt(itm.discountMoney);
-							});
 							this.dataCount = res.dataCount; // 数据总数
-							sa.f5TableHeight();		// 刷新表格高度
+							sa.f5TableHeight(); // 刷新表格高度
 						}.bind(this));
 					},
 					// 新增
@@ -182,35 +234,38 @@
 					},
 					//复审
 					toReview(data) {
-						let ss = data.preTopupMoney?',充值金额:'+data.preTopupMoney+'元)':")";
-						sa.confirm('您确认对('+data.customerName+ss+'复审吗?', function() {
+						let ss = data.preTopupMoney ? ',充值金额:' + data.preTopupMoney + '元)' : ")";
+						sa.confirm('您确认对(' + data.customerName + ss + '复审吗?', function() {
 							sa.ajax('/TbChargeRecord/review?id=' + data.id, function(res) {
 								sa.ok('复审成功');
 								this.f5();
-								sa.f5TableHeight();		// 刷新表格高度
+								sa.f5TableHeight(); // 刷新表格高度
 							}.bind(this))
 						}.bind(this));
 					},
 					// 删除
 					del: function(data) {
-						let ss = data.preTopupMoney?',充值金额:'+data.preTopupMoney+'元)':")";
-						sa.confirm('是否删除('+data.customerName+ss+',此操作不可撤销', function() {
+						let ss = data.preTopupMoney ? ',充值金额:' + data.preTopupMoney + '元)' : ")";
+						sa.confirm('是否删除(' + data.customerName + ss + ',此操作不可撤销', function() {
 							sa.ajax('/TbChargeRecord/delete?id=' + data.id, function(res) {
 								sa.arrayDelete(this.dataList, data);
 								sa.ok('删除成功');
-								sa.f5TableHeight();		// 刷新表格高度 
+								sa.f5TableHeight(); // 刷新表格高度 
 							}.bind(this))
 						}.bind(this));
 					},
 					decrypt(word, keyStr) {
-						if(!word){
+						if (!word) {
 							return;
 						}
 						keyStr = keyStr || 'h!f78tr#L3D$2Z0q';
 						let base64 = CryptoJS.enc.Base64.parse(word);
 						let src = CryptoJS.enc.Base64.stringify(base64);
 						let key = CryptoJS.enc.Utf8.parse(keyStr);
-						let decrypt = CryptoJS.AES.decrypt(src, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7});
+						let decrypt = CryptoJS.AES.decrypt(src, key, {
+							mode: CryptoJS.mode.ECB,
+							padding: CryptoJS.pad.Pkcs7
+						});
 						//  let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
 						return CryptoJS.enc.Utf8.stringify(decrypt).toString();
 					},

+ 351 - 0
sp-admin/sa-view/tb-deduction-record/tb-deduction-record-error-list.html

@@ -0,0 +1,351 @@
+<!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="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css">
+		<link rel="stylesheet" href="../../static/sa.css">
+		<script src="https://unpkg.com/vue@2.6.10/dist/vue.js"></script>
+		<script src="https://unpkg.com/element-ui@2.13.0/lib/index.js"></script>
+		<script src="https://unpkg.com/http-vue-loader@1.4.2/src/httpVueLoader.js"></script>
+		<script src="https://unpkg.com/jquery@3.4.1/dist/jquery.js"></script>
+		<script src="https://www.layuicdn.com/layer-v3.1.1/layer.js"></script>
+		<script src="../../static/sa.js"></script>
+		<style>
+			.all-btn {
+				background: #1890ff;
+				color: white;
+				border-radius: 3px;
+				padding: 2px;
+				cursor: pointer;
+			}
+		</style>
+	</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.businessNo"></sa-item>
+					<sa-item type="text" name="车牌号" v-model="p.carNo"></sa-item>
+					<sa-item type="enum" name="收费项目">
+						<el-select v-model="p.feeType" clearable placeholder="请选择" filterable>
+							<el-option label="核酸检测" value="1"></el-option>
+							<el-option label="消杀作业" value="2"></el-option>
+							<el-option label="装卸作业" value="3"></el-option>
+							<el-option label="停车费" value="4"></el-option>
+							<el-option label="过磅费" value="5"></el-option>
+							<el-option label="入场管理费" value="6"></el-option>
+							<el-option label="充电打冷作业" value="7"></el-option>
+						</el-select>
+					</sa-item>
+					<sa-item type="enum" name="业务类型">
+						<el-select v-model="p.itemTypeName" clearable placeholder="请选择" filterable>
+							<el-option v-for="item in itemTypeList" :key="item.id" :label="item.name"
+								:value="item.name">
+							</el-option>
+						</el-select>
+					</sa-item>
+					<sa-item type="text" name="支付时间">
+						<el-date-picker v-model="p.payTime" type="daterange" align="right" unlink-panels
+							value-format="yyyy-MM-dd" range-separator="至" start-placeholder="开始日期"
+							end-placeholder="结束日期" :picker-options="pickerOptions">
+						</el-date-picker>
+					</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="index" name="序号"></sa-td>
+					<sa-td name="企业" prop="customerName" width="150"></sa-td>
+					<sa-td name="业务单号" prop="businessNo" width="150"></sa-td>
+					<sa-td name="车牌号" prop="carNo" width="100"></sa-td>
+					<sa-td name="收费项目" prop="feeType" type="enum"
+						:jv="{1: '核酸检测',2: '消杀作业', 3: '装卸作业', 4: '停车业务', 5: '过磅费', 6: '入场管理费', 7: '充电打冷作业'}"></sa-td>
+					<sa-td name="业务类型" prop="itemTypeName" width="150"></sa-td>
+					<sa-td name="订单金额(元)" prop="deductMoney" width="90"></sa-td>
+					<sa-td name="付款时间" prop="payTime" width="150"></sa-td>
+					<sa-td name="异常时间" prop="setTime" width="150"></sa-td>
+					<sa-td name="操作人" prop="setBy"></sa-td>
+					<sa-td name="异常原因" prop="errorRemark"></sa-td>
+					<sa-td name="已退金额(元)" prop="refundMoney" width="90"></sa-td>
+					<sa-td name="退款时间" prop="refundTime" width="150"></sa-td>
+					<sa-td name="退款原因" prop="refundReason" width="100"></sa-td>
+					<el-table-column label="操作" fixed="right" width="120px">
+						<template slot-scope="s">
+							<el-button class="c-btn" type="warning"
+								v-if="sa.isAuth('tb-deduction-record-list-refund')&&s.row.deductMoney>s.row.refundMoney"
+								@click="refundFn(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>
+				<el-dialog title="异常单退款" :visible.sync="refund.visible" :modal="false" width="400px">
+					<div>
+						<el-form>
+							<sa-item type="text" name="企业名称" v-model="refund.form.customerName" :disabled="true" br>
+							</sa-item>
+							<sa-item type="text" name="可退款金额" v-model="refund.form.deductMoney" :disabled="true" br>
+							</sa-item>
+							<sa-item type="num" name="退款金额" v-model="refund.form.refundMoney"  :disabled="true">
+							</sa-item>
+							<sa-item type="enum" name="退款方式" br>
+								<el-select v-model="refund.form.payingType">
+									<el-option label="请选择" v-for="(item,index) in payingTypeList" :key="item.id"
+										:label="item.name" :value="item.id">
+									</el-option>
+								</el-select>
+							</sa-item>
+							<sa-item type="textarea" name="退款原因" v-model="refund.form.refundReason" need :rows="2" br>
+							</sa-item>
+						</el-form>
+					</div>
+					<span slot="footer" class="dialog-footer">
+						<el-button @click="refund.visible = false">取 消</el-button>
+						<el-button type="primary" @click="sureRefund">确 定</el-button>
+					</span>
+				</el-dialog>
+			</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: {
+					refund: {
+						visible: false,
+						form: {
+							id: '',
+							customerId: '',
+							customerName: '',
+							deductMoney: 0,
+							refundMoney: 0,
+							refundReason: '',
+							payingType: 1
+						}
+					},
+					payingTypeList: [],
+					p: { // 查询参数  
+						id: '', // 主键 
+						businessId: '', // 业务id 
+						businessNo: '', // 业务单号 
+						carNo: '', // 车牌号 
+						feeType: '', // 收费类型 
+						itemTypeId: '', // 业务类型id 
+						itemTypeName: '', // 业务类型 
+						itemId: '', //  
+						itemName: '', // 业务项 
+						itemPrice: '', // 项目金额(元) 
+						unitPrice: '', //  
+						payDay: '', // 支付日期 
+						payTime: '', // 支付时间 
+						payType: '', // 支付方式(3=微信支付) 
+						payMode: '', //  
+						createTime: '', // 创建时间 
+						updateTime: '', // 更新时间 
+						businessItemId: '', //  
+						businessItemNo: '', // 业务项单号 
+						pickCustomerName: '', //  
+						customerName: '', // 客户名称 
+						entityName: '', // 主体名称 
+						taxRate: '', //  
+						noTaxPrice: '', //  
+						taxPrice: '', //  
+						weight: '', //  
+						num: '', //  
+						isSettle: '', // 是否结算 
+						remark: '', // 备注 
+						invoice: '', // 发票 
+						transactionId: '', // 微信交易单号 
+						outTradeNo: '', // 支付单号 
+						businessCarId: '', //  
+						businessCarNo: '', //  
+						kaiDanPerson: '', // 开单员 
+						diaoDuPerson: '', // 调度员 
+						jiChaPerson: '', // 稽查员 
+						customerId: '', // 客户id 
+						deductMoney: '', // 扣除金额 
+						feeDetailsId: '', // 收费明细id 
+						reviewBy: '', // 复核人员 
+						reviewTime: '', // 复核时间 
+						reviewStatus: '', // 复核状态,0-未复核、1-已复核 
+						partner: '', // 合作伙伴 
+						originalMoney: '', // 原金额 
+						totalMoney: '', // 余额 
+						pageNo: 1, // 当前页 
+						pageSize: 10, // 页大小 
+						sortType: 0, // 排序方式 
+						status: 0
+					},
+					pickerOptions: {
+						shortcuts: [{
+							text: '最近一周',
+							onClick(picker) {
+								const end = new Date();
+								const start = new Date();
+								start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
+								picker.$emit('pick', [start, end]);
+							}
+						}, {
+							text: '最近一个月',
+							onClick(picker) {
+								const end = new Date();
+								const start = new Date();
+								start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
+								picker.$emit('pick', [start, end]);
+							}
+						}, {
+							text: '最近三个月',
+							onClick(picker) {
+								const end = new Date();
+								const start = new Date();
+								start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
+								picker.$emit('pick', [start, end]);
+							}
+						}]
+					},
+					reviewStatusList: [{
+							id: 2,
+							name: '全部'
+						},
+						{
+							id: 0,
+							name: '未复核'
+						},
+						{
+							id: 1,
+							name: '已复核'
+						}
+					],
+					dataCount: 0,
+					dataList: [], // 数据集合
+					itemTypeList: [],
+				},
+				methods: {
+					refundFn(data) {
+						Object.assign(this.refund, {
+							visible: true,
+							form: {
+								id: data.id,
+								customerName: data.customerName,
+								deductMoney: data.deductMoney - data.refundMoney,
+								refundMoney: data.deductMoney - data.refundMoney,
+								refundReason: '',
+								payingType: 1
+							}
+						})
+					},
+					sureRefund() {
+						let form = this.refund.form;
+						let refundMoney = form.refundMoney;
+						if (refundMoney <= 0) {
+							sa.error('退款金额须大于0')
+							return;
+						}
+						if (refundMoney > form.deductMoney) {
+							sa.error('退款金额不能大于可退款金额')
+							return;
+						}
+						if (!form.refundReason) {
+							sa.error('请输入退款原因')
+							return;
+						}
+						sa.ajax('/TbDeductionRecord/refund', form, function(res) {
+							this.refund.visible = false;
+							sa.alert('已退款');
+							this.f5();
+						}.bind(this))
+					},
+					getPayingType() {
+						sa.ajax('/TbAccount/getPayingType', function(res) {
+							this.payingTypeList = res.data;
+						}.bind(this))
+					},
+					setError(data) {
+						let that = this;
+						layer.prompt({
+							title: '输入异常原因'
+						}, function(pass, index) {
+							layer.close(index);
+							sa.ajax('/TbDeductionRecord/setError', {
+								id: data.id,
+								errorRemark: pass
+							}, function(res) {
+								layer.msg('成功');
+								that.f5();
+							})
+						});
+					},
+					// 刷新
+					f5: function() {
+						sa.ajax('/TbDeductionRecord/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-deduction-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-deduction-record-add.html?id=' + data.id, '1000px', '90%');
+					},
+					// 新增
+					add: function(data) {
+						sa.showIframe('新增数据', 'tb-deduction-record-add.html?id=-1', '1000px', '90%');
+					},
+					//复审
+					toReview(data) {
+						let ss = ',业务单号:' + data.businessNo + ')';
+						sa.confirm('您确认对(' + data.customerName + ss + '复审吗?', function() {
+							sa.ajax('/TbDeductionRecord/review?id=' + data.id, function(res) {
+								sa.ok('复审成功');
+								this.f5();
+								sa.f5TableHeight(); // 刷新表格高度
+							}.bind(this))
+						}.bind(this));
+					},
+					getItemTypeList() {
+						sa.ajax('/TbItemType/getList', {
+							pageNo: 1,
+							pageSize: 100
+						}, function(resp) {
+							this.itemTypeList = resp.data;
+						}.bind(this));
+					},
+				},
+				created: function() {
+					this.f5();
+					this.getItemTypeList();
+					sa.onInputEnter();
+					this.getPayingType();
+				}
+			})
+		</script>
+	</body>
+</html>

+ 158 - 108
sp-admin/sa-view/tb-deduction-record/tb-deduction-record-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="https://unpkg.com/element-ui@2.13.0/lib/theme-chalk/index.css">
 		<link rel="stylesheet" href="../../static/sa.css">
@@ -13,6 +14,18 @@
 		<script src="https://unpkg.com/jquery@3.4.1/dist/jquery.js"></script>
 		<script src="https://www.layuicdn.com/layer-v3.1.1/layer.js"></script>
 		<script src="../../static/sa.js"></script>
+		<style>
+			.sum-div {
+				text-align: right;
+				padding: 10px 150px 10px;
+				font-weight: bold;
+			}
+
+			.sum-title {
+				color: darkred;
+				font-weight: bold;
+			}
+		</style>
 	</head>
 	<body>
 		<div class="vue-box" style="display: none;" :style="'display: block;'">
@@ -20,11 +33,11 @@
 				<!-- ------------- 检索参数 ------------- -->
 				<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.customerName"></sa-item>
 					<sa-item type="text" name="业务单号" v-model="p.businessNo"></sa-item>
 					<sa-item type="text" name="车牌号" v-model="p.carNo"></sa-item>
-					<sa-item type="enum" name="收费项目" >
-						<el-select v-model="p.feeType"  clearable placeholder="请选择" filterable>
+					<sa-item type="enum" name="收费项目">
+						<el-select v-model="p.feeType" clearable placeholder="请选择" filterable>
 							<el-option label="核酸检测" value="1"></el-option>
 							<el-option label="消杀作业" value="2"></el-option>
 							<el-option label="装卸作业" value="3"></el-option>
@@ -34,67 +47,62 @@
 							<el-option label="充电打冷作业" value="7"></el-option>
 						</el-select>
 					</sa-item>
-					<sa-item type="enum" name="业务类型" >
+					<sa-item type="enum" name="业务类型">
 						<el-select v-model="p.itemTypeName" clearable placeholder="请选择" filterable>
-							<el-option v-for="item in itemTypeList" :key="item.id"
-									   :label="item.name" :value="item.name">
+							<el-option v-for="item in itemTypeList" :key="item.id" :label="item.name"
+								:value="item.name">
 							</el-option>
 						</el-select>
 					</sa-item>
 					<sa-item type="text" name="支付时间">
-						<el-date-picker
-								v-model="p.payTime"
-								type="daterange"
-								align="right"
-								unlink-panels
-								value-format="yyyy-MM-dd"
-								range-separator="至"
-								start-placeholder="开始日期"
-								end-placeholder="结束日期"
-								:picker-options="pickerOptions">
+						<el-date-picker v-model="p.payTime" type="daterange" align="right" unlink-panels
+							value-format="yyyy-MM-dd" range-separator="至" start-placeholder="开始日期"
+							end-placeholder="结束日期" :picker-options="pickerOptions">
 						</el-date-picker>
 					</sa-item>
-<!--					<sa-item type="enum" name="支付方式" v-model="p.payType" -->
-<!--						:jv="{3: '微信支付'}" jtype="2" def="不限"></sa-item>-->
 					<sa-item type="text" name="复核状态">
 						<el-select v-model="p.reviewStatus" clearable placeholder="请选择">
-							<el-option
-									v-for="item in reviewStatusList"
-									:key="item.id"
-									:label="item.name"
-									:value="item.id">
+							<el-option v-for="item in reviewStatusList" :key="item.id" :label="item.name"
+								:value="item.id">
+							</el-option>
+						</el-select>
+					</sa-item>
+					<sa-item type="text" name="订单状态">
+						<el-select v-model="p.status"  placeholder="请选择">
+							<el-option  label="全部" :value="-1">
+							</el-option>
+							<el-option  label="正常" :value="1">
+							</el-option>
+							<el-option  label="异常" :value="0">
 							</el-option>
 						</el-select>
 					</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>
+					<sa-item type="fast-btn" show="reset" style="display: inline;"></sa-item>
+					<el-button v-if="sa.isAuth('tb-deduction-record-export')" type="primary" icon="el-icon-download" @click="exportFn">导出</el-button>
 				</el-form>
 				<!-- ------------- 快捷按钮 ------------- -->
 				<!-- ------------- 数据列表 ------------- -->
-				<el-table class="data-table" ref="data-table" :data="dataList" >
+				<div class="sum-div">总共 <span class="sum-title">{{dataCount}}</span>条;扣款金额:<span
+						class="sum-title">¥{{totalMoney}}</span>元</div>
+				<el-table class="data-table" ref="data-table" :data="dataList">
 					<sa-td type="index" name="序号"></sa-td>
-					<sa-td name="客户名称" prop="customerName" width="150"></sa-td>
-					<sa-td name="合作伙伴" prop="pickCustomerName" width="150"></sa-td>
-					<el-table-column label="业务单号" width="140px">
-						<template slot-scope="s">
-							<span v-if="s.row.businessNo != null && s.row.businessNo != ''">{{s.row.businessNo}}</span>
-							<span v-else>{{s.row.businessCarNo}}</span>
-						</template>
-					</el-table-column>
+					<sa-td name="企业" prop="customerName" width="150"></sa-td>
+					<sa-td name="业务单号" prop="businessNo" width="150"></sa-td>
 					<sa-td name="车牌号" prop="carNo" width="100"></sa-td>
 					<sa-td name="收费项目" prop="feeType" type="enum"
-						   :jv="{1: '核酸检测',2: '消杀作业', 3: '装卸作业', 4: '停车业务', 5: '过磅费', 6: '入场管理费', 7: '充电打冷作业'}"></sa-td>
+						:jv="{1: '核酸检测',2: '消杀作业', 3: '装卸作业', 4: '停车业务', 5: '过磅费', 6: '入场管理费', 7: '充电打冷作业'}"></sa-td>
 					<sa-td name="业务类型id" prop="itemTypeId" v-if="false"></sa-td>
 					<sa-td name="业务类型" prop="itemTypeName" width="150"></sa-td>
-<!--					<sa-td name="业务项" prop="itemName" ></sa-td>-->
 					<sa-td name="原金额" prop="originalMoney" width="120"></sa-td>
 					<sa-td name="扣除金额" prop="deductMoney" width="90"></sa-td>
-					<sa-td name="余额" prop="totalMoney" width="150"></sa-td>
+					<sa-td name="余额" prop="totalMoney"></sa-td>
+					<sa-td name="订单状态" prop="status" type="enum" :jv="{0: '异常',1: '正常'}"></sa-td>
 					<sa-td name="结算状态" prop="isSettle" type="enum" :jv="{0: '未结算',1: '已结算'}"></sa-td>
 					<sa-td name="复核状态" prop="reviewStatus" type="enum" :jv="{0: '未复核',1: '已复核'}"></sa-td>
-					<sa-td name="税率%" >
+					<sa-td name="税率%">
 						<template slot-scope="s">
-						<span>{{s.row.taxRate * 100}}</span>
+							<span>{{s.row.taxRate * 100}}</span>
 						</template>
 					</sa-td>
 					<el-table-column label="税额(元)">
@@ -107,78 +115,83 @@
 							<span>{{Number(s.row.noTaxPrice).toFixed(2)}}</span>
 						</template>
 					</el-table-column>
-					<sa-td name="生成时间" prop="createTime" width="150px"></sa-td>
-					<sa-td name="款时间" prop="payTime" width="150px"></sa-td>
-					<el-table-column label="操作" fixed="right"  width="240px">
+					<!-- <sa-td name="生成时间" prop="createTime" width="150px"></sa-td> -->
+					<sa-td name="款时间" prop="payTime" width="150px"></sa-td>
+					<el-table-column label="操作" fixed="right" width="240px">
 						<template slot-scope="s">
-							<el-button class="c-btn" type="primary" icon="el-icon-edit"
-									   v-if="s.row.reviewStatus!=1 && sa.isAuth('tb-deduction-record-list-review')"
-									   @click="toReview(s.row)">复审</el-button>
+							<el-button class="c-btn" type="primary"
+								v-if="s.row.reviewStatus!=1 && sa.isAuth('tb-deduction-record-list-review')"
+								@click="toReview(s.row)">复审</el-button>
+							<el-button class="c-btn" type="warning" v-if="sa.isAuth('tb-deduction-record-set-error')"
+								@click="setError(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: {
+					totalMoney:0,
 					p: { // 查询参数  
-						id: '',		// 主键 
-						businessId: '',		// 业务id 
-						businessNo: '',		// 业务单号 
-						carNo: '',		// 车牌号 
-						feeType: '',		// 收费类型 
-						itemTypeId: '',		// 业务类型id 
-						itemTypeName: '',		// 业务类型 
-						itemId: '',		//  
-						itemName: '',		// 业务项 
-						itemPrice: '',		// 项目金额(元) 
-						unitPrice: '',		//  
-						payDay: '',		// 支付日期 
-						payTime: '',		// 支付时间 
-						payType: '',		// 支付方式(3=微信支付) 
-						payMode: '',		//  
-						createTime: '',		// 创建时间 
-						updateTime: '',		// 更新时间 
-						businessItemId: '',		//  
-						businessItemNo: '',		// 业务项单号 
-						pickCustomerName: '',		//  
-						customerName: '',		// 客户名称 
-						entityName: '',		// 主体名称 
-						taxRate: '',		//  
-						noTaxPrice: '',		//  
-						taxPrice: '',		//  
-						weight: '',		//  
-						num: '',		//  
-						isSettle: '',		// 是否结算 
-						remark: '',		// 备注 
-						invoice: '',		// 发票 
-						transactionId: '',		// 微信交易单号 
-						outTradeNo: '',		// 支付单号 
-						businessCarId: '',		//  
-						businessCarNo: '',		//  
-						kaiDanPerson: '',		// 开单员 
-						diaoDuPerson: '',		// 调度员 
-						jiChaPerson: '',		// 稽查员 
-						customerId: '',		// 客户id 
-						deductMoney: '',		// 扣除金额 
-						feeDetailsId: '',		// 收费明细id 
-						reviewBy: '',		// 复核人员 
-						reviewTime: '',		// 复核时间 
-						reviewStatus: '',		// 复核状态,0-未复核、1-已复核 
-						partner: '',		// 合作伙伴 
-						originalMoney: '',		// 原金额 
-						totalMoney: '',		// 余额 
-						pageNo: 1,		// 当前页 
-						pageSize: 10,	// 页大小 
-						sortType: 0		// 排序方式 
+						id: '', // 主键 
+						businessId: '', // 业务id 
+						businessNo: '', // 业务单号 
+						carNo: '', // 车牌号 
+						feeType: '', // 收费类型 
+						itemTypeId: '', // 业务类型id 
+						itemTypeName: '', // 业务类型 
+						itemId: '', //  
+						itemName: '', // 业务项 
+						itemPrice: '', // 项目金额(元) 
+						unitPrice: '', //  
+						payDay: '', // 支付日期 
+						payTime: '', // 支付时间 
+						payType: '', // 支付方式(3=微信支付) 
+						payMode: '', //  
+						createTime: '', // 创建时间 
+						updateTime: '', // 更新时间 
+						businessItemId: '', //  
+						businessItemNo: '', // 业务项单号 
+						pickCustomerName: '', //  
+						customerName: '', // 客户名称 
+						entityName: '', // 主体名称 
+						taxRate: '', //  
+						noTaxPrice: '', //  
+						taxPrice: '', //  
+						weight: '', //  
+						num: '', //  
+						isSettle: '', // 是否结算 
+						remark: '', // 备注 
+						invoice: '', // 发票 
+						transactionId: '', // 微信交易单号 
+						outTradeNo: '', // 支付单号 
+						businessCarId: '', //  
+						businessCarNo: '', //  
+						kaiDanPerson: '', // 开单员 
+						diaoDuPerson: '', // 调度员 
+						jiChaPerson: '', // 稽查员 
+						customerId: '', // 客户id 
+						deductMoney: '', // 扣除金额 
+						feeDetailsId: '', // 收费明细id 
+						reviewBy: '', // 复核人员 
+						reviewTime: '', // 复核时间 
+						reviewStatus: '', // 复核状态,0-未复核、1-已复核 
+						partner: '', // 合作伙伴 
+						originalMoney: '', // 原金额 
+						totalMoney: '', // 余额 
+						pageNo: 1, // 当前页 
+						pageSize: 10, // 页大小 
+						sortType: 0, // 排序方式 
+						status:-1
 					},
 					pickerOptions: {
 						shortcuts: [{
@@ -207,22 +220,59 @@
 							}
 						}]
 					},
-					reviewStatusList:[
-						{id:2,name:'全部'},
-						{id:0,name:'未复核'},
-						{id:1,name:'已复核'}
+					reviewStatusList: [{
+							id: 2,
+							name: '全部'
+						},
+						{
+							id: 0,
+							name: '未复核'
+						},
+						{
+							id: 1,
+							name: '已复核'
+						}
 					],
 					dataCount: 0,
 					dataList: [], // 数据集合
-					itemTypeList:[],
+					itemTypeList: [],
 				},
 				methods: {
+					getSum(){
+						sa.ajax('/TbDeductionRecord/getSum', sa.removeNull(this.p), function(res) {
+							this.totalMoney=res.data;
+						}.bind(this));
+					},
+					exportFn () {
+						sa.confirm('是否导出符合筛选条件的扣费记录', function() {
+							sa.ajax('/TbDeductionRecord/export', sa.removeNull(this.p),
+								function(res) {
+									window.location.href=res.data;
+								}.bind(this))
+						}.bind(this));
+					},
+					setError(data) {
+						let that = this;
+						layer.prompt({
+							title: '输入异常原因'
+						}, function(pass, index) {
+							layer.close(index);
+							sa.ajax('/TbDeductionRecord/setError', {
+								id: data.id,
+								errorRemark: pass
+							}, function(res) {
+								layer.msg('成功');
+								that.f5();
+							})
+						});
+					},
 					// 刷新
 					f5: function() {
 						sa.ajax('/TbDeductionRecord/getList', sa.removeNull(this.p), function(res) {
 							this.dataList = res.data; // 数据
 							this.dataCount = res.dataCount; // 数据总数 
-							sa.f5TableHeight();		// 刷新表格高度 
+							sa.f5TableHeight(); // 刷新表格高度 
+							this.getSum();
 						}.bind(this));
 					},
 					// 查看
@@ -232,7 +282,7 @@
 					// 查看 - 根据选中的
 					getBySelect: function(data) {
 						var selection = this.$refs['data-table'].selection;
-						if(selection.length == 0) {
+						if (selection.length == 0) {
 							return sa.msg('请选择一条数据')
 						}
 						this.get(selection[0]);
@@ -247,12 +297,12 @@
 					},
 					//复审
 					toReview(data) {
-						let ss = ',业务单号:'+data.businessNo+')';
-						sa.confirm('您确认对('+data.customerName+ss+'复审吗?', function() {
+						let ss = ',业务单号:' + data.businessNo + ')';
+						sa.confirm('您确认对(' + data.customerName + ss + '复审吗?', function() {
 							sa.ajax('/TbDeductionRecord/review?id=' + data.id, function(res) {
 								sa.ok('复审成功');
 								this.f5();
-								 sa.f5TableHeight();		// 刷新表格高度
+								sa.f5TableHeight(); // 刷新表格高度
 							}.bind(this))
 						}.bind(this));
 					},
@@ -260,7 +310,7 @@
 						sa.ajax('/TbItemType/getList', {
 							pageNo: 1,
 							pageSize: 100
-						}, function (resp) {
+						}, function(resp) {
 							this.itemTypeList = resp.data;
 						}.bind(this));
 					},

+ 1 - 1
sp-admin/sa-view/tb-fee-statistics/tb-fee-statistics-list.html

@@ -78,7 +78,7 @@
 							<span>{{Number(s.row.noTaxMoney).toFixed(2)}}</span>
 						</template>
 					</el-table-column>
-					<sa-td name="支付方式" prop="payType" type="enum" :jv="{3: '微信支付'}"></sa-td>
+					<sa-td name="支付方式" prop="payType" type="enum" :jv="{3: '微信支付',5: '余额支付'}"></sa-td>
 
 					<sa-td name="开单员" prop="kaiDanPerson"></sa-td>
 					<sa-td name="复核员" prop="diaoDuPerson"></sa-td>

+ 386 - 378
sp-admin/sa-view/tb-goods/tb-goods-list.html

@@ -1,389 +1,397 @@
 <!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.name"></sa-item>
-            <el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
-            <el-button type="info" icon="el-icon-search" @click="p.name = ''; f5()">重置</el-button>
-            <el-button v-if="sa.isAuth('tb-goods-add')" size="mini" type="primary" @click="add()">增加</el-button>
-            <br/>
-        </el-form>
+	<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.name"></sa-item>
+					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
+					<el-button type="info" icon="el-icon-search" @click="p.name = ''; f5()">重置</el-button>
+					<el-button v-if="sa.isAuth('tb-goods-add')" size="mini" type="primary" @click="add()">增加</el-button>
+					<br />
+				</el-form>
 
-        <!-- ------------- 数据列表 ------------- -->
-        <el-table class="data-table" ref="data-table" :data="dataList">
-            <el-table-column type="index" width="50">
-            </el-table-column>
-            <sa-td name="业务名称" prop="name" width="120"></sa-td>
-            <sa-td name="付款步骤" prop="payStep" type="enum" :jv="{1: '下单后', 2: '确认后'}" width="80"></sa-td>
-            <sa-td name="载重" prop="needWeight" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
-                   @change="s => updateNeedWeight(s.row)" width="90"></sa-td>
-            <sa-td name="规格" prop="needCarSize" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
-                   @change="s => updateNeedCarSize(s.row)" width="90"></sa-td>
-            <sa-td name="车辆" prop="mulCar" type="switch" :jv="{0: '单辆[#005500]', 1: '多辆[#ff0000]'}"
-                   @change="s => updateMulCar(s.row)" width="90"></sa-td>
-            <sa-td name="客户" prop="needCustomer" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
-                   @change="s => updateNeedCustomer(s.row)" width="90"></sa-td>
-            <sa-td name="货物" prop="needOwner" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
-                   @change="s => updateNeedOwner(s.row)" width="90"></sa-td>
-            <sa-td name="件数" prop="needOperateTime" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
-                   @change="s => updateNeedOperateTime(s.row)" width="90"></sa-td>
-            <sa-td name="空车" prop="chinaCarPay" type="switch" :jv="{0: '免停车费[#005500]', 1: '收停车费[#ff0000]'}"
-                   @change="s => updateChinaCarPay(s.row)" width="120"></sa-td>
-            <sa-td name="载重车" prop="vietnamCarPay" type="switch" :jv="{0: '免停车费[#005500]', 1: '收停车费[#ff0000]'}"
-                   @change="s => updateVietnamCarPay(s.row)" width="120"></sa-td>
-            <el-table-column label="空车离场限制" width="140">
-                <template slot-scope="s">
-                    <el-select v-model="s.row.chinaCarLeave" @change="chinaLeaveChange(s.row)">
-                        <el-option v-for="item in leaveSetting" :key="item.id" :value="item.id"
-                                   :label="item.name">
-                        </el-option>
-                    </el-select>
-                </template>
-            </el-table-column>
-            <el-table-column label="载重车离场限制" width="140">
-                <template slot-scope="s">
-                    <el-select v-model="s.row.vietnamCarLeave" @change="vietnamLeaveChange(s.row)">
-                        <el-option v-for="item in leaveSetting" :key="item.id" :value="item.id"
-                                   :label="item.name">
-                        </el-option>
-                    </el-select>
-                </template>
-            </el-table-column>
-            <el-table-column label="预充值自动扣费类型" width="140">
-                <template slot-scope="s">
-                    <el-select v-model="s.row.autoDeductionType" @change="deductionTypeChange(s.row)">
-                        <el-option v-for="item in deductionTypeList" :key="item.id" :value="item.id"
-                                   :label="item.name">
-                        </el-option>
-                    </el-select>
-                </template>
-            </el-table-column>
-            <sa-td name="创建时间" prop="createTime" width="160"></sa-td>
-            <el-table-column label="操作" fixed="right" width="230">
-                <template slot-scope="s">
-                    <el-button v-if="sa.isAuth('tb-goods-item-type')" class="c-btn" type="primary"
-                               @click="businessFn(s.row)">收费项
-                    </el-button>
-                    <el-button v-if="sa.isAuth('tb-goods-edit')" class="c-btn" type="primary"
-                               icon="el-icon-edit" @click="update(s.row)">修改
-                    </el-button>
-                    <el-button v-if="sa.isAuth('tb-goods-del')" 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: { // 查询参数
-                name: '', // 名称
-                pageNo: 1, // 当前页
-                pageSize: 10, // 页大小
-                sortType: 0 // 排序方式
-            },
-            dataCount: 0,
-            dataList: [], // 数据集合
-            leaveSetting: [],
-            deductionTypeList: []
-        },
-        methods: {
-            businessFn(data) {
-                sa.showIframe('收费项', '../relation-goods-type/relation-goods-type-list.html?goodsId=' + data.id,
-                    '1080px', '90%');
-            },
-            // 刷新
-            f5: function () {
-                sa.ajax('/TbGoods/getList', sa.removeNull(this.p), function (res) {
-                    this.dataList = res.data; // 数据
-                    this.dataCount = res.dataCount; // 数据总数
-                    sa.f5TableHeight(); // 刷新表格高度
-                }.bind(this));
-            },
-            getLeaveSetting: function () {
-                sa.ajax('/TbGoods/getLeaveSetting', function (res) {
-                    this.leaveSetting = res.data; // 数据
-                }.bind(this));
-            },
-            getDeductionTypeList: function () {
-                sa.ajax('/TbGoods/getDeductionTypeList', function (res) {
-                    this.deductionTypeList = res.data; // 数据
-                }.bind(this));
-            },
-            chinaLeaveChange(v) {
-                let obj = {
-                    id: v.id,
-                    chinaCarLeave: v.chinaCarLeave
-                }
-                sa.ajax('/TbGoods/chinaLeaveChange', obj, function (resp) {
+				<!-- ------------- 数据列表 ------------- -->
+				<el-table class="data-table" ref="data-table" :data="dataList">
+					<el-table-column type="index" width="50">
+					</el-table-column>
+					<sa-td name="业务名称" prop="name" width="120"></sa-td>
+					<sa-td name="付款步骤" prop="payStep" type="enum" :jv="{1: '下单后', 2: '确认后'}" width="80"></sa-td>
+					<sa-td name="载重" prop="needWeight" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
+						@change="s => updateNeedWeight(s.row)" width="90"></sa-td>
+					<sa-td name="规格" prop="needCarSize" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
+						@change="s => updateNeedCarSize(s.row)" width="90"></sa-td>
+					<sa-td name="车辆" prop="mulCar" type="switch" :jv="{0: '单辆[#005500]', 1: '多辆[#ff0000]'}"
+						@change="s => updateMulCar(s.row)" width="90"></sa-td>
+					<sa-td name="客户" prop="needCustomer" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
+						@change="s => updateNeedCustomer(s.row)" width="90"></sa-td>
+					<sa-td name="合作伙伴" prop="needPartner" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
+						@change="s => updateNeedPartner(s.row)" width="90"></sa-td>
+					<sa-td name="货物" prop="needOwner" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
+						@change="s => updateNeedOwner(s.row)" width="90"></sa-td>
+					<sa-td name="件数" prop="needOperateTime" type="switch" :jv="{0: '选填[#005500]', 1: '必填[#ff0000]'}"
+						@change="s => updateNeedOperateTime(s.row)" width="90"></sa-td>
 
-                }.bind(this))
-            },
-            vietnamLeaveChange(v) {
-                let obj = {
-                    id: v.id,
-                    vietnamCarLeave: v.vietnamCarLeave
-                }
-                sa.ajax('/TbGoods/vietnamLeaveChange', obj, function (resp) {
+					<el-table-column label="空车离场限制" width="140">
+						<template slot-scope="s">
+							<el-select v-model="s.row.chinaCarLeave" @change="chinaLeaveChange(s.row)">
+								<el-option v-for="item in leaveSetting" :key="item.id" :value="item.id"
+									:label="item.name">
+								</el-option>
+							</el-select>
+						</template>
+					</el-table-column>
+					<el-table-column label="载重车离场限制" width="140">
+						<template slot-scope="s">
+							<el-select v-model="s.row.vietnamCarLeave" @change="vietnamLeaveChange(s.row)">
+								<el-option v-for="item in leaveSetting" :key="item.id" :value="item.id"
+									:label="item.name">
+								</el-option>
+							</el-select>
+						</template>
+					</el-table-column>
+					<!-- <el-table-column label="预充值自动扣费类型" width="140">
+						<template slot-scope="s">
+							<el-select v-model="s.row.autoDeductionType" @change="deductionTypeChange(s.row)">
+								<el-option v-for="item in deductionTypeList" :key="item.id" :value="item.id"
+									:label="item.name">
+								</el-option>
+							</el-select>
+						</template>
+					</el-table-column> -->
+					<sa-td name="创建时间" prop="createTime" width="160"></sa-td>
+					<el-table-column label="操作" fixed="right" width="230">
+						<template slot-scope="s">
+							<el-button v-if="sa.isAuth('tb-goods-item-type')" class="c-btn" type="primary"
+								@click="businessFn(s.row)">收费项
+							</el-button>
+							<el-button v-if="sa.isAuth('tb-goods-edit')" class="c-btn" type="primary"
+								icon="el-icon-edit" @click="update(s.row)">修改
+							</el-button>
+							<el-button v-if="sa.isAuth('tb-goods-del')" 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: { // 查询参数
+						name: '', // 名称
+						pageNo: 1, // 当前页
+						pageSize: 10, // 页大小
+						sortType: 0 // 排序方式
+					},
+					dataCount: 0,
+					dataList: [], // 数据集合
+					leaveSetting: [],
+					deductionTypeList: []
+				},
+				methods: {
+					businessFn(data) {
+						sa.showIframe('收费项', '../relation-goods-type/relation-goods-type-list.html?goodsId=' + data.id,
+							'1080px', '90%');
+					},
+					// 刷新
+					f5: function() {
+						sa.ajax('/TbGoods/getList', sa.removeNull(this.p), function(res) {
+							this.dataList = res.data; // 数据
+							this.dataCount = res.dataCount; // 数据总数
+							sa.f5TableHeight(); // 刷新表格高度
+						}.bind(this));
+					},
+					getLeaveSetting: function() {
+						sa.ajax('/TbGoods/getLeaveSetting', function(res) {
+							this.leaveSetting = res.data; // 数据
+						}.bind(this));
+					},
+					getDeductionTypeList: function() {
+						sa.ajax('/TbGoods/getDeductionTypeList', function(res) {
+							this.deductionTypeList = res.data; // 数据
+						}.bind(this));
+					},
+					chinaLeaveChange(v) {
+						let obj = {
+							id: v.id,
+							chinaCarLeave: v.chinaCarLeave
+						}
+						sa.ajax('/TbGoods/chinaLeaveChange', obj, function(resp) {
 
-                }.bind(this))
-            },
-            deductionTypeChange(v) {
-                let obj = {
-                    id: v.id,
-                    autoDeductionType: v.autoDeductionType
-                }
-                sa.ajax('/TbGoods/autoDeductionType', obj, function (resp) {
+						}.bind(this))
+					},
+					vietnamLeaveChange(v) {
+						let obj = {
+							id: v.id,
+							vietnamCarLeave: v.vietnamCarLeave
+						}
+						sa.ajax('/TbGoods/vietnamLeaveChange', obj, function(resp) {
 
-                }.bind(this))
-            },
-            updateMulCar(data) {
-                let obj = {
-                    id: data.id,
-                    mulCar: data.mulCar
-                }
-                sa.ajax('/TbGoods/updateMulCar', obj, function (resp) {
+						}.bind(this))
+					},
+					deductionTypeChange(v) {
+						let obj = {
+							id: v.id,
+							autoDeductionType: v.autoDeductionType
+						}
+						sa.ajax('/TbGoods/autoDeductionType', obj, function(resp) {
 
-                }.bind(this))
-            },
-            updateNeedOwner(v) {
-                let obj = {
-                    id: v.id,
-                    value: v.needOwner
-                }
-                sa.ajax('/TbGoods/updateNeedOwner', obj, function (resp) {
+						}.bind(this))
+					},
+					updateMulCar(data) {
+						let obj = {
+							id: data.id,
+							mulCar: data.mulCar
+						}
+						sa.ajax('/TbGoods/updateMulCar', obj, function(resp) {
 
-                }.bind(this))
-            },
-            updateNeedCustomer(v) {
-                let obj = {
-                    id: v.id,
-                    value: v.needCustomer
-                }
-                sa.ajax('/TbGoods/updateNeedCustomer', obj, function (resp) {
+						}.bind(this))
+					},
+					updateNeedOwner(v) {
+						let obj = {
+							id: v.id,
+							value: v.needOwner
+						}
+						sa.ajax('/TbGoods/updateNeedOwner', obj, function(resp) {
 
-                }.bind(this))
-            },
-            // 查看
-            get: function (data) {
-                sa.showIframe('数据详情', 'tb-goods-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]);
-            },
+						}.bind(this))
+					},
+					updateNeedPartner(v){
+						let obj = {
+							id: v.id,
+							value: v.needPartner
+						}
+						sa.ajax('/TbGoods/updateNeedPartner', obj, function(resp) {
+						
+						}.bind(this))
+					},
+					updateNeedCustomer(v) {
+						let obj = {
+							id: v.id,
+							value: v.needCustomer
+						}
+						sa.ajax('/TbGoods/updateNeedCustomer', obj, function(resp) {
 
-            // 修改
-            update: function (data) {
-                sa.showIframe('修改数据', 'tb-goods-add.html?id=' + data.id, '450px', '50%');
-            },
-            // 新增
-            add: function (data) {
-                sa.showIframe('新增数据', 'tb-goods-add.html?id=-1', '450px', '50%');
-            },
-            // 删除
-            del: function (data) {
-                sa.confirm('是否删除,此操作不可撤销', function () {
-                    sa.ajax('/TbGoods/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('/TbGoods/deleteByIds', {
-                        ids: ids.join(',')
-                    }, function (res) {
-                        sa.arrayDelete(this.dataList, selection);
-                        sa.ok('删除成功');
-                        sa.f5TableHeight(); // 刷新表格高度
-                    }.bind(this))
-                }.bind(this));
-            },
-            // 改 - 状态(1=禁用,2=启用)
-            updateStatus: function (data) {
-                // 声明变量记录是否成功
-                var isOk = false;
-                var oldValue = data.status;
-                var ajax = sa.ajax('/TbGoods/updateStatus', {
-                    id: data.id,
-                    value: data.status
-                }, function (res) {
-                    isOk = true;
-                    sa.msg('修改成功');
-                }.bind(this));
-                // 如果未能修改成功, 则回滚
-                $.when(ajax).done(function () {
-                    if (isOk == false) {
-                        data.status = oldValue;
-                    }
-                })
-            },
-            // 改 - 载重是否必填(1=是,0=否)
-            updateNeedWeight: function (data) {
-                // 声明变量记录是否成功
-                var isOk = false;
-                var oldValue = data.needWeight;
-                var ajax = sa.ajax('/TbGoods/updateNeedWeight', {
-                    id: data.id,
-                    value: data.needWeight
-                }, function (res) {
-                    isOk = true;
-                    sa.msg('修改成功');
-                }.bind(this));
-                // 如果未能修改成功, 则回滚
-                $.when(ajax).done(function () {
-                    if (isOk == false) {
-                        data.status = oldValue;
-                    }
-                })
-            },
-            // 改 - 规格是否必填(1=是,0=否)
-            updateNeedCarSize: function (data) {
-                // 声明变量记录是否成功
-                var isOk = false;
-                var oldValue = data.needCarSize;
-                var ajax = sa.ajax('/TbGoods/updateNeedCarSize', {
-                    id: data.id,
-                    value: data.needCarSize
-                }, function (res) {
-                    isOk = true;
-                    sa.msg('修改成功');
-                }.bind(this));
-                // 如果未能修改成功, 则回滚
-                $.when(ajax).done(function () {
-                    if (isOk == false) {
-                        data.status = oldValue;
-                    }
-                })
-            },
-            // 改 - 规格是否必填(1=是,0=否)
-            updateChinaCarPay: function (data) {
-                // 声明变量记录是否成功
-                var isOk = false;
-                var oldValue = data.chinaCarPay;
-                var ajax = sa.ajax('/TbGoods/updateChinaCarPay', {
-                    id: data.id,
-                    value: data.chinaCarPay
-                }, function (res) {
-                    isOk = true;
-                    sa.msg('修改成功');
-                }.bind(this));
-                // 如果未能修改成功, 则回滚
-                $.when(ajax).done(function () {
-                    if (isOk == false) {
-                        data.status = oldValue;
-                    }
-                })
-            },
-            // 改 - 规格是否必填(1=是,0=否)
-            updateVietnamCarPay: function (data) {
-                // 声明变量记录是否成功
-                var isOk = false;
-                var oldValue = data.vietnamCarPay;
-                var ajax = sa.ajax('/TbGoods/updateVietnamCarPay', {
-                    id: data.id,
-                    value: data.vietnamCarPay
-                }, function (res) {
-                    isOk = true;
-                    sa.msg('修改成功');
-                }.bind(this));
-                // 如果未能修改成功, 则回滚
-                $.when(ajax).done(function () {
-                    if (isOk == false) {
-                        data.status = oldValue;
-                    }
-                })
-            },
-            // 改 - 申报单是否必填(1=是,0=否)
-            updateNeedDeclare: function (data) {
-                // 声明变量记录是否成功
-                var isOk = false;
-                var oldValue = data.needDeclare;
-                var ajax = sa.ajax('/TbGoods/updateNeedDeclare', {
-                    id: data.id,
-                    value: data.needDeclare
-                }, function (res) {
-                    isOk = true;
-                    sa.msg('修改成功');
-                }.bind(this));
-                // 如果未能修改成功, 则回滚
-                $.when(ajax).done(function () {
-                    if (isOk == false) {
-                        data.status = oldValue;
-                    }
-                })
-            },
-            // 改 - 申报时间是否必填(1=是,0=否)
-            updateNeedOperateTime: function (data) {
-                // 声明变量记录是否成功
-                var isOk = false;
-                var oldValue = data.needOperateTime;
-                var ajax = sa.ajax('/TbGoods/updateNeedOperateTime', {
-                    id: data.id,
-                    value: data.needOperateTime
-                }, function (res) {
-                    isOk = true;
-                    sa.msg('修改成功');
-                }.bind(this));
-                // 如果未能修改成功, 则回滚
-                $.when(ajax).done(function () {
-                    if (isOk == false) {
-                        data.status = oldValue;
-                    }
-                })
-            },
-        },
-        created: function () {
-            this.f5();
-            this.getLeaveSetting();
-            this.getDeductionTypeList();
-            sa.onInputEnter();
-        }
-    })
-</script>
-</body>
+						}.bind(this))
+					},
+					// 查看
+					get: function(data) {
+						sa.showIframe('数据详情', 'tb-goods-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-goods-add.html?id=' + data.id, '450px', '50%');
+					},
+					// 新增
+					add: function(data) {
+						sa.showIframe('新增数据', 'tb-goods-add.html?id=-1', '450px', '50%');
+					},
+					// 删除
+					del: function(data) {
+						sa.confirm('是否删除,此操作不可撤销', function() {
+							sa.ajax('/TbGoods/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('/TbGoods/deleteByIds', {
+								ids: ids.join(',')
+							}, function(res) {
+								sa.arrayDelete(this.dataList, selection);
+								sa.ok('删除成功');
+								sa.f5TableHeight(); // 刷新表格高度
+							}.bind(this))
+						}.bind(this));
+					},
+					// 改 - 状态(1=禁用,2=启用)
+					updateStatus: function(data) {
+						// 声明变量记录是否成功
+						var isOk = false;
+						var oldValue = data.status;
+						var ajax = sa.ajax('/TbGoods/updateStatus', {
+							id: data.id,
+							value: data.status
+						}, function(res) {
+							isOk = true;
+							sa.msg('修改成功');
+						}.bind(this));
+						// 如果未能修改成功, 则回滚
+						$.when(ajax).done(function() {
+							if (isOk == false) {
+								data.status = oldValue;
+							}
+						})
+					},
+					// 改 - 载重是否必填(1=是,0=否)
+					updateNeedWeight: function(data) {
+						// 声明变量记录是否成功
+						var isOk = false;
+						var oldValue = data.needWeight;
+						var ajax = sa.ajax('/TbGoods/updateNeedWeight', {
+							id: data.id,
+							value: data.needWeight
+						}, function(res) {
+							isOk = true;
+							sa.msg('修改成功');
+						}.bind(this));
+						// 如果未能修改成功, 则回滚
+						$.when(ajax).done(function() {
+							if (isOk == false) {
+								data.status = oldValue;
+							}
+						})
+					},
+					// 改 - 规格是否必填(1=是,0=否)
+					updateNeedCarSize: function(data) {
+						// 声明变量记录是否成功
+						var isOk = false;
+						var oldValue = data.needCarSize;
+						var ajax = sa.ajax('/TbGoods/updateNeedCarSize', {
+							id: data.id,
+							value: data.needCarSize
+						}, function(res) {
+							isOk = true;
+							sa.msg('修改成功');
+						}.bind(this));
+						// 如果未能修改成功, 则回滚
+						$.when(ajax).done(function() {
+							if (isOk == false) {
+								data.status = oldValue;
+							}
+						})
+					},
+					// 改 - 规格是否必填(1=是,0=否)
+					updateChinaCarPay: function(data) {
+						// 声明变量记录是否成功
+						var isOk = false;
+						var oldValue = data.chinaCarPay;
+						var ajax = sa.ajax('/TbGoods/updateChinaCarPay', {
+							id: data.id,
+							value: data.chinaCarPay
+						}, function(res) {
+							isOk = true;
+							sa.msg('修改成功');
+						}.bind(this));
+						// 如果未能修改成功, 则回滚
+						$.when(ajax).done(function() {
+							if (isOk == false) {
+								data.status = oldValue;
+							}
+						})
+					},
+					// 改 - 规格是否必填(1=是,0=否)
+					updateVietnamCarPay: function(data) {
+						// 声明变量记录是否成功
+						var isOk = false;
+						var oldValue = data.vietnamCarPay;
+						var ajax = sa.ajax('/TbGoods/updateVietnamCarPay', {
+							id: data.id,
+							value: data.vietnamCarPay
+						}, function(res) {
+							isOk = true;
+							sa.msg('修改成功');
+						}.bind(this));
+						// 如果未能修改成功, 则回滚
+						$.when(ajax).done(function() {
+							if (isOk == false) {
+								data.status = oldValue;
+							}
+						})
+					},
+					// 改 - 申报单是否必填(1=是,0=否)
+					updateNeedDeclare: function(data) {
+						// 声明变量记录是否成功
+						var isOk = false;
+						var oldValue = data.needDeclare;
+						var ajax = sa.ajax('/TbGoods/updateNeedDeclare', {
+							id: data.id,
+							value: data.needDeclare
+						}, function(res) {
+							isOk = true;
+							sa.msg('修改成功');
+						}.bind(this));
+						// 如果未能修改成功, 则回滚
+						$.when(ajax).done(function() {
+							if (isOk == false) {
+								data.status = oldValue;
+							}
+						})
+					},
+					// 改 - 申报时间是否必填(1=是,0=否)
+					updateNeedOperateTime: function(data) {
+						// 声明变量记录是否成功
+						var isOk = false;
+						var oldValue = data.needOperateTime;
+						var ajax = sa.ajax('/TbGoods/updateNeedOperateTime', {
+							id: data.id,
+							value: data.needOperateTime
+						}, function(res) {
+							isOk = true;
+							sa.msg('修改成功');
+						}.bind(this));
+						// 如果未能修改成功, 则回滚
+						$.when(ajax).done(function() {
+							if (isOk == false) {
+								data.status = oldValue;
+							}
+						})
+					},
+				},
+				created: function() {
+					this.f5();
+					this.getLeaveSetting();
+					this.getDeductionTypeList();
+					sa.onInputEnter();
+				}
+			})
+		</script>
+	</body>
 </html>

+ 4 - 4
sp-admin/sa-view/tb-item-type/tb-item-list.html

@@ -24,9 +24,9 @@
 					<sa-item type="text" name="车型" v-model="p.itemName"></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-button v-if="sa.isAuth('tb-item-manager-add')" type="primary" icon="el-icon-plus"
+					<el-button v-if="sa.isAuth('tb-item-manager-add')" type="primary" icon="el-icon-plus"
 						@click="add()">新增
-					</el-button> -->
+					</el-button>
 					<br />
 				</el-form>
 				<!-- ------------- 数据列表 ------------- -->
@@ -54,9 +54,9 @@
 							<el-button v-if="sa.isAuth('tb-item-manager-edit')" class="c-btn" type="primary"
 								icon="el-icon-edit" @click="update(s.row)">修改
 							</el-button>
-						<!-- 	<el-button v-if="sa.isAuth('tb-item-manager-del')" class="c-btn" type="danger"
+							<el-button v-if="sa.isAuth('tb-item-manager-del')" class="c-btn" type="danger"
 								icon="el-icon-delete" @click="del(s.row)">删除
-							</el-button> -->
+							</el-button>
 						</template>
 					</el-table-column>
 				</el-table>

+ 4 - 4
sp-admin/sa-view/tb-item-type/tb-item-type-list.html

@@ -24,8 +24,8 @@
 					<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>
-					<!-- <el-button v-if="sa.isAuth('tb-item-type-add')" type="primary" icon="el-icon-plus" @click="add()">新增
-					</el-button> -->
+					<el-button v-if="sa.isAuth('tb-item-type-add')" type="primary" icon="el-icon-plus" @click="add()">新增
+					</el-button>
 					<br />
 				</el-form>
 				<!-- ------------- 数据列表 ------------- -->
@@ -46,9 +46,9 @@
 							<el-button v-if="sa.isAuth('tb-item-type-edit')" class="c-btn" type="primary"
 								icon="el-icon-edit" @click="update(s.row)">修改
 							</el-button>
-						<!-- 	<el-button v-if="sa.isAuth('tb-item-type-del')" class="c-btn" type="danger"
+							<el-button v-if="sa.isAuth('tb-item-type-del')" class="c-btn" type="danger"
 								icon="el-icon-delete" @click="del(s.row)">删除
-							</el-button> -->
+							</el-button>
 						</template>
 					</el-table-column>
 				</el-table>

+ 134 - 0
sp-admin/sa-view/tb-refund-record/tb-refund-record-add.html

@@ -0,0 +1,134 @@
+<!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.refundMoney" br></sa-item>
+						<sa-item type="text" name="退款操作人" v-model="m.refundBy" br></sa-item>
+						<sa-item type="text" name="退款时间" v-model="m.refundTime" br></sa-item>
+						<sa-item type="text" name="退款类型" v-model="m.refundType" br></sa-item>
+						<sa-item type="text" name="退款号" v-model="m.refundNo" br></sa-item>
+						<sa-item type="text" name="对应扣款记录ID" v-model="m.deductionRecordId" br></sa-item>
+						<sa-item type="text" name="业务ID" v-model="m.businessId" br></sa-item>
+						<sa-item type="text" name="业务项ID" v-model="m.businessIditemId" 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: '',		// 企业名称 
+							refundMoney: '',		// 退款金额 
+							refundBy: '',		// 退款操作人 
+							refundTime: '',		// 退款时间 
+							refundType: '',		// 退款类型 
+							refundNo: '',		// 退款号 
+							deductionRecordId: '',		// 对应扣款记录ID 
+							businessId: '',		// 业务ID 
+							businessIditemId: '',		// 业务项ID 
+						}
+					},
+					// 提交数据 
+					ok: function(){
+						// 表单校验 
+						let m = this.m;
+						sa.checkNull(m.id, '请输入 []');
+						sa.checkNull(m.customerId, '请输入 [客户ID]');
+						sa.checkNull(m.customerName, '请输入 [企业名称]');
+						sa.checkNull(m.refundMoney, '请输入 [退款金额]');
+						sa.checkNull(m.refundBy, '请输入 [退款操作人]');
+						sa.checkNull(m.refundTime, '请输入 [退款时间]');
+						sa.checkNull(m.refundType, '请输入 [退款类型]');
+						sa.checkNull(m.refundNo, '请输入 [退款号]');
+						sa.checkNull(m.deductionRecordId, '请输入 [对应扣款记录ID]');
+						sa.checkNull(m.businessId, '请输入 [业务ID]');
+						sa.checkNull(m.businessIditemId, '请输入 [业务项ID]');
+				
+						// 开始增加或修改
+						if(this.id <= 0) {	// 添加
+							sa.ajax('/TbRefundRecord/add', m, function(res){
+								sa.alert('增加成功', this.clean); 
+							}.bind(this));
+						} else {	// 修改
+							sa.ajax('/TbRefundRecord/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('/TbRefundRecord/getById?id=' + this.id, function(res) {
+							this.m = res.data;
+							if(res.data == null) {
+								sa.alert('未能查找到 id=' + this.id + " 详细数据");
+							}
+						}.bind(this))
+					}
+				}
+			})
+			
+		</script>
+	</body>
+</html>

+ 70 - 0
sp-admin/sa-view/tb-refund-record/tb-refund-record-info.html

@@ -0,0 +1,70 @@
+<!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.refundMoney}}</sa-info>
+						<sa-info name="退款操作人" br>{{m.refundBy}}</sa-info>
+						<sa-info name="退款时间" br>{{m.refundTime}}</sa-info>
+						<sa-info name="退款类型" br>{{m.refundType}}</sa-info>
+						<sa-info name="退款号" br>{{m.refundNo}}</sa-info>
+						<sa-info name="对应扣款记录ID" br>{{m.deductionRecordId}}</sa-info>
+						<sa-info name="业务ID" br>{{m.businessId}}</sa-info>
+						<sa-info name="业务项ID" br>{{m.businessIditemId}}</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('/TbRefundRecord/getById?id=' + this.id, function(res) {
+						this.m = res.data;
+						if(res.data == null) {
+							sa.alert('未能查找到 id=' + this.id + " 详细数据");
+						}
+					}.bind(this))
+				}
+			})
+			
+		</script>
+	</body>
+</html>

+ 167 - 0
sp-admin/sa-view/tb-refund-record/tb-refund-record-list.html

@@ -0,0 +1,167 @@
+<!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>
+		<style>
+			.sum-div {
+				text-align: right;
+				padding: 10px 150px 10px;
+				font-weight: bold;
+			}
+
+			.sum-title {
+				color: darkred;
+				font-weight: bold;
+			}
+		</style>
+	</head>
+	<body>
+		<div class="vue-box" :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="date" name="退款时间" v-model="p.refundTime"></sa-item>
+					<el-button type="primary" icon="el-icon-search" @click="p.pageNo = 1; f5()">查询</el-button>
+					<el-button type="info" icon="el-icon-refresh" @click="p.customerName = '';p.refundTime=''; f5()">重置</el-button>
+					<el-button v-if="sa.isAuth('tb-refund-record-export')" type="primary" icon="el-icon-download" @click="exportFn">导出</el-button>
+				</el-form>
+				<!-- ------------- 数据列表 ------------- -->
+				<div class="sum-div">总共 <span
+						class="sum-title">{{dataCount}}</span>条;退款金额:<span class="sum-title">¥{{totalMoney}}</span>元</div>
+				<el-table class="data-table" ref="data-table" :data="dataList">
+					<sa-td type="index" name="序号" width="80"></sa-td>
+					<sa-td name="企业名称" prop="customerName" width="230"></sa-td>
+					<sa-td name="退款金额" prop="refundMoney"></sa-td>
+					<sa-td name="业务单号" prop="refundNo"  width="140"></sa-td>
+					<sa-td name="业务类型" prop="itemTypeName"></sa-td>
+					<sa-td name="车型" prop="itemName"></sa-td>
+					<sa-td name="车牌号" prop="carNo"></sa-td>
+					<sa-td name="退款时间" prop="refundTime"></sa-td>
+					<sa-td name="退款操作人" prop="refundBy"></sa-td>
+					<sa-td name="退款原因" prop="refundDesc"></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: { // 查询参数  
+						id: '', //  
+						customerId: '', // 客户ID 
+						customerName: '', // 企业名称 
+						refundTime: '', // 退款时间 
+						refundType: 3, // 退款类型 
+						pageNo: 1, // 当前页 
+						pageSize: 10, // 页大小 
+						sortType: 0 // 排序方式 
+					},
+					dataCount: 0,
+					dataList: [], // 数据集合 
+				},
+				computed: {
+					totalMoney() {
+						let list=this.dataList;
+						let totalMoney=0;
+						for(let i in list){
+							totalMoney+=list[i].refundMoney;
+						}
+						return totalMoney;
+					}
+				},
+				methods: {
+					exportFn () {
+						sa.confirm('是否导出符合筛选条件的扣费记录', function() {
+							sa.ajax('/TbRefundRecord/export', sa.removeNull(this.p),
+								function(res) {
+									window.location.href=res.data;
+								}.bind(this))
+						}.bind(this));
+					},
+					// 刷新
+					f5: function() {
+						sa.ajax('/TbRefundRecord/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-refund-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-refund-record-add.html?id=' + data.id, '1000px', '90%');
+					},
+					// 新增
+					add: function(data) {
+						sa.showIframe('新增数据', 'tb-refund-record-add.html?id=-1', '1000px', '90%');
+					},
+					// 删除
+					del: function(data) {
+						sa.confirm('是否删除,此操作不可撤销', function() {
+							sa.ajax('/TbRefundRecord/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('/TbRefundRecord/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>

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

@@ -22,7 +22,7 @@ var sa = {
 		api_url: 'https://dxkaa1.gxbtka.com/pro',
 		web_url: 'http://www.baidu.com'
 	}
-	sa.cfg = cfg_prod; // 最终环境 , 上线前请选择正确的环境
+	sa.cfg = cfg_dev; // 最终环境 , 上线前请选择正确的环境
 })();
 
 

+ 55 - 98
sp-server/src/main/java/com/pj/api/open/service/OpenService.java

@@ -9,6 +9,7 @@ import cn.hutool.log.StaticLog;
 import com.pj.api.open.ResultJson;
 import com.pj.api.open.bo.CheckCarNumberBO;
 import com.pj.api.open.bo.InRecordBO;
+import com.pj.api.wx.bo.ManagerBO;
 import com.pj.constants.business.CarEnum;
 import com.pj.constants.business.GoodsEnum;
 import com.pj.constants.business.PayEnum;
@@ -18,6 +19,7 @@ import com.pj.project.sync.SyncService;
 import com.pj.project.sync.request.item.IOrderItem;
 import com.pj.project.sync.response.IOrderPriceRes;
 import com.pj.project.tb_account.AutomaticPay;
+
 import com.pj.project.tb_business.TbBusiness;
 import com.pj.project.tb_business.TbBusinessService;
 
@@ -118,7 +120,8 @@ public class OpenService {
         ) {
             //=======创建新的放行记录==========
             tbBusinessCar = new TbBusinessCar();
-            tbBusinessCar.setCarNo(carNo).setPay(0).setCarSize(0D).setIsLock(0)
+            tbBusinessCar.setCarNo(carNo).setPay(0).setCarSize(0D).setIsLock(0).setPayType(CarEnum.PayTypeEnum.NO_PAY_TYPE.getType())
+                    .setPay(0)
                     .setCarCompany(tbCar != null ? tbCar.getCustomerName() : "临时").setCreateTime(now)
                     .setInChannel(channel).setRealInTime(now).setCarType(CarEnum.CarTypeEnum.EMPTY_TYPE.getType())
                     .setBasePartMoney(new BigDecimal("0")).setTimeUpdate(now).setConfirmJudge(CarEnum.ConfirmJudgeEnum.NO_NEED_JUDGE.getCode())
@@ -151,7 +154,6 @@ public class OpenService {
     }
 
     final TimedCache<String, String> IMAGE_CACHE = CacheUtil.newTimedCache(30 * 60 * 1000);
-    final TimedCache<String, BigDecimal> BUSINESS_MONEY_CACHE = CacheUtil.newTimedCache(5000);
 
     private ResultJson handlerOut(String carNo, String channel, String image) {
         carNo = carNo.toUpperCase();
@@ -177,10 +179,10 @@ public class OpenService {
             }
         }
         //判断是否4.2米以下蓝色车牌===免停车费
-        if (StrUtil.isNotEmpty(tbBusinessCar.getColor()) && tbBusinessCar.getCarSize() != null) {
+        if (StrUtil.isNotEmpty(tbBusinessCar.getColor())) {
             String freeColor = partConfig.getFreeColor();
-            //4.2米以下蓝色车辆
-            if (tbBusinessCar.getColor().contains(freeColor) && tbBusinessCar.getCarSize() <= partConfig.getFreeCarLength()) {
+            //4蓝色车辆
+            if (tbBusinessCar.getColor().contains(freeColor)) {
                 log.error("请求返回【蓝牌未备案车辆,放行】:{},{}", carNo, ResultJson.success());
                 freeOut(tbBusinessCar, now, channel, image);
                 return ResultJson.success();
@@ -191,38 +193,26 @@ public class OpenService {
             freeOut(tbBusinessCar, now, channel, image);
             return ResultJson.success();
         }
-        if (tbBusinessCar.getIsLock() == 1) {
-            RedisUtil.setByMINUTES(channel, carNo, 2);
-            log.error("请求返回:车辆已锁定:{}", carNo);
-            return ResultJson.error("车辆已锁定");
-        }
         String businessCarId = tbBusinessCar.getId();
-        //String carNoPrefix = StrUtil.sub(carNo, 0, 1);
         String carType = tbBusinessCar.getCarType();
-        BigDecimal yueCarMoney = new BigDecimal(0);
-        BigDecimal chinaCarMoney = new BigDecimal(0);
-        IOrderPriceRes yueRes = new IOrderPriceRes();
-        IOrderPriceRes chinaRes = new IOrderPriceRes();
+        IOrderPriceRes partMoneyRes;
         IOrderPriceRes businessRes = new IOrderPriceRes();
         List<IOrderItem> expenses = new ArrayList<>();
         List<TbBusiness> businessList = tbBusinessService.findOtherBusinessByCarId(businessCarId);
-        int payPart = tbBusinessCar.getPay();
-        businessList = businessList.stream().filter(tbBusiness -> tbBusiness.getPayStatus() != PayEnum.PayStatusEnum.HAS_PAY_CONFIRM.getCode()).collect(Collectors.toList());
-        if (businessList.isEmpty()) {//无业务车辆===>计算停车费
+        BigDecimal hasPayPartMoney=tbBusinessCar.getMoney();
+        if (businessList.isEmpty()) {
+            //无业务车辆===>计算停车费
             //如果已经支付过,则从支付时间算起,重新计算停车费
-            IOrderPriceRes res = tbBusinessService.getPartMoney(tbBusinessCar.getRealInTime(), now, carNo, tbBusinessCar.getColor());
-            double dif = res.getTotalOrderPrice().doubleValue();
-            if (dif > 0 && payPart == 0) {
+            Date inTime=tbBusinessCar.getRealInTime();
+            if (hasPayPartMoney.compareTo(BigDecimal.ZERO)>0){
+                inTime=now;
+            }
+            IOrderPriceRes res = tbBusinessService.getPartMoney(inTime, now, carNo, tbBusinessCar.getColor());
+            double dif = res.getTotalOrderPrice().subtract(tbBusinessCar.getMoney()).doubleValue();
+            if (dif > 0) {
                 RedisUtil.setByMINUTES(channel, carNo, 5);
                 log.error("请求返回:请缴停车费:{},{}元", carNo, dif);
                 //是否可以预充值缴费 true扣款成功 false否
-                boolean flag = automaticPay.payPartMoney(tbBusinessCar, res, now);
-                if (flag) {
-                    tbBusinessCar.setMoney(new BigDecimal(dif));
-                    freeOut(tbBusinessCar, now, channel, image);
-                    automaticPay.unbindRun(carNo);
-                    return ResultJson.success();
-                }
                 return ResultJson.error("请缴停车费" + dif + "元");
             } else {
                 //无需交停车费,又没有支付的--->设置成免费车辆
@@ -233,113 +223,80 @@ public class OpenService {
                 return ResultJson.success();
             }
         } else {
-            //有业务的车
-            //1、分越重车和空车
-            //空车是否收费
+            //有业务的车--->都要交停车费
             //该车所有的业务都是到达卡口才进行扣费才会进入自动扣费
-            if (CarEnum.CarTypeEnum.EMPTY_TYPE.getType().equals(carType)) {
-                boolean chinaCarPay = businessList.stream().anyMatch(tbBusiness -> {
-                    TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
-                    return tbGoods.getChinaCarPay() == 1;
-                });
-                if (chinaCarPay && payPart == 0) {
-                    IOrderPriceRes res = tbBusinessService.getPartMoney(tbBusinessCar.getRealInTime(), now, carNo, tbBusinessCar.getColor());
-                    double dif = res.getTotalOrderPrice().doubleValue();
-                    if (dif > 0) {
-                        RedisUtil.setByMINUTES(channel, carNo, 5);
-                        log.error("中国车停车费:{},{}元", carNo, dif);
-                        chinaCarMoney = new BigDecimal(dif);
-                        chinaRes = res;
-                        //  return ResultJson.error("请缴停车费" + dif + "元");
-                    } else {
-                        if (tbBusinessCar.getPayTime() == null) {
-                            tbBusinessCar.setPayType(CarEnum.PayTypeEnum.FEE_TYPE.getType()).setPay(1);
-                        }
-                    }
-                }
-            } else {//越南车=重车
-                boolean vietnamCarPay = businessList.stream().anyMatch(tbBusiness -> {
-                    TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
-                    return tbGoods.getVietnamCarPay() == 1;
-                });
-                if (vietnamCarPay && payPart == 0) {
-                    IOrderPriceRes res = tbBusinessService.getPartMoney(tbBusinessCar.getRealInTime(), now, carNo, tbBusinessCar.getColor());
-                    double dif = res.getTotalOrderPrice().doubleValue();
-                    if (dif > 0) {
-                        RedisUtil.setByMINUTES(channel, carNo, 5);
-                        log.error("越南车停车费:{},{}元", carNo, dif);
-                        yueCarMoney = new BigDecimal(dif);
-                        yueRes = res;
-                    } else {
-                        if (tbBusinessCar.getPayTime() == null) {
-                            tbBusinessCar.setPayType(CarEnum.PayTypeEnum.FEE_TYPE.getType()).setPay(1);
-                        }
-                    }
+            Date inTime=tbBusinessCar.getRealInTime();
+            if (hasPayPartMoney.compareTo(BigDecimal.ZERO)>0){
+                inTime=now;
+            }
+            partMoneyRes = tbBusinessService.getPartMoney(inTime, now, carNo, tbBusinessCar.getColor());
+            double dif = partMoneyRes.getTotalOrderPrice().doubleValue();
+            if (dif > 0) {
+                RedisUtil.setByMINUTES(channel, carNo, 5);
+                log.error("停车费:{},{}元", carNo, dif);
+            }else {
+                if (tbBusinessCar.getPayTime() == null) {
+                    tbBusinessCar.setPayType(CarEnum.PayTypeEnum.FEE_TYPE.getType()).setPay(1);
                 }
             }
         }
         //============业务费计算是否交完
-        int autoPayCount = 0;
+        //businessList = businessList.stream().filter(tbBusiness -> tbBusiness.getPayStatus() != PayEnum.PayStatusEnum.HAS_PAY_CONFIRM.getCode()).collect(Collectors.toList());
         List<String> businessIds = businessList.stream().map(TbBusiness::getId).collect(Collectors.toList());
         List<TbBusinessItem> businessItems = tbBusinessItemService.findByBusinessId(businessIds);
-        //入场管理费。。。。
-       // boolean needPayManagerMoney = tbBusinessService.needPayManagerMoney(carNo, businessItems);
         for (TbBusiness tbBusiness : businessList) {
             TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
-            if (GoodsEnum.DeductionTypeEnum.OUT_KK.getCode().equals(tbGoods.getAutoDeductionType())) {
-                autoPayCount++;
-            }
-            int vietnamLeave = tbGoods.getVietnamCarLeave();
-            int chinaCarLeave = tbGoods.getChinaCarLeave();
+            //重车离场限制
+            int weiCarLeave = tbGoods.getVietnamCarLeave();
+            //空车离场限制
+            int emptyCarLeave = tbGoods.getChinaCarLeave();
             boolean pay = tbBusiness.getPayMoney().doubleValue() >= tbBusiness.getItemPrice().doubleValue();
-
             //需要交业务费
-            if (CarEnum.CarTypeEnum.WEIGHT_TYPE.getType().equals(carType)) {//越南车==重车
-                if (GoodsEnum.LeaveEnum.PART_MONEY.getCode() != vietnamLeave
+            if (CarEnum.CarTypeEnum.WEIGHT_TYPE.getType().equals(carType)) {//==重车
+                if (GoodsEnum.LeaveEnum.PART_MONEY.getCode() != weiCarLeave
                         && !pay) {
                     RedisUtil.setByMINUTES(channel, carNo, 5);
                     tbBusinessItemService.buildExpenses(businessItems, expenses);
                     log.error("越南车==重车:缴纳业务费用:{}", carNo);
-                    // businessMoney = businessMoney.add(tbBusiness.getItemPrice());
-                    // return ResultJson.error("请缴纳业务费用");
                 }
             } else {
-                if (GoodsEnum.LeaveEnum.PART_MONEY.getCode() != chinaCarLeave
+                if (GoodsEnum.LeaveEnum.PART_MONEY.getCode() != emptyCarLeave
                         && !pay) {
                     RedisUtil.setByMINUTES(channel, carNo, 5);
                     tbBusinessItemService.buildExpenses(businessItems, expenses);
-//                    businessMoney = businessMoney.add(tbBusiness.getItemPrice());
-//                    log.error("需要缴纳业务费用:{},{}", carNo, businessMoney.toString());
-                    // return ResultJson.error("请缴纳业务费用");
                 }
             }
         }
         if (!expenses.isEmpty()) {
             businessRes = syncService.orderPriceCal(expenses);
         }
-        if (autoPayCount == businessList.size()) {
-            log.info("车辆到达卡口进行扣停车费和业务费:{}", carNo);
-            //自动缴费
-            boolean flag = automaticPay.payBusinessAndPartMoney(businessList, businessRes, tbBusinessCar, chinaRes, yueRes);
-            if (flag) {
-                tbDeductionBindService.autoUnbindCar(tbBusinessCar.getCarNo());
-                freeOut(tbBusinessCar, now, channel, image);
-                return ResultJson.success();
-            }
-        }
-        BigDecimal carMoney = chinaCarMoney.add(yueCarMoney);
+        BigDecimal carMoney = partMoneyRes.getTotalOrderPrice();
+
         BigDecimal businessMoney = businessRes.getTotalOrderPrice();
         BigDecimal total = businessMoney.add(carMoney);
+        //入场管理费。。。。
+        //ManagerBO dto = tbBusinessService.needPayManagerMoney(carNo, businessCarId, businessItems);
+        // total = dto.getPrice().add(total);
         if (total.doubleValue() > 0) {
             String desc = "请缴";
             if (businessMoney.doubleValue() > 0) {
                 desc += "业务费" + businessMoney.toString() + "元";
             }
+            // if (dto.getPrice().doubleValue() > 0) {
+            //     desc += " 入场管理费" + dto.getPrice().toString() + "元";
+            //  }
             if (carMoney.doubleValue() > 0) {
                 desc += " 停车费" + carMoney.toString() + "元";
             }
-            log.error("请求返回:{},{}", carNo, desc);
             RedisUtil.setByMINUTES(channel, carNo, 5);
+            boolean flag = automaticPay.payBusinessAndPartMoney(businessList, tbBusinessCar, partMoneyRes);
+            if (flag) {
+                //
+                log.error("预存款扣款成功,返回:{},{}", carNo, desc);
+                freeOut(tbBusinessCar, now, channel, image);
+                return ResultJson.success();
+            }
+            log.error("请求返回:{},{}", carNo, desc);
             return ResultJson.error(desc);
         }
         freeOut(tbBusinessCar, now, channel, image);

+ 10 - 2
sp-server/src/main/java/com/pj/api/pushfee/task/FeeDetailSyncTask.java

@@ -28,6 +28,8 @@ import com.pj.project.tb_fee_details.TbFeeDetails;
 import com.pj.project.tb_fee_details.TbFeeDetailsService;
 import com.pj.project.tb_fee_item.TbFeeItem;
 import com.pj.project.tb_fee_item.TbFeeItemService;
+import com.pj.project.tb_item.TbItem;
+import com.pj.project.tb_item.TbItemService;
 import lombok.extern.slf4j.Slf4j;
 
 import java.math.BigDecimal;
@@ -75,14 +77,21 @@ public class FeeDetailSyncTask extends Task {
             }
         }
         TbFeeItemService tbFeeItemService = SpringUtil.getBean(TbFeeItemService.class);
+        TbItemService tbItemService = SpringUtil.getBean(TbItemService.class);
         TbFeeItem tbFeeItem = tbFeeItemService.getById(tbFeeDetails.getFeeType());
+      TbItem tbItem= tbItemService.getById(tbFeeDetails.getItemId());
         String subBillNo = StrUtil.isEmpty(tbFeeDetails.getBusinessNo()) ? tbFeeDetails.getBusinessCarNo() : tbFeeDetails.getBusinessCarNo();
         String classifyPath = tbFeeDetails.getFeeType() + "-" + itemTypeId + "-" + itemId;
         opd.setSyncType(syncType)
                 .setSubjectNo(tbFeeDetails.getCarNo())
                 .setSubjectName(tbFeeDetails.getCarNo())
                 .setSubBillNo(subBillNo)
-                .setBizTypeNo(itemTypeId)
+                .setBizTypeNo(itemTypeId).setPayStatus("1")
+                .setPayStatusDesc("已支付")
+                .setGoodNo(tbItem.getItemCode()).setGoodName(tbItem.getItemName())
+                .setBillStatusDesc(tbFeeDetails.getItemTypeName()+tbFeeDetails.getItemName())
+                .setBillDesc(tbFeeDetails.getItemTypeName()+tbFeeDetails.getItemName())
+                .setQuantity(tbFeeDetails.getNum())
                 .setBizTypeName(tbFeeDetails.getItemTypeName())
                 .setChargeItemName(tbFeeItem.getName())
                 .setChargeItemNo(tbFeeDetails.getFeeType() + "")
@@ -91,7 +100,6 @@ public class FeeDetailSyncTask extends Task {
                 .setPaidSerialNo(tbFeeDetails.getTransactionId())
                 .setPaidAmount(tbFeeDetails.getItemPrice())
                 .setRefundAmount(BigDecimal.valueOf(0))
-                .setPayStatus("支付成功")
                 .setPayTime(DateUtil.parse(tbFeeDetails.getPayTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")))
                 .setBillTime(tbFeeDetails.getCreateTime())
                 .setPrice(tbFeeDetails.getItemPrice())

+ 2 - 1
sp-server/src/main/java/com/pj/api/service/ApiService.java

@@ -13,6 +13,7 @@ import com.pj.current.config.MyConfig;
 import com.pj.current.config.WxConfig;
 import com.pj.current.satoken.StpUserUtil;
 import com.pj.project.tb_account.TbAccount;
+import com.pj.project.tb_account.TbAccountBO;
 import com.pj.project.tb_account.TbAccountService;
 import com.pj.project.tb_business.TbBusiness;
 import com.pj.project.tb_business.TbBusinessService;
@@ -207,7 +208,7 @@ public class ApiService {
         return tbDeclareService.getList(so);
     }
 
-    public TbAccount getAccountInfo(String customerId) {
+    public TbAccountBO getAccountInfo(String customerId) {
         return accountService.getByCustomerId(customerId);
     }
 

+ 4 - 1
sp-server/src/main/java/com/pj/api/wx/bo/ManagerBO.java

@@ -1,11 +1,13 @@
 package com.pj.api.wx.bo;
 
 import lombok.Data;
+import lombok.experimental.Accessors;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
 
 @Data
+@Accessors(chain = true)
 public class ManagerBO implements Serializable {
     private String calculateId;
     private String name;
@@ -13,6 +15,7 @@ public class ManagerBO implements Serializable {
     private String id;
     private String carNo;
     private String carId;
-    private BigDecimal price;
+    private BigDecimal price=BigDecimal.valueOf(0);
+    private boolean need;
 
 }

+ 1 - 0
sp-server/src/main/java/com/pj/api/wx/bo/PriceBO.java

@@ -14,6 +14,7 @@ public class PriceBO {
     private String id;
     private BigDecimal p;
     private String uniqExpenseId;
+    private String businessId;
     private String calculateId;
     private String carDesc;
     private String hourDesc;

+ 5 - 19
sp-server/src/main/java/com/pj/api/wx/service/WxService.java

@@ -268,16 +268,10 @@ public class WxService {
                             .setPayNo(transactionId).setOutTradeNo(outTradeNo);
                     tbBusiness.setPayStatus(PayEnum.PayStatusEnum.HAS_PAY_CONFIRM.getCode());
                     tbBusinessService.updateById(tbBusiness);
-                    TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
                     List<TbBusinessCar> carList = tbBusinessCarService.findOtherBusinessCar(businessId);
                     carList.forEach(tbBusinessCar -> {
-                        String carType = tbBusinessCar.getCarType();
-                        //
-                        if (CarEnum.CarTypeEnum.EMPTY_TYPE.getType().equals(carType) && tbGoods.getChinaCarPay() == 0
-                                || CarEnum.CarTypeEnum.WEIGHT_TYPE.getType().equals(carType) && tbGoods.getVietnamCarPay() == 0) {
-                            tbBusinessCar.setPay(1).setPayTime(finalPayTime).setPayOpenid(payopenid);
-                            tbBusinessCarService.updateById(tbBusinessCar);
-                        }
+                        tbBusinessCar.setPay(1).setPayTime(finalPayTime).setPayOpenid(payopenid);
+                        tbBusinessCarService.updateById(tbBusinessCar);
                     });
                 }
                 items.forEach(tbBusinessItem -> tbBusinessItem.setPayStatus(1).setPayTime(finalPayTime).setCalculateId(tbOrder.getCalculateId()));
@@ -287,18 +281,10 @@ public class WxService {
             String i = attach.getI();
             //入场管理费
             if (StrUtil.isNotEmpty(i)) {
-                // ManagerBO managerBO = JSONUtil.toBean(i, ManagerBO.class);
-                //   tbFeeDetailsService.chargeManagerFee(managerBO, transactionId, outTradeNo, payTime, PayEnum.PayType.WX_PAY);//添加cars的收费明细
-            }
-
-            tbFeeStatisticsService.addOrUpdateStatistic(payTime);//更新当前日期的日统计
-
-
-            String a = attach.getA();
-            if (StrUtil.isNotEmpty(a)) {//充值的======>
-                AccountChargeBO chargeBO = JSONUtil.toBean(a, AccountChargeBO.class);
-                tbAccountService.recharge(chargeBO.getId(), chargeBO.getC(), TbChargeRecord.Ch.WECHAT.getType(), money);
+                 ManagerBO managerBO = JSONUtil.toBean(i, ManagerBO.class);
+                   tbFeeDetailsService.chargeManagerFee(managerBO, businessId,transactionId, outTradeNo, payTime, PayEnum.PayType.WX_PAY);//添加cars的收费明细
             }
+            tbFeeStatisticsService.addOrUpdateStatistic(payTime, PayEnum.PayType.WX_PAY.getCode());//更新当前日期的日统计
         }
         tbOrder.setOrderStatus(orderStatus)
                 .setTransactionId(notifyBO.getTransactionId())

+ 12 - 6
sp-server/src/main/java/com/pj/constants/business/FeeTypeEnum.java

@@ -8,17 +8,18 @@ import java.util.*;
 @Getter
 @AllArgsConstructor
 public enum FeeTypeEnum {
-//    OTHER_FEE(-1, "其他"),
-//    NUCLEIC_FEE(1, "核酸检测"),
+    OTHER_FEE(-1, "其他"),
+    //    NUCLEIC_FEE(1, "核酸检测"),
 //    DISINFECT_FEE(2, "消杀作业"),
-//    STEVEDORE_FEE(3, "装卸作业"),
+    STEVEDORE_FEE(3, "装卸作业"),
     PARK_FEE(4, "停车业务"),
-//    WEIGHT_FEE(5, "过磅费"),
+    //    WEIGHT_FEE(5, "过磅费"),
     MANAGE_FEE(6, "入场管理费");
-//    CHARGE_FEE(7, "充电打冷作业");
+    //    CHARGE_FEE(7, "充电打冷作业");
     private int code;
     private String desc;
-//
+
+    //
 //    public static List<Map<String, Object>> getList() {
 //        List<Map<String, Object>> list = new ArrayList<>();
 //        for (FeeTypeEnum feeTypeEnum : FeeTypeEnum.values()) {
@@ -33,4 +34,9 @@ public enum FeeTypeEnum {
 //      return   Arrays.stream(FeeTypeEnum.values()).filter(feeTypeEnum -> feeTypeEnum.getCode()==code)
 //                .findAny().orElse(OTHER_FEE).getDesc();
 //    }
+    public static FeeTypeEnum getEnum(int code) {
+        return Arrays.stream(FeeTypeEnum.values()).filter(feeTypeEnum -> feeTypeEnum.getCode() == code)
+                .findAny().orElse(OTHER_FEE);
+    }
+
 }

+ 2 - 2
sp-server/src/main/java/com/pj/constants/business/GoodsEnum.java

@@ -36,8 +36,8 @@ public class GoodsEnum {
     @AllArgsConstructor
     public static enum LeaveEnum {
         PART_MONEY(1, "只交停车费"),
-        BUSINESS_MONEY(2, "只交业务费"),
-        APART_BUSINESS(3, "停车费+业务费");
+//        BUSINESS_MONEY(2, "只交业务费"),
+        APART_BUSINESS(3, "停车费+管理费");
         private Integer code;
         private String desc;
 

+ 1 - 1
sp-server/src/main/java/com/pj/constants/business/PayEnum.java

@@ -12,7 +12,7 @@ public class PayEnum {
         NO_PAY(1, "未支付"),
         HAS_PAY(2, "已支付"),
         HAS_PAY_CONFIRM(3, "已支付已确认"),
-        HAS_PAY_PART(4, "已支付"),
+        REFUND_STATUS(4, "已退款"),
         ;
         private int code;
         private String desc;

+ 8 - 0
sp-server/src/main/java/com/pj/current/config/MyConfig.java

@@ -54,6 +54,14 @@ public class MyConfig {
      * 收入场管理费需要先做的业务类型
      */
     private List<String> managerItemType;
+    /**
+     * 装卸管理费
+     */
+    private List<String> unLoadItem;
+    /**
+     * 每辆车都收费
+     */
+    private List<String> everyCarPay;
 
 
 }

+ 110 - 104
sp-server/src/main/java/com/pj/project/tb_account/AutomaticPay.java

@@ -9,8 +9,11 @@ import cn.hutool.log.StaticLog;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.pj.api.wx.bo.PriceBO;
 import com.pj.constants.business.CarEnum;
+import com.pj.constants.business.FeeTypeEnum;
 import com.pj.constants.business.GoodsEnum;
 import com.pj.constants.business.PayEnum;
+import com.pj.project.sync.SyncService;
+import com.pj.project.sync.request.item.IOrderItem;
 import com.pj.project.sync.response.IOrderPriceRes;
 import com.pj.project.sync.response.item.PriceDetailItem;
 import com.pj.project.tb_business.TbBusiness;
@@ -42,6 +45,7 @@ import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.stream.Collectors;
@@ -74,8 +78,9 @@ public class AutomaticPay {
     private TbDeductionBindService tbDeductionBindService;
     @Resource
     private TbFeeStatisticsService tbFeeStatisticsService;
-    private Integer feeType;
 
+    @Resource
+    private SyncService syncService;
 
 
     /**
@@ -95,36 +100,31 @@ public class AutomaticPay {
     }
 
 
-
     /**
      * 生成扣费记录
-     *
-     * @param tbFeeDetailsList
-     * @param tbAccount
      */
-    public void createTbDeductionRecord(List<TbFeeDetails> tbFeeDetailsList, TbAccount tbAccount, String plate, String customerName, String no) {
-        String bindIdStr = deductionBindService.getBindId(plate);
-        BigDecimal banlanc = new BigDecimal(AesUtil.decryptECB(tbAccount.getTotalMoney(), AesUtil.reverse(tbAccount.getAccSalt())));
-        for (TbFeeDetails feeDetails : tbFeeDetailsList) {
-            TbDeductionRecord deductionRecord = BeanUtil.toBean(feeDetails, TbDeductionRecord.class);
-            BigDecimal itemPrice = feeDetails.getItemPrice();
-            deductionRecord.setDeductionBindId(bindIdStr)
-                    .setCustomerId(tbAccount.getCustomerId())
-                    .setCustomerName(customerName)
-                    .setOriginalMoney(banlanc.toString())
-                    .setDeductMoney(itemPrice)
-                    .setFeeDetailsId(feeDetails.getId())
-                    .setReviewStatus(0)
-                    .setCarNo(plate)
-                    .setPreOrderNum(no);
-            banlanc = banlanc.subtract(itemPrice);
-            deductionRecord.setTotalMoney(banlanc.toString());
-            deductionRecord.insert();
-//            feeDetails.setCarNo(plate);
-            feeDetails.setPreOrderNum(no);
-            feeDetails.setCustomerName(customerName);
-            tbFeeDetailsService.updateById(feeDetails);
-        }
+    public void createTbDeductionRecord(TbFeeDetails feeDetails, BigDecimal originalMoney, BigDecimal balance,
+                                        String customerId,String customerName,String plate, String businessCarId, FeeTypeEnum feeTypeEnum) {
+        TbDeductionRecord deductionRecord = BeanUtil.toBean(feeDetails, TbDeductionRecord.class);
+        BigDecimal itemPrice = feeDetails.getItemPrice();
+        String no = feeDetails.getBusinessNo();
+        deductionRecord
+                .setCustomerId(customerId)
+                .setCustomerName(customerName)
+                .setDeductMoney(itemPrice)
+                .setBusinessNo(no)
+                .setOriginalMoney(originalMoney).setBusinessId(feeDetails.getBusinessId())
+                .setTotalMoney(balance).setBusinessCarId(businessCarId)
+                .setFeeDetailsId(feeDetails.getId()).setItemName(feeDetails.getItemName())
+                .setItemTypeId(feeDetails.getItemTypeId()).setItemTypeName(feeDetails.getItemTypeName())
+                .setReviewStatus(0).setFeeType(feeTypeEnum.getCode()).setFeeTypeName(feeTypeEnum.getDesc())
+                .setCarNo(plate).setBusinessItemId(feeDetails.getBusinessItemId())
+                .setFeeDetailsId(feeDetails.getId())
+                .setBusinessNo(feeDetails.getBusinessNo())
+                .setPreOrderNum(no);
+        deductionRecord.insert();
+        feeDetails.setPreOrderNum(no);
+        tbFeeDetailsService.updateById(feeDetails);
     }
 
     /**
@@ -208,8 +208,6 @@ public class AutomaticPay {
     }
 
 
-
-
     /**
      * 补录进场解绑逻辑
      *
@@ -306,7 +304,7 @@ public class AutomaticPay {
     }
 
     /**
-     * 支付停车费
+     * 预付款支付停车费
      *
      * @param tbBusinessCar
      * @param now
@@ -319,16 +317,16 @@ public class AutomaticPay {
         if (bind == null) {
             return false;
         }
-        TbAccount tbAccount = tbAccountService.getByCustomerId(bind.getCustomerId());
-        String key = AesUtil.reverse(tbAccount.getAccSalt());
-        BigDecimal balance = new BigDecimal(tbAccount.getTotalMoney());
+        TbAccount tbAccount = tbAccountService.getAccountByCustomerId(bind.getCustomerId());
+        BigDecimal balance = tbAccount.getTotalMoney();
         //不足
         BigDecimal partMoney = orderPriceRes.getTotalOrderPrice();
         if (balance.compareTo(partMoney) < 0) {
             return false;
         }
         balance = balance.subtract(partMoney);
-        tbAccount.setTotalMoney(AesUtil.encryptECB(balance.toString(), key));
+        //更新余额+累计扣款
+        tbAccount.setTotalMoney(balance).setLastSumMoney(tbAccount.getLastSumMoney().add(partMoney));
         tbAccountService.updateById(tbAccount);
         tbBusinessCar.setMoney(partMoney).setPayType(CarEnum.PayTypeEnum.HAS_PAY_TYPE.getType()).setPayTime(now);
         //todo 自动扣款修改
@@ -352,8 +350,8 @@ public class AutomaticPay {
         //车辆的扣费记录
         List<TbFeeDetails> parkFeeDetailsList = tbFeeDetailsService.chargeParkFee(
                 priceBOList, null, null, now, PayEnum.PayType.PER_PAY);
-        this.createTbDeductionRecord(parkFeeDetailsList, tbAccount, tbBusinessCar.getCarNo(), bind.getCustomerName(), no);
-        tbFeeStatisticsService.addOrUpdateStatistic(now);//更新当前日期的日统计
+
+        tbFeeStatisticsService.addOrUpdateStatistic(now, PayEnum.PayType.PER_PAY.getCode());//更新当前日期的日统计
         return true;
     }
 
@@ -364,81 +362,89 @@ public class AutomaticPay {
      * @return
      */
     public boolean payBusinessAndPartMoney(List<TbBusiness> businessList,
-                                           IOrderPriceRes businessRes,
                                            TbBusinessCar tbBusinessCar,
-                                           IOrderPriceRes chinaCarRes,
-                                           IOrderPriceRes yueCarRes) {
+                                           IOrderPriceRes partMoneyRes) {
         Date now = new Date();
-        TbDeductionBind bind = null;
         for (TbBusiness tbBusiness : businessList) {
-            List<TbBusinessCar> cars = tbBusinessCarService.findOtherBusinessCar(tbBusiness.getId());
-            for (TbBusinessCar car : cars) {
-                String carNo = car.getCarNo();
-                bind = tbDeductionBindService.getBindCarByPlate(carNo);
-                if (bind != null) {
-                    break;
+            TbAccount tbAccount = tbAccountService.getAccountByCustomerId(tbBusiness.getCustomerId());
+            BigDecimal balance = tbAccount.getTotalMoney();
+            //停车费扣除
+            BigDecimal partMoney = partMoneyRes.getTotalOrderPrice();
+            if (partMoney.compareTo(balance) > 0) {
+                return false;//不够交
+            }
+            if (tbBusinessCar.getPay() == 0 && partMoney.compareTo(BigDecimal.ZERO) > 0) {
+                String uniqExpenseId = partMoneyRes.getUniqueExpenseId();
+                String calculateId = partMoneyRes.getCalculateId();
+                String carDesc = partMoneyRes.getCarDesc();
+                String hourDesc = partMoneyRes.getHourDesc();
+                List<PriceDetailItem> items = partMoneyRes.getFireResult().get(0).getPriceDetail();
+                if (partMoneyRes.getTotalOrderPrice().intValue() > 0) {
+                    items = partMoneyRes.getFireResult().get(0).getPriceDetail();
+                }
+                PriceBO priceBO = new PriceBO();
+                List<PriceBO> priceBOList = new ArrayList<>();
+                priceBO.setId(tbBusinessCar.getId()).setP(partMoney).setCalculateId(calculateId)
+                        .setCarDesc(carDesc).setHourDesc(hourDesc).setBusinessId(tbBusiness.getId())
+                        .setUniqExpenseId(uniqExpenseId);
+                priceBOList.add(priceBO);
+                for (PriceDetailItem item : items) {
+                    if (item.getKey().toLowerCase().trim().equals("standard")) {
+                        priceBO.setStandard(new BigDecimal(item.getValue()));
+                    } else if (item.getKey().toLowerCase().trim().equals("extraPrice")) {
+                        priceBO.setStandard(new BigDecimal(item.getValue()));
+                    }
                 }
+                BigDecimal afterBalance = balance.subtract(partMoney);
+                tbAccount.setTotalMoney(afterBalance);
+                tbAccountService.updateById(tbAccount);
+                String plate = tbBusinessCar.getCarNo();
+                tbBusinessCar.setPay(1).setPayType(CarEnum.PayTypeEnum.HAS_PAY_TYPE.getType())
+                        .setPayTime(now).setMoney(partMoney);
+                tbBusinessCarService.updateById(tbBusinessCar);
+                List<TbFeeDetails> parkFeeDetailsList = tbFeeDetailsService.chargeParkFee(priceBOList, null, null, now, PayEnum.PayType.PER_PAY);
+                //停车费明细
+                this.createTbDeductionRecord(parkFeeDetailsList.get(0), balance, afterBalance,
+                      tbBusiness.getCustomerId(),tbBusiness.getCustomerName(), plate, tbBusinessCar.getId(), FeeTypeEnum.PARK_FEE);
+
+            }
+            List<TbBusinessItem> items = tbBusinessItemService.findByBusinessId(tbBusiness.getId());
+            items = items.stream().filter(item -> item.getPayStatus() == 0).collect(Collectors.toList());
+            for (TbBusinessItem item : items) {
+                if (item.getPayStatus() == 1) {//已支付的
+                    continue;
+                }
+                int feeType = item.getPayType();
+                FeeTypeEnum feeTypeEnum = FeeTypeEnum.getEnum(feeType);
+                List<IOrderItem> expenses = new ArrayList<>();
+                tbBusinessItemService.buildExpenses(Collections.singletonList(item), expenses);
+                IOrderPriceRes res = syncService.orderPriceCal(expenses);
+                BigDecimal price = res.getTotalOrderPrice();
+                if (balance.compareTo(price) < 0) {
+                    return false;
+                }
+                item.setPayStatus(1).setPayTime(new Date());
+                tbBusinessItemService.updateById(item);
+                String customerId = tbBusiness.getCustomerId();
+                BigDecimal afterBalance = balance.subtract(price);
+                tbAccount.setTotalMoney(afterBalance);
+                tbAccountService.updateById(tbAccount);
+                //支付金额累加
+                tbBusiness.setPayMoney(tbBusiness.getPayMoney().add(price));
+                tbBusinessService.updateById(tbBusiness);
+                TbFeeDetails details = tbFeeDetailsService.savePrePayDetails(res, item, tbBusinessCar, tbBusiness, feeTypeEnum);
+                createTbDeductionRecord(details, balance, afterBalance, customerId,tbBusiness.getCustomerName(),
+                        tbBusinessCar.getCarNo(), tbBusinessCar.getId(), feeTypeEnum);
             }
         }
-        //未绑定
-        if (bind == null) {
-            return false;
-        }
-        BigDecimal businessMoney = businessRes.getTotalOrderPrice();
-        BigDecimal chinaCarMoney = chinaCarRes.getTotalOrderPrice();
-        BigDecimal yueCarMoney = yueCarRes.getTotalOrderPrice();
-        BigDecimal totalMoney = businessMoney.add(chinaCarMoney).add(yueCarMoney).add(chinaCarMoney);
-        TbAccount tbAccount = tbAccountService.getByCustomerId(bind.getCustomerId());
-        String key = AesUtil.reverse(tbAccount.getAccSalt());
-        BigDecimal balance = new BigDecimal(tbAccount.getTotalMoney());
-        //不足
-        if (balance.doubleValue() < totalMoney.doubleValue()) {
-            return false;
+
+        if (businessList.isEmpty()&&partMoneyRes.getTotalOrderPrice().compareTo(BigDecimal.ZERO)>0){
+            //单独交停车费
+
         }
-        balance = balance.subtract(totalMoney);
-        tbAccount.setTotalMoney(AesUtil.encryptECB(balance.toString(), key));
-        tbAccountService.updateById(tbAccount);
-        String businessCalculateId = businessRes.getCalculateId();
-        businessList.forEach(tbBusiness -> {
-            tbBusiness.setPayStatus(PayEnum.PayStatusEnum.HAS_PAY_CONFIRM.getCode()).setCalculateId(businessCalculateId)
-                    .setPayMoney(tbBusiness.getItemPrice()).setTotalMoney(tbBusiness.getItemPrice());
-        });
-        tbBusinessService.updateBatchById(businessList);
-        List<TbBusinessItem> tbBusinessItems = tbBusinessItemService.findByBusinessIdList(businessList.stream().map(TbBusiness::getId).collect(Collectors.toList()));
-        tbBusinessItems.parallelStream().forEach(item -> item.setPayStatus(1).setPayTime(now).setCalculateId(businessCalculateId));
-        tbBusinessItemService.updateBatchById(tbBusinessItems);
-        tbBusinessCar.setPay(1).setPayType(CarEnum.PayTypeEnum.HAS_PAY_TYPE.getType())
-                .setPayTime(now);
-        tbBusinessCarService.updateById(tbBusinessCar);
+
         //todo 构造统计数据
-        BigDecimal p = chinaCarRes.getTotalOrderPrice();
-        String uniqExpenseId = chinaCarRes.getUniqueExpenseId();
-        String calculateId = chinaCarRes.getCalculateId();
-        String carDesc = chinaCarRes.getCarDesc();
-        String hourDesc = chinaCarRes.getHourDesc();
-        List<PriceDetailItem> items = chinaCarRes.getFireResult().get(0).getPriceDetail();
-        if (yueCarRes.getTotalOrderPrice().intValue() > 0) {
-            items = yueCarRes.getFireResult().get(0).getPriceDetail();
-        }
-        PriceBO priceBO = new PriceBO();
-        List<PriceBO> priceBOList = new ArrayList<>();
-        priceBO.setId(tbBusinessCar.getId()).setP(p).setCalculateId(calculateId)
-                .setCarDesc(carDesc).setHourDesc(hourDesc)
-                .setUniqExpenseId(uniqExpenseId);
-        for (PriceDetailItem item : items) {
-            if (item.getKey().toLowerCase().trim().equals("standard")) {
-                priceBO.setStandard(new BigDecimal(item.getValue()));
-            } else if (item.getKey().toLowerCase().trim().equals("extraPrice")) {
-                priceBO.setStandard(new BigDecimal(item.getValue()));
-            }
-        }
-        String plate = tbBusinessCar.getCarNo();
-        String no = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + RandomUtil.randomNumbers(4);
-        List<TbFeeDetails> parkFeeDetailsList = tbFeeDetailsService.chargeParkFee(priceBOList, null, null, now, PayEnum.PayType.PER_PAY);
-        this.createTbDeductionRecord(parkFeeDetailsList, tbAccount, plate, bind.getCustomerName(), no);
-        List<TbFeeDetails> tbFeeDetails = tbFeeDetailsService.chargeBusinessFee(tbBusinessItems, null, null, now, PayEnum.PayType.PER_PAY);
-        createTbDeductionRecord(tbFeeDetails, tbAccount, plate, bind.getCustomerName(), no);
-        tbFeeStatisticsService.addOrUpdateStatistic(now);//更新当前日期的日统计
+        tbFeeStatisticsService.addOrUpdateStatistic(now, PayEnum.PayType.PER_PAY.getCode());//更新当前日期的日统计
         return true;
     }
 }

+ 35 - 0
sp-server/src/main/java/com/pj/project/tb_account/ChargeBO.java

@@ -0,0 +1,35 @@
+package com.pj.project.tb_account;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+public class ChargeBO implements Serializable {
+
+
+    /**
+     * id :
+     * customerId :
+     * customerName :
+     * totalMoney : 0
+     * preTopupMoney : 0
+     * discountMoney : 0
+     * totalTopup : 0
+     * payingType :
+     */
+
+    private String id;
+    private String customerId;
+    private String customerName;
+    //充值金额
+    private BigDecimal preTopupMoney;
+    //优惠金额
+    private BigDecimal discountMoney;
+    //实际收款
+    private BigDecimal totalTopup;
+    private int payingType;
+    private String remark;
+
+}

+ 24 - 5
sp-server/src/main/java/com/pj/project/tb_account/TbAccount.java

@@ -8,6 +8,7 @@ import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.*;
 
 /**
@@ -35,6 +36,8 @@ public class TbAccount extends Model<TbAccount> implements Serializable {
      */
     public static final String PERMISSION_CODE = "tb-account";
     public static final String PERMISSION_LIST_ADD = "tb-account-list-add";
+    public static final String TB_ACCOUNT_BALANCE_LIST = "tb-account-balance-list";
+    public static final String PERMISSION_LIST_REFUND = "tb-account-list-refund";
     public static final String PERMISSION_LIST_UPDATE = "tb-account-list-update";
 
 
@@ -48,6 +51,10 @@ public class TbAccount extends Model<TbAccount> implements Serializable {
      * 客户id
      */
     private String customerId;
+    /**
+     * 客户名称
+     */
+    private String customerName;
 
     /**
      * 账户
@@ -57,17 +64,29 @@ public class TbAccount extends Model<TbAccount> implements Serializable {
     /**
      * 冻结金额
      */
-    private String lockMoney = AesUtil.encryptECB("0");
-
+    private BigDecimal lockMoney = BigDecimal.ZERO;
     /**
      * 可用金额
      */
-    private String actMoney = AesUtil.encryptECB("0");
-
+    private BigDecimal actMoney = BigDecimal.ZERO;
     /**
      * 总金额
      */
-    private String totalMoney = AesUtil.encryptECB("0");
+    private BigDecimal totalMoney = BigDecimal.ZERO;
+
+    /**
+     * 上一次充值之后到本次充值之间的累计扣款
+     */
+    private BigDecimal lastSumMoney = BigDecimal.ZERO;
+    /**
+     * 上一次充值之后到本次充值之间的累计退款
+     */
+    private BigDecimal lastSumRefundMoney = BigDecimal.ZERO;
+    /**
+     * 上一次余额
+     */
+    private BigDecimal lastChargeBalance = BigDecimal.ZERO;
+
 
     /**
      * 纳税识别号

+ 2 - 1
sp-server/src/main/java/com/pj/project/tb_account/TbAccountBO.java

@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -31,7 +32,7 @@ public class TbAccountBO implements Serializable {
     /**
      * 总金额
      */
-    private String totalMoney = AesUtil.encryptECB("0");
+    private BigDecimal totalMoney =BigDecimal.valueOf(0);
 
     /**
      * 联系号码

+ 59 - 18
sp-server/src/main/java/com/pj/project/tb_account/TbAccountController.java

@@ -2,6 +2,7 @@ package com.pj.project.tb_account;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.pj.constants.UserTypeEnum;
 import com.pj.current.satoken.StpUserUtil;
 import com.pj.project.tb_charge_record.TbChargeRecord;
@@ -9,12 +10,13 @@ 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.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 
-
 /**
  * Controller: tb_account -- 客户账户
  *
@@ -32,39 +34,76 @@ public class TbAccountController {
 
     @RequestMapping(value = "getCustomerAccount")
     @SaCheckPermission(TbAccount.PERMISSION_CODE)
-    public AjaxJson getCustomerAccount(String customerId) {
+    public AjaxJson getCustomerAccount(@RequestParam String customerId) {
         return AjaxJson.getSuccessData(tbAccountService.getByCustomerId(customerId));
     }
 
+
+    /**
+     * 充值
+     *
+     * @return
+     */
     @RequestMapping(value = "recharge")
-    public AjaxJson recharge() {
-        if (!StrUtil.equals(StpUserUtil.getCustomerId(), UserTypeEnum.PLATFORM_ADMIN.getCustomerId())) {
-            return AjaxJson.getError("无权限充值");
-        }
-        SoMap soMap = SoMap.getRequestSoMap();
-        String customerId = soMap.getString("customerId");
-        String money = soMap.getString("money");
-        tbAccountService.recharge(customerId, money);
+    @SaCheckPermission(TbAccount.PERMISSION_LIST_ADD)
+    public AjaxJson recharge2(ChargeBO tbAccount) {
+        tbAccountService.recharge(tbAccount);
         return AjaxJson.getSuccess();
     }
 
+    @RequestMapping(value = "getBalance")
+    @SaCheckPermission(TbAccount.TB_ACCOUNT_BALANCE_LIST)
+    public AjaxJson getBalance() {
+        SoMap soMap = SoMap.getRequestSoMap();
+        Page<TbBalanceBO> page = tbAccountService.getBalancePage(soMap);
+        return AjaxJson.getPageData(page.getSize(), page.getRecords());
+    }
 
-    @RequestMapping(value = "recharge2")
-    @SaCheckPermission(TbAccount.PERMISSION_LIST_ADD)
-    public AjaxJson recharge2() {
+    @RequestMapping(value = "getBalance/list")
+    @SaCheckPermission(TbAccount.TB_ACCOUNT_BALANCE_LIST)
+    public AjaxJson getBalanceList() {
         SoMap soMap = SoMap.getRequestSoMap();
-        tbAccountService.recharge(soMap);
+        return AjaxJson.getSuccessData(tbAccountService.getBalanceList(soMap));
+    }
+
+    @RequestMapping(value = "export")
+    @SaCheckPermission(TbAccount.TB_ACCOUNT_BALANCE_LIST)
+    public AjaxJson export() {
+        SoMap soMap = SoMap.getRequestSoMap();
+        return AjaxJson.getSuccessData(tbAccountService.export(soMap));
+    }
+    @RequestMapping(value = "getSum")
+    @SaCheckPermission(TbAccount.TB_ACCOUNT_BALANCE_LIST)
+    public AjaxJson getSum() {
+        SoMap soMap = SoMap.getRequestSoMap();
+        return AjaxJson.getSuccessData(tbAccountService.getSum(soMap));
+    }
+
+
+    @RequestMapping(value = "refund/account")
+    @SaCheckPermission(TbAccount.PERMISSION_LIST_REFUND)
+    public AjaxJson refund() {
+        SoMap soMap = SoMap.getRequestSoMap();
+        String id = soMap.getString("id");
+        String refundMoney = soMap.getString("refundMoney");
+        String refundReason = soMap.getString("refundReason");
+        int payingType = soMap.getInt("payingType");
+        tbAccountService.refund(id, new BigDecimal(refundMoney), payingType, refundReason);
         return AjaxJson.getSuccess();
     }
 
-    /** 查 - 根据id */
+    /**
+     * 查 - 根据id
+     */
     @RequestMapping("getById")
-    public AjaxJson getById(Long id){
+    public AjaxJson getById(Long id) {
         TbAccount t = tbAccountService.getById(id);
         return AjaxJson.getSuccessData(t);
     }
 
-    /** 查集合 - 根据条件(参数为空时代表忽略指定条件) */
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
     @RequestMapping("getList")
     public AjaxJson getList() {
         SoMap so = SoMap.getRequestSoMap();
@@ -76,6 +115,7 @@ public class TbAccountController {
         return AjaxJson.getPageData(so.getDataCount(), list);
     }
 
+
     @RequestMapping("update")
     @SaCheckPermission(TbAccount.PERMISSION_LIST_UPDATE)
     public AjaxJson updateAccount() {
@@ -86,10 +126,11 @@ public class TbAccountController {
 
     /**
      * 获取付款方式
+     *
      * @return
      */
     @RequestMapping("getPayingType")
-    public AjaxJson getPayingType(){
+    public AjaxJson getPayingType() {
         return AjaxJson.getSuccessData(TbChargeRecord.PayingTypeEnum.getList());
     }
 }

+ 6 - 0
sp-server/src/main/java/com/pj/project/tb_account/TbAccountMapper.java

@@ -3,8 +3,10 @@ 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.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 
@@ -41,5 +43,9 @@ public interface TbAccountMapper extends BaseMapper<TbAccount> {
      */
     List<TbAccountBO> getTbAccountBOList(SoMap so);
 
+    TbAccountBO getByCustomerId(String customerId);
+
     TbAccount getAccountByPlate(String plate);
+
+    void updateBalance(@Param("id") String id, @Param("balance") BigDecimal balance);
 }

+ 79 - 68
sp-server/src/main/java/com/pj/project/tb_account/TbAccountMapper.xml

@@ -36,29 +36,32 @@
                               acc_salt = #{accSalt}
         where id = #{id}
     </update>
+    <update id="updateBalance">
+        update tb_account set total_money=#{balance} where id=#{id}
+    </update>
     <!-- ================================== 查询相关 ================================== -->
     <!-- 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="payPassword" column="pay_password" />
-        <result property="payPasswordSalt" column="pay_password_salt" />
-        <result property="createTime" column="create_time" />
-        <result property="createBy" column="create_by" />
-        <result property="updateTime" column="update_time" />
-        <result property="updateBy" column="update_by" />
-        <result property="taxNum" column="tax_num" />
-        <result property="bank" column="bank" />
-        <result property="bankAccount" column="bank_account" />
-        <result property="address" column="address" />
-        <result property="accSalt" column="acc_salt" />
+        <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="payPassword" column="pay_password"/>
+        <result property="payPasswordSalt" column="pay_password_salt"/>
+        <result property="createTime" column="create_time"/>
+        <result property="createBy" column="create_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="taxNum" column="tax_num"/>
+        <result property="bank" column="bank"/>
+        <result property="bankAccount" column="bank_account"/>
+        <result property="address" column="address"/>
+        <result property="accSalt" column="acc_salt"/>
     </resultMap>
 
     <!-- 查 - 根据id -->
@@ -74,75 +77,83 @@
     </sql>
 
     <!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
-    <select id="getList" resultMap="model">
+    <select id="getList" resultType="com.pj.project.tb_account.TbAccount">
         <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("payPassword") '> and pay_password = #{payPassword} </if>
-            <if test=' this.has("payPasswordSalt") '> and pay_password_salt = #{payPasswordSalt} </if>
-            <if test=' this.has("createTime") '> and create_time = #{createTime} </if>
-            <if test=' this.has("createBy") '> and create_by = #{createBy} </if>
-            <if test=' this.has("updateTime") '> and update_time = #{updateTime} </if>
-            <if test=' this.has("updateBy") '> and update_by = #{updateBy} </if>
-            <if test=' this.has("taxNum") '> and tax_num = #{taxNum} </if>
-            <if test=' this.has("bank") '> and bank = #{bank} </if>
-            <if test=' this.has("bankAccount") '> and bank_account = #{bankAccount} </if>
-            <if test=' this.has("address") '> and address = #{address} </if>
-            <if test=' this.has("accSalt") '> and acc_salt = #{accSalt} </if>
+            <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("accountNo") '>and account_no = #{accountNo}</if>
+            <if test=' this.has("lockMoney") '>and lock_money = #{lockMoney}</if>
+            <if test=' this.has("filterMoney") '>and total_money &gt; 0</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("payPassword") '>and pay_password = #{payPassword}</if>
+            <if test=' this.has("payPasswordSalt") '>and pay_password_salt = #{payPasswordSalt}</if>
+            <if test=' this.has("createTime") '>and create_time = #{createTime}</if>
+            <if test=' this.has("createBy") '>and create_by = #{createBy}</if>
+            <if test=' this.has("updateTime") '>and update_time = #{updateTime}</if>
+            <if test=' this.has("updateBy") '>and update_by = #{updateBy}</if>
+            <if test=' this.has("taxNum") '>and tax_num = #{taxNum}</if>
+            <if test=' this.has("bank") '>and bank = #{bank}</if>
+            <if test=' this.has("bankAccount") '>and bank_account = #{bankAccount}</if>
+            <if test=' this.has("address") '>and address = #{address}</if>
+            <if test=' this.has("accSalt") '>and acc_salt = #{accSalt}</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'> pay_password desc </when>
-            <when test='sortType == 9'> pay_password_salt desc </when>
-            <when test='sortType == 10'> create_time desc </when>
-            <when test='sortType == 11'> create_by desc </when>
-            <when test='sortType == 12'> update_time desc </when>
-            <when test='sortType == 13'> update_by desc </when>
-            <when test='sortType == 14'> tax_num desc </when>
-            <when test='sortType == 15'> bank desc </when>
-            <when test='sortType == 16'> bank_account desc </when>
-            <when test='sortType == 17'> address desc </when>
-            <when test='sortType == 18'> acc_salt desc </when>
-            <otherwise> id desc </otherwise>
+            <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'>pay_password desc</when>
+            <when test='sortType == 9'>pay_password_salt desc</when>
+            <when test='sortType == 10'>create_time desc</when>
+            <when test='sortType == 11'>create_by desc</when>
+            <when test='sortType == 12'>update_time desc</when>
+            <when test='sortType == 13'>update_by desc</when>
+            <when test='sortType == 14'>tax_num desc</when>
+            <when test='sortType == 15'>bank desc</when>
+            <when test='sortType == 16'>bank_account desc</when>
+            <when test='sortType == 17'>address desc</when>
+            <when test='sortType == 18'>acc_salt desc</when>
+            <otherwise>id desc</otherwise>
         </choose>
     </select>
 
 
     <select id="getTbAccountBOList" resultType="com.pj.project.tb_account.TbAccountBO">
-        select a.id,c.id as customerId,c.name as customerName,c.phone,c.duty_people as dutyPeople,a.total_money as totalMoney,
+        select a.id,c.id as customerId,c.name as customerName,c.phone,c.duty_people as dutyPeople,a.total_money as
+        totalMoney,
         a.tax_num as taxNum,a.bank,a.bank_account as bankAccount,a.update_time as updateTime,a.update_by as updateBy,
         a.address
-        from tb_costomer c left join tb_account a on c.id=a.customer_id
-        <where>
-            and c.status=1 and c.judge_status=2
-            <if test=' this.has("customerId") '> and c.id = #{customerId} </if>
-            <if test=' this.has("customerName") '> and c.name like "%" #{customerName} "%" </if>
-            <if test=' this.has("phone") '> and c.phone like "%" #{phone} "%" </if>
-            <if test=' this.has("dutyPeople") '> and c.duty_people like "%" #{dutyPeople} "%" </if>
-            <if test=' this.has("updateBy") '> and a.update_by like "%" #{updateBy} "%" </if>
-        </where>
-
+        from tb_costomer c ,tb_account a where c.id=a.customer_id and c.status=1 and c.judge_status=2
+        <if test=' this.has("customerId") '>and c.id = #{customerId}</if>
+        <if test=' this.has("customerName") '>and c.name like "%" #{customerName} "%"</if>
+        <if test=' this.has("phone") '>and c.phone like "%" #{phone} "%"</if>
+        <if test=' this.has("dutyPeople") '>and c.duty_people like "%" #{dutyPeople} "%"</if>
+        <if test=' this.has("updateBy") '>and a.update_by like "%" #{updateBy} "%"</if>
+        order by a.total_money desc
     </select>
 
     <select id="getAccountByPlate" resultType="com.pj.project.tb_account.TbAccount">
         select a.* from tb_deduction_bind b left join tb_account a on a.customer_id=b.customer_id
         <where>
             and a.status=1 and b.unbind_time is null
-            and b.bind_car = #{plate} 
+            and b.bind_car = #{plate}
         </where>
     </select>
+    <select id="getByCustomerId" resultType="com.pj.project.tb_account.TbAccountBO">
+           select a.id,c.id as customerId,c.name as customerName,c.phone,c.duty_people as dutyPeople,a.total_money as
+        totalMoney,
+        a.tax_num as taxNum,a.bank,a.bank_account as bankAccount,a.update_time as updateTime,a.update_by as updateBy,
+        a.address
+        from tb_costomer c ,tb_account a where c.id=a.customer_id and c.status=1 and c.judge_status=2
+        and c.id=#{customerId}
+    </select>
 
 </mapper>

+ 281 - 92
sp-server/src/main/java/com/pj/project/tb_account/TbAccountService.java

@@ -3,27 +3,50 @@ package com.pj.project.tb_account;
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.codec.Base64;
 import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.RandomUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.log.StaticLog;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.annotation.ExcelProperty;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.pj.current.config.SystemObject;
 import com.pj.current.satoken.StpUserUtil;
+import com.pj.project.tb_charge_record.BalanceDTO;
 import com.pj.project.tb_charge_record.TbChargeRecord;
 import com.pj.project.tb_charge_record.TbChargeRecordService;
 import com.pj.project.tb_costomer.TbCostomer;
 import com.pj.project.tb_costomer.TbCostomerService;
+import com.pj.project.tb_deduction_bind.TbDeductionBindService;
+import com.pj.project.tb_deduction_record.TbDeductionRecord;
+import com.pj.project.tb_deduction_record.TbDeductionRecordService;
+import com.pj.project.tb_refund_record.TbRefundRecord;
+import com.pj.project.tb_refund_record.TbRefundRecordService;
+import com.pj.project4sp.uploadfile.UploadConfig;
 import com.pj.utils.AesUtil;
 import com.pj.utils.sg.AjaxError;
 import com.pj.utils.sg.NbUtil;
 import com.pj.utils.so.SoMap;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
+import java.io.File;
 import java.math.BigDecimal;
+import java.text.DateFormat;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * Service: tb_account -- 客户账户
@@ -42,123 +65,85 @@ public class TbAccountService extends ServiceImpl<TbAccountMapper, TbAccount> im
     TbCostomerService tbCostomerService;
     @Resource
     TbChargeRecordService tbChargeRecordService;
+    @Resource
+    private TbRefundRecordService tbRefundRecordService;
+    @Resource
+    @Lazy
+    private TbDeductionRecordService tbDeductionRecordService;
+    @Resource
+    private UploadConfig uploadConfig;
 
     /**
      * 根据客户Id,获取客户存款账户,并解密金额
+     *
      * @param customerId
      * @return
      */
-    public TbAccount getByCustomerId(String customerId) {
-        QueryWrapper<TbAccount> ew = new QueryWrapper<>();
-        ew.eq("customer_id", customerId);
-        TbAccount account = tbAccountMapper.selectOne(ew);
-        if (account == null) {
-            account = new TbAccount();
-        }
-        String key = AesUtil.reverse(account.getAccSalt());
-        account.setTotalMoney(AesUtil.decryptECB(account.getTotalMoney(),key));
-
-        return account;
+    public TbAccountBO getByCustomerId(String customerId) {
+        return tbAccountMapper.getByCustomerId(customerId);
     }
 
-    public List<TbAccountBO> getList(SoMap so){
-        return tbAccountMapper.getTbAccountBOList(so);
-    }
-
-    public void recharge(String customerId, String money) {
-        TbAccount account = this.getByCustomerId(customerId);
-        recharge(account, TbChargeRecord.Ch.PC.getType(), new BigDecimal(money), new BigDecimal(money));
+    public TbAccount getAccountByCustomerId(String customerId) {
+        QueryWrapper<TbAccount> ew = new QueryWrapper<>();
+        ew.lambda().eq(TbAccount::getCustomerId, customerId);
+        return getOne(ew);
     }
 
-    public void recharge(String id, BigDecimal money, String chargeType, BigDecimal payMoney) {
-        TbAccount account = this.getById(id);
-        recharge(account, chargeType, money, payMoney);
+    public List<TbAccountBO> getList(SoMap so) {
+        return tbAccountMapper.getTbAccountBOList(so);
     }
 
-    public void recharge(TbAccount account, String chargeType, BigDecimal money, BigDecimal payMoney) {
-        String totalMoney = account.getTotalMoney();
-        if (NumberUtil.isNumber(totalMoney)) {
-            totalMoney = Base64.encode(totalMoney.getBytes());
-        }
-        BigDecimal total = new BigDecimal(Base64.decodeStr(totalMoney)).add(money);
-        account.setTotalMoney(Base64.encode(total.toString()));
-        this.updateById(account);
-        String customerId = account.getCustomerId();
-        TbChargeRecord record = new TbChargeRecord();
-        TbCostomer tbCostomer = tbCostomerService.getById(customerId);
-        record.setChargeChannel(chargeType).setMoney(money).setPayMoney(payMoney)
-                .setCreateTime(new Date()).setNo(DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomNumbers(4))
-                .setCustomerId(customerId).setCustomerName(tbCostomer.getName());
-        tbChargeRecordService.save(record);
-
-    }
 
     /**
      * 充值
      */
-    public void recharge(SoMap so){
-        String salt = so.getString("salt");
-        String preTopupMoney = so.getString("preTopupMoney");//充值金额
-        String discountMoney = so.getString("discountMoney");//优惠金额
-        String key = AesUtil.reverse(salt);
-        String decTotalTopup = AesUtil.decryptECB(preTopupMoney,key);
-        if(!NumberUtil.isNumber(decTotalTopup)){
-            throw new AjaxError("充值金额必须是数字!");
-        }
-        if(Double.valueOf(decTotalTopup)<=0){
-            throw new AjaxError("总计充值金额不得小于零元!");
-        }
-        String beforeBalance = preTopupMoney;
-        TbAccount account;
-        String accIdStr = so.getString("id");
-        if(!NumberUtil.isNumber(accIdStr)){
-            account = getTbAccountByMap(so);
-            account.setTotalMoney(preTopupMoney);
-            account.setAccSalt(salt);
-        }else {
-            long accId = Long.parseLong(accIdStr);
-            account = tbAccountMapper.getById(accId);
-            String totalMoneyStr = AesUtil.decryptECB(account.getTotalMoney(),AesUtil.reverse(account.getAccSalt()));
-            if(NumberUtil.isNumber(totalMoneyStr)){
-                beforeBalance = account.getTotalMoney();
-                BigDecimal totalMoneyBig =new BigDecimal(totalMoneyStr).add(new BigDecimal(decTotalTopup));
-                account.setTotalMoney(AesUtil.encryptECB(totalMoneyBig.toString(),key));
-                account.setAccSalt(salt);
-                account.setUpdateTime(new Date());
-                account.setUpdateBy(StpUserUtil.getLoginName());
-            }
-        }
-        account.insertOrUpdate();
+    public void recharge(ChargeBO chargeBO) {
+        TbAccount tbAccount = this.getById(chargeBO.getId());
+        //账户余额
+        BigDecimal balance = tbAccount.getTotalMoney();
+        BigDecimal zero = BigDecimal.ZERO;
+        //充值金额
+        BigDecimal chargeMoney = chargeBO.getPreTopupMoney();
+        BigDecimal afterChargeBalance = chargeMoney.add(balance);
+        tbAccount.setTotalMoney(afterChargeBalance);
+        this.updateById(tbAccount);
         //保存充值记录
-        TbChargeRecord record = BeanUtil.fillBeanWithMap(so, new TbChargeRecord(),false);
-        record.setStatus(1)
-                .setId(null)
-                .setAccountId(account.getId())
-                .setTotalTopupMoney(preTopupMoney)
-                .setPreTopupMoney(preTopupMoney)
-                .setDiscountMoney(discountMoney)
-                .setTotalMoney(account.getTotalMoney())
-                .setBeforeBalance(beforeBalance)
+        TbCostomer tbCostomer = tbCostomerService.getById(chargeBO.getCustomerId());
+        TbChargeRecord record = new TbChargeRecord();
+        //余额=原金额+本次充值金额-退款金额 ----->充值时退款金额为0
+        record.setTotalMoney(balance.add(chargeMoney));
+        record.setStatus(1).setType(TbChargeRecord.TypeEunm.ACCOUNT_CHARGE.getType())
+                .setBeforeMoney(balance)
+                //充值金额
+                .setPreTopupMoney(chargeBO.getPreTopupMoney())
+                //实际收款金额
+                .setTotalTopupMoney(chargeBO.getTotalTopup())
+                //优惠金额
+                .setRefundMoney(zero).setCustomerId(tbAccount.getCustomerId())
+                .setDiscountMoney(chargeBO.getDiscountMoney())
+                .setCustomerName(tbCostomer.getName())
+                .setRemark(chargeBO.getRemark())
+                .setAccountId(tbAccount.getId())
                 .setChargeChannel(TbChargeRecord.Ch.PC.getType())
-                .setCreateTime(new Date())
-                .setSalt(salt)
+                .setCreateTime(new Date()).setPayingType(chargeBO.getPayingType())
                 .setChargePeople(StpUserUtil.getLoginName())
                 .setNo(getIdByNow());
-      tbChargeRecordService.save(record);
+        tbChargeRecordService.save(record);
     }
 
     /**
      * 修改Account
+     *
      * @param so
      */
-    public void updateAccount(SoMap so){
+    public void updateAccount(SoMap so) {
         String accIdStr = so.getString("id");
         TbAccount account = null;
-        if(!NumberUtil.isNumber(accIdStr)){
+        if (!NumberUtil.isNumber(accIdStr)) {
             account = getTbAccountByMap(so);
-        }else {
+        } else {
             account = tbAccountMapper.getById(Long.parseLong(accIdStr));
-            account = BeanUtil.fillBeanWithMap(so, account,false);
+            account = BeanUtil.fillBeanWithMap(so, account, false);
             account.setUpdateBy(StpUserUtil.getLoginName());
             account.setUpdateTime(new Date());
         }
@@ -171,11 +156,12 @@ public class TbAccountService extends ServiceImpl<TbAccountMapper, TbAccount> im
 
     /**
      * 根据Map赋值,生成Account对象
+     *
      * @param so
      * @return
      */
-    private TbAccount getTbAccountByMap(SoMap so){
-        TbAccount account = BeanUtil.fillBeanWithMap(so, new TbAccount(),false);
+    private TbAccount getTbAccountByMap(SoMap so) {
+        TbAccount account = BeanUtil.fillBeanWithMap(so, new TbAccount(), false);
         account.setId(null);
         String loginName = StpUserUtil.getLoginName();
         account.setCreateBy(loginName);
@@ -189,17 +175,220 @@ public class TbAccountService extends ServiceImpl<TbAccountMapper, TbAccount> im
 
     /**
      * 根据车牌号获取绑定信息
+     *
      * @param plate
      * @return
      */
-    public TbAccount getTbAccountByPlate(String plate){
-        if(NbUtil.isNullStr(plate)) return null;
+    public TbAccount getTbAccountByPlate(String plate) {
+        if (NbUtil.isNullStr(plate)) return null;
         return tbAccountMapper.getAccountByPlate(plate);
     }
 
-    public String getIdByNow(){
+    public String getIdByNow() {
         return DateUtil.format(new Date(), "yyyyMMddHHmmss") + RandomUtil.randomNumbers(4);
     }
 
 
+    public void updateBalance(String id, BigDecimal balance) {
+        tbAccountMapper.updateBalance(id, balance);
+    }
+
+    /**
+     * 退款
+     *
+     * @param id
+     * @param refundMoney
+     * @param refundReason
+     */
+    public void refund(String id, BigDecimal refundMoney, int payingType, String refundReason) {
+        TbAccount tbAccount = this.getById(id);
+        if (tbAccount == null) {
+            throw new AjaxError("账户不存在");
+        }
+        BigDecimal balance = tbAccount.getTotalMoney();
+        if (balance.compareTo(refundMoney) < 0) {
+            throw new AjaxError("可用余额不足");
+        }
+        //更新余额
+        tbAccount.setTotalMoney(balance.subtract(refundMoney));
+        this.updateById(tbAccount);
+        // 保存退款记录
+        TbChargeRecord record = new TbChargeRecord();
+        BigDecimal zero = BigDecimal.valueOf(0);
+        record.setStatus(1).setType(TbChargeRecord.TypeEunm.ACCOUNT_REFUND.getType())
+                .setBeforeMoney(balance)
+                .setPreTopupMoney(zero)
+                .setTotalTopupMoney(zero)
+                .setPayMoney(zero)
+                .setCustomerId(tbAccount.getCustomerId())
+                .setRefundMoney(refundMoney)
+                .setDiscountMoney(zero)
+                .setTotalMoney(balance.subtract(refundMoney))
+                .setCustomerName(tbAccount.getCustomerName())
+                .setRemark(refundReason).setRefundBy(StpUserUtil.getCreateBy())
+                .setRefundTime(new Date())
+                .setAccountId(tbAccount.getId())
+                .setChargeChannel(TbChargeRecord.Ch.PC.getType())
+                .setCreateTime(new Date()).setPayingType(payingType)
+                .setChargePeople(StpUserUtil.getLoginName())
+                .setNo(getIdByNow());
+        tbChargeRecordService.save(record);
+        TbRefundRecord tbRefundRecord = new TbRefundRecord();
+        tbRefundRecord.setRefundMoney(refundMoney).setRefundDesc(refundReason)
+                .setRefundNo(getIdByNow()).setRefundBy(StpUserUtil.getCreateBy())
+                .setRefundTime(new Date()).setRefundType(TbChargeRecord.TypeEunm.ACCOUNT_REFUND.getType())
+                .setCustomerName(tbAccount.getCustomerName());
+        tbRefundRecordService.save(tbRefundRecord);
+    }
+
+    /**
+     * 获取账户余额---列表
+     *
+     * @param soMap
+     * @return
+     */
+    public List<TbBalanceBO> getBalanceList(SoMap soMap) {
+        List<TbAccount> list = tbAccountMapper.getList(soMap);
+        String endDay = soMap.getString("endTime");
+        //充值、余额退款、异常单退款
+        List<TbChargeRecord> endChargeList = tbChargeRecordService.getChargeListBefore(endDay);
+        //累计扣款
+        List<TbDeductionRecord> endDeductionRecordList = tbDeductionRecordService.getBeforeList(endDay);
+        String beginDay = soMap.getString("beginTime");
+        List<TbBalanceBO> tbBalanceBOList = new ArrayList<>();
+        for (TbAccount tbAccount : list) {
+            TbBalanceBO tbBalanceBO = new TbBalanceBO();
+            tbBalanceBO.setCustomerName(tbAccount.getCustomerName());
+            String customerId = tbAccount.getCustomerId();
+            //期末累计充值
+            double endChargeSum = endChargeList.stream().filter(tbChargeRecord -> StrUtil.equals(tbChargeRecord.getCustomerId(), customerId))
+                    .collect(Collectors.summarizingDouble(record -> record.getPreTopupMoney().doubleValue())).getSum();
+            //期末累计余额退款
+            double endBalanceRefundSum = endChargeList.stream()
+                    .filter(tbChargeRecord -> StrUtil.equals(tbChargeRecord.getCustomerId(), customerId) && tbChargeRecord.getType() == 2)
+                    .collect(Collectors.summarizingDouble(record -> record.getRefundMoney().doubleValue())).getSum();
+            //期末累计异常单退款
+            double endErrorOrderRefundSum = endChargeList.stream()
+                    .filter(tbChargeRecord -> StrUtil.equals(tbChargeRecord.getCustomerId(), customerId) && tbChargeRecord.getType() == 3)
+                    .collect(Collectors.summarizingDouble(record -> record.getRefundMoney().doubleValue())).getSum();
+            //累计扣款
+            double endDeductMoney = endDeductionRecordList.stream().filter(tbDeductionRecord -> StrUtil.equals(tbDeductionRecord.getCustomerId(), customerId))
+                    .collect(Collectors.summarizingDouble(record -> record.getDeductMoney().doubleValue())).getSum();
+            //退款金额
+            BigDecimal endRefundMoney = BigDecimal.valueOf(NumberUtil.sub(endBalanceRefundSum, endErrorOrderRefundSum));
+            //最终余额 =累计充值-累计扣除-(累计余额退款-累计异常单退款)
+            BigDecimal endBalance = BigDecimal.valueOf(endChargeSum).subtract(BigDecimal.valueOf(endDeductMoney)).subtract(endRefundMoney);
+            StaticLog.info("{},{}", tbAccount.getCustomerName(), endBalance);
+            tbBalanceBO.setEndMoney(endBalance);
+            //期初点累计充值
+            double startChargeSum = endChargeList.stream()
+                    .filter(tbChargeRecord -> {
+                        String chargeDay = DateUtil.format(tbChargeRecord.getCreateTime(), "yyyy-MM-dd");
+                        return StrUtil.equals(tbChargeRecord.getCustomerId(), customerId) && StrUtil.compare(chargeDay, beginDay, true) < 0;
+                    })
+                    .collect(Collectors.summarizingDouble(record -> record.getPreTopupMoney().doubleValue())).getSum();
+            //期初累计余额退款
+            double startBalanceRefundSum = endChargeList.stream()
+                    .filter(tbChargeRecord -> {
+                        String chargeDay = DateUtil.format(tbChargeRecord.getCreateTime(), "yyyy-MM-dd");
+                        return StrUtil.equals(tbChargeRecord.getCustomerId(), customerId)
+                                && tbChargeRecord.getType() == 2
+                                && StrUtil.compare(chargeDay, beginDay, true) < 0;
+                    })
+                    .collect(Collectors.summarizingDouble(record -> record.getRefundMoney().doubleValue())).getSum();
+            //期初累计异常单退款
+            double startErrorOrderRefundSum = endChargeList.stream()
+                    .filter(tbChargeRecord -> {
+                        String chargeDay = DateUtil.format(tbChargeRecord.getCreateTime(), "yyyy-MM-dd");
+                        return StrUtil.equals(tbChargeRecord.getCustomerId(), customerId)
+                                && tbChargeRecord.getType() == 3
+                                && StrUtil.compare(chargeDay, beginDay, true) < 0;
+                    })
+                    .collect(Collectors.summarizingDouble(record -> record.getRefundMoney().doubleValue())).getSum();
+            //累计扣款
+            double startDeductMoney = endDeductionRecordList.stream()
+                    .filter(tbDeductionRecord -> {
+                        String chargeDay = DateUtil.format(tbDeductionRecord.getCreateTime(), "yyyy-MM-dd");
+                        return StrUtil.equals(tbDeductionRecord.getCustomerId(), customerId) && StrUtil.compare(chargeDay, beginDay, true) < 0;
+                    })
+                    .collect(Collectors.summarizingDouble(record -> record.getDeductMoney().doubleValue())).getSum();
+            //期初余额 =累计充值-累计扣除-累计余额退款+累计异常单退款
+            //退款金额
+            BigDecimal startRefundMoney = BigDecimal.valueOf(NumberUtil.sub(startBalanceRefundSum, startErrorOrderRefundSum));
+            //最终余额 =累计充值-累计扣除-(累计余额退款-累计异常单退款)
+            BigDecimal startBalance = BigDecimal.valueOf(startChargeSum).subtract(BigDecimal.valueOf(startDeductMoney)).subtract(startRefundMoney);
+            StaticLog.info("{},{}", tbAccount.getCustomerName(), startBalance);
+            tbBalanceBO.setDeuctionMoney(BigDecimal.valueOf(NumberUtil.sub(endDeductMoney, startDeductMoney)))
+                    .setBalanceRefundMoney(BigDecimal.valueOf(NumberUtil.sub(endBalanceRefundSum, startBalanceRefundSum)))
+                    .setErrorRefundMoney(BigDecimal.valueOf(NumberUtil.sub(endErrorOrderRefundSum, startErrorOrderRefundSum)))
+                    .setChargeMoney(BigDecimal.valueOf(NumberUtil.sub(endChargeSum, startChargeSum))).setBeginMoney(startBalance);
+            tbBalanceBOList.add(tbBalanceBO);
+        }
+        BigDecimal zero = BigDecimal.ZERO;
+        return tbBalanceBOList.stream().filter(tbBalanceBO -> tbBalanceBO.getBeginMoney().compareTo(zero) > 0
+                || tbBalanceBO.getChargeMoney().compareTo(zero) > 0 || tbBalanceBO.getDeuctionMoney().compareTo(zero) > 0 || tbBalanceBO.getEndMoney().compareTo(zero) > 0)
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * 获取账户余额--分页
+     */
+    public Page<TbBalanceBO> getBalancePage(SoMap soMap) {
+        List<TbBalanceBO> tbBalanceBOList = getBalanceList(soMap);
+        int pageNo = soMap.getInt("pageNo");
+        int pageSize = soMap.getInt("pageSize");
+        int total = tbBalanceBOList.size();
+        tbBalanceBOList = tbBalanceBOList.stream().skip((pageNo - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
+        Page<TbBalanceBO> page = new Page<>();
+        page.setSize(total).setRecords(tbBalanceBOList);
+        return page;
+    }
+
+    public String export(SoMap soMap) {
+        List<TbBalanceBO> list = this.getBalanceList(soMap);
+        BigDecimal beginMoney = BigDecimal.ZERO;
+        BigDecimal chargeMoney = BigDecimal.ZERO;
+        BigDecimal deuctionMoney = BigDecimal.ZERO;
+        BigDecimal balanceRefundMoney = BigDecimal.ZERO;
+        BigDecimal errorRefundMoney = BigDecimal.ZERO;
+        BigDecimal endMoney = BigDecimal.ZERO;
+        for (int i = 0; i < list.size(); i++) {
+            TbBalanceBO tbBalanceBO = list.get(i);
+            tbBalanceBO.setIndex(i + 1);
+            beginMoney = beginMoney.add(tbBalanceBO.getBeginMoney());
+            chargeMoney = chargeMoney.add(tbBalanceBO.getChargeMoney());
+            deuctionMoney = deuctionMoney.add(tbBalanceBO.getDeuctionMoney());
+            balanceRefundMoney = balanceRefundMoney.add(tbBalanceBO.getBalanceRefundMoney());
+            errorRefundMoney = errorRefundMoney.add(tbBalanceBO.getErrorRefundMoney());
+            endMoney = endMoney.add(tbBalanceBO.getEndMoney());
+        }
+        TbBalanceBO tbBalanceBO = new TbBalanceBO();
+        tbBalanceBO.setIndex(list.size() + 1).setEndMoney(endMoney)
+                .setChargeMoney(chargeMoney).setDeuctionMoney(deuctionMoney).setCustomerName("合计")
+                .setBalanceRefundMoney(balanceRefundMoney).setErrorRefundMoney(errorRefundMoney).setBeginMoney(beginMoney);
+        list.add(tbBalanceBO);
+        String flieTypeFolder = "/export/";
+        String currDateFolder = DateUtil.today();
+        String fileName = "record-" + RandomUtil.randomNumbers(6) + ".xlsx";
+        String fileFolder = new File(uploadConfig.rootFolder).getAbsolutePath() +
+                uploadConfig.httpPrefix + flieTypeFolder + currDateFolder + "/";
+        if (!FileUtil.exist(fileFolder)) {
+            FileUtil.mkdir(fileFolder);
+        }
+        EasyExcel.write(fileFolder + fileName, TbBalanceBO.class).sheet("余额列表导出")
+                .doWrite(() -> list);
+        return SystemObject.config.getDomain() + uploadConfig.httpPrefix + flieTypeFolder + currDateFolder + "/" + fileName;
+
+    }
+
+    /**
+     * 获取筛选的总金额
+     * @param soMap
+     * @return
+     */
+    public Double getSum(SoMap soMap) {
+        List<TbAccountBO> list = this.getList(soMap);
+        return list.stream().collect(Collectors.summarizingDouble(account -> account.getTotalMoney().doubleValue())).getSum();
+    }
 }
+

+ 52 - 0
sp-server/src/main/java/com/pj/project/tb_account/TbBalanceBO.java

@@ -0,0 +1,52 @@
+package com.pj.project.tb_account;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+@Accessors(chain = true)
+public class TbBalanceBO implements Serializable {
+
+    @ExcelProperty(index = 0,value = "序号")
+    private int index;
+    /**
+     * 企业
+     */
+    @ExcelProperty(index = 1,value = "企业名称")
+    private String customerName;
+    /**
+     * 期初余额
+     */
+    @ExcelProperty(index = 2,value = "期初余额")
+    private BigDecimal beginMoney=BigDecimal.ZERO;
+    /**
+     * 充值金额
+     */
+    @ExcelProperty(index = 3,value = "本期充值")
+    private BigDecimal chargeMoney=BigDecimal.ZERO;
+    /**
+     * 本期扣款
+     */
+    @ExcelProperty(index = 4,value = "本期扣除")
+    private BigDecimal deuctionMoney=BigDecimal.ZERO;
+    /**
+     * 余额退款
+     */
+    @ExcelProperty(index = 5,value = "余额退款")
+    private BigDecimal balanceRefundMoney=BigDecimal.ZERO;
+    /**
+     * 异常单退款
+     */
+    @ExcelProperty(index = 6,value = "异常退款")
+    private BigDecimal errorRefundMoney=BigDecimal.ZERO;
+
+    /**
+     * 期末余额
+     */
+    @ExcelProperty(index = 7,value = "期末余额")
+    private BigDecimal endMoney=BigDecimal.ZERO;
+}

+ 2 - 0
sp-server/src/main/java/com/pj/project/tb_business/OtherBusinessBO.java

@@ -15,6 +15,7 @@ public class OtherBusinessBO implements Serializable {
     private String id;
     private String customerId;
     private String customerName;
+    private String pickCustomerName;
     private String declareNo;
     private String operator;
     private String chinaCarNo;
@@ -27,6 +28,7 @@ public class OtherBusinessBO implements Serializable {
     private String carJson;
     private String itemJson;
     private String owner;
+    private String pickCustomerId;
     private Double netWeight;
     private List<TbItem> items = new ArrayList<>();
     private List<TbBusinessCar> cars = new ArrayList<>();

+ 10 - 5
sp-server/src/main/java/com/pj/project/tb_business/TbBusiness.java

@@ -14,9 +14,8 @@ import lombok.experimental.Accessors;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * Model: tb_business -- 入境登记
@@ -309,6 +308,12 @@ public class TbBusiness extends Model<TbBusiness> implements Serializable {
      * 计费系统订单计算ID
      */
     private String calculateId;
+    private String pickCustomerName;
+    private String pickCustomerId;
+    /**
+     * 是否存在异常
+     */
+    private int hasError=0;
 
 
 
@@ -321,7 +326,7 @@ public class TbBusiness extends Model<TbBusiness> implements Serializable {
     private String carNoStr;
 
     public String getCarNoStr() {
-        List<String>list=new ArrayList<>();
+        Set<String> list=new HashSet<>();
         String carNo=getCardNo();
         String chinaCarNo=getChinaCarNo();
         if (StrUtil.isNotEmpty(carNo)){
@@ -330,7 +335,7 @@ public class TbBusiness extends Model<TbBusiness> implements Serializable {
         if (StrUtil.isNotEmpty(chinaCarNo)){
             list.add(chinaCarNo);
         }
-        return StrUtil.join("、",list);
+        return  StrUtil.splitTrim(StrUtil.join("、",list),"、").stream().distinct().collect(Collectors.joining("、"));
     }
 
     public void setCardNo(String cardNo) {

+ 20 - 24
sp-server/src/main/java/com/pj/project/tb_business/TbBusinessController.java

@@ -55,15 +55,12 @@ public class TbBusinessController {
     private TbBusinessCarService tbBusinessCarService;
 
 
-
     @RequestMapping(value = "getMsg")
     public AjaxJson getMsg() {
         return AjaxJson.getSuccessData(BusinessMessageManager.get(StpUserUtil.getCustomerId()));
     }
 
 
-
-
     /**
      * 确认业务
      */
@@ -241,27 +238,6 @@ public class TbBusinessController {
         return AjaxJson.getSuccess();
     }
 
-    /**
-     * 线下收费
-     *
-     * @return
-     */
-    @RequestMapping("manualConfirm")
-    @SaCheckPermission(TbBusiness.PERMISSION_MANUAL_PAY)
-    public AjaxJson manualConfirm() {
-        SoMap so = SoMap.getRequestSoMap();
-        String id = so.getString("id");
-        String remark = so.getString("remark");
-        String cars = so.getString("cars");
-        Date payTime = so.getDateTime("payTime");
-        int payChannelType = so.getInt("payChannelType");
-        int payType = so.getInt("payType");
-        String transactionId = so.getString("transactionId");
-        List<TbBusinessCar> carList = JSONUtil.toList(cars, TbBusinessCar.class);
-        tbBusinessService.manualConfirmPay(id, carList, remark,payTime,payChannelType,payType,transactionId);
-        return AjaxJson.getSuccess();
-    }
-
 
     @RequestMapping(value = "unBindCar")
     public AjaxJson unBindCar(String id, String businessCarId) {
@@ -385,4 +361,24 @@ public class TbBusinessController {
     }
 
 
+    @RequestMapping("addCar")
+    @SaCheckPermission(value = TbBusiness.PERMISSION_FLAX_BUSINESS_EDIT)
+    public AjaxJson addCar(TbBusinessCar tbBusinessCar) {
+        if (StrUtil.isEmpty(tbBusinessCar.getCarNo())) {
+            return AjaxJson.getError("请输入车牌号");
+        }
+        tbBusinessService.addBusinessCar(tbBusinessCar);
+
+        return AjaxJson.getSuccess();
+    }
+
+    /**
+     * 查
+     */
+    @RequestMapping("deleteBusinessCar")
+    @SaCheckPermission(TbBusiness.PERMISSION_FLAX_BUSINESS_EDIT)
+    public AjaxJson delete(String id, String businessId) {
+        tbBusinessService.deleteBusinessCar(id,businessId);
+        return AjaxJson.getSuccess();
+    }
 }

+ 4 - 0
sp-server/src/main/java/com/pj/project/tb_business/TbBusinessMapper.xml

@@ -16,6 +16,7 @@
             <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("pickCustomerName") '>and pick_customer_name like concat('%', #{pickCustomerName} ,'%')</if>
             <if test=' this.has("owner") '>and owner like concat('%', #{owner} ,'%')</if>
             <if test=' this.has("no") '>and no like concat('%', #{no},'%')</if>
             <if test=' this.has("businessGoodsName") '>and business_goods_name like concat('%', #{businessGoodsName},'%')</if>
@@ -52,6 +53,9 @@
             <if test='adminConfirmInput !=null and adminConfirmInput>-1'>and admin_confirm_input =
                 #{adminConfirmInput}
             </if>
+            <if test='hasError !=null and hasError>-1'>and has_error =
+                #{hasError}
+            </if>
             <if test='isCar==0'>
                 and declare_no is not null
             </if>

+ 147 - 202
sp-server/src/main/java/com/pj/project/tb_business/TbBusinessService.java

@@ -23,6 +23,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 
 import com.pj.api.open.bo.ItemPriceBO;
 import com.pj.api.pushfee.oa.CallbackBO;
+import com.pj.api.wx.bo.ManagerBO;
 import com.pj.api.wx.bo.MsgDataBO;
 import com.pj.api.wx.bo.PriceBO;
 import com.pj.api.wx.service.WxService;
@@ -331,6 +332,9 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
     public IOrderPriceRes getPartMoney(Date iTime, Date oTime, String carNo, String carColor) {
         long minutes = DateUtil.between(iTime, oTime, DateUnit.MINUTE);
         double hours = NumberUtil.div(minutes, 60, 1);
+        if (hours == 0) {
+            hours = 0.1D;
+        }
         List<IOrderItem> expenses = new ArrayList<>();
         TbMildCar tbMildCar = tbMildCarService.findByCarNo(carNo);
         IOrderPriceRes res = new IOrderPriceRes();
@@ -339,7 +343,7 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
         res.setHourDesc(PartFeeEnum.IN_24_HOURS.getDesc());
         if (tbMildCar == null) {
             // 9.6以上
-            carSize = 13D;
+            carSize = 12D;
             res.setCarDesc(PartFeeEnum.BIG_CAR.getDesc());
         }
         if (hours > 24) {
@@ -425,7 +429,6 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
     }
 
 
-
     /**
      * 微信端获取缴费信息
      *
@@ -437,23 +440,10 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
         Map<String, Object> result = new HashMap<>();
         //对应的业务
         List<TbBusiness> businessList = this.findOtherBusinessByCarId(businessCarId);
+        //是否需要交停车费---->业务车都要交
+//        boolean needPayPartMoney = !businessList.isEmpty();
         TbBusinessCar tbBusinessCar = tbBusinessCarService.getById(businessCarId);
         String carNo = tbBusinessCar.getCarNo();
-        //越南车是否需要支付---停车费
-        int vietnamCarPay = businessList.stream().anyMatch(tbBusiness -> {
-            TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
-            return tbGoods.getVietnamCarPay() == 1;
-        }) ? 1 : 0;
-        //中国车是否需要支付--停车费
-        int chinaCarPay = businessList.stream().anyMatch(tbBusiness -> {
-            TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
-            return tbGoods.getChinaCarPay() == 1;
-        }) ? 1 : 0;
-        //无业务的车辆,中国车和越南车都需要支付
-        if (businessList.isEmpty()) {
-            vietnamCarPay = 1;
-            chinaCarPay = 1;
-        }
         businessList = businessList.stream().filter(tbBusiness -> {
             TbGoods tbGoods = tbGoodsService.getById(tbBusiness.getGoodsId());
             Integer payStep = tbGoods.getPayStep();
@@ -480,35 +470,22 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
         carMap.put("price", 0);
         List<String> carCalculateIds = new ArrayList<>();
         //停车费
-        if (pay == 0 && inTime != null) {
+        if (inTime != null) {
             Date outTime = tbBusinessCar.getRealOutTime();
             String cacheCarNo = RedisUtil.get(channel);
-            if (outTime == null && StrUtil.isNotEmpty(cacheCarNo)) {
+            if (outTime == null && StrUtil.isNotEmpty(cacheCarNo) && StrUtil.equals(carNo.trim().toUpperCase(), cacheCarNo.trim().toUpperCase())) {
                 outTime = new Date();
             }
             if (outTime != null) {
-                String carType = tbBusinessCar.getCarType();
-                if (StrUtil.isEmpty(carType)) {
-                    carType = CarEnum.CarTypeEnum.EMPTY_TYPE.getType();
-                }
                 //默认需要缴费--->
                 BigDecimal partMoney = new BigDecimal("1");
-
                 if (StrUtil.isNotEmpty(tbBusinessCar.getColor()) && tbBusinessCar.getCarSize() != null) {
                     String freeColor = partConfig.getFreeColor();
                     //4.2米以下蓝色车辆
-                    if (tbBusinessCar.getColor().contains(freeColor) && tbBusinessCar.getCarSize() <= partConfig.getFreeCarLength()) {
+                    if (tbBusinessCar.getColor().contains(freeColor)) {
                         partMoney = new BigDecimal("0");
                     }
                 }
-                //越南车牌,是否免费
-                if (CarEnum.CarTypeEnum.WEIGHT_TYPE.getType().equals(carType) && vietnamCarPay == 0) {
-                    partMoney = new BigDecimal("0");
-                }
-                //中国车,是否免费
-                if (CarEnum.CarTypeEnum.EMPTY_TYPE.getType().equals(carType) && chinaCarPay == 0) {
-                    partMoney = new BigDecimal("0");
-                }
                 if (CarEnum.PayTypeEnum.FEE_TYPE.getType().equals(tbBusinessCar.getPayType())) {
                     partMoney = new BigDecimal("0");
                 }
@@ -529,7 +506,6 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
                     }
                     //todo 计算停车费
                 }
-                // partMoney = calculationPartMoney(inTime, outTime, tbBusinessCar.getCarSize());
                 carMap.put("price", partMoney);
             }
         }
@@ -545,26 +521,9 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
             List<IOrderItem> expenses = new ArrayList<>();
             items = items.stream().filter(item -> item.getPayStatus() == 0).collect(Collectors.toList());
             //如果不需要支付,则过滤掉入场管理费
-//            boolean needPayManagerMoney = needPayManagerMoney(carNo, items);
-//            if (needPayManagerMoney) {
-//                //查询出对应的费项
-//                TbItem tbItem = tbItemService.findByName(SystemObject.config.getManagerWord());
-//                if (tbItem != null) {
-//                    List<IOrderItem> managerList = new ArrayList<>();
-//                    IOrderItem iOrderItem = new IOrderItem();
-//                    iOrderItem.setExpenseNum(1).setUniqExpenseId(tbItem.getItemCode());
-//                    managerList.add(iOrderItem);
-//                    IOrderPriceRes managerPriceRes = syncService.orderPriceCal(managerList);
-//                    Map<String, Object> managerMap = new HashMap<>();
-//                    managerMap.put("id", tbItem.getId());
-//                    managerMap.put("name", tbItem.getItemName());
-//                    managerMap.put("carNo", carNo);
-//                    managerMap.put("carId", businessCarId);
-//                    managerMap.put("label", tbItem.getItemName() + "(入场管理费)");
-//                    managerMap.put("price", managerPriceRes.getTotalOrderPrice());
-//                    managerMap.put("calculateId", managerPriceRes.getCalculateId());
-//                    result.put("manager", managerMap);
-//                }
+//            ManagerBO dto = needPayManagerMoney(carNo, businessCarId, items);
+//            if (dto.isNeed()) {
+//                result.put("manager", dto);
 //            }
             items.forEach(item -> {
                 String num = item.getNum();
@@ -573,7 +532,7 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
                 iOrderItem.setExpenseNum(Integer.parseInt(num)).setUniqExpenseId(itemCode);
                 expenses.add(iOrderItem);
             });
-            if (!expenses.isEmpty()){
+            if (!expenses.isEmpty()) {
                 IOrderPriceRes orderPriceRes = syncService.orderPriceCal(expenses);
                 BigDecimal totalPrice = orderPriceRes.getTotalOrderPrice();
                 carCalculateIds.add(orderPriceRes.getCalculateId());
@@ -621,12 +580,13 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
      * @param carNo
      * @return
      */
-    public boolean needPayManagerMoney(String carNo, List<TbBusinessItem> items) {
+    public ManagerBO needPayManagerMoney(String carNo, String carId, List<TbBusinessItem> items) {
+        ManagerBO dto = new ManagerBO();
         List<String> needItemTypeList = SystemObject.config.getManagerItemType();
         //是否有相关业务,,,没有的话直接不用交入场管理费
         boolean before = items.stream().anyMatch(item -> needItemTypeList.contains(item.getItemTypeName()));
         if (!before) {
-            return false;
+            return dto;
         }
         String carPrefix = StrUtil.sub(carNo, 0, 1);
         boolean isvietnamCar = !CAR_LIST.contains(carPrefix);
@@ -636,8 +596,25 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
         //中国车是否需要支付
         boolean chinaNeePay = managerList.contains(ManagerEnum.CHINA_PAY.getType());
         //是否需要支付入场管理费
-        return isvietnamCar && verNeePay || !isvietnamCar && chinaNeePay;
-
+        boolean need = isvietnamCar && verNeePay || !isvietnamCar && chinaNeePay;
+        dto.setNeed(need);
+        if (need) {
+            //查询出对应的费项
+            TbItem tbItem = tbItemService.findByName(SystemObject.config.getManagerWord());
+            if (tbItem != null) {
+                List<IOrderItem> itemList = new ArrayList<>();
+                IOrderItem iOrderItem = new IOrderItem();
+                iOrderItem.setExpenseNum(1).setUniqExpenseId(tbItem.getItemCode());
+                itemList.add(iOrderItem);
+                IOrderPriceRes managerPriceRes = syncService.orderPriceCal(itemList);
+                dto.setCalculateId(managerPriceRes.getCalculateId())
+                        .setPrice(managerPriceRes.getTotalOrderPrice())
+                        .setCarNo(carNo).setId(tbItem.getId())
+                        .setLabel(tbItem.getItemName() + "(入场管理费)")
+                        .setName(tbItem.getItemName()).setCarId(carId);
+            }
+        }
+        return dto;
     }
 
     public List<TbBusiness> findOtherBusinessByCarId(String businessCarId) {
@@ -709,115 +686,6 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
         return tbBusinessMapper.checkCarBusinessTypeByTime(typeId, carNo, timeStart, timeEnd, businessId);
     }
 
-    /**
-     * 线下收费
-     *
-     * @param id
-     * @param cars
-     * @param remark
-     * @param payTime
-     * @param payChannelType
-     * @param payType
-     * @param transactionId
-     */
-    public void manualConfirmPay(String id, List<TbBusinessCar> cars, String remark, Date payTime, int payChannelType, int payType, String transactionId) {
-        TbBusiness db = this.getById(id);
-        if (db == null) {
-            throw new BusinessException("业务不存在");
-        }
-        List<TbBusinessItem> items = tbBusinessItemService.findByBusinessId(id);
-        TbDeductionBind bind = null;
-        BigDecimal partMoney = new BigDecimal(0);
-        String plate = null;
-        List<PriceBO> priceBOList = new ArrayList<>();
-        TbGoods tbGoods = tbGoodsService.getById(db.getGoodsId());
-        //该确认确未确认
-        if (tbGoods.getPayStep().equals(GoodsEnum.PayStep.AFTER_CONFIRM.getCode()) && db.getAdminConfirmInput() == 0) {
-            throw new AjaxError("该业务需要确认后才能收费");
-        }
-        for (TbBusinessCar tbBusinessCar : cars) {
-            String carNo = tbBusinessCar.getCarNo().toUpperCase();
-            String prefix = StrUtil.sub(carNo, 0, 1);
-            if (CAR_LIST.contains(prefix) && tbGoods.getChinaCarPay() == 1
-                    || !CAR_LIST.contains(prefix) && tbGoods.getVietnamCarPay() == 1) {
-                Date realInTime = tbBusinessCar.getRealInTime();
-                Date realOutTime = tbBusinessCar.getRealOutTime();
-                if (realInTime != null && realOutTime != null) {
-                    IOrderPriceRes orderPriceRes = getPartMoney(realInTime, realOutTime, tbBusinessCar.getCarNo(),tbBusinessCar.getColor());
-                    BigDecimal price=orderPriceRes.getTotalOrderPrice();
-                    if (price.doubleValue() > 0) {
-                        PriceBO priceBO = new PriceBO();
-                        priceBO.setId(tbBusinessCar.getId()).setP(price);
-                        priceBOList.add(priceBO);
-                    }
-                    partMoney = partMoney.add(price);
-                    tbBusinessCar.setMoney(price);
-                }
-            }
-            tbBusinessCar.setPay(1).setPayTime(payTime)
-                    .setPayType(CarEnum.PayTypeEnum.HAS_PAY_TYPE.getType());
-            if (payType == PayEnum.PayType.PER_PAY.getCode()) {
-                TbDeductionBind deductionBind = tbDeductionBindService.getBindCarByPlate(carNo);
-                if (deductionBind != null) {
-                    plate = carNo;
-                    bind = deductionBind;
-                }
-            }
-        }
-        BigDecimal itemPrice = db.getItemPrice();
-        BigDecimal money = itemPrice.add(partMoney);
-        String no = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")) + RandomUtil.randomNumbers(4);
-        if (payType == PayEnum.PayType.PER_PAY.getCode()) {
-            if (bind == null) {
-                throw new AjaxError("车辆未绑定预支付款,无法完成收费");
-            }
-            TbAccount tbAccount = tbAccountService.getByCustomerId(bind.getCustomerId());
-            String key = AesUtil.reverse(tbAccount.getAccSalt());
-            BigDecimal balance = new BigDecimal(tbAccount.getTotalMoney());
-            if (balance.compareTo(money) < 0) {
-                throw new AjaxError("车辆绑定账户余额不足,无法完成收费");
-            }
-            balance = balance.subtract(money);
-            tbAccount.setTotalMoney(AesUtil.encryptECB(balance.toString(), key));
-            tbAccountService.updateById(tbAccount);
-            //生成扣款记录
-            if (partMoney.doubleValue() > 0 && !priceBOList.isEmpty()) {
-                //车辆的扣费记录
-                List<TbFeeDetails> parkFeeDetailsList = tbFeeDetailsService.chargeParkFee(
-                        priceBOList, null, null, payTime, PayEnum.PayType.PER_PAY);
-                automaticPay.createTbDeductionRecord(parkFeeDetailsList, tbAccount, plate, bind.getCustomerName(), no);
-            }
-            //生成收费明细
-            List<TbFeeDetails> tbFeeDetailsList = tbFeeDetailsService.chargeBusinessFee(
-                    items, null, null, payTime, PayEnum.PayType.PER_PAY);
-            //生成扣费记录
-            automaticPay.createTbDeductionRecord(tbFeeDetailsList, tbAccount, plate, bind.getCustomerName(), no);
-            automaticPay.unbindRun(plate);
-        } else if (payType == PayEnum.PayType.OFF_LINE_PAY.getCode()) {
-            //车辆的扣费记录
-            if (partMoney.doubleValue() > 0) {
-                tbFeeDetailsService.chargeParkFee(
-                        priceBOList, null, null, payTime, PayEnum.PayType.OFF_LINE_PAY);
-            }
-            //生成收费明细
-            tbFeeDetailsService.chargeBusinessFee(
-                    items, null, null, payTime, PayEnum.PayType.OFF_LINE_PAY);
-        }
-        db.setPayStatus(PayEnum.PayStatusEnum.HAS_PAY_CONFIRM.getCode())
-                .setPayMoney(db.getItemPrice())
-                .setPayType(payType).setPayChannelType(payChannelType)
-                .setTransactionId(transactionId)
-                .setPayTime(payTime);
-        items.forEach(tbBusinessItem -> tbBusinessItem
-                .setPayStatus(1).setPayTime(payTime)
-                .setRemark(StrUtil.isEmpty(remark) ? "手动确认" : remark)
-        );
-        this.updateById(db);
-        tbBusinessCarService.updateBatchById(cars);
-        tbBusinessItemService.updateBatchById(items);
-        tbFeeStatisticsService.addOrUpdateStatistic(payTime);//更新当前日期的日统计
-
-    }
 
     public void unBindCar(String id, String businessCarId) {
         QueryWrapper<TbBusiness> ew = new QueryWrapper<>();
@@ -853,9 +721,17 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
         BigDecimal price = new BigDecimal("0");
         List<TbBusinessItem> itemList = new ArrayList<>();
         String no = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")) + RandomUtil.randomNumbers(4);
+        String pickCustomerId = otherBusinessBO.getPickCustomerId();
+        TbCostomer partner = null;
+        if (StrUtil.isNotEmpty(pickCustomerId)) {
+            partner = tbCostomerService.getById(pickCustomerId);
+            tbBusiness.setPickCustomerId(pickCustomerId).setPickCustomerName(partner.getName());
+        }
         int index = 1;
+        int size = cars.size();
         for (TbItem tbItem : tbItems) {
             TbItem db = tbItemService.getById(tbItem.getId());
+            String itemName = db.getItemName();
             TbBusinessItem item = new TbBusinessItem();
             int num = tbItem.getNum();
             String typeId = tbItem.getTypeId();
@@ -863,10 +739,17 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
             BigDecimal itemTotalPrice = tbItem.getPrice().multiply(new BigDecimal(num));
             item.setNo(no + "0" + index).setPayTypeName(db.getPayTypeName()).setPayType(db.getPayType())
                     .setBusinessType(db.getBusinessType()).setTaxRate(NumberUtil.div(db.getTaxRate().doubleValue(), 100D, 2));
-            item.setItemCode(db.getItemCode()).setNum(num + "").setItemId(db.getId())
+            item.setItemCode(db.getItemCode()).setNum(num + "").setItemId(db.getId()).setCabinetNo(tbItem.getCabinetNo())
                     .setItemName(db.getItemName()).setItemPrice(db.getPrice()).setRemark(tbItem.getRemark())
                     .setItemTypeId(typeId).setItemTypeName(tbItemType.getName())
                     .setUnit(db.getUnit()).setTotal(itemTotalPrice).setCreateTime(now);
+            if (partner != null) {
+                item.setPick(1).setPickCustomerId(pickCustomerId).setPickCustomerName(partner.getName())
+                        .setPickBy(StpUserUtil.getCreateBy()).setPickTime(now);
+            }
+            if (SystemObject.config.getEveryCarPay().contains(itemName)) {
+                itemTotalPrice = itemTotalPrice.multiply(BigDecimal.valueOf(size));
+            }
             price = price.add(itemTotalPrice);
             itemList.add(item);
             index++;
@@ -880,9 +763,8 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
         tbBusiness.setCreateTime(now).setCreateByCustomerId(StpUserUtil.getCustomerId())
                 .setItemPrice(price).setTotalMoney(price).setOwner(otherBusinessBO.getOwner());
         tbBusiness.setChinaCarNo(otherBusinessBO.getChinaCarNo());
+
         this.save(tbBusiness);
-        Integer chinaCarPay = tbGoods.getChinaCarPay();
-        Integer vietnamCarPay = tbGoods.getVietnamCarPay();
         String carBuseinssNo = DateUtil.format(now, "yyyyMMddHHmm");
         for (TbBusinessCar car : cars) {
             String carNo = car.getCarNo().trim().toUpperCase();
@@ -920,10 +802,6 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
                 }
             }
             db.setPayType(CarEnum.PayTypeEnum.NO_PAY_TYPE.getType());
-            if ((CarEnum.CarTypeEnum.EMPTY_TYPE.getType().equals(carType) && chinaCarPay == 0)
-                    || (CarEnum.CarTypeEnum.WEIGHT_TYPE.getType().equals(carType) && vietnamCarPay == 0)) {
-                db.setPayType(CarEnum.PayTypeEnum.FEE_TYPE.getType());
-            }
             TbCar tbCar = tbCarService.findByCardNo(carNo);
             if (tbCar != null) {
                 db.setCarCompany(tbCar.getCustomerName());
@@ -984,8 +862,6 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
             relationBusinessCarService.removeByIds(removeIds);
         }
         TbGoods tbGoods = tbGoodsService.getById(otherBusinessBO.getGoodsId());
-        Integer chinaCarPay = tbGoods.getChinaCarPay();
-        Integer vietnamCarPay = tbGoods.getVietnamCarPay();
         String carBuseinssNo = DateUtil.format(now, "yyyyMMddHHmm");
         List<TbBusinessItem> itemList = new ArrayList<>();
         if (PayEnum.PayStatusEnum.HAS_PAY_CONFIRM.getCode() != dbBusiness.getPayStatus()) {
@@ -993,18 +869,35 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
             BigDecimal price = new BigDecimal("0");
             String no = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")) + RandomUtil.randomNumbers(4);
             int index = 1;
+            String pickCustomerId = otherBusinessBO.getPickCustomerId();
+            TbCostomer partner = null;
+            if (StrUtil.isNotEmpty(pickCustomerId)) {
+                partner = tbCostomerService.getById(pickCustomerId);
+                dbBusiness.setPickCustomerId(pickCustomerId).setPickCustomerName(partner.getName());
+            }
+            int size = cars.size();
             for (TbItem tbItem : tbItems) {
                 TbItem db = tbItemService.getById(tbItem.getId());
+                String itemName = db.getItemName();
                 TbBusinessItem item = new TbBusinessItem();
                 int num = tbItem.getNum();
                 TbItemType tbItemType = tbItemTypeService.getById(tbItem.getTypeId());
                 BigDecimal itemTotalPrice = tbItem.getPrice().multiply(new BigDecimal(num));
+
                 item.setNo(no + "0" + index).setPayTypeName(db.getPayTypeName()).setPayType(db.getPayType())
                         .setBusinessType(db.getBusinessType()).setTaxRate(NumberUtil.div(db.getTaxRate().doubleValue(), 100D, 2));
                 item.setItemCode(db.getItemCode()).setNum(num + "").setItemId(db.getId()).setBusinessId(dbBusiness.getId())
                         .setItemName(db.getItemName()).setItemPrice(db.getPrice()).setRemark(tbItem.getRemark())
                         .setItemTypeId(tbItem.getTypeId()).setItemTypeName(tbItemType.getName())
+                        .setCabinetNo(tbItem.getCabinetNo())
                         .setUnit(db.getUnit()).setTotal(itemTotalPrice).setCreateTime(now);
+                if (partner != null) {
+                    item.setPick(1).setPickCustomerId(pickCustomerId).setPickCustomerName(partner.getName())
+                            .setPickBy(StpUserUtil.getCreateBy()).setPickTime(now);
+                }
+                if (SystemObject.config.getEveryCarPay().contains(itemName)) {
+                    itemTotalPrice = itemTotalPrice.multiply(BigDecimal.valueOf(size));
+                }
                 price = price.add(itemTotalPrice);
                 itemList.add(item);
                 index++;
@@ -1018,7 +911,6 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
             for (TbBusinessItem item : itemList) {
                 checkOtherBusiness(item.getItemTypeId(), otherBusinessBO.getOperateTime(), dbBusiness.getId(), carNo);
             }
-            String carType = tbBusinessCar.getCarType();
             if (StrUtil.isNotEmpty(businessCarId)) {
                 //原来已存在的
                 TbBusinessCar dbBusinessCar = tbBusinessCarService.getById(businessCarId);
@@ -1031,16 +923,15 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
                     //把关联删除掉,然后添加新的关联
                     relationBusinessCarService.removeByBusinessIdAndCarId(dbBusiness.getId(), businessCarId);
                     TbBusinessCar otherCar = tbBusinessCarService.findTheLastRecord(carNo);
+
                     if (otherCar == null ||//不存在或者已离场===>新建
                             (otherCar.getRealInTime() != null && otherCar.getRealOutTime() != null)) {
                         otherCar = new TbBusinessCar();
                         otherCar.setCreateTime(now).setPay(0).setNo(carBuseinssNo + RandomUtil.randomNumbers(4))
                                 .setCarNo(carNo).setCarType(tbBusinessCar.getCarType()).setCarSize(tbBusinessCar.getCarSize())
                                 .setNetWeight(tbBusinessCar.getNetWeight()).setCustomerId(dbBusiness.getCustomerId())
-                                .setTimeUpdate(now).setIsLock(0).setCarType(tbBusinessCar.getCarType());
-                        if ((CarEnum.CarTypeEnum.EMPTY_TYPE.getType().equals(carType) && chinaCarPay == 0) || (CarEnum.CarTypeEnum.WEIGHT_TYPE.getType().equals(carType) && vietnamCarPay == 0)) {
-                            otherCar.setPayType(CarEnum.PayTypeEnum.FEE_TYPE.getType());
-                        }
+                                .setTimeUpdate(now).setIsLock(0).setCarType(tbBusinessCar.getCarType())
+                                .setConfirmJudge(CarEnum.ConfirmJudgeEnum.NO_JUDGE.getCode());
                         tbBusinessCarService.save(otherCar);
                     } else {
                         List<TbBusiness> tbBusinessList = this.findOtherBusinessByCarId(businessCarId);
@@ -1053,7 +944,8 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
                     relationBusinessCarService.save(relationBusinessCar);
                 } else {
                     dbBusinessCar.setNetWeight(tbBusinessCar.getNetWeight()).setNetWeight(tbBusinessCar.getNetWeight())
-                            .setCarSize(tbBusinessCar.getCarSize()).setCarType(tbBusinessCar.getCarType());
+                            .setCarSize(tbBusinessCar.getCarSize()).setCarType(tbBusinessCar.getCarType())
+                            .setConfirmJudge(CarEnum.ConfirmJudgeEnum.NO_JUDGE.getCode());
                     tbBusinessCarService.updateById(dbBusinessCar);
                 }
             } else {
@@ -1074,10 +966,8 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
                 }
                 checkCar.setCarNo(carNo).setCarType(tbBusinessCar.getCarType()).setCarSize(tbBusinessCar.getCarSize())
                         .setNetWeight(tbBusinessCar.getNetWeight()).setCustomerId(dbBusiness.getCustomerId())
-                        .setTimeUpdate(now).setIsLock(0).setCarType(tbBusinessCar.getCarType());
-                if ((CarEnum.CarTypeEnum.EMPTY_TYPE.getType().equals(carType) && chinaCarPay == 0) || (CarEnum.CarTypeEnum.WEIGHT_TYPE.getType().equals(carType) && vietnamCarPay == 0)) {
-                    checkCar.setPayType(CarEnum.PayTypeEnum.FEE_TYPE.getType());
-                }
+                        .setTimeUpdate(now).setIsLock(0).setCarType(tbBusinessCar.getCarType()).setBusinessType(1)
+                        .setConfirmJudge(CarEnum.ConfirmJudgeEnum.NO_JUDGE.getCode());
                 tbBusinessCarService.saveOrUpdate(checkCar);
                 RelationBusinessCar relationBusinessCar = new RelationBusinessCar();
                 relationBusinessCar.setBusinessId(dbBusiness.getId()).setBusinessCarId(checkCar.getId());
@@ -1088,18 +978,23 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
             dbBusiness.setGoodsId(otherBusinessBO.getGoodsId())
                     .setGoodsName(tbGoods.getName()).setPayStep(tbGoods.getPayStep());
         }
-        String declareNo = otherBusinessBO.getDeclareNo();
-        if (!StrUtil.equals(declareNo, dbBusiness.getDeclareNo())) {
-            tbDeclareService.rebackDeclareNo(dbBusiness.getDeclareNo());
-            TbDeclare tbDeclare = tbDeclareService.findByDeclareNo(declareNo);
-            tbDeclare.setBusinessId(dbBusiness.getId());
-            tbDeclareService.updateById(tbDeclare);
+        String customerId=otherBusinessBO.getCustomerId();
+        if (StrUtil.isNotEmpty(customerId)){
+            TbCostomer tbCostomer=tbCostomerService.getById(customerId);
+            dbBusiness.setCustomerId(customerId).setCustomerName(tbCostomer.getName());
+        }
+        String pickCustomerId=otherBusinessBO.getPickCustomerId();
+        if (StrUtil.isNotEmpty(pickCustomerId)){
+            TbCostomer tbCostomer=tbCostomerService.getById(pickCustomerId);
+            dbBusiness.setPickCustomerId(pickCustomerId).setPickCustomerName(tbCostomer.getName());
         }
+
         dbBusiness.setCardSize(otherBusinessBO.getCarSize()).setNetWeight(otherBusinessBO.getNetWeight())
                 .setOperator(otherBusinessBO.getOperator()).setOperateTime(otherBusinessBO.getOperateTime())
-                .setGoodsId(otherBusinessBO.getGoodsId()).setOwner(otherBusinessBO.getOwner()).setBusinessGoodsName(otherBusinessBO.getBusinessGoodsName())
+                .setGoodsId(otherBusinessBO.getGoodsId())
+                .setOwner(otherBusinessBO.getOwner()).setBusinessGoodsName(otherBusinessBO.getBusinessGoodsName())
                 .setBusinessGoodsNum(otherBusinessBO.getBusinessGoodsNum())
-                .setDeclareNo(declareNo).setCardNo(otherBusinessBO.getCardNo());
+                .setCardNo(otherBusinessBO.getCardNo());
         String chinaCar = cars.stream().filter(tbBusinessCar -> CAR_LIST.contains(StrUtil.sub(tbBusinessCar.getCarNo(), 0, 1)))
                 .map(TbBusinessCar::getCarNo).collect(Collectors.joining("、")).toUpperCase();
         dbBusiness.setChinaCarNo(chinaCar);
@@ -1253,7 +1148,7 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
             outTime = payTime;
         }
         //计算停车费
-        IOrderPriceRes parkMoney = this.getPartMoney(inTime, outTime, tbBusinessCar.getCarNo(),tbBusinessCar.getColor());
+        IOrderPriceRes parkMoney = this.getPartMoney(inTime, outTime, tbBusinessCar.getCarNo(), tbBusinessCar.getColor());
         tbBusinessCar.setMoney(parkMoney.getTotalOrderPrice());
     }
 
@@ -1489,8 +1384,6 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
                     .setPayTime(businessPayTime);
         }
         this.save(tbBusiness);
-        Integer chinaCarPay = tbGoods.getChinaCarPay();
-        Integer vietnamCarPay = tbGoods.getVietnamCarPay();
         String carBuseinssNo = DateUtil.format(now, "yyyyMMddHHmm");
         //业务车
         for (TbBusinessCar car : cars) {
@@ -1501,10 +1394,6 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
             }
 
             car.setCreateTime(now).setNo(carBuseinssNo + RandomUtil.randomNumbers(4));
-            if ((CarEnum.CarTypeEnum.EMPTY_TYPE.getType().equals(carType) && chinaCarPay == 0)
-                    || (CarEnum.CarTypeEnum.WEIGHT_TYPE.getType().equals(carType) && vietnamCarPay == 0)) {
-                car.setPayType(CarEnum.PayTypeEnum.FEE_TYPE.getType());
-            }
             TbCar tbCar = tbCarService.findByCardNo(carNo);
             if (tbCar != null) {
                 car.setCarCompany(tbCar.getCustomerName());
@@ -1641,4 +1530,60 @@ public class TbBusinessService extends ServiceImpl<TbBusinessMapper, TbBusiness>
     }
 
 
+    /**
+     * 额外添加车牌
+     *
+     * @param tbBusinessCar
+     */
+    public void addBusinessCar(TbBusinessCar tbBusinessCar) {
+        String businessId = tbBusinessCar.getBusinessId();
+        TbBusiness tbBusiness = this.getById(businessId);
+        String carNo = tbBusinessCar.getCarNo().trim().toUpperCase();
+        TbBusinessCar lastRecord = tbBusinessCarService.findTheLastRecord(carNo);
+        String businessCarId;
+        Date now = new Date();
+        if (lastRecord == null || lastRecord.getRealOutTime() != null) {
+            //不存在或者已经离场
+            tbBusinessCar
+                    .setBusinessType(CarEnum.BusinessTypeEnum.BUSINESS_CAR.getType())
+                    .setCarNo(carNo).setPay(0).setIsLock(0).setPayUnloadMoney(0)
+                    .setPayType(CarEnum.PayTypeEnum.NO_PAY_TYPE.getType()).setPay(0)
+                    .setCreateTime(now).setCarType(CarEnum.CarTypeEnum.EMPTY_TYPE.getType())
+                    .setTimeUpdate(now)
+                    .setConfirmJudge(CarEnum.ConfirmJudgeEnum.NO_NEED_JUDGE.getCode())
+                    .setNo(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")) + RandomUtil.randomNumbers(4));
+            tbBusinessCarService.save(tbBusinessCar);
+            businessCarId = tbBusinessCar.getId();
+        } else {
+            businessCarId = lastRecord.getId();
+            lastRecord.setPayType(CarEnum.PayTypeEnum.NO_PAY_TYPE.getType()).setCustomerId(tbBusiness.getCustomerId())
+                    .setCarNo(carNo).setConfirmJudge(CarEnum.ConfirmJudgeEnum.NO_JUDGE.getCode()).setPayUnloadMoney(0)
+                    .setTimeUpdate(now)
+                    .setBusinessType(CarEnum.BusinessTypeEnum.BUSINESS_CAR.getType());
+            tbBusinessCarService.updateById(lastRecord);
+        }
+        tbBusiness.setCardNo(tbBusiness.getCardNo() + "、" + carNo);
+        this.updateById(tbBusiness);
+        RelationBusinessCar relationBusinessCar = new RelationBusinessCar();
+        relationBusinessCar.setBusinessId(businessId).setBusinessCarId(businessCarId);
+        relationBusinessCarService.save(relationBusinessCar);
+    }
+
+    /**
+     * 删除业务车
+     *
+     * @param carId
+     * @param businessId
+     */
+    public void deleteBusinessCar(String carId, String businessId) {
+
+        relationBusinessCarService.removeByBusinessIdAndCarId(businessId, carId);
+        List<RelationBusinessCar> list = relationBusinessCarService.findByBusinessCarId(carId);
+        if (list.isEmpty()) {
+            TbBusinessCar db = tbBusinessCarService.getById(carId);
+            if (db.getRealInTime() == null) {
+                tbBusinessCarService.removeById(carId);
+            }
+        }
+    }
 }

+ 8 - 1
sp-server/src/main/java/com/pj/project/tb_business_car/TbBusinessCar.java

@@ -157,7 +157,14 @@ public class TbBusinessCar extends Model<TbBusinessCar> implements Serializable
      * 交易单号
      */
     private String outTradeNo;
+    /**
+     * 订单状态---异常 0&正常 1
+     */
+    private int orderStatus=1;
 
-
+    /**
+     * 是否支付了装卸业务管理费
+     */
+    private int payUnloadMoney=0;
 
 }

+ 4 - 3
sp-server/src/main/java/com/pj/project/tb_business_car/TbBusinessCarController.java

@@ -53,10 +53,11 @@ public class TbBusinessCarController {
      */
     @RequestMapping("delete")
     @SaCheckPermission(TbBusiness.PERMISSION_CODE)
-    public AjaxJson delete(String id) {
+    public AjaxJson delete(String id,String businessId) {
         return tbBusinessCarService.deleteCar(id);
     }
 
+
     /**
      * 查 - 根据id
      */
@@ -220,8 +221,8 @@ public class TbBusinessCarController {
     public AjaxJson confirmJudge() {
         SoMap soMap = SoMap.getRequestSoMap();
         String id = soMap.getString("id");
-        tbBusinessCarService.confirmJudgePass(id);
-        return AjaxJson.getSuccess();
+       String msg= tbBusinessCarService.confirmJudgePass(id);
+        return AjaxJson.getSuccess(msg);
     }
 
     /**

+ 123 - 14
sp-server/src/main/java/com/pj/project/tb_business_car/TbBusinessCarService.java

@@ -9,21 +9,31 @@ import com.alibaba.excel.EasyExcel;
 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.business.FeeTypeEnum;
 import com.pj.constants.business.CarEnum;
+import com.pj.constants.business.FeeTypeEnum;
+import com.pj.constants.business.PayEnum;
 import com.pj.current.config.PartConfig;
 import com.pj.current.config.SystemObject;
 import com.pj.current.satoken.StpUserUtil;
 import com.pj.project.relation_business_car.RelationBusinessCar;
 import com.pj.project.relation_business_car.RelationBusinessCarService;
+import com.pj.project.sync.SyncService;
+import com.pj.project.sync.request.item.IOrderItem;
+import com.pj.project.sync.response.IOrderPriceRes;
+import com.pj.project.tb_account.AutomaticPay;
+import com.pj.project.tb_account.TbAccount;
+import com.pj.project.tb_account.TbAccountService;
 import com.pj.project.tb_business.TbBusiness;
 import com.pj.project.tb_business.TbBusinessService;
 import com.pj.project.tb_business_car.statics.CarStatics;
+import com.pj.project.tb_business_item.TbBusinessItem;
+import com.pj.project.tb_business_item.TbBusinessItemService;
 import com.pj.project.tb_car.TbCar;
 import com.pj.project.tb_car.TbCarService;
 import com.pj.project.tb_deduction_bind.TbDeductionBindService;
 import com.pj.project.tb_fee_details.TbFeeDetails;
 import com.pj.project.tb_fee_details.TbFeeDetailsService;
+import com.pj.project.tb_fee_statistics.TbFeeStatisticsService;
 import com.pj.project.tb_mild_car.TbMildCar;
 import com.pj.project.tb_mild_car.TbMildCarService;
 import com.pj.project4sp.global.BusinessException;
@@ -31,6 +41,7 @@ import com.pj.project4sp.uploadfile.UploadConfig;
 import com.pj.utils.sg.AjaxError;
 import com.pj.utils.sg.AjaxJson;
 import com.pj.utils.so.SoMap;
+import org.aspectj.weaver.loadtime.Aj;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
@@ -42,6 +53,7 @@ import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.stream.Collectors;
 
 /**
@@ -63,6 +75,9 @@ public class TbBusinessCarService extends ServiceImpl<TbBusinessCarMapper, TbBus
     @Lazy
     private TbBusinessService tbBusinessService;
     @Resource
+    @Lazy
+    private TbBusinessItemService tbBusinessItemService;
+    @Resource
     TbCarService tbCarService;
     @Resource
     @Lazy
@@ -83,6 +98,20 @@ public class TbBusinessCarService extends ServiceImpl<TbBusinessCarMapper, TbBus
     @Resource
     private PartConfig partConfig;
 
+    @Resource
+    @Lazy
+    private TbAccountService tbAccountService;
+
+    @Resource
+    @Lazy
+    private TbFeeStatisticsService tbFeeStatisticsService;
+
+    @Resource
+    @Lazy
+    private AutomaticPay automaticPay;
+    @Resource
+    private SyncService syncService;
+
 
     /**
      * 查集合 - 根据条件(参数为空时代表忽略指定条件)
@@ -207,8 +236,8 @@ public class TbBusinessCarService extends ServiceImpl<TbBusinessCarMapper, TbBus
             t.setId(db.getId()).setBusinessType(db.getBusinessType());
         }
         t.setCarNo(carNo).setPay(0).setIsLock(0)
-                .setBasePartMoney(new BigDecimal("0"))
-                .setTimeUpdate(new Date())
+                .setBasePartMoney(new BigDecimal("0")).setPayType(CarEnum.PayTypeEnum.NO_PAY_TYPE.getType())
+                .setTimeUpdate(new Date()).setConfirmJudge(CarEnum.ConfirmJudgeEnum.NO_NEED_JUDGE.getCode())
                 .setNo(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmm")) + RandomUtil.randomNumbers(4));
         if (t.getColor().contains(partConfig.getFreeColor())) {
             TbMildCar tbMildCar = tbMildCarService.findByCarNo(carNo);
@@ -256,7 +285,7 @@ public class TbBusinessCarService extends ServiceImpl<TbBusinessCarMapper, TbBus
         }
         if (t.getRealInTime() != null && t.getRealOutTime() != null
                 && StrUtil.equals(db.getPayType(), CarEnum.PayTypeEnum.NO_PAY_TYPE.getType())) {
-            BigDecimal money = tbBusinessService.getPartMoney(t.getRealInTime(), t.getRealOutTime(), t.getCarNo(),t.getColor()).getTotalOrderPrice();
+            BigDecimal money = tbBusinessService.getPartMoney(t.getRealInTime(), t.getRealOutTime(), t.getCarNo(), t.getColor()).getTotalOrderPrice();
             t.setMoney(money);
             db.setMoney(money);
         }
@@ -469,7 +498,7 @@ public class TbBusinessCarService extends ServiceImpl<TbBusinessCarMapper, TbBus
         List<TbBusiness> businessList = tbBusinessService.findOtherBusinessByCarId(id);
         businessList.forEach(tbBusiness -> {
             List<TbBusinessCar> tbBusinessCars = this.findOtherBusinessCar(tbBusiness.getId());
-            tbBusinessCars.stream().filter(tbBusinessCar -> !StrUtil.equals(tbBusinessCar.getId(),id)).forEach(tbBusinessCar -> {
+            tbBusinessCars.stream().filter(tbBusinessCar -> !StrUtil.equals(tbBusinessCar.getId(), id)).forEach(tbBusinessCar -> {
                 tbBusinessCar.setConfirmJudge(CarEnum.ConfirmJudgeEnum.CALL_BACK.getCode())
                         .setConfirmJudgeContent(judgeContent).setConfirmJudgeTime(new Date())
                         .setConfirmJudgeBy(StpUserUtil.getCreateBy());
@@ -483,17 +512,97 @@ public class TbBusinessCarService extends ServiceImpl<TbBusinessCarMapper, TbBus
      *
      * @param id
      */
-    public void confirmJudgePass(String id) {
+    public String confirmJudgePass(String id) {
         List<TbBusiness> businessList = tbBusinessService.findOtherBusinessByCarId(id);
-        businessList.forEach(tbBusiness -> {
+        if (businessList.isEmpty()) {
+            throw new AjaxError("车辆对应业务已被删除");
+        }
+        AtomicReference<String> msg = new AtomicReference<>("");
+        for (TbBusiness tbBusiness : businessList) {
+            Date now = new Date();
             List<TbBusinessCar> tbBusinessCars = this.findOtherBusinessCar(tbBusiness.getId());
-            tbBusinessCars.forEach(tbBusinessCar -> {
-                tbBusinessCar.setConfirmJudge(CarEnum.ConfirmJudgeEnum.JUDGE_PASS.getCode())
-                        .setConfirmJudgeContent("审核通过").setConfirmJudgeTime(new Date())
-                        .setConfirmJudgeBy(StpUserUtil.getCreateBy());
-                this.updateById(tbBusinessCar);
-            });
-        });
+
+            //审核
+            List<TbBusinessItem> tbBusinessItems = tbBusinessItemService.findByBusinessId(tbBusiness.getId());
+            String customerId = tbBusiness.getPickCustomerId();
+            TbAccount tbAccount = tbAccountService.getAccountByCustomerId(customerId);
+            for (TbBusinessCar tbBusinessCar : tbBusinessCars) {
+                if (tbBusinessCar.getConfirmJudge()!=CarEnum.ConfirmJudgeEnum.JUDGE_PASS.getCode()){
+                    tbBusinessCar.setConfirmJudge(CarEnum.ConfirmJudgeEnum.JUDGE_PASS.getCode())
+                            .setConfirmJudgeContent("审核通过").setConfirmJudgeTime(now)
+                            .setConfirmJudgeBy(StpUserUtil.getCreateBy());
+                    for (TbBusinessItem item : tbBusinessItems) {
+                        String itemName = item.getItemName();
+                        // todo 扣除 人工、机械装卸车辆---->每辆车都要支付----->
+                        if (SystemObject.config.getEveryCarPay().contains(itemName) && tbBusinessCar.getPayUnloadMoney() == 0) {
+                            List<IOrderItem> expenses = new ArrayList<>();
+                            IOrderItem orderItem = new IOrderItem();
+                            orderItem.setExpenseNum(Integer.parseInt(item.getNum()))
+                                    .setUniqExpenseId(item.getItemCode());
+                            expenses.add(orderItem);
+                            IOrderPriceRes res = syncService.orderPriceCal(expenses);
+                            BigDecimal price = res.getTotalOrderPrice();
+                            BigDecimal balance = tbAccount.getTotalMoney();
+                            if (price.compareTo(balance) > 0) {
+                                throw new AjaxError("[" + tbAccount.getCustomerName() + "]账户余额不足扣除" + item.getItemName());
+                            } else {
+                                tbBusinessCar.setPayUnloadMoney(1);
+                                item.setPayTime(now).setPayStatus(1).setPayType(PayEnum.PayType.PER_PAY.getCode())
+                                        .setPayTypeName(PayEnum.PayType.PER_PAY.getDesc());
+                                tbBusinessItemService.updateById(item);
+                                tbBusiness.setPayMoney(price.add(tbBusiness.getPayMoney()));
+                                tbBusinessService.updateById(tbBusiness);
+                                BigDecimal afterBalance = balance.subtract(price);
+                                tbAccount.setTotalMoney(afterBalance);//增加累计扣款
+                                tbAccountService.updateById(tbAccount);
+                                TbFeeDetails details = tbFeeDetailsService.savePrePayDetails(res, item, tbBusinessCar, tbBusiness, FeeTypeEnum.STEVEDORE_FEE);
+                                tbFeeStatisticsService.addOrUpdateStatistic(now, PayEnum.PayType.PER_PAY.getCode());//更新当前日期的日统计
+                                automaticPay.createTbDeductionRecord(details, balance, afterBalance, tbBusiness.getPickCustomerId(),tbBusiness.getPickCustomerName(), tbBusinessCar.getCarNo(), tbBusinessCar.getId(), FeeTypeEnum.STEVEDORE_FEE);
+                            }
+                        }
+                    }
+                    this.updateById(tbBusinessCar);
+                }
+            }
+            //其他费项 装卸业务管理费” 进行预存款扣除
+            for (TbBusinessItem item : tbBusinessItems) {
+                //业务类型是装卸业务管理费且未支付的进行扣款
+                if (item.getPayStatus() == 0 && SystemObject.config.getUnLoadItem().contains(item.getItemTypeName())) {
+                    List<IOrderItem> expenses = new ArrayList<>();
+                    IOrderItem orderItem = new IOrderItem();
+                    orderItem.setExpenseNum(Integer.parseInt(item.getNum()))
+                            .setUniqExpenseId(item.getItemCode());
+                    expenses.add(orderItem);
+                    IOrderPriceRes res = syncService.orderPriceCal(expenses);
+                    BigDecimal price = res.getTotalOrderPrice();
+                    BigDecimal balance = tbAccount.getTotalMoney();
+                    if (price.compareTo(balance) > 0) {
+                        throw new AjaxError("[" + tbAccount.getCustomerName() + "]账户余额不足扣除" + item.getItemName());
+                    } else {
+                        BigDecimal afterBalance = balance.subtract(price);
+                        tbAccount.setTotalMoney(afterBalance);//增加累计扣款
+                        tbAccountService.updateById(tbAccount);
+                        item.setPayTime(now).setPayStatus(1).setPayType(PayEnum.PayType.PER_PAY.getCode())
+                                .setPayTypeName(PayEnum.PayType.PER_PAY.getDesc());
+                        tbBusinessItemService.updateById(item);
+                        tbBusiness.setPayMoney(price.add(tbBusiness.getPayMoney()));
+                        tbBusinessService.updateById(tbBusiness);
+                        //查找越南车--->统计以
+                        TbBusinessCar tbBusinessCar = tbBusinessCars.stream().filter(car -> !CAR_LIST.contains(car.getCarNo().substring(0, 1)))
+                                .findAny().orElse(tbBusinessCars.get(0));
+                        TbFeeDetails details = tbFeeDetailsService.savePrePayDetails(res, item, tbBusinessCar, tbBusiness, FeeTypeEnum.STEVEDORE_FEE);
+                        tbFeeStatisticsService.addOrUpdateStatistic(now, PayEnum.PayType.PER_PAY.getCode());//更新当前日期的日统计
+                        automaticPay.createTbDeductionRecord(details, balance, afterBalance, tbBusiness.getPickCustomerId(),tbBusiness.getPickCustomerName(), tbBusinessCar.getCarNo(), tbBusinessCar.getId(), FeeTypeEnum.STEVEDORE_FEE);
+                    }
+                }
+            }
+
+        }
+        return msg.get();
+    }
+
+    private void pay() {
+
     }
 
     /**

+ 14 - 1
sp-server/src/main/java/com/pj/project/tb_business_item/TbBusinessItem.java

@@ -59,6 +59,10 @@ public class TbBusinessItem extends Model<TbBusinessItem> implements Serializabl
 	 */
 	private String itemCode;
 	private String itemId;
+	/**
+	 * 柜号
+	 */
+	private String cabinetNo;
 
 	/**
 	 * 项目金额(元) 
@@ -95,7 +99,7 @@ public class TbBusinessItem extends Model<TbBusinessItem> implements Serializabl
 	private String unit;
 	private BigDecimal total;
 	private String ticket;
-	//支付状态
+	//支付状态 0=未支付 1 =已支付 3=已退款
 	private Integer payStatus=0;
 	private Date payTime;
 	private Date createTime;
@@ -128,6 +132,15 @@ public class TbBusinessItem extends Model<TbBusinessItem> implements Serializabl
 	 * 计价ID
 	 */
 	private String calculateId;
+	/**
+	 * 是否异常
+	 */
+	private int hasError=0;
+
+
+	private String refundBy;
+	private BigDecimal refundMoney=BigDecimal.ZERO;
+	private Date refundTime;
 
 	@TableField(exist = false)
 	private String goodsName;

+ 3 - 1
sp-server/src/main/java/com/pj/project/tb_business_item/TbBusinessItemService.java

@@ -297,7 +297,9 @@ public class TbBusinessItemService extends ServiceImpl<TbBusinessItemMapper, TbB
      * @return
      */
     public void buildExpenses(List<TbBusinessItem> businessItems, List<IOrderItem> orderItems) {
-        businessItems.forEach(item -> {
+        businessItems
+                .stream().filter(item -> item.getPayStatus()==0)
+                .forEach(item -> {
             IOrderItem orderItem = new IOrderItem();
             orderItem.setUniqExpenseId(item.getItemCode()).setExpenseNum(Integer.parseInt(item.getNum()));
             orderItems.add(orderItem);

+ 17 - 0
sp-server/src/main/java/com/pj/project/tb_charge_record/BalanceDTO.java

@@ -0,0 +1,17 @@
+package com.pj.project.tb_charge_record;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+public class BalanceDTO implements Serializable {
+    private String customerName;
+    //累计充值金额
+    private BigDecimal chargeMoney=BigDecimal.ZERO;
+    //累计账户退款金额
+    private BigDecimal refundMoney=BigDecimal.ZERO;
+    //剩余余额
+    private BigDecimal balance=BigDecimal.ZERO;
+}

+ 45 - 7
sp-server/src/main/java/com/pj/project/tb_charge_record/TbChargeRecord.java

@@ -70,17 +70,21 @@ public class TbChargeRecord extends Model<TbChargeRecord> implements Serializabl
     /**
      * 预充值金额
      */
-    private String preTopupMoney;
+    private BigDecimal preTopupMoney;
 
     /**
-     * 总计充值金额
+     * 实际收款金额
      */
-    private String totalTopupMoney;
+    private BigDecimal totalTopupMoney;
+    /**
+     * 原金额
+     */
+    private BigDecimal beforeMoney;
 
     /**
-     * 总金额
+     * 
      */
-    private String totalMoney;
+    private BigDecimal totalMoney;
     /**
      * 支付金额
      */
@@ -89,7 +93,11 @@ public class TbChargeRecord extends Model<TbChargeRecord> implements Serializabl
     /**
      * 充值前余额
      */
-    private String beforeBalance;
+    private BigDecimal beforeBalance;
+    /**
+     * 上一次充值之后到本次充值之间的累计扣款
+     */
+    private BigDecimal lastSumMoney;
 
     /**
      * 充值渠道
@@ -115,7 +123,19 @@ public class TbChargeRecord extends Model<TbChargeRecord> implements Serializabl
     /**
      * 优惠金额
      */
-    public String discountMoney;
+    public BigDecimal discountMoney;
+    /**
+     * 退款金额
+     */
+    public BigDecimal refundMoney;
+    /**
+     * 退款人
+     */
+    public String refundBy;
+    /**
+     * 退款时间
+     */
+    public Date refundTime;
 
     /**
      * 付款方式
@@ -154,6 +174,14 @@ public class TbChargeRecord extends Model<TbChargeRecord> implements Serializabl
     public String updateBy;
 
     public Date updateTime;
+    /**
+     * 类型 1=账户充值,2=账户退款,3=异常单退款
+     */
+    private int type=1;
+
+
+
+
 
     @Getter
     @AllArgsConstructor
@@ -164,6 +192,16 @@ public class TbChargeRecord extends Model<TbChargeRecord> implements Serializabl
         private String type;
     }
 
+    @Getter
+    @AllArgsConstructor
+    public static enum TypeEunm {
+        ACCOUNT_CHARGE(1,"账户充值"),
+        ACCOUNT_REFUND(2,"账户退款"),
+        ORDER_REFUND(3,"异常单退款");
+        private int type;
+        private String desc;
+    }
+
     /**
      * 付款方式
      */

+ 7 - 0
sp-server/src/main/java/com/pj/project/tb_charge_record/TbChargeRecordMapper.java

@@ -3,8 +3,10 @@ package com.pj.project.tb_charge_record;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.pj.utils.so.SoMap;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
 
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 
@@ -59,4 +61,9 @@ public interface TbChargeRecordMapper extends BaseMapper<TbChargeRecord> {
     List<TbChargeRecord> getList(SoMap so);
 
     Map getPrintReceiptInfo(Long id);
+
+
+    BalanceDTO getBalance(@Param("customerName") String customerName, @Param("eDay") String eDay);
+
+    BigDecimal getAccountDeductionMoney(@Param("customerName") String customerName, @Param("bDay") String bDay, @Param("eDay") String eDay);
 }

+ 32 - 0
sp-server/src/main/java/com/pj/project/tb_charge_record/TbChargeRecordMapper.xml

@@ -83,6 +83,7 @@
         <where>
             and status=1
             <if test=' this.has("id") '> and id = #{id} </if>
+            <if test=' this.has("type") and type !=0 '> and type = #{type} </if>
             <if test=' this.has("accountId") '> and account_id = #{accountId} </if>
             <if test=' this.has("customerId") '> and customer_id = #{customerId} </if>
             <if test=' this.has("customerName") '> and customer_name like "%" #{customerName} "%" </if>
@@ -132,4 +133,35 @@
         from tb_charge_record c left join tb_account a on a.id=c.account_id
         where c.id = #{id}
     </select>
+    <select id="getBalance" resultType="com.pj.project.tb_charge_record.BalanceDTO">
+        SELECT
+	SUM( pre_topup_money ) as chargeMoney,
+	SUM(refund_money) as refundMoney,
+	(SUM( pre_topup_money )-SUM(refund_money)) as balance
+        FROM
+	tb_charge_record WHERE type !=3
+        <if test="customerName !='' and customerName !=null">
+            and customer_name like concat('%',#{customerName},'%')
+        </if>
+
+        <if test="eDay !='' and eDay !=null">
+            and date_format(create_time,'%Y-%m-%d')&lt;= #{eDay}
+        </if>
+        GROUP BY customer_id;
+    </select>
+    <select id="getAccountDeductionMoney" resultType="java.math.BigDecimal">
+        SELECT
+        SUM(refund_money) as refundMoney
+        FROM
+        tb_charge_record WHERE type =2
+        <if test="customerName !='' and customerName !=null">
+            and customer_name like concat('%',#{customerName},'%')
+        </if>
+
+        <if test="eDay !='' and eDay !=null">
+            and date_format(create_time,'%Y-%m-%d')&lt;= #{eDay}
+        </if>
+        GROUP BY customer_id;
+    </select>
+
 </mapper>

+ 67 - 7
sp-server/src/main/java/com/pj/project/tb_charge_record/TbChargeRecordService.java

@@ -4,6 +4,7 @@ import cn.hutool.core.util.NumberUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONArray;
 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;
@@ -50,15 +51,13 @@ public class TbChargeRecordService extends ServiceImpl<TbChargeRecordMapper, TbC
      */
     int delete(Long id) {
         TbChargeRecord chargeRecord = tbChargeRecordMapper.selectById(id);
-        String key = AesUtil.reverse(chargeRecord.getSalt());
-        String preTopupMoney = chargeRecord.getPreTopupMoney();//充值金额
-        BigDecimal divMoney = new BigDecimal(AesUtil.decryptECB(preTopupMoney, key));
+        BigDecimal preTopupMoney = chargeRecord.getPreTopupMoney();//充值金额
         TbAccount tbAccount = tbAccountService.getById(chargeRecord.getAccountId());
         String accountKey = AesUtil.reverse(tbAccount.getAccSalt());
-        BigDecimal totalMoney = new BigDecimal(AesUtil.decryptECB(tbAccount.getTotalMoney(), accountKey));
-        BigDecimal balance = totalMoney.subtract(divMoney);
-        String balanceMoney = AesUtil.encryptECB(balance.toString(), accountKey);
-        tbAccount.setTotalMoney(balanceMoney);
+//        BigDecimal totalMoney = new BigDecimal(AesUtil.decryptECB(tbAccount.getTotalMoney(), accountKey));
+//        BigDecimal balance = totalMoney.subtract(divMoney);
+//        String balanceMoney = AesUtil.encryptECB(balance.toString(), accountKey);
+//        tbAccount.setTotalMoney(balanceMoney);
         tbAccountService.updateById(tbAccount);
         chargeRecord.setStatus(0);
         chargeRecord.setUpdateBy(StpUserUtil.getLoginName());
@@ -119,4 +118,65 @@ public class TbChargeRecordService extends ServiceImpl<TbChargeRecordMapper, TbC
         if (id == null) return null;
         return tbChargeRecordMapper.getPrintReceiptInfo(id);
     }
+
+    /**
+     * 查询某个时间段内的账户余额
+     *
+     * @param customerId
+     * @param bDay
+     * @param eDay
+     * @return
+     */
+    public BalanceDTO getBalance(String customerName, String eDay) {
+        return tbChargeRecordMapper.getBalance(customerName, eDay);
+    }
+
+    /**
+     * 查询累计余额退款
+     *
+     * @param customerName
+     * @param bDay
+     * @param eDay
+     * @return
+     */
+    public BigDecimal getAccountDeductionMoney(String customerName, String bDay, String eDay) {
+        return tbChargeRecordMapper.getAccountDeductionMoney(customerName, bDay, eDay);
+    }
+
+
+    /**
+     * 获取区间内的所有充值
+     *
+     * @param bDay
+     * @param eDay
+     * @return
+     */
+    public List<TbChargeRecord> betweenDaysList(String bDay, String eDay) {
+        QueryWrapper<TbChargeRecord> ew = new QueryWrapper<>();
+        ew.ge("date_format(create_time,'%Y-%m-%d')", bDay)
+                .le("date_format(create_time,'%Y-%m-%d')", eDay);
+        return list(ew);
+    }
+
+    /**
+     * 某时间点前的充值记录
+     * @param eDay
+     * @return
+     */
+    public List<TbChargeRecord> getChargeListBefore(String eDay) {
+        QueryWrapper<TbChargeRecord> ew = new QueryWrapper<>();
+        ew.le("date_format(create_time,'%Y-%m-%d')", eDay);
+        return list(ew);
+    }
+
+    /**
+     * 某个时间点的退款记录
+     * @param eDay
+     * @return
+     */
+    public List<TbChargeRecord> getRefundListBefore(String eDay) {
+        QueryWrapper<TbChargeRecord> ew = new QueryWrapper<>();
+        ew.le("date_format(refund_time,'%Y-%m-%d')", eDay);
+        return list(ew);
+    }
 }

+ 6 - 0
sp-server/src/main/java/com/pj/project/tb_costomer/TbCostomerController.java

@@ -209,4 +209,10 @@ public class TbCostomerController {
         tbCostomerService.initPush();
         return AjaxJson.getSuccess();
     }
+
+    @RequestMapping("init-account")
+    public AjaxJson pushAccount(){
+        tbCostomerService.initAccount();
+        return AjaxJson.getSuccess();
+    }
 }

+ 18 - 0
sp-server/src/main/java/com/pj/project/tb_costomer/TbCostomerService.java

@@ -1,5 +1,7 @@
 package com.pj.project.tb_costomer;
 
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.RandomUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -8,6 +10,8 @@ import com.pj.constants.business.SyncTypeEnum;
 import com.pj.project.sync.SyncService;
 import com.pj.project.sync.dto.PartnerDTO;
 import com.pj.project.sync.dto.PartnerParam;
+import com.pj.project.tb_account.TbAccount;
+import com.pj.project.tb_account.TbAccountService;
 import com.pj.project.tb_init_permission.TbInitPermission;
 import com.pj.project.tb_init_permission.TbInitPermissionService;
 import com.pj.project4sp.SP;
@@ -24,6 +28,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import javax.xml.crypto.Data;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -57,6 +62,9 @@ public class TbCostomerService extends ServiceImpl<TbCostomerMapper, TbCostomer>
     @Resource
     private SyncService syncService;
 
+    @Resource
+    private TbAccountService tbAccountService;
+
     /**
      * 增
      */
@@ -293,4 +301,14 @@ public class TbCostomerService extends ServiceImpl<TbCostomerMapper, TbCostomer>
         partnerDTO.setPartnersList(partnerParams);
         syncService.syncPartnes(partnerDTO);
     }
+
+    public void initAccount() {
+        List<TbCostomer> list = list();
+        list.forEach(tbCostomer -> {
+            TbAccount tbAccount=new TbAccount();
+            tbAccount.setCustomerId(tbCostomer.getId()).setCustomerName(tbCostomer.getName())
+                    .setCreateTime(new Date()).setAccountNo(RandomUtil.randomNumbers(12));
+            tbAccountService.save(tbAccount);
+        });
+    }
 }

+ 92 - 19
sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecord.java

@@ -1,5 +1,7 @@
 package com.pj.project.tb_deduction_record;
 
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.extension.activerecord.Model;
 import lombok.Data;
@@ -35,227 +37,298 @@ public class TbDeductionRecord extends Model<TbDeductionRecord> implements Seria
      */
     public static final String PERMISSION_CODE = "tb-deduction-record";
     public static final String PERMISSION_LIST_REVIEW = "tb-deduction-record-list-review";
+    public static final String PERMISSION_LIST_REFUND = "tb-deduction-record-list-refund";
+    public static final String PERMISSION_LIST_SET_ERROR = "tb-deduction-record-set-error";
+    public static final String PERMISSION_LIST_EXPORT = "tb-deduction-record-export";
 
     // ---------- 表中字段 ----------
     /**
      * 主键
      */
+    @ExcelIgnore
     public String id;
 
     /**
      * 客户id
      */
+    @ExcelIgnore
     public String customerId;
 
     /**
      * 客户名称
      */
+    @ExcelProperty(index = 0,value = "企业名称")
     public String customerName;
 
-    /**
-     * 扣除金额
-     */
-    public BigDecimal deductMoney;
 
+
+    @ExcelIgnore
     private String businessId;
 
     /**
      * 业务单号
      */
+    @ExcelProperty(index = 1,value = "业务单号")
     private String businessNo;
 
     /**
      * 车牌号
      */
+    @ExcelProperty(index =2,value = "车牌号")
     private String carNo;
 
     /**
      * 收费类型
      */
+    @ExcelIgnore
     private Integer feeType;
+    @ExcelIgnore
+    private String feeTypeName;
 
     /**
      * 业务类型id
      */
+    @ExcelIgnore
     private String itemTypeId;
 
+
     /**
      * 业务类型
      */
+    @ExcelProperty(index = 3,value = "业务类型")
     private String itemTypeName;
 
     /**
      * 业务项 id
      */
+    @ExcelIgnore
     private String itemId;
 
     /**
      * 业务项
      */
+    @ExcelProperty(index =4,value = "车型")
     private String itemName;
 
     /**
      * 项目金额(元)
      */
+    @ExcelIgnore
     private BigDecimal itemPrice = new BigDecimal(0);
 
     /**
      * 支付日期
      */
+    @ExcelIgnore
     private String payDay;
 
-
+    @ExcelProperty(index = 5,value = "扣款时间")
     private String payTime;
 
     /**
      * 支付方式(3=微信支付)
      */
+    @ExcelIgnore
     private Integer payType;
 
     /**
      * 创建时间
      */
+    @ExcelIgnore
     private Date createTime;
     /**
      * 更新时间
      */
+    @ExcelIgnore
     private Date updateTime;
-
+    @ExcelIgnore
     private String businessItemId;
-
+    @ExcelIgnore
     private String businessItemNo;
 
     /**
      * 合作伙伴
      */
+    @ExcelIgnore
     private String pickCustomerName;
 
     /**
      * 开票主体
      */
+    @ExcelIgnore
     private String entityName;
 
 
     /**
      * 不含税款
      */
+    @ExcelProperty(index =6,value = "不含税金额")
     private BigDecimal noTaxPrice = new BigDecimal(0);
 
     /**
      * 税款
      */
+    @ExcelProperty(index = 7,value = "税额")
     private BigDecimal taxPrice = new BigDecimal(0);
 
     /**
      * 税率
      */
+    @ExcelProperty(index = 8,value = "税率")
     private BigDecimal taxRate = new BigDecimal(0);
 
 
     /**
      * 单价
      */
+    @ExcelIgnore
     private BigDecimal unitPrice = new BigDecimal(0);
 
-    /**
-     * 重量
-     */
-    private Double weight;
+
 
     /**
      * 数量
      */
+    @ExcelIgnore
     private Integer num = 0;
 
     /**
      * 是否结算(0=未结算, 1=已结算)
      */
+    @ExcelIgnore
     private Integer isSettle;
 
     /**
      * 支付方式(1=直接支付)
      */
+    @ExcelIgnore
     private Integer payMode;
 
     /**
      * 备注
      */
+    @ExcelIgnore
     private String remark;
 
     /**
      * 发票
      */
+    @ExcelIgnore
     private String invoice;
 
-    /**
-     * 微信支付订单号
-     */
-    private String transactionId;
 
     /**
      *
      */
+    @ExcelIgnore
     private String businessCarId;
-
+    @ExcelIgnore
     private String businessCarNo;
+    @ExcelIgnore
     private String outTradeNo;
 
     /**
      * 开单员
      */
+    @ExcelIgnore
     private String kaiDanPerson;
     /**
      * 统计稽查员
      */
+    @ExcelIgnore
     private String jiChaPerson;
     /**
      * 现场调度
      */
+    @ExcelIgnore
     private String diaoDuPerson;
 
     /**
      * 收费明细id
      */
+    @ExcelIgnore
     public String feeDetailsId;
 
     /**
      * 复核人员
      */
+    @ExcelProperty(index = 9,value = "复核员")
     public String reviewBy;
 
     /**
      * 复核时间
      */
+    @ExcelProperty(index = 10,value = "复核时间")
     public Date reviewTime;
 
     /**
      * 复核状态,0-未复核、1-已复核
      */
+    @ExcelIgnore
     public Integer reviewStatus;
 
     /**
      * 原金额
      */
-    public String originalMoney;
-
+    @ExcelProperty(index = 11,value = "原金额")
+    public BigDecimal originalMoney;
+    /**
+     * 订单金额
+     */
+    @ExcelProperty(index = 12,value = "扣款金额")
+    private BigDecimal deductMoney;
     /**
      * 余额
      */
-    public String totalMoney;
+    @ExcelProperty(index = 13,value = "余额")
+    public BigDecimal totalMoney;
 
     /**
      * 绑定表Id
      */
+    @ExcelIgnore
     public String deductionBindId;
 
     /**
      * 预存款自动收费订单号
      */
+    @ExcelIgnore
     private String preOrderNum;
 
     /**
      * 统计非中心ID
      */
+    @ExcelIgnore
     private String calculateId;
+    //正常单1 异常单 0
+    @ExcelIgnore
+    private int status=1;
+    @ExcelIgnore
+    private String errorRemark;
+    @ExcelIgnore
+    private Date setTime;
+    @ExcelIgnore
+    private String setBy;
+
+    /**
+     * 退款金额
+     */
+    @ExcelIgnore
+    public BigDecimal refundMoney=BigDecimal.ZERO;
+    /**
+     * 退款人
+     */
+    @ExcelIgnore
+    public String refundBy;
+    /**
+     * 退款原因
+     */
+    @ExcelIgnore
+    public String refundReason;
+    /**
+     * 退款时间
+     */
+    @ExcelIgnore
+    public Date refundTime;
 
 }

+ 36 - 16
sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecordController.java

@@ -13,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.util.List;
 
 
@@ -58,25 +59,44 @@ public class TbDeductionRecordController {
 		int line = tbDeductionRecordService.review(id);
 		return AjaxJson.getByLine(line);
 	}
-	
-	
-	// ------------------------- 前端接口 -------------------------
-	
-	
-	/** 改 - 不传不改 [G] */
-	@RequestMapping("updateByNotNull")
-	public AjaxJson updateByNotNull(Long id){
-		AjaxError.throwBy(true, "如需正常调用此接口,请删除此行代码");
-		// 鉴别身份,是否为数据创建者 
-		long userId = SP.publicMapper.getColumnByIdToLong(TbDeductionRecord.TABLE_NAME, "user_id", id);
-		AjaxError.throwBy(userId != StpUserUtil.getLoginIdAsLong(), "此数据您无权限修改");
-		// 开始修改 (请只保留需要修改的字段)
+
+	@RequestMapping("refund")
+	@SaCheckPermission(TbDeductionRecord.PERMISSION_LIST_REFUND)
+	public AjaxJson refund() {
+		SoMap soMap=SoMap.getRequestSoMap();
+		String id=soMap.getString("id");
+		String refundMoney=soMap.getString("refundMoney");
+		String refundReason=soMap.getString("refundReason");
+		int payingType=soMap.getInt("payingType");
+		tbDeductionRecordService.refund(id,new BigDecimal(refundMoney),refundReason,payingType);
+		return AjaxJson.getSuccess();
+	}
+
+	@RequestMapping("setError")
+	@SaCheckPermission(TbDeductionRecord.PERMISSION_LIST_SET_ERROR)
+	public AjaxJson setError() {
+		SoMap soMap=SoMap.getRequestSoMap();
+		String id=soMap.getString("id");
+		String errorRemark=soMap.getString("errorRemark");
+		tbDeductionRecordService.setError(id,errorRemark);
+		return AjaxJson.getSuccess();
+	}
+	@RequestMapping("export")
+	@SaCheckPermission(TbDeductionRecord.PERMISSION_LIST_EXPORT)
+	public AjaxJson export() {
 		SoMap so = SoMap.getRequestSoMap();
-		so.clearNotIn("id", "businessId", "businessNo", "carNo", "feeType", "itemTypeId", "itemTypeName", "itemId", "itemName", "itemPrice", "unitPrice", "payDay", "payTime", "payType", "payMode", "createTime", "updateTime", "businessItemId", "businessItemNo", "pickCustomerName", "customerName", "entityName", "taxRate", "noTaxPrice", "taxPrice", "weight", "num", "isSettle", "remark", "invoice", "transactionId", "outTradeNo", "businessCarId", "businessCarNo", "kaiDanPerson", "diaoDuPerson", "jiChaPerson", "customerId", "deductMoney", "feeDetailsId", "reviewBy", "reviewTime", "reviewStatus", "partner", "originalMoney", "totalMoney").clearNull().humpToLineCase();	
-		int line = SP.publicMapper.updateBySoMapById(TbDeductionRecord.TABLE_NAME, so, id);
-		return AjaxJson.getByLine(line);
+		String url = tbDeductionRecordService.export(so);
+		return AjaxJson.getSuccessData(url);
+	}
+
+	@RequestMapping("getSum")
+	@SaCheckPermission(TbDeductionRecord.PERMISSION_LIST_EXPORT)
+	public AjaxJson getSum() {
+		SoMap so = SoMap.getRequestSoMap();
+		return AjaxJson.getSuccessData(tbDeductionRecordService.getSum(so));
 	}
 	
+
 	
 	
 	

+ 3 - 0
sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecordMapper.java

@@ -4,8 +4,10 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.pj.project.tb_business_item.TbBusinessItem;
 import com.pj.utils.so.SoMap;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 import org.springframework.stereotype.Repository;
 
+import java.math.BigDecimal;
 import java.util.List;
 
 /**
@@ -52,5 +54,6 @@ public interface TbDeductionRecordMapper extends BaseMapper<TbDeductionRecord> {
 	 */
 	List<TbDeductionRecord> getList(SoMap so);
 
+	BigDecimal getSumDeuction(@Param("customerName") String customerName, @Param("eDay") String eDay);
 
 }

+ 17 - 2
sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecordMapper.xml

@@ -130,13 +130,28 @@
 		<include refid="select_sql"></include>
 		where id = #{id}
 	</select>
-	
+	<select id="getSumDeuction" resultType="java.math.BigDecimal">
+		SELECT
+		(SUM(deduct_money)-SUM(refund_money)) as deductMoney
+		FROM tb_deduction_record
+		<trim prefix="where" prefixOverrides="and">
+			<if test="customerName !='' and customerName !=null">
+				and customer_name like concat('%',#{customerName},'%')
+			</if>
+
+			<if test="eDay !='' and eDay !=null">
+				and date_format(pay_day,'%Y-%m-%d')&lt;= #{eDay}
+			</if>
+		</trim>
+		GROUP BY customer_id;
+	</select>
 	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
-	<select id="getList" resultMap="model">
+	<select id="getList" resultType="com.pj.project.tb_deduction_record.TbDeductionRecord">
 		<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("status") and status !=-1 '> and status = #{status} </if>
 			<if test=' this.has("businessNo") '> and business_no like "%" #{businessNo} "%" </if>
 			<if test=' this.has("carNo") '> and car_no like "%" #{carNo} "%" </if>
 			<if test=' this.has("feeType") '> and fee_type = #{feeType} </if>

+ 192 - 18
sp-server/src/main/java/com/pj/project/tb_deduction_record/TbDeductionRecordService.java

@@ -1,22 +1,49 @@
 package com.pj.project.tb_deduction_record;
 
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.RandomUtil;
+import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONArray;
 import cn.hutool.json.JSONUtil;
+import cn.hutool.log.StaticLog;
+import com.alibaba.excel.EasyExcel;
 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.constants.business.PayEnum;
+import com.pj.current.config.SystemObject;
 import com.pj.current.satoken.StpUserUtil;
+import com.pj.project.tb_account.TbAccount;
+import com.pj.project.tb_account.TbAccountService;
+import com.pj.project.tb_business.TbBusiness;
+import com.pj.project.tb_business.TbBusinessService;
+import com.pj.project.tb_business_car.TbBusinessCarService;
+import com.pj.project.tb_business_item.TbBusinessItem;
+import com.pj.project.tb_business_item.TbBusinessItemService;
 import com.pj.project.tb_charge_record.TbChargeRecord;
 import com.pj.project.tb_charge_record.TbChargeRecordMapper;
+import com.pj.project.tb_charge_record.TbChargeRecordService;
+import com.pj.project.tb_mild_car.TbMildCar;
+import com.pj.project.tb_refund_record.TbRefundRecord;
+import com.pj.project.tb_refund_record.TbRefundRecordService;
+import com.pj.project4sp.uploadfile.UploadConfig;
+import com.pj.utils.sg.AjaxError;
 import com.pj.utils.so.SoMap;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
+import java.io.File;
+import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * Service: TbDeductionRecord -- 扣费记录
@@ -24,45 +51,61 @@ import java.util.Map;
  * @author qzy
  */
 @Service
+@Transactional
 public class TbDeductionRecordService extends ServiceImpl<TbDeductionRecordMapper, TbDeductionRecord> implements IService<TbDeductionRecord> {
 
     /**
      * 底层 Mapper 对象
      */
     @Autowired
-    TbDeductionRecordMapper TbDeductionRecordMapper;
+    TbDeductionRecordMapper tbDeductionRecordMapper;
+
+    @Resource
+    private TbAccountService tbAccountService;
+    @Resource
+    private TbChargeRecordService tbChargeRecordService;
+    @Resource
+    @Lazy
+    private TbBusinessService tbBusinessService;
+    @Resource
+    @Lazy
+    private TbBusinessItemService tbBusinessItemService;
+    @Resource
+    private TbRefundRecordService tbRefundRecordService;
+    @Resource
+    private UploadConfig uploadConfig;
 
     /**
      * 增
      */
     int add(TbDeductionRecord t) {
-        return TbDeductionRecordMapper.add(t);
+        return tbDeductionRecordMapper.add(t);
     }
 
 
     /**
-     *  复审
+     * 复审
      */
     int review(Long id) {
-        TbDeductionRecord chargeRecord = TbDeductionRecordMapper.selectById(id);
+        TbDeductionRecord chargeRecord = tbDeductionRecordMapper.selectById(id);
         chargeRecord.setReviewStatus(1);
         chargeRecord.setReviewBy(StpUserUtil.getLoginName());
         chargeRecord.setReviewTime(new Date());
-        return TbDeductionRecordMapper.updateById(chargeRecord);
+        return tbDeductionRecordMapper.updateById(chargeRecord);
     }
 
     /**
      * 改
      */
     int update(TbDeductionRecord t) {
-        return TbDeductionRecordMapper.update(t);
+        return tbDeductionRecordMapper.update(t);
     }
 
     /**
      * 查
      */
     TbDeductionRecord getById(Long id) {
-        return TbDeductionRecordMapper.getById(id);
+        return tbDeductionRecordMapper.getById(id);
     }
 
     /**
@@ -70,28 +113,159 @@ public class TbDeductionRecordService extends ServiceImpl<TbDeductionRecordMappe
      */
     List<TbDeductionRecord> getList(SoMap so) {
         String customerId = StpUserUtil.getCustomerId();
-        if(!UserTypeEnum.PLATFORM_ADMIN.getCustomerId().equals(customerId)){
-            so.put("customerId",customerId);
+        if (!UserTypeEnum.PLATFORM_ADMIN.getCustomerId().equals(customerId)) {
+            so.put("customerId", customerId);
         }
-        if(ObjectUtil.isNotEmpty(so.get("parTime[]"))){
+        if (ObjectUtil.isNotEmpty(so.get("parTime[]"))) {
             JSONArray jsonArray = JSONUtil.parseArray(so.getString("parTime[]"));
-            if(jsonArray.size()==2){
-                so.put("startTime",jsonArray.get(0));
-                so.put("endTime",jsonArray.get(1));
+            if (jsonArray.size() == 2) {
+                so.put("startTime", jsonArray.get(0));
+                so.put("endTime", jsonArray.get(1));
             }
         }
-        return TbDeductionRecordMapper.getList(so);
+        return tbDeductionRecordMapper.getList(so);
     }
 
     /**
      * 根据业务项id查找扣费明细
+     *
      * @param businessItemId
      * @return
      */
     public TbDeductionRecord findByBusinessItemId(Long businessItemId) {
-        QueryWrapper<TbDeductionRecord>ew=new QueryWrapper<>();
-        ew.lambda().eq(TbDeductionRecord::getBusinessItemId,businessItemId);
-        List<TbDeductionRecord>list=list(ew);
-        return list.isEmpty()?null:list.get(0);
+        QueryWrapper<TbDeductionRecord> ew = new QueryWrapper<>();
+        ew.lambda().eq(TbDeductionRecord::getBusinessItemId, businessItemId);
+        List<TbDeductionRecord> list = list(ew);
+        return list.isEmpty() ? null : list.get(0);
+    }
+
+    public void setError(String id, String errorRemark) {
+        TbDeductionRecord record = this.getById(id);
+        if (record == null) {
+            throw new AjaxError("记录不存在");
+        }
+        String businessId = record.getBusinessId();
+        TbBusiness tbBusiness = tbBusinessService.getById(businessId);
+        tbBusiness.setHasError(1);
+        tbBusinessService.updateById(tbBusiness);
+        TbBusinessItem tbBusinessItem = tbBusinessItemService.getById(record.getBusinessItemId());
+        tbBusinessItem.setHasError(1);
+        tbBusinessItemService.updateById(tbBusinessItem);
+        record.setErrorRemark(errorRemark)
+                .setStatus(0)
+                .setSetBy(StpUserUtil.getCreateBy())
+                .setSetTime(new Date());
+        this.updateById(record);
+    }
+
+    public void refund(String id, BigDecimal refundMoney, String refundReason, int payingType) {
+        TbDeductionRecord record = this.getById(id);
+        if (record == null) {
+            throw new AjaxError("记录不存在");
+        }
+        //可退款金额=订单金额-已退款金额
+        BigDecimal carRefundMoney = record.getDeductMoney().subtract(record.getRefundMoney());
+        if (carRefundMoney.compareTo(refundMoney) < 0) {
+            throw new AjaxError("退款金额大于可退款金额");
+        }
+        record.setRefundBy(StpUserUtil.getCreateBy())
+                .setRefundMoney(record.getRefundMoney().add(refundMoney))
+                .setRefundTime(new Date())
+                .setRefundReason(refundReason);
+        this.updateById(record);
+        //更新退款
+        TbChargeRecord chargeRecord = new TbChargeRecord();
+        BigDecimal zero = BigDecimal.valueOf(0);
+        TbAccount tbAccount = tbAccountService.getAccountByCustomerId(record.getCustomerId());
+        BigDecimal balance = tbAccount.getTotalMoney();
+        tbAccount.setTotalMoney(balance.add(refundMoney));
+        tbAccountService.updateById(tbAccount);
+        chargeRecord.setStatus(1).setType(TbChargeRecord.TypeEunm.ORDER_REFUND.getType())
+                .setBeforeMoney(balance)
+                .setPreTopupMoney(zero)
+                .setTotalTopupMoney(zero)
+                .setPayMoney(zero)
+                .setRefundMoney(refundMoney)
+                .setDiscountMoney(zero).setCustomerId(tbAccount.getCustomerId())
+                .setTotalMoney(balance.add(refundMoney))
+                .setCustomerName(tbAccount.getCustomerName())
+                .setRemark(refundReason).setRefundBy(StpUserUtil.getCreateBy())
+                .setRefundTime(new Date())
+                .setRefundBy(StpUserUtil.getCreateBy())
+                .setAccountId(tbAccount.getId())
+                .setChargeChannel(TbChargeRecord.Ch.PC.getType())
+                .setCreateTime(new Date()).setPayingType(payingType)
+                .setChargePeople(StpUserUtil.getLoginName())
+                .setNo(record.getBusinessNo());
+        tbChargeRecordService.save(chargeRecord);
+        //更新业务已支付金额
+        TbBusiness tbBusiness = tbBusinessService.getById(record.getBusinessId());
+        tbBusiness.setPayMoney(tbBusiness.getPayMoney().subtract(refundMoney));
+        tbBusinessService.updateById(tbBusiness);
+
+        TbBusinessItem tbBusinessItem = tbBusinessItemService.getById(record.getBusinessItemId());
+        tbBusinessItem.setRefundBy(StpUserUtil.getCreateBy())
+                .setRefundTime(new Date())
+                .setRefundMoney(tbBusinessItem.getRefundMoney().add(refundMoney))
+                .setPayStatus(PayEnum.PayStatusEnum.REFUND_STATUS.getCode());
+        tbBusinessItemService.updateById(tbBusinessItem);
+
+        TbRefundRecord tbRefundRecord = new TbRefundRecord();
+        tbRefundRecord.setRefundMoney(refundMoney).setRefundDesc(refundReason)
+                .setRefundNo(tbBusiness.getNo()).setRefundBy(StpUserUtil.getCreateBy())
+                .setRefundTime(new Date()).setRefundType(TbChargeRecord.TypeEunm.ORDER_REFUND.getType())
+                .setCustomerName(tbAccount.getCustomerName()).setItemName(tbBusinessItem.getItemName())
+                .setCarNo(record.getCarNo())
+                .setItemTypeName(tbBusinessItem.getItemTypeName()).setBusinessId(tbBusiness.getId()).setBusinessItemId(tbBusinessItem.getId() + "");
+
+        tbRefundRecordService.save(tbRefundRecord);
+    }
+
+    /**
+     * 查询某个时间段内的总扣款
+     *
+     * @param eDay
+     * @return
+     */
+    public BigDecimal getSumDeuction(String customerName, String eDay) {
+        return tbDeductionRecordMapper.getSumDeuction(customerName, eDay);
+    }
+
+    /**
+     *某个时间段的扣款记录
+     * @param eDay
+     * @return
+     */
+    public List<TbDeductionRecord> getBeforeList(String eDay) {
+        QueryWrapper<TbDeductionRecord> ew = new QueryWrapper<>();
+        ew.le("date_format(pay_time,'%Y-%m-%d')", eDay);
+        return list(ew);
+    }
+
+
+    /**
+     * 导出
+     *
+     * @param so
+     * @return
+     */
+    public String export(SoMap so) {
+        List<TbDeductionRecord> list = tbDeductionRecordMapper.getList(so);
+        String flieTypeFolder = "/export/";
+        String currDateFolder = DateUtil.today();
+        String fileName = "record-" + RandomUtil.randomNumbers(6) + ".xlsx";
+        String fileFolder = new File(uploadConfig.rootFolder).getAbsolutePath() +
+                uploadConfig.httpPrefix + flieTypeFolder + currDateFolder + "/";
+        if (!FileUtil.exist(fileFolder)) {
+            FileUtil.mkdir(fileFolder);
+        }
+        EasyExcel.write(fileFolder + fileName, TbDeductionRecord.class).sheet("扣费记录导出")
+                .doWrite(() -> list);
+        return SystemObject.config.getDomain() + uploadConfig.httpPrefix + flieTypeFolder + currDateFolder + "/" + fileName;
+    }
+
+    public Double getSum(SoMap so) {
+        List<TbDeductionRecord> list = tbDeductionRecordMapper.getList(so);
+        return   list.stream().collect(Collectors.summarizingDouble(record->record.getDeductMoney().doubleValue())).getSum();
     }
 }

+ 1 - 1
sp-server/src/main/java/com/pj/project/tb_fee_details/TbFeeDetails.java

@@ -165,7 +165,7 @@ public class TbFeeDetails implements Serializable {
     /**
      * 重量
      */
-    private Double weight;
+    private String weight;
 
     /**
      * 数量

+ 133 - 125
sp-server/src/main/java/com/pj/project/tb_fee_details/TbFeeDetailsService.java

@@ -29,11 +29,13 @@ import com.pj.current.satoken.StpUserUtil;
 import com.pj.current.task.TaskService;
 import com.pj.project.relation_business_car.RelationBusinessCar;
 import com.pj.project.relation_business_car.RelationBusinessCarService;
+import com.pj.project.sync.response.IOrderPriceRes;
 import com.pj.project.tb_business.TbBusiness;
 import com.pj.project.tb_business.TbBusinessService;
 import com.pj.project.tb_business_car.TbBusinessCar;
 import com.pj.project.tb_business_car.TbBusinessCarService;
 import com.pj.project.tb_business_item.TbBusinessItem;
+import com.pj.project.tb_business_item.TbBusinessItemService;
 import com.pj.project.tb_costomer.TbCostomer;
 import com.pj.project.tb_costomer.TbCostomerService;
 import com.pj.project.tb_deduction_bind.TbDeductionBindService;
@@ -89,6 +91,8 @@ public class TbFeeDetailsService extends ServiceImpl<TbFeeDetailsMapper, TbFeeDe
     @Lazy
     TbBusinessService tbBusinessService;
     @Resource
+    TbBusinessItemService tbBusinessItemService;
+    @Resource
     private MyConfig myConfig;
     @Resource
     private PartConfig partConfig;
@@ -177,49 +181,45 @@ public class TbFeeDetailsService extends ServiceImpl<TbFeeDetailsMapper, TbFeeDe
      */
     public List<TbFeeDetails> chargeParkFee(List<PriceBO> cars, String transactionId, String outTradeNo, Date now, PayEnum.PayType payType) {
         List<TbFeeDetails> details = new ArrayList<>();
-       if (!cars.isEmpty()){
-           String uniqExpenseId = cars.get(0).getUniqExpenseId();
-           TbItem tbItem = tbItemService.findByCode(uniqExpenseId);
-           BigDecimal taxRate=BigDecimal.valueOf(tbItem.getTaxRate()).divide(BigDecimal.valueOf(100),2,BigDecimal.ROUND_UP);
-           for (PriceBO bo1 : cars) {
-               //本次支付的停车费金额
-               BigDecimal payPrice = bo1.getP();
-               if (payPrice.compareTo(BigDecimal.valueOf(0)) == 0) {
-                   continue;
-               }
-               TbBusinessCar car = tbBusinessCarService.getById(bo1.getId());
-               String bindIdStr = "";
-               if (payType.getCode() == PayEnum.PayType.PER_PAY.getCode()) {
-                   bindIdStr = tbDeductionBindService.getBindId(car.getCarNo());
-               }
-               //24小时内的停车费
-               BigDecimal in24Price = bo1.getStandard();
-               TbFeeDetails in24Detail = new TbFeeDetails();
-               in24Detail.setItemName(bo1.getCarDesc());
-               //24小时内的停车费
-               in24Detail.setNum(1).setItemTypeName(PartFeeEnum.IN_24_HOURS.getDesc()).setCalculateId(bo1.getCalculateId())
-                       .setUnitPrice(in24Price).setItemPrice(in24Price).setModule(payType.getDesc()).setBusinessId(bindIdStr);
-               setFee(taxRate, in24Detail, car, transactionId, outTradeNo, now);
-               String type = StrUtil.isEmpty(in24Detail.getId()) ? SyncTypeEnum.INSERT.getCode() : SyncTypeEnum.UPDATE.getCode();
-               saveOrUpdate(in24Detail);
-               details.add(in24Detail);
-               taskService.addTask(new FeeDetailSyncTask(RandomUtil.randomNumbers(10), 1000, in24Detail.getId(), type, payType));
-               //24小时外的停车费
-               BigDecimal out24Price = payPrice.subtract(in24Price);
-               if (out24Price.compareTo(BigDecimal.valueOf(0)) > 0) {
-                   TbFeeDetails out24Details = new TbFeeDetails();
-                   BigDecimal unitPrice = bo1.getExtraPrice();
-                   int num = out24Price.divide(unitPrice, BigDecimal.ROUND_UP, 0).intValue();
-                   out24Details.setNum(num).setItemTypeName(PartFeeEnum.OUT_24_HOURS.getDesc())
-                           .setUnitPrice(unitPrice).setItemPrice(out24Price).setModule(payType.getDesc()).setBusinessId(bindIdStr);
-                   setFee(taxRate, out24Details, car, transactionId, outTradeNo, now);
-                   type = StrUtil.isEmpty(out24Details.getId()) ? SyncTypeEnum.INSERT.getCode() : SyncTypeEnum.UPDATE.getCode();
-                   saveOrUpdate(out24Details);
-                   taskService.addTask(new FeeDetailSyncTask(RandomUtil.randomNumbers(10), 1000, out24Details.getId(), type, payType));
-                   details.add(out24Details);
-               }
-           }
-       }
+        if (!cars.isEmpty()) {
+            String uniqExpenseId = cars.get(0).getUniqExpenseId();
+            TbItem tbItem = tbItemService.findByCode(uniqExpenseId);
+            BigDecimal taxRate = BigDecimal.valueOf(tbItem.getTaxRate()).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_UP);
+            for (PriceBO bo1 : cars) {
+                //本次支付的停车费金额
+                BigDecimal payPrice = bo1.getP();
+                if (payPrice.compareTo(BigDecimal.valueOf(0)) == 0) {
+                    continue;
+                }
+                TbBusinessCar car = tbBusinessCarService.getById(bo1.getId());
+                //24小时内的停车费
+                BigDecimal in24Price = bo1.getStandard();
+                TbFeeDetails in24Detail = new TbFeeDetails();
+                in24Detail.setItemName(bo1.getCarDesc());
+                //24小时内的停车费
+                in24Detail.setNum(1).setItemTypeName(PartFeeEnum.IN_24_HOURS.getDesc()).setCalculateId(bo1.getCalculateId())
+                        .setUnitPrice(in24Price).setItemPrice(in24Price).setModule(payType.getDesc()).setBusinessId(bo1.getBusinessId());
+                setFee(taxRate, in24Detail, car, transactionId, outTradeNo, now);
+                String type = StrUtil.isEmpty(in24Detail.getId()) ? SyncTypeEnum.INSERT.getCode() : SyncTypeEnum.UPDATE.getCode();
+                saveOrUpdate(in24Detail);
+                details.add(in24Detail);
+                taskService.addTask(new FeeDetailSyncTask(RandomUtil.randomNumbers(10), 1000, in24Detail.getId(), type, payType));
+                //24小时外的停车费
+                BigDecimal out24Price = payPrice.subtract(in24Price);
+                if (out24Price.compareTo(BigDecimal.valueOf(0)) > 0) {
+                    TbFeeDetails out24Details = new TbFeeDetails();
+                    BigDecimal unitPrice = bo1.getExtraPrice();
+                    int num = out24Price.divide(unitPrice, BigDecimal.ROUND_UP, 0).intValue();
+                    out24Details.setNum(num).setItemTypeName(PartFeeEnum.OUT_24_HOURS.getDesc())
+                            .setUnitPrice(unitPrice).setItemPrice(out24Price).setModule(payType.getDesc()).setBusinessId(bo1.getBusinessId());
+                    setFee(taxRate, out24Details, car, transactionId, outTradeNo, now);
+                    type = StrUtil.isEmpty(out24Details.getId()) ? SyncTypeEnum.INSERT.getCode() : SyncTypeEnum.UPDATE.getCode();
+                    saveOrUpdate(out24Details);
+                    taskService.addTask(new FeeDetailSyncTask(RandomUtil.randomNumbers(10), 1000, out24Details.getId(), type, payType));
+                    details.add(out24Details);
+                }
+            }
+        }
         return details;
     }
 
@@ -279,8 +279,7 @@ public class TbFeeDetailsService extends ServiceImpl<TbFeeDetailsMapper, TbFeeDe
                 carNo = business.getChinaCarNo();
             }
             TbGoods businessCfg = tbGoodsService.getById(business.getGoodsId());
-            if ((GoodsEnum.LeaveEnum.BUSINESS_MONEY.getCode().equals(businessCfg.getChinaCarLeave())
-                    || GoodsEnum.LeaveEnum.APART_BUSINESS.getCode().equals(businessCfg.getChinaCarLeave()))
+            if ((GoodsEnum.LeaveEnum.APART_BUSINESS.getCode().equals(businessCfg.getChinaCarLeave()))
                     && GoodsEnum.LeaveEnum.PART_MONEY.getCode().equals(businessCfg.getVietnamCarLeave())) {
                 carNo = business.getChinaCarNo();
             }
@@ -303,11 +302,11 @@ public class TbFeeDetailsService extends ServiceImpl<TbFeeDetailsMapper, TbFeeDe
                     .setFeeType(feeType)
                     .setItemTypeId(item.getItemTypeId()).setItemTypeName(item.getItemTypeName())
                     .setItemId(item.getItemId()).setItemName(item.getItemName())
-                    .setPayDay(toDay).setPayType(3).setCreateTime(now).setUpdateTime(now)
+                    .setPayDay(toDay).setPayType(payType.getCode()).setCreateTime(now).setUpdateTime(now)
                     .setBusinessItemId(item.getId() + "")
                     .setPickCustomerName(item.getPickCustomerName())
                     .setCustomerName(business.getCustomerName())
-                    .setIsSettle(1).setPayMode(1).setPayTime(nowStr).setWeight(business.getNetWeight())
+                    .setIsSettle(1).setPayMode(1).setPayTime(nowStr)
                     .setTransactionId(transactionId).setOutTradeNo(outTradeNo)
                     .setNum(Integer.valueOf(item.getNum()))
                     .setModule(module);
@@ -319,7 +318,55 @@ public class TbFeeDetailsService extends ServiceImpl<TbFeeDetailsMapper, TbFeeDe
         return feeDetails;
     }
 
-    public String export(SoMap so) {
+    /**
+     * 预充值支付明细保存
+     * @param item
+     * @param tbBusinessCar
+     * @param business
+     * @return
+     */
+    public TbFeeDetails savePrePayDetails(IOrderPriceRes res, TbBusinessItem item, TbBusinessCar tbBusinessCar, TbBusiness business, FeeTypeEnum feeTypeEnum){
+        Integer feeType =feeTypeEnum.getCode();
+        Double taxRate = item.getTaxRate();
+        Date now=new Date();
+        //添加此item的收费明细
+        TbFeeDetails businessFeeDetail = new TbFeeDetails();
+        businessFeeDetail.setTaxRate(BigDecimal.valueOf(taxRate));
+        BigDecimal taxPrice = item.getTotal()
+                .divide(BigDecimal.valueOf(1).add(businessFeeDetail.getTaxRate()), 2, BigDecimal.ROUND_HALF_UP)
+                .multiply(businessFeeDetail.getTaxRate());
+        taxPrice = taxPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
+        BigDecimal noTaxPrice = item.getTotal().subtract(taxPrice);
+        noTaxPrice = noTaxPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
+        businessFeeDetail.setBusinessId(item.getBusinessId()).setBusinessNo(business.getNo())
+                .setBusinessItemNo(item.getNo()).setBusinessCarId(tbBusinessCar.getId()).setBusinessCarNo(tbBusinessCar.getCarNo())
+                .setCarNo(tbBusinessCar.getCarNo()).setCalculateId(res.getCalculateId())
+                .setItemPrice(item.getTotal()).setUnitPrice(item.getItemPrice()).setNoTaxPrice(noTaxPrice).setTaxPrice(taxPrice)
+                .setFeeType(feeType)
+                .setItemTypeId(item.getItemTypeId()).setItemTypeName(item.getItemTypeName())
+                .setItemId(item.getItemId()).setItemName(item.getItemName())
+                .setPayDay(DateUtil.today()).setPayType(PayEnum.PayType.PER_PAY.getCode()).setCreateTime(now).setUpdateTime(now)
+                .setBusinessItemId(item.getId() + "").setWeight(tbBusinessCar.getNetWeight())
+                .setPickCustomerName(item.getPickCustomerName())
+                .setCustomerName(business.getCustomerName())
+                .setIsSettle(1).setPayMode(1).setPayTime(DateUtil.now())
+                .setNum(Integer.valueOf(item.getNum()))
+                .setModule(PayEnum.PayType.PER_PAY.getDesc());
+        this.save(businessFeeDetail);
+        taskService.addTask(new FeeDetailSyncTask(RandomUtil.randomNumbers(10), 1000, businessFeeDetail.getId(), SyncTypeEnum.INSERT.getCode(), PayEnum.PayType.PER_PAY));
+        return businessFeeDetail;
+    }
+
+    public List<TbFeeDetails> savePrePayDetails(IOrderPriceRes res, List<TbBusinessItem> itemList, TbBusinessCar tbBusinessCar, TbBusiness business, FeeTypeEnum feeTypeEnum) {
+        List<TbFeeDetails> feeDetailsList=new ArrayList<>();
+        for (TbBusinessItem item : itemList) {
+            TbFeeDetails  feeDetails=  savePrePayDetails(res, item, tbBusinessCar, business, feeTypeEnum);
+            feeDetailsList.add(feeDetails);
+        }
+        return feeDetailsList;
+    }
+
+        public String export(SoMap so) {
         Date now = new Date();
         String nowStr = DateUtil.format(now, "yyyy-MM-dd HH:mm");
         String beginTime = so.getString("beginTime");
@@ -654,87 +701,48 @@ public class TbFeeDetailsService extends ServiceImpl<TbFeeDetailsMapper, TbFeeDe
         return tbFeeDetailsMapper.getTotalMoney(so);
     }
 
-    public List<TbFeeDetails> findByBusinessNo(String businessNo) {
-        QueryWrapper<TbFeeDetails> ew = new QueryWrapper<>();
-        ew.eq("business_no", businessNo);
-        return list(ew);
-    }
-
     public List<TbFeeStatistics> getDayStatistics(String toDay) {
         return tbFeeDetailsMapper.getDayStatistics(toDay);
     }
 
 
-    /**
-     * 预充值自动缴费-收费明细生成
-     *
-     * @param items
-     * @param transactionId
-     * @param outTradeNo
-     * @param now
-     */
-    public List<TbFeeDetails> autoChargeBusinessFee(List<TbBusinessItem> items, String transactionId, String outTradeNo,
-                                                    Date now) {
-        List<TbFeeDetails> feeDetails = new ArrayList<TbFeeDetails>();
-        String nowStr = DateUtil.format(now, "yyyy-MM-dd HH:mm:ss");
-        String toDay = DateUtil.format(now, "yyyy-MM-dd");
-        for (TbBusinessItem item : items) {
-            Integer feeType = item.getPayType();
-            Double taxRate = item.getTaxRate();
-            //添加此item的收费明细
-            TbBusiness business = tbBusinessService.getById(item.getBusinessId());
-            TbFeeDetails businessFeeDetail = new TbFeeDetails();
-            businessFeeDetail.setTaxRate(BigDecimal.valueOf(taxRate));
-            BigDecimal taxPrice = item.getTotal()
-                    .divide(BigDecimal.valueOf(1).add(businessFeeDetail.getTaxRate()), 2, BigDecimal.ROUND_HALF_UP)
-                    .multiply(businessFeeDetail.getTaxRate());
-            taxPrice = taxPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
-            BigDecimal noTaxPrice = item.getTotal().subtract(taxPrice);
-            noTaxPrice = noTaxPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
-
-            String carNo = business.getCardNo();
-            if (StrUtil.isEmpty(business.getCardNo())) {
-                carNo = business.getChinaCarNo();
-            }
-            TbGoods businessCfg = tbGoodsService.getById(business.getGoodsId());
-            if ((GoodsEnum.LeaveEnum.BUSINESS_MONEY.getCode() == businessCfg.getChinaCarLeave() || GoodsEnum.LeaveEnum.APART_BUSINESS.getCode() == businessCfg.getChinaCarLeave())
-                    && GoodsEnum.LeaveEnum.BUSINESS_MONEY.getCode() != businessCfg.getVietnamCarLeave() && GoodsEnum.LeaveEnum.APART_BUSINESS.getCode() != businessCfg.getVietnamCarLeave()) {
-                carNo = business.getChinaCarNo();
-            }
-            String businessCarIds = "";
-            String businessCarNos = "";
-            List<RelationBusinessCar> relation = relationBusinessCarService.findByBusinessId(item.getBusinessId());
-            for (RelationBusinessCar rela : relation) {
-                TbBusinessCar bt = tbBusinessCarService.getById(rela.getBusinessCarId());
-                if (StrUtil.contains(carNo, bt.getCarNo())) {
-                    businessCarIds += bt.getId() + ",";
-                    businessCarNos += bt.getNo() + ",";
-                }
-            }
-            businessCarIds = StrUtil.sub(businessCarIds, 0, businessCarIds.length() - 1);
-            businessCarNos = StrUtil.sub(businessCarNos, 0, businessCarNos.length() - 1);
-            businessFeeDetail.setBusinessId(item.getBusinessId()).setBusinessNo(business.getNo())
-                    .setBusinessItemNo(item.getNo()).setBusinessCarId(businessCarIds).setBusinessCarNo(businessCarNos)
-                    .setCarNo(carNo).setModule(PayEnum.PayType.PER_PAY.getDesc())
-                    .setItemPrice(item.getTotal()).setUnitPrice(item.getItemPrice()).setNoTaxPrice(noTaxPrice).setTaxPrice(taxPrice)
-                    .setFeeType(feeType)
-                    .setItemTypeId(item.getItemTypeId()).setItemTypeName(item.getItemTypeName())
-                    .setItemId(item.getItemId()).setItemName(item.getItemName())
-                    .setPayDay(toDay).setPayType(PayEnum.PayType.PER_PAY.getCode()).setCreateTime(now).setUpdateTime(now)
-                    .setBusinessItemId(item.getId() + "")
-                    .setPickCustomerName(item.getPickCustomerName())
-                    .setCustomerName(business.getCustomerName())
-                    .setIsSettle(1).setPayMode(1).setPayTime(nowStr).setWeight(business.getNetWeight())
-                    .setTransactionId(transactionId).setOutTradeNo(outTradeNo)
-                    .setNum(Integer.valueOf(item.getNum()));
-            this.saveOrUpdate(businessFeeDetail);
-            feeDetails.add(businessFeeDetail);
-        }
-        return feeDetails;
-    }
-
-
-    public void chargeManagerFee(ManagerBO managerBO, String transactionId, String outTradeNo, Date payTime, PayEnum.PayType wxPay) {
-
+    public void chargeManagerFee(ManagerBO managerBO, String businessId, String transactionId, String outTradeNo, Date payTime, PayEnum.PayType wxPay) {
+        String nowStr = DateUtil.format(payTime, "yyyy-MM-dd HH:mm:ss");
+        String toDay = DateUtil.format(payTime, "yyyy-MM-dd");
+        Date now = new Date();
+        TbBusinessItem item = tbBusinessItemService.getById(managerBO.getId());
+        Integer feeType = item.getPayType();
+        Double taxRate = item.getTaxRate();
+        //添加此item的收费明细
+        TbBusiness business = tbBusinessService.getById(businessId);
+        TbFeeDetails businessFeeDetail = new TbFeeDetails();
+        businessFeeDetail.setTaxRate(BigDecimal.valueOf(taxRate));
+        BigDecimal taxPrice = item.getTotal()
+                .divide(BigDecimal.valueOf(1).add(businessFeeDetail.getTaxRate()), 2, BigDecimal.ROUND_HALF_UP)
+                .multiply(businessFeeDetail.getTaxRate());
+        taxPrice = taxPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
+        BigDecimal noTaxPrice = item.getTotal().subtract(taxPrice);
+        noTaxPrice = noTaxPrice.setScale(2, BigDecimal.ROUND_HALF_UP);
+        String carNo = managerBO.getCarNo();
+        businessFeeDetail.setBusinessId(item.getBusinessId()).setBusinessNo(business.getNo())
+                .setBusinessItemNo(item.getNo())
+                .setBusinessCarId(managerBO.getCarId())
+                .setBusinessCarNo(carNo)
+                .setCarNo(carNo).setCalculateId(item.getCalculateId())
+                .setItemPrice(item.getTotal()).setUnitPrice(item.getItemPrice()).setNoTaxPrice(noTaxPrice).setTaxPrice(taxPrice)
+                .setFeeType(feeType)
+                .setItemTypeId(item.getItemTypeId()).setItemTypeName(item.getItemTypeName())
+                .setItemId(item.getItemId()).setItemName(item.getItemName())
+                .setPayDay(toDay).setPayType(wxPay.getCode()).setCreateTime(now).setUpdateTime(now)
+                .setBusinessItemId(item.getId() + "")
+                .setPickCustomerName(item.getPickCustomerName())
+                .setCustomerName(business.getCustomerName())
+                .setIsSettle(1).setPayMode(1).setPayTime(nowStr)
+                .setTransactionId(transactionId).setOutTradeNo(outTradeNo)
+                .setNum(Integer.valueOf(item.getNum()))
+                .setModule(wxPay.getDesc());
+        String type = StrUtil.isEmpty(businessFeeDetail.getId()) ? SyncTypeEnum.INSERT.getCode() : SyncTypeEnum.UPDATE.getCode();
+        saveOrUpdate(businessFeeDetail);
+        taskService.addTask(new FeeDetailSyncTask(RandomUtil.randomNumbers(10), 1000, businessFeeDetail.getId(), type, wxPay));
     }
 }

+ 1 - 1
sp-server/src/main/java/com/pj/project/tb_fee_details/dto/ExportFeeDetailDTO.java

@@ -21,7 +21,7 @@ public class ExportFeeDetailDTO {
     private String feeType;
     private String itemTypeName;
     private String itemName;
-    private Double weight;
+    private String weight;
     private Integer num;
     private BigDecimal unitPrice;
     private BigDecimal itemPrice;

+ 2 - 2
sp-server/src/main/java/com/pj/project/tb_fee_statistics/TbFeeStatisticsService.java

@@ -119,7 +119,7 @@ public class TbFeeStatisticsService extends ServiceImpl<TbFeeStatisticsMapper, T
     /**
      * 照搬收费明细到日统计
      */
-    public void addOrUpdateStatistic(Date now) {
+    public void addOrUpdateStatistic(Date now,int payType) {
         String toDay = DateUtil.format(now, "yyyy-MM-dd");
         String thisYear = StrUtil.sub(toDay, 0, 4);
         String thisMonth = StrUtil.sub(toDay, 0, 7);
@@ -134,7 +134,7 @@ public class TbFeeStatisticsService extends ServiceImpl<TbFeeStatisticsMapper, T
                     .setNum(stat.getNum()).setTaxMoney(stat.getTaxMoney()).setTaxRate(stat.getTaxRate())
                     .setTaxes(stat.getTaxes()).setNoTaxMoney(stat.getNoTaxMoney())
                     .setDay(toDay).setMonth(thisMonth).setYear(thisYear)
-                    .setPayType(3);
+                    .setPayType(payType);
             this.saveOrUpdate(statistics);
         }
 

+ 6 - 2
sp-server/src/main/java/com/pj/project/tb_goods/TbGoods.java

@@ -92,8 +92,10 @@ public class TbGoods extends Model<TbGoods> implements Serializable {
      * 1: '下单后', 2: '确认后'
      */
     private Integer payStep = 2;
-    private Integer chinaCarPay = 1;
-    private Integer vietnamCarPay = 1;
+    //空车限制
+//    private Integer chinaCarPay = 1;
+    //重车限制
+//    private Integer vietnamCarPay = 1;
 
     private Integer chinaCarLeave = 1;
     private Integer vietnamCarLeave = 1;
@@ -105,5 +107,7 @@ public class TbGoods extends Model<TbGoods> implements Serializable {
      */
     private Integer autoDeductionType;
 
+    private Integer needPartner=1;
+
 
 }

+ 6 - 1
sp-server/src/main/java/com/pj/project/tb_goods/TbGoodsController.java

@@ -196,7 +196,12 @@ public class TbGoodsController {
         int line = SP.publicMapper.updateColumnById(TbGoods.TABLE_NAME, "need_customer", value, id);
         return AjaxJson.getByLine(line);
     }
-
+    @RequestMapping("updateNeedPartner")
+    @SaCheckPermission(TbGoods.PERMISSION_CODE_EDIT)
+    public AjaxJson updateNeedPartner(Long id, String value) {
+        int line = SP.publicMapper.updateColumnById(TbGoods.TABLE_NAME, "need_partner", value, id);
+        return AjaxJson.getByLine(line);
+    }
     /**
      * 改 - 申报时间是否必填(1=是,0=否)
      */

+ 3 - 0
sp-server/src/main/java/com/pj/project/tb_item/TbItem.java

@@ -92,6 +92,9 @@ public class TbItem extends Model<TbItem> implements Serializable {
     @TableField(exist = false)
     private String remark;
 
+    @TableField(exist = false)
+    private String cabinetNo;
+
 
 
     @TableField(exist = false)

+ 3 - 1
sp-server/src/main/java/com/pj/project/tb_item_type/TbItemTypeService.java

@@ -155,7 +155,9 @@ public class TbItemTypeService extends ServiceImpl<TbItemTypeMapper, TbItemType>
                 list.stream()
                         .filter(relationTypeItem -> relationTypeItem.getItemId().equals(item.getId()) && relationTypeItem.getTypeId().equals(typeId))
                         .findFirst().ifPresent(relationTypeItem -> {
-                    item.setInc(relationTypeItem.getInc()).setNeedRemark(relationTypeItem.getNeedRemark()).setTypeId(relationGoodsType.getTypeId());
+                    item.setInc(relationTypeItem.getInc())
+                            .setNeedRemark(relationTypeItem.getNeedRemark())
+                            .setTypeId(relationGoodsType.getTypeId());
                 });
             }
             tbItemType.setItems(items);

+ 127 - 0
sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecord.java

@@ -0,0 +1,127 @@
+package com.pj.project.tb_refund_record;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.EqualsAndHashCode;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * Model: tb_refund_record -- 退款记录表
+ * @author qzy 
+ */
+@Data
+@Accessors(chain = true)
+@TableName(TbRefundRecord.TABLE_NAME)
+@EqualsAndHashCode(callSuper = false)
+public class TbRefundRecord extends Model<TbRefundRecord> implements Serializable {
+
+	// ---------- 模块常量 ----------
+	/**
+	 * 序列化版本id 
+	 */
+	private static final long serialVersionUID = 1L;	
+	/**
+	 * 此模块对应的表名 
+	 */
+	public static final String TABLE_NAME = "tb_refund_record";	
+	/**
+	 * 此模块对应的权限码 
+	 */
+	public static final String PERMISSION_CODE = "tb-refund-record";	
+	public static final String PERMISSION_CODE_EXPORT = "tb-refund-record-export";
+
+
+	// ---------- 表中字段 ----------
+	/**
+	 *  
+	 */
+	@TableId(type = IdType.AUTO)
+	@ExcelIgnore
+	private Long id;	
+
+	/**
+	 * 客户ID 
+	 */
+	@ExcelIgnore
+	private String customerId;
+
+	/**
+	 * 企业名称 
+	 */
+	@ExcelProperty(index = 0,value = "企业名称")
+	private String customerName;	
+
+	/**
+	 * 退款金额 
+	 */
+	@ExcelProperty(index = 1,value = "退款金额")
+	private BigDecimal refundMoney;
+
+	/**
+	 * 退款操作人 
+	 */
+	@ExcelProperty(index = 2,value = "退款人")
+	private String refundBy;	
+
+	/**
+	 * 退款时间 
+	 */
+	@ExcelProperty(index = 3,value = "退款时间")
+	private Date refundTime;
+
+	/**
+	 * 退款类型 
+	 */
+	@ExcelIgnore
+	private int refundType=3;
+	@ExcelProperty(index = 4,value = "退款原因")
+	private String refundDesc;
+
+	/**
+	 * 退款号 
+	 */
+	@ExcelProperty(index = 5,value = "业务单号")
+	private String refundNo;	
+
+	/**
+	 * 对应扣款记录ID 
+	 */
+	@ExcelIgnore
+	private String deductionRecordId;	
+
+	/**
+	 * 业务ID 
+	 */
+	@ExcelIgnore
+	private String businessId;	
+
+	/**
+	 * 业务项ID 
+	 */
+	@ExcelIgnore
+	private String businessItemId;
+	@ExcelProperty(index = 6,value = "业务类型")
+	private String itemTypeName;
+	@ExcelProperty(index = 7,value = "车型")
+	private String itemName;
+	@ExcelProperty(index = 8,value = "车牌号")
+	private String carNo;
+	@ExcelIgnore
+	private int type=3;
+
+
+
+
+
+	
+
+
+}

+ 51 - 0
sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecordController.java

@@ -0,0 +1,51 @@
+package com.pj.project.tb_refund_record;
+
+import java.util.List;
+
+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.*;
+
+import com.pj.utils.sg.*;
+import com.pj.project4sp.SP;
+
+import com.pj.current.satoken.StpUserUtil;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+
+
+/**
+ * Controller: tb_refund_record -- 退款记录表
+ * @author qzy 
+ */
+@RestController
+@RequestMapping("/TbRefundRecord/")
+public class TbRefundRecordController {
+
+	/** 底层 Service 对象 */
+	@Autowired
+	TbRefundRecordService tbRefundRecordService;
+
+
+	/** 查集合 - 根据条件(参数为空时代表忽略指定条件) */  
+	@RequestMapping("getList")
+	public AjaxJson getList() { 
+		SoMap so = SoMap.getRequestSoMap();
+		List<TbRefundRecord> list = tbRefundRecordService.getList(so.startPage());
+		return AjaxJson.getPageData(so.getDataCount(), list);
+	}
+	@RequestMapping("export")
+	@SaCheckPermission(value = TbRefundRecord.PERMISSION_CODE_EXPORT)
+	public AjaxJson export() {
+		SoMap so = SoMap.getRequestSoMap();
+		String url = tbRefundRecordService.export(so);
+		return AjaxJson.getSuccessData(url);
+	}
+	
+
+	
+	
+	
+	
+
+}

+ 24 - 0
sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecordMapper.java

@@ -0,0 +1,24 @@
+package com.pj.project.tb_refund_record;
+
+import java.util.List;
+
+import org.apache.ibatis.annotations.Mapper;
+
+import com.pj.utils.so.*;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * Mapper: tb_refund_record -- 退款记录表
+ * @author qzy 
+ */
+
+@Mapper
+@Repository
+public interface TbRefundRecordMapper extends BaseMapper <TbRefundRecord> {
+
+
+	List<TbRefundRecord> getList(SoMap so);
+
+
+}

+ 53 - 0
sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecordMapper.xml

@@ -0,0 +1,53 @@
+<?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_refund_record.TbRefundRecordMapper">
+
+
+	<!-- 公共查询sql片段 -->
+	<sql id="select_sql">
+		select * 
+		from tb_refund_record 
+	</sql>
+	<!-- 查集合 - 根据条件(参数为空时代表忽略指定条件) [G] -->
+	<select id="getList" resultType="com.pj.project.tb_refund_record.TbRefundRecord">
+		<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("customerName") '> and customer_name like concat('%',#{customerName},'%')  </if>
+			<if test=' this.has("refundMoney") '> and refund_money = #{refundMoney} </if>
+			<if test=' this.has("refundBy") '> and refund_by = #{refundBy} </if>
+			<if test=' this.has("refundTime") '> and date_format(refund_time,'%Y-%m-%d') = #{refundTime} </if>
+			<if test=' this.has("refundType") '> and refund_type = #{refundType} </if>
+			<if test=' this.has("refundNo") '> and refund_no = #{refundNo} </if>
+			<if test=' this.has("deductionRecordId") '> and deduction_record_id = #{deductionRecordId} </if>
+			<if test=' this.has("businessId") '> and business_id = #{businessId} </if>
+			<if test=' this.has("businessIditemId") '> and business_iditem_id = #{businessIditemId} </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'> refund_money desc </when>
+			<when test='sortType == 5'> refund_by desc </when>
+			<when test='sortType == 6'> refund_time desc </when>
+			<when test='sortType == 7'> refund_type desc </when>
+			<when test='sortType == 8'> refund_no desc </when>
+			<when test='sortType == 9'> deduction_record_id desc </when>
+			<when test='sortType == 10'> business_id desc </when>
+			<when test='sortType == 11'> business_iditem_id desc </when>
+			<otherwise> id desc </otherwise>
+		</choose>
+	</select>
+	
+	
+	
+	
+	
+	
+	
+	
+	
+
+</mapper>

+ 82 - 0
sp-server/src/main/java/com/pj/project/tb_refund_record/TbRefundRecordService.java

@@ -0,0 +1,82 @@
+package com.pj.project.tb_refund_record;
+
+import java.io.File;
+import java.util.List;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.RandomUtil;
+import com.alibaba.excel.EasyExcel;
+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.current.config.SystemObject;
+import com.pj.project.tb_charge_record.TbChargeRecord;
+import com.pj.project.tb_deduction_record.TbDeductionRecord;
+import com.pj.project.tb_pay_record.TbPayRecord;
+import com.pj.project.tb_pay_record.TbPayRecordMapper;
+import com.pj.project4sp.uploadfile.UploadConfig;
+import com.pj.utils.so.SoMap;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.pj.utils.sg.*;
+
+import javax.annotation.Resource;
+
+/**
+ * Service: tb_refund_record -- 退款记录表
+ *
+ * @author qzy
+ */
+@Service
+public class TbRefundRecordService extends ServiceImpl<TbRefundRecordMapper, TbRefundRecord> implements IService<TbRefundRecord> {
+
+    /**
+     * 底层 Mapper 对象
+     */
+    @Autowired
+    TbRefundRecordMapper tbRefundRecordMapper;
+
+    @Resource
+    private UploadConfig uploadConfig;
+
+    /**
+     * 查集合 - 根据条件(参数为空时代表忽略指定条件)
+     */
+    List<TbRefundRecord> getList(SoMap so) {
+        return tbRefundRecordMapper.getList(so);
+    }
+
+    /**
+     * 获取某个时间点前的异常单退款
+     * @param eDay
+     * @return
+     */
+    public List<TbRefundRecord>getErrorOrderBeforeList(String eDay){
+        QueryWrapper<TbRefundRecord> ew = new QueryWrapper<>();
+        ew.le("date_format(refund_time,'%Y-%m-%d')", eDay);
+        return list(ew);
+    }
+
+
+    /**
+     * 导出
+     * @param so
+     * @return
+     */
+    public String export(SoMap so) {
+        List<TbRefundRecord> list = tbRefundRecordMapper.getList(so);
+        String flieTypeFolder = "/export/";
+        String currDateFolder = DateUtil.today();
+        String fileName = "record-" + RandomUtil.randomNumbers(6) + ".xlsx";
+        String fileFolder = new File(uploadConfig.rootFolder).getAbsolutePath() +
+                uploadConfig.httpPrefix + flieTypeFolder + currDateFolder + "/";
+        if (!FileUtil.exist(fileFolder)) {
+            FileUtil.mkdir(fileFolder);
+        }
+        EasyExcel.write(fileFolder + fileName, TbRefundRecord.class).sheet("退款记录导出")
+                .doWrite(() ->list);
+        return SystemObject.config.getDomain() + uploadConfig.httpPrefix + flieTypeFolder + currDateFolder + "/" + fileName;
+    }
+}

+ 2 - 0
sp-server/src/main/resources/application-dev.yml

@@ -52,6 +52,8 @@ spring:
         manager-money: "1" #场地管理费 1--->越南车交 2 标识中国车交
         manager-word: "越南车"   #费项
         manager-item-type: "干杂货人工装卸,汽车吊"
+        un-load-item: "装卸业务管理费"  #装卸管理费
+        every-car-pay: "人工、机械装卸车辆"  #每辆车都收费
 part-config:
     base-price: 30 #基础费用
     extra-price: 10 #过夜额外收费