index.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. <template>
  2. <com-head :options="headList" >
  3. <el-form label-width="84px" inline="true">
  4. <el-form-item label="场景标题:">
  5. <el-input v-model="search.state.sceneTitle" placeholder="请输入"></el-input>
  6. </el-form-item>
  7. <el-form-item label="拍摄时间:">
  8. <el-date-picker
  9. v-model="time"
  10. type="daterange"
  11. range-separator="至"
  12. start-placeholder="开始日期"
  13. end-placeholder="结束日期">
  14. </el-date-picker>
  15. </el-form-item>
  16. <el-form-item class="searh-btns" style="grid-area: 1 / 3 / 2 / 4;">
  17. <el-button type="primary" @click="search.submit">查询</el-button>
  18. <el-button type="primary" plain @click="search.reset">重置</el-button>
  19. </el-form-item>
  20. </el-form>
  21. </com-head>
  22. <div class="body-layer">
  23. <div class="body-head">
  24. <h3 style="visibility: hidden;">场景管理</h3>
  25. <div class="table-ctrl-right">
  26. <el-button type="primary" v-power="'sync'" :disabled="getRoke('sync')" @click="asynccj">同步场景</el-button>
  27. </div>
  28. </div>
  29. <el-table
  30. ref="multipleTable"
  31. :data="dataList.state"
  32. tooltip-effect="dark"
  33. style="width: 100%"
  34. @row-click="selectRow"
  35. @selection-change="dataList.changeSelectRows"
  36. >
  37. <!-- -1 计算失败 0 计算中 1 计算成功并可以外网访问,不能编辑 2计算成功只能内网,能编辑 -->
  38. <el-table-column label="序号" width="55" v-slot:default="{ $index }">
  39. <div style="text-align: center">{{ pag.state.size * (pag.state.currPage - 1) + $index + 1 }}</div>
  40. </el-table-column>
  41. <el-table-column label="场景标题" prop="sceneName"></el-table-column>
  42. <el-table-column label="S/N码" prop="snCode"></el-table-column>
  43. <el-table-column label="浏览数量" prop="viewCount"></el-table-column>
  44. <el-table-column
  45. label="拍摄时间"
  46. prop="createTime"
  47. v-slot:default="{ row }"
  48. >
  49. {{ row.createTime.substr(0, 11) }}</el-table-column
  50. >
  51. <el-table-column label="操作" v-slot:default="{ row }">
  52. <span class="oper-span" v-power="'view'" @click="shareHandle(row)">查看</span>
  53. <span class="oper-span" :class="{disable:!(butisShow && user.info.id == row.creatorId)}" v-power="'edit'" @click="editModel(row)">编辑</span>
  54. <span class="oper-span" @click="download(row)" v-if="row.num" >下载</span>
  55. <span :class="!((butisShow)&&~user.info.cameraSns.indexOf(row.snCode))?'disable oper-span':'oper-span'" v-power="'del'" @click="dataList.delete(row)" style="color: var(--primaryColor)" >删除</span
  56. >
  57. </el-table-column>
  58. </el-table>
  59. <com-pagination
  60. @size-change="pag.sizeChange"
  61. @current-change="pag.currentChange"
  62. :current-page="pag.state.currPage"
  63. :page-size="pag.state.size"
  64. layout="total, sizes, prev, pager, next, jumper"
  65. :total="pag.state.total"/>
  66. <com-dialog
  67. title="场景归属"
  68. v-model:show="editCompany.show"
  69. @submit="updateItemCompany"
  70. >
  71. <el-form ref="form" :model="form" label-width="84px" class="vrmodel-from">
  72. <el-form-item label="所属架构" class="mandatory">
  73. <com-company v-model="editCompany.data.deptId" hideAll />
  74. </el-form-item>
  75. </el-form>
  76. </com-dialog>
  77. <com-dialog
  78. title="选择相机"
  79. :width="480"
  80. v-model:show="cameraCompany.show"
  81. @submit="updateCameraCompany"
  82. enterText="确 定"
  83. >
  84. <el-form ref="form" :model="form" label-width="90px" class="vrmodel-from">
  85. <el-form-item label="选择相机:" class="mandatory">
  86. <el-select v-model="cameraCompany.data" placeholder="请选择">
  87. <el-option
  88. v-for="item in cameras"
  89. :key="item.cameraSn"
  90. :label="item.cameraSn"
  91. :value="item.cameraSn">
  92. </el-option>
  93. </el-select>
  94. </el-form-item>
  95. </el-form>
  96. </com-dialog>
  97. <com-dialog
  98. title="场景离线包下载"
  99. :width="500"
  100. v-model:show="cameraDownload.show"
  101. :hideFloor="cameraDownload.data.type == '1'"
  102. enterText="下 载"
  103. @quit="suspend"
  104. @submit="downloadItemCompany"
  105. >
  106. <div>
  107. <div class="title">
  108. {{
  109. cameraDownload.data.type == "0"
  110. ? "下载场景离线数据包,可在本地运行查看。"
  111. : cameraDownload.data.type == "1"
  112. ? "正在打包场景离线数据"
  113. : cameraDownload.data.name
  114. }}
  115. </div>
  116. <div style="marginTop:20px" v-if="cameraDownload.data.type == '0'">
  117. 当前剩余下载次数:<span>{{ cameraDownload.data.value }}</span
  118. >次
  119. </div>
  120. <div v-else-if="cameraDownload.data.type == '1'">
  121. <div
  122. class="text"
  123. style="display:flex;justify-content: space-between;margin-top:15px"
  124. >
  125. <span>{{ cameraDownload.data.name }}</span>
  126. <span>{{ cameraDownload.data.percent }}%</span>
  127. </div>
  128. <div>
  129. <el-slider
  130. :disabled="true"
  131. v-model="cameraDownload.data.percent"
  132. :show-tooltip="false"
  133. >
  134. </el-slider>
  135. </div>
  136. </div>
  137. </div>
  138. </com-dialog>
  139. <com-dialog
  140. title="同步场景"
  141. v-model:show="asyncSceneCompany"
  142. @submit="asyncSceneCompany = false"
  143. enterText="确 定"
  144. >
  145. <com-async :data="cameraCompany.data" v-if="cameraCompany.data" />
  146. </com-dialog>
  147. </div>
  148. </template>
  149. <script>
  150. import { ref, watch } from "vue";
  151. import getTableState from "@/state/tableRef";
  152. import auth from "@/state/viewAuth";
  153. import user from '@/state/user'
  154. import comAsync from "./async";
  155. import comHead from "@/components/head";
  156. import comDialog from "@/components/dialog";
  157. import comPagination from "@/components/pagination";
  158. import comCompany from "@/components/company-select";
  159. import { getApp } from '@/app'
  160. import { dateFormat,getRoke } from '@/util'
  161. import { ADMIN_USER_ID } from '@/constant'
  162. import {
  163. getSceneList,
  164. deleteScene,
  165. // getCameraOptions,
  166. getListByUser,
  167. checkHasDownload,
  168. getDownloadProcess,
  169. downloadScene,
  170. } from '@/request/config'
  171. import axios from 'axios';
  172. export default {
  173. name: 'vrmodel',
  174. setup() {
  175. const state = getTableState({
  176. getUrl: getSceneList,
  177. delUrl: deleteScene,
  178. delAttr: {'sceneNum': 'num'},
  179. searchAttr: { start: "", end: '', sceneTitle: '', snCode: '' }
  180. });
  181. const editCompany = ref({data: {}, show: false})
  182. const cameraCompany = ref({data: null, show: false})
  183. const asyncSceneCompany = ref(false)
  184. const cameras = ref([])
  185. const headList = ref([{ name: "场景管理", value: 2 }]);
  186. const currModel = ref(1)
  187. const time = ref(null)
  188. const cameraDownload = ref({ data: { type: 0, value: 0 }, show: false });
  189. const butisShow =ref({show:false})
  190. watch(time, () => {
  191. if (time.value) {
  192. console.log(time.value[0], time.value[1])
  193. let start1 = new Date(time.value[0])
  194. let start2 = new Date(time.value[1])
  195. if (start2.getTime() - start1.getTime() < 0) {
  196. getApp().$message.error('结束日期必须大于开始日期', '提示')
  197. } else {
  198. state.search.value.state.start = dateFormat(start1, 'yyyy-MM-dd')
  199. state.search.value.state.end = dateFormat(start2, 'yyyy-MM-dd')
  200. }
  201. } else {
  202. state.search.value.state.start = state.search.value.state.end = ''
  203. }
  204. })
  205. watch(
  206. [() => state.search.value.state.start, () => state.search.value.state.end],
  207. () => {
  208. if (!state.search.value.state.start || !state.search.value.state.end) {
  209. time.value = null
  210. }
  211. }
  212. )
  213. watch(asyncSceneCompany, () => {
  214. asyncSceneCompany.value || state.dataList.value.refer()
  215. })
  216. return { ...state,butisShow, headList, currModel, time, auth, editCompany, cameras, cameraCompany, asyncSceneCompany, user,cameraDownload,ADMIN_USER_ID,getRoke };
  217. },
  218. created(){
  219. let list = {
  220. 1:false,//'超级管理员',
  221. 2:false,//'平台管理员',
  222. 3:true,//'总队',
  223. 4:true,//'支队',
  224. 5:true,//'大队',
  225. }
  226. let roleLevel = sessionStorage.getItem('roleLevel')
  227. this.butisShow = list[roleLevel] || false
  228. console.log('user.info.cameraSns',this.user.info.cameraSns)
  229. },
  230. methods: {
  231. download(item) {
  232. //查询下载进度 0未创建 1打包中 2等待下载
  233. let statelist = {
  234. 0:0,
  235. 1:1,
  236. 2:0,
  237. 3:2,
  238. }
  239. axios
  240. .get(checkHasDownload + item.num, { sceneNum: item.num, isTiles: true })
  241. .then((res) => {
  242. console.log("type---> res :", res.data);
  243. this.cameraDownload.data = {
  244. type: statelist[res.data.downloadStatus],
  245. downloadStatus:res.data.downloadStatus,
  246. sceneNum: item.num,
  247. value: res.data.count,
  248. name: item.sceneName + ".zip",
  249. url: res.data.downloadUrl,
  250. percent:0,
  251. };
  252. if(res.data.count == 0 && (res.data.downloadStatus == 0 || res.data.downloadStatus == 2)){
  253. return this.$message.error("暂无剩余下载次数!", "提示");
  254. }else{
  255. this.cameraDownload.show = true;
  256. }
  257. if(res.data.downloadStatus == 1){//下载中
  258. this.downloadItemCompany()
  259. }
  260. });
  261. },
  262. async activated() {
  263. let res = await axios.get(getListByUser)
  264. console.log('cameras',res)
  265. this.cameras = res.data
  266. },
  267. editModel(item) {
  268. window.open(process.env.VUE_APP_DOMAIN + '/epc.html?m=' + item.num + '&token=' + user.value.token)
  269. },
  270. shareHandle(item) {
  271. window.open(process.env.VUE_APP_DOMAIN + '/spc.html?m=' + item.num)
  272. },
  273. suspend(){
  274. clearTimeout(this.timer)
  275. },
  276. downloadItemCompany() {
  277. //查询下载进度 0未创建 1打包中 2等待下载
  278. //查询进度
  279. let that = this
  280. const { sceneNum, url,downloadStatus } = this.cameraDownload.data;
  281. let download = (downloadUrl) =>{
  282. let iframe = document.createElement('iframe')
  283. iframe.style.display = 'none'
  284. iframe.src = downloadUrl
  285. document.body.appendChild(iframe);
  286. that.cameraDownload.show = false;
  287. }
  288. console.log('downloadStatus',downloadStatus)
  289. if(downloadStatus == 3){
  290. return download(url)
  291. }else if(downloadStatus == 0 || downloadStatus == 2 ){
  292. axios.get(downloadScene+sceneNum).then((resdata) => {
  293. if(resdata.data.downloadStatus !== 1){
  294. clearTimeout(this.timer)
  295. that.cameraDownload.show = false;
  296. return this.$message.error("暂无剩余下载次数!", "提示");
  297. }
  298. });
  299. }
  300. let fn = () => {
  301. that.timer = setTimeout(() => {
  302. callback();
  303. }, 1000);
  304. // downIngs[this.scene.num] = this.timer;
  305. };
  306. let callback = () => {
  307. axios.get(getDownloadProcess, {
  308. params:{
  309. sceneNum: sceneNum,
  310. isTiles: true,
  311. }
  312. }).then((res) => {
  313. const { percent,url } = res.data
  314. that.cameraDownload.data.type = 1
  315. that.cameraDownload.data.percent = parseInt(percent)
  316. if(!url){
  317. fn()
  318. }else{ //拿到下载链接
  319. url&&download(url)
  320. }
  321. });
  322. }
  323. fn()
  324. // if (type !== 2) {
  325. // this.cameraDownload.data = {
  326. // ...cameraDownloaddata,
  327. // type: 1,
  328. // value: 50,
  329. // };
  330. // }
  331. },
  332. updateCameraCompany() {
  333. if (!this.cameraCompany.data) {
  334. return this.$message.error('请选择相机!', '提示')
  335. }
  336. this.cameraCompany.show = false
  337. this.asyncSceneCompany = true
  338. },
  339. asynccj(){
  340. this.activated()
  341. this.cameraCompany.show = true
  342. },
  343. },
  344. components: {
  345. "com-head": comHead,
  346. "com-dialog": comDialog,
  347. "com-company": comCompany,
  348. "com-async": comAsync,
  349. "com-pagination": comPagination
  350. },
  351. };
  352. </script>
  353. <style lang="scss" scoped>
  354. .table-ctrl-right {
  355. .search-scene {
  356. margin: 0 20px 0 26px;
  357. }
  358. i {
  359. margin-left: 20px;
  360. font-size: 1.7rem;
  361. vertical-align: middle;
  362. cursor: pointer;
  363. &.active {
  364. color: var(--primaryColor);
  365. }
  366. }
  367. }
  368. .mode2-layer {
  369. flex: 1;
  370. overflow-y: auto;
  371. }
  372. .grid-data {
  373. display: grid;
  374. grid: auto-flow / 1fr 1fr 1fr 1fr;
  375. grid-column-gap: 40px;
  376. grid-row-gap: 40px;
  377. padding-right: 30px;
  378. }
  379. .table-img {
  380. width: 50px;
  381. position: relative;
  382. img {
  383. width: 100%;
  384. }
  385. div {
  386. position: absolute;
  387. z-index: 1;
  388. left: 0;
  389. top: 0;
  390. right: 0;
  391. bottom: 0;
  392. background-color: rgba(0,0,0,0.8);
  393. display: flex;
  394. align-items: center;
  395. justify-content: center;
  396. color: #fff;
  397. }
  398. }
  399. .un-data {
  400. height: 100%;
  401. display: flex;
  402. align-items: center;
  403. justify-content: center;
  404. font-size: 14px;
  405. color: #909399;
  406. }
  407. .oper-depar {
  408. cursor: pointer;
  409. }
  410. .vrmodel-from {
  411. // width: 320px;
  412. // margin: 0 auto;
  413. }
  414. </style>
  415. <style>
  416. .vrmodel-from .el-select {
  417. width: 100%;
  418. }
  419. .el-slider__button-wrapper {
  420. top: -6px !important;
  421. }
  422. </style>