一些不靠谱的java.util.List深复制方法

本文探讨了Java中List深复制的几种不靠谱方法及其原因,包括遍历循环复制、使用构造方法复制等,并介绍了一种相对靠谱的序列化深复制方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前探讨过Java数组的深复制问题,现在来说说<一些不靠谱的java.util.List深复制方法>。为什么不说<靠谱的深复制方法>呢?因为在寻找探索<靠谱的深复制方法>的过程中,我发现了这些不靠谱的方法,写下来是希望给自己和他人提个醒,不要犯这样的错误。

 

这是下面要频繁使用的一个JavaBean

 

Java代码  收藏代码
  1. class Person implements Serializable{  
  2.     private int age;  
  3.     private String name;  
  4.       
  5.     public Person(){};  
  6.     public Person(int age,String name){  
  7.         this.age=age;  
  8.         this.name=name;  
  9.     }  
  10.       
  11.     public int getAge() {  
  12.         return age;  
  13.     }  
  14.     public void setAge(int age) {  
  15.         this.age = age;  
  16.     }  
  17.     public String getName() {  
  18.         return name;  
  19.     }  
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.       
  24.     public String toString(){  
  25.         return this.name+"-->"+this.age;  
  26.     }  
  27.       
  28. }  
 

 

后台打印List集合的一个静态方法

 

Java代码  收藏代码
  1. public static <T> void printList(List<T> list){  
  2.     System.out.println("---begin---");  
  3.     for(T t : list){  
  4.         System.out.println(t);  
  5.     }  
  6.     System.out.println("---end---");  
  7. }  
 

 

后台打印数组的一个静态方法

 

Java代码  收藏代码
  1. public static <T> void printArray(T[] array){  
  2.     System.out.println("---begin---");  
  3.     for(T t : array){  
  4.         System.out.println(t);  
  5.     }  
  6.     System.out.println("---end---");  
  7. }  
 

 

这是数据源集合,下面将通过各种方法企图来深复制该List集合中的元素

 

Java代码  收藏代码
  1. List<Person> srcList=new ArrayList<Person>();  
  2. Person p1=new Person(20,"123");  
  3. Person p2=new Person(21,"ABC");  
  4. Person p3=new Person(22,"abc");  
  5. srcList.add(p1);  
  6. srcList.add(p2);  
  7. srcList.add(p3);  
  

1、遍历循环复制

 

Java代码  收藏代码
  1. List<Person> destList=new ArrayList<Person>(srcList.size());  
  2. for(Person p : srcList){  
  3.     destList.add(p);  
  4. }  
  5.           
  6. printList(destList);  
  7. srcList.get(0).setAge(100);  
  8. printList(destList);  

 

 上面的代码在add时候,并没有new Person()操作。因此,在srcList.get(0).setAge(100);破坏源数据时,目标集合destList中元素的输出同样受到了影响,原因是浅复制造成的。

 

后台输出结果代码  收藏代码
  1. ---begin---  
  2. 123-->20  
  3. ABC-->21  
  4. abc-->22  
  5. ---end---  
  6. ---begin---  
  7. 123-->100  
  8. ABC-->21  
  9. abc-->22  
  10. ---end---  
 

2、使用List实现类的构造方法

 

Java代码  收藏代码
  1. List<Person> destList=new ArrayList<Person>(srcList);  
  2. printList(destList);  
  3. srcList.get(0).setAge(100);  
  4. printList(destList);  

 

 通过ArrayList的构造方法来复制集合内容,同样是浅复制,在修改了源数据集合后,目标数据集合对应内容也发生了改变。在查阅资料的过程中,看到有人说这种方式 能实现深复制,其实这是不对的。对于某些特殊的元素,程序运行的结果形似深复制,其实还是浅复制。具体一会儿再说。

 

后台打印输出代码  收藏代码
  1. ---begin---  
  2. 123-->20  
  3. ABC-->21  
  4. abc-->22  
  5. ---end---  
  6. ---begin---  
  7. 123-->100  
  8. ABC-->21  
  9. abc-->22  
  10. ---end---  
 

