channelList.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. <template>
  2. <div id="channelList" style="width: 100%">
  3. <div class="page-header">
  4. <div class="page-title">
  5. <el-button icon="el-icon-back" size="mini" style="font-size: 20px; color: #000;" type="text" @click="showDevice" ></el-button>
  6. <el-divider direction="vertical"></el-divider>
  7. 通道列表
  8. </div>
  9. <div class="page-header-btn">
  10. <div v-if="!showTree" style="display: inline;">
  11. 搜索:
  12. <el-input @input="search" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字"
  13. prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input>
  14. 通道类型:
  15. <el-select size="mini" @change="search" style="width: 8rem; margin-right: 1rem;" v-model="channelType" placeholder="请选择"
  16. default-first-option>
  17. <el-option label="全部" value=""></el-option>
  18. <el-option label="设备" value="false"></el-option>
  19. <el-option label="子目录" value="true"></el-option>
  20. </el-select>
  21. 在线状态:
  22. <el-select size="mini" style="width: 8rem; margin-right: 1rem;" @change="search" v-model="online" placeholder="请选择"
  23. default-first-option>
  24. <el-option label="全部" value=""></el-option>
  25. <el-option label="在线" value="true"></el-option>
  26. <el-option label="离线" value="false"></el-option>
  27. </el-select>
  28. 码流类型重置:
  29. <el-select size="mini" style="width: 16rem; margin-right: 1rem;" @change="subStreamChange" v-model="subStream"
  30. placeholder="请选择码流类型" default-first-option >
  31. <el-option label="stream:0(主码流)" value="stream:0"></el-option>
  32. <el-option label="stream:1(子码流)" value="stream:1"></el-option>
  33. <el-option label="streamnumber:0(主码流-2022)" value="streamnumber:0"></el-option>
  34. <el-option label="streamnumber:1(子码流-2022)" value="streamnumber:1"></el-option>
  35. <el-option label="streamprofile:0(主码流-大华)" value="streamprofile:0"></el-option>
  36. <el-option label="streamprofile:1(子码流-大华)" value="streamprofile:1"></el-option>
  37. <el-option label="streamMode:main(主码流-水星+TP-LINK)" value="streamMode:main"></el-option>
  38. <el-option label="streamMode:sub(子码流-水星+TP-LINK)" value="streamMode:sub"></el-option>
  39. </el-select>
  40. </div>
  41. <el-button icon="el-icon-refresh-right" circle size="mini" @click="refresh()"></el-button>
  42. <el-button v-if="showTree" icon="iconfont icon-list" circle size="mini" @click="switchList()"></el-button>
  43. <el-button v-if="!showTree" icon="iconfont icon-tree" circle size="mini" @click="switchTree()"></el-button>
  44. </div>
  45. </div>
  46. <devicePlayer ref="devicePlayer"></devicePlayer>
  47. <el-container v-loading="isLoging" style="height: 82vh;">
  48. <el-aside width="auto" style="height: 82vh; background-color: #ffffff; overflow: auto" v-if="showTree">
  49. <DeviceTree ref="deviceTree" :device="device" :onlyCatalog="true" :clickEvent="treeNodeClickEvent"></DeviceTree>
  50. </el-aside>
  51. <el-main style="padding: 5px;">
  52. <el-table ref="channelListTable" :data="deviceChannelList" :height="winHeight" style="width: 100%"
  53. header-row-class-name="table-header">
  54. <el-table-column prop="channelId" label="通道编号" min-width="180">
  55. </el-table-column>
  56. <el-table-column prop="deviceId" label="设备编号" min-width="180">
  57. </el-table-column>
  58. <el-table-column prop="name" label="通道名称" min-width="180">
  59. <template v-slot:default="scope">
  60. <el-input
  61. v-show="scope.row.edit"
  62. v-model="scope.row.name"
  63. placeholder="通道名称"
  64. :maxlength="255"
  65. show-word-limit
  66. clearable
  67. />
  68. <span v-show="!scope.row.edit">{{ scope.row.name }}</span>
  69. </template>
  70. </el-table-column>
  71. <el-table-column label="快照" min-width="100">
  72. <template v-slot:default="scope">
  73. <el-image
  74. :src="getSnap(scope.row)"
  75. :preview-src-list="getBigSnap(scope.row)"
  76. @error="getSnapErrorEvent(scope.row.deviceId, scope.row.channelId)"
  77. :fit="'contain'"
  78. style="width: 60px">
  79. <div slot="error" class="image-slot">
  80. <i class="el-icon-picture-outline"></i>
  81. </div>
  82. </el-image>
  83. </template>
  84. </el-table-column>
  85. <el-table-column prop="subCount" label="子节点数" min-width="100">
  86. </el-table-column>
  87. <el-table-column prop="manufacture" label="厂家" min-width="100">
  88. </el-table-column>
  89. <el-table-column label="位置信息" min-width="120">
  90. <template v-slot:default="scope">
  91. <el-input
  92. v-show="scope.row.edit"
  93. v-model="scope.row.location"
  94. placeholder="例:117.234,36.378"
  95. :maxlength="30"
  96. show-word-limit
  97. clearable
  98. />
  99. <span v-show="!scope.row.edit">{{ scope.row.location }}</span>
  100. </template>
  101. </el-table-column>
  102. <el-table-column prop="ptzType" label="云台类型" min-width="100">
  103. <template v-slot:default="scope">
  104. <el-select v-show="scope.row.edit" v-model="scope.row.ptzType"
  105. placeholder="云台类型" filterable>
  106. <el-option
  107. v-for="(value, key) in ptzTypes"
  108. :key="key"
  109. :label="value"
  110. :value="key"
  111. />
  112. </el-select>
  113. <div v-show="!scope.row.edit">{{ scope.row.ptzTypeText }}</div>
  114. </template>
  115. </el-table-column>
  116. <el-table-column label="开启音频" min-width="100">
  117. <template slot-scope="scope">
  118. <el-switch @change="updateChannel(scope.row)" v-model="scope.row.hasAudio" active-color="#409EFF">
  119. </el-switch>
  120. </template>
  121. </el-table-column>
  122. <el-table-column label="码流类型" min-width="180">
  123. <template slot-scope="scope">
  124. <el-select size="mini" style="margin-right: 1rem;" @change="channelSubStreamChange(scope.row)" v-model="scope.row.streamIdentification"
  125. placeholder="请选择码流类型" default-first-option >
  126. <el-option label="stream:0(主码流)" value="stream:0"></el-option>
  127. <el-option label="stream:1(子码流)" value="stream:1"></el-option>
  128. <el-option label="streamnumber:0(主码流-2022)" value="streamnumber:0"></el-option>
  129. <el-option label="streamnumber:1(子码流-2022)" value="streamnumber:1"></el-option>
  130. <el-option label="streamprofile:0(主码流-大华)" value="streamprofile:0"></el-option>
  131. <el-option label="streamprofile:1(子码流-大华)" value="streamprofile:1"></el-option>
  132. <el-option label="streamMode:main(主码流-水星+TP-LINK)" value="streamMode:main"></el-option>
  133. <el-option label="streamMode:sub(子码流-水星+TP-LINK)" value="streamMode:sub"></el-option>
  134. </el-select>
  135. </template>
  136. </el-table-column>
  137. <el-table-column label="状态" min-width="100">
  138. <template slot-scope="scope">
  139. <div slot="reference" class="name-wrapper">
  140. <el-tag size="medium" v-if="scope.row.status === true">在线</el-tag>
  141. <el-tag size="medium" type="info" v-if="scope.row.status === false">离线</el-tag>
  142. </div>
  143. </template>
  144. </el-table-column>
  145. <el-table-column label="操作" min-width="340" fixed="right">
  146. <template slot-scope="scope">
  147. <el-button size="medium" v-bind:disabled="device == null || device.online === 0" icon="el-icon-video-play"
  148. type="text" @click="sendDevicePush(scope.row)">播放
  149. </el-button>
  150. <el-button size="medium" v-bind:disabled="device == null || device.online === 0"
  151. icon="el-icon-switch-button"
  152. type="text" style="color: #f56c6c" v-if="!!scope.row.streamId"
  153. @click="stopDevicePush(scope.row)">停止
  154. </el-button>
  155. <el-divider direction="vertical"></el-divider>
  156. <el-button
  157. v-if="scope.row.edit"
  158. size="medium"
  159. type="text"
  160. icon="el-icon-edit-outline"
  161. @click="handleSave(scope.row)"
  162. >
  163. 保存
  164. </el-button>
  165. <el-button
  166. v-else
  167. size="medium"
  168. type="text"
  169. icon="el-icon-edit"
  170. @click="handleEdit(scope.row)"
  171. >
  172. 编辑
  173. </el-button>
  174. <el-divider direction="vertical"></el-divider>
  175. <el-button size="medium" icon="el-icon-s-open" type="text"
  176. v-if="scope.row.subCount > 0 || scope.row.parental === 1"
  177. @click="changeSubchannel(scope.row)">查看
  178. </el-button>
  179. <el-divider v-if="scope.row.subCount > 0 || scope.row.parental === 1" direction="vertical"></el-divider>
  180. <!-- <el-button size="medium" v-bind:disabled="device == null || device.online === 0"-->
  181. <!-- icon="el-icon-video-camera"-->
  182. <!-- type="text" @click="queryRecords(scope.row)">设备录像-->
  183. <!-- </el-button>-->
  184. <!-- <el-button size="medium" v-bind:disabled="device == null || device.online === 0" icon="el-icon-cloudy"-->
  185. <!-- type="text" @click="queryCloudRecords(scope.row)">云端录像-->
  186. <!-- </el-button>-->
  187. <el-dropdown @command="(command)=>{moreClick(command, scope.row)}">
  188. <el-button size="medium" type="text" >
  189. 更多功能<i class="el-icon-arrow-down el-icon--right"></i>
  190. </el-button>
  191. <el-dropdown-menu slot="dropdown">
  192. <el-dropdown-item command="records" v-bind:disabled="device == null || device.online === 0">
  193. 设备录像</el-dropdown-item>
  194. <el-dropdown-item command="cloudRecords" v-bind:disabled="device == null || device.online === 0" >
  195. 云端录像</el-dropdown-item>
  196. </el-dropdown-menu>
  197. </el-dropdown>
  198. </template>
  199. </el-table-column>
  200. </el-table>
  201. <el-pagination
  202. style="float: right"
  203. @size-change="handleSizeChange"
  204. @current-change="currentChange"
  205. :current-page="currentPage"
  206. :page-size="count"
  207. :page-sizes="[15, 25, 35, 50]"
  208. layout="total, sizes, prev, pager, next"
  209. :total="total">
  210. </el-pagination>
  211. </el-main>
  212. </el-container>
  213. <!--设备列表-->
  214. </div>
  215. </template>
  216. <script>
  217. import devicePlayer from './dialog/devicePlayer.vue'
  218. import uiHeader from '../layout/UiHeader.vue'
  219. import DeviceService from "./service/DeviceService";
  220. import DeviceTree from "./common/DeviceTree";
  221. export default {
  222. name: 'channelList',
  223. components: {
  224. devicePlayer,
  225. uiHeader,
  226. DeviceTree
  227. },
  228. data() {
  229. return {
  230. deviceService: new DeviceService(),
  231. device: null,
  232. deviceId: this.$route.params.deviceId,
  233. parentChannelId: this.$route.params.parentChannelId,
  234. deviceChannelList: [],
  235. videoComponentList: [],
  236. currentPlayerInfo: {}, //当前播放对象
  237. updateLooper: 0, //数据刷新轮训标志
  238. searchSrt: "",
  239. channelType: "",
  240. online: "",
  241. subStream: "",
  242. winHeight: window.innerHeight - 200,
  243. currentPage: 1,
  244. count: 15,
  245. total: 0,
  246. beforeUrl: "/deviceList",
  247. isLoging: false,
  248. showTree: false,
  249. loadSnap: {},
  250. ptzTypes: {
  251. 0: "未知",
  252. 1: "球机",
  253. 2: "半球",
  254. 3: "固定枪机",
  255. 4: "遥控枪机"
  256. }
  257. };
  258. },
  259. mounted() {
  260. if (this.deviceId) {
  261. this.deviceService.getDevice(this.deviceId, (result) => {
  262. this.device = result;
  263. }, (error) => {
  264. console.log("获取设备信息失败")
  265. console.error(error)
  266. })
  267. }
  268. this.initData();
  269. },
  270. destroyed() {
  271. this.$destroy('videojs');
  272. clearTimeout(this.updateLooper);
  273. },
  274. methods: {
  275. initData: function () {
  276. if (typeof (this.parentChannelId) == "undefined" || this.parentChannelId == 0) {
  277. this.getDeviceChannelList();
  278. } else {
  279. this.showSubchannels();
  280. }
  281. },
  282. initParam: function () {
  283. this.deviceId = this.$route.params.deviceId;
  284. this.parentChannelId = this.$route.params.parentChannelId;
  285. this.currentPage = 1;
  286. this.count = 15;
  287. if (this.parentChannelId == "" || this.parentChannelId == 0) {
  288. this.beforeUrl = "/deviceList"
  289. }
  290. },
  291. currentChange: function (val) {
  292. this.currentPage = val;
  293. this.initData();
  294. },
  295. handleSizeChange: function (val) {
  296. this.count = val;
  297. this.getDeviceChannelList();
  298. },
  299. getDeviceChannelList: function () {
  300. let that = this;
  301. if (typeof (this.$route.params.deviceId) == "undefined") return;
  302. this.$axios({
  303. method: 'get',
  304. url: `/api/device/query/devices/${this.$route.params.deviceId}/channels`,
  305. params: {
  306. page: that.currentPage,
  307. count: that.count,
  308. query: that.searchSrt,
  309. online: that.online,
  310. channelType: that.channelType
  311. }
  312. }).then(function (res) {
  313. if (res.data.code === 0) {
  314. that.total = res.data.data.total;
  315. that.deviceChannelList = res.data.data.list;
  316. that.deviceChannelList.forEach(e => {
  317. e.ptzType = e.ptzType + "";
  318. that.$set(e, "edit", false);
  319. that.$set(e, "location", "");
  320. if (e.customLongitude && e.customLatitude) {
  321. that.$set(e, "location", e.customLongitude + "," + e.customLatitude);
  322. }else if (e.longitude && e.latitude) {
  323. that.$set(e, "location", e.longitude + "," + e.latitude);
  324. }
  325. });
  326. // 防止出现表格错位
  327. that.$nextTick(() => {
  328. that.$refs.channelListTable.doLayout();
  329. })
  330. }
  331. }).catch(function (error) {
  332. console.log(error);
  333. });
  334. },
  335. //通知设备上传媒体流
  336. sendDevicePush: function (itemData) {
  337. let deviceId = this.deviceId;
  338. this.isLoging = true;
  339. let channelId = itemData.channelId;
  340. console.log("通知设备推流1:" + deviceId + " : " + channelId);
  341. let that = this;
  342. this.$axios({
  343. method: 'get',
  344. url: '/api/play/start/' + deviceId + '/' + channelId,
  345. params: {
  346. isSubStream: this.isSubStream
  347. }
  348. }).then(function (res) {
  349. console.log(res)
  350. that.isLoging = false;
  351. if (res.data.code === 0) {
  352. setTimeout(() => {
  353. let snapId = deviceId + "_" + channelId;
  354. that.loadSnap[deviceId + channelId] = 0;
  355. that.getSnapErrorEvent(snapId)
  356. }, 5000)
  357. itemData.streamId = res.data.data.stream;
  358. that.$refs.devicePlayer.openDialog("media", deviceId, channelId, {
  359. streamInfo: res.data.data,
  360. hasAudio: itemData.hasAudio
  361. });
  362. setTimeout(() => {
  363. that.initData();
  364. }, 1000)
  365. } else {
  366. that.$message.error(res.data.msg);
  367. }
  368. }).catch(function (e) {
  369. console.error(e)
  370. that.isLoging = false;
  371. // that.$message.error("请求超时");
  372. });
  373. },
  374. moreClick: function (command, itemData) {
  375. if (command === "records") {
  376. this.queryRecords(itemData)
  377. }else if (command === "cloudRecords") {
  378. this.queryCloudRecords(itemData)
  379. }
  380. },
  381. queryRecords: function (itemData) {
  382. let deviceId = this.deviceId;
  383. let channelId = itemData.channelId;
  384. this.$router.push(`/gbRecordDetail/${deviceId}/${channelId}`)
  385. },
  386. queryCloudRecords: function (itemData) {
  387. let deviceId = this.deviceId;
  388. let channelId = itemData.channelId;
  389. this.$router.push(`/cloudRecordDetail/rtp/${deviceId}_${channelId}`)
  390. },
  391. stopDevicePush: function (itemData) {
  392. var that = this;
  393. this.$axios({
  394. method: 'get',
  395. url: '/api/play/stop/' + this.deviceId + "/" + itemData.channelId,
  396. params: {
  397. isSubStream: this.isSubStream
  398. }
  399. }).then(function (res) {
  400. that.initData();
  401. }).catch(function (error) {
  402. if (error.response.status === 402) { // 已经停止过
  403. that.initData();
  404. } else {
  405. console.log(error)
  406. }
  407. });
  408. },
  409. getSnap: function (row) {
  410. let baseUrl = window.baseUrl ? window.baseUrl : "";
  411. return ((process.env.NODE_ENV === 'development') ? process.env.BASE_API : baseUrl) + '/api/device/query/snap/' + row.deviceId + '/' + row.channelId;
  412. },
  413. getBigSnap: function (row) {
  414. return [this.getSnap(row)]
  415. },
  416. getSnapErrorEvent: function (deviceId, channelId) {
  417. if (typeof (this.loadSnap[deviceId + channelId]) != "undefined") {
  418. console.log("下载截图" + this.loadSnap[deviceId + channelId])
  419. if (this.loadSnap[deviceId + channelId] > 5) {
  420. delete this.loadSnap[deviceId + channelId];
  421. return;
  422. }
  423. setTimeout(() => {
  424. let url = (process.env.NODE_ENV === 'development' ? "debug" : "") + '/api/device/query/snap/' + deviceId + '/' + channelId
  425. this.loadSnap[deviceId + channelId]++
  426. document.getElementById(deviceId + channelId).setAttribute("src", url + '?' + new Date().getTime())
  427. }, 1000)
  428. }
  429. },
  430. showDevice: function () {
  431. this.$router.push(this.beforeUrl).then(() => {
  432. this.initParam();
  433. this.initData();
  434. })
  435. },
  436. changeSubchannel(itemData) {
  437. this.beforeUrl = this.$router.currentRoute.path;
  438. var url = `/${this.$router.currentRoute.name}/${this.$router.currentRoute.params.deviceId}/${itemData.channelId}`
  439. this.$router.push(url).then(() => {
  440. this.searchSrt = "";
  441. this.channelType = "";
  442. this.online = "";
  443. this.initParam();
  444. this.initData();
  445. })
  446. },
  447. showSubchannels: function (channelId) {
  448. if (!this.showTree) {
  449. this.$axios({
  450. method: 'get',
  451. url: `/api/device/query/sub_channels/${this.deviceId}/${this.parentChannelId}/channels`,
  452. params: {
  453. page: this.currentPage,
  454. count: this.count,
  455. query: this.searchSrt,
  456. online: this.online,
  457. channelType: this.channelType
  458. }
  459. }).then((res) => {
  460. if (res.data.code === 0) {
  461. this.total = res.data.data.total;
  462. this.deviceChannelList = res.data.data.list;
  463. this.deviceChannelList.forEach(e => {
  464. e.ptzType = e.ptzType + "";
  465. this.$set(e, "edit", false);
  466. this.$set(e, "location", "");
  467. if (e.customLongitude && e.customLatitude) {
  468. this.$set(e, "location", e.customLongitude + "," + e.customLatitude);
  469. }else if (e.longitude && e.latitude) {
  470. this.$set(e, "location", e.longitude + "," + e.latitude);
  471. }
  472. });
  473. // 防止出现表格错位
  474. this.$nextTick(() => {
  475. this.$refs.channelListTable.doLayout();
  476. })
  477. }
  478. }).catch(function (error) {
  479. console.log(error);
  480. });
  481. } else {
  482. this.$axios({
  483. method: 'get',
  484. url: `/api/device/query/tree/channel/${this.deviceId}`,
  485. params: {
  486. parentId: this.parentChannelId,
  487. page: this.currentPage,
  488. count: this.count,
  489. }
  490. }).then((res) => {
  491. if (res.data.code === 0) {
  492. this.total = res.data.total;
  493. this.deviceChannelList = res.data.list;
  494. // 防止出现表格错位
  495. this.$nextTick(() => {
  496. this.$refs.channelListTable.doLayout();
  497. })
  498. }
  499. }).catch(function (error) {
  500. console.log(error);
  501. });
  502. }
  503. },
  504. search: function () {
  505. this.currentPage = 1;
  506. this.total = 0;
  507. this.initData();
  508. },
  509. updateChannel: function (row) {
  510. this.$axios({
  511. method: 'post',
  512. url: `/api/device/query/channel/update/${this.deviceId}`,
  513. params: row
  514. }).then(function (res) {
  515. console.log(JSON.stringify(res));
  516. });
  517. },
  518. subStreamChange: function () {
  519. this.$confirm('确定重置所有通道的码流类型?', '提示', {
  520. confirmButtonText: '确定',
  521. cancelButtonText: '取消',
  522. type: 'warning'
  523. }).then(() => {
  524. this.$axios({
  525. method: 'post',
  526. url: `/api/device/query/channel/stream/identification/update/`,
  527. params: {
  528. deviceId: this.deviceId,
  529. streamIdentification: this.subStream
  530. }
  531. }).then((res)=> {
  532. console.log(JSON.stringify(res));
  533. this.initData()
  534. }).finally(()=>{
  535. this.subStream = ""
  536. })
  537. }).catch(() => {
  538. this.subStream = ""
  539. });
  540. },
  541. channelSubStreamChange: function (row) {
  542. this.$axios({
  543. method: 'post',
  544. url: `/api/device/query/channel/stream/identification/update/`,
  545. params: {
  546. deviceId: this.deviceId,
  547. channelId: row.channelId,
  548. streamIdentification: row.streamIdentification
  549. }
  550. }).then(function (res) {
  551. console.log(JSON.stringify(res));
  552. });
  553. },
  554. refresh: function () {
  555. this.initData();
  556. },
  557. switchTree: function () {
  558. this.showTree = true;
  559. this.deviceChannelList = [];
  560. this.parentChannelId = 0;
  561. this.currentPage = 1;
  562. },
  563. switchList: function () {
  564. this.showTree = false;
  565. this.deviceChannelList = [];
  566. this.parentChannelId = 0;
  567. this.currentPage = 1;
  568. this.initData();
  569. },
  570. treeNodeClickEvent: function (device, data, isCatalog) {
  571. console.log(device)
  572. if (!!!data.channelId) {
  573. this.parentChannelId = device.deviceId;
  574. } else {
  575. this.parentChannelId = data.channelId;
  576. }
  577. this.initData();
  578. },
  579. // 保存
  580. handleSave(row) {
  581. if (row.location) {
  582. const segements = row.location.split(",");
  583. if (segements.length !== 2) {
  584. console.log(1)
  585. this.$message.warning("位置信息格式有误,例:117.234,36.378");
  586. return;
  587. } else {
  588. row.customLongitude = parseFloat(segements[0]);
  589. row.customLatitude = parseFloat(segements[1]);
  590. if (!(row.customLongitude && row.customLatitude)) {
  591. this.$message.warning("位置信息格式有误,例:117.234,36.378");
  592. return;
  593. }
  594. }
  595. } else {
  596. delete row.longitude;
  597. delete row.latitude;
  598. }
  599. Object.keys(row).forEach(key => {
  600. const value = row[key];
  601. if (value === null || value === undefined || (typeof value === "string" && value.trim() === "")) {
  602. delete row[key];
  603. }
  604. });
  605. this.$axios({
  606. method: 'post',
  607. url: `/api/device/query/channel/update/${this.deviceId}`,
  608. params: row
  609. }).then(response => {
  610. if (response.data.code === 0) {
  611. this.$message.success("修改成功!");
  612. this.initData();
  613. } else {
  614. this.$message.error("修改失败!");
  615. }
  616. }).catch(_ => {
  617. this.$message.error("修改失败!");
  618. })
  619. },
  620. // 是否正在编辑
  621. isEdit() {
  622. let editing = false;
  623. this.deviceChannelList.forEach(e => {
  624. if (e.edit) {
  625. editing = true;
  626. }
  627. });
  628. return editing;
  629. },
  630. // 编辑
  631. handleEdit(row) {
  632. if (this.isEdit()) {
  633. this.$message.warning('请保存当前编辑项!');
  634. } else {
  635. row.edit = true;
  636. }
  637. }
  638. }
  639. };
  640. </script>
  641. <style>
  642. .videoList {
  643. display: flex;
  644. flex-wrap: wrap;
  645. align-content: flex-start;
  646. }
  647. .video-item {
  648. position: relative;
  649. width: 15rem;
  650. height: 10rem;
  651. margin-right: 1rem;
  652. background-color: #000000;
  653. }
  654. .video-item-img {
  655. position: absolute;
  656. top: 0;
  657. bottom: 0;
  658. left: 0;
  659. right: 0;
  660. margin: auto;
  661. width: 100%;
  662. height: 100%;
  663. }
  664. .video-item-img:after {
  665. content: "";
  666. display: inline-block;
  667. position: absolute;
  668. z-index: 2;
  669. top: 0;
  670. bottom: 0;
  671. left: 0;
  672. right: 0;
  673. margin: auto;
  674. width: 3rem;
  675. height: 3rem;
  676. background-image: url("../assets/loading.png");
  677. background-size: cover;
  678. background-color: #000000;
  679. }
  680. .video-item-title {
  681. position: absolute;
  682. bottom: 0;
  683. color: #000000;
  684. background-color: #ffffff;
  685. line-height: 1.5rem;
  686. padding: 0.3rem;
  687. width: 14.4rem;
  688. }
  689. </style>