This commit is contained in:
likun 2025-06-13 17:53:39 +08:00
parent 0e04941e65
commit 4ed261d9b4
15 changed files with 745 additions and 28 deletions

208
ui/package-lock.json generated
View File

@ -9,6 +9,7 @@
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"@ant-design/icons-vue": "^7.0.1", "@ant-design/icons-vue": "^7.0.1",
"ant-design-vue": "^4.0.0-rc.6",
"axios": "^1.8.4", "axios": "^1.8.4",
"echarts": "^5.6.0", "echarts": "^5.6.0",
"element-plus": "^2.9.7", "element-plus": "^2.9.7",
@ -495,6 +496,15 @@
"@babel/core": "^7.0.0-0" "@babel/core": "^7.0.0-0"
} }
}, },
"node_modules/@babel/runtime": {
"version": "7.27.6",
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.27.6.tgz",
"integrity": "sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": { "node_modules/@babel/template": {
"version": "7.27.0", "version": "7.27.0",
"resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.27.0.tgz", "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.27.0.tgz",
@ -567,6 +577,18 @@
"vue": "^3.2.0" "vue": "^3.2.0"
} }
}, },
"node_modules/@emotion/hash": {
"version": "0.9.2",
"resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.9.2.tgz",
"integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
"license": "MIT"
},
"node_modules/@emotion/unitless": {
"version": "0.8.1",
"resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.8.1.tgz",
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==",
"license": "MIT"
},
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.25.2", "version": "0.25.2",
"resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz",
@ -1845,6 +1867,16 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@simonwep/pickr": {
"version": "1.8.2",
"resolved": "https://registry.npmmirror.com/@simonwep/pickr/-/pickr-1.8.2.tgz",
"integrity": "sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==",
"license": "MIT",
"dependencies": {
"core-js": "^3.15.1",
"nanopop": "^2.1.0"
}
},
"node_modules/@sindresorhus/merge-streams": { "node_modules/@sindresorhus/merge-streams": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmmirror.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", "resolved": "https://registry.npmmirror.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
@ -2222,6 +2254,59 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/ant-design-vue": {
"version": "4.0.0-rc.6",
"resolved": "https://registry.npmmirror.com/ant-design-vue/-/ant-design-vue-4.0.0-rc.6.tgz",
"integrity": "sha512-j+GAhgC1p1+nmQVbaEeY2miZ1h+8jBLlxTESX93MwcshVaYTkZNhiyddtl92VvEDJTedzuX+1oT3TP5wG/+tHg==",
"license": "MIT",
"dependencies": {
"@ant-design/colors": "^6.0.0",
"@ant-design/icons-vue": "^6.1.0",
"@babel/runtime": "^7.10.5",
"@ctrl/tinycolor": "^3.5.0",
"@emotion/hash": "^0.9.0",
"@emotion/unitless": "^0.8.0",
"@simonwep/pickr": "~1.8.0",
"array-tree-filter": "^2.1.0",
"async-validator": "^4.0.0",
"csstype": "^3.1.1",
"dayjs": "^1.10.5",
"dom-align": "^1.12.1",
"dom-scroll-into-view": "^2.0.0",
"lodash": "^4.17.21",
"lodash-es": "^4.17.15",
"resize-observer-polyfill": "^1.5.1",
"scroll-into-view-if-needed": "^2.2.25",
"shallow-equal": "^1.0.0",
"stylis": "^4.1.3",
"throttle-debounce": "^5.0.0",
"vue-types": "^3.0.0",
"warning": "^4.0.0"
},
"engines": {
"node": ">=12.22.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/ant-design-vue"
},
"peerDependencies": {
"vue": ">=3.2.0"
}
},
"node_modules/ant-design-vue/node_modules/@ant-design/icons-vue": {
"version": "6.1.0",
"resolved": "https://registry.npmmirror.com/@ant-design/icons-vue/-/icons-vue-6.1.0.tgz",
"integrity": "sha512-EX6bYm56V+ZrKN7+3MT/ubDkvJ5rK/O2t380WFRflDcVFgsvl3NLH7Wxeau6R8DbrO5jWR6DSTC3B6gYFp77AA==",
"license": "MIT",
"dependencies": {
"@ant-design/colors": "^6.0.0",
"@ant-design/icons-svg": "^4.2.1"
},
"peerDependencies": {
"vue": ">=3.0.3"
}
},
"node_modules/anymatch": { "node_modules/anymatch": {
"version": "3.1.3", "version": "3.1.3",
"resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
@ -2249,6 +2334,12 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/array-tree-filter": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
"integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==",
"license": "MIT"
},
"node_modules/async-validator": { "node_modules/async-validator": {
"version": "4.2.5", "version": "4.2.5",
"resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz", "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
@ -2519,6 +2610,12 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/compute-scroll-into-view": {
"version": "1.0.20",
"resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.20.tgz",
"integrity": "sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==",
"license": "MIT"
},
"node_modules/confbox": { "node_modules/confbox": {
"version": "0.2.2", "version": "0.2.2",
"resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.2.2.tgz", "resolved": "https://registry.npmmirror.com/confbox/-/confbox-0.2.2.tgz",
@ -2556,6 +2653,17 @@
"url": "https://github.com/sponsors/mesqueeb" "url": "https://github.com/sponsors/mesqueeb"
} }
}, },
"node_modules/core-js": {
"version": "3.43.0",
"resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.43.0.tgz",
"integrity": "sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==",
"hasInstallScript": true,
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/cross-spawn": { "node_modules/cross-spawn": {
"version": "7.0.6", "version": "7.0.6",
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
@ -2685,6 +2793,18 @@
"node": ">=0.10" "node": ">=0.10"
} }
}, },
"node_modules/dom-align": {
"version": "1.12.4",
"resolved": "https://registry.npmmirror.com/dom-align/-/dom-align-1.12.4.tgz",
"integrity": "sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==",
"license": "MIT"
},
"node_modules/dom-scroll-into-view": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/dom-scroll-into-view/-/dom-scroll-into-view-2.0.1.tgz",
"integrity": "sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==",
"license": "MIT"
},
"node_modules/dotenv": { "node_modules/dotenv": {
"version": "16.5.0", "version": "16.5.0",
"resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.5.0.tgz", "resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.5.0.tgz",
@ -3408,6 +3528,15 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/is-plain-object": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-3.0.1.tgz",
"integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-stream": { "node_modules/is-stream": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-4.0.1.tgz", "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-4.0.1.tgz",
@ -3482,7 +3611,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/jsesc": { "node_modules/jsesc": {
@ -3586,6 +3714,18 @@
"lodash-es": "*" "lodash-es": "*"
} }
}, },
"node_modules/loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
},
"bin": {
"loose-envify": "cli.js"
}
},
"node_modules/lru-cache": { "node_modules/lru-cache": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
@ -3745,6 +3885,12 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
} }
}, },
"node_modules/nanopop": {
"version": "2.4.2",
"resolved": "https://registry.npmmirror.com/nanopop/-/nanopop-2.4.2.tgz",
"integrity": "sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw==",
"license": "MIT"
},
"node_modules/neo-async": { "node_modules/neo-async": {
"version": "2.6.2", "version": "2.6.2",
"resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz", "resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz",
@ -4116,6 +4262,12 @@
"url": "https://github.com/sponsors/jonschlinkert" "url": "https://github.com/sponsors/jonschlinkert"
} }
}, },
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==",
"license": "MIT"
},
"node_modules/reusify": { "node_modules/reusify": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz", "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz",
@ -4695,6 +4847,15 @@
"url": "https://paulmillr.com/funding/" "url": "https://paulmillr.com/funding/"
} }
}, },
"node_modules/scroll-into-view-if-needed": {
"version": "2.2.31",
"resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.31.tgz",
"integrity": "sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==",
"license": "MIT",
"dependencies": {
"compute-scroll-into-view": "^1.0.20"
}
},
"node_modules/scule": { "node_modules/scule": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz", "resolved": "https://registry.npmmirror.com/scule/-/scule-1.3.0.tgz",
@ -4711,6 +4872,12 @@
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
}, },
"node_modules/shallow-equal": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/shallow-equal/-/shallow-equal-1.2.1.tgz",
"integrity": "sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==",
"license": "MIT"
},
"node_modules/shebang-command": { "node_modules/shebang-command": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
@ -4861,6 +5028,12 @@
"integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/stylis": {
"version": "4.3.6",
"resolved": "https://registry.npmmirror.com/stylis/-/stylis-4.3.6.tgz",
"integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==",
"license": "MIT"
},
"node_modules/superjson": { "node_modules/superjson": {
"version": "2.2.2", "version": "2.2.2",
"resolved": "https://registry.npmmirror.com/superjson/-/superjson-2.2.2.tgz", "resolved": "https://registry.npmmirror.com/superjson/-/superjson-2.2.2.tgz",
@ -4931,6 +5104,15 @@
"node": ">=10" "node": ">=10"
} }
}, },
"node_modules/throttle-debounce": {
"version": "5.0.2",
"resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
"integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==",
"license": "MIT",
"engines": {
"node": ">=12.22"
}
},
"node_modules/tinyexec": { "node_modules/tinyexec": {
"version": "0.3.2", "version": "0.3.2",
"resolved": "https://registry.npmmirror.com/tinyexec/-/tinyexec-0.3.2.tgz", "resolved": "https://registry.npmmirror.com/tinyexec/-/tinyexec-0.3.2.tgz",
@ -5468,6 +5650,30 @@
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/vue-types": {
"version": "3.0.2",
"resolved": "https://registry.npmmirror.com/vue-types/-/vue-types-3.0.2.tgz",
"integrity": "sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==",
"license": "MIT",
"dependencies": {
"is-plain-object": "3.0.1"
},
"engines": {
"node": ">=10.15.0"
},
"peerDependencies": {
"vue": "^3.0.0"
}
},
"node_modules/warning": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/warning/-/warning-4.0.3.tgz",
"integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
"license": "MIT",
"dependencies": {
"loose-envify": "^1.0.0"
}
},
"node_modules/webpack-virtual-modules": { "node_modules/webpack-virtual-modules": {
"version": "0.6.2", "version": "0.6.2",
"resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", "resolved": "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",

View File

@ -10,6 +10,7 @@
}, },
"dependencies": { "dependencies": {
"@ant-design/icons-vue": "^7.0.1", "@ant-design/icons-vue": "^7.0.1",
"ant-design-vue": "^4.0.0-rc.6",
"axios": "^1.8.4", "axios": "^1.8.4",
"echarts": "^5.6.0", "echarts": "^5.6.0",
"element-plus": "^2.9.7", "element-plus": "^2.9.7",

View File

@ -8,18 +8,27 @@ import locale from "element-plus/dist/locale/zh-cn.mjs"; // 中文语言
import '@/assets/styles/global.scss' // global css import '@/assets/styles/global.scss' // global css
import 'element-plus/dist/index.css' import 'element-plus/dist/index.css'
import App from './App.vue' import App from './App.vue'
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/reset.css';
import router from './router' import router from './router'
import * as ElementPlusIconsVue from '@element-plus/icons-vue' import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'; import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
import './permission' import './permission'
import * as echarts from 'echarts' import * as echarts from 'echarts'
const pinia = createPinia(); const pinia = createPinia();
pinia.use(piniaPluginPersistedstate); pinia.use(piniaPluginPersistedstate);
const app = createApp(App) const app = createApp(App)
app.config.productionTip = false;
app.use(Antd);
for (const [key, component] of Object.entries(ElementPlusIconsVue)) { for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component) app.component(key, component)
} }