3、使用list.addAll()方法

 

Java代码  收藏代码
  1. List<Person> destList=new ArrayList<Person>();  
  2. destList.addAll(srcList);  
  3. printList(destList);  
  4. srcList.get(0).setAge(100);  
  5. printList(destList);  

 

 java.util.list.addAll()方法同样是浅复制

 

后台打印输出代码  收藏代码
  1. ---begin---  
  2. 123-->20  
  3. ABC-->21  
  4. abc-->22  
  5. ---end---  
  6. ---begin---  
  7. 123-->100  
  8. ABC-->21  
  9. abc-->22  
  10. ---end---  
 

4、使用System.arraycopy()方法

 

Java代码  收藏代码
  1. Person[] srcPersons=srcList.toArray(new Person[0]);  
  2. Person[] destPersons=new Person[srcPersons.length];  
  3. System.arraycopy(srcPersons, 0, destPersons, 0, srcPersons.length);  
  4. //destPersons=srcPersons.clone();  
  5.   
  6. printArray(destPersons);  
  7. srcPersons[0].setAge(100);  
  8. printArray(destPersons);  
  9.   
  10. List<Person> destList=Arrays.asList(destPersons);  
  11. printList(destList);  

这种方式虽然比较变态,但是起码证明了System.arraycopy()方法和clone()是不能对List集合进行深复制的。

 

 

5、使用序列化方法(相对靠谱的方法)

 

Java代码  收藏代码
  1. public static <T> List<T> deepCopy(List<T> src) throws IOException, ClassNotFoundException {  
  2.     ByteArrayOutputStream byteOut = new ByteArrayOutputStream();  
  3.     ObjectOutputStream out = new ObjectOutputStream(byteOut);  
  4.     out.writeObject(src);  
  5.   
  6.     ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());  
  7.     ObjectInputStream in = new ObjectInputStream(byteIn);  
  8.     @SuppressWarnings("unchecked")  
  9.     List<T> dest = (List<T>) in.readObject();  
  10.     return dest;  
  11. }  
 

 

Java代码  收藏代码
  1. List<Person> destList=deepCopy(srcList);  
  2. printList(destList);  
  3. srcList.get(0).setAge(100);  
  4. printList(destList);  

这是比较靠谱的做法,听说是国外某位程序大师提出来的。实际运行的结果也同样是正确的。

后台打印输出代码  收藏代码
  1. ---begin---  
  2. 123-->20  
  3. ABC-->21  
  4. abc-->22  
  5. ---end---  
  6. ---begin---  
  7. 123-->20  
  8. ABC-->21  
  9. abc-->22  
  10. ---end---  
 

 

其实,上面这些不靠谱List深复制的做法在某些情况是可行的,这也是为什么有些人说这其中的一些做法是可以实现深复制的原因。哪些情况下是可行(本质上可能还是不靠谱)的呢?比如List<String>这样的情况。我上面使用的是List<Person>,它和List<String>的区别就在于Person类和String类的区别,Person类提供了破坏数据的2个setter方法。因此,在浅复制的情况下,源数据被修改破坏之后,使用相同引用指向该数据的目标集合中的对应元素也就发生了相同的变化。

因此,在需求要求必须深复制的情况下,要是使用上面提到的方法,请确保List<T>中的T类对象是不易被外部修改和破坏的。

