Răsfoiți Sursa

feat(UploadAsset;Router): 更新路由历史模式为history;新增素材上传界面;

fxs 2 luni în urmă
părinte
comite
4037c9c800
53 a modificat fișierele cu 1085 adăugiri și 347 ștergeri
  1. 5 2
      components.d.ts
  2. 284 5
      package-lock.json
  3. 2 1
      package.json
  4. 0 1
      public/img/default/defaultGame.svg
  5. BIN
      public/img/default/defaultHead.png
  6. 0 1
      public/img/platformIcon/backup/tt - 副本.svg
  7. 0 1
      public/img/platformIcon/backup/tt.svg
  8. 0 1
      public/img/platformIcon/backup/web - 副本.svg
  9. 0 1
      public/img/platformIcon/backup/web.svg
  10. 0 1
      public/img/platformIcon/backup/wx - 副本.svg
  11. 0 1
      public/img/platformIcon/backup/wx.svg
  12. 0 1
      public/img/platformIcon/tt.svg
  13. 0 1
      public/img/platformIcon/web.svg
  14. 0 1
      public/img/platformIcon/wx.svg
  15. 0 0
      public/img/promotion/acc-manage-active.svg
  16. 0 0
      public/img/promotion/acc-manage-default.svg
  17. 0 1
      public/img/promotion/ad-manage-active.svg
  18. 0 1
      public/img/promotion/ad-manage-default.svg
  19. 0 0
      public/img/promotion/ad-tencent.svg
  20. 0 1
      public/img/promotion/ad-tt.svg
  21. 0 0
      public/logo.svg
  22. 3 0
      src/assets/css/common.css
  23. 53 33
      src/components/dialog/customIndicatorDialog.vue
  24. 1 2
      src/components/echarts/HomeAnalysisLine.vue
  25. 4 4
      src/components/form/CSelect.vue
  26. 14 16
      src/components/table/Table.vue
  27. 12 10
      src/components/table/TableQueryForm.vue
  28. 21 10
      src/hooks/HomeSelect/useAnalysisSelect.ts
  29. 0 2
      src/hooks/HomeSelect/useHomeSelect.ts
  30. 39 49
      src/hooks/HomeSelect/useOverviewSelect.ts
  31. 0 1
      src/hooks/useCustomIndicatorDialog.ts
  32. 8 3
      src/hooks/useDialogDrag.ts
  33. 22 16
      src/hooks/useRequest.ts
  34. 1 0
      src/hooks/useTableScroll.ts
  35. 7 16
      src/main.ts
  36. 3 2
      src/router/index.ts
  37. 6 1
      src/router/material.ts
  38. 16 6
      src/types/HomeTypes/index.ts
  39. 3 4
      src/types/Tables/table.ts
  40. 26 4
      src/types/echarts/homeAnalysisChart.ts
  41. 2 0
      src/utils/axios/axiosInstance.ts
  42. 12 1
      src/utils/common/index.ts
  43. 199 90
      src/views/Home/Home.vue
  44. 14 5
      src/views/Index.vue
  45. 2 2
      src/views/Login/LoginView.vue
  46. 56 3
      src/views/Material/FilmLibrary.vue
  47. 5 31
      src/views/Material/Material.vue
  48. 257 0
      src/views/Material/UploadAsset.vue
  49. 0 2
      src/views/Promotion/accManage/accTencentAd.vue
  50. 1 2
      src/views/Promotion/accManage/accTtAd.vue
  51. 1 2
      src/views/Promotion/adManage/tencentAd.vue
  52. 6 9
      src/views/Promotion/adManage/ttad.vue
  53. 0 0
      stats.html

+ 5 - 2
components.d.ts

@@ -11,6 +11,7 @@ declare module 'vue' {
     CIcon: typeof import('./src/components/cIcon/cIcon.vue')['default']
     CSelect: typeof import('./src/components/form/CSelect.vue')['default']
     CustomIndicatorDialog: typeof import('./src/components/dialog/customIndicatorDialog.vue')['default']
+    ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
     ElButton: typeof import('element-plus/es')['ElButton']
     ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
@@ -24,22 +25,24 @@ declare module 'vue' {
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
+    ElInputTag: typeof import('element-plus/es')['ElInputTag']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
+    ElPageHeader: typeof import('element-plus/es')['ElPageHeader']
     ElPagination: typeof import('element-plus/es')['ElPagination']
     ElPopover: typeof import('element-plus/es')['ElPopover']
     ElRow: typeof import('element-plus/es')['ElRow']
     ElSelect: typeof import('element-plus/es')['ElSelect']
-    ElStatistic: typeof import('element-plus/es')['ElStatistic']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
+    ElTag: typeof import('element-plus/es')['ElTag']
     ElText: typeof import('element-plus/es')['ElText']
+    ElUpload: typeof import('element-plus/es')['ElUpload']
     HomeAnalysisLine: typeof import('./src/components/echarts/HomeAnalysisLine.vue')['default']
     IconIcBaselineVisibility: typeof import('~icons/ic/baseline-visibility')['default']
     IconIcBaselineVisibilityOff: typeof import('~icons/ic/baseline-visibility-off')['default']
-    IconMaterialSymbolsLightLogout: typeof import('~icons/material-symbols-light/logout')['default']
     IconMdiPassword: typeof import('~icons/mdi/password')['default']
     Menu: typeof import('./src/components/navigation/Menu.vue')['default']
     MenuTable: typeof import('./src/components/promotion/MenuTable.vue')['default']

+ 284 - 5
package-lock.json

@@ -9,8 +9,9 @@
       "version": "0.0.0",
       "dependencies": {
         "@element-plus/icons-vue": "^2.3.1",
+        "axios": "^1.7.9",
         "echarts": "^5.5.1",
-        "element-plus": "^2.8.5",
+        "element-plus": "^2.9.6",
         "lodash": "^4.17.21",
         "pinia": "^2.2.4",
         "vue": "^3.5.11",
@@ -2104,6 +2105,23 @@
       "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==",
       "license": "MIT"
     },
+    "node_modules/asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+      "license": "MIT"
+    },
+    "node_modules/axios": {
+      "version": "1.7.9",
+      "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.9.tgz",
+      "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
+      "license": "MIT",
+      "dependencies": {
+        "follow-redirects": "^1.15.6",
+        "form-data": "^4.0.0",
+        "proxy-from-env": "^1.1.0"
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -2154,6 +2172,19 @@
         "node": ">=8"
       }
     },
+    "node_modules/call-bind-apply-helpers": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+      "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
@@ -2276,6 +2307,18 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/combined-stream": {
+      "version": "1.0.8",
+      "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
+      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+      "license": "MIT",
+      "dependencies": {
+        "delayed-stream": "~1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.8"
+      }
+    },
     "node_modules/computeds": {
       "version": "0.0.1",
       "resolved": "https://registry.npmmirror.com/computeds/-/computeds-0.0.1.tgz",
@@ -2404,6 +2447,15 @@
         "node": ">=8"
       }
     },
+    "node_modules/delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.4.0"
+      }
+    },
     "node_modules/detect-libc": {
       "version": "1.0.3",
       "resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz",
@@ -2417,6 +2469,20 @@
         "node": ">=0.10"
       }
     },
+    "node_modules/dunder-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
+      "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "gopd": "^1.2.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/echarts": {
       "version": "5.5.1",
       "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
@@ -2434,9 +2500,9 @@
       "license": "0BSD"
     },
     "node_modules/element-plus": {
-      "version": "2.8.5",
-      "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.8.5.tgz",
-      "integrity": "sha512-Px+kPbRTVvn5oa5+9saa7QEOnUweKXm0JVI7yJHzKF/doQGixwcFMsQEF2+3Fy62EA/7dRRKVuhsNGGZYNk3cw==",
+      "version": "2.9.6",
+      "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.6.tgz",
+      "integrity": "sha512-D9zU28Ce0s/9O/Vp3ewemikxzFVA6gdZyMwmWijHijo+t5/9H3sHRTIm1WlfeNpFW2Yq0y8nHXD0fU5YxU6qlQ==",
       "license": "MIT",
       "dependencies": {
         "@ctrl/tinycolor": "^3.4.1",
@@ -2447,7 +2513,7 @@
         "@types/lodash-es": "^4.17.6",
         "@vueuse/core": "^9.1.0",
         "async-validator": "^4.2.5",
-        "dayjs": "^1.11.3",
+        "dayjs": "^1.11.13",
         "escape-html": "^1.0.3",
         "lodash": "^4.17.21",
         "lodash-es": "^4.17.21",
@@ -2586,6 +2652,51 @@
         "errno": "cli.js"
       }
     },
+    "node_modules/es-define-property": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
+      "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-errors": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
+      "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-object-atoms": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+      "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
+    "node_modules/es-set-tostringtag": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+      "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+      "license": "MIT",
+      "dependencies": {
+        "es-errors": "^1.3.0",
+        "get-intrinsic": "^1.2.6",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/esbuild": {
       "version": "0.21.5",
       "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz",
@@ -3080,6 +3191,41 @@
       "dev": true,
       "license": "ISC"
     },
+    "node_modules/follow-redirects": {
+      "version": "1.15.9",
+      "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
+      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://github.com/sponsors/RubenVerborgh"
+        }
+      ],
+      "license": "MIT",
+      "engines": {
+        "node": ">=4.0"
+      },
+      "peerDependenciesMeta": {
+        "debug": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/form-data": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.2.tgz",
+      "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
+      "license": "MIT",
+      "dependencies": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.8",
+        "es-set-tostringtag": "^2.1.0",
+        "mime-types": "^2.1.12"
+      },
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/frac": {
       "version": "1.1.2",
       "resolved": "https://registry.npmmirror.com/frac/-/frac-1.1.2.tgz",
@@ -3119,6 +3265,15 @@
         "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
       }
     },
+    "node_modules/function-bind": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+      "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/get-caller-file": {
       "version": "2.0.5",
       "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -3129,6 +3284,43 @@
         "node": "6.* || 8.* || >= 10.*"
       }
     },
+    "node_modules/get-intrinsic": {
+      "version": "1.2.7",
+      "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
+      "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind-apply-helpers": "^1.0.1",
+        "es-define-property": "^1.0.1",
+        "es-errors": "^1.3.0",
+        "es-object-atoms": "^1.0.0",
+        "function-bind": "^1.1.2",
+        "get-proto": "^1.0.0",
+        "gopd": "^1.2.0",
+        "has-symbols": "^1.1.0",
+        "hasown": "^2.0.2",
+        "math-intrinsics": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/get-proto": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
+      "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+      "license": "MIT",
+      "dependencies": {
+        "dunder-proto": "^1.0.1",
+        "es-object-atoms": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/glob-parent": {
       "version": "6.0.2",
       "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -3155,6 +3347,18 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/gopd": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
+      "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/graceful-fs": {
       "version": "4.2.11",
       "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -3179,6 +3383,45 @@
         "node": ">=8"
       }
     },
+    "node_modules/has-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
+      "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+      "license": "MIT",
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
+    "node_modules/hasown": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
+      "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+      "license": "MIT",
+      "dependencies": {
+        "function-bind": "^1.1.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/he": {
       "version": "1.2.0",
       "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz",
@@ -3591,6 +3834,15 @@
         "semver": "bin/semver"
       }
     },
+    "node_modules/math-intrinsics": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+      "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/memoize-one": {
       "version": "6.0.0",
       "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
@@ -3644,6 +3896,27 @@
         "node": ">=4"
       }
     },
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "license": "MIT",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
     "node_modules/minimatch": {
       "version": "9.0.5",
       "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
@@ -4135,6 +4408,12 @@
         "node": ">=6.0.0"
       }
     },