View File

@ -0,0 +1,23 @@
<script setup>
import {ref} from 'vue';
import {defineAsyncComponent} from 'vue';
const editLayout = defineAsyncComponent(() => import("./analyseMetricEditorLayout.vue"))
const editor = defineAsyncComponent(() => import("./editor/event.vue"))
const editorAreaInfo = {
editorPane: editor,
}
const selectValue = ref('')
</script>
<template>
<!-- <a-select ref="select" v-model:value="selectValue" :options="options1"></a-select>-->
<component :is="editLayout" :editorAreaInfo="editorAreaInfo"/>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,66 @@
<script setup>
defineProps({
editorAreaInfo: {
editorPane: null,
}
})
</script>
<template>
<div class="editorContainer .clearfix">
<div class="editorOperationArea">
<component :is="editorAreaInfo.editorPane"/>
</div>
<div class="editorFinishArea">
<div class="editorFinishBtns">
<el-button size="large">
保存
</el-button>
<el-button type="primary" size="large">
计算
</el-button>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.clearfix::after {
content: "";
display: block;
clear: both; /*清除元素左右两侧浮动的属性*/
}
.editorContainer {
width: 100%;
height: 100%;
position: relative;
}
.editorFinishArea {
width: 100%;
height: 60px;
position: absolute;
bottom: 0;
left: 0;
border-top: 1px solid #dddddd;
display: flex;
align-items: center;
justify-content: end;
}
.editorFinishBtns {
margin-right: 10px;
}
.editorOperationArea {
width: 100%;
height: calc(100% - 60px);
position: absolute;
top: 0;
left: 0;
}
</style>

