瀏覽代碼

统计报表调整

yangzj 2 年之前
父節點
當前提交
02496f4aa5
共有 46 個文件被更改,包括 3628 次插入1685 次删除
  1. 5 1
      common/apiurl.js
  2. 8 0
      common/http.api.js
  3. 1 1
      components/tableRanking.vue
  4. 18 0
      pages.json
  5. 6 3
      pages/dataOverview/operationalAnalysis/operationalAnalysis.scss
  6. 169 0
      pages/dataOverview/statisticalReport copy/components/arrearsReport.vue
  7. 129 0
      pages/dataOverview/statisticalReport copy/components/checkWorkAttendance.vue
  8. 106 0
      pages/dataOverview/statisticalReport copy/components/parkingReallyIncome.vue
  9. 147 0
      pages/dataOverview/statisticalReport copy/components/reallyReceivable.vue
  10. 68 0
      pages/dataOverview/statisticalReport copy/components/report.scss
  11. 144 0
      pages/dataOverview/statisticalReport copy/components/revenueReport.vue
  12. 118 0
      pages/dataOverview/statisticalReport copy/components/sectionBerth.vue
  13. 120 0
      pages/dataOverview/statisticalReport copy/components/tollCollectorPerformance.vue
  14. 49 0
      pages/dataOverview/statisticalReport copy/statisticalReport.scss
  15. 328 0
      pages/dataOverview/statisticalReport copy/statisticalReport.vue
  16. 54 49
      pages/dataOverview/statisticalReport/statisticalReport.scss
  17. 167 317
      pages/dataOverview/statisticalReport/statisticalReport.vue
  18. 0 76
      pages/operationalAnalysis/parkModel/components/revenueRanking.vue
  19. 0 185
      pages/operationalAnalysis/parkModel/components/sectionAnalysis.vue
  20. 0 180
      pages/operationalAnalysis/parkModel/components/sourceOfPayment.vue
  21. 0 149
      pages/operationalAnalysis/parkModel/components/tollCollectorPerformance.vue
  22. 0 152
      pages/operationalAnalysis/parkModel/components/trafficFlow.vue
  23. 5 5
      pages/operationalAnalysis/parkModel/index.vue
  24. 0 76
      pages/operationalAnalysis/roadModel/components/revenueRanking.vue
  25. 0 180
      pages/operationalAnalysis/roadModel/components/sourceOfPayment.vue
  26. 0 149
      pages/operationalAnalysis/roadModel/components/tollCollectorPerformance.vue
  27. 0 152
      pages/operationalAnalysis/roadModel/components/trafficFlow.vue
  28. 120 0
      pages/statisticalReport/parkModel/components/arrearsReport.vue
  29. 114 0
      pages/statisticalReport/parkModel/components/parkingReallyIncome.vue
  30. 113 0
      pages/statisticalReport/parkModel/components/reallyReceivable.vue
  31. 68 0
      pages/statisticalReport/parkModel/components/report.scss
  32. 144 0
      pages/statisticalReport/parkModel/components/revenueReport.vue
  33. 281 0
      pages/statisticalReport/parkModel/index.vue
  34. 120 0
      pages/statisticalReport/roadModel/components/arrearsReport.vue
  35. 113 0
      pages/statisticalReport/roadModel/components/reallyReceivable.vue
  36. 141 0
      pages/statisticalReport/roadModel/components/recoveryReport.vue
  37. 68 0
      pages/statisticalReport/roadModel/components/report.scss
  38. 144 0
      pages/statisticalReport/roadModel/components/revenueReport.vue
  39. 118 0
      pages/statisticalReport/roadModel/components/sectionBerth.vue
  40. 286 0
      pages/statisticalReport/roadModel/index.vue
  41. 49 0
      pages/statisticalReport/styles/report.scss
  42. 23 10
      static/icons/operationalAnalysisIcons/parking-lot-analysis-icon.svg
  43. 21 0
      static/icons/statisticalReportIcons/parking-lot-income-icon.svg
  44. 21 0
      static/icons/statisticalReportIcons/really-receivable-icon.svg
  45. 21 0
      static/icons/statisticalReportIcons/recovery-report-icon.svg
  46. 21 0
      static/icons/statisticalReportIcons/section-berth-icon.svg

+ 5 - 1
common/apiurl.js

@@ -86,7 +86,11 @@ export const apiurl = {
 		// 获取停车场实收统计接口
 		getParkingReallyIncomeUrl: '/admin/reportparking/realamt',
 		// 获取停车场实收统计总数据接口
-		getParkingReallyIncomeTotalUrl: '/admin/reportparking/realamttotal'
+		getParkingReallyIncomeTotalUrl: '/admin/reportparking/realamttotal',
+		// 获取追缴统计接口
+		getRecoveryReportUrl: '/admin/report/pursue',
+		// 获取追缴统计汇总接口
+		getRecoverySumReportUrl: '/admin/report/pursuesum'
 	},
 	// 收费员业绩管理模块接口
 	tollCollectorPerformance: {

+ 8 - 0
common/http.api.js

@@ -177,6 +177,14 @@ const install = (Vue, vm) => {
 		// 获取停车场实收统计总数据
 		getParkingReallyIncomeTotalApi: (params = {}) => vm.$u.http.get(apiurl.statisticalReport.getParkingReallyIncomeTotalUrl, {
 			params
+		}),
+		// 获取追缴统计
+		getRecoveryReportApi: (params = {}) => vm.$u.http.get(apiurl.statisticalReport.getRecoveryReportUrl, {
+			params
+		}),
+		// 获取追缴统计总和
+		getRecoverySumReportApi: (params = {}) => vm.$u.http.get(apiurl.statisticalReport.getRecoverySumReportUrl, {
+			params
 		})
 	};
 	// 收费员业绩管理模块接口

+ 1 - 1
components/tableRanking.vue

@@ -14,7 +14,7 @@
 					<!-- 表格数据行 -->
 					<uni-tr v-for="(item, index) in tableData.list" :key="index">
 						<uni-td class="table-box-td" align="center" v-for="(field, index) in tableTh" :key="index">
-							{{ item[field.key] }}</uni-td>
+							{{ item[field.key] || item[field.key] === 0 ? item[field.key] : '-' }}</uni-td>
 					</uni-tr>
 				</uni-table>
 			</view>

+ 18 - 0
pages.json

@@ -194,6 +194,24 @@
         "navigationBarBackgroundColor": "#1767F2",
         "navigationBarTextStyle": "white"
       }
+    },
+    {
+      "path": "pages/statisticalReport/roadModel/index",
+      "style": {
+        "navigationBarTitleText": "路段统计",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#1767F2",
+        "navigationBarTextStyle": "white"
+      }
+    },
+    {
+      "path": "pages/statisticalReport/parkModel/index",
+      "style": {
+        "navigationBarTitleText": "停车场统计",
+        "enablePullDownRefresh": false,
+        "navigationBarBackgroundColor": "#1767F2",
+        "navigationBarTextStyle": "white"
+      }
     }
   ],
   "globalStyle": {

+ 6 - 3
pages/dataOverview/operationalAnalysis/operationalAnalysis.scss

@@ -41,9 +41,12 @@
           margin: 0 auto 16px;
         }
         .name {
-          white-space: nowrap;
-          overflow: hidden;
-          text-overflow: ellipsis;
+          // white-space: nowrap;
+          // overflow: hidden;
+          // text-overflow: ellipsis;
+          color: #393939;
+          font-family: PingFangSC-Regular, PingFang SC;
+					font-size: 20px;
         }
       }
     }

+ 169 - 0
pages/dataOverview/statisticalReport copy/components/arrearsReport.vue

@@ -0,0 +1,169 @@
+<!-- 欠费统计 -->
+<template>
+	<view class="container">
+		<view class="tab">
+			<u-tabs
+				:list="tabList"
+				lineColor="#fff"
+				:activeStyle="{
+					color: '#fff',
+					fontWeight: 'bold',
+					transform: 'scale(1.05)'
+				}"
+				:inactiveStyle="{
+					color: '#000',
+					transform: 'scale(1)'
+				}"
+				@click="tabClick">
+			</u-tabs>
+		</view>
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData"
+					@pageChange="pageChange" />
+			</view>
+		</view>
+		<view class="total">
+			<view>
+				欠费次数<text>{{ totalData.oweCount || 0 }}</text>次,欠费金额<text>{{ totalData.amtOwe || 0 }}</text>元
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [
+						{ field: '车牌号', key: 'vehicleNo', width: 100 },
+						{ field: '车主姓名', key: 'name', width: 100 },
+						{ field: '联系方式', key: 'mobile', width: 100 },
+						{ field: '欠费次数(次)', width: 80, key: 'oweCount' },
+						{ field: '欠费金额(元)', width: 80, key: 'amtOwe' }
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				loading: false,
+				totalData: {},
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				tabCurName: 'road',
+				currentDate: [],
+				beginTime: undefined,
+				endTime: undefined,
+				tabList: [
+					{ name: '路段', value: 'road' },
+					{ name: '停车场', value: 'parking' }
+				]
+			}
+		},
+		methods: {
+			tabClick(item) {
+				this.tabCurName = item.value
+				this.tableData.current = 1
+				if (this.tabCurName === 'road') {
+					this.getArreasReportTotal()
+					this.getArreasReportList()
+				} else {
+					this.getParkingArreasReportTotal()
+					this.getParkingArreasReportList()
+				}
+			},
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				if (this.tabCurName === 'road') {
+					this.getArreasReportTotal()
+					this.getArreasReportList()
+				} else {
+					this.getParkingArreasReportTotal()
+					this.getParkingArreasReportList()
+				}
+			},
+			getArreasReportTotal() {
+				uni.$u.api.statisticalReportApi.getArrearsReportTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.totalData = res.data
+					}
+				})
+			},
+			getParkingArreasReportTotal() {
+				uni.$u.api.statisticalReportApi.getParkingArrearsReportTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.totalData = res.data
+					}
+				})
+			},
+			getArreasReportList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getArrearsReportListApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime,
+					pageNum: this.tableData.current,
+					pageSize: 10
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			getParkingArreasReportList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getParkingArrearsReportListApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime,
+					pageNum: this.tableData.current,
+					pageSize: 10
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			pageChange(cur) {
+				this.tableData.current = cur
+				if (this.tabCurName === 'road') {
+					this.getArreasReportList()
+				} else {
+					this.getParkingArreasReportList()
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+	.tab {
+		margin-bottom: 10px;
+	}
+</style>
+

+ 129 - 0
pages/dataOverview/statisticalReport copy/components/checkWorkAttendance.vue

@@ -0,0 +1,129 @@
+<!-- 考勤统计 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-search">
+				<view class="table-search-item">
+					<u--input class="input" placeholder="请输入工号" v-model="payeeNo"></u--input>
+				</view>
+				<view class="table-search-item">
+					<u--input class="input" placeholder="请输入姓名" v-model="payeeName"></u--input>
+				</view>
+				<view class="table-search-item">
+					<u-button class="btn" text="确认"
+						color="linear-gradient(157deg, #FECF4C 4%, #FECF4B 5%, #FCA225 100%)" :loading="loading" @click="confirm"></u-button>
+				</view>
+			</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData"
+					@pageChange="pageChange" />
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '工号',
+							width: 80,
+							key: 'payeeNo'
+						},
+						{
+							field: '姓名',
+							width: 90,
+							key: 'payeeName'
+						},
+						{
+							field: '实出勤(天)',
+							width: 70,
+							key: 'realDays'
+						},
+						{
+							field: '缺勤(天)',
+							width: 70,
+							key: 'missDays'
+						},
+						{
+							field: '缺卡(次)',
+							width: 70,
+							key: 'missPunchCount'
+						},
+						{
+							field: '早退(次)',
+							width: 70,
+							key: 'leavePunchCount'
+						},
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				loading: false,
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				currentDate: [],
+				beginTime: undefined,
+				endTime: undefined,
+				payeeNo: undefined,
+				payeeName: undefined
+			}
+		},
+		methods: {
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				} else {
+					this.beginTime = undefined
+					this.endTime = undefined
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				this.getPunchList()
+			},
+			getPunchList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getPunchListApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime,
+					payeeNo: this.payeeNo,
+					payeeName: this.payeeName,
+					pageNum: this.tableData.current,
+					pageSize: 10
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			pageChange(cur) {
+				this.tableData.current = cur
+				this.getPunchList()
+			},
+			confirm() {
+				this.tableData.current = 1
+				this.getPunchList()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 106 - 0
pages/dataOverview/statisticalReport copy/components/parkingReallyIncome.vue

@@ -0,0 +1,106 @@
+<!-- 停车场实收统计 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData"
+					@pageChange="pageChange" />
+			</view>
+		</view>
+		<view class="total">
+			<view>
+				停车数量<text>{{ totalData.vehicleCount || 0 }}</text>辆,实收金额<text>{{ totalData.realAmount || 0 }}</text>元
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '停车场名称',
+							width: 120,
+							key: 'parkingName'
+						},
+						{
+							field: '停车数量(次)',
+							width: 120,
+							key: 'vehicleCount'
+						},
+						{
+							field: '实收金额(元)',
+							width: 80,
+							key: 'realAmount'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				loading: false,
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				totalData: {},
+				currentDate: [],
+				beginTime: undefined,
+				endTime: undefined
+			}
+		},
+		methods: {
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				this.getList();
+				this.getTotal();
+			},
+			getList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getParkingReallyIncomeApi({
+					pageNum: this.tableData.current,
+					pageSize: 10,
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			getTotal() {
+				uni.$u.api.statisticalReportApi.getParkingReallyIncomeTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						const { realAmount, vehicleCount } = res.data
+						this.totalData.realAmount = realAmount
+						this.totalData.vehicleCount = vehicleCount
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 147 - 0
pages/dataOverview/statisticalReport copy/components/reallyReceivable.vue

@@ -0,0 +1,147 @@
+<!-- 应收实收分析 -->
+<template>
+	<view class="container">
+		<view class="tab">
+			<u-tabs
+				:list="tabList"
+				lineColor="#fff"
+				:activeStyle="{
+					color: '#fff',
+					fontWeight: 'bold',
+					transform: 'scale(1.05)'
+				}"
+				:inactiveStyle="{
+					color: '#000',
+					transform: 'scale(1)'
+				}"
+				@click="tabClick">
+			</u-tabs>
+		</view>
+		<view class="table">
+			<view class="table-date" v-if="params.queryDate">{{ params.title }}</view>
+			<view class="table-box">
+				<uni-table emptyText="暂无更多数据" :loading="loading">
+					<!-- 表头行 -->
+					<uni-tr>
+						<uni-th class="table-box-th" align="center" v-for="(item, index) in tableTh" :key="index"
+							:width="item.width || ''">{{ item.field }}
+						</uni-th>
+					</uni-tr>
+					<!-- 表格数据行 -->
+					<uni-tr v-for="(item, index) in tableData.list" :key="index">
+						<uni-td class="table-box-td" align="center" v-for="(field, fIndex) in tableTh" :key="fIndex">
+							{{ item[field.key] }}</uni-td>
+					</uni-tr>
+				</uni-table>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '时间',
+							width: 120,
+							key: 'statisTime'
+						},
+						{
+							field: '应收金额(元)',
+							width: 80,
+							key: 'payAmount'
+						},
+						{
+							field: '实收金额(元)',
+							width: 80,
+							key: 'realAmount'
+						},
+						{
+							field: '逃费金额(元)',
+							width: 80,
+							key: 'runawayAmount'
+						},
+						{
+							field: `“一分钱停车”减免`,
+							width: 120,
+							key: 'oneAmount'
+						},
+						{
+							field: '“八折停车”减免',
+							width: 110,
+							key: 'eightAmount'
+						},
+						{
+							field: '欠费金额(元)',
+							width: 80,
+							key: 'amtOwe'
+						},
+						{
+							field: '退款金额(元)',
+							width: 80,
+							key: 'backAmount'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				currentDate: [],
+				tableData: {
+					list: []
+				},
+				params: {
+					reportType: 2,
+					queryDate: '',
+					title: ''
+				},
+				loading: false,
+				tabCurName: 'road',
+				tabList: [
+					{ name: '路段', value: 'road' },
+					{ name: '停车场', value: 'parking' }
+				]
+			}
+		},
+		methods: {
+			tabClick(item) {
+				this.tabCurName = item.value
+				if (this.tabCurName === 'road') {
+					this.getReallyReceivableList()
+				} else {
+					this.getParkingReallyReceivableList()
+				}
+			},
+			getData(obj) {
+				this.params = obj
+				this.getReallyReceivableList()
+			},
+			getReallyReceivableList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getReallyReceivableListApi(this.params).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.data.itemList
+					}
+					this.loading = false
+				})
+			},
+			getParkingReallyReceivableList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getParkingReallyReceivableListApi(this.params).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.data.itemList
+					}
+					this.loading = false
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 68 - 0
pages/dataOverview/statisticalReport copy/components/report.scss