+    "node_modules/proxy-from-env": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
+      "license": "MIT"
+    },
     "node_modules/prr": {
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",

+ 2 - 1
package.json

@@ -17,8 +17,9 @@
   },
   "dependencies": {
     "@element-plus/icons-vue": "^2.3.1",
+    "axios": "^1.7.9",
     "echarts": "^5.5.1",
-    "element-plus": "^2.8.5",
+    "element-plus": "^2.9.6",
     "lodash": "^4.17.21",
     "pinia": "^2.2.4",
     "vue": "^3.5.11",

+ 0 - 1
public/img/default/defaultGame.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1725591308908" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4433" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M704.32 974.4H321.81333333c-77.54666667 0-150.61333333-30.4-205.76-85.54666667S30.50666667 760.64 30.50666667 683.2v-0.42666667c0-77.54666667 30.4-150.61333333 85.54666666-205.76C171.2 421.86666667 244.26666667 391.46666667 321.81333333 391.46666667h382.61333334c77.54666667 0 150.61333333 30.4 205.76 85.54666666 55.14666667 55.14666667 85.54666667 128.21333333 85.54666666 205.76v0.42666667c0 77.54666667-30.4 150.61333333-85.54666666 205.76s-128.32 85.44-205.86666667 85.44zM321.81333333 466.24c-119.36 0-216.53333333 97.17333333-216.53333333 216.53333333v0.42666667c0 119.36 97.17333333 216.53333333 216.53333333 216.53333333h382.61333334c119.36 0 216.53333333-97.17333333 216.53333333-216.53333333v-0.42666667c0-119.36-97.17333333-216.53333333-216.53333333-216.53333333H321.81333333z" fill="#ac4cfd" p-id="4434"></path><path d="M263.89333333 655.68H412.8v57.38666667H263.89333333z" fill="#ac4cfd" p-id="4435"></path><path d="M311.11466667 756.24106667l0.35093333-148.90666667 57.38666667 0.1344-0.352 148.90666667zM682.77333333 764.69333333c-45.65333333 0-82.88-37.12-82.88-82.88s37.12-82.88 82.88-82.88 82.88 37.12 82.88 82.88-37.12 82.88-82.88 82.88z m0-117.65333333c-19.2 0-34.88 15.68-34.88 34.88s15.68 34.88 34.88 34.88 34.88-15.68 34.88-34.88-15.57333333-34.88-34.88-34.88zM545.70666667 463.78666667L488.53333333 432.74666667l100.05333334-184.42666667H385.81333333l-27.84-49.38666667 86.4-143.36 55.78666667 33.49333334-56.74666667 94.18666666h199.89333334l28.58666666 48z" fill="#ac4cfd" p-id="4436"></path></svg>

BIN
public/img/default/defaultHead.png


+ 0 - 1
public/img/platformIcon/backup/tt - 副本.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726209175050" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1296" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M0 0m184.32 0l655.36 0q184.32 0 184.32 184.32l0 655.36q0 184.32-184.32 184.32l-655.36 0q-184.32 0-184.32-184.32l0-655.36q0-184.32 184.32-184.32Z" fill="#111111" p-id="1297"></path><path d="M204.27776 670.59712a246.25152 246.25152 0 0 1 245.97504-245.97504v147.57888a98.49856 98.49856 0 0 0-98.38592 98.38592c0 48.34304 26.14272 100.352 83.54816 100.352 3.81952 0 93.55264-0.88064 93.55264-77.19936V134.35904h157.26592a133.31456 133.31456 0 0 0 133.12 132.99712l-0.13312 147.31264a273.152 273.152 0 0 1-142.62272-38.912l-0.06144 317.98272c0 146.00192-124.24192 224.77824-241.14176 224.77824-131.74784 0.03072-231.1168-106.56768-231.1168-247.92064z" fill="#FF4040" p-id="1298"></path><path d="M164.92544 631.23456a246.25152 246.25152 0 0 1 245.97504-245.97504v147.57888a98.49856 98.49856 0 0 0-98.38592 98.38592c0 48.34304 26.14272 100.352 83.54816 100.352 3.81952 0 93.55264-0.88064 93.55264-77.19936V94.99648h157.26592a133.31456 133.31456 0 0 0 133.12 132.99712l-0.13312 147.31264a273.152 273.152 0 0 1-142.62272-38.912l-0.06144 317.98272c0 146.00192-124.24192 224.77824-241.14176 224.77824-131.74784 0.03072-231.1168-106.56768-231.1168-247.92064z" fill="#00F5FF" p-id="1299"></path><path d="M410.91072 427.58144c-158.8224 20.15232-284.44672 222.72-154.112 405.00224 120.40192 98.47808 373.68832 41.20576 380.70272-171.85792l-0.17408-324.1472a280.7296 280.7296 0 0 0 142.88896 38.62528V261.2224a144.98816 144.98816 0 0 1-72.8064-54.82496 135.23968 135.23968 0 0 1-54.70208-72.45824h-123.66848l-0.08192 561.41824c-0.11264 78.46912-130.9696 106.41408-164.18816 30.2592-83.18976-39.77216-64.37888-190.9248 46.31552-192.57344z" fill="#FFFFFF" p-id="1300"></path></svg>

+ 0 - 1
public/img/platformIcon/backup/tt.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1725874777803" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1034" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M866.304 0H157.696C71.168 0 0 69.632 0 156.16v711.168C0 954.368 71.168 1024 157.696 1024h709.12c86.528 0 157.184-69.632 157.696-156.16V156.16C1023.488 69.632 952.832 0 866.304 0zM842.24 444.416c-63.488 0.512-126.976-19.456-179.2-56.32 0 80.384 0 160.768 1.024 241.152 0 10.752 0.512 21.504-0.512 32.256-2.56 39.424-15.36 77.312-34.816 111.616-16.896 29.184-39.936 55.808-67.584 75.776-35.328 26.112-79.36 40.96-123.392 41.984-22.528 0.512-45.056-0.512-66.56-5.632-30.72-6.656-60.416-19.456-86.016-37.376-0.512-0.512-1.536-1.024-1.536-1.536-27.648-19.456-50.688-44.544-67.584-73.728-23.04-38.4-34.816-83.968-33.28-129.024 1.024-41.472 13.312-82.432 34.816-117.76 19.456-32.256 47.104-59.904 79.36-79.36 46.592-28.672 103.424-40.96 157.696-33.28v30.72c0.512 12.8 0 25.6 0.512 37.888v65.024c-16.384-5.632-34.304-5.632-51.2-1.536-19.968 4.608-39.424 13.312-55.296 26.624-9.728 8.192-17.92 17.92-23.552 29.184-9.728 18.944-13.312 40.96-11.264 62.464 2.56 20.48 11.264 40.448 24.576 56.32 9.216 10.752 20.48 19.968 32.768 27.136 33.28 18.432 76.288 16.896 108.544-3.584 31.232-19.456 51.2-54.784 51.2-91.136V322.56c0.512-62.976 0-125.952 0.512-188.928h130.048c-0.512 11.264 1.024 22.016 3.072 33.28h0.512c3.584 18.432 10.24 35.84 18.944 52.736 13.312 25.6 32.768 48.64 57.344 63.488 1.536 1.024 2.56 2.56 4.096 3.584 18.432 11.264 38.4 19.968 59.392 24.064 12.288 2.56 25.088 3.584 37.376 4.096v129.536z" fill="#000000" p-id="1035"></path></svg>

+ 0 - 1
public/img/platformIcon/backup/web - 副本.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726209354219" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1023" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M-78.43050413-31.57210636m209.68898924 0l745.56084983 0q209.68898924 0 209.68898803 209.68898925l0 745.56084982q0 209.68898924-209.68898803 209.68898803l-745.56084983 0q-209.68898924 0-209.68898924-209.68898803l0-745.56084982q0-209.68898924 209.68898924-209.68898925Z" fill="#FFFFFF" p-id="1024"></path><path d="M705.22384595 648.51918119L503.11860861 1032.59951255a478.30058416 478.30058416 0 0 1-401.90389514-737.40627815l209.3045587 370.660237z" fill="#539E55" p-id="1025"></path><path d="M513.773568 331.93543453L940.19798691 355.68517484C1047.62320729 596.96617031 934.67103141 878.34461738 693.39003593 985.76983776A548.53474592 548.53474592 0 0 1 497.32519344 1032.72945103l207.15433954-383.90395942z" fill="#F1BF45" p-id="1026"></path><path d="M313.30347569 671.66651582l-212.19360768-376.40338485c143.84664607-221.51311815 441.86129749-288.35730773 663.36276602-144.51066167a478.78985774 478.78985774 0 0 1 175.84751562 205.14572788l-426.01812848-23.84629791z" fill="#D44F3E" p-id="1027"></path><path d="M504.03891002 550.8973078m-221.33837733 0a221.33837733 221.33837733 0 1 0 442.67675466 0 221.33837733 221.33837733 0 1 0-442.67675466 0Z" fill="#FFFFFF" p-id="1028"></path><path d="M340.94747436 556.72200185a168.91612972 163.09143567 90 1 0 326.18287134 0 168.91612972 163.09143567 90 1 0-326.18287134 0Z" fill="#467EE6" p-id="1029"></path></svg>

+ 0 - 1
public/img/platformIcon/backup/web.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1725845503147" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1030" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M34.13333334-8.53333334l948.08746667 0-77.55093333 900.02773334-401.95413334 123.42613333-382.29333333-123.42613333zM793.25866668 263.44106666l22.9376-136.53333333-610.57706667-1.09226667 39.3216 409.6 397.58506667 0 0 107.04213334-133.25653334 46.96746666-138.71786666-49.152-8.73813334-57.89013333-109.22666666 1.09226667 16.384 144.1792 233.74506666 81.92 245.76-77.55093334 31.67573334-329.86453333-432.5376 0-10.92266667-138.71786667 456.56746667 0z" p-id="1031"></path></svg>

+ 0 - 1
public/img/platformIcon/backup/wx - 副本.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726209181365" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1467" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M0 0m184.32 0l655.36 0q184.32 0 184.32 184.32l0 655.36q0 184.32-184.32 184.32l-655.36 0q-184.32 0-184.32-184.32l0-655.36q0-184.32 184.32-184.32Z" fill="#65DB79" p-id="1468"></path><path d="M663.21408 407.02976c-128.75776 0-233.13408 87.296-233.13408 194.97984s104.37632 194.97984 233.13408 194.97984a273.85856 273.85856 0 0 0 88.79104-14.76608l66.74432 35.55328-8.98048-64.12288a183.78752 183.78752 0 0 0 86.5792-151.64416c-0.01024-107.68384-104.38656-194.97984-233.13408-194.97984z" fill="#FFFFFF" p-id="1469"></path><path d="M404.48 194.56c137.0112 0 250.28608 83.968 276.16256 195.2768-48.82432-4.01408-302.08 23.27552-261.85728 271.36-36.4032 0.1024-86.016-1.49504-121.5488-13.4656l-80.62976 42.97728 10.8544-77.45536C164.7104 571.7504 122.88 505.00608 122.88 430.08c0-130.048 126.07488-235.52 281.6-235.52z" fill="#FFFFFF" p-id="1470"></path><path d="M313.344 352.256m-36.864 0a36.864 36.864 0 1 0 73.728 0 36.864 36.864 0 1 0-73.728 0Z" fill="#65DB79" p-id="1471"></path><path d="M497.664 352.256m-36.864 0a36.864 36.864 0 1 0 73.728 0 36.864 36.864 0 1 0-73.728 0Z" fill="#65DB79" p-id="1472"></path><path d="M585.728 544.768m-32.768 0a32.768 32.768 0 1 0 65.536 0 32.768 32.768 0 1 0-65.536 0Z" fill="#65DB79" p-id="1473"></path><path d="M741.376 544.768m-32.768 0a32.768 32.768 0 1 0 65.536 0 32.768 32.768 0 1 0-65.536 0Z" fill="#65DB79" p-id="1474"></path></svg>

+ 0 - 1
public/img/platformIcon/backup/wx.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1725845505819" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1183" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M236.24 323.769c0 24.005 19.32 43.325 43.325 43.325s43.326-19.32 43.326-43.325c0-24.005-19.321-43.325-43.326-43.325-24.004 0-43.325 19.32-43.325 43.325z m336.064 223.067c0 18.735 15.223 33.958 33.958 33.958s33.958-15.223 33.958-33.958-15.223-33.958-33.958-33.958-33.958 15.223-33.958 33.958zM456.38 323.769c0 24.005 19.32 43.325 43.325 43.325 24.005 0 43.325-19.32 43.325-43.325 0-24.005-19.32-43.325-43.325-43.325-24.005 0-43.325 19.32-43.325 43.325z" p-id="1184"></path><path d="M858.017 0H165.983C74.648 0 0.293 74.356 0.293 166.276v690.863c0 91.92 74.355 166.276 165.69 166.276h692.034c91.335 0 165.69-74.356 165.69-166.276V166.276C1023.707 74.94 949.352 0 858.017 0zM384.366 686.18c-38.642 0-69.672-8.197-108.899-15.808L167.154 724.82l31.03-93.09C120.316 577.28 74.063 507.022 74.063 422.128c0-147.54 139.929-264.05 310.303-264.05 152.81 0 286.298 93.09 313.23 217.798a255.341 255.341 0 0 0-29.859-1.757c-147.54 0-264.05 110.07-264.05 245.315 0 22.834 3.513 44.496 9.367 64.988-9.367 1.171-18.735 1.757-28.688 1.757z m457.843 108.313l23.42 77.283-84.895-46.838c-31.03 7.61-62.06 15.808-93.09 15.808-147.541 0-264.051-100.703-264.051-225.41 0-124.12 116.51-225.408 264.05-225.408 139.344 0 263.465 101.288 263.465 225.409-0.585 70.843-46.838 132.903-108.899 179.156z" p-id="1185"></path><path d="M741.507 546.836c0 18.735 15.223 33.958 33.958 33.958s33.958-15.223 33.958-33.958-15.223-33.958-33.958-33.958c-19.32 0-33.958 15.223-33.958 33.958z" p-id="1186"></path></svg>

+ 0 - 1
public/img/platformIcon/tt.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726209175050" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1296" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M0 0m184.32 0l655.36 0q184.32 0 184.32 184.32l0 655.36q0 184.32-184.32 184.32l-655.36 0q-184.32 0-184.32-184.32l0-655.36q0-184.32 184.32-184.32Z" fill="#111111" p-id="1297"></path><path d="M204.27776 670.59712a246.25152 246.25152 0 0 1 245.97504-245.97504v147.57888a98.49856 98.49856 0 0 0-98.38592 98.38592c0 48.34304 26.14272 100.352 83.54816 100.352 3.81952 0 93.55264-0.88064 93.55264-77.19936V134.35904h157.26592a133.31456 133.31456 0 0 0 133.12 132.99712l-0.13312 147.31264a273.152 273.152 0 0 1-142.62272-38.912l-0.06144 317.98272c0 146.00192-124.24192 224.77824-241.14176 224.77824-131.74784 0.03072-231.1168-106.56768-231.1168-247.92064z" fill="#FF4040" p-id="1298"></path><path d="M164.92544 631.23456a246.25152 246.25152 0 0 1 245.97504-245.97504v147.57888a98.49856 98.49856 0 0 0-98.38592 98.38592c0 48.34304 26.14272 100.352 83.54816 100.352 3.81952 0 93.55264-0.88064 93.55264-77.19936V94.99648h157.26592a133.31456 133.31456 0 0 0 133.12 132.99712l-0.13312 147.31264a273.152 273.152 0 0 1-142.62272-38.912l-0.06144 317.98272c0 146.00192-124.24192 224.77824-241.14176 224.77824-131.74784 0.03072-231.1168-106.56768-231.1168-247.92064z" fill="#00F5FF" p-id="1299"></path><path d="M410.91072 427.58144c-158.8224 20.15232-284.44672 222.72-154.112 405.00224 120.40192 98.47808 373.68832 41.20576 380.70272-171.85792l-0.17408-324.1472a280.7296 280.7296 0 0 0 142.88896 38.62528V261.2224a144.98816 144.98816 0 0 1-72.8064-54.82496 135.23968 135.23968 0 0 1-54.70208-72.45824h-123.66848l-0.08192 561.41824c-0.11264 78.46912-130.9696 106.41408-164.18816 30.2592-83.18976-39.77216-64.37888-190.9248 46.31552-192.57344z" fill="#FFFFFF" p-id="1300"></path></svg>

+ 0 - 1
public/img/platformIcon/web.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726209354219" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1023" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M-78.43050413-31.57210636m209.68898924 0l745.56084983 0q209.68898924 0 209.68898803 209.68898925l0 745.56084982q0 209.68898924-209.68898803 209.68898803l-745.56084983 0q-209.68898924 0-209.68898924-209.68898803l0-745.56084982q0-209.68898924 209.68898924-209.68898925Z" fill="#FFFFFF" p-id="1024"></path><path d="M705.22384595 648.51918119L503.11860861 1032.59951255a478.30058416 478.30058416 0 0 1-401.90389514-737.40627815l209.3045587 370.660237z" fill="#539E55" p-id="1025"></path><path d="M513.773568 331.93543453L940.19798691 355.68517484C1047.62320729 596.96617031 934.67103141 878.34461738 693.39003593 985.76983776A548.53474592 548.53474592 0 0 1 497.32519344 1032.72945103l207.15433954-383.90395942z" fill="#F1BF45" p-id="1026"></path><path d="M313.30347569 671.66651582l-212.19360768-376.40338485c143.84664607-221.51311815 441.86129749-288.35730773 663.36276602-144.51066167a478.78985774 478.78985774 0 0 1 175.84751562 205.14572788l-426.01812848-23.84629791z" fill="#D44F3E" p-id="1027"></path><path d="M504.03891002 550.8973078m-221.33837733 0a221.33837733 221.33837733 0 1 0 442.67675466 0 221.33837733 221.33837733 0 1 0-442.67675466 0Z" fill="#FFFFFF" p-id="1028"></path><path d="M340.94747436 556.72200185a168.91612972 163.09143567 90 1 0 326.18287134 0 168.91612972 163.09143567 90 1 0-326.18287134 0Z" fill="#467EE6" p-id="1029"></path></svg>

+ 0 - 1
public/img/platformIcon/wx.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726209181365" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1467" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M0 0m184.32 0l655.36 0q184.32 0 184.32 184.32l0 655.36q0 184.32-184.32 184.32l-655.36 0q-184.32 0-184.32-184.32l0-655.36q0-184.32 184.32-184.32Z" fill="#65DB79" p-id="1468"></path><path d="M663.21408 407.02976c-128.75776 0-233.13408 87.296-233.13408 194.97984s104.37632 194.97984 233.13408 194.97984a273.85856 273.85856 0 0 0 88.79104-14.76608l66.74432 35.55328-8.98048-64.12288a183.78752 183.78752 0 0 0 86.5792-151.64416c-0.01024-107.68384-104.38656-194.97984-233.13408-194.97984z" fill="#FFFFFF" p-id="1469"></path><path d="M404.48 194.56c137.0112 0 250.28608 83.968 276.16256 195.2768-48.82432-4.01408-302.08 23.27552-261.85728 271.36-36.4032 0.1024-86.016-1.49504-121.5488-13.4656l-80.62976 42.97728 10.8544-77.45536C164.7104 571.7504 122.88 505.00608 122.88 430.08c0-130.048 126.07488-235.52 281.6-235.52z" fill="#FFFFFF" p-id="1470"></path><path d="M313.344 352.256m-36.864 0a36.864 36.864 0 1 0 73.728 0 36.864 36.864 0 1 0-73.728 0Z" fill="#65DB79" p-id="1471"></path><path d="M497.664 352.256m-36.864 0a36.864 36.864 0 1 0 73.728 0 36.864 36.864 0 1 0-73.728 0Z" fill="#65DB79" p-id="1472"></path><path d="M585.728 544.768m-32.768 0a32.768 32.768 0 1 0 65.536 0 32.768 32.768 0 1 0-65.536 0Z" fill="#65DB79" p-id="1473"></path><path d="M741.376 544.768m-32.768 0a32.768 32.768 0 1 0 65.536 0 32.768 32.768 0 1 0-65.536 0Z" fill="#65DB79" p-id="1474"></path></svg>

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
public/img/promotion/acc-manage-active.svg


Fișier diff suprimat deoarece este prea mare
+ 0 - 0
public/img/promotion/acc-manage-default.svg


+ 0 - 1
public/img/promotion/ad-manage-active.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729041716770" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6002" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M854.528 34.816H172.032c-79.36 0-143.36 64.512-143.36 143.872v441.344c0 22.016 17.92 39.424 39.424 39.424h752.64c22.016 0 39.424-17.92 39.424-39.424 0-22.016-17.92-39.424-39.424-39.424H107.52V178.688c0-35.328 28.672-64.512 64.512-64.512h682.496c35.328 0 64.512 28.672 64.512 64.512v345.6c0 22.016 17.92 39.424 39.424 39.424s39.424-17.92 39.424-39.424V178.688c0.512-79.36-64-143.872-143.36-143.872zM958.976 747.008h-890.88c-22.016 0-39.424 17.92-39.424 39.424s17.92 39.424 39.424 39.424h407.04c-1.024 3.072-1.536 6.656-1.536 9.728v138.752c0 22.016 17.92 39.424 39.424 39.424s39.424-17.92 39.424-39.424v-138.752c0-3.584-0.512-6.656-1.536-9.728h407.04c22.016 0 39.424-17.92 39.424-39.424s-16.896-39.424-38.4-39.424z" fill="#197afb" p-id="6003"></path><path d="M406.016 207.36c-18.944 1.024-32.768 11.776-40.96 31.744L286.72 449.536v3.072c-1.024 4.096-1.536 7.68-1.536 10.752 1.024 16.384 10.24 24.064 27.136 24.064 14.336 0 23.552-6.144 28.672-17.92l12.288-36.352h107.52l10.752 36.352c5.12 12.288 14.848 17.92 28.672 17.92 17.408 0 26.112-7.68 27.136-22.528 0-4.096-1.024-9.216-3.072-15.36L448.512 239.104c-9.216-21.504-23.04-31.744-42.496-31.744z m-36.352 172.544l36.352-112.128 36.352 112.128H369.664zM574.464 211.968c-17.92 1.024-27.648 10.752-28.672 28.672v218.112c1.024 17.92 11.264 27.648 30.208 28.672h66.56c84.992-4.096 129.024-49.152 133.12-134.656-3.072-90.624-48.64-137.728-136.192-140.8h-65.024z m140.8 139.264c-2.048 53.248-26.112 81.408-72.704 83.456h-39.424V264.704h34.816c50.176 1.024 76.288 29.696 77.312 86.528z" fill="#197afb" p-id="6004"></path></svg>

+ 0 - 1
public/img/promotion/ad-manage-default.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729041826578" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="859" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M854.528 34.816H172.032c-79.36 0-143.36 64.512-143.36 143.872v441.344c0 22.016 17.92 39.424 39.424 39.424h752.64c22.016 0 39.424-17.92 39.424-39.424 0-22.016-17.92-39.424-39.424-39.424H107.52V178.688c0-35.328 28.672-64.512 64.512-64.512h682.496c35.328 0 64.512 28.672 64.512 64.512v345.6c0 22.016 17.92 39.424 39.424 39.424s39.424-17.92 39.424-39.424V178.688c0.512-79.36-64-143.872-143.36-143.872zM958.976 747.008h-890.88c-22.016 0-39.424 17.92-39.424 39.424s17.92 39.424 39.424 39.424h407.04c-1.024 3.072-1.536 6.656-1.536 9.728v138.752c0 22.016 17.92 39.424 39.424 39.424s39.424-17.92 39.424-39.424v-138.752c0-3.584-0.512-6.656-1.536-9.728h407.04c22.016 0 39.424-17.92 39.424-39.424s-16.896-39.424-38.4-39.424z" fill="#333333" p-id="860"></path><path d="M406.016 207.36c-18.944 1.024-32.768 11.776-40.96 31.744L286.72 449.536v3.072c-1.024 4.096-1.536 7.68-1.536 10.752 1.024 16.384 10.24 24.064 27.136 24.064 14.336 0 23.552-6.144 28.672-17.92l12.288-36.352h107.52l10.752 36.352c5.12 12.288 14.848 17.92 28.672 17.92 17.408 0 26.112-7.68 27.136-22.528 0-4.096-1.024-9.216-3.072-15.36L448.512 239.104c-9.216-21.504-23.04-31.744-42.496-31.744z m-36.352 172.544l36.352-112.128 36.352 112.128H369.664zM574.464 211.968c-17.92 1.024-27.648 10.752-28.672 28.672v218.112c1.024 17.92 11.264 27.648 30.208 28.672h66.56c84.992-4.096 129.024-49.152 133.12-134.656-3.072-90.624-48.64-137.728-136.192-140.8h-65.024z m140.8 139.264c-2.048 53.248-26.112 81.408-72.704 83.456h-39.424V264.704h34.816c50.176 1.024 76.288 29.696 77.312 86.528z" fill="#333333" p-id="861"></path></svg>

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
public/img/promotion/ad-tencent.svg


+ 0 - 1
public/img/promotion/ad-tt.svg

@@ -1 +0,0 @@
-<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1729042167533" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2214" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M751.84 328.88L611.472 83.04l-166.2 41.144 188.536 322.152z" fill="#01C6D2" p-id="2215"></path><path d="M195.024 212.424l-48.48 158.272h369.88l-47.824-158.272z" fill="#76E4D9" p-id="2216"></path><path d="M231.584 397.92L96 636.48 205.248 754.48l184.208-319.096z" fill="#3468D4" p-id="2217"></path><path d="M385.184 576.192L273.16 695.888l136.896 238.896 160.296-37.856z" fill="#3058B0" p-id="2218"></path><path d="M505.288 651.128l45.712 157.816h275.848l48.12-157.816z" fill="#3568D5" p-id="2219"></path><path d="M814.544 263.76l-183.52 321.968L786.96 623.76 928 385.496z" fill="#3C8BFF" p-id="2220"></path></svg>

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
public/logo.svg


+ 3 - 0
src/assets/css/common.css

@@ -0,0 +1,3 @@
+.w220{
+    width: 220px !important;
+}

+ 53 - 33
src/components/dialog/customIndicatorDialog.vue

@@ -1,15 +1,16 @@
 <script setup lang="ts">
-import type { TableFields } from '@/types/Tables/table'
+import type { BaseFieldItem, TableFields } from '@/types/Tables/table'
 import type { FormInstance, FormRules } from 'element-plus'
 import type {
   DialogProps,
   SaveForm,
 } from '@/types/Tables/customIndicatorDialog'
 
-import { ref, reactive, watch } from 'vue'
+import { reactive, ref, watch } from 'vue'
 import { useTable } from '@/hooks/useTable'
 import { useCustomIndicatorDialog } from '@/hooks/useCustomIndicatorDialog'
 import { useDialogDrag } from '@/hooks/useDialogDrag'
+import { Search } from '@element-plus/icons-vue'
 
 const { isFixedField } = useTable()
 const {
@@ -112,7 +113,7 @@ const fillFomrData = () => {
 }
 
 /**
- * @description: 对话框打开,做一些公布设置
+ * @description: 对话框打开
  * @return {*}
  */
 const indicatorOpen = () => {
@@ -243,6 +244,18 @@ const cancelSelect = (name: string) => {
     }
   }
 }
+
+/**
+ * @description: 判断当前是否有跟搜索框的值匹配的指标
+ * @param {BaseFieldItem} field 当前指标组
+ * @return {boolean} 是否有匹配的指标
+ */
+const hasMatchIndicator = (field: BaseFieldItem<TableFields>): boolean => {
+  let result = field.children.find(item => {
+    return item.label.includes(indicatorSearch.value)
+  })
+  return Boolean(result)
+}
 initSortedTableFieldsInfo(sortedTableFieldsInfo, props.tableFieldsInfo)
 
 defineExpose({ showCustomIndicator })
@@ -266,20 +279,23 @@ defineExpose({ showCustomIndicator })
           <el-input
             v-model="indicatorSearch"
             style="width: 240px"
-            placeholder="Please Input"
+            placeholder="输入指标名称搜索"
+            :suffix-icon="Search"
           />
         </div>
         <div class="indicatorWrapper">
           <div class="indicatorSider">
-            <div
-              @click="goToIndicator(item.name)"
-              v-for="item in indicatorFields"
-              class="indicatorCategory"
-              :class="{
-                indicatorCategoryActive: indicatorNavActive === item.name,
-              }"
-            >
-              {{ item.label }}
+            <div v-for="item in indicatorFields">
+              <div
+                v-show="hasMatchIndicator(item)"
+                @click="goToIndicator(item.name)"
+                class="indicatorCategory"
+                :class="{
+                  indicatorCategoryActive: indicatorNavActive === item.name,
+                }"
+              >
+                {{ item.label }}
+              </div>
             </div>
           </div>
           <div class="indicatorContent">