对于以下代码,我想要测试函数queryCardByItsmApplyCode,接口应该是什么呢? package com.jd.jacp.impl.rest.space.web; import com.alibaba.csp.sentinel.EntryType; import com.alibaba.csp.sentinel.annotation.SentinelResource; import com.alibaba.csp.sentinel.slots.block.BlockException; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.google.gson.Gson; import com.jd.jacp.common.dto.Result; import com.jd.jacp.common.entity.PageData; import com.jd.jacp.common.entity.QueryWorkbenchDto; import com.jd.jacp.common.entity.QueryWorkbenchVo; import com.jd.jacp.common.exception.ServiceException; import com.jd.jacp.common.tool.AssertUtils; import com.jd.jacp.common.tool.BeanMapper; import com.jd.jacp.common.tool.DateUtils; import com.jd.jacp.common.vo.ResultGenerator; import com.jd.jacp.common.vo.SaveDateVO; import com.jd.jacp.common.vo.TestQueryCardBySprintIdVO; import com.jd.jacp.common.vo.UpdateField; import com.jd.jacp.demand.api.vo.DemandResponse; import com.jd.jacp.demand.vo.WorkbenchTypeEnum; import com.jd.jacp.impl.common.BaseApiController; import com.jd.jacp.impl.common.aop.TokenValidation; import com.jd.jacp.impl.rest.space.dto.CardQuery; import com.jd.jacp.impl.rest.space.dto.ProjectCardQuery; import com.jd.jacp.impl.rest.space.dto.ProjectCardResponse; import com.jd.jacp.impl.rest.space.dto.SpaceCardQuery; import com.jd.jacp.impl.rest.space.validator.SpaceValidator; import com.jd.jacp.space.api.ISpaceApiService; import com.jd.jacp.space.api.vo.*; import com.jd.jacp.space.service.IBizSpaceCardCommitService; import com.jd.jacp.space.service.IBizSpaceCardReleaseService; import com.jd.jacp.space.service.IBizSpaceCardService; import com.jd.jacp.space.vo.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.util.Arrays; import java.util.Date; import java.util.List; import java.util.Objects; /** * 团队空间-卡片接口 * * @author chenhengyu * @index 4 */ @RestController @RequestMapping("${api.gateway}") @Slf4j public class CardApiController extends BaseApiController { @Autowired private ISpaceApiService service; @Autowired private IBizSpaceCardService cardService; @Autowired private SpaceValidator spaceValidator; @Autowired private IBizSpaceCardCommitService cardCommitService; @Autowired private IBizSpaceCardReleaseService spaceCardReleaseService; private IBizSpaceCardService iBizSpaceCardService; /** * 创建卡片 * * @param request * @return */ @PostMapping("/space/{spaceId}/card") public Result<CardResponse> createCard(@PathVariable("spaceId") Integer spaceId, @RequestBody @Validated CardRequest request) { request.setSpaceId(spaceId); spaceValidator.assertViewSpace(getAppCode(), spaceId, getOptUser()); return ResultGenerator.success(service.createCard(request, getOptUser())); } /** * 根据卡片ID修改卡片状态 * * @param request * @return */ @PutMapping("/space/{spaceId}/card/{cardId}/status") @SentinelResource(value = "space#card#status", entryType = EntryType.IN) public Result<Boolean> updateCard(@PathVariable("spaceId") Integer spaceId, @PathVariable("cardId") Integer cardId, @RequestBody @Validated CardStatusRequest request) throws BlockException { request.setId(cardId); spaceValidator.assertViewSpace(getAppCode(), spaceId, getOptUser()); return ResultGenerator.success(service.updateCardStatus(request, getOptUser())); } /** * 修改卡片状态到阶段的第一个状态 * * @param request * @return */ @PutMapping("/space/{spaceId}/card/{cardId}/stage") @SentinelResource(value = "space#card#stage", entryType = EntryType.IN) public Result<Boolean> moveToStageFirstStatus(@PathVariable("spaceId") Integer spaceId, @PathVariable("cardId") Integer cardId, @RequestBody @Validated CardStageRequest request) throws BlockException { log.info("收到请求修改卡片状态到阶段的第一个状态,接口调用入参:spaceId={},cardId={},request={}", spaceId, cardId, request); request.setId(cardId); spaceValidator.assertViewSpace(getAppCode(), spaceId, getOptUser()); CardStatusResponse firstStatus = service.queryCardActiveStatusAndStage(spaceId) .stream() .filter(item -> Objects.equals(item.getStageId(), request.getStageId())) .findFirst() .orElse(null); AssertUtils.notNull(firstStatus, "该阶段下存在可用的状态。"); CardStatusRequest statusRequest = new CardStatusRequest() .setId(request.getId()) .setStatusId(firstStatus.getStatusCode()); return ResultGenerator.success(service.updateCardStatus(statusRequest, getOptUser())); } /** * 修改卡片状态到当前阶段的下一个状态或目标阶段的第一个状态 * 如果卡片当前阶段存在下一个状态则卡片进入下一个状态;如果卡片已经是当前阶段最后一个状态则进入目标阶段的第一个状态 * * @param request * @return */ @PutMapping("/space/{spaceId}/card/{cardId}/moveToNextStatus") @SentinelResource("space#card#moveToNextStatus") public Result<Boolean> moveToNextStatus(@PathVariable("spaceId") Integer spaceId, @PathVariable("cardId") Integer cardId, @RequestBody @Validated CardStageRequest request) throws BlockException { log.info("收到Jtest 应用提测通过的回调请求:{},{},{},{}", spaceId, cardId, request, System.currentTimeMillis()); request.setId(cardId); return ResultGenerator.success(service.moveToNextStatus(spaceId, request, getOptUser(), null)); } /** * 根据卡片ID获取卡片信息 * * @param cardId * @return */ @GetMapping(value = "/space/card/{cardId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Result<CardResponse> getCard(@PathVariable("cardId") Integer cardId) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); return ResultGenerator.success(card); } @GetMapping(value = "/space/card/workbench", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Result<PageData<QueryWorkbenchDto>> getCardWorkbench(@Validated QueryWorkbenchVo workbenchVo) { if (!WorkbenchTypeEnum.getAllValue().contains(workbenchVo.getTabType())) { throw new ServiceException("工作台数据查询异常,查询类型数据错误"); } PageData<QueryWorkbenchDto> cardWorkbench = cardService.getCardWorkbench(workbenchVo); return ResultGenerator.success(cardWorkbench); } @GetMapping(value = "/space/cardTask/workbench", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Result<PageData<QueryWorkbenchDto>> getPersonHourWorkbench(@Validated QueryWorkbenchVo workbenchVo) { if (!WorkbenchTypeEnum.getAllValue().contains(workbenchVo.getTabType())) { throw new ServiceException("工作台数据查询异常,查询类型数据错误"); } PageData<QueryWorkbenchDto> personHourWorkbench = cardService.getPersonHourWorkbench(workbenchVo); return ResultGenerator.success(personHourWorkbench); } /** * 根据卡片code获取卡片信息 * * @param cardCode * @return */ @GetMapping("/space/card/code/{cardCode}") public Result<CardResponse> getCardByCode(@PathVariable("cardCode") String cardCode) { CardResponse card = service.getCardByCode(cardCode); AssertUtils.notNull(card, "卡片{cardCode}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); log.info("/space/card/code/{} ;card : {}", cardCode, new Gson().toJson(card)); return ResultGenerator.success(card); } /** * 批量根据卡片code获取卡片信息 * * @param cardCodes * @return */ @GetMapping("/space/card/code/batch/{cardCodes}") public Result<List<CardResponse>> batchGetCardByCode(@PathVariable("cardCodes") List<String> cardCodes) { List<CardResponse> cards = service.getCardByCodes(cardCodes); return ResultGenerator.success(cards); } /** * 保存需求与提交相关信息 * * @param commitVo * @return\ */ @PostMapping("space/card/saveCommitInfo") public Result saveCommitInfo(@RequestBody CommitVo commitVo) { if (CollectionUtils.isEmpty(commitVo.getCodeList())) { return Result.success(); } cardCommitService.saveCommitInfo(commitVo); return ResultGenerator.success(); } /** * 获取子卡片信息 * * @param cardId 卡片ID * @return */ @GetMapping("/space/card/{cardId}/children") public Result<List<CardResponse>> queryChildren(@PathVariable("cardId") Integer cardId) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); return ResultGenerator.success(service.queryChildren(cardId)); } /** * 查询某erp参与的所有状态为未完成且所属迭代未归档的卡片 * * @param erp * @return */ @GetMapping("/space/card/unfinished") public Result<List<CardResponse>> getUnfinishedCardsByErp(@RequestParam("erp") String erp) { spaceValidator.assertCurrentUser(getAppCode(), userHelper.getUserByErp(erp)); return ResultGenerator.success(service.getUnfinishedCard(erp)); } /** * 查询某erp的所有卡片 * * @param erp * @param keyword 关键词,支持卡片编码全匹配和卡片名称的模糊匹配 * @param archived 卡片所在迭代是否归档。0-未归档,1-已归档,null-全部 * @return */ @GetMapping("/space/card") public Result<List<CardResponse>> getCardsByErp( @RequestParam("erp") String erp, @RequestParam(value = "keyword", required = false) String keyword, @RequestParam(value = "archived", required = false) Integer archived) { spaceValidator.assertCurrentUser(getAppCode(), userHelper.getUserByErp(erp)); return ResultGenerator.success(service.queryCard(erp, keyword, archived)); } /** * 获取需求对应的卡片信息 * * @param demandId 需求ID * @return */ @GetMapping("/space/card/demand/{demandId}") public Result<CardResponse> getCardByDemandId(@PathVariable("demandId") Integer demandId) { CardResponse card = service.getCardByDemandId(demandId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); return ResultGenerator.success(card); } /** * 查询指定迭代的所有卡片 * * @param sprintId 迭代ID * @return */ @GetMapping("/space/sprint/{sprintId}/card") public Result<List<CardResponse>> getCardsBySprint(@PathVariable("sprintId") Integer sprintId) { // service.getSprint(sprintId); SprintResponse sprint = service.getSprint(sprintId); if (Objects.nonNull(sprint)) { spaceValidator.assertViewSpace(getAppCode(), sprint.getSpaceId(), getOptUser()); } return ResultGenerator.success(service.queryCardBySprintId(sprintId)); } /** * 根据项目ID查询相关卡片列表 * * @param projectId 项目ID * @return */ @GetMapping("/space/card/project/{projectId}") public Result<List<CardResponse>> queryCardsByProjectId(@PathVariable("projectId") String projectId) { return ResultGenerator.success(service.queryCardsByProjectId(projectId)); } /** * 团队空间卡片筛选 * * @param query 查询条件 */ @PostMapping("space/{spaceId}/card/query") public Result<Page<CardResponse>> querySpaceCardByFilter(@PathVariable("spaceId") Integer spaceId, @RequestBody @Validated SpaceCardQuery query) { spaceValidator.assertViewSpace(getAppCode(), spaceId, getOptUser()); // 1 参数转化 log.info("卡片列表查询:参数转化"); CardQueryVO queryVO = BeanMapper.copyProperties(query, CardQueryVO.class); queryVO.setSpaceId(spaceId); queryVO.setKeyword(query.getKeyword()); queryVO.setOwner(query.getOwnerErp()); if (!StringUtils.isEmpty(query.getTaskProcessorErp())) { queryVO.setProcessorList(Arrays.asList(query.getTaskProcessorErp())); } queryVO.setStageIds(query.getStageIds()); queryVO.setCardStates(query.getStatusIds()); queryVO.setArchived(query.getArchived()); queryVO.setSprintId(query.getSprintId()); queryVO.setCreators(query.getCreatorErp()); queryVO.setTagNames(query.getTagNames()); queryVO.setPriority(query.getPriority()); // 条件查询命中的所有靠谱IDS log.info("卡片列表查询:查询命中卡片"); Page<CardList> cardPage = cardService.queryCardList(query.buildPage(), getOptUser(), queryVO); Page<CardResponse> result = new Page<>(); result.setTotal(cardPage.getTotal()); result.setCurrent(cardPage.getCurrent()); result.setSize(cardPage.getSize()); result.setRecords(CardResponse.of(cardPage.getRecords())); return ResultGenerator.success(result); } /** * 项目卡片筛选 * * @param query 查询条件 */ @PostMapping(value = "space/card/project/query", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Result<Page<ProjectCardResponse>> queryProjectCardByFilter(@RequestBody @Validated ProjectCardQuery query) { // 1 参数转化 log.info("卡片列表查询:参数转化"); CardQueryVO queryVO = BeanMapper.copyProperties(query, CardQueryVO.class); log.info("参数信息projectId的值:{}", query.getProjectId()); queryVO.setPmpProjectId(query.getProjectId()); log.info("参数信息keyWord的值:{}", query.getKeyWord()); queryVO.setKeyword(query.getKeyWord()); log.info("参数信息creatorErp的值:{}", query.getCreatorErp()); queryVO.setCreators(query.getCreatorErp()); log.info("参数信息projectLock的值:{}", query.getProjectLock()); queryVO.setProjectLock(query.getProjectLock()); if (Objects.nonNull(query.getDemandIdFilterType())) { QueryFilter filter = QueryFilter.builder() .columnName("demand_id") .filterType(query.getDemandIdFilterType().toString()) .build(); queryVO.setQueryFilters(Arrays.asList(filter)); } int size = queryVO.getQueryFilters().size(); log.info("参数信息queryFilters的大小:{}", size); if (size > 0) { List<QueryFilter> queryFilters = queryVO.getQueryFilters(); for (QueryFilter queryFilter : queryFilters) { log.info("参数信息queryFilter的值:{}", queryFilter); } } // 条件查询命中的所有靠谱IDS log.info("卡片列表查询:查询命中卡片"); Page<CardList> cardPage = cardService.queryConditionTreeCardList(query.buildPage(), getOptUser(), queryVO); Page<ProjectCardResponse> result = new Page<>(); result.setTotal(cardPage.getTotal()); result.setCurrent(cardPage.getCurrent()); result.setSize(cardPage.getSize()); result.setRecords(ProjectCardResponse.of(cardPage.getRecords())); return ResultGenerator.success(result); } /** * 获取卡片备注信息 * * @param cardId 卡片ID * @return */ @GetMapping("/space/card/{cardId}/remark") public Result<List<CardRemarkResponse>> queryCardRemark(@PathVariable("cardId") Integer cardId) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); return ResultGenerator.success(service.queryCardRemarkByCardId(cardId)); } /** * 增加卡片备注 * * @param cardId 卡片ID * @return */ @PostMapping("/space/card/{cardId}/remark") public Result<String> addCardRemark(@PathVariable("cardId") Integer cardId, @RequestBody CardRemarkRequest remarkRequest) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); remarkRequest.setCardId(cardId); service.addCardRemark(remarkRequest, getOptUser()); return ResultGenerator.success(); } /** * 获取卡片发布信息 * * @param cardId 卡片ID * @return */ @GetMapping("/space/card/{cardId}/release") public Result<CardReleaseResponse> getCardRelease(@PathVariable("cardId") Integer cardId) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); return ResultGenerator.success(service.getCardRelease(cardId)); } /** * 修改卡片发布信息 * * @param cardId 卡片ID * @return */ @PutMapping("/space/card/{cardId}/release") public Result<String> addCardRelease(@PathVariable("cardId") Integer cardId, @RequestBody CardReleaseRequest releaseRequest) { log.info("收到修改卡片发布信息的的回调 cardId:{},CardReleaseRequest:{}", cardId, releaseRequest); CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); releaseRequest.setCardId(cardId); service.updateCardRelease(releaseRequest, getOptUser()); return ResultGenerator.success(); } /** * 获取卡片操作历史 * * @param cardId 卡片ID * @param actionTypes 操作类型 * @return */ @GetMapping("/space/card/{cardId}/history") public Result<List<CardHistoryResponse>> queryCardLog(@PathVariable("cardId") Integer cardId, @RequestParam Integer[] actionTypes) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); return ResultGenerator.success(service.queryCardHistory(cardId, actionTypes, getOptUser())); } /** * 获取卡片标签信息 * * @param cardId 卡片ID * @return */ @GetMapping("/space/card/{cardId}/tag") public Result<List<SpaceTagResponse>> queryCardTag(@PathVariable("cardId") Integer cardId) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); return ResultGenerator.success(service.queryCardTag(cardId)); } /** * 批量获取卡片标签信息 * * @param cardIds 卡片ID * @return */ @GetMapping("/space/card/batch/{cardIds}/tag") public Result<List<SpaceTagResponse>> batchQueryCardTag(@PathVariable("cardIds") List<Integer> cardIds) { List<SpaceTagResponse> spaceTagResponses = service.batchQueryCardTag(cardIds); return ResultGenerator.success(spaceTagResponses); } /** * 新增卡片标签信息 * * @param cardId 卡片ID * @return */ @PostMapping("/space/card/{cardId}/tag/{tagId}") public Result<Boolean> addCardTag(@PathVariable("cardId") Integer cardId, @PathVariable("tagId") Integer tagId) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); return ResultGenerator.success(service.addCardTag(cardId, tagId, getOptUser())); } /** * 删除卡片标签信息 * * @param cardId 卡片ID * @return */ @DeleteMapping("/space/card/{cardId}/tag/{tagId}") public Result<Boolean> removeCardTag(@PathVariable("cardId") Integer cardId, @PathVariable("tagId") Integer tagId) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); return ResultGenerator.success(service.removeCardTag(cardId, tagId, getOptUser())); } /** * 修改一个卡片信息 * * @param cardId * @param taskRequest * @return */ @PutMapping(value = {"/agile/space/card/{cardId}"}) public Result<Boolean> updateTask(@PathVariable("cardId") Integer cardId, @RequestBody List<UpdateField> taskRequest) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); spaceValidator.assertViewSpace(getAppCode(), card.getSpaceId(), getOptUser()); return ResultGenerator.success(service.updateCard(cardId, card.getSpaceId(), taskRequest, getOptUser())); } /** * 根据erp和时间区间查询任务所属的卡片和任务信息 * * @param erp * @param startDate * @param endDate * @return 卡片和任务信息 */ @GetMapping("/space/cardTask") public Result<List<CardTaskResponse>> queryCardTaskByErp(@RequestParam("erp") String erp, @RequestParam("startDate") long startDate, @RequestParam("endDate") long endDate) { Date startDateTemp = new Date(startDate); Date endDateTemp = new Date(endDate); if (DateUtils.betweenDays(startDateTemp, endDateTemp) > 90) { return ResultGenerator.badRequest("开始日期和结束日期能超过90天"); } return ResultGenerator.success(service.queryCardTaskByErpAndTime(erp, startDateTemp, endDateTemp)); } /** * 根据卡片ID批量获取卡片信息 * * @param cardQuery * @return */ @PostMapping("/space/card/query") public Result<List<CardResponse>> queryCards(@RequestBody CardQuery cardQuery) { List<CardResponse> cards = service.queryCardByBatchIds(cardQuery.getCardIds()); return ResultGenerator.success(cards); } @PostMapping("/space/card/queryByCodes") public Result<List<CardResponse>> queryByCodes(@RequestBody List<String> codes) { List<CardResponse> cards = service.getCardByCodes(codes); return ResultGenerator.success(cards); } /** * 根据卡片ID批量获取需求信息 * * @param cardQuery * @return */ @PostMapping("/space/demand/query") public Result<List<DemandResponse>> queryDemandByCardIds(@RequestBody CardQuery cardQuery) { List<DemandResponse> demandResponseList = service.queryDemandByCardIds(cardQuery.getCardIds()); return ResultGenerator.success(demandResponseList); } /** * 取消卡片的项目关联 * * @param cardId * @param projectId * @return */ @DeleteMapping(value = "/space/card/{cardId}/project/{projectId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) public Result<Boolean> removeCardProjectRelation(@PathVariable("cardId") Integer cardId, @PathVariable("projectId") String projectId, @RequestParam(value = "remark", required = false) String remark) { CardResponse card = service.getCard(cardId); AssertUtils.notNull(card, "卡片{cardId}存在!"); boolean result = cardService.removeProjectRelation(cardId, card.getSprintId(), projectId, getOptUser(), remark); return ResultGenerator.success(result); } /** * 卡片和项目绑定(项目管理专用,确认时调用) * * @param cardId * @param projectId * @return * @ignore */ @PutMapping("/space/card/{cardId}/project/{projectId}") public Result<Boolean> bindCardProjectRelation(@PathVariable("cardId") Integer cardId, @PathVariable("projectId") String projectId) { boolean result = cardService.bindProjectRelation(cardId, projectId, getOptUser()); return ResultGenerator.success(result); } /** * 根据任务人所在部门code查询部门卡片 */ @PostMapping("/space/card") public Result<List<CardWithDeptResponse>> queryCardsByOrg(@RequestBody @Validated CardWithDeptRequest query) { if (DateUtils.betweenDays(query.getStartDate(), query.getEndDate()) > 90) { return ResultGenerator.badRequest("开始日期和结束日期能超过90天"); } spaceValidator.assertOrgId(getAppCode(), query.getOrgId(), getOptUser()); List<CardWithDeptResponse> result = service.queryCardsByTaskOrgId(query); return ResultGenerator.success(result); } /** * 批量删除卡片(暂时未开放,) * 传参{"cardIdList":[1]} * * @param * @return * @ignore */ // @DeleteMapping("/space/{spaceId}/card") // public Result deleteCard(@PathVariable("spaceId") Integer spaceId, // @RequestBody List<Integer> cardIdList) { // spaceValidator.assertViewSpace(getAppCode(), spaceId, getOptUser()); // // service.logicDeleteCardList(spaceId, cardIdList, getOptUser()); // // return ResultGenerator.genSuccessResult(); // } @PostMapping("/space/card/saveCaseEndDate") public Result saveCaseEndDate(@RequestBody SaveDateVO saveDateVO) { log.info("开始保存【{}】提测评审完成时间", saveDateVO.getCardIdList()); spaceCardReleaseService.saveRealCaseEndDate(saveDateVO.getCardIdList()); return ResultGenerator.success(); } @PostMapping("/card/updateCardRealDateBySprintId") public Result updateCardRealDateBySprintId(@RequestBody List<CardRealDateVO> list) { cardService.updateCardRealDateBySprintId(list); return ResultGenerator.success(); } @GetMapping("/space/v1/getDelayedCards") public Result getDelayedCards(@RequestParam("spaceCodes") List<String> spaceCodes, @RequestParam("delayedTime") Integer delayedTime) { return ResultGenerator.success(cardService.getDelayedCards(spaceCodes, delayedTime)); } @PostMapping("/space/v1/TestQueryCardBySprintId") @SentinelResource(value = "rest#space#card#TestQueryCardBySprintId", entryType = EntryType.IN) public Result TestQueryCardBySprintId(@RequestBody @Validated TestQueryCardBySprintIdVO queryVo) { if (queryVo.getSprintId() == null) { throw new ServiceException("迭代id能为空"); } return ResultGenerator.success(cardService.TestQueryCardBySprintId(queryVo)); } @PostMapping("/space/v1/queryCardByItsmApplyCode") public Result queryCardByItsmApplyCode(@RequestParam("itsmApplyCode") String itsmApplyCode){ if(itsmApplyCode.equals("")){ throw new ServiceException("ITSM流程编码能为空"); } return ResultGenerator.success(cardService.queryCardByItsmApplyCode(itsmApplyCode)); } @PostMapping("/space/v1/TestQueryCardBySprintIds") @SentinelResource(value = "rest#space#card#TestQueryCardBySprintId", entryType = EntryType.IN) public Result TestQueryCardBySprintIds(@RequestBody @Validated TestQueryCardBySprintIdVO queryVo) { if (queryVo.getSprintIds() == null) { throw new ServiceException("迭代id集合能为空"); } return ResultGenerator.success(cardService.TestQueryCardBySprintId(queryVo)); } /** * 根据卡片code获取卡片信息 * * @param cardCode * @return */ @GetMapping("/v1/space/card/getCardByCode") @TokenValidation @SentinelResource(value = "rest#space#card#getCardByCode", entryType = EntryType.IN) public Result<CardResponse> getCardByCodeV1(@RequestParam("cardCode") String cardCode) throws BlockException { CardResponse card = service.getCardByCode(cardCode); return ResultGenerator.success(card); } }
最新发布
08-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值