@@ -0,0 +1,68 @@
+.table {
+	padding: 19px 15px;
+	background-color: #fff;
+	border-radius: 5px;
+	font-family: PingFangSC-Regular, PingFang SC;
+	&-title {
+		text-align: center;
+		margin-bottom: 10px;
+	}
+	&-date {
+		margin-bottom: 10px;
+		font-size: 14px;
+		color: #434343;
+		text-align: center;
+	}
+	&-search {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 10px;
+		&-item {
+			width: 38%;
+			margin-right: 2%;
+			.input {
+				height: 29px;
+				padding: 0 9px!important;
+			}
+			&:last-child {
+				width: 53px;
+				margin-right: 0;
+				.btn {
+					width: 53px;
+					height: 31px;
+				}
+			}
+		}
+	}
+	&-box {
+		&-th {
+			border-bottom: none;
+			background-color: #EDF3FF;
+			font-size: 12px;
+			color: #434343;
+		}
+
+		&-td {
+			font-size: 12px;
+			color: #434343;
+			word-wrap: break-word;
+		}
+	}
+
+	&-pagination {
+		width: 130px;
+		margin: 20px auto 0;
+	}
+}
+.total {
+	color: #CADDFC;
+	margin-top: 24px;
+	text-align: center;
+	font-size: 14px;
+	line-height: 17px;
+	text {
+		color: #fff;
+		padding: 0 5px;
+	}
+}

+ 144 - 0
pages/dataOverview/statisticalReport copy/components/revenueReport.vue

