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

This commit is contained in:
q4speed 2020-05-15 11:24:09 +08:00
commit cee0e9a345
25 changed files with 203 additions and 249 deletions

View File

@ -2,9 +2,10 @@ package io.metersphere.base.mapper;
import io.metersphere.base.domain.User;
import io.metersphere.base.domain.UserExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface UserMapper {
long countByExample(UserExample example);
@ -28,5 +29,6 @@ public interface UserMapper {
int updateByPrimaryKey(User record);
int updatePassword(User record);
}

View File

@ -303,12 +303,5 @@
phone = #{phone,jdbcType=VARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
<!--修改密码-->
<update id="updatePassword" parameterType="io.metersphere.base.domain.User">
update user
set
password=#{password,jdbcType=VARCHAR},
update_time = #{updateTime,jdbcType=BIGINT}
where id=#{id,jdbcType=VARCHAR}
</update>
</mapper>

View File

@ -25,9 +25,7 @@
AND load_test.id = #{request.id}
</if>
</where>
<if test="request.recent">
order by load_test.update_time desc
</if>
order by load_test.update_time desc
</select>
</mapper>

View File

@ -3,10 +3,15 @@ package io.metersphere.base.mapper.ext;
import io.metersphere.base.domain.User;
import io.metersphere.controller.request.UserRequest;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface ExtUserMapper {
List<User> getUserList(@Param("userRequest") UserRequest request);
int updatePassword(User record);
String getDefaultLanguage(String paramKey);
}

View File

@ -41,5 +41,9 @@
update_time = #{updateTime,jdbcType=BIGINT}
where id=#{id,jdbcType=VARCHAR}
</update>
<select id="getDefaultLanguage" parameterType="java.lang.String" resultType="java.lang.String">
select param_value from system_parameter
where param_key=#{paramKey,jdbcType=VARCHAR}
</select>
</mapper>

View File

@ -1,6 +1,7 @@
package io.metersphere.controller;
import io.metersphere.base.domain.UserRole;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.LoginRequest;
import io.metersphere.dto.UserDTO;
import io.metersphere.service.UserService;
@ -87,4 +88,10 @@ public class LoginController {
return ResultHolder.success("");
}
/*Get default language*/
@GetMapping(value = "/language")
public String getDefaultLanguage() {
return userService.getDefaultLanguage();
}
}

View File

@ -1,16 +0,0 @@
package io.metersphere.dto;
import io.metersphere.base.domain.Role;
import io.metersphere.base.domain.User;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class UserOperateDTO extends User {
private List<Role> roleList;
}

View File

@ -1,18 +0,0 @@
package io.metersphere.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class UserRoleDTO {
private String id;
private String roleId;
private String type;
private String name;
private String desc;
private String parentId;
private Boolean switchable = true;
}

View File

