Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
W23123 2020-02-13 12:22:21 +08:00
commit fec574d869
12 changed files with 192 additions and 60 deletions

View File

@ -35,7 +35,8 @@ public class LoginController {
try { try {
subject.login(token); subject.login(token);
if (subject.isAuthenticated()) { if (subject.isAuthenticated()) {
return ResultHolder.success(""); // 返回 userDTO
return ResultHolder.success(subject.getSession().getAttribute("user"));
} else { } else {
return ResultHolder.error("login fail"); return ResultHolder.error("login fail");
} }

View File

@ -1,6 +1,7 @@
package io.metersphere.controller; package io.metersphere.controller;
import io.metersphere.requests.testplan.FileOperationRequest; import io.metersphere.controller.request.testplan.FileOperationRequest;
import io.metersphere.controller.request.testplan.SaveTestPlanRequest;
import io.metersphere.service.FileService; import io.metersphere.service.FileService;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -21,6 +22,11 @@ public class TestPlanController {
@Resource @Resource
private FileService fileService; private FileService fileService;
@PostMapping("/save")
public void save(@RequestBody SaveTestPlanRequest request) {
System.out.println(String.format("save test plan: %s", request.getName()));
}
@PostMapping("/file/upload") @PostMapping("/file/upload")
public void uploadJmx(MultipartFile file) throws IOException { public void uploadJmx(MultipartFile file) throws IOException {
fileService.upload(file.getOriginalFilename(), file); fileService.upload(file.getOriginalFilename(), file);

View File

@ -1,4 +1,4 @@
package io.metersphere.requests.testplan; package io.metersphere.controller.request.testplan;
public class FileOperationRequest { public class FileOperationRequest {
private String name; private String name;

View File

@ -0,0 +1,31 @@
package io.metersphere.controller.request.testplan;
public class SaveTestPlanRequest {
private String fileId;
private String project;
private String name;
public String getFileId() {
return fileId;
}
public void setFileId(String fileId) {
this.fileId = fileId;
}
public String getProject() {
return project;
}
public void setProject(String project) {
this.project = project;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -1,6 +1,8 @@
package io.metersphere.security; package io.metersphere.security;
import io.metersphere.dto.UserDTO;
import io.metersphere.service.UserService;
import io.metersphere.user.SessionUser; import io.metersphere.user.SessionUser;
import org.apache.shiro.SecurityUtils; import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*; import org.apache.shiro.authc.*;
@ -10,6 +12,8 @@ import org.apache.shiro.subject.PrincipalCollection;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
/** /**
* 自定义Realm 注入service 可能会导致在 service的aop 失效例如@Transactional, * 自定义Realm 注入service 可能会导致在 service的aop 失效例如@Transactional,
@ -23,6 +27,8 @@ import org.slf4j.LoggerFactory;
public class ShiroDBRealm extends AuthorizingRealm { public class ShiroDBRealm extends AuthorizingRealm {
private Logger logger = LoggerFactory.getLogger(ShiroDBRealm.class); private Logger logger = LoggerFactory.getLogger(ShiroDBRealm.class);
@Resource
private UserService userService;
/** /**
* 权限认证 * 权限认证
@ -40,10 +46,16 @@ public class ShiroDBRealm extends AuthorizingRealm {
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken; UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
String userId = token.getUsername(); String userId = token.getUsername();
String password = String.valueOf(token.getPassword()); String password = String.valueOf(token.getPassword());
SessionUser sessionUser = new SessionUser(); UserDTO user = userService.getUserDTO(userId);
String msg;
if (user == null) {
msg = "not exist user is trying to login, user:" + userId;
logger.warn(msg);
throw new UnknownAccountException(msg);
}
// TODO 密码验证roles 等内容填充
sessionUser.setName(userId); SessionUser sessionUser = SessionUser.fromUser(user);
sessionUser.setId(userId);
SecurityUtils.getSubject().getSession().setAttribute("user", sessionUser); SecurityUtils.getSubject().getSession().setAttribute("user", sessionUser);
return new SimpleAuthenticationInfo(userId, password, getName()); return new SimpleAuthenticationInfo(userId, password, getName());
} }

View File

@ -1,26 +1,18 @@
package io.metersphere.user; package io.metersphere.user;
import io.metersphere.dto.UserDTO;
import org.springframework.beans.BeanUtils;
import java.io.Serializable; import java.io.Serializable;
public class SessionUser implements Serializable { public class SessionUser extends UserDTO implements Serializable {
private static final long serialVersionUID = -7149638440406959033L; private static final long serialVersionUID = -7149638440406959033L;
private String id;
private String name;
public String getId() { public static SessionUser fromUser(UserDTO user) {
return id; SessionUser sessionUser = new SessionUser();
BeanUtils.copyProperties(user, sessionUser);
return sessionUser;
} }
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
} }

View File

@ -41,6 +41,10 @@
</template> </template>
<script> <script>
import Cookies from 'js-cookie';
const TokenKey = 'Admin-Token';
export default { export default {
name: "Login", name: "Login",
data() { data() {
@ -102,7 +106,9 @@
submit(form) { submit(form) {
this.$refs[form].validate((valid) => { this.$refs[form].validate((valid) => {
if (valid) { if (valid) {
this.$post("signin", this.form, function () { this.$post("signin", this.form, (response) => {
// cookie
Cookies.set(TokenKey, response.data);
window.location.href = "/" window.location.href = "/"
}); });
} else { } else {

View File

@ -13,15 +13,10 @@
<el-table :data="items" style="width: 100%"> <el-table :data="items" style="width: 100%">
<el-table-column prop="name" label="名称"/> <el-table-column prop="name" label="名称"/>
<el-table-column prop="description" label="描述"/> <el-table-column prop="description" label="描述"/>
<el-table-column width="100"> <el-table-column>
<template slot-scope="scope"> <template slot-scope="scope">
<el-button @click="edit(scope.row)" type="primary" icon="el-icon-edit" size="mini" circle <el-button @click="edit(scope.row)" type="primary" icon="el-icon-edit" size="mini" circle/>
class="edit"/> <el-button @click="del(scope.row)" type="danger" icon="el-icon-delete" size="mini" circle/>
<el-popconfirm title="这个工作空间确定要删除吗?" @onConfirm="del(scope.row)">
<el-button slot="reference" type="primary" icon="el-icon-delete" size="mini"
circle
class="edit"/>
</el-popconfirm>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -88,9 +83,17 @@
// }); // });
}, },
del(row) { del(row) {
this.$get('/workspace/delete/' + row.id, () => { this.$confirm('这个工作空间确定要删除吗?', '提示', {
Message.success('删除成功'); confirmButtonText: '确定',
this.list(); cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$get('/workspace/delete/' + row.id, () => {
Message.success('删除成功');
this.list();
});
}).catch(() => {
}); });
window.console.log(row); window.console.log(row);
}, },

View File

@ -2,8 +2,8 @@
<div class="testplan-container"> <div class="testplan-container">
<el-row> <el-row>
<el-col :span="10"> <el-col :span="10">
<el-input placeholder="请输入名称" v-model="testplanName" class="input-with-select"> <el-input placeholder="请输入名称" v-model="testPlan.name" class="input-with-select">
<el-select v-model="project" slot="prepend" placeholder="请选择项目"> <el-select v-model="testPlan.project" slot="prepend" placeholder="请选择项目">
<el-option <el-option
v-for="item in projects" v-for="item in projects"
:key="item.id" :key="item.id"
@ -19,32 +19,35 @@
</el-row> </el-row>
<el-tabs v-model="active" type="border-card" :stretch="true"> <el-tabs v-model="active" type="border-card" :stretch="true">
<el-tab-pane <el-tab-pane label="基础配置">
v-for="item in tabs" <test-plan-basic-config v-on:change-test-plan="changeTestPlan"/>
:key="item.id" </el-tab-pane>
:label="item.title" <el-tab-pane label="压力配置">
> <test-plan-pressure-config v-on:change-test-plan="changeTestPlan"/>
<component :is="active === item.id ? item.component : false"/> </el-tab-pane>
<el-tab-pane label="高级配置">
<test-plan-advanced-config v-on:change-test-plan="changeTestPlan"/>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</template> </template>
<script> <script>
import BasicConfig from './components/BasicConfig'; import TestPlanBasicConfig from './components/BasicConfig';
import PressureConfig from './components/PressureConfig'; import TestPlanPressureConfig from './components/PressureConfig';
import AdvancedConfig from './components/AdvancedConfig'; import TestPlanAdvancedConfig from './components/AdvancedConfig';
export default { export default {
name: "CreateTestPlan", name: "CreateTestPlan",
components: { components: {
BasicConfig, TestPlanBasicConfig,
PressureConfig, TestPlanPressureConfig,
AdvancedConfig TestPlanAdvancedConfig,
}, },
data() { data() {
return { return {
project: '', savePath: "/testplan/save",
testPlan: {},
projects: [{ projects: [{
id: '选项1', id: '选项1',
name: '黄金糕' name: '黄金糕'
@ -61,7 +64,6 @@
id: '选项5', id: '选项5',
name: '北京烤鸭' name: '北京烤鸭'
}], }],
testplanName: '',
active: '0', active: '0',
tabs: [{ tabs: [{
title: '场景配置', title: '场景配置',
@ -80,16 +82,23 @@
}, },
methods: { methods: {
save() { save() {
window.console.log("save") if (!this.validTestPlan()) {
return;
}
/// todo: save this.$post(this.savePath, this.testPlan).then(response => {
this.$message({ if (response) {
message: '保存成功!', this.$message({
type: 'success' message: '保存成功!',
type: 'success'
});
}
}).catch((response) => {
this.$message.error(response.message);
}); });
}, },
saveAndRun() { saveAndRun() {
window.console.log("saveAndRun") window.console.log("saveAndRun");
/// todo: saveAndRun /// todo: saveAndRun
this.$message({ this.$message({
@ -97,6 +106,41 @@
type: 'success' type: 'success'
}); });
}, },
changeTestPlan(updateFunc) {
updateFunc(this.testPlan);
window.console.log(this.testPlan);
},
validTestPlan() {
if (!this.testPlan.name) {
this.$message({
message: '测试名称不能为空!',
type: 'error'
});
return false;
}
if (!this.testPlan.project) {
this.$message({
message: '项目不能为空!',
type: 'error'
});
return false;
}
if (!this.testPlan.fileId) {
this.$message({
message: 'jmx文件不能为空',
type: 'error'
});
return false;
}
/// todo:
return true;
},
cancel() { cancel() {
this.$router.push({path: '/'}) this.$router.push({path: '/'})
} }

View File

@ -3,14 +3,28 @@
</style> </style>
<template> <template>
<div>我是第三个子组件</div> <div>
我是第三个子组件
<el-button @click="testChange()" type="text" size="small">修改TestPlan值</el-button>
</div>
</template> </template>
<script> <script>
export default { export default {
name: "TestPlanAdvancedConfig",
data() { data() {
return { return {
} }
},
methods: {
testChange() {
this._changeTestPlan(function (testPlan) {
testPlan.advancedConfig = "2"
})
},
_changeTestPlan(updateTestPlanFunc) {
this.$emit('change-test-plan', updateTestPlanFunc);
},
} }
} }
</script> </script>

View File

@ -52,6 +52,7 @@
<script> <script>
export default { export default {
name: "TestPlanBasicConfig",
data() { data() {
return { return {
jmxUploadPath: '/testplan/file/upload', jmxUploadPath: '/testplan/file/upload',
@ -65,6 +66,11 @@
beforeUpload(file) { beforeUpload(file) {
window.console.log(file); window.console.log(file);
/// todo: testPlan使
this._changeTestPlan(function (testPlan) {
testPlan.fileId = file.name;
});
if (!this.fileValidator(file)) { if (!this.fileValidator(file)) {
/// todo: /// todo:
return false; return false;
@ -103,8 +109,8 @@
} }
} }
}).catch((response) => { }).catch((response) => {
this.$message.error(response.message); this.$message.error(response.message);
}); });
}, },
handleDelete(file, index) { handleDelete(file, index) {
this.$alert('确认删除文件: ' + file.name + "", '', { this.$alert('确认删除文件: ' + file.name + "", '', {
@ -133,6 +139,9 @@
} }
}); });
}, },
_changeTestPlan(updateTestPlanFunc) {
this.$emit('change-test-plan', updateTestPlanFunc);
},
fileValidator(file) { fileValidator(file) {
/// todo: /// todo:
return file.size > 0; return file.size > 0;

View File

@ -3,14 +3,28 @@
</style> </style>
<template> <template>
<div>我是第二个子组件</div> <div>
我是第二个子组件
<el-button @click="testChange()" type="text" size="small">修改TestPlan值</el-button>
</div>
</template> </template>
<script> <script>
export default { export default {
name: "TestPlanPressureConfig",
data() { data() {
return { return {
} }
},
methods: {
testChange() {
this._changeTestPlan(function (testPlan) {
testPlan.pressureConifg = "1"
})
},
_changeTestPlan(updateTestPlanFunc) {
this.$emit('change-test-plan', updateTestPlanFunc);
},
} }
} }
</script> </script>