图书馆综合管理系统
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.

286 lines
10 KiB

7 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
6 months ago
6 months ago
6 months ago
7 months ago
6 months ago
6 months ago
6 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
7 months ago
6 months ago
7 months ago
  1. <template>
  2. <div class="app-container">
  3. <div class="venue-header">
  4. <h4><i class="iconfont icon-shuju" />数据总览</h4>
  5. <p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p>
  6. </div>
  7. <div class="venue-content dataScreening-content">
  8. <crudOperation :permission="permission">
  9. <template v-slot:middle>
  10. <el-button v-permission="permission.add" class="check-btn" size="mini" @click="toAdd(1)">
  11. <i class="iconfont icon-shengchengpandiandan" />
  12. 全量盘点
  13. </el-button>
  14. </template>
  15. <template v-slot:right>
  16. <el-button :loading="crud.downloadLoading" size="mini" @click="doExport(1)">
  17. <i class="iconfont icon-daochu" />
  18. 导出
  19. </el-button>
  20. </template>
  21. </crudOperation>
  22. <div class="venue-left">
  23. <div class="container-right tab-content">
  24. <span class="right-top-line" />
  25. <span class="left-bottom-line" />
  26. <ul class="tab-nav">
  27. <li v-for="(item,index) in floorOptions" :key="index" :class="{ 'active-tab-nav': tabIndex == index }" @click="changeActiveTab(index)">{{ item.floorName }}<i /></li>
  28. <!-- 最右侧装饰img -->
  29. <span class="tab-right-img" />
  30. </ul>
  31. <div class="total-data">
  32. <span>楼层概况</span>
  33. <p>区域{{ baseData.regionCount }}</p>
  34. <p>书架{{ baseData.shelfCount }}</p>
  35. <p>摄像头{{ baseData.deviceCount }}</p>
  36. </div>
  37. <CanvasPreview ref="previewRefs" v-loading="prewLoading" page-preview="floor" :current-mark-data="currentMarkData" :image-url="imageUrl" />
  38. </div>
  39. </div>
  40. <div class="venue-right">
  41. <div class="lib-right-item lib-info">
  42. <h4>场馆概况</h4>
  43. <ul class="data-right-list">
  44. <li><p>楼层</p><span><i>{{ baseData.floorCount }}</i></span></li>
  45. <li><p>区域</p><span><i>{{ baseData.regionCount }}</i></span></li>
  46. <li><p>书架</p><span><i>{{ baseData.shelfCount }}</i></span></li>
  47. <li><p>摄像头</p><span><i>{{ baseData.deviceCount }}</i></span></li>
  48. </ul>
  49. </div>
  50. <div class="lib-right-item">
  51. <h4>盘点概况</h4>
  52. <!-- <div class="refresh-date">2024-11-28 09:46</div> -->
  53. <ul class="data-right-list">
  54. <li><p>在架</p><span><i>{{ baseStockData.onShelfNum }}</i></span></li>
  55. <li><p>错架</p><span><i>{{ baseStockData.errorShelfNum }}</i></span> <span class="percentage">{{ baseStockData.errorShelfProbo }}</span></li>
  56. <li><p>错序</p><span><i>{{ baseStockData.errorOrderNum }}</i></span><span class="percentage">{{ baseStockData.errorOrderProbo }}</span></li>
  57. </ul>
  58. </div>
  59. <div class="lib-right-item">
  60. <h4>流通统计</h4>
  61. <div class="refresh-date">2024-11-28 09:46</div>
  62. <bookSwiper ref="bookSwiperRefs" />
  63. </div>
  64. </div>
  65. </div>
  66. <eForm ref="eform" />
  67. <exportForm ref="exportform" />
  68. </div>
  69. </template>
  70. <script>
  71. import { FetchInitStockInfo } from '@/api/stockTask/index'
  72. import { dataScreeningCrud } from '@/views/visualCheck/mixins/index'
  73. import { FetchInitLibraryRegionList } from '@/api/area/index'
  74. import crudStockTaskLog from '@/api/stockTaskLog/index'
  75. import CRUD, { presenter, header, crud } from '@crud/crud'
  76. import crudOperation from '@crud/CRUD.operation'
  77. import { mapGetters } from 'vuex'
  78. import defaultImg from '@/assets/images/system/default-img.jpg'
  79. import bookSwiper from '@/views/components/bookSwiper.vue'
  80. import CanvasPreview from '@/views/components/canvasPreview.vue'
  81. import eForm from './module/form'
  82. import exportForm from './module/export'
  83. export default {
  84. name: 'DataScreening',
  85. components: { crudOperation, bookSwiper, CanvasPreview, eForm, exportForm },
  86. cruds() {
  87. return CRUD({ title: '数据总览', url: 'api/libraryFloor/initLibraryFloorList', crudMethod: { ...crudStockTaskLog }, sort: [], optShow: {
  88. add: false,
  89. edit: false,
  90. del: false,
  91. download: false,
  92. group: false,
  93. reset: false
  94. }})
  95. },
  96. mixins: [presenter(), header(), crud(), dataScreeningCrud],
  97. data() {
  98. const _this = this
  99. return {
  100. prewLoading: false,
  101. floorOptions: [],
  102. tabIndex: 0,
  103. defaultImg: defaultImg,
  104. imageUrl: defaultImg,
  105. imageRegionUrl: defaultImg,
  106. currentMarkData: null,
  107. allCoverData: [],
  108. swiperActiveIndex: 0,
  109. rightDataIndex: null,
  110. swiperOptionContent: {
  111. slidesPerView: 'auto',
  112. on: {
  113. slideChangeTransitionStart: function() {
  114. _this.rightDataIndex = null
  115. _this.swiperActiveIndex = this.activeIndex
  116. _this.swiperTitle.slideTo(this.activeIndex, 500, false)
  117. }
  118. }
  119. },
  120. swiperOptionTitle: {
  121. slidesPerView: 'auto',
  122. freeMode: true
  123. },
  124. tabListData: [{ name: '热门图书' }, { name: '热门架位' }, { name: '冷面图书' }],
  125. permission: {
  126. add: ['admin', 'floor:add'],
  127. edit: ['admin', 'floor:edit'],
  128. del: ['admin', 'floor:del']
  129. },
  130. swiperParams: {},
  131. swiperShelfParams: {}
  132. }
  133. },
  134. computed: {
  135. ...mapGetters([
  136. 'user',
  137. 'baseApi'
  138. ]),
  139. swiperContent() {
  140. return this.$refs.swiperContent.$el.swiper
  141. }
  142. },
  143. methods: {
  144. [CRUD.HOOK.beforeRefresh]() {
  145. },
  146. [CRUD.HOOK.afterRefresh](crud) {
  147. this.floorOptions = crud.data
  148. if (this.$route.query.floorTabIndex) {
  149. this.tabIndex = this.$route.query.floorTabIndex
  150. } else {
  151. this.tabIndex = 0
  152. }
  153. this.changeActiveTab(this.tabIndex)
  154. // 盘点概况
  155. const params = {
  156. 'floorId': this.floorOptions[this.tabIndex].id
  157. }
  158. this.handleInitStockInfo(params)
  159. this.$nextTick(() => {
  160. this.$refs.bookSwiperRefs.swiperParams = {
  161. 'floorId': this.floorOptions[this.tabIndex].id
  162. }
  163. this.$refs.bookSwiperRefs.swiperShelfParams = {
  164. 'floorId': this.floorOptions[this.tabIndex].id
  165. }
  166. if (this.$refs.bookSwiperRefs.swiperActiveIndex === 0) {
  167. this.$refs.bookSwiperRefs.getInitHotBookList()
  168. } else {
  169. this.$refs.bookSwiperRefs.getInitHotShelfList()
  170. }
  171. })
  172. },
  173. toAdd(type) {
  174. this.$refs.eform.formVisible = true
  175. this.$refs.eform.setData(type)
  176. this.$refs.eform.form.stockRegion = '全部区域'
  177. },
  178. doExport(type) {
  179. this.$refs.exportform.formExportVisible = true
  180. this.$refs.exportform.type = 1
  181. },
  182. async getInitStockInfo(data) {
  183. const promises = data.map(item => {
  184. const params = {
  185. 'floorId': this.floorOptions[this.tabIndex].id,
  186. 'regionId': item.id
  187. }
  188. return FetchInitStockInfo(params)
  189. })
  190. const results = await Promise.all(promises)
  191. if (!Array.isArray(this.baseStockDataAllShelf)) {
  192. this.baseStockDataAllShelf = []
  193. }
  194. // 为每个结果对象添加id字段
  195. results.forEach((result, index) => {
  196. result.id = data[index].id
  197. })
  198. this.baseStockDataAllShelf = this.baseStockDataAllShelf.concat(results)
  199. return this.baseStockDataAllShelf
  200. },
  201. async changeActiveTab(index) {
  202. this.prewLoading = true
  203. if (this.$refs.previewRefs.canvasPreview.lowerCanvasEl) {
  204. this.$refs.previewRefs.canvasPreview.clear()
  205. this.$refs.previewRefs.canvasPreview.dispose()
  206. }
  207. this.allCoverData = []
  208. this.tabIndex = index
  209. const params = {
  210. 'floorId': this.floorOptions[index].id
  211. }
  212. try {
  213. const res = await FetchInitLibraryRegionList(params)
  214. console.log(res)
  215. this.allCoverData = res.content
  216. if (this.floorOptions[index].floorMap) {
  217. this.imageUrl = this.baseApi + '/api/fileRelevant/getImg?imgId=' + this.floorOptions[index].floorMap
  218. } else {
  219. this.imageUrl = this.defaultImg
  220. }
  221. if (this.allCoverData.length !== 0) {
  222. this.currentMarkData = this.allCoverData[0]
  223. // const signPoint = this.allCoverData.find(item => item.signPoint !== null)?.signPoint
  224. const imgInfo = JSON.parse(this.allCoverData[0].signPoint).imgInfo
  225. const baseStockDataAllShelf = await this.getInitStockInfo(this.allCoverData)
  226. const parsedSignPoints = this.allCoverData.map(item => {
  227. const signPoint = item.signPoint ? JSON.parse(item.signPoint) : null
  228. return {
  229. id: item.id,
  230. name: item.regionName,
  231. floorName: item.floorName,
  232. floorId: item.floorId,
  233. pointInfo: signPoint ? signPoint.pointInfo[0].pointInfo : null
  234. }
  235. })
  236. parsedSignPoints.forEach(parsedItem => {
  237. const baseStockItem = baseStockDataAllShelf.find(baseItem => baseItem.id === parsedItem.id)
  238. if (baseStockDataAllShelf) {
  239. Object.assign(parsedItem, baseStockItem)
  240. }
  241. })
  242. const result = {
  243. pointInfo: parsedSignPoints,
  244. imgInfo: imgInfo
  245. }
  246. console.log('result', result)
  247. this.$nextTick(() => {
  248. this.$refs.previewRefs.initCanvasPreview(result, this.tabIndex)
  249. })
  250. } else {
  251. this.currentMarkData = {}
  252. setTimeout(() => {
  253. this.prewLoading = false
  254. }, 500)
  255. }
  256. } catch (error) {
  257. console.error(error)
  258. }
  259. },
  260. handleSlidClickFun(index) {
  261. this.rightDataIndex = null
  262. this.handleSlideToFun(index)
  263. },
  264. handleSlideToFun(index) {
  265. this.swiperActiveIndex = index
  266. this.swiperContent.slideTo(index, 500, false)
  267. this.swiperTitle.slideTo(index, 500, false)
  268. }
  269. }
  270. }
  271. </script>
  272. <style lang="scss" scoped>
  273. </style>