diff --git a/package-lock.json b/package-lock.json index ae9d88f..a6d9faa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,12 @@ "name": "management", "version": "0.0.0", "dependencies": { + "@kjgl77/datav-vue3": "^1.7.4", "@vueuse/core": "^13.1.0", "animate.css": "^4.1.1", "axios": "^1.8.1", "dayjs": "^1.11.13", + "echarts": "^5.6.0", "event-source-polyfill": "^1.0.31", "js-base64": "^3.7.7", "jsencrypt": "^3.3.2", @@ -435,6 +437,15 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.27.1", + "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.27.1.tgz", + "integrity": "sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.27.0", "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.27.0.tgz", @@ -900,6 +911,52 @@ "node": ">=18" } }, + "node_modules/@jiaminghi/bezier-curve": { + "version": "0.0.9", + "resolved": "https://registry.npmmirror.com/@jiaminghi/bezier-curve/-/bezier-curve-0.0.9.tgz", + "integrity": "sha512-u9xJPOEl6Dri2E9FfmJoGxYQY7vYJkURNX04Vj64tdi535tPrpkuf9Sm0lNr3QTKdHQh0DdNRsaa62FLQNQEEw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5" + } + }, + "node_modules/@jiaminghi/c-render": { + "version": "0.4.3", + "resolved": "https://registry.npmmirror.com/@jiaminghi/c-render/-/c-render-0.4.3.tgz", + "integrity": "sha512-FJfzj5hGj7MLqqqI2D7vEzHKbQ1Ynnn7PJKgzsjXaZpJzTqs2Yw5OSeZnm6l7Qj7jyPAP53lFvEQNH4o4j6s+Q==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@jiaminghi/bezier-curve": "*", + "@jiaminghi/color": "*", + "@jiaminghi/transition": "*" + } + }, + "node_modules/@jiaminghi/charts": { + "version": "0.2.18", + "resolved": "https://registry.npmmirror.com/@jiaminghi/charts/-/charts-0.2.18.tgz", + "integrity": "sha512-K+HXaOOeWG9OOY1VG6M4mBreeeIAPhb9X+khG651AbnwEwL6G2UtcAQ8GWCq6GzhczcLwwhIhuaHqRygwHC0sA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5", + "@jiaminghi/c-render": "^0.4.3" + } + }, + "node_modules/@jiaminghi/color": { + "version": "1.1.3", + "resolved": "https://registry.npmmirror.com/@jiaminghi/color/-/color-1.1.3.tgz", + "integrity": "sha512-ZY3hdorgODk4OSTbxyXBPxAxHPIVf9rPlKJyK1C1db46a50J0reFKpAvfZG8zMG3lvM60IR7Qawgcu4ZDO3+Hg==", + "license": "MIT" + }, + "node_modules/@jiaminghi/transition": { + "version": "1.1.11", + "resolved": "https://registry.npmmirror.com/@jiaminghi/transition/-/transition-1.1.11.tgz", + "integrity": "sha512-owBggipoHMikDHHDW5Gc7RZYlVuvxHADiU4bxfjBVkHDAmmck+fCkm46n2JzC3j33hWvP9nSCAeh37t6stgWeg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.5.5" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.8", "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", @@ -957,6 +1014,86 @@ "resolved": "https://registry.npmmirror.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz", "integrity": "sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==" }, + "node_modules/@kjgl77/datav-vue3": { + "version": "1.7.4", + "resolved": "https://registry.npmmirror.com/@kjgl77/datav-vue3/-/datav-vue3-1.7.4.tgz", + "integrity": "sha512-zYVTVKkklUxwtiNKS1qPBilm4rTW+WItfp0zVpaRAI8wgXkLSPbDR9xPq2+UcU/Jft7/DVdMfBp709E2ResuPQ==", + "license": "MIT", + "dependencies": { + "@jiaminghi/c-render": "^0.4.3", + "@jiaminghi/charts": "^0.2.18", + "@jiaminghi/color": "^1.1.3", + "@vueuse/core": "^10.11.1" + } + }, + "node_modules/@kjgl77/datav-vue3/node_modules/@types/web-bluetooth": { + "version": "0.0.20", + "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz", + "integrity": "sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==", + "license": "MIT" + }, + "node_modules/@kjgl77/datav-vue3/node_modules/@vueuse/core": { + "version": "10.11.1", + "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-10.11.1.tgz", + "integrity": "sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.20", + "@vueuse/metadata": "10.11.1", + "@vueuse/shared": "10.11.1", + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@kjgl77/datav-vue3/node_modules/@vueuse/metadata": { + "version": "10.11.1", + "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.11.1.tgz", + "integrity": "sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@kjgl77/datav-vue3/node_modules/@vueuse/shared": { + "version": "10.11.1", + "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-10.11.1.tgz", + "integrity": "sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==", + "license": "MIT", + "dependencies": { + "vue-demi": ">=0.14.8" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@kjgl77/datav-vue3/node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2561,6 +2698,16 @@ "node": ">= 0.4" } }, + "node_modules/echarts": { + "version": "5.6.0", + "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz", + "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.6.1" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.125", "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.125.tgz", @@ -4415,6 +4562,12 @@ "resolved": "https://registry.npmmirror.com/treemate/-/treemate-0.3.11.tgz", "integrity": "sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==" }, + "node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, "node_modules/typescript": { "version": "5.7.3", "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.7.3.tgz", @@ -5084,6 +5237,15 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zrender": { + "version": "5.6.1", + "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.1.tgz", + "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } } } } diff --git a/package.json b/package.json index e3ddd2b..cfc4912 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,17 @@ "type-check": "vue-tsc --build" }, "dependencies": { + "@kjgl77/datav-vue3": "^1.7.4", "@vueuse/core": "^13.1.0", "animate.css": "^4.1.1", "axios": "^1.8.1", "dayjs": "^1.11.13", + "echarts": "^5.6.0", "event-source-polyfill": "^1.0.31", "js-base64": "^3.7.7", "jsencrypt": "^3.3.2", "lodash-es": "^4.17.21", + "naive-ui": "^2.41.0", "pinia": "^3.0.1", "pinia-plugin-persistedstate": "^4.2.0", "sass": "^1.85.1", @@ -27,8 +30,7 @@ "unplugin-auto-import": "^19.1.1", "unplugin-vue-components": "^28.4.1", "vue": "^3.5.13", - "vue-router": "^4.5.0", - "naive-ui": "^2.41.0" + "vue-router": "^4.5.0" }, "devDependencies": { "@tsconfig/node22": "^22.0.0", diff --git a/src/assets/scss/_variables.scss b/src/assets/scss/_variables.scss new file mode 100644 index 0000000..0a84b89 --- /dev/null +++ b/src/assets/scss/_variables.scss @@ -0,0 +1,102 @@ +// 颜色 +$colors: ( + "primary": #db9e3f, + "info-1": #4394e4, + "info": #4b67af, + "white": #ffffff, + "light": #f9f9f9, + "grey-1": #999999, + "grey": #666666, + "dark-1": #5f5f5f, + "dark": #222222, + "black-1": #171823, + "black": #000000, +); + +// 字体大小 +$base-font-size: 16px; +$font-sizes: ( + xxs: 0.1, + //8px + xs: 0.125, + //10px + sm: 0.2875, + //12px + md: 0.1625, + //13px + lg: 0.175, + //14px + xl: 0.2, + //16px + xxl: 0.225, + //18px + xxxl: 0.25 //20px,,,, +); + +// 宽高 +.w-100 { + width: 100%; +} + +.h-100 { + height: 100%; +} + +//flex +.d-flex { + display: flex; +} + +.flex-column { + flex-direction: column; +} + +.flex-wrap { + flex-wrap: wrap; +} + +.flex-nowrap { + flex-wrap: nowrap; +} + +$flex-jc: ( + start: flex-start, + end: flex-end, + center: center, + between: space-between, + around: space-around, + evenly: space-evenly, +); + +$flex-ai: ( + start: flex-start, + end: flex-end, + center: center, + stretch: stretch, +); + +.flex-1 { + flex: 1; +} + +//.mt-1 => margin top +//spacing +$spacing-types: ( + m: margin, + p: padding, +); +$spacing-directions: ( + t: top, + r: right, + b: bottom, + l: left, +); +$spacing-base-size: 16px; +$spacing-sizes: ( + 0: 0, + 1: 0.25, + 2: 0.5, + 3: 1, + 4: 1.5, + 5: 3, +); \ No newline at end of file diff --git a/src/assets/scss/common.scss b/src/assets/scss/common.scss index 721b6d4..65f7a60 100644 --- a/src/assets/scss/common.scss +++ b/src/assets/scss/common.scss @@ -110,24 +110,31 @@ .mt#{$i} { margin-top: #{$i}px !important; } + .mr#{$i} { margin-right: #{$i}px !important; } + .mb#{$i} { margin-bottom: #{$i}px !important; } + .ml#{$i} { margin-left: #{$i}px !important; } + .pt#{$i} { padding-top: #{$i}px !important; } + .pr#{$i} { padding-right: #{$i}px !important; } + .pb#{$i} { padding-bottom: #{$i}px !important; } + .pl#{$i} { padding-left: #{$i}px !important; } @@ -484,4 +491,4 @@ /* 鼠标悬浮手指 */ .pointer { cursor: pointer; -} +} \ No newline at end of file diff --git a/src/assets/scss/style.scss b/src/assets/scss/style.scss new file mode 100644 index 0000000..f0f4640 --- /dev/null +++ b/src/assets/scss/style.scss @@ -0,0 +1,194 @@ +@import "./variables"; + +// 全局样式 +* { + margin: 0; + padding: 0; + list-style-type: none; + box-sizing: border-box; + outline: none; +} + +html { + margin: 0; + padding: 0; +} + +body { + // font-family: Arial, Helvetica, sans-serif; + // line-height: 1.2em; + // background-color: #f1f1f1; + margin: 0; + padding: 0; + overflow: hidden; +} + +a { + color: #343440; + text-decoration: none; + box-sizing: border-box; +} + +.clearfix { + &::after { + content: ""; + display: table; + height: 0; + line-height: 0; + visibility: hidden; + clear: both; + } +} + +// 图标 +.iconfont { + font-size: 20px !important; + color: #5cd9e8; +} + +//浮动 +.float-r { + float: right; +} + +//浮动 +.float-l { + float: left; +} + +// 字体加粗 +.fw-b { + font-weight: bold; +} + +//文章一行显示,多余省略号显示 +.title-item { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.bg-color-black { + background-color: rgba(19, 25, 47, 0.6); +} + +.bg-color-blue { + background-color: #1a5cd7; +} + +.colorBlack { + color: #272727 !important; + + &:hover { + color: #272727 !important; + } +} + +.colorGrass { + color: #33cea0; + + &:hover { + color: #33cea0 !important; + } +} + +.colorRed { + color: #ff5722; + + &:hover { + color: #ff5722 !important; + } +} + +.colorText { + color: #d3d6dd !important; + + &:hover { + color: #d3d6dd !important; + } +} + +.colorBlue { + color: #257dff !important; + + &:hover { + color: #257dff !important; + } +} + +//颜色 +@each $colorkey, $color in $colors { + .text-#{$colorkey} { + color: $color; + } + + .bg-#{$colorkey} { + background-color: $color; + } +} + +//对齐 +@each $var in (left, center, right) { + .text-#{$var} { + text-align: $var !important; + } +} + +//flex +@each $key, $value in $flex-jc { + .jc-#{$key} { + justify-content: $value; + } +} + +@each $key, $value in $flex-ai { + .ai-#{$key} { + align-items: $value; + } +} + +//字体 +@each $fontkey, $fontvalue in $font-sizes { + .fs-#{$fontkey} { + font-size: $fontvalue * $base-font-size; + } +} + +//.mt-1 => margin top +//spacing + +@each $typekey, $type in $spacing-types { + + //.m-1 + @each $sizekey, $size in $spacing-sizes { + .#{$typekey}-#{$sizekey} { + #{$type}: $size * $spacing-base-size; + } + } + + //.mx-1 + @each $sizekey, $size in $spacing-sizes { + .#{$typekey}x-#{$sizekey} { + #{$type}-left: $size * $spacing-base-size; + #{$type}-right: $size * $spacing-base-size; + } + + .#{$typekey}y-#{$sizekey} { + #{$type}-top: $size * $spacing-base-size; + #{$type}-bottom: $size * $spacing-base-size; + } + } + + //.mt-1 + @each $directionkey, $direction in $spacing-directions { + @each $sizekey, $size in $spacing-sizes { + .#{$typekey}#{$directionkey}-#{$sizekey} { + #{$type}-#{$direction}: $size * $spacing-base-size; + } + } + } + + .#{$typekey} { + #{$type}: 0; + } +} \ No newline at end of file diff --git a/src/components/customFileUpload/index.ts b/src/components/customFileUpload/index.ts index 8d229c4..4704fb3 100644 --- a/src/components/customFileUpload/index.ts +++ b/src/components/customFileUpload/index.ts @@ -8,9 +8,9 @@ interface OBJ { objectUrl: string; preSignedUrl: string; } -// export const getPreSignedUrl = async (fileName: string) => { -// const resp = await api.get("/file/getPreSignedUrl", { -// fileName, -// }); -// return resp.data as OBJ; -// }; +export const getPreSignedUrl = async (fileName: string) => { + const resp = await api.get("/file/getPreSignedUrl", { + fileName, + }); + return resp.data as OBJ; +}; diff --git a/src/components/customImageUpload/index.vue b/src/components/customImageUpload/index.vue index 1f9ddcd..c68fa7e 100644 --- a/src/components/customImageUpload/index.vue +++ b/src/components/customImageUpload/index.vue @@ -14,7 +14,7 @@ > 选择照片上传 diff --git a/src/main.ts b/src/main.ts index 4c4dbe7..54198a4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,19 +1,16 @@ import { createApp } from "vue"; - -// pinia store import pinia from "@/stores"; import "animate.css"; import App from "./App.vue"; import router from "./router"; import "./assets/scss/common.scss"; -import './assets/main.scss' -// import { initEnums, } from "@/utils/emnus"; - -// initEnums(); - +import "./assets/main.scss"; +// import "./assets/scss/_variables.scss"; +import './assets/scss/style.scss'; +// @ts-ignore +import DataVVue3 from "@kjgl77/datav-vue3"; const app = createApp(App); - app.use(router); app.use(pinia); - +app.use(DataVVue3); app.mount("#app"); diff --git a/src/views/overviewLargeScreen/assets/pageBg.png b/src/views/overviewLargeScreen/assets/pageBg.png new file mode 100644 index 0000000..d393f2b Binary files /dev/null and b/src/views/overviewLargeScreen/assets/pageBg.png differ diff --git a/src/views/overviewLargeScreen/components/bottomLeft/chart/draw.vue b/src/views/overviewLargeScreen/components/bottomLeft/chart/draw.vue new file mode 100644 index 0000000..69a7070 --- /dev/null +++ b/src/views/overviewLargeScreen/components/bottomLeft/chart/draw.vue @@ -0,0 +1,146 @@ + + + diff --git a/src/views/overviewLargeScreen/components/bottomLeft/chart/index.vue b/src/views/overviewLargeScreen/components/bottomLeft/chart/index.vue new file mode 100644 index 0000000..a5929ce --- /dev/null +++ b/src/views/overviewLargeScreen/components/bottomLeft/chart/index.vue @@ -0,0 +1,71 @@ + + + diff --git a/src/views/overviewLargeScreen/components/bottomLeft/index.vue b/src/views/overviewLargeScreen/components/bottomLeft/index.vue new file mode 100644 index 0000000..46631ec --- /dev/null +++ b/src/views/overviewLargeScreen/components/bottomLeft/index.vue @@ -0,0 +1,47 @@ + + + + + diff --git a/src/views/overviewLargeScreen/components/bottomRight/chart/draw.tsx b/src/views/overviewLargeScreen/components/bottomRight/chart/draw.tsx new file mode 100644 index 0000000..c9af240 --- /dev/null +++ b/src/views/overviewLargeScreen/components/bottomRight/chart/draw.tsx @@ -0,0 +1,365 @@ +import { defineComponent, watch, ref } from 'vue'; +// 声明类型 +const PropsType = { + cdata: { + type: Object, + require: true + } +} as const + +// 定义主体 +export default defineComponent({ + props: PropsType, + setup(props) { + // 定义 ref + const chartRef = ref() + // 定义颜色 + const colorList = { + linearYtoG: { + type: "linear", + x: 0, + y: 0, + x2: 1, + y2: 1, + colorStops: [ + { + offset: 0, + color: "#f5b44d" + }, + { + offset: 1, + color: "#28f8de" + } + ] + }, + linearGtoB: { + type: "linear", + x: 0, + y: 0, + x2: 1, + y2: 0, + colorStops: [ + { + offset: 0, + color: "#43dfa2" + }, + { + offset: 1, + color: "#28f8de" + } + ] + }, + linearBtoG: { + type: "linear", + x: 0, + y: 0, + x2: 1, + y2: 0, + colorStops: [ + { + offset: 0, + color: "#1c98e8" + }, + { + offset: 1, + color: "#28f8de" + } + ] + }, + areaBtoG: { + type: "linear", + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { + offset: 0, + color: "rgba(35,184,210,.2)" + }, + { + offset: 1, + color: "rgba(35,184,210,0)" + } + ] + } + } + // 配置项 + let options ={} + + // 监听 + watch( + () => props.cdata, + (val: any) => { + options = { + title: { + text: "", + textStyle: { + color: "#D3D6DD", + fontSize: 24, + fontWeight: "normal" + }, + subtext: val.year + "/" + val.weekCategory[6], + subtextStyle: { + color: "#fff", + fontSize: 16 + }, + top: 50, + left: 80 + }, + legend: { + top: 120, + left: 80, + orient: "vertical", + itemGap: 15, + itemWidth: 12, + itemHeight: 12, + data: ["平均指标", "我的指标"], + textStyle: { + color: "#fff", + fontSize: 14 + } + }, + tooltip: { + trigger: "item" + }, + radar: { + center: ["68%", "27%"], + radius: "40%", + name: { + color: "#fff" + }, + splitNumber: 8, + axisLine: { + lineStyle: { + color: colorList.linearYtoG, + opacity: 0.6 + } + }, + splitLine: { + lineStyle: { + color: colorList.linearYtoG, + opacity: 0.6 + } + }, + splitArea: { + areaStyle: { + color: "#fff", + opacity: 0.1, + shadowBlur: 25, + shadowColor: "#000", + shadowOffsetX: 0, + shadowOffsetY: 5 + } + }, + indicator: [ + { + name: "服务态度", + max: val.maxData + }, + { + name: "产品质量", + max: 10 + }, + { + name: "任务效率", + max: 12 + }, + { + name: "售后保障", + max: 3.5 + } + ] + }, + grid: { + left: 90, + right: 80, + bottom: '15%', + top: "50%" + }, + xAxis: { + type: "category", + position: "bottom", + axisLine: true, + axisLabel: { + color: "rgba(255,255,255,.8)", + fontSize: 12 + }, + data: val.weekCategory + }, + // 下方Y轴 + yAxis: { + name: "工单", + nameLocation: "end", + nameGap: 24, + nameTextStyle: { + color: "rgba(255,255,255,.5)", + fontSize: 14 + }, + max: val.maxData, + splitNumber: 4, + + axisLine: { + lineStyle: { + opacity: 0 + } + }, + splitLine: { + show: true, + lineStyle: { + color: "#fff", + opacity: 0.1 + } + }, + axisLabel: { + color: "rgba(255,255,255,.8)", + fontSize: 12 + } + }, + series: [ + { + name: "", + type: "radar", + symbolSize: 0, + data: [ + { + value: val.radarDataAvg[6], + name: "平均指标", + itemStyle: { + normal: { + color: "#f8d351" + } + }, + lineStyle: { + normal: { + opacity: 0 + } + }, + areaStyle: { + normal: { + color: "#f8d351", + shadowBlur: 25, + shadowColor: "rgba(248,211,81,.3)", + shadowOffsetX: 0, + shadowOffsetY: -10, + opacity: 1 + } + } + }, + { + value: val.radarData[6], + name: "我的指标", + itemStyle: { + normal: { + color: "#43dfa2" + } + }, + lineStyle: { + normal: { + opacity: 0 + } + }, + areaStyle: { + normal: { + color: colorList.linearGtoB, + shadowBlur: 15, + shadowColor: "rgba(0,0,0,.2)", + shadowOffsetX: 0, + shadowOffsetY: 5, + opacity: 0.8 + } + } + } + ] + }, + { + name: "", + type: "line", + smooth: true, + symbol: "emptyCircle", + symbolSize: 8, + itemStyle: { + normal: { + color: "#fff" + } + }, + lineStyle: { + normal: { + color: colorList.linearBtoG, + width: 3 + } + }, + areaStyle: { + normal: { + color: colorList.areaBtoG + } + }, + data: val.weekLineData, + lineSmooth: true, + markLine: { + silent: true, + data: [ + { + type: "average", + name: "平均值" + } + ], + precision: 0, + label: { + normal: { + formatter: "平均值: \n {c}" + } + }, + lineStyle: { + normal: { + color: "rgba(248,211,81,.7)" + } + } + }, + tooltip: { + position: "top", + formatter: "{c} m", + backgroundColor: "rgba(28,152,232,.2)", + padding: 6 + } + }, + { + name: "占位背景", + type: "bar", + itemStyle: { + normal: { + show: true, + color: "#000", + opacity: 0 + } + }, + silent: true, + barWidth: "50%", + data: val.weekMaxData, + animation: false + } + ] + } + // 手动触发更新 + if (chartRef.value) { + // 通过初始化参数打入数据 + chartRef.value.initChart(options) + } + }, + { + immediate: true, + deep: true + } + ) + + return () => { + const height = "480px" + const width = "100%" + + return
+ +
+ } + } +}) + diff --git a/src/views/overviewLargeScreen/components/bottomRight/chart/index.tsx b/src/views/overviewLargeScreen/components/bottomRight/chart/index.tsx new file mode 100644 index 0000000..cbab09f --- /dev/null +++ b/src/views/overviewLargeScreen/components/bottomRight/chart/index.tsx @@ -0,0 +1,92 @@ +import { defineComponent, reactive, onMounted, ref, onUnmounted } from "vue"; +import Draw from "./draw"; + +export default defineComponent({ + components: { + Draw, + }, + setup() { + const drawTiming = ref(0); + const cdata = reactive({ + year: null, + weekCategory: [], + radarData: [], + radarDataAvg: [], + maxData: 12000, + weekMaxData: [], + weekLineData: [], + }); + + // methods + const setData = () => { + // 清空轮询数据 + cdata.weekCategory = []; + cdata.weekMaxData = []; + cdata.weekLineData = []; + cdata.radarData = []; + cdata.radarDataAvg = []; + + const dateBase = new Date(); + cdata.year = dateBase.getFullYear(); + // 周数据 + for (let i = 0; i < 7; i++) { + // 日期 + const date = new Date(); + cdata.weekCategory.unshift( + [date.getMonth() + 1, date.getDate() - i].join("/") + ); + + // 折线图数据 + cdata.weekMaxData.push(cdata.maxData); + const distance = Math.round(Math.random() * 11000 + 500); + cdata.weekLineData.push(distance); + + // 雷达图数据 + // 我的指标 + const averageSpeed = +(Math.random() * 5 + 3).toFixed(3); + const maxSpeed = averageSpeed + +(Math.random() * 3).toFixed(2); + const hour = +(distance / 1000 / averageSpeed).toFixed(1); + const radarDayData = [distance, averageSpeed, maxSpeed, hour]; + cdata.radarData.unshift(radarDayData); + + // 平均指标 + const distanceAvg = Math.round(Math.random() * 8000 + 4000); + const averageSpeedAvg = +(Math.random() * 4 + 4).toFixed(3); + const maxSpeedAvg = averageSpeedAvg + +(Math.random() * 2).toFixed(2); + const hourAvg = +(distance / 1000 / averageSpeed).toFixed(1); + const radarDayDataAvg = [ + distanceAvg, + averageSpeedAvg, + maxSpeedAvg, + hourAvg, + ]; + cdata.radarDataAvg.unshift(radarDayDataAvg); + } + }; + + // 定时函数 + const drawTimingFn = () => { + setData(); + drawTiming.value = setInterval(() => { + setData(); + }, 6000); + }; + + // 生命周期 + onMounted(() => { + drawTimingFn(); + }); + + onUnmounted(() => { + clearInterval(drawTiming.value); + }); + + return () => { + return ( +
+ +
+ ); + }; + }, +}); diff --git a/src/views/overviewLargeScreen/components/bottomRight/index.vue b/src/views/overviewLargeScreen/components/bottomRight/index.vue new file mode 100644 index 0000000..1832a00 --- /dev/null +++ b/src/views/overviewLargeScreen/components/bottomRight/index.vue @@ -0,0 +1,47 @@ + + + + + diff --git a/src/views/overviewLargeScreen/components/center/chart/draw.tsx b/src/views/overviewLargeScreen/components/center/chart/draw.tsx new file mode 100644 index 0000000..6ed09ec --- /dev/null +++ b/src/views/overviewLargeScreen/components/center/chart/draw.tsx @@ -0,0 +1,92 @@ +import { defineComponent, watch, shallowReactive } from 'vue' + +// 声明类型 +const PropsType = { + tips: { + type: Number, + default: 50, + require: true + }, + colorObj: { + type: Object, + default: () => ({ + textStyle: "#3fc0fb", + series: { + color: ["#00bcd44a", "transparent"], + dataColor: { + normal: "#03a9f4", + shadowColor: "#97e2f5" + } + } + }) + } +} as const + +// 定义主体 +export default defineComponent({ + props: PropsType, + setup(props) { + // 配置项 + let options = shallowReactive({title:null,series:null}) + + watch( + () => props.tips, + (val: any) => { + options = { + title: { + text: val * 1 + "%", + x: "center", + y: "center", + textStyle: { + color: props.colorObj.textStyle, + fontSize: 16 + } + }, + series: [ + { + type: "pie", + radius: ["75%", "80%"], + center: ["50%", "50%"], + hoverAnimation: false, + color: props.colorObj.series.color, + label: { + normal: { + show: false + } + }, + data: [ + { + value: val, + itemStyle: { + normal: { + color: props.colorObj.series.dataColor.normal, + shadowBlur: 10, + shadowColor: props.colorObj.series.dataColor.shadowColor + } + } + }, + { + value: 100 - val + } + ] + } + ] + } + }, + { + immediate: true, + deep: true + } + ) + + return () => { + const height = "100px" + const width = "120px" + + return
+ +
+ } + } +}) + diff --git a/src/views/overviewLargeScreen/components/center/index.vue b/src/views/overviewLargeScreen/components/center/index.vue new file mode 100644 index 0000000..fc78c07 --- /dev/null +++ b/src/views/overviewLargeScreen/components/center/index.vue @@ -0,0 +1,232 @@ + + + + + diff --git a/src/views/overviewLargeScreen/components/centerLeft1/chart/draw.tsx b/src/views/overviewLargeScreen/components/centerLeft1/chart/draw.tsx new file mode 100644 index 0000000..5319c92 --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerLeft1/chart/draw.tsx @@ -0,0 +1,97 @@ +import { defineComponent, ref, watch, shallowReactive } from 'vue' + +// 声明类型 +const PropsType = { + cdata: { + type: Object, + require: true + } +} as const + +// 定义主体 +export default defineComponent({ + props: PropsType, + setup(props) { + // 定义 ref + const chartRef = ref() + // 配置项 + let options = shallowReactive({color:null,tooltip:null,toolbox:null,calculable:null,legend:null,series:null}) + + watch( + () => props.cdata, + (val: any) => { + options = { + color: [ + '#37a2da', + '#32c5e9', + '#9fe6b8', + '#ffdb5c', + '#ff9f7f', + '#fb7293', + '#e7bcf3', + '#8378ea' + ], + tooltip: { + trigger: 'item', + formatter: '{a}
{b} : {c} ({d}%)' + }, + toolbox: { + show: true + }, + calculable: true, + legend: { + orient: 'horizontal', + icon: 'circle', + bottom: 0, + x: 'center', + data: val.xData, + textStyle: { + color: '#fff' + } + }, + series: [ + { + name: '通过率统计', + type: 'pie', + radius: [10, 50], + roseType: 'area', + center: ['50%', '40%'], + itemStyle: { + borderRadius: 5 + }, + label: { + show: true, + color: "#fff", + }, + emphasis: { + label: { + show: false + } + }, + data: val.seriesData + } + ] + } + // 手动触发更新 + if (chartRef.value) { + // 通过初始化参数打入数据 + chartRef.value.initChart(options) + } + }, + { + immediate: true, + deep: true + } + ) + + return () => { + const height = "220px" + const width = "260px" + + return
+ +
+ } + } +}) + diff --git a/src/views/overviewLargeScreen/components/centerLeft1/chart/index.tsx b/src/views/overviewLargeScreen/components/centerLeft1/chart/index.tsx new file mode 100644 index 0000000..2467467 --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerLeft1/chart/index.tsx @@ -0,0 +1,39 @@ +import { defineComponent, onUnmounted, reactive } from 'vue' +import Draw from './draw' + +export default defineComponent({ + components: { + Draw, + }, + setup() { + let intervalInstance = null + const cdata = reactive({ + xData: ['数据1', '数据2', '数据3', '数据4', '数据5', '数据6'], + seriesData: [ + { value: 10, name: '数据1' }, + { value: 5, name: '数据2' }, + { value: 15, name: '数据3' }, + { value: 25, name: '数据4' }, + { value: 20, name: '数据5' }, + { value: 35, name: '数据6' }, + ], + }) + intervalInstance = setInterval(() => { + const data = cdata.seriesData + cdata.seriesData = data.map((e) => { + return { value: e.value + 10, name: e.name } + }) + }, 1000) + + onUnmounted(() => { + clearInterval(intervalInstance) + }) + return () => { + return ( +
+ +
+ ) + } + }, +}) diff --git a/src/views/overviewLargeScreen/components/centerLeft1/index.vue b/src/views/overviewLargeScreen/components/centerLeft1/index.vue new file mode 100644 index 0000000..53b527d --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerLeft1/index.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/src/views/overviewLargeScreen/components/centerLeft2/chart/draw.tsx b/src/views/overviewLargeScreen/components/centerLeft2/chart/draw.tsx new file mode 100644 index 0000000..9a3c9dd --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerLeft2/chart/draw.tsx @@ -0,0 +1,217 @@ +import { defineComponent, watch, shallowReactive, nextTick, ref, onUnmounted } from 'vue'; + +// 声明类型 +const PropsType = { + cdata: { + type: Array, + require: true + } +} as const + +// 定义主体 +export default defineComponent({ + props: PropsType, + setup(props) { + // 配置项 + let options = shallowReactive({showLegendSymbol:null,tooltip:null,geo:null,series:null}) + // 设置点的位置(经纬度) + const geoCoordMap = { + 厦门市: [118.11022, 24.490474, 20], + 福州市: [119.206239, 26.275302, 20], + 泉州市: [118.589421, 24.908853, 20], + 漳州市: [117.561801, 24.510897, 20], + 龙岩市: [116.82978, 25.391603, 20], + 莆田市: [119.007558, 25.591011, 20], + 三明市: [117.435001, 26.465444, 20], + 南平市: [118.178459, 27.535627, 20], + 宁德市: [119.527082, 27.15924, 20], + } + const seriesData = [ + { + name: '厦门市', + }, + { + name: '福州市', + }, + { + name: '泉州市', + }, + { + name: '漳州市', + }, + { + name: '龙岩市', + }, + { + name: '莆田市', + }, + { + name: '三明市', + }, + { + name: '南平市', + }, + { + name: '宁德市', + }, + ] + const convertData = function (data) { + const scatterData = []; + for (let i = 0; i < data.length; i++) { + const geoCoord = geoCoordMap[data[i].name]; + if (geoCoord) { + scatterData.push({ + name: data[i].name, + value: geoCoord.concat(data[i].value), + }); + } + } + return scatterData; + } + // 监听 + watch( + () => props.cdata, + (val: any) => { + options = { + showLegendSymbol: true, + tooltip: { + trigger: 'item', + textStyle: { + fontSize: 14, + lineHeight: 22, + }, + position: point => { + // 固定在顶部 + return [point[0] + 50, point[1] - 20]; + }, + // 如果需要自定义 tooltip样式,需要使用formatter + /* + formatter: params => { + return `
...
` + } + */ + }, + // 如果需要根据不同的数据展示深浅不一的颜色,则把这里打开 + // visualMap: { + // min: 0, + // max: 10, + // show: false, + // seriesIndex: 0, + // // 颜色 + // inRange: { + // color: ['rgba(41,166,206, .5)', 'rgba(69,117,245, .9)'], + // }, + // }, + // 底部背景 + geo: [{ + show: true, + aspectScale: 0.85, //长宽比 + zoom: 1.16, + top: '10%', + left: '17%', + map: '福建', + roam: false, + itemStyle: { + normal: { + borderColor: '#7ad5ff7f', + shadowOffsetY: 5, + shadowBlur: 15, + areaColor: 'rgba(5,21,35,0.1)' + } + } + }], + series: [ + { + name: '相关指数', + type: 'map', + aspectScale: 0.85, //长宽比 + zoom: 1.16, //缩放 + mapType: '福建', // 自定义扩展图表类型 + top: '9%', + left: '16%', + itemStyle: { + normal: { + // 背景渐变色 + areaColor: { + type: 'linear-gradient', + x: 0, + y: 300, + x2: 0, + y2: 0, + colorStops: [{ + offset: 0, + color: 'RGBA(19,96,187,1)' // 0% 处的颜色 + }, { + offset: 1, + color: 'RGBA(7,193,223,1)' // 50% 处的颜色 + }], + global: true // 缺省为 false + }, + borderColor: '#4ECEE6', + borderWidth: 1, + }, + emphasis: { + areaColor: '#4f7fff', + borderColor: 'rgba(0,242,252,.6)', + borderWidth: 2, + shadowBlur: 10, + shadowColor: '#00f2fc', + }, + }, + label: { + formatter: params => `${params.name}`, + show: true, + position: 'insideRight', + textStyle: { + fontSize: 14, + color: '#efefef', + }, + emphasis: { + textStyle: { + color: '#fff', + }, + }, + }, + data: val, + }, + { + type: 'effectScatter', + coordinateSystem: 'geo', + symbolSize: 7, + effectType: 'ripple', + legendHoverLink: false, + showEffectOn: 'render', + rippleEffect: { + period: 4, + scale: 2.5, + brushType: 'stroke', + }, + zlevel: 1, + itemStyle: { + normal: { + color: '#99FBFE', + shadowBlur: 5, + shadowColor: '#fff', + }, + }, + data: convertData(seriesData), + }, + ], + } + }, + { + immediate: true, + deep: true + } + ) + return () => { + const height = "360px" + const width = "330px" + + return
+ +
+ } + } +}) + diff --git a/src/views/overviewLargeScreen/components/centerLeft2/chart/index.tsx b/src/views/overviewLargeScreen/components/centerLeft2/chart/index.tsx new file mode 100644 index 0000000..341c0a9 --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerLeft2/chart/index.tsx @@ -0,0 +1,58 @@ +import { defineComponent, reactive } from 'vue' +import Draw from './draw' + +export default defineComponent({ + components: { + Draw + }, + setup() { + const cdata = reactive([ + { + // 名字需要与 “common/map/fujian.js” 地图数据文件里面定义的一一对应,不能是 “福州” 或者 “闽” 之类的缩写 + name: '福州市', + value: 10, + elseData: { + // 这里放置地图 tooltip 里想显示的数据 + } + }, + { + name: '厦门市', + value: 9, + }, + { + name: '漳州市', + value: 8, + }, + { + name: '泉州市', + value: 7, + }, + { + name: '三明市', + value: 6, + }, + { + name: '莆田市', + value: 5, + }, + { + name: '南平市', + value: 4, + }, + { + name: '龙岩市', + value: 3, + }, + { + name: '宁德市', + value: 2, + } + ]) + + return () => { + return
+ +
+ } + } +}) \ No newline at end of file diff --git a/src/views/overviewLargeScreen/components/centerLeft2/index.vue b/src/views/overviewLargeScreen/components/centerLeft2/index.vue new file mode 100644 index 0000000..85b1f47 --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerLeft2/index.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/src/views/overviewLargeScreen/components/centerRight1/chart/draw.tsx b/src/views/overviewLargeScreen/components/centerRight1/chart/draw.tsx new file mode 100644 index 0000000..3211a60 --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerRight1/chart/draw.tsx @@ -0,0 +1,131 @@ +import { defineComponent, watch, shallowReactive } from 'vue' + +// 声明类型 +const PropsType = { + cdata: { + type: Object, + require: true + } +} as const + +// 定义主体 +export default defineComponent({ + props: PropsType, + setup(props) { + // 定义固定配置项 + const lineStyle = { + normal: { + width: 1, + opacity: 0.5 + } + }; + // 配置项 + let options = shallowReactive({radar:null,series:null}) + + watch( + () => props.cdata, + (val: any) => { + options = { + radar: { + indicator: val.indicatorData, + shape: "circle", + splitNumber: 5, + radius: ["0%", "65%"], + name: { + textStyle: { + color: "rgb(238, 197, 102)" + } + }, + splitLine: { + lineStyle: { + color: [ + "rgba(238, 197, 102, 0.1)", + "rgba(238, 197, 102, 0.2)", + "rgba(238, 197, 102, 0.4)", + "rgba(238, 197, 102, 0.6)", + "rgba(238, 197, 102, 0.8)", + "rgba(238, 197, 102, 1)" + ].reverse() + } + }, + splitArea: { + show: false + }, + axisLine: { + lineStyle: { + color: "rgba(238, 197, 102, 0.5)" + } + } + }, + series: [ + { + name: "北京", + type: "radar", + lineStyle: lineStyle, + data: val.dataBJ, + symbol: "none", + itemStyle: { + normal: { + color: "#F9713C" + } + }, + areaStyle: { + normal: { + opacity: 0.1 + } + } + }, + { + name: "上海", + type: "radar", + lineStyle: lineStyle, + data: val.dataSH, + symbol: "none", + itemStyle: { + normal: { + color: "#B3E4A1" + } + }, + areaStyle: { + normal: { + opacity: 0.05 + } + } + }, + { + name: "广州", + type: "radar", + lineStyle: lineStyle, + data: val.dataGZ, + symbol: "none", + itemStyle: { + normal: { + color: "rgb(238, 197, 102)" + } + }, + areaStyle: { + normal: { + opacity: 0.05 + } + } + } + ] + } + }, + { + immediate: true, + deep: true + } + ) + + return () => { + const height = "200px" + const width = "260px" + + return
+ +
+ } + } +}) + diff --git a/src/views/overviewLargeScreen/components/centerRight1/chart/index.tsx b/src/views/overviewLargeScreen/components/centerRight1/chart/index.tsx new file mode 100644 index 0000000..ea3ba66 --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerRight1/chart/index.tsx @@ -0,0 +1,51 @@ +import { defineComponent, reactive } from 'vue' +import Draw from './draw' +export default defineComponent({ + components: { + Draw + }, + setup() { + const cdata = reactive({ + indicatorData: [ + { name: "数据1", max: 300 }, + { name: "数据2", max: 250 }, + { name: "数据3", max: 300 }, + { name: "数据4", max: 5 }, + { name: "数据5", max: 200 }, + { name: "数据6", max: 100 } + ], + dataBJ: [ + [94, 69, 114, 2.08, 73, 39, 22], + [99, 73, 110, 2.43, 76, 48, 23], + [31, 12, 30, 0.5, 32, 16, 24], + [42, 27, 43, 1, 53, 22, 25], + [154, 117, 157, 3.05, 92, 58, 26], + [234, 185, 230, 4.09, 123, 69, 27], + [160, 120, 186, 2.77, 91, 50, 28] + ], + dataGZ: [ + [84, 94, 140, 2.238, 68, 18, 22], + [93, 77, 104, 1.165, 53, 7, 23], + [99, 130, 227, 3.97, 55, 15, 24], + [146, 84, 139, 1.094, 40, 17, 25], + [113, 108, 137, 1.481, 48, 15, 26], + [81, 48, 62, 1.619, 26, 3, 27], + [56, 48, 68, 1.336, 37, 9, 28] + ], + dataSH: [ + [91, 45, 125, 0.82, 34, 23, 1], + [65, 27, 78, 0.86, 45, 29, 2], + [83, 60, 84, 1.09, 73, 27, 3], + [109, 81, 121, 1.28, 68, 51, 4], + [106, 77, 114, 1.07, 55, 51, 5], + [109, 81, 121, 1.28, 68, 51, 6], + [106, 77, 114, 1.07, 55, 51, 7] + ] + }) + return () => { + return
+ +
+ } + } +}) \ No newline at end of file diff --git a/src/views/overviewLargeScreen/components/centerRight1/index.vue b/src/views/overviewLargeScreen/components/centerRight1/index.vue new file mode 100644 index 0000000..8a2411c --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerRight1/index.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/src/views/overviewLargeScreen/components/centerRight2/index.vue b/src/views/overviewLargeScreen/components/centerRight2/index.vue new file mode 100644 index 0000000..cea92a1 --- /dev/null +++ b/src/views/overviewLargeScreen/components/centerRight2/index.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/src/views/overviewLargeScreen/constant/index.ts b/src/views/overviewLargeScreen/constant/index.ts new file mode 100644 index 0000000..ea148ae --- /dev/null +++ b/src/views/overviewLargeScreen/constant/index.ts @@ -0,0 +1,39 @@ +type ModuleInfo = { + name: string; + icon: string; +}[]; +// 星期 +export const WEEK = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"]; + +// 主题名称与副标题名称 +export const title = "大数据可视化平台"; +export const subtitle = ["数据分析1", "数据分析2", "vue-big-screen"]; + +export const moduleInfo: ModuleInfo = [ + // 中间的几个模块 + { + name: "任务通过率", + icon: "icon-chart-bar", + }, + { + name: "地图数据", + icon: "icon-tongji4", + }, + { + name: "产品销售渠道分析", + icon: "icon-align-left", + }, + { + name: "任务完成排行榜", + icon: "icon-zhibiao2", + }, + // 底部两个模块 + { + name: "数据统计图", + icon: "icon-vector", + }, + { + name: "工单修复以及满意度统计图", + icon: "icon-fenxi7", + }, +]; diff --git a/src/views/overviewLargeScreen/index.vue b/src/views/overviewLargeScreen/index.vue index 3ea9fe8..42b6c49 100644 --- a/src/views/overviewLargeScreen/index.vue +++ b/src/views/overviewLargeScreen/index.vue @@ -1,9 +1,323 @@ + - \ No newline at end of file + diff --git a/src/views/overviewLargeScreen/utils/index.ts b/src/views/overviewLargeScreen/utils/index.ts new file mode 100644 index 0000000..fba1567 --- /dev/null +++ b/src/views/overviewLargeScreen/utils/index.ts @@ -0,0 +1,36 @@ +/** + * @param {date} time 需要转换的时间 + * @param {String} fmt 需要转换的格式 如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss + * @returns {String} + */ +export const formatTime = ( + time: string | number | Date, + fmt: string +): string => { + if (!time) return '' + const date = new Date(time) + const o = { + 'M+': date.getMonth() + 1, + 'd+': date.getDate(), + 'H+': date.getHours(), + 'm+': date.getMinutes(), + 's+': date.getSeconds(), + 'q+': Math.floor((date.getMonth() + 3) / 3), + S: date.getMilliseconds(), + } + if (/(y+)/.test(fmt)) + fmt = fmt.replace( + RegExp.$1, + (date.getFullYear() + '').substr(4 - RegExp.$1.length) + ) + for (const k in o) { + if (new RegExp('(' + k + ')').test(fmt)) { + fmt = fmt.replace( + RegExp.$1, + // @ts-ignore: Unreachable code error + RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length) + ) + } + } + return fmt +} diff --git a/src/views/overviewLargeScreen/utils/useDraw.ts b/src/views/overviewLargeScreen/utils/useDraw.ts new file mode 100644 index 0000000..004bfe0 --- /dev/null +++ b/src/views/overviewLargeScreen/utils/useDraw.ts @@ -0,0 +1,69 @@ +import { ref } from "vue"; + +export default function useDraw() { + // * 指向最外层容器 + const appRef = ref(); + // * 定时函数 + const timer = ref(0); + // * 默认缩放值 + const scale = { + width: "1", + height: "1", + }; + // * 设计稿尺寸(px) + const baseWidth = 1920; + const baseHeight = 1080; + + // * 需保持的比例(默认1.77778) + const baseProportion = parseFloat((baseWidth / baseHeight).toFixed(5)); + const calcRate = () => { + // 当前宽高比 + const currentRate = parseFloat( + (window.innerWidth / window.innerHeight).toFixed(5) + ); + if (appRef.value) { + if (currentRate > baseProportion) { + // 表示更宽 + scale.width = ( + (window.innerHeight * baseProportion) / + baseWidth + ).toFixed(5); + scale.height = (window.innerHeight / baseHeight).toFixed(5); + appRef.value.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`; + } else { + // 表示更高 + scale.height = ( + window.innerWidth / + baseProportion / + baseHeight + ).toFixed(5); + scale.width = (window.innerWidth / baseWidth).toFixed(5); + appRef.value.style.transform = `scale(${scale.width}, ${scale.height}) translate(-50%, -50%)`; + } + } + }; + + const resize = () => { + clearTimeout(timer.value); + timer.value = setTimeout(() => { + calcRate(); + }, 200); + }; + + // 改变窗口大小重新绘制 + const windowDraw = () => { + window.addEventListener("resize", resize); + }; + + // 改变窗口大小重新绘制 + const unWindowDraw = () => { + window.removeEventListener("resize", resize); + }; + + return { + appRef, + calcRate, + windowDraw, + unWindowDraw, + }; +} diff --git a/tsconfig.app.json b/tsconfig.app.json index a19716c..1d2fbd9 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -1,15 +1,28 @@ { "extends": "@vue/tsconfig/tsconfig.dom.json", - "include": ["src/**/*", "src/**/*.vue", "src/**/*.d.ts"], - "exclude": ["src/**/__tests__/*", "node_modules", "dist", "management"], + "include": [ + "src/**/*", + "src/**/*.vue", + "src/**/*.d.ts" + ], + "exclude": [ + "src/**/__tests__/*", + "node_modules", + "dist", + "management" + ], "compilerOptions": { "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "paths": { - "@/*": ["./src/*"] + "@/*": [ + "./src/*" + ] }, "jsx": "preserve", "jsxImportSource": "vue", "verbatimModuleSyntax": true, - "types": ["naive-ui/volar.d.ts"] + "types": [ + "naive-ui/volar.d.ts" + ] } -} +} \ No newline at end of file