测试用例批量移动
This commit is contained in:
parent
bc518448a6
commit
6854a6f5d3
|
@ -6,6 +6,8 @@ import io.metersphere.base.domain.*;
|
|||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
|
||||
import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
|
||||
import io.metersphere.excel.domain.ExcelResponse;
|
||||
import io.metersphere.service.TestCaseService;
|
||||
import io.metersphere.user.SessionUtils;
|
||||
|
@ -82,5 +84,9 @@ public class TestCaseController {
|
|||
testCaseService.testCaseTemplateExport(response);
|
||||
}
|
||||
|
||||
@PostMapping("/batch/edit")
|
||||
public void editTestCaseBath(@RequestBody TestCaseBatchRequest request){
|
||||
testCaseService.editTestCaseBath(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,12 +2,10 @@ package io.metersphere.controller;
|
|||
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||
import io.metersphere.base.domain.TestPlanTestCase;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
|
||||
import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
|
||||
import io.metersphere.controller.request.testplancase.QueryTestPlanCaseRequest;
|
||||
import io.metersphere.dto.TestPlanCaseDTO;
|
||||
import io.metersphere.service.TestPlanTestCaseService;
|
||||
|
@ -40,7 +38,7 @@ public class TestPlanTestCaseController {
|
|||
}
|
||||
|
||||
@PostMapping("/batch/edit")
|
||||
public void editTestCaseBath(@RequestBody TestCaseBatchRequest request){
|
||||
public void editTestCaseBath(@RequestBody TestPlanCaseBatchRequest request){
|
||||
testPlanTestCaseService.editTestCaseBath(request);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
package io.metersphere.controller.request.testcase;
|
||||
|
||||
import io.metersphere.base.domain.TestCase;
|
||||
import io.metersphere.base.domain.TestCaseWithBLOBs;
|
||||
import io.metersphere.base.domain.TestPlanTestCase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TestCaseBatchRequest extends TestPlanTestCase {
|
||||
public class TestCaseBatchRequest extends TestCaseWithBLOBs {
|
||||
|
||||
private List<Integer> ids;
|
||||
private List<String> ids;
|
||||
|
||||
public List<Integer> getIds() {
|
||||
public List<String> getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public void setIds(List<Integer> ids) {
|
||||
public void setIds(List<String> ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package io.metersphere.controller.request.testcase;
|
||||
|
||||
import io.metersphere.base.domain.TestCase;
|
||||
import io.metersphere.base.domain.TestPlanTestCase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class TestPlanCaseBatchRequest extends TestPlanTestCase {
|
||||
|
||||
private List<Integer> ids;
|
||||
|
||||
public List<Integer> getIds() {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public void setIds(List<Integer> ids) {
|
||||
this.ids = ids;
|
||||
}
|
||||
}
|
|
@ -1,16 +1,17 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.EasyExcelFactory;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
|
||||
import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
|
||||
import io.metersphere.excel.domain.ExcelErrData;
|
||||
import io.metersphere.excel.domain.ExcelResponse;
|
||||
import io.metersphere.excel.domain.TestCaseExcelData;
|
||||
|
@ -31,7 +32,6 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -269,4 +269,16 @@ public class TestCaseService {
|
|||
list.add(explain);
|
||||
return list;
|
||||
}
|
||||
|
||||
public void editTestCaseBath(TestCaseBatchRequest request) {
|
||||
TestCaseExample testCaseExample = new TestCaseExample();
|
||||
testCaseExample.createCriteria().andIdIn(request.getIds());
|
||||
|
||||
TestCaseWithBLOBs testCase = new TestCaseWithBLOBs();
|
||||
BeanUtils.copyBean(testCase, request);
|
||||
testCaseMapper.updateByExampleSelective(
|
||||
testCase,
|
||||
testCaseExample);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,10 @@ import io.metersphere.base.mapper.TestPlanTestCaseMapper;
|
|||
import io.metersphere.base.mapper.ext.ExtTestCaseMapper;
|
||||
import io.metersphere.commons.constants.TestPlanTestCaseStatus;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.controller.request.testcase.QueryTestCaseRequest;
|
||||
import io.metersphere.controller.request.testcase.TestCaseBatchRequest;
|
||||
import io.metersphere.controller.request.testcase.TestPlanCaseBatchRequest;
|
||||
import io.metersphere.controller.request.testplancase.QueryTestPlanCaseRequest;
|
||||
import io.metersphere.dto.TestPlanCaseDTO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
|
@ -44,7 +42,7 @@ public class TestPlanTestCaseService {
|
|||
return testPlanTestCaseMapper.deleteByPrimaryKey(id);
|
||||
}
|
||||
|
||||
public void editTestCaseBath(TestCaseBatchRequest request) {
|
||||
public void editTestCaseBath(TestPlanCaseBatchRequest request) {
|
||||
TestPlanTestCaseExample testPlanTestCaseExample = new TestPlanTestCaseExample();
|
||||
testPlanTestCaseExample.createCriteria().andIdIn(request.getIds());
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
@testCaseCopy="copyTestCase"
|
||||
@testCaseDetail="showTestCaseDetail"
|
||||
@refresh="refresh"
|
||||
@moveToNode="moveToNode"
|
||||
ref="testCaseList">
|
||||
</test-case-list>
|
||||
</el-main>
|
||||
|
@ -39,6 +40,9 @@
|
|||
:select-node="selectNode"
|
||||
ref="testCaseEditDialog">
|
||||
</test-case-edit>
|
||||
|
||||
<test-case-move @refresh="refresh" ref="testCaseMove"/>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -49,10 +53,11 @@
|
|||
import {CURRENT_PROJECT} from '../../../../common/js/constants';
|
||||
import TestCaseList from "./components/TestCaseList";
|
||||
import SelectMenu from "../common/SelectMenu";
|
||||
import TestCaseMove from "./components/TestCaseMove";
|
||||
|
||||
export default {
|
||||
name: "TestCase",
|
||||
components: {TestCaseList, NodeTree, TestCaseEdit, SelectMenu},
|
||||
components: {TestCaseMove, TestCaseList, NodeTree, TestCaseEdit, SelectMenu},
|
||||
comments: {},
|
||||
data() {
|
||||
return {
|
||||
|
@ -144,7 +149,6 @@
|
|||
},
|
||||
editTestCase(testCase) {
|
||||
this.testCaseReadOnly = false;
|
||||
console.log(this.selectNode);
|
||||
this.$refs.testCaseEditDialog.open(testCase);
|
||||
},
|
||||
copyTestCase(testCase) {
|
||||
|
@ -203,6 +207,14 @@
|
|||
this.treeNodes = response.data;
|
||||
});
|
||||
}
|
||||
},
|
||||
moveToNode(selectIds) {
|
||||
if (selectIds.size < 1) {
|
||||
this.$warning(this.$t('test_track.plan_view.select_manipulate'));
|
||||
return;
|
||||
}
|
||||
this.$refs.testCaseEditDialog.getModuleOptions();
|
||||
this.$refs.testCaseMove.open(this.$refs.testCaseEditDialog.moduleOptions, selectIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,6 +242,9 @@
|
|||
type: Object
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getSelectOptions();
|
||||
},
|
||||
methods: {
|
||||
open(testCase) {
|
||||
this.resetForm();
|
||||
|
@ -309,7 +312,7 @@
|
|||
param.projectId = JSON.parse(localStorage.getItem(CURRENT_PROJECT)).id;
|
||||
}
|
||||
this.$post('/test/case/' + this.operationType, param, () => {
|
||||
this.$message.success(this.$t('commons.save_success'));
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.dialogFormVisible = false;
|
||||
this.$emit("refresh");
|
||||
});
|
||||
|
|
|
@ -67,23 +67,17 @@
|
|||
this.init();
|
||||
},
|
||||
handleExceed(files, fileList) {
|
||||
this.$message.warning(this.$t('test_track.case.import.upload_limit_count'));
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_count'));
|
||||
},
|
||||
UploadValidate(file) {
|
||||
var suffix =file.name.substring(file.name.lastIndexOf('.') + 1);
|
||||
if (suffix != 'xls' && suffix != 'xlsx') {
|
||||
this.$message({
|
||||
message: this.$t('test_track.case.import.upload_limit_format'),
|
||||
type: 'warning'
|
||||
});
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_format'));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.size / 1024 / 1024 > 20) {
|
||||
this.$message({
|
||||
message: this.$t('test_track.case.import.upload_limit_size'),
|
||||
type: 'warning'
|
||||
});
|
||||
this.$warning(this.$t('test_track.case.import.upload_limit_size'));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -91,7 +85,7 @@
|
|||
handleSuccess(response) {
|
||||
let res = response.data;
|
||||
if (res.success) {
|
||||
this.$message.success(this.$t('test_track.case.import.success'));
|
||||
this.$success(this.$t('test_track.case.import.success'));
|
||||
this.dialogVisible = false;
|
||||
this.$emit("refresh");
|
||||
} else {
|
||||
|
@ -100,7 +94,7 @@
|
|||
this.fileList = [];
|
||||
},
|
||||
handleError(err, file, fileList) {
|
||||
this.$message.error(err.message);
|
||||
this.$error(err.message);
|
||||
},
|
||||
init() {
|
||||
this.fileList = [];
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
</template>
|
||||
<template v-slot:button>
|
||||
<ms-table-button icon="el-icon-upload2" :content="$t('test_track.case.import.import')" @click="importTestCase"/>
|
||||
<!--<ms-table-button icon="el-icon-right" :content="$t('test_track.case.import.import')" @click="dialogVisible = true"/>-->
|
||||
<ms-table-button icon="el-icon-right" :content="$t('test_track.case.move')" @click="moveToNode"/>
|
||||
<!--<test-case-export/>-->
|
||||
</template>
|
||||
</ms-table-header>
|
||||
|
@ -73,7 +73,8 @@
|
|||
<el-table-column
|
||||
prop="updateTime"
|
||||
sortable
|
||||
:label="$t('commons.update_time')">
|
||||
:label="$t('commons.update_time')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
|
@ -213,10 +214,7 @@
|
|||
let testCaseId = testCase.id;
|
||||
this.$post('/test/case/delete/' + testCaseId, {}, () => {
|
||||
this.initTableData();
|
||||
this.$message({
|
||||
message: this.$t('commons.delete_success'),
|
||||
type: 'success'
|
||||
});
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
});
|
||||
},
|
||||
refresh() {
|
||||
|
@ -249,6 +247,9 @@
|
|||
},
|
||||
importTestCase() {
|
||||
this.$refs.testCaseImport.open();
|
||||
},
|
||||
moveToNode() {
|
||||
this.$emit('moveToNode', this.selectIds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
<template>
|
||||
|
||||
<el-dialog :title="$t('test_track.plan_view.change_executor')"
|
||||
:visible.sync="dialogVisible"
|
||||
:before-close="close"
|
||||
width="20%">
|
||||
|
||||
<el-select v-model.trim="module"
|
||||
:placeholder="$t('test_track.plan_view.select_executor')"
|
||||
filterable>
|
||||
<el-option v-for="item in moduleOptions" :key="item.id"
|
||||
:label="item.path" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer
|
||||
@cancel="close"
|
||||
@confirm="save"/>
|
||||
</template>
|
||||
|
||||
|
||||
</el-dialog>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from '../../../common/components/MsDialogFooter';
|
||||
|
||||
export default {
|
||||
name: "TestCaseMove",
|
||||
components: {MsDialogFooter},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
module: '',
|
||||
moduleOptions: [],
|
||||
selectIds: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
save() {
|
||||
if (this.module === '') {
|
||||
this.$warning(this.$t('test_track.plan_view.select_execute_result'));
|
||||
return;
|
||||
}
|
||||
let param = {};
|
||||
param.nodeId = this.module;
|
||||
this.moduleOptions.forEach(item => {
|
||||
if (item.id === this.module) {
|
||||
param.nodePath = item.path;
|
||||
}
|
||||
});
|
||||
|
||||
if (this.module === '') {
|
||||
this.$warning(this.$t('test_track.plan_view.select_executor'));
|
||||
return;
|
||||
}
|
||||
param.ids = [...this.selectIds];
|
||||
this.$post('/test/case/batch/edit' , param, () => {
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.close();
|
||||
this.$emit('refresh');
|
||||
});
|
||||
|
||||
},
|
||||
open(moduleOptions, selectIds) {
|
||||
this.moduleOptions = moduleOptions;
|
||||
this.selectIds = selectIds;
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
close() {
|
||||
this.module = '';
|
||||
this.selectIds = [];
|
||||
this.dialogVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -65,7 +65,7 @@
|
|||
let param = {};
|
||||
let url = this.buildParam(param);
|
||||
this.$post(url, param, () => {
|
||||
this.$message.success(this.$t('commons.save_success'));
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.$emit('refresh');
|
||||
this.close();
|
||||
});
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
const children = parent.data.children || parent.data;
|
||||
const index = children.findIndex(d => d.id === data.id);
|
||||
children.splice(index, 1);
|
||||
this.$message.success(this.$t('commons.delete_success'));
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
this.$emit("refresh");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@
|
|||
Object.assign(param, this.form);
|
||||
param.workspaceId = localStorage.getItem(WORKSPACE_ID);
|
||||
this.$post('/test/plan/' + this.operationType, param, () => {
|
||||
this.$message.success(this.$t('commons.save_success'));
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.dialogFormVisible = false;
|
||||
this.$emit("refresh");
|
||||
});
|
||||
|
@ -165,10 +165,7 @@
|
|||
if (response.success) {
|
||||
this.projects = response.data;
|
||||
} else {
|
||||
this.$message()({
|
||||
type: 'warning',
|
||||
message: response.message
|
||||
});
|
||||
this.$warning()(response.message);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -48,13 +48,15 @@
|
|||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('commons.create_time')">
|
||||
:label="$t('commons.create_time')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('commons.update_time')">
|
||||
:label="$t('commons.update_time')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
|
@ -142,10 +144,7 @@
|
|||
let testPlanId = testPlan.id;
|
||||
this.$post('/test/plan/delete/' + testPlanId, {}, () => {
|
||||
this.initTableData();
|
||||
this.$message({
|
||||
message: this.$t('commons.delete_success'),
|
||||
type: 'success'
|
||||
});
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
});
|
||||
},
|
||||
intoPlan(row, event, column) {
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
this.$post('/test/plan/case/batch/edit' , param, () => {
|
||||
this.executor = '';
|
||||
this.selectIds.clear();
|
||||
this.$message.success(this.$t('commons.save_success'));
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.executorEditVisible = false;
|
||||
this.$emit('refresh');
|
||||
});
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
saveStatus() {
|
||||
let param = {};
|
||||
if (this.status === '') {
|
||||
this.$message.warning(this.$t('test_track.plan_view.select_execute_result'));
|
||||
this.$warning(this.$t('test_track.plan_view.select_execute_result'));
|
||||
return;
|
||||
}
|
||||
param.status = this.status;
|
||||
|
@ -51,7 +51,7 @@
|
|||
this.$post('/test/plan/case/batch/edit' , param, () => {
|
||||
this.selectIds.clear();
|
||||
this.status = '';
|
||||
this.$message.success(this.$t('commons.save_success'));
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.statusEditVisible = false;
|
||||
this.$emit('refresh');
|
||||
});
|
||||
|
|
|
@ -96,7 +96,7 @@
|
|||
param.testCaseIds = [...this.selectIds];
|
||||
this.$post('/test/plan/relevance' , param, () => {
|
||||
this.selectIds.clear();
|
||||
this.$message.success("保存成功");
|
||||
this.$success("保存成功");
|
||||
this.dialogFormVisible = false;
|
||||
this.$emit('refresh');
|
||||
});
|
||||
|
|
|
@ -216,7 +216,7 @@
|
|||
return;
|
||||
}
|
||||
this.$refs.drawer.closeDrawer();
|
||||
this.$message.success(this.$t('commons.save_success'));
|
||||
this.$success(this.$t('commons.save_success'));
|
||||
this.$emit('refresh');
|
||||
});
|
||||
},
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('commons.name')">
|
||||
:label="$t('commons.name')"
|
||||
show-overflow-tooltip>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="priority"
|
||||
|
@ -81,7 +82,8 @@
|
|||
<el-table-column
|
||||
sortable
|
||||
prop="updateTime"
|
||||
:label="$t('commons.update_time')">
|
||||
:label="$t('commons.update_time')"
|
||||
show-overflow-tooltip>
|
||||
<template v-slot:default="scope">
|
||||
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
|
||||
</template>
|
||||
|
@ -230,10 +232,7 @@
|
|||
let testCaseId = testCase.id;
|
||||
this.$post('/test/plan/case/delete/' + testCaseId, {}, () => {
|
||||
this.$emit("refresh");
|
||||
this.$message({
|
||||
message: this.$t('commons.delete_success'),
|
||||
type: 'success'
|
||||
});
|
||||
this.$success(this.$t('commons.delete_success'));
|
||||
});
|
||||
},
|
||||
handleSelectAll(selection) {
|
||||
|
@ -254,7 +253,7 @@
|
|||
},
|
||||
handleBatch(type){
|
||||
if (this.selectIds.size < 1) {
|
||||
this.$message.warning(this.$t('test_track.plan_view.select_manipulate'));
|
||||
this.$warning(this.$t('test_track.plan_view.select_manipulate'));
|
||||
return;
|
||||
}
|
||||
if (type === 'executor'){
|
||||
|
|
|
@ -185,10 +185,11 @@ export default {
|
|||
recent_plan: "Recent plan",
|
||||
recent_case: "Recent case",
|
||||
case: {
|
||||
test_case: "Test Case",
|
||||
test_case: "Test case",
|
||||
move: "Move case",
|
||||
case_list: "Test Case List",
|
||||
create_case: "Create Case",
|
||||
eitd_case: "Eidt Case",
|
||||
edit_case: "Edit Case",
|
||||
no_project: "There is no project in this workspace, please create the project first",
|
||||
priority: "Priority",
|
||||
type: "Type",
|
||||
|
|
|
@ -231,6 +231,7 @@ export default {
|
|||
recent_case: "最近的用例",
|
||||
case: {
|
||||
test_case: "测试用例",
|
||||
move: "移动用例",
|
||||
case_list: "用例列表",
|
||||
create_case: "创建用例",
|
||||
edit_case: "编辑用例",
|
||||
|
|
Loading…
Reference in New Issue