index.tsx 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. import { getTokenInfo } from "@/utils/storage";
  2. import { useCallback, useEffect, useMemo, useRef, useState } from "react";
  3. import styles from "./index.module.scss";
  4. import dayjs from "dayjs";
  5. import { Button, message } from "antd";
  6. import classNames from "classnames";
  7. import * as echarts from "echarts/core";
  8. import { TooltipComponent, GridComponent } from "echarts/components";
  9. import { BarChart } from "echarts/charts";
  10. import { CanvasRenderer } from "echarts/renderers";
  11. import history from "@/utils/history";
  12. import { getStores2API1 } from "@/store/action/stores1";
  13. import { getHomeNumsAPI } from "@/store/action/login";
  14. import { useSelector } from "react-redux";
  15. import { RootState } from "@/store";
  16. echarts.use([TooltipComponent, GridComponent, BarChart, CanvasRenderer]);
  17. export default function Home() {
  18. // 顶部右侧数据
  19. const tabListTemp = useMemo(() => {
  20. return [
  21. { id: 1, done: false, path: "/object", name: "藏品登记" },
  22. { id: 2, done: false, path: "/object/2", name: "藏品总账" },
  23. { id: 3, done: false, path: "/object/3", name: "入库管理" },
  24. { id: 4, done: false, path: "/object/4", name: "出库管理" },
  25. { id: 5, done: false, path: "/object/6", name: "藏品注销" },
  26. ];
  27. }, []);
  28. // 右下方的数据
  29. const tempDone = useMemo(() => {
  30. return [
  31. { id: 1, done: false, path: "/object", num: 0, name: "藏品登记" },
  32. { id: 2, done: false, path: "/object/3", num: 0, name: "入库管理" },
  33. { id: 3, done: false, path: "/object/4", num: 0, name: "出库管理" },
  34. { id: 4, done: false, path: "/object/5", num: 0, name: "藏品修改" },
  35. { id: 5, done: false, path: "/object/6", num: 0, name: "藏品注销" },
  36. { id: 6, done: false, path: "/stores/3", num: 0, name: "藏品移库" },
  37. ];
  38. }, []);
  39. const [tabList, setTabList] = useState(tabListTemp);
  40. const powerInfo = useSelector(
  41. (state: RootState) => state.loginStore.authPageArr
  42. );
  43. useEffect(() => {
  44. powerInfo.forEach((v: any) => {
  45. if (v.id === 100) tabListTemp[0].done = tempDone[0].done = true;
  46. if (v.id === 200) tabListTemp[1].done = true;
  47. if (v.id === 300) tabListTemp[2].done = tempDone[1].done = true;
  48. if (v.id === 400) tabListTemp[3].done = tempDone[2].done = true;
  49. if (v.id === 500) tempDone[3].done = true;
  50. if (v.id === 600) tabListTemp[4].done = tempDone[4].done = true;
  51. if (v.id === 800) tempDone[5].done = true;
  52. });
  53. window.setTimeout(() => {
  54. setTabList(tabListTemp);
  55. }, 100);
  56. }, [powerInfo, tabListTemp, tempDone]);
  57. // 实时时间
  58. const [nowTime, setNowTime] = useState(
  59. dayjs(Date.now()).format("YYYY年MM月DD HH:mm")
  60. );
  61. // 点击头部右侧和下面右侧
  62. const toPageFu = useCallback((path: string, flag: boolean) => {
  63. if (flag) return message.warning("没有该模块权限!");
  64. history.push(path);
  65. }, []);
  66. const timeRef = useRef(-1);
  67. useEffect(() => {
  68. timeRef.current = window.setInterval(() => {
  69. setNowTime(() => {
  70. return dayjs(Date.now()).format("YYYY年MM月DD HH:mm");
  71. });
  72. }, 1000);
  73. return () => {
  74. clearInterval(timeRef.current);
  75. };
  76. }, []);
  77. const userInfo = useMemo(() => {
  78. return getTokenInfo().user;
  79. }, []);
  80. // -----------图表
  81. const echartsFu = useCallback(async () => {
  82. const res = await getStores2API1();
  83. let list = res.data;
  84. if (list && list.length && list.length > 7) {
  85. list = list.slice(0, 7);
  86. } else {
  87. const num = 7 - list.length;
  88. for (let i = 0; i < num; i++) {
  89. if (i % 2 !== 0) list.unshift({ groupKey: "", count: null });
  90. else list.push({ groupKey: "", count: null });
  91. }
  92. }
  93. const chartDom: any = document.querySelector(".chart");
  94. const myChart = echarts.init(chartDom);
  95. const option = {
  96. color: ["#9F1927"],
  97. tooltip: {
  98. trigger: "axis",
  99. axisPointer: {
  100. type: "shadow",
  101. },
  102. },
  103. grid: {
  104. left: "3%",
  105. right: "4%",
  106. bottom: "3%",
  107. containLabel: true,
  108. },
  109. xAxis: [
  110. {
  111. type: "category",
  112. data: list.map((v: any) => v.groupKey),
  113. axisTick: {
  114. show: false,
  115. alignWithLabel: false,
  116. },
  117. axisLabel: {
  118. interval: 0, //强制文字产生间隔
  119. textStyle: {
  120. color: "#000", //坐标值得具体的颜色
  121. fontSize: 12,
  122. },
  123. },
  124. axisLine: {
  125. //Y轴坐标轴
  126. show: true,
  127. // 坐标的颜色和宽度
  128. lineStyle: {
  129. width: 2,
  130. color: "#9F1927",
  131. },
  132. },
  133. },
  134. ],
  135. yAxis: [
  136. {
  137. type: "value",
  138. axisLabel: {
  139. textStyle: {
  140. color: "#000", //坐标值得具体的颜色
  141. },
  142. },
  143. axisLine: {
  144. //Y轴坐标轴
  145. show: true,
  146. lineStyle: {
  147. width: 2,
  148. color: "#9F1927",
  149. },
  150. },
  151. // 隐藏背景坐标线段
  152. splitLine: {
  153. show: false,
  154. },
  155. },
  156. ],
  157. series: [
  158. {
  159. name: "",
  160. type: "bar",
  161. barMaxwidth: "50%",
  162. data: list.map((v: any) => v.count),
  163. itemStyle: {
  164. normal: {
  165. color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
  166. { offset: 0, color: "rgba(159, 25, 39, .5)" }, //渐变头部色
  167. { offset: 1, color: "rgba(159, 25, 39, 1)" },
  168. ]),
  169. barBorderRadius: 2,
  170. label: {
  171. show: true, //开启显示
  172. position: "top", //在上方显示
  173. textStyle: {
  174. //数值样式
  175. color: "#9F1927",
  176. fontSize: 16,
  177. },
  178. },
  179. },
  180. },
  181. },
  182. ],
  183. };
  184. option && myChart.setOption(option);
  185. }, []);
  186. // 代办提醒
  187. const [doneList, setDoneList] = useState(tempDone);
  188. const doneNumsAPIFu = useCallback(async () => {
  189. const res = await getHomeNumsAPI();
  190. const data = [...tempDone];
  191. res.data.forEach((v: any) => {
  192. if (v.groupKey === "register") data[0].num = v.count;
  193. else if (v.groupKey === "in") data[1].num = v.count;
  194. else if (v.groupKey === "out") data[2].num = v.count;
  195. else if (v.groupKey === "edit") data[3].num = v.count;
  196. else if (v.groupKey === "cancel") data[4].num = v.count;
  197. else if (v.groupKey === "move") data[5].num = v.count;
  198. });
  199. setDoneList(data);
  200. }, [tempDone]);
  201. useEffect(() => {
  202. echartsFu();
  203. doneNumsAPIFu();
  204. }, [doneNumsAPIFu, echartsFu]);
  205. return (
  206. <div className={styles.Home}>
  207. <div className="homeMain">
  208. {/* 顶部页面 */}
  209. <div className="title">
  210. <div className="titleL">
  211. <h3>
  212. 欢迎 {userInfo.realName} 进入
  213. <br />
  214. <br />
  215. 乐山大佛博物馆馆藏管理系统!
  216. </h3>
  217. <p>{nowTime}</p>
  218. </div>
  219. <div className="titleR">
  220. {tabList.map((v, i) => (
  221. <div
  222. onClick={() => toPageFu(v.path, !v.done)}
  223. className={classNames("row", !v.done ? "noAuth" : "")}
  224. key={v.id}
  225. >
  226. <div className={`bac${v.id}`}></div>
  227. <p>{v.name}</p>
  228. </div>
  229. ))}
  230. </div>
  231. </div>
  232. {/* 下面数据 */}
  233. <div className="flooBox">
  234. <div className="flooBoxL">
  235. <div className="flooTit">
  236. <div>藏馆统计</div>
  237. <Button onClick={() => history.push("/stores/2")}>
  238. 查看更多
  239. </Button>
  240. </div>
  241. {/* 图表 */}
  242. <div className="chartBox">
  243. <div className="chartTit">(件)</div>
  244. <div className="chart"></div>
  245. </div>
  246. </div>
  247. <div className="flooBoxR">
  248. <div className="flooTit">
  249. <div>审核提醒</div>
  250. </div>
  251. <div className="doneBox">
  252. {doneList.map((v, i) => (
  253. <div
  254. onClick={() => toPageFu(v.path, !v.done)}
  255. className={classNames(
  256. "doneRow",
  257. i >= 4 ? "noneRow" : "",
  258. !v.done ? "noAuth" : ""
  259. )}
  260. key={v.id}
  261. >
  262. <div className="doneRow_tit">{v.name}</div>
  263. <div className="doneRow_txt">
  264. 共有&emsp;<span>{v.num}</span>&emsp;待审核事项
  265. </div>
  266. </div>
  267. ))}
  268. </div>
  269. </div>
  270. </div>
  271. </div>
  272. </div>
  273. );
  274. }