diff --git a/src/index.css b/src/index.css
index ec2585e..ed3149b 100644
--- a/src/index.css
+++ b/src/index.css
@@ -1,13 +1,19 @@
body {
margin: 0;
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
- 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
- sans-serif;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans',
+ 'Droid Sans', 'Helvetica Neue', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
- font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
- monospace;
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
+}
+section {
+ display: block;
+}
+
+main section {
+ margin-top: 1em;
+ margin-bottom: 1em;
}
diff --git a/src/mock/1/1.json b/src/mock/2.0/1.json
similarity index 100%
rename from src/mock/1/1.json
rename to src/mock/2.0/1.json
diff --git a/src/mock/2.0/trade.json b/src/mock/2.0/trade.json
new file mode 100644
index 0000000..1007b49
--- /dev/null
+++ b/src/mock/2.0/trade.json
@@ -0,0 +1,46 @@
+{
+ "get|/service-web/QueryData/GetTradeSummary": {
+ "errcode": 0,
+ "errmsg": "",
+ "data": null,
+ "loading": false,
+ "result1": {
+ "SumML|999-9999": 27018,
+ "SumMLrate|-20-100": 23,
+ "SumMLKPIrate|20-100": 23,
+ "SumOrder|999-999": 27018,
+ "SumOrderrate": "@float(-20,20,2,2)",
+ "SumOrderKPIrate|20-100": 25,
+ "SumPersonNum|999-999": 27018,
+ "SumPersonNumrate|-50-1": 33,
+ "SumPersonNumKPIrate|20-100": 33,
+ "groups": "2023-05-01~2023-05-31",
+ "key": "@increment"
+ },
+ "result2": {
+ "SumML|999-9999": 27018,
+ "SumOrder|999-999": 27018,
+ "SumPersonNum|999-999": 27018,
+ "groups": "2022-05-01~2023-05-31",
+ "key": "@increment"
+ }
+ },
+ "get|/service-web/QueryData/GetYJ": {
+ "errcode": 0,
+ "errmsg": "",
+ "data": null,
+ "loading": false,
+ "result1|10": [
+ {
+ "AvgML|999-9999": 27018,
+ "COLI_Department": "1,2,28,7",
+ "OPI_SN": "@id",
+ "OPI_Name": "@cname",
+ "COLI_YJLY|999-99999": 215493,
+ "groups": "2023-05-01~2023-05-31",
+ "key": "@increment"
+ }
+ ],
+ "result2": []
+ }
+}
diff --git a/src/mock/index.js b/src/mock/index.js
index fa94fe3..de3855d 100644
--- a/src/mock/index.js
+++ b/src/mock/index.js
@@ -10,21 +10,21 @@ const configArray = files.keys().reduce((s, c) => s.concat(files(c)), []);
// 注册所有的mock服务
configArray.forEach((item) => {
- for (const [path, target] of Object.entries(item)) {
- const protocol = path.split('|');
- // const apiUrl = new RegExp(`${protocol[1]}.*`);
- // fetch 不支持mock
- // Mock.mock(apiUrl, protocol[0].toLocaleLowerCase(), target);
+ for (const [path, target] of Object.entries(item)) {
+ const protocol = path.split('|');
+ // const apiUrl = new RegExp(`${protocol[1]}.*`);
+ // fetch 不支持mock
+ // Mock.mock(apiUrl, protocol[0].toLocaleLowerCase(), target);
- // fetchMock.mock(matcher, response, options)
- fetchMock.mock(
- `path:${protocol[1]}`,
- () => {
- const res = Mock.mock(target);
- console.log(`invoke mock`, protocol[1], res);
- return res;
- },
- { method: protocol[0] }
- );
- }
+ // fetchMock.mock(matcher, response, options)
+ fetchMock.mock(
+ `path:${protocol[1]}`,
+ () => {
+ const res = Mock.mock(target);
+ console.log(`invoke mock`, protocol[1], res);
+ return res;
+ },
+ { method: protocol[0], delay: 1000 }
+ );
+ }
});
diff --git a/src/stores/Index.js b/src/stores/Index.js
index becfcde..d7948a2 100644
--- a/src/stores/Index.js
+++ b/src/stores/Index.js
@@ -10,6 +10,7 @@ import SaleStore from "./SaleStore";
import WechatStore from "./Wechat";
import WhatsAppStore from "./WhatsApp";
import CustomerServicesStore from "./CustomerServices";
+import TradeStore from "./Trade";
class Index {
constructor() {
@@ -24,9 +25,10 @@ class Index {
this.wechatStore = new WechatStore(this);
this.whatsAppStore = new WhatsAppStore(this);
this.customerServicesStore = new CustomerServicesStore(this);
+ this.TradeStore = new TradeStore(this);
makeAutoObservable(this);
}
}
-export default Index;
\ No newline at end of file
+export default Index;
diff --git a/src/stores/Trade.js b/src/stores/Trade.js
new file mode 100644
index 0000000..68f3006
--- /dev/null
+++ b/src/stores/Trade.js
@@ -0,0 +1,44 @@
+import { makeAutoObservable, runInAction } from 'mobx';
+import * as req from '../utils/request';
+import { isEmpty } from '../utils/commons';
+
+/**
+ * 计算变化值
+ */
+const calcRate = (r1, r2) => {
+ // 的
+};
+
+class Trade {
+ constructor(rootStore) {
+ this.rootStore = rootStore;
+ makeAutoObservable(this);
+ }
+
+ fetchSummaryData() {
+ this.summaryData.loading = true;
+ req.fetchJSON('/service-web/QueryData/GetTradeSummary').then((json) => {
+ if (json.errcode === 0) {
+ runInAction(() => {
+ this.summaryData = { loading: false, ...json };
+ });
+ }
+ });
+ }
+
+ fetchTradeData() {
+ this.yearlyData.loading = true;
+ req.fetchJSON('/service-web/QueryData/GetYJ').then((json) => {
+ if (json.errcode === 0) {
+ runInAction(() => {
+ this.yearlyData = { loading: false, ...json };
+ });
+ }
+ });
+ }
+
+ summaryData = { loading: false };
+ yearlyData = { loading: false };
+}
+
+export default Trade;
diff --git a/src/utils/commons.js b/src/utils/commons.js
index 952920f..14c35c5 100644
--- a/src/utils/commons.js
+++ b/src/utils/commons.js
@@ -150,10 +150,22 @@ export function isNotEmpty(val) {
return val !== undefined && val !== null && val !== "";
}
+/**
+ * ! 不支持计算 Set 或 Map
+ * @param {*} val
+ * @example
+ * true if: 0, [], {}, null, '', undefined
+ * false if: 'false', 'undefined'
+ */
export function isEmpty(val) {
- return val === undefined || val === null || val === "";
+ // return val === undefined || val === null || val === "";
+ return [Object, Array].includes((val || {}).constructor) && !Object.entries((val || {})).length;
}
+/**
+ * @example
+ * empty(0) => false
+ */
export function empty(a) {
if (a === "") return true; // 检验空字符串
if (a === "null") return true; // 检验字符串类型的null
@@ -162,7 +174,6 @@ export function empty(a) {
if (Array.prototype.isPrototypeOf(a) && a.length === 0) return true; // 检验空数组
if (Object.prototype.isPrototypeOf(a) && Object.keys(a).length === 0) return true; // 检验空对象
return false;
- // return [Object, Array].includes((obj || {}).constructor) && !Object.entries((obj || {})).length;
}
export function prepareUrl(url) {
diff --git a/src/views/Home.jsx b/src/views/Home.jsx
index bcd4ee2..635e274 100644
--- a/src/views/Home.jsx
+++ b/src/views/Home.jsx
@@ -1,31 +1,77 @@
-import React, {Component, useContext} from 'react';
-import {observer} from 'mobx-react';
-import {Row, Col, Button, Tabs, Table} from 'antd';
-import {stores_Context} from '../config';
-import {useNavigate} from "react-router-dom";
-import {
- SlackOutlined,
- SketchOutlined,
- AntCloudOutlined,
- RedditOutlined,
- GithubOutlined
-} from '@ant-design/icons';
+import { useContext, useEffect } from 'react';
+import { observer } from 'mobx-react';
+import { Row, Col, Spin, Card, Statistic, Progress } from 'antd';
+import { stores_Context } from '../config';
+import { useNavigate } from 'react-router-dom';
+import { SlackOutlined, SketchOutlined, AntCloudOutlined, RedditOutlined, GithubOutlined, ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';
+import { isEmpty } from './../utils/commons';
+import './home.css';
const Home = () => {
+ const navigate = useNavigate();
+ const { TradeStore } = useContext(stores_Context);
+ const { yearlyData, summaryData } = TradeStore;
- const navigate = useNavigate();
- const {auth_store} = useContext(stores_Context);
+ useEffect(() => {
+ if (isEmpty(summaryData?.result1)) {
+ TradeStore.fetchSummaryData();
+ }
+ if (isEmpty(yearlyData?.result1)) {
+ TradeStore.fetchTradeData();
+ }
+ return () => {};
+ }, []);
+ const StatisticCard = (props) => {
+ const valueStyle = { color: props.VSrate < 0 ? '#cf1322' : '#3f8600' };
+ const VSIcon = () => (props.VSrate < 0 ?