commit 7dc783a27a0e078f00043f56656aaca606d754af Author: 戴业伟 <806724993@qq.com> Date: Fri Jan 5 17:28:54 2024 +0800 feat: init diff --git a/.env.development b/.env.development new file mode 100644 index 0000000..76993a8 --- /dev/null +++ b/.env.development @@ -0,0 +1,12 @@ +## 开发环境 + +# 变量必须以 VITE_ 为前缀才能暴露给外部读取 +NODE_ENV='development' + +VITE_APP_PORT = 8090 + +# API请求前缀 +VITE_APP_BASE_API = '/api' + +# proxy代理配置 +VITE_APP_API_URL = ' http://192.168.1.7:12500/' diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..2a4f357 --- /dev/null +++ b/.env.production @@ -0,0 +1,9 @@ +## 生产环境 + +VITE_APP_PORT = 3000 + +# API请求前缀 +VITE_APP_BASE_API = '/zsqy' + +# proxy代理配置 +VITE_APP_API_URL = "" diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..43af40f --- /dev/null +++ b/.eslintignore @@ -0,0 +1,14 @@ +dist +node_modules +public +.husky +.vscode +.idea +*.sh +*.md + +src/assets + +.eslintrc.cjs +.prettierrc.cjs +.stylelintrc.cjs diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json new file mode 100644 index 0000000..f4738bf --- /dev/null +++ b/.eslintrc-auto-import.json @@ -0,0 +1,284 @@ +{ + "globals": { + "Component": true, + "ComponentPublicInstance": true, + "ComputedRef": true, + "EffectScope": true, + "ElMessage": true, + "ElMessageBox": true, + "ElNotification": true, + "InjectionKey": true, + "PropType": true, + "Ref": true, + "VNode": true, + "asyncComputed": true, + "autoResetRef": true, + "computed": true, + "computedAsync": true, + "computedEager": true, + "computedInject": true, + "computedWithControl": true, + "controlledComputed": true, + "controlledRef": true, + "createApp": true, + "createEventHook": true, + "createGlobalState": true, + "createInjectionState": true, + "createReactiveFn": true, + "createReusableTemplate": true, + "createSharedComposable": true, + "createTemplatePromise": true, + "createUnrefFn": true, + "customRef": true, + "debouncedRef": true, + "debouncedWatch": true, + "defineAsyncComponent": true, + "defineComponent": true, + "eagerComputed": true, + "effectScope": true, + "extendRef": true, + "getCurrentInstance": true, + "getCurrentScope": true, + "h": true, + "ignorableWatch": true, + "inject": true, + "isDefined": true, + "isProxy": true, + "isReactive": true, + "isReadonly": true, + "isRef": true, + "makeDestructurable": true, + "markRaw": true, + "nextTick": true, + "onActivated": true, + "onBeforeMount": true, + "onBeforeUnmount": true, + "onBeforeUpdate": true, + "onClickOutside": true, + "onDeactivated": true, + "onErrorCaptured": true, + "onKeyStroke": true, + "onLongPress": true, + "onMounted": true, + "onRenderTracked": true, + "onRenderTriggered": true, + "onScopeDispose": true, + "onServerPrefetch": true, + "onStartTyping": true, + "onUnmounted": true, + "onUpdated": true, + "pausableWatch": true, + "provide": true, + "reactify": true, + "reactifyObject": true, + "reactive": true, + "reactiveComputed": true, + "reactiveOmit": true, + "reactivePick": true, + "readonly": true, + "ref": true, + "refAutoReset": true, + "refDebounced": true, + "refDefault": true, + "refThrottled": true, + "refWithControl": true, + "resolveComponent": true, + "resolveRef": true, + "resolveUnref": true, + "shallowReactive": true, + "shallowReadonly": true, + "shallowRef": true, + "syncRef": true, + "syncRefs": true, + "templateRef": true, + "throttledRef": true, + "throttledWatch": true, + "toRaw": true, + "toReactive": true, + "toRef": true, + "toRefs": true, + "toValue": true, + "triggerRef": true, + "tryOnBeforeMount": true, + "tryOnBeforeUnmount": true, + "tryOnMounted": true, + "tryOnScopeDispose": true, + "tryOnUnmounted": true, + "unref": true, + "unrefElement": true, + "until": true, + "useActiveElement": true, + "useAnimate": true, + "useArrayDifference": true, + "useArrayEvery": true, + "useArrayFilter": true, + "useArrayFind": true, + "useArrayFindIndex": true, + "useArrayFindLast": true, + "useArrayIncludes": true, + "useArrayJoin": true, + "useArrayMap": true, + "useArrayReduce": true, + "useArraySome": true, + "useArrayUnique": true, + "useAsyncQueue": true, + "useAsyncState": true, + "useAttrs": true, + "useBase64": true, + "useBattery": true, + "useBluetooth": true, + "useBreakpoints": true, + "useBroadcastChannel": true, + "useBrowserLocation": true, + "useCached": true, + "useClipboard": true, + "useCloned": true, + "useColorMode": true, + "useConfirmDialog": true, + "useCounter": true, + "useCssModule": true, + "useCssVar": true, + "useCssVars": true, + "useCurrentElement": true, + "useCycleList": true, + "useDark": true, + "useDateFormat": true, + "useDebounce": true, + "useDebounceFn": true, + "useDebouncedRefHistory": true, + "useDeviceMotion": true, + "useDeviceOrientation": true, + "useDevicePixelRatio": true, + "useDevicesList": true, + "useDisplayMedia": true, + "useDocumentVisibility": true, + "useDraggable": true, + "useDropZone": true, + "useElementBounding": true, + "useElementByPoint": true, + "useElementHover": true, + "useElementSize": true, + "useElementVisibility": true, + "useEventBus": true, + "useEventListener": true, + "useEventSource": true, + "useEyeDropper": true, + "useFavicon": true, + "useFetch": true, + "useFileDialog": true, + "useFileSystemAccess": true, + "useFocus": true, + "useFocusWithin": true, + "useFps": true, + "useFullscreen": true, + "useGamepad": true, + "useGeolocation": true, + "useIdle": true, + "useImage": true, + "useInfiniteScroll": true, + "useIntersectionObserver": true, + "useInterval": true, + "useIntervalFn": true, + "useKeyModifier": true, + "useLastChanged": true, + "useLocalStorage": true, + "useMagicKeys": true, + "useManualRefHistory": true, + "useMediaControls": true, + "useMediaQuery": true, + "useMemoize": true, + "useMemory": true, + "useMounted": true, + "useMouse": true, + "useMouseInElement": true, + "useMousePressed": true, + "useMutationObserver": true, + "useNavigatorLanguage": true, + "useNetwork": true, + "useNow": true, + "useObjectUrl": true, + "useOffsetPagination": true, + "useOnline": true, + "usePageLeave": true, + "useParallax": true, + "useParentElement": true, + "usePerformanceObserver": true, + "usePermission": true, + "usePointer": true, + "usePointerLock": true, + "usePointerSwipe": true, + "usePreferredColorScheme": true, + "usePreferredContrast": true, + "usePreferredDark": true, + "usePreferredLanguages": true, + "usePreferredReducedMotion": true, + "usePrevious": true, + "useRafFn": true, + "useRefHistory": true, + "useResizeObserver": true, + "useScreenOrientation": true, + "useScreenSafeArea": true, + "useScriptTag": true, + "useScroll": true, + "useScrollLock": true, + "useSessionStorage": true, + "useShare": true, + "useSlots": true, + "useSorted": true, + "useSpeechRecognition": true, + "useSpeechSynthesis": true, + "useStepper": true, + "useStorage": true, + "useStorageAsync": true, + "useStyleTag": true, + "useSupported": true, + "useSwipe": true, + "useTemplateRefsList": true, + "useTextDirection": true, + "useTextSelection": true, + "useTextareaAutosize": true, + "useThrottle": true, + "useThrottleFn": true, + "useThrottledRefHistory": true, + "useTimeAgo": true, + "useTimeout": true, + "useTimeoutFn": true, + "useTimeoutPoll": true, + "useTimestamp": true, + "useTitle": true, + "useToNumber": true, + "useToString": true, + "useToggle": true, + "useTransition": true, + "useUrlSearchParams": true, + "useUserMedia": true, + "useVModel": true, + "useVModels": true, + "useVibrate": true, + "useVirtualList": true, + "useWakeLock": true, + "useWebNotification": true, + "useWebSocket": true, + "useWebWorker": true, + "useWebWorkerFn": true, + "useWindowFocus": true, + "useWindowScroll": true, + "useWindowSize": true, + "watch": true, + "watchArray": true, + "watchAtMost": true, + "watchDebounced": true, + "watchDeep": true, + "watchEffect": true, + "watchIgnorable": true, + "watchImmediate": true, + "watchOnce": true, + "watchPausable": true, + "watchPostEffect": true, + "watchSyncEffect": true, + "watchThrottled": true, + "watchTriggerable": true, + "watchWithFilter": true, + "whenever": true + } +} diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 0000000..361770f --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,141 @@ +module.exports = { + root: true, + env: { + browser: true, + es2021: true, + node: true, + }, + parser: "vue-eslint-parser", + extends: [ + // https://eslint.vuejs.org/user-guide/#usage + "plugin:vue/vue3-recommended", + "./.eslintrc-auto-import.json", + "prettier", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended", + ], + parserOptions: { + ecmaVersion: "latest", + sourceType: "module", + parser: "@typescript-eslint/parser", + project: "./tsconfig.*?.json", + createDefaultProgram: false, + extraFileExtensions: [".vue"], + }, + plugins: ["vue", "@typescript-eslint"], + rules: { + // 禁止使用 var,用 let 和 const 代替 + "no-var": "error", + + // 在 Vue 的 v-for 循环中要求使用 :key + "vue/require-v-for-key": "error", // vue的for循环是否必须有key + + // 关闭 Vue 组件名必须多字的规则 + "vue/multi-word-component-names": "off", + + // 关闭 Vue 的 v-model 中的参数规则 + "vue/no-v-model-argument": "off", + + // Vue 的 setup() 函数必须使用的变量规则 + "vue/script-setup-uses-vars": "error", + + // 关闭 Vue 组件名的保留规则 + "vue/no-reserved-component-names": "off", + + // 关闭 Vue 事件名的命名规则 + "vue/custom-event-name-casing": "off", + + // 关闭 Vue 属性的顺序规则 + "vue/attributes-order": "off", + + // 关闭一个文件只能有一个组件规则 + "vue/one-component-per-file": "off", + + // 关闭 HTML 标签闭合换行规则 + "vue/html-closing-bracket-newline": "off", + + // 关闭 HTML 属性每行最大数量规则 + "vue/max-attributes-per-line": "off", + + // 关闭多行 HTML 元素内容的规则 + "vue/multiline-html-element-content-newline": "off", + + // 关闭单行 HTML 元素内容的规则 + "vue/singleline-html-element-content-newline": "off", + + // 关闭 HTML 属性连字符的规则 + "vue/attribute-hyphenation": "off", + + // 关闭要求 Vue 默认属性的规则 + "vue/require-default-prop": "off", + + // 关闭要求 Vue 显式触发事件的规则 + "vue/require-explicit-emits": "off", + + // HTML 标签自闭合规则 + "vue/html-self-closing": [ + "error", + { + html: { + void: "always", // 自闭合标签必须自闭合 + normal: "never", // 普通标签不得自闭合 + component: "always", // 组件标签必须自闭合 + }, + svg: "always", + math: "always", + }, + ], + + // 警告空方法检查 + "@typescript-eslint/no-empty-function": "warn", + + // 关闭 any 类型的警告 + "@typescript-eslint/no-explicit-any": "off", + + // 关闭使用 @ts-ignore 的警告 + "@typescript-eslint/ban-ts-ignore": "off", + + // 关闭使用 @ts-comment 的警告 + "@typescript-eslint/ban-ts-comment": "off", + + // 关闭一些特定类型的警告 + "@typescript-eslint/ban-types": "off", + + // 关闭函数返回类型的警告 + "@typescript-eslint/explicit-function-return-type": "off", + + // 关闭 any 类型的警告 + "@typescript-eslint/no-explicit-any": "off", + + // 关闭使用 require 的警告 + "@typescript-eslint/no-var-requires": "off", + + // 关闭使用尚未定义的变量的警告 + "@typescript-eslint/no-use-before-define": "off", + + // 关闭模块导出类型的警告 + "@typescript-eslint/explicit-module-boundary-types": "off", + + // 未使用的变量的警告 + "@typescript-eslint/no-unused-vars": "warn", + + // Prettier 配置 + "prettier/prettier": [ + "error", + { + useTabs: false, // 不使用制表符 + }, + ], + }, + // eslint不能对html文件生效 + overrides: [ + { + files: ["*.html"], + processor: "vue/.vue", + }, + ], + // https://eslint.org/docs/latest/use/configure/language-options#specifying-globals + globals: { + OptionType: "readonly", + }, +}; diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..38f4dc1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local +.vscode + +# Editor directories and files +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.local + +package-lock.json +pnpm-lock.yaml +.vscode/extensions.json +.vscode/settings.json diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100644 index 0000000..e8511ea --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npx --no-install commitlint --edit $1 diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..37568d1 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/bin/sh +. "$(dirname "$0")/_/husky.sh" + +npm run lint:lint-staged diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..f3e9850 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,11 @@ +dist +node_modules +public +.husky +.vscode +.idea +*.sh +*.md + +src/assets +stats.html diff --git a/.prettierrc.cjs b/.prettierrc.cjs new file mode 100644 index 0000000..347fb32 --- /dev/null +++ b/.prettierrc.cjs @@ -0,0 +1,46 @@ +module.exports = { + // (x)=>{},单个参数箭头函数是否显示小括号。(always:始终显示;avoid:省略括号。默认:always) + arrowParens: "always", + // 开始标签的右尖括号是否跟随在最后一行属性末尾,默认false + bracketSameLine: false, + // 对象字面量的括号之间打印空格 (true - Example: { foo: bar } ; false - Example: {foo:bar}) + bracketSpacing: true, + // 是否格式化一些文件中被嵌入的代码片段的风格(auto|off;默认auto) + embeddedLanguageFormatting: "auto", + // 指定 HTML 文件的空格敏感度 (css|strict|ignore;默认css) + htmlWhitespaceSensitivity: "css", + // 当文件已经被 Prettier 格式化之后,是否会在文件顶部插入一个特殊的 @format 标记,默认false + insertPragma: false, + // 在 JSX 中使用单引号替代双引号,默认false + jsxSingleQuote: false, + // 每行最多字符数量,超出换行(默认80) + printWidth: 80, + // 超出打印宽度 (always | never | preserve ) + proseWrap: "preserve", + // 对象属性是否使用引号(as-needed | consistent | preserve;默认as-needed:对象的属性需要加引号才添加;) + quoteProps: "as-needed", + // 是否只格式化在文件顶部包含特定注释(@prettier| @format)的文件,默认false + requirePragma: false, + // 结尾添加分号 + semi: true, + // 使用单引号 (true:单引号;false:双引号) + singleQuote: false, + // 缩进空格数,默认2个空格 + tabWidth: 2, + // 元素末尾是否加逗号,默认es5: ES5中的 objects, arrays 等会添加逗号,TypeScript 中的 type 后不加逗号 + trailingComma: "es5", + // 指定缩进方式,空格或tab,默认false,即使用空格 + useTabs: false, + // vue 文件中是否缩进 +
+
+
+ +
+
+
+
+
+
+
+
+ + + + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..576f02c --- /dev/null +++ b/package.json @@ -0,0 +1,110 @@ +{ + "name": "iec104", + "version": "0.0.1", + "private": true, + "scripts": { + "preinstall": "npx only-allow pnpm", + "dev": "vite serve --mode development", + "dev:prod": "vite serve --mode production", + "build:prod": "vite build --mode production && vue-tsc --noEmit", + "prepare": "husky install", + "lint:eslint": "eslint --fix --ext .ts,.js,.vue ./src ", + "lint:prettier": "prettier --write \"**/*.{js,cjs,ts,json,tsx,css,less,scss,vue,html,md}\"", + "lint:stylelint": "stylelint \"**/*.{css,scss,vue}\" --fix", + "lint:lint-staged": "lint-staged", + "commit": "git-cz" + }, + "config": { + "commitizen": { + "path": "node_modules/cz-git" + } + }, + "lint-staged": { + "*.{js,ts}": [ + "eslint --fix", + "prettier --write" + ], + "*.{cjs,json}": [ + "prettier --write" + ], + "*.{vue,html}": [ + "eslint --fix", + "prettier --write", + "stylelint --fix" + ], + "*.{scss,css}": [ + "stylelint --fix --allow-empty-input", + "prettier --write" + ], + "*.md": [ + "prettier --write" + ] + }, + "dependencies": { + "@vicons/antd": "^0.12.0", + "@vicons/ionicons5": "^0.12.0", + "@vitejs/plugin-vue": "^4.4.0", + "@vueuse/core": "^10.5.0", + "@wangeditor/editor": "^5.1.23", + "@wangeditor/editor-for-vue": "5.1.10", + "@types/crypto-js": "^4.1.1", + "axios": "^1.6.0", + "crypto-js": "^4.2.0", + "echarts": "^5.4.3", + "lodash-es": "^4.17.21", + "naive-ui": "^2.36.0", + "path-browserify": "^1.0.1", + "path-to-regexp": "^6.2.1", + "pinia": "^2.1.7", + "terser": "^5.24.0", + "vue": "^3.3.8", + "vue-router": "^4.2.5", + "vue-types": "^5.1.1", + "vue3-seamless-scroll": "^2.0.1", + "vuedraggable": "^2.24.3" + }, + "devDependencies": { + "@commitlint/cli": "^17.8.1", + "@commitlint/config-conventional": "^17.8.1", + "@iconify-json/ep": "^1.1.12", + "@types/lodash": "^4.14.201", + "@types/path-browserify": "^1.0.2", + "@typescript-eslint/eslint-plugin": "^6.12.0", + "@typescript-eslint/parser": "^6.12.0", + "@vitejs/plugin-vue-jsx": "^3.0.2", + "autoprefixer": "^10.4.16", + "commitizen": "^4.3.0", + "cz-git": "^1.7.1", + "eslint": "^8.54.0", + "eslint-config-prettier": "^8.10.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-vue": "^9.18.1", + "fast-glob": "^3.3.2", + "husky": "^8.0.3", + "lint-staged": "^13.3.0", + "postcss": "^8.4.31", + "postcss-html": "^1.5.0", + "postcss-px-to-viewport": "^1.1.1", + "postcss-scss": "^4.0.9", + "prettier": "^2.8.8", + "sass": "^1.69.5", + "stylelint": "^15.11.0", + "stylelint-config-html": "^1.1.0", + "stylelint-config-recess-order": "^4.3.0", + "stylelint-config-recommended-scss": "^13.1.0", + "stylelint-config-recommended-vue": "^1.5.0", + "stylelint-config-standard": "^34.0.0", + "stylelint-config-standard-scss": "^11.1.0", + "typescript": "^5.3.2", + "unplugin-auto-import": "^0.15.3", + "unplugin-icons": "^0.16.6", + "unplugin-vue-components": "^0.24.1", + "vite": "^4.5.0", + "vite-plugin-svg-icons": "^2.0.1", + "vue-tsc": "^1.8.22" + }, + "engines": { + "node": ">=16.0.0" + } +} diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..80b2b22 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,20 @@ +module.exports = { + plugins: { + autoprefixer: {}, //// 用来给不同的浏览器自动添加相应前缀,如-webkit-,-moz-等等 + "postcss-px-to-viewport": { + unitToConvert: "px", // 要转化的单位 + viewportWidth: 1920, // UI设计稿的宽度 + viewportHeight: 1080, + unitPrecision: 6, // 转换后的精度,即小数点位数 + propList: ["*"], // 指定转换的css属性的单位,*代表全部css属性的单位都进行转换 + viewportUnit: "vw", // 指定需要转换成的视窗单位,默认vw + fontViewportUnit: "vw", // 指定字体需要转换成的视窗单位,默认vw + selectorBlackList: [".ignore"], // 指定不转换为视窗单位的类名, + minPixelValue: 1, // 默认值1,小于或等于1px则不进行转换 + mediaQuery: false, // 是否在媒体查询的css代码中也进行转换,默认false + replace: true, // 是否转换后直接更换属性值 + exclude: /(\/|\\)(node_modules)(\/|\\)/, // 设置忽略文件,用正则做目录名匹配 + // landscape: true // 是否处理横屏情况, + }, + }, +}; diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..de873ed Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/font/PingFang.otf b/public/font/PingFang.otf new file mode 100644 index 0000000..db15dc5 Binary files /dev/null and b/public/font/PingFang.otf differ diff --git a/public/font/SourceHanSansCN-Light.otf b/public/font/SourceHanSansCN-Light.otf new file mode 100644 index 0000000..1cff8e6 Binary files /dev/null and b/public/font/SourceHanSansCN-Light.otf differ diff --git a/public/font/SourceHanSansK-Regular.ttf b/public/font/SourceHanSansK-Regular.ttf new file mode 100644 index 0000000..52a4dec Binary files /dev/null and b/public/font/SourceHanSansK-Regular.ttf differ diff --git a/public/font/YouSheBiaoTiHei-2.ttf b/public/font/YouSheBiaoTiHei-2.ttf new file mode 100644 index 0000000..3729151 Binary files /dev/null and b/public/font/YouSheBiaoTiHei-2.ttf differ diff --git a/public/font/index.css b/public/font/index.css new file mode 100644 index 0000000..24a9179 --- /dev/null +++ b/public/font/index.css @@ -0,0 +1,27 @@ +@font-face { + font-family: YouSheBiaoTiHei; + font-style: normal; + font-weight: normal; + src: url("./YouSheBiaoTiHei-2.ttf"); +} + +@font-face { + font-family: SourceHanSansCN; + font-style: normal; + font-weight: normal; + src: url("./SourceHanSansCN-Light.otf"); +} + +@font-face { + font-family: SourceHanSansK; + font-style: normal; + font-weight: normal; + src: url("./SourceHanSansK-Regular.ttf"); +} + +@font-face { + font-family: PingFang; + font-style: normal; + font-weight: normal; + src: url("./PingFang.otf"); +} \ No newline at end of file diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..de873ed Binary files /dev/null and b/public/logo.png differ diff --git a/public/logo2.png b/public/logo2.png new file mode 100644 index 0000000..7cb6473 Binary files /dev/null and b/public/logo2.png differ diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..f06bddf --- /dev/null +++ b/src/App.vue @@ -0,0 +1,10 @@ + + + diff --git a/src/api/axios.ts b/src/api/axios.ts new file mode 100644 index 0000000..d51234d --- /dev/null +++ b/src/api/axios.ts @@ -0,0 +1,48 @@ +import axios, { AxiosResponse, AxiosRequestConfig } from "axios"; +import { ResultEnum } from "@/enums/httpEnum"; +// import { ErrorPageNameMap } from "@/enums/pageEnum"; +// import { redirectErrorPage } from "@/utils"; + +const axiosInstance = axios.create({ + baseURL: import.meta.env.DEV + ? import.meta.env.VITE_APP_API_URL + : `http://${window.location.host}/`, + timeout: ResultEnum.TIMEOUT, +}); + +// 请求拦截器 +axiosInstance.interceptors.request.use( + (config) => { + return config; + }, + (error: AxiosRequestConfig) => { + return Promise.reject(error); + } +); + +// 响应拦截器 +axiosInstance.interceptors.response.use( + (res: AxiosResponse) => { + const { message, success } = res.data as { + success: boolean; + message: string; + }; + + // 如果是文件流,直接过 + if (res.config.responseType === "blob") return Promise.resolve(res.data); + if (success) return Promise.resolve(res.data); + // 如果 success 为 false,显示服务器返回的错误消息 + window["$message"].error(message || "系统错误"); + + // 重定向 + // if (ErrorPageNameMap.get(status)) redirectErrorPage(status); + return Promise.resolve(res.data); + }, + (err: AxiosResponse) => { + window["$message"].error("接口异常,请检查"); + return Promise.reject(err); + } +); + +// 导出 axios 实例 +export default axiosInstance; diff --git a/src/api/http.ts b/src/api/http.ts new file mode 100644 index 0000000..aefd735 --- /dev/null +++ b/src/api/http.ts @@ -0,0 +1,221 @@ +import axiosInstance from "./axios"; +import type { + RequestGlobalConfigType, + RequestConfigType, +} from "@/enums/httpEnum"; +import { + RequestHttpEnum, + ContentTypeEnum, + RequestBodyEnum, + RequestDataTypeEnum, + RequestContentTypeEnum, + RequestParamsObjType, +} from "@/enums/httpEnum"; + +export const get = (url: string, params?: object) => { + return axiosInstance({ + url: url, + method: RequestHttpEnum.GET, + params: params, + headers: { + Authorization: "7df1bd95-bf13-4660-a07d-90b8b1b314e8", + }, + }); +}; + +export const post = (url: string, data?: object, headersType?: string) => { + return axiosInstance({ + url: url, + method: RequestHttpEnum.POST, + data: data, + headers: { + "Content-Type": headersType || ContentTypeEnum.JSON, + Authorization: "7df1bd95-bf13-4660-a07d-90b8b1b314e8", + }, + }); +}; + +export const patch = (url: string, data?: object, headersType?: string) => { + return axiosInstance({ + url: url, + method: RequestHttpEnum.PATCH, + data: data, + headers: { + "Content-Type": headersType || ContentTypeEnum.JSON, + }, + }); +}; + +export const put = ( + url: string, + data?: object, + headersType?: ContentTypeEnum +) => { + return axiosInstance({ + url: url, + method: RequestHttpEnum.PUT, + data: data, + headers: { + "Content-Type": headersType || ContentTypeEnum.JSON, + }, + }); +}; + +export const del = (url: string, params?: object) => { + return axiosInstance({ + url: url, + method: RequestHttpEnum.DELETE, + params, + }); +}; + +// 获取请求函数,默认get +export const http = (type?: RequestHttpEnum) => { + switch (type) { + case RequestHttpEnum.GET: + return get; + + case RequestHttpEnum.POST: + return post; + + case RequestHttpEnum.PATCH: + return patch; + + case RequestHttpEnum.PUT: + return put; + + case RequestHttpEnum.DELETE: + return del; + + default: + return get; + } +}; + +/** + * * 自定义请求 + * @param targetParams 当前组件参数 + * @param globalParams 全局参数 + */ +export const customizeHttp = ( + targetParams: RequestConfigType, + globalParams: RequestGlobalConfigType +) => { + if (!targetParams || !globalParams) { + return; + } + + // 全局 + const { + // 全局请求源地址 + requestOriginUrl, + // 全局请求内容 + requestParams: globalRequestParams, + } = globalParams; + + // 目标组件(优先级 > 全局组件) + const { + // requestInterval, + // 请求地址 + requestUrl, + // 普通 / sql + requestContentType, + // 获取数据的方式 + requestDataType, + // 请求方式 get/post/del/put/patch + requestHttpType, + // 请求体类型 none / form-data / x-www-form-urlencoded / json /xml + requestParamsBodyType, + // SQL 请求对象 + requestSQLContent, + // 请求内容 params / cookie / header / body: 同 requestParamsBodyType + requestParams: targetRequestParams, + } = targetParams; + + // 静态排除 + if (requestDataType === RequestDataTypeEnum.STATIC) return; + + if (!requestUrl) { + return; + } + + // 处理头部 + const headers: RequestParamsObjType = { + ...globalRequestParams.Header, + ...targetRequestParams.Header, + }; + + // data 参数 + let data: RequestParamsObjType | FormData | string = {}; + // params 参数 + const params: RequestParamsObjType = targetRequestParams.Params; + // form 类型处理 + const formData: FormData = new FormData(); + formData.set("default", "defaultData"); + // 类型处理 + + switch (requestParamsBodyType) { + case RequestBodyEnum.NONE: + break; + + case RequestBodyEnum.JSON: + headers["Content-Type"] = ContentTypeEnum.JSON; + data = JSON.parse(targetRequestParams.Body["json"]); + // json 赋值给 data + break; + + case RequestBodyEnum.XML: + headers["Content-Type"] = ContentTypeEnum.XML; + // xml 字符串赋值给 data + data = targetRequestParams.Body["xml"]; + break; + + case RequestBodyEnum.X_WWW_FORM_URLENCODED: + headers["Content-Type"] = ContentTypeEnum.FORM_URLENCODED; + const bodyFormData = targetRequestParams.Body["x-www-form-urlencoded"]; + for (const i in bodyFormData) formData.set(i, bodyFormData[i]); + // FormData 赋值给 data + data = formData; + break; + + case RequestBodyEnum.FORM_DATA: + headers["Content-Type"] = ContentTypeEnum.FORM_DATA; + const bodyFormUrlencoded = targetRequestParams.Body["form-data"]; + for (const i in bodyFormUrlencoded) { + formData.set(i, bodyFormUrlencoded[i]); + } + // FormData 赋值给 data + data = formData; + break; + } + + // sql 处理 + if (requestContentType === RequestContentTypeEnum.SQL) { + headers["Content-Type"] = ContentTypeEnum.JSON; + data = requestSQLContent; + } + // 如果定义了 requestInterval 且请求次数未达到某个上限,则使用 setInterval 实现轮询 + // let requestCount = 0; + // if (requestInterval && requestCount < 1) { + // const intervalId = setInterval(() => { + // // 在此处调用 customizeHttp 以实现轮询 + // customizeHttp(targetParams, globalParams); + + // // 增加请求计数 + // requestCount++; + + // // 如果请求次数达到上限,清除定时器 + // if (requestCount >= 1) { + // clearInterval(intervalId); + // } + // }, requestInterval * 1000); + // } + + return axiosInstance({ + url: `${requestOriginUrl}${requestUrl}`, + method: requestHttpType, + data, + params, + headers, + }); +}; diff --git a/src/api/system/index.ts b/src/api/system/index.ts new file mode 100644 index 0000000..4fbc74d --- /dev/null +++ b/src/api/system/index.ts @@ -0,0 +1 @@ +export * from "./menu"; diff --git a/src/api/system/menu.ts b/src/api/system/menu.ts new file mode 100644 index 0000000..8b7ec2a --- /dev/null +++ b/src/api/system/menu.ts @@ -0,0 +1,16 @@ +import { get, post } from "@/api/http"; + +const fix = "/menu"; + +const url = { + insert: `${fix}/insert`, // 分页查询 + tree: `${fix}/tree`, // 查询菜单 +}; + +export const insertMenu = (params: Object) => { + return post(url.insert, params); +}; + +export const getTree = () => { + return get(url.tree); +}; diff --git a/src/assets/images/401.gif b/src/assets/images/401.gif new file mode 100644 index 0000000..cd6e0d9 Binary files /dev/null and b/src/assets/images/401.gif differ diff --git a/src/assets/images/404.png b/src/assets/images/404.png new file mode 100644 index 0000000..3d8e230 Binary files /dev/null and b/src/assets/images/404.png differ diff --git a/src/assets/images/404_cloud.png b/src/assets/images/404_cloud.png new file mode 100644 index 0000000..c6281d0 Binary files /dev/null and b/src/assets/images/404_cloud.png differ diff --git a/src/assets/images/account-logo.png b/src/assets/images/account-logo.png new file mode 100644 index 0000000..22cffd5 Binary files /dev/null and b/src/assets/images/account-logo.png differ diff --git a/src/assets/images/active.png b/src/assets/images/active.png new file mode 100644 index 0000000..e614e49 Binary files /dev/null and b/src/assets/images/active.png differ diff --git a/src/assets/images/camera1.png b/src/assets/images/camera1.png new file mode 100644 index 0000000..20e4840 Binary files /dev/null and b/src/assets/images/camera1.png differ diff --git a/src/assets/images/camera2.png b/src/assets/images/camera2.png new file mode 100644 index 0000000..610e518 Binary files /dev/null and b/src/assets/images/camera2.png differ diff --git a/src/assets/images/chart.png b/src/assets/images/chart.png new file mode 100644 index 0000000..1ffb051 Binary files /dev/null and b/src/assets/images/chart.png differ diff --git a/src/assets/images/header.png b/src/assets/images/header.png new file mode 100644 index 0000000..ac6f91f Binary files /dev/null and b/src/assets/images/header.png differ diff --git a/src/assets/images/inactive.png b/src/assets/images/inactive.png new file mode 100644 index 0000000..dab9757 Binary files /dev/null and b/src/assets/images/inactive.png differ diff --git a/src/assets/images/login.svg b/src/assets/images/login.svg new file mode 100644 index 0000000..2490aa7 --- /dev/null +++ b/src/assets/images/login.svg @@ -0,0 +1,127 @@ + + + Group 21 + Created with Sketch. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +