refactor(案例评审,场景): 评审评论可以增加图片、表头操作列增加创建时间并存储上一次的排序方式、场景增加批量复制按钮、负责人将名称和ID位置互换

评审评论可以增加图片、表头操作列增加创建时间并存储上一次的排序方式、场景增加批量复制按钮、负责人将名称和ID位置互换
This commit is contained in:
song-tianyang 2021-06-25 18:12:28 +08:00 committed by 刘瑞斌
parent de4a57b4a8
commit d07153a182
24 changed files with 603 additions and 52 deletions

View File

@ -10,20 +10,16 @@ import io.metersphere.api.service.ApiAutomationService;
import io.metersphere.base.domain.ApiScenario; import io.metersphere.base.domain.ApiScenario;
import io.metersphere.base.domain.ApiScenarioWithBLOBs; import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import io.metersphere.base.domain.Schedule; import io.metersphere.base.domain.Schedule;
import io.metersphere.base.domain.UserGroup;
import io.metersphere.commons.constants.ApiRunMode; import io.metersphere.commons.constants.ApiRunMode;
import io.metersphere.commons.constants.OperLogConstants; import io.metersphere.commons.constants.OperLogConstants;
import io.metersphere.commons.constants.PermissionConstants; import io.metersphere.commons.constants.PermissionConstants;
import io.metersphere.commons.constants.TriggerMode; import io.metersphere.commons.constants.TriggerMode;
import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager; import io.metersphere.commons.utils.Pager;
import io.metersphere.commons.utils.SessionUtils;
import io.metersphere.controller.request.ScheduleRequest; import io.metersphere.controller.request.ScheduleRequest;
import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.log.annotation.MsAuditLog;
import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest; import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest;
import io.metersphere.track.request.testplan.FileOperationRequest; import io.metersphere.track.request.testplan.FileOperationRequest;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -32,9 +28,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
@RestController @RestController
@RequestMapping(value = "/api/automation") @RequestMapping(value = "/api/automation")
@ -251,6 +245,11 @@ public class ApiAutomationController {
public List<JmxInfoDTO> batchGenPerformanceTestJmx(@RequestBody ApiScenarioBatchRequest request) { public List<JmxInfoDTO> batchGenPerformanceTestJmx(@RequestBody ApiScenarioBatchRequest request) {
return apiAutomationService.batchGenPerformanceTestJmx(request); return apiAutomationService.batchGenPerformanceTestJmx(request);
} }
@PostMapping("/batchCopy")
public void batchCopy(@RequestBody ApiScenarioBatchRequest request) {
apiAutomationService.batchCopy(request);
}
@PostMapping("/file/download") @PostMapping("/file/download")
public ResponseEntity<byte[]> download(@RequestBody FileOperationRequest fileOperationRequest) { public ResponseEntity<byte[]> download(@RequestBody FileOperationRequest fileOperationRequest) {

View File

@ -315,6 +315,20 @@ public class ApiAutomationService {
} }
} }
private boolean isCustomNumExist(ApiScenarioWithBLOBs blobs) {
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria()
.andCustomNumEqualTo(blobs.getCustomNum())
.andProjectIdEqualTo(blobs.getProjectId())
.andIdNotEqualTo(blobs.getId());
List<ApiScenario> list = apiScenarioMapper.selectByExample(example);
if (CollectionUtils.isNotEmpty(list)) {
return true;
}else {
return false;
}
}
private int getNextNum(String projectId) { private int getNextNum(String projectId) {
ApiScenario apiScenario = extApiScenarioMapper.getNextNum(projectId); ApiScenario apiScenario = extApiScenarioMapper.getNextNum(projectId);
if (apiScenario == null) { if (apiScenario == null) {
@ -2149,4 +2163,51 @@ public class ApiAutomationService {
return returnList; return returnList;
} }
} }
public void batchCopy(ApiScenarioBatchRequest batchRequest) {
ServiceUtils.getSelectAllIds(batchRequest, batchRequest.getCondition(),
(query) -> extApiScenarioMapper.selectIdsByQuery((ApiScenarioRequest) query));
List<ApiScenarioWithBLOBs> apiScenarioList = extApiScenarioMapper.selectIds(batchRequest.getIds());
for (ApiScenarioWithBLOBs apiModel:apiScenarioList) {
ApiScenarioWithBLOBs newModel = apiModel;
newModel.setId(UUID.randomUUID().toString());
newModel.setName("copy_"+apiModel.getName());
newModel.setCreateTime(System.currentTimeMillis());
newModel.setNum(getNextNum(newModel.getProjectId()));
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andNameEqualTo(newModel.getName()).
andProjectIdEqualTo(newModel.getProjectId()).andStatusNotEqualTo("Trash").andIdNotEqualTo(newModel.getId());
if (apiScenarioMapper.countByExample(example) > 0) {
continue;
}else {
boolean insertFlag = true;
if (StringUtils.isNotBlank(newModel.getCustomNum())) {
insertFlag = false;
String projectId = newModel.getProjectId();
Project project = projectMapper.selectByPrimaryKey(projectId);
if (project != null) {
Boolean customNum = project.getScenarioCustomNum();
// 未开启自定义ID
if (!customNum) {
insertFlag = true;
newModel.setCustomNum(null);
} else {
boolean isCustomNumExist = true;
try {
isCustomNumExist = this.isCustomNumExist(newModel);
}catch (Exception e){}
insertFlag = !isCustomNumExist;
}
}
}
if(insertFlag){
apiScenarioMapper.insert(newModel);
}
}
}
// uploadFiles(request, bodyFiles, scenarioFiles);
}
} }

View File

@ -374,7 +374,6 @@
from api_scenario from api_scenario
left join project on api_scenario.project_id = project.id left join project on api_scenario.project_id = project.id
<include refid="queryWhereCondition"/> <include refid="queryWhereCondition"/>
<include refid="io.metersphere.base.mapper.ext.ExtBaseMapper.orders"/>
</select> </select>
<select id="listReview" resultMap="BaseResultMap"> <select id="listReview" resultMap="BaseResultMap">
select api_scenario.id, api_scenario.project_id, api_scenario.tags, api_scenario.user_id, api_scenario.num, select api_scenario.id, api_scenario.project_id, api_scenario.tags, api_scenario.user_id, api_scenario.num,

View File

