├── .env.development ├── .env.production ├── .env.staging ├── .gitignore ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── public └── favicon.ico ├── src ├── App.vue ├── assets │ ├── css │ │ ├── mixin.scss │ │ └── reset.css │ ├── img │ │ ├── 404.png │ │ ├── admin.png │ │ ├── avatar.png │ │ └── login.jpg │ └── pages │ │ └── 可视化.html ├── components │ ├── Amap.vue │ ├── Icons.vue │ ├── NotFound.vue │ ├── RouteView.vue │ ├── WEditor.vue │ └── olmap.vue ├── layout │ ├── Aside.vue │ ├── Header.vue │ └── Index.vue ├── main.js ├── router │ ├── index.js │ └── router.js ├── store │ ├── index.js │ └── mutation-types.js ├── utils │ ├── axios.js │ ├── oss.js │ └── tool.js └── views │ ├── Index.vue │ ├── admin │ ├── AuthList.vue │ ├── RoleList.vue │ └── User.vue │ ├── common │ ├── Editor.vue │ └── XGPlayer.vue │ ├── data │ ├── Charts.vue │ └── List.vue │ └── login │ └── Login.vue └── vite.config.js /.env.development: -------------------------------------------------------------------------------- 1 | NODE_ENV = development 2 | 3 | VITE_APP_TITLE = '【开发环境】后台管理系统' 4 | VITE_APP_BASE_API = '' 5 | -------------------------------------------------------------------------------- /.env.production: -------------------------------------------------------------------------------- 1 | NODE_ENV = production 2 | 3 | VITE_APP_TITLE = '【生产环境】后台管理系统' 4 | VITE_APP_BASE_API = '' 5 | -------------------------------------------------------------------------------- /.env.staging: -------------------------------------------------------------------------------- 1 | NODE_ENV = staging 2 | 3 | VITE_APP_TITLE = '郑州无源淹没可视化系统' 4 | VITE_APP_BASE_API = '' 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 2022floodmap 2 | webgis毕业设计 3 | # 依赖安装 4 | npm install 5 | # 运行 6 | npm run dev 7 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 郑州无源淹没可视化平台 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite_admin", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "@amap/amap-jsapi-loader": "^1.0.1", 11 | "@antv/g2plot": "^2.4.5", 12 | "@element-plus/icons": "^0.0.11", 13 | "ajax": "^0.0.4", 14 | "ali-oss": "^6.16.0", 15 | "axios": "^0.24.0", 16 | "dayjs": "^1.10.7", 17 | "echarts": "4.2.1", 18 | "element-plus": "^1.3.0-beta.3", 19 | "esri-loader": "^3.5.0", 20 | "jquery": "^3.6.0", 21 | "nprogress": "^0.2.0", 22 | "ol": "^5.3.3", 23 | "qs": "^6.10.2", 24 | "screenfull": "^6.0.0", 25 | "video.js": "^7.18.1", 26 | "videojs-contrib-hls": "^5.15.0", 27 | "vite": "^2.7.10", 28 | "vue": "^3.2.8", 29 | "vue-router": "^4.0.11", 30 | "vue-video-player": "^5.0.2", 31 | "vuex": "^4.0.2", 32 | "vuex-persistedstate": "^4.1.0", 33 | "wangeditor": "^4.7.11", 34 | "xgplayer": "^2.31.4" 35 | }, 36 | "devDependencies": { 37 | "@vitejs/plugin-vue": "^2.0.1", 38 | "@vue/compiler-sfc": "^3.2.26", 39 | "js-base64": "^3.7.2", 40 | "sass": "^1.47.0", 41 | "secure-ls": "^1.2.6", 42 | "vite-plugin-imp": "^2.1.2" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fly372000/2022floodmap/225643ffd9472387877b2b724dbb3fcac2ac35e4/public/favicon.ico -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 31 | -------------------------------------------------------------------------------- /src/assets/css/mixin.scss: -------------------------------------------------------------------------------- 1 | /* 隐藏右侧滚动条 */ 2 | @mixin no_scrollbar { 3 | overflow: hidden; 4 | overflow-y: scroll; 5 | overflow: -moz-hidden-unscrollable; 6 | scrollbar-width: none; 7 | &::-webkit-scrollbar { 8 | width: 0 !important; 9 | } 10 | } 11 | 12 | /* 自定义右侧滚动条 */ 13 | @mixin zdy_scrollbar { 14 | scrollbar-width: thin; 15 | scrollbar-color: #e5e5e5 #f7f7f9; 16 | &::-webkit-scrollbar { 17 | width: 10px; 18 | height: 8px; 19 | background-color: #f5f5f5; 20 | } 21 | &::-webkit-scrollbar-thumb { 22 | background-color: #ddd; 23 | border-radius: 10px; 24 | } 25 | &::-webkit-scrollbar-thumb:hover { 26 | background-color: rgba(101, 45, 190, 0.362); 27 | border-radius: 10px; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/assets/css/reset.css: -------------------------------------------------------------------------------- 1 | html { 2 | -ms-overflow-style: none; 3 | overflow: -moz-scrollbars-none; 4 | overflow: hidden; 5 | overflow-y: scroll; 6 | scrollbar-width: none; 7 | } 8 | html::-webkit-scrollbar { 9 | width: 0 !important; 10 | } 11 | body { 12 | -webkit-text-size-adjust: 100%; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-font-smoothing: antialiased; 15 | text-rendering: optimizeLegibility; 16 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; 17 | } 18 | body, 19 | ol, 20 | ul, 21 | h1, 22 | h2, 23 | h3, 24 | h4, 25 | h5, 26 | h6, 27 | p, 28 | th, 29 | td, 30 | dl, 31 | dd, 32 | form, 33 | fieldset, 34 | legend, 35 | input, 36 | textarea, 37 | select { 38 | margin: 0; 39 | padding: 0; 40 | } 41 | a { 42 | text-decoration: none; 43 | } 44 | a:hover { 45 | text-decoration: underline; 46 | } 47 | em { 48 | font-style: normal; 49 | } 50 | /* li { 51 | list-style: none; 52 | } */ 53 | img { 54 | border: 0; 55 | vertical-align: middle; 56 | } 57 | table { 58 | border-collapse: collapse; 59 | border-spacing: 0; 60 | } 61 | p { 62 | word-wrap: break-word; 63 | } 64 | /* 禁止复制选中文本 */ 65 | /* * { 66 | user-select: none; 67 | -moz-user-select: none; 68 | -ms-user-select: none; 69 | -webkit-user-select: none; 70 | } */ 71 | -------------------------------------------------------------------------------- /src/assets/img/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fly372000/2022floodmap/225643ffd9472387877b2b724dbb3fcac2ac35e4/src/assets/img/404.png -------------------------------------------------------------------------------- /src/assets/img/admin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fly372000/2022floodmap/225643ffd9472387877b2b724dbb3fcac2ac35e4/src/assets/img/admin.png -------------------------------------------------------------------------------- /src/assets/img/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fly372000/2022floodmap/225643ffd9472387877b2b724dbb3fcac2ac35e4/src/assets/img/avatar.png -------------------------------------------------------------------------------- /src/assets/img/login.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fly372000/2022floodmap/225643ffd9472387877b2b724dbb3fcac2ac35e4/src/assets/img/login.jpg -------------------------------------------------------------------------------- /src/assets/pages/可视化.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 鄱阳降雨可视化 6 | 7 | 8 |
9 |
10 | 11 | 143 | 144 | 145 | -------------------------------------------------------------------------------- /src/components/Amap.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 83 | 84 | 103 | -------------------------------------------------------------------------------- /src/components/Icons.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 30 | -------------------------------------------------------------------------------- /src/components/NotFound.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 32 | 33 | 44 | -------------------------------------------------------------------------------- /src/components/RouteView.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /src/components/WEditor.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 77 | 78 | 86 | -------------------------------------------------------------------------------- /src/components/olmap.vue: -------------------------------------------------------------------------------- 1 | 2 | 23 | 222 | -------------------------------------------------------------------------------- /src/layout/Aside.vue: -------------------------------------------------------------------------------- 1 | 53 | 54 | 84 | 85 | 172 | -------------------------------------------------------------------------------- /src/layout/Header.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 75 | 76 | 123 | -------------------------------------------------------------------------------- /src/layout/Index.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 35 | 36 | 93 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue"; 2 | import "./assets/css/reset.css"; 3 | import ElementPlus from "element-plus"; 4 | import "element-plus/dist/index.css"; 5 | // 自定义icon组件 6 | import Icons from "@/components/Icons.vue"; 7 | 8 | import App from "./App.vue"; 9 | import router from "./router"; 10 | import store from "./store"; 11 | import axios from "./utils/axios"; 12 | import qs from "qs"; 13 | import oss from "./utils/oss"; /* 上传文件 */ 14 | 15 | const app = createApp(App); 16 | 17 | app.config.globalProperties.$axios = axios; 18 | app.config.globalProperties.$qs = qs; 19 | app.config.globalProperties.$oss = oss; 20 | 21 | // 全部加载 22 | app.use(ElementPlus); 23 | // 引入自定义Icons 24 | app.component("Icons", Icons); 25 | 26 | app.use(router).use(store).mount("#app"); 27 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from "vue-router"; 2 | import { decode } from "js-base64"; 3 | import { routes } from "./router"; 4 | import NProgress from "nprogress"; 5 | import "nprogress/nprogress.css"; 6 | 7 | NProgress.configure({ showSpinner: false }); 8 | 9 | const router = createRouter({ 10 | history: createWebHistory(), 11 | routes: [...routes], 12 | scrollBehavior(to, from, savedPosition) { 13 | if (savedPosition) { 14 | return savedPosition; 15 | } else { 16 | return { top: 0 }; 17 | } 18 | } 19 | }); 20 | 21 | router.beforeEach((to, from, next) => { 22 | NProgress.start(); 23 | 24 | document.title = to.meta && to.meta.title ? to.meta.title + " - 管理应用" : "管理系统"; 25 | 26 | const jwt = sessionStorage.getItem("jwt") || ""; 27 | 28 | if (to.path === "/login") { 29 | !!jwt ? next("/") : next(); 30 | } else { 31 | if (from.name === "Login" && !jwt) { 32 | next(false); 33 | return false; 34 | } 35 | if (!!jwt) { 36 | if (to.meta.hasOwnProperty("roles")) { 37 | let roles = to.meta.roles || []; 38 | let { role } = jwt && JSON.parse(decode(jwt)); 39 | roles.includes(role) ? next() : next("/error"); 40 | return false; 41 | } 42 | next(); 43 | } else { 44 | next("/login"); 45 | } 46 | } 47 | }); 48 | 49 | router.afterEach(() => { 50 | NProgress.done(); 51 | }); 52 | 53 | export default router; 54 | -------------------------------------------------------------------------------- /src/router/router.js: -------------------------------------------------------------------------------- 1 | import Layout from "../layout/Index.vue"; 2 | import RouteView from "../components/RouteView.vue"; 3 | 4 | const layoutMap = [ 5 | { 6 | path: "", 7 | name: "Index", 8 | meta: { title: "研究区域位置", icon: "HomeFilled" }, 9 | component: () => import("../views/Index.vue") 10 | }, 11 | { 12 | path: "olmap", 13 | name: "plmap", 14 | meta: { title: "淹没可视化", icon: "LocationFilled" }, 15 | component: () => import("../components/olmap.vue") 16 | }, 17 | 18 | 19 | { 20 | path: "table", 21 | name: "DataList", 22 | meta: { title: "行政区淹没情况", icon: "DataAnalysis"}, 23 | component: () => import("../views/data/List.vue") 24 | }, 25 | 26 | 27 | { 28 | path: "admin", 29 | name: "Admin", 30 | meta: { title: "用户管理", icon: "User", roles: ["admin"] }, 31 | component: RouteView, 32 | children: [ 33 | { 34 | path: "", 35 | name: "AdminAuth", 36 | meta: { title: "用户列表" }, 37 | component: () => import("../views/admin/AuthList.vue") 38 | }, 39 | { 40 | path: "role", 41 | name: "AdminRole", 42 | meta: { title: "角色列表" }, 43 | component: () => import("../views/admin/RoleList.vue") 44 | } 45 | ] 46 | }, 47 | /* { 48 | path: "player", 49 | name: "Player", 50 | meta: { title: "淹没模拟动画", icon: "Film" }, 51 | component: () => import("../views/common/XGPlayer.vue") 52 | }, */ 53 | { 54 | path: "charts", 55 | name: "Charts", 56 | meta: { title: "数据可视化", icon: "trend-charts" }, 57 | component: () => import("../views/data/Charts.vue") 58 | }, 59 | /* { 60 | path: "editor", 61 | name: "Editor", 62 | meta: { title: "项目简介", icon: "Document" }, 63 | component: () => import("../views/common/Editor.vue") 64 | }, */ 65 | { 66 | path: "user", 67 | name: "User", 68 | hidden: true /* 不在侧边导航展示 */, 69 | meta: { title: "个人中心" }, 70 | component: () => import("../views/admin/User.vue") 71 | }, 72 | { 73 | path: "/error", 74 | name: "NotFound", 75 | hidden: true, 76 | meta: { title: "404" }, 77 | component: () => import("../components/NotFound.vue") 78 | }, 79 | { 80 | path: "/:w+", 81 | hidden: true, 82 | redirect: { name: "NotFound" } 83 | } 84 | ]; 85 | 86 | const routes = [ 87 | { path: "/login", name: "Login", meta: { title: "登录" }, component: () => import("../views/login/Login.vue") }, 88 | { path: "/", name: "Layout", component: Layout, children: [...layoutMap] } 89 | ]; 90 | 91 | export { routes, layoutMap }; 92 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import { createStore } from "vuex"; 2 | import { layoutMap } from "../router/router"; 3 | import { filterAsyncRouter } from "../utils/tool"; 4 | import createPersistedState from "vuex-persistedstate"; 5 | import SecureLS from "secure-ls"; 6 | import { CLEAR_USER, SET_USER, SET_ROUTES } from "./mutation-types"; 7 | 8 | const state = { 9 | users: null, 10 | routers: [] 11 | }; 12 | 13 | const getters = { 14 | getUserName(state) { 15 | return !state.users ? "" : state.users.username; 16 | } 17 | }; 18 | 19 | const mutations = { 20 | [CLEAR_USER](state) { 21 | state.users = null; 22 | state.routers = []; 23 | }, 24 | [SET_USER](state, payload) { 25 | state.users = payload; 26 | }, 27 | [SET_ROUTES](state, payload) { 28 | state.routers = payload; 29 | } 30 | }; 31 | 32 | const ls = new SecureLS({ 33 | encodingType: "aes" /* 加密方式 */, 34 | isCompression: false /* 压缩数据 */, 35 | encryptionSecret: "vite-vue" /* 加密密钥 */ 36 | }); 37 | 38 | const actions = { 39 | clearUser({ commit }) { 40 | commit(CLEAR_USER); 41 | }, 42 | setUser({ commit }, payload) { 43 | let deepCopy = JSON.parse(JSON.stringify(layoutMap)), 44 | accessedRouters = filterAsyncRouter(deepCopy, payload.role); 45 | commit(SET_USER, payload); 46 | commit(SET_ROUTES, accessedRouters); 47 | } 48 | }; 49 | 50 | const myPersistedState = createPersistedState({ 51 | key: "store", 52 | storage: window.sessionStorage, 53 | // storage: { 54 | // getItem: state => ls.get(state), 55 | // setItem: (state, value) => ls.set(state, value), 56 | // removeItem: state => ls.remove(state) 57 | // } /* 永久存储 */ 58 | reducer(state) { 59 | return { ...state }; 60 | } 61 | }); 62 | 63 | export default createStore({ 64 | state, 65 | getters, 66 | mutations, 67 | actions 68 | // plugins: [myPersistedState] 69 | }); 70 | -------------------------------------------------------------------------------- /src/store/mutation-types.js: -------------------------------------------------------------------------------- 1 | // 清除用户信息 2 | export const CLEAR_USER = "CLEAR_USER"; 3 | // 存储用户信息 4 | export const SET_USER = "SET_USER"; 5 | // 存储路由菜单 6 | export const SET_ROUTES = "SET_ROUTES"; 7 | -------------------------------------------------------------------------------- /src/utils/axios.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | // 创建 axios 4 | const service = axios.create({ 5 | baseURL: import.meta.env.VITE_APP_BASE_API, 6 | timeout: 10000 7 | }); 8 | 9 | // 请求拦截 request 10 | service.interceptors.request.use( 11 | config => { 12 | // 用户请求头 13 | // config.headers.token = ""; 14 | // config.headers.userId = ""; 15 | return config; 16 | }, 17 | err => { 18 | Promise.reject(err); 19 | } 20 | ); 21 | 22 | // 相应拦截 reponse 23 | service.interceptors.response.use( 24 | response => { 25 | // 处理登录无效问题 26 | return response; 27 | }, 28 | err => { 29 | return Promise.reject(err); 30 | } 31 | ); 32 | 33 | export default service; 34 | -------------------------------------------------------------------------------- /src/utils/oss.js: -------------------------------------------------------------------------------- 1 | import dayjs from "dayjs"; 2 | import OSS from "ali-oss"; 3 | import { ElMessage } from "element-plus"; 4 | 5 | /* 文件重命名 */ 6 | const fileRename = (file, rootPath = "", fileType = [], size = 0) => { 7 | if (!(file instanceof Object)) return null; 8 | // 文件大小限制 9 | if (size && file.size >= size * 1024 * 1024) { 10 | ElMessage.warning(`上传的文件大小不能超过 ${size}M,请重新上传!`); 11 | return null; 12 | } 13 | 14 | let fileName = file.name.toLowerCase(), 15 | dotIndex = fileName.lastIndexOf("."), 16 | fileSuffix = fileName.substr(dotIndex); 17 | let fileTypeString = fileType.join("."); 18 | // 文件类型限制 19 | if (fileTypeString && !fileTypeString.includes(fileSuffix)) { 20 | ElMessage.error("上传文件类型有误,请重新上传!"); 21 | return null; 22 | } 23 | // 文件路径处理 24 | let filePath = dayjs().format("YYYY_MM/DD_HHmmss_SSS"); 25 | return rootPath + filePath + fileSuffix; 26 | }; 27 | 28 | /** 29 | * @module 文件上传 30 | * @param {Object} file - 文件对象 31 | * @param {String} rootPath - 文件根路径 32 | * @param {Array} fileType - 文件类型 33 | * @param {Number} size - 文件大小 34 | * @returns {String} - 上传文件地址 35 | **/ 36 | export default async (file, rootPath, fileType, size) => { 37 | let fileName = fileRename(file, rootPath, fileType, size); 38 | if (!fileName) return null; 39 | // 配置client-OSS 40 | let client = new OSS({ 41 | region: "oss-cn-beijing", 42 | accessKeyId: "accessKeyId", 43 | accessKeySecret: "accessKeySecret", 44 | stsToken: "" /* 鉴权 */, 45 | bucket: "bucket" /* oss文件前缀 */ 46 | }); 47 | 48 | try { 49 | let { res, url } = await client.put(fileName, file); 50 | if (res.status == 200) { 51 | ElMessage.success("上传成功"); 52 | return url; 53 | } 54 | ElMessage.error("上传失败"); 55 | return null; 56 | } catch (e) { 57 | ElMessage.error("文件上传失败"); 58 | return null; 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /src/utils/tool.js: -------------------------------------------------------------------------------- 1 | /* 处理权限 */ 2 | export const hasPermission = (route, role) => { 3 | if (route.meta && route.meta.roles) { 4 | return route.meta.roles.includes(role); 5 | } 6 | return true; /* 默认不设权限 */ 7 | }; 8 | 9 | export const filterAsyncRouter = (routerMap, roles) => { 10 | const accessedRouters = routerMap.filter(route => { 11 | if (hasPermission(route, roles)) { 12 | if (route.children && route.children.length) { 13 | route.children = filterAsyncRouter(route.children, roles); 14 | } 15 | return true; 16 | } 17 | return false; 18 | }); 19 | return accessedRouters; 20 | }; 21 | -------------------------------------------------------------------------------- /src/views/Index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 24 | 25 | 32 | -------------------------------------------------------------------------------- /src/views/admin/AuthList.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 21 | -------------------------------------------------------------------------------- /src/views/admin/RoleList.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 13 | 14 | 21 | -------------------------------------------------------------------------------- /src/views/admin/User.vue: -------------------------------------------------------------------------------- 1 | 72 | 73 | 104 | 105 | 137 | -------------------------------------------------------------------------------- /src/views/common/Editor.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 36 | 37 | 44 | -------------------------------------------------------------------------------- /src/views/common/XGPlayer.vue: -------------------------------------------------------------------------------- 1 | 37 | 38 | 59 | 60 | -------------------------------------------------------------------------------- /src/views/data/Charts.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 152 | 153 | 155 | -------------------------------------------------------------------------------- /src/views/data/List.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 263 | 264 | 272 | -------------------------------------------------------------------------------- /src/views/login/Login.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 115 | 116 | 137 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "vite"; 2 | import vue from "@vitejs/plugin-vue"; 3 | const { resolve } = require("path"); 4 | 5 | export default defineConfig({ 6 | plugins: [vue()], 7 | resolve: { 8 | alias: [ 9 | { 10 | find: "@", 11 | replacement: resolve(__dirname, "src") 12 | } 13 | ] 14 | }, 15 | server: { 16 | open: true, 17 | cors: true 18 | // proxy: { 19 | // "/api": { 20 | // target: "https://www.baidu.com", 21 | // changeOrigin: true, 22 | // rewrite: path => path.replace(/^\/api/, "") 23 | // } 24 | // } 25 | }, 26 | /* 打包配置 */ 27 | base: "./", 28 | build: { 29 | brotliSize: false, 30 | emptyOutDir: false, 31 | outDir: "dist", 32 | assetsDir: "static" 33 | } 34 | }); 35 | --------------------------------------------------------------------------------