feat(测试跟踪): 非MS平台集成支持平台状态字段导入导出
--story=1012478 --user=宋昌昌 与JIRA集成,在MS列表中导出缺陷时,希望能够支持导出“平台状态”字段 https://www.tapd.cn/55049933/s/1396115
This commit is contained in:
parent
dd381da0a0
commit
84137c7364
|
@ -20,6 +20,7 @@ public enum IssueExportHeadField {
|
|||
COMMENT("comment", Translator.get("comment"), IssueExcelData::getComment),
|
||||
RESOURCE("resource", Translator.get("issue_resource"), IssueExcelData::getResourceName),
|
||||
PLATFORM("platform", Translator.get("issue_platform"), IssueExcelData::getPlatform),
|
||||
PLATFORM_STATUS("platformStatus", Translator.get("platform_status"), IssueExcelData::getPlatformStatus),
|
||||
CREATE_TIME("createTime", Translator.get("create_time"), issueExcelData -> issueExcelData.getCreateTime() != null ? DateUtils.getTimeStr(issueExcelData.getCreateTime()) : null);
|
||||
|
||||
private String id;
|
||||
|
|
|
@ -66,6 +66,8 @@ public class IssueExcelData implements Serializable {
|
|||
private String priority;
|
||||
@ExcelIgnore
|
||||
Map<String, Object> customData = new LinkedHashMap<>();
|
||||
@ExcelIgnore
|
||||
List<String> tapdUsers = new ArrayList<>();
|
||||
|
||||
public List<List<String>> getHead(Boolean isThirdTemplate, List<CustomFieldDao> customFields, IssueExportRequest request) {
|
||||
return new ArrayList<>();
|
||||
|
|
|
@ -4,10 +4,10 @@ import com.alibaba.excel.annotation.ExcelProperty;
|
|||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import io.metersphere.dto.CustomFieldDao;
|
||||
import io.metersphere.request.issues.IssueExportRequest;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Data;
|
||||
import org.hibernate.validator.constraints.Length;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class IssueExcelDataTw extends IssueExcelData{
|
|||
@NotBlank(message = "{cannot_be_null}")
|
||||
@Length(max = 1000)
|
||||
@ColumnWidth(100)
|
||||
@ExcelProperty("缺陷内容")
|
||||
@ExcelProperty("缺陷描述")
|
||||
private String description;
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,9 +1,16 @@
|
|||
package io.metersphere.excel.handler;
|
||||
|
||||
import com.alibaba.excel.metadata.Head;
|
||||
import com.alibaba.excel.metadata.data.DataFormatData;
|
||||
import com.alibaba.excel.metadata.data.WriteCellData;
|
||||
import com.alibaba.excel.util.BooleanUtils;
|
||||
import com.alibaba.excel.write.handler.CellWriteHandler;
|
||||
import com.alibaba.excel.write.handler.RowWriteHandler;
|
||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
||||
import com.alibaba.excel.write.handler.context.RowWriteHandlerContext;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
|
||||
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
|
||||
import io.metersphere.commons.constants.CustomFieldScene;
|
||||
import io.metersphere.commons.constants.CustomFieldType;
|
||||
import io.metersphere.commons.utils.JSON;
|
||||
|
@ -12,25 +19,23 @@ import io.metersphere.dto.CustomFieldOptionDTO;
|
|||
import io.metersphere.excel.constants.IssueExportHeadField;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.Comment;
|
||||
import org.apache.poi.ss.usermodel.Drawing;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 表头, 单元格后置处理
|
||||
*/
|
||||
public class IssueTemplateHeadWriteHandler implements RowWriteHandler, SheetWriteHandler {
|
||||
public class IssueTemplateHeadWriteHandler implements RowWriteHandler, SheetWriteHandler, CellWriteHandler {
|
||||
|
||||
private Sheet sheet;
|
||||
private Drawing<?> drawingPatriarch;
|
||||
private Map<String, String> memberMap;
|
||||
private Map<Integer, String> headCommentIndexMap = new HashMap<>();
|
||||
private Map<Integer, String> dateFieldIndexMap = new HashMap<>();
|
||||
|
||||
public IssueTemplateHeadWriteHandler(Map<String, String> memberMap, List<List<String>> headList, List<CustomFieldDao> customFields) {
|
||||
this.memberMap = memberMap;
|
||||
|
@ -56,7 +61,7 @@ public class IssueTemplateHeadWriteHandler implements RowWriteHandler, SheetWrit
|
|||
customFieldDao.setType(CustomFieldType.MEMBER.getValue());
|
||||
} else {
|
||||
// 自定义字段
|
||||
List<CustomFieldDao> fields = customFields.stream().filter(field -> StringUtils.equals(field.getName(), head)).collect(Collectors.toList());
|
||||
List<CustomFieldDao> fields = customFields.stream().filter(field -> StringUtils.equals(field.getName(), head)).toList();
|
||||
if (fields.size() > 0) {
|
||||
customFieldDao = fields.get(0);
|
||||
} else {
|
||||
|
@ -79,6 +84,18 @@ public class IssueTemplateHeadWriteHandler implements RowWriteHandler, SheetWrit
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
|
||||
Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
|
||||
DataFormat dataFormat = workbook.createDataFormat();
|
||||
for (WriteCellData<?> writeCellData : cellDataList) {
|
||||
WriteCellStyle writeCellStyle = writeCellData.getOrCreateStyle();
|
||||
DataFormatData dataFormatData = new DataFormatData();
|
||||
dataFormatData.setIndex(dataFormat.getFormat("@"));
|
||||
writeCellStyle.setDataFormatData(dataFormatData);
|
||||
}
|
||||
}
|
||||
|
||||
private String getCommentByCustomField(CustomFieldDao field) {
|
||||
String commentText = "";
|
||||
if (StringUtils.equalsAnyIgnoreCase(field.getType(),
|
||||
|
@ -86,6 +103,8 @@ public class IssueTemplateHeadWriteHandler implements RowWriteHandler, SheetWrit
|
|||
if (StringUtils.equalsAnyIgnoreCase(field.getScene(), CustomFieldScene.ISSUE.name()) &&
|
||||
StringUtils.equalsAnyIgnoreCase(field.getName(), "状态", "严重程度")) {
|
||||
commentText = Translator.get("options").concat(JSON.toJSONString(getOptionValues(field)));
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(field.getName(), Translator.get("platform_status"))) {
|
||||
commentText = Translator.get("options").concat(JSON.toJSONString(getOptionsLabel(field.getOptions())));
|
||||
} else {
|
||||
commentText = Translator.get("options").concat(JSON.toJSONString(getOptionsText(field.getOptions())));
|
||||
}
|
||||
|
@ -159,6 +178,20 @@ public class IssueTemplateHeadWriteHandler implements RowWriteHandler, SheetWrit
|
|||
return options;
|
||||
}
|
||||
|
||||
private List<String> getOptionsLabel(String optionStr) {
|
||||
if (StringUtils.isEmpty(optionStr)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<String> options = new ArrayList<>();
|
||||
List<Map> optionMapList = JSON.parseArray(optionStr, Map.class);
|
||||
optionMapList.forEach(optionMap -> {
|
||||
String optionText = optionMap.get("label").toString();
|
||||
options.add(optionText);
|
||||
});
|
||||
return options;
|
||||
}
|
||||
|
||||
private List<String> getCascadSelect(String optionStr) {
|
||||
if (StringUtils.isEmpty(optionStr)) {
|
||||
return Collections.emptyList();
|
||||
|
|
|
@ -22,6 +22,7 @@ import io.metersphere.excel.utils.ExcelValidateHelper;
|
|||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.request.issues.IssueImportRequest;
|
||||
import io.metersphere.service.IssuesService;
|
||||
import io.metersphere.xpack.track.dto.PlatformStatusDTO;
|
||||
import io.metersphere.xpack.track.dto.request.IssuesUpdateRequest;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.collections.MapUtils;
|
||||
|
@ -40,6 +41,18 @@ import java.util.stream.Collectors;
|
|||
|
||||
public class IssueExcelListener extends AnalysisEventListener<Map<Integer, String>> {
|
||||
|
||||
/**
|
||||
* dataClass: EXCEL数据实例class
|
||||
* request: 导入参数
|
||||
* isThirdPlatform: 是否是第三方平台
|
||||
* headMap: excel表头字段集合
|
||||
* customFields: 自定义字段集合(模板自定义字段 + 平台自定义字段)
|
||||
* issuesService: 业务类
|
||||
* memberMap: 成员集合
|
||||
* platformStatusList: 平台状态列表
|
||||
* excelHeadFieldMap: excel表头字段字典值
|
||||
* issueCustomFieldMap: 缺陷自定义字段KeyMap
|
||||
*/
|
||||
private Class dataClass;
|
||||
private IssueImportRequest request;
|
||||
private Boolean isThirdPlatform;
|
||||
|
@ -47,9 +60,8 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
private List<CustomFieldDao> customFields;
|
||||
private IssuesService issuesService;
|
||||
private Map<String, String> memberMap;
|
||||
/**
|
||||
* excel表头字段字典值
|
||||
*/
|
||||
private List<PlatformStatusDTO> platformStatusList;
|
||||
private List<String> tapdUsers;
|
||||
private Map<String, String> headFieldTransferDic = new HashMap<>();
|
||||
private Map<String, List<CustomFieldResourceDTO>> issueCustomFieldMap = new HashMap<>();
|
||||
|
||||
|
@ -61,19 +73,21 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
/**
|
||||
* insertList: 新增缺陷集合
|
||||
* updateList: 覆盖缺陷集合
|
||||
* errList: 校验失败缺陷集合
|
||||
* errList: 校验失败错误信息集合
|
||||
*/
|
||||
protected List<IssueExcelData> insertList = new ArrayList<>();
|
||||
protected List<IssueExcelData> updateList = new ArrayList<>();
|
||||
protected List<ExcelErrData<IssueExcelData>> errList = new ArrayList<>();
|
||||
|
||||
public IssueExcelListener(IssueImportRequest request, Class clazz, Boolean isThirdPlatform, List<CustomFieldDao> customFields, Map<String, String> memberMap) {
|
||||
public IssueExcelListener(IssueImportRequest request, Class clazz, Boolean isThirdPlatform, List<CustomFieldDao> customFields, Map<String, String> memberMap, List<PlatformStatusDTO> platformStatusList, List<String> tapdUsers) {
|
||||
this.request = request;
|
||||
this.dataClass = clazz;
|
||||
this.isThirdPlatform = isThirdPlatform;
|
||||
this.customFields = customFields;
|
||||
this.issuesService = CommonBeanFactory.getBean(IssuesService.class);
|
||||
this.memberMap = memberMap;
|
||||
this.platformStatusList = platformStatusList;
|
||||
this.tapdUsers = tapdUsers;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -85,9 +99,11 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
issueExcelData = this.parseDataToModel(data);
|
||||
// EXCEL校验, 如果不是第三方模板则需要校验
|
||||
errMsg = new StringBuilder(!isThirdPlatform ? ExcelValidateHelper.validateEntity(issueExcelData) : StringUtils.EMPTY);
|
||||
// 校验自定义字段
|
||||
// 校验自定义字段及平台状态及TAPD处理人
|
||||
if (StringUtils.isEmpty(errMsg)) {
|
||||
validateCustomField(issueExcelData, errMsg);
|
||||
validateAndTransferPlatformStatus(issueExcelData, errMsg);
|
||||
validateTapdUsers(issueExcelData, errMsg);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
errMsg = new StringBuilder(Translator.get("parse_data_error"));
|
||||
|
@ -139,6 +155,9 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存缺陷数据
|
||||
*/
|
||||
public void saveData() {
|
||||
//excel中用例都有错误时就返回,只要有用例可用于更新或者插入就不返回
|
||||
if (!errList.isEmpty()) {
|
||||
|
@ -176,6 +195,9 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
issueCustomFieldMap.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* headMap转换
|
||||
*/
|
||||
private void formatHeadMap() {
|
||||
for (Integer key : headMap.keySet()) {
|
||||
String name = headMap.get(key);
|
||||
|
@ -185,6 +207,11 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验自定义字段
|
||||
* @param data excel数据
|
||||
* @param errMsg 错误信息
|
||||
*/
|
||||
public void validateCustomField(IssueExcelData data, StringBuilder errMsg) {
|
||||
Map<String, List<CustomFieldDao>> customFieldMap = customFields.stream().collect(Collectors.groupingBy(CustomFieldDao::getName));
|
||||
data.getCustomData().forEach((k, v) -> {
|
||||
|
@ -210,6 +237,45 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验并转换平台状态
|
||||
* @param data excel数据
|
||||
* @param errMsg 错误信息
|
||||
*/
|
||||
public void validateAndTransferPlatformStatus(IssueExcelData data, StringBuilder errMsg) {
|
||||
String platformStatus = data.getPlatformStatus();
|
||||
if (StringUtils.isNotEmpty(platformStatus) && CollectionUtils.isNotEmpty(platformStatusList)) {
|
||||
Optional<PlatformStatusDTO> first = platformStatusList.stream().filter(status -> StringUtils.equals(status.getLabel(), platformStatus)).findFirst();
|
||||
if (first.isPresent()) {
|
||||
data.setPlatformStatus(first.get().getValue());
|
||||
} else {
|
||||
errMsg.append(IssueExportHeadField.PLATFORM_STATUS.getName()).append(Translator.get("options_not_exist")).append(";");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验TAPD处理人
|
||||
* @param data excel数据
|
||||
* @param errMsg 错误信息
|
||||
*/
|
||||
public void validateTapdUsers(IssueExcelData data, StringBuilder errMsg) {
|
||||
List<String> tarTapdUsers = data.getTapdUsers();
|
||||
if (CollectionUtils.isNotEmpty(tarTapdUsers) && CollectionUtils.isNotEmpty(tapdUsers)) {
|
||||
tarTapdUsers.forEach(tapdUser -> {
|
||||
Optional<String> first = tapdUsers.stream().filter(user -> StringUtils.equals(user, tapdUser)).findFirst();
|
||||
if (first.isEmpty()) {
|
||||
errMsg.append(Translator.get("tapd_user")).append(Translator.get("options_not_exist")).append(";");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析表格数据 -> excel数据
|
||||
* @param rowData 表格数据
|
||||
* @return excel数据
|
||||
*/
|
||||
private IssueExcelData parseDataToModel(Map<Integer, String> rowData) {
|
||||
IssueExcelData data = new IssueExcelDataFactory().getIssueExcelDataLocal();
|
||||
for (Map.Entry<Integer, String> headEntry : headMap.entrySet()) {
|
||||
|
@ -226,16 +292,28 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
data.setTitle(value);
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(field, IssueExportHeadField.DESCRIPTION.getId())) {
|
||||
data.setDescription(value);
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(field, IssueExportHeadField.PLATFORM_STATUS.getName())) {
|
||||
data.setPlatformStatus(value);
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(field, Translator.get("tapd_user"))) {
|
||||
if (StringUtils.isEmpty(value)) {
|
||||
data.setTapdUsers(null);
|
||||
} else if (value.contains(",")) {
|
||||
data.setTapdUsers(Arrays.stream(value.split(",")).map(String::trim).collect(Collectors.toList()));
|
||||
} else if (value.contains(";")) {
|
||||
data.setTapdUsers(Arrays.stream(value.split(";")).map(String::trim).collect(Collectors.toList()));
|
||||
} else {
|
||||
data.setTapdUsers(List.of(value.trim()));
|
||||
}
|
||||
} else {
|
||||
// 自定义字段
|
||||
if (StringUtils.isNotEmpty(value) && (value.contains(","))) {
|
||||
// 逗号分隔
|
||||
List<String> dataList = Arrays.asList(org.springframework.util.StringUtils.trimAllWhitespace(value).split(","));
|
||||
List<String> dataList = Arrays.stream(value.split(",")).map(String::trim).toList();
|
||||
List<String> formatDataList = dataList.stream().map(item -> "\"" + item + "\"").collect(Collectors.toList());
|
||||
data.getCustomData().put(field, formatDataList);
|
||||
} else if (StringUtils.isNotEmpty(value) && (value.contains(";"))){
|
||||
// 分号分隔
|
||||
List<String> dataList = Arrays.asList(org.springframework.util.StringUtils.trimAllWhitespace(value).split(";"));
|
||||
List<String> dataList = Arrays.stream(value.split(";")).map(String::trim).toList();
|
||||
List<String> formatDataList = dataList.stream().map(item -> "\"" + item + "\"").collect(Collectors.toList());
|
||||
data.getCustomData().put(field, formatDataList);
|
||||
} else {
|
||||
|
@ -246,13 +324,20 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* excel数据 -> issue请求数据
|
||||
* @param issueExcelData excel数据
|
||||
* @return issue请求数据
|
||||
*/
|
||||
private IssuesUpdateRequest convertToIssue(IssueExcelData issueExcelData) {
|
||||
IssuesUpdateRequest issuesUpdateRequest = new IssuesUpdateRequest();
|
||||
issuesUpdateRequest.setTapdUsers(issueExcelData.getTapdUsers());
|
||||
issuesUpdateRequest.setWorkspaceId(request.getWorkspaceId());
|
||||
issuesUpdateRequest.setProjectId(request.getProjectId());
|
||||
issuesUpdateRequest.setThirdPartPlatform(isThirdPlatform);
|
||||
issuesUpdateRequest.setDescription(issueExcelData.getDescription());
|
||||
issuesUpdateRequest.setTitle(issueExcelData.getTitle());
|
||||
issuesUpdateRequest.setPlatformStatus(issueExcelData.getPlatformStatus());
|
||||
if (BooleanUtils.isTrue(issueExcelData.getAddFlag())) {
|
||||
issuesUpdateRequest.setCreator(SessionUtils.getUserId());
|
||||
} else {
|
||||
|
@ -285,10 +370,21 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缺陷存在
|
||||
* @param num 缺陷ID
|
||||
* @param projectId 项目ID
|
||||
* @return issues
|
||||
*/
|
||||
private Issues checkIssueExist(Integer num, String projectId) {
|
||||
return issuesService.checkIssueExist(num, projectId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建自定义字段
|
||||
* @param issueExcelData excel对象
|
||||
* @param issuesUpdateRequest 缺陷请求对象
|
||||
*/
|
||||
private void buildFields(IssueExcelData issueExcelData, IssuesUpdateRequest issuesUpdateRequest) {
|
||||
if (MapUtils.isEmpty(issueExcelData.getCustomData())) {
|
||||
return;
|
||||
|
@ -368,14 +464,9 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
String parseStr = parseCascadingOptionText(customFieldDao.getOptions(), v.toString());
|
||||
customFieldItemDTO.setValue(parseStr);
|
||||
customFieldResourceDTO.setValue(parseStr);
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(type, CustomFieldType.DATE.getValue())) {
|
||||
Date vdate = DateUtils.parseDate(v.toString(), "yyyy/MM/dd");
|
||||
v = DateUtils.format(vdate, "yyyy-MM-dd");
|
||||
customFieldItemDTO.setValue(v.toString());
|
||||
customFieldResourceDTO.setValue("\"" + v + "\"");
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(type, CustomFieldType.DATETIME.getValue())) {
|
||||
Date vdate = DateUtils.parseDate(v.toString());
|
||||
v = DateUtils.format(vdate, "yyyy-MM-dd'T'HH:mm");
|
||||
Date vDate = DateUtils.parseDate(v.toString(), "yyyy-MM-dd HH:mm:ss");
|
||||
v = DateUtils.format(vDate, "yyyy-MM-dd'T'HH:mm");
|
||||
customFieldItemDTO.setValue(v.toString());
|
||||
customFieldResourceDTO.setValue("\"" + v + "\"");
|
||||
} else {
|
||||
|
@ -406,18 +497,29 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
return issuesService.getIssue(issueId).getPlatformId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验字段是否为下拉框
|
||||
* @param type 字段类型
|
||||
* @return boolean
|
||||
*/
|
||||
private Boolean isSelect(String type) {
|
||||
return StringUtils.equalsAnyIgnoreCase(type, CustomFieldType.SELECT.getValue(), CustomFieldType.RADIO.getValue(),
|
||||
CustomFieldType.MULTIPLE_SELECT.getValue(), CustomFieldType.CHECKBOX.getValue(),
|
||||
CustomFieldType.CASCADING_SELECT.getValue(), CustomFieldType.MEMBER.getValue(), CustomFieldType.MULTIPLE_MEMBER.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验字段非法格式
|
||||
* @param type 字段类型
|
||||
* @param value 字段值
|
||||
* @return boolean
|
||||
*/
|
||||
private Boolean isIllegalFormat(String type, Object value) {
|
||||
try {
|
||||
if (StringUtils.equalsAnyIgnoreCase(type, CustomFieldType.DATE.getValue())) {
|
||||
DateUtils.parseDate(value.toString(), "yyyy/MM/dd");
|
||||
DateUtils.parseDate(value.toString(), "yyyy-MM-dd");
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(type, CustomFieldType.DATETIME.getValue())) {
|
||||
DateUtils.parseDate(value.toString());
|
||||
DateUtils.parseDate(value.toString(), "yyyy-MM-dd HH:mm:ss");
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(type, CustomFieldType.INT.getValue())) {
|
||||
Integer.parseInt(value.toString());
|
||||
} else if (StringUtils.equalsAnyIgnoreCase(type, CustomFieldType.FLOAT.getValue())) {
|
||||
|
@ -433,6 +535,12 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否选项中包含该值
|
||||
* @param value 值
|
||||
* @param options 选项
|
||||
* @return boolean
|
||||
*/
|
||||
private Boolean isOptionInclude(Object value, String options) {
|
||||
AtomicReference<Boolean> isInclude = new AtomicReference<>(Boolean.TRUE);
|
||||
if (value instanceof List) {
|
||||
|
@ -443,11 +551,16 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
}
|
||||
});
|
||||
} else {
|
||||
isInclude.set(StringUtils.contains(options, "\"" + value.toString() + "\""));
|
||||
isInclude.set(StringUtils.contains(options, value.toString()));
|
||||
}
|
||||
return isInclude.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否包含导出字段
|
||||
* @param name 导出字段名称
|
||||
* @return boolean
|
||||
*/
|
||||
public Boolean exportFieldsContains(String name) {
|
||||
for (IssueExportHeadField issueExportHeadField : IssueExportHeadField.values()) {
|
||||
if (StringUtils.equals(name, issueExportHeadField.getName())) {
|
||||
|
@ -457,6 +570,12 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析选择类型字段 (文本 -> 值)
|
||||
* @param options 选项
|
||||
* @param tarVal 文本
|
||||
* @return 值
|
||||
*/
|
||||
public String parseOptionText(String options, String tarVal) {
|
||||
if (StringUtils.isEmpty(options)) {
|
||||
return StringUtils.EMPTY;
|
||||
|
@ -475,18 +594,23 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
}
|
||||
return parseArr.toString();
|
||||
} else {
|
||||
tarVal = tarVal + ",";
|
||||
for (Map option : optionList) {
|
||||
String text = option.get("text").toString();
|
||||
String value = option.get("value").toString();
|
||||
if (StringUtils.containsIgnoreCase(tarVal, text + ",")) {
|
||||
tarVal = tarVal.replaceAll(text, value);
|
||||
if (StringUtils.containsIgnoreCase(text, tarVal)) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return tarVal.substring(0, tarVal.length() - 1);
|
||||
return tarVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析级联类型字段(文本 -> 值)
|
||||
* @param cascadingOption 级联选项
|
||||
* @param tarVal 文本
|
||||
* @return 值
|
||||
*/
|
||||
public String parseCascadingOptionText(String cascadingOption, String tarVal) {
|
||||
List<String> values = new ArrayList<>();
|
||||
if (StringUtils.isEmpty(cascadingOption)) {
|
||||
|
@ -510,6 +634,12 @@ public class IssueExcelListener extends AnalysisEventListener<Map<Integer, Strin
|
|||
return values.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配级联层级options
|
||||
* @param options 级联选项
|
||||
* @param tarVal 文本
|
||||
* @return json对象
|
||||
*/
|
||||
private JSONObject findJsonOption(JSONArray options, String tarVal) {
|
||||
if (options.size() == 0) {
|
||||
return null;
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.alibaba.fastjson.JSONArray;
|
|||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.google.common.base.Joiner;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
import io.metersphere.base.mapper.ext.ExtIssueCommentMapper;
|
||||
|
@ -54,6 +55,7 @@ import io.metersphere.service.remote.project.TrackIssueTemplateService;
|
|||
import io.metersphere.service.wapper.TrackProjectService;
|
||||
import io.metersphere.service.wapper.UserService;
|
||||
import io.metersphere.utils.DistinctKeyUtil;
|
||||
import io.metersphere.xpack.track.dto.AttachmentRequest;
|
||||
import io.metersphere.xpack.track.dto.PlatformStatusDTO;
|
||||
import io.metersphere.xpack.track.dto.PlatformUser;
|
||||
import io.metersphere.xpack.track.dto.*;
|
||||
|
@ -799,11 +801,6 @@ public class IssuesService {
|
|||
if (StringUtils.equalsAnyIgnoreCase(customField.getType(), CustomFieldType.RICH_TEXT.getValue(), CustomFieldType.TEXTAREA.getValue())) {
|
||||
fieldDao.setValue(fieldDao.getTextValue());
|
||||
}
|
||||
if (StringUtils.equalsAnyIgnoreCase(customField.getType(), CustomFieldType.DATE.getValue()) && StringUtils.isNotEmpty(fieldDao.getValue()) && !StringUtils.equals(fieldDao.getValue(), "null")) {
|
||||
Date date = DateUtils.parseDate(fieldDao.getValue().replaceAll("\"", StringUtils.EMPTY), "yyyy-MM-dd");
|
||||
String format = DateUtils.format(date, "yyyy/MM/dd");
|
||||
fieldDao.setValue("\"" + format + "\"");
|
||||
}
|
||||
if (StringUtils.equalsAnyIgnoreCase(customField.getType(), CustomFieldType.DATETIME.getValue()) && StringUtils.isNotEmpty(fieldDao.getValue()) && !StringUtils.equals(fieldDao.getValue(), "null")) {
|
||||
Date date = null;
|
||||
if (fieldDao.getValue().contains("T") && fieldDao.getValue().length() == 18) {
|
||||
|
@ -815,7 +812,7 @@ public class IssuesService {
|
|||
} else {
|
||||
date = DateUtils.parseDate(fieldDao.getValue().replaceAll("\"", StringUtils.EMPTY));
|
||||
}
|
||||
String format = DateUtils.format(date, "yyyy/MM/dd HH:mm:ss");
|
||||
String format = DateUtils.format(date, "yyyy-MM-dd HH:mm:ss");
|
||||
fieldDao.setValue("\"" + format + "\"");
|
||||
}
|
||||
if (StringUtils.equalsAnyIgnoreCase(customField.getType(), CustomFieldType.SELECT.getValue(),
|
||||
|
@ -1664,13 +1661,20 @@ public class IssuesService {
|
|||
|
||||
public void issueImportTemplate(String projectId, HttpServletResponse response) {
|
||||
Map<String, String> userMap = baseUserService.getProjectMemberOption(projectId).stream().collect(Collectors.toMap(User::getId, User::getName));
|
||||
// 获取第三方平台自定义字段
|
||||
List<CustomFieldDao> pluginCustomFields = getPluginCustomFields(projectId);
|
||||
// 获取缺陷模板及自定义字段
|
||||
IssueTemplateDao issueTemplate = getIssueTemplateByProjectId(projectId);
|
||||
List<CustomFieldDao> customFields = Optional.ofNullable(issueTemplate.getCustomFields()).orElse(new ArrayList<>());
|
||||
customFields.addAll(pluginCustomFields);
|
||||
// TAPD暂时未拆分插件, 插件字段手动获取
|
||||
if (StringUtils.equals(issueTemplate.getPlatform(), IssuesManagePlatform.Tapd.name())) {
|
||||
customFields.add(buildTapdUserCustomField(projectId));
|
||||
}
|
||||
// 根据自定义字段获取表头
|
||||
List<List<String>> heads = new IssueExcelDataFactory().getIssueExcelDataLocal().getHead(issueTemplate.getIsThirdTemplate(), customFields, null);
|
||||
// 导出空模板, heads->表头, headHandler->表头处理
|
||||
IssueTemplateHeadWriteHandler headHandler = new IssueTemplateHeadWriteHandler(userMap, heads, issueTemplate.getCustomFields());
|
||||
IssueTemplateHeadWriteHandler headHandler = new IssueTemplateHeadWriteHandler(userMap, heads, customFields);
|
||||
new EasyExcelExporter(new IssueExcelDataFactory().getExcelDataByLocal())
|
||||
.exportByCustomWriteHandler(response, heads, null, Translator.get("issue_import_template_name"),
|
||||
Translator.get("issue_import_template_sheet"), headHandler);
|
||||
|
@ -1687,10 +1691,23 @@ public class IssuesService {
|
|||
IssueTemplateDao issueTemplate = getIssueTemplateByProjectId(request.getProjectId());
|
||||
List<CustomFieldDao> customFields = Optional.ofNullable(issueTemplate.getCustomFields()).orElse(new ArrayList<>());
|
||||
customFields.addAll(pluginCustomFields);
|
||||
// 非Local平台需要解析平台状态字段
|
||||
List<PlatformStatusDTO> platformStatus = new ArrayList<>();
|
||||
if (!IssuesManagePlatform.Local.equals(issueTemplate.getPlatform())) {
|
||||
CustomFieldDao customFieldDao = buildPlatformStatusCustomField(request.getWorkspaceId(), request.getProjectId());
|
||||
platformStatus = JSON.parseArray(customFieldDao.getOptions(), PlatformStatusDTO.class);
|
||||
}
|
||||
// TAPD暂时未拆分插件, 插件字段手动获取
|
||||
List<String> tapdUsers = new ArrayList<>();
|
||||
if (StringUtils.equals(issueTemplate.getPlatform(), IssuesManagePlatform.Tapd.name())) {
|
||||
CustomFieldDao tapdField = buildTapdUserCustomField(request.getProjectId());
|
||||
List<JSONObject> jsonObjects = JSON.parseArray(tapdField.getOptions(), JSONObject.class);
|
||||
tapdUsers = jsonObjects.stream().map(item -> item.getString("value")).collect(Collectors.toList());
|
||||
}
|
||||
// 获取本地EXCEL数据对象
|
||||
Class clazz = new IssueExcelDataFactory().getExcelDataByLocal();
|
||||
// IssueExcelListener读取file内容
|
||||
IssueExcelListener issueExcelListener = new IssueExcelListener(request, clazz, issueTemplate.getIsThirdTemplate(), customFields, userMap);
|
||||
IssueExcelListener issueExcelListener = new IssueExcelListener(request, clazz, issueTemplate.getIsThirdTemplate(), customFields, userMap, platformStatus, tapdUsers);
|
||||
try {
|
||||
EasyExcelFactory.read(importFile.getInputStream(), issueExcelListener).sheet().doRead();
|
||||
} catch (IOException e) {
|
||||
|
@ -1718,6 +1735,17 @@ public class IssuesService {
|
|||
IssueTemplateDao issueTemplate = getIssueTemplateByProjectId(request.getProjectId());
|
||||
List<CustomFieldDao> customFields = Optional.ofNullable(issueTemplate.getCustomFields()).orElse(new ArrayList<>());
|
||||
customFields.addAll(pluginCustomFields);
|
||||
// 非Local平台需要展示平台状态字段
|
||||
List<PlatformStatusDTO> platformStatus = new ArrayList<>();
|
||||
if (!IssuesManagePlatform.Local.equals(issueTemplate.getPlatform())) {
|
||||
CustomFieldDao customFieldDao = buildPlatformStatusCustomField(request.getWorkspaceId(), request.getProjectId());
|
||||
customFields.add(customFieldDao);
|
||||
platformStatus = JSON.parseArray(customFieldDao.getOptions(), PlatformStatusDTO.class);
|
||||
}
|
||||
// TAPD暂时未拆分插件, 插件字段手动获取
|
||||
if (StringUtils.equals(issueTemplate.getPlatform(), IssuesManagePlatform.Tapd.name())) {
|
||||
customFields.add(buildTapdUserCustomField(request.getProjectId()));
|
||||
}
|
||||
// 根据自定义字段获取表头内容
|
||||
List<List<String>> heads = new IssueExcelDataFactory().getIssueExcelDataLocal().getHead(issueTemplate.getIsThirdTemplate(), customFields, request);
|
||||
// 获取导出缺陷列表
|
||||
|
@ -1725,9 +1753,9 @@ public class IssuesService {
|
|||
// 解析issue对象数据->excel对象数据
|
||||
List<IssueExcelData> excelDataList = parseIssueDataToExcelData(exportIssues);
|
||||
// 解析excel对象数据->excel列表数据
|
||||
List<List<Object>> data = parseExcelDataToList(heads, excelDataList);
|
||||
List<List<Object>> data = parseExcelDataToList(heads, excelDataList, platformStatus);
|
||||
// 导出EXCEL
|
||||
IssueTemplateHeadWriteHandler headHandler = new IssueTemplateHeadWriteHandler(userMap, heads, issueTemplate.getCustomFields());
|
||||
IssueTemplateHeadWriteHandler headHandler = new IssueTemplateHeadWriteHandler(userMap, heads, customFields);
|
||||
// heads-> 表头内容, data -> 导出EXCEL列表数据, headHandler -> 表头处理
|
||||
new EasyExcelExporter(new IssueExcelDataFactory().getExcelDataByLocal())
|
||||
.exportByCustomWriteHandler(response, heads, data, Translator.get("issue_list_export_excel"),
|
||||
|
@ -1786,6 +1814,11 @@ public class IssuesService {
|
|||
List<String> comments = commentDTOList.stream().map(IssueCommentDTO::getDescription).collect(Collectors.toList());
|
||||
item.setComment(StringUtils.join(comments, ";"));
|
||||
}
|
||||
|
||||
// TAPD平台需展示TAPD处理人
|
||||
if (IssuesManagePlatform.Tapd.name().equals(item.getPlatform())) {
|
||||
item.setTapdUsers(getTapdIssueCurrentOwner(item.getId()));
|
||||
}
|
||||
});
|
||||
// 解析自定义字段
|
||||
buildCustomField(issues, isThirdTemplate, customFields);
|
||||
|
@ -1814,7 +1847,7 @@ public class IssuesService {
|
|||
}
|
||||
}
|
||||
|
||||
private List<List<Object>> parseExcelDataToList(List<List<String>> heads, List<IssueExcelData> excelDataList) {
|
||||
private List<List<Object>> parseExcelDataToList(List<List<String>> heads, List<IssueExcelData> excelDataList, List<PlatformStatusDTO> platformStatus) {
|
||||
List<List<Object>> result = new ArrayList<>();
|
||||
IssueExportHeadField[] exportHeadFields = IssueExportHeadField.values();
|
||||
//转化excel头
|
||||
|
@ -1832,12 +1865,26 @@ public class IssuesService {
|
|||
boolean isSystemField = false;
|
||||
for (IssueExportHeadField exportHeadField : exportHeadFields) {
|
||||
if (StringUtils.equals(head, exportHeadField.getName())) {
|
||||
if (StringUtils.equals(head, IssueExportHeadField.PLATFORM_STATUS.getName())) {
|
||||
String platformVal = exportHeadField.parseExcelDataValue(data);
|
||||
Optional<PlatformStatusDTO> first = platformStatus.stream().filter(status -> StringUtils.equals(status.getValue(), platformVal)).findFirst();
|
||||
if (first.isPresent()) {
|
||||
rowData.add(first.get().getLabel());
|
||||
} else {
|
||||
rowData.add(StringUtils.EMPTY);
|
||||
}
|
||||
} else {
|
||||
rowData.add(exportHeadField.parseExcelDataValue(data));
|
||||
}
|
||||
isSystemField = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isSystemField) {
|
||||
if (StringUtils.equals(head, Translator.get("tapd_user"))) {
|
||||
rowData.add(Joiner.on(";").join(data.getTapdUsers()));
|
||||
continue;
|
||||
}
|
||||
// 自定义字段
|
||||
Object value = customData.get(head);
|
||||
if (value == null || StringUtils.equals(value.toString(), "null")) {
|
||||
|
@ -1925,27 +1972,36 @@ public class IssuesService {
|
|||
}
|
||||
|
||||
private String parseOptionValue(String options, String tarVal) {
|
||||
if (StringUtils.isEmpty(options) || StringUtils.isEmpty(tarVal)) {
|
||||
if (StringUtils.isEmpty(options) || StringUtils.isEmpty(tarVal) || StringUtils.equalsAny(tarVal, "null", "[]")) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
List<String> tarVals = new ArrayList<>();
|
||||
List<String> vals = JSON.parseArray(tarVal, String.class);
|
||||
List<Map> optionList = JSON.parseArray(options, Map.class);
|
||||
for (Map option : optionList) {
|
||||
String text = option.get("text").toString();
|
||||
String value = option.get("value").toString();
|
||||
if (StringUtils.containsIgnoreCase(tarVal, value)) {
|
||||
tarVal = tarVal.replaceAll(value, text);
|
||||
vals.forEach(val -> {
|
||||
if (StringUtils.equals(val, value)) {
|
||||
tarVals.add(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
return tarVal;
|
||||
return tarVals.toString();
|
||||
}
|
||||
|
||||
public String parseCascadingOptionValue(String cascadingOption, String tarVal) {
|
||||
List<String> values = new ArrayList<>();
|
||||
if (StringUtils.isEmpty(cascadingOption)) {
|
||||
if (StringUtils.isEmpty(cascadingOption) || StringUtils.isEmpty(tarVal) || StringUtils.equalsAny(tarVal, "null", "[]")) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
JSONArray options = JSONArray.parseArray(cascadingOption);
|
||||
JSONArray talVals = JSONArray.parseArray(tarVal);
|
||||
JSONArray talVals = new JSONArray();
|
||||
if (tarVal.contains("[") || tarVal.contains("]")) {
|
||||
talVals = JSONArray.parseArray(tarVal);
|
||||
} else {
|
||||
talVals = JSONArray.parseArray("[" + tarVal + "]");
|
||||
}
|
||||
if (options.size() == 0 || talVals.size() == 0) {
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
@ -2086,6 +2142,43 @@ public class IssuesService {
|
|||
return tapdUsers;
|
||||
}
|
||||
|
||||
public CustomFieldDao buildPlatformStatusCustomField(String workspaceId, String projectId) {
|
||||
PlatformIssueTypeRequest platformIssueTypeRequest = new PlatformIssueTypeRequest();
|
||||
platformIssueTypeRequest.setWorkspaceId(workspaceId);
|
||||
platformIssueTypeRequest.setProjectId(projectId);
|
||||
List<PlatformStatusDTO> platformStatus = issuesService.getPlatformStatus(platformIssueTypeRequest);
|
||||
CustomFieldDao customFieldDao = new CustomFieldDao();
|
||||
customFieldDao.setName(Translator.get("platform_status"));
|
||||
customFieldDao.setRequired(false);
|
||||
customFieldDao.setType(CustomFieldType.SELECT.getValue());
|
||||
customFieldDao.setOptions(JSON.toJSONString(platformStatus));
|
||||
return customFieldDao;
|
||||
}
|
||||
|
||||
public CustomFieldDao buildTapdUserCustomField(String projectId) {
|
||||
Project project = projectMapper.selectByPrimaryKey(projectId);
|
||||
IssuesRequest request = new IssuesRequest();
|
||||
request.setProjectId(projectId);
|
||||
request.setWorkspaceId(project.getWorkspaceId());
|
||||
List<Map<String, String>> tapdUsers = new ArrayList<>();
|
||||
List<PlatformUser> tapdProjectUsers = getTapdProjectUsers(request);
|
||||
if (CollectionUtils.isNotEmpty(tapdProjectUsers)) {
|
||||
tapdProjectUsers.forEach(tapdUser -> {
|
||||
Map<String, String> user = new HashMap<>();
|
||||
user.put("text", tapdUser.getUser());
|
||||
user.put("value", tapdUser.getUser());
|
||||
tapdUsers.add(user);
|
||||
});
|
||||
}
|
||||
CustomFieldDao customFieldDao = new CustomFieldDao();
|
||||
customFieldDao.setId(Translator.get("tapd_user"));
|
||||
customFieldDao.setName(Translator.get("tapd_user"));
|
||||
customFieldDao.setRequired(false);
|
||||
customFieldDao.setType(CustomFieldType.MULTIPLE_SELECT.getValue());
|
||||
customFieldDao.setOptions(JSON.toJSONString(tapdUsers));
|
||||
return customFieldDao;
|
||||
}
|
||||
|
||||
@MsAuditLog(module = OperLogModule.TRACK_TEST_CASE, type = OperLogConstants.ASSOCIATE_ISSUE, content = "#msClass.getIssueLogDetails(#caseId, #refId, #issuesId)", msClass = TestCaseIssueService.class)
|
||||
public void insertIssueRelateLog(String issuesId, String caseId, String refId, String refType) {
|
||||
testCaseIssueService.add(issuesId, caseId, refId, refType);
|
||||
|
|
|
@ -46,8 +46,8 @@ issue_import_template_name=Issue_Template
|
|||
issue_import_template_sheet=Template
|
||||
issue_list_export_excel=Issue_Data_Export
|
||||
issue_list_export_excel_sheet=Data
|
||||
date_import_cell_format_comment=The date cell format is YYYY/MM/DD (1999/10/01)
|
||||
datetime_import_cell_format_comment=The date and time cell format is YYYY/MM/DD HH:MM:SS (1999/10/01 10:01:01)
|
||||
date_import_cell_format_comment=The date cell format is YYYY-MM-DD (1999-10-01)
|
||||
datetime_import_cell_format_comment=The date and time cell format is YYYY-MM-DD HH:MM:SS (1999-10-01 01:01:01)
|
||||
int_import_cell_format_comment=cell format: 100001
|
||||
float_import_cell_format_comment=cell format: 24
|
||||
multiple_input_import_cell_format_comment=This field has multiple values. Separate multiple values with commas or semicolons
|
||||
|
@ -55,17 +55,20 @@ cascading_select_import_cell_format_comment=This cell is a cascade selection. Pl
|
|||
options_tips=(format{key:value}, please fill in the corresponding value)Option value:
|
||||
options_key_tips=(format{key:value},please fill in the corresponding key)Option value:
|
||||
# issue import and issue export
|
||||
id=Issue ID
|
||||
title==Title
|
||||
description=Description
|
||||
case_count=Case count
|
||||
comment=Comment
|
||||
issue_resource=Issue resource
|
||||
issue_platform=Issue platform
|
||||
platform_status=Platform status
|
||||
create_time=CreateTime
|
||||
can_not_be_null=Can not be null
|
||||
excel_field_not_exist=Not exist
|
||||
options_not_exist=Incorrect option value
|
||||
format_error=Format error
|
||||
tapd_user=Tapd User
|
||||
# issue status
|
||||
new=new
|
||||
resolved=resolved
|
||||
|
|
|
@ -23,8 +23,8 @@ issue_import_template_name=缺陷模版
|
|||
issue_import_template_sheet=模版
|
||||
issue_list_export_excel=缺陷数据导出
|
||||
issue_list_export_excel_sheet=数据
|
||||
date_import_cell_format_comment=日期类型单元格格式为: YYYY/MM/DD (1999/10/01)
|
||||
datetime_import_cell_format_comment=日期时间类型单元格格式为: YYYY/MM/DD HH:MM:SS (1999/10/01 10:01:01)
|
||||
date_import_cell_format_comment=日期类型单元格格式为: YYYY-MM-DD (1999-10-01)
|
||||
datetime_import_cell_format_comment=日期时间类型单元格格式为: YYYY-MM-DD HH:MM:SS (1999-10-01 01:01:01)
|
||||
int_import_cell_format_comment=整型单元格格式为: 100001
|
||||
float_import_cell_format_comment=浮点单元格格式为: 24
|
||||
multiple_input_import_cell_format_comment=该单元格可输入多个值,多个值请用逗号或分号隔开(v1;v2)
|
||||
|
@ -32,17 +32,20 @@ cascading_select_import_cell_format_comment=该单元格为级联选择,选择
|
|||
options_tips=(格式{key:value},请填写对应的value)选项:
|
||||
options_key_tips=(格式{key:value},请填写对应的key)选项:
|
||||
# issue import and issue export
|
||||
id=缺陷ID
|
||||
title=缺陷标题
|
||||
description=缺陷描述
|
||||
case_count=用例数
|
||||
comment=评论
|
||||
issue_resource=缺陷来源
|
||||
issue_platform=缺陷平台
|
||||
platform_status=平台状态
|
||||
create_time=创建时间
|
||||
can_not_be_null=不能为空
|
||||
excel_field_not_exist=不存在该字段
|
||||
options_not_exist=选项值有误
|
||||
format_error=格式有误
|
||||
tapd_user=Tapd 处理人
|
||||
# issue status
|
||||
new=新建
|
||||
resolved=已解决
|
||||
|
|
|
@ -23,8 +23,8 @@ issue_import_template_name=缺陷模版
|
|||
issue_import_template_sheet=模版
|
||||
issue_list_export_excel=缺陷數據導出
|
||||
issue_list_export_excel_sheet=數據
|
||||
date_import_cell_format_comment=日期單元格格式爲: YYYY/MM/DD (1999/10/01)
|
||||
datetime_import_cell_format_comment=日期時間單元格格式爲: YYYY/MM/DD HH:MM:SS (1999/10/01 10:01:01)
|
||||
date_import_cell_format_comment=日期單元格格式爲: YYYY-MM-DD (1999-10-01)
|
||||
datetime_import_cell_format_comment=日期時間單元格格式爲: YYYY-MM-DD HH:MM:SS (1999-10-01 01:01:01)
|
||||
int_import_cell_format_comment=單元格格式: 100001
|
||||
float_import_cell_format_comment=單元格格式: 24
|
||||
multiple_input_import_cell_format_comment=該單元格可輸入多個值,多個值請用逗號或分號隔開(v1;v2)
|
||||
|
@ -32,17 +32,20 @@ cascading_select_import_cell_format_comment=該單元格爲級聯選擇,選擇
|
|||
options_tips=(格式{key:value},請填寫對應value)選項:
|
||||
options_key_tips=(格式{key:value},請填寫對應key)選項:
|
||||
# issue import and issue export
|
||||
id=缺陷ID
|
||||
title=缺陷標題
|
||||
description=缺陷描述
|
||||
case_count=用例數
|
||||
comment=評論
|
||||
issue_resource=缺陷來源
|
||||
issue_platform=缺陷平臺
|
||||
platform_status=平台狀態
|
||||
create_time=創建時間
|
||||
can_not_be_null=不能爲空
|
||||
excel_field_not_exist=不存在該字段
|
||||
options_not_exist=選項值有誤
|
||||
format_error=格式有誤
|
||||
tapd_user=Tapd 處理人
|
||||
#issue status
|
||||
new=新建
|
||||
resolved=已解決
|
||||
|
|
|
@ -385,6 +385,6 @@ span.ms-top.el-tag.el-tag--info.el-tag--small.el-tag--light span {
|
|||
.el-select__tags .el-tag .el-tag__close.el-icon-close::before {
|
||||
font-size: 24px;
|
||||
position: relative;
|
||||
top: 9px;
|
||||
top: -2px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -50,7 +50,8 @@
|
|||
|
||||
<script>
|
||||
import IssueExportFieldSelectItem from "@/business/issue/components/export/IssueExportFieldSelectItem";
|
||||
import {getIssuePartTemplateWithProject} from "@/api/issue";
|
||||
import {enableThirdPartTemplate, getIssuePartTemplateWithProject} from "@/api/issue";
|
||||
import {getCurrentProjectID} from "@/business/utils/sdk-utils";
|
||||
|
||||
export default {
|
||||
name: "IssueExportFieldSelect",
|
||||
|
@ -63,7 +64,7 @@ export default {
|
|||
{
|
||||
id: 'id',
|
||||
key: 'A',
|
||||
name: 'ID',
|
||||
name: this.$t("test_track.issue.id"),
|
||||
enable: true,
|
||||
disabled: true
|
||||
},
|
||||
|
@ -88,37 +89,37 @@ export default {
|
|||
id: 'creator',
|
||||
key: 'E',
|
||||
name: this.$t("commons.creator"),
|
||||
enable: true
|
||||
enable: false
|
||||
},
|
||||
{
|
||||
id: 'caseCount',
|
||||
key: 'A',
|
||||
name: this.$t("test_track.home.case_size"),
|
||||
enable: true
|
||||
enable: false
|
||||
},
|
||||
{
|
||||
id: 'comment',
|
||||
key: 'B',
|
||||
name: this.$t("commons.comment"),
|
||||
enable: true
|
||||
enable: false
|
||||
},
|
||||
{
|
||||
id: 'resource',
|
||||
key: 'C',
|
||||
name: this.$t("test_track.issue.issue_resource"),
|
||||
enable: true
|
||||
enable: false
|
||||
},
|
||||
{
|
||||
id: 'platform',
|
||||
key: 'D',
|
||||
name: this.$t("test_track.issue.issue_platform"),
|
||||
enable: true
|
||||
enable: false
|
||||
},
|
||||
{
|
||||
id: 'createTime',
|
||||
key: 'E',
|
||||
name: this.$t("commons.create_time"),
|
||||
enable: true
|
||||
enable: false
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -131,12 +132,35 @@ export default {
|
|||
created() {
|
||||
this.loading = true;
|
||||
getIssuePartTemplateWithProject((template) => {
|
||||
if (template.platform && template.platform !== 'Local') {
|
||||
this.customFields.push({
|
||||
id: 'platformStatus',
|
||||
key: '#',
|
||||
name: this.$t("test_track.issue.platform_status"),
|
||||
enable: true
|
||||
});
|
||||
}
|
||||
if (template.platform && template.platform === 'Tapd') {
|
||||
this.customFields.push({
|
||||
id: this.$t("test_track.issue.tapd_current_owner"),
|
||||
key: '&',
|
||||
name: this.$t("test_track.issue.tapd_current_owner"),
|
||||
enable: true
|
||||
});
|
||||
}
|
||||
template.customFields.forEach(item => {
|
||||
item.enable = true;
|
||||
this.customFields.push(item);
|
||||
});
|
||||
this.loading = false;
|
||||
});
|
||||
enableThirdPartTemplate(getCurrentProjectID())
|
||||
.then((res) => {
|
||||
if (res.data) {
|
||||
// 第三方模板
|
||||
this.baseFields = this.baseFields.filter(item => (item.id !== 'description' && item.id !== 'title'));
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
getExportParam() {
|
||||
|
|
|
@ -131,13 +131,13 @@ const TRACK_HEADER = {
|
|||
{id: 'num', key: '1', label: 'test_track.issue.id'},
|
||||
{id: 'title', key: '2', label: 'test_track.issue.title'},
|
||||
{id: 'platformStatus', key: '3', label: 'test_track.issue.platform_status', width: 120},
|
||||
{id: 'platform', key: '4', label: 'test_track.issue.platform'},
|
||||
{id: 'platform', key: '4', label: 'test_track.issue.issue_platform'},
|
||||
{id: 'creatorName', key: '5', label: 'custom_field.issue_creator'},
|
||||
{id: 'resourceName', key: '6', label: 'test_track.issue.issue_resource'},
|
||||
{id: 'description', key: '7', label: 'test_track.issue.description'},
|
||||
{id: 'caseCount', key: '9', label: 'api_test.definition.api_case_number'},
|
||||
{id: 'createTime', key: '8', label: 'commons.create_time'},
|
||||
{id: 'updateTime', key: 'a', label: 'commons.update_time'}
|
||||
{id: 'updateTime', key: '0', label: 'commons.update_time'}
|
||||
],
|
||||
//用例评审
|
||||
TEST_CASE_REVIEW: [
|
||||
|
|
Loading…
Reference in New Issue