View File

@ -1,11 +0,0 @@
<script setup>
</script>
<template>
</template>
<style scoped>
</style>

View File

@ -0,0 +1,339 @@
<script setup>
import {FunctionOutlined} from '@ant-design/icons-vue';
import {ref, computed} from "vue";
const eventAllData = {
userProperties: [
{
name: "account_id",
alias: "账户id",
propertyType: 2,
},
{
name: "account_name",
alias: "账户名",
propertyType: 2,
},
{
name: "role_id",
alias: "角色id",
propertyType: 2,
},
{
name: "server_id",
alias: "服务器id",
propertyType: 2,
},
{
name: "currency_coin",
alias: "金币数",
propertyType: 1,
},
],
eventDescList: [
{
name: "role_login",
alias: "角色登录",
fields: [
{
name: "sign_day",
alias: "签到天数",
propertyType: 1,
}
]
},
{
name: "item_change",
alias: "item_change",
fields: [
{
name: "item_id",
alias: "item_id",
propertyType: 1,
},
{
name: "item_name",
alias: "item_name",
propertyType: 2,
},
{
name: "num_before",
alias: "num_before",
propertyType: 1,
},
{
name: "num_after",
alias: "num_after",
propertyType: 1,
},
{
name: "delta",
alias: "delta",
propertyType: 1,
}
]
},
{
name: "role_logout",
alias: "角色登出",
fields: [
{
name: "online_duration",
alias: "在线时长",
propertyType: 1,
}
]
}
]
}
const selectEventValue = ref('')
const selectEventOptions = ref([])
eventAllData.eventDescList.forEach((eventInfo) => {
let addOptionInfo = {
value: eventInfo.name,
label: eventInfo.name,
}
if (eventInfo.alias !== undefined && eventInfo.alias !== "") {
addOptionInfo.label = eventInfo.alias
}
selectEventOptions.value.push(addOptionInfo)
})
selectEventValue.value = selectEventOptions.value[0].label
const selectedEventInfo = ref({})
const defaultSelectEventRelationMetrics = {
label: "预置指标",
options: [
{
value: "totalCount",
label: "总次数",
opList: []
},
{
value: "triggerUserCount",
label: "触发用户数",
opList: []
},
{
value: "userAvgCount",
label: "人均次数",
opList: []
}
]
}
const defaultMetricTypeNumberOpList1 = [
"总和", "均值", "人均值", "中位数", "最大值", "最小值", "去重数", "方差", "标准差",
"99分位数", "95分位数", "90分位数", "85分位数", "80分位数", "75分位数", "70分位数",
"60分位数", "50分位数", "40分位数", "30分位数", "20分位数", "10分位数", "5分位数"
]
const defaultMetricTypeNumberOpList2 = [
"totalCount", "avg", "avgPerUser", "median", "max", "min", "distinct", "variance", "standardDeviation",
"99qualtile", "95qualtile", "90qualtile", "85qualtile", "80qualtile", "75qualtile", "70qualtile",
"60qualtile", "50qualtile", "40qualtile", "30qualtile", "20qualtile", "10qualtile", "5qualtile"
]
const defaultMetricTypeNumberOpList = []
const defaultMetricTypeStringOpList = [{value: "distinct", label: "去重数"}]
for (let i = 0; i < defaultMetricTypeNumberOpList1.length; i++) {
defaultMetricTypeNumberOpList.push({
value: defaultMetricTypeNumberOpList2[i],
label: defaultMetricTypeNumberOpList1[i]
})
}
console.log("oplist:", defaultMetricTypeNumberOpList)
const selectedEventRelationMetricValue = ref('')
const disableMetricSelectOp = ref(true)
const selectEventRelationMetrics = computed(() => {
const eventInfo = eventAllData.eventDescList.find((v, i) => v.alias === selectEventValue.value)
if (!eventInfo) {
return [defaultSelectEventRelationMetrics]
}
console.log("选择事件:", eventInfo)
selectedEventInfo.value = eventInfo
let userMetrics = {
label: "用户属性",
options: []
}
let eventMetrics = {
label: "事件属性",
options: []
}
eventInfo.fields.forEach(field => {
let opList = []
if (field.propertyType === 1) {
opList = defaultMetricTypeNumberOpList
} else if (field.propertyType === 2) {
opList = defaultMetricTypeStringOpList
}
eventMetrics.options.push({
value: field.name,
label: field.alias,
opList: opList
})
})
eventAllData.userProperties.forEach(field => {
let opList = []
if (field.propertyType === 1) {
opList = defaultMetricTypeNumberOpList
} else if (field.propertyType === 2) {
opList = defaultMetricTypeStringOpList
}
userMetrics.options.push({
value: field.name,
label: field.alias,
opList: opList
})
})
return [defaultSelectEventRelationMetrics, eventMetrics, userMetrics,]
})
const selectedMetricRelationOpValue = ref('')
const selectMetricRelationOpList = computed(() => {
console.log("selectEventRelationMetrics:", selectedEventRelationMetricValue.value)
console.log("selectEventRelationMetrics:", selectEventRelationMetrics.value)
let opList = []
selectEventRelationMetrics.value.find((v, idx) => {
const selectedMetric = v.options.find((v1, idx1) => {
return v1.value === selectedEventRelationMetricValue.value
})
if (selectedMetric) {
opList = selectedMetric.opList
return true
}
return false
})
console.log("oplist", opList)
selectedMetricRelationOpValue.value = ''
disableMetricSelectOp.value = opList.length === 0;
return opList
})
const onSelectEvent = (value) => {
}
onSelectEvent(selectEventValue.value)
</script>
<template>
<div class="editorAreaOuter">
<div class="editorAreaInner">
<el-row style="height: 40px" align="middle">
<el-col :span="6">
<span style="font-weight: bold;">
分析指标
</span>
</el-col>
<el-col :span="10" :offset="8">
<el-row justify="end">
<el-button class="editorTopRightToolBarBtn">
<el-icon :size="20">
<Plus/>
</el-icon>
</el-button>
<el-button class="editorTopRightToolBarBtn">
<FunctionOutlined style="font-size: 20px"/>
</el-button>
</el-row>
</el-col>
</el-row>
<el-row style="width: 100%;height: 50px;">
<a-space :size="5">
<div
style="background-color: #202241;border-radius: 5px;;width: 3px;height: 35px;display: inline-flex;justify-content: center;align-items: center;">
<!-- <p style="font-weight: bold;color: white;margin: 0">1</p>-->
</div>
<a-select ref="select" v-model:value="selectEventValue" :options="selectEventOptions" @change="onSelectEvent"
style="width: 100px;margin: 0"/>
<div
style="background-color: #202241;border-radius: 5px;width: 25px;height: 25px;display: flex;justify-content: center;align-items: center;">
<p style="color: white;margin: 0"></p>
</div>
<a-select ref="metricSelect" v-model:value="selectedEventRelationMetricValue"
:options="selectEventRelationMetrics" @change=""
style="width: 100px;margin: 0"/>
<!-- <div-->
<!-- style="background-color: #202241;border-radius: 5px;;width: 25px;height: 25px;display: flex;justify-content: center;align-items: center;">-->
<!-- <p style="color: white;margin: 0">.</p>-->
<!-- </div>-->
<div
style="height: 100%;display: inline-flex;flex-direction: column;justify-content: end">
<p style="color: black;font-weight: bold;font-size: 20px;margin: 0">·</p>
</div>
<a-select ref="metricSelect" :disabled="disableMetricSelectOp" v-model:value="selectedMetricRelationOpValue"
:options="selectMetricRelationOpList" @change=""
style="width: 100px;margin: 0"/>
</a-space>
</el-row>
<el-row style="height: 30px"></el-row>
<el-row style="height: 40px" align="middle">
<el-col :span="6">
<span style="font-weight: bold;">
全局筛选
</span>
</el-col>
<el-col :span="10" :offset="8">
<el-row justify="end">
<el-button class="editorTopRightToolBarBtn">
<el-icon :size="20">
<Plus/>
</el-icon>
</el-button>
</el-row>
</el-col>
</el-row>
<el-row style="height: 30px"></el-row>
<el-row style="height: 40px" align="middle">
<el-col :span="6">
<span style="font-weight: bold;">
分组项
</span>
</el-col>
<el-col :span="10" :offset="8">
<el-row justify="end">
<el-button class="editorTopRightToolBarBtn">
<el-icon :size="20">
<Plus/>
</el-icon>
</el-button>
</el-row>
</el-col>
</el-row>
</div>
</div>
</template>
<style scoped>
.editorAreaOuter {
width: 100%;
height: 100%;
position: relative;
}
.editorAreaInner {
width: calc(100% - 30px);
height: calc(100% - 10px);
position: absolute;
top: 10px;
left: 15px;
}
.editorTopRightToolBarBtn {
margin: 0;
padding: 0 8px 0 8px;
border: 0
}
</style>

View File

@ -2,7 +2,7 @@
import {ref, onMounted, nextTick, watchEffect} from 'vue'; import {ref, onMounted, nextTick, watchEffect} from 'vue';
import {getTodayBegin} from "@/utils/time.js"; import {getTodayBegin} from "@/utils/time.js";
const value1 = ref(''); const value1 = ref('过去7天');
const pass7DaysStart = getTodayBegin() const pass7DaysStart = getTodayBegin()
pass7DaysStart.setTime(pass7DaysStart.getTime() - 3600 * 1000 * 24 * 7) pass7DaysStart.setTime(pass7DaysStart.getTime() - 3600 * 1000 * 24 * 7)
@ -92,4 +92,10 @@ const shortcuts = [
.el-picker__popper.el-popper .el-popper__arrow:before { .el-picker__popper.el-popper .el-popper__arrow:before {
display: none; display: none;
} }
</style>
<style lang="scss">
p {
margin: 0;
}
</style> </style>

View File

@ -1,14 +1,24 @@
<script setup> <script setup>
import {defineAsyncComponent} from "vue"; import {defineAsyncComponent} from "vue";
import analyseEditor from './components/analyse/analyseMetricEditorEvent.vue';
const analyseMainIndex = defineAsyncComponent(() => import('./layout/analyseMainIndex.vue')) const analyseMainIndex = defineAsyncComponent(() => import('./layout/analyseMainIndex.vue'))
const analyseCustomInfo = {
analyseName: "事件分析",
leftPaneInfo: {
paneComponent: analyseEditor,
},
rightPaneInfo: {
paneComponent: analyseEditor,
}
}
</script> </script>
<template> <template>
<div style="height: 100%"> <analyseMainIndex :analyseCustomInfo="analyseCustomInfo"/>
<analyseMainIndex/>
</div>
</template> </template>
<style scoped> <style scoped>

View File

@ -3,6 +3,20 @@ import {Splitpanes, Pane} from 'splitpanes'
import 'splitpanes/dist/splitpanes.css' import 'splitpanes/dist/splitpanes.css'
import {defineAsyncComponent} from 'vue'; import {defineAsyncComponent} from 'vue';
const props = defineProps({
analyseCustomInfo: {
analyseName: '', //
leftPaneInfo: {
paneComponent: null,
},
rightPaneInfo: {
paneComponent: null,
},
},
})
console.log("custom info:", props.analyseCustomInfo)
const contentLeft = defineAsyncComponent(() => import("./analyseMainContentLeft.vue")) const contentLeft = defineAsyncComponent(() => import("./analyseMainContentLeft.vue"))
const contentRight = defineAsyncComponent(() => import("./analyseMainContentRight.vue")) const contentRight = defineAsyncComponent(() => import("./analyseMainContentRight.vue"))
@ -11,10 +25,10 @@ const contentRight = defineAsyncComponent(() => import("./analyseMainContentRigh
<template> <template>
<Splitpanes> <Splitpanes>
<Pane size="25" min-size="20" max-size="30"> <Pane size="25" min-size="20" max-size="30">
<contentLeft/> <contentLeft :paneInfo="analyseCustomInfo.leftPaneInfo"/>
</Pane> </Pane>
<Pane size="75" min-size="70" max-size="80"> <Pane size="75" min-size="70" max-size="80">
<contentRight/> <contentRight :paneInfo="analyseCustomInfo.rightPaneInfo"/>
</Pane> </Pane>
</Splitpanes> </Splitpanes>
</template> </template>

View File

@ -1,13 +1,22 @@
<script setup> <script setup>
const props = defineProps({
paneInfo: {
paneComponent: null,
},
})
</script> </script>
<template> <template>
<div class="content pane-left"> <div class="contentPane">
左边部分 <component :is="paneInfo.paneComponent"/>
</div> </div>
</template> </template>
<style scoped> <style scoped>
.contentPane {
width: 100%;
height: 100%;
}
</style> </style>

View File

@ -1,6 +1,12 @@
<script setup> <script setup>
import {defineAsyncComponent} from 'vue'; import {defineAsyncComponent} from 'vue';
const props = defineProps({
paneInfo: {
paneComponent: null,
},
})
const layoutToolbar = defineAsyncComponent(() => import("./analyseMainContentRightToolbar.vue")) const layoutToolbar = defineAsyncComponent(() => import("./analyseMainContentRightToolbar.vue"))
const layoutResult = defineAsyncComponent(() => import("./analyseMainContentRightResult.vue")) const layoutResult = defineAsyncComponent(() => import("./analyseMainContentRightResult.vue"))
</script> </script>

View File

@ -112,16 +112,41 @@ onBeforeUnmount(() => {
<el-row> <el-row>
<el-table :data="testResultTable"> <el-table :data="testResultTable">
<el-table-column prop="metric" label="指标"></el-table-column> <el-table-column prop="metric" label="指标"></el-table-column>
<el-table-column prop="stageAcc" label="阶段汇总"></el-table-column> <el-table-column label="阶段汇总">
<el-table-column prop="day20250530" label="2025-05-30(五)"></el-table-column> <template #default="scope">
<el-table-column prop="day20250531" label="2025-05-31(六)"></el-table-column> <a href="#">{{ scope.row.stageAcc }}</a>
<el-table-column prop="day20250601" label="2025-06-01(日)"></el-table-column> </template>
<el-table-column prop="day20250602" label="2025-06-02(一)"></el-table-column> </el-table-column>
<el-table-column label="2025-05-30(五)">
<template #default="scope">
<a href="#">{{ scope.row.day20250530 }}</a>
</template>
</el-table-column>
<el-table-column label="2025-05-31(六)">
<template #default="scope">
<a href="#">{{ scope.row.day20250531 }}</a>
</template>
</el-table-column>
<el-table-column label="2025-06-01(日)">
<template #default="scope">
<a href="#">{{ scope.row.day20250601 }}</a>
</template>
</el-table-column>
<el-table-column label="2025-06-02(一)">
<template #default="scope">
<a href="#">{{ scope.row.day20250602 }}</a>
</template>
</el-table-column>
</el-table> </el-table>
</el-row> </el-row>
</template> </template>
<style scoped> <style scoped>
a {
color: #333;
}
.clearfix::after { .clearfix::after {
content: ""; content: "";
display: block; display: block;

View File

@ -49,6 +49,7 @@
<style scoped lang="scss"> <style scoped lang="scss">
.headerAnalyseDesc { .headerAnalyseDesc {
height: 100%;
display: flex; display: flex;
float: left; float: left;
justify-content: center; justify-content: center;
@ -56,6 +57,7 @@
} }
.headerAnalyseToolbar { .headerAnalyseToolbar {
height: 100%;
display: flex; display: flex;
float: right; float: right;
justify-content: center; justify-content: center;

View File

@ -1,9 +1,21 @@
<script setup> <script setup>
import {defineAsyncComponent} from 'vue'; import {defineAsyncComponent} from 'vue';
const props = defineProps({
analyseCustomInfo: {
analyseName: '', //
leftPaneInfo: {
paneComponent: null,
},
rightPaneInfo: {
paneComponent: null,
},
},
})
const layoutHeader = defineAsyncComponent(() => import("./analyseMainHeader.vue")) const layoutHeader = defineAsyncComponent(() => import("./analyseMainHeader.vue"))
const layoutContent = defineAsyncComponent(() => import("./analyseMainContent.vue")) const layoutContent = defineAsyncComponent(() => import("./analyseMainContent.vue"))
</script> </script>
<template> <template>
@ -12,7 +24,7 @@ const layoutContent = defineAsyncComponent(() => import("./analyseMainContent.vu
<layoutHeader/> <layoutHeader/>
</el-row> </el-row>
<el-row class="analyseMainContent"> <el-row class="analyseMainContent">
<layoutContent/> <layoutContent :analyseCustomInfo="analyseCustomInfo"/>
</el-row> </el-row>
</div> </div>
</template> </template>