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

295 lines
11 KiB

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