@@ -0,0 +1,144 @@
+<!-- 营收统计 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData"
+					@pageChange="pageChange" />
+			</view>
+		</view>
+		<view class="total">
+			<view>
+				车辆<text>{{ totalData.vehicleCount || 0 }}</text>辆,应收金额<text>{{ totalData.payAmount || 0 }}</text>元,实收金额<text>{{ totalData.realAmount || 0 }}</text>元,
+				欠费金额<text>{{ totalData.amtOwe || 0 }}</text>元,其中贵州银行快捷支付<text>{{ totalData.quickAmt || 0 }}</text>元,贵州银行聚合支付<text>{{ totalData.unionAmt || 0 }}</text>元,微信支付<text>{{ totalData.wechatAmt || 0 }}</text>元,无感支付<text>{{ totalData.unconsAmt || 0 }}</text>元,现金支付<text>{{ totalData.cashAmt || 0 }}</text>元
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '停车场/路段',
+							width: 120,
+							key: 'roadName'
+						},
+						{
+							field: '车辆(辆)',
+							width: 80,
+							key: 'vehicleCount'
+						},
+						{
+							field: '应收金额(元)',
+							width: 80,
+							key: 'payAmount'
+						},
+						{
+							field: '实收金额(次)',
+							width: 80,
+							key: 'realAmount'
+						},
+						{
+							field: '欠费金额(元)',
+							width: 80,
+							key: 'amtOwe'
+						},
+						{
+							field: '贵州银行快捷支付(元)',
+							width: 150,
+							key: 'quickAmt'
+						},
+						{
+							field: '贵州银行聚合支付(元)',
+							width: 150,
+							key: 'unionAmt'
+						},
+						{
+							field: '微信(元)',
+							width: 80,
+							key: 'wechatAmt'
+						},
+						{
+							field: '无感(元)',
+							width: 80,
+							key: 'unconsAmt'
+						},
+						{
+							field: '现金(元)',
+							width: 80,
+							key: 'cashAmt'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				loading: false,
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				totalData: {},
+				currentDate: [],
+				beginTime: undefined,
+				endTime: undefined
+			}
+		},
+		methods: {
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				this.getIncomeTotal()
+				this.getIncomeList()
+			},
+			getIncomeTotal() {
+				uni.$u.api.statisticalReportApi.getIncomeTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.totalData = res.data
+					}
+				})
+			},
+			getIncomeList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getIncomeListApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime,
+					pageNum: this.tableData.current,
+					pageSize: 10
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			pageChange(cur) {
+				this.tableData.current = cur
+				this.getIncomeList()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 118 - 0
pages/dataOverview/statisticalReport copy/components/sectionBerth.vue

@@ -0,0 +1,118 @@
+<!-- 路段泊位统计 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData"
+					@pageChange="pageChange" />
+			</view>
+		</view>
+		<view class="total">
+			<view>
+				停车数量<text>{{ totalData.vehicleCount || 0 }}</text>辆,实收金额<text>{{ totalData.realAmount || 0 }}</text>元
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '路段名称',
+							key: 'roadName'
+						},
+						{
+							field: '所属泊位',
+							key: 'spaceName'
+						},
+						{
+							field: '停车数量(次)',
+							width: 80,
+							key: 'vehicleCount'
+						},
+						{
+							field: '实收金额(元)',
+							width: 80,
+							key: 'realAmount'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				beginTime: '',
+				endTime: '',
+				totalData: {},
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				currentDate: [],
+				loading: false
+			}
+		},
+		methods: {
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				} else {
+					this.beginTime = undefined
+					this.endTime = undefined
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				this.getRoadSpaceTotal()
+				this.getRoadSpaceList()
+			},
+			getRoadSpaceTotal() {
+				uni.$u.api.statisticalReportApi.getRoadSpaceTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.totalData = res.data
+					}
+				})
+			},
+			getRoadSpaceList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getRoadSpaceListApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime,
+					pageNum: this.tableData.current,
+					pageSize: 10
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows;
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			/**
+			 * 分页切换
+			 * @param { Number } cur
+			 */
+			pageChange(cur) {
+				this.tableData.current = cur
+				this.getRoadSpaceList()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 120 - 0
pages/dataOverview/statisticalReport copy/components/tollCollectorPerformance.vue

@@ -0,0 +1,120 @@
+<!-- 收费员业绩统计 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData" @pageChange="pageChange"/>
+			</view>
+		</view>
+		<view class="total">
+			<view>
+				应收金额<text>{{ totalData.payAmount || 0 }}</text>元,实收金额<text>{{ totalData.realAmount || 0 }}</text>元
+			</view>
+			<view>
+				现金收入<text>{{ totalData.cashAmt || 0 }}</text>元,非现金收入<text>{{ totalData.otherAmt || 0 }}</text>元
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '工号',
+							key: 'payeeNo'
+						},
+						{
+							field: '姓名',
+							key: 'payeeName'
+						},
+						{
+							field: '所属路段',
+							key: 'roadName'
+						},
+						{
+							field: '应收金额(元)',
+							key: 'payAmount',
+							width: 80
+						},
+						{
+							field: '实收金额(元)',
+							key: 'realAmount',
+							width: 80
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				totalData: {},
+				beginTime: undefined,
+				endTime: undefined,
+				loading: false,
+				currentDate: []
+			}
+		},
+		methods: {
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				} else {
+					this.beginTime = undefined
+					this.endTime = undefined
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				this.getTollCollectorAchieveTotal()
+				this.getTollCollectorAchieveList()
+			},
+			getTollCollectorAchieveTotal() {
+				uni.$u.api.statisticalReportApi.getTollCollectorAchieveTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.totalData = res.data
+					}
+				})
+			},
+			getTollCollectorAchieveList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getTollCollectorAchieveListApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime,
+					pageNum: this.tableData.current,
+					pageSize: 10
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			pageChange(cur) {
+				this.tableData.current = cur
+				this.getTollCollectorAchieveList()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 49 - 0
pages/dataOverview/statisticalReport copy/statisticalReport.scss

@@ -0,0 +1,49 @@
+.report {
+	padding: 15px;
+	font-family: PingFangSC-Regular, PingFang SC;
+	&-header {
+		background-color: #fff;
+		border-radius: 5px;
+		padding: 15px;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 10px;
+		&-left {
+			display: flex;
+			align-items: center;
+			text {
+				margin-left: 5px;
+				color: #434343;
+				font-size: 15px;
+			}
+		}
+		&-right {
+			.tab {
+				display: flex;
+				border: solid 1px #1767F2;
+				&-item {
+					width: 40px;
+					height: 28px;
+					line-height: 28px;
+					text-align: center;
+					border-right: solid 1px #1767F2;
+					color: #1767F2;
+					font-size: 16px;
+					&:last-child {
+						border-right: none;
+					}
+				}
+				.active {
+					background-color: #1767f2;
+					color: #fff;
+				}
+			}
+		}
+	}
+	&-content {
+		// padding: 19px 15px;
+		// background-color: #fff;
+		// border-radius: 5px;
+	}
+}

+ 328 - 0
pages/dataOverview/statisticalReport copy/statisticalReport.vue

@@ -0,0 +1,328 @@
+<!-- 统计报表 -->
+<template>
+	<view class="report">
+		<view class="report-header">
+			<view class="report-header-left" @click="typePicker = true">
+				<u-icon name="arrow-down" color="#000" size="15"></u-icon>
+				<text>{{ currentType.text }}</text>
+			</view>
+			<view class="report-header-right" v-if="currentType.value === 6">
+				<view class="tab">
+					<view class="tab-item" v-for="(item, index) in tabList" :key="index"
+						:class="{'active': tabCur === item.value}" @click="tabClick(item)">{{ item.label }}</view>
+				</view>
+			</view>
+			<view class="report-header-right" v-else>
+				<uni-datetime-picker v-model="curDate" type="daterange" @change="dateChange">
+					<u--text text="日期查询" color="#1767F2"></u--text>
+				</uni-datetime-picker>
+			</view>
+		</view>
+		<view class="report-content">
+			<template v-if="currentType.value === 1">
+				<TollCollectorPerformance ref="tollCollectorPerformance"/>
+			</template>
+			<template v-else-if="currentType.value === 2">
+				<SectionBerth ref="sectionBerth"/>
+			</template>
+			<template v-else-if="currentType.value === 3">
+				<ParkingReallyIncome ref="parkingReallyIncome"/>
+			</template>
+			<template v-else-if="currentType.value === 4">
+				<ArrearsReport ref="arrearsReport" />
+			</template>
+			<template v-else-if="currentType.value === 5">
+				<RevenueReport ref="revenueReport" />
+			</template>
+			<template v-else-if="currentType.value === 6">
+				<ReallyReceivable ref="reallyReceivable"/>
+			</template>
+			<template v-else-if="currentType.value === 7">
+				<CheckWorkAttendance ref="checkWorkAttendance" />
+			</template>
+		</view>
+		<!-- 报表类型 -->
+		<u-picker :show="typePicker" :columns="typeList" @confirm="typeConfirm" @cancel="typePicker = false"></u-picker>
+		<!-- 年 -->
+		<u-picker :show="yearPicker" :columns="yearList" :defaultIndex="defaultYear" @confirm="yearConfirm"
+			@cancel="yearPicker = false"></u-picker>
+		<!-- 月 -->
+		<u-picker :show="monthPicker" :columns="monthList" :defaultIndex="defaultMonth" @confirm="monthConfirm"
+			@cancel="monthPicker = false"></u-picker>
+		<!-- 日 -->
+		<u-picker :show="dayPicker" :columns="dayList" :defaultIndex="defaultDay" @confirm="dayConfirm"
+			@cancel="dayPicker = false"></u-picker>
+	</view>
+</template>
+
+<script>
+	import TollCollectorPerformance from './components/tollCollectorPerformance.vue'
+	import SectionBerth from './components/sectionBerth.vue'
+	import ParkingReallyIncome from './components/parkingReallyIncome.vue'
+	import ArrearsReport from './components/arrearsReport.vue'
+	import RevenueReport from './components/revenueReport.vue'
+	import ReallyReceivable from './components/reallyReceivable.vue'
+	import CheckWorkAttendance from './components/checkWorkAttendance.vue'
+	export default {
+		components: {
+			TollCollectorPerformance,
+			SectionBerth,
+			ParkingReallyIncome,
+			ArrearsReport,
+			RevenueReport,
+			ReallyReceivable,
+			CheckWorkAttendance
+		},
+		data() {
+			return {
+				tabList: [{
+						label: '年',
+						value: 2
+					},
+					{
+						label: '月',
+						value: 1
+					},
+					{
+						label: '日',
+						value: 0
+					}
+				],
+				currentType: {},
+				tabCur: 2,
+				typePicker: false,
+				typeList: [[
+					// {
+					// 	text: '收费员业绩统计',
+					// 	value: 1,
+					// 	key: 'tollCollectorPerformance'
+					// },
+					{
+						text: '路段泊位统计',
+						value: 2,
+						key: 'sectionBerth'
+					},
+					{
+						text: '停车场实收统计',
+						value: 3,
+						key: 'parkingReallyIncome'
+					},
+					{
+						text: '欠费统计',
+						value: 4,
+						key: 'arrearsReport'
+					},
+					{
+						text: '营收统计',
+						value: 5,
+						key: 'revenueReport'
+					},
+					{
+						text: '应收实收分析',
+						value: 6,
+						key: 'reallyReceivable'
+					},
+					{
+						text: '考勤统计',
+						value: 7,
+						key: 'checkWorkAttendance'
+					}
+				]],
+				// 日期
+				curDate: [],
+				// 参数
+				params: {
+					reportType: 2,
+					queryDate: '',
+					title: ''
+				},
+				// 年
+				yearPicker: false,
+				yearList: this.getYearList(),
+				defaultYear: [4],
+				currentYear: '',
+				yearObj: {},
+				// 月
+				monthPicker: false,
+				monthList: this.getMonthList(),
+				defaultMonth: [],
+				currentMonth: '01',
+				monthObj: {},
+				// 日
+				dayPicker: false,
+				dayList: this.getDayList(),
+				defaultDay: [],
+				currentDay: '01',
+				dayObj: {}
+			}
+		},
+		onShow() {
+			this.currentType = this.typeList[0][0]
+			if (this.currentType.value === 5 || this.currentType.value === 7) {
+				let today = uni.$u.timeFormat(new Date(), 'yyyy-mm-dd')
+				this.curDate = [today, today]
+			} else {
+				this.curDate = []
+			}
+			setTimeout(() => {
+				if (this.currentType.value === 6) {
+					this.currentYear = this.yearList[0][4].value
+					this.yearObj = this.yearList[0][4]
+					this.params.title = this.yearList[0][4].text
+					this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
+					this.$refs[this.currentType.key].getData(this.params)
+				} else {
+					this.$refs[this.currentType.key].getData(this.curDate)
+				}
+			}, 500)
+		},
+		methods: {
+			getYearList() {
+				const date = new Date()
+				const year = date.getFullYear();
+				const list = [
+					[]
+				]
+				for (let i = year - 4; i < year + 1; i++) {
+					const obj = {
+						text: String(i),
+						value: String(i)
+					}
+					list[0].push(obj)
+				}
+				return list
+			},
+			getMonthList() {
+				const date = new Date()
+				const month = date.getMonth()
+				const list = [
+					[]
+				]
+				for (let i = 1; i < 13; i++) {
+					const obj = {
+						text: String(i),
+						value: String(i)
+					}
+					if (i < 10) {
+						obj.text = '0' + i
+						obj.value = '0' + i
+					}
+					list[0].push(obj)
+				}
+				setTimeout(() => {
+					this.defaultMonth = [0]
+				}, 1000)
+				return list
+			},
+			getDayList() {
+				const date = new Date()
+				const year = date.getFullYear()
+				let month = date.getMonth()
+				if (this.monthObj) {
+					month = parseInt(this.monthObj.value)
+					month = String(month)
+				}
+				const day = date.getDate()
+				const dayLen = (new Date(year, month, 0)).getDate()
+				const list = [
+					[]
+				]
+				for (let i = 1; i < dayLen + 1; i++) {
+					const obj = {
+						text: String(i),
+						value: String(i)
+					}
+					if (i < 10) {
+						obj.text = '0' + i
+						obj.value = '0' + i
+					}
+					list[0].push(obj)
+				}
+				setTimeout(() => {
+					this.defaultDay = [0]
+				}, 1000)
+				return list
+			},
+			tabClick(item) {
+				this.tabCur = item.value
+				switch (item.value) {
+					case 2:
+						this.yearPicker = true
+						break
+					case 1:
+						this.monthPicker = true
+						break
+					case 0:
+						this.dayPicker = true
+						break
+				}
+				this.params.reportType = this.tabCur
+			},
+			typeConfirm(e) {
+				this.currentType = e.value[0]
+				this.typePicker = false
+				if (this.currentType.value === 5 || this.currentType.value === 7) {
+					let today = uni.$u.timeFormat(new Date(), 'yyyy-mm-dd')
+					this.curDate = [today, today]
+				} else {
+					this.curDate = []
+				}
+				setTimeout(() => {
+					if (this.currentType.value === 6) {
+						this.currentYear = this.yearList[0][4].value
+						this.yearObj = this.yearList[0][4]
+						this.params.title = this.yearList[0][4].text
+						this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
+						this.$refs[this.currentType.key].getData(this.params)
+					} else {
+						this.$refs[this.currentType.key].getData(this.curDate)
+					}
+				}, 500)
+			},
+			dateChange(e) {
+				this.curDate = e
+				this.$refs[this.currentType.key].getData(this.curDate)
+			},
+			yearConfirm(e) {
+				this.defaultYear = [e.indexs[0]]
+				this.currentYear = e.value[0].value
+				this.params.title = e.value[0].text
+				this.yearObj = e.value[0]
+				this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
+				this.$refs[this.currentType.key].getData(this.params)
+				this.yearPicker = false
+			},
+			monthConfirm(e) {
+				this.defaultMonth = [e.indexs[0]]
+				this.currentMonth = e.value[0].value
+				this.monthObj = e.value[0]
+				this.params.title = `${this.yearObj.text}-${this.monthObj.text}`
+				this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
+				this.$refs[this.currentType.key].getData(this.params)
+				this.monthPicker = false
+				this.dayList = this.getDayList()
+			},
+			dayConfirm(e) {
+				this.defaultDay = [e.indexs[0]]
+				this.title = e.value[0].text
+				this.currentDay = e.value[0].value
+				this.dayObj = e.value[0]
+				this.params.title = `${this.yearObj.text}-${this.monthObj.text}-${this.dayObj.text}`
+				this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
+				this.$refs[this.currentType.key].getData(this.params)
+				this.dayPicker = false
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	page {
+		background-color: #1767F2;
+		min-height: calc(100vh - 44px);
+	}
+</style>
+
+<style lang="scss" scoped>
+	@import './statisticalReport.scss';
+</style>

+ 54 - 49
pages/dataOverview/statisticalReport/statisticalReport.scss

@@ -1,49 +1,54 @@
-.report {
-	padding: 15px;
-	font-family: PingFangSC-Regular, PingFang SC;
-	&-header {
-		background-color: #fff;
-		border-radius: 5px;
-		padding: 15px;
-		display: flex;
-		justify-content: space-between;
-		align-items: center;
-		margin-bottom: 10px;
-		&-left {
-			display: flex;
-			align-items: center;
-			text {
-				margin-left: 5px;
-				color: #434343;
-				font-size: 15px;
-			}
-		}
-		&-right {
-			.tab {
-				display: flex;
-				border: solid 1px #1767F2;
-				&-item {
-					width: 40px;
-					height: 28px;
-					line-height: 28px;
-					text-align: center;
-					border-right: solid 1px #1767F2;
-					color: #1767F2;
-					font-size: 16px;
-					&:last-child {
-						border-right: none;
-					}
-				}
-				.active {
-					background-color: #1767f2;
-					color: #fff;
-				}
-			}
-		}
-	}
-	&-content {
-		// padding: 19px 15px;
-		// background-color: #fff;
-		// border-radius: 5px;
-	}
-}
+.operation {
+  padding: 15px;
+  font-family: PingFangSC-Regular, PingFang SC;
+  &-header {
+    width: 100%;
+    border: solid 1px #fff;
+    display: flex;
+    justify-content: space-between;
+    border-radius: 5px;
+    margin-bottom: 18px;
+    &-item {
+      width: 50%;
+      text-align: center;
+      line-height: 49px;
+      color: #fff;
+      font-size: 20px;
+      font-family: PingFangSC-Regular, PingFang SC;
+    }
+    .active {
+      background-color: #fff;
+      color: #434343;
+    }
+  }
+  &-main {
+    padding: 30px 15px 0;
+    background-color: #fff;
+    border-radius: 5px;
+    &-menu {
+      display: flex;
+      flex-wrap: wrap;
+      &-item {
+        width: calc(33% - 20px);
+        text-align: center;
+        margin-right: 30px;
+        margin-bottom: 29px;
+        &:nth-child(3n) {
+          margin-right: 0;
+        }
+        .image {
+          width: 88px;
+          margin: 0 auto 16px;
+        }
+        .name {
+          // white-space: nowrap;
+          // overflow: hidden;
+          // text-overflow: ellipsis;
+          color: #393939;
+          font-family: PingFangSC-Regular, PingFang SC;
+					font-size: 20px;
+        }
+      }
+    }
+  }
+}

+ 167 - 317
pages/dataOverview/statisticalReport/statisticalReport.vue

@@ -1,328 +1,178 @@
-<!-- 统计报表 -->
+<!-- 运营分析 -->
 <template>
-	<view class="report">
-		<view class="report-header">
-			<view class="report-header-left" @click="typePicker = true">
-				<u-icon name="arrow-down" color="#000" size="15"></u-icon>
-				<text>{{ currentType.text }}</text>
-			</view>
-			<view class="report-header-right" v-if="currentType.value === 6">
-				<view class="tab">
-					<view class="tab-item" v-for="(item, index) in tabList" :key="index"
-						:class="{'active': tabCur === item.value}" @click="tabClick(item)">{{ item.label }}</view>
-				</view>
-			</view>
-			<view class="report-header-right" v-else>
-				<uni-datetime-picker v-model="curDate" type="daterange" @change="dateChange">
-					<u--text text="日期查询" color="#1767F2"></u--text>
-				</uni-datetime-picker>
-			</view>
-		</view>
-		<view class="report-content">
-			<template v-if="currentType.value === 1">
-				<TollCollectorPerformance ref="tollCollectorPerformance"/>
-			</template>
-			<template v-else-if="currentType.value === 2">
-				<SectionBerth ref="sectionBerth"/>
-			</template>
-			<template v-else-if="currentType.value === 3">
-				<ParkingReallyIncome ref="parkingReallyIncome"/>
-			</template>
-			<template v-else-if="currentType.value === 4">
-				<ArrearsReport ref="arrearsReport" />
-			</template>
-			<template v-else-if="currentType.value === 5">
-				<RevenueReport ref="revenueReport" />
-			</template>
-			<template v-else-if="currentType.value === 6">
-				<ReallyReceivable ref="reallyReceivable"/>
-			</template>
-			<template v-else-if="currentType.value === 7">
-				<CheckWorkAttendance ref="checkWorkAttendance" />
-			</template>
-		</view>
-		<!-- 报表类型 -->
-		<u-picker :show="typePicker" :columns="typeList" @confirm="typeConfirm" @cancel="typePicker = false"></u-picker>
-		<!-- 年 -->
-		<u-picker :show="yearPicker" :columns="yearList" :defaultIndex="defaultYear" @confirm="yearConfirm"
-			@cancel="yearPicker = false"></u-picker>
-		<!-- 月 -->
-		<u-picker :show="monthPicker" :columns="monthList" :defaultIndex="defaultMonth" @confirm="monthConfirm"
-			@cancel="monthPicker = false"></u-picker>
-		<!-- 日 -->
-		<u-picker :show="dayPicker" :columns="dayList" :defaultIndex="defaultDay" @confirm="dayConfirm"
-			@cancel="dayPicker = false"></u-picker>
-	</view>
+  <view class="operation">
+    <view class="operation-header">
+      <view
+        class="operation-header-item"
+        v-for="(item, index) in tabList"
+        :key="index"
+        :class="{ active: tabCur === item.key }"
+        @click="tabCur = item.key"
+      >
+        <text>{{ item.label }}</text>
+      </view>
+    </view>
+    <view class="operation-main">
+      <template v-if="tabCur === 'road'">
+        <view class="operation-main-menu">
+          <view
+            class="operation-main-menu-item"
+            v-for="(item, index) in roadMenuList"
+            :key="index"
+            @click="jumpPage(item.url, item.params)"
+          >
+            <view class="image">
+              <u--image :showLoading="true" :src="item.icon" width="88px" height="88px" />
+            </view>
+            <view class="name">
+              <text>{{ item.name }}</text>
+            </view>
+          </view>
+        </view>
+      </template>
+      <template v-if="tabCur === 'park'">
+        <view class="operation-main-menu">
+          <view
+            class="operation-main-menu-item"
+            v-for="(item, index) in parkMenuList"
+            :key="index"
+            @click="jumpPage(item.url, item.params)"
+          >
+            <view class="image">
+              <u--image :showLoading="true" :src="item.icon" width="88px" height="88px" />
+            </view>
+            <view class="name">
+              <text>{{ item.name }}</text>
+            </view>
+          </view>
+        </view>
+      </template>
+    </view>
+  </view>
 </template>
 
 <script>
-	import TollCollectorPerformance from './components/tollCollectorPerformance.vue'
-	import SectionBerth from './components/sectionBerth.vue'
-	import ParkingReallyIncome from './components/parkingReallyIncome.vue'
-	import ArrearsReport from './components/arrearsReport.vue'
-	import RevenueReport from './components/revenueReport.vue'
-	import ReallyReceivable from './components/reallyReceivable.vue'
-	import CheckWorkAttendance from './components/checkWorkAttendance.vue'
-	export default {
-		components: {
-			TollCollectorPerformance,
-			SectionBerth,
-			ParkingReallyIncome,
-			ArrearsReport,
-			RevenueReport,
-			ReallyReceivable,
-			CheckWorkAttendance
-		},
-		data() {
-			return {
-				tabList: [{
-						label: '年',
-						value: 2
-					},
-					{
-						label: '月',
-						value: 1
-					},
-					{
-						label: '日',
-						value: 0
-					}
-				],
-				currentType: {},
-				tabCur: 2,
-				typePicker: false,
-				typeList: [[
-					// {
-					// 	text: '收费员业绩统计',
-					// 	value: 1,
-					// 	key: 'tollCollectorPerformance'
-					// },
-					{
-						text: '路段泊位统计',
-						value: 2,
-						key: 'sectionBerth'
-					},
-					{
-						text: '停车场实收统计',
-						value: 3,
-						key: 'parkingReallyIncome'
-					},
-					{
-						text: '欠费统计',
-						value: 4,
-						key: 'arrearsReport'
-					},
-					{
-						text: '营收统计',
-						value: 5,
-						key: 'revenueReport'
-					},
-					{
-						text: '应收实收分析',
-						value: 6,
-						key: 'reallyReceivable'
-					},
-					{
-						text: '考勤统计',
-						value: 7,
-						key: 'checkWorkAttendance'
-					}
-				]],
-				// 日期
-				curDate: [],
-				// 参数
-				params: {
-					reportType: 2,
-					queryDate: '',
-					title: ''
-				},
-				// 年
-				yearPicker: false,
-				yearList: this.getYearList(),
-				defaultYear: [4],
-				currentYear: '',
-				yearObj: {},
-				// 月
-				monthPicker: false,
-				monthList: this.getMonthList(),
-				defaultMonth: [],
-				currentMonth: '01',
-				monthObj: {},
-				// 日
-				dayPicker: false,
-				dayList: this.getDayList(),
-				defaultDay: [],
-				currentDay: '01',
-				dayObj: {}
-			}
-		},
-		onShow() {
-			this.currentType = this.typeList[0][0]
-			if (this.currentType.value === 5 || this.currentType.value === 7) {
-				let today = uni.$u.timeFormat(new Date(), 'yyyy-mm-dd')
-				this.curDate = [today, today]
-			} else {
-				this.curDate = []
-			}
-			setTimeout(() => {
-				if (this.currentType.value === 6) {
-					this.currentYear = this.yearList[0][4].value
-					this.yearObj = this.yearList[0][4]
-					this.params.title = this.yearList[0][4].text
-					this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
-					this.$refs[this.currentType.key].getData(this.params)
-				} else {
-					this.$refs[this.currentType.key].getData(this.curDate)
-				}
-			}, 500)
-		},
-		methods: {
-			getYearList() {
-				const date = new Date()
-				const year = date.getFullYear();
-				const list = [
-					[]
-				]
-				for (let i = year - 4; i < year + 1; i++) {
-					const obj = {
-						text: String(i),
-						value: String(i)
-					}
-					list[0].push(obj)
-				}
-				return list
-			},
-			getMonthList() {
-				const date = new Date()
-				const month = date.getMonth()
-				const list = [
-					[]
-				]
-				for (let i = 1; i < 13; i++) {
-					const obj = {
-						text: String(i),
-						value: String(i)
-					}
-					if (i < 10) {
-						obj.text = '0' + i
-						obj.value = '0' + i
-					}
-					list[0].push(obj)
-				}
-				setTimeout(() => {
-					this.defaultMonth = [0]
-				}, 1000)
-				return list
-			},
-			getDayList() {
-				const date = new Date()
-				const year = date.getFullYear()
-				let month = date.getMonth()
-				if (this.monthObj) {
-					month = parseInt(this.monthObj.value)
-					month = String(month)
-				}
-				const day = date.getDate()
-				const dayLen = (new Date(year, month, 0)).getDate()
-				const list = [
-					[]
-				]
-				for (let i = 1; i < dayLen + 1; i++) {
-					const obj = {
-						text: String(i),
-						value: String(i)
-					}
-					if (i < 10) {
-						obj.text = '0' + i
-						obj.value = '0' + i
-					}
-					list[0].push(obj)
-				}
-				setTimeout(() => {
-					this.defaultDay = [0]
-				}, 1000)
-				return list
-			},
-			tabClick(item) {
-				this.tabCur = item.value
-				switch (item.value) {
-					case 2:
-						this.yearPicker = true
-						break
-					case 1:
-						this.monthPicker = true
-						break
-					case 0:
-						this.dayPicker = true
-						break
-				}
-				this.params.reportType = this.tabCur
-			},
-			typeConfirm(e) {
-				this.currentType = e.value[0]
-				this.typePicker = false
-				if (this.currentType.value === 5 || this.currentType.value === 7) {
-					let today = uni.$u.timeFormat(new Date(), 'yyyy-mm-dd')
-					this.curDate = [today, today]
-				} else {
-					this.curDate = []
-				}
-				setTimeout(() => {
-					if (this.currentType.value === 6) {
-						this.currentYear = this.yearList[0][4].value
-						this.yearObj = this.yearList[0][4]
-						this.params.title = this.yearList[0][4].text
-						this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
-						this.$refs[this.currentType.key].getData(this.params)
-					} else {
-						this.$refs[this.currentType.key].getData(this.curDate)
-					}
-				}, 500)
-			},
-			dateChange(e) {
-				this.curDate = e
-				this.$refs[this.currentType.key].getData(this.curDate)
-			},
-			yearConfirm(e) {
-				this.defaultYear = [e.indexs[0]]
-				this.currentYear = e.value[0].value
-				this.params.title = e.value[0].text
-				this.yearObj = e.value[0]
-				this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
-				this.$refs[this.currentType.key].getData(this.params)
-				this.yearPicker = false
-			},
-			monthConfirm(e) {
-				this.defaultMonth = [e.indexs[0]]
-				this.currentMonth = e.value[0].value
-				this.monthObj = e.value[0]
-				this.params.title = `${this.yearObj.text}-${this.monthObj.text}`
-				this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
-				this.$refs[this.currentType.key].getData(this.params)
-				this.monthPicker = false
-				this.dayList = this.getDayList()
-			},
-			dayConfirm(e) {
-				this.defaultDay = [e.indexs[0]]
-				this.title = e.value[0].text
-				this.currentDay = e.value[0].value
-				this.dayObj = e.value[0]
-				this.params.title = `${this.yearObj.text}-${this.monthObj.text}-${this.dayObj.text}`
-				this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`
-				this.$refs[this.currentType.key].getData(this.params)
-				this.dayPicker = false
-			}
-		}
-	}
+export default {
+  data() {
+    return {
+      tabList: [
+        { key: 'road', label: '路段' },
+        { key: 'park', label: '停车场' }
+      ],
+      tabCur: 'road',
+      roadMenuList: [
+        {
+          icon: '/static/icons/statisticalReportIcons/section-berth-icon.svg',
+          name: '路段泊位实收统计',
+          url: 'pages/statisticalReport/roadModel/index',
+          params: {
+            title: '路段泊位实收统计',
+            key: 'sectionBerth'
+          }
+        },
+        {
+          icon: '/static/icons/operationalAnalysisIcons/arrearage-analysis-icon.svg',
+          name: '欠费统计',
+          url: 'pages/statisticalReport/roadModel/index',
+          params: {
+            title: '欠费统计',
+            key: 'arrearsReport'
+          }
+        },
+        {
+          icon: '/static/icons/operationalAnalysisIcons/revenue-analysis-icon.svg',
+          name: '营收统计',
+          url: 'pages/statisticalReport/roadModel/index',
+          params: {
+            title: '营收统计',
+            key: 'revenueReport'
+          }
+        },
+        {
+          icon: '/static/icons/statisticalReportIcons/really-receivable-icon.svg',
+          name: '应收实收分析',
+          url: 'pages/statisticalReport/roadModel/index',
+          params: {
+            title: '应收实收分析',
+            key: 'reallyReceivable'
+          }
+        },
+        {
+          icon: '/static/icons/statisticalReportIcons/recovery-report-icon.svg',
+          name: '追缴统计',
+          url: 'pages/statisticalReport/roadModel/index',
+          params: {
+            title: '追缴统计',
+            key: 'recoveryReport'
+          }
+        }
+      ],
+      parkMenuList: [
+        {
+          icon: '/static/icons/statisticalReportIcons/parking-lot-income-icon.svg',
+          name: '停车场实收统计',
+          url: 'pages/statisticalReport/parkModel/index',
+          params: {
+            title: '停车场实收统计',
+            key: 'parkingReallyIncome'
+          }
+        },
+        {
+          icon: '/static/icons/operationalAnalysisIcons/arrearage-analysis-icon.svg',
+          name: '欠费统计',
+          url: 'pages/statisticalReport/parkModel/index',
+          params: {
+            title: '欠费统计',
+            key: 'arrearsReport'
+          }
+        },
+        {
+          icon: '/static/icons/operationalAnalysisIcons/revenue-analysis-icon.svg',
+          name: '营收统计',
+          url: 'pages/statisticalReport/parkModel/index',
+          params: {
+            title: '营收统计',
+            key: 'revenueReport'
+          }
+        },
+        {
+          icon: '/static/icons/statisticalReportIcons/really-receivable-icon.svg',
+          name: '应收实收统计',
+          url: 'pages/statisticalReport/parkModel/index',
+          params: {
+            title: '应收实收统计',
+            key: 'reallyReceivable'
+          }
+        }
+      ]
+    };
+  },
+  onShow() {},
+  methods: {
+    /**
+     * 跳转指定页面
+     * @param {*} url
+     * @param {*} params
+     * @param {*} type
+     */
+    jumpPage(url, params, type = 'navigateTo') {
+      uni.$u.route({
+        url,
+        params,
+        type
+      });
+    }
+  }
+};
 </script>
 
 <style lang="scss">
-	page {
-		background-color: #1767F2;
-		min-height: calc(100vh - 44px);
-	}
+page {
+  background-color: #1767f2;
+  min-height: calc(100vh - 44px);
+}
 </style>
 
 <style lang="scss" scoped>
-	@import './statisticalReport.scss';
+@import './statisticalReport.scss';
 </style>

+ 0 - 76
pages/operationalAnalysis/parkModel/components/revenueRanking.vue

@@ -1,76 +0,0 @@
-<!-- 路段/停车场营收排行 -->
-<template>
-	<view class="ranking">
-		<TableRanking :loading="loading" :title="title" :tableTh="tableTh" :tableData="tableData" @pageChange="pageChange"/>
-	</view>
-</template>
-
-<script>
-	import TableRanking from '@/components/tableRanking.vue'
-	export default {
-		components: {
-			TableRanking
-		},
-		props: {
-			title: {
-				type: String,
-				default: ''
-			},
-			tableTh: {
-				type: Array,
-				default: () => [
-					{ field: '路段编号', key: 'roadNo' },
-					{ field: '路段名称', key: 'roadName' },
-					{ field: '收益(元)', key: 'amt' }
-				]
-			}
-		},
-		data() {
-			return {
-				tableData: {
-					current: 1,
-					total: 0,
-					list: []
-				},
-				reportType: '',
-				queryDate: '',
-				loading: false
-			}
-		},
-		methods: {
-			getData({ reportType, queryDate }) {
-				this.reportType = reportType
-				this.queryDate = queryDate
-				this.tableData.current = 1
-				this.getList()
-			},
-			getList() {
-				this.loading = true
-				uni.$u.api.operationalAnalysisApi.getParkingLotRevenueDataApi({
-					pageNum: this.tableData.current,
-					pageSize: 10,
-					reportType: this.reportType,
-					queryDate: this.queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						this.tableData.list = res.rows
-						this.tableData.total = res.total
-					}
-					this.loading = false
-				}).catch(() => {
-					this.loading = false
-				})
-			},
-			pageChange(current) {
-				this.tableData.current = current
-				this.getList()
-			}
-		}
-	}
-</script>
-<style lang="scss" scoped>
-	.ranking-title {
-		text-align: center;
-		margin-bottom: 10px;
-	}
-</style>

+ 0 - 185
pages/operationalAnalysis/parkModel/components/sectionAnalysis.vue

@@ -1,185 +0,0 @@
-<!-- 路段分析 -->
-<template>
-	<view class="section">
-		<!-- 营收趋势分析 -->
-		<view class="section-part">
-			<view class="section-part-title"><text>|</text>营收趋势分析</view>
-			<view class="section-part-content">
-				<ColumnChart v-if="revenueTrendsData.series[0].data.length" :chartData="revenueTrendsData" :title="title" :opts="opts1"/>
-				<view class="empty" v-else>
-					<u-empty></u-empty>
-				</view>
-			</view>
-		</view>
-		<view class="section-part">
-			<view class="section-part-title"><text>|</text>车流量统计</view>
-			<view class="section-part-content">
-				<ColumnChart v-if="trafficFlowData.series[0].data.length" :chartData="trafficFlowData" :title="title" :opts="opts2"/>
-				<view class="empty" v-else>
-					<u-empty></u-empty>
-				</view>
-			</view>
-		</view>
-		<u-loading-page :loading="loading" loading-text="loading..."></u-loading-page>
-	</view>
-</template>
-
-<script>
-	import ColumnChart from '@/components/columnChart.vue'
-	export default {
-		components: {
-			ColumnChart
-		},
-		props: {
-			title: {
-				type: String,
-				default: ''
-			}
-		},
-		data() {
-			return {
-				loading: false,
-				opts1: {
-					enableScroll: true,
-					xAxis: {
-						rotateLabel: true,
-						scrollShow: true,
-						itemCount: 8
-					},
-					yAxis: {
-						showTitle: true,
-						splitNumber: 5,
-						data: [{
-							title: '收益(元)',
-							titleOffsetY: -3
-						}]
-					},
-					legend: {
-						show: false
-					},
-					dataLabel: false,
-					padding: [20, 0, 10, 0],
-					extra: {
-						column: {
-							width: 20
-						}
-					}
-				},
-				opts2: {
-					enableScroll: true,
-					xAxis: {
-						rotateLabel: true,
-						scrollShow: true,
-						itemCount: 8
-					},
-					yAxis: {
-						showTitle: true,
-						splitNumber: 5,
-						data: [{
-							title: '车辆(辆)',
-							titleOffsetY: 0,
-							titleOffsetX: 10
-						}]
-					},
-					legend: {
-						show: false
-					},
-					dataLabel: false,
-					padding: [10, 0, 10, 0],
-					extra: {
-						column: {
-							width: 20
-						}
-					}
-				},
-				revenueTrendsData: {
-					categories: [],
-					series: [{
-						name: '',
-						data: []
-					}]
-				},
-				trafficFlowData: {
-					categories: [],
-					series: [{
-						name: '',
-						data: []
-					}]
-				}
-			}
-		},
-		methods: {
-			getData({ reportType, queryDate }) {
-				this.reportType = reportType
-				this.queryDate = queryDate
-				this.loading = true
-				this.getRevenueTrendsData()
-				this.getRoadTrafficFlowData()
-			},
-			getRevenueTrendsData() {
-				uni.$u.api.operationalAnalysisApi.getRevenueTrendsDataApi({
-					reportType: this.reportType,
-					queryDate: this.queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							this.revenueTrendsData.categories = res.data.itemList.map(item => {
-								return item.roadName
-							})
-							this.revenueTrendsData.series[0].data = res.data.itemList.map(item => {
-								return item.amt
-							})
-						} else {
-							this.revenueTrendsData.categories = []
-							this.revenueTrendsData.series[0].data = []
-						}
-					}
-					this.loading = false
-				})
-			},
-			getRoadTrafficFlowData() {
-				uni.$u.api.operationalAnalysisApi.getRoadTrafficFlowDataApi({
-					reportType: this.reportType,
-					queryDate: this.queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							this.trafficFlowData.categories = res.data.itemList.map(item => {
-								return item.roadName
-							})
-							this.trafficFlowData.series[0].data = res.data.itemList.map(item => {
-								return item.vehicleCount
-							})
-						} else {
-							this.trafficFlowData.categories = []
-							this.trafficFlowData.series[0].data = []
-						}
-					}
-					this.loading = false
-				})
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.section {
-		&-part {
-			background-color: #fff;
-			border-radius: 5px;
-			margin-bottom: 10px;
-
-			&-title {
-				padding: 15px;
-
-				text {
-					color: #f00;
-					margin-right: 5px;
-				}
-			}
-		}
-		.empty {
-			padding: 15px;
-		}
-	}
-</style>

+ 0 - 180
pages/operationalAnalysis/parkModel/components/sourceOfPayment.vue

@@ -1,180 +0,0 @@
-<!-- 支付来源分析 -->
-<template>
-	<view class="revenue">
-		<view class="revenue-line">
-			<LineChart v-if="hasData" :chartData="chartData" :title="title" :opts="opts" />
-			<view class="empty" v-else>
-				<u-empty></u-empty>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import LineChart from '@/components/lineChart.vue'
-	export default {
-		components: {
-			LineChart
-		},
-		props: {
-			title: {
-				type: String,
-				default: ''
-			},
-			opts: {
-				type: Object,
-				default: () => {
-					return {
-						xAxis: {
-							rotateLabel: true
-						},
-						yAxis: {
-							showTitle: true,
-							splitNumber: 5,
-							data: [{
-								title: '元',
-								titleOffsetY: -5
-							}]
-						},
-						legend: {
-							show: true
-						},
-						dataLabel: false,
-						extra: {
-							column: {
-								width: 20
-							}
-						}
-					}
-				}
-			}
-		},
-		data() {
-			return {
-				paySourceList: [],
-				chartData: {
-					categories: [],
-					series: []
-				},
-				hasData: false
-			}
-		},
-		created() {
-			this.getDict()
-		},
-		methods: {
-			getData({
-				reportType,
-				queryDate
-			}) {
-				this.hasData = false
-				this.chartData.categories = []
-				this.chartData.series = []
-				this.getPaySourceData({
-					reportType,
-					queryDate
-				})
-			},
-			getDict() {
-				uni.$u.api.getDictApi({
-					type: 'pay_platform'
-				}).then(res => {
-					if (res.code === 200) {
-						this.paySourceList = res.data
-					}
-				})
-			},
-			getPaySourceData({
-				reportType,
-				queryDate
-			}) {
-				uni.$u.api.operationalAnalysisApi.getPaySourceDataApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							this.chartData.series[0] = {
-								name: '路段',
-								data: []
-							}
-							let cateList = []
-							res.data.itemList.forEach(item => {
-								cateList.push(this.getDictLabel(item.payPlatform))
-							})
-							this.chartData.categories = cateList
-							this.chartData.series[0].data = res.data.itemList.map(item => {
-								return item.amt
-							})
-						}
-						this.getParkingData({ reportType, queryDate })
-					}
-				})
-			},
-			getParkingData({
-				reportType,
-				queryDate
-			}) {
-				uni.$u.api.operationalAnalysisApi.getParkingPaySourceDataApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							if (this.chartData.series.length) {
-								this.chartData.series[1] = {
-									name: '停车场',
-									data: []
-								}
-								this.chartData.series[1].data = res.data.itemList.map(item => {
-									return item.amt
-								})
-							} else {
-								this.chartData.series[0] = {
-									name: '停车场',
-									data: []
-								}
-								this.chartData.series[0].data = res.data.itemList.map(item => {
-									return item.amt
-								})
-							}
-							if (!this.chartData.categories.length) {
-								let cateList = []
-								res.data.itemList.forEach(item => {
-									cateList.push(this.getDictLabel(item.payPlatform))
-								})
-								this.chartData.categories = cateList
-							}
-							this.hasData = true
-						} else if (this.chartData.series.length === 1) {
-							this.hasData = true
-						} else if (!this.chartData.series.length) {
-							this.hasData = false
-						}
-					}
-				})
-			},
-			getDictLabel(value) {
-				let name
-				this.paySourceList.forEach(item => {
-					if (item.dictValue == value) {
-						name = item.dictLabel
-					}
-				})
-				if (!name) name = '其他'
-				return name
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.revenue {
-		background-color: #fff;
-		border-radius: 5px;
-
-		.empty {
-			padding: 15px;
-		}
-	}
-</style>

+ 0 - 149
pages/operationalAnalysis/parkModel/components/tollCollectorPerformance.vue

@@ -1,149 +0,0 @@
-<!-- 收费员业绩 -->
-<template>
-	<view class="performance">
-		<template v-if="type === 'table'">
-			<TableRanking :loading="loading" :title="title" :tableTh="tableTh" :tableData="tableData"  @pageChange="pageChange"/>
-		</template>
-		<template v-else>
-			<LineChart v-if="chartData.series[0].data.length" :chartData="chartData" :title="title" :opts="opts"/>
-			<view class="empty" v-else>
-				<u-empty></u-empty>
-			</view>
-		</template>
-	</view>
-</template>
-
-<script>
-	import TableRanking from '@/components/tableRanking.vue'
-	import LineChart from '@/components/lineChart.vue'
-	export default {
-		components: {
-			TableRanking,
-			LineChart
-		},
-		props: {
-			type: {
-				type: String,
-				default: 'table'
-			},
-			title: {
-				type: String,
-				default: ''
-			},
-			tableTh: {
-				type: Array,
-				default: () => [
-					{ width: 100, field: '工号', key: 'payeeNo' },
-					{ width: 100, field: '姓名', key: 'payeeName' },
-					{ width: 100, field: '收益(元)', key: 'amt' }
-				]
-			},
-		},
-		data() {
-			return {
-				chartData: {
-					categories: [],
-					series: [{
-						name: '',
-						data: []
-					}]
-				},
-				tableData: {
-					current: 1,
-					total: 0,
-					list: []
-				},
-				reportType: '',
-				queryDate: '',
-				loading: false,
-				opts: {
-					enableScroll: true,
-					xAxis: {
-						rotateLabel: true,
-						scrollShow: true,
-						itemCount: 8
-					},
-					yAxis: {
-						showTitle: true,
-						splitNumber: 5,
-						data: [{
-							title: '元',
-							titleOffsetY: -3
-						}]
-					},
-					legend: {
-						show: false
-					},
-					dataLabel: false,
-					padding: [20, 10, 10, 10],
-					extra: {
-						column: {
-							width: 20
-						}
-					}
-				}
-			}
-		},
-		methods: {
-			getData({ reportType, queryDate }) {
-				if (this.type === 'table') {
-					this.tableData.current = 1
-					this.getTableData({ reportType, queryDate })
-				} else {
-					this.getChartData({ reportType, queryDate })
-				}
-			},
-			getTableData({ reportType, queryDate }) {
-				this.loading = true
-				uni.$u.api.operationalAnalysisApi.getTollCollectorPerformanceApi({
-					pageNum: this.tableData.current,
-					pageSize: 10,
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						this.tableData.list = res.rows
-						this.tableData.total = res.total
-					}
-					this.loading = false
-				}).catch(() => {
-					this.loading = false
-				})
-			},
-			getChartData({ reportType, queryDate }) {
-				uni.$u.api.operationalAnalysisApi.getTollCollectorPerformanceApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.rows && res.rows.length) {
-							this.chartData.categories = res.rows.map(item => {
-								return item.payeeName
-							})
-							this.chartData.series[0].data = res.rows.map(item => {
-								return item.amt
-							})
-						} else {
-							this.chartData.categories = []
-							this.chartData.series[0].data = []
-						}
-					}
-				})
-			},
-			pageChange(current) {
-				this.tableData.current = current
-				this.getTableData()
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.performance {
-		background-color: #fff;
-		border-radius: 5px;
-		.empty {
-			padding: 15px;
-		}
-	}
-</style>

+ 0 - 152
pages/operationalAnalysis/parkModel/components/trafficFlow.vue

@@ -1,152 +0,0 @@
-<!-- 车流量分析 -->
-<template>
-	<view class="revenue">
-		<view class="revenue-line">
-			<LineChart v-if="hasData" :chartData="chartData" :title="title" :opts="opts" />
-			<view class="empty" v-else>
-				<u-empty></u-empty>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import LineChart from '@/components/lineChart.vue'
-	export default {
-		components: {
-			LineChart
-		},
-		props: {
-			title: {
-				type: String,
-				default: ''
-			},
-			opts: {
-				type: Object,
-				default: () => {
-					return {
-						enableScroll: true,
-						xAxis: {
-							rotateLabel: true,
-							scrollShow: true,
-							itemCount: 8
-						},
-						yAxis: {
-							showTitle: true,
-							splitNumber: 5,
-							data: [{
-								title: '辆',
-								titleOffsetY: -3
-							}]
-						},
-						legend: {
-							show: true
-						},
-						dataLabel: false,
-						padding: [20, 10, 10, 10],
-						extra: {
-							column: {
-								width: 20
-							}
-						}
-					}
-				}
-			}
-		},
-		data() {
-			return {
-				chartData: {
-					categories: [],
-					series: []
-				},
-				reportType: '',
-				queryDate: '',
-				hasData: false
-			}
-		},
-		methods: {
-			getData({
-				reportType,
-				queryDate
-			}) {
-				this.chartData.categories = []
-				this.chartData.series = []
-				this.reportType = reportType
-				this.queryDate = queryDate
-				this.hasData = false;
-				this.getRoadData({ reportType, queryDate });
-			},
-			getRoadData({ reportType, queryDate }) {
-				uni.$u.api.operationalAnalysisApi.getTrafficFlowDataApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							this.chartData.series[0] = {
-								name: '路段',
-								data: []
-							}
-							this.chartData.categories = res.data.itemList.map(item => {
-								return item.statisTime
-							})
-							this.chartData.series[0].data = res.data.itemList.map(item => {
-								return item.vehicleCount
-							})
-						}
-					}
-					this.getParkingData({ reportType, queryDate });
-				})
-			},
-			getParkingData({ reportType, queryDate }) {
-				uni.$u.api.operationalAnalysisApi.getParkingTrafficFlowDataApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							if (this.chartData.series.length) {
-								this.chartData.series[1] = {
-									name: '停车场',
-									data: []
-								}
-								this.chartData.series[1].data = res.data.itemList.map(item => {
-									return item.vehicleCount
-								})
-							} else {
-								this.chartData.series[0] = {
-									name: '停车场',
-									data: []
-								}
-								this.chartData.series[0].data = res.data.itemList.map(item => {
-									return item.vehicleCount
-								})
-							}
-							if (!this.chartData.categories.length) {
-								this.chartData.categories = res.data.itemList.map(item => {
-									return item.statisTime
-								})
-							}
-							this.hasData = true
-						} else if (this.chartData.series.length === 1) {
-							this.hasData = true
-						} else if (!this.chartData.series.length) {
-							this.hasData = false
-						}
-					}
-				})
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.revenue {
-		background-color: #fff;
-		border-radius: 5px;
-
-		.empty {
-			padding: 15px;
-		}
-	}
-</style>

+ 5 - 5
pages/operationalAnalysis/parkModel/index.vue

@@ -3,7 +3,7 @@
  * @Author: 空白格
  * @Date: 2022-08-02 15:32:15
  * @LastEditors: 空白格
- * @LastEditTime: 2022-08-02 16:22:52
+ * @LastEditTime: 2022-08-03 13:53:18
  * @FilePath: \parking_operation\pages\operationalAnalysis\parkModel\index.vue
  * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved. 
 -->
@@ -34,10 +34,10 @@
         <revenue-analysis ref="revenueAnalysis" :title="title" />
       </template>
       <template v-else-if="templateKey === 'incomeAnalysis'">
-        <income-analysis ref="incomeAnalysis" :title="title"/>
+        <income-analysis ref="incomeAnalysis" :title="title" />
       </template>
       <template v-else-if="templateKey === 'paymentMethod'">
-        <payment-method ref="paymentMethod" :title="title"/>
+        <payment-method ref="paymentMethod" :title="title" />
       </template>
     </view>
     <!-- 年 -->
@@ -71,8 +71,8 @@
 import ParkingLotAnalysis from './components/parkingLotAnalysis.vue';
 import ArrearsAnalysis from './components/arrearsAnalysis.vue';
 import RevenueAnalysis from './components/revenueAnalysis.vue';
-import IncomeAnalysis from './components/incomeAnalysis.vue'
-import PaymentMethod from './components/paymentMethod.vue'
+import IncomeAnalysis from './components/incomeAnalysis.vue';
+import PaymentMethod from './components/paymentMethod.vue';
 export default {
   components: {
     ParkingLotAnalysis,

+ 0 - 76
pages/operationalAnalysis/roadModel/components/revenueRanking.vue

@@ -1,76 +0,0 @@
-<!-- 路段/停车场营收排行 -->
-<template>
-	<view class="ranking">
-		<TableRanking :loading="loading" :title="title" :tableTh="tableTh" :tableData="tableData" @pageChange="pageChange"/>
-	</view>
-</template>
-
-<script>
-	import TableRanking from '@/components/tableRanking.vue'
-	export default {
-		components: {
-			TableRanking
-		},
-		props: {
-			title: {
-				type: String,
-				default: ''
-			},
-			tableTh: {
-				type: Array,
-				default: () => [
-					{ field: '路段编号', key: 'roadNo' },
-					{ field: '路段名称', key: 'roadName' },
-					{ field: '收益(元)', key: 'amt' }
-				]
-			}
-		},
-		data() {
-			return {
-				tableData: {
-					current: 1,
-					total: 0,
-					list: []
-				},
-				reportType: '',
-				queryDate: '',
-				loading: false
-			}
-		},
-		methods: {
-			getData({ reportType, queryDate }) {
-				this.reportType = reportType
-				this.queryDate = queryDate
-				this.tableData.current = 1
-				this.getList()
-			},
-			getList() {
-				this.loading = true
-				uni.$u.api.operationalAnalysisApi.getParkingLotRevenueDataApi({
-					pageNum: this.tableData.current,
-					pageSize: 10,
-					reportType: this.reportType,
-					queryDate: this.queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						this.tableData.list = res.rows
-						this.tableData.total = res.total
-					}
-					this.loading = false
-				}).catch(() => {
-					this.loading = false
-				})
-			},
-			pageChange(current) {
-				this.tableData.current = current
-				this.getList()
-			}
-		}
-	}
-</script>
-<style lang="scss" scoped>
-	.ranking-title {
-		text-align: center;
-		margin-bottom: 10px;
-	}
-</style>

+ 0 - 180
pages/operationalAnalysis/roadModel/components/sourceOfPayment.vue

@@ -1,180 +0,0 @@
-<!-- 支付来源分析 -->
-<template>
-	<view class="revenue">
-		<view class="revenue-line">
-			<LineChart v-if="hasData" :chartData="chartData" :title="title" :opts="opts" />
-			<view class="empty" v-else>
-				<u-empty></u-empty>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import LineChart from '@/components/lineChart.vue'
-	export default {
-		components: {
-			LineChart
-		},
-		props: {
-			title: {
-				type: String,
-				default: ''
-			},
-			opts: {
-				type: Object,
-				default: () => {
-					return {
-						xAxis: {
-							rotateLabel: true
-						},
-						yAxis: {
-							showTitle: true,
-							splitNumber: 5,
-							data: [{
-								title: '元',
-								titleOffsetY: -5
-							}]
-						},
-						legend: {
-							show: true
-						},
-						dataLabel: false,
-						extra: {
-							column: {
-								width: 20
-							}
-						}
-					}
-				}
-			}
-		},
-		data() {
-			return {
-				paySourceList: [],
-				chartData: {
-					categories: [],
-					series: []
-				},
-				hasData: false
-			}
-		},
-		created() {
-			this.getDict()
-		},
-		methods: {
-			getData({
-				reportType,
-				queryDate
-			}) {
-				this.hasData = false
-				this.chartData.categories = []
-				this.chartData.series = []
-				this.getPaySourceData({
-					reportType,
-					queryDate
-				})
-			},
-			getDict() {
-				uni.$u.api.getDictApi({
-					type: 'pay_platform'
-				}).then(res => {
-					if (res.code === 200) {
-						this.paySourceList = res.data
-					}
-				})
-			},
-			getPaySourceData({
-				reportType,
-				queryDate
-			}) {
-				uni.$u.api.operationalAnalysisApi.getPaySourceDataApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							this.chartData.series[0] = {
-								name: '路段',
-								data: []
-							}
-							let cateList = []
-							res.data.itemList.forEach(item => {
-								cateList.push(this.getDictLabel(item.payPlatform))
-							})
-							this.chartData.categories = cateList
-							this.chartData.series[0].data = res.data.itemList.map(item => {
-								return item.amt
-							})
-						}
-						this.getParkingData({ reportType, queryDate })
-					}
-				})
-			},
-			getParkingData({
-				reportType,
-				queryDate
-			}) {
-				uni.$u.api.operationalAnalysisApi.getParkingPaySourceDataApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							if (this.chartData.series.length) {
-								this.chartData.series[1] = {
-									name: '停车场',
-									data: []
-								}
-								this.chartData.series[1].data = res.data.itemList.map(item => {
-									return item.amt
-								})
-							} else {
-								this.chartData.series[0] = {
-									name: '停车场',
-									data: []
-								}
-								this.chartData.series[0].data = res.data.itemList.map(item => {
-									return item.amt
-								})
-							}
-							if (!this.chartData.categories.length) {
-								let cateList = []
-								res.data.itemList.forEach(item => {
-									cateList.push(this.getDictLabel(item.payPlatform))
-								})
-								this.chartData.categories = cateList
-							}
-							this.hasData = true
-						} else if (this.chartData.series.length === 1) {
-							this.hasData = true
-						} else if (!this.chartData.series.length) {
-							this.hasData = false
-						}
-					}
-				})
-			},
-			getDictLabel(value) {
-				let name
-				this.paySourceList.forEach(item => {
-					if (item.dictValue == value) {
-						name = item.dictLabel
-					}
-				})
-				if (!name) name = '其他'
-				return name
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.revenue {
-		background-color: #fff;
-		border-radius: 5px;
-
-		.empty {
-			padding: 15px;
-		}
-	}
-</style>

+ 0 - 149
pages/operationalAnalysis/roadModel/components/tollCollectorPerformance.vue

@@ -1,149 +0,0 @@
-<!-- 收费员业绩 -->
-<template>
-	<view class="performance">
-		<template v-if="type === 'table'">
-			<TableRanking :loading="loading" :title="title" :tableTh="tableTh" :tableData="tableData"  @pageChange="pageChange"/>
-		</template>
-		<template v-else>
-			<LineChart v-if="chartData.series[0].data.length" :chartData="chartData" :title="title" :opts="opts"/>
-			<view class="empty" v-else>
-				<u-empty></u-empty>
-			</view>
-		</template>
-	</view>
-</template>
-
-<script>
-	import TableRanking from '@/components/tableRanking.vue'
-	import LineChart from '@/components/lineChart.vue'
-	export default {
-		components: {
-			TableRanking,
-			LineChart
-		},
-		props: {
-			type: {
-				type: String,
-				default: 'table'
-			},
-			title: {
-				type: String,
-				default: ''
-			},
-			tableTh: {
-				type: Array,
-				default: () => [
-					{ width: 100, field: '工号', key: 'payeeNo' },
-					{ width: 100, field: '姓名', key: 'payeeName' },
-					{ width: 100, field: '收益(元)', key: 'amt' }
-				]
-			},
-		},
-		data() {
-			return {
-				chartData: {
-					categories: [],
-					series: [{
-						name: '',
-						data: []
-					}]
-				},
-				tableData: {
-					current: 1,
-					total: 0,
-					list: []
-				},
-				reportType: '',
-				queryDate: '',
-				loading: false,
-				opts: {
-					enableScroll: true,
-					xAxis: {
-						rotateLabel: true,
-						scrollShow: true,
-						itemCount: 8
-					},
-					yAxis: {
-						showTitle: true,
-						splitNumber: 5,
-						data: [{
-							title: '元',
-							titleOffsetY: -3
-						}]
-					},
-					legend: {
-						show: false
-					},
-					dataLabel: false,
-					padding: [20, 10, 10, 10],
-					extra: {
-						column: {
-							width: 20
-						}
-					}
-				}
-			}
-		},
-		methods: {
-			getData({ reportType, queryDate }) {
-				if (this.type === 'table') {
-					this.tableData.current = 1
-					this.getTableData({ reportType, queryDate })
-				} else {
-					this.getChartData({ reportType, queryDate })
-				}
-			},
-			getTableData({ reportType, queryDate }) {
-				this.loading = true
-				uni.$u.api.operationalAnalysisApi.getTollCollectorPerformanceApi({
-					pageNum: this.tableData.current,
-					pageSize: 10,
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						this.tableData.list = res.rows
-						this.tableData.total = res.total
-					}
-					this.loading = false
-				}).catch(() => {
-					this.loading = false
-				})
-			},
-			getChartData({ reportType, queryDate }) {
-				uni.$u.api.operationalAnalysisApi.getTollCollectorPerformanceApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.rows && res.rows.length) {
-							this.chartData.categories = res.rows.map(item => {
-								return item.payeeName
-							})
-							this.chartData.series[0].data = res.rows.map(item => {
-								return item.amt
-							})
-						} else {
-							this.chartData.categories = []
-							this.chartData.series[0].data = []
-						}
-					}
-				})
-			},
-			pageChange(current) {
-				this.tableData.current = current
-				this.getTableData()
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.performance {
-		background-color: #fff;
-		border-radius: 5px;
-		.empty {
-			padding: 15px;
-		}
-	}
-</style>

+ 0 - 152
pages/operationalAnalysis/roadModel/components/trafficFlow.vue

@@ -1,152 +0,0 @@
-<!-- 车流量分析 -->
-<template>
-	<view class="revenue">
-		<view class="revenue-line">
-			<LineChart v-if="hasData" :chartData="chartData" :title="title" :opts="opts" />
-			<view class="empty" v-else>
-				<u-empty></u-empty>
-			</view>
-		</view>
-	</view>
-</template>
-
-<script>
-	import LineChart from '@/components/lineChart.vue'
-	export default {
-		components: {
-			LineChart
-		},
-		props: {
-			title: {
-				type: String,
-				default: ''
-			},
-			opts: {
-				type: Object,
-				default: () => {
-					return {
-						enableScroll: true,
-						xAxis: {
-							rotateLabel: true,
-							scrollShow: true,
-							itemCount: 8
-						},
-						yAxis: {
-							showTitle: true,
-							splitNumber: 5,
-							data: [{
-								title: '辆',
-								titleOffsetY: -3
-							}]
-						},
-						legend: {
-							show: true
-						},
-						dataLabel: false,
-						padding: [20, 10, 10, 10],
-						extra: {
-							column: {
-								width: 20
-							}
-						}
-					}
-				}
-			}
-		},
-		data() {
-			return {
-				chartData: {
-					categories: [],
-					series: []
-				},
-				reportType: '',
-				queryDate: '',
-				hasData: false
-			}
-		},
-		methods: {
-			getData({
-				reportType,
-				queryDate
-			}) {
-				this.chartData.categories = []
-				this.chartData.series = []
-				this.reportType = reportType
-				this.queryDate = queryDate
-				this.hasData = false;
-				this.getRoadData({ reportType, queryDate });
-			},
-			getRoadData({ reportType, queryDate }) {
-				uni.$u.api.operationalAnalysisApi.getTrafficFlowDataApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							this.chartData.series[0] = {
-								name: '路段',
-								data: []
-							}
-							this.chartData.categories = res.data.itemList.map(item => {
-								return item.statisTime
-							})
-							this.chartData.series[0].data = res.data.itemList.map(item => {
-								return item.vehicleCount
-							})
-						}
-					}
-					this.getParkingData({ reportType, queryDate });
-				})
-			},
-			getParkingData({ reportType, queryDate }) {
-				uni.$u.api.operationalAnalysisApi.getParkingTrafficFlowDataApi({
-					reportType,
-					queryDate
-				}).then(res => {
-					if (res.code === 200) {
-						if (res.data.itemList && res.data.itemList.length) {
-							if (this.chartData.series.length) {
-								this.chartData.series[1] = {
-									name: '停车场',
-									data: []
-								}
-								this.chartData.series[1].data = res.data.itemList.map(item => {
-									return item.vehicleCount
-								})
-							} else {
-								this.chartData.series[0] = {
-									name: '停车场',
-									data: []
-								}
-								this.chartData.series[0].data = res.data.itemList.map(item => {
-									return item.vehicleCount
-								})
-							}
-							if (!this.chartData.categories.length) {
-								this.chartData.categories = res.data.itemList.map(item => {
-									return item.statisTime
-								})
-							}
-							this.hasData = true
-						} else if (this.chartData.series.length === 1) {
-							this.hasData = true
-						} else if (!this.chartData.series.length) {
-							this.hasData = false
-						}
-					}
-				})
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.revenue {
-		background-color: #fff;
-		border-radius: 5px;
-
-		.empty {
-			padding: 15px;
-		}
-	}
-</style>

+ 120 - 0
pages/statisticalReport/parkModel/components/arrearsReport.vue

@@ -0,0 +1,120 @@
+<!-- 欠费统计 -->
+<template>
+  <view class="container">
+    <view class="table">
+      <view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+      <view class="table-box">
+        <TableRanking
+          :loading="loading"
+          :padding="'0'"
+          :tableTh="tableTh"
+          :tableData="tableData"
+          @pageChange="pageChange"
+        />
+      </view>
+    </view>
+    <view class="total">
+      <view>
+        欠费次数
+        <text>{{ totalData.oweCount || 0 }}</text>次,欠费金额
+        <text>{{ totalData.amtOwe || 0 }}</text>元
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import TableRanking from '@/components/tableRanking.vue';
+export default {
+  components: {
+    TableRanking
+  },
+  props: {
+    tableTh: {
+      type: Array,
+      default: () => {
+        return [
+          { field: '车牌号', key: 'vehicleNo', width: 100 },
+          { field: '车主姓名', key: 'name', width: 100 },
+          { field: '联系方式', key: 'mobile', width: 100 },
+          { field: '欠费次数(次)', width: 80, key: 'oweCount' },
+          { field: '欠费金额(元)', width: 80, key: 'amtOwe' }
+        ];
+      }
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      totalData: {},
+      tableData: {
+        current: 1,
+        total: 0,
+        list: []
+      },
+      currentDate: [],
+      beginTime: undefined,
+      endTime: undefined
+    };
+  },
+  methods: {
+    tabClick(item) {
+      this.tabCurName = item.value;
+      this.tableData.current = 1;
+			this.getArreasReportTotal();
+			this.getArreasReportList();
+    },
+    getData(data) {
+      if (data.length) {
+        this.beginTime = data[0];
+        this.endTime = data[1];
+      }
+      this.currentDate = data;
+      this.tableData.current = 1;
+      this.getArreasReportTotal();
+      this.getArreasReportList();
+    },
+    getArreasReportTotal() {
+      uni.$u.api.statisticalReportApi
+        .getParkingArrearsReportTotalApi({
+          beginTime: this.beginTime,
+          endTime: this.endTime
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.totalData = res.data;
+          }
+        });
+    },
+    getArreasReportList() {
+      this.loading = true;
+      uni.$u.api.statisticalReportApi
+        .getParkingArrearsReportListApi({
+          beginTime: this.beginTime,
+          endTime: this.endTime,
+          pageNum: this.tableData.current,
+          pageSize: 10
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.tableData.list = res.rows;
+            this.tableData.total = res.total;
+          }
+          this.loading = false;
+        });
+    },
+    pageChange(cur) {
+      this.tableData.current = cur;
+      this.getArreasReportList();
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './report.scss';
+.tab {
+  margin-bottom: 10px;
+}
+</style>
+

+ 114 - 0
pages/statisticalReport/parkModel/components/parkingReallyIncome.vue

@@ -0,0 +1,114 @@
+<!--
+ * @Description: 统计报表 => 停车场实收统计
+ * @Author: 空白格
+ * @Date: 2022-08-03 13:30:32
+ * @LastEditors: 空白格
+ * @LastEditTime: 2022-08-03 13:30:33
+ * @FilePath: \parking_operation\pages\statisticalReport\parkModel\components\parkingReallyIncome.vue
+ * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved. 
+-->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData"
+					@pageChange="pageChange" />
+			</view>
+		</view>
+		<view class="total">
+			<view>
+				停车数量<text>{{ totalData.vehicleCount || 0 }}</text>辆,实收金额<text>{{ totalData.realAmount || 0 }}</text>元
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '停车场名称',
+							width: 120,
+							key: 'parkingName'
+						},
+						{
+							field: '停车数量(次)',
+							width: 120,
+							key: 'vehicleCount'
+						},
+						{
+							field: '实收金额(元)',
+							width: 80,
+							key: 'realAmount'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				loading: false,
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				totalData: {},
+				currentDate: [],
+				beginTime: undefined,
+				endTime: undefined
+			}
+		},
+		methods: {
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				this.getList();
+				this.getTotal();
+			},
+			getList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getParkingReallyIncomeApi({
+					pageNum: this.tableData.current,
+					pageSize: 10,
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			getTotal() {
+				uni.$u.api.statisticalReportApi.getParkingReallyIncomeTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						const { realAmount, vehicleCount } = res.data
+						this.totalData.realAmount = realAmount
+						this.totalData.vehicleCount = vehicleCount
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 113 - 0
pages/statisticalReport/parkModel/components/reallyReceivable.vue

@@ -0,0 +1,113 @@
+<!-- 应收实收分析 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="params.queryDate">{{ params.title }}</view>
+			<view class="table-box">
+				<uni-table emptyText="暂无更多数据" :loading="loading">
+					<!-- 表头行 -->
+					<uni-tr>
+						<uni-th class="table-box-th" align="center" v-for="(item, index) in tableTh" :key="index"
+							:width="item.width || ''">{{ item.field }}
+						</uni-th>
+					</uni-tr>
+					<!-- 表格数据行 -->
+					<uni-tr v-for="(item, index) in tableData.list" :key="index">
+						<uni-td class="table-box-td" align="center" v-for="(field, fIndex) in tableTh" :key="fIndex">
+							{{ item[field.key] }}</uni-td>
+					</uni-tr>
+				</uni-table>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '时间',
+							width: 120,
+							key: 'statisTime'
+						},
+						{
+							field: '应收金额(元)',
+							width: 80,
+							key: 'payAmount'
+						},
+						{
+							field: '实收金额(元)',
+							width: 80,
+							key: 'realAmount'
+						},
+						{
+							field: '逃费金额(元)',
+							width: 80,
+							key: 'runawayAmount'
+						},
+						{
+							field: `“一分钱停车”减免`,
+							width: 120,
+							key: 'oneAmount'
+						},
+						{
+							field: '“八折停车”减免',
+							width: 110,
+							key: 'eightAmount'
+						},
+						{
+							field: '欠费金额(元)',
+							width: 80,
+							key: 'amtOwe'
+						},
+						{
+							field: '退款金额(元)',
+							width: 80,
+							key: 'backAmount'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				currentDate: [],
+				tableData: {
+					list: []
+				},
+				params: {
+					reportType: 2,
+					queryDate: '',
+					title: ''
+				},
+				loading: false
+			}
+		},
+		methods: {
+			tabClick(item) {
+				this.tabCurName = item.value
+				this.getReallyReceivableList()
+			},
+			getData(obj) {
+				this.params = obj
+				this.getReallyReceivableList()
+			},
+			getReallyReceivableList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getParkingReallyReceivableListApi(this.params).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.data.itemList
+					}
+					this.loading = false
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 68 - 0
pages/statisticalReport/parkModel/components/report.scss

@@ -0,0 +1,68 @@
+.table {
+	padding: 19px 15px;
+	background-color: #fff;
+	border-radius: 5px;
+	font-family: PingFangSC-Regular, PingFang SC;
+	&-title {
+		text-align: center;
+		margin-bottom: 10px;
+	}
+	&-date {
+		margin-bottom: 10px;
+		font-size: 14px;
+		color: #434343;
+		text-align: center;
+	}
+	&-search {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 10px;
+		&-item {
+			width: 38%;
+			margin-right: 2%;
+			.input {
+				height: 29px;
+				padding: 0 9px!important;
+			}
+			&:last-child {
+				width: 53px;
+				margin-right: 0;
+				.btn {
+					width: 53px;
+					height: 31px;
+				}
+			}
+		}
+	}
+	&-box {
+		&-th {
+			border-bottom: none;
+			background-color: #EDF3FF;
+			font-size: 12px;
+			color: #434343;
+		}
+
+		&-td {
+			font-size: 12px;
+			color: #434343;
+			word-wrap: break-word;
+		}
+	}
+
+	&-pagination {
+		width: 130px;
+		margin: 20px auto 0;
+	}
+}
+.total {
+	color: #CADDFC;
+	margin-top: 24px;
+	text-align: center;
+	font-size: 14px;
+	line-height: 17px;
+	text {
+		color: #fff;
+		padding: 0 5px;
+	}
+}

+ 144 - 0
pages/statisticalReport/parkModel/components/revenueReport.vue

@@ -0,0 +1,144 @@
+<!-- 营收统计 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData"
+					@pageChange="pageChange" />
+			</view>
+		</view>
+		<view class="total">
+			<view>
+				车辆<text>{{ totalData.vehicleCount || 0 }}</text>辆,应收金额<text>{{ totalData.payAmount || 0 }}</text>元,实收金额<text>{{ totalData.realAmount || 0 }}</text>元,
+				欠费金额<text>{{ totalData.amtOwe || 0 }}</text>元,其中贵州银行快捷支付<text>{{ totalData.quickAmt || 0 }}</text>元,贵州银行聚合支付<text>{{ totalData.unionAmt || 0 }}</text>元,微信支付<text>{{ totalData.wechatAmt || 0 }}</text>元,无感支付<text>{{ totalData.unconsAmt || 0 }}</text>元,现金支付<text>{{ totalData.cashAmt || 0 }}</text>元
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '停车场/路段',
+							width: 120,
+							key: 'roadName'
+						},
+						{
+							field: '车辆(辆)',
+							width: 80,
+							key: 'vehicleCount'
+						},
+						{
+							field: '应收金额(元)',
+							width: 80,
+							key: 'payAmount'
+						},
+						{
+							field: '实收金额(次)',
+							width: 80,
+							key: 'realAmount'
+						},
+						{
+							field: '欠费金额(元)',
+							width: 80,
+							key: 'amtOwe'
+						},
+						{
+							field: '贵州银行快捷支付(元)',
+							width: 150,
+							key: 'quickAmt'
+						},
+						{
+							field: '贵州银行聚合支付(元)',
+							width: 150,
+							key: 'unionAmt'
+						},
+						{
+							field: '微信(元)',
+							width: 80,
+							key: 'wechatAmt'
+						},
+						{
+							field: '无感(元)',
+							width: 80,
+							key: 'unconsAmt'
+						},
+						{
+							field: '现金(元)',
+							width: 80,
+							key: 'cashAmt'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				loading: false,
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				totalData: {},
+				currentDate: [],
+				beginTime: undefined,
+				endTime: undefined
+			}
+		},
+		methods: {
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				this.getIncomeTotal()
+				this.getIncomeList()
+			},
+			getIncomeTotal() {
+				uni.$u.api.statisticalReportApi.getIncomeTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.totalData = res.data
+					}
+				})
+			},
+			getIncomeList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getIncomeListApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime,
+					pageNum: this.tableData.current,
+					pageSize: 10
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			pageChange(cur) {
+				this.tableData.current = cur
+				this.getIncomeList()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 281 - 0
pages/statisticalReport/parkModel/index.vue

@@ -0,0 +1,281 @@
+<!--
+ * @Description: 统计报表 => 停车场模块
+ * @Author: 空白格
+ * @Date: 2022-08-03 11:55:13
+ * @LastEditors: 空白格
+ * @LastEditTime: 2022-08-03 13:51:11
+ * @FilePath: \parking_operation\pages\statisticalReport\parkModel\index.vue
+ * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved. 
+-->
+<template>
+  <view class="report">
+    <view class="report-header">
+      <view class="report-header-left">&nbsp;</view>
+      <view class="report-header-right" v-if="templateKey === 'reallyReceivable'">
+        <view class="tab">
+          <view
+            class="tab-item"
+            v-for="(item, index) in tabList"
+            :key="index"
+            :class="{'active': tabCur === item.value}"
+            @click="tabClick(item)"
+          >{{ item.label }}</view>
+        </view>
+      </view>
+      <view class="report-header-right" v-else>
+        <uni-datetime-picker v-model="curDate" type="daterange" @change="dateChange">
+          <u--text text="日期查询" color="#1767F2"></u--text>
+        </uni-datetime-picker>
+      </view>
+    </view>
+    <view class="report-content">
+      <template v-if="templateKey === 'parkingReallyIncome'">
+        <ParkingReallyIncome ref="parkingReallyIncome"/>
+      </template>
+      <template v-else-if="templateKey === 'arrearsReport'">
+        <ArrearsReport ref="arrearsReport" />
+      </template>
+      <template v-else-if="templateKey === 'revenueReport'">
+        <RevenueReport ref="revenueReport" />
+      </template>
+      <template v-else-if="templateKey === 'reallyReceivable'">
+        <ReallyReceivable ref="reallyReceivable" />
+      </template>
+    </view>
+    <!-- 年 -->
+    <u-picker
+      :show="yearPicker"
+      :columns="yearList"
+      :defaultIndex="defaultYear"
+      @confirm="yearConfirm"
+      @cancel="yearPicker = false"
+    />
+    <!-- 月 -->
+    <u-picker
+      :show="monthPicker"
+      :columns="monthList"
+      :defaultIndex="defaultMonth"
+      @confirm="monthConfirm"
+      @cancel="monthPicker = false"
+    />
+    <!-- 日 -->
+    <u-picker
+      :show="dayPicker"
+      :columns="dayList"
+      :defaultIndex="defaultDay"
+      @confirm="dayConfirm"
+      @cancel="dayPicker = false"
+    />
+  </view>
+</template>
+
+<script>
+import ParkingReallyIncome from './components/parkingReallyIncome.vue';
+import ArrearsReport from './components/arrearsReport.vue';
+import RevenueReport from './components/revenueReport.vue';
+import ReallyReceivable from './components/reallyReceivable.vue';
+export default {
+  components: {
+    ParkingReallyIncome,
+    ArrearsReport,
+    RevenueReport,
+    ReallyReceivable
+  },
+  data() {
+    return {
+      tabList: [
+        {
+          label: '年',
+          value: 2
+        },
+        {
+          label: '月',
+          value: 1
+        },
+        {
+          label: '日',
+          value: 0
+        }
+      ],
+      templateKey: '',
+      // 日期
+      curDate: [],
+      tabCur: 2,
+      // 参数
+      params: {
+        reportType: 2,
+        queryDate: '',
+        title: ''
+      },
+      // 年
+      yearPicker: false,
+      yearList: this.getYearList(),
+      defaultYear: [4],
+      currentYear: '',
+      yearObj: {},
+      // 月
+      monthPicker: false,
+      monthList: this.getMonthList(),
+      defaultMonth: [],
+      currentMonth: '01',
+      monthObj: {},
+      // 日
+      dayPicker: false,
+      dayList: this.getDayList(),
+      defaultDay: [],
+      currentDay: '01',
+      dayObj: {}
+    };
+  },
+  onLoad(options) {
+    uni.setNavigationBarTitle({
+      title: options.title || '路段报表'
+    });
+    this.templateKey = options.key;
+    console.log(this.templateKey);
+  },
+  onShow() {
+    if (
+      this.templateKey === 'revenueReport' ||
+      this.templateKey === 'reallyReceivable'
+    ) {
+      let today = uni.$u.timeFormat(new Date(), 'yyyy-mm-dd');
+      this.curDate = [today, today];
+    } else {
+      this.curDate = [];
+    }
+    this.$nextTick(() => {
+      if (this.templateKey === 'reallyReceivable') {
+        this.currentYear = this.yearList[0][4].value;
+        this.yearObj = this.yearList[0][4];
+        this.params.title = this.yearList[0][4].text;
+        this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`;
+        this.$refs[this.templateKey].getData(this.params);
+      } else {
+        this.$refs[this.templateKey].getData(this.curDate);
+      }
+    });
+  },
+  methods: {
+    getYearList() {
+      const date = new Date();
+      const year = date.getFullYear();
+      const list = [[]];
+      for (let i = year - 4; i < year + 1; i++) {
+        const obj = {
+          text: String(i),
+          value: String(i)
+        };
+        list[0].push(obj);
+      }
+      return list;
+    },
+    getMonthList() {
+      const date = new Date();
+      const month = date.getMonth();
+      const list = [[]];
+      for (let i = 1; i < 13; i++) {
+        const obj = {
+          text: String(i),
+          value: String(i)
+        };
+        if (i < 10) {
+          obj.text = '0' + i;
+          obj.value = '0' + i;
+        }
+        list[0].push(obj);
+      }
+      setTimeout(() => {
+        this.defaultMonth = [0];
+      }, 1000);
+      return list;
+    },
+    getDayList() {
+      const date = new Date();
+      const year = date.getFullYear();
+      let month = date.getMonth();
+      if (this.monthObj) {
+        month = parseInt(this.monthObj.value);
+        month = String(month);
+      }
+      const day = date.getDate();
+      const dayLen = new Date(year, month, 0).getDate();
+      const list = [[]];
+      for (let i = 1; i < dayLen + 1; i++) {
+        const obj = {
+          text: String(i),
+          value: String(i)
+        };
+        if (i < 10) {
+          obj.text = '0' + i;
+          obj.value = '0' + i;
+        }
+        list[0].push(obj);
+      }
+      setTimeout(() => {
+        this.defaultDay = [0];
+      }, 1000);
+      return list;
+    },
+    tabClick(item) {
+      this.tabCur = item.value;
+      switch (item.value) {
+        case 2:
+          this.yearPicker = true;
+          break;
+        case 1:
+          this.monthPicker = true;
+          break;
+        case 0:
+          this.dayPicker = true;
+          break;
+      }
+      this.params.reportType = this.tabCur;
+    },
+    dateChange(e) {
+      this.curDate = e;
+      this.$refs[this.templateKey].getData(this.curDate);
+    },
+    yearConfirm(e) {
+      this.defaultYear = [e.indexs[0]];
+      this.currentYear = e.value[0].value;
+      this.params.title = e.value[0].text;
+      this.yearObj = e.value[0];
+      this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`;
+      this.$refs[this.templateKey].getData(this.params);
+      this.yearPicker = false;
+    },
+    monthConfirm(e) {
+      this.defaultMonth = [e.indexs[0]];
+      this.currentMonth = e.value[0].value;
+      this.monthObj = e.value[0];
+      this.params.title = `${this.yearObj.text}-${this.monthObj.text}`;
+      this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`;
+      this.$refs[this.templateKey].getData(this.params);
+      this.monthPicker = false;
+      this.dayList = this.getDayList();
+    },
+    dayConfirm(e) {
+      this.defaultDay = [e.indexs[0]];
+      this.title = e.value[0].text;
+      this.currentDay = e.value[0].value;
+      this.dayObj = e.value[0];
+      this.params.title = `${this.yearObj.text}-${this.monthObj.text}-${this.dayObj.text}`;
+      this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`;
+      this.$refs[this.templateKey].getData(this.params);
+      this.dayPicker = false;
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+page {
+  background-color: #1767f2;
+  min-height: calc(100vh - 44px);
+}
+</style>
+
+<style lang="scss" scoped>
+@import './../styles/report.scss';
+</style>

+ 120 - 0
pages/statisticalReport/roadModel/components/arrearsReport.vue

@@ -0,0 +1,120 @@
+<!-- 欠费统计 -->
+<template>
+  <view class="container">
+    <view class="table">
+      <view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+      <view class="table-box">
+        <TableRanking
+          :loading="loading"
+          :padding="'0'"
+          :tableTh="tableTh"
+          :tableData="tableData"
+          @pageChange="pageChange"
+        />
+      </view>
+    </view>
+    <view class="total">
+      <view>
+        欠费次数
+        <text>{{ totalData.oweCount || 0 }}</text>次,欠费金额
+        <text>{{ totalData.amtOwe || 0 }}</text>元
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import TableRanking from '@/components/tableRanking.vue';
+export default {
+  components: {
+    TableRanking
+  },
+  props: {
+    tableTh: {
+      type: Array,
+      default: () => {
+        return [
+          { field: '车牌号', key: 'vehicleNo', width: 100 },
+          { field: '车主姓名', key: 'name', width: 100 },
+          { field: '联系方式', key: 'mobile', width: 100 },
+          { field: '欠费次数(次)', width: 80, key: 'oweCount' },
+          { field: '欠费金额(元)', width: 80, key: 'amtOwe' }
+        ];
+      }
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      totalData: {},
+      tableData: {
+        current: 1,
+        total: 0,
+        list: []
+      },
+      currentDate: [],
+      beginTime: undefined,
+      endTime: undefined
+    };
+  },
+  methods: {
+    tabClick(item) {
+      this.tabCurName = item.value;
+      this.tableData.current = 1;
+			this.getArreasReportTotal();
+			this.getArreasReportList();
+    },
+    getData(data) {
+      if (data.length) {
+        this.beginTime = data[0];
+        this.endTime = data[1];
+      }
+      this.currentDate = data;
+      this.tableData.current = 1;
+      this.getArreasReportTotal();
+      this.getArreasReportList();
+    },
+    getArreasReportTotal() {
+      uni.$u.api.statisticalReportApi
+        .getArrearsReportTotalApi({
+          beginTime: this.beginTime,
+          endTime: this.endTime
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.totalData = res.data;
+          }
+        });
+    },
+    getArreasReportList() {
+      this.loading = true;
+      uni.$u.api.statisticalReportApi
+        .getArrearsReportListApi({
+          beginTime: this.beginTime,
+          endTime: this.endTime,
+          pageNum: this.tableData.current,
+          pageSize: 10
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.tableData.list = res.rows;
+            this.tableData.total = res.total;
+          }
+          this.loading = false;
+        });
+    },
+    pageChange(cur) {
+      this.tableData.current = cur;
+      this.getArreasReportList();
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './report.scss';
+.tab {
+  margin-bottom: 10px;
+}
+</style>
+

+ 113 - 0
pages/statisticalReport/roadModel/components/reallyReceivable.vue

@@ -0,0 +1,113 @@
+<!-- 应收实收分析 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="params.queryDate">{{ params.title }}</view>
+			<view class="table-box">
+				<uni-table emptyText="暂无更多数据" :loading="loading">
+					<!-- 表头行 -->
+					<uni-tr>
+						<uni-th class="table-box-th" align="center" v-for="(item, index) in tableTh" :key="index"
+							:width="item.width || ''">{{ item.field }}
+						</uni-th>
+					</uni-tr>
+					<!-- 表格数据行 -->
+					<uni-tr v-for="(item, index) in tableData.list" :key="index">
+						<uni-td class="table-box-td" align="center" v-for="(field, fIndex) in tableTh" :key="fIndex">
+							{{ item[field.key] }}</uni-td>
+					</uni-tr>
+				</uni-table>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '时间',
+							width: 120,
+							key: 'statisTime'
+						},
+						{
+							field: '应收金额(元)',
+							width: 80,
+							key: 'payAmount'
+						},
+						{
+							field: '实收金额(元)',
+							width: 80,
+							key: 'realAmount'
+						},
+						{
+							field: '逃费金额(元)',
+							width: 80,
+							key: 'runawayAmount'
+						},
+						{
+							field: `“一分钱停车”减免`,
+							width: 120,
+							key: 'oneAmount'
+						},
+						{
+							field: '“八折停车”减免',
+							width: 110,
+							key: 'eightAmount'
+						},
+						{
+							field: '欠费金额(元)',
+							width: 80,
+							key: 'amtOwe'
+						},
+						{
+							field: '退款金额(元)',
+							width: 80,
+							key: 'backAmount'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				currentDate: [],
+				tableData: {
+					list: []
+				},
+				params: {
+					reportType: 2,
+					queryDate: '',
+					title: ''
+				},
+				loading: false
+			}
+		},
+		methods: {
+			tabClick(item) {
+				this.tabCurName = item.value
+				this.getReallyReceivableList()
+			},
+			getData(obj) {
+				this.params = obj
+				this.getReallyReceivableList()
+			},
+			getReallyReceivableList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getReallyReceivableListApi(this.params).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.data.itemList
+					}
+					this.loading = false
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 141 - 0
pages/statisticalReport/roadModel/components/recoveryReport.vue

@@ -0,0 +1,141 @@
+<!--
+ * @Description: 统计报表 => 追缴统计(路段)
+ * @Author: 空白格
+ * @Date: 2022-08-03 11:21:31
+ * @LastEditors: 空白格
+ * @LastEditTime: 2022-08-03 11:46:05
+ * @FilePath: \parking_operation\pages\statisticalReport\roadModel\components\recoveryReport.vue
+ * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved. 
+-->
+<template>
+  <view class="container">
+    <view class="table">
+      <view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+      <view class="table-box">
+        <TableRanking
+          :loading="loading"
+          :padding="'0'"
+          :tableTh="tableTh"
+          :tableData="tableData"
+          @pageChange="pageChange"
+        />
+      </view>
+    </view>
+    <view class="total">
+      <view>
+        数据统计,收费员共
+        <text>{{ totalData.dataCount || 0 }}</text>人,累计追缴
+        <text>{{ totalData.pursueCount || 0 }}</text>次,其中追缴现金金额
+        <text>{{ totalData.cashAmt || 0 }}</text>元,追缴非现金金额
+        <text>{{ totalData.otherAmount || 0 }}</text>元,追缴总额共计
+        <text>{{ totalData.quickAmt || 0 }}</text>元
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import TableRanking from '@/components/tableRanking.vue';
+export default {
+  components: {
+    TableRanking
+  },
+  props: {
+    tableTh: {
+      type: Array,
+      default: () => {
+        return [
+          {
+            field: '收费员',
+            width: 120,
+            key: 'payeeName'
+          },
+          {
+            field: '追缴次数',
+            width: 80,
+            key: 'pursueCount'
+          },
+          {
+            field: '追缴现金金额(元)',
+            width: 80,
+            key: 'cashAmt'
+          },
+          {
+            field: '追缴非现金金额(元)',
+            width: 80,
+            key: 'otherAmount'
+          },
+          {
+            field: '追缴总额(元)',
+            width: 80,
+            key: 'totalAmt'
+          }
+        ];
+      }
+    }
+  },
+  data() {
+    return {
+      loading: false,
+      tableData: {
+        current: 1,
+        total: 0,
+        list: []
+      },
+      totalData: {},
+      currentDate: [],
+      beginTime: undefined,
+      endTime: undefined
+    };
+  },
+  methods: {
+    getData(data) {
+      if (data.length) {
+        this.beginTime = data[0];
+        this.endTime = data[1];
+      }
+      this.currentDate = data;
+      this.tableData.current = 1;
+      this.getIncomeTotal();
+      this.getIncomeList();
+    },
+    getIncomeTotal() {
+      uni.$u.api.statisticalReportApi
+        .getRecoverySumReportApi({
+          beginTime: this.beginTime,
+          endTime: this.endTime
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.totalData = res.data;
+          }
+        });
+    },
+    getIncomeList() {
+      this.loading = true;
+      uni.$u.api.statisticalReportApi
+        .getRecoveryReportApi({
+          beginTime: this.beginTime,
+          endTime: this.endTime,
+          pageNum: this.tableData.current,
+          pageSize: 10
+        })
+        .then((res) => {
+          if (res.code === 200) {
+            this.tableData.list = res.rows;
+            this.tableData.total = res.total;
+          }
+          this.loading = false;
+        });
+    },
+    pageChange(cur) {
+      this.tableData.current = cur;
+      this.getIncomeList();
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+@import './report.scss';
+</style>

+ 68 - 0
pages/statisticalReport/roadModel/components/report.scss

@@ -0,0 +1,68 @@
+.table {
+	padding: 19px 15px;
+	background-color: #fff;
+	border-radius: 5px;
+	font-family: PingFangSC-Regular, PingFang SC;
+	&-title {
+		text-align: center;
+		margin-bottom: 10px;
+	}
+	&-date {
+		margin-bottom: 10px;
+		font-size: 14px;
+		color: #434343;
+		text-align: center;
+	}
+	&-search {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 10px;
+		&-item {
+			width: 38%;
+			margin-right: 2%;
+			.input {
+				height: 29px;
+				padding: 0 9px!important;
+			}
+			&:last-child {
+				width: 53px;
+				margin-right: 0;
+				.btn {
+					width: 53px;
+					height: 31px;
+				}
+			}
+		}
+	}
+	&-box {
+		&-th {
+			border-bottom: none;
+			background-color: #EDF3FF;
+			font-size: 12px;
+			color: #434343;
+		}
+
+		&-td {
+			font-size: 12px;
+			color: #434343;
+			word-wrap: break-word;
+		}
+	}
+
+	&-pagination {
+		width: 130px;
+		margin: 20px auto 0;
+	}
+}
+.total {
+	color: #CADDFC;
+	margin-top: 24px;
+	text-align: center;
+	font-size: 14px;
+	line-height: 17px;
+	text {
+		color: #fff;
+		padding: 0 5px;
+	}
+}

+ 144 - 0
pages/statisticalReport/roadModel/components/revenueReport.vue

@@ -0,0 +1,144 @@
+<!-- 营收统计 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData"
+					@pageChange="pageChange" />
+			</view>
+		</view>
+		<view class="total">
+			<view>
+				车辆<text>{{ totalData.vehicleCount || 0 }}</text>辆,应收金额<text>{{ totalData.payAmount || 0 }}</text>元,实收金额<text>{{ totalData.realAmount || 0 }}</text>元,
+				欠费金额<text>{{ totalData.amtOwe || 0 }}</text>元,其中贵州银行快捷支付<text>{{ totalData.quickAmt || 0 }}</text>元,贵州银行聚合支付<text>{{ totalData.unionAmt || 0 }}</text>元,微信支付<text>{{ totalData.wechatAmt || 0 }}</text>元,无感支付<text>{{ totalData.unconsAmt || 0 }}</text>元,现金支付<text>{{ totalData.cashAmt || 0 }}</text>元
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '停车场/路段',
+							width: 120,
+							key: 'roadName'
+						},
+						{
+							field: '车辆(辆)',
+							width: 80,
+							key: 'vehicleCount'
+						},
+						{
+							field: '应收金额(元)',
+							width: 80,
+							key: 'payAmount'
+						},
+						{
+							field: '实收金额(次)',
+							width: 80,
+							key: 'realAmount'
+						},
+						{
+							field: '欠费金额(元)',
+							width: 80,
+							key: 'amtOwe'
+						},
+						{
+							field: '贵州银行快捷支付(元)',
+							width: 150,
+							key: 'quickAmt'
+						},
+						{
+							field: '贵州银行聚合支付(元)',
+							width: 150,
+							key: 'unionAmt'
+						},
+						{
+							field: '微信(元)',
+							width: 80,
+							key: 'wechatAmt'
+						},
+						{
+							field: '无感(元)',
+							width: 80,
+							key: 'unconsAmt'
+						},
+						{
+							field: '现金(元)',
+							width: 80,
+							key: 'cashAmt'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				loading: false,
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				totalData: {},
+				currentDate: [],
+				beginTime: undefined,
+				endTime: undefined
+			}
+		},
+		methods: {
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				this.getIncomeTotal()
+				this.getIncomeList()
+			},
+			getIncomeTotal() {
+				uni.$u.api.statisticalReportApi.getIncomeTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.totalData = res.data
+					}
+				})
+			},
+			getIncomeList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getIncomeListApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime,
+					pageNum: this.tableData.current,
+					pageSize: 10
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			pageChange(cur) {
+				this.tableData.current = cur
+				this.getIncomeList()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 118 - 0
pages/statisticalReport/roadModel/components/sectionBerth.vue

@@ -0,0 +1,118 @@
+<!-- 路段泊位统计 -->
+<template>
+	<view class="container">
+		<view class="table">
+			<view class="table-date" v-if="currentDate">{{ currentDate.join(' 至 ') }}</view>
+			<view class="table-box">
+				<TableRanking :loading="loading" :padding="'0'" :tableTh="tableTh" :tableData="tableData"
+					@pageChange="pageChange" />
+			</view>
+		</view>
+		<view class="total">
+			<view>
+				停车数量<text>{{ totalData.vehicleCount || 0 }}</text>辆,实收金额<text>{{ totalData.realAmount || 0 }}</text>元
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import TableRanking from '@/components/tableRanking.vue'
+	export default {
+		components: {
+			TableRanking
+		},
+		props: {
+			tableTh: {
+				type: Array,
+				default: () => {
+					return [{
+							field: '路段名称',
+							key: 'roadName'
+						},
+						{
+							field: '所属泊位',
+							key: 'spaceName'
+						},
+						{
+							field: '停车数量(次)',
+							width: 80,
+							key: 'vehicleCount'
+						},
+						{
+							field: '实收金额(元)',
+							width: 80,
+							key: 'realAmount'
+						}
+					]
+				}
+			}
+		},
+		data() {
+			return {
+				beginTime: '',
+				endTime: '',
+				totalData: {},
+				tableData: {
+					current: 1,
+					total: 0,
+					list: []
+				},
+				currentDate: [],
+				loading: false
+			}
+		},
+		methods: {
+			getData(data) {
+				if (data.length) {
+					this.beginTime = data[0]
+					this.endTime = data[1]
+				} else {
+					this.beginTime = undefined
+					this.endTime = undefined
+				}
+				this.currentDate = data
+				this.tableData.current = 1
+				this.getRoadSpaceTotal()
+				this.getRoadSpaceList()
+			},
+			getRoadSpaceTotal() {
+				uni.$u.api.statisticalReportApi.getRoadSpaceTotalApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime
+				}).then(res => {
+					if (res.code === 200) {
+						this.totalData = res.data
+					}
+				})
+			},
+			getRoadSpaceList() {
+				this.loading = true
+				uni.$u.api.statisticalReportApi.getRoadSpaceListApi({
+					beginTime: this.beginTime,
+					endTime: this.endTime,
+					pageNum: this.tableData.current,
+					pageSize: 10
+				}).then(res => {
+					if (res.code === 200) {
+						this.tableData.list = res.rows;
+						this.tableData.total = res.total
+					}
+					this.loading = false
+				})
+			},
+			/**
+			 * 分页切换
+			 * @param { Number } cur
+			 */
+			pageChange(cur) {
+				this.tableData.current = cur
+				this.getRoadSpaceList()
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	@import './report.scss';
+</style>

+ 286 - 0
pages/statisticalReport/roadModel/index.vue

@@ -0,0 +1,286 @@
+<!--
+ * @Description: 统计报表 => 路段模块
+ * @Author: 空白格
+ * @Date: 2022-08-03 09:26:29
+ * @LastEditors: 空白格
+ * @LastEditTime: 2022-08-03 12:00:19
+ * @FilePath: \parking_operation\pages\statisticalReport\roadModel\index.vue
+ * @Copyright: Copyright (c) 2016~2022 by 空白格, All Rights Reserved. 
+-->
+<!-- 统计报表 -->
+<template>
+  <view class="report">
+    <view class="report-header">
+      <view class="report-header-left">&nbsp;</view>
+      <view class="report-header-right" v-if="templateKey === 'reallyReceivable'">
+        <view class="tab">
+          <view
+            class="tab-item"
+            v-for="(item, index) in tabList"
+            :key="index"
+            :class="{'active': tabCur === item.value}"
+            @click="tabClick(item)"
+          >{{ item.label }}</view>
+        </view>
+      </view>
+      <view class="report-header-right" v-else>
+        <uni-datetime-picker v-model="curDate" type="daterange" @change="dateChange">
+          <u--text text="日期查询" color="#1767F2"></u--text>
+        </uni-datetime-picker>
+      </view>
+    </view>
+    <view class="report-content">
+      <template v-if="templateKey === 'sectionBerth'">
+        <SectionBerth ref="sectionBerth" />
+      </template>
+      <template v-else-if="templateKey === 'arrearsReport'">
+        <ArrearsReport ref="arrearsReport" />
+      </template>
+      <template v-else-if="templateKey === 'revenueReport'">
+        <RevenueReport ref="revenueReport" />
+      </template>
+      <template v-else-if="templateKey === 'reallyReceivable'">
+        <ReallyReceivable ref="reallyReceivable" />
+      </template>
+      <template v-else-if="templateKey === 'recoveryReport'">
+        <RecoveryReport ref="recoveryReport" />
+      </template>
+    </view>
+    <!-- 年 -->
+    <u-picker
+      :show="yearPicker"
+      :columns="yearList"
+      :defaultIndex="defaultYear"
+      @confirm="yearConfirm"
+      @cancel="yearPicker = false"
+    />
+    <!-- 月 -->
+    <u-picker
+      :show="monthPicker"
+      :columns="monthList"
+      :defaultIndex="defaultMonth"
+      @confirm="monthConfirm"
+      @cancel="monthPicker = false"
+    />
+    <!-- 日 -->
+    <u-picker
+      :show="dayPicker"
+      :columns="dayList"
+      :defaultIndex="defaultDay"
+      @confirm="dayConfirm"
+      @cancel="dayPicker = false"
+    />
+  </view>
+</template>
+
+<script>
+import SectionBerth from './components/sectionBerth.vue';
+import ArrearsReport from './components/arrearsReport.vue';
+import RevenueReport from './components/revenueReport.vue';
+import ReallyReceivable from './components/reallyReceivable.vue';
+import RecoveryReport from './components/recoveryReport.vue';
+export default {
+  components: {
+    SectionBerth,
+    ArrearsReport,
+    RevenueReport,
+    ReallyReceivable,
+    RecoveryReport
+  },
+  data() {
+    return {
+      tabList: [
+        {
+          label: '年',
+          value: 2
+        },
+        {
+          label: '月',
+          value: 1
+        },
+        {
+          label: '日',
+          value: 0
+        }
+      ],
+      templateKey: '',
+      // 日期
+      curDate: [],
+      tabCur: 2,
+      // 参数
+      params: {
+        reportType: 2,
+        queryDate: '',
+        title: ''
+      },
+      // 年
+      yearPicker: false,
+      yearList: this.getYearList(),
+      defaultYear: [4],
+      currentYear: '',
+      yearObj: {},
+      // 月
+      monthPicker: false,
+      monthList: this.getMonthList(),
+      defaultMonth: [],
+      currentMonth: '01',
+      monthObj: {},
+      // 日
+      dayPicker: false,
+      dayList: this.getDayList(),
+      defaultDay: [],
+      currentDay: '01',
+      dayObj: {}
+    };
+  },
+  onLoad(options) {
+    uni.setNavigationBarTitle({
+      title: options.title || '路段报表'
+    });
+    this.templateKey = options.key;
+  },
+  onShow() {
+    if (
+      this.templateKey === 'revenueReport' ||
+      this.templateKey === 'reallyReceivable'
+    ) {
+      let today = uni.$u.timeFormat(new Date(), 'yyyy-mm-dd');
+      this.curDate = [today, today];
+    } else {
+      this.curDate = [];
+    }
+    this.$nextTick(() => {
+      if (this.templateKey === 'reallyReceivable') {
+        this.currentYear = this.yearList[0][4].value;
+        this.yearObj = this.yearList[0][4];
+        this.params.title = this.yearList[0][4].text;
+        this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`;
+        this.$refs[this.templateKey].getData(this.params);
+      } else {
+        this.$refs[this.templateKey].getData(this.curDate);
+      }
+    });
+  },
+  methods: {
+    getYearList() {
+      const date = new Date();
+      const year = date.getFullYear();
+      const list = [[]];
+      for (let i = year - 4; i < year + 1; i++) {
+        const obj = {
+          text: String(i),
+          value: String(i)
+        };
+        list[0].push(obj);
+      }
+      return list;
+    },
+    getMonthList() {
+      const date = new Date();
+      const month = date.getMonth();
+      const list = [[]];
+      for (let i = 1; i < 13; i++) {
+        const obj = {
+          text: String(i),
+          value: String(i)
+        };
+        if (i < 10) {
+          obj.text = '0' + i;
+          obj.value = '0' + i;
+        }
+        list[0].push(obj);
+      }
+      setTimeout(() => {
+        this.defaultMonth = [0];
+      }, 1000);
+      return list;
+    },
+    getDayList() {
+      const date = new Date();
+      const year = date.getFullYear();
+      let month = date.getMonth();
+      if (this.monthObj) {
+        month = parseInt(this.monthObj.value);
+        month = String(month);
+      }
+      const day = date.getDate();
+      const dayLen = new Date(year, month, 0).getDate();
+      const list = [[]];
+      for (let i = 1; i < dayLen + 1; i++) {
+        const obj = {
+          text: String(i),
+          value: String(i)
+        };
+        if (i < 10) {
+          obj.text = '0' + i;
+          obj.value = '0' + i;
+        }
+        list[0].push(obj);
+      }
+      setTimeout(() => {
+        this.defaultDay = [0];
+      }, 1000);
+      return list;
+    },
+    tabClick(item) {
+      this.tabCur = item.value;
+      switch (item.value) {
+        case 2:
+          this.yearPicker = true;
+          break;
+        case 1:
+          this.monthPicker = true;
+          break;
+        case 0:
+          this.dayPicker = true;
+          break;
+      }
+      this.params.reportType = this.tabCur;
+    },
+    dateChange(e) {
+      this.curDate = e;
+      this.$refs[this.templateKey].getData(this.curDate);
+    },
+    yearConfirm(e) {
+      this.defaultYear = [e.indexs[0]];
+      this.currentYear = e.value[0].value;
+      this.params.title = e.value[0].text;
+      this.yearObj = e.value[0];
+      this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`;
+      this.$refs[this.templateKey].getData(this.params);
+      this.yearPicker = false;
+    },
+    monthConfirm(e) {
+      this.defaultMonth = [e.indexs[0]];
+      this.currentMonth = e.value[0].value;
+      this.monthObj = e.value[0];
+      this.params.title = `${this.yearObj.text}-${this.monthObj.text}`;
+      this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`;
+      this.$refs[this.templateKey].getData(this.params);
+      this.monthPicker = false;
+      this.dayList = this.getDayList();
+    },
+    dayConfirm(e) {
+      this.defaultDay = [e.indexs[0]];
+      this.title = e.value[0].text;
+      this.currentDay = e.value[0].value;
+      this.dayObj = e.value[0];
+      this.params.title = `${this.yearObj.text}-${this.monthObj.text}-${this.dayObj.text}`;
+      this.params.queryDate = `${this.currentYear}-${this.currentMonth}-${this.currentDay}`;
+      this.$refs[this.templateKey].getData(this.params);
+      this.dayPicker = false;
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+page {
+  background-color: #1767f2;
+  min-height: calc(100vh - 44px);
+}
+</style>
+
+<style lang="scss" scoped>
+@import './../styles/report.scss';
+</style>

+ 49 - 0
pages/statisticalReport/styles/report.scss

@@ -0,0 +1,49 @@
+.report {
+	padding: 15px;
+	font-family: PingFangSC-Regular, PingFang SC;
+	&-header {
+		background-color: #fff;
+		border-radius: 5px;
+		padding: 15px;
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 10px;
+		&-left {
+			display: flex;
+			align-items: center;
+			text {
+				margin-left: 5px;
+				color: #434343;
+				font-size: 15px;
+			}
+		}
+		&-right {
+			.tab {
+				display: flex;
+				border: solid 1px #1767F2;
+				&-item {
+					width: 40px;
+					height: 28px;
+					line-height: 28px;
+					text-align: center;
+					border-right: solid 1px #1767F2;
+					color: #1767F2;
+					font-size: 16px;
+					&:last-child {
+						border-right: none;
+					}
+				}
+				.active {
+					background-color: #1767f2;
+					color: #fff;
+				}
+			}
+		}
+	}
+	&-content {
+		// padding: 19px 15px;
+		// background-color: #fff;
+		// border-radius: 5px;
+	}
+}

File diff suppressed because it is too large
+ 23 - 10
static/icons/operationalAnalysisIcons/parking-lot-analysis-icon.svg


File diff suppressed because it is too large
+ 21 - 0
static/icons/statisticalReportIcons/parking-lot-income-icon.svg


File diff suppressed because it is too large
+ 21 - 0
static/icons/statisticalReportIcons/really-receivable-icon.svg


File diff suppressed because it is too large
+ 21 - 0
static/icons/statisticalReportIcons/recovery-report-icon.svg


File diff suppressed because it is too large
+ 21 - 0
static/icons/statisticalReportIcons/section-berth-icon.svg