feat(项目设置): 新增消息通知类型-mock

https://www.tapd.cn/55049933/prong/stories/view/1155049933001009922
--user=郭雨琦
This commit is contained in:
guoyuqi 2022-10-24 16:41:09 +08:00 committed by 刘瑞斌
parent d1cb9f5e5c
commit e3fbe59afb
10 changed files with 199 additions and 6 deletions

View File

@ -8,8 +8,10 @@ import io.metersphere.api.dto.mock.config.MockConfigRequest;
import io.metersphere.api.dto.mock.config.MockExpectConfigRequest; import io.metersphere.api.dto.mock.config.MockExpectConfigRequest;
import io.metersphere.api.dto.mock.config.response.MockConfigResponse; import io.metersphere.api.dto.mock.config.response.MockConfigResponse;
import io.metersphere.api.dto.mock.config.response.MockExpectConfigResponse; import io.metersphere.api.dto.mock.config.response.MockExpectConfigResponse;
import io.metersphere.commons.constants.NoticeConstants;
import io.metersphere.commons.utils.mock.MockApiUtils; import io.metersphere.commons.utils.mock.MockApiUtils;
import io.metersphere.commons.utils.mock.MockTestDataUtil; import io.metersphere.commons.utils.mock.MockTestDataUtil;
import io.metersphere.notice.annotation.SendNotice;
import io.metersphere.service.definition.ApiDefinitionService; import io.metersphere.service.definition.ApiDefinitionService;
import io.metersphere.service.MockConfigService; import io.metersphere.service.MockConfigService;
import io.metersphere.base.domain.ApiDefinitionWithBLOBs; import io.metersphere.base.domain.ApiDefinitionWithBLOBs;

View File

