祁阳图书馆智慧大屏
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.

408 lines
16 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. <!-- eslint-disable no-prototype-builtins -->
  2. <template>
  3. <div class="page-wrapper ">
  4. <div class="page-three">
  5. <div class="three-item three01">
  6. <div class="database-title">本年累计借阅数量</div>
  7. <div class="three-lending">
  8. <div class="three-lending-left">
  9. <h5>本年累计借阅</h5>
  10. <ul class="totalItem">
  11. <li
  12. v-for="(item, index) in yearTotal"
  13. :key="index"
  14. :class="[{'yearTotal': item.id === 'yearTotal'}]"
  15. >
  16. <div class="pageLeft-flop-box">
  17. <div>
  18. <span v-for="(ls, i) in item.valueArr" :key="item.id + i" :class="[{'flop-figure': !isNaN(ls)}, {'flop-comma': isNaN(ls)}]">
  19. <i v-if="!isNaN(ls)">0123456789</i>
  20. <!-- <span v-else>{{ ls }}</span> -->
  21. </span>
  22. </div>
  23. </div>
  24. </li>
  25. </ul>
  26. <YearCircle :year-all-num="yearAllNum" />
  27. </div>
  28. <div class="three-lending-right lending-ranking">
  29. <h5>分馆累计借阅排行榜</h5>
  30. <div class="ranking-cont">
  31. <ul class="ranking-title">
  32. <li style="width: 0.625rem;">排名</li>
  33. <li style="width: 1.5rem; text-align: left;">图书馆名称</li>
  34. <li style="flex:1;" />
  35. <li style="width: 1.25rem; padding-right: .125rem; text-align: right;">借阅数量</li>
  36. </ul>
  37. <ul class="ranking-list">
  38. <li v-for="(item,index) in rankingYearWithPercentage" :key="index" :class="{ 'hovered': index === currentHover }">
  39. <div style="width: .625rem; color: #79B8FF;" :class="[{'ranking-num1':index===0},{'ranking-num2':index===1},{'ranking-num3':index===2}]">{{ index>=3 ? index+1 : null }}</div>
  40. <div style="width: 1.5rem; text-align: left;">{{ item.name }}</div>
  41. <div class="ranking-progress" style="flex:1; align-self: center;">
  42. <el-progress :percentage="item.percentage" :stroke-width="8" :show-text="false" color="#009afb" />
  43. </div>
  44. <div style="width: 1.25rem; padding-right: .125rem; text-align: right;">{{ item.JCC_YEAR }}<i style="padding-left:.0625rem;"></i></div>
  45. </li>
  46. </ul>
  47. </div>
  48. </div>
  49. </div>
  50. </div>
  51. <div class="three-item three02">
  52. <div class="database-title">今日借阅数量</div>
  53. <div class="three-lending">
  54. <div class="three-lending-left">
  55. <h5>今日累计借阅</h5>
  56. <ul class="totalItem">
  57. <li
  58. v-for="(item, index) in todayTotal"
  59. :key="index"
  60. :class="[{'todayTotal': item.id === 'todayTotal'}]"
  61. >
  62. <div class="pageLeft-flop-box">
  63. <div>
  64. <span v-for="(ls, i) in item.valueArr" :key="item.id + i" :class="[{'flop-figure': !isNaN(ls)}, {'flop-comma': isNaN(ls)}]">
  65. <i v-if="!isNaN(ls)">0123456789</i>
  66. <!-- <span v-else>{{ ls }}</span> -->
  67. </span>
  68. </div>
  69. </div>
  70. </li>
  71. </ul>
  72. <TodayCircle :today-all-num="todayAllNum" />
  73. </div>
  74. <div class="three-lending-right lending-ranking">
  75. <h5>分馆今日借阅排行榜 </h5>
  76. <div class="ranking-cont">
  77. <ul class="ranking-title">
  78. <li style="width: 0.625rem;">排名</li>
  79. <li style="width: 1.5rem; text-align: left;">图书馆名称</li>
  80. <li style="flex:1;" />
  81. <li style="width: 1.25rem; padding-right: .125rem; text-align: right;">借阅数量</li>
  82. </ul>
  83. <ul class="ranking-list">
  84. <li v-for="(item,index) in rankingTodayWithPercentage" :key="index" :class="{ 'hovered': index === currentHover }">
  85. <div style="width: 0.625rem; color: #79B8FF;" :class="[{'ranking-num1':index===0},{'ranking-num2':index===1},{'ranking-num3':index===2}]">{{ index>=3 ? index+1 : null }}</div>
  86. <div style="width: 1.5rem; text-align: left;">{{ item.name }}</div>
  87. <div class="ranking-progress" style="flex:1; align-self: center;">
  88. <el-progress :percentage="item.percentage" :stroke-width="8" :show-text="false" color="#009afb" />
  89. </div>
  90. <div style="width: 1.25rem; padding-right: .125rem; text-align: right;">{{ item.JCC_DAY }}<i style="padding-left:.0625rem;"></i></div>
  91. </li>
  92. </ul>
  93. </div>
  94. </div>
  95. </div>
  96. </div>
  97. <div class="three-item three03">
  98. <div class="database-title">今日借阅趋势</div>
  99. <div class="chart-wrapper" style="width: 11.25rem;height: calc(100% - 35px);">
  100. <LineChart :chart-day-data="chartDayData" />
  101. </div>
  102. </div>
  103. <div class="three-item three04">
  104. <div class="database-title">近7日借阅统计</div>
  105. <div class="chart-wrapper" style="width: 11.25rem;height: calc(100% - 20px);">
  106. <BarEcharts ref="weeklyRef" :chart-weekly-data="chartWeeklyData" />
  107. </div>
  108. </div>
  109. </div>
  110. </div>
  111. </template>
  112. <script>
  113. import { FetchLibcodeDetails, FetchLendingTotal, FetchTodayJH, FetchWeekJH } from '@/api/library'
  114. import LineChart from '@/components/echart/lineChart'
  115. import BarEcharts from '@/components/echart/barEcharts'
  116. import YearCircle from '@/components/echart/yearCircle'
  117. import TodayCircle from '@/components/echart/todayCircle'
  118. export default {
  119. name: 'PageThree',
  120. components: {
  121. LineChart,
  122. BarEcharts,
  123. YearCircle,
  124. TodayCircle
  125. },
  126. data() {
  127. return {
  128. currentHover: -1,
  129. chartDayData: {
  130. timeData: [],
  131. returnData: [],
  132. borrowedData: []
  133. },
  134. chartWeeklyData: {
  135. date: [],
  136. inchartWeeklyData: [],
  137. outchartWeeklyData: []
  138. },
  139. todayTotal: [],
  140. yearTotal: [],
  141. rankingYearData: [],
  142. rankingTodayData: [],
  143. rankingYearWithPercentage: [],
  144. rankingTodayWithPercentage: [],
  145. yearAllNum: {
  146. headerLib: 0,
  147. branchLib: 0
  148. },
  149. todayAllNum: {
  150. headerLib: 0,
  151. branchLib: 0
  152. },
  153. rankInterval: null
  154. }
  155. },
  156. computed: {
  157. },
  158. beforeDestroy() {
  159. clearInterval(this.rankInterval)
  160. this.rankInterval = null
  161. },
  162. created() {
  163. },
  164. activated() {
  165. this.getLendingTotal()
  166. this.getTodayJH()
  167. // if (this.rankingYearWithPercentage.length !== 0) {
  168. // this.currentHover = -1
  169. // this.rankInterval = setInterval(() => {
  170. // this.currentHover = (this.currentHover + 1) % this.rankingYearWithPercentage.length
  171. // }, 1000)
  172. // }
  173. },
  174. deactivated() {
  175. clearInterval(this.rankInterval)
  176. this.rankInterval = null
  177. },
  178. mounted() {
  179. // this.getLendingTotal()
  180. // this.getTodayJH()
  181. this.getWeekJH()
  182. },
  183. methods: {
  184. paddingNum(num, length) {
  185. for (var len = (num + '').length; len < length; len = num.length) {
  186. num = '0' + num
  187. }
  188. return num
  189. },
  190. // 获取本年今年借阅情况
  191. getLendingTotal() {
  192. this.todayTotal = []
  193. this.yearTotal = []
  194. FetchLendingTotal().then(res => {
  195. const result = JSON.parse(res.data)
  196. if (result.success & result.resultlist.length !== 0) {
  197. // console.log('result.resultlist', result.resultlist)
  198. // JCC_YEAR 本年借阅册数
  199. // JCC_DAY 今日借阅册数
  200. const dayNum = result.resultlist.filter(item => item.LIBCODE !== '999').reduce((acc, obj) => acc + obj.JCC_DAY, 0)
  201. const yearNum = result.resultlist.filter(item => item.LIBCODE !== '999').reduce((acc, obj) => acc + obj.JCC_YEAR, 0)
  202. this.todayTotal.push({
  203. id: 'todayTotal',
  204. name: '今日累计借阅',
  205. value: this.$parent.formatter(this.paddingNum(dayNum, 5)),
  206. valueArr: this.$parent.formatter(this.paddingNum(dayNum, 5)).split('')
  207. })
  208. this.yearTotal.push({
  209. id: 'yearTotal',
  210. name: '本年累计借阅',
  211. value: this.$parent.formatter(yearNum),
  212. valueArr: this.$parent.formatter(yearNum).split('')
  213. })
  214. // 总管就是QYTSG的数据,分馆就是其他除去999以为的合计
  215. this.yearAllNum = {
  216. 'headerLib': result.resultlist.filter(item => item.LIBCODE === 'QYTSG')[0].JCC_YEAR,
  217. 'branchLib': result.resultlist.filter(item => item.LIBCODE !== 'QYTSG' && item.LIBCODE !== '999').reduce((acc, obj) => acc + obj.JCC_YEAR, 0)
  218. }
  219. this.todayAllNum = {
  220. 'headerLib': result.resultlist.filter(item => item.LIBCODE === 'QYTSG')[0].JCC_DAY,
  221. 'branchLib': result.resultlist.filter(item => item.LIBCODE !== 'QYTSG' && item.LIBCODE !== '999').reduce((acc, obj) => acc + obj.JCC_DAY, 0)
  222. }
  223. // 排行榜显示前6的
  224. this.getLibcodeDetails(result.resultlist)
  225. this.$parent.timedRefresh(this.todayTotal, 'todayTotal')
  226. this.$parent.timedRefresh(this.yearTotal, 'yearTotal')
  227. console.log('this.todayTotal', this.todayTotal)
  228. console.log('this.yearTotal', this.yearTotal)
  229. } else {
  230. this.todayTotal = []
  231. this.yearTotal = []
  232. }
  233. }).catch(error => {
  234. console.error('Error', error)
  235. })
  236. },
  237. // 分管显示内容
  238. getLibcodeDetails(data) {
  239. FetchLibcodeDetails().then(res => {
  240. const result = JSON.parse(res.data)
  241. if (result.length !== 0) {
  242. const newDataArray = []
  243. data.forEach(item => {
  244. const foundItem = result.find(library => library.tcId === item.LIBCODE)
  245. if (foundItem) {
  246. const yearValue = item.JCC_YEAR || 0
  247. const dayValue = item.JCC_DAY || 0
  248. const newObj = {
  249. name: foundItem.name,
  250. JCC_YEAR: yearValue,
  251. JCC_DAY: dayValue
  252. }
  253. newDataArray.push(newObj)
  254. }
  255. })
  256. // 2. 根据JCC_YEAR的值进行降序排序
  257. this.rankingYearData = newDataArray.sort((a, b) => b.JCC_YEAR - a.JCC_YEAR).slice(0, 6)
  258. this.rankingYearWithPercentage = this.rankingDataComputed(this.rankingYearData, 'JCC_YEAR')
  259. // 3. 根据JCC_DAY的值进行降序排序
  260. this.rankingTodayData = newDataArray.sort((a, b) => b.JCC_DAY - a.JCC_DAY).slice(0, 6)
  261. this.rankingTodayWithPercentage = this.rankingDataComputed(this.rankingTodayData, 'JCC_DAY')
  262. this.rankInterval = setInterval(() => {
  263. this.currentHover = (this.currentHover + 1) % this.rankingYearWithPercentage.length
  264. }, 1000)
  265. }
  266. }).catch(error => {
  267. console.error('Error', error)
  268. })
  269. },
  270. rankingDataComputed(rankingData, numType) {
  271. if (!rankingData || rankingData.length === 0) {
  272. console.log('没有数据')
  273. return []
  274. }
  275. // eslint-disable-next-line no-prototype-builtins
  276. if (typeof rankingData[0] !== 'object' || !rankingData[0].hasOwnProperty(numType)) {
  277. return []
  278. }
  279. const firstPlaceNum = rankingData[0][numType] // NAN
  280. if (firstPlaceNum === 0) {
  281. // 处理除数为0的情况
  282. console.log('firstPlaceNum为0,不可用于被除')
  283. return []
  284. }
  285. return rankingData.map(item => {
  286. const percentage = (item[numType] / firstPlaceNum) * 100
  287. return { ...item, percentage }
  288. })
  289. },
  290. // 今日借还
  291. getTodayJH() {
  292. FetchTodayJH().then(res => {
  293. const result = res.data
  294. if (result.length !== 0) {
  295. this.chartDayData = {
  296. timeData: [],
  297. returnData: [],
  298. borrowedData: []
  299. }
  300. const time = ['07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00']
  301. time.forEach((hour, index) => {
  302. // 查找 result 中是否有对应的 logHour
  303. const foundItem = result.find(item => item.logHour === index + 7) // 因为 logHour 是从 7 开始,所以需要加上 7
  304. if (foundItem) {
  305. // 如果找到了对应的 logHour,则将数据加入 chartDayData
  306. this.chartDayData.timeData.push(`${foundItem.logHour}:00`)
  307. this.chartDayData.returnData.push(foundItem.hccDay)
  308. this.chartDayData.borrowedData.push(foundItem.jccDay)
  309. } else {
  310. // 如果没找到对应的 logHour,则将默认值加入 chartDayData
  311. this.chartDayData.timeData.push(`${hour}`)
  312. this.chartDayData.returnData.push(0) // 默认值为 0
  313. this.chartDayData.borrowedData.push(0) // 默认值为 0
  314. }
  315. })
  316. } else {
  317. this.chartDayData = {
  318. timeData: [],
  319. returnData: [],
  320. borrowedData: []
  321. }
  322. }
  323. }).catch(error => {
  324. console.error('Error', error)
  325. })
  326. },
  327. getWeekJH() {
  328. FetchWeekJH().then(res => {
  329. const result = res.data
  330. if (result.length !== 0) {
  331. // 获取当天日期
  332. const currentDate = new Date()
  333. const today = currentDate.toISOString().slice(0, 10)
  334. // 根据数据排除当天的数据
  335. const filteredData = result.filter(entry => {
  336. const entryDate = new Date(entry.createTime).toISOString().slice(0, 10)
  337. return entryDate !== today
  338. })
  339. // 获取过去一周的
  340. const pastWeekDates = []
  341. for (let i = 1; i <= 7; i++) {
  342. const date = new Date()
  343. date.setDate(currentDate.getDate() - i)
  344. pastWeekDates.push(date.toISOString().slice(0, 10))
  345. }
  346. const matchData = filteredData.reduce((accData, item) => {
  347. // 根据已有的数据获取相关日期
  348. const entryDate = new Date(item.createTime).toISOString().slice(0, 10)
  349. if (accData[entryDate]) {
  350. accData[entryDate].jccDayTotal += item.jccDayTotal
  351. accData[entryDate].hccDayTotal += item.hccDayTotal
  352. } else {
  353. accData[entryDate] = {
  354. jccDayTotal: item.jccDayTotal,
  355. hccDayTotal: item.hccDayTotal
  356. }
  357. }
  358. return accData
  359. }, {})
  360. const completeData = pastWeekDates.map(date => ({
  361. date: date.split('-').join('/'),
  362. jccDayTotal: matchData[date] ? matchData[date].jccDayTotal : 0,
  363. hccDayTotal: matchData[date] ? matchData[date].hccDayTotal : 0
  364. }))
  365. // 根据时间排序
  366. completeData.sort((a, b) => new Date(a.date) - new Date(b.date))
  367. // 日期X轴数据
  368. this.chartWeeklyData.date = completeData.map(item => item.date)
  369. // in 归还
  370. this.chartWeeklyData.inchartWeeklyData = completeData.map(item => item.hccDayTotal)
  371. // // out 借出
  372. this.chartWeeklyData.outchartWeeklyData = completeData.map(item => item.jccDayTotal)
  373. console.log(this.chartWeeklyData.date)
  374. } else {
  375. this.chartWeeklyData = {
  376. date: [],
  377. inchartWeeklyData: [],
  378. outchartWeeklyData: []
  379. }
  380. }
  381. }).catch(error => {
  382. console.error('Error', error)
  383. })
  384. }
  385. }
  386. }
  387. </script>
  388. <style lang="scss">
  389. @import "~@/assets/styles/index.scss";
  390. @import "~@/assets/styles/font-some.css";
  391. </style>