Merge branch 'feature/pivot'

feature/pivot
Lei OT 2 years ago
commit 6a7c0a2064

361
package-lock.json generated

@ -12,10 +12,14 @@
"@ant-design/pro-components": "^2.6.16", "@ant-design/pro-components": "^2.6.16",
"antd": "^4.22.6", "antd": "^4.22.6",
"dingtalk-jsapi": "^3.0.9", "dingtalk-jsapi": "^3.0.9",
"insert-css": "^2.0.0",
"mobx": "^6.6.1", "mobx": "^6.6.1",
"mobx-react": "^7.5.2", "mobx-react": "^7.5.2",
"react": "^18.2.0", "react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-dnd": "^16.0.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-draggable": "^4.4.6",
"react-router-dom": "^6.3.0", "react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1", "react-scripts": "^5.0.1",
"web-vitals": "^2.1.4", "web-vitals": "^2.1.4",
@ -4826,6 +4830,21 @@
"react-dom": ">=16.9.0" "react-dom": ">=16.9.0"
} }
}, },
"node_modules/@react-dnd/asap": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz",
"integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A=="
},
"node_modules/@react-dnd/invariant": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz",
"integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw=="
},
"node_modules/@react-dnd/shallowequal": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA=="
},
"node_modules/@rollup/plugin-babel": { "node_modules/@rollup/plugin-babel": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@ -5395,6 +5414,15 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"node_modules/@types/hoist-non-react-statics": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
"integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==",
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"node_modules/@types/html-minifier-terser": { "node_modules/@types/html-minifier-terser": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@ -5475,8 +5503,7 @@
"node_modules/@types/prop-types": { "node_modules/@types/prop-types": {
"version": "15.7.5", "version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
"dev": true
}, },
"node_modules/@types/q": { "node_modules/@types/q": {
"version": "1.5.5", "version": "1.5.5",
@ -5497,7 +5524,6 @@
"version": "18.2.20", "version": "18.2.20",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz",
"integrity": "sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==", "integrity": "sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==",
"dev": true,
"dependencies": { "dependencies": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*", "@types/scheduler": "*",
@ -5513,6 +5539,17 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"node_modules/@types/react-redux": {
"version": "7.1.30",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.30.tgz",
"integrity": "sha512-i2kqM6YaUwFKduamV6QM/uHbb0eCP8f8ZQ/0yWf+BsAVVsZPRYJ9eeGWZ3uxLfWwwA0SrPRMTPTqsPFkY3HZdA==",
"dependencies": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"node_modules/@types/resize-observer-browser": { "node_modules/@types/resize-observer-browser": {
"version": "0.1.7", "version": "0.1.7",
"resolved": "https://registry.npmmirror.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz", "resolved": "https://registry.npmmirror.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz",
@ -5534,8 +5571,7 @@
"node_modules/@types/scheduler": { "node_modules/@types/scheduler": {
"version": "0.16.3", "version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==", "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
"dev": true
}, },
"node_modules/@types/semver": { "node_modules/@types/semver": {
"version": "7.3.13", "version": "7.3.13",
@ -7441,6 +7477,14 @@
"wrap-ansi": "^7.0.0" "wrap-ansi": "^7.0.0"
} }
}, },
"node_modules/clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
"engines": {
"node": ">=6"
}
},
"node_modules/co": { "node_modules/co": {
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@ -7775,6 +7819,14 @@
"postcss": "^8.4" "postcss": "^8.4"
} }
}, },
"node_modules/css-box-model": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
"integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
"dependencies": {
"tiny-invariant": "^1.0.6"
}
},
"node_modules/css-declaration-sorter": { "node_modules/css-declaration-sorter": {
"version": "6.3.1", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
@ -8599,6 +8651,16 @@
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
}, },
"node_modules/dnd-core": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz",
"integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
"dependencies": {
"@react-dnd/asap": "^5.0.1",
"@react-dnd/invariant": "^4.0.1",
"redux": "^4.2.0"
}
},
"node_modules/dns-equal": { "node_modules/dns-equal": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
@ -11156,6 +11218,14 @@
"@babel/runtime": "^7.7.6" "@babel/runtime": "^7.7.6"
} }
}, },
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"dependencies": {
"react-is": "^16.7.0"
}
},
"node_modules/hoopy": { "node_modules/hoopy": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@ -11538,7 +11608,7 @@
}, },
"node_modules/insert-css": { "node_modules/insert-css": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/insert-css/-/insert-css-2.0.0.tgz", "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz",
"integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA==" "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA=="
}, },
"node_modules/internal-slot": { "node_modules/internal-slot": {
@ -14565,6 +14635,11 @@
"node": ">= 4.0.0" "node": ">= 4.0.0"
} }
}, },
"node_modules/memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
},
"node_modules/merge-descriptors": { "node_modules/merge-descriptors": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@ -17049,6 +17124,11 @@
"performance-now": "^2.1.0" "performance-now": "^2.1.0"
} }
}, },
"node_modules/raf-schd": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz",
"integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ=="
},
"node_modules/randombytes": { "node_modules/randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -17703,6 +17783,24 @@
"node": ">=14" "node": ">=14"
} }
}, },
"node_modules/react-beautiful-dnd": {
"version": "13.1.1",
"resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz",
"integrity": "sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==",
"dependencies": {
"@babel/runtime": "^7.9.2",
"css-box-model": "^1.2.0",
"memoize-one": "^5.1.1",
"raf-schd": "^4.0.2",
"react-redux": "^7.2.0",
"redux": "^4.0.4",
"use-memo-one": "^1.1.1"
},
"peerDependencies": {
"react": "^16.8.5 || ^17.0.0 || ^18.0.0",
"react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/react-color": { "node_modules/react-color": {
"version": "2.17.3", "version": "2.17.3",
"resolved": "https://registry.npmmirror.com/react-color/-/react-color-2.17.3.tgz", "resolved": "https://registry.npmmirror.com/react-color/-/react-color-2.17.3.tgz",
@ -17844,6 +17942,35 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/react-dnd": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
"integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
"dependencies": {
"@react-dnd/invariant": "^4.0.1",
"@react-dnd/shallowequal": "^4.0.1",
"dnd-core": "^16.0.1",
"fast-deep-equal": "^3.1.3",
"hoist-non-react-statics": "^3.3.2"
},
"peerDependencies": {
"@types/hoist-non-react-statics": ">= 3.3.1",
"@types/node": ">= 12",
"@types/react": ">= 16",
"react": ">= 16.14"
},
"peerDependenciesMeta": {
"@types/hoist-non-react-statics": {
"optional": true
},
"@types/node": {
"optional": true
},
"@types/react": {
"optional": true
}
}
},
"node_modules/react-dom": { "node_modules/react-dom": {
"version": "18.2.0", "version": "18.2.0",
"resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz", "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz",
@ -17856,6 +17983,19 @@
"react": "^18.2.0" "react": "^18.2.0"
} }
}, },
"node_modules/react-draggable": {
"version": "4.4.6",
"resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.6.tgz",
"integrity": "sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==",
"dependencies": {
"clsx": "^1.1.1",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"react": ">= 16.3.0",
"react-dom": ">= 16.3.0"
}
},
"node_modules/react-error-overlay": { "node_modules/react-error-overlay": {
"version": "6.0.11", "version": "6.0.11",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
@ -17871,6 +18011,35 @@
"resolved": "https://registry.npmmirror.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "resolved": "https://registry.npmmirror.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
}, },
"node_modules/react-redux": {
"version": "7.2.9",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz",
"integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==",
"dependencies": {
"@babel/runtime": "^7.15.4",
"@types/react-redux": "^7.1.20",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^17.0.2"
},
"peerDependencies": {
"react": "^16.8.3 || ^17 || ^18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-redux/node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
},
"node_modules/react-refresh": { "node_modules/react-refresh": {
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@ -18109,6 +18278,14 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"dependencies": {
"@babel/runtime": "^7.9.2"
}
},
"node_modules/reflect-metadata": { "node_modules/reflect-metadata": {
"version": "0.1.13", "version": "0.1.13",
"resolved": "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "resolved": "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
@ -19746,6 +19923,11 @@
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
}, },
"node_modules/tiny-invariant": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
"integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw=="
},
"node_modules/tinycolor2": { "node_modules/tinycolor2": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.4.2.tgz", "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.4.2.tgz",
@ -20231,6 +20413,14 @@
"requires-port": "^1.0.0" "requires-port": "^1.0.0"
} }
}, },
"node_modules/use-memo-one": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz",
"integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/use-sync-external-store": { "node_modules/use-sync-external-store": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
@ -24912,6 +25102,21 @@
"rc-util": "^5.24.4" "rc-util": "^5.24.4"
} }
}, },
"@react-dnd/asap": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/@react-dnd/asap/-/asap-5.0.2.tgz",
"integrity": "sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A=="
},
"@react-dnd/invariant": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@react-dnd/invariant/-/invariant-4.0.2.tgz",
"integrity": "sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw=="
},
"@react-dnd/shallowequal": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-4.0.2.tgz",
"integrity": "sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA=="
},
"@rollup/plugin-babel": { "@rollup/plugin-babel": {
"version": "5.3.1", "version": "5.3.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz",
@ -25327,6 +25532,15 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/hoist-non-react-statics": {
"version": "3.3.5",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz",
"integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==",
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
}
},
"@types/html-minifier-terser": { "@types/html-minifier-terser": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@ -25407,8 +25621,7 @@
"@types/prop-types": { "@types/prop-types": {
"version": "15.7.5", "version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
"dev": true
}, },
"@types/q": { "@types/q": {
"version": "1.5.5", "version": "1.5.5",
@ -25429,7 +25642,6 @@
"version": "18.2.20", "version": "18.2.20",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.20.tgz",
"integrity": "sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==", "integrity": "sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==",
"dev": true,
"requires": { "requires": {
"@types/prop-types": "*", "@types/prop-types": "*",
"@types/scheduler": "*", "@types/scheduler": "*",
@ -25445,6 +25657,17 @@
"@types/react": "*" "@types/react": "*"
} }
}, },
"@types/react-redux": {
"version": "7.1.30",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.30.tgz",
"integrity": "sha512-i2kqM6YaUwFKduamV6QM/uHbb0eCP8f8ZQ/0yWf+BsAVVsZPRYJ9eeGWZ3uxLfWwwA0SrPRMTPTqsPFkY3HZdA==",
"requires": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0",
"redux": "^4.0.0"
}
},
"@types/resize-observer-browser": { "@types/resize-observer-browser": {
"version": "0.1.7", "version": "0.1.7",
"resolved": "https://registry.npmmirror.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz", "resolved": "https://registry.npmmirror.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.7.tgz",
@ -25466,8 +25689,7 @@
"@types/scheduler": { "@types/scheduler": {
"version": "0.16.3", "version": "0.16.3",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==", "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
"dev": true
}, },
"@types/semver": { "@types/semver": {
"version": "7.3.13", "version": "7.3.13",
@ -26924,6 +27146,11 @@
"wrap-ansi": "^7.0.0" "wrap-ansi": "^7.0.0"
} }
}, },
"clsx": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="
},
"co": { "co": {
"version": "4.6.0", "version": "4.6.0",
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
@ -27185,6 +27412,14 @@
"postcss-selector-parser": "^6.0.9" "postcss-selector-parser": "^6.0.9"
} }
}, },
"css-box-model": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz",
"integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==",
"requires": {
"tiny-invariant": "^1.0.6"
}
},
"css-declaration-sorter": { "css-declaration-sorter": {
"version": "6.3.1", "version": "6.3.1",
"resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz",
@ -27796,6 +28031,16 @@
"resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="
}, },
"dnd-core": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-16.0.1.tgz",
"integrity": "sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==",
"requires": {
"@react-dnd/asap": "^5.0.1",
"@react-dnd/invariant": "^4.0.1",
"redux": "^4.2.0"
}
},
"dns-equal": { "dns-equal": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
@ -29682,6 +29927,14 @@
"@babel/runtime": "^7.7.6" "@babel/runtime": "^7.7.6"
} }
}, },
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
"react-is": "^16.7.0"
}
},
"hoopy": { "hoopy": {
"version": "0.1.4", "version": "0.1.4",
"resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
@ -29963,7 +30216,7 @@
}, },
"insert-css": { "insert-css": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/insert-css/-/insert-css-2.0.0.tgz", "resolved": "https://registry.npmjs.org/insert-css/-/insert-css-2.0.0.tgz",
"integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA==" "integrity": "sha512-xGq5ISgcUP5cvGkS2MMFLtPDBtrtQPSFfC6gA6U8wHKqfjTIMZLZNxOItQnoSjdOzlXOLU/yD32RKC4SvjNbtA=="
}, },
"internal-slot": { "internal-slot": {
@ -32217,6 +32470,11 @@
"fs-monkey": "^1.0.3" "fs-monkey": "^1.0.3"
} }
}, },
"memoize-one": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz",
"integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="
},
"merge-descriptors": { "merge-descriptors": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@ -33847,6 +34105,11 @@
"performance-now": "^2.1.0" "performance-now": "^2.1.0"
} }
}, },
"raf-schd": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz",
"integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ=="
},
"randombytes": { "randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -34308,6 +34571,20 @@
"whatwg-fetch": "^3.6.2" "whatwg-fetch": "^3.6.2"
} }
}, },
"react-beautiful-dnd": {
"version": "13.1.1",
"resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz",
"integrity": "sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==",
"requires": {
"@babel/runtime": "^7.9.2",
"css-box-model": "^1.2.0",
"memoize-one": "^5.1.1",
"raf-schd": "^4.0.2",
"react-redux": "^7.2.0",
"redux": "^4.0.4",
"use-memo-one": "^1.1.1"
}
},
"react-color": { "react-color": {
"version": "2.17.3", "version": "2.17.3",
"resolved": "https://registry.npmmirror.com/react-color/-/react-color-2.17.3.tgz", "resolved": "https://registry.npmmirror.com/react-color/-/react-color-2.17.3.tgz",
@ -34413,6 +34690,18 @@
} }
} }
}, },
"react-dnd": {
"version": "16.0.1",
"resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-16.0.1.tgz",
"integrity": "sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==",
"requires": {
"@react-dnd/invariant": "^4.0.1",
"@react-dnd/shallowequal": "^4.0.1",
"dnd-core": "^16.0.1",
"fast-deep-equal": "^3.1.3",
"hoist-non-react-statics": "^3.3.2"
}
},
"react-dom": { "react-dom": {
"version": "18.2.0", "version": "18.2.0",
"resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz", "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz",
@ -34422,6 +34711,15 @@
"scheduler": "^0.23.0" "scheduler": "^0.23.0"
} }
}, },
"react-draggable": {
"version": "4.4.6",
"resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.6.tgz",
"integrity": "sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==",
"requires": {
"clsx": "^1.1.1",
"prop-types": "^15.8.1"
}
},
"react-error-overlay": { "react-error-overlay": {
"version": "6.0.11", "version": "6.0.11",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
@ -34437,6 +34735,26 @@
"resolved": "https://registry.npmmirror.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "resolved": "https://registry.npmmirror.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
}, },
"react-redux": {
"version": "7.2.9",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz",
"integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==",
"requires": {
"@babel/runtime": "^7.15.4",
"@types/react-redux": "^7.1.20",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^17.0.2"
},
"dependencies": {
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
}
}
},
"react-refresh": { "react-refresh": {
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
@ -34623,6 +34941,14 @@
"minimatch": "^3.0.5" "minimatch": "^3.0.5"
} }
}, },
"redux": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
"integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
"requires": {
"@babel/runtime": "^7.9.2"
}
},
"reflect-metadata": { "reflect-metadata": {
"version": "0.1.13", "version": "0.1.13",
"resolved": "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "resolved": "https://registry.npmmirror.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz",
@ -35860,6 +36186,11 @@
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="
}, },
"tiny-invariant": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz",
"integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw=="
},
"tinycolor2": { "tinycolor2": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.4.2.tgz", "resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.4.2.tgz",
@ -36208,6 +36539,12 @@
"requires-port": "^1.0.0" "requires-port": "^1.0.0"
} }
}, },
"use-memo-one": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz",
"integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==",
"requires": {}
},
"use-sync-external-store": { "use-sync-external-store": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",

@ -7,10 +7,14 @@
"@ant-design/pro-components": "^2.6.16", "@ant-design/pro-components": "^2.6.16",
"antd": "^4.22.6", "antd": "^4.22.6",
"dingtalk-jsapi": "^3.0.9", "dingtalk-jsapi": "^3.0.9",
"insert-css": "^2.0.0",
"mobx": "^6.6.1", "mobx": "^6.6.1",
"mobx-react": "^7.5.2", "mobx-react": "^7.5.2",
"react": "^18.2.0", "react": "^18.2.0",
"react-beautiful-dnd": "^13.1.1",
"react-dnd": "^16.0.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-draggable": "^4.4.6",
"react-router-dom": "^6.3.0", "react-router-dom": "^6.3.0",
"react-scripts": "^5.0.1", "react-scripts": "^5.0.1",
"web-vitals": "^2.1.4", "web-vitals": "^2.1.4",

@ -32,7 +32,7 @@
padding: 0; padding: 0;
} }
.p-s1{ .p-s1{
padding: .5em; padding: .5rem!important;
} }
.sticky-top{ .sticky-top{

@ -42,6 +42,7 @@ import ExchangeRate from './charts/ExchangeRate';
import KPI from './views/KPI'; import KPI from './views/KPI';
import Distribution from './views/Distribution'; import Distribution from './views/Distribution';
import Detail from './views/Detail'; import Detail from './views/Detail';
import DataPivot from './views/DataPivot';
import Welcome from './views/Welcome'; import Welcome from './views/Welcome';
import { stores_Context, APP_VERSION } from './config'; import { stores_Context, APP_VERSION } from './config';
import { WaterMark } from '@ant-design/pro-components'; import { WaterMark } from '@ant-design/pro-components';
@ -52,7 +53,7 @@ const App = () => {
const menu_items = [ const menu_items = [
{ key: 1, label: <NavLink to="/">欢迎</NavLink>, icon: <CoffeeOutlined /> }, { key: 1, label: <NavLink to="/">欢迎</NavLink>, icon: <CoffeeOutlined /> },
{ key: 'annual', label: <NavLink to="/annual">综合看板</NavLink>, icon: <BarChartOutlined /> }, { key: 'annual', label: <NavLink to="/annual">综合看板</NavLink>, icon: <DashboardOutlined /> },
{ {
key: 2, key: 2,
label: '市场', label: '市场',
@ -61,12 +62,17 @@ const App = () => {
{ {
key: 21, key: 21,
label: <NavLink to="/orders">订单数据</NavLink>, label: <NavLink to="/orders">订单数据</NavLink>,
icon: <FileProtectOutlined />, // icon: <FileProtectOutlined />,
}, },
{ {
key: 22, key: 22,
label: <NavLink to="/dashboard">仪表盘</NavLink>, label: <NavLink to="/dashboard">仪表盘</NavLink>,
icon: <DashboardOutlined />, // icon: <DashboardOutlined />,
},
{
key: 'orders-pivot',
label: <NavLink to="/orders/pivot">数据透视</NavLink>,
// icon: <DashboardOutlined />,
}, },
], ],
}, },
@ -190,6 +196,7 @@ const App = () => {
<Route path="/orders" element={<Orders />} /> <Route path="/orders" element={<Orders />} />
<Route path="/orders_sub/:ordertype/:ordertype_sub/:ordertype_title" element={<Orders_sub />} /> <Route path="/orders_sub/:ordertype/:ordertype_sub/:ordertype_title" element={<Orders_sub />} />
<Route path="/dashboard" element={<Dashboard />} /> <Route path="/dashboard" element={<Dashboard />} />
<Route path="/:page/pivot" element={<DataPivot />} />
</Route> </Route>
<Route element={<ProtectedRoute auth={['admin', 'director_bu', 'customer_care']} />}> <Route element={<ProtectedRoute auth={['admin', 'director_bu', 'customer_care']} />}>
<Route path="/customer_care_inchina" element={<Customer_care_inchina />} /> <Route path="/customer_care_inchina" element={<Customer_care_inchina />} />

@ -153,6 +153,6 @@ export const resultDataCb = (dataRaw, dateGroup, { data1, data2 }, fieldMapper,
})); }));
const retData = [].concat(parseData1, reindexData2 ).map(ele => ({...ele, [fieldMapper.dateKey]: data1KeyMappedStr[ele[fieldMapper.dateKey]] || data2KeyMappedStr[ele[fieldMapper.dateKey]]})); const retData = [].concat(parseData1, reindexData2 ).map(ele => ({...ele, [fieldMapper.dateKey]: data1KeyMappedStr[ele[fieldMapper.dateKey]] || data2KeyMappedStr[ele[fieldMapper.dateKey]]}));
const avg1 = parse1.avgVal; const avg1 = parse1.avgVal;
// console.log('callback', dateGroup, retData, data1KeyMappedStr, data2KeyMappedStr); // console.log('callback', dateGroup, retData, avg1, parse2.avgVal, data1KeyMappedStr, data2KeyMappedStr);
cb(dateGroup, retData, avg1, parse2.avgVal); cb(dateGroup, retData, avg1, parse2.avgVal);
}; };

