Przeglądaj źródła

脚本初始化

罗浩军 2 dni temu
commit
567b350b84

+ 19 - 0
.gitignore

@@ -0,0 +1,19 @@
+.DS_Store
+node_modules/
+dist/
+doc/
+test/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+
+# 测试用页面及js
+src/router/modules/test.js
+src/views/test/**/*.vue

+ 5 - 0
build/utils.js

@@ -0,0 +1,5 @@
+const path = require("path");
+module.exports = {
+    pathResolve: (url) => path.resolve(__dirname, "../" + (url || "")),
+    assetsPath: (url) => path.posix.join("static", url),
+}

+ 191 - 0
build/webpack.config.js

@@ -0,0 +1,191 @@
+const utils = require("./utils");
+const path = require("path");
+const { VueLoaderPlugin } = require('vue-loader');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+const HtmlWebpackPlugin = require("html-webpack-plugin");
+
+function resolve(dir) {
+    return path.join(__dirname, "..", dir);
+}
+
+module.exports = (env) => {
+    console.log("process.env.NODE_ENV", env.NODE_ENV);
+    return {
+        mode: 'production',
+        entry: {
+            app: './src/index.js'
+        },
+        context: utils.pathResolve(),
+        output: {
+            filename: 'static/js/[name].js',
+            path: utils.pathResolve("dist"),
+        },
+
+        resolve: {
+            extensions: [".js", ".vue", ".json", ".scss"],
+            alias: {
+                "@": utils.pathResolve("src"),
+            }
+        },
+        externals: {
+            vue: "Vue",
+            lodash: "_",
+            echarts: "echarts",
+            "xlsx-js-style": "XLSX",
+            "maplibre-gl": "maplibregl",
+        },
+        
+        module: {
+            rules: [
+                {
+                    test: /\.vue$/,
+                    loader: "vue-loader",
+                    options: {
+                        esModule: false,
+                    }
+                },
+                {
+                    test: /\.js$/,
+                    loader: 'babel-loader'
+                },
+                {
+                    test: "/\.css$/",
+                    use: [
+                        env.NODE_ENV !== 'production'
+                            ? 'vue-style-loader'
+                            : MiniCssExtractPlugin.loader,
+                        'css-loader'
+                    ]
+                },
+                {
+                    test: /\.s[ac]ss$/i,
+                    use: [
+                        env.NODE_ENV !== 'production'
+                            ? 'vue-style-loader'
+                            : MiniCssExtractPlugin.loader,
+                        // 将 CSS 转化成 CommonJS 模块
+                        {
+                            loader: 'css-loader',
+                            options: { importLoaders: 1 }
+                        },
+                        // 将 Sass 编译成 CSS
+                        {
+                            loader: 'sass-loader',
+                            options: {
+                                sassOptions: {
+                                    quietDeps: true,
+                                    outputStyle: 'compressed'
+                                }
+                            }
+                        }
+                    ],
+                },
+                {
+                    test: /\.md$/,
+                    use: ["text-loader"],
+                },
+                {
+                    test: /\.svg$/,
+                    loader: "svg-sprite-loader",
+                    include: [resolve("src/icons")],
+                    options: {
+                        symbolId: "icon-[name]",
+                    },
+                },
+                {
+                    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
+                    loader: "url-loader",
+                    exclude: [resolve("src/icons")],
+                    options: {
+                        limit: 1,
+                        name: utils.assetsPath("img/[name].[hash:7].[ext]"),
+                    },
+                },
+                {
+                    test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
+                    loader: "url-loader",
+                    options: {
+                        limit: 10000,
+                        name: utils.assetsPath("media/[name].[hash:7].[ext]"),
+                    },
+                },
+                {
+                    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
+                    loader: "url-loader",
+                    options: {
+                        limit: 10000,
+                        name: utils.assetsPath("fonts/[name].[hash:7].[ext]"),
+                    },
+                },
+                {
+                test: require.resolve("lodash"),
+                    loader: "expose-loader",
+                    options: {
+                        exposes: {
+                            globalName: "_",
+                            moduleLocalName: "lodash",
+                        },
+                    },
+
+                },
+                {
+                    test: require.resolve("moment"),
+                    loader: "expose-loader",
+                    options: {
+                        exposes: {
+                            globalName: "moment",
+                            moduleLocalName: "moment",
+                        },
+                    },
+
+                }
+            ]
+        },
+        // 优化
+        optimization: {
+            splitChunks: {
+                // 提高到50KB
+                minSize: 50000,
+                // 最大尺寸约240KB
+                minSizeReduction: 50000,
+                // 设置最大尺寸约240KB
+                maxSize: 244000,
+
+                cacheGroups: {
+                    vendors: {
+                        test: /[\\/]node_modules[\\/](vue|element-ui|moment)[\\/]/,
+                        name: 'vendors',
+                        chunks: 'all',
+                    },
+                    // 添加common组提取公共模块
+                    common: {       
+                        minChunks: 2,
+                        priority: -20,
+                        reuseExistingChunk: true,
+                        name: 'common'
+                    }
+                }
+            },
+            // 添加其他优化配置
+            removeEmptyChunks: true,
+            mergeDuplicateChunks: true
+        },
+
+        plugins: [
+            // 请确保引入这个插件!
+            new VueLoaderPlugin(),
+            
+            new HtmlWebpackPlugin({
+                inject: true,
+                template: "index.html",
+                title: "分区计量漏损控制系统",
+                minify: {
+                    removeComments: true,
+                    collapseWhitespace: true,
+                    removeAttributeQuotes: true,
+                },
+                chunks: ["manifest", "vendor", "app"],
+            }),
+        ]
+    }
+};

