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

434 lines
15 KiB

7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
7 months ago
6 months ago
7 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
6 months ago
7 months ago
7 months ago
  1. <template>
  2. <div class="dashboard-container">
  3. <div class="dashboard-editor-container">
  4. <panel-group :top-object-num="topObjectNum" />
  5. <el-row :gutter="20" style="margin-bottom:20px;height: calc(50vh - 174px);">
  6. <el-col :xs="24" :sm="24" :lg="12">
  7. <div class="container-wrap">
  8. <span class="right-top-line" />
  9. <span class="left-bottom-line" />
  10. <h3 class="home-item-title">
  11. 盘点日志
  12. <router-link :to="{ path: '/check/check/checkLog'}">
  13. <div style="position: absolute; right: 20px; top: 20px; color: #999;" class="el-icon-more" />
  14. </router-link>
  15. </h3>
  16. <div class="home-flowable" style="height: calc(100% - 54px); overflow-x: hidden;">
  17. <div class="home-tab">
  18. <span :class="{'home-tab-active': flowableTabIndex == 0}">未完成({{ stockLogIncompleteData.length !==0? stockLogIncompleteData.length: 0 }})</span>
  19. <span :class="{'home-tab-active': flowableTabIndex == 1}">已完成({{ stockLogCompletedData.length !==0? stockLogCompletedData.length: 0 }})</span>
  20. <!-- <span :class="{'home-tab-active': flowableTabIndex == 2}">已完成({{ flowableData.length !==0? flowableData.length: 0 }})</span>
  21. <span :class="{'home-tab-active': flowableTabIndex == 3}" @click="toMoreProcess">更多任务</span> -->
  22. </div>
  23. <div class="home-flowable-list" style="height: calc(100% - 45px); overflow-y: auto; overflow-x: hidden;">
  24. <el-table v-if="stockLogIncompleteData.length !== 0" height="calc(100%)" :data="stockLogIncompleteData" class="archives-table" stripe style="width: 100%">
  25. <el-table-column prop="stockBill" label="盘点单号" />
  26. <el-table-column prop="stockRegion" label="目标位置" />
  27. <el-table-column prop="stockGridNum" label="目标数量" align="right">
  28. <template slot-scope="scope">
  29. <div>{{ scope.row.stockGridNum + ' / '+ (scope.row.totalGridNum?scope.row.totalGridNum:'0') +' 层位' }}</div>
  30. </template>
  31. </el-table-column>
  32. <el-table-column prop="state" label="盘点状态" align="center">
  33. <template slot-scope="scope">
  34. <span v-if="scope.row.state === 0" class="row-state row-lending state-active">已终止</span>
  35. <span v-if="scope.row.state === 1" class="row-state row-warehousing state-active">排队中</span>
  36. <span v-if="scope.row.state === 2" class="row-state row-binding state-active">盘点中</span>
  37. <span v-if="scope.row.state === 3" class="row-state row-physical state-active">已完成</span>
  38. </template>
  39. </el-table-column>
  40. <!-- <el-table-column prop="createTime" label="申请时间" width="180"> -->
  41. <!-- <template slot-scope="scope"> -->
  42. <!-- <div>{{ scope.row.createTime | parseTime }}</div> -->
  43. <!-- </template> -->
  44. <!-- </el-table-column> -->
  45. </el-table>
  46. <div v-else class="empty-main" style="height: 100%;">
  47. <svg-icon icon-class="empty" class-name="empty-img" />
  48. <p>暂无数据</p>
  49. </div>
  50. </div>
  51. </div>
  52. </div>
  53. </el-col>
  54. <el-col :xs="24" :sm="24" :lg="12">
  55. <div class="container-wrap">
  56. <span class="right-top-line" />
  57. <span class="left-bottom-line" />
  58. <h3 class="home-item-title">
  59. 服务器监控
  60. <div style="position: absolute; right: 20px; top: 20px; color: #999; cursor: pointer;" class="el-icon-refresh" @click="refreshSystemData" />
  61. </h3>
  62. <!-- <div class="chart-wrapper"> -->
  63. <serverProgress :system-data="systemData" />
  64. <!-- </div> -->
  65. </div>
  66. </el-col>
  67. </el-row>
  68. <el-row :gutter="20" style="height:calc(50vh - 174px);">
  69. <el-col :xs="24" :sm="24" :lg="8">
  70. <!-- 档案借阅 -->
  71. <div class="container-wrap">
  72. <span class="right-top-line" />
  73. <span class="left-bottom-line" />
  74. <h3 class="home-item-title">
  75. 盘点概况
  76. </h3>
  77. <div v-if="lendData.otherData.length !== 0" class="chart-wrapper">
  78. <lend-across :lend-data="lendData" />
  79. </div>
  80. <div v-else class="empty-main">
  81. <svg-icon icon-class="empty" class-name="empty-img" />
  82. <p>暂无数据</p>
  83. </div>
  84. </div>
  85. </el-col>
  86. <el-col :xs="24" :sm="24" :lg="8">
  87. <!-- 档案类型 -->
  88. <div class="container-wrap">
  89. <span class="right-top-line" />
  90. <span class="left-bottom-line" />
  91. <h3 class="home-item-title">
  92. 流通统计
  93. </h3>
  94. <div class="refresh-date">2024-11-28 09:46</div>
  95. <div class="chart-wrapper" style="padding: 0 10px; margin-top: -10px;">
  96. <bookSwiper />
  97. </div>
  98. </div>
  99. </el-col>
  100. <el-col :xs="24" :sm="24" :lg="8">
  101. <!-- 档案门类 -->
  102. <div class="container-wrap">
  103. <span class="right-top-line" />
  104. <span class="left-bottom-line" />
  105. <h3 class="home-item-title">
  106. 馆藏统计
  107. </h3>
  108. <div v-if="typeData.length !== 0" class="chart-wrapper">
  109. <type-pie :type-data="typeData" />
  110. </div>
  111. <div v-else class="empty-main">
  112. <svg-icon icon-class="empty" class-name="empty-img" />
  113. <p>暂无数据</p>
  114. </div>
  115. </div>
  116. </el-col>
  117. </el-row>
  118. </div>
  119. </div>
  120. </template>
  121. <script>
  122. import PanelGroup from './dashboard/PanelGroup'
  123. import lendAcross from '@/views/components/echarts/lendAcross.vue'
  124. // import catePie from '@/views/components/echarts/catePie.vue'
  125. import typePie from '@/views/components/echarts/typePie.vue'
  126. import bookSwiper from '@/views/components/bookSwiper.vue'
  127. import serverProgress from '@/views/components/echarts/serverProgress.vue'
  128. import { FetchInitHomeInfo } from '@/api/stockTask/index'
  129. import { FetchInitStockLogList } from '@/api/stockTaskLog/index'
  130. import { FetchSystemInfo } from '@/api/home/cpu/index'
  131. import { mapGetters } from 'vuex'
  132. export default {
  133. name: 'Dashboard',
  134. components: {
  135. PanelGroup,
  136. lendAcross,
  137. // catePie,
  138. bookSwiper,
  139. typePie,
  140. serverProgress
  141. },
  142. data() {
  143. return {
  144. topObjectNum: {
  145. regionCount: 0,
  146. shelfCount: 0,
  147. gridCount: 0,
  148. deviceCount: 0
  149. },
  150. archivesTotalNum: 0,
  151. flowableData: [],
  152. flowableTabIndex: 0,
  153. lendData: {
  154. archivesTotalNum: null,
  155. otherData: []
  156. },
  157. cateData: [],
  158. typeData: [],
  159. addArcivesData: {
  160. addArcivesMaxCount: null,
  161. addArcivesMonth: [],
  162. addArcivesNum: [],
  163. addArcivesNumFile: []
  164. },
  165. echartsTimer: null,
  166. refreshtime: 10000,
  167. systemTimer: null,
  168. systemData: {
  169. cpuPercentage: 0,
  170. memPercentage: 0,
  171. sysFilesPercentage: 0
  172. },
  173. stockLogCompletedData: [],
  174. stockLogIncompleteData: []
  175. }
  176. },
  177. computed: {
  178. ...mapGetters([
  179. 'user'
  180. ])
  181. },
  182. created() {
  183. this.handleMainData()
  184. this.getSystemInfo()
  185. this.getStockLog()
  186. },
  187. mounted() {
  188. // const _this = this
  189. // // 每隔一分钟刷新档案借阅和档案类型的数据
  190. // this.echartsTimer = setInterval(() => {
  191. // _this.lendData = {
  192. // archivesTotalNum: null,
  193. // otherData: []
  194. // }
  195. // _this.cateData = []
  196. // _this.typeData = []
  197. // _this.addArcivesData = {
  198. // addArcivesMaxCount: null,
  199. // addArcivesMonth: [],
  200. // addArcivesNum: [],
  201. // addArcivesNumFile: []
  202. // }
  203. // _this.handleMainData()
  204. // }, this.refreshtime)
  205. // 服务器监控定时更新
  206. // this.systemTimer = setInterval(() => {
  207. // _this.systemData = {
  208. // cpuPercentage: 0,
  209. // memPercentage: 0,
  210. // sysFilesPercentage: 0
  211. // }
  212. // this.getSystemInfo()
  213. // }, 3000)
  214. },
  215. methods: {
  216. getSystemInfo() {
  217. FetchSystemInfo().then(res => {
  218. // cpu 占有率 (总的cpuTotal-空闲的cpuFree)/总的cpuTotal
  219. this.systemData.cpuPercentage = Math.round((res.cpuTotal - res.cpuFree) / res.cpuTotal * 100)
  220. // 内存占比 使用的memUsed/总的memTotal
  221. this.systemData.memPercentage = Math.round(res.memUsed / res.memTotal * 100)
  222. // 磁盘占比 多个磁盘 使用总和sysFiles[i].used的和/总的总和sysFiles[i].total的和
  223. let sysFilesTotalUsed = 0
  224. let sysFilesTotal = 0
  225. res.sysFiles.forEach(item => {
  226. sysFilesTotalUsed += parseFloat(item.used)
  227. sysFilesTotal += parseFloat(item.total)
  228. })
  229. this.systemData.sysFilesPercentage = Math.round((sysFilesTotalUsed / sysFilesTotal) * 100)
  230. })
  231. },
  232. refreshSystemData() {
  233. this.systemData = {
  234. cpuPercentage: 0,
  235. memPercentage: 0,
  236. sysFilesPercentage: 0
  237. }
  238. this.getSystemInfo()
  239. },
  240. getStockLog() {
  241. FetchInitStockLogList().then(res => {
  242. this.stockLogCompletedData = res.content.filter(item => [0, 3].includes(item.state))
  243. this.stockLogIncompleteData = res.content.filter(item => [1, 2].includes(item.state))
  244. })
  245. },
  246. toMoreProcess() {
  247. this.$router.push({ path: '/user/center?activeIndex=2' })
  248. },
  249. handleMainData() {
  250. // const fondsAffiliation = []
  251. // fondsAffiliation.push(this.user.fonds.id.toString())
  252. // const params = {
  253. // fondsAffiliations: fondsAffiliation
  254. // }
  255. FetchInitHomeInfo().then(data => {
  256. this.topObjectNum = {
  257. regionCount: data.regionCount,
  258. shelfCount: data.shelfCount,
  259. gridCount: data.gridCount,
  260. deviceCount: data.deviceCount
  261. }
  262. // this.flowableData = data.flows
  263. // '标签', '装盒', '入库', '借阅', '开放', '实体', '审批'
  264. // "archivesTotalNum 总数 archivesTagNum 标签 installNum 已装盒 storageNum 入库 borrowNum 借阅 openNum 开放 entityNum 实体 approveNum 审批
  265. // 档案统计
  266. // this.lendData.archivesTotalNum = data.archivesTotalNum
  267. // this.lendData.otherData = [
  268. // data.archivesTagNum, data.installNum, data.storageNum, data.borrowNum, data.openNum, data.entityNum, data.approveNum
  269. // ]
  270. // // 档案类别
  271. // let maxCount = 0
  272. // data.statisNumJSON.archives.forEach(archive => {
  273. // if (archive.count > maxCount) {
  274. // maxCount = archive.count
  275. // }
  276. // })
  277. // data.statisNumJSON.singles.forEach(single => {
  278. // if (single.count > maxCount) {
  279. // maxCount = single.count
  280. // }
  281. // })
  282. // this.addArcivesData.addArcivesMaxCount = maxCount
  283. // const currentDate = new Date() // 获取当前日期
  284. // const currentYear = currentDate.getFullYear() // 获取当前年份
  285. // const currentMonth = currentDate.getMonth() // 获取当前月份(从 0 到 11,所以要加 1)
  286. // let startYear = currentYear - 1 // 去年的年份
  287. // let startMonth = currentMonth + 1 // 当前月份加上 1
  288. // const result = [] // 存储每个年份和月份的组合
  289. // const xResult = []
  290. // while (startYear < currentYear || startMonth <= currentMonth) {
  291. // xResult.push(startYear + '/' + startMonth)
  292. // result.push({ year: startYear, month: startMonth, archivesCount: 0, singlesCount: 0 })
  293. // // 计算下一个月份
  294. // startMonth += 1
  295. // if (startMonth > 12) {
  296. // startYear += 1
  297. // startMonth = 1
  298. // }
  299. // }
  300. // result.forEach(yearMonthObj => {
  301. // data.statisNumJSON.archives.forEach(archive => {
  302. // if (parseInt(archive.month) === yearMonthObj.month) {
  303. // yearMonthObj.archivesCount = archive.count
  304. // return
  305. // }
  306. // })
  307. // data.statisNumJSON.singles.forEach(single => {
  308. // if (parseInt(single.month) === yearMonthObj.month) {
  309. // yearMonthObj.singlesCount = single.count
  310. // return
  311. // }
  312. // })
  313. // })
  314. // this.addArcivesData.addArcivesMonth = xResult
  315. // this.addArcivesData.addArcivesNum = result.map(function(obj) {
  316. // return obj.archivesCount
  317. // })
  318. // this.addArcivesData.addArcivesNumFile = result.map(function(obj) {
  319. // return obj.singlesCount
  320. // })
  321. // // 档案类型
  322. // for (const type in data.typeGroupBy) {
  323. // if (data.typeGroupBy.hasOwnProperty(type)) {
  324. // this.typeData.push({ name: type, value: data.typeGroupBy[type] })
  325. // }
  326. // }
  327. })
  328. }
  329. }
  330. }
  331. </script>
  332. <style rel="stylesheet/scss" lang="scss" scoped>
  333. .dashboard-editor-container {
  334. padding: 20px;
  335. position: relative;
  336. .chart-wrapper {
  337. height: calc(100% - 55px);
  338. }
  339. }
  340. @media (max-width: 1024px) {
  341. .chart-wrapper {
  342. padding: 8px;
  343. }
  344. }
  345. .el-col {
  346. height: 100%;
  347. }
  348. .container-left,
  349. .container-right,
  350. .container-wrap,
  351. .el-card,
  352. .header-container-wrap {
  353. min-height: 100%;
  354. }
  355. .container-wrap {
  356. min-height: auto;
  357. height: 100%;
  358. }
  359. .home-item-title{
  360. position: relative;
  361. padding: 18px 0 18px 15px;
  362. font-size: 16px;
  363. color: #0C0E1E;
  364. &::before{
  365. position: absolute;
  366. left: 0;
  367. top: 50%;
  368. content: "";
  369. width: 3px;
  370. height: 16px;
  371. background-color: #0348F3;
  372. transform: translateY(-50%);
  373. }
  374. }
  375. .home-flowable{
  376. padding: 0 20px;
  377. }
  378. .home-tab{
  379. display: flex;
  380. justify-content: flex-start;
  381. span{
  382. display: block;
  383. margin-right: 30px;
  384. padding-bottom: 3px;
  385. border-bottom: 3px solid #fff;
  386. &.home-tab-active{
  387. color: #0348F3;
  388. // border-bottom: 3px solid #0348F3;
  389. }
  390. }
  391. }
  392. ::v-deep .home-flowable-list .el-table__body-wrapper::-webkit-scrollbar {
  393. width: 5px !important;
  394. height: 5px !important;
  395. background-color: #DDE8FB !important;
  396. }
  397. ::v-deep .home-flowable-list .el-table__body-wrapper::-webkit-scrollbar-thumb {
  398. border-radius: 3px;
  399. background-color: #4578F6 !important;
  400. }
  401. ::v-deep .home-flowable-list .el-table__body-wrapper::-webkit-scrollbar-thumb:hover {
  402. background-color: #4578F6 !important;
  403. }
  404. ::v-deep .home-flowable-list .el-table__body-wrapper::-webkit-scrollbar-corner {
  405. background-color: #DDE8FB !important;
  406. }
  407. .refresh-date{
  408. position: absolute;
  409. right: 14px;
  410. top: 10px;
  411. font-size: 12px;
  412. line-height: 30px;
  413. }
  414. </style>