index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  1. <template>
  2. <div class="scene-management-body" v-loading.fullscreen.lock="fullscreenLoading">
  3. <div class="order-management-body">
  4. <div class="order-management-inner">
  5. <div class="base-info">
  6. <span>关键词:</span>
  7. <el-input
  8. @keyup.enter.native="currentPage=1&&_getSceneData()"
  9. v-model="searchKey"
  10. placeholder="关键词"
  11. ></el-input>
  12. <el-button type="primary" @click="currentPage=1&&_getSceneData()" color="red">搜索</el-button>
  13. </div>
  14. </div>
  15. <!-- 全部 -->
  16. <div class="scene-management_bottom" v-if="tabIndex==0">
  17. <div class="order-management-table">
  18. <div class="scene-management_tab">
  19. <ul>
  20. <li
  21. v-for="(item,index) in tabs"
  22. :key="index"
  23. :class="{'scene-management_tab_li_active':item.idx==tabIndex}"
  24. @click="clickTabItem(item.idx)"
  25. >
  26. {{item.name}}
  27. <span
  28. v-if="item.idx != -2"
  29. style="margin:0 10px;color: #999;font-weight: normal;"
  30. >/</span>
  31. </li>
  32. </ul>
  33. <!-- <div style="float: right;vertical-align: middle;">
  34. <el-button type="primary" icon="el-icon-upload" @click="" color='red'>恢复</el-button>
  35. <el-button type="danger" icon="el-icon-delete" @click="" color='red'>删除</el-button>
  36. </div>-->
  37. </div>
  38. <el-table
  39. key="order_table"
  40. ref="order_table"
  41. class="e-table"
  42. :data="scenes"
  43. style="width: 100%"
  44. >
  45. <el-table-column label="场景封面" width="120">
  46. <template slot-scope="scope">
  47. <a :href="scope.row.webSite" target="_blank" style="cursor: pointer;">
  48. <img :src="scope.row.thumb" width="100%" height />
  49. </a>
  50. </template>
  51. </el-table-column>
  52. <el-table-column label="分类">
  53. <template slot-scope="scope">
  54. <el-select v-model="scope.row.sceneType" @change="changTypeHandle(scope.row)" placeholder="请选择">
  55. <el-option label='其他' :value="0"></el-option>
  56. <el-option label='文博' :value="1"></el-option>
  57. <el-option label='地产' :value="2"></el-option>
  58. <el-option label='电商' :value="3"></el-option>
  59. <el-option label='餐饮' :value="4"></el-option>
  60. <el-option label='家具' :value="5"></el-option>
  61. </el-select>
  62. </template>
  63. </el-table-column>
  64. <el-table-column prop="sceneName" width="200" label="标题"></el-table-column>
  65. <el-table-column label="拍摄时间" width="200">
  66. <template slot-scope="scope">
  67. <div>{{new Date(scope.row.createTime).format('yyyy-MM-dd hh:mm:ss')}}</div>
  68. </template>
  69. </el-table-column>
  70. <el-table-column label="经纬度" width="200">
  71. <template slot-scope="scope">
  72. <div v-if="scope.row.longitude">经度:{{scope.row.longitude}}</div>
  73. <div v-if="scope.row.latitude">维度:{{scope.row.latitude }}</div>
  74. <span v-if="!scope.row.latitude&&!scope.row.longitude">/</span>
  75. </template>
  76. </el-table-column>
  77. <el-table-column prop="childName" label="设备ID" width="150"></el-table-column>
  78. <el-table-column prop="userName" label="用户名" width="150"></el-table-column>
  79. <el-table-column prop="scenekey" label="权限"></el-table-column>
  80. <el-table-column prop="viewCount" label="浏览数"></el-table-column>
  81. <el-table-column prop="sceneType" label="平台展示">
  82. <template slot-scope="scope">
  83. <el-switch
  84. @change="_updateSceneStatus(scope.row.id,scope.row.status)"
  85. v-model="scope.row.statusBoo"
  86. active-color="#13ce66"
  87. inactive-color="#ff4949"
  88. ></el-switch>
  89. </template>
  90. </el-table-column>
  91. <el-table-column prop="status" label="操作">
  92. <template slot-scope="scope">
  93. <el-button
  94. v-if="scope.row.sceneScheme>4"
  95. type="text"
  96. @click="_downloadScene(scope.row.num);"
  97. class="download_btn"
  98. >下载</el-button>
  99. <el-button type="text" @click="_deleScene(scope.row.id)" class="delete_btn">删除</el-button>
  100. </template>
  101. </el-table-column>
  102. </el-table>
  103. </div>
  104. <div class="order-management-pagination">
  105. <el-pagination
  106. @current-change="handleCurrentChange"
  107. :current-page.sync="currentPage"
  108. :page-size="pageSize"
  109. layout="total, prev, pager, next, jumper"
  110. :total="total"
  111. ></el-pagination>
  112. </div>
  113. </div>
  114. <!-- 展示中 -->
  115. <div class="scene-management_bottom" v-if="tabIndex==1">
  116. <div class="order-management-table">
  117. <div class="scene-management_tab">
  118. <ul>
  119. <li
  120. v-for="(item,index) in tabs"
  121. :key="index"
  122. :class="{'scene-management_tab_li_active':item.idx==tabIndex}"
  123. @click="clickTabItem(item.idx)"
  124. >
  125. {{item.name}}
  126. <span
  127. v-if="item.idx != -2"
  128. style="margin:0 10px;color: #999;font-weight: normal;"
  129. >/</span>
  130. </li>
  131. </ul>
  132. <!-- <div style="float: right;vertical-align: middle;">
  133. <el-button type="primary" icon="el-icon-upload" @click="" color='red'>恢复</el-button>
  134. <el-button type="danger" icon="el-icon-delete" @click="" color='red'>删除</el-button>
  135. </div>-->
  136. </div>
  137. <el-table
  138. key="order_table1"
  139. ref="order_table1"
  140. class="e-table"
  141. :data="scenes"
  142. style="width: 100%"
  143. >
  144. <el-table-column label="场景封面" width="120">
  145. <template slot-scope="scope">
  146. <a :href="scope.row.webSite" target="_blank" style="cursor: pointer;">
  147. <img :src="scope.row.thumb" width="100%" height />
  148. </a>
  149. </template>
  150. </el-table-column>
  151. <el-table-column prop="sceneType" label="分类"></el-table-column>
  152. <el-table-column prop="sceneName" width="200" label="标题"></el-table-column>
  153. <el-table-column label="拍摄时间" width="200">
  154. <template slot-scope="scope">
  155. <div>{{new Date(scope.row.createTime).format('yyyy-MM-dd hh:mm:ss')}}</div>
  156. </template>
  157. </el-table-column>
  158. <el-table-column label="经纬度" width="200">
  159. <template slot-scope="scope">
  160. <div v-if="scope.row.longitude">经度:{{scope.row.longitude}}</div>
  161. <div v-if="scope.row.latitude">维度:{{scope.row.latitude }}</div>
  162. <span v-if="!scope.row.latitude&&!scope.row.longitude">/</span>
  163. </template>
  164. </el-table-column>
  165. <el-table-column prop="childName" width="150" label="设备ID"></el-table-column>
  166. <el-table-column prop="userName" width="150" label="用户名"></el-table-column>
  167. <el-table-column prop="scenekey" label="权限"></el-table-column>
  168. <el-table-column prop="viewCount" label="浏览数"></el-table-column>
  169. <el-table-column prop="sceneType" label="平台展示">
  170. <template slot-scope="scope">
  171. <el-switch
  172. @change="_updateSceneStatus(scope.row.id,scope.row.status)"
  173. v-model="scope.row.statusBoo"
  174. active-color="#13ce66"
  175. inactive-color="#ff4949"
  176. ></el-switch>
  177. </template>
  178. </el-table-column>
  179. <el-table-column prop="status" label="操作">
  180. <template slot-scope="scope">
  181. <el-button type="text" @click="_deleScene(scope.row.id)" class="delete_btn">删除</el-button>
  182. </template>
  183. </el-table-column>
  184. </el-table>
  185. </div>
  186. <div class="order-management-pagination">
  187. <el-pagination
  188. @current-change="handleCurrentChange"
  189. :current-page.sync="currentPage"
  190. :page-size="10"
  191. layout="total, prev, pager, next, jumper"
  192. :total="total"
  193. ></el-pagination>
  194. </div>
  195. </div>
  196. <!-- 已隐藏 -->
  197. <div class="scene-management_bottom" v-if="tabIndex==-2">
  198. <div class="order-management-table">
  199. <div class="scene-management_tab">
  200. <ul>
  201. <li
  202. v-for="(item,index) in tabs"
  203. :key="index"
  204. :class="{'scene-management_tab_li_active':item.idx==tabIndex}"
  205. @click="clickTabItem(item.idx)"
  206. >
  207. {{item.name}}
  208. <span
  209. v-if="item.idx != -2"
  210. style="margin:0 10px;color: #999;font-weight: normal;"
  211. >/</span>
  212. </li>
  213. </ul>
  214. <!-- <div style="float: right;vertical-align: middle;">
  215. <el-button type="primary" icon="el-icon-upload" @click="" color='red'>恢复</el-button>
  216. <el-button type="danger" icon="el-icon-delete" @click="" color='red'>删除</el-button>
  217. </div>-->
  218. </div>
  219. <el-table
  220. key="order_table2"
  221. ref="order_table2"
  222. class="e-table"
  223. :data="scenes"
  224. style="width: 100%"
  225. >
  226. <el-table-column label="场景封面" width="120">
  227. <template slot-scope="scope">
  228. <a :href="scope.row.webSite" target="_blank" style="cursor: pointer;">
  229. <img :src="scope.row.thumb" width="100%" height />
  230. </a>
  231. </template>
  232. </el-table-column>
  233. <el-table-column prop="sceneType" label="分类"></el-table-column>
  234. <el-table-column prop="sceneName" width="200" label="标题"></el-table-column>
  235. <el-table-column label="拍摄时间" width="200">
  236. <template slot-scope="scope">
  237. <div>{{new Date(scope.row.createTime).format('yyyy-MM-dd hh:mm:ss')}}</div>
  238. </template>
  239. </el-table-column>
  240. <el-table-column label="经纬度" width="200">
  241. <template slot-scope="scope">
  242. <div v-if="scope.row.longitude">经度:{{scope.row.longitude}}</div>
  243. <div v-if="scope.row.latitude">维度:{{scope.row.latitude }}</div>
  244. <span v-if="!scope.row.latitude&&!scope.row.longitude">/</span>
  245. </template>
  246. </el-table-column>
  247. <el-table-column prop="childName" width="150" label="设备ID"></el-table-column>
  248. <el-table-column prop="userName" width="150" label="用户名"></el-table-column>
  249. <el-table-column prop="scenekey" label="权限"></el-table-column>
  250. <el-table-column prop="viewCount" label="浏览数"></el-table-column>
  251. <el-table-column prop="sceneType" label="平台展示">
  252. <template slot-scope="scope">
  253. <el-switch
  254. @change="_updateSceneStatus(scope.row.id,scope.row.status)"
  255. v-model="scope.row.statusBoo"
  256. active-color="#13ce66"
  257. inactive-color="#ff4949"
  258. ></el-switch>
  259. </template>
  260. </el-table-column>
  261. <el-table-column prop="status" label="操作">
  262. <template slot-scope="scope">
  263. <el-button type="text" @click="_deleScene(scope.row.id)" class="delete_btn">删除</el-button>
  264. </template>
  265. </el-table-column>
  266. </el-table>
  267. </div>
  268. <div class="order-management-pagination">
  269. <el-pagination
  270. @current-change="handleCurrentChange"
  271. :current-page.sync="currentPage"
  272. :page-size="10"
  273. layout="total, prev, pager, next, jumper"
  274. :total="total"
  275. ></el-pagination>
  276. </div>
  277. </div>
  278. </div>
  279. <el-dialog
  280. width="500px"
  281. title="下载场景"
  282. :visible.sync="download.showSta"
  283. :before-close="_handleClose"
  284. >
  285. <el-form v-if="download.showSta" label-width="100px">
  286. <div id="progressText" class>
  287. <span>{{download.downloadSta}}</span>
  288. </div>
  289. <div>
  290. <span id="downloadDataName">{{download.downloadDataName}}</span>
  291. <span id="percent">{{download.percent}}%</span>
  292. <el-progress :percentage="download.percent" :color="progressColor" :show-text="false"></el-progress>
  293. </div>
  294. </el-form>
  295. <div slot="footer" class="dialog-footer">
  296. <el-button @click="_handleClose" class="cancle-download-btn">取消下载</el-button>
  297. </div>
  298. </el-dialog>
  299. </div>
  300. </template>
  301. <script>
  302. const _sceneTypeName = {
  303. 0: "其他",
  304. 1: "文博",
  305. 2: "地产",
  306. 3: "电商",
  307. 4: "餐饮",
  308. 5: "家居"
  309. };
  310. export default {
  311. data() {
  312. return {
  313. getRowKeys(row) {
  314. return row.number;
  315. },
  316. download: {
  317. showSta: false,
  318. downloadSta: "正在拉取数据",
  319. downloadDataName: "场景数据.zip",
  320. percent: 0,
  321. timer: 0
  322. },
  323. downloadDialogVisible: false,
  324. progressColor: "#09e1c0",
  325. tabs: [
  326. { name: "全部", idx: 0 },
  327. { name: "展示中", idx: 1 },
  328. { name: "已隐藏", idx: -2 }
  329. ],
  330. expands: [],
  331. expandedArr: [],
  332. scenes: [],
  333. currentPage: 1,
  334. key_input: "",
  335. fullscreenLoading: false,
  336. total: 0,
  337. // expressNum_input: "",
  338. searchDate: [],
  339. searchKey: "",
  340. searchOrderNumber: "",
  341. searchPhone: "",
  342. searchExpressNum: "",
  343. hasClickSearch: false,
  344. tabIndex: 0,
  345. pageSize: 10,
  346. value2: true
  347. };
  348. },
  349. watch: {
  350. currentPage() {
  351. this._getSceneData();
  352. },
  353. tabIndex() {
  354. this._getSceneData();
  355. }
  356. },
  357. methods: {
  358. async changTypeHandle(item) {
  359. this.fullscreenLoading = true;
  360. await this.$http.post("/manager/scene/updateSceneType", {
  361. sceneType: item.sceneType,
  362. sceneId: item.id
  363. });
  364. this._getSceneData();
  365. this.fullscreenLoading = false;
  366. },
  367. handleCurrentChange(val) {
  368. let page = val;
  369. // console.log(`当前页: ${val}`)
  370. if (this.total > 0 && !this.hasClickSearch) {
  371. this._getSceneData(page);
  372. } else {
  373. this._searchOrderByPage(page);
  374. }
  375. },
  376. clickTabItem(idx) {
  377. // console.log(idx)
  378. this.tabIndex = idx;
  379. this.total = 0;
  380. this.hasClickSearch = false;
  381. this.currentPage = 0;
  382. this.$refs.searchKey.currentValue = this.key_input = "";
  383. this._getSceneData(1);
  384. },
  385. async _getSceneData() {
  386. this.fullscreenLoading = true;
  387. let status = this.tabIndex === 0 ? null : this.tabIndex;
  388. let res = await this.$http.post("/manager/scene/list", {
  389. type: status,
  390. searchKey: this.searchKey,
  391. pageNum: this.currentPage,
  392. pageSize: this.pageSize
  393. });
  394. this.fullscreenLoading = false;
  395. if (res.code === 0) {
  396. let temp = res.data.list;
  397. for (var i = 0; i < temp.length; i++) {
  398. temp[i].sceneType = _sceneTypeName[temp[i].sceneType];
  399. temp[i].scenekey = temp[i].scenekey ? "私密" : "公开";
  400. temp[i]["userName"] = temp[i]["userName"]
  401. ? temp[i]["userName"]
  402. : "未绑定";
  403. let gpsStr = temp[i].gps || "";
  404. if (gpsStr instanceof Object) {
  405. JSON.parse(gpsStr, (k, v) => {
  406. if (k && k === "latitude") {
  407. temp[i].latitude = this.formatDegree(v);
  408. } else if (k && k === "longitude") {
  409. temp[i].longitude = this.formatDegree(v);
  410. }
  411. });
  412. }
  413. if (temp[i].status === 1) {
  414. temp[i].statusBoo = true;
  415. } else if (temp[i].status === -2) {
  416. temp[i].statusBoo = false;
  417. } else {
  418. temp[i].statusBoo = "";
  419. }
  420. }
  421. this.scenes = temp;
  422. this.total = res.data.total ? res.data.total : this.total;
  423. }
  424. },
  425. formatDegree(value) {
  426. value = Math.abs(value);
  427. var v1 = Math.floor(value); // 度
  428. var v2 = Math.floor((value - v1) * 60); // 分
  429. var v3 = Math.round(((value - v1) * 3600) % 60); // 秒
  430. return v1 + "°" + v2 + "'" + v3 + '"';
  431. },
  432. async _updateSceneStatus(num, status) {
  433. let tempStatus;
  434. if (status === 1) {
  435. tempStatus = -2;
  436. } else if (status === -2) {
  437. tempStatus = 1;
  438. } else {
  439. this.$notify.error({
  440. title: "错误",
  441. message: "切换失败"
  442. });
  443. return;
  444. }
  445. this.fullscreenLoading = true;
  446. await this.$http.post("/manager/scene/updateStatus", {
  447. type: tempStatus,
  448. sceneId: num
  449. });
  450. this._getSceneData();
  451. this.fullscreenLoading = false;
  452. },
  453. _downloadScene(sceneCode) {
  454. this.fullscreenLoading = true;
  455. let promise = this.$http.get(
  456. `/scene/getInfo?num=${sceneCode}&t=${new Date().getTime()}`
  457. ); // 请求sceneData.json数据
  458. promise.then(resp => {
  459. this.fullscreenLoading = false;
  460. resp.data.sceneScheme = 1; // 禁止本地端放大缩小
  461. this.$http
  462. .post("https://test.4dkankan.com/downloadData/", {
  463. sceneCode: sceneCode,
  464. sceneInfo: JSON.stringify(resp)
  465. })
  466. .then(resp => {
  467. // 将请求发送至服务器后再轮询
  468. if (resp["sta"] === 1003) {
  469. // 文件已存在
  470. this._browserDownload(resp["data"]["url"]); // 调用浏览器下载文件
  471. } else {
  472. this.download.showSta = true;
  473. this.download.downloadDataName = `${sceneCode}.zip`;
  474. if (resp["sta"] === 1000 || resp["sta"] === 1002) {
  475. this._downloadHandler(resp);
  476. }
  477. if (resp["sta"] === 1001) {
  478. this._compressHandler(resp);
  479. }
  480. this.download.timer = setInterval(() => {
  481. this.$http
  482. .get(
  483. `https://test.4dkankan.com/downloadData/process?sceneCode=${sceneCode}`
  484. )
  485. .then(resp => {
  486. console.log(resp);
  487. if (resp["sta"] === 1000) {
  488. this._downloadHandler(resp);
  489. }
  490. if (resp["sta"] === 1001) {
  491. this._compressHandler(resp);
  492. }
  493. });
  494. }, 1000);
  495. }
  496. });
  497. });
  498. },
  499. _handleClose() {
  500. this.$confirm("取消下载?", "提示")
  501. .then(() => {
  502. this.download.showSta = false;
  503. clearInterval(this.download.timer);
  504. })
  505. .catch(_ => {});
  506. },
  507. _downloadHandler(resp) {
  508. this.download.downloadSta = "正在拉取数据";
  509. this.download.percent = parseInt(resp["data"]["percent"]);
  510. let percent = parseInt(resp["data"]["percent"]);
  511. this.download.percent = percent;
  512. },
  513. _compressHandler(resp) {
  514. this.download.downloadSta = "正在压缩数据";
  515. let percent = parseInt(resp["data"]["percent"]);
  516. this.download.percent = percent;
  517. if (percent === 100) {
  518. this.download.showSta = false;
  519. clearInterval(this.download.timer);
  520. this._browserDownload(resp["data"]["url"]);
  521. }
  522. },
  523. _browserDownload(url) {
  524. let a = document.createElement("a");
  525. let urlArr = url.split("/");
  526. let fileName = urlArr[urlArr.length - 1];
  527. a.href = url;
  528. a.download = fileName;
  529. a.style.display = "none";
  530. document.body.appendChild(a);
  531. a.click();
  532. document.body.removeChild(a);
  533. },
  534. _deleScene(num) {
  535. this.$confirm("此操作将删除该场景, 是否继续?", "提示", {
  536. confirmButtonText: "确定",
  537. cancelButtonText: "取消",
  538. type: "warning"
  539. })
  540. .then(async () => {
  541. this.fullscreenLoading = true;
  542. let res = await this.$http.post("/manager/scene/delete", {
  543. sceneId: num
  544. });
  545. if (res.code === 0) {
  546. this.$message({
  547. type: "success",
  548. message: "删除成功!"
  549. });
  550. this._getSceneData();
  551. } else {
  552. this.$message({
  553. type: "error",
  554. message: res.msg
  555. });
  556. this._getSceneData();
  557. }
  558. this.fullscreenLoading = false;
  559. })
  560. .catch(() => {
  561. this.$message({
  562. type: "info",
  563. message: "已取消删除"
  564. });
  565. this.fullscreenLoading = false;
  566. });
  567. }
  568. },
  569. created() {
  570. this._getSceneData();
  571. }
  572. };
  573. </script>
  574. <style lang="css" scoped>
  575. @import "./style.css";
  576. </style>
  577. <style type="text/css">
  578. .el-table__expand-icon > i {
  579. display: none !important;
  580. }
  581. .delete_btn span {
  582. color: #f56c6c;
  583. }
  584. .download_btn span {
  585. color: #09e1c0;
  586. }
  587. .el-dialog__body {
  588. padding: 10px 20px;
  589. }
  590. .el-dialog__title {
  591. font-weight: 700;
  592. }
  593. .el-progress-bar {
  594. margin-top: 10px;
  595. }
  596. .el-dialog {
  597. border-radius: 7px;
  598. }
  599. .cancle-download-btn {
  600. background: #09e1c0;
  601. color: white;
  602. width: 120px;
  603. font-size: 16px;
  604. font-weight: 100;
  605. letter-spacing: 1px;
  606. border: none;
  607. }
  608. .cancle-download-btn:hover {
  609. background: #09e1c0;
  610. color: white;
  611. }
  612. .cancle-download-btn:focus {
  613. color: white;
  614. }
  615. #progressText {
  616. padding: 0 0 20px 0;
  617. font-weight: 100;
  618. }
  619. #downloadDataName,
  620. #percent {
  621. font-size: 16px;
  622. font-weight: 200;
  623. color: black;
  624. }
  625. #percent {
  626. float: right;
  627. }
  628. </style>