+ 27 - 0
build/webpack.dev.js

@@ -0,0 +1,27 @@
+const { merge } = require("webpack-merge");
+const path = require("path");
+const baseConfig = require("./webpack.config.js");
+
+module.exports = merge(baseConfig({
+    NODE_ENV: "development"
+}), {
+    devServer: {
+        client: {
+            logging: "error",
+            overlay: true,
+            progress: true,
+            reconnect: 10
+        },
+        compress: false,
+        host: "0.0.0.0",
+        hot: true,
+        liveReload: true,
+        open: true,
+        port: 8000,
+        static: {
+            directory: path.join(__dirname, '../'),
+        },
+        watchFiles: ['src/**/*', 'public/**/*']
+    },
+    mode: 'development'
+})

+ 17 - 0
build/webpack.prod.js

@@ -0,0 +1,17 @@
+const baseConfig = require("./webpack.config.js");
+const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
+const { CleanWebpackPlugin } = require('clean-webpack-plugin');
+const { merge } = require("webpack-merge");
+
+module.exports = merge(baseConfig({
+    NODE_ENV: "production"
+}), {
+    plugins: [
+        new CleanWebpackPlugin(),
+        // 提取CSS样式文件
+        new MiniCssExtractPlugin({
+            filename: 'static/css/[name].[contenthash:8].css',
+        })
+    ],
+    mode: 'production'
+})

+ 257 - 0
index.html