@ -312,14 +312,16 @@ function getFields(props) {
rules={[{ required: true, message: '选择小组' }]} rules={[{ required: true, message: '选择小组' }]}
> >
<GroupSelect {...fieldProps.DepartmentList} labelInValue={true} /> <GroupSelect {...fieldProps.DepartmentList} labelInValue={true} />
</Form.Item>, fieldProps?.DepartmentList?.col </Form.Item>,
fieldProps?.DepartmentList?.col
), ),
item( item(
'WebCode', 'WebCode',
99, 99,
<Form.Item name={`WebCode`} initialValue={at(props, 'initialValue.WebCode')[0] || (fieldProps?.WebCode?.show_all ? { key: 'ALL', label: '所有来源' } : undefined)}> <Form.Item name={`WebCode`} initialValue={at(props, 'initialValue.WebCode')[0] || (fieldProps?.WebCode?.show_all ? { key: 'ALL', label: '所有来源' } : undefined)}>
<SiteSelect {...fieldProps.WebCode} labelInValue={true} /> <SiteSelect {...fieldProps.WebCode} labelInValue={true} />
</Form.Item> </Form.Item>,
fieldProps?.WebCode?.col
), ),
item( item(
'IncludeTickets', 'IncludeTickets',

@ -1,4 +1,4 @@
import { fixTo4Decimals, fixTo1Decimals } from "../utils/commons"; import { fixTo4Decimals, fixTo1Decimals, fixToInt, groupBy, sortBy, cloneDeep, pick, unique, flush } from '../utils/commons';
/** /**
* 事业部 * 事业部
@ -123,11 +123,7 @@ export const dataFieldAlias = dataFieldOptions.reduce(
* KPI对象 * KPI对象
*/ */
export const KPIObjects = [ export const KPIObjects = [
{ key: 'overview', value: 'overview', label: '海纳', data: [ { key: 'overview', value: 'overview', label: '海纳', data: [{ key: 'ALL', value: 'ALL', label: '海纳' }, ...overviewGroup] },
{ key: 'ALL', value: 'ALL', label: '海纳' },
...overviewGroup
]
},
{ {
key: 'bizarea', key: 'bizarea',
value: 'bizarea', value: 'bizarea',
@ -173,3 +169,252 @@ export const KPISubjects = [
// { key: 'reply_eff_wa', value: 'reply_eff_wa', label: 'WA回复效率'}, // { key: 'reply_eff_wa', value: 'reply_eff_wa', label: 'WA回复效率'},
// { key: 'sum_person_num', value: 'sum_person_num', label: '人数' }, // { key: 'sum_person_num', value: 'sum_person_num', label: '人数' },
]; ];
/**
* 数据透视计算
* @param {object[]} data
* @param {any[]} groupbyKeys
* @returns
*/
export const pivotBy = (data, [rows, columns, date]) => {
// console.time('pivot----');
console.log('pivotBy', [rows, columns, date]);
const groupbyKeys = flush([].concat(rows, columns, [date]));
const getKeys = (keys) => keys.map((keyField) => [...new Set(data.map((f) => f[keyField]))]);
const [rowsKeys, columnsKeys, dateKeys] = [getKeys(rows), getKeys(columns), getKeys([date])];
const calcTradeFields = (dataObj, keepKeys = [], seriesKey = '') => {
const outerKeys = [];
const _keepKeys = [...keepKeys, seriesKey];
const DataGroupByKeys = {};
Object.keys(dataObj).forEach((colKey) => {
const _len = dataObj[colKey].length;
const _rowKey = dataObj[colKey].map((v) => v.key).join('_');
outerKeys.push(_rowKey);
const initialData = {
...pick(dataObj[colKey][0], _keepKeys),
...(keepKeys.length === 0
? { rowLabel: '总' }
: {
rowLabel: cloneDeep(keepKeys)
// .slice(0, -1)
.map((_k) => dataObj[colKey][0][_k])
.join('»'),
}),
_label: colKey || '(空)',
key: _rowKey,
SumOrder: _len,
SumPersonNum: 0,
ConfirmOrder: 0,
transactions: 0,
SumML: 0,
quotePrice: 0,
tourdays: 0,
applyDays: 0,
confirmDays: 0,
};
const calculatedData = dataObj[colKey].reduce((r, v) => {
r.SumPersonNum += v.personNum;
r.ConfirmOrder += Number(v.orderState) === 1 ? 1 : 0;
r.transactions += v.transactions;
r.SumML += v.ML;
r.quotePrice += v.quotePrice;
r.tourdays += v.tourdays;
r.applyDays += v.applyDays;
r.confirmDays += v.confirmDays;
return r;
}, initialData);
// Calculations
calculatedData.tourdays = Math.ceil(calculatedData.tourdays / _len);
calculatedData.applyDays = Math.ceil(calculatedData.applyDays / _len);
calculatedData.confirmDays = Math.ceil(calculatedData.confirmDays / _len);
const _rowCalc = {
ConfirmRates: calculatedData.ConfirmOrder ? fixTo4Decimals(calculatedData.ConfirmOrder / calculatedData.SumOrder) : 0,
OrderValue: calculatedData.SumOrder ? fixToInt(calculatedData.SumML / calculatedData.SumOrder) : 0,
};
DataGroupByKeys[colKey] = { ...calculatedData, ..._rowCalc };
});
return { groupByKeys: DataGroupByKeys, key: outerKeys.join('_') };
};
const groupData = groupBy(data, (row) => groupbyKeys.map((kk) => `${row[kk]}`).join('=@='));
const rowsNcolumnsItems = calcTradeFields(groupData, [...rows, ...columns], date);
const pivotResult = Object.values(rowsNcolumnsItems.groupByKeys);
const transposeData = (keys, dataProp, [dataKey, colKeys]=[]) =>
Object.keys(dataProp)
.map((rowKey) => {
const _colKey = dataKey || 'dataKey';
const _colData = groupBy(dataProp[rowKey], (crow) => (colKeys || keys).map((kk) => `${crow[kk]}`).join('=@='));
const _columnsObj = calcTradeFields(_colData);
return { ...pick(dataProp[rowKey][0], keys), [_colKey]: _columnsObj.groupByKeys, key: _columnsObj.key };
})
.map((everyR) => {
const _colKey = dataKey || 'dataKey';
const allColumns = Object.values(everyR[_colKey]).reduce((r, c) => r.concat([c]), []);
const summaryCalc = ['ConfirmOrder', 'SumOrder', 'SumML', 'transactions', 'SumPersonNum', 'quotePrice', 'tourdays', 'applyDays', 'confirmDays'].reduce(
(r, skey) => ({ ...r, [skey]: allColumns.reduce((a, c) => a + c[skey], 0) }),
everyR
);
summaryCalc.tourdays = Math.ceil(summaryCalc.tourdays / allColumns.length);
summaryCalc.applyDays = Math.ceil(summaryCalc.applyDays / allColumns.length);
summaryCalc.confirmDays = Math.ceil(summaryCalc.confirmDays / allColumns.length);
summaryCalc.ConfirmRates = summaryCalc.ConfirmOrder ? fixTo4Decimals(summaryCalc.ConfirmOrder / summaryCalc.SumOrder) : 0;
summaryCalc.OrderValue = summaryCalc.SumOrder ? fixToInt(summaryCalc.SumML / summaryCalc.SumOrder) : 0;
return { ...everyR, ...summaryCalc };
});
const rowsData = groupBy(data, (row) => rows.map((kk) => `${row[kk]}`).join('=@='));
const summaryRows = transposeData(rows, rowsData, ['columns', columns]);
const columnsData = groupBy(data, (row) => columns.map((kk) => `${row[kk]}`).join('=@='));
const summaryColumns = transposeData(columns, columnsData, ['rows', rows]);
// console.timeEnd('pivot----');
return { data: pivotResult, columnValues: [rowsKeys, columnsKeys, dateKeys], summaryRows, summaryColumns };
};
// todo: 优化 pivotBy 速度
export const pivotBy3 = (data, [rows, columns, date]) => {
console.log('pivotBy', [rows, columns, date]);
console.time('pivot2');
// const rowKeys = new Set(data.map(row => row[rows[0]]));
const rowKeys = rows.map((keyField) => {
const keyu = new Set(data.map((f) => f[keyField]));
return keyu;
});
const colKeys = new Set(data.map(row => row[columns[0]]));
const dateKeys = new Set(data.map(row => row[date]));
const aggregatedData = {};
data.forEach(row => {
const rowKey = row[rows[0]] ?? '__total';
const colKey = row[columns[0]] ?? '__total';
const dateKey = row[date];
if (!aggregatedData[rowKey]) {
aggregatedData[rowKey] = {};
}
// if (!aggregatedData[rowKey][colKey]) {
// aggregatedData[rowKey][colKey] = {};
// }
if (!aggregatedData[rowKey][colKey]) {
aggregatedData[rowKey][colKey] = {
SumOrder: 0,
// other aggregated fields
SumPersonNum: 0,
ConfirmOrder: 0,
transactions: 0,
SumML: 0,
// ...
quotePrice: 0,
tourdays: 0,
applyDays: 0,
confirmDays: 0,
};
}
aggregatedData[rowKey][colKey].SumOrder++;
aggregatedData[rowKey][colKey].SumPersonNum += row.personNum;
aggregatedData[rowKey][colKey].ConfirmOrder += Number(row.orderState === 1);
aggregatedData[rowKey][colKey].transactions += row.transactions;
aggregatedData[rowKey][colKey].SumML += row.ML;
// aggregate other fields
});
const summarizedData = [];
// Generate summary rows
for (const rowKey of rowKeys) {
const rowAggregations = {
SumOrder: 0,
// other aggregated fields
SumPersonNum: 0,
ConfirmOrder: 0,
transactions: 0,
SumML: 0,
// ...
quotePrice: 0,
tourdays: 0,
applyDays: 0,
confirmDays: 0,
};
// Calculate aggregates over colKey
for (const colKey in aggregatedData[rowKey]) {
rowAggregations.SumOrder += aggregatedData[rowKey][colKey].SumOrder;
rowAggregations.SumPersonNum += aggregatedData[rowKey][colKey].SumPersonNum;
rowAggregations.ConfirmOrder += aggregatedData[rowKey][colKey].ConfirmOrder;
rowAggregations.transactions += aggregatedData[rowKey][colKey].transactions;
rowAggregations.SumML += aggregatedData[rowKey][colKey].SumML;
// ...aggregate all other fields
}
const row = {
[rows[0]]: rowKey,
...rowAggregations
};
summarizedData.push(row);
}
// Generate summary columns
for (const colKey of colKeys) {
const colAggregations = {
SumOrder: 0,
// other aggregated fields
SumPersonNum: 0,
ConfirmOrder: 0,
transactions: 0,
SumML: 0,
// ...
quotePrice: 0,
tourdays: 0,
applyDays: 0,
confirmDays: 0,
};
// Calculate aggregates over rowKey
for (const rowKey in aggregatedData) {
if (aggregatedData[rowKey][colKey]) {
colAggregations.SumOrder += aggregatedData[rowKey][colKey].SumOrder;
colAggregations.SumPersonNum += aggregatedData[rowKey][colKey].SumPersonNum;
colAggregations.ConfirmOrder += aggregatedData[rowKey][colKey].ConfirmOrder;
colAggregations.transactions += aggregatedData[rowKey][colKey].transactions;
colAggregations.SumML += aggregatedData[rowKey][colKey].SumML;
// ...aggregate all other fields
}
}
const col = {
[columns[0]]: colKey,
...colAggregations
};
summarizedData.push(col);
}
console.timeEnd('pivot2');
console.log('pivot2 ddd', aggregatedData);
return {
data: [], // aggregatedData,
columnValues: [rowKeys, colKeys, dateKeys],
summaryRows: summarizedData.filter(r => r[rows[0]]),
summaryColumns: summarizedData.filter(c => c[columns[0]])
};
};

@ -0,0 +1,49 @@
import { makeAutoObservable, runInAction, toJS } from 'mobx';
import { fetchJSON } from '../utils/request';
import { isEmpty, sortBy, pick, merge, fixTo2Decimals, groupBy, sortKeys, fixToInt, cloneDeep } from '../utils/commons';
import { dataFieldAlias } from './../libs/ht';
class Trade {
constructor(rootStore) {
this.rootStore = rootStore;
makeAutoObservable(this);
}
/**
* 明细
*/
getDetailData = async (param, page) => {
this.detailData[page] = { loading: true, dataSource: [], originData: [] };
const json = await fetchJSON('/service-Analyse2/GetTradeApartDetail', param);
if (json.errcode === 0) {
runInAction(() => {
this.detailData[page].loading = false;
this.detailData[page].dataSource = json.result;
this.detailData[page].originData = json.result;
});
}
return json.result;
};
setSearchValues(body) {
this.searchValues = body;
}
timeLineKey = 'week';
setTimeLineKey(v) {
this.timeLineKey = v;
}
resetData = () => {
this.detailData = {
orders: { loading: false, dataSource: [], originData: [] },
};
};
searchValues = {};
detailData = {
orders: { loading: false, dataSource: [], originData: [] },
};
}
export default Trade;

@ -69,7 +69,7 @@ class Distribution {
this.scatterDays = daysData; this.scatterDays = daysData;
}); });
} }
return this.detailData; return json.result;
}; };
resetData = () => { resetData = () => {

@ -14,6 +14,7 @@ import TradeStore from "./Trade";
import KPI from "./KPI"; import KPI from "./KPI";
import DictData from "./DictData"; import DictData from "./DictData";
import Distribution from "./Distribution"; import Distribution from "./Distribution";
import DataPivot from './DataPivot';
class Index { class Index {
constructor() { constructor() {
this.dashboard_store = new DashboardStore(this); this.dashboard_store = new DashboardStore(this);
@ -31,6 +32,7 @@ class Index {
this.KPIStore = new KPI(this); this.KPIStore = new KPI(this);
this.DictDataStore = new DictData(this); this.DictDataStore = new DictData(this);
this.DistributionStore = new Distribution(this); this.DistributionStore = new Distribution(this);
this.DataPivotStore = new DataPivot(this);
makeAutoObservable(this); makeAutoObservable(this);
} }

@ -353,6 +353,20 @@ export function pick(object, keys) {
}, {}); }, {});
} }
/**
* 返回对象的副本经过筛选以省略指定的键
* @param {*} object
* @param {string[]} keysToOmit
* @returns
*/
export function omit(object, keysToOmit) {
return Object.fromEntries(
Object.entries(object).filter(
([key]) => !keysToOmit.includes(key)
)
);
}
/** /**
* 深拷贝 * 深拷贝
*/ */

