Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
fec574d869
|
@ -35,7 +35,8 @@ public class LoginController {
|
|||
try {
|
||||
subject.login(token);
|
||||
if (subject.isAuthenticated()) {
|
||||
return ResultHolder.success("");
|
||||
// 返回 userDTO
|
||||
return ResultHolder.success(subject.getSession().getAttribute("user"));
|
||||
} else {
|
||||
return ResultHolder.error("login fail");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
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 org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
|
@ -21,6 +22,11 @@ public class TestPlanController {
|
|||
@Resource
|
||||
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")
|
||||
public void uploadJmx(MultipartFile file) throws IOException {
|
||||
fileService.upload(file.getOriginalFilename(), file);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package io.metersphere.requests.testplan;
|
||||
package io.metersphere.controller.request.testplan;
|
||||
|
||||
public class FileOperationRequest {
|
||||
private String name;
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,8 @@
|
|||
package io.metersphere.security;
|
||||
|
||||
|
||||
import io.metersphere.dto.UserDTO;
|
||||
import io.metersphere.service.UserService;
|
||||
import io.metersphere.user.SessionUser;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authc.*;
|
||||
|
@ -10,6 +12,8 @@ import org.apache.shiro.subject.PrincipalCollection;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
|
||||
/**
|
||||
* 自定义Realm 注入service 可能会导致在 service的aop 失效,例如@Transactional,
|
||||
|
@ -23,6 +27,8 @@ import org.slf4j.LoggerFactory;
|
|||
public class ShiroDBRealm extends AuthorizingRealm {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(ShiroDBRealm.class);
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
/**
|
||||
* 权限认证
|
||||
|
@ -40,10 +46,16 @@ public class ShiroDBRealm extends AuthorizingRealm {
|
|||
UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
|
||||
String userId = token.getUsername();
|
||||
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.setId(userId);
|
||||
SessionUser sessionUser = SessionUser.fromUser(user);
|
||||
SecurityUtils.getSubject().getSession().setAttribute("user", sessionUser);
|
||||
return new SimpleAuthenticationInfo(userId, password, getName());
|
||||
}
|
||||
|
|
|
@ -1,26 +1,18 @@
|
|||
package io.metersphere.user;
|
||||
|
||||
import io.metersphere.dto.UserDTO;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SessionUser implements Serializable {
|
||||
public class SessionUser extends UserDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7149638440406959033L;
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
public static SessionUser fromUser(UserDTO user) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,10 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
const TokenKey = 'Admin-Token';
|
||||
|
||||
export default {
|
||||
name: "Login",
|
||||
data() {
|
||||
|
@ -102,7 +106,9 @@
|
|||
submit(form) {
|
||||
this.$refs[form].validate((valid) => {
|
||||
if (valid) {
|
||||
this.$post("signin", this.form, function () {
|
||||
this.$post("signin", this.form, (response) => {
|
||||
// 登录信息保存 cookie
|
||||
Cookies.set(TokenKey, response.data);
|
||||
window.location.href = "/"
|
||||
});
|
||||
} else {
|
||||
|
|
|
@ -13,15 +13,10 @@
|
|||
<el-table :data="items" style="width: 100%">
|
||||
<el-table-column prop="name" label="名称"/>
|
||||
<el-table-column prop="description" label="描述"/>
|
||||
<el-table-column width="100">
|
||||
<el-table-column>
|
||||
<template slot-scope="scope">
|
||||
<el-button @click="edit(scope.row)" type="primary" icon="el-icon-edit" size="mini" circle
|
||||
class="edit"/>
|
||||
<el-popconfirm title="这个工作空间确定要删除吗?" @onConfirm="del(scope.row)">
|
||||
<el-button slot="reference" type="primary" icon="el-icon-delete" size="mini"
|
||||
circle
|
||||
class="edit"/>
|
||||
</el-popconfirm>
|
||||
<el-button @click="edit(scope.row)" type="primary" icon="el-icon-edit" size="mini" circle/>
|
||||
<el-button @click="del(scope.row)" type="danger" icon="el-icon-delete" size="mini" circle/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -88,9 +83,17 @@
|
|||
// });
|
||||
},
|
||||
del(row) {
|
||||
this.$get('/workspace/delete/' + row.id, () => {
|
||||
Message.success('删除成功');
|
||||
this.list();
|
||||
this.$confirm('这个工作空间确定要删除吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$get('/workspace/delete/' + row.id, () => {
|
||||
Message.success('删除成功');
|
||||
this.list();
|
||||
});
|
||||
}).catch(() => {
|
||||
|
||||
});
|
||||
window.console.log(row);
|
||||
},
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<div class="testplan-container">
|
||||
<el-row>
|
||||
<el-col :span="10">
|
||||
<el-input placeholder="请输入名称" v-model="testplanName" class="input-with-select">
|
||||
<el-select v-model="project" slot="prepend" placeholder="请选择项目">
|
||||
<el-input placeholder="请输入名称" v-model="testPlan.name" class="input-with-select">
|
||||
<el-select v-model="testPlan.project" slot="prepend" placeholder="请选择项目">
|
||||
<el-option
|
||||
v-for="item in projects"
|
||||
:key="item.id"
|
||||
|
@ -19,32 +19,35 @@
|
|||
</el-row>
|
||||
|
||||
<el-tabs v-model="active" type="border-card" :stretch="true">
|
||||
<el-tab-pane
|
||||
v-for="item in tabs"
|
||||
:key="item.id"
|
||||
:label="item.title"
|
||||
>
|
||||
<component :is="active === item.id ? item.component : false"/>
|
||||
<el-tab-pane label="基础配置">
|
||||
<test-plan-basic-config v-on:change-test-plan="changeTestPlan"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="压力配置">
|
||||
<test-plan-pressure-config v-on:change-test-plan="changeTestPlan"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="高级配置">
|
||||
<test-plan-advanced-config v-on:change-test-plan="changeTestPlan"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BasicConfig from './components/BasicConfig';
|
||||
import PressureConfig from './components/PressureConfig';
|
||||
import AdvancedConfig from './components/AdvancedConfig';
|
||||
import TestPlanBasicConfig from './components/BasicConfig';
|
||||
import TestPlanPressureConfig from './components/PressureConfig';
|
||||
import TestPlanAdvancedConfig from './components/AdvancedConfig';
|
||||
|
||||
export default {
|
||||
name: "CreateTestPlan",
|
||||
components: {
|
||||
BasicConfig,
|
||||
PressureConfig,
|
||||
AdvancedConfig
|
||||
TestPlanBasicConfig,
|
||||
TestPlanPressureConfig,
|
||||
TestPlanAdvancedConfig,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
project: '',
|
||||
savePath: "/testplan/save",
|
||||
testPlan: {},
|
||||
projects: [{
|
||||
id: '选项1',
|
||||
name: '黄金糕'
|
||||
|
@ -61,7 +64,6 @@
|
|||
id: '选项5',
|
||||
name: '北京烤鸭'
|
||||
}],
|
||||
testplanName: '',
|
||||
active: '0',
|
||||
tabs: [{
|
||||
title: '场景配置',
|
||||
|
@ -80,16 +82,23 @@
|
|||
},
|
||||
methods: {
|
||||
save() {
|
||||
window.console.log("save")
|
||||
if (!this.validTestPlan()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/// todo: save
|
||||
this.$message({
|
||||
message: '保存成功!',
|
||||
type: 'success'
|
||||
this.$post(this.savePath, this.testPlan).then(response => {
|
||||
if (response) {
|
||||
this.$message({
|
||||
message: '保存成功!',
|
||||
type: 'success'
|
||||
});
|
||||
}
|
||||
}).catch((response) => {
|
||||
this.$message.error(response.message);
|
||||
});
|
||||
},
|
||||
saveAndRun() {
|
||||
window.console.log("saveAndRun")
|
||||
window.console.log("saveAndRun");
|
||||
|
||||
/// todo: saveAndRun
|
||||
this.$message({
|
||||
|
@ -97,6 +106,41 @@
|
|||
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() {
|
||||
this.$router.push({path: '/'})
|
||||
}
|
||||
|
|
|
@ -3,14 +3,28 @@
|
|||
</style>
|
||||
|
||||
<template>
|
||||
<div>我是第三个子组件</div>
|
||||
<div>
|
||||
我是第三个子组件
|
||||
<el-button @click="testChange()" type="text" size="small">修改TestPlan值</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "TestPlanAdvancedConfig",
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
testChange() {
|
||||
this._changeTestPlan(function (testPlan) {
|
||||
testPlan.advancedConfig = "2"
|
||||
})
|
||||
},
|
||||
_changeTestPlan(updateTestPlanFunc) {
|
||||
this.$emit('change-test-plan', updateTestPlanFunc);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
|
||||
<script>
|
||||
export default {
|
||||
name: "TestPlanBasicConfig",
|
||||
data() {
|
||||
return {
|
||||
jmxUploadPath: '/testplan/file/upload',
|
||||
|
@ -65,6 +66,11 @@
|
|||
beforeUpload(file) {
|
||||
window.console.log(file);
|
||||
|
||||
/// todo: 上传的文件需要绑定到当前testPlan,这里暂时使用文件名
|
||||
this._changeTestPlan(function (testPlan) {
|
||||
testPlan.fileId = file.name;
|
||||
});
|
||||
|
||||
if (!this.fileValidator(file)) {
|
||||
/// todo: 显示错误信息
|
||||
return false;
|
||||
|
@ -103,8 +109,8 @@
|
|||
}
|
||||
}
|
||||
}).catch((response) => {
|
||||
this.$message.error(response.message);
|
||||
});
|
||||
this.$message.error(response.message);
|
||||
});
|
||||
},
|
||||
handleDelete(file, index) {
|
||||
this.$alert('确认删除文件: ' + file.name + "?", '', {
|
||||
|
@ -133,6 +139,9 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
_changeTestPlan(updateTestPlanFunc) {
|
||||
this.$emit('change-test-plan', updateTestPlanFunc);
|
||||
},
|
||||
fileValidator(file) {
|
||||
/// todo: 是否需要对文件内容和大小做限制
|
||||
return file.size > 0;
|
||||
|
|
|
@ -3,14 +3,28 @@
|
|||
</style>
|
||||
|
||||
<template>
|
||||
<div>我是第二个子组件</div>
|
||||
<div>
|
||||
我是第二个子组件
|
||||
<el-button @click="testChange()" type="text" size="small">修改TestPlan值</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "TestPlanPressureConfig",
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
testChange() {
|
||||
this._changeTestPlan(function (testPlan) {
|
||||
testPlan.pressureConifg = "1"
|
||||
})
|
||||
},
|
||||
_changeTestPlan(updateTestPlanFunc) {
|
||||
this.$emit('change-test-plan', updateTestPlanFunc);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
Loading…
Reference in New Issue