@@ -0,0 +1,257 @@
+<!DOCTYPE html>
+<html lang="en">
+
+<head>
+
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <!-- <meta name="renderer" content="webkit"> -->
+    <title><%= htmlWebpackPlugin.options.title %></title>
+    <link rel="stylesheet" href="./static/css/v-charts.min.css">
+    <link rel="stylesheet" href="./static/css/video-js.min.css">
+    <link rel="stylesheet" href="./static/css/maplibre-gl.css">
+    <style>
+        .chromeframe {
+            margin: 0.2em 0;
+            background: #ccc;
+            color: #000;
+            padding: 0.2em 0;
+        }
+        
+        #loader-wrapper {
+            position: fixed;
+            top: 0;
+            left: 0;
+            width: 100%;
+            height: 100%;
+            z-index: 999999;
+        }
+        
+        #loader {
+            display: block;
+            position: relative;
+            left: 50%;
+            top: 50%;
+            width: 150px;
+            height: 150px;
+            margin: -75px 0 0 -75px;
+            border-radius: 50%;
+            border: 3px solid transparent;
+            /* COLOR 1 */
+            border-top-color: #FFF;
+            -webkit-animation: spin 2s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            -ms-animation: spin 2s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            -moz-animation: spin 2s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            -o-animation: spin 2s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            animation: spin 2s linear infinite;
+            /* Chrome, Firefox 16+, IE 10+, Opera */
+            z-index: 1001;
+        }
+        
+        #loader:before {
+            content: "";
+            position: absolute;
+            top: 5px;
+            left: 5px;
+            right: 5px;
+            bottom: 5px;
+            border-radius: 50%;
+            border: 3px solid transparent;
+            /* COLOR 2 */
+            border-top-color: #FFF;
+            -webkit-animation: spin 3s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            -moz-animation: spin 3s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            -o-animation: spin 3s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            -ms-animation: spin 3s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            animation: spin 3s linear infinite;
+            /* Chrome, Firefox 16+, IE 10+, Opera */
+        }
+        
+        #loader:after {
+            content: "";
+            position: absolute;
+            top: 15px;
+            left: 15px;
+            right: 15px;
+            bottom: 15px;
+            border-radius: 50%;
+            border: 3px solid transparent;
+            border-top-color: #FFF;
+            /* COLOR 3 */
+            -moz-animation: spin 1.5s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            -o-animation: spin 1.5s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            -ms-animation: spin 1.5s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            -webkit-animation: spin 1.5s linear infinite;
+            /* Chrome, Opera 15+, Safari 5+ */
+            animation: spin 1.5s linear infinite;
+            /* Chrome, Firefox 16+, IE 10+, Opera */
+        }
+        
+        @-webkit-keyframes spin {
+            0% {
+                -webkit-transform: rotate(0deg);
+                /* Chrome, Opera 15+, Safari 3.1+ */
+                -ms-transform: rotate(0deg);
+                /* IE 9 */
+                transform: rotate(0deg);
+                /* Firefox 16+, IE 10+, Opera */
+            }
+            100% {
+                -webkit-transform: rotate(360deg);
+                /* Chrome, Opera 15+, Safari 3.1+ */
+                -ms-transform: rotate(360deg);
+                /* IE 9 */
+                transform: rotate(360deg);
+                /* Firefox 16+, IE 10+, Opera */
+            }
+        }
+        
+        @keyframes spin {
+            0% {
+                -webkit-transform: rotate(0deg);
+                /* Chrome, Opera 15+, Safari 3.1+ */
+                -ms-transform: rotate(0deg);
+                /* IE 9 */
+                transform: rotate(0deg);
+                /* Firefox 16+, IE 10+, Opera */
+            }
+            100% {
+                -webkit-transform: rotate(360deg);
+                /* Chrome, Opera 15+, Safari 3.1+ */
+                -ms-transform: rotate(360deg);
+                /* IE 9 */
+                transform: rotate(360deg);
+                /* Firefox 16+, IE 10+, Opera */
+            }
+        }
+        
+        #loader-wrapper .loader-section {
+            position: fixed;
+            top: 0;
+            width: 51%;
+            height: 100%;
+            background: #2e598f;
+            /* Old browsers */
+            z-index: 1000;
+            -webkit-transform: translateX(0);
+            /* Chrome, Opera 15+, Safari 3.1+ */
+            -ms-transform: translateX(0);
+            /* IE 9 */
+            transform: translateX(0);
+            /* Firefox 16+, IE 10+, Opera */
+        }
+        
+        #loader-wrapper .loader-section.section-left {
+            left: 0;
+        }
+        
+        #loader-wrapper .loader-section.section-right {
+            right: 0;
+        }
+        /* Loaded */
+        
+        .loaded #loader-wrapper .loader-section.section-left {
+            -webkit-transform: translateX(-100%);
+            /* Chrome, Opera 15+, Safari 3.1+ */
+            -ms-transform: translateX(-100%);
+            /* IE 9 */
+            transform: translateX(-100%);
+            /* Firefox 16+, IE 10+, Opera */
+            -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
+            transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
+        }
+        
+        .loaded #loader-wrapper .loader-section.section-right {
+            -webkit-transform: translateX(100%);
+            /* Chrome, Opera 15+, Safari 3.1+ */
+            -ms-transform: translateX(100%);
+            /* IE 9 */
+            transform: translateX(100%);
+            /* Firefox 16+, IE 10+, Opera */
+            -webkit-transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
+            transition: all 0.7s 0.3s cubic-bezier(0.645, 0.045, 0.355, 1.000);
+        }
+        
+        .loaded #loader {
+            opacity: 0;
+            -webkit-transition: all 0.3s ease-out;
+            transition: all 0.3s ease-out;
+        }
+        
+        .loaded #loader-wrapper {
+            visibility: hidden;
+            -webkit-transform: translateY(-100%);
+            /* Chrome, Opera 15+, Safari 3.1+ */
+            -ms-transform: translateY(-100%);
+            /* IE 9 */
+            transform: translateY(-100%);
+            /* Firefox 16+, IE 10+, Opera */
+            -webkit-transition: all 0.3s 1s ease-out;
+            transition: all 0.3s 1s ease-out;
+        }
+        /* JavaScript Turned Off */
+        
+        .no-js #loader-wrapper {
+            display: none;
+        }
+        
+        .no-js h1 {
+            color: #222222;
+        }
+        
+        #loader-wrapper .load_title {
+            font-family: 'Microsoft YaHei','PingFang SC',hanyi_black_simple, "Helvetica Neue", Arial, sans-serif;
+            color: #FFF;
+            font-size: 19px;
+            width: 100%;
+            text-align: center;
+            z-index: 9999999999999;
+            position: absolute;
+            top: 60%;
+            opacity: 1;
+            line-height: 30px;
+        }
+        
+        #loader-wrapper .load_title span {
+            font-weight: normal;
+            font-style: italic;
+            font-size: 13px;
+            color: #FFF;
+            opacity: 0.5;
+        }
+    </style>
+    <!-- scada调度操作库 -->
+    <script type="text/javascript" src="./static/js/meta2d.js"></script>
+</head>
+
+<body>
+       
+    <div id="app">
+        <div id="loader-wrapper">
+            <div id="loader"></div>
+            <div class="loader-section section-left"></div>
+            <div class="loader-section section-right"></div>
+            <div class="load_title">正在加载 <%= htmlWebpackPlugin.options.title %>,请耐心等待</div>
+        </div>
+    </div>
+    <script src="./static/js/maplibre-gl.js"></script>
+    <script src="./static/js/vue.min.js"></script>
+    <script src="./static/js/lodash.min.js"></script>
+    <script src="./static/js/xlsx.min.js"></script>
+    <script src="./static/js/echarts.min.js"></script>
+    <script src="./static/js/v-charts.min.js"></script>
+</body>
+
+</html>