@@ -288,24 +304,31 @@ defineExpose({ showCustomIndicator })
               :data-anchor="field.name"
               class="indicatorBlock"
             >
-              <div class="indicatorGroup">
-                <span>{{ field.label }}</span>
+              <div v-show="hasMatchIndicator(field)">
+                <div class="indicatorGroup">
+                  <span>{{ field.label }}</span>
+                </div>
+                <el-row class="indicatorItem">
+                  <template v-for="item in field.children">
+                    <el-col
+                      :span="8"
+                      v-show="item.label.includes(indicatorSearch)"
+                    >
+                      <el-checkbox-group
+                        v-model="field.value"
+                        @change="changeIndicatorChecked"
+                      >
+                        <el-checkbox
+                          style="margin-bottom: 16px"
+                          :value="item.name"
+                          :label="item.label"
+                          :disabled="isFixedField(props.fixedFields, item)"
+                        />
+                      </el-checkbox-group>
+                    </el-col>
+                  </template>
+                </el-row>
               </div>
-              <el-row class="indicatorItem">
-                <el-col :span="8" v-for="item in field.children">
-                  <el-checkbox-group
-                    v-model="field.value"
-                    @change="changeIndicatorChecked"
-                  >
-                    <el-checkbox
-                      style="margin-bottom: 16px"
-                      :value="item.name"
-                      :label="item.label"
-                      :disabled="isFixedField(props.fixedFields, item)"
-                    />
-                  </el-checkbox-group>
-                </el-col>
-              </el-row>
             </div>
           </div>
         </div>
