提交 98eeb7bc 编写于 作者: S shiziyuan9527
package io.metersphere.commons.constants;
public enum APITestStatus {
Saved, Starting, Running, Completed, Error
Saved, Starting, Running, Reporting, Completed, Error
}
......@@ -57,23 +57,17 @@ public class PersonRepoImpl implements PersonRepo {
LdapTemplate ldapTemplate = getConnection();
String filter = getUserFilter();
String[] arr = getUserOu();
String ou = getUserOu();
List<Person> result = null;
for (String ou : arr) {
try {
result = ldapTemplate.search(query().base(ou.trim()).filter(filter, username), getContextMapper());
if (result.size() == 1) {
return result.get(0);
}
} catch (NameNotFoundException e) {
MSException.throwException(Translator.get("login_fail_ou_error"));
} catch (InvalidNameException e) {
MSException.throwException(Translator.get("login_fail_ou_error"));
} catch (InvalidSearchFilterException e) {
MSException.throwException(Translator.get("login_fail_filter_error"));
}
try {
result = ldapTemplate.search(query().base(ou).filter(filter, username), getContextMapper());
} catch (NameNotFoundException e) {
MSException.throwException(Translator.get("login_fail_ou_error"));
} catch (InvalidNameException e) {
MSException.throwException(Translator.get("login_fail_ou_error"));
} catch (InvalidSearchFilterException e) {
MSException.throwException(Translator.get("login_fail_filter_error"));
}
if (result.size() != 1) {
......@@ -93,16 +87,14 @@ public class PersonRepoImpl implements PersonRepo {
return filter;
}
private String[] getUserOu() {
private String getUserOu() {
String ou = service.getValue(ParamConstants.LDAP.OU.getValue());
if (StringUtils.isBlank(ou)) {
MSException.throwException(Translator.get("ldap_ou_is_null"));
}
String[] arr = ou.split("\\|");
return arr;
return ou;
}
protected ContextMapper getContextMapper() {
......
......@@ -4,7 +4,7 @@
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="search"
:title="$t('api_report.title')"
:title="$t('api_report.title')" :advanced="advanced"
:show-create="false"/>
</template>
<el-table :data="tableData" class="table-content" @sort-change="sort"
......@@ -14,13 +14,13 @@
<el-table-column prop="testName" :label="$t('api_report.test_name')" width="200" show-overflow-tooltip/>
<el-table-column prop="projectName" :label="$t('load_test.project_name')" width="150" show-overflow-tooltip/>
<el-table-column prop="userName" :label="$t('api_test.creator')" width="150" show-overflow-tooltip/>
<el-table-column width="250" :label="$t('commons.create_time')" sortable
prop="createTime">
<el-table-column prop="createTime" width="250" :label="$t('commons.create_time')" sortable>
<template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column prop="triggerMode" width="150" :label="'触发方式'" column-key="triggerMode" :filters="triggerFilters">
<el-table-column prop="triggerMode" width="150" :label="$t('commons.trigger_mode.name')"
column-key="triggerMode" :filters="triggerFilters">
<template v-slot:default="scope">
<report-trigger-mode-item :trigger-mode="scope.row.triggerMode"/>
</template>
......@@ -34,8 +34,10 @@
</el-table-column>
<el-table-column width="150" :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator-button :tip="$t('api_report.detail')" icon="el-icon-s-data" @exec="handleView(scope.row)" type="primary"/>
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_report.delete')" icon="el-icon-delete" @exec="handleDelete(scope.row)" type="danger"/>
<ms-table-operator-button :tip="$t('api_report.detail')" icon="el-icon-s-data"
@exec="handleView(scope.row)" type="primary"/>
<ms-table-operator-button :is-tester-permission="true" :tip="$t('api_report.delete')"
icon="el-icon-delete" @exec="handleDelete(scope.row)" type="danger"/>
</template>
</el-table-column>
</el-table>
......@@ -55,16 +57,21 @@
import {_filter, _sort} from "../../../../common/js/utils";
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
import ReportTriggerModeItem from "../../common/tableItem/ReportTriggerModeItem";
import {REPORT_CONFIGS} from "../../common/components/search/search-components";
export default {
components: {
ReportTriggerModeItem,
MsTableOperatorButton,
MsApiReportStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination},
MsApiReportStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination
},
data() {
return {
result: {},
condition: {},
advanced: {
components: REPORT_CONFIGS
},
tableData: [],
multipleSelection: [],
currentPage: 1,
......@@ -80,9 +87,9 @@
{text: 'Error', value: 'Error'}
],
triggerFilters: [
{text: '手动', value: 'MANUAL'},
{text: '定时任务', value: 'SCHEDULE'},
{text: 'API', value: 'API'}
{text: this.$t('commons.trigger_mode.manual'), value: 'MANUAL'},
{text: this.$t('commons.trigger_mode.schedule'), value: 'SCHEDULE'},
{text: this.$t('commons.trigger_mode.api'), value: 'API'}
],
}
},
......@@ -92,7 +99,8 @@
},
methods: {
search() {
search(advanced) {
console.log(advanced)
if (this.testId !== 'all') {
this.condition.testId = this.testId;
}
......
......@@ -4,7 +4,7 @@
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<ms-table-header :is-tester-permission="true" :condition.sync="condition" @search="search"
:title="$t('commons.test')"
:title="$t('commons.test')" :advanced="advanced"
@create="create" :createTip="$t('load_test.create')"/>
</template>
<el-table :data="tableData" class="table-content" @sort-change="sort" @row-click="handleView"
......@@ -54,6 +54,7 @@
import MsApiTestStatus from "./ApiTestStatus";
import MsTableOperators from "../../common/components/MsTableOperators";
import {_filter, _sort} from "../../../../common/js/utils";
import {TEST_CONFIGS} from "../../common/components/search/search-components";
export default {
components: {
......@@ -64,6 +65,9 @@
return {
result: {},
condition: {},
advanced: {
components: TEST_CONFIGS
},
projectId: null,
tableData: [],
multipleSelection: [],
......@@ -102,9 +106,8 @@
create() {
this.$router.push('/api/test/create');
},
search() {
search(advanced) {
console.log(advanced)
if (this.projectId !== 'all') {
this.condition.projectId = this.projectId;
}
......
<template>
<div>
<el-row :gutter="10" type="flex" justify="space-between" align="middle">
<el-col v-if="extractType == 'Regex'" :span="5">
<el-col v-if="extractType === 'Regex'" :span="5">
<el-select :disabled="isReadOnly" class="extract-item" v-model="common.useHeaders" :placeholder="$t('api_test.request.assertions.select_subject')" size="small">
<el-option v-for="item in useHeadersOption" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
......
......@@ -3,16 +3,18 @@
<div>
<el-row class="table-title" type="flex" justify="space-between" align="middle">
<slot name="title">
{{title}}
{{title}}
</slot>
</el-row>
<el-row type="flex" justify="space-between" align="middle">
<span class="operate-button">
<ms-table-button :is-tester-permission="isTesterPermission" v-if="showCreate" icon="el-icon-circle-plus-outline" :content="createTip" @click="create"/>
<ms-table-button :is-tester-permission="isTesterPermission" v-if="showCreate" icon="el-icon-circle-plus-outline"
:content="createTip" @click="create"/>
<slot name="button"></slot>
</span>
<span>
<ms-table-search-bar :condition.sync="condition" @change="search"/>
<ms-table-search-bar :condition.sync="condition" @change="search" class="search-bar"/>
<ms-table-adv-search-bar :condition="advanced" @search="search" v-if="advanced"/>
</span>
</el-row>
</div>
......@@ -22,45 +24,47 @@
<script>
import MsTableSearchBar from './MsTableSearchBar';
import MsTableButton from './MsTableButton';
import MsTableAdvSearchBar from "./search/MsTableAdvSearchBar";
export default {
name: "MsTableHeader",
components: {MsTableSearchBar, MsTableButton},
props: {
title: {
type: String,
default() {
return this.$t('commons.name');
}
},
showCreate: {
type: Boolean,
default: true
},
condition: {
type: Object
},
createTip: {
type: String,
default() {
return this.$t('commons.create');
}
},
isTesterPermission: {
type: Boolean,
default: false
export default {
name: "MsTableHeader",
components: {MsTableAdvSearchBar, MsTableSearchBar, MsTableButton},
props: {
title: {
type: String,
default() {
return this.$t('commons.name');
}
},
methods: {
search() {
this.$emit('update:condition', this.condition);
this.$emit('search');
},
create() {
this.$emit('create');
showCreate: {
type: Boolean,
default: true
},
condition: {
type: Object
},
advanced: Object,
createTip: {
type: String,
default() {
return this.$t('commons.create');
}
},
isTesterPermission: {
type: Boolean,
default: false
}
},
methods: {
search(value) {
this.$emit('update:condition', this.condition);
this.$emit('search', value);
},
create() {
this.$emit('create');
}
}
}
</script>
<style>
......@@ -79,4 +83,8 @@
margin-bottom: -5px;
}
.search-bar {
width: 200px
}
</style>
<template>
<span class="adv-search-bar">
<el-link type="primary" @click="open">{{$t('commons.adv_search.title')}}</el-link>
<el-dialog :title="$t('commons.adv_search.combine')" :visible.sync="visible" width="70%">
<div>
<div class="search-label">{{$t('commons.adv_search.combine')}}: </div>
<el-select v-model="logic" :placeholder="$t('commons.please_select')" size="small" class="search-combine">
<el-option v-for="o in options" :key="o.value" :label="o.label" :value="o.value"/>
</el-select>
<div class="search-items">
<component class="search-item" v-for="(component, index) in condition.components" :key="index"
:is="component.name" :component="component"/>
</div>
</div>
<template v-slot:footer>
<div class="dialog-footer">
<el-button @click="visible = false">{{$t('commons.cancel')}}</el-button>
<el-button type="primary" @click="search">{{$t('commons.adv_search.search')}}</el-button>
</div>
</template>
</el-dialog>
</span>
</template>
<script>
import components from "./search-components";
export default {
components: {...components},
name: "MsTableAdvSearchBar",
props: {
condition: Object,
},
data() {
return {
visible: false,
options: [{
label: this.$t("commons.adv_search.and"),
value: "and"
}, {
label: this.$t("commons.adv_search.or"),
value: "or"
}],
logic: this.condition.logic || "and"
}
},
methods: {
search() {
let condition = {
logic: this.logic
}
this.condition.components.forEach(component => {
if (Array.isArray(component.value)) {
if (component.value.length > 0) {
condition[component.key] = {
operator: component.operator,
value: component.value
}
}
} else {
if (component.value !== undefined && component.value !== null) {
condition[component.key] = {
operator: component.operator,
value: component.value
}
}
}
});
this.$emit('search', condition);
},
open() {
this.visible = true;
}
}
}
</script>
<style scoped>
.adv-search-bar {
margin-left: 5px;
}
.dialog-footer {
text-align: center;
}
.search-label {
display: inline-block;
width: 80px;
box-sizing: border-box;
padding-left: 5px;
}
.search-combine {
width: 160px;
}
.search-items {
width: 100%;
}
.search-item {
display: inline-block;
width: 50%;
max-width: 50%;
margin-top: 10px;
}
</style>
<template>
<div>
<div class="search-label">{{component.label}}:</div>
<el-select class="search-operator" v-model="operator" :placeholder="$t('commons.please_select')" size="small"
@change="change" @input="input">
<el-option v-for="o in operators" :key="o.value" :label="o.label" :value="o.value"/>
</el-select>
<div class="search-content" v-if="showContent(operator)">
<slot v-bind:component="component"></slot>
</div>
</div>
</template>
<script>
export default {
name: "MsTableSearchComponent",
props: ['component'],
data() {
return {
operators: this.component.operators || [],
operator: (() => {
if (this.component.operator === undefined && this.component.operators.length > 0) {
this.$emit('input', this.component.operators[0].value);
return this.component.operators[0].value;
} else {
this.component.operator
}
})()
}
},
methods: {
change(value) {
this.$emit('change', value);
},
input(value) {
this.$emit('input', value);
}
},
computed: {
showContent() {
return operator => {
if (this.component.showContent) {
return this.component.showContent(operator);
}
return true;
}
}
}
}
</script>
<style scoped>
.search-label {
display: inline-block;
width: 80px;
box-sizing: border-box;
padding-left: 5px;
}
.search-operator {
display: inline-block;
width: 160px;
}
.search-content {
display: inline-block;
margin: 0 5px 0 10px;
width: calc(100% - 255px);
}
</style>
<template>
<ms-table-search-component v-model="component.operator" :component="component">
<template v-slot="scope">
<el-date-picker
v-model="scope.component.value" v-bind="scope.component.props"
:placeholder="$t('commons.date.select_date')" size="small"
:type="type" :key="type" value-format="timestamp"
:range-separator="$t('commons.date.range_separator')"
:start-placeholder="$t('commons.date.start_date')"
:end-placeholder="$t('commons.date.end_date')">
</el-date-picker>
</template>
</ms-table-search-component>
</template>
<script>
import MsTableSearchComponent from "./MsTableSearchComponet";
import {OPERATORS} from "./search-components"
export default {
name: "MsTableSearchDatePicker",
components: {MsTableSearchComponent},
props: ['component'],
data() {
return {
type: "daterange"
}
},
methods: {
change(value) {
if (value === OPERATORS.BETWEEN.value) {
if (!Array.isArray(this.component.value)) {
this.component.value = [];
}
this.type = "daterange";
} else {
if (Array.isArray(this.component.value)) {
this.component.value = "";
}
this.type = "date";
}
}
}
}
</script>
<style scoped>
</style>
<template>
<ms-table-search-component v-model="component.operator" :component="component" @change="change">
<template v-slot="scope">
<el-date-picker v-model="scope.component.value" v-bind="scope.component.props"
:placeholder="$t('commons.date.select_date_time')" size="small"
:type="type" :key="type" value-format="timestamp"
:range-separator="$t('commons.date.range_separator')"
:start-placeholder="$t('commons.date.start_date_time')"
:end-placeholder="$t('commons.date.end_date_time')">
</el-date-picker>
</template>
</ms-table-search-component>
</template>
<script>
import MsTableSearchComponent from "./MsTableSearchComponet";
import {OPERATORS} from "./search-components"
export default {
name: "MsTableSearchDateTimePicker",
components: {MsTableSearchComponent},
props: ['component'],
data() {
return {
type: "datetimerange"
}
},
methods: {
change(value) {
if (value === OPERATORS.BETWEEN.value) {
if (!Array.isArray(this.component.value)) {
this.component.value = [];
}
this.type = "datetimerange";
} else {
if (Array.isArray(this.component.value)) {
this.component.value = "";
}
this.type = "datetime";
}
}
}
}
</script>
<style scoped>
</style>
<template>
<ms-table-search-component v-model="component.operator" :component="component">
<template v-slot="scope">
<el-input v-model="scope.component.value" v-bind="props"
:placeholder="$t('commons.input_content')" size="small"/>
</template>
</ms-table-search-component>
</template>
<script>
import MsTableSearchComponent from "./MsTableSearchComponet";
export default {
name: "MsTableSearchInput",
components: {MsTableSearchComponent},
props: ['component'],
data() {
return {
props: {
maxlength: "60",
showWordLimit: true,
...this.component.props
}
}
}
}
</script>
<style scoped>
</style>
<template>
<ms-table-search-component v-model="component.operator" :component="component">
<template v-slot="scope">
<el-select v-model="scope.component.value" :placeholder="$t('commons.please_select')" size="small" filterable
v-bind="scope.component.props" class="search-select">
<el-option v-for="op in options" :key="op.value" :label="label(op)" :value="op.value"></el-option>
</el-select>
</template>
</ms-table-search-component>
</template>
<script>
import MsTableSearchComponent from "./MsTableSearchComponet";
export default {
name: "MsTableSearchSelect",
components: {MsTableSearchComponent},
props: ['component'],
data() {
return {
options: !(this.component.options instanceof Array) ? [] : this.component.options || []
}
},
created() {
if (!(this.component.options instanceof Array) && this.component.options.url) {
this.$get(this.component.options.url, response => {
if (response.data) {
response.data.forEach(item => {
this.options.push({label: item[this.component.options.labelKey], value: item[this.component.options.valueKey]})
})
}
})
}
},
computed: {
label() {
return op => {
if (this.component.options.showLabel) {
return this.component.options.showLabel(op);
}
return op.label;
}
}
}
}
</script>
<style scoped>
.search-select {
display: inline-block;
width: 100%;
}
</style>
import MsTableSearchInput from "./MsTableSearchInput";
import MsTableSearchDateTimePicker from "./MsTableSearchDateTimePicker";
import MsTableSearchDatePicker from "./MsTableSearchDatePicker";
import MsTableSearchSelect from "./MsTableSearchSelect";
import i18n from "../../../../../i18n/i18n";
export default {
MsTableSearchInput, MsTableSearchDatePicker, MsTableSearchDateTimePicker, MsTableSearchSelect
}
export const OPERATORS = {
LIKE: {
label: i18n.t("commons.adv_search.operators.like"),
value: "like"
},
NOT_LIKE: {
label: i18n.t("commons.adv_search.operators.not_like"),
value: "not like"
},
IN: {
label: i18n.t("commons.adv_search.operators.in"),
value: "in"
},
NOT_IN: {
label: i18n.t("commons.adv_search.operators.not_in"),
value: "not in"
},
GT: {
label: i18n.t("commons.adv_search.operators.gt"),
value: ">"
},
GE: {
label: i18n.t("commons.adv_search.operators.ge"),
value: ">="
},
LT: {
label: i18n.t("commons.adv_search.operators.lt"),
value: "<"
},
LE: {
label: i18n.t("commons.adv_search.operators.le"),
value: "<="
},
EQ: {
label: i18n.t("commons.adv_search.operators.equals"),
value: "=="
},
BETWEEN: {
label: i18n.t("commons.adv_search.operators.between"),
value: "between"
},
CURRENT_USER: {
label: i18n.t("commons.adv_search.operators.current_user"),
value: "current user"
},
}
export const NAME = {
key: "name",
name: 'MsTableSearchInput',
label: i18n.t('commons.name'),
operators: [OPERATORS.LIKE, OPERATORS.NOT_LIKE],
}
export const UPDATE_TIME = {
key: "updateTime",
name: 'MsTableSearchDateTimePicker',
label: i18n.t('commons.update_time'),
operators: [OPERATORS.BETWEEN, OPERATORS.GT, OPERATORS.GE, OPERATORS.LT, OPERATORS.LE, OPERATORS.EQ],
}
export const PROJECT_NAME = {
key: "projectName",
name: 'MsTableSearchInput',
label: i18n.t('commons.adv_search.project'),
operators: [OPERATORS.LIKE, OPERATORS.NOT_LIKE],
}
export const TEST_NAME = {
key: "testName",
name: 'MsTableSearchInput',
label: i18n.t('commons.adv_search.test'),
operators: [OPERATORS.LIKE, OPERATORS.NOT_LIKE],
}
export const CREATE_TIME = {
key: "createTime",
name: 'MsTableSearchDateTimePicker',
label: i18n.t('commons.create_time'),
operators: [OPERATORS.BETWEEN, OPERATORS.GT, OPERATORS.GE, OPERATORS.LT, OPERATORS.LE, OPERATORS.EQ],
}
export const STATUS = {
key: "status",
name: 'MsTableSearchSelect',
label: i18n.t('commons.status'),
operators: [OPERATORS.IN, OPERATORS.NOT_IN],
options: [
{label: "Saved", value: "Saved"}, {label: "Starting", value: "Starting"},
{label: "Running", value: "Running"}, {label: "Reporting", value: "Reporting"},
{label: "Completed", value: "Completed"}, {label: "Error", value: "Error"}
],
props: {
multiple: true
}
}
export const CREATOR = {
key: "creator",
name: 'MsTableSearchSelect',
label: i18n.t('api_test.creator'),
operators: [OPERATORS.IN, OPERATORS.NOT_IN, OPERATORS.CURRENT_USER],
options: {
url: "/user/list",
labelKey: "name",
valueKey: "id",
showLabel: option => {
return option.label + "(" + option.value + ")";
}
},
props: {
multiple: true
},
showContent: operator => {
return operator !== OPERATORS.CURRENT_USER.value;
}
}
export const TRIGGER_MODE = {
key: "triggerMode",
name: 'MsTableSearchSelect',
label: i18n.t('commons.trigger_mode.name'),
operators: [OPERATORS.IN, OPERATORS.NOT_IN],
options: [
{label: i18n.t("commons.trigger_mode.manual"), value: "MANUAL"},
{label: i18n.t("commons.trigger_mode.schedule"), value: "SCHEDULE"},
{label: i18n.t("commons.trigger_mode.api"), value: "API"}
],
props: {
multiple: true
}
}
export const TEST_CONFIGS = [NAME, UPDATE_TIME, PROJECT_NAME, CREATE_TIME, STATUS, CREATOR]
export const REPORT_CONFIGS = [NAME, TEST_NAME, PROJECT_NAME, CREATE_TIME, STATUS, CREATOR, TRIGGER_MODE]
<template>
<span>
<span v-if="triggerMode == 'MANUAL'">手动</span>
<span v-if="triggerMode == 'SCHEDULE'">定时任务</span>
<span v-if="triggerMode == 'API'">API</span>
<span v-if="triggerMode === 'MANUAL'">{{$t('commons.trigger_mode.manual')}}</span>
<span v-if="triggerMode === 'SCHEDULE'">{{$t('commons.trigger_mode.schedule')}}</span>
<span v-if="triggerMode === 'API'">{{$t('commons.trigger_mode.api')}}</span>
</span>
</template>
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册