Plik diff jest za duży
+ 11088 - 0
package-lock.json


+ 50 - 0
package.json

@@ -0,0 +1,50 @@
+{
+  "name": "webpack5",
+  "version": "1.0.0",
+  "description": "这是一个本地通过webpack5打包框架",
+  "main": "index.js",
+  "scripts": {
+    "start": "webpack-dev-server --config build/webpack.dev.js"
+  },
+  "author": "",
+  "license": "ISC",
+  "devDependencies": {
+    "@babel/core": "^7.27.4",
+    "@babel/preset-env": "^7.27.2",
+    "babel-loader": "^10.0.0",
+    "clean-webpack-plugin": "^4.0.0",
+    "css-loader": "^7.1.2",
+    "expose-loader": "^5.0.1",
+    "file-loader": "^6.2.0",
+    "html-webpack-plugin": "^5.6.3",
+    "mini-css-extract-plugin": "^2.9.2",
+    "sass": "^1.89.2",
+    "sass-loader": "^16.0.5",
+    "svg-sprite-loader": "^6.0.11",
+    "url-loader": "^4.1.1",
+    "vue-loader": "^15.11.1",
+    "vue-style-loader": "^4.1.3",
+    "vue-template-compiler": "^2.7.16",
+    "webpack": "^5.99.9",
+    "webpack-bundle-analyzer": "^4.10.2",
+    "webpack-cli": "^6.0.1",
+    "webpack-dev-server": "^5.2.2",
+    "webpack-merge": "^6.0.1"
+  },
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 8"
+  ],
+  "dependencies": {
+    "axios": "^0.17.1",
+    "echarts": "^5.6.0",
+    "element-ui": "^2.15.14",
+    "js-cookie": "^3.0.5",
+    "lodash": "^4.17.21",
+    "moment": "^2.30.1",
+    "vue": "^2.7.16",
+    "vue-router": "^3.6.5",
+    "vuex": "^3.6.2"
+  }
+}

