frontend backend
This commit is contained in:
parent
de8e29f4f9
commit
c27167a3ba
|
@ -0,0 +1,29 @@
|
|||
# Created by .ignore support plugin (hsz.mobi)
|
||||
.DS_Store
|
||||
node_modules
|
||||
node/
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.iml
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
|
||||
src/main/resources/static
|
||||
src/main/resources/templates
|
||||
target
|
|
@ -0,0 +1,258 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.2.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>backend</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<shiro.version>1.4.0</shiro.version>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.theborakompanioni</groupId>
|
||||
<artifactId>thymeleaf-extras-shiro</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
<version>5.0.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<groupId>commons-collections</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-web</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.45</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<addResources>true</addResources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<attach>true</attach>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Overlay guacamole-common-js (zip) -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>main-class-placement</id>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<target>
|
||||
<move todir="src/main/resources/static">
|
||||
<fileset dir="../frontend/dist">
|
||||
<exclude name="*.html"/>
|
||||
</fileset>
|
||||
</move>
|
||||
<move todir="src/main/resources/templates">
|
||||
<fileset dir="../frontend/dist">
|
||||
<include name="*.html"/>
|
||||
</fileset>
|
||||
</move>
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.mybatis.generator</groupId>
|
||||
<artifactId>mybatis-generator-maven-plugin</artifactId>
|
||||
<version>1.3.7</version>
|
||||
<configuration>
|
||||
<verbose>true</verbose>
|
||||
<overwrite>true</overwrite>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.41</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
|
||||
</project>
|
|
@ -0,0 +1,14 @@
|
|||
# https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
insert_final_newline = false
|
||||
trim_trailing_whitespace = false
|
|
@ -0,0 +1,29 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
node/
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.iml
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
.setting
|
||||
.project
|
||||
.classpath
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"name": "vue-demo",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.26",
|
||||
"@fortawesome/free-regular-svg-icons": "^5.12.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.12.0",
|
||||
"@fortawesome/vue-fontawesome": "^0.1.9",
|
||||
"axios": "^0.19.0",
|
||||
"core-js": "^3.4.3",
|
||||
"element-ui": "^2.13.0",
|
||||
"vue": "^2.6.10",
|
||||
"vue-i18n": "^8.15.3",
|
||||
"vue-router": "^3.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^4.1.0",
|
||||
"@vue/cli-plugin-eslint": "^4.1.0",
|
||||
"@vue/cli-service": "^4.1.0",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"vue-template-compiler": "^2.6.10"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/essential",
|
||||
"eslint:recommended"
|
||||
],
|
||||
"rules": {},
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>vue-demo</artifactId>
|
||||
<groupId>com.fit2cloud</groupId>
|
||||
<version>1.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>frontend</artifactId>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<frontend-maven-plugin.version>1.9.1</frontend-maven-plugin.version>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.github.eirslett</groupId>
|
||||
<artifactId>frontend-maven-plugin</artifactId>
|
||||
<version>${frontend-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<!-- optional: you don't really need execution ids, but it looks nice in your build log. -->
|
||||
<id>install node and yarn</id>
|
||||
<goals>
|
||||
<goal>install-node-and-yarn</goal>
|
||||
</goals>
|
||||
<!-- optional: default phase is "generate-resources" -->
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<nodeVersion>v12.14.1</nodeVersion>
|
||||
<yarnVersion>v1.21.1</yarnVersion>
|
||||
</configuration>
|
||||
</execution>
|
||||
<!-- Install all project dependencies -->
|
||||
<execution>
|
||||
<id>yarn install</id>
|
||||
<goals>
|
||||
<goal>yarn</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<!-- optional: The default argument is actually
|
||||
"install", so unless you need to run some other yarn command,
|
||||
you can remove this whole <configuration> section.
|
||||
-->
|
||||
<arguments>install</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
<!-- Build and minify static files -->
|
||||
<execution>
|
||||
<id>yarn build</id>
|
||||
<goals>
|
||||
<goal>yarn</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<arguments>build</arguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
Binary file not shown.
After Width: | Height: | Size: 104 KiB |
Binary file not shown.
After Width: | Height: | Size: 245 KiB |
Binary file not shown.
After Width: | Height: | Size: 274 KiB |
Binary file not shown.
After Width: | Height: | Size: 94 KiB |
Binary file not shown.
After Width: | Height: | Size: 104 KiB |
Binary file not shown.
After Width: | Height: | Size: 355 KiB |
|
@ -0,0 +1,82 @@
|
|||
import {Message, MessageBox} from 'element-ui';
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
install(Vue) {
|
||||
if (!axios) {
|
||||
window.console.error('You have to install axios');
|
||||
return
|
||||
}
|
||||
|
||||
if (!Message) {
|
||||
window.console.error('You have to install Message of ElementUI');
|
||||
return
|
||||
}
|
||||
|
||||
let login = function () {
|
||||
MessageBox.alert("认证信息已过期,请重新登录。", {
|
||||
callback: () => {
|
||||
window.location.href = "/login"
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
axios.defaults.withCredentials = true;
|
||||
|
||||
axios.interceptors.response.use(response => {
|
||||
if (response.headers["authentication-status"] === "invalid") {
|
||||
login();
|
||||
}
|
||||
return response;
|
||||
}, error => {
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
Vue.prototype.$get = function (url, success) {
|
||||
if (!success) {
|
||||
return axios.get(url);
|
||||
} else {
|
||||
axios.get(url).then(response => {
|
||||
if (!response.data) {
|
||||
return success(response);
|
||||
}
|
||||
if (response.data.success) {
|
||||
return success(response.data);
|
||||
} else {
|
||||
window.console.warn(response.data);
|
||||
Message.warning(response.data.message);
|
||||
}
|
||||
}).catch(error => {
|
||||
window.console.error(error.response || error.message);
|
||||
Message.error({message: error.message, showClose: true});
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
Vue.prototype.$post = function (url, data, success) {
|
||||
if (!success) {
|
||||
return axios.post(url, data);
|
||||
} else {
|
||||
axios.post(url, data).then(response => {
|
||||
if (!response.data) {
|
||||
return success(response);
|
||||
}
|
||||
if (response.data.success) {
|
||||
return success(response.data);
|
||||
} else {
|
||||
window.console.warn(response.data);
|
||||
Message.warning(response.data.message);
|
||||
}
|
||||
}).catch(error => {
|
||||
window.console.error(error.response || error.message);
|
||||
Message.error({message: error.message, showClose: true});
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
Vue.prototype.$all = function (array, callback) {
|
||||
if (array.length < 1) return;
|
||||
axios.all(array).then(axios.spread(callback));
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
const options = function (value, array) {
|
||||
if (!value) return '';
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
if (value === array[i].key) {
|
||||
return array[i].value
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
const filters = {
|
||||
"options": options,
|
||||
};
|
||||
|
||||
export default {
|
||||
install(Vue) {
|
||||
// 注册公用过滤器
|
||||
Object.keys(filters).forEach(key => {
|
||||
Vue.filter(key, filters[key])
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import {library} from '@fortawesome/fontawesome-svg-core'
|
||||
import {fas} from '@fortawesome/free-solid-svg-icons'
|
||||
import {far} from '@fortawesome/free-regular-svg-icons'
|
||||
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome'
|
||||
|
||||
export default {
|
||||
install(Vue) {
|
||||
library.add(fas, far);
|
||||
Vue.component('font-awesome-icon', FontAwesomeIcon);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
const en_US = {
|
||||
i18n: {
|
||||
'home': 'Home',
|
||||
}
|
||||
};
|
||||
|
||||
export default en_US
|
|
@ -0,0 +1,26 @@
|
|||
import Vue from 'vue';
|
||||
import VueI18n from "vue-i18n";
|
||||
import enLocale from "element-ui/lib/locale/lang/en";
|
||||
import zh_CNLocale from "element-ui/lib/locale/lang/zh-CN";
|
||||
import en_US from "./en_US";
|
||||
import zh_CN from "./zh_CN";
|
||||
|
||||
Vue.use(VueI18n);
|
||||
|
||||
const messages = {
|
||||
'en_US': {
|
||||
...en_US,
|
||||
...enLocale
|
||||
},
|
||||
'zh_CN': {
|
||||
...zh_CN,
|
||||
...zh_CNLocale
|
||||
}
|
||||
};
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: 'en_US',
|
||||
messages,
|
||||
});
|
||||
|
||||
export default i18n;
|
|
@ -0,0 +1,7 @@
|
|||
const zh_CN = {
|
||||
i18n: {
|
||||
'home': '首页',
|
||||
}
|
||||
};
|
||||
|
||||
export default zh_CN
|
|
@ -0,0 +1,200 @@
|
|||
<template>
|
||||
<div class="container" v-if="ready">
|
||||
<el-row type="flex">
|
||||
<el-col :span="12">
|
||||
<el-form :model="form" :rules="rules" ref="form">
|
||||
<div class="logo">
|
||||
<img src="../assets/MeterSphere-彩色.png" style="width: 224px" alt="">
|
||||
</div>
|
||||
<div class="title">
|
||||
<span id="s1">登录</span>
|
||||
<span id="s2">MeterSphere</span>
|
||||
</div>
|
||||
<div class="border"></div>
|
||||
<div class="welcome">
|
||||
欢迎回来,请输入用户名和密码登录MeterSphere
|
||||
</div>
|
||||
<div class="form">
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="form.username" placeholder="邮箱" autocomplete="off" maxlength="100"
|
||||
show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input v-model="form.password" placeholder="密码" show-password autocomplete="off"
|
||||
maxlength="20" show-word-limit/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" class="submit" @click="submit('form')">登录
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="msg">
|
||||
{{msg}}
|
||||
</div>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="12" class="image">
|
||||
<div></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Login",
|
||||
data() {
|
||||
let validateEmail = (rule, value, callback) => {
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
let EMAIL_REGEX = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||
if (!EMAIL_REGEX.test(value)) {
|
||||
callback(new Error('邮箱格式不正确'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
return {
|
||||
form: {
|
||||
username: '',
|
||||
password: ''
|
||||
},
|
||||
rules: {
|
||||
username: [
|
||||
{required: true, message: '请输入邮箱', trigger: 'blur'},
|
||||
{validator: validateEmail, trigger: 'blur'}
|
||||
],
|
||||
password: [
|
||||
{required: true, message: '请输入密码', trigger: 'blur'},
|
||||
{min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur'}
|
||||
]
|
||||
},
|
||||
msg: '',
|
||||
ready: false
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$get("/isLogin").then(response => {
|
||||
if (!response.data.success) {
|
||||
this.ready = true;
|
||||
} else {
|
||||
window.location.href = "/"
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
submit(form) {
|
||||
this.$refs[form].validate((valid) => {
|
||||
if (valid) {
|
||||
this.$post("signin", this.form, function () {
|
||||
window.location.href = "/"
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
min-width: 800px;
|
||||
max-width: 1440px;
|
||||
height: 560px;
|
||||
margin: calc((100vh - 560px) / 2) auto 0;
|
||||
background-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin: 30px 30px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin-top: 50px;
|
||||
font-size: 32px;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title > #s1 {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.title > #s2 {
|
||||
color: #151515;
|
||||
}
|
||||
|
||||
.border {
|
||||
height: 2px;
|
||||
margin: 20px auto 20px;
|
||||
position: relative;
|
||||
width: 80px;
|
||||
background: #8B479B;
|
||||
}
|
||||
|
||||
.welcome {
|
||||
margin-top: 50px;
|
||||
font-size: 14px;
|
||||
color: #999999;
|
||||
letter-spacing: 0;
|
||||
line-height: 18px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
margin-top: 60px;
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 40px;
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
.btn > .submit {
|
||||
width: 100%;
|
||||
border-radius: 0;
|
||||
border-color: #8B479B;
|
||||
background-color: #8B479B;
|
||||
}
|
||||
|
||||
.btn > .submit:hover {
|
||||
border-color: rgba(139, 71, 155, 0.9);
|
||||
background-color: rgba(139, 71, 155, 0.9);
|
||||
}
|
||||
|
||||
.btn > .submit:active {
|
||||
border-color: rgba(139, 71, 155, 0.8);
|
||||
background-color: rgba(139, 71, 155, 0.8);
|
||||
}
|
||||
|
||||
.msg {
|
||||
margin-top: 10px;
|
||||
padding: 0 40px;
|
||||
color: red;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.image {
|
||||
background: url(../assets/info.png);
|
||||
height: 560px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Neue Haas Grotesk Text Pro", "Arial Nova", "Segoe UI", "Helvetica Neue", ".PingFang SC", "PingFang SC", "Source Han Sans SC", "Noto Sans CJK SC", "Source Han Sans CN", "Noto Sans SC", "Source Han Sans TC", "Noto Sans CJK TC", "Hiragino Sans GB", sans-serif;
|
||||
font-size: 14px;
|
||||
background-color: #F5F5F5;
|
||||
line-height: 26px;
|
||||
color: #2B415C;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.form .el-input > .el-input__inner {
|
||||
border-radius: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.png">
|
||||
<title>MeterSphere</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="login"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
import Vue from 'vue';
|
||||
import {Button, Col, Form, FormItem, Input, Row} from 'element-ui';
|
||||
import 'element-ui/lib/theme-chalk/index.css';
|
||||
import Login from "./Login.vue";
|
||||
import Ajax from "../common/ajax";
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
Vue.use(Row);
|
||||
Vue.use(Col);
|
||||
Vue.use(Form);
|
||||
Vue.use(FormItem);
|
||||
Vue.use(Input);
|
||||
Vue.use(Button);
|
||||
Vue.use(Ajax);
|
||||
|
||||
new Vue({
|
||||
el: '#login',
|
||||
render: h => h(Login)
|
||||
});
|
|
@ -0,0 +1,105 @@
|
|||
<template>
|
||||
<el-col v-if="auth">
|
||||
<el-row id="header-top" type="flex" justify="space-between" align="middle">
|
||||
<a class="logo"/>
|
||||
<ms-user/>
|
||||
</el-row>
|
||||
<el-row id="header-bottom" type="flex" justify="space-between" align="middle">
|
||||
<el-col :span="10">
|
||||
<ms-menus/>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-row type="flex" justify="center" align="middle">
|
||||
<el-button type="primary" size="small">创建测试</el-button>
|
||||
</el-row>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<ms-setting/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<ms-view/>
|
||||
<ms-web-socket/>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsMenus from "./components/HeaderMenus";
|
||||
import MsSetting from "./components/HeaderSetting";
|
||||
import MsView from "./components/router/View";
|
||||
import MsUser from "./components/HeaderUser";
|
||||
import MsWebSocket from "./components/websocket/WebSocket";
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
data() {
|
||||
return {
|
||||
auth: false,
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
this.$get("/isLogin").then(response => {
|
||||
if (response.data.success) {
|
||||
this.auth = true;
|
||||
} else {
|
||||
window.location.href = "/login"
|
||||
}
|
||||
}).catch(() => {
|
||||
window.location.href = "/login"
|
||||
});
|
||||
},
|
||||
components: {MsWebSocket, MsUser, MsMenus, MsSetting, MsView}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
body {
|
||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
#header-top {
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
padding: 0 10px;
|
||||
background-color: rgb(44, 42, 72);
|
||||
color: rgb(245, 245, 245);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 156px;
|
||||
margin-right: 20px;
|
||||
display: inline-block;
|
||||
background-size: 156px 30px;
|
||||
height: 40px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% center;
|
||||
background-image: url("../assets/MeterSphere-反白.png");
|
||||
}
|
||||
|
||||
#header-bottom {
|
||||
height: 40px;
|
||||
padding: 0 15px;
|
||||
border-bottom: 1px solid #E6E6E6;
|
||||
cursor: default;
|
||||
color: #404040;
|
||||
}
|
||||
|
||||
.menus > * {
|
||||
color: inherit;
|
||||
padding: 0;
|
||||
max-width: 180px;
|
||||
white-space: pre;
|
||||
cursor: pointer;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.menus > a {
|
||||
padding-right: 15px;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
<template>
|
||||
<el-menu class="header-menu" :unique-opened="true" mode="horizontal"
|
||||
menu-trigger="click">
|
||||
<el-menu-item index="1"><a href="/" style="text-decoration: none;">{{ $t("i18n.home") }}</a></el-menu-item>
|
||||
<el-submenu index="2" popper-class="submenu">
|
||||
<template slot="title">工作空间</template>
|
||||
<el-menu-item index="2-1">工作空间1</el-menu-item>
|
||||
<el-menu-item index="2-2">工作空间2</el-menu-item>
|
||||
<el-menu-item index="2-3">显示全部</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="3" popper-class="submenu">
|
||||
<template slot="title">项目</template>
|
||||
<el-menu-item index="3-1">项目1</el-menu-item>
|
||||
<el-menu-item index="3-2">项目2</el-menu-item>
|
||||
<el-menu-item index="3-3">显示全部</el-menu-item>
|
||||
<el-menu-item index="create-project">
|
||||
<el-button type="text">创建项目</el-button>
|
||||
</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="4" popper-class="submenu">
|
||||
<template slot="title">测试</template>
|
||||
<el-menu-item index="4-1">测试1</el-menu-item>
|
||||
<el-menu-item index="4-2">测试2</el-menu-item>
|
||||
<el-menu-item index="4-3">显示全部</el-menu-item>
|
||||
<el-menu-item index="create-test" route="{path:'test'}">
|
||||
<el-button type="text">创建测试</el-button>
|
||||
</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="5" popper-class="submenu">
|
||||
<template slot="title">报告</template>
|
||||
<el-menu-item index="5-1">报告1</el-menu-item>
|
||||
<el-menu-item index="5-2">报告2</el-menu-item>
|
||||
<el-menu-item index="5-3">显示全部</el-menu-item>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsMenus"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.header-menu.el-menu--horizontal > li.el-menu-item {
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.header-menu.el-menu--horizontal > li {
|
||||
height: 39px;
|
||||
line-height: 40px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.header-menu.el-menu--horizontal > li.el-submenu > * {
|
||||
height: 39px;
|
||||
line-height: 40px;
|
||||
color: inherit;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,33 @@
|
|||
<template>
|
||||
<el-row class="settings" type="flex" justify="end" align="middle">
|
||||
<router-link to="/content">
|
||||
<font-awesome-icon :icon="['fas', 'user-plus']" size="lg"/>
|
||||
</router-link>
|
||||
<router-link to="/content">
|
||||
<font-awesome-icon :icon="['fas', 'cog']" size="lg"/>
|
||||
</router-link>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsSetting"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.settings > * {
|
||||
padding-left: 15px;
|
||||
cursor: pointer;
|
||||
line-height: 40px;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.settings > * :hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.settings > * :active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<el-dropdown size="medium" @command="handleCommand">
|
||||
<span class="dropdown-link">
|
||||
莫 鹍<i class="el-icon-caret-bottom el-icon--right"/>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="personal">个人信息</el-dropdown-item>
|
||||
<el-dropdown-item command="logout">退出系统</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsUser",
|
||||
methods: {
|
||||
handleCommand(command) {
|
||||
switch (command) {
|
||||
case "personal":
|
||||
this.$i18n.locale = "zh_CN";
|
||||
break;
|
||||
case "logout":
|
||||
this.$get("/signout", function () {
|
||||
window.location.href = "/login";
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dropdown-link {
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
color: rgb(245, 245, 245);
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,15 @@
|
|||
<template>
|
||||
<div>
|
||||
adfdsaf
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "RouterSidebar"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,33 @@
|
|||
<template>
|
||||
<div id="body">
|
||||
<router-view name="sidebar" class="sidebar"/>
|
||||
<router-view name="content" class="content"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsView"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#body {
|
||||
width: 100%;
|
||||
height: calc(100vh - 80px);
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: relative;
|
||||
width: 330px;
|
||||
height: 100%;
|
||||
max-width: 750px;
|
||||
min-width: 250px;
|
||||
}
|
||||
|
||||
.content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,28 @@
|
|||
import Vue from "vue";
|
||||
import VueRouter from 'vue-router'
|
||||
import RouterSidebar from "./RouterSidebar";
|
||||
import Setting from "../settings/Setting";
|
||||
import Workspace from "../settings/Workspace";
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
const router = new VueRouter({
|
||||
routes: [
|
||||
{
|
||||
path: "/sidebar", components: {
|
||||
sidebar: RouterSidebar
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "/content", components: {
|
||||
content: Setting
|
||||
}, children: [
|
||||
{
|
||||
path: 'workspace',
|
||||
component: Workspace
|
||||
}
|
||||
]
|
||||
}]
|
||||
});
|
||||
|
||||
export default router
|
|
@ -0,0 +1,36 @@
|
|||
<template>
|
||||
<div class="create-box">
|
||||
<el-tooltip class="item" effect="dark" :content="tips" placement="left">
|
||||
<el-button @click="exec()" type="primary" size="mini" circle>
|
||||
<font-awesome-icon :icon="['fas', 'plus']"/>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsCreateBox",
|
||||
props: {
|
||||
tips: String,
|
||||
exec: Function
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.create-box {
|
||||
width: 100%;
|
||||
background: #FCFCFC;
|
||||
border-bottom-left-radius: 3px;
|
||||
border-bottom-right-radius: 3px;
|
||||
box-shadow: 0 5px 20px 0 rgba(0, 0, 0, .1);
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.create-box .el-button--mini.is-circle {
|
||||
width: 28.5px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,65 @@
|
|||
<template>
|
||||
<el-row type="flex" align="middle" class="current-user">
|
||||
<el-avatar shape="square" size="small" :src="squareUrl"/>
|
||||
<span class="username">kun@fit2cloud.com</span>
|
||||
<el-button class="edit" type="primary" icon="el-icon-edit" size="mini"
|
||||
circle @click="editVisible = true"/>
|
||||
<el-dialog :title="title" :visible.sync="editVisible" width="30%">
|
||||
<el-form :model="form" label-position="top" size="small">
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码">
|
||||
<el-input v-model="form.mobile" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="editVisible = false" size="medium">更新</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsCurrentUser",
|
||||
data() {
|
||||
return {
|
||||
editVisible: false,
|
||||
id: "123456",
|
||||
squareUrl: "https://cube.elemecdn.com/9/c2/f0ee8a3c7c9638a54940382568c9dpng.png",
|
||||
form: {
|
||||
name: "kun@fit2cloud.com",
|
||||
mobile: ""
|
||||
}
|
||||
}
|
||||
}, computed: {
|
||||
title: function () {
|
||||
return "编辑账号(id: " + this.id + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.current-user .username {
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin: 0 5px;
|
||||
overflow-x: hidden;
|
||||
padding-bottom: 0;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
width: 180px;
|
||||
}
|
||||
|
||||
.current-user .edit {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.current-user:hover .edit {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,64 @@
|
|||
<template>
|
||||
<el-row type="flex">
|
||||
<div class="menus">
|
||||
<ms-current-user/>
|
||||
<el-divider/>
|
||||
<h1>设置</h1>
|
||||
<ms-setting-menu/>
|
||||
</div>
|
||||
<div class="container">
|
||||
<router-view class="main-content"/>
|
||||
</div>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsCurrentUser from "./CurrentUser";
|
||||
import MsSettingMenu from "./SettingMenu";
|
||||
|
||||
export default {
|
||||
name: "MsSetting",
|
||||
components: {MsSettingMenu, MsCurrentUser},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.menus {
|
||||
width: 280px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #E6E6E6;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
background-color: #FFF;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 15px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.main-content {
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.main-content span.title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
margin-top: 0;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
word-wrap: break-word;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,61 @@
|
|||
<template>
|
||||
<el-menu menu-trigger="click" :default-active="$route.path" router>
|
||||
<el-submenu index="1">
|
||||
<template slot="title">
|
||||
<font-awesome-icon class="icon account" :icon="['far', 'address-card']" size="lg"/>
|
||||
<span>账号</span>
|
||||
</template>
|
||||
<el-menu-item>用户</el-menu-item>
|
||||
<el-menu-item index="/content/workspace">工作空间</el-menu-item>
|
||||
<el-menu-item>API Keys</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index=2>
|
||||
<template slot="title">
|
||||
<font-awesome-icon class="icon workspace" :icon="['far', 'clone']" size="lg"/>
|
||||
<span>工作空间</span>
|
||||
</template>
|
||||
<el-menu-item>成员</el-menu-item>
|
||||
<el-menu-item>证书</el-menu-item>
|
||||
<el-menu-item>测试计划</el-menu-item>
|
||||
<el-menu-item>警告</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-submenu index="3">
|
||||
<template slot="title">
|
||||
<font-awesome-icon class="icon" :icon="['far', 'user']" size="lg"/>
|
||||
<span>个人</span>
|
||||
</template>
|
||||
<el-menu-item>个人设置</el-menu-item>
|
||||
<el-menu-item>API Keys</el-menu-item>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsSettingMenu"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-menu {
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.el-menu-item {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 24px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.account {
|
||||
color: #5a78f0;
|
||||
}
|
||||
|
||||
.workspace {
|
||||
color: #44b349;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<div v-loading="loading">
|
||||
<el-card>
|
||||
<div slot="header">
|
||||
<el-row type="flex" justify="space-between" align="middle">
|
||||
<span class="title">工作空间</span>
|
||||
<span class="search">
|
||||
<el-input type="text" size="small" placeholder="根据ID,名称搜索" prefix-icon="el-icon-search"
|
||||
maxlength="60" v-model="condition" clearable/>
|
||||
</span>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-table :data="items" style="width: 100%">
|
||||
<el-table-column prop="id" label="ID" width="180"/>
|
||||
<el-table-column prop="name" label="名称"/>
|
||||
<el-table-column prop="owner" label="创建者"/>
|
||||
<el-table-column prop="enable" label="启用"/>
|
||||
<el-table-column width="50">
|
||||
<template slot-scope="scope">
|
||||
<el-button @click="edit(scope.row)" type="primary" icon="el-icon-edit" size="mini" circle
|
||||
class="edit"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
<ms-create-box :tips="btnTips" :exec="create"/>
|
||||
<el-dialog title="创建工作空间" :visible.sync="createVisible" width="30%">
|
||||
<el-form :model="form" label-position="left" label-width="100px" size="small">
|
||||
<el-form-item label="名称">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="启用">
|
||||
<el-switch v-model="form.enable"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="createVisible = false" size="medium">创建</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsCreateBox from "./CreateBox";
|
||||
|
||||
export default {
|
||||
name: "MsWorkspace",
|
||||
components: {MsCreateBox},
|
||||
methods: {
|
||||
create() {
|
||||
this.createVisible = true;
|
||||
this.$get("/test/user", function (response) {
|
||||
window.console.log(response);
|
||||
});
|
||||
},
|
||||
edit(row) {
|
||||
window.console.log(row);
|
||||
this.loading = true;
|
||||
let self = this;
|
||||
let getUser1 = this.$get("/test/user");
|
||||
let getUser2 = this.$get("/test/sleep");
|
||||
this.$all([getUser1, getUser2], function (r1, r2) {
|
||||
window.console.log(r1.data.data, r2.data.data);
|
||||
self.loading = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
createVisible: false,
|
||||
btnTips: "添加工作空间",
|
||||
condition: "",
|
||||
items: [{
|
||||
id: '123456',
|
||||
name: 'Default workspace',
|
||||
owner: 'mk',
|
||||
enable: "是"
|
||||
}],
|
||||
form: {
|
||||
name: "",
|
||||
enable: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.search {
|
||||
width: 240px;
|
||||
}
|
||||
|
||||
.edit {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.el-table__row:hover .edit {
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div class="test">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MsWebSocket",
|
||||
data() {
|
||||
return {
|
||||
websocket: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initWebSocket();
|
||||
},
|
||||
destroyed() {
|
||||
// this.websocket.close() //离开路由之后断开websocket连接
|
||||
},
|
||||
methods: {
|
||||
initWebSocket() {
|
||||
window.console.log("init WebSocket");
|
||||
const uri = "ws://" + window.location.host + "/socket";
|
||||
this.websocket = new WebSocket(uri);
|
||||
this.websocket.onmessage = this.onMessage;
|
||||
this.websocket.onopen = this.onOpen;
|
||||
this.websocket.onerror = this.onError;
|
||||
this.websocket.onclose = this.onClose;
|
||||
},
|
||||
onOpen() {
|
||||
let actions = {"test": "12345"};
|
||||
this.send(JSON.stringify(actions));
|
||||
},
|
||||
onError(e) {
|
||||
window.console.error(e)
|
||||
},
|
||||
onMessage(e) {
|
||||
window.console.log(e.data)
|
||||
},
|
||||
onClose(e) {
|
||||
window.console.log('断开连接', e);
|
||||
},
|
||||
send(Data) {
|
||||
this.websocket.send(Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="zh">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.png">
|
||||
<title>MeterSphere</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
import Vue from 'vue';
|
||||
import ElementUI from 'element-ui';
|
||||
import 'element-ui/lib/theme-chalk/index.css';
|
||||
import icon from "../common/icon";
|
||||
import filters from "../common/filter";
|
||||
import ajax from "../common/ajax";
|
||||
import App from './App.vue';
|
||||
import router from "./components/router/router";
|
||||
import i18n from "../i18n/i18n";
|
||||
|
||||
Vue.config.productionTip = false;
|
||||
Vue.use(icon);
|
||||
Vue.use(ElementUI, {
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
});
|
||||
Vue.use(filters);
|
||||
Vue.use(ajax);
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
i18n,
|
||||
render: h => h(App)
|
||||
});
|
|
@ -0,0 +1,26 @@
|
|||
module.exports = {
|
||||
productionSourceMap: true,
|
||||
configureWebpack: {
|
||||
devtool: 'source-map'
|
||||
},
|
||||
devServer: {
|
||||
proxy: {
|
||||
['^(?!/login)']: {
|
||||
target: 'http://localhost:8888',
|
||||
ws: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
pages: {
|
||||
performance: {
|
||||
entry: "src/performance/main.js",
|
||||
template: "src/performance/index.html",
|
||||
filename: "index.html"
|
||||
},
|
||||
login: {
|
||||
entry: "src/login/login.js",
|
||||
template: "src/login/login.html",
|
||||
filename: "login.html"
|
||||
}
|
||||
}
|
||||
};
|
257
pom.xml
257
pom.xml
|
@ -1,196 +1,83 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.2.2.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.fit2cloud</groupId>
|
||||
<artifactId>metersphere-server</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>root</name>
|
||||
<modules>
|
||||
<module>frontend</module>
|
||||
<module>backend</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<shiro.version>1.4.0</shiro.version>
|
||||
<java.version>1.8</java.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<jmeter.version>5.2.1</jmeter.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- jmeter -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<groupId>org.apache.jmeter</groupId>
|
||||
<artifactId>ApacheJMeter_http</artifactId>
|
||||
<version>${jmeter.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.theborakompanioni</groupId>
|
||||
<artifactId>thymeleaf-extras-shiro</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mybatis.spring.boot</groupId>
|
||||
<artifactId>mybatis-spring-boot-starter</artifactId>
|
||||
<version>1.3.2</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
<version>5.0.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-core</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<groupId>commons-collections</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>commons-beanutils</artifactId>
|
||||
<groupId>commons-beanutils</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-web</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.shiro</groupId>
|
||||
<artifactId>shiro-spring</artifactId>
|
||||
<version>${shiro.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.10</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpasyncclient</artifactId>
|
||||
<version>4.1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.45</version>
|
||||
<groupId>org.influxdb</groupId>
|
||||
<artifactId>influxdb-java</artifactId>
|
||||
<version>2.16</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.29</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/java</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
<include>**/*.xml</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<addResources>true</addResources>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<skipTests>true</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<attach>true</attach>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
|
@ -199,60 +86,6 @@
|
|||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Overlay guacamole-common-js (zip) -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>main-class-placement</id>
|
||||
<phase>generate-resources</phase>
|
||||
<configuration>
|
||||
<target>
|
||||
<move todir="src/main/resources/static">
|
||||
<fileset dir="../frontend/dist">
|
||||
<exclude name="*.html"/>
|
||||
</fileset>
|
||||
</move>
|
||||
<move todir="src/main/resources/templates">
|
||||
<fileset dir="../frontend/dist">
|
||||
<include name="*.html"/>
|
||||
</fileset>
|
||||
</move>
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.mybatis.generator</groupId>
|
||||
<artifactId>mybatis-generator-maven-plugin</artifactId>
|
||||
<version>1.3.7</version>
|
||||
<configuration>
|
||||
<verbose>true</verbose>
|
||||
<overwrite>true</overwrite>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.41</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
|
||||
</project>
|
Loading…
Reference in New Issue