@ -8,13 +8,13 @@ import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
import io.metersphere.commons.constants.PerformanceTestStatus;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.track.request.testplan.*;
import io.metersphere.dto.LoadTestDTO;
import io.metersphere.i18n.Translator;
import io.metersphere.performance.engine.Engine;
import io.metersphere.performance.engine.EngineFactory;
import io.metersphere.service.FileService;
import io.metersphere.service.TestResourceService;
import io.metersphere.track.request.testplan.*;
import org.apache.commons.collections4.ListUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
@ -247,7 +247,6 @@ public class PerformanceTestService {
public List<LoadTestDTO> recentTestPlans(QueryTestPlanRequest request) {
// 查询最近的测试计划
request.setRecent(true);
return extLoadTestMapper.list(request);
}

View File

@ -1,47 +0,0 @@
package io.metersphere.service;
import io.metersphere.base.domain.SystemParameter;
import io.metersphere.base.domain.SystemParameterExample;
import io.metersphere.base.mapper.SystemParameterMapper;
import io.metersphere.commons.constants.ParamConstants;
import io.metersphere.commons.utils.EncryptUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
@Service
@Transactional(rollbackFor = Exception.class)
public class RegistryParamService {
@Resource
private SystemParameterMapper parameterMapper;
public List<SystemParameter> getRegistry(String type) {
List<SystemParameter> paramList = this.getParamList(type);
for (SystemParameter parameter : paramList) {
if (StringUtils.equalsIgnoreCase(ParamConstants.Type.PASSWORD.getValue(), parameter.getType())) {
parameter.setParamValue(EncryptUtils.aesDecrypt(parameter.getParamValue()).toString());
}
}
paramList.sort(Comparator.comparingInt(SystemParameter::getSort));
return paramList;
}
public void updateRegistry(List<SystemParameter> parameters) {
for (SystemParameter parameter : parameters) {
if (StringUtils.equalsIgnoreCase(ParamConstants.Type.PASSWORD.getValue(), parameter.getType())) {
parameter.setParamValue(EncryptUtils.aesEncrypt(parameter.getParamValue()).toString());
}
parameterMapper.updateByPrimaryKey(parameter);
}
}
public List<SystemParameter> getParamList(String type) {
SystemParameterExample example = new SystemParameterExample();
example.createCriteria().andParamKeyLike(type + "%");
return parameterMapper.selectByExample(example);
}
}

View File

@ -223,7 +223,7 @@ public class TestResourcePoolService {
List<TestResourcePoolDTO> testResourcePools = listResourcePools(request);
// 重新校验 pool
for (TestResourcePoolDTO pool : testResourcePools) {
// 手动设置成无效的, 排除
// 手动设置成无效的, 排除
if (INVALID.name().equals(pool.getStatus())) {
continue;
}

View File

@ -344,4 +344,10 @@ public class UserService {
userRole.setUpdateTime(System.currentTimeMillis());
userRoleMapper.insertSelective(userRole);
}
public String getDefaultLanguage() {
final String key = "default.language";
return extUserMapper.getDefaultLanguage(key);
}
}

View File

@ -7,5 +7,4 @@ import lombok.Setter;
@Setter
public class QueryTestPlanRequest extends TestPlanRequest {
private String workspaceId;
private boolean recent = false; // 表示查询最近的测试
}

View File

@ -4,10 +4,18 @@ VALUES ('admin', 'Administrator', 'admin@fit2cloud.com', md5('fit2cloud'), '1',
INSERT INTO user_role (id, user_id, role_id, source_id, create_time, update_time)
VALUES (uuid(), 'admin', 'admin', '1', 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time) VALUES ('admin', '系统管理员', null, null, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time) VALUES ('org_admin', '组织管理员', null, null, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time) VALUES ('test_manager', '测试经理', null, null, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time) VALUES ('test_user', '测试人员', null, null, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time) VALUES ('test_viewer', 'Viewer', null, null, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time)
VALUES ('admin', '系统管理员', NULL, NULL, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time)
VALUES ('org_admin', '组织管理员', NULL, NULL, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time)
VALUES ('test_manager', '测试经理', NULL, NULL, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time)
VALUES ('test_user', '测试人员', NULL, NULL, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time)
VALUES ('test_viewer', 'Viewer', NULL, NULL, 1581576575948, 1581576575948);
INSERT INTO test_case_report_template (id,name,content) VALUES (uuid(), 'default','{\"components\": [1,2,3,4,5]}');
INSERT INTO test_case_report_template (id, name, content)
VALUES (uuid(), 'default', '{\"components\": [1,2,3,4,5]}');
INSERT INTO system_parameter (param_key, param_value, type, sort)
VALUES ('default.language', 'zh_CN', 'text', 5);

View File

@ -18,7 +18,7 @@
</template>
<script>
import {EN_US, TokenKey, ZH_CN, ZH_TW} from '../../../../common/js/constants';
import {DEFAULT_LANGUAGE, EN_US, TokenKey, ZH_CN, ZH_TW} from '../../../../common/js/constants';
import {getCurrentUser} from "../../../../common/js/utils";
export default {
@ -38,7 +38,7 @@
let lang = this.currentUser().language;
this.currentUserInfo = this.currentUser();
if (!lang) {
lang = 'zh_CN';
lang = localStorage.getItem(DEFAULT_LANGUAGE);
}
this.checkLanguage(lang)
},

View File

@ -104,14 +104,14 @@
<el-input-number v-model="item.maxConcurrency" :min="1" :max="9999"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="4">
<el-col :offset="2" :span="2">
<span class="box">
<el-button @click="addResourceInfo()" type="primary" size="mini" circle>
<el-button @click="addResourceInfo()" type="success" size="mini" circle>
<font-awesome-icon :icon="['fas', 'plus']"/>
</el-button>
</span>
<span class="box">
<el-button @click="removeResourceInfo(index)" type="primary" size="mini" circle>
<el-button @click="removeResourceInfo(index)" type="danger" size="mini" circle>
<font-awesome-icon :icon="['fas', 'minus']"/>
</el-button>
</span>
@ -187,14 +187,14 @@
<el-input-number v-model="item.maxConcurrency" :min="1" :max="9999"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="4">
<el-col :offset="2" :span="2">
<span class="box">
<el-button @click="addResourceInfo()" type="primary" size="mini" circle>
<el-button @click="addResourceInfo()" type="success" size="mini" circle>
<font-awesome-icon :icon="['fas', 'plus']"/>
</el-button>
</span>
<span class="box">
<el-button @click="removeResourceInfo(index)" type="primary" size="mini" circle>
<el-button @click="removeResourceInfo(index)" type="danger" size="mini" circle>
<font-awesome-icon :icon="['fas', 'minus']"/>
</el-button>
</span>

View File

@ -33,7 +33,7 @@
position: relative;
border: 1px solid #EBEEF5;
box-sizing: border-box;
min-height: calc(100vh - 80px);
height: calc(100vh - 80px);
background: white;
}
@ -42,7 +42,6 @@
}
.case-container {
min-height: 600px;
margin-top: 0;
margin-left: 0;
}

View File

@ -20,7 +20,7 @@
ref="nodeTree"/>
</el-aside>
<el-main class="test-case-list">
<el-main>
<test-case-list
:current-project="currentProject"
:select-node-ids="selectNodeIds"
@ -226,7 +226,7 @@
<style scoped>
.test-case-list {
.el-main {
padding: 15px;
}

View File

@ -1,7 +1,7 @@
<template>
<div>
<el-card class="table-card" v-loading="result.loading">
<div class="card-container">
<el-card class="card-content" v-loading="result.loading">
<template v-slot:header>
<ms-table-header :condition.sync="condition" @search="initTableData"

View File

@ -18,7 +18,7 @@
</el-aside>
<el-main>
<test-plan-test-case-list
<test-plan-test-case-list class="table-list"
@openTestCaseRelevanceDialog="openTestCaseRelevanceDialog"
@refresh="refresh"
:plan-id="planId"

View File

@ -19,28 +19,26 @@
<el-container>
<el-main class="case-content" v-loading="result.loading">
<!-- <el-scrollbar> -->
<el-table
:data="testCases"
row-key="id"
@select-all="handleSelectAll"
@select="handleSelectionChange"
height="70vh"
ref="table">
<el-table
:data="testCases"
row-key="id"
@select-all="handleSelectAll"
@select="handleSelectionChange"
height="70vh"
ref="table">
<el-table-column
type="selection"></el-table-column>
<el-table-column
type="selection"></el-table-column>
<el-table-column
prop="name"
:label="$t('test_track.case.name')"
style="width: 100%">
<template v-slot:default="scope">
{{scope.row.name}}
</template>
</el-table-column>
</el-table>
<!-- </el-scrollbar> -->
<el-table-column
prop="name"
:label="$t('test_track.case.name')"
style="width: 100%">
<template v-slot:default="scope">
{{scope.row.name}}
</template>
</el-table-column>
</el-table>
</el-main>
</el-container>
</el-container>

View File

@ -1,125 +1,127 @@
<template>
<el-card class="table-card" v-loading="result.loading">
<template v-slot:header>
<ms-table-header :condition.sync="condition" @search="initTableData" :show-create="false">
<template v-slot:title>
<node-breadcrumb class="table-title" :nodes="selectParentNodes" @refresh="refresh"/>
</template>
<template v-slot:button>
<ms-table-button v-if="!showMyTestCase" icon="el-icon-s-custom" :content="$t('test_track.plan_view.my_case')" @click="searchMyTestCase"/>
<ms-table-button v-if="showMyTestCase" icon="el-icon-files" :content="$t('test_track.plan_view.all_case')" @click="searchMyTestCase"/>
<ms-table-button icon="el-icon-connection" :content="$t('test_track.plan_view.relevance_test_case')" @click="$emit('openTestCaseRelevanceDialog')"/>
<ms-table-button icon="el-icon-edit-outline" :content="$t('test_track.plan_view.change_execution_results')" @click="handleBatch('status')"/>
<ms-table-button icon="el-icon-user" :content="$t('test_track.plan_view.change_executor')" @click="handleBatch('executor')"/>
<ms-table-button v-if="!testPlan.reportId" icon="el-icon-document" :content="$t('创建测试报告')" @click="openTestReport"/>
<ms-table-button v-if="testPlan.reportId" icon="el-icon-document" :content="$t('查看测试报告')" @click="openReport"/>
</template>
</ms-table-header>
</template>
<div class="card-container">
<el-card class="card-content" v-loading="result.loading">
<template v-slot:header>
<ms-table-header :condition.sync="condition" @search="initTableData" :show-create="false">
<template v-slot:title>
<node-breadcrumb class="table-title" :nodes="selectParentNodes" @refresh="refresh"/>
</template>
<template v-slot:button>
<ms-table-button v-if="!showMyTestCase" icon="el-icon-s-custom" :content="$t('test_track.plan_view.my_case')" @click="searchMyTestCase"/>
<ms-table-button v-if="showMyTestCase" icon="el-icon-files" :content="$t('test_track.plan_view.all_case')" @click="searchMyTestCase"/>
<ms-table-button icon="el-icon-connection" :content="$t('test_track.plan_view.relevance_test_case')" @click="$emit('openTestCaseRelevanceDialog')"/>
<ms-table-button icon="el-icon-edit-outline" :content="$t('test_track.plan_view.change_execution_results')" @click="handleBatch('status')"/>
<ms-table-button icon="el-icon-user" :content="$t('test_track.plan_view.change_executor')" @click="handleBatch('executor')"/>
<ms-table-button v-if="!testPlan.reportId" icon="el-icon-document" :content="$t('创建测试报告')" @click="openTestReport"/>
<ms-table-button v-if="testPlan.reportId" icon="el-icon-document" :content="$t('查看测试报告')" @click="openReport"/>
</template>
</ms-table-header>
</template>
<executor-edit ref="executorEdit" :select-ids="selectIds" @refresh="initTableData"/>
<status-edit ref="statusEdit" :select-ids="selectIds" @refresh="initTableData"/>
<executor-edit ref="executorEdit" :select-ids="selectIds" @refresh="initTableData"/>
<status-edit ref="statusEdit" :select-ids="selectIds" @refresh="initTableData"/>
<el-table
@select-all="handleSelectAll"
@filter-change="filter"
@sort-change="sort"
@select="handleSelectionChange"
row-key="id"
:data="tableData">
<el-table
@select-all="handleSelectAll"
@filter-change="filter"
@sort-change="sort"
@select="handleSelectionChange"
row-key="id"
:data="tableData">
<el-table-column
type="selection"></el-table-column>
<el-table-column
type="selection"></el-table-column>
<el-table-column
prop="name"
:label="$t('commons.name')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="priority"
:filters="priorityFilters"
column-key="priority"
:label="$t('test_track.case.priority')">
<template v-slot:default="scope">
<priority-table-item :value="scope.row.priority" ref="priority"/>
</template>
</el-table-column>
<el-table-column
prop="name"
:label="$t('commons.name')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="priority"
:filters="priorityFilters"
column-key="priority"
:label="$t('test_track.case.priority')">
<template v-slot:default="scope">
<priority-table-item :value="scope.row.priority" ref="priority"/>
</template>
</el-table-column>
<el-table-column
prop="type"
:filters="typeFilters"
column-key="type"
:label="$t('test_track.case.type')"
show-overflow-tooltip>
<template v-slot:default="scope">
<type-table-item :value="scope.row.type"/>
</template>
</el-table-column>
<el-table-column
prop="type"
:filters="typeFilters"
column-key="type"
:label="$t('test_track.case.type')"
show-overflow-tooltip>
<template v-slot:default="scope">
<type-table-item :value="scope.row.type"/>
</template>
</el-table-column>
<el-table-column
prop="method"
:filters="methodFilters"
column-key="method"
:label="$t('test_track.case.method')"
show-overflow-tooltip>
<template v-slot:default="scope">
<method-table-item :value="scope.row.method"/>
</template>
</el-table-column>
<el-table-column
prop="method"
:filters="methodFilters"
column-key="method"
:label="$t('test_track.case.method')"
show-overflow-tooltip>
<template v-slot:default="scope">
<method-table-item :value="scope.row.method"/>
</template>
</el-table-column>
<el-table-column
prop="nodePath"
:label="$t('test_track.case.module')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="nodePath"
:label="$t('test_track.case.module')"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="executorName"
:label="$t('test_track.plan_view.executor')">
</el-table-column>
<el-table-column
prop="executorName"
:label="$t('test_track.plan_view.executor')">
</el-table-column>
<el-table-column
prop="status"
:filters="statusFilters"
column-key="status"
:label="$t('test_track.plan_view.execute_result')">
<template v-slot:default="scope">
<status-table-item :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column
prop="status"
:filters="statusFilters"
column-key="status"
:label="$t('test_track.plan_view.execute_result')">
<template v-slot:default="scope">
<status-table-item :value="scope.row.status"/>
</template>
</el-table-column>
<el-table-column
sortable
prop="updateTime"
:label="$t('commons.update_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator-button :tip="$t('commons.edit')" icon="el-icon-edit" @exec="handleEdit(scope.row)" />
<ms-table-operator-button :tip="$t('test_track.plan_view.cancel_relevance')" icon="el-icon-unlock" type="danger" @exec="handleDelete(scope.row)"/>
</template>
</el-table-column>
</el-table>
<el-table-column
sortable
prop="updateTime"
:label="$t('commons.update_time')"
show-overflow-tooltip>
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column
:label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator-button :tip="$t('commons.edit')" icon="el-icon-edit" @exec="handleEdit(scope.row)" />
<ms-table-operator-button :tip="$t('test_track.plan_view.cancel_relevance')" icon="el-icon-unlock" type="danger" @exec="handleDelete(scope.row)"/>
</template>
</el-table-column>
</el-table>
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
:total="total"/>
<ms-table-pagination :change="search" :current-page.sync="currentPage" :page-size.sync="pageSize"
:total="total"/>
<test-plan-test-case-edit
ref="testPlanTestCaseEdit"
:search-param="condition"
@refresh="initTableData"
@refreshTable="search"/>
<test-plan-test-case-edit
ref="testPlanTestCaseEdit"
:search-param="condition"
@refresh="initTableData"
@refreshTable="search"/>
<test-report-template-list @openReport="openReport" :plan-id="planId" ref="testReporTtemplateList"/>
<test-case-report-view :plan-id="planId" ref="testCaseReportView"/>
<test-report-template-list @openReport="openReport" :plan-id="planId" ref="testReporTtemplateList"/>
<test-case-report-view :plan-id="planId" ref="testCaseReportView"/>
</el-card>
</div>
</template>
<script>
@ -339,5 +341,4 @@
margin-left: 10px;
width: 240px;
}
</style>

View File

@ -33,6 +33,15 @@ body {
clear: both;
}
.card-container {
position: relative;
}
.card-content {
width: 100%;
position: absolute;
}
.table-card > .el-card__body {
padding-top: 0;
}

View File

@ -1,4 +1,5 @@
export const TokenKey = 'Admin-Token';
export const DEFAULT_LANGUAGE = 'default_language';
export const ROLE_ADMIN = 'admin';
export const ROLE_ORG_ADMIN = 'org_admin';

View File

@ -42,6 +42,7 @@
<script>
import {saveLocalStorage} from '../common/js/utils';
import {DEFAULT_LANGUAGE} from "../common/js/constants";
export default {
@ -107,11 +108,16 @@
this.$post("signin", this.form, response => {
saveLocalStorage(response);
let language = response.data.language;
if (!language) {
language = 'zh_CN';
this.$get("language", response => {
language = response.data;
localStorage.setItem(DEFAULT_LANGUAGE, language)
window.location.href = "/"
})
} else {
window.location.href = "/"
}
this.$setLang(language);
window.location.href = "/"
});
} else {
return false;