BIN
src/assets/images/401_images/401.gif


BIN
src/assets/images/404_images/404.png


BIN
src/assets/images/404_images/404_cloud.png


+ 3 - 0
src/config/website.js

@@ -0,0 +1,3 @@
+export default {
+    
+}

+ 17 - 0
src/index.js

@@ -0,0 +1,17 @@
+import Vue from "vue";
+import router from "@/router/index.js";
+import ElementUI from "element-ui";
+import '@/styles/index.scss' // global css
+import App from "@/views/app.vue";
+
+Vue.use(ElementUI);
+
+function sum(a, b) {
+    return a + b;
+}
+
+new Vue({
+    el: "#app",
+    router,
+    render: (h) => h(App),
+});

+ 18 - 0
src/permission.js

@@ -0,0 +1,18 @@
+import router from "./router/index.js";
+import NProgress from "nprogress"; 
+import 'nprogress/nprogress.css';
+
+router.beforeEach((to, from, next) => {
+    NProgress.start();
+
+    if (to.path === '/login') {
+        next()
+    } else {
+        next('/login');
+    }
+});
+
+
+router.afterEach((to, from) => {
+    NProgress.done();
+})

+ 18 - 0
src/router/index.js

@@ -0,0 +1,18 @@
+import VueRouter from "vue-router";
+import Vue from "vue";
+
+Vue.use(VueRouter);
+
+
+
+export default new VueRouter({
+    scrollBehavior: () => ({ y: 0 }),
+    routes: [
+        { path: "/", redirect: "/login", hidden: true },
+        { path: '*', redirect: '/404', hidden: true },
+        {
+            path: "/404", 
+            component: () => import("@/views/error/404.vue")
+        }
+    ]
+});

+ 14 - 0
src/store/getters.js

@@ -0,0 +1,14 @@
+export default {
+    // 系统语言
+    language: state => state.app.language,
+    // 侧边栏状态
+    sidebar: state => state.app.sidebar,
+    // 获取登录token
+    token: state => state.user.token,
+    // 是否显示返回首页按钮
+    ShowBackHome: state => state.app.showBackHome,
+    // 用户头像
+    avatar: state => state.user.avatar,
+    // 
+    userId: state => state.user.userInfo ? state.user.userInfo.uid : "",
+}

+ 17 - 0
src/store/index.js

@@ -0,0 +1,17 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+import getters from './getters'
+
+import app from './modules/app'
+import user from './modules/user'
+
+Vue.use(Vuex);
+
+
+export default new Vuex.Store({
+    modules: {
+        app,
+        user,
+    },
+    getters
+});

+ 15 - 0
src/store/modules/app.js

@@ -0,0 +1,15 @@
+import Cookie from "@/utils/cookie.js";
+
+export default {
+    state: {
+        
+    },
+
+    mutations: {
+        
+    },
+
+    action: {
+        
+    }
+}

+ 13 - 0
src/store/modules/common.js

@@ -0,0 +1,13 @@
+export default {
+    state: {
+        
+    },
+
+    mutations: {
+        
+    },
+
+    actions: {
+        
+    }
+}

+ 42 - 0
src/store/modules/user.js

@@ -0,0 +1,42 @@
+import { updateToken } from "@/utils/auth.js";
+import Cookies from "js-cookie";
+import router from "@/router/index.js";
+
+
+export default {
+    state: {
+        userInfo: null,
+        token: null
+    },
+
+    mutations: {
+        setUserInfo(state, userInfo) {
+            state.userInfo = userInfo;
+            Cookies.set("_uid", userInfo.uid);
+        },
+        setToken(state, token) {
+            state.token = token;
+            // 更新token信息
+            updateToken(token);
+        }
+    },
+
+    actions: {
+        login({ commit}, params) {
+            
+        },
+
+        logout({ commit }, autoClose) {
+            commit("setUserInfo", null);
+            commit("setToken", null);
+            
+            if (autoClose) {
+                // 关闭当前窗口
+                window.close();
+            } else {
+                 // 跳转回登录页面
+                router.push({ path: "/login" });
+            }
+        }
+    }
+}

+ 2 - 0
src/styles/element-ui.scss

@@ -0,0 +1,2 @@
+$--font-path: '~element-ui/lib/theme-chalk/fonts';
+@import "~element-ui/packages/theme-chalk/src/index";

+ 7 - 0
src/styles/index.scss

@@ -0,0 +1,7 @@
+@import "var.scss";
+@import "element-ui.scss";
+
+html{
+    font-size: 14px;
+    line-height: 1em;
+}

+ 1 - 0
src/styles/var.scss

@@ -0,0 +1 @@
+$-font-size: 14px !default;

+ 13 - 0
src/utils/auth.js

@@ -0,0 +1,13 @@
+import store from '@/store/index.js';
+import Cookies from 'js-cookie';
+
+const TokenKey = 'connect.sid1'; 
+
+export function getToken() {
+    return store.getters.token || Cookies.get(TokenKey);
+}
+
+export function updateToken(token) {
+    return token ? Cookies.set(TokenKey, token, { path: '' }) : Cookies.remove(TokenKey);
+}
+

+ 12 - 0
src/utils/request.js

@@ -0,0 +1,12 @@
+import axios from 'axios';
+// 请求超时时间
+const timeout = 30 * 1000; 
+// 创建基础服务请求代理
+const baseServer = axios.create({
+  timeout: timeout,
+  baseURL: baseURL,
+  headers:{
+    "Content-Type": "application/json;charset=UTF-8",
+  },
+  withCredentials: true,
+});

+ 15 - 0
src/views/app.vue

@@ -0,0 +1,15 @@
+<template>
+  <el-container>
+    <el-header>
+      <el-menu>
+        <el-menu-item>首页</el-menu-item>
+      </el-menu>
+    </el-header>
+  </el-container>
+</template>
+
+<script>
+export default {
+
+}
+</script>

+ 228 - 0
src/views/error/404.vue

