index.vue 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695
  1. <template>
  2. <div class="app-container" style="padding-top: 20px;height: 120vh;" v-loading="loading"
  3. element-loading-text="拼命加载中"
  4. element-loading-spinner="el-icon-loading"
  5. element-loading-background="rgba(0, 0, 0, 0.8)">
  6. <div class="ntgs">
  7. <el-row :gutter="10" class="mb8">
  8. <div class="iuer" style="margin-bottom:10px;">
  9. <!-- <div style="display: flex;align-items: center; " class="ingaqe">
  10. <el-select v-model="queryParams.name" placeholder="请选监控名称" clearable>
  11. <el-option
  12. v-for="dict in postList"
  13. :key="dict.indexCode"
  14. :label="dict.name"
  15. :value="dict.name"
  16. />
  17. </el-select>
  18. <div class="ksfpofg" @click="handleQuery">
  19. 搜索
  20. </div>
  21. </div> -->
  22. <!-- <div class="ite">
  23. <div class="ksfpo" @click="osge" v-hasPermi="['system:camera:openDz']">
  24. <img src="../../../assets/images/icon_ssjk_kman_open.png" alt="" style="width:10px;height: 10px;">
  25. 开门</div>
  26. <div class="ksfpo ksfpok" @click="osgef" v-hasPermi="['system:camera:closeDz']">
  27. <img src="../../../assets/images/icon_ssjk_kman_close.png" alt="" style="width:10px;height: 10px;">
  28. 关门</div>
  29. </div> -->
  30. <!-- -->
  31. </div>
  32. <!-- <el-col :span="1.5">
  33. <el-button
  34. type="primary"
  35. plain
  36. icon="el-icon-plus"
  37. size="mini"
  38. @click="handleAdd"
  39. v-hasPermi="['investigate:table:add']"
  40. >新增</el-button>
  41. </el-col>
  42. <el-col :span="1.5">
  43. <el-button
  44. type="danger"
  45. plain
  46. icon="el-icon-delete"
  47. size="mini"
  48. :disabled="multiple"
  49. @click="handleDelete"
  50. v-hasPermi="['investigate:table:remove']"
  51. >删除</el-button>
  52. </el-col> -->
  53. <!-- <el-col :span="1.5">
  54. <el-button
  55. type="warning"
  56. plain
  57. icon="el-icon-download"
  58. size="mini"
  59. @click="handleExport"
  60. v-hasPermi="['investigate:table:export']"
  61. >导出</el-button>
  62. </el-col> -->
  63. <!-- <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar> -->
  64. </el-row>
  65. <div>
  66. <el-row :gutter="20">
  67. <!-- postList -->
  68. <el-col :span='5'>
  69. <div style="background-color: #fff;border-radius: 10px;padding: 20px 20px;height: 100vh;">
  70. <p style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">通道列表</p>
  71. <div style=" height: 36px;;line-height: 36px;margin-top: 10px;"v-for="(item,index) in channelNumberList">
  72. <div @click="ishg(item)" style="display: flex;align-items: center;justify-content: space-between;">
  73. <div style="font-size: 16px;
  74. color: #333333;"> {{item.channelNum == null?'暂无数据' : item.channelNum}}</div>
  75. <img src="../../../assets/images/icon_htgl_zd.png" alt="" style="width: 10px;height: 12px;">
  76. </div>
  77. </div>
  78. </div>
  79. </el-col>
  80. <!-- v-if="isshoe" -->
  81. <el-col :span='14' style="padding-left: 30px; background-color: #fff;border-radius: 10px;padding: 20px; height: 100vh;" >
  82. <div style="display: flex;align-items: center;justify-content: space-between;margin-bottom: 18px;">
  83. <p style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">实时预览
  84. </p>
  85. <div>
  86. <!-- <el-button type="danger" plain>删除</el-button>
  87. <el-button type="warning" plain>置顶</el-button> -->
  88. <el-button type="success" plain>关闭</el-button>
  89. </div>
  90. </div>
  91. <div class="dflext mb10">
  92. <div>
  93. <el-button type="primary" @click="clickEnableDraw">绘图</el-button>
  94. <el-button type="primary" plain @click="clickAddSnapPolygon">添加图形</el-button>
  95. <el-button type="primary" plain @click="clickDelAllSnapPolygon">清除所有图形</el-button>
  96. <el-button type="primary" plain @click="clickGetSnapPolygon">获取坐标点</el-button>
  97. </div>
  98. <div style="flex: 1;"></div>
  99. <div class="disbtn" @click="getdrawFn">
  100. <img src="../../../assets/images/dchose.png" v-if="isdisflag"/>
  101. <img src="../../../assets/images/dnchose.png" v-else/>
  102. 禁用绘制
  103. </div>
  104. <!-- <el-button type="primary" plain @click="clickCapturePic">抓图</el-button> -->
  105. </div>
  106. <span style="font-size: 12px;color: red;">先点击绘图按钮,在点击添加图片按钮开始绘制,若绘制多个框每次绘制前需点击添加图片按钮,绘制完成后点击获取坐标点
  107. 。</span>
  108. <div style="width: 100%; height: 480px;">
  109. <div v-if="isfse" id="divPlugin" style="width: 100%; height: 440px;" ></div>
  110. </div>
  111. <!-- <img src="../../../assets/images/pic_ssyl_lt.png" alt="" style="width: 100%; margin-top: 20px;"> -->
  112. <!-- 344 -->
  113. <!-- <video id="video" controls autoplay muted width="100%" height="480px"style="margin-top: 20px;"></video> -->
  114. <!-- <video
  115. class="videosmall"
  116. ref="videosmallone"
  117. preload="auto"
  118. muted
  119. autoplay
  120. width="95%"
  121. type="rtmp/flv"
  122. >
  123. <source src="" />
  124. </video> -->
  125. </el-col>
  126. <el-col :span="5">
  127. <div style="background-color: #fff;border-radius: 10px;padding: 20px 20px;height: 100vh;">
  128. <p style="margin: 0;border-left: 6px solid #03BF8A;margin-left: -20px;padding-left: 10px;font-weight: 800;">绘制区域</p>
  129. <div class="drawings-list">
  130. <div class="tflex" v-for="(shape, index) in shapes" :key="index">
  131. <!-- :class="{ selected: selectedIndex === index }" -->
  132. <div class="txt" >
  133. <el-popover
  134. placement="top-start"
  135. width="200"
  136. trigger="hover"
  137. >
  138. <div v-for="(ite,idx) in shape.points">
  139. {{ite.x}},{{ite.y}}
  140. </div>
  141. <div slot="reference">区域{{shape.id}}</div>
  142. </el-popover>
  143. </div>
  144. <img class="delimg" src="../../../assets/images/del.png" @click.stop="clickDelSnapPolygon(shape.id,index)"/>
  145. </div>
  146. </div>
  147. </div>
  148. </el-col>
  149. <!-- <el-col :span="24">
  150. <div class="ihgswq wrapper" ref="wrapper" style=" overflow: hidden;">
  151. <div class="fijge content nhgwesvq" ref="content" style="width:1610px;">
  152. <div class='shotw ' v-for="(item,index) in postList" :key="index" @click="isfgw(item)" >
  153. <img src="../../../assets/images/fengm.png" alt="">
  154. <img src="../../../assets/images/icon_spjk_play.png" alt="" class="iges">
  155. <p style="font-size: 14px;">{{item.name}}</p>
  156. </div>
  157. </div>
  158. </div>
  159. </el-col> -->
  160. </el-row>
  161. <!-- <pagination
  162. v-show="total>0"
  163. :total="total"
  164. :page.sync="queryParams.pageNo"
  165. :limit.sync="queryParams.pageSize"
  166. @pagination="getList"
  167. /> -->
  168. </div>
  169. </div>
  170. <!-- 添加或修改岗位对话框 -->
  171. <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
  172. </el-dialog>
  173. <el-dialog :title="titles" :visible.sync="opens" width="1000px" append-to-body>
  174. </el-dialog>
  175. <el-dialog title="页面二维码" :visible.sync="opent" width="200px" style="padding: 0;" class="nhgrls" append-to-body>
  176. <div v-show="opent" style="display: flex;justify-content: center;align-items: center;">
  177. <!-- <span>{{'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg}}</span> -->
  178. <!-- <vue-qr :text="'https://qszdh.qs163.cn/pages/index/index?id=' + this.bg" :size="200"></vue-qr> -->
  179. </div>
  180. </el-dialog>
  181. </div>
  182. </template>
  183. <script>
  184. import { listChannelNumber, listChannelNumbernopa,getChannelNumber, delChannelNumber, addChannelNumber, updateChannelNumber } from "@/api/system/channelNumber"
  185. import { listWarnManage, getWarnManage, delWarnManage, addWarnManage, updateWarnManage } from "@/api/manage/warnManage"
  186. // import { listPost, getPost, delPost, addPost, updatePost,updateFs,updateGx } from "@/api/kaoch/renyuan";
  187. // import { listReservat,camera,cameraIndexCode, listReservatd, getReservat, delReservat, addReservat, updateReservat,setPass,delReservathx,openDz,closeDz } from "@/api/tonggi/houtai";
  188. // import vueQr from "vue-qr";
  189. // import videojs from 'video.js'
  190. // import 'video.js/dist/video-js.css'
  191. // import {videoPlayer} from 'vue-video-player'
  192. // import 'videojs-flash'
  193. // import flvjs from 'flv.js/dist/flv.min.js'
  194. // import flvjs from "flv.js";
  195. import mqtt from 'mqtt';
  196. import { MqttClient } from 'mqtt'
  197. // 状态变量
  198. // const client = mqtt.connect('ws://13.229.167.76:1884/mqtt')
  199. var client = MqttClient||null
  200. import Bscroll from "better-scroll";
  201. export default {
  202. name: "Post",
  203. dicts: ['sys_normal_disable','sys_yes_no','youke','tjzh','youkes','lafafen','fange','jluly'],
  204. // components: {
  205. // vueQr,
  206. // videoPlayer
  207. // },
  208. data() {
  209. return {
  210. // 遮罩层
  211. loading: true,
  212. opent:false,
  213. bg:null,
  214. titles:'',
  215. editableTabsValue:'6',
  216. opens:false,
  217. // 通道管理表格数据
  218. channelNumberList: [],
  219. imageUrl:'@/assets/logo/logo.png',
  220. printObj: {
  221. id: "nhgrew", // 这里是要打印元素的ID
  222. popTitle: "", // 打印的标题
  223. },
  224. pickerOptions:{
  225. disabledDate (time) {
  226. //disabledDate 文档上:设置禁用状态,参数为当前日期,要求返回 Boolean
  227. // return time.getTime() > Date.now()//选当前时间之前的时间
  228. return time.getTime() < Date.now() - 8.64e7;//选当前时间之后的时间
  229. }
  230. },
  231. // 选中数组
  232. ids: [],
  233. // 非单个禁用
  234. single: true,
  235. checkedScoreDataDetails: [],
  236. scoreDataDetailsList:[],
  237. tabPosition:'left',
  238. // 非多个禁用
  239. multiple: true,
  240. // 显示搜索条件
  241. showSearch: true,
  242. // 总条数
  243. total: 0,
  244. // 岗位表格数据
  245. postList: [],
  246. // 弹出层标题
  247. title: "",
  248. // 是否显示弹出层
  249. open: false,
  250. // 查询参数
  251. queryParams: {
  252. pageNo: 1,
  253. pageSize:500,
  254. name:null,
  255. postCode: undefined,
  256. postName: undefined,
  257. status: undefined,
  258. reservatType:undefined
  259. },
  260. // 表单参数
  261. form: {},
  262. // 表单校验
  263. rules: {
  264. receptionId: [
  265. { required: true, message: "不能为空", trigger: "blur" }
  266. ],
  267. },
  268. ruless:{
  269. visitName: [
  270. { required: true, message: "不能为空", trigger: "blur" }
  271. ],
  272. visitPhone: [
  273. { required: true, message: "不能为空", trigger: "blur" }
  274. ],
  275. visitNum: [
  276. { required: true, message: "不能为空", trigger: "blur" }
  277. ],
  278. visitDate: [
  279. { required: true, message: "不能为空", trigger: "blur" }
  280. ],
  281. visitTime: [
  282. { required: true, message: "不能为空", trigger: "blur" }
  283. ],
  284. },
  285. forms:{},
  286. tableMaxHeight:'200',
  287. kje:0,
  288. ksjegsg:[],
  289. Scroll: null,
  290. videoShow: false,
  291. flvPlayer:null,
  292. player: null,
  293. name:null,
  294. isshiwa:false,
  295. isjfwe:{},
  296. isshoe:false,
  297. webRtcServer: null,
  298. camera_ip: '127.0.0.1:8000',
  299. g_iWndIndex:0,
  300. iRtspPort:'',//预览中的ip
  301. szDeviceIdentify:'',//ip_port,
  302. isfse:false,
  303. g_bEnableDraw:false,
  304. // 所有绘制的图形
  305. shapes: [],
  306. // 禁用
  307. isdisflag:false,
  308. connectionStatus:'',
  309. isConnected:false,
  310. connecting:false,
  311. messages:[{ type: 'sent' , content: '', timestamp: '' }],
  312. messageToSend:[],
  313. mqttConfig:{
  314. url: 'ws://13.229.167.76:1884/mqtt',
  315. topic: 'detection/rect'
  316. },
  317. mqttThemeName:{
  318. url: 'ws://13.229.167.76:1884/mqtt',
  319. topic: 'detection/rect'
  320. },
  321. };
  322. },
  323. created() {
  324. this.isfse = false
  325. // this.getList();
  326. this.getListtd()
  327. window.onresize = () => {
  328. this.changeTableMaxHeight()
  329. }
  330. this.changeTableMaxHeight()
  331. },
  332. mounted() {
  333. this.toggleConnection()
  334. // this.webRtcServer = new WebRtcStreamer('video', location.protocol + '//' + this.camera_ip)
  335. // //需要查看的rtsp地址,根据自己的摄像头传入对应的rtsp地址即可。注意:视频编码格式必须是H264的,否则无法正常显示,编码格式可在摄像头的后台更改
  336. // this.webRtcServer.connect('rtsp://admin:zxy123456@192.168.101.64:554/h264/ch1/main/av_stream')
  337. window.onresize = () => {
  338. this.changeTableMaxHeight()
  339. }
  340. this.changeTableMaxHeight()
  341. this.$nextTick(() => {
  342. this.initScroll()
  343. })
  344. },
  345. beforeDestroy() {
  346. // this.destoryVideo()
  347. if(WebVideoCtrl){
  348. console.log(this.szDeviceIdentify)
  349. WebVideoCtrl.I_Logout(this.szDeviceIdentify)
  350. WebVideoCtrl.I_StopAllPlay()
  351. WebVideoCtrl.I_DestroyPlugin()
  352. WebVideoCtrl.I_Resize()
  353. }
  354. },
  355. methods: {
  356. /** 查询通道管理列表 */
  357. getListtd() {
  358. this.loading = true
  359. let queryParams = {}
  360. listChannelNumbernopa().then(response => {
  361. this.channelNumberList = response.rows
  362. if(this.channelNumberList.length !=0){
  363. let snghs = this.channelNumberList[0].videoAddress.split('@')
  364. let snghst = snghs[1].split(':')
  365. let snsgduan = snghst[1].split('/')
  366. console.log(snghs,snghst,snsgduan)
  367. let sgse={'ip':snghst[0],'duank':snsgduan[0],
  368. 'account':this.channelNumberList[0].account,
  369. 'password':this.channelNumberList[0].password,
  370. }
  371. this.getVideo(sgse)
  372. WebVideoCtrl.I_ShowPlugin()
  373. this.loading = false
  374. }
  375. // getWarnManage(this.$route.query.id).then(response => {
  376. // this.form = response.data
  377. this.loading = false
  378. })
  379. },
  380. clickEnableDraw() {
  381. WebVideoCtrl.I_SetDrawStatus(true).then(() => {
  382. this.g_bEnableDraw = true;
  383. // showOPInfo("启用绘制成功!");
  384. }, (oError) => {
  385. // showOPInfo("启用绘制失败!", oError.errorCode, oError.errorMsg);
  386. });
  387. },
  388. getdrawFn(){
  389. this.isdisflag=!this.isdisflag;
  390. if(this.isdisflag){
  391. this.clickDisableDraw()
  392. }else{
  393. this.clickEnableDraw()
  394. }
  395. },
  396. // 禁用多边形绘制
  397. clickDisableDraw() {
  398. WebVideoCtrl.I_SetDrawStatus(false).then(() => {
  399. this.g_bEnableDraw = false;
  400. // showOPInfo("禁用绘制成功!");
  401. this.clickAddSnapPolygon()
  402. }, (oError) => {
  403. // showOPInfo("禁用绘制失败!", oError.errorCode, oError.errorMsg);
  404. });
  405. },
  406. clickGetSnapPolygon() {
  407. var that=this;
  408. WebVideoCtrl.I_GetSnapPolygonInfo(this.g_iWndIndex).then((szXml) => {
  409. console.log('获取图形:', szXml);
  410. that.getpoint(szXml)
  411. });
  412. },
  413. //获取x,y轴
  414. getpoint(xmlString){
  415. var that=this;
  416. const parser = new DOMParser();
  417. const xmlDoc = parser.parseFromString(xmlString, "text/xml");
  418. // 获取所有 SnapPolygon 节点
  419. const polygonNodes = xmlDoc.querySelectorAll("SnapPolygon");
  420. var newArr=[];
  421. var arr1=JSON.parse(JSON.stringify(this.shapes))
  422. // 提取每个多边形的 id 和坐标点
  423. this.polygons = Array.from(polygonNodes).map((polygonNode) => {
  424. const id = polygonNode.querySelector("id").textContent;
  425. const pointNodes = polygonNode.querySelectorAll("point");
  426. const points = Array.from(pointNodes).map((pointNode) => ({
  427. x: pointNode.querySelector("x").textContent,
  428. y: pointNode.querySelector("y").textContent,
  429. }));
  430. var newobj={
  431. id:id,
  432. points:points
  433. }
  434. newArr.push(newobj)
  435. // return { id, points };
  436. });
  437. this.shapes = arr1.map(item1 => {
  438. const matchedItem = newArr.find(item2 => item2.id == item1.id);
  439. return {
  440. id: item1.id,
  441. points: matchedItem ? matchedItem.points : item1.points
  442. };
  443. });
  444. // this.shapes=JSON.parse(JSON.stringify(newArr))
  445. this.messageToSend = this.shapes
  446. this.sendMessage()
  447. console.log(this.shapes)
  448. },
  449. toggleConnection(){
  450. if (this.isConnected) {
  451. // 断开连接
  452. client.end()
  453. this.isConnected= false
  454. this.connectionStatus = 'Disconnected'
  455. return
  456. }
  457. // 建立连接
  458. this.connecting = true
  459. try {
  460. client= mqtt.connect(this.mqttConfig.url, {
  461. clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
  462. keepalive: 60,
  463. clean: true,
  464. connectTimeout: 4000,
  465. reconnectPeriod: 1000
  466. })
  467. client.on('connect', () => {
  468. this.isConnected = true
  469. this.connectionStatus= 'Connected'
  470. this.connecting = false
  471. console.log(3)
  472. // 订阅主题
  473. client.subscribe(this.mqttConfig.topic, (err) => {
  474. if (err) {
  475. console.error('Subscribe error:', err)
  476. }else{
  477. console.log('成功订阅 detection/rect 主题!')
  478. }
  479. })
  480. })
  481. client.on('message', (topic, message) => {
  482. // 接受信息
  483. console.log(topic,message)
  484. this.messages.unshift({
  485. type: 'received',
  486. content: message.toString(),
  487. timestamp: new Date().toLocaleTimeString()
  488. })
  489. })
  490. client.on('error', (err) => {
  491. console.error('MQTT Error:', err)
  492. this.connectionStatus= 'Error'
  493. this.connecting = false
  494. })
  495. } catch (error) {
  496. console.error('Connection error:', error)
  497. this.connectionStatus= 'Error'
  498. this.connecting = false
  499. }
  500. },
  501. sendMessage(){
  502. if (!client || !this.messageToSend) return
  503. this.messageToSend = JSON.stringify(this.messageToSend)
  504. console.log(this.messageToSend)
  505. client.publish(this.mqttConfig.topic, this.messageToSend)
  506. this.messages.unshift({
  507. type: 'sent',
  508. content: this.messageToSend,
  509. timestamp: new Date().toLocaleTimeString()
  510. })
  511. this.messageToSend = []
  512. },
  513. // 添加图形,最多不超过16个图形
  514. clickAddSnapPolygon() {
  515. var that=this;
  516. if (!this.g_bEnableDraw) {
  517. return;
  518. }
  519. var shapes=JSON.parse(JSON.stringify(this.shapes))
  520. let szId = 1; // 默认从 1 开始
  521. if(shapes&&shapes.length>0){
  522. const ids = shapes.map(item => item.id).sort((a, b) => a - b);
  523. for (const id of ids) {
  524. if (id > szId) {
  525. // 如果当前 id > szId,说明 szId 未被使用
  526. break;
  527. }
  528. szId = Number(id) + 1; // 否则,继续检查下一个
  529. }
  530. }
  531. if (!/^[1-9]\d*$/.test(szId)) {
  532. alert("图形ID只能为正整数!");
  533. return
  534. }
  535. if (Number(szId) > 32) {
  536. alert("图形ID范围1-32!");
  537. return
  538. }
  539. console.log(szId)
  540. // var szName = encodeString($("#snapName").val());
  541. var szName = '';
  542. var szInfo={
  543. }
  544. var szInfo = "<?xml version='1.0' encoding='utf-8'?>";
  545. szInfo += "<SnapPolygonList>";
  546. szInfo += "<SnapPolygon>";
  547. szInfo += "<id>" + szId + "</id>"; // [1, 32]
  548. szInfo += "<polygonType>0</polygonType>"; //如果想绘制多边形,polygonType指需要改为1
  549. szInfo += "<PointNumMax>17</PointNumMax>"; // [MinClosed, 17]
  550. szInfo += "<MinClosed>4</MinClosed>"; // [4, 17]
  551. szInfo += "<tips>#" + szId + "#" + szName + "</tips>";
  552. szInfo += "<isClosed>false</isClosed>";
  553. szInfo += "<color><r>0</r><g>255</g><b>0</b></color>";
  554. szInfo += "<pointList/>";
  555. szInfo += "</SnapPolygon>";
  556. szInfo += "</SnapPolygonList>";
  557. WebVideoCtrl.I_SetSnapPolygonInfo(this.g_iWndIndex, szInfo).then(() => {
  558. // showOPInfo("添加图形成功!");
  559. var obj={
  560. id:szId,
  561. points:[]
  562. }
  563. if(this.shapes&&this.shapes.length){
  564. this.shapes.splice(Number(szId)-1,0,obj)
  565. }else{
  566. this.shapes.push(obj)
  567. }
  568. });
  569. WebVideoCtrl.I_SetSnapDrawMode(this.g_iWndIndex, 2);
  570. },
  571. //删除图形
  572. clickDelSnapPolygon(szId,idx) {
  573. if (!this.g_bEnableDraw) {
  574. return;
  575. }
  576. var aShapes = [];
  577. aShapes.push({
  578. polygonType: 0,
  579. id: szId
  580. });
  581. this.shapes.splice(idx,1)
  582. WebVideoCtrl.I_ClearSnapInfo(this.g_iWndIndex, aShapes);
  583. },
  584. // 清空图形
  585. clickDelAllSnapPolygon() {
  586. if (!this.g_bEnableDraw) {
  587. return;
  588. }
  589. WebVideoCtrl.I_ClearSnapInfo(this.g_iWndIndex).then(() => {
  590. // showOPInfo("清空图形成功!");
  591. this.shapes=[];
  592. }, (oError) => {
  593. // showOPInfo("清空图形失败!", oError.errorCode, oError.errorMsg);
  594. });
  595. },
  596. // 通道点击
  597. ishg(val){
  598. this.isfse = false
  599. if(WebVideoCtrl){
  600. console.log(this.szDeviceIdentify)
  601. this.clickDelAllSnapPolygon()
  602. WebVideoCtrl.I_Logout(this.szDeviceIdentify)
  603. WebVideoCtrl.I_StopAllPlay()
  604. WebVideoCtrl.I_DestroyPlugin()
  605. WebVideoCtrl.I_Resize()
  606. }
  607. let snghs = val.videoAddress.split('@')
  608. let snghst = snghs[1].split(':')
  609. let snsgduan = snghst[1].split('/')
  610. console.log(snghs,snghst,snsgduan)
  611. let sgse={'ip':snghst[0],'duank':snsgduan[0],
  612. 'account':val.account,
  613. 'password':val.password,
  614. }
  615. this.getVideo(sgse)
  616. WebVideoCtrl.I_ShowPlugin()
  617. // this.clickStartRealPlay('192.168.101.64', '80',1, 0, 1);
  618. },
  619. init(val) { //这个val 就是一个地址,例如: http://192.168.2.201:85/live/9311272c49b845baa2b2810ad9bf3f68.flv 这是个服务器返回给我的一个监控视频流地址
  620. setTimeout(() => { //使用定时器是因为,在mounted声明周期里调用,可能会出现DOM没加载出来的原因
  621. var videoElement = this.$refs.videosmallone; // 获取到html中的video标签
  622. this.isshiwa = true
  623. if (flvjs.isSupported()) {
  624. //因为我这个是复用组件,进来先判断 player是否存在,如果存在,销毁掉它,不然会占用TCP名额
  625. if (this.player !== null) {
  626. this.player.pause();
  627. this.player.unload();
  628. this.player.detachMediaElement();
  629. this.player.destroy();
  630. this.player = null;
  631. }
  632. this.player = flvjs.createPlayer( //创建直播流,加载到DOM中去
  633. {
  634. type: "flv",
  635. url: val, //你的url地址
  636. isLive: true, //数据源是否为直播流
  637. hasAudio: false, //数据源是否包含有音频
  638. hasVideo: true, //数据源是否包含有视频
  639. enableStashBuffer: true, //是否启用缓存区
  640. },
  641. {
  642. enableWorker: false, //不启用分离线程
  643. enableStashBuffer: false, //关闭IO隐藏缓冲区
  644. autoCleanupSourceBuffer: true, //自动清除缓存
  645. lazyLoad: false,
  646. }
  647. );
  648. this.isshoe = true
  649. this.player.attachMediaElement(videoElement); //放到dom中去
  650. //!!!!!!这里需要注意,有的时候load加载完成不一定可以播放,要是播放不成功,用settimeout 给下面的this.player.play() 延时几百毫秒再播放
  651. // setTimeout(this.player.play(), 48000);
  652. setTimeout(() =>{
  653. //到时间时只执行一次就停止
  654. this.player.load();//准备完成
  655. this.player.play()
  656. console.log('播放')
  657. },900)
  658. }
  659. }, 500);
  660. },
  661. createVideo() {
  662. if (flvjs.isSupported()) {
  663. console.log(1)
  664. var videoElement = document.getElementById('myFlvVideo')
  665. console.log(videoElement,flvjs)
  666. this.flvPlayer = flvjs.createPlayer(
  667. {
  668. type: 'application/x-mpegURL',
  669. isLive: true,
  670. hasAudio: false,
  671. url:'https://stream1.freetv.fun/86d463c0006da643e45e26b34875df87059dcba13e69d0a5471b185793c122a2.m3u8'
  672. },
  673. {
  674. cors: true, // 是否跨域
  675. enableWorker: false, // 是否多线程工作
  676. enableStashBuffer: false, // 是否启用缓存
  677. stashInitialSize: 400, // 缓存大小(kb) 默认384kb
  678. autoCleanupSourceBuffer: true // 是否自动清理缓存
  679. }
  680. )
  681. this.flvPlayer.attachMediaElement(videoElement)
  682. this.flvPlayer.load()
  683. this.flvPlayer.play()
  684. console.log(1244)
  685. // 报错重连
  686. this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {
  687. console.log('errorType:', errType)
  688. console.log('errorDetail:', errDetail)
  689. if (this.flvPlayer) {
  690. this.destoryVideo()
  691. this.createVideo()
  692. }
  693. })
  694. }
  695. console.log(this.flvPlayer.play())
  696. },
  697. destoryVideo() {
  698. this.player.pause()
  699. this.player.unload()
  700. this.player.detachMediaElement()
  701. this.player.destroy()
  702. this.player = null
  703. },
  704. initScroll() {
  705. // 给内层盒子设置宽度,不设置宽度的话无法滚动
  706. // let width = this.goods.length * 60
  707. // // 如果有外边距,可以这样写。需要去掉最后一个元素的外边距,在后面减一下
  708. // let width = this.goodslength * (60 + 10) - 10
  709. let width = 6 * (200 + 10) - 10
  710. // this.$refs.content.style.width = width + 'px'
  711. this.$nextTick(()=>{
  712. if(!this.Scroll) {
  713. this.Scroll = new Bscroll(this.$refs.wrapper,{
  714. click: true, // 配置允许点击事件
  715. scrollX: true, // 开启横向滚动
  716. eventPassthrough: 'vertical', // 当设置 eventPassthrough 为 'vertical' 的时候,scrollY 无效
  717. mouseWheel: true,
  718. scrollbar: { // 滚动条, 要加相对位置
  719. fade: true
  720. }
  721. })
  722. } else {
  723. this.Scroll.refresh() // 重新计算 better-scroll,当 DOM 结构发生变化的时确保滚动效果正常
  724. }
  725. })
  726. },
  727. /** 查询岗位列表 */
  728. getList() {
  729. // this.queryParams
  730. this.loading = true
  731. // getWarnManage(this.$route.query.id).then(response => {
  732. // this.form = response.data
  733. const url = new URL('rtsp://admin:zxy123456@192.168.101.64:554/h264/ch1/main/av_stream');
  734. const auth = url.username + ':' + url.password;
  735. console.log(url.username,url.password,8)
  736. // this.username = url.username;
  737. // this.password = url.password;
  738. this.getVideo()
  739. WebVideoCtrl.I_ShowPlugin()
  740. this.loading = false
  741. // this.open = true
  742. // this.title = "修改告警管理"
  743. // })
  744. // camera(this.queryParams).then(response => {
  745. // this.postList = response.data.data.list;
  746. // if(response.data.data != null){
  747. // if(response.data.data.list.length != 0){
  748. // let ne = response.data.data.list[0]
  749. // response.data.data.list.filter(rtu=>{
  750. // if(rtu.name == '后门道闸'){
  751. // console.log(3,rtu)
  752. // ne = rtu
  753. // return
  754. // }
  755. // })
  756. // this.isfgw(ne)
  757. // this.isjfwe =ne
  758. // }
  759. // }
  760. // // this.postList=[{'nsje':null,'visitPhone':null,'isReception':'Y'}]
  761. // this.total = response.data.data.total;
  762. // this.loading = false;
  763. // });
  764. },
  765. getListh() {
  766. this.loading = true;
  767. listReservatd().then(response => {
  768. // this.postList = response.rows;
  769. this.ksjegsg= response.data
  770. // this.total = response.total;
  771. this.loading = false;
  772. });
  773. },
  774. isfgw(val){
  775. this.isjfwe = val
  776. let nhge={cameraIndexCode:val.indexCode}
  777. this.isshiwa = false
  778. this.isshoe= false
  779. cameraIndexCode(nhge.cameraIndexCode).then(response => {
  780. console.log(response.data.data.url)
  781. this.isshoe= true
  782. this.init(response.data.data.url)
  783. this.isshiwa = true
  784. // this.postList = response.rows;
  785. // this.total = response.total;
  786. });
  787. console.log(val,4)
  788. },
  789. osge(){
  790. console.log(this.isjfwe,45)
  791. if(this.isjfwe.name == '后门道闸'){
  792. this.isjfwe.name ='后门抓拍一体机1'
  793. }
  794. let nge={equipmentName:this.isjfwe.name}
  795. openDz(nge).then(response => {
  796. });
  797. },
  798. osgef(){
  799. if(this.isjfwe.name == '后门道闸'){
  800. this.isjfwe.name ='后门抓拍一体机1'
  801. }
  802. let nge={equipmentName:this.isjfwe.name}
  803. closeDz(nge).then(response => {
  804. // this.postList = response.rows;
  805. });
  806. },
  807. ilw(row,val){
  808. this.kje = val
  809. // console.log(row)
  810. if(row.value == 0){
  811. this.queryParams.reservatType = undefined
  812. }else{
  813. this.queryParams.reservatType = row.value
  814. }
  815. console.log(this.kje)
  816. this.queryParams.pageNum = 1
  817. this.getList()
  818. },
  819. nhgwel(item){
  820. this.form.receptionId = item.receptionId
  821. this.form.receptionName = item.receptionName
  822. this.form.receptionPhone = item.phonenumber
  823. },
  824. getPass(row) {
  825. const _this = this
  826. this.$confirm('是否审核通过', "提醒", {
  827. confirmButtonText: "确定",
  828. cancelButtonText: "取消",
  829. type: "warning"
  830. }).then(function() {
  831. return setPass({
  832. visitType: 3,
  833. reservatId: row.reservatId,
  834. // xmStatus:row.xmStatus
  835. })
  836. }).then(() => {
  837. _this.getList();
  838. _this.msgSuccess("提交成功");
  839. })
  840. },
  841. infoBtn(row) {
  842. const _this = this
  843. this.$confirm('是否拒绝', "提醒", {
  844. confirmButtonText: "确定",
  845. cancelButtonText: "取消",
  846. type: "warning"
  847. }).then(function() {
  848. return setPass({
  849. visitType: 2,
  850. reservatId: row.reservatId,
  851. // xmStatus:row.xmStatus
  852. })
  853. }).then(() => {
  854. _this.getList();
  855. _this.msgSuccess("提交成功");
  856. })
  857. },
  858. // 取消按钮
  859. cancel() {
  860. this.open = false;
  861. this.opens = false;
  862. this.reset();
  863. },
  864. // 表单重置
  865. reset() {
  866. this.form = {
  867. receptionId:undefined,
  868. receptionPhone:undefined,
  869. // postSort: 0,
  870. // status: "0",
  871. receptionName: undefined
  872. };
  873. this.resetForm("form");
  874. },
  875. /** 搜索按钮操作 */
  876. handleQuery() {
  877. this.queryParams.pageNum = 1;
  878. this.getList();
  879. },
  880. /** 重置按钮操作 */
  881. resetQuery() {
  882. this.resetForm("queryForm");
  883. this.handleQuery();
  884. },
  885. // 多选框选中数据
  886. handleSelectionChange(selection) {
  887. this.ids = selection.map(item => item.reservatId)
  888. this.single = selection.length!=1
  889. this.multiple = !selection.length
  890. },
  891. nhgeo(row){
  892. this.reset();
  893. this.open = true;
  894. this.title = "分配接待人员";
  895. this.form.reservatId = row.reservatId;
  896. this.form.reservatConfigTimeId=row.reservatConfigTimeId;
  897. this.form.visitDate=row.visitDate
  898. },
  899. handleDeleteh(row){
  900. this.$router.push({
  901. path: '/bjqs',
  902. query: {
  903. 'id':row.reservatId,
  904. 'name':null,
  905. 'names':null,
  906. 'isxz':1
  907. }
  908. })
  909. },
  910. /** 新增按钮操作 */
  911. handleAdd() {
  912. this.forms = {
  913. reservatType:'1'
  914. }
  915. this.opens = true;
  916. this.titles = "添加预约人员";
  917. // this.scoreDataDetailsList = []
  918. // this.$router.push({
  919. // path: '/system/bjq',
  920. // })
  921. // this.$router.push({
  922. // path: '/bjqs',
  923. // query: {
  924. // 'id':null,
  925. // 'name':null,
  926. // 'names':null,
  927. // 'isxz':1
  928. // }
  929. // })
  930. },
  931. /** 修改按钮操作 */
  932. handleUpdate(row) {
  933. this.reset();
  934. const recordId = row.recordId || this.ids
  935. getReservat(recordId).then(response => {
  936. this.forms = response.data;
  937. this.opens = true;
  938. this.title = "修改访问记录";
  939. });
  940. },
  941. /** 提交按钮 */
  942. submitForm: function() {
  943. this.$refs["form"].validate(valid => {
  944. if (valid) {
  945. // if (this.form.reservatId != null) {
  946. updateReservat(this.form).then(response => {
  947. this.$modal.msgSuccess("操作成功");
  948. this.open = false;
  949. this.getList();
  950. });
  951. // } else {
  952. // addReservat(this.form).then(response => {
  953. // this.$modal.msgSuccess("新增成功");
  954. // this.open = false;
  955. // this.getList();
  956. // });
  957. // }
  958. }
  959. });
  960. },
  961. submitForms: function() {
  962. this.$refs["forms"].validate(valid => {
  963. if (valid) {
  964. // if (this.form.reservatId != null) {
  965. // updateReservat(this.forms).then(response => {
  966. // this.$modal.msgSuccess("操作成功");
  967. // this.open = false;
  968. // this.getList();
  969. // });
  970. // } else {
  971. this.forms.visitTime = this.forms.visitTime + '-' + this.forms.visitTime
  972. addReservat(this.forms).then(response => {
  973. this.$modal.msgSuccess("新增成功");
  974. this.opens = false;
  975. this.getList();
  976. });
  977. // }
  978. }
  979. });
  980. },
  981. nglqw(val){
  982. this.opent = true
  983. this.bg = val.investigateTableId
  984. },
  985. iszheg(event){
  986. console.log(event);
  987. // 校验身份证:
  988. console.log(reg.test(this.form.idCard),23741)
  989. if ( reg.test(this.form.idCard)|| _IDre15.test(this.form.idCard)) {
  990. // this.idea();
  991. this.go(this.form.idCard);
  992. // callback()
  993. } else {
  994. if(ncjsle.test(this.form.idCard) || nhyeli.test(this.form.idCard)){
  995. console.log(3)
  996. }else{
  997. if(gnse.test(this.form.idCard) ){
  998. console.log(4)
  999. }else{
  1000. if(tw.test(this.form.idCard) || twe.test(this.form.idCard)){
  1001. console.log(5)
  1002. }else{
  1003. this.$message.error('证件格式不正确');
  1004. }
  1005. }
  1006. }
  1007. }
  1008. },
  1009. erw(row){
  1010. this.$router.push({
  1011. path: '/reny/ewm',
  1012. query:{
  1013. 'tenantId':row.investigateTableId
  1014. }
  1015. })
  1016. },
  1017. hussar_17Click(val) {
  1018. const _this = this
  1019. var url =process.env.VUE_APP_BASE_API + 'pages/index/index?id=' + val.investigateTableId;
  1020. console.log(url,this.$refs.canvas,6)
  1021. this.opent = true
  1022. QRCode.toCanvas(
  1023. canvas,
  1024. url,//生成二维码的数据
  1025. {width: 100, height:100, margin: 1.5},//margin调整二维码的白边大小
  1026. function (error) {
  1027. if (error) {
  1028. console.log(error);
  1029. }
  1030. }
  1031. );
  1032. // console.log(qrcode,987)
  1033. },
  1034. /** 成绩_子添加按钮操作 */
  1035. handleAddScoreDataDetails() {
  1036. let obj = {};
  1037. obj.duty = "";
  1038. obj.idCard = "";
  1039. obj.phonenumber = "";
  1040. obj.userName = "";
  1041. this.scoreDataDetailsList.push(obj);
  1042. console.log(this.scoreDataDetailsList)
  1043. },
  1044. /** 成绩_子删除按钮操作 */
  1045. handleDeleteScoreDataDetails() {
  1046. if (this.checkedScoreDataDetails.length == 0) {
  1047. this.$modal.msgError("请先选择要删除的数据");
  1048. } else {
  1049. const scoreDataDetailsList = this.scoreDataDetailsList;
  1050. const checkedScoreDataDetails = this.checkedScoreDataDetails;
  1051. this.scoreDataDetailsList = scoreDataDetailsList.filter(function(item) {
  1052. return checkedScoreDataDetails.indexOf(item.index) == -1
  1053. });
  1054. }
  1055. },
  1056. /** 复选框选中数据 */
  1057. handleScoreDataDetailsSelectionChange(selection) {
  1058. this.checkedScoreDataDetails = selection.map(item => item.index)
  1059. },
  1060. /** 成绩_子序号 */
  1061. rowScoreDataDetailsIndex({ row, rowIndex }) {
  1062. row.index = rowIndex + 1;
  1063. },
  1064. /** 删除按钮操作 */
  1065. handleDelete(row) {
  1066. const postIds = row.recordId || this.ids;
  1067. delReservat(postIds).then(response => {
  1068. this.$modal.msgSuccess("操作成功");
  1069. this.getList();
  1070. });
  1071. // this.$modal.confirm('是否确认删除数据项?').then(function() {
  1072. // return delPost(postIds);
  1073. // }).then(() => {
  1074. // this.getList();
  1075. // this.$modal.msgSuccess("删除成功");
  1076. // }).catch(() => {});
  1077. },
  1078. handleDeletehx(row) {
  1079. const postIds = row.reservatId || this.ids;
  1080. let nhg={}
  1081. nhg.reservatId = postIds
  1082. delReservathx(nhg).then(response => {
  1083. this.$modal.msgSuccess("操作成功");
  1084. this.getList();
  1085. });
  1086. // this.$modal.confirm('是否确认删除数据项?').then(function() {
  1087. // return delPost(postIds);
  1088. // }).then(() => {
  1089. // this.getList();
  1090. // this.$modal.msgSuccess("删除成功");
  1091. // }).catch(() => {});
  1092. },
  1093. // 发送短信
  1094. handleUpdatefas(row){
  1095. updateFs(row).then(response => {
  1096. this.$modal.msgSuccess("发送成功");
  1097. // this.getList();
  1098. });
  1099. },
  1100. handleDeletegx(row){
  1101. updateGx(row).then(response => {
  1102. this.$modal.msgSuccess("发送成功");
  1103. // this.getList();
  1104. });
  1105. },
  1106. /** 导出按钮操作 */
  1107. handleExport() {
  1108. this.download('system/reservat/export', {
  1109. ...this.queryParams
  1110. }, `预约人员.xlsx`)
  1111. },
  1112. // 获取屏幕高度
  1113. showFilterForm () {
  1114. this.filterActive = !this.filterActive
  1115. this.changeTableMaxHeight()
  1116. },
  1117. changeTableMaxHeight () {
  1118. let height = document.body.offsetHeight // 网页可视区域高度
  1119. // if (this.filterActive) {
  1120. // this.tableMaxHeight = height - 320
  1121. // } else {
  1122. this.tableMaxHeight = height - 350
  1123. // }
  1124. console.log(height)
  1125. },
  1126. // 播放摄像头
  1127. getVideo(row) {
  1128. var that=this;
  1129. this.isfse = true
  1130. console.log(row)
  1131. this.initVideoPlay(row.ip, '80', row.account, row.password,'divPlugin')
  1132. },
  1133. // 有插件
  1134. initVideoPlay(ip, port, username, password,id) {
  1135. var that = this;
  1136. var g_iWndIndex = 0; //可以不用设置这个变量,有窗口参数的接口中,不用传值,开发包会默认使用当前选择窗口
  1137. var g_oLocalConfig = null; //本地配置
  1138. // let ip = this.szIP //硬盘录像机ip
  1139. // let port = this.szPort //默认为80端口
  1140. // let username = this.szUsername //账号:
  1141. // let password = this.szPassword // 密码
  1142. var iRtspPort = ''
  1143. // 1.初始化插件参数及插入插件
  1144. WebVideoCtrl.I_InitPlugin({
  1145. bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
  1146. iWndowType: 1,
  1147. bDebugMode: true,
  1148. cbSelWnd: function(xmlDoc) {
  1149. g_iWndIndex = parseInt($(xmlDoc).find("SelectWnd").eq(0).text(), 10);
  1150. const szInfo = "当前选择的窗口编号:" + g_iWndIndex;
  1151. this.g_iWndIndex = g_iWndIndex;
  1152. console.log(szInfo, "szInfo");
  1153. },
  1154. cbDoubleClickWnd: function(iWndIndex, bFullScreen) {
  1155. let szInfo = "当前放大的窗口编号:" + iWndIndex;
  1156. if (!bFullScreen) {
  1157. szInfo = "当前还原的窗口编号:" + iWndIndex;
  1158. }
  1159. // console.log(szInfo, "szInfo");
  1160. },
  1161. cbEvent: function(iEventType, iParam1, iParam2) {
  1162. if (2 == iEventType) {
  1163. // 回放正常结束
  1164. console.log("窗口" + iParam1 + "回放结束!");
  1165. } else if (-1 == iEventType) {
  1166. console.log("设备" + iParam1 + "网络错误!");
  1167. } else if (3001 == iEventType) {
  1168. clickStopRecord(g_szRecordType, iParam1);
  1169. }
  1170. },
  1171. //2.登录摄像头
  1172. cbInitPluginComplete: function() {
  1173. const oLiveView = {
  1174. iProtocol: 1, // protocol 1:http, 2:https
  1175. szIP: ip, // protocol ip
  1176. szPort: port, // protocol port
  1177. szUsername: username, // device username
  1178. szPassword: password, // device password
  1179. iStreamType: 1, // stream 1:main stream 2:sub-stream 3:third stream 4:transcode stream
  1180. iChannelID: 1, // channel no
  1181. bZeroChannel: false, // zero channel
  1182. };
  1183. // var swidth=Number((that.width*Number(that.scale))).toFixed(2)
  1184. // var sheight=Number((that.height*Number(that.scale))).toFixed(2)
  1185. // that.swidth=swidth
  1186. // that.sheight=sheight
  1187. WebVideoCtrl.I_InsertOBJECTPlugin(id).then(
  1188. () => {
  1189. // setTimeout(function(){
  1190. // WebVideoCtrl.I_Resize(swidth,sheight)
  1191. // },300)
  1192. WebVideoCtrl.I_Login(
  1193. oLiveView.szIP,
  1194. oLiveView.iProtocol,
  1195. oLiveView.szPort,
  1196. oLiveView.szUsername,
  1197. oLiveView.szPassword, {
  1198. timeout: 3000,
  1199. async: false,
  1200. success: function(xmlDoc) {
  1201. console.log(" 登录成功!");
  1202. let a = ip
  1203. let b = port
  1204. setTimeout(function() {
  1205. //延迟方法
  1206. setTimeout(function() {
  1207. //调用预览摄像头这里可以循环创建
  1208. that.clickStartRealPlay(a, b,1, 0, 1);
  1209. // that.clickStartRealPlay(a, b, 1, 1,2);
  1210. // that.clickStartRealPlay(a, b, 1, 2,3);
  1211. // clickStartRealPlay(a,b, 1, 3, 4);
  1212. // clickStartRealPlay(a,b, 1, 4, 5);
  1213. // clickStartRealPlay(a,b, 1, 5, 6);
  1214. // clickStartRealPlay(a,b, 1, 6, 7);
  1215. // clickStartRealPlay(a,b, 1, 7, 8);
  1216. }, 1000);
  1217. setTimeout(function() {
  1218. // 获取通道 (如果多个摄像头需要获取多个通道需要调用)
  1219. // getChannelInfo(a);
  1220. //获取端口 (在这里获取RTSP 端口号 预览时传入)
  1221. getDevicePort(a);
  1222. }, 10)
  1223. }, 10);
  1224. },
  1225. error: function(oError) {
  1226. console.log(" 登录失败!", oError);
  1227. },
  1228. }
  1229. );
  1230. // 检查插件是否最新
  1231. WebVideoCtrl.I_CheckPluginVersion().then((bFlag) => {
  1232. if (bFlag) {
  1233. alert(
  1234. "检测到新的插件版本,双击开发包目录里的HCWebSDKPlugin.exe升级!"
  1235. );
  1236. }
  1237. });
  1238. },
  1239. () => {
  1240. alert(
  1241. "插件初始化失败,请确认是否已安装插件;如果未安装,请双击开发包目录里的HCWebSDKPlugin.exe安装!"
  1242. );
  1243. }
  1244. );
  1245. },
  1246. });
  1247. // 3.获取通道
  1248. function getChannelInfo(a) {
  1249. var szDeviceIdentify = a,
  1250. oSel = null; //通道列表
  1251. if (null == szDeviceIdentify) {
  1252. return;
  1253. }
  1254. // 模拟通道 有
  1255. WebVideoCtrl.I_GetAnalogChannelInfo(szDeviceIdentify, {
  1256. success: function(xmlDoc) {
  1257. var oChannels = $(xmlDoc).find("VideoInputChannel");
  1258. $.each(oChannels, function(i) {
  1259. var id = $(this).find("id").eq(0).text(),
  1260. name = $(this).find("name").eq(0).text();
  1261. if ("" == name) {
  1262. name = "Camera " + (i < 9 ? "0" + (i + 1) : (i + 1));
  1263. }
  1264. // console.log(id + "通道id是")
  1265. // console.log(name + "通道name是")
  1266. });
  1267. console.log(szDeviceIdentify + " 获取模拟通道成功!");
  1268. },
  1269. error: function(oError) {
  1270. console.log(szDeviceIdentify + " 获取模拟通道失败!", oError.errorCode, oError.errorMsg);
  1271. }
  1272. });
  1273. // 数字通道
  1274. WebVideoCtrl.I_GetDigitalChannelInfo(szDeviceIdentify, {
  1275. success: function(xmlDoc) {
  1276. var oChannels = $(xmlDoc).find("InputProxyChannelStatus");
  1277. $.each(oChannels, function(i) {
  1278. var id = $(this).find("id").eq(0).text(),
  1279. name = $(this).find("name").eq(0).text(),
  1280. online = $(this).find("online").eq(0).text();
  1281. if ("false" == online) { // 过滤禁用的数字通道
  1282. return true;
  1283. }
  1284. if ("" == name) {
  1285. name = "IPCamera " + (i < 9 ? "0" + (i + 1) : (i + 1));
  1286. }
  1287. });
  1288. console.log(szDeviceIdentify + " 获取数字通道成功!");
  1289. },
  1290. error: function(oError) {
  1291. console.log(szDeviceIdentify + " 获取数字通道失败!", oError.errorCode, oError.errorMsg);
  1292. }
  1293. });
  1294. // 零通道
  1295. WebVideoCtrl.I_GetZeroChannelInfo(szDeviceIdentify, {
  1296. success: function(xmlDoc) {
  1297. var oChannels = $(xmlDoc).find("ZeroVideoChannel");
  1298. $.each(oChannels, function(i) {
  1299. var id = $(this).find("id").eq(0).text(),
  1300. name = $(this).find("name").eq(0).text();
  1301. if ("" == name) {
  1302. name = "Zero Channel " + (i < 9 ? "0" + (i + 1) : (i + 1));
  1303. }
  1304. if ("true" == $(this).find("enabled").eq(0).text()) { // 过滤禁用的零通道
  1305. }
  1306. });
  1307. console.log(szDeviceIdentify + " 获取零通道成功!");
  1308. },
  1309. error: function(oError) {
  1310. console.log(szDeviceIdentify + " 获取零通道失败!", oError.errorCode, oError.errorMsg);
  1311. }
  1312. });
  1313. };
  1314. //4.获取端口
  1315. function getDevicePort(a) {
  1316. var szDeviceIdentify = a;
  1317. if (null == szDeviceIdentify) {
  1318. return;
  1319. }
  1320. WebVideoCtrl.I_GetDevicePort(szDeviceIdentify).then((oPort) => {
  1321. // console.log(oPort.iDevicePort + "iDevicePort的值是")
  1322. // console.log(oPort.iRtspPort + "iRtspPort的值是")
  1323. console.log(szDeviceIdentify + " 获取端口成功!");
  1324. iRtspPort = oPort.iRtspPort
  1325. that.iRtspPort = iRtspPort
  1326. }, (oError) => {
  1327. var szInfo = "获取端口失败!";
  1328. console.log(szDeviceIdentify + szInfo, oError.errorCode, oError.errorMsg);
  1329. });
  1330. };
  1331. },
  1332. // 5.开始预览
  1333. clickStartRealPlay(szIP, szPort, iStreamType, iWndIndex, iChannelID) {
  1334. var that=this;
  1335. var oWndInfo = WebVideoCtrl.I_GetWindowStatus(this.g_iWndIndex),
  1336. szDeviceIdentify = szIP + "_" + szPort, //ip
  1337. iChannelID = iChannelID,
  1338. bZeroChannel = false,
  1339. iPort = this.iRtspPort,
  1340. szInfo = "";
  1341. iStreamType = iStreamType;
  1342. if (null == szDeviceIdentify) {
  1343. return null;
  1344. }
  1345. this.szDeviceIdentify = szDeviceIdentify;
  1346. var startRealPlay = function() {
  1347. WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
  1348. iStreamType: iStreamType,
  1349. iChannelID: iChannelID,
  1350. bZeroChannel: bZeroChannel,
  1351. iWndIndex: iWndIndex, //要播放的窗口
  1352. iPort: iPort, //如果多个摄像头需要必填 (RTSP 端口号)
  1353. success: function() {
  1354. szInfo = "开始预览窗口" + iWndIndex + "成功!";
  1355. console.log(szDeviceIdentify + " " + szInfo);
  1356. },
  1357. error: function(oError) {
  1358. console.log(szDeviceIdentify + " 开始预览窗口" + iWndIndex + "失败!", oError
  1359. .errorCode, oError.errorMsg);
  1360. }
  1361. });
  1362. };
  1363. if (oWndInfo != null) { // 已经在播放了,先停止
  1364. WebVideoCtrl.I_Stop({
  1365. success: function() {
  1366. startRealPlay();
  1367. }
  1368. });
  1369. } else {
  1370. startRealPlay();
  1371. }
  1372. },
  1373. }
  1374. };
  1375. </script>
  1376. <style lang="scss">
  1377. .isjses{
  1378. .el-tabs--left .el-tabs__nav-wrap.is-left::after{
  1379. width:6px;
  1380. }
  1381. .el-tabs--left .el-tabs__active-bar.is-left,{
  1382. width:6px;
  1383. }
  1384. }
  1385. .ingaqe{
  1386. .el-input--medium{
  1387. width:100%;
  1388. }
  1389. }
  1390. .nhgrls{
  1391. .el-dialog__body{
  1392. padding: 0;
  1393. }
  1394. }
  1395. .hyr{
  1396. span{
  1397. text-decoration:underline;
  1398. }
  1399. }
  1400. </style>
  1401. <style scoped lang="scss">
  1402. .nghwgq{
  1403. display: flex;
  1404. flex-direction: column;
  1405. justify-content: center;
  1406. align-items: center;
  1407. margin-top: 90px;
  1408. div{
  1409. color:#aaa;
  1410. }
  1411. }
  1412. .ihgswq{
  1413. // width:100%;
  1414. // overflow-x: hidden;
  1415. // margin-top: 30px;
  1416. }
  1417. .fijge{
  1418. // width: 110%;
  1419. display: flex;
  1420. display: -webkit-flex;
  1421. justify-content: space-between;
  1422. .shotw{
  1423. position: relative;
  1424. // width:32%;
  1425. width: 238px;
  1426. height: 140px;
  1427. margin-left: 0;
  1428. margin-right: 20px;
  1429. margin-bottom: 15px;
  1430. img{
  1431. height: 100%;
  1432. cursor:pointer;
  1433. }
  1434. p{
  1435. // bottom:-10px;
  1436. margin: 0;
  1437. font-weight: bold;
  1438. font-size: 16px;
  1439. padding: 5px 10px;
  1440. cursor:pointer;
  1441. }
  1442. .iges{
  1443. position: absolute;
  1444. top:50%;
  1445. left:50%;
  1446. width:30px;
  1447. height: 30px;
  1448. transform: translate(-50%,-50%);
  1449. cursor:pointer;
  1450. }
  1451. }
  1452. }
  1453. .nhgwesvq{
  1454. width:1610px !important;
  1455. }
  1456. .shotw{
  1457. position: relative;
  1458. margin-left: -20px;
  1459. margin-right: -20px;
  1460. img{
  1461. width:100%;
  1462. height: 80vh;
  1463. }
  1464. p{
  1465. position: absolute;
  1466. bottom: 0;
  1467. left:0;
  1468. background-color: rgba(0, 0, 0, .5);
  1469. width: 100%;
  1470. padding: 13px 5px;
  1471. color:#fff;
  1472. font-weight: bold;
  1473. font-size: 18px;
  1474. }
  1475. .p{
  1476. top:0px;
  1477. height: 60px;
  1478. margin: 0;
  1479. padding-left: 20px;
  1480. }
  1481. }
  1482. .ksfpo{
  1483. background-color: #3464EB;
  1484. padding: 6px 12px;
  1485. border-radius: 4px ;
  1486. color:#fff;
  1487. cursor:pointer;
  1488. }
  1489. .ksfpok{
  1490. background-color: #FFFFFF;
  1491. padding: 5px 11px;
  1492. border-radius: 4px;
  1493. color:#3464EB;
  1494. border: 1px solid #3464EB;
  1495. margin-left: 10px;
  1496. cursor:pointer;
  1497. }
  1498. .ksfpofg{
  1499. background-color: #75DB75;
  1500. padding: 5px 11px;
  1501. border-radius: 4px;
  1502. color:#FFFFFF;
  1503. border: 1px solid #75DB75;
  1504. margin-left: 10px;
  1505. cursor:pointer;
  1506. }
  1507. .iuer{
  1508. display: flex;
  1509. justify-content: space-between;
  1510. align-items: center;
  1511. .ite{
  1512. display: flex;
  1513. justify-content: space-between;
  1514. align-items: center;
  1515. p{
  1516. cursor:pointer;
  1517. margin: 0;
  1518. font-size: 15px;
  1519. font-family: PingFang SC;
  1520. font-weight: 500;
  1521. color:#666666;
  1522. padding: 4px 12px;
  1523. background: #Fff;
  1524. border-radius: 4px;
  1525. margin-right: 20px;
  1526. position: relative;
  1527. }
  1528. .actt{
  1529. background: #fff;
  1530. // border-bottom: 3px solid #5974E0;
  1531. // border-radius: 0;
  1532. // border-bottom-right-radius: 4px;
  1533. color: #5974E0;
  1534. }
  1535. .actt{
  1536. &::after {
  1537. content: "";
  1538. width: 40%;
  1539. height: 5px;
  1540. border-radius: 3px;
  1541. transform: translate(-50%);
  1542. background-color: #5974E0;
  1543. position: absolute;
  1544. left: 50%;
  1545. bottom:-3px;
  1546. }
  1547. }
  1548. }
  1549. }
  1550. .lqw{
  1551. padding: 0 10px;
  1552. margin: 0;
  1553. margin-bottom: 20px;
  1554. }
  1555. .nhgel{
  1556. height: 170px;
  1557. background-color: #313b61;
  1558. width: 100%;
  1559. position: absolute;
  1560. top:0;
  1561. left:0;
  1562. z-index: 0;
  1563. }
  1564. .app-container{
  1565. background-color: #f3f4f6;
  1566. padding-top: 10px;
  1567. height: 180vh;
  1568. }
  1569. .ntgs{
  1570. position: relative;
  1571. // background-color: #fff;
  1572. padding: 5px;
  1573. // border-radius: 5px;
  1574. padding-top: 10px;
  1575. padding: 10px 20px;
  1576. .pagination-container{
  1577. height: 50px;
  1578. }
  1579. }
  1580. .nghfs{
  1581. position: relative;
  1582. background-color: #fff;
  1583. padding-top: 18px !important;
  1584. padding: 5px;
  1585. // border-radius: 5px;
  1586. // margin-bottom: 20px;
  1587. }
  1588. .ksf{
  1589. img{
  1590. width:100%;
  1591. height: 100%;
  1592. }
  1593. }
  1594. .ingwfaq{
  1595. font-weight: bold;
  1596. font-size: 16px;
  1597. }
  1598. .dflex{display: flex;}
  1599. .dflext{display: flex;align-items: flex-start;}
  1600. .drawings-list{width: 100%;flex: 0 0 auto;padding-left: 10px;line-height:36px ;
  1601. .delimg{width: 15px;height: 15px;margin-left: 5px;}
  1602. .txt{font-size: 12px;padding-left: 5px;flex: 1;}
  1603. .tflex{display: flex;align-items: center;}
  1604. }
  1605. .disbtn{display: flex;align-items: center;flex: 0 0 auto;min-height: 34px;cursor: pointer;
  1606. img{width: 14px;height: 14px;margin-right: 10px;}
  1607. font-weight: 500;
  1608. font-size: 14px;
  1609. color: #444444;
  1610. }
  1611. </style>