【前端】智能库房综合管理系统前端项目
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.

559 lines
17 KiB

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