@@ -516,9 +539,6 @@ defineExpose({ showCustomIndicator })
   right: 8px;
 }
 
-.dragBlock:not(.notAllow):hover {
-  // background-color: #e7e7e7;
-}
 // 禁止拖拽
 .notAllow {
   cursor: not-allowed;

+ 1 - 2
src/components/echarts/HomeAnalysisLine.vue

@@ -2,9 +2,8 @@
 import type { EChartsOption, SeriesOption } from 'echarts'
 import type { LegendInfo } from '@/types/echarts/homeAnalysisChart'
 
-import { onMounted, ref, shallowRef, watch } from 'vue'
+import { nextTick, onMounted, ref, shallowRef, watch } from 'vue'
 import { cloneDeep } from 'lodash'
-import { nextTick } from 'vue'
 import { debounceFunc } from '@/utils/common'
 import echarts from './index'
 import type { YAXisOption } from 'echarts/types/dist/shared'

+ 4 - 4
src/components/form/CSelect.vue

@@ -1,6 +1,6 @@
 <script setup lang="ts">
-import { CSelectType } from '@/types/HomeTypes'
 import type { CSelectItem } from '@/types/HomeTypes'
+import { CSelectType } from '@/types/HomeTypes'
 
 interface Props {
   selectInfo: {
@@ -24,8 +24,8 @@ const emits = defineEmits(['changeSelect'])
  */
 const changeSelect = (newVal: any, name: string, item: CSelectItem) => {
   // 这里如果有图例的话需要去同步一下cnName
-  if (item.CnName) {
-    item.CnName = item.options.find(item => item.value === newVal)?.label
+  if (item.label) {
+    item.label = item.options.find(item => item.value === newVal)?.label
   }
   emits('changeSelect', newVal, name)
 }
@@ -43,7 +43,7 @@ const changeSelect = (newVal: any, name: string, item: CSelectItem) => {
         <!-- 对于值为对象的选项需要给value-key,默认为value -->
         <el-select
           v-model="selectItem.value"
-          placeholder="Select"
+          placeholder=""
           @change="changeSelect(selectItem.value, selectItem.name, selectItem)"
           v-bind="$attrs"
           :multiple="

+ 14 - 16
src/components/table/Table.vue

@@ -1,24 +1,15 @@
 <script setup lang="ts">
 import type {
   BaseFieldItem,
+  TableData,
   TableFields,
   TableProps,
 } from '@/types/Tables/table'
-
-import type { TableData } from '@/types/Tables/table'
 import type { PaginationConfig } from '@/types/Tables/pagination'
 
-import {
-  computed,
-  nextTick,
-  onMounted,
-  reactive,
-  ref,
-  watch,
-  type Ref,
-} from 'vue'
-
-import { Plus, Operation } from '@element-plus/icons-vue'
+import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
+
+import { Operation, Plus } from '@element-plus/icons-vue'
 import { useTable } from '@/hooks/useTable'
 import { useTableScroll } from '@/hooks/useTableScroll'
 import { generateUniqueFilename } from '@/utils/common'
@@ -90,7 +81,9 @@ const tableFieldLWidth = 200 // 长单元格的宽度
 const tableFieldSWidth = 150 // 短单元格的宽度
 
 // 表格数据
-const tableData = reactive<Array<TableData>>(props.tableData)
+const tableData = reactive<Array<TableData>>(
+  JSON.parse(JSON.stringify(props.tableData)),
+)
 
 // 缓存的表格数据,如果使用了远程分页,则将每一页的表格数据缓存下来
 const cacheTableData = reactive<Array<Array<TableData>>>([])
@@ -227,6 +220,8 @@ const tableSizeChange = (size: number) => {
   if (props.remotePagination) {
     emits('pageSizeChange', size)
   }
+  // setScrollAndHeader()
+  // setScrollPos(true)
   paginationConfig.curPage = 1
 }
 
@@ -530,7 +525,11 @@ defineExpose({
           <div style="font-size: 14px; font-weight: bold; margin-bottom: 8px">
             导出时,将自动过滤掉部分暂不支持导出的指标列内容:
           </div>
-          <div style="font-size: 12px">{{ excludeFields.join('、') }}</div>
+          <div style="font-size: 12px">
+            {{
+              excludeExportFields.length > 0 ? excludeFields.join('、') : '无'
+            }}
+          </div>
         </div>
 
         <template #footer>
@@ -598,7 +597,6 @@ defineExpose({
 }
 
 .operationContainer {
-  position: -webkit-sticky;
   position: sticky;
   width: 100%;
   padding: 10px 20px;

+ 12 - 10
src/components/table/TableQueryForm.vue

@@ -2,12 +2,12 @@
 import type { TableFilterItem } from '@/types/Tables/table'
 import { TableFilterType } from '@/types/Tables/table'
 
-import { nextTick, onMounted, reactive, ref, shallowRef } from 'vue'
+import { onMounted, reactive, ref } from 'vue'
 
 import { resetReactive } from '@/utils/common'
 import { useDate } from '@/hooks/useDate'
 import { Search } from '@element-plus/icons-vue'
-import { debounceFunc } from '@/utils/common'
+import { throttleFunc } from '@/utils/common'
 import type { FormInstance } from 'element-plus'
 
 const { shortcuts, disableDate } = useDate()
@@ -22,6 +22,9 @@ const props = defineProps<TableQueryFormProps>()
 
 const emits = defineEmits(['queryTable'])
 
+// 节流间隔时间
+const throttleIntervalTime = 1000
+
 // 表单ref
 const filterFormRef = ref<FormInstance>()
 
@@ -137,12 +140,11 @@ const getParams = () => {
  */
 const queryTable = () => {
   let queryParams = getParams()
-  console.log(props.filtersInfo)
   emits('queryTable', queryParams)
 }
 
-// 防抖版本
-const debounceQueryTable = debounceFunc(queryTable, 150)
+// 节流版本
+const throttleQueryTable = throttleFunc(queryTable, throttleIntervalTime)
 
 /**
  * @description: 重置查询表单
@@ -153,8 +155,8 @@ const resetFilterForm = () => {
   queryTable()
 }
 
-// 防抖版本重置
-const debounceReset = debounceFunc(resetFilterForm, 150)
+// 节流版本重置
+const throttleReset = throttleFunc(resetFilterForm, throttleIntervalTime)
 
 onMounted(() => {
   initFilterForm()
@@ -204,7 +206,7 @@ defineExpose({
             </template>
           </el-input>
         </el-form-item>
-        <!-- </div> -->
+
         <template v-for="item in filtersInfo" :key="item.name">
           <el-form-item :prop="item.name" style="height: 30px">
             <el-input
@@ -280,10 +282,10 @@ defineExpose({
       </el-form>
     </div>
     <div class="filterButtonContainer">
-      <el-button class="queryBtn" color="#197afb" @click="debounceQueryTable"
+      <el-button class="queryBtn" color="#197afb" @click="throttleQueryTable"
         >查询</el-button
       >
-      <el-button class="queryBtn" color="#626aef" plain @click="debounceReset"
+      <el-button class="queryBtn" color="#626aef" plain @click="throttleReset"
         >重置</el-button
       >
     </div>

+ 21 - 10
src/hooks/HomeSelect/useAnalysisSelect.ts

@@ -1,13 +1,14 @@
-import { CSelectType } from '@/types/HomeTypes'
 import type {
   BaseOption,
-  DateOption,
-  CSelectInfo,
-  CSelectRadio,
   CSelectDate,
+  CSelectInfo,
   CSelectLegend,
+  CSelectRadio,
+  DateOption,
 } from '@/types/HomeTypes'
+import { CSelectType } from '@/types/HomeTypes'
 import { reactive } from 'vue'
+import { useDate } from '../useDate'
 
 //  项目分析菜单选择数据
 interface ProjctAnalySeleInfo extends CSelectInfo {
@@ -20,11 +21,13 @@ interface ProjctAnalySeleInfo extends CSelectInfo {
 interface ProductAnalySeleInfo extends CSelectInfo {
   mediaSelect: CSelectRadio
   dateSelect: CSelectDate
+  dataSource: CSelectRadio
 }
 
 // 每个菜单的选择数据格式
 interface AnalysisSelectInfo {
   [key: string]: CSelectInfo
+
   projAnalysis: ProjctAnalySeleInfo
   productAnalysis: ProductAnalySeleInfo
 }
@@ -33,6 +36,7 @@ interface AnalysisSelectInfo {
 interface LegendSelectInfo extends CSelectInfo {
   [key: string]: CSelectLegend
 }
+
 // 左侧工具栏选择信息格式
 interface LeftToolsSelectInfo extends CSelectInfo {
   dataSource: CSelectRadio
@@ -46,6 +50,7 @@ interface RightToolsSelectInfo extends CSelectInfo {
 // 项目分析图表数据请求格式
 interface ProjectChartDataParams {
   [key: string]: any
+
   project: string
   media: string
   startTime: string
@@ -55,6 +60,7 @@ interface ProjectChartDataParams {
 // 产品分析图表数据请求格式
 interface ProductChartDataParams {
   [key: string]: any
+
   media: string
   startTime: string
   endTime: string
@@ -74,7 +80,6 @@ export type {
   RightToolsSelectInfo,
 }
 
-import { useDate } from '../useDate'
 const { createSelectDateOption } = useDate()
 
 export function useAnalysisSelect() {
@@ -166,13 +171,13 @@ export function useAnalysisSelect() {
     projectSelect: {
       type: CSelectType.Radio,
       name: 'project',
-      value: projSelectOptions[0].value,
+      value: 'all',
       options: projSelectOptions,
     },
     mediaSelect: {
       type: CSelectType.Radio,
       name: 'media',
-      value: mediaSelectOptions[0].value,
+      value: 'all',
       options: mediaSelectOptions,
     },
     dateSelect: {
@@ -197,6 +202,12 @@ export function useAnalysisSelect() {
       value: dateSelectOptions[0].value,
       options: dateSelectOptions,
     },
+    dataSource: {
+      type: CSelectType.Radio,
+      name: 'date',
+      value: mediaSelectOptions[0].value,
+      options: mediaSelectOptions,
+    },
   })
 
   //   计数来源图例的选项
@@ -232,7 +243,7 @@ export function useAnalysisSelect() {
         type: CSelectType.RadioLegend,
         name: 'countResource',
         value: countResourceOptions[0].value,
-        CnName: countResourceOptions[0].label,
+        label: countResourceOptions[0].label,
         options: countResourceOptions,
         color: '#197afb',
       },
@@ -240,7 +251,7 @@ export function useAnalysisSelect() {
         type: CSelectType.RadioLegend,
         name: 'indicator',
         value: indicatorOptions[0].value,
-        CnName: indicatorOptions[0].label,
+        label: indicatorOptions[0].label,
         options: indicatorOptions,
         color: '#f9b65d',
       },
@@ -250,7 +261,7 @@ export function useAnalysisSelect() {
       consumeResource: {
         type: CSelectType.RadioLegend,
         name: 'consumeResource',
-        CnName: categoryOptions[0].label,
+        label: categoryOptions[0].label,
         value: categoryOptions[0].value,
         options: categoryOptions,
         color: '#197afb',

+ 0 - 2
src/hooks/HomeSelect/useHomeSelect.ts

@@ -8,7 +8,6 @@ const {
   legendSelectInfo,
   leftToolsSelectInfo,
   rightToolsSelectInfo,
-
 } = useAnalysisSelect()
 
 export function useHomeSelect() {
@@ -19,6 +18,5 @@ export function useHomeSelect() {
     legendSelectInfo,
     leftToolsSelectInfo,
     rightToolsSelectInfo,
-
   }
 }

+ 39 - 49
src/hooks/HomeSelect/useOverviewSelect.ts

@@ -1,22 +1,20 @@
-import { CSelectType } from '@/types/HomeTypes'
 import type {
   BaseOption,
-  DateOption,
   CSelectInfo,
-  CSelectRadio,
-  CSelectDate,
   CSelectMutipleTag,
+  CSelectRadio,
 } from '@/types/HomeTypes'
+import { CSelectType } from '@/types/HomeTypes'
 import { reactive } from 'vue'
 
 //  总览数据的选择框的信息格式
 interface OverviewSelectInfo extends CSelectInfo {
   mediaSelect: CSelectRadio
-  dateSelect: CSelectDate
+  // dateSelect: CSelectDate
   customIndicatorSelect: CSelectMutipleTag
 }
-import { useDate } from '../useDate'
-const { createSelectDateOption } = useDate()
+
+// const { createSelectDateOption } = useDate()
 export type { OverviewSelectInfo }
 
 export function useOverviewSelect() {
@@ -26,42 +24,34 @@ export function useOverviewSelect() {
       label: '全部媒体',
       value: 'all',
     },
-    {
-      label: '全部媒体1',
-      value: 'all1',
-    },
   ]
-
-  // 日期选择
-  const dateSelectOptions: Array<DateOption> = createSelectDateOption()
-
   // 自定义指标选择
-  const indicatorSelectOptions: Array<BaseOption> = [
-    {
-      label: '测试1',
-      value: 'ce1',
-    },
-    {
-      label: '测试2',
-      value: 'ce2',
-    },
-    {
-      label: '测试3',
-      value: 'ce3',
-    },
-    {
-      label: '测试4',
-      value: 'ce4',
-    },
-    {
-      label: '测试5',
-      value: 'ce5',
-    },
-    {
-      label: '测试6',
-      value: 'ce6',
-    },
-  ]
+  // const indicatorSelectOptions: Array<BaseOption> = [
+  //   {
+  //     label: '测试1',
+  //     value: 'ce1',
+  //   },
+  //   {
+  //     label: '测试2',
+  //     value: 'ce2',
+  //   },
+  //   {
+  //     label: '测试3',
+  //     value: 'ce3',
+  //   },
+  //   {
+  //     label: '测试4',
+  //     value: 'ce4',
+  //   },
+  //   {
+  //     label: '测试5',
+  //     value: 'ce5',
+  //   },
+  //   {
+  //     label: '测试6',
+  //     value: 'ce6',
+  //   },
+  // ]
 
   // 广告数据选择栏数据
   const overviewSelectInfo = reactive<OverviewSelectInfo>({
@@ -71,18 +61,18 @@ export function useOverviewSelect() {
       value: mediaSelectOptions[0].value,
       options: mediaSelectOptions,
     },
-    dateSelect: {
-      type: CSelectType.Radio,
-      name: 'date',
-      value: dateSelectOptions[0].value,
-      options: dateSelectOptions,
-    },
+    // dateSelect: {
+    //   type: CSelectType.Radio,
+    //   name: 'date',
+    //   value: dateSelectOptions[0].value,
+    //   options: dateSelectOptions,
+    // },
     customIndicatorSelect: {
       tagText: '自定义指标',
       type: CSelectType.MultipleTag,
       name: 'customIndicator',
-      value: indicatorSelectOptions.map(item => item.value),
-      options: indicatorSelectOptions,
+      value: [],
+      options: [],
     },
   })
 

+ 0 - 1
src/hooks/useCustomIndicatorDialog.ts

@@ -46,7 +46,6 @@ export function useCustomIndicatorDialog() {
     fixedIndicator: TableFields[],
   ) => {
     let result: TableFields[] = []
-    // 对于固定的指标,为了防止传入的数据有误,所有直接state设置为true
     propIndicator.forEach(item => {
       result.push(
         ...item.children.filter(item => {

+ 8 - 3
src/hooks/useDialogDrag.ts

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-10-25 15:26:00
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-10-30 09:24:13
+ * @LastEditTime: 2024-11-02 09:52:13
  * @FilePath: \Quantity-Creation-Management-System\src\hooks\useDialogDrag.ts
  * @Description: 只用于自定义指标对话框的拖拽功能
  *
@@ -42,7 +42,7 @@ export function useDialogDrag(
   }
 
   /**
-   * @description: 拖拽过程
+   * @description: 进入拖拽元素触发
    * @param {*} e 拖拽事件对象
    * @return {*}
    */
@@ -67,7 +67,7 @@ export function useDialogDrag(
   }
 
   /**
-   * @description: 拖拽结束
+   * @description: 在目标元素上拖动
    * @param {*} e 拖拽对象
    * @return {*}
    */
@@ -76,6 +76,11 @@ export function useDialogDrag(
     if (!e.target) return
   }
 
+  /**
+   * @description: 拖拽结束
+   * @param {DragEvent} e 拖拽对象
+   * @return {*}
+   */
   const dragEnd = (e: DragEvent) => {
     if (!e.target) return
     dragingRef.value?.classList.remove('dragMove')

+ 22 - 16
src/hooks/useRequest.ts

@@ -1,37 +1,43 @@
 import type { AxiosResponse } from 'axios'
 import type { ResponseInfo } from '@/types/axios'
+import { MessageType } from '@/types/axios'
 
 import { ElMessage } from 'element-plus'
-import { MessageType } from '@/types/axios'
 
 import 'element-plus/theme-chalk/el-message.css'
 import 'element-plus/theme-chalk/el-message-box.css'
 
 export function useRequest() {
-  let baseURL = ''
-  if (import.meta.env.MODE === 'development') {
-    baseURL = 'http://server.ichunhao.cn'
-  } else {
-    baseURL = 'http://service.ichunhao.cn'
-  }
+  // let baseURL = 'http://fronttest.ichunhao.cn'
+  let baseURL = 'http://127.0.0.1:8113'
+
+  // if (import.meta.env.MODE === 'development') {
+  //   baseURL = 'http://server.ichunhao.cn'
+  // } else {
+  //   baseURL = 'http://service.ichunhao.cn'
+  // }
 
   const loginUrl = 'http://server.ichunhao.cn'
+  // TODO 改掉API
   const AllApi = {
     userLogin: `${loginUrl}/user/login`,
     getRefreshToken: `${loginUrl}/user/refreshToken`,
-    mockAdTTAcc: `http://127.0.0.1:8003/mock/ad/ttacc`,
-    mockAdTTProj: `http://127.0.0.1:8003/mock/ad/ttproj`,
-    mockAdTTAd: `http://127.0.0.1:8003/mock/ad/ttad`,
-    mockChart: `http://127.0.0.1:8003/mock/home/chart`,
-    mockChartProduct: `http://127.0.0.1:8003/mock/home/chartProduct`,
-    mockOverview: `http://127.0.0.1:8003/mock/home/overview`,
+    mockAdTTAcc: `${baseURL}/mock/ad/ttacc`,
+    mockAdTTProj: `${baseURL}/mock/ad/ttproj`,
+    mockAdTTAd: `${baseURL}/mock/ad/ttad`,
+    mockChart: `${baseURL}/mock/home/chart`,
+    mockChartProduct: `${baseURL}/mock/home/chartProduct`,
+
+    // mockOverview: `http://192.168.1.220:8080/dashboard/overview`,
+    mockOverview: `${baseURL}/mock/home/overview`, // 主页总览数据,
+    tags: `${baseURL}/tags`, // 主页总览数据,
   }
 
   /**
    * @description: 根据返回码给出提示
-   * @param {AxiosResponse} data 返回的数据
-   * @param {string} kind 请求类型
-   * @return {*}
+   * @param data 返回的数据
+   * @param  kind 请求类型
+   * @param showMsg 是否显示提示
    */
   const analysisResCode = (
     data: AxiosResponse,

+ 1 - 0
src/hooks/useTableScroll.ts

@@ -99,5 +99,6 @@ export function useTableScroll(
     initScroll,
     setScrollAndHeader,
     obScroll,
+    setScrollPos,
   }
 }

+ 7 - 16
src/main.ts

@@ -6,6 +6,7 @@ import router from './router'
 
 import * as ElementPlusIconsVue from '@element-plus/icons-vue'
 import '@/assets/base.css'
+import '@/assets/css/common.css'
 
 const app = createApp(App)
 
@@ -15,21 +16,11 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
 app.use(createPinia())
 
 app.use(router)
-
-/**
- * @description:  全局异常捕获,此处只用于调试
- * @param {*} err 错误对象
- * @param {*} instance 触发该错误的组件实例
- * @param {*} info 错误来源类型信息
- * @return {*}
- */
-// app.config.errorHandler = (err, instance, info) => {
-//   console.log('-----------------')
-//   console.log('未被捕获的异常')
-//   console.log(err)
-//   console.log(instance)
-//   console.log(info)
-//   console.log('-----------------')
-// }
+// 捕获全局错误
+app.config.errorHandler = (err, instance, info) => {
+  console.log(err) // 错误对象
+  console.log(instance) // 触发该错误的组件实例
+  console.log(info) // 指出错误来源类型信息的字符串
+}
 
 app.mount('#app')

+ 3 - 2
src/router/index.ts

@@ -1,4 +1,4 @@
-import { createRouter, createWebHashHistory } from 'vue-router'
+import { createRouter, createWebHistory } from 'vue-router'
 
 import { authLogin } from '@/utils/axios/auth'
 
@@ -28,7 +28,8 @@ const routes = [
 ]
 
 const router = createRouter({
-  history: createWebHashHistory(),
+  // history: createWebHashHistory(),
+  history: createWebHistory(),
   routes,
 })
 

+ 6 - 1
src/router/material.ts

@@ -9,10 +9,15 @@ export default [
     },
     children: [
       {
-        path: '/material/filmLibrary',
+        path: 'filmLibrary',
         name: 'FilmLibrary',
         component: () => import('@/views/Material/FilmLibrary.vue'),
       },
+      {
+        path: 'uploadAsset',
+        name: 'UploadAsset',
+        component: () => import('@/views/Material/UploadAsset.vue'),
+      },
     ],
   },
 ]

+ 16 - 6
src/types/HomeTypes/index.ts

@@ -1,9 +1,16 @@
 // 总览广告数据类型
 interface overviewAdvertisingData {
-  name: string
-  title: string
-  value: number
-  rate: number
+  name: string // 名称
+  title: string // 标题
+  value: number // 值
+  rate: number // 比例,上升为正,下降为负
+}
+
+// 总览广告数据返回格式
+interface OverviewRes {
+  data: Array<overviewAdvertisingData> // 数据
+  media: Array<BaseOption> // 媒体字段
+  indicator: Array<BaseOption> // 自定义指标字段
 }
 
 // 选择框类型
@@ -21,6 +28,8 @@ interface CSelectOption {
   value: any
 }
 
+interface BaseOption {}
+
 // 基本下拉框选项类型
 interface BaseOption extends CSelectOption {
   value: string
@@ -48,7 +57,7 @@ interface CSelectItem {
   type: CSelectType
   tagText?: string // 展示在多选框的文字,保持不变
   color?: string // 颜色,只在legend中存在
-  CnName?: string // 中文名,只在legend中生效
+  label?: string // 中文名,只在legend中生效
   options: Array<CSelectOption>
 }
 
@@ -87,7 +96,7 @@ interface CSelectLegend extends CSelectItem {
   options: Array<BaseOption>
   color: string
   value: string
-  CnName: string
+  label: string
 }
 
 // 选择框信息的基本组织格式
@@ -115,4 +124,5 @@ export type {
   CSelectMutiple,
   CSelectMutipleTag,
   CSelectLegend,
+  OverviewRes,
 }

+ 3 - 4
src/types/Tables/table.ts

@@ -1,11 +1,11 @@
-import type { AllAdMgeTtTablesData, AllAdmgeTtFields } from './tableData/ttAd'
+import type { AllAdmgeTtFields, AllAdMgeTtTablesData } from './tableData/ttAd'
 import type {
-  AllAdMgeTencentTablesData,
   AllAdmgeTencentFields,
+  AllAdMgeTencentTablesData,
 } from './tableData/tencentAd'
 import type {
-  AllTtAccMgeTablesData,
   AllTtAccMgeFields,
+  AllTtAccMgeTablesData,
 } from './tableData/ttAcc'
 import type {
   AllTencentAccMgeFields,
@@ -132,7 +132,6 @@ interface CustomIndicatorScheme {
 }
 
 // 每个表格需要的信息格式,包含通用的属性
-
 interface TableInfoItem<
   TData extends TableData, // 数据必须来自所有表格数据类型
   TFields extends BaseFieldItem<TableFields>, // 字段必须来自被basefieldItem包装过得所有表格字段

+ 26 - 4
src/types/echarts/homeAnalysisChart.ts

@@ -1,4 +1,6 @@
-interface ProjectAnalysisData {
+import type { BaseOption } from '@/types/HomeTypes'
+
+export interface ProjectAnalysisData {
   stat_datetime: string // 日期时间字符串
   active: string // 活跃状态
   active_cost: string // 活跃成本
@@ -17,12 +19,32 @@ interface ProjectAnalysisData {
   convert_rate: string // 转化率
 }
 
-interface ProductAnalysisData {
-  cost: string // 模拟生成的cost数据
-  name: string // 固定值
+// 项目分析返回格式
+export interface ProjectRes {
+  data: Array<ProjectAnalysisData>
+  media: Array<BaseOption> // 媒体
+  project: Array<BaseOption> // 项目
+  /**
+   *  图例字段,用于切换表格展示的数据
+   *  key 用于区分图例,value 为该图例可选择的字段
+   */
+  legend: Record<string, Array<BaseOption>>
+}
+
+// 产品分析数据
+export interface ProductAnalysisData {
+  cost: string // 消耗,相当于value
+  cost2: string // 名称
   date: string // 生成类似 "2024-10-01" 格式的日期
 }
 
+export interface ProductAnalysisRes {
+  data: Array<ProductAnalysisData>
+  media: Array<BaseOption>
+  dataSource: Array<BaseOption>
+  legend: Record<string, Array<BaseOption>>
+}
+
 type HomeAnalysisChartData = ProjectAnalysisData | ProductAnalysisData
 
 interface LegendInfo {

+ 2 - 0
src/utils/axios/axiosInstance.ts

@@ -124,5 +124,7 @@ axiosInstance.interceptors.response.use(
   },
 )
 
+axiosInstance.defaults.timeout = 30 * 1000
+
 // 导出实例
 export default axiosInstance

+ 12 - 1
src/utils/common/index.ts

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-26 15:46:42
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-10-29 14:24:21
+ * @LastEditTime: 2024-11-11
  * @FilePath: \Quantity-Creation-Management-System\src\utils\common\index.ts
  * @Description:
  *
@@ -207,6 +207,8 @@ export const fuzzySearch = (
   text: string,
   matchCase: boolean = true,
 ): boolean => {
+  console.log('执行')
+  console.log(pattern, text)
   const regex = new RegExp(pattern, matchCase ? 'i' : '') // 'i' 标志表示忽略大小写
   return regex.test(text)
 }
@@ -239,3 +241,12 @@ export const generateUniqueFilename = (extension: string = 'xlsx'): string => {
   const uniqueFilename = `${timestamp}_${randomStr}.${extension}`
   return uniqueFilename
 }
+
+/**
+ * 根据传入的日期字符串,返回对应的时间戳(秒级)
+ * 如:Fri Feb 14 2025 17:06:14 GMT+0800 (中国标准时间)
+ * @param dateString
+ */
+export const convertToTimestampInSeconds = (dateString: Date): number => {
+  return Math.floor(new Date(dateString).getTime() / 1000)
+}

+ 199 - 90
src/views/Home/Home.vue

@@ -1,15 +1,26 @@
 <script setup lang="ts">
 import type { ResponseInfo } from '@/types/axios'
-import type { AllOptionsVal } from '@/types/HomeTypes'
-import type { DateOptionVal, overviewAdvertisingData } from '@/types/HomeTypes'
+
+import {
+  type BaseOption,
+  type CSelectLegend,
+  CSelectType,
+  type DateOptionVal,
+  type overviewAdvertisingData,
+} from '@/types/HomeTypes'
 import type { BaseMenu } from '@/types/Promotion/Menu'
 import type {
   HomeAnalysisChartData,
   LegendInfo,
+  ProductAnalysisRes,
+  ProjectRes,
 } from '@/types/echarts/homeAnalysisChart'
-import type { AnalysisSelectInfo } from '@/hooks/HomeSelect/useAnalysisSelect'
+import type {
+  AnalysisSelectInfo,
+  LegendSelectInfo,
+} from '@/hooks/HomeSelect/useAnalysisSelect'
 
-import { computed, reactive, ref, watch } from 'vue'
+import { computed, reactive, ref } from 'vue'
 import { useRequest } from '@/hooks/useRequest'
 import { useHomeSelect } from '@/hooks/HomeSelect/useHomeSelect'
 
@@ -17,20 +28,72 @@ import Menu from '@/components/navigation/Menu.vue'
 import CSelect from '@/components/form/CSelect.vue'
 import HomeAnalysisLine from '@/components/echarts/HomeAnalysisLine.vue'
 import axiosInstance from '@/utils/axios/axiosInstance'
-import AnimationNumber from '@/components/animationNumber/AnimationNumber.vue'
 
 import '@/assets/css/statistic.css'
 import type { AxiosRequestConfig } from 'axios'
+import StatisticCard from '@/components/statisticCard/StatisticCard.vue'
+import { convertToTimestampInSeconds } from '@/utils/common' // 主页所有数据的返回格式
+
+// 主页所有数据的返回格式
+interface HomeResInfo {
+  overview: {
+    data: overviewAdvertisingData[]
+    indicator: Array<BaseOption>
+    media: Array<BaseOption>
+  }
+  product: {}
+  project: {}
+}
 
 const { AllApi } = useRequest()
 
-const {
-  overviewSelectInfo,
-  projctAnalySeleInfo,
-  productAnalySeleInfo,
-  legendSelectInfo,
-  leftToolsSelectInfo,
-} = useHomeSelect()
+const { overviewSelectInfo, projctAnalySeleInfo, productAnalySeleInfo } =
+  useHomeSelect()
+
+let chartReqcontroller: AbortController | null = null // 请求控制器,用于取消请求
+let chartReqList: Array<string> = [] // 表格的请求列表,暂时只存了url,可以存其他的
+
+const createDateRange = (day: number): [Date, Date] => {
+  const end = new Date()
+  const start = new Date()
+  start.setTime(start.getTime() - 3600 * 1000 * 24 * day)
+  return [start, end]
+}
+
+// 快速选择日期
+const shortcuts = [
+  {
+    text: '上一周',
+    value: () => createDateRange(7),
+  },
+  {
+    text: '上个月',
+    value: () => createDateRange(30),
+  },
+  {
+    text: '近三个月',
+    value: () => createDateRange(90),
+  },
+]
+// 选择的日期
+const selectDate = ref<[Date, Date]>(shortcuts[0].value())
+
+/**
+ * 禁用日期
+ * @param time 时间
+ */
+const disableDate = (time: Date) => {
+  return time.getTime() > Date.now()
+}
+
+/**
+ * 日期变化,重新请求总览数据
+ */
+const dateChange = () => {
+  // changeDateRange(val)
+
+  getOverviewData()
+}
 
 // 总览数据的自定义指标最多选择个数
 const maxSelectOverviewIndicator = 6
@@ -66,7 +129,9 @@ const overviewDataConfig: {
 } = {
   url: AllApi.mockOverview,
   config: {
-    params: {},
+    params: {
+      overview: {},
+    },
   },
 }
 
@@ -102,7 +167,16 @@ const chartLoading = ref<boolean>(true)
 // 图表数据
 const chartData = reactive<Array<HomeAnalysisChartData>>([])
 
+// legend信息
+const legendInfo: {
+  [key: string]: LegendSelectInfo
+} = reactive({
+  projAnalysis: {},
+  productAnalysis: {},
+})
+
 /**
+ * @deprecated
  * @description: (暂时废弃,因为会导致更换指标的时候,数组的变化导致数据重新执行动画)
  * 根据已选择自定义指标动态的加入广告数据概况
  * @return {*}
@@ -149,14 +223,58 @@ const changeChartSelect = () => {
  * @param {*} newMenu 新的菜单值
  * @return {*}
  */
-const analysisiMenuChange = (newMenu: string) => {
+const analysisMenuChange = (newMenu: string) => {
   analysisiMenuActive.value = newMenu
 
   getChartData()
 }
 
-let chartReqcontroller: AbortController | null = null // 请求控制器,用于取消请求
-let chartReqList: Array<string> = [] // 表格的请求列表,暂时只存了url,可以存其他的
+/**
+ * 根据返回的legend创建legend信息
+ * @param data
+ */
+const createLegendInfo = (data: ProjectRes | ProductAnalysisRes) => {
+  const legends = data.legend
+  // 2种颜色
+  const colorList = [
+    '#00e070',
+    '#1495eb',
+    '#993333', // Dark Red
+    '#FFD700', // Bright Yellow
+    '#FF00FF', // Magenta
+    '#FFA500', // Orange
+    '#800080', // Dark Purple
+    '#A52A2A', // Brown
+    '#FF4500', // Orange Red
+    '#FF6347', // Tomato
+    '#B22222', // Firebrick
+    '#FF1493', // Deep Pink
+  ]
+  let count = 0
+  for (const [k, v] of Object.entries(legends)) {
+    const legendItem: CSelectLegend = {
+      type: CSelectType.RadioLegend,
+      name: k,
+      value: v[0].value,
+      label: v[0].label,
+      options: v,
+      color: colorList[count++ % colorList.length],
+    }
+    legendInfo[analysisiMenuActive.value][k] = legendItem
+  }
+}
+
+/**
+ * 根据返回的数据解析出图表数据
+ * @param res
+ */
+const analysisResChartData = (res: ResponseInfo) => {
+  const resInfo =
+    analysisiMenuActive.value === 'projAnalysis'
+      ? (res.data as ProjectRes)
+      : (res.data as ProductAnalysisRes)
+  return resInfo
+}
 
 /**
  * @description: 获取图表数据
@@ -172,8 +290,10 @@ const getChartData = async () => {
     config.signal = chartReqcontroller.signal
     chartLoading.value = true
     const res = (await axiosInstance.get(url, config)) as ResponseInfo
+    const data = analysisResChartData(res) // 解析出图表数据
+    createLegendInfo(data) // 创建对应的legend信息
     if (res.code !== 0) throw new Error('获取图表数据失败')
-    chartData.splice(0, chartData.length, ...res.data)
+    chartData.splice(0, chartData.length, ...data.data)
   } catch (err) {
     console.log(err)
   } finally {
@@ -190,65 +310,38 @@ const getChartData = async () => {
  */
 const analysisLegendInfo = computed<Array<LegendInfo>>(() => {
   let result: Array<LegendInfo> = []
-  for (let [_k, v] of Object.entries(
-    legendSelectInfo[analysisiMenuActive.value],
-  )) {
+  for (let [_k, v] of Object.entries(legendInfo[analysisiMenuActive.value])) {
     result.push({
       value: v.value,
-      color: v.color!,
-      cnName: v.CnName,
+      color: v.color,
+      cnName: v.label,
     })
   }
   return result
 })
 
-// const lengendInfo = reactive<Array<LegendInfo>>([])
-
-// const initLegend = ()=>{
-//   for (let [_k, v] of Object.entries(
-//     legendSelectInfo[analysisiMenuActive.value],
-//   )) {
-//     lengendInfo.push({
-//       value: v.value,
-//       color: v.color!,
-//       cnName: v.CnName,
-//     })
-//   }
-// }
-
-// initLegend();
-
-// const changeLengend = (newval: any, name: string) => {
-//   console.log(newval, name)
-//   console.log(legendSelectInfo)
-//   console.log(analysisLegendInfo.value)
-//   if(legendSelectInfo[analysisiMenuActive.value])
-// }
-
 /**
  * @description: 创建新的自定义指标选择框的值
  * @param {*} data 返回的数据
  * @return {*}
  */
-const createIndicatorSelectInfo = (data: Array<overviewAdvertisingData>) => {
-  let options = data.map(item => {
-    return {
-      value: item.name,
-      label: item.title,
-    }
-  })
-  // 形成新的值,也就是把所有的name都取出来
-  let values = data.slice(0, maxSelectOverviewIndicator).map(item => item.name)
-
-  // 更新自定义指标选项
-  let overviewOptions = overviewSelectInfo.customIndicatorSelect.options
-  overviewOptions.splice(0, overviewOptions.length, ...options)
-
-  // 更新值
+const createIndicatorSelectInfo = (options: BaseOption[]) => {
+  let values = options
+    .slice(0, maxSelectOverviewIndicator)
+    .map(item => item.value)
+  overviewSelectInfo.customIndicatorSelect.options = options
   let overviewValues = overviewSelectInfo.customIndicatorSelect.value
   overviewValues.splice(0, overviewValues.length, ...values)
 }
 
+const createMediaSelectInfo = (options: BaseOption[]) => {
+  overviewSelectInfo.mediaSelect.options = options
+  const originValue = overviewSelectInfo.mediaSelect.value
+  if (!options.find(item => item.value === originValue)) {
+    overviewSelectInfo.mediaSelect.value = options[0].value
+  }
+}
+
 /**
  * @description: 创建广告数据概况请求参数
  * @return {*}
@@ -256,18 +349,17 @@ const createIndicatorSelectInfo = (data: Array<overviewAdvertisingData>) => {
 const createOverviewReqParams = () => {
   let result: { [key: string]: any } = {}
   for (let [k, v] of Object.entries(overviewSelectInfo)) {
-    // 除了自定义指标,另外两个选择框的值就作为请求参数
+    // 将媒体字段的值加入
     if (k !== 'customIndicatorSelect') {
-      if (v.name === 'date') {
-        // date选择框需要单独处理一下
-        result['startTime'] = v.value.startTime
-        result['endTime'] = v.value.endTime
-      } else {
-        result[v.name] = v.value
-      }
+      result[v.name] = v.value
     }
   }
-  overviewDataConfig.config.params = result
+  // indicator暂时不传
+  result['indicator'] = []
+  // 转秒级时间戳
+  result['start_time'] = convertToTimestampInSeconds(selectDate.value[0])
+  result['end_time'] = convertToTimestampInSeconds(selectDate.value[0])
+  overviewDataConfig.config.params.overview = result
 }
 
 let overviewReqcontroller: AbortController | null = null // 请求控制器,用于取消请求
@@ -285,12 +377,16 @@ const getOverviewData = async () => {
     overviewReqList.push(url) // 添加到请求列表
     overviewReqcontroller && overviewReqcontroller.abort() // 取消上一次请求
     overviewReqcontroller = new AbortController()
-    config.signal = overviewReqcontroller.signal
+    // config.signal = overviewReqcontroller.signal
 
-    let res = (await axiosInstance.get(url, config)) as ResponseInfo
+    let res = (await axiosInstance.post(url, config.params)) as ResponseInfo
     if (res.code !== 0) throw new Error('获取广告数据概况失败')
-    let data = res.data as Array<overviewAdvertisingData>
-    createIndicatorSelectInfo(data) // 根据返回的数据去更新自定义指标选项和值
+    const resData = res.data as HomeResInfo
+    let data = resData.overview.data
+    const indicator = resData.overview.indicator
+    const media = resData.overview.media
+    createIndicatorSelectInfo(indicator) // 根据返回的数据去更新自定义指标选项和值
+    createMediaSelectInfo(media)
     overviewAdvertisingData.splice(0, overviewAdvertisingData.length, ...data)
   } catch (err: any) {
     console.log(err)
@@ -314,13 +410,16 @@ const getOverviewData = async () => {
 const changeOverviewSelect = (_newSelect: any, name: string) => {
   if (name === 'customIndicator') {
     // console.log(_newSelect)
-
     return
   }
 
   getOverviewData()
 }
-import StatisticCard from '@/components/statisticCard/StatisticCard.vue'
+
+const changeLegend = () => {
+  getChartData()
+}
+
 getChartData()
 getOverviewData()
 </script>
@@ -333,7 +432,26 @@ getOverviewData()
           <span class="overviewTitle">广告数据概况</span>
           <span class="getDetail">查看详情</span>
         </div>
-        <div class="overviewFilterBox">
+        <div
+          class="overviewFilterBox"
+          style="display: flex; align-items: center"
+        >
+          <div style="margin-right: 10px">
+            <el-date-picker
+              v-model="selectDate"
+              :disabled-date="disableDate"
+              :unlink-panels="false"
+              @change="dateChange"
+              type="daterange"
+              range-separator="至"
+              start-placeholder="Start date"
+              end-placeholder="End date"
+              :shortcuts="shortcuts"
+              :size="'default'"
+            >
+            </el-date-picker>
+          </div>
+
           <CSelect
             :multiple-limit="maxSelectOverviewIndicator"
             size="default"
@@ -388,7 +506,7 @@ getOverviewData()
             mode="horizontal"
             default-active="projAnalysis"
             :menu-list="dataAnalysisMenuList"
-            @active-change="analysisiMenuChange"
+            @active-change="analysisMenuChange"
           ></Menu>
         </div>
       </div>
@@ -402,23 +520,13 @@ getOverviewData()
             ></CSelect>
           </div>
           <div class="chartBoxTools">
-            <div
-              class="dataTools"
-              v-if="analysisiMenuActive === 'productAnalysis'"
-            >
-              <div class="dataToolItem"></div>
-              <div class="dataToolItem">
-                <CSelect
-                  class="dataSource"
-                  :select-info="leftToolsSelectInfo"
-                ></CSelect>
-              </div>
-            </div>
+            <!--            :select-info="legendSelectInfo[analysisiMenuActive]"-->
             <div class="legendTools">
               <CSelect
                 :select-style="`width:100px;margin-right:15px;`"
                 size="small"
-                :select-info="legendSelectInfo[analysisiMenuActive]"
+                :select-info="legendInfo[analysisiMenuActive]"
+                @change-select="changeLegend"
               ></CSelect>
             </div>
           </div>
@@ -443,6 +551,7 @@ getOverviewData()
 .homeContainer {
   padding-top: 3vh;
 }
+
 .advertisingDataOverview {
   width: 1320px;
   margin: 0 auto;

+ 14 - 5
src/views/Index.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import type { BaseMenu } from '@/types/Promotion/Menu'
 
-import { onMounted, ref } from 'vue'
+import { onMounted } from 'vue'
 import { setLoginState } from '@/utils/localStorage/localStorage'
 import { removeAllToeken } from '@/utils/token/token'
 
@@ -123,7 +123,7 @@ onMounted(() => {})
           placement="bottom-end"
           trigger="hover"
           :width="300"
-          :offset="20"
+          :offset="10"
         >
           <template #reference>
             <div class="headPopperRef">
@@ -132,6 +132,7 @@ onMounted(() => {})
                 :src="resourceInfo.defaultHead"
                 :size="24"
               ></cIcon>
+              <span class="popperUserName">{{ userInfo.name }}</span>
               <el-icon class="popperArrowIcon"><ArrowDown /></el-icon>
             </div>
           </template>
@@ -229,7 +230,6 @@ onMounted(() => {})
 }
 
 .navBarBox {
-  position: -webkit-sticky;
   position: sticky;
   display: flex;
   align-items: center;
@@ -282,10 +282,11 @@ onMounted(() => {})
 .headPopperRef {
   display: flex;
   align-items: center;
+  padding: 10px 5px;
 }
 
 .popperHeadIcon {
-  margin-right: 10px;
+  margin-right: 5px;
 }
 
 .popperArrowIcon {
@@ -294,6 +295,14 @@ onMounted(() => {})
   transform: rotate(0deg);
 }
 
+.popperUserName {
+  font-size: 12px;
+  font-weight: 400;
+  color: #333;
+  margin-right: 15px;
+  user-select: none;
+}
+
 .headPopperRef:hover > .popperArrowIcon {
   transition: transform 0.2s linear 0s;
   transform: rotate(180deg);
@@ -413,7 +422,7 @@ onMounted(() => {})
   position: relative;
   width: 100%;
   height: calc(100% - 64px);
-  overflow: hidden;
+  /*overflow: hidden*/
 
   background-color: #f2f3f5;
 

+ 2 - 2
src/views/Login/LoginView.vue

@@ -3,7 +3,7 @@ import type { RuleInfo } from '@/types/input'
 
 import { onMounted, reactive, ref } from 'vue'
 import { useRequest } from '@/hooks/useRequest'
-import { setToken, setRefreshToken } from '@/utils/token/token'
+import { setRefreshToken, setToken } from '@/utils/token/token'
 import { setLoginState } from '@/utils/localStorage/localStorage'
 
 import router from '@/router'
@@ -126,7 +126,7 @@ onMounted(() => {})
       <div class="banner"></div>
       <div class="logoBox">
         <div class="logoImg">
-          <CIcon :src="resourceInfo.logo"></CIcon>
+          <CIcon :size="30" :src="resourceInfo.logo"></CIcon>
         </div>
 
         <span class="logoText">淳皓科技</span>

+ 56 - 3
src/views/Material/FilmLibrary.vue

@@ -1,9 +1,62 @@
 <script setup lang="ts">
-import Table from '@/components/table/Table.vue'
+import { Plus } from '@element-plus/icons-vue'
+import router from '@/router'
+import Menu from '@/components/navigation/Menu.vue'
+import { ref } from 'vue'
+import type { BaseMenu } from '@/types/Promotion/Menu.ts'
+
+const moveToUpload = () => {
+  router.push({ name: 'UploadAsset' })
+}
+
+const defaultActive = ref<string>(router.currentRoute.value.path)
+const menu: Array<BaseMenu> = [
+  {
+    name: 'filmLibrary',
+    title: '成片库',
+    path: '/material/filmLibrary',
+  },
+]
 </script>
 
 <template>
-  <div>水电费卡斯柯龙卷风考拉手机</div>
+  <div class="filmLibraryContainer">
+    <div class="flSlider">
+      <Menu
+        mode="vertical"
+        :menu-list="menu"
+        :default-active="defaultActive"
+        :router="true"
+      ></Menu>
+    </div>
+
+    <div class="flContent">
+      <el-button
+        color="#197AFB"
+        :icon="Plus"
+        class="el-button-mini"
+        @click="moveToUpload"
+        >上传素材
+      </el-button>
+    </div>
+  </div>
 </template>
 
-<style scoped></style>
+<style scoped>
+.filmLibraryContainer {
+  width: 100%;
+  height: 100%;
+  display: flex;
+}
+
+.flSlider {
+  height: 100%;
+  position: relative;
+}
+
+.el-button-mini {
+  font-size: 12px;
+  border-radius: 3px;
+  padding: 7px 15px;
+}
+</style>

+ 5 - 31
src/views/Material/Material.vue

@@ -1,32 +1,13 @@
 <script setup lang="ts">
-import router from '@/router'
-import Menu from '@/components/navigation/Menu.vue'
-import type { BaseMenu } from '@/types/Promotion/Menu'
-import { ref } from 'vue'
-
-const defaultActive = ref<string>(router.currentRoute.value.path)
-const menu: Array<BaseMenu> = [
-  {
-    name: 'filmLibrary',
-    title: '成片库',
-    path: '/material/filmLibrary',
-  },
-]
+// import router from '@/router'
+// import Menu from '@/components/navigation/Menu.vue'
+// import type { BaseMenu } from '@/types/Promotion/Menu'
+// import { ref } from 'vue'
 </script>
 
 <template>
   <div class="materialContainer">
-    <div class="materialSiderBar">
-      <Menu
-        mode="vertical"
-        :menu-list="menu"
-        :default-active="defaultActive"
-        :router="true"
-      ></Menu>
-    </div>
-    <div class="materialContent">
-      <router-view></router-view>
-    </div>
+    <router-view></router-view>
   </div>
 </template>
 
@@ -34,12 +15,5 @@ const menu: Array<BaseMenu> = [
 .materialContainer {
   width: 100%;
   height: 100%;
-  display: flex;
-}
-
-.materialSiderBar {
-  /* width: 180px; */
-  height: 100%;
-  position: relative;
 }
 </style>

+ 257 - 0
src/views/Material/UploadAsset.vue

@@ -0,0 +1,257 @@
+<script setup lang="ts">
+import { nextTick, reactive, ref } from 'vue'
+import type { FormRules } from 'element-plus'
+
+import axiosInstance from '@/utils/axios/axiosInstance.ts'
+import { useRequest } from '@/hooks/useRequest.ts'
+import type { ResponseInfo } from '@/types/axios.ts'
+
+const { AllApi } = useRequest()
+
+interface UploadAssetForm {
+  name: string
+  tag: Array<string>
+  gid: string
+  filePath: string
+  md5: string
+}
+
+interface GameInfo {
+  gid: string
+  label: string
+}
+
+interface TagInfo {
+  value: string
+}
+
+const uploadForm = reactive<UploadAssetForm>({
+  name: '',
+  tag: [],
+  gid: '',
+  filePath: '',
+  md5: '',
+})
+
+const rules = reactive<FormRules<UploadAssetForm>>({
+  name: [
+    { required: true, message: '请输入创意名', trigger: 'blur' },
+    { min: 3, max: 5, message: '3-5个字符', trigger: 'blur' },
+  ],
+  tag: [{ required: true, message: '请选择标签', trigger: 'blur' }],
+  gid: [{ required: true, message: '请选择游戏', trigger: 'blur' }],
+})
+
+const gameInfoList = reactive<Array<GameInfo>>([
+  {
+    gid: '1',
+    label: '游戏1',
+  },
+  {
+    gid: '2',
+    label: '游戏12',
+  },
+  {
+    gid: '3',
+    label: '游戏13',
+  },
+])
+
+const tagInput = ref('')
+const autocompleteRef = ref()
+
+const tagSearch = async (queryString: string, cb: any) => {
+  const resInfo = (await axiosInstance.get(AllApi.tags)) as ResponseInfo
+  if (resInfo.code !== 0) {
+    return []
+  }
+  const results = resInfo.data as Array<TagInfo>
+
+  const result = queryString
+    ? results.filter(createFilter(queryString))
+    : results
+
+  cb(result)
+}
+
+const createFilter = (queryString: string) => {
+  return (restaurant: TagInfo) => {
+    return (
+      restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
+    )
+  }
+}
+
+const handleTagSelect = (tag: TagInfo) => {
+  uploadForm.tag.push(tag.value)
+  tagInput.value = ''
+  nextTick(() => {
+    autocompleteRef.value.blur()
+  })
+}
+
+const goBack = () => {
+  console.log('back')
+}
+</script>
+
+<template>
+  <div class="uploadAssetContainer">
+    <el-page-header class="header" @back="goBack">
+      <template #content>
+        <span class="mr-3">上传素材</span>
+      </template>
+    </el-page-header>
+    <div class="content">
+      <p class="title">素材信息</p>
+      <div class="formContainer">
+        <el-form
+          :rules="rules"
+          :model="uploadForm"
+          :label-position="'left'"
+          label-width="auto"
+          class="uploadForm"
+        >
+          <el-form-item label="创意名" prop="name">
+            <el-input
+              placeholder="请输入创意名"
+              class="w220"
+              v-model="uploadForm.name"
+            />
+          </el-form-item>
+          <el-form-item label="游戏" prop="gid">
+            <el-select
+              class="w220"
+              v-model="uploadForm.gid"
+              placeholder="选择游戏"
+            >
+              <el-option
+                v-for="item in gameInfoList"
+                :label="item.label"
+                :value="item.gid"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item label="标签" prop="tag">
+            <div class="tagContainer">
+              <el-autocomplete
+                :debounce="200"
+                v-model="tagInput"
+                :fetch-suggestions="tagSearch"
+                clearable
+                class="inline-input w220"
+                placeholder="请输入标签以搜索"
+                @select="handleTagSelect"
+                ref="autocompleteRef"
+              />
+              <el-input-tag
+                clearable
+                class="inputTag"
+                v-model="uploadForm.tag"
+                placeholder="如需新建标签,请直接在此处输入后回车"
+              />
+            </div>
+          </el-form-item>
+          <el-form-item label="文件" prop="filePath">
+            <div class="fileContainer">
+              <el-upload
+                class="uploadContainer"
+                drag
+                multiple
+                :auto-upload="false"
+                list-type="picture"
+              >
+                <el-icon class="el-icon--upload">
+                  <upload-filled />
+                </el-icon>
+                <div class="el-upload__text">
+                  <p>将文件或文件夹拖到此处,或点击上传文件</p>
+                  <p class="upload-tips">
+                    1.仅支持图片和视频文件,上传添加不超过500个
+                  </p>
+                  <p class="upload-tips">
+                    2.支持图片格式:png、jpg、jpeg、gif,不超过100MB;支持视频格式:mp4、mpeg、3pg、avi、mov,不超过5G
+                  </p>
+                  <p class="upload-tips">
+                    3.素材上传后需对尺寸、码率等进行分析,约1-3分钟后方可用于投放
+                  </p>
+                </div>
+                <template #file="{ file }">
+                  <div>
+                    <img
+                      class="el-upload-list__item-thumbnail"
+                      :src="file.url"
+                      alt=""
+                    />
+                    <div>撒都</div>
+                  </div>
+                </template>
+              </el-upload>
+            </div>
+          </el-form-item>
+        </el-form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+.uploadAssetContainer {
+  width: 100%;
+}
+
+.header {
+  width: 100%;
+  height: 5vh;
+  display: flex;
+  background: #f8f9fc;
+  align-items: center;
+  padding-left: 30px;
+  border-bottom: 1px solid #e8eaec;
+}
+
+.title {
+  padding: 15px;
+  font-size: 16px;
+  font-weight: 700;
+  color: #333;
+  background: #f8f9fc;
+  border-radius: 3px 3px 0 0;
+}
+
+.content {
+  width: 90%;
+
+  margin: 10px auto;
+}
+
+.formContainer {
+  padding: 24px;
+  background-color: #fff;
+}
+
+.tagContainer {
+  display: flex;
+  flex-direction: column;
+}
+
+.inputTag {
+  margin-top: 15px;
+  height: 50px;
+  width: 800px;
+}
+
+.fileContainer {
+  width: 800px;
+}
+
+.uploadContainer > .el-upload__text {
+  color: #606266;
+  font-size: 14px;
+  text-align: center;
+}
+
+.upload-tips {
+  color: #b6b7b7;
+}
+</style>

+ 0 - 2
src/views/Promotion/accManage/accTencentAd.vue

@@ -34,7 +34,6 @@ import type { MenuTableReq } from '@/types/Tables/MenuTable/menuTableReq'
 
 import { TableFilterType } from '@/types/Tables/table'
 import { useRequest } from '@/hooks/useRequest'
-import { useDate } from '@/hooks/useDate'
 import { reactive } from 'vue'
 
 import MenuTable from '@/components/promotion/MenuTable.vue'
@@ -81,7 +80,6 @@ interface Operation extends Operations {
 }
 
 const { AllApi } = useRequest()
-const { shortcuts } = useDate()
 
 // 所有子字段信息
 const AllFields: AllFieldsInfo = {

+ 1 - 2
src/views/Promotion/accManage/accTtAd.vue

@@ -35,7 +35,7 @@ import type { MenuTableReq } from '@/types/Tables/MenuTable/menuTableReq'
 
 import { TableFilterType } from '@/types/Tables/table'
 import { useRequest } from '@/hooks/useRequest'
-import { useDate } from '@/hooks/useDate'
+
 import { reactive } from 'vue'
 
 import MenuTable from '@/components/promotion/MenuTable.vue'
@@ -82,7 +82,6 @@ interface Operation extends Operations {
 }
 
 const { AllApi } = useRequest()
-const { shortcuts } = useDate()
 
 // 所有子字段信息
 const AllFields: AllFieldsInfo = {

+ 1 - 2
src/views/Promotion/adManage/tencentAd.vue

@@ -35,7 +35,7 @@ import type { MenuTableReq } from '@/types/Tables/MenuTable/menuTableReq'
 
 import { TableFilterType } from '@/types/Tables/table'
 import { useRequest } from '@/hooks/useRequest'
-import { useDate } from '@/hooks/useDate'
+
 import { reactive } from 'vue'
 
 import MenuTable from '@/components/promotion/MenuTable.vue'
@@ -79,7 +79,6 @@ interface Operation extends Operations {
 }
 
 const { AllApi } = useRequest()
-const { shortcuts } = useDate()
 
 // 所有子字段信息
 const AllFields: AllFieldsInfo = {

+ 6 - 9
src/views/Promotion/adManage/ttad.vue

@@ -6,33 +6,30 @@ import type {
   Operations,
 } from '@/types/Tables/Operations/operations'
 import type {
+  BaseFieldItem,
   FilterInfo,
   TableInfoItem,
-  BaseFieldItem,
 } from '@/types/Tables/table'
+import { TableFilterType } from '@/types/Tables/table'
 import type { TablePaginationProps } from '@/types/Tables/pagination'
 import type { BaseMenu } from '@/types/Promotion/Menu'
 
 import type {
   AdmgeTTAccData,
-  AdmgeTTProjData,
-  AdmgeTTAdData,
-} from '@/types/Tables/tableData/ttAd'
-import type {
   AdmgeTTAccFileds,
-  AdmgeTTProjFileds,
+  AdmgeTTAdData,
   AdmgeTTAdFileds,
+  AdmgeTTProjData,
+  AdmgeTTProjFileds,
 } from '@/types/Tables/tableData/ttAd'
 
 import type {
-  BaseTableInfo,
   BaseAllFieldsInfo,
   BaseAllFilterInfo,
   BaseAllFixedFiledsInfo,
+  BaseTableInfo,
 } from '@/types/Tables/tablePageData'
 import type { MenuTableReq } from '@/types/Tables/MenuTable/menuTableReq'
-
-import { TableFilterType } from '@/types/Tables/table'
 import { useRequest } from '@/hooks/useRequest'
 import { useDate } from '@/hooks/useDate'
 import { reactive } from 'vue'

Fișier diff suprimat deoarece este prea mare
+ 0 - 0
stats.html


Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff