feat(项目设置): 补充待更新其他功能

--user=郭雨琦
This commit is contained in:
guoyuqi 2022-07-18 23:13:34 +08:00 committed by xiaomeinvG
parent 6a8065853e
commit b9061856e2
9 changed files with 150 additions and 14 deletions

View File

@ -273,7 +273,7 @@ public class ApiDefinitionController {
@RequiresPermissions(PermissionConstants.PROJECT_API_DEFINITION_READ_EDIT_API)
@MsAuditLog(module = OperLogModule.API_DEFINITION, type = OperLogConstants.BATCH_UPDATE, beforeEvent = "#msClass.getLogDetails(#request)", content = "#msClass.getLogDetails(#request)", msClass = ApiDefinitionService.class)
@SendNotice(taskType = NoticeConstants.TaskType.API_DEFINITION_TASK, event = NoticeConstants.Event.UPDATE, target = "#targetClass.getBLOBs(#request.ids)", targetClass = ApiDefinitionService.class,
subject = "接口定义通知")
subject = "接口定义通知")
public void editByParams(@RequestBody ApiBatchRequest request) {
apiDefinitionService.editApiByParam(request);
}
@ -357,6 +357,12 @@ public class ApiDefinitionController {
apiDefinitionService.saveFollows(definitionId, follows);
}
@PostMapping("/delete/follows/batch")
public void deleteFollows(@RequestBody List<String> definitionIds) {
apiDefinitionService.deleteFollows(definitionIds);
}
@GetMapping("/getWorkerQueue")
public String getWorkerQueue() {
return execThreadPoolExecutor.getWorkerQueue();

View File

@ -1,8 +1,8 @@
package io.metersphere.api.dto.definition;
import io.metersphere.plugin.core.MsTestElement;
import io.metersphere.api.dto.definition.response.Response;
import io.metersphere.base.domain.Schedule;
import io.metersphere.plugin.core.MsTestElement;
import lombok.Getter;
import lombok.Setter;
@ -71,4 +71,7 @@ public class SaveApiDefinitionRequest {
//是否进入待更新列表
private Boolean toBeUpdated;
//同步的内容
private String triggerUpdate;
}

View File

@ -0,0 +1,8 @@
package io.metersphere.api.service;
import io.metersphere.api.dto.definition.ApiSyncCaseRequest;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs;
public interface ApiCaseBatchSyncService {
void oneClickSyncCase(ApiSyncCaseRequest apiSyncCaseRequest, ApiDefinitionWithBLOBs apiDefinitionWithBLOBs);
}

View File

@ -368,13 +368,25 @@ public class ApiDefinitionService {
if (StringUtils.equals(request.getProtocol(), "DUBBO")) {
request.setMethod("dubbo://");
}
// 存储依赖关系
ApiDefinitionSyncService apiDefinitionSyncService = CommonBeanFactory.getBean(ApiDefinitionSyncService.class);
if (apiDefinitionSyncService != null) {
apiDefinitionSyncService.syncApi(request);
if (StringUtils.isBlank(request.getTriggerUpdate())) {
// 设置是否需要进入待更新列表
ApiDefinitionSyncService apiDefinitionSyncService = CommonBeanFactory.getBean(ApiDefinitionSyncService.class);
if (apiDefinitionSyncService != null) {
apiDefinitionSyncService.syncApi(request);
}
}
ApiDefinitionWithBLOBs returnModel = updateTest(request);
if (StringUtils.isNotBlank(request.getTriggerUpdate())) {
//一键同步case
ApiSyncCaseRequest apiSyncCaseRequest = JSONObject.parseObject(request.getTriggerUpdate(), ApiSyncCaseRequest.class);
ApiCaseBatchSyncService apiCaseSyncService = CommonBeanFactory.getBean(ApiCaseBatchSyncService.class);
if (apiCaseSyncService != null) {
apiCaseSyncService.oneClickSyncCase(apiSyncCaseRequest, returnModel);
}
}
MockConfigService mockConfigService = CommonBeanFactory.getBean(MockConfigService.class);
mockConfigService.updateMockReturnMsgByApi(returnModel);
FileUtils.createBodyFiles(request.getRequest().getId(), bodyFiles);
@ -614,9 +626,11 @@ public class ApiDefinitionService {
test.setEnvironmentId(request.getEnvironmentId());
test.setUserId(request.getUserId());
test.setRemark(request.getRemark());
if (request.getToBeUpdated() != null && request.getToBeUpdated()) {
if (request.getToBeUpdated() != null) {
test.setToBeUpdated(request.getToBeUpdated());
test.setToBeUpdateTime(System.currentTimeMillis());
if (request.getToBeUpdated()) {
test.setToBeUpdateTime(System.currentTimeMillis());
}
}
if (StringUtils.isNotEmpty(request.getTags()) && !StringUtils.equals(request.getTags(), "[]")) {
test.setTags(request.getTags());
@ -2583,4 +2597,12 @@ public class ApiDefinitionService {
relationshipEdgeService.saveBatch(request);
}
}
public void deleteFollows(List<String> definitionIds) {
if (CollectionUtils.isNotEmpty(definitionIds)) {
ApiDefinitionFollowExample example = new ApiDefinitionFollowExample();
example.createCriteria().andDefinitionIdIn(definitionIds);
apiDefinitionFollowMapper.deleteByExample(example);
}
}
}

View File

@ -181,6 +181,24 @@
</ms-dialog-footer>
</template>
</el-dialog>
<el-dialog :visible.sync="batchSyncApiVisible" :title="$t('commons.save')+$t('commons.setting')">
<el-row style="margin-bottom: 10px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1)">
<div class="timeClass">
<span>{{ $t('api_test.definition.one_click_sync') + "case" }}</span>
<el-switch v-model="syncCases"></el-switch>
</div>
<span>{{ $t('workstation.batch_sync_api_tips') }}</span>
</el-row>
<span v-if="syncCases">{{ $t('workstation.sync') + $t('commons.setting') }}</span><br/>
<sync-settings v-if="syncCases" ref="synSetting"></sync-settings>
<span slot="footer" class="dialog-footer">
<el-button @click="batchSyncApiVisible = false"> </el-button>
<el-button type="primary" @click="batchSync()"> </el-button>
</span>
</el-dialog>
</div>
</template>
@ -202,6 +220,7 @@ import {createComponent} from ".././jmeter/components";
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
import {getProjectMemberOption} from "@/network/user";
import SyncSettings from "@/business/components/xpack/workstation/component/SyncSettings";
const {Body} = require("@/business/components/api/definition/model/ApiTestModel");
const Sampler = require("@/business/components/api/definition/components/jmeter/components/sampler/sampler");
@ -217,7 +236,7 @@ export default {
ApiOtherInfo,
MsFormDivider,
MsJsr233Processor, MsResponseText, MsApiRequestForm, MsInputTag, MsSelectTree, MsChangeHistory,
HttpApiVersionDiff
HttpApiVersionDiff, SyncSettings,
},
data() {
let validateURL = (rule, value, callback) => {
@ -269,6 +288,8 @@ export default {
newRequest: Sampler,
newResponse: {},
createNewVersionVisible: false,
batchSyncApiVisible: false,
syncCases: true,
};
},
props: {moduleOptions: {}, request: {}, response: {}, basisData: {}, syncTabs: Array, projectId: String},
@ -473,7 +494,11 @@ export default {
this.httpForm.versionId = this.$refs.versionHistory.currentVersion.id;
}
}
this.$emit('saveApi', this.httpForm);
if (hasLicense() && this.httpForm.caseTotal > 0) {
this.batchSyncApiVisible = true;
} else {
this.$emit('saveApi', this.httpForm);
}
this.count = 0;
this.$store.state.apiStatus.set("fromChange", false);
this.$store.state.apiMap.set(this.httpForm.id, this.$store.state.apiStatus);
@ -485,6 +510,15 @@ export default {
}
});
},
batchSync() {
if (hasLicense() && this.httpForm.caseTotal > 0) {
if (this.$refs.synSetting && this.$refs.synSetting.fromData) {
let fromData = this.$refs.synSetting.fromData;
this.httpForm.triggerUpdate = JSON.stringify(fromData);
}
this.$emit('saveApi', this.httpForm);
}
},
createModules() {
this.$emit("createRootModelInTree");
},
@ -768,6 +802,11 @@ export default {
</script>
<style scoped>
.timeClass {
display: flex;
flex-direction: row;
justify-content: space-between;
}
.base-info .el-form-item {
width: 100%;

View File

@ -248,6 +248,16 @@
:visible.sync="resVisible" class="api-import" destroy-on-close @close="resVisible=false">
<ms-request-result-tail :response="response" ref="debugResult"/>
</el-dialog>
<el-dialog :visible.sync="batchSyncCaseVisible" :title="$t('commons.batch')+$t('workstation.sync')">
<span>{{ $t('workstation.sync') + $t('commons.setting') }}</span><br/>
<sync-settings ref="synSetting"></sync-settings>
<span style="color: red">{{ $t('workstation.batch_sync_api_tips') }}</span>
<span slot="footer" class="dialog-footer">
<el-button @click="batchSyncCaseVisible = false"> </el-button>
<el-button type="primary" @click="batchSync()"> </el-button>
</span>
</el-dialog>
</span>
</template>
@ -297,6 +307,7 @@ import {editApiTestCaseOrder} from "@/network/api";
import {TYPE_TO_C} from "@/business/components/api/automation/scenario/Setting";
import i18n from "@/i18n/i18n";
import MsSearch from "@/business/components/common/components/search/MsSearch";
import SyncSettings from "@/business/components/xpack/workstation/component/SyncSettings";
export default {
name: "ApiCaseSimpleList",
@ -324,6 +335,7 @@ export default {
MsRequestResultTail,
MsApiCaseRunModeWithEnv,
MsSearch,
SyncSettings,
PlanStatusTableItem: () => import("../../../../track/common/tableItems/plan/PlanStatusTableItem"),
MsTaskCenter: () => import("@/business/components/task/TaskCenter"),
},
@ -360,6 +372,28 @@ export default {
permissions: ['PROJECT_API_DEFINITION:READ+RUN']
},
],
batchButtons: [
{
name: this.$t('api_test.definition.request.batch_delete'),
handleClick: this.handleDeleteToGcBatch,
permissions: ['PROJECT_API_DEFINITION:READ+DELETE_CASE']
},
{
name: this.$t('api_test.definition.request.batch_edit'),
handleClick: this.handleEditBatch,
permissions: ['PROJECT_API_DEFINITION:READ+EDIT_CASE']
},
{
name: this.$t('api_test.automation.batch_execute'),
handleClick: this.handleRunBatch,
permissions: ['PROJECT_API_DEFINITION:READ+RUN']
},
{
name: this.$t('commons.batch') + this.$t('workstation.sync'),
handleClick: this.openBatchSync,
permissions: ['PROJECT_TRACK_PLAN:READ+SCHEDULE']
},
],
trashButtons: [
{
name: this.$t('commons.reduction'),
@ -459,6 +493,7 @@ export default {
versionEnable: false,
userFilters: [],
environmentsFilters: [],
batchSyncCaseVisible: false,
};
},
props: {
@ -499,7 +534,12 @@ export default {
this.buttons = this.trashButtons;
} else {
this.operators = this.simpleOperators;
this.buttons = this.simpleButtons;
if (hasLicense()) {
this.buttons = this.batchButtons;
} else {
this.buttons = this.simpleButtons;
}
}
// tab
this.condition.versionId = this.currentVersion;
@ -1016,6 +1056,21 @@ export default {
this.initTable();
});
},
openBatchSync() {
this.batchSyncCaseVisible = true;
},
batchSync() {
let selectIds = this.$refs.caseTable.selectIds;
let fromData = this.$refs.synSetting.fromData;
fromData.ids = selectIds;
if (hasLicense()) {
this.$post('/api/sync/case/batch', fromData, response => {
this.batchSyncCaseVisible = false;
this.$message.success("success");
this.initTable();
});
}
},
handleDelete(apiCase) {
this.$alert(this.$t('api_test.definition.request.delete_case_confirm') + ' ' + apiCase.name + " ", '', {
confirmButtonText: this.$t('commons.confirm'),

View File

@ -1242,6 +1242,7 @@ export default {
api_import: "Api Import",
check_select: "Please check the API",
api_project: "Project",
one_click_sync: "One-click sync",
select_comp: {
no_data: "No Data",
add_data: "Add Data"
@ -1506,7 +1507,7 @@ export default {
base_url: "Base URL",
base_url_description: "Base URL as URL prefix for all requests",
scenario_step_is_empty: "Scenario: {0} has none step!",
base_scenario_step_is_empty:"Scenario step is empty!",
base_scenario_step_is_empty: "Scenario step is empty!",
url_invalid: "Invalid URL",
variables: "Variables",
headers: "Headers",

View File

@ -1251,6 +1251,7 @@ export default {
api_import: "接口导入",
check_select: "请勾选接口",
api_project: "所属项目",
one_click_sync: "一键同步",
select_comp: {
no_data: "无数据",
add_data: "去添加"
@ -1514,7 +1515,7 @@ export default {
base_url: "基础URL",
base_url_description: "基础URL作为所有请求的URL前缀",
scenario_step_is_empty: "场景: {0} 的步骤为空,无法导入",
base_scenario_step_is_empty:"原场景步骤为空",
base_scenario_step_is_empty: "原场景步骤为空",
variables: "自定义变量",
headers: "请求头",
kv_description: "所有请求可以使用自定义变量",

View File

@ -1248,6 +1248,7 @@ export default {
api_import: "接口導入",
check_select: "請勾選接口",
api_project: "所屬項目",
one_click_sync: "一鍵同步",
select_comp: {
no_data: "無數據",
add_data: "去添加"
@ -1511,7 +1512,7 @@ export default {
base_url: "基礎URL",
base_url_description: "基礎URL作為所有請求的URL前綴",
scenario_step_is_empty: "場景: {0} 的步驟為空,無法導入",
base_scenario_step_is_empty:"原場景步驟為空",
base_scenario_step_is_empty: "原場景步驟為空",
variables: "自定義變量",
headers: "請求頭",
kv_description: "所有請求可以使用自定義變量",