@ -714,6 +714,11 @@
"name": "批量创建性能测试", "name": "批量创建性能测试",
"resourceId": "PROJECT_API_SCENARIO" "resourceId": "PROJECT_API_SCENARIO"
}, },
{
"id": "PROJECT_API_SCENARIO:READ+BATCH_COPY",
"name": "批量复制",
"resourceId": "PROJECT_API_SCENARIO"
},
{ {
"id": "PROJECT_API_REPORT:READ", "id": "PROJECT_API_REPORT:READ",
"name": "查询报告", "name": "查询报告",

View File

@ -14,11 +14,12 @@
:batch-operators="buttons" :batch-operators="buttons"
:total="total" :total="total"
:fields.sync="fields" :fields.sync="fields"
field-key="API_SCENARIO" :field-key=tableHeaderKey
operator-width="200" operator-width="200"
@refresh="search(projectId)" @refresh="search(projectId)"
@callBackSelectAll="callBackSelectAll" @callBackSelectAll="callBackSelectAll"
@callBackSelect="callBackSelect" @callBackSelect="callBackSelect"
@saveSortField="saveSortField"
ref="scenarioTable"> ref="scenarioTable">
<span v-for="(item) in fields" :key="item.key"> <span v-for="(item) in fields" :key="item.key">
@ -119,6 +120,17 @@
<span>{{ scope.row.updateTime | timestampFormatDate }}</span> <span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template> </template>
</ms-table-column > </ms-table-column >
<ms-table-column prop="createTime"
:field="item"
:fields-width="fieldsWidth"
:label="$t('commons.create_time')"
sortable
min-width="180px">
<template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template>
</ms-table-column >
<ms-table-column prop="stepTotal" <ms-table-column prop="stepTotal"
:field="item" :field="item"
:fields-width="fieldsWidth" :fields-width="fieldsWidth"
@ -202,7 +214,7 @@ import MsRunMode from "./common/RunMode";
import MsTaskCenter from "../../../task/TaskCenter"; import MsTaskCenter from "../../../task/TaskCenter";
import { import {
getCustomTableHeader, getCustomTableWidth, getCustomTableHeader, getCustomTableWidth,getLastTableSortField,saveLastTableSortField
} from "@/common/js/tableUtils"; } from "@/common/js/tableUtils";
import HeaderCustom from "@/business/components/common/head/HeaderCustom"; import HeaderCustom from "@/business/components/common/head/HeaderCustom";
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate"; import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
@ -275,6 +287,7 @@ export default {
data() { data() {
return { return {
result: {}, result: {},
tableHeaderKey:"API_SCENARIO",
type: API_SCENARIO_LIST, type: API_SCENARIO_LIST,
fields: getCustomTableHeader('API_SCENARIO'), fields: getCustomTableHeader('API_SCENARIO'),
fieldsWidth: getCustomTableWidth('API_SCENARIO'), fieldsWidth: getCustomTableWidth('API_SCENARIO'),
@ -376,6 +389,11 @@ export default {
handleClick: this.batchCreatePerformance, handleClick: this.batchCreatePerformance,
permissions: ['PROJECT_API_SCENARIO:READ+CREATE_PERFORMANCE_BATCH'] permissions: ['PROJECT_API_SCENARIO:READ+CREATE_PERFORMANCE_BATCH']
}, },
{
name: this.$t('api_test.batch_copy'),
handleClick: this.batchCopy,
permissions: ['PROJECT_API_SCENARIO:READ+BATCH_COPY']
},
{ {
name: this.$t('test_track.case.batch_move_case'), name: this.$t('test_track.case.batch_move_case'),
handleClick: this.handleBatchMove, handleClick: this.handleBatchMove,
@ -421,8 +439,13 @@ export default {
this.operators = this.unTrashOperators; this.operators = this.unTrashOperators;
this.buttons = this.unTrashButtons; this.buttons = this.unTrashButtons;
this.condition.filters = {status: ["Prepare", "Underway", "Completed"]}; this.condition.filters = {status: ["Prepare", "Underway", "Completed"]};
let orderArr = this.getSortField();
if(orderArr){
this.condition.orders = orderArr;
}
this.search(); this.search();
this.getPrincipalOptions([]); this.getPrincipalOptions([]);
}, },
watch: { watch: {
selectNodeIds() { selectNodeIds() {
@ -864,6 +887,37 @@ export default {
} }
}); });
}, },
batchCopy(){
this.$alert(this.$t('api_test.definition.request.batch_copy_confirm') + " ", '', {
confirmButtonText: this.$t('commons.confirm'),
callback: (action) => {
if (action === 'confirm') {
this.infoDb = false;
let param = {};
this.buildBatchParam(param);
this.$post('/api/automation/batchCopy', param, response => {
this.$success(this.$t('api_test.definition.request.batch_copy_end'));
this.search();
});
}
}
});
},
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
}
} }
}; };
</script> </script>

View File

