Bläddra i källkod

Merge branch 'dev-2.19.0' of http://101.36.160.140:21044/province-vue-qh/province-vue-all into dev-2.19.0

* 'dev-2.19.0' of http://101.36.160.140:21044/province-vue-qh/province-vue-all:
  视频相关
  视频相关
  视频相关
  视频相关
  视频相关
  视频相关
  视频相关
  fix:bug
  视频相关
  视频相关
  视频相关
  视频相关
  视频相关
  视频相关
wzq 4 månader sedan
förälder
incheckning
fbf3c98fe1

+ 5 - 1
src/api/previewPlayback/index.js

@@ -11,5 +11,9 @@ export const controlling = (data) => {
11 11
 }
12 12
 
13 13
 export const getPlayback = (data) => {
14
-	return request('/getPlayback', data, 'get')
14
+	return request('/getPlayback', data, 'post')
15
+}
16
+
17
+export const manualCapture = (data) => {
18
+	return request('/manualCapture', data, 'get')
15 19
 }

+ 96 - 15
src/components/video/Live.vue

@@ -1,11 +1,12 @@
1 1
 <!-- 实时视频监控 -->
2 2
 <script setup>
3
-	import { getPreview, controlling } from '@/api/previewPlayback'
3
+	import { getPreview, controlling, manualCapture } from '@/api/previewPlayback'
4 4
 	import { useRoute } from 'vue-router'
5 5
 	import commonSelect from '@/components/CommonSelector/index.vue'
6 6
 	import api from '@/api/orgInfo/info'
7 7
 	import cameraApi from '@/api/camera/index'
8 8
 	import { message } from 'ant-design-vue'
9
+	import { downloadLink } from '@/utils/systemUtils'
9 10
 
10 11
 	const activeKey = ref('1')
11 12
 	const route = useRoute()
@@ -21,6 +22,7 @@
21 22
 	let videoMap = {}
22 23
 	let currentWindowIndex = 0
23 24
 	const mode = 0 // 0 普通模式  1 高级模式
25
+	const isActive = ref(false)
24 26
 
