diff --git a/backend/src/main/java/io/metersphere/api/controller/ApiTestCaseController.java b/backend/src/main/java/io/metersphere/api/controller/ApiTestCaseController.java index 5fc824fe7f..3c06c514a1 100644 --- a/backend/src/main/java/io/metersphere/api/controller/ApiTestCaseController.java +++ b/backend/src/main/java/io/metersphere/api/controller/ApiTestCaseController.java @@ -12,6 +12,7 @@ import io.metersphere.commons.constants.NoticeConstants; import io.metersphere.commons.constants.OperLogConstants; import io.metersphere.commons.utils.PageUtils; import io.metersphere.commons.utils.Pager; +import io.metersphere.controller.request.ResetOrderRequest; import io.metersphere.log.annotation.MsAuditLog; import io.metersphere.notice.annotation.SendNotice; import io.metersphere.track.request.testcase.ApiCaseRelevanceRequest; @@ -133,6 +134,11 @@ public class ApiTestCaseController { apiTestCaseService.editApiBathByParam(request); } + @PostMapping("/edit/order") + public void orderCase(@RequestBody ResetOrderRequest request) { + apiTestCaseService.updateOrder(request); + } + @PostMapping("/reduction") @MsAuditLog(module = "api_definition", type = OperLogConstants.RESTORE, beforeEvent = "#msClass.getLogDetails(#request.ids)", content = "#msClass.getLogDetails(#request.ids)", msClass = ApiTestCaseService.class) public List reduction(@RequestBody ApiTestBatchRequest request) { diff --git a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java index e2dd1fdd56..a1acb14b7e 100644 --- a/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java +++ b/backend/src/main/java/io/metersphere/api/service/ApiTestCaseService.java @@ -24,6 +24,8 @@ import io.metersphere.base.mapper.ext.*; import io.metersphere.commons.constants.*; import io.metersphere.commons.exception.MSException; import io.metersphere.commons.utils.*; +import io.metersphere.controller.request.OrderRequest; +import io.metersphere.controller.request.ResetOrderRequest; import io.metersphere.i18n.Translator; import io.metersphere.log.utils.ReflexObjectUtil; import io.metersphere.log.vo.DetailColumn; @@ -102,7 +104,7 @@ public class ApiTestCaseService { } public List list(ApiTestCaseRequest request) { - request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); + initRequest(request, true, false); if (request.getModuleIds() == null && request.getModuleId() != null) { List moduleIds = new ArrayList<>(); moduleIds.add(request.getModuleId()); @@ -145,7 +147,9 @@ public class ApiTestCaseService { */ private ApiTestCaseRequest initRequest(ApiTestCaseRequest request, boolean setDefultOrders, boolean checkThisWeekData) { if (setDefultOrders) { - request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders())); + List orders = ServiceUtils.getDefaultSortOrder(request.getOrders()); + orders.forEach(i -> i.setPrefix("t1")); + request.setOrders(orders); } if (checkThisWeekData) { if (request.isSelectThisWeedData()) { @@ -337,15 +341,14 @@ public class ApiTestCaseService { test.setDescription(request.getDescription()); test.setNum(getNextNum(request.getApiDefinitionId())); test.setFollowPeople(request.getFollowPeople()); + test.setOrder(ServiceUtils.getNextOrder(request.getProjectId(), extApiTestCaseMapper::getLastOrder)); if (StringUtils.equals("[]", request.getTags())) { test.setTags(""); } else { test.setTags(request.getTags()); } ApiTestCaseWithBLOBs apiTestCaseWithBLOBs = apiTestCaseMapper.selectByPrimaryKey(test.getId()); - if (apiTestCaseWithBLOBs != null) { - apiTestCaseMapper.updateByPrimaryKey(apiTestCaseWithBLOBs); - } else { + if (apiTestCaseWithBLOBs == null) { apiTestCaseMapper.insert(test); } return test; @@ -1018,4 +1021,22 @@ public class ApiTestCaseService { } return new ArrayList<>(); } + + public void initOrderField() { + ServiceUtils.initOrderField(ApiTestCaseWithBLOBs.class, ApiTestCaseMapper.class, + extApiTestCaseMapper::selectProjectIds, + extApiTestCaseMapper::getIdsOrderByCreateTime); + } + + /** + * 用例自定义排序 + * @param request + */ + public void updateOrder(ResetOrderRequest request) { + ServiceUtils.updateOrderField(request, ApiTestCaseWithBLOBs.class, + apiTestCaseMapper::selectByPrimaryKey, + extApiTestCaseMapper::getPreOrder, + extApiTestCaseMapper::getLastOrder, + apiTestCaseMapper::updateByPrimaryKeySelective); + } } diff --git a/backend/src/main/java/io/metersphere/base/domain/ApiTestCase.java b/backend/src/main/java/io/metersphere/base/domain/ApiTestCase.java index 0cbace102a..716c47c712 100644 --- a/backend/src/main/java/io/metersphere/base/domain/ApiTestCase.java +++ b/backend/src/main/java/io/metersphere/base/domain/ApiTestCase.java @@ -41,5 +41,7 @@ public class ApiTestCase implements Serializable { private String followPeople; + private Long order; + private static final long serialVersionUID = 1L; -} \ No newline at end of file +} diff --git a/backend/src/main/java/io/metersphere/base/domain/ApiTestCaseExample.java b/backend/src/main/java/io/metersphere/base/domain/ApiTestCaseExample.java index 92dee67719..c42e6e9912 100644 --- a/backend/src/main/java/io/metersphere/base/domain/ApiTestCaseExample.java +++ b/backend/src/main/java/io/metersphere/base/domain/ApiTestCaseExample.java @@ -1313,6 +1313,66 @@ public class ApiTestCaseExample { addCriterion("follow_people not between", value1, value2, "followPeople"); return (Criteria) this; } + + public Criteria andOrderIsNull() { + addCriterion("`order` is null"); + return (Criteria) this; + } + + public Criteria andOrderIsNotNull() { + addCriterion("`order` is not null"); + return (Criteria) this; + } + + public Criteria andOrderEqualTo(Long value) { + addCriterion("`order` =", value, "order"); + return (Criteria) this; + } + + public Criteria andOrderNotEqualTo(Long value) { + addCriterion("`order` <>", value, "order"); + return (Criteria) this; + } + + public Criteria andOrderGreaterThan(Long value) { + addCriterion("`order` >", value, "order"); + return (Criteria) this; + } + + public Criteria andOrderGreaterThanOrEqualTo(Long value) { + addCriterion("`order` >=", value, "order"); + return (Criteria) this; + } + + public Criteria andOrderLessThan(Long value) { + addCriterion("`order` <", value, "order"); + return (Criteria) this; + } + + public Criteria andOrderLessThanOrEqualTo(Long value) { + addCriterion("`order` <=", value, "order"); + return (Criteria) this; + } + + public Criteria andOrderIn(List values) { + addCriterion("`order` in", values, "order"); + return (Criteria) this; + } + + public Criteria andOrderNotIn(List values) { + addCriterion("`order` not in", values, "order"); + return (Criteria) this; + } + + public Criteria andOrderBetween(Long value1, Long value2) { + addCriterion("`order` between", value1, value2, "order"); + return (Criteria) this; + } + + public Criteria andOrderNotBetween(Long value1, Long value2) { + addCriterion("`order` not between", value1, value2, "order"); + return (Criteria) this; + } } public static class Criteria extends GeneratedCriteria { @@ -1407,4 +1467,4 @@ public class ApiTestCaseExample { this(condition, value, secondValue, null); } } -} \ No newline at end of file +} diff --git a/backend/src/main/java/io/metersphere/base/mapper/ApiTestCaseMapper.xml b/backend/src/main/java/io/metersphere/base/mapper/ApiTestCaseMapper.xml index 53252cc80a..1ca34f16dc 100644 --- a/backend/src/main/java/io/metersphere/base/mapper/ApiTestCaseMapper.xml +++ b/backend/src/main/java/io/metersphere/base/mapper/ApiTestCaseMapper.xml @@ -20,6 +20,7 @@ + @@ -84,9 +85,9 @@ - id, project_id, `name`, priority, api_definition_id, create_user_id, update_user_id, - create_time, update_time, num, tags, last_result_id, `status`, original_status, delete_time, - delete_user_id, version, follow_people + id, project_id, `name`, priority, api_definition_id, create_user_id, update_user_id, + create_time, update_time, num, tags, last_result_id, `status`, original_status, delete_time, + delete_user_id, version, follow_people, `order` description, request @@ -122,7 +123,7 @@ + + + + update api_test_case diff --git a/backend/src/main/java/io/metersphere/commons/utils/ServiceUtils.java b/backend/src/main/java/io/metersphere/commons/utils/ServiceUtils.java index 5c46ddbfe1..06edb1328c 100644 --- a/backend/src/main/java/io/metersphere/commons/utils/ServiceUtils.java +++ b/backend/src/main/java/io/metersphere/commons/utils/ServiceUtils.java @@ -209,4 +209,15 @@ public class ServiceUtils { MSException.throwException("更新 order 字段失败"); } } + + /** + * 创建时获取下一个 order 值 + * @param projectId + * @param getLastOrderFunc + * @return + */ + public static Long getNextOrder(String projectId, BiFunction getLastOrderFunc) { + Long lastOrder = getLastOrderFunc.apply(projectId, null); + return (lastOrder == null ? 0 : lastOrder) + 5000; + } } diff --git a/backend/src/main/java/io/metersphere/listener/AppStartListener.java b/backend/src/main/java/io/metersphere/listener/AppStartListener.java index 0d468e4a67..9a639158a6 100644 --- a/backend/src/main/java/io/metersphere/listener/AppStartListener.java +++ b/backend/src/main/java/io/metersphere/listener/AppStartListener.java @@ -3,6 +3,7 @@ package io.metersphere.listener; import io.metersphere.api.jmeter.JMeterService; import io.metersphere.api.jmeter.NewDriverManager; import io.metersphere.api.service.ApiAutomationService; +import io.metersphere.api.service.ApiTestCaseService; import io.metersphere.base.domain.JarConfig; import io.metersphere.commons.utils.LogUtil; import io.metersphere.commons.utils.RunInterface; @@ -48,6 +49,8 @@ public class AppStartListener implements ApplicationListener + @@ -213,12 +216,13 @@ import { _filter, _sort, getCustomTableHeader, - getCustomTableWidth, getLastTableSortField + getCustomTableWidth, getLastTableSortField, handleRowDrop } from "@/common/js/tableUtils"; import {API_CASE_LIST} from "@/common/js/constants"; import HeaderLabelOperate from "@/business/components/common/head/HeaderLabelOperate"; import ApiCaseBatchRun from "@/business/components/api/definition/components/list/ApiCaseBatchRun"; import MsRequestResultTail from "../../../../api/definition/components/response/RequestResultTail"; +import {editApiTestCaseOrder} from "@/network/api"; export default { name: "ApiCaseSimpleList", @@ -260,6 +264,7 @@ export default { selectDataRange: "all", clickRow: {}, buttons: [], + enableOrderDrag: true, simpleButtons: [ {name: this.$t('api_test.definition.request.batch_delete'), handleClick: this.handleDeleteToGcBatch}, {name: this.$t('api_test.definition.request.batch_edit'), handleClick: this.handleEditBatch}, @@ -374,8 +379,6 @@ export default { planId: String }, created: function () { - this.condition.orders = getLastTableSortField(this.tableHeaderKey); - if (this.trashEnable) { this.operators = this.trashOperators; this.buttons = this.trashButtons; @@ -493,12 +496,16 @@ export default { if (this.$refs.caseTable) { this.$refs.caseTable.clearSelectRows(); } + this.condition.orders = getLastTableSortField(this.tableHeaderKey); if (this.condition.orders) { const index = this.condition.orders.findIndex(d => d.name && d.name === 'case_path'); if (index !== -1) { this.condition.orders.splice(index, 1); } } + + this.enableOrderDrag = this.condition.orders.length > 0 ? false : true; + if (this.apiDefinitionId) { this.condition.apiDefinitionId = this.apiDefinitionId; } @@ -564,6 +571,12 @@ export default { } }) this.$nextTick(function () { + + handleRowDrop(this.tableData, (param) => { + param.projectId = this.condition.projectId; + editApiTestCaseOrder(param); + }); + if (this.$refs.caseTable) { this.$refs.caseTable.doLayout(); this.$refs.caseTable.checkTableRowIsSelect(); diff --git a/frontend/src/business/components/track/case/components/TestCaseList.vue b/frontend/src/business/components/track/case/components/TestCaseList.vue index 5008211c9e..cd220be814 100644 --- a/frontend/src/business/components/track/case/components/TestCaseList.vue +++ b/frontend/src/business/components/track/case/components/TestCaseList.vue @@ -518,10 +518,9 @@ export default { //initCondition(this.condition); initCondition(this.condition, this.condition.selectAll); this.condition.orders = getLastTableSortField(this.tableHeaderKey); - this.enableOrderDrag = true; - if (this.condition.orders.length > 0) { - this.enableOrderDrag = false; - } + + this.enableOrderDrag = this.condition.orders.length > 0 ? false : true; + if (this.planId) { // param.planId = this.planId; this.condition.planId = this.planId; diff --git a/frontend/src/network/api.js b/frontend/src/network/api.js index b51f3224dd..ef3fad82ac 100644 --- a/frontend/src/network/api.js +++ b/frontend/src/network/api.js @@ -1,6 +1,6 @@ import {post} from "@/common/js/ajax"; import {success} from "@/common/js/message"; -import {baseGet} from "@/network/base-network"; +import {baseGet, basePost} from "@/network/base-network"; export function apiCaseBatchRun(condition) { return post('/api/testcase/batch/run', condition, () => { @@ -25,3 +25,6 @@ export function getShareScenarioReport(shareId, reportId, callback) { } +export function editApiTestCaseOrder(request, callback) { + return basePost('/api/testcase/edit/order', request, callback); +}