Index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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" style="height: 390px;">
  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="320" />
  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 " style="height: 390px;">
  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="320" />
  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 " style="height: 390px;">
  148. <div class="title"><img src="/@/assets/imgs/tj3.png" alt="" /><span>按标本类型统计</span></div>
  149. <Echart :options="pieOptionsData" :height="320" />
  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. const monthNum = new Date().getMonth()
  188. console.log('monthNum', monthNum);
  189. const enterSpecimen = ref();
  190. const outSpecimen = ref();
  191. const returnSpecimen = ref();
  192. const year = new Date().getFullYear()
  193. //本月出、入、回库数
  194. enterSpecimen.value = await WorkbenchApi.getEnterSpecimenList(year);
  195. outSpecimen.value = await WorkbenchApi.getOutSpecimenList(year);
  196. returnSpecimen.value = await WorkbenchApi.getReturnSpecimenList(year);
  197. const enter = enterSpecimen.value.data
  198. const out = outSpecimen.value.data
  199. const return1 = returnSpecimen.value.data
  200. enterNumber.value = enter[monthNum].number;
  201. outNumber.value = out[monthNum].number;
  202. returnNumber.value = return1[monthNum].number;
  203. enterNumber1.value = enter[monthNum-1].number;
  204. outNumber1.value = out[monthNum-1].number;
  205. // TODO 这里
  206. console.log('return1',return1)
  207. returnNumber1.value = return1[monthNum-1].number;
  208. enterRatio.value = (enterNumber.value - enterNumber1.value) / enterNumber.value * 100;
  209. outRatio.value = (outNumber.value - outNumber1.value) / outNumber.value * 100;
  210. returnRatio.value = (returnNumber.value - returnNumber1.value) / returnNumber.value * 100;
  211. })
  212. const loading = ref(true)
  213. // 获取统计数
  214. let totalSate = reactive<WorkplaceTotal>({
  215. project: 0,
  216. access: 0,
  217. todo: 0
  218. })
  219. const getCount = async () => {
  220. const data = {
  221. project: 40,
  222. access: 2340,
  223. todo: 10
  224. }
  225. totalSate = Object.assign(totalSate, data)
  226. }
  227. const getAllApi = async () => {
  228. await Promise.all([
  229. getCount(),
  230. ])
  231. loading.value = false
  232. }
  233. //历年标本数量统计
  234. const yearOptionsData = reactive<EChartsOption>(yearOptions) as EChartsOption
  235. //本月入库数
  236. const enterRatioOptionsData = reactive<EChartsOption>(enterRatioOptions) as EChartsOption
  237. //本月出库数
  238. const outRatioOptionsData = reactive<EChartsOption>(outRatioOptions) as EChartsOption
  239. //本月回库数
  240. const returnRatioOptionsData = reactive<EChartsOption>(returnRatioOptions) as EChartsOption
  241. //历年标本来源增减统计
  242. const originOptionsData = reactive<EChartsOption>(originOptions) as EChartsOption
  243. //本年标本数量统计
  244. const mouthOptionsData = reactive<EChartsOption>(mouthOptions) as EChartsOption
  245. //按标本类型统计
  246. const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
  247. getAllApi()
  248. </script>
  249. <style scoped>
  250. .bg {
  251. background-image: url("../asset/imgs/bg.jpg");
  252. background-repeat: no-repeat;
  253. background-attachment: fixed;
  254. background-size: cover;
  255. /* background-color: #f8f3e0; */
  256. }
  257. .el-card {
  258. --el-card-border-color: #fff !important;
  259. margin: 0 10px 20px 10px;
  260. --el-card-border-radius: .625rem;
  261. }
  262. .title {
  263. font-size: 22px;
  264. font-weight: bold;
  265. margin-bottom: 10px;
  266. display: flex;
  267. align-items: center;
  268. }
  269. .title img {
  270. width: 30px;
  271. height: 30px;
  272. }
  273. .title span {
  274. margin-left: 10px;
  275. }
  276. .specimen-month {
  277. display: flex;
  278. justify-content: space-between;
  279. align-items: center;
  280. margin: 0 5%;
  281. }
  282. .month {
  283. width: 40%;
  284. /* padding: 0 10px; */
  285. }
  286. .month1 {
  287. width: 60%;
  288. padding: 0 10px;
  289. }
  290. .month-bottom div:nth-child(1) {
  291. font-size: 40px;
  292. font-weight: bold;
  293. }
  294. .month-bottom span {
  295. font-size: 20px;
  296. font-weight: bold;
  297. color: #f7cb6b;
  298. /* color: #e7a13f; */
  299. }
  300. .introduce {
  301. display: flex;
  302. margin: 0 10px 20px 10px;
  303. justify-content: space-between;
  304. }
  305. .introduce-num {
  306. width: 19%;
  307. padding: 20px 0;
  308. display: flex;
  309. align-items: center;
  310. /* background-color: antiquewhite; */
  311. /* background-color: #fdf5e1; */
  312. background-color: #f9f2ec;
  313. justify-content: space-around;
  314. border-radius: .625rem;
  315. border: 3px solid #fff;
  316. /* background-image:url("/@/assets/imgs/introduce.jpg"); */
  317. }
  318. .introduce-img img {
  319. width: 80px;
  320. height: 80px;
  321. /* margin-top: 10%; */
  322. }
  323. .introduce-text div:nth-child(1) {
  324. font-size: 1.4rem;
  325. }
  326. .introduce-text div:nth-child(2) {
  327. font-size: 2.8rem;
  328. color: rgba(143, 53, 36, 0.7);
  329. /* color: #deb887; */
  330. font-weight: bold;
  331. }
  332. @media (min-width: 100px) {
  333. .introduce {
  334. flex-direction: column;
  335. }
  336. .introduce-num {
  337. width: 100%;
  338. margin-bottom: 20px;
  339. }
  340. }
  341. @media (min-width: 400px) {
  342. .introduce {
  343. flex-direction: column;
  344. }
  345. .introduce-num {
  346. width: 100%;
  347. margin-bottom: 20px;
  348. }
  349. }
  350. @media (min-width: 800px) {
  351. .introduce {
  352. flex-direction: column;
  353. }
  354. .introduce-num {
  355. width: 100%;
  356. }
  357. .introduce-num:nth-child(5) {
  358. width: 100%;
  359. margin-bottom: 0px;
  360. }
  361. }
  362. @media (min-width:1000px) {
  363. .introduce {
  364. flex-direction: row;
  365. }
  366. .introduce-num {
  367. width: 19%;
  368. margin-bottom: 0px;
  369. }
  370. .introduce-num:nth-child(5) {
  371. width: 19%;
  372. margin-bottom: 0px;
  373. }
  374. }
  375. @media (min-width:2560px) {
  376. .introduce {
  377. flex-direction: row;
  378. }
  379. .introduce-num {
  380. width: 19%;
  381. margin-bottom: 0px;
  382. }
  383. .introduce-num:nth-child(5) {
  384. width: 19%;
  385. margin-bottom: 0px;
  386. }
  387. }
  388. </style>