Merge branch 'v1.1'
This commit is contained in:
commit
f0e3fd22a0
|
@ -8,5 +8,6 @@ import java.util.List;
|
|||
public class Body {
|
||||
private String type;
|
||||
private String raw;
|
||||
private String format;
|
||||
private List<KeyValue> kvs;
|
||||
}
|
||||
|
|
|
@ -14,4 +14,6 @@ public interface ExtUserMapper {
|
|||
|
||||
String getDefaultLanguage(String paramKey);
|
||||
|
||||
List<User> searchUser(String condition);
|
||||
|
||||
}
|
||||
|
|
|
@ -3,23 +3,23 @@
|
|||
<mapper namespace="io.metersphere.base.mapper.ext.ExtUserMapper">
|
||||
|
||||
<resultMap id="BaseResultMap" type="io.metersphere.base.domain.User">
|
||||
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="email" jdbcType="VARCHAR" property="email" />
|
||||
<result column="password" jdbcType="VARCHAR" property="password" />
|
||||
<result column="status" jdbcType="VARCHAR" property="status" />
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||
<result column="language" jdbcType="VARCHAR" property="language" />
|
||||
<result column="last_workspace_id" jdbcType="VARCHAR" property="lastWorkspaceId" />
|
||||
<result column="last_organization_id" jdbcType="VARCHAR" property="lastOrganizationId" />
|
||||
<result column="phone" jdbcType="VARCHAR" property="phone" />
|
||||
<id column="id" jdbcType="VARCHAR" property="id"/>
|
||||
<result column="name" jdbcType="VARCHAR" property="name"/>
|
||||
<result column="email" jdbcType="VARCHAR" property="email"/>
|
||||
<result column="password" jdbcType="VARCHAR" property="password"/>
|
||||
<result column="status" jdbcType="VARCHAR" property="status"/>
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime"/>
|
||||
<result column="update_time" jdbcType="BIGINT" property="updateTime"/>
|
||||
<result column="language" jdbcType="VARCHAR" property="language"/>
|
||||
<result column="last_workspace_id" jdbcType="VARCHAR" property="lastWorkspaceId"/>
|
||||
<result column="last_organization_id" jdbcType="VARCHAR" property="lastOrganizationId"/>
|
||||
<result column="phone" jdbcType="VARCHAR" property="phone"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getUserList" resultMap="BaseResultMap">
|
||||
select u.id, u.name, u.email, u.phone, u.language, u.status, u.source,
|
||||
u.last_organization_id, u.last_workspace_id, u.language, u.create_time, u.update_time
|
||||
from `user` u
|
||||
u.last_organization_id, u.last_workspace_id, u.language, u.create_time, u.update_time
|
||||
from `user` u
|
||||
<where>
|
||||
<if test="userRequest.id != null">
|
||||
AND u.id like CONCAT('%', #{userRequest.id},'%')
|
||||
|
@ -47,4 +47,8 @@
|
|||
where param_key=#{paramKey,jdbcType=VARCHAR}
|
||||
</select>
|
||||
|
||||
<select id="searchUser" parameterType="java.lang.String" resultType="io.metersphere.base.domain.User">
|
||||
select id, name, email, last_organization_id, last_workspace_id from `user` where id like CONCAT('%', #{condition},'%') or email like CONCAT('%', #{condition},'%') limit 100;
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -284,4 +284,10 @@ public class UserController {
|
|||
return userService.getTestManagerAndTestUserList(request);
|
||||
}
|
||||
|
||||
@GetMapping("/search/{condition}")
|
||||
@RequiresRoles(value = {RoleConstants.ADMIN, RoleConstants.ORG_ADMIN, RoleConstants.TEST_MANAGER}, logical = Logical.OR)
|
||||
public List<User> searchUser(@PathVariable String condition) {
|
||||
return userService.searchUser(condition);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -382,7 +382,7 @@ public class UserService {
|
|||
userRoleExample.createCriteria().andUserIdEqualTo(userId).andSourceIdEqualTo(request.getOrganizationId());
|
||||
List<UserRole> userRoles = userRoleMapper.selectByExample(userRoleExample);
|
||||
if (userRoles.size() > 0) {
|
||||
MSException.throwException(Translator.get("user_already_exists"));
|
||||
MSException.throwException(Translator.get("user_already_exists") + ": " + userId);
|
||||
} else {
|
||||
for (String roleId : request.getRoleIds()) {
|
||||
UserRole userRole = new UserRole();
|
||||
|
@ -566,4 +566,8 @@ public class UserService {
|
|||
MSException.throwException(msg);
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<User> searchUser(String condition) {
|
||||
return extUserMapper.searchUser(condition);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<el-collapse-transition>
|
||||
<el-tabs v-model="activeName" v-show="isActive">
|
||||
<el-tab-pane label="Body" name="body" class="pane">
|
||||
<ms-code-edit :read-only="true" :data="response.body" :modes="modes" ref="codeEdit"/>
|
||||
<ms-code-edit :mode="mode" :read-only="true" :data="response.body" :modes="modes" ref="codeEdit"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="Headers" name="headers" class="pane">
|
||||
<pre>{{response.headers}}</pre>
|
||||
|
@ -31,6 +31,7 @@
|
|||
import MsAssertionResults from "./AssertionResults";
|
||||
import MsCodeEdit from "../../../common/components/MsCodeEdit";
|
||||
import MsDropdown from "../../../common/components/MsDropdown";
|
||||
import {BODY_FORMAT} from "../../test/model/ScenarioModel";
|
||||
|
||||
export default {
|
||||
name: "MsResponseText",
|
||||
|
@ -50,6 +51,7 @@
|
|||
isActive: false,
|
||||
activeName: "body",
|
||||
modes: ['text', 'json', 'xml', 'html'],
|
||||
mode: BODY_FORMAT.TEXT
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -58,7 +60,7 @@
|
|||
this.isActive = !this.isActive;
|
||||
},
|
||||
modeChange(mode) {
|
||||
this.$refs.codeEdit.setMode(mode);
|
||||
this.mode = mode;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -9,20 +9,26 @@
|
|||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
|
||||
<ms-dropdown :default-command="body.format" v-if="body.type == 'Raw'" :commands="modes" @command="modeChange"/>
|
||||
|
||||
<ms-api-key-value :is-read-only="isReadOnly" :items="body.kvs" v-if="body.isKV()"/>
|
||||
|
||||
<el-input :disabled="isReadOnly" class="textarea" type="textarea" v-model="body.raw" :autosize="{ minRows: 10, maxRows: 25}" resize="none"
|
||||
v-else/>
|
||||
<div class="body-raw" v-if="body.type == 'Raw'">
|
||||
<ms-code-edit :mode="body.format" :read-only="isReadOnly" :data.sync="body.raw" :modes="modes" ref="codeEdit"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsApiKeyValue from "./ApiKeyValue";
|
||||
import {Body, BODY_TYPE} from "../model/ScenarioModel";
|
||||
import {Body, BODY_FORMAT, BODY_TYPE} from "../model/ScenarioModel";
|
||||
import MsCodeEdit from "../../../common/components/MsCodeEdit";
|
||||
import MsDropdown from "../../../common/components/MsDropdown";
|
||||
|
||||
export default {
|
||||
name: "MsApiBody",
|
||||
components: {MsApiKeyValue},
|
||||
components: {MsDropdown, MsCodeEdit, MsApiKeyValue},
|
||||
props: {
|
||||
body: Body,
|
||||
isReadOnly: {
|
||||
|
@ -33,16 +39,24 @@
|
|||
|
||||
data() {
|
||||
return {
|
||||
type: BODY_TYPE
|
||||
type: BODY_TYPE,
|
||||
modes: ['text', 'json', 'xml', 'html']
|
||||
};
|
||||
},
|
||||
|
||||
methods: {},
|
||||
methods: {
|
||||
modeChange(mode) {
|
||||
this.body.format = mode;
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
if (this.body.type === null) {
|
||||
if (!this.body.type) {
|
||||
this.body.type = BODY_TYPE.KV;
|
||||
}
|
||||
if (!this.body.format) {
|
||||
this.body.format = BODY_FORMAT.TEXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -51,4 +65,19 @@
|
|||
.textarea {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.body-raw {
|
||||
padding: 15px 0;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.el-dropdown {
|
||||
margin-left: 20px;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.ace_editor {
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
@ -37,6 +37,13 @@ export const BODY_TYPE = {
|
|||
RAW: "Raw"
|
||||
}
|
||||
|
||||
export const BODY_FORMAT = {
|
||||
TEXT: "text",
|
||||
JSON: "json",
|
||||
XML: "xml",
|
||||
HTML: "html",
|
||||
}
|
||||
|
||||
export const ASSERTION_TYPE = {
|
||||
TEXT: "Text",
|
||||
REGEX: "Regex",
|
||||
|
@ -820,12 +827,42 @@ class JMXGenerator {
|
|||
|
||||
addRequestHeader(httpSamplerProxy, request) {
|
||||
let name = request.name + " Headers";
|
||||
this.addBodyFormat(request);
|
||||
let headers = this.filterKV(request.headers);
|
||||
if (headers.length > 0) {
|
||||
httpSamplerProxy.put(new HeaderManager(name, headers));
|
||||
}
|
||||
}
|
||||
|
||||
addBodyFormat(request) {
|
||||
let bodyFormat = request.body.format;
|
||||
if (bodyFormat) {
|
||||
switch (bodyFormat) {
|
||||
case BODY_FORMAT.JSON:
|
||||
this.addContentType(request, 'application/json');
|
||||
break;
|
||||
case BODY_FORMAT.HTML:
|
||||
this.addContentType(request, 'text/html');
|
||||
break;
|
||||
case BODY_FORMAT.XML:
|
||||
this.addContentType(request, 'text/xml');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addContentType(request, type) {
|
||||
for (let index in request.headers) {
|
||||
if (request.headers[index].name == 'Content-Type') {
|
||||
request.headers.splice(index, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
request.headers.push(new KeyValue('Content-Type', type));
|
||||
}
|
||||
|
||||
addRequestArguments(httpSamplerProxy, request) {
|
||||
let args = this.filterKV(request.parameters);
|
||||
if (args.length > 0) {
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
components: { editor: require('vue2-ace-editor')},
|
||||
data() {
|
||||
return {
|
||||
mode: 'text',
|
||||
formatData: ''
|
||||
}
|
||||
},
|
||||
|
@ -25,6 +24,12 @@
|
|||
return false;
|
||||
}
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default() {
|
||||
return 'text';
|
||||
}
|
||||
},
|
||||
modes: {
|
||||
type: Array,
|
||||
default() {
|
||||
|
@ -35,6 +40,14 @@
|
|||
mounted() {
|
||||
this.format();
|
||||
},
|
||||
watch: {
|
||||
formatData() {
|
||||
this.$emit('update:data', this.formatData);
|
||||
},
|
||||
mode() {
|
||||
this.format();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editorInit: function (editor) {
|
||||
require('brace/ext/language_tools') //language extension prerequsite...
|
||||
|
@ -51,19 +64,19 @@
|
|||
}
|
||||
},
|
||||
format() {
|
||||
if (this.mode === 'json') {
|
||||
if (this.mode === 'json' && this.readOnly) {
|
||||
try {
|
||||
this.formatData = JSON.stringify(JSON.parse(this.data), null, '\t');
|
||||
} catch (e) {
|
||||
this.formatData = this.data;
|
||||
if (this.data) {
|
||||
this.formatData = this.data;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.formatData = this.data;
|
||||
if (this.data) {
|
||||
this.formatData = this.data;
|
||||
}
|
||||
}
|
||||
},
|
||||
setMode(mode) {
|
||||
this.mode = mode;
|
||||
this.format();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,15 @@
|
|||
props: {
|
||||
commands: {
|
||||
type: Array
|
||||
},
|
||||
defaultCommand: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (this.commands && this.commands.length > 0) {
|
||||
if (this.defaultCommand) {
|
||||
this.currentCommand = this.defaultCommand;
|
||||
} else if (this.commands && this.commands.length > 0) {
|
||||
this.currentCommand = this.commands [0];
|
||||
}
|
||||
},
|
||||
|
|
|
@ -28,23 +28,31 @@
|
|||
<el-dialog :title="$t('member.create')" :visible.sync="createVisible" width="30%" :destroy-on-close="true"
|
||||
@close="handleClose">
|
||||
<el-form :model="form" ref="form" :rules="rules" label-position="right" label-width="100px" size="small">
|
||||
<el-form-item :label="$t('commons.member')" prop="memberSign" :rules="{required: true, message: $t('member.input_id_or_email'), trigger: 'change'}">
|
||||
<el-autocomplete
|
||||
class="input-with-autocomplete"
|
||||
v-model="form.memberSign"
|
||||
|
||||
<el-form-item :label="$t('commons.member')" prop="ids" :rules="{required: true, message: $t('member.input_id_or_email'), trigger: 'blur'}">
|
||||
<el-select
|
||||
v-model="form.ids"
|
||||
multiple
|
||||
filterable
|
||||
remote
|
||||
reserve-keyword
|
||||
:popper-append-to-body="false"
|
||||
class="select-width"
|
||||
:placeholder="$t('member.input_id_or_email')"
|
||||
:trigger-on-focus="false"
|
||||
:fetch-suggestions="querySearch"
|
||||
size="small"
|
||||
highlight-first-item
|
||||
value-key="email"
|
||||
@select="handleSelect"
|
||||
>
|
||||
<template v-slot:default="scope">
|
||||
<span class="org-member-name">{{scope.item.id}}</span>
|
||||
<span class="org-member-email">{{scope.item.email}}</span>
|
||||
</template>
|
||||
</el-autocomplete>
|
||||
:remote-method="remoteMethod"
|
||||
:loading="loading">
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.id"
|
||||
:label="item.id"
|
||||
:value="item.id">
|
||||
<template>
|
||||
<span class="org-member-name">{{item.id}}</span>
|
||||
<span class="org-member-email">{{item.email}}</span>
|
||||
</template>
|
||||
</el-option>
|
||||
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.role')" prop="roleIds">
|
||||
<el-select v-model="form.roleIds" multiple :placeholder="$t('role.please_choose_role')" class="select-width">
|
||||
|
@ -136,6 +144,9 @@
|
|||
currentPage: 1,
|
||||
pageSize: 5,
|
||||
total: 0,
|
||||
options: [],
|
||||
loading: false,
|
||||
ids: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -165,6 +176,7 @@
|
|||
},
|
||||
handleClose() {
|
||||
this.form = {};
|
||||
this.options = [];
|
||||
},
|
||||
edit(row) {
|
||||
this.updateVisible = true;
|
||||
|
@ -217,9 +229,9 @@
|
|||
}
|
||||
this.form = {};
|
||||
this.createVisible = true;
|
||||
this.result = this.$get('/user/list/', response => {
|
||||
this.userList = response.data;
|
||||
});
|
||||
// this.result = this.$get('/user/list/', response => {
|
||||
// this.userList = response.data;
|
||||
// });
|
||||
this.result = this.$get('/role/list/org', response => {
|
||||
this.$set(this.form, "roles", response.data);
|
||||
})
|
||||
|
@ -228,19 +240,8 @@
|
|||
this.$refs[formName].validate((valid) => {
|
||||
let orgId = this.currentUser().lastOrganizationId;
|
||||
if (valid) {
|
||||
let userIds = [];
|
||||
let userId = this.form.userId;
|
||||
let email = this.form.memberSign;
|
||||
let member = this.userList.find(user => user.id === email || user.email === email);
|
||||
if (!member) {
|
||||
this.$warning(this.$t('member.no_such_user'));
|
||||
return false;
|
||||
} else {
|
||||
userId = member.id;
|
||||
}
|
||||
userIds.push(userId);
|
||||
let param = {
|
||||
userIds: userIds,
|
||||
userIds: this.form.ids,
|
||||
roleIds: this.form.roleIds,
|
||||
organizationId: orgId
|
||||
};
|
||||
|
@ -254,21 +255,21 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
querySearch(queryString, cb) {
|
||||
var userList = this.userList;
|
||||
var results = queryString ? userList.filter(this.createFilter(queryString)) : userList;
|
||||
// 调用 callback 返回建议列表的数据
|
||||
cb(results);
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return (user) => {
|
||||
return (user.email.indexOf(queryString.toLowerCase()) === 0 || user.id.indexOf(queryString.toLowerCase()) === 0);
|
||||
};
|
||||
},
|
||||
handleSelect(item) {
|
||||
this.$set(this.form, "userId", item.id);
|
||||
remoteMethod(query) {
|
||||
query = query.trim()
|
||||
if (query !== '') {
|
||||
this.loading = true;
|
||||
setTimeout(() => {
|
||||
this.loading = false;
|
||||
this.$get("/user/search/" + query, response => {
|
||||
this.options = response.data;
|
||||
})
|
||||
}, 200);
|
||||
} else {
|
||||
this.options = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in New Issue