@ -13,11 +13,9 @@ import io.metersphere.api.parse.api.ApiDefinitionImport;
import io.metersphere.api.parse.scenario.TcpTreeTableDataParser; import io.metersphere.api.parse.scenario.TcpTreeTableDataParser;
import io.metersphere.api.tcp.TCPPool; import io.metersphere.api.tcp.TCPPool;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.MockConfigMapper; import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.MockExpectConfigMapper;
import io.metersphere.base.mapper.ProjectApplicationMapper;
import io.metersphere.base.mapper.ProjectMapper;
import io.metersphere.base.mapper.ext.ExtMockExpectConfigMapper; import io.metersphere.base.mapper.ext.ExtMockExpectConfigMapper;
import io.metersphere.commons.constants.NoticeConstants;
import io.metersphere.commons.constants.ProjectApplicationType; import io.metersphere.commons.constants.ProjectApplicationType;
import io.metersphere.commons.constants.PropertyConstant; import io.metersphere.commons.constants.PropertyConstant;
import io.metersphere.commons.exception.MSException; import io.metersphere.commons.exception.MSException;
@ -26,6 +24,8 @@ import io.metersphere.commons.utils.mock.MockApiUtils;
import io.metersphere.dto.ProjectConfig; import io.metersphere.dto.ProjectConfig;
import io.metersphere.environment.service.BaseEnvironmentService; import io.metersphere.environment.service.BaseEnvironmentService;
import io.metersphere.i18n.Translator; import io.metersphere.i18n.Translator;
import io.metersphere.notice.sender.NoticeModel;
import io.metersphere.notice.service.NoticeSendService;
import io.metersphere.service.definition.ApiDefinitionService; import io.metersphere.service.definition.ApiDefinitionService;
import io.metersphere.service.ext.ExtProjectApplicationService; import io.metersphere.service.ext.ExtProjectApplicationService;
import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.CollectionUtils;
@ -75,6 +75,14 @@ public class MockConfigService {
private String tcpMockPorts; private String tcpMockPorts;
@Resource @Resource
private BaseEnvironmentService baseEnvironmentService; private BaseEnvironmentService baseEnvironmentService;
@Resource
private NoticeSendService noticeSendService;
@Resource
private ApiDefinitionMapper apiDefinitionMapper;
@Resource
private ProjectVersionMapper projectVersionMapper;
public List<MockExpectConfigWithBLOBs> selectMockExpectConfigByApiId(String apiId) { public List<MockExpectConfigWithBLOBs> selectMockExpectConfigByApiId(String apiId) {
return extMockExpectConfigMapper.selectByApiId(apiId); return extMockExpectConfigMapper.selectByApiId(apiId);
@ -169,6 +177,33 @@ public class MockConfigService {
return returnRsp; return returnRsp;
} }
public void sendMockNotice(MockExpectConfigWithBLOBs mockExpectConfigWithBLOBs, String defaultContext, String event) {
String context = SessionUtils.getUserId().concat(defaultContext).concat(":").concat(mockExpectConfigWithBLOBs.getName());
Map<String, Object> paramMap = new HashMap<>();
MockConfig mockConfig = mockConfigMapper.selectByPrimaryKey(mockExpectConfigWithBLOBs.getMockConfigId());
getParamMap(paramMap, SessionUtils.getUserId(), mockExpectConfigWithBLOBs, mockConfig);
NoticeModel noticeModel = NoticeModel.builder().operator(SessionUtils.getUserId()).context(context).testId(mockExpectConfigWithBLOBs.getId()).subject("接口定义通知").paramMap(paramMap).excludeSelf(true).event(event).build();
noticeSendService.send(NoticeConstants.TaskType.API_DEFINITION_TASK, noticeModel);
}
private void getParamMap(Map<String, Object> paramMap, String userId, MockExpectConfigWithBLOBs mockExpectConfigWithBLOBs, MockConfig mockConfig) {
paramMap.put("operator", userId);
paramMap.put("id", mockExpectConfigWithBLOBs.getId());
paramMap.put("name", mockExpectConfigWithBLOBs.getName());
paramMap.put("createUser", mockExpectConfigWithBLOBs.getCreateUserId());
if (mockConfig != null) {
ApiDefinitionWithBLOBs apiDefinitionWithBLOBs = apiDefinitionMapper.selectByPrimaryKey(mockConfig.getApiId());
if (apiDefinitionWithBLOBs != null) {
paramMap.put("projectId", apiDefinitionWithBLOBs.getProjectId());
paramMap.put("apiDefinitionId", apiDefinitionWithBLOBs.getId());
ProjectVersion projectVersion = projectVersionMapper.selectByPrimaryKey(apiDefinitionWithBLOBs.getVersionId());
paramMap.put("version", projectVersion.getName());
}
}
}
public MockExpectConfig updateMockExpectConfigStatus(MockExpectConfigRequest request) { public MockExpectConfig updateMockExpectConfigStatus(MockExpectConfigRequest request) {
if (StringUtils.isNotEmpty(request.getId()) && StringUtils.isNotEmpty(request.getStatus())) { if (StringUtils.isNotEmpty(request.getId()) && StringUtils.isNotEmpty(request.getStatus())) {
MockExpectConfigWithBLOBs model = new MockExpectConfigWithBLOBs(); MockExpectConfigWithBLOBs model = new MockExpectConfigWithBLOBs();
@ -177,6 +212,7 @@ public class MockConfigService {
model.setUpdateTime(timeStmp); model.setUpdateTime(timeStmp);
model.setStatus(request.getStatus()); model.setStatus(request.getStatus());
mockExpectConfigMapper.updateByPrimaryKeySelective(model); mockExpectConfigMapper.updateByPrimaryKeySelective(model);
sendMockNotice(model, "更新了mock", NoticeConstants.Event.MOCK_UPDATE);
return model; return model;
} else { } else {
return null; return null;
@ -219,14 +255,17 @@ public class MockConfigService {
model.setCreateUserId(SessionUtils.getUserId()); model.setCreateUserId(SessionUtils.getUserId());
model.setStatus("true"); model.setStatus("true");
mockExpectConfigMapper.insert(model); mockExpectConfigMapper.insert(model);
sendMockNotice(model, "新建了mock", NoticeConstants.Event.MOCK_CREATE);
} else { } else {
mockExpectConfigMapper.updateByPrimaryKeySelective(model); mockExpectConfigMapper.updateByPrimaryKeySelective(model);
model = mockExpectConfigMapper.selectByPrimaryKey(model.getId());
sendMockNotice(model, "更新了mock", NoticeConstants.Event.MOCK_UPDATE);
} }
if (StringUtils.isNotEmpty(request.getCopyId())) { if (StringUtils.isNotEmpty(request.getCopyId())) {
FileUtils.copyBdyFile(request.getCopyId(), model.getId()); FileUtils.copyBdyFile(request.getCopyId(), model.getId());
} }
FileUtils.createBodyFiles(model.getId(), bodyFiles); FileUtils.createBodyFiles(model.getId(), bodyFiles);
return model; return mockExpectConfigMapper.selectByPrimaryKey(model.getId());
} }
private String getMockExpectId(String mockConfigId) { private String getMockExpectId(String mockConfigId) {
@ -637,6 +676,7 @@ public class MockConfigService {
public void deleteMockExpectConfig(String id) { public void deleteMockExpectConfig(String id) {
MockExpectConfigWithBLOBs mockBlobs = mockExpectConfigMapper.selectByPrimaryKey(id); MockExpectConfigWithBLOBs mockBlobs = mockExpectConfigMapper.selectByPrimaryKey(id);
if (mockBlobs != null) { if (mockBlobs != null) {
sendMockNotice(mockBlobs, "删除了mock", NoticeConstants.Event.MOCK_DELETE);
this.deleteMockExpectFiles(mockBlobs); this.deleteMockExpectFiles(mockBlobs);
mockExpectConfigMapper.deleteByPrimaryKey(id); mockExpectConfigMapper.deleteByPrimaryKey(id);
} }

View File

@ -244,7 +244,10 @@
</ms-main-container> </ms-main-container>
</ms-container> </ms-container>
<mock-edit-drawer :is-tcp=isTcp :api-id="mockConfigData.apiId"
:api-params="apiParams"
@refreshMockInfo="refreshMockInfo"
:mock-config-id="mockConfigData.id" ref="mockEditDrawer"/>
</div> </div>
</template> </template>
<script> <script>
@ -279,6 +282,8 @@ import MsEnvironmentSelect from "./components/case/MsEnvironmentSelect";
import {PROJECT_ID, WORKSPACE_ID} from "metersphere-frontend/src/utils/constants"; import {PROJECT_ID, WORKSPACE_ID} from "metersphere-frontend/src/utils/constants";
import {useApiStore} from "@/store"; import {useApiStore} from "@/store";
import {buildTree} from "metersphere-frontend/src/model/NodeTree"; import {buildTree} from "metersphere-frontend/src/model/NodeTree";
import {createMockConfig, getMockApiParams, getTcpMockInfo, mockExpectConfig} from "@/api/api-mock";
import MockEditDrawer from "@/business/definition/components/mock/MockEditDrawer";
const store = useApiStore(); const store = useApiStore();
export default { export default {
@ -341,6 +346,7 @@ export default {
MockConfig, MockConfig,
MsEditCompleteContainer, MsEditCompleteContainer,
MsEnvironmentSelect, MsEnvironmentSelect,
MockEditDrawer,
MxVersionSelect: () => import("metersphere-frontend/src/components/version/MxVersionSelect"), MxVersionSelect: () => import("metersphere-frontend/src/components/version/MxVersionSelect"),
}, },
props: { props: {
@ -392,6 +398,9 @@ export default {
currentVersion: null, currentVersion: null,
trashVersion: null, trashVersion: null,
isAsideHidden: true, isAsideHidden: true,
mockConfigData: {},
apiParams: {},
isTcp: false
}; };
}, },
activated() { activated() {
@ -505,6 +514,23 @@ export default {
if (this.$route.query.caseId) { if (this.$route.query.caseId) {
this.activeDom = 'middle'; this.activeDom = 'middle';
} }
if (this.$route.query.mockId) {
if (this.currentProtocol === "TCP") {
this.isTcp = true;
}
mockExpectConfig(this.$route.query.mockId).then(res => {
this.mockExpectConfigData = res.data;
if (this.mockExpectConfigData.mockConfigId) {
let mockParam = {};
mockParam.id = this.mockExpectConfigData.mockConfigId;
createMockConfig(mockParam).then(response => {
this.mockConfigData = response.data;
this.searchApiParams(this.mockConfigData.apiId)
this.$refs.mockEditDrawer.open(this.mockExpectConfigData)
});
}
})
}
}, },
methods: { methods: {
removeTab(name) { removeTab(name) {
@ -942,6 +968,27 @@ export default {
let targetName = this.$t("commons.mock") + "-" + data.apiName; let targetName = this.$t("commons.mock") + "-" + data.apiName;
this.handleMockTabsConfig(targetName, "MOCK", data); this.handleMockTabsConfig(targetName, "MOCK", data);
}, },
refreshMockInfo(mockConfigId) {
let mockParam = {};
mockParam.id = mockConfigId;
createMockConfig(mockParam).then(response => {
this.mockConfigData = response.data;
});
},
searchApiParams(apiId) {
getMockApiParams(apiId).then(response => {
this.apiParams = response.data;
if (!this.apiParams.query) {
this.apiParams.query = [];
}
if (!this.apiParams.rest) {
this.apiParams.rest = [];
}
if (!this.apiParams.form) {
this.apiParams.form = [];
}
});
},
saveApi(data) { saveApi(data) {
this.setTabTitle(data); this.setTabTitle(data);
this.refresh(data); this.refresh(data);

View File

@ -88,6 +88,8 @@ export function getUrl(d) {
case "API_DEFINITION_TASK" : case "API_DEFINITION_TASK" :
if (d.operation.startsWith('CASE_') || d.operation.startsWith('EXECUTE_')) { if (d.operation.startsWith('CASE_') || d.operation.startsWith('EXECUTE_')) {
url += "/api/definition?caseId=" + d.resourceId; url += "/api/definition?caseId=" + d.resourceId;
} else if (d.operation.startsWith('MOCK_')) {
url += "/api/definition?mockId=" + d.resourceId;
} else { } else {
url += "/api/definition?resourceId=" + d.resourceId; url += "/api/definition?resourceId=" + d.resourceId;
} }

View File

@ -2461,6 +2461,9 @@ const message = {
'CASE_CREATE': ' Created API Case', 'CASE_CREATE': ' Created API Case',
'CASE_UPDATE': ' Updated API Case', 'CASE_UPDATE': ' Updated API Case',
'CASE_DELETE': ' Delete API Case', 'CASE_DELETE': ' Delete API Case',
'MOCK_CREATE': 'Created mock',
'MOCK_UPDATE': 'Updated mock',
'MOCK_DELETE': 'Delete mock',
'EXECUTE_SUCCESSFUL': ' Execute', 'EXECUTE_SUCCESSFUL': ' Execute',
'EXECUTE_FAILED': ' Execute', 'EXECUTE_FAILED': ' Execute',
'EXECUTE_COMPLETED': ' Execute', 'EXECUTE_COMPLETED': ' Execute',

View File

@ -2469,6 +2469,9 @@ const message = {
'CASE_CREATE': '创建了接口用例', 'CASE_CREATE': '创建了接口用例',
'CASE_UPDATE': '更新了接口用例', 'CASE_UPDATE': '更新了接口用例',
'CASE_DELETE': '删除了接口用例', 'CASE_DELETE': '删除了接口用例',
'MOCK_CREATE': '创建了mock',
'MOCK_UPDATE': '更新了mock',
'MOCK_DELETE': '删除了mock',
'EXECUTE_SUCCESSFUL': '执行', 'EXECUTE_SUCCESSFUL': '执行',
'EXECUTE_FAILED': '执行', 'EXECUTE_FAILED': '执行',
'EXECUTE_COMPLETED': '执行', 'EXECUTE_COMPLETED': '执行',

View File

@ -2466,6 +2466,9 @@ const message = {
'CASE_CREATE': '創建了接口用例', 'CASE_CREATE': '創建了接口用例',
'CASE_UPDATE': '更新了接口用例', 'CASE_UPDATE': '更新了接口用例',
'CASE_DELETE': '刪除了接口用例', 'CASE_DELETE': '刪除了接口用例',
'MOCK_CREATE': '創建了mock',
'MOCK_UPDATE': '更新了mock',
'MOCK_DELETE': '刪除了mock',
'EXECUTE_SUCCESSFUL': '執行', 'EXECUTE_SUCCESSFUL': '執行',
'EXECUTE_FAILED': '執行', 'EXECUTE_FAILED': '執行',
'EXECUTE_COMPLETED': '執行', 'EXECUTE_COMPLETED': '執行',

View File

@ -51,6 +51,10 @@ public interface NoticeConstants {
String CASE_UPDATE = "CASE_UPDATE"; String CASE_UPDATE = "CASE_UPDATE";
String CASE_DELETE = "CASE_DELETE"; String CASE_DELETE = "CASE_DELETE";
String MOCK_CREATE = "MOCK_CREATE";
String MOCK_UPDATE = "MOCK_UPDATE";
String MOCK_DELETE = "MOCK_DELETE";
String COMMENT = "COMMENT"; String COMMENT = "COMMENT";
String IMPORT = "IMPORT"; String IMPORT = "IMPORT";

View File

@ -63,14 +63,17 @@ public class AfterReturningNoticeSendService {
switch (sendNotice.event()) { switch (sendNotice.event()) {
case NoticeConstants.Event.CREATE: case NoticeConstants.Event.CREATE:
case NoticeConstants.Event.CASE_CREATE: case NoticeConstants.Event.CASE_CREATE:
case NoticeConstants.Event.MOCK_CREATE:
operation = "创建了"; operation = "创建了";
break; break;
case NoticeConstants.Event.UPDATE: case NoticeConstants.Event.UPDATE:
case NoticeConstants.Event.CASE_UPDATE: case NoticeConstants.Event.CASE_UPDATE:
case NoticeConstants.Event.MOCK_UPDATE:
operation = "更新了"; operation = "更新了";
break; break;
case NoticeConstants.Event.DELETE: case NoticeConstants.Event.DELETE:
case NoticeConstants.Event.CASE_DELETE: case NoticeConstants.Event.CASE_DELETE:
case NoticeConstants.Event.MOCK_DELETE:
operation = "删除了"; operation = "删除了";
break; break;
case NoticeConstants.Event.COMMENT: case NoticeConstants.Event.COMMENT:

View File

@ -73,6 +73,9 @@ export default {
{value: 'CASE_CREATE', label: 'CASE ' + this.$t('commons.create')}, {value: 'CASE_CREATE', label: 'CASE ' + this.$t('commons.create')},
{value: 'CASE_UPDATE', label: 'CASE ' + this.$t('commons.update')}, {value: 'CASE_UPDATE', label: 'CASE ' + this.$t('commons.update')},
{value: 'CASE_DELETE', label: 'CASE ' + this.$t('commons.delete')}, {value: 'CASE_DELETE', label: 'CASE ' + this.$t('commons.delete')},
{value: 'MOCK_CREATE', label: 'MOCK ' + this.$t('commons.create')},
{value: 'MOCK_UPDATE', label: 'MOCK ' + this.$t('commons.update')},
{value: 'MOCK_DELETE', label: 'MOCK ' + this.$t('commons.delete')},
{value: 'EXECUTE_SUCCESSFUL', label: 'CASE ' + this.$t('commons.run_success')}, {value: 'EXECUTE_SUCCESSFUL', label: 'CASE ' + this.$t('commons.run_success')},
{value: 'EXECUTE_FAILED', label: 'CASE ' + this.$t('commons.run_fail')}, {value: 'EXECUTE_FAILED', label: 'CASE ' + this.$t('commons.run_fail')},
], ],
@ -257,6 +260,64 @@ export default {
label: this.$t('api_test.definition.document.order'), label: this.$t('api_test.definition.document.order'),
value: 'order', value: 'order',
}, },
],
mockVariables: [
{
label: this.$t('group.operator'),
value: 'operator',
},
{
label: 'id',
value: 'id',
},
{
label: this.$t('project.id'),
value: 'projectId',
},
{
label: this.$t('commons.name'),
value: 'name',
},
{
label: this.$t('api_test.definition.id'),
value: 'apiDefinitionId',
},
{
label: this.$t('commons.create_user_id'),
value: 'createUserId',
},
{
label: this.$t('commons.update_user_id'),
value: 'updateUserId',
},
{
label: this.$t('commons.create_time'),
value: 'createTime',
},
{
label: this.$t('commons.update_time'),
value: 'updateTime',
},
{
label: this.$t('commons.tag'),
value: 'tags',
},
{
label: this.$t('commons.status'),
value: 'status',
},
{
label: this.$t('commons.delete_time'),
value: 'deleteTime',
},
{
label: this.$t('commons.delete_user_id'),
value: 'deleteUserId',
},
{
label: this.$t('commons.version'),
value: 'version',
},
] ]
}; };
}, },
@ -316,6 +377,20 @@ export default {
.replace('接口定义', '接口用例'); .replace('接口定义', '接口用例');
this.variables = this.caseVariables; this.variables = this.caseVariables;
break; break;
case 'MOCK_CREATE':
robotTemplate = this.robotTitle.replace('接口定义', '接口用例');
this.variables = this.mockVariables;
break;
case 'MOCK_UPDATE':
robotTemplate = this.robotTitle.replace('创建', '更新')
.replace('接口定义', '接口用例');
this.variables = this.mockVariables;
break;
case 'MOCK_DELETE':
robotTemplate = this.robotTitle.replace('创建', '删除')
.replace('接口定义', '接口用例');
this.variables = this.mockVariables;
break;
case 'EXECUTE_SUCCESSFUL': case 'EXECUTE_SUCCESSFUL':
robotTemplate = this.robotTitle.replace('创建', '执行') robotTemplate = this.robotTitle.replace('创建', '执行')
.replace('接口定义', '接口用例成功'); .replace('接口定义', '接口用例成功');
@ -346,8 +421,19 @@ export default {
row.userIds.splice(i, 1); row.userIds.splice(i, 1);
} }
break; break;
case "MOCK_CREATE":
receiverOptions.unshift({id: 'FOLLOW_PEOPLE', name: this.$t('api_test.automation.follow_people')});
receiverOptions.unshift({id: 'CREATOR', name: this.$t('commons.create_user')});
if (row.isSet) {
if (i < 0) {
row.userIds.unshift('FOLLOW_PEOPLE');
}
}
break;
case "UPDATE": case "UPDATE":
case "CASE_UPDATE": case "CASE_UPDATE":
case "MOCK_UPDATE":
case "MOCK_DELETE":
receiverOptions.unshift({id: 'FOLLOW_PEOPLE', name: this.$t('api_test.automation.follow_people')}); receiverOptions.unshift({id: 'FOLLOW_PEOPLE', name: this.$t('api_test.automation.follow_people')});
receiverOptions.unshift({id: 'CREATOR', name: this.$t('commons.create_user')}); receiverOptions.unshift({id: 'CREATOR', name: this.$t('commons.create_user')});
if (row.isSet) { if (row.isSet) {