index.vue 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055
  1. <template>
  2. <div class="app-container">
  3. <!-- 搜索 增加 -->
  4. <el-form :model="query" ref="query" :inline="true" >
  5. <el-form-item label="设备id:" >
  6. <el-input
  7. v-model="query.code"
  8. placeholder="请输入设备id"
  9. clearable
  10. ></el-input>
  11. </el-form-item>
  12. <el-form-item label="设备名称:" >
  13. <el-input
  14. v-model="query.name"
  15. placeholder="请输入设备名称"
  16. clearable
  17. ></el-input>
  18. </el-form-item>
  19. <el-form-item label="单位名称" >
  20. <el-input
  21. v-model="query.unit"
  22. placeholder="请输入单位名称"
  23. clearable
  24. ></el-input>
  25. </el-form-item>
  26. <el-form-item class="right" >
  27. <el-button plain size="mini" @click="resetQuery">重置</el-button>
  28. <el-button
  29. type="primary"
  30. size="mini"
  31. @click="getData()"
  32. >搜索</el-button>
  33. </el-form-item>
  34. <br>
  35. <el-button type="primary" size="mini" @click="AddoOrEdit()">新增</el-button>
  36. </el-form>
  37. <!-- <el-divider></el-divider> -->
  38. <!-- 初始化数据 -->
  39. <el-table
  40. :data="tableData"
  41. style="width: 100%;margin-top:20px"
  42. row-key="id"
  43. :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
  44. v-loading="loading"
  45. border
  46. >
  47. <el-table-column prop="id" label="id" show-overflow-tooltip></el-table-column>
  48. <el-table-column prop="code" label="设备id" show-overflow-tooltip></el-table-column>
  49. <el-table-column prop="{name}" label="设备名称" show-overflow-tooltip>
  50. <template slot-scope="scope">
  51. {{scope.row.name}}
  52. </template>
  53. </el-table-column>
  54. <el-table-column prop="brand" label="品牌" show-overflow-tooltip></el-table-column>
  55. <el-table-column prop="unit" label="单位名称" show-overflow-tooltip></el-table-column>
  56. <el-table-column prop="address" label="安装位置" show-overflow-tooltip></el-table-column>
  57. <el-table-column label="操作" width="250" fixed="right">
  58. <template slot-scope="scope">
  59. <el-button
  60. class="lans"
  61. @click="playListOperation(scope.row)"
  62. >画面列表</el-button
  63. >
  64. <el-button
  65. class="lans"
  66. @click="AddoOrEdit(scope.row)"
  67. >编辑</el-button
  68. >
  69. <el-button
  70. class="hongs"
  71. @click="handleDelete(scope.$index, scope.row)"
  72. >删除</el-button
  73. >
  74. </template>
  75. </el-table-column>
  76. </el-table>
  77. <!-- 初始化分页 -->
  78. <el-pagination
  79. background
  80. @current-change="handleCurrentChange"
  81. :page-sizes="[10, 15, 20, 30]"
  82. @size-change="handleSizeChange"
  83. :current-page="query.current"
  84. :page-size="query.size"
  85. layout="sizes,prev, pager, next"
  86. :total="totalCount"
  87. >
  88. </el-pagination>
  89. <!-- 编辑 -->
  90. <el-dialog :title="title" class="roleDialog" :visible.sync="dialogAddOrEdit" width="680px" append-to-body style="word-break:break-all; word-wrap:break-all;" @close='closeDialog'>
  91. <el-form ref="AddOrEditForm" :rules="rules" :model="AddOrEditForm" label-width="100px" >
  92. <el-row>
  93. <el-col :span="12">
  94. <el-form-item label="设备名称" prop="name">
  95. <el-input v-model="AddOrEditForm.name" placeholder="请输入设备名称" width="30%" />
  96. </el-form-item>
  97. </el-col>
  98. <el-col :span="12">
  99. <el-form-item label="设备品牌" prop="brand">
  100. <el-input v-model="AddOrEditForm.brand" placeholder="请输入设备品牌" width="30%" />
  101. </el-form-item>
  102. </el-col>
  103. </el-row>
  104. <el-row>
  105. <el-col :span="12">
  106. <el-form-item label="安装位置" prop="address">
  107. <el-input v-model="AddOrEditForm.address" placeholder="请输入安装位置" width="30%" />
  108. </el-form-item>
  109. </el-col>
  110. <el-col :span="12">
  111. <el-form-item label="所属单位" prop="unit">
  112. <el-input v-model="AddOrEditForm.unit" placeholder="请输入所属单位" width="30%" />
  113. </el-form-item>
  114. </el-col>
  115. </el-row>
  116. </el-form>
  117. <el-row class="sblb">设备列表</el-row>
  118. <el-form>
  119. <el-form-item label="关联设备">
  120. <el-col :span="12">
  121. <el-select v-model="AddOrEditForm.GLcode" placeholder="请选择关联设备" @change="deviceUrl(AddOrEditForm.GLcode)" style="width:150%">
  122. <el-option
  123. v-for="dict in idOptions"
  124. :key="dict.dictValue"
  125. :label="dict.dictLabel"
  126. :value="dict.dictValue"
  127. ></el-option>
  128. </el-select>
  129. </el-col>
  130. </el-form-item>
  131. </el-form>
  132. <el-table
  133. class="dh"
  134. v-if = "dhUrlStatus"
  135. :data="dhUrl"
  136. height="200"
  137. stripe
  138. border
  139. :header-cell-style="{ background: '#EBF1FF', color: '#606266' }"
  140. style="width: 100%;cursor:pointer">
  141. <el-table-column property="id" label="通道编号" width="80"></el-table-column>
  142. <el-table-column property="name" label="通道名称" width="80">
  143. <template slot-scope="scope">
  144. <span>{{scope.row.name}}</span>
  145. </template>
  146. </el-table-column>
  147. <el-table-column property="url" label="视频地址" class="url">
  148. <template slot-scope="scope">
  149. <span>{{scope.row.url}}</span>
  150. </template>
  151. </el-table-column>
  152. </el-table>
  153. <el-table
  154. class="otherBrand"
  155. v-if = "otherBrandStatus"
  156. :data="otherBrand"
  157. height="200"
  158. stripe
  159. border
  160. :header-cell-style="{ background: '#EBF1FF', color: '#606266' }"
  161. style="width: 100%;cursor:pointer">
  162. <el-table-column prop="id" label="通道编号" width="80">
  163. <template slot-scope="scope">
  164. <span>{{scope.row.id}}</span>
  165. </template>
  166. </el-table-column>
  167. <el-table-column prop="name" label="通道名称" width="90">
  168. <template slot-scope="scope">
  169. <el-input type="text" v-model="scope.row.name" placeholder="通道名称" @input="inputChange(scope.$index,scope.row)" />
  170. </template>
  171. </el-table-column>
  172. <el-table-column prop="url" label="视频地址" class="url">
  173. <template slot-scope="scope">
  174. <el-input type="text" v-model="scope.row.url" placeholder="请输入视频地址" @input="inputChange(scope.$index,scope.row)"/>
  175. </template>
  176. </el-table-column>
  177. </el-table>
  178. <div slot="footer" class="dialog-footer">
  179. <el-button type="primary" @click="submitForm" v-if="!loading">确 定</el-button>
  180. <el-button :loading="loading" type="primary" v-else>提交中...</el-button>
  181. <el-button @click="cancel" plain>取 消</el-button>
  182. </div>
  183. </el-dialog>
  184. <!-- 播放列表 -->
  185. <el-dialog :title="playListTitle" class="roleDialog" :visible.sync="playList" width="680px" append-to-body style="word-break:break-all; word-wrap:break-all;" @close='closeDialog'>
  186. <el-table class="bflb"
  187. :data="dhUrl"
  188. height="200"
  189. stripe
  190. border
  191. :header-cell-style="{ background: '#EBF1FF', color: '#606266' }"
  192. style="width: 100%;cursor:pointer">
  193. <el-table-column property="id" label="通道编号" width="100"></el-table-column>
  194. <el-table-column property="name" label="通道名称" width="100"></el-table-column>
  195. <el-table-column property="url" label="视频地址" class="url"></el-table-column>
  196. <el-table-column label="操作" width="190" fixed="right">
  197. <template slot-scope="scope">
  198. <el-button
  199. class="lans"
  200. @click="play(scope.row)"
  201. >播放</el-button
  202. >
  203. <el-button
  204. v-if="NoHplay"
  205. class="lans"
  206. @click="Hplay(scope.row)"
  207. >回放</el-button
  208. >
  209. </template>
  210. </el-table-column>
  211. </el-table>
  212. <div slot="footer" class="dialog-footer">
  213. <!-- <el-button type="primary" @click="submitForm" v-if="!loading">确 定</el-button>
  214. <el-button :loading="loading" type="primary" v-else>提交中...</el-button> -->
  215. <el-button type="primary" @click="cancel">关 闭</el-button>
  216. </div>
  217. </el-dialog>
  218. <el-dialog title="回放时间选择" :visible.sync="dialogFormVisible3" width="600" @close='closeDialog'>
  219. <div class="block">
  220. <el-date-picker
  221. @change="dateData"
  222. value-format="yyyy-MM-dd HH:mm:ss"
  223. v-model="value"
  224. range-separator
  225. type="datetimerange"
  226. align="center"
  227. start-placeholder="开始日期"
  228. end-placeholder="结束日期"
  229. class="picker"
  230. :default-time="['00:00:00', '23:59:59']">
  231. </el-date-picker>
  232. <el-button
  233. v-if="dateDataJlStatus"
  234. size="small"
  235. type="primary"
  236. class="search-button pickerBut"
  237. @click="dateDataJl" >确定</el-button>
  238. </div>
  239. </el-dialog>
  240. <el-dialog :visible.sync="dialogTable2" @close='closeDialog2'>
  241. <template slot="title">
  242. <div
  243. class="titleZise"
  244. style="font-size: 15px; color: #484848; font-weight: 700"
  245. >
  246. {{ this.cameraNo }}
  247. </div>
  248. </template>
  249. <video
  250. class="hlsVideo monitor-height"
  251. ref="hlsVideo"
  252. style="width: 100%"
  253. controls
  254. preload="true"
  255. muted
  256. ></video>
  257. </el-dialog>
  258. </div>
  259. </template>
  260. <script>
  261. // 引入导出Excel表格依赖
  262. import FileSaver from "file-saver";
  263. import Hls from "hls.js";
  264. import { deviceList, getLocalDeviceList, deviceAdd, deviceEdit, deviceRemove, getLocalUnitNodes, getLocalChannel } from "@/api/device/camera2";
  265. import qs from 'qs'
  266. import { set } from 'js-cookie';
  267. export default {
  268. name: "javascriptthree",
  269. data() {
  270. return {
  271. // 状态数据字典
  272. statusOptions: [
  273. {
  274. dictLabel:"未知",
  275. dictValue:0
  276. },{
  277. dictLabel:"在线",
  278. dictValue:1
  279. },{
  280. dictLabel:"离线",
  281. dictValue:2
  282. }
  283. ],
  284. cameraTypeOptions:[
  285. {
  286. dictLabel:"枪机",
  287. dictValue:1
  288. },{
  289. dictLabel:"球机",
  290. dictValue:2
  291. },{
  292. dictLabel:"半球",
  293. dictValue:3
  294. },{
  295. dictLabel:"证据通道",
  296. dictValue:4
  297. }
  298. ],
  299. listQuery:{
  300. deviceCode:undefined,
  301. deviceName:undefined,
  302. dwtype:undefined,
  303. current:1,
  304. pageSize:15,
  305. sort:undefined,
  306. },
  307. dialogWidth: "680px",
  308. dialogWidth1: "70%",
  309. formLabelWidth: "130px",
  310. //input输入框--设备id
  311. device_id: "",
  312. //input输入框--设备名称
  313. device_name: "",
  314. dialogTable: false,
  315. gridData: [],
  316. gridData1: [],
  317. dialogTable1: false,
  318. cameraNo: "",
  319. dialogTable2: false,
  320. hls: "",
  321. //动态列表信息存储
  322. tableData:[],
  323. cols: [],
  324. //列表总数存储
  325. totalCount: 0,
  326. // //列表起始页
  327. // pageNo: 1,
  328. // //列表每页长度
  329. // pageSize: 15,
  330. //本地注册弹窗
  331. dialogFormVisible: false,
  332. //公共title (本地注册)
  333. //from表单提交
  334. from_data: [],
  335. //本地注册列表单条信息存储
  336. row: "",
  337. status2:false,
  338. value: '',
  339. dialogFormVisible3:false,
  340. starTime:undefined,
  341. endTime:undefined,
  342. hrow:undefined,
  343. loading:true,
  344. query:{
  345. code:undefined,
  346. name:undefined,
  347. unit:undefined,
  348. current:1,
  349. size:15,
  350. id:undefined,
  351. },
  352. dateDataJlStatus:false,//回放记录时间button状态
  353. //表格自适应高度
  354. tableHeight:undefined,
  355. // 新增修改删除
  356. title:undefined,//弹框标题
  357. dialogAddOrEdit:false, //弹框
  358. AddOrEditForm:{//修改增加表单
  359. "address": undefined,
  360. "brand": undefined,
  361. "code": undefined,
  362. "delFlag": 0,
  363. "deviceInfo": undefined,
  364. "deviceType": undefined,
  365. "dhCode": undefined,
  366. "id": undefined,
  367. "name": undefined,
  368. "unit": undefined,
  369. "GLcode":undefined
  370. },
  371. // 表单校验
  372. rules: {
  373. address: [
  374. { required: true, message: "设备地址不能为空", trigger: "blur" }
  375. ],
  376. brand: [
  377. { required: true, message: "设备品牌不能为空", trigger: "blur" }
  378. ],
  379. id: [
  380. { required: true, message: "设备编号不能为空", trigger: "blur" }
  381. ],
  382. name: [
  383. { required: true, message: "设备名称不能为空", trigger: "blur" }
  384. ],
  385. unit: [
  386. { required: true, message: "所属单位不能为空", trigger: "blur" }
  387. ],
  388. },
  389. //大华关联设备
  390. idOptions:[
  391. ],
  392. //大华关联设备通道信息
  393. dhUrl:[],
  394. //大华或其它设备table 或form状态
  395. dhUrlStatus:false,
  396. //播放列表弹框
  397. playList:false,
  398. //画面列表标题
  399. playListTitle:undefined,
  400. //其它品牌添加
  401. otherBrand:{
  402. id:1,
  403. name:undefined,
  404. url:undefined
  405. },
  406. //其它品牌视频url
  407. otherBrandStatus:false,
  408. otherBrand:[
  409. ],
  410. tabClickLabel:"视频地址",
  411. //其它品牌禁止回放
  412. NoHplay:true
  413. };
  414. },
  415. watch: {
  416. },
  417. mounted(){
  418. // table高度
  419. if(window.innerWidth <1920){
  420. this.tableHeight = window.innerHeight - 300
  421. }else{
  422. this.tableHeight = window.innerHeight - 295
  423. }
  424. // 监听窗口大小变化
  425. let self = this;
  426. window.onresize = function() {
  427. self.tableHeight = window.innerHeight - 300
  428. }
  429. this.getData();
  430. },
  431. created() {
  432. this.$once("hook:beforeDestroy", () => {
  433. this.destroyHls();
  434. });
  435. },
  436. methods: {
  437. /** 重置按钮操作 */
  438. resetQuery() {
  439. this.query = {
  440. code:undefined,
  441. name:undefined,
  442. unit:undefined,
  443. current:1,
  444. size:15,
  445. id:undefined
  446. },
  447. this.handleQuery();
  448. },
  449. /** 搜索按钮操作 */
  450. handleQuery() {
  451. this.getData();
  452. },
  453. //获取大华 => 关联摄像头设备信息 (新增修改)
  454. GLSB(){
  455. getLocalDeviceList({"pageSize":1000,"size":"1","joinDevice":0}).then(Response =>{
  456. if(Response.data.pageList){
  457. this.idOptions = Response.data.pageList.map((val, ind) => {
  458. return {
  459. dictLabel: `${val.name}(${val.id})`,
  460. dictValue: val.id
  461. };
  462. })
  463. this.idOptions.push({dictLabel:"其它品牌(1)",dictValue:1})
  464. }
  465. })
  466. },
  467. //回放时间选项
  468. dateData(val){
  469. this.starTime = new Date(val[0]).getTime()
  470. this.endTime = new Date(val[1]).getTime()
  471. this.dialogFormVisible3 = false
  472. this.playH(this.starTime/1000,this.endTime/1000)
  473. },
  474. //记录回放时间选项
  475. dateDataJl(){
  476. this.dialogFormVisible3 = false
  477. this.playH(this.starTime/1000,this.endTime/1000)
  478. },
  479. //数据初始化
  480. getData(){
  481. let arr = []
  482. deviceList(this.query).then(Response =>{
  483. for(let i = 0; i<Response.data.pageList.length; i++){
  484. arr[i] = {}
  485. arr[i] = Response.data.pageList[i]
  486. }
  487. this.tableData = arr
  488. this.totalCount = Response.data.totalCount
  489. this.loading = false
  490. this.status2 = true
  491. })
  492. },
  493. Select() {
  494. this.Select_DeviceList();
  495. },
  496. Select_DeviceList(data) {
  497. var that = this;
  498. that.cols = [
  499. {
  500. property: "id",
  501. label: "设备id",
  502. width: "",
  503. },
  504. // {
  505. // property:"uuid",
  506. // label:"设备唯一编码",
  507. // width:""
  508. // },
  509. {
  510. property: "name",
  511. label: "设备名称",
  512. width: "",
  513. },
  514. {
  515. property: "deviceIp",
  516. label: "设备IP",
  517. width: "",
  518. },
  519. {
  520. property: "manufacturer",
  521. label: "厂商类型",
  522. width: "",
  523. },
  524. {
  525. property: "unitnum",
  526. label: "单元数目",
  527. width: "",
  528. },
  529. {
  530. property: "devicePort",
  531. label: "设备端口",
  532. width: "",
  533. },
  534. {
  535. property: "registerStatus",
  536. label: "本地注册",
  537. width: "",
  538. },
  539. {
  540. property: "status",
  541. label: "设备状态",
  542. width: "",
  543. },
  544. ];
  545. //获取视频设备列表
  546. api.getLocalDeviceList(data).then((request) => {
  547. that.tableData = [];
  548. that.totalCount = request.totalCount;
  549. for (let i = 0; i < request.pageList.length; i++) {
  550. var pageList = request.pageList[i];
  551. that.tableData.push(pageList);
  552. pageList.manufacturer == 1
  553. ? (pageList.manufacturer = "大华")
  554. : pageList.manufacturer == 2
  555. ? (pageList.manufacturer = "海康")
  556. : (pageList.manufacturer = "未知");
  557. pageList.status == 1
  558. ? (pageList.status = "在线")
  559. : pageList.status == 2
  560. ? (pageList.status = "离线")
  561. : "";
  562. }
  563. });
  564. },
  565. //分页查询
  566. handleCurrentChange(val) {
  567. this.query.current = val;
  568. this.getData();
  569. },
  570. //分页查询
  571. handleSizeChange(val) {
  572. this.query.size = val;
  573. this.getData();
  574. },
  575. //画面列表
  576. playListOperation(row){
  577. this.playListTitle = `"${row.name}"摄像头 画面列表`
  578. getLocalChannel({"pageSize":1000,"size":"1","deviceId":row.code,"unitType":1}).then(Response =>{
  579. if(Response.data.pageList.length>0){
  580. this.dhUrl = Response.data.pageList.map((val, index) =>{
  581. return {
  582. id: index + 1,
  583. name: val.name,
  584. url: "http://" + val.nvr_ip + ":" + val.hls_port + "/live/cameraid/" + val.deviceId + "%24" + val.id.split("$")[(val.id.split("$")).length-1] + "/substream/1.m3u8",
  585. data:val
  586. };
  587. })
  588. this.NoHplay = true
  589. this.dhUrlStatus = true
  590. this.playList = true
  591. }else{
  592. this.query.code = row.code
  593. deviceList(this.query).then(Response =>{
  594. if(Response.data.pageList.length>0){
  595. if(Response.data.pageList[0].deviceInfo){
  596. let json = JSON.parse(Response.data.pageList[0].deviceInfo)
  597. for(let i =0;i<json.length;i++){
  598. if(!json[i] || json[i] && !json[i].name){
  599. json.splice(i,1)
  600. i--
  601. }
  602. }
  603. this.dhUrl = json.map((val, index) =>{
  604. return {
  605. id: index + 1,
  606. name: val.name,
  607. url:val.url,
  608. data:val
  609. }
  610. })
  611. this.NoHplay = false
  612. this.dhUrlStatus = true
  613. this.playList = true
  614. }else{
  615. this.dhUrl = []
  616. this.NoHplay = false
  617. this.dhUrlStatus = true
  618. this.playList = true
  619. }
  620. }
  621. })
  622. }
  623. })
  624. },
  625. //播放按钮
  626. play(row) {
  627. this.destroyHls()
  628. //let url = "http://" + row.nvr_ip + ":" + row.hls_port + "/live/cameraid/" + row.deviceId + "%24" + row.id.split("$")[(row.id.split("$")).length-1] + "/substream/1.m3u8"
  629. this.loadVideoFn(row.url)
  630. },
  631. //回放url
  632. playH(start,end){
  633. this.destroyHls()
  634. let row = this.hrow
  635. let url = "http://" + row.data.nvr_ip + ":" + row.data.hls_port + "/vod/device/cameraid/" + row.data.deviceId + "%24" + row.data.id.split("$")[(row.data.id.split("$")).length-1] + "/substream/1/recordtype/1/totallength/" + Number(end-start) + "/begintime/" + start + "/endtime/" + end + ".m3u8"
  636. this.loadVideoFn(url)
  637. },
  638. destroyHls: function () {
  639. if (this.hls) {
  640. this.$refs.hlsVideo.pause();
  641. this.hls.destroy();
  642. this.hls = null;
  643. }
  644. },
  645. loadVideoFn(url) {
  646. this.dialogTable2 = true
  647. setTimeout(() =>{
  648. if (Hls.isSupported()) {
  649. this.hls = new Hls();
  650. this.hls.loadSource(url);
  651. this.hls.attachMedia(this.$refs.hlsVideo);
  652. this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
  653. console.log("加载成功");
  654. this.$refs.hlsVideo.play();
  655. });
  656. this.hls.on(Hls.Events.ERROR, (event, data) => {
  657. // console.log(event, data);
  658. // 监听出错事件
  659. console.log("加载失败");
  660. });
  661. }
  662. },1000)
  663. },
  664. //设备列表序号
  665. indexMethod(index) {
  666. return index + 1;
  667. },
  668. //回放视频
  669. Hplay(row){
  670. this.dialogFormVisible3 = true
  671. if(this.endTime){
  672. this.dateDataJlStatus = true
  673. }else{
  674. this.dateDataJlStatus = false
  675. }
  676. this.hrow = row
  677. },
  678. //新增修改
  679. AddoOrEdit(row){
  680. this.GLSB()
  681. if(row){
  682. this.AddOrEditForm = row
  683. if(row.code != "1"){
  684. getLocalChannel({"pageSize":1000,"size":"1","deviceId":row.code,"unitType":1}).then(Response =>{
  685. if(Response.data.pageList){
  686. this.dhUrl = Response.data.pageList.map((val, index) =>{
  687. return {
  688. id: index + 1,
  689. name: val.name,
  690. url: "http://" + val.nvr_ip + ":" + val.hls_port + "/live/cameraid/" + val.deviceId + "%24" + val.id.split("$")[(val.id.split("$")).length-1] + "/substream/1.m3u8"
  691. };
  692. })
  693. this.otherBrandStatus = false
  694. this.otherBrand = []
  695. this.title = `"${row.name}" 摄像头信息修改`
  696. this.dhUrlStatus = true
  697. this.dialogAddOrEdit = true
  698. this.AddOrEditForm.GLcode = this.AddOrEditForm.code
  699. }
  700. })
  701. }else{
  702. if(row.deviceInfo){
  703. deviceList({current:this.query.current,size:this.query.size,code:row.code}).then(Response =>{
  704. if(Response.data.pageList.length>0){
  705. let json = JSON.parse(Response.data.pageList[0].deviceInfo)
  706. for(let i =0;i<json.length;i++){
  707. if(!json[i] || json[i] && !json[i].name){
  708. json.splice(i,1)
  709. i--
  710. }
  711. }
  712. let arr = []
  713. arr= json.map((val, index) =>{
  714. return {
  715. id: index + 1,
  716. name: val.name,
  717. url:val.url,
  718. }
  719. })
  720. if(arr.length<50){
  721. for(let i = arr.length;i<50; i++){
  722. arr[i] = {}
  723. arr[i].id= i+1
  724. arr.name = undefined
  725. arr.url = undefined
  726. }
  727. this.otherBrand = arr
  728. }
  729. this.dhUrlStatus = false
  730. this.dhUrl = []
  731. this.title = `"${row.name}" 摄像头信息修改`
  732. this.otherBrandStatus = true
  733. this.AddOrEditForm.GLcode = Number(row.code)
  734. this.dialogAddOrEdit = true
  735. }
  736. })
  737. }else{
  738. let arr = []
  739. for(let i = arr.length;i<50; i++){
  740. arr[i] = {}
  741. arr[i].id= i+1
  742. arr.name = undefined
  743. arr.url = undefined
  744. }
  745. this.otherBrand = arr
  746. this.dhUrlStatus = false
  747. this.dhUrl = []
  748. this.title = `"${row.name}" 摄像头信息修改`
  749. this.otherBrandStatus = true
  750. this.AddOrEditForm.GLcode = Number(row.code)
  751. this.dialogAddOrEdit = true
  752. }
  753. }
  754. }else{
  755. this.title = "新增摄像头信息"
  756. this.dialogAddOrEdit = true
  757. }
  758. },
  759. //编辑框
  760. inputChange(index,row){
  761. this.$set(this.otherBrand,index,row)
  762. },
  763. //删除
  764. handleDelete(index, row) {
  765. this.$confirm("确定删除该数据吗?", "删除", {
  766. confirmButtonText: "确定",
  767. cancelButtonText: "取消",
  768. type: "warning",
  769. })
  770. .then(() => {
  771. deviceRemove(row.id).then((response) => {
  772. this.$message.success("删除成功")
  773. this.reset()
  774. this.getData()
  775. })
  776. })
  777. .catch(() => {
  778. this.$message.info("已取消删除")
  779. });
  780. },
  781. //关联设备选项
  782. deviceUrl(val){
  783. if(val != "1"){
  784. this.AddOrEditForm.GLcode = val
  785. getLocalChannel({"pageSize":1000,"size":"1","deviceId":val,"unitType":1}).then(Response =>{
  786. if(Response.data.pageList){
  787. this.dhUrl = Response.data.pageList.map((val, index) =>{
  788. return {
  789. id: index + 1,
  790. name: val.name,
  791. url: "http://" + val.nvr_ip + ":" + val.hls_port + "/live/cameraid/" + val.deviceId + "%24" + val.id.split("$")[(val.id.split("$")).length-1] + "/substream/1.m3u8"
  792. };
  793. })
  794. this.otherBrandStatus = false
  795. this.otherBrand = []
  796. this.dhUrlStatus = true
  797. }
  798. })
  799. }else{
  800. setTimeout(()=>{
  801. let arr =[]
  802. for(let i=0;i<50;i++){
  803. arr[i] = {}
  804. arr[i].id = i+1
  805. arr[i].name = undefined
  806. arr[i].url = undefined
  807. }
  808. this.otherBrand = arr
  809. this.dhUrl = []
  810. this.dhUrlStatus = false
  811. this.otherBrandStatus = true
  812. },1)
  813. }
  814. },
  815. //表单提交
  816. submitForm(){
  817. if(this.AddOrEditForm.code){//修改
  818. this.AddOrEditForm.code = this.AddOrEditForm.GLcode
  819. if(this.dhUrlStatus){
  820. deviceEdit(this.AddOrEditForm).then(Response =>{
  821. if(Response.status == "SUCCESS"){
  822. this.$message.success("修改成功")
  823. this.reset()
  824. this.getData()
  825. }
  826. })
  827. }else if(this.otherBrandStatus){
  828. this.$refs["AddOrEditForm"].validate(valid => {
  829. if (valid) {
  830. let arr = []
  831. for(let i =0; i<this.otherBrand.length;i++){
  832. if(this.otherBrand[i].name && !this.otherBrand[i].url){
  833. this.$message.warning(`请添加通道'${i+1}' 的视频播放地址`)
  834. return
  835. }
  836. if(this.otherBrand[i].url && !this.otherBrand[i].name){
  837. this.$message.warning(`请添加通道'${i+1}' 的通道名称`)
  838. return
  839. }
  840. arr[i] = {id:undefined,name:undefined,url:undefined}
  841. arr[i].id = i + 1
  842. arr[i].name = this.otherBrand[i].name
  843. arr[i].url = this.otherBrand[i].url
  844. }
  845. if(arr.length>0){
  846. this.AddOrEditForm.deviceInfo = JSON.stringify(arr)
  847. }
  848. deviceEdit(this.AddOrEditForm).then(Response =>{
  849. if(Response.status == "SUCCESS"){
  850. this.$message.success("修改成功")
  851. this.reset()
  852. this.getData()
  853. }
  854. })
  855. }
  856. })
  857. }else{
  858. this.$message.warning("请选择关联设备")
  859. }
  860. }else{//新增
  861. this.AddOrEditForm.code = this.AddOrEditForm.GLcode
  862. if(this.dhUrlStatus){ //大华设备
  863. this.AddOrEditForm.dhCode = this.AddOrEditForm.code
  864. this.$refs["AddOrEditForm"].validate(valid => {
  865. if (valid) {
  866. deviceAdd(this.AddOrEditForm).then(Response =>{
  867. if(Response.status == "SUCCESS"){
  868. this.$message.success("添加成功")
  869. this.reset()
  870. this.getData()
  871. }
  872. })
  873. }
  874. })
  875. }else if(this.otherBrandStatus){//非大华设备
  876. this.AddOrEditForm.dhCode = 0
  877. this.$refs["AddOrEditForm"].validate(valid => {
  878. if (valid) {
  879. let arr = []
  880. for(let i =0; i<this.otherBrand.length;i++){
  881. if(this.otherBrand[i].name && !this.otherBrand[i].url){
  882. this.$message.warning(`请添加通道'${i+1}' 的视频播放地址`)
  883. return
  884. }
  885. if(this.otherBrand[i].url && !this.otherBrand[i].name){
  886. this.$message.warning(`请添加通道'${i+1}' 的通道名称`)
  887. return
  888. }
  889. if(this.otherBrand[i].name){
  890. arr[i] = {id:undefined,name:undefined,url:undefined}
  891. arr[i].id = i + 1
  892. arr[i].name = this.otherBrand[i].name
  893. arr[i].url = this.otherBrand[i].url
  894. }
  895. }
  896. if(arr.length>0){
  897. this.AddOrEditForm.deviceInfo = JSON.stringify(arr)
  898. }
  899. deviceAdd(this.AddOrEditForm).then(Response =>{
  900. if(Response.status == "SUCCESS"){
  901. this.$message.success("添加成功")
  902. this.reset()
  903. this.getData()
  904. }
  905. })
  906. }
  907. })
  908. }else{
  909. this.$message.warning("请选择关联设备")
  910. }
  911. }
  912. },
  913. //表单取消
  914. cancel(){
  915. this.reset()
  916. // this.destroyHls()
  917. },
  918. //关闭弹框
  919. closeDialog(){
  920. this.destroyHls()
  921. this.reset()
  922. },
  923. //关闭弹框
  924. closeDialog2(){
  925. this.destroyHls()
  926. },
  927. //重置条件
  928. reset(){
  929. this.dialogAddOrEdit = false
  930. this.playList = false
  931. this.query.code = undefined
  932. this.query.name = undefined
  933. this.query.unit = undefined
  934. this.query.id = undefined
  935. setTimeout(()=>{
  936. this.dhUrl = []
  937. this.dhUrlStatus = false
  938. this.title=undefined
  939. this.playListTitle=undefined
  940. this.otherBrand = []
  941. this.otherBrandStatus = false
  942. this.NoHplay = true
  943. this.AddOrEditForm = {
  944. "address": undefined,
  945. "brand": undefined,
  946. "code": undefined,
  947. "delFlag": undefined,
  948. "deviceInfo": undefined,
  949. "deviceType": undefined,
  950. "dhCode": undefined,
  951. "id": undefined,
  952. "name": undefined,
  953. "unit": undefined,
  954. "GLcode":undefined,
  955. }
  956. },500)
  957. }
  958. }
  959. };
  960. </script>
  961. <style>
  962. .el-dialog__headerbtn{
  963. top:3px;
  964. }
  965. .el-range-editor.el-input__inner{
  966. width:80%;
  967. margin:0 10% !important;
  968. }
  969. .pickerBut{
  970. width:10%;display: inline-block;
  971. margin:20px 45% 0;
  972. }
  973. .sblb{
  974. vertical-align: middle;
  975. width:100%;
  976. font-size: 16px;
  977. font-weight: 700;
  978. color: #606266;
  979. padding-bottom:10px;
  980. border-bottom:1px solid #ccc;
  981. margin:20px 0;
  982. }
  983. .roleDialog .el-dialog .el-form-item {
  984. margin: 20px 20px 0;
  985. }
  986. .roleDialog .el-dialog .el-form-item:first-child,
  987. .roleDialog .el-dialog .el-form-item:nth-child(2) {
  988. display: inline-block;
  989. }
  990. .el-dialog .el-form-item.table-item {
  991. width: 96%;
  992. }
  993. .el-dialog .el-form-item{
  994. width:100%;
  995. }
  996. .el-input__inner{
  997. height:40px;
  998. line-height: 40px;
  999. }
  1000. .roleDialog .el-dialog .el-form-item{
  1001. margin:10px 0
  1002. }
  1003. .el-input__inner{
  1004. height:32px;
  1005. line-height: 32px;
  1006. }
  1007. .bflb .el-table__row td:nth-child(3) div{
  1008. white-space: pre-line;
  1009. white-space: pre-wrap;
  1010. height:50px;
  1011. line-height: 25px;
  1012. }
  1013. .otherBrand .el-table__body .el-input__inner{
  1014. height:32px;
  1015. line-height: 32px;
  1016. margin-top:-6px;
  1017. }
  1018. /* table{table-layout: fixed;}
  1019. td{word-break: break-all; word-wrap:break-word;} */
  1020. </style>
  1021. <style>
  1022. </style>