无法找到匹配方法:JIRA/Groovy脚本字段计算状态耗时报错
问题分析
你的脚本明显没写完(item.created.getTime...后面的代码缺失),而且逻辑上只考虑了当前时间和变更时间的差,没处理状态变更的完整时间线——要准确计算工单在某状态的停留时长,得跟踪进入状态和离开状态的时间点才行。
先把你提供的不完整代码贴出来:
我尝试计算JIRA工单在某一状态下停留的时长,但遇到了错误。以下是用于脚本字段的Groovy脚本:
import com.atlassian.jira.component.ComponentAccessor def changeHistoryManager = ComponentAccessor.changeHistoryManager def currentStatusName = issue?.status?.name def rt = [0L] changeHistoryManager.getChangeItemsForField (issue, "status").reverse().each {item -> def timeDiff = System.currentTimeMillis() - item.created.getTime...
解决方案
根据你的需求,分两种场景给你提供完整的可运行脚本:
场景1:计算工单当前状态的停留时长
如果要统计工单从最后一次进入当前状态到现在的时长,用这个脚本:
import com.atlassian.jira.component.ComponentAccessor def changeHistoryManager = ComponentAccessor.changeHistoryManager def issueCreatedDate = issue.created.getTime() def currentTime = System.currentTimeMillis() def totalDuration = 0L // 获取所有状态变更记录,按时间正序排列 def statusChanges = changeHistoryManager.getChangeItemsForField(issue, "status") if (statusChanges.isEmpty()) { // 边界情况:工单从未变更过状态,时长从创建到现在 totalDuration = currentTime - issueCreatedDate } else { def currentStatus = issue.status.name def lastEnterTime = issueCreatedDate // 遍历所有状态变更,找到最后一次进入当前状态的时间 statusChanges.each { change -> def toStatus = change.toString def changeTime = change.created.getTime() if (toStatus == currentStatus) { lastEnterTime = changeTime } } // 计算从进入当前状态到现在的时长 totalDuration = currentTime - lastEnterTime } // 转换为友好的小时格式(可改成分钟/天,调整除数即可) def hours = totalDuration / (1000 * 60 * 60) return String.format("%.2f小时", hours)
场景2:计算工单在指定状态的总停留时长(多次进入累加)
如果要统计工单历史上所有进入目标状态的时长总和(比如多次进入"In Progress"的时间加起来),用这个脚本:
import com.atlassian.jira.component.ComponentAccessor def changeHistoryManager = ComponentAccessor.changeHistoryManager def targetStatusName = "In Progress" // 替换成你要统计的状态名称 def issueCreatedDate = issue.created.getTime() def currentTime = System.currentTimeMillis() def totalDuration = 0L def statusChanges = changeHistoryManager.getChangeItemsForField(issue, "status") def statusTimeline = [] // 把工单创建时间作为初始状态的时间点加入时间线 statusTimeline.add([status: issue.getStatusObject().getOriginalStatus().name, time: issueCreatedDate]) // 把所有状态变更记录加入时间线 statusChanges.each { change -> statusTimeline.add([status: change.toString, time: change.created.getTime()]) } // 加入当前时间,作为时间线的终点 statusTimeline.add([status: issue.status.name, time: currentTime]) // 遍历时间线,累加目标状态的停留时长 for (int i = 0; i < statusTimeline.size() - 1; i++) { def currentEntry = statusTimeline[i] def nextEntry = statusTimeline[i+1] if (currentEntry.status == targetStatusName) { totalDuration += nextEntry.time - currentEntry.time } } // 转换为小时格式返回 def hours = totalDuration / (1000 * 60 * 60) return String.format("%.2f小时", hours)
注意事项
- 确保脚本字段拥有足够的权限,能调用
ComponentAccessor获取changeHistoryManager - 状态名称要和JIRA系统里的完全一致(注意大小写、空格,比如不要把"In Progress"写成"InProgress")
- 如果需要返回纯数字(用于报表或其他计算),可以直接返回
hours或者totalDuration,去掉String.format那一行
内容的提问来源于stack exchange,提问作者user1783675
相关产品推荐
相关产品推荐