@ -14,7 +14,8 @@
:batch-operators="buttons" :batch-operators="buttons"
:screenHeight="screenHeight" :screenHeight="screenHeight"
:fields.sync="fields" :fields.sync="fields"
field-key="API_CASE" :field-key="tableHeaderKey"
@saveSortField="saveSortField"
operator-width="170px" operator-width="170px"
@refresh="initTable" @refresh="initTable"
ref="caseTable" ref="caseTable"
@ -96,6 +97,16 @@
<span>{{ scope.row.updateTime | timestampFormatDate }}</span> <span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template> </template>
</ms-table-column> </ms-table-column>
<ms-table-column prop="createTime"
:field="item"
:fields-width="fieldsWidth"
:label="$t('commons.create_time')"
sortable
min-width="180px">
<template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template>
</ms-table-column >
</span> </span>
<template v-slot:opt-behind="scope"> <template v-slot:opt-behind="scope">
@ -155,7 +166,7 @@ import {
_filter, _filter,
_sort, _sort,
getCustomTableHeader, getCustomTableHeader,
getCustomTableWidth, getCustomTableWidth,saveLastTableSortField,getLastTableSortField
} from "@/common/js/tableUtils"; } from "@/common/js/tableUtils";
import {API_CASE_LIST} from "@/common/js/constants"; import {API_CASE_LIST} from "@/common/js/constants";
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate"; import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
@ -186,6 +197,7 @@ export default {
data() { data() {
return { return {
type: API_CASE_LIST, type: API_CASE_LIST,
tableHeaderKey:"API_CASE",
fields: getCustomTableHeader('API_CASE'), fields: getCustomTableHeader('API_CASE'),
fieldsWidth: getCustomTableWidth('API_CASE'), fieldsWidth: getCustomTableWidth('API_CASE'),
condition: { condition: {
@ -280,6 +292,10 @@ export default {
planId: String planId: String
}, },
created: function () { created: function () {
let orderArr = this.getSortField();
if(orderArr){
this.condition.orders = orderArr;
}
this.initTable(); this.initTable();
// this.$nextTick(() => { // this.$nextTick(() => {
// this.$refs.caseTable.bodyWrapper.scrollTop = 5 // this.$refs.caseTable.bodyWrapper.scrollTop = 5
@ -577,6 +593,21 @@ export default {
column.width = finalWidth; column.width = finalWidth;
column.realWidth = finalWidth; column.realWidth = finalWidth;
}, },
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
},
createPerformance(row, environment) { createPerformance(row, environment) {
/** /**
* 思路调用后台创建性能测试的方法把当前案例的hashTree在后台转化为jmx并文件创建性能测试 * 思路调用后台创建性能测试的方法把当前案例的hashTree在后台转化为jmx并文件创建性能测试

View File

@ -15,7 +15,8 @@
@refresh="initTable" @refresh="initTable"
:fields.sync="fields" :fields.sync="fields"
:table-is-loading="this.result.loading" :table-is-loading="this.result.loading"
field-key="API_DEFINITION" :field-key="tableHeaderKey"
@saveSortField="saveSortField"
ref="table"> ref="table">
<span v-for="(item) in fields" :key="item.key"> <span v-for="(item) in fields" :key="item.key">
@ -114,6 +115,16 @@
<span>{{ scope.row.updateTime | timestampFormatDate }}</span> <span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template> </template>
</ms-table-column> </ms-table-column>
<ms-table-column prop="createTime"
:field="item"
:fields-width="fieldsWidth"
:label="$t('commons.create_time')"
sortable
min-width="180px">
<template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template>
</ms-table-column >
<ms-table-column <ms-table-column
prop="caseTotal" prop="caseTotal"
@ -177,7 +188,8 @@ import MsTipButton from "@/business/components/common/components/MsTipButton";
import CaseBatchMove from "@/business/components/api/definition/components/basis/BatchMove"; import CaseBatchMove from "@/business/components/api/definition/components/basis/BatchMove";
import { import {
initCondition, initCondition,
getCustomTableHeader, getCustomTableWidth, buildBatchParam, checkTableRowIsSelected getCustomTableHeader, getCustomTableWidth, buildBatchParam, checkTableRowIsSelected,
saveLastTableSortField,getLastTableSortField
} from "@/common/js/tableUtils"; } from "@/common/js/tableUtils";
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate"; import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
import {Body} from "@/business/components/api/definition/model/ApiTestModel"; import {Body} from "@/business/components/api/definition/model/ApiTestModel";
@ -209,6 +221,7 @@ export default {
data() { data() {
return { return {
type: API_LIST, type: API_LIST,
tableHeaderKey:"API_DEFINITION",
fields: getCustomTableHeader('API_DEFINITION'), fields: getCustomTableHeader('API_DEFINITION'),
fieldsWidth: getCustomTableWidth('API_DEFINITION'), fieldsWidth: getCustomTableWidth('API_DEFINITION'),
condition: { condition: {
@ -406,6 +419,10 @@ export default {
this.tableOperatorButtons = this.tableUsualOperatorButtons; this.tableOperatorButtons = this.tableUsualOperatorButtons;
this.condition.filters = {status: ["Prepare", "Underway", "Completed"]}; this.condition.filters = {status: ["Prepare", "Underway", "Completed"]};
} }
let orderArr = this.getSortField();
if(orderArr){
this.condition.orders = orderArr;
}
this.initTable(); this.initTable();
this.getMaintainerOptions(); this.getMaintainerOptions();
}, },
@ -794,6 +811,21 @@ export default {
this.$emit('updateInitApiTableOpretion','0'); this.$emit('updateInitApiTableOpretion','0');
return false; return false;
} }
},
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
} }
}, },
}; };

View File

@ -249,6 +249,7 @@ export default {
this.condition.orders = []; this.condition.orders = [];
} }
_sort(column, this.condition); _sort(column, this.condition);
this.$emit("saveSortField", this.fieldKey,this.condition.orders);
this.handleRefresh(); this.handleRefresh();
}, },
handleBatchEdit() { handleBatchEdit() {

View File

@ -136,7 +136,7 @@ import ReportTriggerModeItem from "../../common/tableItem/ReportTriggerModeItem"
import {REPORT_CONFIGS} from "../../common/components/search/search-components"; import {REPORT_CONFIGS} from "../../common/components/search/search-components";
import MsTableHeader from "../../common/components/MsTableHeader"; import MsTableHeader from "../../common/components/MsTableHeader";
import ShowMoreBtn from "../../track/case/components/ShowMoreBtn"; import ShowMoreBtn from "../../track/case/components/ShowMoreBtn";
import {_filter, _sort} from "@/common/js/tableUtils"; import {_filter, _sort,saveLastTableSortField,getLastTableSortField} from "@/common/js/tableUtils";
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter"; import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
import SameTestReports from "@/business/components/performance/report/components/SameTestReports"; import SameTestReports from "@/business/components/performance/report/components/SameTestReports";
@ -160,6 +160,7 @@ export default {
}, },
data() { data() {
return { return {
tableHeaderKey:"PERFORMANCE_REPORT_TABLE",
result: {}, result: {},
deletePath: "/performance/report/delete/", deletePath: "/performance/report/delete/",
condition: { condition: {
@ -250,6 +251,10 @@ export default {
} else { } else {
this.condition.testId = null; this.condition.testId = null;
} }
let orderArr = this.getSortField();
if(orderArr){
this.condition.orders = orderArr;
}
if (!getCurrentProjectID()) { if (!getCurrentProjectID()) {
return; return;
} }
@ -324,7 +329,12 @@ export default {
}); });
}, },
sort(column) { sort(column) {
//
if (this.condition.orders) {
this.condition.orders = [];
}
_sort(column, this.condition); _sort(column, this.condition);
this.saveSortField(this.tableHeaderKey,this.condition.orders);
this.initTableData(); this.initTableData();
}, },
filter(filters) { filter(filters) {
@ -340,6 +350,21 @@ export default {
this.selectRows.add(row); this.selectRows.add(row);
} }
}, },
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
},
handleSelectAll(selection) { handleSelectAll(selection) {
if (selection.length > 0) { if (selection.length > 0) {
this.tableData.forEach(item => { this.tableData.forEach(item => {

View File

@ -101,7 +101,7 @@ import MsTableOperators from "../../common/components/MsTableOperators";
import {getCurrentProjectID, getCurrentWorkspaceId} from "@/common/js/utils"; import {getCurrentProjectID, getCurrentWorkspaceId} from "@/common/js/utils";
import MsTableHeader from "../../common/components/MsTableHeader"; import MsTableHeader from "../../common/components/MsTableHeader";
import {TEST_CONFIGS} from "../../common/components/search/search-components"; import {TEST_CONFIGS} from "../../common/components/search/search-components";
import {_filter, _sort} from "@/common/js/tableUtils"; import {_filter, _sort,saveLastTableSortField,getLastTableSortField} from "@/common/js/tableUtils";
export default { export default {
components: { components: {
@ -115,6 +115,7 @@ export default {
}, },
data() { data() {
return { return {
tableHeaderKey:"PERFORMANCE_TEST_TABLE",
result: {}, result: {},
deletePath: "/performance/delete", deletePath: "/performance/delete",
condition: { condition: {
@ -179,6 +180,10 @@ export default {
}); });
}, },
initTableData() { initTableData() {
let orderArr = this.getSortField();
if(orderArr){
this.condition.orders = orderArr;
}
this.condition.projectId = getCurrentProjectID(); this.condition.projectId = getCurrentProjectID();
this.condition.workspaceId = getCurrentWorkspaceId(); this.condition.workspaceId = getCurrentWorkspaceId();
this.result = this.$post(this.buildPagePath('/performance/list'), this.condition, response => { this.result = this.$post(this.buildPagePath('/performance/list'), this.condition, response => {
@ -234,7 +239,12 @@ export default {
}); });
}, },
sort(column) { sort(column) {
//
if (this.condition.orders) {
this.condition.orders = [];
}
_sort(column, this.condition); _sort(column, this.condition);
this.saveSortField(this.tableHeaderKey,this.condition.orders);
this.initTableData(); this.initTableData();
}, },
filter(filters) { filter(filters) {
@ -257,6 +267,21 @@ export default {
return; return;
} }
this.$router.push('/performance/test/create'); this.$router.push('/performance/test/create');
},
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
} }
} }
}; };

View File

@ -74,7 +74,7 @@
<el-option <el-option
v-for="(item) in memberOptions" v-for="(item) in memberOptions"
:key="item.id" :key="item.id"
:label="item.id + ' (' + item.name + ')'" :label="item.name + ' (' + item.id + ')'"
:value="item.id"> :value="item.id">
</el-option> </el-option>
</el-select> </el-select>

View File

@ -17,8 +17,9 @@
@handlePageChange="initTableData" @handlePageChange="initTableData"
@handleRowClick="handleEdit" @handleRowClick="handleEdit"
:fields.sync="fields" :fields.sync="fields"
field-key="TRACK_TEST_CASE" :field-key="tableHeaderKey"
@refresh="initTableData" @refresh="initTableData"
@saveSortField="saveSortField"
:custom-fields="testCaseTemplate.customFields" :custom-fields="testCaseTemplate.customFields"
ref="table"> ref="table">
@ -102,6 +103,16 @@
<span>{{ scope.row.updateTime | timestampFormatDate }}</span> <span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template> </template>
</ms-table-column> </ms-table-column>
<ms-table-column prop="createTime"
:field="item"
:fields-width="fieldsWidth"
:label="$t('commons.create_time')"
sortable
min-width="150px">
<template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template>
</ms-table-column >
<ms-table-column v-for="field in testCaseTemplate.customFields" :key="field.id" <ms-table-column v-for="field in testCaseTemplate.customFields" :key="field.id"
:filters="field.name === '用例等级' ? priorityFilters : null" :filters="field.name === '用例等级' ? priorityFilters : null"
@ -163,10 +174,10 @@ import {
deepClone, deepClone,
getCustomFieldBatchEditOption, getCustomFieldBatchEditOption,
getCustomFieldValue, getCustomFieldValue,
getCustomTableWidth, getCustomTableWidth, getLastTableSortField,
getPageInfo, getPageInfo,
getTableHeaderWithCustomFields, getTableHeaderWithCustomFields,
initCondition, initCondition, saveLastTableSortField,
} from "@/common/js/tableUtils"; } from "@/common/js/tableUtils";
import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate"; import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate";
import PlanStatusTableItem from "@/business/components/track/common/tableItems/plan/PlanStatusTableItem"; import PlanStatusTableItem from "@/business/components/track/common/tableItems/plan/PlanStatusTableItem";
@ -207,6 +218,7 @@ export default {
data() { data() {
return { return {
type: TEST_CASE_LIST, type: TEST_CASE_LIST,
tableHeaderKey:"TRACK_TEST_CASE",
screenHeight: 'calc(100vh - 310px)', screenHeight: 'calc(100vh - 310px)',
tableLabel: [], tableLabel: [],
deletePath: "/test/case/delete", deletePath: "/test/case/delete",
@ -307,6 +319,10 @@ export default {
created: function () { created: function () {
this.$emit('setCondition', this.condition); this.$emit('setCondition', this.condition);
this.condition.filters = {reviewStatus: ["Prepare", "Pass", "UnPass"]}; this.condition.filters = {reviewStatus: ["Prepare", "Pass", "UnPass"]};
let orderArr = this.getSortField();
if(orderArr){
this.condition.orders = orderArr;
}
this.initTableData(); this.initTableData();
let redirectParam = this.$route.query.dataSelectRange; let redirectParam = this.$route.query.dataSelectRange;
this.checkRedirectEditPage(redirectParam); this.checkRedirectEditPage(redirectParam);
@ -599,6 +615,21 @@ export default {
this.$refs.testBatchMove.close(); this.$refs.testBatchMove.close();
this.refresh(); this.refresh();
}); });
},
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
} }
} }
}; };

View File

@ -20,7 +20,8 @@
:screen-height="screenHeight" :screen-height="screenHeight"
@handlePageChange="getIssues" @handlePageChange="getIssues"
:fields.sync="fields" :fields.sync="fields"
field-key="ISSUE_LIST" :field-key="tableHeaderKey"
@saveSortField="saveSortField"
@refresh="getIssues" @refresh="getIssues"
:custom-fields="issueTemplate.customFields" :custom-fields="issueTemplate.customFields"
ref="table" ref="table"
@ -77,6 +78,17 @@
</span> </span>
</template> </template>
</ms-table-column> </ms-table-column>
<ms-table-column prop="createTime"
:field="item"
:fields-width="fieldsWidth"
:label="$t('commons.create_time')"
sortable
min-width="180px">
<template v-slot:default="scope">
<span>{{ scope.row.createTime | timestampFormatDate }}</span>
</template>
</ms-table-column >
<issue-description-table-item :fields-width="fieldsWidth" :field="item"/> <issue-description-table-item :fields-width="fieldsWidth" :field="item"/>
@ -128,7 +140,7 @@ import {getIssues} from "@/network/Issue";
import { import {
getCustomFieldValue, getCustomFieldValue,
getCustomTableWidth, getCustomTableWidth,
getPageInfo, getTableHeaderWithCustomFields, getPageInfo, getTableHeaderWithCustomFields,saveLastTableSortField,getLastTableSortField
} from "@/common/js/tableUtils"; } from "@/common/js/tableUtils";
import MsContainer from "@/business/components/common/components/MsContainer"; import MsContainer from "@/business/components/common/components/MsContainer";
import MsMainContainer from "@/business/components/common/components/MsMainContainer"; import MsMainContainer from "@/business/components/common/components/MsMainContainer";
@ -150,6 +162,7 @@ export default {
return { return {
page: getPageInfo(), page: getPageInfo(),
fields: [], fields: [],
tableHeaderKey:"ISSUE_LIST",
fieldsWidth: getCustomTableWidth('ISSUE_LIST'), fieldsWidth: getCustomTableWidth('ISSUE_LIST'),
screenHeight: 'calc(100vh - 290px)', screenHeight: 'calc(100vh - 290px)',
operators: [ operators: [
@ -211,6 +224,10 @@ export default {
}, },
getIssues() { getIssues() {
this.page.condition.projectId = this.projectId; this.page.condition.projectId = this.projectId;
let orderArr = this.getSortField();
if(orderArr){
this.page.condition.orders = orderArr;
}
this.page.result = getIssues(this.page); this.page.result = getIssues(this.page);
}, },
handleEdit(data) { handleEdit(data) {
@ -237,6 +254,21 @@ export default {
return false; return false;
} }
return true; return true;
},
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
} }
} }
}; };

View File

@ -239,7 +239,14 @@ import TestReportTemplateList from "../view/comonents/TestReportTemplateList";
import TestCaseReportView from "../view/comonents/report/TestCaseReportView"; import TestCaseReportView from "../view/comonents/report/TestCaseReportView";
import MsDeleteConfirm from "../../../common/components/MsDeleteConfirm"; import MsDeleteConfirm from "../../../common/components/MsDeleteConfirm";
import {TEST_PLAN_CONFIGS} from "../../../common/components/search/search-components"; import {TEST_PLAN_CONFIGS} from "../../../common/components/search/search-components";
import {_filter, _sort, deepClone, getLabel} from "@/common/js/tableUtils"; import {
_filter,
_sort,
deepClone,
getLabel,
getLastTableSortField,
saveLastTableSortField
} from "@/common/js/tableUtils";
import {TEST_PLAN_LIST} from "@/common/js/constants"; import {TEST_PLAN_LIST} from "@/common/js/constants";
import {Test_Plan_List} from "@/business/components/common/model/JsonData"; import {Test_Plan_List} from "@/business/components/common/model/JsonData";
import HeaderCustom from "@/business/components/common/head/HeaderCustom"; import HeaderCustom from "@/business/components/common/head/HeaderCustom";
@ -267,6 +274,7 @@ export default {
createUser: "", createUser: "",
type: TEST_PLAN_LIST, type: TEST_PLAN_LIST,
headerItems: Test_Plan_List, headerItems: Test_Plan_List,
tableHeaderKey:"TEST_PLAN_LIST",
tableLabel: [], tableLabel: [],
result: {}, result: {},
cardResult: {}, cardResult: {},
@ -308,6 +316,10 @@ export default {
this.projectId = getCurrentProjectID(); this.projectId = getCurrentProjectID();
} }
this.hasEditPermission = hasPermission('PROJECT_TRACK_PLAN:READ+EDIT'); this.hasEditPermission = hasPermission('PROJECT_TRACK_PLAN:READ+EDIT');
let orderArr = this.getSortField();
if(orderArr){
this.condition.orders = orderArr;
}
this.initTableData(); this.initTableData();
}, },
methods: { methods: {
@ -412,7 +424,12 @@ export default {
this.initTableData(); this.initTableData();
}, },
sort(column) { sort(column) {
//
if (this.condition.orders) {
this.condition.orders = [];
}
_sort(column, this.condition); _sort(column, this.condition);
this.saveSortField(this.tableHeaderKey,this.condition.orders);
this.initTableData(); this.initTableData();
}, },
openTestReportTemplate(data) { openTestReportTemplate(data) {
@ -427,6 +444,21 @@ export default {
row.redirectFrom = "testPlan"; row.redirectFrom = "testPlan";
this.$refs.scheduleMaintain.open(row); this.$refs.scheduleMaintain.open(row);
}, },
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
}
} }
}; };
</script> </script>

View File

@ -89,7 +89,7 @@ import {
_sort, checkTableRowIsSelect, _sort, checkTableRowIsSelect,
getSelectDataCounts, getSelectDataCounts,
initCondition, initCondition,
setUnSelectIds, toggleAllSelection, setUnSelectIds, toggleAllSelection,saveLastTableSortField,getLastTableSortField
} from "@/common/js/tableUtils"; } from "@/common/js/tableUtils";
import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover"; import MsTableHeaderSelectPopover from "@/business/components/common/components/table/MsTableHeaderSelectPopover";
import {getCurrentProjectID} from "@/common/js/utils"; import {getCurrentProjectID} from "@/common/js/utils";
@ -107,6 +107,7 @@ export default {
return { return {
result: {}, result: {},
enableDeleteTip: false, enableDeleteTip: false,
tableHeaderKey:"TRACK_REPORT_TABLE",
queryPath: "/test/plan/report/list", queryPath: "/test/plan/report/list",
condition: { condition: {
components: TEST_PLAN_REPORT_CONFIGS components: TEST_PLAN_REPORT_CONFIGS
@ -147,11 +148,16 @@ export default {
this.projectId = getCurrentProjectID(); this.projectId = getCurrentProjectID();
} }
this.isTestManagerOrTestUser = true; this.isTestManagerOrTestUser = true;
this.initTableData(); this.initTableData();
}, },
methods: { methods: {
initTableData() { initTableData() {
initCondition(this.condition, this.condition.selectAll); initCondition(this.condition, this.condition.selectAll);
let orderArr = this.getSortField();
if(orderArr){
this.condition.orders = orderArr;
}
this.selectRows = new Set(); this.selectRows = new Set();
if (this.planId) { if (this.planId) {
this.condition.planId = this.planId; this.condition.planId = this.planId;
@ -232,7 +238,12 @@ export default {
this.initTableData(); this.initTableData();
}, },
sort(column) { sort(column) {
//
if (this.condition.orders) {
this.condition.orders = [];
}
_sort(column, this.condition); _sort(column, this.condition);
this.saveSortField(this.tableHeaderKey,this.condition.orders);
this.initTableData(); this.initTableData();
}, },
openReport(planId) { openReport(planId) {
@ -251,6 +262,21 @@ export default {
// //
this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows); this.selectDataCounts = getSelectDataCounts(this.condition, this.total, this.selectRows);
}, },
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
}
} }
} }
</script> </script>

View File

@ -1,8 +1,7 @@
<template> <template>
<div v-loading="result.loading"> <div v-loading="result.loading">
<div class="comment-list"> <div class="comment-list">
<review-comment-item v-for="(comment,index) in comments" <review-comment-item v-for="(comment) in comments" v-bind:key="comment.id"
:key="index"
:comment="comment" :comment="comment"
@refresh="refresh" @refresh="refresh"
:review-status="reviewStatus"/> :review-status="reviewStatus"/>
@ -15,20 +14,10 @@
</div> </div>
</div> </div>
<div> <div>
<el-input <div>
v-permission="['PROJECT_TRACK_REVIEW:READ+COMMENT']" <mavon-editor v-if="showEditor" @imgAdd="imgAdd" :default-open="'edit'" class="mavon-editor" :imageFilter="imageFilter"
ref="test" :toolbars="richDataToolbars" @imgDel="imgDel" v-model="textarea" ref="md"/>
type="textarea" </div>
:placeholder="$t('test_track.comment.send_comment')"
v-model.trim="textarea"
maxlength="180"
show-word-limt
resize="none"
:autosize="{ minRows: 4, maxRows: 4}"
@keyup.ctrl.enter.native="sendComment"
:disabled="isReadOnly"
>
</el-input>
<el-button type="primary" size="mini" class="send-btn" <el-button type="primary" size="mini" class="send-btn"
v-permission="['PROJECT_TRACK_REVIEW:READ+COMMENT']" v-permission="['PROJECT_TRACK_REVIEW:READ+COMMENT']"
@click="sendComment" :disabled="isReadOnly"> @click="sendComment" :disabled="isReadOnly">
@ -40,10 +29,12 @@
<script> <script>
import ReviewCommentItem from "./ReviewCommentItem"; import ReviewCommentItem from "./ReviewCommentItem";
import FormRichTextItem from "@/business/components/track/case/components/FormRichTextItem";
import {getUUID} from "@/common/js/utils";
export default { export default {
name: "ReviewComment", name: "ReviewComment",
components: {ReviewCommentItem}, components: {ReviewCommentItem,FormRichTextItem},
props: { props: {
caseId: String, caseId: String,
comments: Array, comments: Array,
@ -54,12 +45,54 @@ export default {
return { return {
result: {}, result: {},
textarea: '', textarea: '',
isReadOnly: false loadCommenItem:true,
labelWidth: '120px',
showEditor:true,
isReadOnly: false,
richDataToolbars: {
bold: false, //
italic: false, //
header: false, //
underline: false, // 线
strikethrough: false, // 线
mark: false, //
superscript: false, //
subscript: false, //
quote: false, //
ol: false, //
ul: false, //
link: false, //
imagelink: true, //
code: false, // code
table: false, //
fullscreen: false, //
readmodel: false, //
htmlcode: false, // html
help: true, //
/* 1.3.5 */
undo: false, //
redo: false, //
trash: false, //
save: false, // eventssave
/* 1.4.2 */
navigation: false, //
/* 2.1.8 */
alignleft: false, //
aligncenter: false, //
alignright: false, //
/* 2.2.1 */
subfield: false, //
preview: false, //
}
}; };
}, },
created() { created() {
this.isReadOnly = false; this.isReadOnly = false;
}, },
watch:{
comments(){
}
},
methods: { methods: {
sendComment() { sendComment() {
let comment = {}; let comment = {};
@ -74,7 +107,7 @@ export default {
this.result = this.$post('/test/case/comment/save', comment, () => { this.result = this.$post('/test/case/comment/save', comment, () => {
this.$success(this.$t('test_track.comment.send_success')); this.$success(this.$t('test_track.comment.send_success'));
this.refresh(); this.refresh();
this.textarea = ''; this.$refs.md.toolbar_left_click('trash');
}); });
}, },
inputLight() { inputLight() {
@ -83,6 +116,42 @@ export default {
refresh() { refresh() {
this.$emit('getComments'); this.$emit('getComments');
}, },
//
imgAdd(pos, file){
let param = {
id: getUUID().substring(0, 8)
};
file.prefix = param.id;
this.result = this.$fileUpload('/resource/md/upload', file, null, param, () => {
this.$success(this.$t('commons.save_success'));
this.$refs.md.$img2Url(pos, '/resource/md/get/' + param.id+"_"+file.name);
this.sendComment();
});
this.$emit('imgAdd', file);
},
imageFilter(file){
let isImg = false;
if(file){
if(file.name){
if (file.name.indexOf("[")> 0 || file.name.indexOf("]") > 0||file.name.indexOf("([)")> 0 || file.name.indexOf(")") > 0){
this.$error("图片名称不能含有特殊字符");
isImg = false;
}else {
isImg = true;
}
}
}
return isImg;
},
imgDel(file) {
if (file && !this.clearImg) {
this.$get('/resource/md/delete/' + file[1].prefix + "_" + file[1].name);
}
},
alertComment(){
alert(JSON.stringify(this.comments))
}
} }
}; };
</script> </script>
@ -95,6 +164,6 @@ export default {
.comment-list { .comment-list {
overflow-y: scroll; overflow-y: scroll;
height: calc(100vh - 250px); height: calc(100vh - 450px);
} }
</style> </style>

View File

@ -19,13 +19,26 @@
</el-button> </el-button>
</span> </span>
<span class="comment-delete"> <span class="comment-delete">
<el-link icon="el-icon-edit" style="font-size: 9px;margin-right: 6px;" @click="openEdit" :disabled="readOnly"/> <el-link icon="el-icon-edit" v-if="!isImage" style="font-size: 9px;margin-right: 6px;" @click="openEdit" :disabled="readOnly"/>
<el-link icon="el-icon-close" @click="deleteComment" :disabled="readOnly"/> <el-link icon="el-icon-close" @click="deleteComment" :disabled="readOnly"/>
</span> </span>
<br/> <br/>
<div class="comment-desc" style="font-size: 10px;color: #303133"> <!-- <div class="comment-desc" style="font-size: 10px;color: #303133">-->
<!-- <pre>{{ comment.description }}</pre>-->
<!-- </div>-->
<div v-if="!isImage" class="comment-desc" style="font-size: 10px;color: #303133">
<pre>{{ comment.description }}</pre> <pre>{{ comment.description }}</pre>
</div> </div>
<div v-if="isImage" class="demo-image__preview">
<pre>{{ imgDescription }}</pre>
<el-image
:z-index="imageIndex"
style="width: 100px; height: 100px;"
fit="contain"
:src="src"
:preview-src-list="srcList">
</el-image>
</div>
</div> </div>
<el-dialog <el-dialog
@ -68,7 +81,18 @@ export default {
data() { data() {
return { return {
visible: false, visible: false,
description: "" imgDescription: "",
imageIndex:99999,
src:"",
srcList:[],
imgNameList:[],
description: "",
imageMatchPattern:"(\\!\\[)\\S+]\\(\\S+\\)",
}
},
computed:{
isImage(){
return this.checkImage(this.comment.description);
} }
}, },
methods: { methods: {
@ -77,10 +101,15 @@ export default {
this.$warning(this.$t('test_track.comment.cannot_delete')); this.$warning(this.$t('test_track.comment.cannot_delete'));
return; return;
} }
this.$parent.result = this.$get("/test/case/comment/delete/" + this.comment.id, () => { this.$get("/test/case/comment/delete/" + this.comment.id, () => {
this.$success(this.$t('commons.delete_success')); this.$success(this.$t('commons.delete_success'));
this.$emit("refresh"); this.$emit("refresh");
}); });
if(this.imgNameList.length > 0){
this.imgNameList.forEach(imgName => {
this.$get('/resource/md/delete/' + imgName);
});
}
}, },
openEdit() { openEdit() {
if (getCurrentUser().id !== this.comment.author) { if (getCurrentUser().id !== this.comment.author) {
@ -96,7 +125,50 @@ export default {
this.$success(this.$t('commons.modify_success')); this.$success(this.$t('commons.modify_success'));
this.$emit("refresh"); this.$emit("refresh");
}); });
} },
checkImage(){
let param = this.comment.description;
let returnFlag = false;
if(param){
let message = param+"";
let messageSplitArr = message.split("](/resource/md/get/");
let matchIndex = message.indexOf("](/resource/md/get/");
if(matchIndex > 0){
for(let itemIndex = 0;itemIndex < messageSplitArr.length; itemIndex ++){
let itemStr = messageSplitArr[itemIndex];
let picNameIndex = itemStr.indexOf("![");
if( picNameIndex < 0){
let endUrlIndex = itemStr.indexOf(")");
if( endUrlIndex > 0){
let itemStrArr = itemStr.substr(0,endUrlIndex);
//if(imgNameList.)
if(this.imgNameList.indexOf(itemStrArr) < 0){
this.imgNameList.push(itemStrArr);
}
let imgUrl = "/resource/md/get/"+itemStrArr;
this.src = imgUrl;
if(this.srcList.indexOf(itemStrArr) < 0){
this.srcList.push(imgUrl);
}
}
}else{
let inputStr = itemStr.substr(0,picNameIndex);
if(this.imgDescription === ""){
this.imgDescription = inputStr;
}else {
this.imgDescription = "\n" + inputStr;
}
}
}
}
if(this.srcList.length > 0){
returnFlag = true;
}
}
return returnFlag;
},
} }
} }
</script> </script>

View File

@ -126,7 +126,7 @@ import MsTableHeader from "../../../common/components/MsTableHeader";
import MsCreateBox from "../../../settings/CreateBox"; import MsCreateBox from "../../../settings/CreateBox";
import MsTablePagination from "../../../common/pagination/TablePagination"; import MsTablePagination from "../../../common/pagination/TablePagination";
import {getCurrentProjectID, getCurrentWorkspaceId} from "@/common/js/utils"; import {getCurrentProjectID, getCurrentWorkspaceId} from "@/common/js/utils";
import {_filter, _sort, deepClone, getLabel} from "@/common/js/tableUtils"; import {_filter, _sort, deepClone, getLabel, getLastTableSortField,saveLastTableSortField} from "@/common/js/tableUtils";
import PlanStatusTableItem from "../../common/tableItems/plan/PlanStatusTableItem"; import PlanStatusTableItem from "../../common/tableItems/plan/PlanStatusTableItem";
import {Test_Case_Review} from "@/business/components/common/model/JsonData"; import {Test_Case_Review} from "@/business/components/common/model/JsonData";
import {TEST_CASE_REVIEW_LIST} from "@/common/js/constants"; import {TEST_CASE_REVIEW_LIST} from "@/common/js/constants";
@ -154,6 +154,7 @@ export default {
type: TEST_CASE_REVIEW_LIST, type: TEST_CASE_REVIEW_LIST,
headerItems: Test_Case_Review, headerItems: Test_Case_Review,
tableLabel: [], tableLabel: [],
tableHeaderKey:"TEST_CASE_REVIEW",
result: {}, result: {},
condition: {}, condition: {},
tableData: [], tableData: [],
@ -178,6 +179,10 @@ export default {
}, },
created() { created() {
this.isTestManagerOrTestUser = true; this.isTestManagerOrTestUser = true;
let orderArr = this.getSortField();
if(orderArr){
this.condition.orders = orderArr;
}
this.initTableData(); this.initTableData();
}, },
computed: { computed: {
@ -256,9 +261,29 @@ export default {
this.initTableData(); this.initTableData();
}, },
sort(column) { sort(column) {
//
if (this.condition.orders) {
this.condition.orders = [];
}
_sort(column, this.condition); _sort(column, this.condition);
this.saveSortField(this.tableHeaderKey,this.condition.orders);
this.initTableData(); this.initTableData();
}, },
saveSortField(key,orders){
saveLastTableSortField(key,JSON.stringify(orders));
},
getSortField(){
let orderJsonStr = getLastTableSortField(this.tableHeaderKey);
let returnObj = null;
if(orderJsonStr){
try {
returnObj = JSON.parse(orderJsonStr);
}catch (e){
return null;
}
}
return returnObj;
}
} }
}; };
</script> </script>

