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

This commit is contained in:
q4speed 2020-05-26 12:15:07 +08:00
commit 0433d8f36b
35 changed files with 325 additions and 129 deletions

View File

@ -8,4 +8,6 @@ import java.util.List;
public interface ExtApiTestMapper {
List<APITestResult> list(@Param("request") QueryAPITestRequest request);
Long countByProjectId(String projectId);
}

View File

@ -29,5 +29,9 @@
</where>
order by api_test.update_time desc
</select>
<select id="countByProjectId" resultType="java.lang.Long">
select count(id) from api_test
where project_id = #{projectId};
</select>
</mapper>

View File

@ -8,4 +8,6 @@ import java.util.List;
public interface ExtLoadTestMapper {
List<LoadTestDTO> list(@Param("request") QueryTestPlanRequest params);
Long countByProjectId(String projectId);
}

View File

@ -27,5 +27,9 @@
</where>
order by load_test.update_time desc
</select>
<select id="countByProjectId" resultType="java.lang.Long">
select count(id) from load_test
where project_id = #{projectId};
</select>
</mapper>

View File

@ -12,4 +12,6 @@ public interface ExtTestCaseMapper {
List<TestCase> getTestCaseNames(@Param("request") QueryTestCaseRequest request);
List<TestCaseDTO> list(@Param("request") QueryTestCaseRequest request);
Long countByProjectId(String projectId);
}

View File

@ -53,4 +53,8 @@
</foreach>
</if>
</select>
<select id="countByProjectId" resultType="java.lang.Long">
select count(id) from test_case
where project_id = #{projectId}
</select>
</mapper>

View File

@ -11,4 +11,6 @@ public interface ExtTestPlanMapper {
List<TestPlanDTO> list(@Param("request") QueryTestPlanRequest params);
List<TestPlanDTOWithMetric> listRelate(@Param("request") QueryTestPlanRequest params);
Long countByProjectId(String projectId);
}

View File

@ -45,5 +45,9 @@
)
order by test_plan.update_time desc
</select>
<select id="countByProjectId" resultType="java.lang.Long">
select count(id) from test_plan
where project_id = #{projectId}
</select>
</mapper>

View File