@@ -0,0 +1,228 @@
+<template>
+  <div style="background:#f0f2f5;margin-top: -20px;height:100%;">
+    <div class="wscn-http404">
+      <div class="pic-404">
+        <img class="pic-404__parent" :src="img_404" alt="404">
+        <img class="pic-404__child left" :src="img_404_cloud" alt="404">
+        <img class="pic-404__child mid" :src="img_404_cloud" alt="404">
+        <img class="pic-404__child right" :src="img_404_cloud" alt="404">
+      </div>
+      <div class="bullshit">
+        <div class="bullshit__oops">OOPS!</div>
+        <div class="bullshit__headline">{{ message }}</div>
+        <div class="bullshit__info">请检查您输入的网址是否正确,请点击以下按钮返回主页或者发送错误报告</div>
+        <a href="" class="bullshit__return-home">返回首页</a>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import img_404 from '@/assets/images/404_images/404.png'
+import img_404_cloud from '@/assets/images/404_images/404_cloud.png'
+
+export default {
+  name: 'page404',
+  data() {
+    return {
+      img_404,
+      img_404_cloud
+    }
+  },
+  computed: {
+    message() {
+      return '这个页面你不能进......'
+    }
+  }
+}
+</script>
+
+<style rel="stylesheet/scss" lang="scss" scoped>
+.wscn-http404 {
+  position: relative;
+  width: 1200px;
+  margin: 20px auto 60px;
+  padding: 0 100px;
+  overflow: hidden;
+  .pic-404 {
+    position: relative;
+    float: left;
+    width: 600px;
+    padding: 150px 0;
+    overflow: hidden;
+    &__parent {
+      width: 100%;
+    }
+    &__child {
+      position: absolute;
+      &.left {
+        width: 80px;
+        top: 17px;
+        left: 220px;
+        opacity: 0;
+        animation-name: cloudLeft;
+        animation-duration: 2s;
+        animation-timing-function: linear;
+        animation-fill-mode: forwards;
+        animation-delay: 1s;
+      }
+      &.mid {
+        width: 46px;
+        top: 10px;
+        left: 420px;
+        opacity: 0;
+        animation-name: cloudMid;
+        animation-duration: 2s;
+        animation-timing-function: linear;
+        animation-fill-mode: forwards;
+        animation-delay: 1.2s;
+      }
+      &.right {
+        width: 62px;
+        top: 100px;
+        left: 500px;
+        opacity: 0;
+        animation-name: cloudRight;
+        animation-duration: 2s;
+        animation-timing-function: linear;
+        animation-fill-mode: forwards;
+        animation-delay: 1s;
+      }
+      @keyframes cloudLeft {
+        0% {
+          top: 17px;
+          left: 220px;
+          opacity: 0;
+        }
+        20% {
+          top: 33px;
+          left: 188px;
+          opacity: 1;
+        }
+        80% {
+          top: 81px;
+          left: 92px;
+          opacity: 1;
+        }
+        100% {
+          top: 97px;
+          left: 60px;
+          opacity: 0;
+        }
+      }
+      @keyframes cloudMid {
+        0% {
+          top: 10px;
+          left: 420px;
+          opacity: 0;
+        }
+        20% {
+          top: 40px;
+          left: 360px;
+          opacity: 1;
+        }
+        70% {
+          top: 130px;
+          left: 180px;
+          opacity: 1;
+        }
+        100% {
+          top: 160px;
+          left: 120px;
+          opacity: 0;
+        }
+      }
+      @keyframes cloudRight {
+        0% {
+          top: 100px;
+          left: 500px;
+          opacity: 0;
+        }
+        20% {
+          top: 120px;
+          left: 460px;
+          opacity: 1;
+        }
+        80% {
+          top: 180px;
+          left: 340px;
+          opacity: 1;
+        }
+        100% {
+          top: 200px;
+          left: 300px;
+          opacity: 0;
+        }
+      }
+    }
+  }
+  .bullshit {
+    position: relative;
+    float: left;
+    width: 300px;
+    padding: 150px 0;
+    overflow: hidden;
+    &__oops {
+      font-size: 32px;
+      font-weight: bold;
+      line-height: 40px;
+      color: #1482f0;
+      opacity: 0;
+      margin-bottom: 20px;
+      animation-name: slideUp;
+      animation-duration: 0.5s;
+      animation-fill-mode: forwards;
+    }
+    &__headline {
+      font-size: 20px;
+      line-height: 24px;
+      color: #1482f0;
+      opacity: 0;
+      margin-bottom: 10px;
+      animation-name: slideUp;
+      animation-duration: 0.5s;
+      animation-delay: 0.1s;
+      animation-fill-mode: forwards;
+    }
+    &__info {
+      font-size: 13px;
+      line-height: 21px;
+      color: grey;
+      opacity: 0;
+      margin-bottom: 30px;
+      animation-name: slideUp;
+      animation-duration: 0.5s;
+      animation-delay: 0.2s;
+      animation-fill-mode: forwards;
+    }
+    &__return-home {
+      display: block;
+      float: left;
+      width: 110px;
+      height: 36px;
+      background: #1482f0;
+      border-radius: 100px;
+      text-align: center;
+      color: #ffffff;
+      opacity: 0;
+      font-size: 14px;
+      line-height: 36px;
+      cursor: pointer;
+      animation-name: slideUp;
+      animation-duration: 0.5s;
+      animation-delay: 0.3s;
+      animation-fill-mode: forwards;
+    }
+    @keyframes slideUp {
+      0% {
+        transform: translateY(60px);
+        opacity: 0;
+      }
+      100% {
+        transform: translateY(0);
+        opacity: 1;
+      }
+    }
+  }
+}
+</style>

Plik diff jest za duży
+ 1 - 0
static/css/maplibre-gl.css


Plik diff jest za duży
+ 2 - 0
static/css/v-charts.min.css


Plik diff jest za duży
+ 1 - 0
static/css/video-js.min.css


Plik diff jest za duży
+ 45 - 0
static/js/echarts.min.js


Plik diff jest za duży
+ 137 - 0
static/js/lodash.min.js


Plik diff jest za duży
+ 59 - 0
static/js/maplibre-gl.js


Plik diff jest za duży
+ 1 - 0
static/js/meta2d.js


Plik diff jest za duży
+ 88 - 0
static/js/turf.min.js


Plik diff jest za duży
+ 1 - 0
static/js/v-charts.min.js


Plik diff jest za duży
+ 6 - 0
static/js/vue.min.js


Plik diff jest za duży
+ 3 - 0
static/js/xlsx.min.js