25 27
 	const init = () => {
26 28
 		window.addEventListener('resize', () => {
@@ -59,7 +61,7 @@
59 61
 	const createPlayer = () => {
60 62
 		player.value = new window.JSPlugin({
61 63
 			szId: 'player',
62
-			szBasePath: './',
64
+			szBasePath: '/h5player/',
63 65
 			iMaxSplit: 4,
64 66
 			iCurrentSplit: parseInt(splitNum.value),
65 67
 			openDebug: true,
@@ -193,8 +195,10 @@
193 195
 	}
194 196
 
195 197
 	const doControl = (command, action = 0, speed = 50, presetIndex = 10) => {
198
+		console.log('do control 2', command)
196 199
 		if (videoMap[currentWindowIndex]) {
197 200
 			const data = videoMap[currentWindowIndex]
201
+			const cameraId = data.cameraId
198 202
 			const c = findCameraByCameraId(cameraId)
199 203
 			if (c.cameraType !== '1') {
200 204
 				return message.warning('该操作必须是球形摄像机')
@@ -212,6 +216,23 @@
212 216
 		}
213 217
 	}
214 218
 
219
+	const circle = () => {
220
+		if (isActive.value) {
221
+			doControl('LEFT', 1)
222
+		} else {
223
+			doControl('LEFT', 0)
224
+		}
225
+		isActive.value = !isActive.value
226
+	}
227
+
228
+	const doControl1 = (command) => {
229
+		console.log('do control 1', command)
230
+		doControl(command, 0)
231
+		setTimeout(() => {
232
+			doControl(command, 1)
233
+		}, 2000)
234
+	}
235
+
215 236
 	const startTrack = () => {
216 237
 		doControl('START_TRACK', 0)
217 238
 	}
@@ -220,6 +241,30 @@
220 241
 		doControl('STOP_TRACK', 1)
221 242
 	}
222 243
 
244
+	const captureOne = (i = null) => {
245
+		console.log('ready capture one')
246
+		if (i == null) {
247
+			i = currentWindowIndex
248
+		}
249
+		if (videoMap[i]) {
250
+			const data = videoMap[i]
251
+			const cameraIndexCode = data.cameraIndexCode
252
+			manualCapture({ cameraIndexCode }).then((url) => {
253
+				console.log('capture url', url)
254
+				downloadLink(url)
255
+			})
256
+		} else {
257
+			return message.warning('请选择播放中的窗口')
258
+		}
259
+	}
260
+
261
+	const captureAll = () => {
262
+		let i = 0
263
+		for (const _ of Object.values(videoMap)) {
264
+			captureOne(i++)
265
+		}
266
+	}
267
+
223 268
 	const orgSelect = (orgId, event) => {
224 269
 		const org = event.node
225 270
 		cameraListData.value = []
@@ -247,7 +292,7 @@
247 292
 				}
248 293
 			]
249 294
 			list.forEach((d) => {
250
-				const type = d.cameraType
295
+				const type = d.live
251 296
 				const temp = {
252 297
 					title: d.cameraName,
253 298
 					key: d.cameraId,
@@ -273,9 +318,9 @@
273 318
 		console.log('选择摄像头', camera)
274 319
 		const { cameraIndexCode } = camera
275 320
 		getPreview({ cameraIndexCode, protocol: 'WS' }).then((resp) => {
276
-			if (!resp || !resp.data || !resp.data.url) return message.error('无法获取视频地址')
277
-			const url = resp.data.url
278
-			const exists = Object.values(videoMap).findIndex((u) => u.url === url)
321
+			if (!resp || !resp.url) return message.error('无法获取视频地址')
322
+			const url = resp.url
323
+			const exists = Object.values(videoMap).findIndex((u) => u.cameraIndexCode === cameraIndexCode)
279 324
 			if (exists >= 0) {
280 325
 				return message.warning(`该视频已经在 ${exists + 1} 窗口播放`)
281 326
 			}
@@ -283,7 +328,7 @@
283 328
 				.then((_) => {
284 329
 					videoMap[currentWindowIndex] = {
285 330
 						url,
286
-						cameraIndexCode: n.cameraIndexCode,
331
+						cameraIndexCode,
287 332
 						cameraId
288 333
 					}
289 334
 				})
@@ -335,11 +380,11 @@
335 380
 						<a-button type="primary" class="btn">中止轮巡</a-button>
336 381
 					</div>
337 382
 					<div class="row">
338
-						<a-button type="primary" class="mr-5 btn">窗口抓图</a-button>
383
+						<a-button type="primary" class="mr-5 btn" @click="captureOne(null)">窗口抓图</a-button>
339 384
 						<a-button type="primary" class="btn" @click="stopPlay">窗口关闭</a-button>
340 385
 					</div>
341 386
 					<div class="row">
342
-						<a-button type="primary" class="mr-5 btn">全部抓图</a-button>
387
+						<a-button type="primary" class="mr-5 btn" @click="captureAll()">全部抓图</a-button>
343 388
 						<a-button type="primary" class="btn" @click="stopAllPlay">全部关闭</a-button>
344 389
 					</div>
345 390
 					<div v-if="hasPerm(['controlCloud'])" class="flex flex-col">
@@ -366,10 +411,15 @@
366 411
 							>
367 412
 								<div class="control-row">
368 413
 									<template v-for="item in list">
369
-										<a-button v-if="item.code !== 'GOTO_PRESET'" :key="item.code" class="small-btn"
414
+										<a-button
415
+											v-if="item.code !== 'GOTO_PRESET'"
416
+											:key="item.code"
417
+											class="small-btn"
418
+											@mousedown="doControl(item.code, 0)"
419
+											@mouseup="doControl(item.code, 1)"
370 420
 											>{{ item.label }}
371 421
 										</a-button>
372
-										<a-button v-else class="small-btn">
422
+										<a-button v-else class="small-btn" :class="{ 'active-button': isActive }" @click="circle()">
373 423
 											<template #icon>
374 424
 												<UndoOutlined />
375 425
 											</template>
@@ -380,12 +430,38 @@
380 430
 						</div>
381 431
 					</div>
382 432
 					<div class="row">
383
-						<a-button type="primary" class="mr-5 btn"> + 聚焦 </a-button>
384
-						<a-button type="primary" class="btn">- 聚焦</a-button>
433
+						<a-button
434
+							type="primary"
435
+							class="mr-5 btn"
436
+							@mousedown="doControl('FOCUS_NEAR', 0)"
437
+							@mouseup="doControl('FOCUS_NEAR', 1)"
438
+						>
439
+							+ 聚焦
440
+						</a-button>
441
+						<a-button
442
+							type="primary"
443
+							class="btn"
444
+							@mousedown="doControl('FOCUS_FAR', 0)"
445
+							@mouseup="doControl('FOCUS_FAR', 1)"
446
+							>- 聚焦</a-button
447
+						>
385 448
 					</div>
386 449
 					<div class="row">
387
-						<a-button type="primary" class="mr-5 btn"> + 调焦 </a-button>
388
-						<a-button type="primary" class="btn">- 调焦</a-button>
450
+						<a-button
451
+							type="primary"
452
+							class="mr-5 btn"
453
+							@mousedown="doControl('ZOOM_IN', 0)"
454
+							@mouseup="doControl('ZOOM_IN', 1)"
455
+						>
456
+							+ 调焦
457
+						</a-button>
458
+						<a-button
459
+							type="primary"
460
+							class="btn"
461
+							@mousedown="doControl('ZOOM_OUT', 0)"
462
+							@mouseup="doControl('ZOOM_OUT', 1)"
463
+							>- 调焦</a-button
464
+						>
389 465
 					</div>
390 466
 					<!--					<div class="row">-->
391 467
 					<!--						<a-button type="primary" class="mr-5 btn"> 录像开始 </a-button>-->
@@ -427,4 +503,9 @@
427 503
 			margin-top: 5px;
428 504
 		}
429 505
 	}
506
+
507
+	.active-button {
508
+		background-color: #1890ff;
509
+		color: white;
510
+	}
430 511
 </style>

+ 5 - 5
src/components/video/Replay.vue

@@ -58,7 +58,7 @@
58 58
 	const createPlayer = () => {
59 59
 		player.value = new window.JSPlugin({
60 60
 			szId: 'player',
61
-			szBasePath: './',
61
+			szBasePath: '/h5player/',
62 62
 			iMaxSplit: 4,
63 63
 			iCurrentSplit: parseInt(splitNum.value),
64 64
 			openDebug: true,
@@ -152,7 +152,7 @@
152 152
 				}
153 153
 			]
154 154
 			list.forEach((d) => {
155
-				const type = d.cameraType
155
+				const type = d.live
156 156
 				const temp = {
157 157
 					title: d.cameraName,
158 158
 					key: d.cameraId,
@@ -181,8 +181,8 @@
181 181
 		}
182 182
 		const { cameraIndexCode } = camera
183 183
 		getPlaybackVideo({ cameraIndexCode }).then((resp) => {
184
-			if (!resp || !resp.data || !resp.data.url) return message.error('无法获取视频地址')
185
-			const url = resp.data.url
184
+			if (!resp || !resp.url) return message.error('无法获取视频地址')
185
+			const url = resp.url
186 186
 			if (url) {
187 187
 				const [realUrl, params] = url.split('?')
188 188
 				const [startTime, endTime] = date.value
@@ -207,7 +207,7 @@
207 207
 			endTime,
208 208
 			cameraIndexCode,
209 209
 			recordLocation: 1,
210
-			protocol: 'WSS'
210
+			protocol: 'wss'
211 211
 		})
212 212
 	}
213 213
 

+ 12 - 2
src/utils/systemUtils.js

@@ -155,9 +155,9 @@ export const getALlOrgData = () => {
155 155
 export const getShiZhou = () => {
156 156
 	const dicList = JSON.parse(localStorage.getItem('DICT_TYPE_TREE_DATA')) || []
157 157
 	let cityList = []
158
-	const d = dicList.find(d => d.dictValue === 'xzqh')
158
+	const d = dicList.find((d) => d.dictValue === 'xzqh')
159 159
 	const children = d.children
160
-	for(const el of children) {
160
+	for (const el of children) {
161 161
 		if (el.name == '青海省') {
162 162
 			cityList = el.children
163 163
 			break
@@ -184,3 +184,13 @@ export const getQueryParams = (name) => {
184 184
 	}
185 185
 	return null
186 186
 }
187
+
188
+export const downloadLink = (url) => {
189
+	const a = document.createElement('a')
190
+	a.href = url
191
+	a.download = 'download'
192
+	a.target = '_blank'
193
+	document.body.appendChild(a)
194
+	a.click()
195
+	document.body.removeChild(a)
196
+}

+ 1 - 1
src/views/Arevenue/Averification/form.vue

@@ -25,7 +25,7 @@
25 25
 								<a-table-summary-cell>
26 26
 									<a-typography-text class="tc"></a-typography-text>
27 27
 								</a-table-summary-cell>
28
-								<a-table-summary-cell> <a-typography-text class="tc"></a-typography-text> </a-table-summary-cell
28
+								<a-table-summary-cell></a-table-summary-cell
29 29
 								><a-table-summary-cell>
30 30
 									<a-typography-text class="tc"></a-typography-text>
31 31
 								</a-table-summary-cell>

+ 3 - 10
src/views/financialSupervision/ProvincialReserveGrainClearingManagement/SafeCostGrainSubsidyClear/index.vue

@@ -27,14 +27,7 @@
27 27
 		<div style="display: flex; justify-content: end; margin-right: 120px">
28 28
 			<span>单位:万公斤、万元</span>
29 29
 		</div>
30
-		<a-table
31
-			id="table"
32
-			:columns="columns"
33
-			:data-source="data"
34
-			bordered
35
-			:pagination="false"
36
-			style="width: 150%; overflow-x: auto; scrollbar-width: none; -ms-overflow-style: none"
37
-		>
30
+		<a-table id="table" :columns="columns" :data-source="data" bordered :pagination="false" :scroll="{ x: 0, y: 500 }">
38 31
 			<template #bodyCell="{ column, text, record }">
39 32
 				<template v-if="['age', 'building', 'street', 'companyAddress'].includes(column.dataIndex)">
40 33
 					<div>
@@ -127,8 +120,8 @@ const flag = ref('1')
127 120
 const columns = [
128 121
 	{
129 122
 		title: '承储企业',
130
-		dataIndex: 'orgId',
131
-		key: 'orgId',
123
+		dataIndex: 'orgName',
124
+		key: 'orgName',
132 125
 		width: 300,
133 126
 		align: 'center',
134 127
 		fixed: 'left'

+ 1 - 1
src/views/financialSupervision/ProvincialReserveGrainClearingManagement/interestSubsidysettlem/index.vue

@@ -28,7 +28,7 @@
28 28
 		<div style="display: flex; justify-content: end; margin-right: 120px">
29 29
 			<span>单位:万公斤、万元</span>
30 30
 		</div>
31
-		<a-table :columns="columns" :data-source="data" bordered :pagination="false" id="table">
31
+		<a-table :columns="columns" :data-source="data" bordered :pagination="false" id="table" :scroll="{ y: 500 }">
32 32
 			<template #bodyCell="{ column, record }">
33 33
 				<template v-if="column.key === 'interestAllocated'">
34 34
 					<a-input autocomplete="off" v-model:value="record.interestAllocated" v-if="flag === 2" />

+ 7 - 6
src/views/financialSupervision/ProvincialReserveGrainClearingManagement/liquidationInterestSubsidy/index.vue

@@ -1,5 +1,5 @@
1 1
 <template>
2
-	<!-- 费用利息补贴清算表 -->
2
+	<!-- 轮换费用利息补贴清算表 -->
3 3
 	<div>
4 4
 		<a-space class="header" ref="tableElem">
5 5
 			<div class="input-box">
@@ -35,6 +35,7 @@
35 35
 			bordered
36 36
 			:pagination="false"
37 37
 			:row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)"
38
+			:scroll="{  y: 500 }"
38 39
 		>
39 40
 			<template #bodyCell="{ column, record }">
40 41
 				<template v-if="column.key === 'totalAllocation'">
@@ -76,16 +77,16 @@
76 77
 				<a-table-summary-row>
77 78
 					<a-table-summary-cell class="tc">合计</a-table-summary-cell>
78 79
 					<a-table-summary-cell>
79
-						<a-typography-text class="tc">{{ totals.totalAverageInventory }}</a-typography-text>
80
+						<a-typography-text class="tc">{{ totals.totalAverageInventory.toFixed(2) }}</a-typography-text>
80 81
 					</a-table-summary-cell>
81 82
 					<a-table-summary-cell>
82
-						<a-typography-text class="tc">{{ totals.totalAverageRawGrainInventory }}</a-typography-text>
83
+						<a-typography-text class="tc">{{ totals.totalAverageRawGrainInventory.toFixed(2) }}</a-typography-text>
83 84
 					</a-table-summary-cell>
84 85
 					<a-table-summary-cell>
85
-						<a-typography-text class="tc">{{ totals.totalAverageRawGrainInventoryPhysical }}</a-typography-text>
86
+						<a-typography-text class="tc">{{ totals.totalAverageRawGrainInventoryPhysical.toFixed(2) }}</a-typography-text>
86 87
 					</a-table-summary-cell>
87 88
 					<a-table-summary-cell>
88
-						<a-typography-text class="tc">{{ totals.totalAverageRawGrainInventoryEmpty }}</a-typography-text>
89
+						<a-typography-text class="tc">{{ totals.totalAverageRawGrainInventoryEmpty.toFixed(2) }}</a-typography-text>
89 90
 					</a-table-summary-cell>
90 91
 					<a-table-summary-cell>
91 92
 						<a-typography-text class="tc"></a-typography-text>
@@ -146,7 +147,7 @@ const columns = [
146 147
 				align: 'center'
147 148
 			},
148 149
 			{
149
-				title: '利息费用',
150
+				title: '利息费用应拨数',
150 151
 				dataIndex: 'interestCostAllocation',
151 152
 				key: 'interestCostAllocation',
152 153
 				width: 200,

+ 16 - 4
src/views/finishedProduct/warehouseFiling/form.vue

@@ -9,7 +9,7 @@
9 9
 			:maskClosable="false"
10 10
 			:title="titleText"
11 11
 		>
12
-			<a-form>
12
+			<a-form style="height: 500px; overflow-y: auto">
13 13
 				<a-row>
14 14
 					<a-col :span="8"
15 15
 						><a-form-item label="所属粮仓名称">
@@ -502,7 +502,7 @@
502 502
 					<a-col :span="3" class=""> </a-col>
503 503
 				</a-row>
504 504
 			</a-form>
505
-			<div class="btn-box">
505
+			<div class="btn-box1">
506 506
 				<a-button @click="isClose">关闭</a-button>
507 507
 			</div>
508 508
 		</a-modal>
@@ -599,7 +599,20 @@ watch(
599 599
 	margin-top: 10px;
600 600
 	text-align: center;
601 601
 }
602
-
602
+.btn-box1 {
603
+	position: absolute;
604
+	margin-top: 10px;
605
+	text-align: center;
606
+	bottom: 20px;
607
+	width: 96%;
608
+	background: rgba(190, 190, 190, 0.2);
609
+}
610
+// ::v-deep .btn-box1 {
611
+// 	margin-top: 10px;
612
+// 	text-align: center;
613
+// 	height: 600px !important;
614
+// 	overflow-y: auto !important;
615
+// }
603 616
 .int-box {
604 617
 	width: 80% !important;
605 618
 }
@@ -610,7 +623,6 @@ watch(
610 623
 .read-the-docs {
611 624
 	color: #888;
612 625
 }
613
-
614 626
 .bp1 {
615 627
 	border: 1px solid #999;
616 628
 	box-sizing: border-box;