fix(项目设置): 缺陷模板复制选项值去重的问题 (#16835)

--story=1008920 --user=宋昌昌 【项目设置】缺陷模版支持跨项目复制 https://www.tapd.cn/55049933/s/1222343
This commit is contained in:
MeterSphere Bot 2022-08-11 20:14:17 +08:00 committed by GitHub
parent 08fcc5d9cb
commit 3bf2bab53d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 18 deletions

View File

@ -68,11 +68,11 @@ public class IssueTemplateController {
@PostMapping("/copy") @PostMapping("/copy")
public void copy(@RequestBody CopyIssueTemplateRequest request) { public void copy(@RequestBody CopyIssueTemplateRequest request) {
issueTemplateService.copy(request); List<IssueTemplate> copyRecords = issueTemplateService.copy(request);
// 目标项目操作日志 // 目标项目操作日志
if (CollectionUtils.isNotEmpty(request.getTargetProjectIds())) { if (CollectionUtils.isNotEmpty(copyRecords)) {
request.getTargetProjectIds().forEach(targetProjectId -> { copyRecords.forEach(copyRecord -> {
issueTemplateService.copyIssueTemplateLog(targetProjectId); issueTemplateService.copyIssueTemplateLog(copyRecord.getProjectId(), copyRecord.getName());
}); });
} }
} }

View File

@ -1,6 +1,7 @@
package io.metersphere.service; package io.metersphere.service;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.metersphere.base.domain.*; import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.*; import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtCustomFieldMapper; import io.metersphere.base.mapper.ext.ExtCustomFieldMapper;
@ -74,6 +75,8 @@ public class IssueTemplateService extends TemplateBaseService {
@Resource @Resource
WorkspaceMapper workspaceMapper; WorkspaceMapper workspaceMapper;
private static final String CUSTOM_FIELD_TYPE = "select";
public String add(UpdateIssueTemplateRequest request) { public String add(UpdateIssueTemplateRequest request) {
checkExist(request); checkExist(request);
IssueTemplate template = new IssueTemplate(); IssueTemplate template = new IssueTemplate();
@ -325,12 +328,12 @@ public class IssueTemplateService extends TemplateBaseService {
return issueTemplateCopyDto; return issueTemplateCopyDto;
} }
public void copy(CopyIssueTemplateRequest request) { public List<IssueTemplate> copy(CopyIssueTemplateRequest request) {
if (CollectionUtils.isEmpty(request.getTargetProjectIds())) { if (CollectionUtils.isEmpty(request.getTargetProjectIds())) {
MSException.throwException("target project not checked"); MSException.throwException("cannot copy, target project not checked");
} }
if (request.getId() == null) { if (request.getId() == null) {
MSException.throwException("source project is empty"); MSException.throwException("copy error, source project is empty");
} }
List<IssueTemplate> issueTemplateRecords = new ArrayList<>(); List<IssueTemplate> issueTemplateRecords = new ArrayList<>();
List<CustomField> customFieldRecords = new ArrayList<>(); List<CustomField> customFieldRecords = new ArrayList<>();
@ -397,9 +400,18 @@ public class IssueTemplateService extends TemplateBaseService {
if (sourceCustomField.getSystem()) { if (sourceCustomField.getSystem()) {
// 系统字段 // 系统字段
String options; String options;
if (StringUtils.equals("select", sourceCustomField.getType())) { if (StringUtils.equals(CUSTOM_FIELD_TYPE, sourceCustomField.getType())) {
options = StringUtils.replace(tarCustomField.getOptions(), "]", ",") + StringUtils.replace(sourceCustomField.getOptions(), "[", ""); // 下拉框选项
List<JSONObject> sourceOptions = JSONObject.parseArray(sourceCustomField.getOptions(), JSONObject.class);
sourceOptions.removeIf(sourceOption -> StringUtils.contains(tarCustomField.getOptions(), sourceOption.get("text").toString()));
if (CollectionUtils.isNotEmpty(sourceOptions)) {
String appendSourceOption = JSONObject.toJSONString(sourceOptions);
options = StringUtils.replace(tarCustomField.getOptions(), "]", ",") + StringUtils.replace(appendSourceOption, "[", "");
} else { } else {
options = tarCustomField.getOptions();
}
} else {
// 普通值
options = "[]"; options = "[]";
} }
tarCustomField.setOptions(options); tarCustomField.setOptions(options);
@ -439,6 +451,7 @@ public class IssueTemplateService extends TemplateBaseService {
if (CollectionUtils.isNotEmpty(customFieldRecords)) { if (CollectionUtils.isNotEmpty(customFieldRecords)) {
extCustomFieldMapper.batchInsert(customFieldRecords); extCustomFieldMapper.batchInsert(customFieldRecords);
} }
return issueTemplateRecords;
} }
public String getLogDetails(String id, List<CustomFieldTemplate> newCustomFieldTemplates) { public String getLogDetails(String id, List<CustomFieldTemplate> newCustomFieldTemplates) {
@ -507,15 +520,15 @@ public class IssueTemplateService extends TemplateBaseService {
return permissionsByUserGroups; return permissionsByUserGroups;
} }
@MsAuditLog(module = OperLogModule.PROJECT_TEMPLATE_MANAGEMENT, type = OperLogConstants.COPY, content = "#msClass.getLogDetails(#targetProjectId)", msClass = IssueTemplateService.class) @MsAuditLog(module = OperLogModule.PROJECT_TEMPLATE_MANAGEMENT, type = OperLogConstants.COPY, content = "#msClass.getLogDetails(#targetProjectId, #targetProjectName)", msClass = IssueTemplateService.class)
public void copyIssueTemplateLog(String targetProjectId) { public void copyIssueTemplateLog(String targetProjectId, String targetProjectName) {
} }
public String getLogDetails(String targetProjectId) { public String getLogDetails(String targetProjectId, String targetProjectName) {
if (targetProjectId == null) { if (targetProjectId == null) {
return null; return null;
} }
OperatingLogDetails details = new OperatingLogDetails(targetProjectId, targetProjectId, "缺陷模板复制", null, null); OperatingLogDetails details = new OperatingLogDetails(targetProjectId, targetProjectId, targetProjectName, null, null);
return JSON.toJSONString(details); return JSON.toJSONString(details);
} }
} }

View File

@ -6,8 +6,8 @@
<span style="font-size:13px; margin-left: 10px">{{$t('custom_field.copy_issue_template_model_tips1')}}</span> <span style="font-size:13px; margin-left: 10px">{{$t('custom_field.copy_issue_template_model_tips1')}}</span>
<i style="font-size: 12px">{{$t('custom_field.copy_issue_template_model_tips2')}}</i> <i style="font-size: 12px">{{$t('custom_field.copy_issue_template_model_tips2')}}</i>
<el-checkbox-group v-model="copyModelVal" @change="checkModelChanged" style="margin-top: 15px"> <el-checkbox-group v-model="copyModelVal" @change="checkModelChanged" style="margin-top: 15px">
<el-checkbox false-label="null" true-label="0" :label="$t('custom_field.copy_issue_template_model_append')" style="margin-left: 10px"></el-checkbox> <el-checkbox false-label="0" true-label="0" :label="$t('custom_field.copy_issue_template_model_append')" style="margin-left: 10px"></el-checkbox>
<el-checkbox false-label="null" true-label="1" :label="$t('custom_field.copy_issue_template_model_cover')" style="margin-left: 25px"></el-checkbox> <el-checkbox false-label="1" true-label="1" :label="$t('custom_field.copy_issue_template_model_cover')" style="margin-left: 25px"></el-checkbox>
</el-checkbox-group> </el-checkbox-group>
<div class="copyTargetProjectTree" style="margin-top: 20px; margin-left: 10px"> <div class="copyTargetProjectTree" style="margin-top: 20px; margin-left: 10px">
<span>{{$t('custom_field.target_project')}}</span> <span>{{$t('custom_field.target_project')}}</span>
@ -59,7 +59,6 @@ export default {
copyData: null, copyData: null,
copyProjects: [], copyProjects: [],
copyModelVal: "0", copyModelVal: "0",
preCopyModelVal: "",
defaultProps: { defaultProps: {
children: 'children', children: 'children',
label: 'name', label: 'name',
@ -81,8 +80,9 @@ export default {
this.initCopyProjects(); this.initCopyProjects();
}, },
checkModelChanged(val) { checkModelChanged(val) {
this.copyModelVal = (val == 'null' || !val) ? this.preCopyModelVal : val; if (val !== "null") {
this.preCopyModelVal = this.copyModelVal; this.copyModelVal = this.copyModelVal !== val ? val : this.copyModelVal;
}
}, },
initCopyProjects() { initCopyProjects() {
let issueTemplateId = this.copyData.id; let issueTemplateId = this.copyData.id;