View File

@ -389,7 +389,11 @@ export default {
id = this.testCase.caseId; id = this.testCase.caseId;
} }
this.result = this.$get('/test/case/comment/list/' + id, res => { this.result = this.$get('/test/case/comment/list/' + id, res => {
this.comments = res.data; if(res.data){
this.comments = null;
this.comments = res.data;
}
}) })
}, },
initData(testCase) { initData(testCase) {

View File

@ -44,7 +44,8 @@ export const CUSTOM_TABLE_HEADER = {
{id: 'caseTotal', key: '8', label: i18n.t('api_test.definition.api_case_number')}, {id: 'caseTotal', key: '8', label: i18n.t('api_test.definition.api_case_number')},
{id: 'caseStatus', key: '9', label: i18n.t('api_test.definition.api_case_status')}, {id: 'caseStatus', key: '9', label: i18n.t('api_test.definition.api_case_status')},
{id: 'casePassingRate', key: 'a', label: i18n.t('api_test.definition.api_case_passing_rate')}, {id: 'casePassingRate', key: 'a', label: i18n.t('api_test.definition.api_case_passing_rate')},
{id: 'status', key: 'b', label: i18n.t('api_test.definition.api_status')} {id: 'status', key: 'b', label: i18n.t('api_test.definition.api_status')},
{id: 'createTime', key: 'c', label: i18n.t('commons.create_time')},
], ],
//接口用例 //接口用例
API_CASE: [ API_CASE: [
@ -56,6 +57,7 @@ export const CUSTOM_TABLE_HEADER = {
{id: 'tags', key: '6', label: i18n.t('commons.tag')}, {id: 'tags', key: '6', label: i18n.t('commons.tag')},
{id: 'createUser', key: '7', label: "创建人"}, {id: 'createUser', key: '7', label: "创建人"},
{id: 'updateTime', key: '8', label: i18n.t('api_test.definition.api_last_time')}, {id: 'updateTime', key: '8', label: i18n.t('api_test.definition.api_last_time')},
{id: 'createTime', key: '9', label: i18n.t('commons.create_time')},
], ],
//场景测试 //场景测试
API_SCENARIO: [ API_SCENARIO: [
@ -70,6 +72,7 @@ export const CUSTOM_TABLE_HEADER = {
{id: 'stepTotal', key: '9', label: i18n.t('api_test.automation.step')}, {id: 'stepTotal', key: '9', label: i18n.t('api_test.automation.step')},
{id: 'lastResult', key: 'a', label: i18n.t('api_test.automation.last_result')}, {id: 'lastResult', key: 'a', label: i18n.t('api_test.automation.last_result')},
{id: 'passRate', key: 'b', label: i18n.t('api_test.automation.passing_rate')}, {id: 'passRate', key: 'b', label: i18n.t('api_test.automation.passing_rate')},
{id: 'createTime', key: 'c', label: i18n.t('commons.create_time')},
], ],
//用例评审 //用例评审
TEST_CASE_REVIEW: [ TEST_CASE_REVIEW: [
@ -171,6 +174,7 @@ export const CUSTOM_TABLE_HEADER = {
{id: 'nodePath', key: '5', label: i18n.t('test_track.case.module')}, {id: 'nodePath', key: '5', label: i18n.t('test_track.case.module')},
{id: 'updateTime', key: '6', label: i18n.t('commons.update_time')}, {id: 'updateTime', key: '6', label: i18n.t('commons.update_time')},
{id: 'createUser', key: '7', label: i18n.t('commons.create_user')}, {id: 'createUser', key: '7', label: i18n.t('commons.create_user')},
{id: 'createTime', key: '8', label: i18n.t('commons.create_time')},
], ],
//缺陷列表 //缺陷列表
ISSUE_LIST: [ ISSUE_LIST: [
@ -181,7 +185,7 @@ export const CUSTOM_TABLE_HEADER = {
{id: 'creatorName', key: '5', label: i18n.t('custom_field.issue_creator')}, {id: 'creatorName', key: '5', label: i18n.t('custom_field.issue_creator')},
{id: 'resourceName', key: '6', label: i18n.t('test_track.issue.issue_resource')}, {id: 'resourceName', key: '6', label: i18n.t('test_track.issue.issue_resource')},
{id: 'description', key: '7', label: i18n.t('test_track.issue.description')}, {id: 'description', key: '7', label: i18n.t('test_track.issue.description')},
{id: 'createTime', key: '8', label: i18n.t('commons.create_time')},
] ]
} }

View File

@ -353,6 +353,21 @@ export function saveCustomTableHeader(key, fields) {
} }
localStorage.setItem(key, result); localStorage.setItem(key, result);
} }
/**
* 将上一次的表格排序字段存在 localStorage
* @param key
* @param fields
*/
export function saveLastTableSortField(key, field) {
let result = field;
localStorage.setItem(key+"_SORT", result);
}
export function getLastTableSortField(key) {
let fieldStr = localStorage.getItem(key+"_SORT");
return fieldStr;
}
/** /**
* 获取对应表格的列宽 * 获取对应表格的列宽

View File

@ -685,6 +685,7 @@ export default {
value: "Value", value: "Value",
create_performance_test: "Create Performance Test", create_performance_test: "Create Performance Test",
create_performance_test_batch: "Batch Create Performance Test", create_performance_test_batch: "Batch Create Performance Test",
batch_copy: "Batch Copy",
export_config: "Export", export_config: "Export",
enable_validate_tip: "No request available", enable_validate_tip: "No request available",
copy: "Copy Test", copy: "Copy Test",
@ -777,6 +778,8 @@ export default {
batch_delete: "Batch deletion", batch_delete: "Batch deletion",
delete_confirm: "Confirm deletion", delete_confirm: "Confirm deletion",
batch_to_performance_confirm: "Confirm Batch Create Performance Test", batch_to_performance_confirm: "Confirm Batch Create Performance Test",
batch_copy_confirm:"Confirm batch copy",
batch_copy_end:"Batch Copy Over",
delete_case_confirm: "Confirm case deletion", delete_case_confirm: "Confirm case deletion",
delete_confirm_step: "Confirm deletion step", delete_confirm_step: "Confirm deletion step",
assertions_rule: "Assertion rule", assertions_rule: "Assertion rule",

View File

@ -684,6 +684,7 @@ export default {
value: "值", value: "值",
create_performance_test: "创建性能测试", create_performance_test: "创建性能测试",
create_performance_test_batch: "批量创建性能测试", create_performance_test_batch: "批量创建性能测试",
batch_copy: "批量复制",
export_config: "导出", export_config: "导出",
enable_validate_tip: "没有可用请求", enable_validate_tip: "没有可用请求",
copy: "复制测试", copy: "复制测试",
@ -777,6 +778,8 @@ export default {
batch_delete: "批量删除", batch_delete: "批量删除",
delete_confirm: "确认删除接口", delete_confirm: "确认删除接口",
batch_to_performance_confirm: "确认批量创建性能测试", batch_to_performance_confirm: "确认批量创建性能测试",
batch_copy_confirm:"确定要进行批量复制吗",
batch_copy_end:"批量复制完成",
delete_case_confirm: "确认删除用例", delete_case_confirm: "确认删除用例",
delete_confirm_step: "确认删除步骤", delete_confirm_step: "确认删除步骤",
assertions_rule: "断言规则", assertions_rule: "断言规则",

View File

@ -684,6 +684,7 @@ export default {
value: "值", value: "值",
create_performance_test: "創建性能測試", create_performance_test: "創建性能測試",
create_performance_test_batch: "批量創建性能測試", create_performance_test_batch: "批量創建性能測試",
batch_copy: "批量複製",
export_config: "導出", export_config: "導出",
enable_validate_tip: "沒有可用請求", enable_validate_tip: "沒有可用請求",
copy: "復制測試", copy: "復制測試",
@ -777,6 +778,8 @@ export default {
batch_delete: "批量刪除", batch_delete: "批量刪除",
delete_confirm: "確認刪除接口", delete_confirm: "確認刪除接口",
batch_to_performance_confirm: "確認批量創建性能測試", batch_to_performance_confirm: "確認批量創建性能測試",
batch_copy_confirm:"確認要進行批量複製嗎",
batch_copy_end:"批量複製完成",
delete_case_confirm: "確認刪除用例", delete_case_confirm: "確認刪除用例",
delete_confirm_step: "確認刪除步驟", delete_confirm_step: "確認刪除步驟",
assertions_rule: "斷言規則", assertions_rule: "斷言規則",