@ -28,7 +28,7 @@ public interface ParamConstants {
}
enum Classify implements ParamConstants {
MAIL("meter"),
MAIL("smtp"),
REGISTRY("registry");
private String value;
@ -86,14 +86,15 @@ public interface ParamConstants {
}
}
public static enum MAIL {
HOST("meter.host", 1),
PORT("meter.port", 2),
ACCOUNT("meter.account", 3),
PASSWORD("meter.password", 4),
SSL("meter.ssl", 5),
TLS("meter.tls", 6),
ANON("meter.anon", 7);
enum MAIL {
SERVER("smtp.server", 1),
PORT("smtp.port", 2),
ACCOUNT("smtp.account", 3),
PASSWORD("smtp.password", 4),
SSL("smtp.ssl", 5),
TLS("smtp.tls", 6),
SMTP("smtp.smtp", 7);
/* ANON("smtp.anon", 7);*/
private String key;
private Integer value;

View File

@ -9,6 +9,7 @@ import io.metersphere.commons.utils.Pager;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.ProjectRequest;
import io.metersphere.dto.ProjectDTO;
import io.metersphere.dto.ProjectRelatedResourceDTO;
import io.metersphere.service.ProjectService;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
@ -71,4 +72,10 @@ public class ProjectController {
public void updateProject(@RequestBody Project Project) {
projectService.updateProject(Project);
}
@GetMapping("/related/resource/{projectId}")
@RequiresRoles(value = {RoleConstants.TEST_MANAGER, RoleConstants.TEST_USER}, logical = Logical.OR)
public ProjectRelatedResourceDTO getRelatedResource(@PathVariable String projectId) {
return projectService.getRelatedResource(projectId);
}
}

View File

@ -0,0 +1,11 @@
package io.metersphere.dto;
import lombok.Data;
@Data
public class ProjectRelatedResourceDTO {
Long testCaseCount;
Long testPlanCount;
Long loadTestCount;
Long apiTestCount;
}

View File

@ -71,20 +71,23 @@ public class PerformanceTestService {
LoadTestReportExample loadTestReportExample = new LoadTestReportExample();
loadTestReportExample.createCriteria().andTestIdEqualTo(testId);
List<LoadTestReport> loadTestReports = loadTestReportMapper.selectByExample(loadTestReportExample);
List<String> reportIdList = loadTestReports.stream().map(LoadTestReport::getId).collect(Collectors.toList());
// delete load_test_report_result
LoadTestReportResultExample loadTestReportResultExample = new LoadTestReportResultExample();
loadTestReportResultExample.createCriteria().andReportIdIn(reportIdList);
loadTestReportResultMapper.deleteByExample(loadTestReportResultExample);
if (!loadTestReports.isEmpty()) {
List<String> reportIdList = loadTestReports.stream().map(LoadTestReport::getId).collect(Collectors.toList());
// delete load_test_report, delete load_test_report_detail
reportIdList.forEach(reportId -> {
LoadTestReportDetailExample example = new LoadTestReportDetailExample();
example.createCriteria().andReportIdEqualTo(reportId);
loadTestReportDetailMapper.deleteByExample(example);
reportService.deleteReport(reportId);
});
// delete load_test_report_result
LoadTestReportResultExample loadTestReportResultExample = new LoadTestReportResultExample();
loadTestReportResultExample.createCriteria().andReportIdIn(reportIdList);
loadTestReportResultMapper.deleteByExample(loadTestReportResultExample);
// delete load_test_report, delete load_test_report_detail
reportIdList.forEach(reportId -> {
LoadTestReportDetailExample example = new LoadTestReportDetailExample();
example.createCriteria().andReportIdEqualTo(reportId);
loadTestReportDetailMapper.deleteByExample(example);
reportService.deleteReport(reportId);
});
}
// delete load_test
loadTestMapper.deleteByPrimaryKey(request.getId());

View File

@ -6,19 +6,26 @@ import io.metersphere.base.domain.Project;
import io.metersphere.base.domain.ProjectExample;
import io.metersphere.base.mapper.LoadTestMapper;
import io.metersphere.base.mapper.ProjectMapper;
import io.metersphere.base.mapper.ext.ExtProjectMapper;
import io.metersphere.base.mapper.ext.*;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.ProjectRequest;
import io.metersphere.dto.ProjectDTO;
import io.metersphere.dto.ProjectRelatedResourceDTO;
import io.metersphere.i18n.Translator;
import io.metersphere.performance.service.PerformanceTestService;
import io.metersphere.track.dto.TestPlanDTO;
import io.metersphere.track.request.testcase.QueryTestCaseRequest;
import io.metersphere.track.request.testcase.QueryTestPlanRequest;
import io.metersphere.track.request.testplan.DeleteTestPlanRequest;
import io.metersphere.track.service.TestCaseService;
import io.metersphere.track.service.TestPlanService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
@ -34,6 +41,18 @@ public class ProjectService {
private PerformanceTestService performanceTestService;
@Resource
private LoadTestMapper loadTestMapper;
@Resource
private ExtTestCaseMapper extTestCaseMapper;
@Resource
private ExtTestPlanMapper extTestPlanMapper;
@Resource
private ExtLoadTestMapper extLoadTestMapperMapper;
@Resource
private ExtApiTestMapper extApiTestMapper;
@Resource
private TestPlanService testPlanService;
@Resource
private TestCaseService testCaseService;
public Project addProject(Project project) {
if (StringUtils.isBlank(project.getName())) {
@ -76,6 +95,7 @@ public class ProjectService {
});
// TODO 删除项目下 测试跟踪 相关
deleteTrackResourceByProjectId(projectId);
// TODO 删除项目下 接口测试 相关
@ -83,6 +103,15 @@ public class ProjectService {
projectMapper.deleteByPrimaryKey(projectId);
}
private void deleteTrackResourceByProjectId(String projectId) {
QueryTestPlanRequest request = new QueryTestPlanRequest();
request.setProjectId(projectId);
testPlanService.listTestPlan(request).forEach(testPlan -> {
testPlanService.deleteTestPlan(testPlan.getId());
});
testCaseService.deleteTestCaseByProjectId(projectId);
}
public void updateProject(Project project) {
project.setCreateTime(null);
project.setUpdateTime(System.currentTimeMillis());
@ -107,4 +136,13 @@ public class ProjectService {
public Project getProjectById(String id) {
return projectMapper.selectByPrimaryKey(id);
}
public ProjectRelatedResourceDTO getRelatedResource(String projectId) {
ProjectRelatedResourceDTO projectRelatedResource = new ProjectRelatedResourceDTO();
projectRelatedResource.setTestCaseCount(extTestCaseMapper.countByProjectId(projectId));
projectRelatedResource.setTestPlanCount(extTestPlanMapper.countByProjectId(projectId));
projectRelatedResource.setLoadTestCount(extLoadTestMapperMapper.countByProjectId(projectId));
projectRelatedResource.setApiTestCount(extApiTestMapper.countByProjectId(projectId));
return projectRelatedResource;
}
}

View File

@ -4,21 +4,21 @@ 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.exception.MSException;
import io.metersphere.commons.utils.EncryptUtils;
import io.metersphere.i18n.Translator;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import javax.annotation.Resource;
@Service
public class SystemParameterService {
@ -65,7 +65,7 @@ public class SystemParameterService {
public void testConnection(HashMap<String, String> hashMap) {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setDefaultEncoding("UTF-8");
javaMailSender.setHost(hashMap.get(ParamConstants.MAIL.PORT.getKey()));
javaMailSender.setHost(hashMap.get(ParamConstants.MAIL.SERVER.getKey()));
javaMailSender.setPort(Integer.valueOf(hashMap.get(ParamConstants.MAIL.PORT.getKey())));
javaMailSender.setUsername(hashMap.get(ParamConstants.MAIL.ACCOUNT.getKey()));
javaMailSender.setPassword(hashMap.get(ParamConstants.MAIL.PASSWORD.getKey()));
@ -78,6 +78,12 @@ public class SystemParameterService {
props.put("mail.smtp.starttls.enable", "true");
}
javaMailSender.setJavaMailProperties(props);
try {
javaMailSender.testConnection();
} catch (MessagingException e) {
MSException.throwException(Translator.get("connection_failed"));
}
}
}

View File

@ -286,4 +286,10 @@ public class TestCaseService {
example.createCriteria().andIdIn(request.getIds());
testCaseMapper.deleteByExample(example);
}
public void deleteTestCaseByProjectId(String projectId) {
TestCaseExample example = new TestCaseExample();
example.createCriteria().andProjectIdEqualTo(projectId);
testCaseMapper.deleteByExample(example);
}
}

View File

@ -66,6 +66,9 @@ public class TestPlanService {
ExtProjectMapper extProjectMapper;
public void addTestPlan(TestPlan testPlan) {
if (getTestPlanByName(testPlan.getName()).size() > 0) {
MSException.throwException(Translator.get("plan_name_already_exists"));
};
testPlan.setId(UUID.randomUUID().toString());
testPlan.setStatus(TestPlanStatus.Prepare.name());
testPlan.setCreateTime(System.currentTimeMillis());
@ -73,6 +76,13 @@ public class TestPlanService {
testPlanMapper.insert(testPlan);
}
public List<TestPlan> getTestPlanByName(String name) {
TestPlanExample example = new TestPlanExample();
example.createCriteria().andWorkspaceIdEqualTo(SessionUtils.getCurrentWorkspaceId())
.andNameEqualTo(name);
return testPlanMapper.selectByExample(example);
}
public TestPlan getTestPlan(String testPlanId) {
return testPlanMapper.selectByPrimaryKey(testPlanId);
}

View File

@ -5,6 +5,7 @@ cannot_be_null=\tCannot be empty
number=Number
row=row
error=error
connection_failed=Connection failed
#user related
user_email_already_exists=User email already exists
user_name_is_null=User name cannot be null
@ -87,4 +88,5 @@ do_not_modify_header_order=Do not modify the header order
module_created_automatically=If there is no such module, will be created automatically
options=options
please_input_workspace_member=Please input workspace merber
test_case_report_template_repeat=The workspace has the same name template
test_case_report_template_repeat=The workspace has the same name template
plan_name_already_exists=Test plan name already exists

View File

@ -13,6 +13,7 @@ password_is_null=密码不能为空
user_id_already_exists=用户id已存在
password_modification_failed=密码修改失败
cannot_delete_current_user=无法删除当前登录用户
connection_failed=连接失败
#load test
edit_load_test_not_found=无法编辑测试,未找到测试:
run_load_test_not_found=无法运行测试,未找到测试:
@ -88,3 +89,4 @@ module_created_automatically=若无该模块将自动创建
options=选项
please_input_workspace_member=请填写该工作空间相关人员
test_case_report_template_repeat=同一工作空间下不能存在同名模版
plan_name_already_exists=测试计划名称已存在

View File

@ -5,6 +5,7 @@ cannot_be_null=不能為空
number=
row=
error=出錯
connection_failed=連接失敗
#user related
user_email_already_exists=用戶郵箱已存在
user_name_is_null=用戶名不能為空
@ -87,4 +88,5 @@ do_not_modify_header_order=請勿修改表頭順序
module_created_automatically=若無該模塊將自動創建
options=選項
please_input_workspace_member=請填寫該工作空間相關人員
test_case_report_template_repeat=同壹工作空間下不能存在同名模版
test_case_report_template_repeat=同壹工作空間下不能存在同名模版
plan_name_already_exists=測試計劃名稱已存在

View File

@ -5,6 +5,9 @@
<slot name="middle"></slot>
<ms-table-operator-button :tip="$t('commons.delete')" icon="el-icon-delete" type="danger" @exec="deleteClick" @click.stop="deleteClickStop"/>
<slot name="behind"></slot>
<!--
<ms-table-operator-button :tip="$t('commons.remove')" icon="el-icon-s-fold" type="danger" @exec="removeClick" @click.stop="removeClickStop"/>
-->
</span>
</template>
@ -26,7 +29,13 @@
},
deleteClickStop() {
this.$emit('deleteClickStop');
}
},
/* removeClick(){
this.$emit('removeClick');
},
removeClickStop(){
this.$emit('removeClickStop')
}*/
}
}
</script>

View File

@ -169,7 +169,7 @@
this.fileList.splice(index, 1);
this.tableData.splice(index, 1);
//
let i = this.uploadList.indexOf(file);
let i = this.uploadList.findIndex(upLoadFile => upLoadFile.name === file.name);
if (i > -1) {
this.uploadList.splice(i, 1);
}

View File

@ -142,16 +142,18 @@
});
},
del(row) {
this.$confirm(this.$t('project.delete_confirm'), this.$t('commons.prompt'), {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.$get('/project/delete/' + row.id, () => {
Message.success(this.$t('commons.delete_success'));
this.list();
this.getRelatedResource(row.id).then(tip => {
this.$confirm(tip + this.$t('project.delete_confirm'), this.$t('commons.prompt'), {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.$get('/project/delete/' + row.id, () => {
Message.success(this.$t('commons.delete_success'));
this.list();
});
}).catch(() => {
});
}).catch(() => {
});
},
search() {
@ -165,6 +167,29 @@
this.total = data.itemCount;
})
},
getRelatedResource(projectId) {
return new Promise((resolve, reject) => {
this.$get('/project/related/resource/' + projectId, response => {
let data = response.data;
let result = '';
result = this.appendDeleteTip(result, data.testCaseCount, this.$t('test_track.case.test_case'));
result = this.appendDeleteTip(result, data.testPlanCount, this.$t('test_track.plan.test_plan') );
result = this.appendDeleteTip(result, data.loadTestCount, this.$t('commons.performance'));
result = this.appendDeleteTip(result, data.apiTestCount, this.$t('commons.api'));
if (result != '') {
result = this.$t('project.delete_tip') + result;
}
resolve(result);
});
});
},
appendDeleteTip(result, count, tip) {
if (count > 0) {
return result + count + "个" + tip + ',';
} else {
return result;
}
}
}
}
</script>

View File

@ -105,7 +105,7 @@
export default {
name: "MsOrganizationMember",
components: {MsCreateBox, MsTablePagination, MsTableHeader, MsRolesTag, MsTableOperator, MsDialogFooter},
created() {
activated() {
this.initTableData();
},
data() {

View File

@ -56,7 +56,11 @@
</el-table-column>
<el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator @editClick="editMember(scope.row)" @deleteClick="delMember(scope.row)"/>
<!--<ms-table-operator @editClick="editMember(scope.row)" @deleteClick="delMember(scope.row)"/>-->
<ms-table-operator-button :tip="$t('commons.edit')" icon="el-icon-edit" @exec="editMember(scope.row)"/>
<ms-table-operator-button :tip="$t('commons.remove')" icon="el-icon-delete" type="danger"
@exec="delMember(scope.row)"/>
</template>
</el-table-column>
</el-table>
@ -150,13 +154,22 @@
import MsTableHeader from "../../common/components/MsTableHeader";
import MsRolesTag from "../../common/components/MsRolesTag";
import MsTableOperator from "../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
import MsDialogFooter from "../../common/components/MsDialogFooter";
import {getCurrentUser, getCurrentWorkspaceId, refreshSessionAndCookies} from "../../../../common/js/utils";
export default {
name: "MsOrganizationWorkspace",
components: {MsCreateBox, MsTablePagination, MsTableHeader, MsRolesTag, MsTableOperator, MsDialogFooter},
mounted() {
components: {
MsCreateBox,
MsTablePagination,
MsTableHeader,
MsRolesTag,
MsTableOperator,
MsDialogFooter,
MsTableOperatorButton
},
activated() {
this.list();
},
computed: {
@ -327,17 +340,17 @@
this.$set(this.memberForm, 'roleIds', roleIds);
},
delMember(row) {
this.$confirm(this.$t('member.delete_confirm'), '', {
this.$confirm(this.$t('member.remove_member'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
}).then(() => {
this.result = this.$get('/user/ws/member/delete/' + this.currentWorkspaceRow.id + '/' + row.id, () => {
this.$success(this.$t('commons.delete_success'));
this.$success(this.$t('commons.remove_success'));
this.cellClick(this.currentWorkspaceRow);
});
}).catch(() => {
this.$info(this.$t('commons.delete_cancel'));
this.$info(this.$t('commons.remove_cancel'));
});
},
updateOrgMember() {

View File

@ -148,7 +148,7 @@
}
},
created() {
activated() {
this.initTableData();
},
methods: {

View File

@ -42,7 +42,15 @@
</el-table-column>
<el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator @editClick="editMember(scope.row)" @deleteClick="delMember(scope.row)"/>
<!--<ms-table-operator @editClick="editMember(scope.row)" @deleteClick="delMember(scope.row)"/>-->
<ms-table-operator-button :tip="$t('commons.edit')" icon="el-icon-edit" @exec="editMember(scope.row)"/>
<ms-table-operator-button :tip="$t('commons.remove')" icon="el-icon-delete" type="danger"
@exec="delMember(scope.row)"/>
<!--<el-tooltip class="item" effect="dark" :content="$t('commons.remove')" placement="bottom">
<el-button :icon="el-icon-remove-outline">下边</el-button>
</el-tooltip>-->
</template>
</el-table-column>
</el-table>
@ -173,13 +181,22 @@
import MsTableHeader from "../../common/components/MsTableHeader";
import MsRolesTag from "../../common/components/MsRolesTag";
import MsTableOperator from "../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
import MsDialogFooter from "../../common/components/MsDialogFooter";
import {getCurrentOrganizationId, getCurrentUser, refreshSessionAndCookies} from "../../../../common/js/utils";
import {DEFAULT, ORGANIZATION} from "../../../../common/js/constants";
export default {
name: "MsOrganization",
components: {MsCreateBox, MsTablePagination, MsTableHeader, MsRolesTag, MsTableOperator, MsDialogFooter},
components: {
MsCreateBox,
MsTablePagination,
MsTableHeader,
MsRolesTag,
MsTableOperator,
MsDialogFooter,
MsTableOperatorButton
},
data() {
return {
queryPath: '/organization/list',
@ -231,7 +248,7 @@
}
}
},
created() {
activated() {
this.initTableData();
},
methods: {
@ -324,7 +341,7 @@
});
},
delMember(row) {
this.$confirm(this.$t('member.delete_confirm'), '', {
this.$confirm(this.$t('member.remove_member'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
@ -337,11 +354,11 @@
let sign = ORGANIZATION;
refreshSessionAndCookies(sign, sourceId);
}
this.$success(this.$t('commons.delete_success'))
this.$success(this.$t('commons.remove_success'))
this.cellClick(this.currentRow);
});
}).catch(() => {
this.$info(this.$t('commons.delete_cancel'));
this.$info(this.$t('commons.remove_cancel'));
});
},
createOrganization(createOrganizationForm) {

View File

@ -76,7 +76,7 @@
formInline: {
host: 'smtp.163.com',
port: '465',
account: 'xjj0608@153.com',
account: 'xjj0608@163.com',
password: '2345678',
},
result: {},
@ -125,24 +125,19 @@
},
testConnection(formInline) {
let param = {
"meter.host": this.formInline.host,
"meter.port": this.formInline.port,
"meter.account": this.formInline.account,
"meter.password": this.formInline.password,
"meter.ssl": this.SSL,
"meter.tls": this.TLS,
"meter.smtp": this.SMTP,
"smtp.server": this.formInline.host,
"smtp.port": this.formInline.port,
"smtp.account": this.formInline.account,
"smtp.password": this.formInline.password,
"smtp.ssl": this.SSL,
"smtp.tls": this.TLS,
"smtp.smtp": this.SMTP,
};
this.$refs[formInline].validate((valid) => {
if (valid) {
this.result = this.$post("/system/testConnection", param, response => {
let flag = response.success;
if (flag) {
this.$success(this.$t('commons.connection_successful'));
} else {
this.$message.error(this.$t('commons.connection_failed'));
}
});
this.$success(this.$t('commons.connection_successful'));
})
} else {
return false;
}
@ -160,13 +155,13 @@
this.showSave = false;
this.show = true;
let param = [
{paramKey: "meter.host", paramValue: this.formInline.host, type: "text", sort: 1},
{paramKey: "meter.port", paramValue: this.formInline.port, type: "text", sort: 2},
{paramKey: "meter.account", paramValue: this.formInline.account, type: "text", sort: 3},
{paramKey: "meter.password", paramValue: this.formInline.password, type: "password", sort: 4},
{paramKey: "meter.ssl", paramValue: this.SSL, type: "text", sort: 5},
{paramKey: "meter.tls", paramValue: this.TLS, type: "text", sort: 6},
{paramKey: "meter.smtp", paramValue: this.SMTP, type: "text", sort: 7}
{paramKey: "smtp.host", paramValue: this.formInline.host, type: "text", sort: 1},
{paramKey: "smtp.port", paramValue: this.formInline.port, type: "text", sort: 2},
{paramKey: "smtp.account", paramValue: this.formInline.account, type: "text", sort: 3},
{paramKey: "smtp.password", paramValue: this.formInline.password, type: "password", sort: 4},
{paramKey: "smtp.ssl", paramValue: this.SSL, type: "text", sort: 5},
{paramKey: "smtp.tls", paramValue: this.TLS, type: "text", sort: 6},
{paramKey: "smtp.smtp", paramValue: this.SMTP, type: "text", sort: 7}
]
this.$refs[formInline].validate(valid => {

View File

@ -100,7 +100,10 @@
</el-table-column>
<el-table-column :label="$t('commons.operating')">
<template v-slot:default="scope">
<ms-table-operator @editClick="editMember(scope.row)" @deleteClick="delMember(scope.row)"/>
<!--<ms-table-operator @editClick="editMember(scope.row)" @deleteClick="delMember(scope.row)"/>-->
<ms-table-operator-button :tip="$t('commons.edit')" icon="el-icon-edit" @exec="editMember(scope.row)"/>
<ms-table-operator-button :tip="$t('commons.remove')" icon="el-icon-delete" type="danger"
@exec="delMember(scope.row)"/>
</template>
</el-table-column>
</el-table>
@ -194,14 +197,23 @@
import MsTableHeader from "../../common/components/MsTableHeader";
import MsRolesTag from "../../common/components/MsRolesTag";
import MsTableOperator from "../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../common/components/MsTableOperatorButton";
import MsDialogFooter from "../../common/components/MsDialogFooter";
import {getCurrentUser, getCurrentWorkspaceId, refreshSessionAndCookies} from "../../../../common/js/utils";
import {DEFAULT, WORKSPACE} from "../../../../common/js/constants";
export default {
name: "MsSystemWorkspace",
components: {MsCreateBox, MsTablePagination, MsTableHeader, MsRolesTag, MsTableOperator, MsDialogFooter},
mounted() {
components: {
MsCreateBox,
MsTablePagination,
MsTableHeader,
MsRolesTag,
MsTableOperator,
MsDialogFooter,
MsTableOperatorButton
},
activated() {
this.list();
},
methods: {
@ -376,7 +388,7 @@
this.$set(this.memberForm, 'roleIds', roleIds);
},
delMember(row) {
this.$confirm(this.$t('member.delete_confirm'), '', {
this.$confirm(this.$t('member.remove_member'), '', {
confirmButtonText: this.$t('commons.confirm'),
cancelButtonText: this.$t('commons.cancel'),
type: 'warning'
@ -389,11 +401,11 @@
let sign = WORKSPACE;
refreshSessionAndCookies(sign, sourceId);
}
this.$success(this.$t('commons.delete_success'));
this.$success(this.$t('commons.remove_success'));
this.cellClick(this.currentWorkspaceRow);
});
}).catch(() => {
this.$info(this.$t('commons.delete_cancel'));
this.$info(this.$t('commons.remove_cancel'));
});
},
updateWorkspaceMember() {

View File

@ -256,7 +256,7 @@
}
}
},
created() {
activated() {
this.initTableData();
},
methods: {

View File

@ -68,29 +68,29 @@
<el-input v-model="form.password" autocomplete="off" show-password/>
</el-form-item>
<div v-for="(role, index) in form.roles" :key="index">
<el-form-item :label="'角色'+index"
<el-form-item :label="$t('commons.role')+index"
:prop="'roles.' + index + '.id'"
:rules="{required: true, message: '请选择角色', trigger: 'change'}"
:rules="{required: true, message: $t('role.please_choose_role'), trigger: 'change'}"
>
<el-select v-model="role.id" placeholder="选择角色类型">
<el-select v-model="role.id" :placeholder="$t('role.please_choose_role')">
<el-option
v-for="item in activeRole(role)"
:key="item.id"
:label="item.name"
:label="$t('role.' + item.id)"
:value="item.id"
>
{{item.name}}
{{$t('role.' + item.id)}}
</el-option>
</el-select>
<el-button @click.prevent="removeRole(role)" style="margin-left: 20px;" v-if="form.roles.length > 1">删除
<el-button @click.prevent="removeRole(role)" style="margin-left: 20px;" v-if="form.roles.length > 1">{{$t('commons.delete')}}
</el-button>
</el-form-item>
<div v-if="role.id === 'org_admin'">
<el-form-item label="选择组织"
<el-form-item :label="$t('organization.select_organization')"
:prop="'roles.' + index + '.ids'"
:rules="{required: true, message: '请选择组织', trigger: 'change'}"
:rules="{required: true, message: $t('organization.select_organization'), trigger: 'change'}"
>
<el-select v-model="role.ids" placeholder="选择组织" multiple>
<el-select v-model="role.ids" :placeholder="$t('organization.select_organization')" multiple>
<el-option
v-for="item in form.orgList"
:key="item.id"
@ -101,11 +101,11 @@
</el-form-item>
</div>
<div v-if="role.id === 'test_manager'">
<el-form-item label="选择工作空间"
<el-form-item :label="$t('workspace.select')"
:prop="'roles.' + index + '.ids'"
:rules="{required: true, message: '请选择工作空间', trigger: 'change'}"
:rules="{required: true, message: $t('workspace.select'), trigger: 'change'}"
>
<el-select v-model="role.ids" placeholder="选择工作空间" multiple>
<el-select v-model="role.ids" :placeholder="$t('workspace.select')" multiple>
<el-option
v-for="item in form.wsList"
:key="item.id"
@ -116,11 +116,11 @@
</el-form-item>
</div>
<div v-if="role.id ==='test_user'">
<el-form-item label="选择工作空间"
<el-form-item :label="$t('workspace.select')"
:prop="'roles.' + index + '.ids'"
:rules="{required: true, message: '请选择工作空间', trigger: 'change'}"
:rules="{required: true, message: $t('workspace.select'), trigger: 'change'}"
>
<el-select v-model="role.ids" placeholder="选择工作空间" multiple>
<el-select v-model="role.ids" :placeholder="$t('workspace.select')" multiple>
<el-option
v-for="item in form.wsList"
:key="item.id"
@ -131,11 +131,11 @@
</el-form-item>
</div>
<div v-if="role.id ==='test_viewer'">
<el-form-item label="选择工作空间"
<el-form-item :label="$t('workspace.select')"
:prop="'roles.' + index + '.ids'"
:rules="{required: true, message: '请选择工作空间', trigger: 'change'}"
:rules="{required: true, message: $t('workspace.select'), trigger: 'change'}"
>
<el-select v-model="role.ids" placeholder="选择工作空间" multiple>
<el-select v-model="role.ids" :placeholder="$t('workspace.select')" multiple>
<el-option
v-for="item in form.wsList"
:key="item.id"
@ -149,7 +149,7 @@
<el-form-item>
<template>
<el-button type="success" style="width: 100%;" @click="addRole('createUserForm')" :disabled="btnAddRole">添加角色</el-button>
<el-button type="success" style="width: 100%;" @click="addRole('createUserForm')" :disabled="btnAddRole">{{$t('role.add')}}</el-button>
</template>
</el-form-item>
</el-form>
@ -177,27 +177,27 @@
<el-input v-model="form.phone" autocomplete="off"/>
</el-form-item>
<div v-for="(role, index) in form.roles" :key="index">
<el-form-item :label="'角色'+index"
<el-form-item :label="$t('commons.role')+index"
:prop="'roles.' + index + '.id'"
:rules="{required: true, message: '请选择角色', trigger: 'change'}"
:rules="{required: true, message: $t('role.please_choose_role'), trigger: 'change'}"
>
<el-select v-model="role.id" placeholder="选择角色类型" :disabled="!!role.id">
<el-select v-model="role.id" :placeholder="$t('role.please_choose_role')" :disabled="!!role.id">
<el-option
v-for="item in activeRole(role)"
:key="item.id"
:label="item.name"
:label="$t('role.' + item.id)"
:value="item.id">
</el-option>
</el-select>
<el-button @click.prevent="removeRole(role)" style="margin-left: 20px;" v-if="form.roles.length > 1">删除
<el-button @click.prevent="removeRole(role)" style="margin-left: 20px;" v-if="form.roles.length > 1">{{$t('commons.delete')}}
</el-button>
</el-form-item>
<div v-if="role.id === 'org_admin'">
<el-form-item label="选择组织"
<el-form-item :label="$t('organization.select_organization')"
:prop="'roles.' + index + '.ids'"
:rules="{required: true, message: '请选择组织', trigger: 'change'}"
:rules="{required: true, message: $t('organization.select_organization'), trigger: 'change'}"
>
<el-select v-model="role.ids" placeholder="选择组织" multiple>
<el-select v-model="role.ids" :placeholder="$t('organization.select_organization')" multiple>
<el-option
v-for="item in form.orgList"
:key="item.id"
@ -208,11 +208,11 @@
</el-form-item>
</div>
<div v-if="role.id === 'test_manager'">
<el-form-item label="选择工作空间"
<el-form-item :label="$t('workspace.select')"
:prop="'roles.' + index + '.ids'"
:rules="{required: true, message: '请选择工作空间', trigger: 'change'}"
:rules="{required: true, message: $t('workspace.select'), trigger: 'change'}"
>
<el-select v-model="role.ids" placeholder="选择工作空间" multiple>
<el-select v-model="role.ids" :placeholder="$t('workspace.select')" multiple>
<el-option
v-for="item in form.wsList"
:key="item.id"
@ -223,11 +223,11 @@
</el-form-item>
</div>
<div v-if="role.id ==='test_user'">
<el-form-item label="选择工作空间"
<el-form-item :label="$t('workspace.select')"
:prop="'roles.' + index + '.ids'"
:rules="{required: true, message: '请选择工作空间', trigger: 'change'}"
:rules="{required: true, message: $t('workspace.select'), trigger: 'change'}"
>
<el-select v-model="role.ids" placeholder="选择工作空间" multiple>
<el-select v-model="role.ids" :placeholder="$t('workspace.select')" multiple>
<el-option
v-for="item in form.wsList"
:key="item.id"
@ -238,11 +238,11 @@
</el-form-item>
</div>
<div v-if="role.id ==='test_viewer'">
<el-form-item label="选择工作空间"
<el-form-item :label="$t('workspace.select')"
:prop="'roles.' + index + '.ids'"
:rules="{required: true, message: '请选择工作空间', trigger: 'change'}"
:rules="{required: true, message: $t('workspace.select'), trigger: 'change'}"
>
<el-select v-model="role.ids" placeholder="选择工作空间" multiple>
<el-select v-model="role.ids" :placeholder="$t('workspace.select')" multiple>
<el-option
v-for="item in form.wsList"
:key="item.id"
@ -255,7 +255,7 @@
</div>
<el-form-item>
<template>
<el-button type="success" style="width: 100%;" @click="addRole('updateUserForm')" :disabled="btnAddRole">添加角色</el-button>
<el-button type="success" style="width: 100%;" @click="addRole('updateUserForm')" :disabled="btnAddRole">{{$t('role.add')}}</el-button>
</template>
</el-form-item>
</el-form>
@ -386,7 +386,7 @@
}
}
},
created() {
activated() {
this.search();
this.getAllRole();
},

View File

@ -130,7 +130,7 @@
total: 0,
}
},
created: function () {
activated: function () {
this.initTableData();
},
methods: {

View File

@ -22,6 +22,7 @@
<el-col :span="11" :offset="2">
<el-form-item :label="$t('test_track.plan.plan_project')" :label-width="formLabelWidth" prop="projectId">
<el-select
:disabled="(form.status == null) ? false : true"
v-model="form.projectId"
:placeholder="$t('test_track.plan.input_plan_project')"
filterable>

View File

@ -56,7 +56,6 @@ export default {
'personal_information': 'Personal Information',
'exit_system': 'Exit System',
'verification': 'Verification',
'set_admin': 'Set Admin',
'system_parameter_setting': 'System Parameter Setting',
'connection_successful': 'Connection successful',
'connection_failed': 'Connection failed',
@ -89,6 +88,9 @@ export default {
'weeks_5': 'Fri',
'weeks_6': 'Sat',
'test_unit': 'tests',
'remove': 'Remove',
'remove_cancel': 'Remove Failed',
'remove_success': 'Remove Success'
},
workspace: {
'create': 'Create Workspace',
@ -121,6 +123,7 @@ export default {
'create': 'Create Project',
'edit': 'Edit Project',
'delete_confirm': 'Are you sure you want to delete this project?',
'delete_tip': 'These resources will be deleted:',
'search_by_name': 'Search by name',
'input_name': 'Please enter a workspace name',
'owning_workspace': 'Owning Workspace',
@ -143,6 +146,7 @@ export default {
'password_format_is_incorrect': 'Password format is incorrect (At least 8-16 characters, at least 1 uppercase letter, 1 lowercase letter and 1 number)',
'old_password': 'Old Password',
'new_password': 'New Password',
'remove_member': 'Are you sure you want to remove this member'
},
user: {
'create': 'Create',
@ -163,6 +167,7 @@ export default {
'test_manager': 'Test Manager',
'test_user': 'Test User',
'test_viewer': 'Test Viewer',
'add': 'Add Role',
},
report: {
'recent': 'Recent Report',

View File

@ -80,7 +80,6 @@ export default {
'weeks_5': '周五',
'weeks_6': '周六',
'test_unit': '测试',
'set_admin': '设置为管理员',
'system_parameter_setting': '系统参数设置',
'connection_successful': '连接成功',
'connection_failed': '连接失败',
@ -88,6 +87,9 @@ export default {
'host_cannot_be_empty': '主机不能为空',
'port_cannot_be_empty': '端口号不能为空',
'account_cannot_be_empty': '帐户不能为空',
'remove': '移除',
'remove_cancel': '移除失败',
'remove_success': '移除成功'
},
workspace: {
'create': '创建工作空间',
@ -118,7 +120,8 @@ export default {
'recent': '最近的项目',
'create': '创建项目',
'edit': '编辑项目',
'delete_confirm': '这个项目确定要删除吗?',
'delete_confirm': '确定要删除这个项目吗?',
'delete_tip': '删除该项目,会删除以下资源:',
'search_by_name': '根据名称搜索',
'input_name': '请输入项目名称',
'owning_workspace': '所属工作空间',
@ -141,6 +144,7 @@ export default {
'password_format_is_incorrect': '密码格式不正确(至少8-16个字符至少1个大写字母1个小写字母和1个数字)',
'old_password': '旧密码',
'new_password': '新密码',
'remove_member': '确定要移除该成员吗'
},
user: {
'create': '创建用户',
@ -160,7 +164,8 @@ export default {
'org_admin': '组织管理员',
'test_manager': '测试经理',
'test_user': '测试人员',
'test_viewer': 'Viewer'
'test_viewer': 'Viewer',
'add': '添加角色',
},
report: {
'recent': '最近的报告',

View File

@ -110,7 +110,8 @@ export default {
'recent': '最近的項目',
'create': '創建項目',
'edit': '編輯項目',
'delete_confirm': '這個項目確定要刪除嗎?',
'delete_confirm': '確定要刪除這個項目嗎?',
'delete_tip': '刪除該項目,會刪除以下資源:',
'search_by_name': '根據名稱搜索',
'input_name': '請輸入項目名稱',
'owning_workspace': '所屬工作空間',
@ -152,7 +153,8 @@ export default {
'org_admin': '組織管理員',
'test_manager': '測試經理',
'test_user': '測試人員',
'test_viewer': 'Viewer'
'test_viewer': 'Viewer',
'add': '添加角色',
},
report: {
'name': '項目名稱',