Index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. <template>
  2. <div class="bg">
  3. <el-skeleton :loading="loading" animated>
  4. <el-row :gutter="20">
  5. <el-col>
  6. <div class="introduce">
  7. <div class="introduce-num" shadow="hover">
  8. <div class="introduce-img">
  9. <img src="/@/assets/imgs/zs2.png" alt="" />
  10. </div>
  11. <div class="introduce-text">
  12. <div>标本总数</div>
  13. <div class="multiple-text-shadow">{{ totalSamples }}</div>
  14. </div>
  15. </div>
  16. <div class="introduce-num">
  17. <div class="introduce-img">
  18. <img src="/@/assets/imgs/kw5.png" alt="" />
  19. </div>
  20. <div class="introduce-text">
  21. <div>矿物</div>
  22. <div>{{ mineralCount }}</div>
  23. </div>
  24. </div>
  25. <div class="introduce-num">
  26. <div class="introduce-img">
  27. <img src="/@/assets/imgs/kw4.png" alt="" />
  28. </div>
  29. <div class="introduce-text">
  30. <div>岩石矿石</div>
  31. <div>{{ rockOreCount }}</div>
  32. </div>
  33. </div>
  34. <div class="introduce-num">
  35. <div class="introduce-img">
  36. <img style="width: 90px;height: 90px;" src="/@/assets/imgs/hs4.png" alt="" />
  37. </div>
  38. <div class="introduce-text">
  39. <div>化石</div>
  40. <div>{{ fossilCount }}</div>
  41. </div>
  42. </div>
  43. <div class="introduce-num">
  44. <div class="introduce-img">
  45. <img style="width: 90px;height: 100px;" src="/@/assets/imgs/ys5.png" alt="" />
  46. </div>
  47. <div class="introduce-text">
  48. <div>陨石</div>
  49. <div>{{ meteoriteCount }}</div>
  50. </div>
  51. </div>
  52. </div>
  53. </el-col>
  54. </el-row>
  55. </el-skeleton>
  56. <!-- 本年标本出入回库情况new -->
  57. <el-skeleton :loading="loading" animated>
  58. <el-row>
  59. <!-- 本年标本出库 -->
  60. <el-col :xl="5" :lg="5" :md="12" :sm="24" :xs="24">
  61. <el-card shadow="hover" class="mr-5px mt-5px" style="height: 300px;">
  62. <div class="title"><img style="width: 25px;height: 25px;" src="/@/assets/imgs/ck5.png"
  63. alt="" /><span>本月出库数</span></div>
  64. <div class="specimen-month">
  65. <div class="month">
  66. <div class="month-bottom">
  67. <div>{{ outNumber }}</div>
  68. <div>月环比&nbsp;<span>{{ outRatio.toFixed(0) }}%</span></div>
  69. </div>
  70. </div>
  71. <div class="month1">
  72. <Echart :options="outRatioOptionsData" :height="200" :width="'140%'" />
  73. </div>
  74. </div>
  75. </el-card>
  76. </el-col>
  77. <!-- 本年标本入库 -->
  78. <el-col :xl="5" :lg="5" :md="12" :sm="24" :xs="24">
  79. <el-card shadow="hover" class="mr-5px mt-5px" style="height: 300px;">
  80. <div class="title"><img style="width: 30px;height: 30px;" src="/@/assets/imgs/rk3.png"
  81. alt="" /><span>本月入库数</span></div>
  82. <div class="specimen-month">
  83. <div class="month">
  84. <div class="month-bottom">
  85. <div>{{ enterNumber }}</div>
  86. <div>月环比&nbsp;<span>{{ enterRatio.toFixed(0) }}%</span></div>
  87. </div>
  88. </div>
  89. <div class="month1">
  90. <Echart :options="enterRatioOptionsData" :height="200" :width="'140%'" />
  91. </div>
  92. </div>
  93. </el-card>
  94. </el-col>
  95. <!-- 本年标本回库 -->
  96. <el-col :xl="5" :lg="5" :md="12" :sm="24" :xs="24">
  97. <el-card shadow="hover" class="mr-5px mt-5px" style="height: 300px;">
  98. <div class="title"><img style="width: 25px;height: 25px;" src="/@/assets/imgs/hk2.png"
  99. alt="" /><span>本月回库数</span></div>
  100. <div class="specimen-month">
  101. <div class="month">
  102. <div class="month-bottom">
  103. <div>{{ returnNumber }}</div>
  104. <div>月环比&nbsp;<span>{{ returnRatio.toFixed(0) }}%</span></div>
  105. </div>
  106. </div>
  107. <div class="month1">
  108. <Echart :options="returnRatioOptionsData" :height="200" :width="'140%'" />
  109. </div>
  110. </div>
  111. </el-card>
  112. </el-col>
  113. <el-col :xl="9" :lg="9" :md="12" :sm="24" :xs="24">
  114. <el-card shadow="hover" class="mr-5px mt-5px" style="height: 300px;">
  115. <div class="title"><img src="/@/assets/imgs/tj3.png" alt="" /><span>本年标本数量统计</span></div>
  116. <el-skeleton :loading="loading" animated>
  117. <Echart :options="mouthOptionsData" :height="230" />
  118. </el-skeleton>
  119. </el-card>
  120. <!-- 历年标本来源增减统计 -->
  121. </el-col>
  122. </el-row>
  123. </el-skeleton>
  124. <!-- 本年标本出入回库情况2 -->
  125. <el-skeleton :loading="loading" animated>
  126. <el-row>
  127. <el-col :xl="9" :lg="9" :md="12" :sm="24" :xs="24">
  128. <el-card shadow="hover" class="mr-5px mt-5px" style="height: 410px;">
  129. <div class="title"><img src="/@/assets/imgs/tj3.png" alt="" /><span>历年标本数量统计</span></div>
  130. <el-skeleton :loading="loading" animated>
  131. <Echart :options="yearOptionsData" :height="340" />
  132. </el-skeleton>
  133. </el-card>
  134. <!-- 历年标本来源增减统计 -->
  135. </el-col>
  136. <el-col :xl="9" :lg="9" :md="12" :sm="24" :xs="24">
  137. <el-card shadow="hover" class="mr-5px mt-5px" style="height: 410px;">
  138. <div class="title"><img src="/@/assets/imgs/tj3.png" alt="" /><span>历年标本来源增减统计</span></div>
  139. <el-skeleton :loading="loading" animated>
  140. <Echart :options="originOptionsData" :height="340" />
  141. </el-skeleton>
  142. </el-card>
  143. <!-- 历年标本来源增减统计 -->
  144. </el-col>
  145. <!-- 本年标本回库 -->
  146. <el-col :xl="6" :lg="6" :md="24" :sm="24" :xs="24">
  147. <el-card shadow="hover" class="mr-5px mt-5px" style="height: 410px;">
  148. <div class="title"><img src="/@/assets/imgs/tj3.png" alt="" /><span>按标本类型统计</span></div>
  149. <Echart :options="pieOptionsData" :height="340" />
  150. </el-card>
  151. </el-col>
  152. </el-row>
  153. </el-skeleton>
  154. </div>
  155. </template>
  156. <script lang="ts" setup>
  157. import { EChartsOption } from 'echarts'
  158. import type { WorkplaceTotal } from './types'
  159. import { pieOptions, yearOptions, enterRatioOptions, originOptions, mouthOptions, outRatioOptions, returnRatioOptions } from './echarts-data'
  160. defineOptions({ name: 'Home' })
  161. //获取标本类型数
  162. import * as WorkbenchApi from '@/api/workbench'
  163. // const workbenchList = ref([] as WorkbenchApi.WorkbenchVO[]) //标本列表
  164. const totalSamples = ref(0);
  165. const mineralCount = ref(0);
  166. const fossilCount = ref(0);
  167. const meteoriteCount = ref(0);
  168. const rockOreCount = ref(0);
  169. const enterNumber = ref(0);
  170. const outNumber = ref(0);
  171. const returnNumber = ref(0);
  172. const enterNumber1 = ref(0);
  173. const outNumber1 = ref(0);
  174. const returnNumber1 = ref(0);
  175. const enterRatio = ref(0);
  176. const outRatio = ref(0);
  177. const returnRatio = ref(0);
  178. //初始化
  179. onMounted(async () => {
  180. const { samples } = await WorkbenchApi.getSpecimenTypeList();
  181. totalSamples.value = samples['标本总数'];
  182. mineralCount.value = samples['矿物'];
  183. fossilCount.value = samples['化石'];
  184. meteoriteCount.value = samples['陨石'];
  185. rockOreCount.value = samples['岩石矿石'];
  186. const month = `${new Date().getMonth() + 1}月`
  187. console.log('month', month);
  188. const enterSpecimen = ref();
  189. const outSpecimen = ref();
  190. const returnSpecimen = ref();
  191. const year = new Date().getFullYear()
  192. //本月出、入、回库数
  193. enterSpecimen.value = await WorkbenchApi.getEnterSpecimenList(year);
  194. outSpecimen.value = await WorkbenchApi.getOutSpecimenList(year);
  195. returnSpecimen.value = await WorkbenchApi.getReturnSpecimenList(year);
  196. const enter = enterSpecimen.value.data
  197. const out = outSpecimen.value.data
  198. const return1 = returnSpecimen.value.data
  199. enterNumber.value = enter[enter.length - 1].number;
  200. outNumber.value = out[out.length - 1].number;
  201. returnNumber.value = return1[return1.length - 1].number;
  202. enterNumber1.value = enter[enter.length - 2].number;
  203. outNumber1.value = out[out.length - 2].number;
  204. // TODO 这里
  205. console.log(return1)
  206. returnNumber1.value = return1[return1.length - 2].number;
  207. enterRatio.value = (enterNumber.value - enterNumber1.value) / enterNumber.value * 100;
  208. outRatio.value = (outNumber.value - outNumber1.value) / outNumber.value * 100;
  209. returnRatio.value = (returnNumber.value - returnNumber1.value) / returnNumber.value * 100;
  210. })
  211. const loading = ref(true)
  212. // 获取统计数
  213. let totalSate = reactive<WorkplaceTotal>({
  214. project: 0,
  215. access: 0,
  216. todo: 0
  217. })
  218. const getCount = async () => {
  219. const data = {
  220. project: 40,
  221. access: 2340,
  222. todo: 10
  223. }
  224. totalSate = Object.assign(totalSate, data)
  225. }
  226. const getAllApi = async () => {
  227. await Promise.all([
  228. getCount(),
  229. ])
  230. loading.value = false
  231. }
  232. //历年标本数量统计
  233. const yearOptionsData = reactive<EChartsOption>(yearOptions) as EChartsOption
  234. //本月入库数
  235. const enterRatioOptionsData = reactive<EChartsOption>(enterRatioOptions) as EChartsOption
  236. //本月出库数
  237. const outRatioOptionsData = reactive<EChartsOption>(outRatioOptions) as EChartsOption
  238. //本月回库数
  239. const returnRatioOptionsData = reactive<EChartsOption>(returnRatioOptions) as EChartsOption
  240. //历年标本来源增减统计
  241. const originOptionsData = reactive<EChartsOption>(originOptions) as EChartsOption
  242. //本年标本数量统计
  243. const mouthOptionsData = reactive<EChartsOption>(mouthOptions) as EChartsOption
  244. //按标本类型统计
  245. const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
  246. getAllApi()
  247. </script>
  248. <style scoped>
  249. .bg {
  250. background-image: url("/@/asset/imgs/bg.jpg");
  251. background-repeat: no-repeat;
  252. background-attachment: fixed;
  253. background-size: cover;
  254. /* background-color: #f8f3e0; */
  255. }
  256. .el-card {
  257. --el-card-border-color: #fff !important;
  258. margin: 0 10px 20px 10px;
  259. --el-card-border-radius: .625rem;
  260. }
  261. .title {
  262. font-size: 22px;
  263. font-weight: bold;
  264. margin-bottom: 10px;
  265. display: flex;
  266. align-items: center;
  267. }
  268. .title img {
  269. width: 30px;
  270. height: 30px;
  271. }
  272. .title span {
  273. margin-left: 10px;
  274. }
  275. .specimen-month {
  276. display: flex;
  277. justify-content: space-between;
  278. align-items: center;
  279. margin: 0 5%;
  280. }
  281. .month {
  282. width: 40%;
  283. /* padding: 0 10px; */
  284. }
  285. .month1 {
  286. width: 60%;
  287. padding: 0 10px;
  288. }
  289. .month-bottom div:nth-child(1) {
  290. font-size: 40px;
  291. font-weight: bold;
  292. }
  293. .month-bottom span {
  294. font-size: 20px;
  295. font-weight: bold;
  296. color: #f7cb6b;
  297. /* color: #e7a13f; */
  298. }
  299. .introduce {
  300. display: flex;
  301. margin: 0 10px 20px 10px;
  302. justify-content: space-between;
  303. }
  304. .introduce-num {
  305. width: 19%;
  306. padding: 20px 0;
  307. display: flex;
  308. align-items: center;
  309. /* background-color: antiquewhite; */
  310. /* background-color: #fdf5e1; */
  311. background-color: #f9f2ec;
  312. justify-content: space-around;
  313. border-radius: .625rem;
  314. border: 3px solid #fff;
  315. /* background-image:url("/@/assets/imgs/introduce.jpg"); */
  316. }
  317. .introduce-img img {
  318. width: 80px;
  319. height: 80px;
  320. /* margin-top: 10%; */
  321. }
  322. .introduce-text div:nth-child(1) {
  323. font-size: 1.4rem;
  324. }
  325. .introduce-text div:nth-child(2) {
  326. font-size: 2.8rem;
  327. color: rgba(143, 53, 36, 0.7);
  328. /* color: #deb887; */
  329. font-weight: bold;
  330. }
  331. @media (min-width: 100px) {
  332. .introduce {
  333. flex-direction: column;
  334. }
  335. .introduce-num {
  336. width: 100%;
  337. margin-bottom: 20px;
  338. }
  339. }
  340. @media (min-width: 400px) {
  341. .introduce {
  342. flex-direction: column;
  343. }
  344. .introduce-num {
  345. width: 100%;
  346. margin-bottom: 20px;
  347. }
  348. }
  349. @media (min-width: 800px) {
  350. .introduce {
  351. flex-direction: column;
  352. }
  353. .introduce-num {
  354. width: 100%;
  355. }
  356. .introduce-num:nth-child(5) {
  357. width: 100%;
  358. margin-bottom: 0px;
  359. }
  360. }
  361. @media (min-width:1000px) {
  362. .introduce {
  363. flex-direction: row;
  364. }
  365. .introduce-num {
  366. width: 19%;
  367. margin-bottom: 0px;
  368. }
  369. .introduce-num:nth-child(5) {
  370. width: 19%;
  371. margin-bottom: 0px;
  372. }
  373. }
  374. @media (min-width:2560px) {
  375. .introduce {
  376. flex-direction: row;
  377. }
  378. .introduce-num {
  379. width: 19%;
  380. margin-bottom: 0px;
  381. }
  382. .introduce-num:nth-child(5) {
  383. width: 19%;
  384. margin-bottom: 0px;
  385. }
  386. }
  387. </style>