【前端】智能库房综合管理系统前端项目
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

556 lines
16 KiB

2 years ago
  1. <template>
  2. <div class="app-container">
  3. <div class="cabinet-top">
  4. <p v-if="deviceData" class="cabinet-info">{{ deviceData.deviceName }} - {{ deviceData.areaNo }} - {{ cabinetNum }} </p>
  5. <div class="cabinet-des">
  6. <p>档案总数{{ archivesNum }}</p>
  7. <span class="cabinet-on">在库</span>
  8. <span class="cabinet-out">已借</span>
  9. <el-button type="primary" class="return-btn" @click="backWarehouse">3D</el-button>
  10. </div>
  11. </div>
  12. <div class="cabinet-main">
  13. <!-- 无库房当前列数据时 - 左边 -->
  14. <div v-if="deviceData" class="cabinet-num row-left-num">
  15. <span v-for="(item,index) in rowNum" :key="index" :style="heightStyle"><i>{{ item }}</i></span>
  16. </div>
  17. <div v-if="deviceData" class="cabinet-num part-left-num">
  18. <span v-for="(item,index) in partLeftNum" :key="index" :style="widhtStyle">{{ item }}</span>
  19. </div>
  20. <div v-if="deviceData" style="position:absolute; left:0; bottom:0; display: flex; font-size: 12px; color: #fff;">
  21. <span style="display:block; margin-top: -12px"></span>
  22. <span style="display:block; margin-top: -5px">/</span>
  23. <span style="display:block; "></span>
  24. </div>
  25. <ul v-if="sortLeft.length === 0" class="cabinet-row">
  26. <li v-for="(item,i) in totalPartRowNum" :key="i" class="cabinet-cell" :style="cellStyle" />
  27. </ul>
  28. <ul v-else class="cabinet-row">
  29. <li v-for="(item,index) in sortLeft" :key="index" class="cabinet-cell" :style="cellStyle">
  30. <!-- <div v-if="item.borrow === 0 && item.total === 0" style="font-size:12px">
  31. {{ item.part_No + '节' + item.row_No + '层' }}
  32. </div> -->
  33. <!-- 部分借出 -->
  34. <div v-if="item.borrow !== 0 && item.total - item.borrow !== 0" class="out-part">
  35. <span>{{ item.borrow }}</span>
  36. </div>
  37. <!-- 部分在库 -->
  38. <div v-if="item.borrow !== 0 && item.total - item.borrow !== 0" class="in-part">
  39. <span>{{ item.total - item.borrow }}</span>
  40. </div>
  41. <!-- 全部借出 -->
  42. <div v-if="item.borrow !== 0 && item.total - item.borrow === 0" class="out-all">
  43. <span>{{ item.borrow }}</span>
  44. </div>
  45. <!-- 全部在库 -->
  46. <div v-if="item.borrow === 0 && item.total - item.borrow !== 0" class="in-all">
  47. <span>{{ item.total - item.borrow }}</span>
  48. </div>
  49. </li>
  50. </ul>
  51. <div :class="['cabinet-panel', isFixed ? 'fixed-panel' : '']" />
  52. <!-- 无库房当前列数据时 - 右边 -->
  53. <ul v-if="sortLeft.length === 0" class="cabinet-row right-cabinet">
  54. <ul v-for="(item,i) in totalPartRowNum" :key="i" class="cabinet-cell" :style="cellStyle" />
  55. </ul>
  56. <ul v-else class="cabinet-row right-cabinet">
  57. <li v-for="(item,index) in sortRight" :key="index" class="cabinet-cell" :style="cellStyle">
  58. <!-- <div v-if="item.borrow === 0 && item.total === 0" style="font-size:12px">
  59. {{ item.part_No + '节' + item.row_No + '层' }}
  60. </div> -->
  61. <!-- 部分借出 -->
  62. <div v-if="item.borrow !== 0 && item.total - item.borrow !== 0" class="out-part">
  63. <span>{{ item.borrow }}</span>
  64. </div>
  65. <!-- 部分在库 -->
  66. <div v-if="item.borrow !== 0 && item.total - item.borrow !== 0" class="in-part">
  67. <span>{{ item.total - item.borrow }}</span>
  68. </div>
  69. <!-- 全部借出 -->
  70. <div v-if="item.borrow !== 0 && item.total - item.borrow !== 0" class="out-all">
  71. <span>{{ item.borrow }}</span>
  72. </div>
  73. <!-- 全部在库 -->
  74. <div v-if="item.borrow === 0 && item.total - item.borrow !== 0" class="in-all">
  75. <span>{{ item.total - item.borrow }}</span>
  76. </div>
  77. </li>
  78. </ul>
  79. <div v-if="deviceData" class="cabinet-num row-right-num">
  80. <span v-for="(item,index) in rowNum" :key="index" :style="heightStyle"><i>{{ item }}</i></span>
  81. </div>
  82. <div v-if="deviceData" class="cabinet-num part-right-num">
  83. <span v-for="(item,index) in partRightNum" :key="index" :style="widhtStyle">{{ item }}</span>
  84. </div>
  85. <div v-if="deviceData" style="position:absolute; right:0; bottom:0; display: flex; font-size: 12px; color: #fff;">
  86. <span style="display:block; "></span>
  87. <span style="display:block; margin-top: -5px">\</span>
  88. <span style="display:block; margin-top: -12px"></span>
  89. </div>
  90. </div>
  91. <div class="cabinet-bottom">
  92. <el-button type="primary" :disabled="isFixed" @click="openCol">开架</el-button>
  93. <el-button type="primary" @click="resetCol">合架</el-button>
  94. <el-button type="primary" @click="ventHandle">通风</el-button>
  95. <el-button type="primary" @click="stopMove">停止</el-button>
  96. </div>
  97. </div>
  98. </template>
  99. <script>
  100. import { FetchGetArchivesNum } from '@/api/archivesManage/statistics'
  101. import CallExternal from '@/api/storeManage/deviceManage/device'
  102. export default {
  103. name: 'DeseCabinet',
  104. data() {
  105. return {
  106. // D6490DA3D4261E8C26D0E3 档案库
  107. // 8F68A6B645B34B00B7ADFE 走廊
  108. storeroomId: 'D6490DA3D4261E8C26D0E3', // 档案库id
  109. deviceData: null, // 获取密集架data
  110. cabinetNum: null, // 当前列num
  111. isFixed: false, // 是否是固定列
  112. totalPartRowNum: null,
  113. archivesNum: null, // 档案总数
  114. left: [], // 左侧
  115. sortLeft: [], // 排序后得left-data
  116. right: [], // 右侧
  117. sortRight: [], // 排序后得right-data
  118. isColumDirection: false, // true 从上往下 false 从下往上 节数从机头开始排
  119. rowNum: [], // 左右两侧层数
  120. partLeftNum: [], // 左底部节点数
  121. partRightNum: [] // 右底部节点数
  122. }
  123. },
  124. computed: {
  125. cellStyle: function() {
  126. let h
  127. if (this.cabinetNum > 8) {
  128. h = '100%/' + (this.deviceData.rowNo - 1)
  129. } else {
  130. h = '100%/' + this.deviceData.rowNo
  131. }
  132. // const h = '100%/' + this.deviceData.rowNo
  133. const w = '100%/' + this.deviceData.partNo
  134. return { width: `calc(${w} - 10px )`, height: `calc(${h} - 10px)` }
  135. },
  136. heightStyle: function() {
  137. let h
  138. if (this.cabinetNum > 8) {
  139. h = '100%/' + (this.deviceData.rowNo - 1)
  140. } else {
  141. h = '100%/' + this.deviceData.rowNo
  142. }
  143. // const h = '100%/' + this.deviceData.rowNo
  144. return { height: `calc(${h})` }
  145. },
  146. widhtStyle: function() {
  147. const w = '100%/' + this.deviceData.partNo
  148. return { width: `calc(${w} - 10px)` }
  149. }
  150. },
  151. created() {
  152. this.handleArchivesNum()
  153. this.getDeviceListAll()
  154. },
  155. mounted() {
  156. if (parseInt(localStorage.getItem('cabinetNum'))) {
  157. this.cabinetNum = parseInt(localStorage.getItem('cabinetNum'))
  158. this.isFixed = this.cabinetNum === 1
  159. } else {
  160. this.cabinetNum = 0
  161. }
  162. },
  163. methods: {
  164. // 档案总数
  165. handleArchivesNum() {
  166. FetchGetArchivesNum().then(data => {
  167. this.archivesNum = data
  168. })
  169. },
  170. // 获取密集架相关信息
  171. getDeviceListAll() {
  172. const params = {
  173. page: 0,
  174. size: 10,
  175. sort: 'sequence,asc',
  176. storeroomId: this.storeroomId
  177. }
  178. CallExternal.getDeviceList(params).then(data => {
  179. data.content.map(item => {
  180. if (item.deviceTypeId.name === '密集架') { // 写死状态
  181. this.deviceData = item
  182. this.totalPartRowNum = item.partNo * item.rowNo
  183. let rowNo
  184. if (this.cabinetNum > 8) { // 战备密集架得情况
  185. rowNo = item.rowNo - 1
  186. } else {
  187. rowNo = item.rowNo
  188. }
  189. for (let i = 0; i < rowNo; i++) {
  190. this.rowNum.push(i + 1)
  191. }
  192. for (let i = 0; i < item.partNo; i++) {
  193. this.partLeftNum.push(i + 1)
  194. this.partRightNum.push(i + 1)
  195. }
  196. this.partLeftNum.reverse()
  197. if (!this.isColumDirection) {
  198. this.rowNum.reverse()
  199. }
  200. this.getInBorrowByQuCol()
  201. }
  202. })
  203. })
  204. },
  205. // 获取密集架左右节/层档案情况
  206. async getInBorrowByQuCol() {
  207. const params = {
  208. deviceId: this.deviceData.id,
  209. quNo: this.deviceData.areaNo,
  210. colNo: this.cabinetNum
  211. }
  212. CallExternal.FetchInBorrowByQuCol(params).then(data => {
  213. data.forEach(item => {
  214. if (item.direction === '左') {
  215. this.left.push(item)
  216. }
  217. if (item.direction === '右') {
  218. this.right.push(item)
  219. }
  220. })
  221. this.setReorderData(this.left, this.sortLeft, false)
  222. this.setReorderData(this.right, this.sortRight, true)
  223. })
  224. },
  225. // 分出左右后重新排序,根据节和层从下往上,left-从右往左, right-从左往右
  226. setReorderData(data, sortData, order) {
  227. let key
  228. if (this.isColumDirection) {
  229. key = 0
  230. } else {
  231. key = this.deviceData.rowNo + 1
  232. }
  233. const arr = []
  234. for (let i = 0; i < this.deviceData.rowNo; i++) {
  235. arr[i] = []
  236. if (this.isColumDirection) {
  237. key++
  238. } else {
  239. key--
  240. }
  241. data.forEach(item => {
  242. if (item.row_No === key) {
  243. arr[i].push(item)
  244. }
  245. if (this.isColumDirection) {
  246. if (key === this.deviceData.rowNo + 1) {
  247. key = 0
  248. }
  249. } else {
  250. if (key === 0) {
  251. key = this.deviceData.rowNo
  252. }
  253. }
  254. })
  255. this.arrSortByKey(arr[i], 'part_No', order)
  256. }
  257. // 筛选完之后,重新全部集合在指定得data内
  258. arr.forEach(item => {
  259. item.forEach(i => {
  260. sortData.push(i)
  261. })
  262. })
  263. },
  264. // 升降序
  265. arrSortByKey(array, property, order) {
  266. return array.sort(function(a, b) {
  267. const value1 = a[property]
  268. const value2 = b[property]
  269. if (order) { // 升序
  270. return value1 - value2
  271. } else { // 降序
  272. return value2 - value1
  273. }
  274. })
  275. },
  276. // 开架
  277. openCol() {
  278. const params = {
  279. deviceId: this.deviceData.id,
  280. quNo: this.deviceData.areaNo,
  281. colNo: this.cabinetNum,
  282. leNo: '',
  283. divNo: '',
  284. zyNo: ''
  285. }
  286. CallExternal.FetchCallExternalOpenCol(params).then(res => {
  287. if (res.success && res.success === '0') {
  288. this.$message.success('开架执行成功')
  289. } else {
  290. this.$message.error(res.msg)
  291. }
  292. }).catch((error) => {
  293. console.log(error)
  294. this.$message.error('连接失败')
  295. })
  296. },
  297. // 合架
  298. resetCol() {
  299. const params = {
  300. deviceId: this.deviceData.id,
  301. quNo: this.deviceData.areaNo
  302. }
  303. CallExternal.FetchCallExternalResetCol(params).then(res => {
  304. if (res.success && res.success === '0') {
  305. this.$message.success('合架执行成功')
  306. } else {
  307. this.$message.error(res.msg)
  308. }
  309. }).catch((error) => {
  310. console.log(error)
  311. this.$message.error('连接失败')
  312. })
  313. },
  314. // 密集架通风
  315. ventHandle() {
  316. const params = {
  317. deviceId: this.deviceData.id,
  318. quNo: this.deviceData.areaNo
  319. }
  320. CallExternal.FetchCallExternalVent(params).then(res => {
  321. if (res.success && res.success === '0') {
  322. this.$message.success('密集架通风执行成功')
  323. } else {
  324. this.$message.error(res.msg)
  325. }
  326. }).catch((error) => {
  327. console.log(error)
  328. this.$message.error('连接失败')
  329. })
  330. },
  331. // 密集架停止移动
  332. stopMove() {
  333. const params = {
  334. deviceId: this.deviceData.id,
  335. quNo: this.deviceData.areaNo
  336. }
  337. CallExternal.FetchCallExternalStopMove(params).then(res => {
  338. if (res.success && res.success === '0') {
  339. this.$message.success('密集架停止移动执行成功')
  340. } else {
  341. this.$message.error(res.msg)
  342. }
  343. }).catch((error) => {
  344. console.log(error)
  345. this.$message.error('连接失败')
  346. })
  347. },
  348. // 返回3D库房
  349. backWarehouse() {
  350. this.$router.push('/storeManage/warehouse3D')
  351. localStorage.setItem('isDeseCabinetPage', true)
  352. }
  353. }
  354. }
  355. </script>
  356. <style lang="scss" scoped>
  357. .cabinet-top{
  358. display: flex;
  359. justify-content: space-between;
  360. width: calc(100vw - 354px);
  361. margin: 0 auto 20px auto;
  362. font-size: 14px;
  363. line-height: 36px;
  364. color: #fff;
  365. .cabinet-info{
  366. font-weight: bold;
  367. }
  368. .cabinet-des{
  369. display: flex;
  370. p{
  371. margin-right: 40px;
  372. }
  373. span{
  374. position: relative;
  375. padding-left: 20px;
  376. margin-right: 40px;
  377. &::before{
  378. content: "";
  379. position: absolute;
  380. left: 0;
  381. top: 50%;
  382. width: 14px;
  383. height: 14px;
  384. border-radius: 50%;
  385. margin-top: -7px;
  386. }
  387. }
  388. .cabinet-on::before{
  389. background-color: #1AAE93;
  390. }
  391. .cabinet-out::before{
  392. background-color: #F65163;
  393. }
  394. }
  395. }
  396. .return-btn,
  397. .cabinet-bottom .el-button{
  398. font-size: 16px;
  399. height: 36px;
  400. padding: 0 33px;
  401. background-color: #339CFF;
  402. }
  403. .cabinet-main{
  404. position: relative;
  405. display: flex;
  406. justify-content: space-between;
  407. width: calc(100vw - 344px);
  408. height: calc(100vh - 322px);
  409. padding-bottom: 30px;
  410. margin: 0 auto;
  411. overflow: hidden;
  412. }
  413. .cabinet-num{
  414. position: absolute;
  415. display: flex;
  416. flex-direction: column;
  417. flex-wrap: wrap;
  418. justify-content: center;
  419. align-items: center;
  420. border-radius: 20px;
  421. background-color: #113D72;
  422. span{
  423. position: relative;
  424. display: block;
  425. font-size: 14px;
  426. color: #fff;
  427. text-align: center;
  428. i{
  429. display: block;
  430. font-style: normal;
  431. position: absolute;
  432. top: 50%;
  433. left: 50%;
  434. transform: translate(-50%, -50%);
  435. }
  436. }
  437. }
  438. .row-left-num{
  439. width: 20px;
  440. height: calc(100vh - 352px);
  441. left: 0;
  442. top: 0;
  443. span{
  444. width: 20px;
  445. }
  446. }
  447. .row-right-num{
  448. width: 20px;
  449. height: calc(100vh - 352px);
  450. right: 0;
  451. top: 0;
  452. span{
  453. width: 20px;
  454. }
  455. }
  456. .part-left-num{
  457. width: calc(100vw/2 - 280px);
  458. height: 20px;
  459. left: 30px;
  460. bottom: 0;
  461. span{
  462. height: 20px;
  463. line-height: 20px;
  464. }
  465. }
  466. .part-right-num{
  467. width: calc(100vw/2 - 280px);
  468. height: 20px;
  469. right: 30px;
  470. bottom: 0;
  471. span{
  472. height: 20px;
  473. line-height: 20px;
  474. }
  475. }
  476. .cabinet-row{
  477. display: flex;
  478. flex: 1;
  479. flex-wrap: wrap;
  480. color: #fff;
  481. text-align: center;
  482. margin-left: 20px;
  483. margin-bottom: -10px;
  484. .cabinet-cell{
  485. margin: 0 0 10px 10px;
  486. font-size: 20px;
  487. background-color: #02255F;
  488. border-radius: 10px;
  489. overflow: hidden;
  490. // &:nth-last-of-type(-n+4) {
  491. // margin-bottom: 0;
  492. // }
  493. // &:nth-child(4n){
  494. // margin-right: 0;
  495. // }
  496. }
  497. .in-all, .out-all, .out-part, .in-part{
  498. position: relative;
  499. width: 100%;
  500. span{
  501. display: block;
  502. position: absolute;
  503. left: 50%;
  504. top: 50%;
  505. transform: translate(-50%,-50%);
  506. z-index: 9;
  507. }
  508. }
  509. .in-all, .out-all{
  510. height: 100%;
  511. }
  512. .out-part, .in-part{
  513. height: 50%;
  514. }
  515. .out-all, .out-part{
  516. background-color: #F65163;
  517. }
  518. .in-all, .in-part{
  519. background-color: #1AAE93;
  520. }
  521. }
  522. .right-cabinet{
  523. margin-left: 0;
  524. margin-right: 30px;
  525. }
  526. .cabinet-panel{
  527. width: 140px;
  528. margin-left: 10px;
  529. background: url('~@/assets/images/panel-n.png') no-repeat;
  530. background-size: 100% 100%;
  531. }
  532. .fixed-panel{
  533. background: url('~@/assets/images/panel-y.png') no-repeat;
  534. background-size: 100% 100%;
  535. }
  536. .cabinet-bottom{
  537. text-align: center;
  538. margin: 30px 0;
  539. ::v-deep .is-disabled{
  540. color: #13439E;
  541. background-color: #02255F;
  542. border-color: #02255F;
  543. }
  544. }
  545. @media screen and (min-width:1200px) and (max-width:1536px){
  546. .cabinet-panel{
  547. width: 92px;
  548. }
  549. }
  550. </style>