@ -0,0 +1,502 @@
import { useContext, useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import { useParams } from 'react-router-dom';
import { stores_Context } from '../config';
import { Row, Col, Spin, Table, Select, Typography, Card, Button } from 'antd';
import { cloneDeep, groupBy, isEmpty, omit, pick, sortBy, unique } from '../utils/commons';
import { dataFieldAlias, pivotBy } from '../libs/ht';
import SearchForm from '../components/search/SearchForm';
import { Line } from '@ant-design/plots';
import DateGroupRadio from '../components/DateGroupRadio';
const { Text } = Typography;
const filterFields = [
{ key: 'country', label: '国籍' },
{ key: 'SourceType', label: '来源类型' },
{ key: 'productType', label: '产品类型' },
{ key: 'guestGroupType', label: '客群类别' },
{ key: 'travelMotivation', label: '出行动机' },
{ key: 'operatorName', label: '顾问' },
{ key: 'WebCode', label: '来源站点' },
// todo: , , [PPC, NL...]
];
const filterFieldsMapped = filterFields.reduce((r, v) => ({ ...r, [v.key]: v }), {});
const quickOptions = [
{ label: '国籍×产品', fields: [['country'], ['productType']] },
{ label: '产品×客群', fields: [['productType'], ['guestGroupType']] },
];
/**
* 计算笛卡尔积
*/
const cartesianProductArray = (arr, sep = '_', index = 0, prefix = '') => {
let result = [];
if(index === arr.length){
return [prefix];
}
arr[index].forEach(item => {
result = result.concat(cartesianProductArray(arr, sep, index+1, prefix ? `${prefix}${sep}${item}` : `${item}`));
});
return result;
};
// TdCellDataTable
const TdCell = (tdprops) => {
// onMouseEnter, onMouseLeave
const { onMouseEnter, onMouseLeave, ...restProps } = tdprops;
return <td {...restProps} />;
};
export default observer((props) => {
const { page } = useParams();
const { date_picker_store: searchFormStore, orders_store, DistributionStore, DataPivotStore } = useContext(stores_Context);
const { formValues, formValuesToSub } = searchFormStore;
const { originData } = DataPivotStore.detailData[page];
const [loading, setLoading] = useState(false);
const [rawData, setRawData] = useState(originData || []);
const [dataBeforePick, setDataBeforePick] = useState([]);
const [dataBeforeXChange, setDataBeforeXChange] = useState([]);
const [dataSource, setDataSource] = useState([]);
// const [dataSourceMapped, setDataSourceMapped] = useState({});
const [pivotTableDataSource, setPivotTableDataSource] = useState([]);
const [pivotTableColumnSummary, setPivotTableColumnSummary] = useState({}); // ,
const [pivotDateColumns, setPivotDateColumns] = useState([[], []]);
const [pivotDateColumnsValues, setPivotDateColumnsValues] = useState([[], []]);
useEffect(() => {
calcDataByDate();
resetX();
resetItemFilter();
return () => {};
}, [pivotDateColumns]);
useEffect(() => {
if (lineChartX === 'day') {
setDataBeforeXChange(dataSource);
}
return () => {};
}, [dataSource]);
const detailRefresh = async (obj) => {
setLoading(true);
DataPivotStore.getDetailData({
...(obj || formValuesToSub),
}, page).then((resData) => {
setLoading(false);
setRawData(resData);
calcDataByDate(resData);
resetX();
resetItemFilter();
});
};
const valKey = 'SumOrder';
const timesKey = 'applyDate';
/**
* 走势的数据
* 汇总
*/
const calcDataByDate = (_rawData) => {
// console.log(';;;;;', pivotDateColumns);
const { data, columnValues, summaryRows, summaryColumns } = pivotBy(_rawData || rawData, [].concat(pivotDateColumns, [timesKey]));
// console.log('data====', data, '\ncolumnValues', columnValues, '\nsummaryRows', summaryRows, '\nsummaryColumns', summaryColumns);
setDataBeforePick(data.sort(sortBy(timesKey)));
// 线
setDataSource(data.sort(sortBy(timesKey)));
//
const sortRowData = cloneDeep(summaryRows).sort(sortBy(valKey)).reverse();
setPivotTableDataSource(sortRowData);
//
const sortColData = summaryColumns.sort(sortBy(valKey)).reverse();
const colDataMapped = isEmpty(pivotDateColumns[1]) ? sortColData[0] : sortColData.reduce((r, v) => ({...r, [v[pivotDateColumns[1][0]]]: v}), {});
setPivotTableColumnSummary(colDataMapped);
//
const _r = (pivotDateColumns[0].map(eleR => unique(sortRowData.map(ele => ele[eleR]))));
const _c = (pivotDateColumns[1].map(eleC => unique(sortColData.map(ele => ele[eleC]))));
// console.log('_r', _r, '_c', _c);
setPivotDateColumnsValues([_r, _c, columnValues[2]]);
};
const line_config = {
// data: dataSource,
padding: 'auto',
xField: timesKey,
yField: valKey,
seriesField: 'rowLabel',
// xAxis: {
// type: 'timeCat',
// },
yAxis: {
min: 0,
maxTickInterval: 5,
},
// smooth: true,
label: {}, //
legend: {
position: 'right-top',
// title: {
// text: ' ' + dataSource.reduce((a, b) => a + b.SumOrder, 0),
// },
itemMarginBottom: 12, //
},
};
const [lineConfig, setLineConfig] = useState(cloneDeep(line_config));
//
// const [leftFields, setLeftFields] = useState(filterFields);
const [rightFields, setRightFields] = useState(filterFields);
const [rowFields, setRowFields] = useState([]);
const [columnFields, setColumnFields] = useState([]);
const [rowSelection, setRowSelection] = useState();
const [columnSelection, setColumnSelection] = useState();
const quickOpt = (i) => {
const { fields: pivotFields } = quickOptions[i];
const [row, col] = pivotFields;
setRowSelection(Object.values(pick(filterFieldsMapped, row)));
setColumnSelection(filterFieldsMapped[col[0]]);
setPivotDateColumns(pivotFields);
};
const handleRowsPick = (v) => {
const pickKeys = v.map((ele) => ele.key);
setRowFields(pickKeys);
// const leftFieldsMapped = leftFields.reduce((r, v) => ({ ...r, [v.key]: v }), {});
const _left = omit(filterFieldsMapped, pickKeys);
setRightFields(isEmpty(v) ? filterFields : Object.values(_left));
// setPivotDateColumns([].concat(pickKeys, columnFields));
setPivotDateColumns([pickKeys, columnFields]);
resetItemFilter();
};
const handleColsPick = (val) => {
const pickKeys = isEmpty(val) ? [] : Array.isArray(val) ? val.map((ele) => ele.key) : [val.key];
setColumnFields(pickKeys);
const afterLeft = Object.values(omit(filterFieldsMapped, rowFields));
setRightFields(afterLeft); //
// const rightFieldsMapped = rightFields.reduce((r, v) => ({ ...r, [v.key]: v }), {});
// const _left = omit(rightFieldsMapped, pickKeys);
// setRightFields(isEmpty(val) ? afterLeft : Object.values(_left)); //
// setPivotDateColumns([].concat(rowFields, pickKeys));
setPivotDateColumns([rowFields, pickKeys]);
resetItemFilter();
};
//
const [rowsItemValues, setRowsItemValues] = useState();
const [columnsItemValues, setColumnsItemValues] = useState();
const [rowsFilter, setRowsFilter] = useState();
const [columnsFilter, setColumnsFilter] = useState();
const resetItemFilter = () => {
setRowsItemValues(null);
setColumnsItemValues(null);
setRowsFilter(null);
setColumnsFilter(null);
};
const handleFieldsItemPick = (v, columnsIndex, columnsName, actionSeries) => {
const _curFilter = { [columnsName]: actionSeries === 'row' ? v : [v] };
// console.log('handleFieldsItemPick', v, columnsIndex, columnsName, actionSeries, _curFilter);
const _rowsF = actionSeries === 'row' ? { ...rowsFilter, ..._curFilter } : rowsFilter;
const _columnsF = actionSeries === 'col' ? { ...columnsFilter, ..._curFilter } : columnsFilter;
actionSeries === 'row' ? setRowsFilter(_rowsF) : setColumnsFilter(_columnsF);
const currentFilterMerge = {
rows: _rowsF || {},
columns: _columnsF || {},
};
setRowsItemValues(currentFilterMerge.rows);
setColumnsItemValues(currentFilterMerge.columns);
const rowsFilterFields = Object.keys(currentFilterMerge.rows).filter((ele) => currentFilterMerge.rows[ele].length);
const dataMappedByRows = groupBy(dataBeforePick, (row) => rowsFilterFields.map((kk) => `${row[kk]}`).join('=@='));
const rowsFilterKey = isEmpty(rowsFilterFields)
? []
: cartesianProductArray(
Object.values(currentFilterMerge.rows)
.map((kv) => kv.map((kf) => kf.key))
.filter((s) => s.length),
'=@='
);
const afterRowsFilter = isEmpty(rowsFilterFields) ? dataBeforePick : rowsFilterKey.reduce((r, _key) => r.concat(dataMappedByRows[_key]), []);
const columnsFilterFields = Object.keys(currentFilterMerge.columns).filter((ele) => currentFilterMerge.rows[ele].length);
const allFilterValues = [].concat(
rowsFilterFields.reduce((r, v) => r.concat(currentFilterMerge.rows[v]), []),
columnsFilterFields.reduce((r, v) => r.concat(currentFilterMerge.columns[v]), [])
);
const dataMapped = groupBy(afterRowsFilter, (row) => row[columnsName]);
const pickData = isEmpty(v) ? afterRowsFilter : Array.isArray(v) ? v.reduce((r, v) => r.concat(dataMapped[v.value]), []) : dataMapped[v.value];
setDataSource(allFilterValues.length === 0 ? dataBeforePick : pickData.sort(sortBy(timesKey)));
resetX();
};
//
const [lineChartX, setLineChartX] = useState('day');
const [avgLine1, setAvgLine1] = useState(0);
const orderCountDataMapper = { data1: 'data1', data2: undefined };
const orderCountDataFieldMapper = { 'dateKey': timesKey, 'valueKey': valKey, 'seriesKey': 'rowLabel', _f: 'sum' };
const resetX = () => {
setLineChartX('day');
setAvgLine1(0);
};
const onChangeXDateFieldGroup = (value, data, avg1) => {
const { xField, yField, seriesField } = lineConfig;
const groupByDate = data.reduce((r, v) => {
(r[v[xField]] || (r[v[xField]] = [])).push(v);
return r;
}, {});
const _data = Object.keys(groupByDate).reduce((r, _d) => {
const xAxisGroup = groupByDate[_d].reduce((a, v) => {
(a[v[seriesField]] || (a[v[seriesField]] = [])).push(v);
return a;
}, {});
Object.keys(xAxisGroup).map((_group) => {
const summaryVal = xAxisGroup[_group].reduce((rows, row) => rows + row[yField], 0);
r.push({ ...xAxisGroup[_group][0], [yField]: summaryVal });
return _group;
});
return r;
}, []);
// .map((row) => ({ [xField]: row[xField], [yField]: row[yField], [seriesField]: row[seriesField], rowX: row.dateRange[0] }));
setLineChartX(value);
setDataSource(_data);
setAvgLine1(avg1);
};
const targetTableProps = {
loading: false,
// sticky: true,
scroll: { x: 1000, y: 400 },
pagination: false,
columns: [
...pivotDateColumns[0].map((ele) => ({ key: ele, title: filterFieldsMapped[ele].label, dataIndex: ele, width: '6em', fixed: 'left' })),
{ key: 'SumOrder', title: '订单数', dataIndex: 'SumOrder', width: '5em' },
...pivotDateColumns[1].map((ele) => ({
key: ele,
title: filterFieldsMapped[ele].label,
align: 'left', className: 'p-s1',
children: cloneDeep(pivotDateColumnsValues[1][0] || []).map((col) => ({
key: col,
title: `${col || '(空)'}: ${pivotTableColumnSummary[col]?.[valKey]}`,
dataIndex: ['columns', col, valKey],
width: '6em',
})),
})),
],
};
return (
<>
<Row gutter={16} className="sticky-top">
<Col className="gutter-row" span={24}>
<SearchForm
defaultValue={{
initialValue: {
...formValues,
...orders_store.searchValues,
},
shows: ['DateType', 'DepartmentList', 'WebCode', 'IncludeTickets', 'dates'], // 'country'
fieldProps: {
DepartmentList: { show_all: false, mode: 'multiple', col: 5 },
WebCode: { show_all: false, mode: 'multiple', col: 5 },
dates: { hide_vs: true },
},
}}
onSubmit={(_err, obj, form, str) => {
detailRefresh(obj);
}}
/>
</Col>
</Row>
{/* extra={<Button type="link">重置</Button>} */}
<Card
size={'small'}
title={'透视选项'}
// extra={quickOptions.map((ele, elei) => (
// <Button key={ele.label} type="link" onClick={() => quickOpt(elei)}>
// {ele.label}
// </Button>
// ))}
>
<Row gutter={16}>
<Col span={24}>
{/* todo: 拖拽的操作 */}
{/* <div className='p-s1' style={{border: '1px solid #d9d9d9 '}}>
{filterFields.map((tag) => (
<Tag key={tag.key} checked={selectedTags.indexOf(tag.key) > -1} onChange={(checked) => handleChange(tag.key, checked)} color={'orange'}>
{tag.label}
</Tag>
))}
</div> */}
</Col>
<Col span={12}>
<Row gutter={8} align={'middle'}>
<Col flex={'4em'} align={'end'}>
<Text strong>: </Text>
</Col>
<Col flex={'auto'}>
<Select
labelInValue
mode={'multiple'}
style={{ width: '100%' }}
placeholder={`选择`}
onChange={(v) => handleRowsPick(v)}
// value={sale_store.salesTrade.pickSales}
// value={rowSelection}
maxTagCount={2}
maxTagPlaceholder={(omittedValues) => ` + ${omittedValues.length} 更多...`}
allowClear={true}
>
{filterFields.map((ele) => (
<Select.Option key={ele.key} value={ele.key}>
{ele.label}
</Select.Option>
))}
</Select>
</Col>
<Col span={24}>
{rowFields.length > 0
? cloneDeep(pivotDateColumnsValues)[0]
// .slice(0, rowFields.length)
.map((_colArr, _colIndex) => (
<Row gutter={8} key={_colArr.join('_')}>
<Col flex={'5em'} align={'end'}>
<Text strong>{filterFieldsMapped[pivotDateColumns[0][_colIndex]]?.label}: </Text>
</Col>
<Col flex={'auto'}>
<Select
size={'small'}
labelInValue
// mode={_colIndex === 0 ? 'multiple' : null}
mode={'multiple'}
style={{ width: '100%' }}
placeholder={`选择`}
onChange={(v) => handleFieldsItemPick(v, _colIndex, pivotDateColumns[0][_colIndex], 'row')}
value={rowsItemValues?.[pivotDateColumns[0][_colIndex]]}
maxTagCount={1}
maxTagPlaceholder={(omittedValues) => ` + ${omittedValues.length} 更多...`}
allowClear={true}
>
{pivotDateColumnsValues[0][_colIndex].map((ele) => (
<Select.Option key={ele} value={ele}>
{ele}
</Select.Option>
))}
</Select>
</Col>
</Row>
))
: null}
</Col>
</Row>
</Col>
<Col span={12} style={{ borderLeft: '1px solid #d9d9d9' }}>
<Row gutter={8} align={'middle'}>
<Col flex={'6em'} align={'end'}>
<Text strong>: </Text>
</Col>
<Col flex={'auto'}>
<Select
labelInValue
// mode={'multiple'}
style={{ width: '100%' }}
placeholder={`选择`}
onChange={(v) => handleColsPick(v)}
// value={sale_store.salesTrade.pickSales}
// value={columnSelection}
maxTagCount={2}
maxTagPlaceholder={(omittedValues) => ` + ${omittedValues.length} 更多...`}
allowClear={true}
>
{rightFields.map((ele) => (
<Select.Option key={ele.key} value={ele.key}>
{ele.label}
</Select.Option>
))}
</Select>
</Col>
<Col span={24}>
{/* {columnFields.length > 0
? cloneDeep(pivotDateColumnsValues)
.slice(rowFields.length)
.map((_colArr, _colIndex) => (
<>
<Row gutter={8} key={_colArr.join('_')}>
<Col flex={'5em'} align={'end'}>
<Text strong>{filterFieldsMapped[pivotDateColumns[_colIndex + rowFields.length]]?.label || _colIndex + rowFields.length}: </Text>
</Col>
<Col flex={'auto'}>
<Select
size={'small'}
labelInValue
mode={_colIndex + rowFields.length === 0 ? 'multiple' : null}
style={{ width: '100%' }}
placeholder={`选择`}
onChange={(v) => handleFieldsItemPick(v, _colIndex + rowFields.length, pivotDateColumns[_colIndex + rowFields.length], 'col')}
// value={sale_store.salesTrade.pickSales}
maxTagCount={1}
maxTagPlaceholder={(omittedValues) => ` + ${omittedValues.length} 更多...`}
allowClear={true}
>
{pivotDateColumnsValues[_colIndex + rowFields.length].map((ele) => (
<Select.Option key={ele} value={ele}>
{ele}
</Select.Option>
))}
</Select>
</Col>
</Row>
</>
))
: null} */}
</Col>
</Row>
</Col>
</Row>
</Card>
<section>
<Row gutter={16} justify={'space-between'} className="mb-1">
<Col flex={'auto'}>
<h3>
走势: <span style={{ fontSize: 'smaller' }}>{dataFieldAlias[lineConfig.yField].label}</span>
</h3>
</Col>
<Col flex={'1 0 50%'} style={{ textAlign: 'right' }} align={'end'}>
<DateGroupRadio
visible={true}
dataRaw={{ data1: dataBeforeXChange }}
onChange={onChangeXDateFieldGroup}
value={lineChartX}
dataMapper={orderCountDataMapper}
fieldMapper={orderCountDataFieldMapper}
/>
</Col>
</Row>
<Spin spinning={loading}>
<Line {...lineConfig} data={dataSource} />
</Spin>
</section>
<section>
<Spin spinning={loading}>
<h3>
透视汇总表: <span style={{ fontSize: 'smaller' }}>{dataFieldAlias[lineConfig.yField].label}</span>
</h3>
<Table {...targetTableProps} dataSource={pivotTableDataSource} components={{ body: { cell: TdCell } }} />
</Spin>
</section>
</>
);
});
Loading…
Cancel
Save