需求报表

This commit is contained in:
2026-04-24 14:58:24 +08:00
parent ea575012a8
commit 739e864699
20 changed files with 760 additions and 11 deletions

View File

@@ -0,0 +1,63 @@
package com.sa.zentao.controller;
import com.sa.zentao.dao.Result;
import com.sa.zentao.entity.ZtStoryExpand;
import com.sa.zentao.service.IZtStoryExpandService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author gqb
* @since 2026-03-30
*/
@RestController
@RequestMapping("/zt-story-expand")
public class ZtStoryExpandController {
@Autowired
private IZtStoryExpandService ztStoryExpandService;
/**
* 打分接口
* @param entity 需求扩展信息
* @return 操作结果
*/
@RequestMapping(value = "/saveScore", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result saveScore(@RequestBody ZtStoryExpand entity) {
ztStoryExpandService.saveScore(entity);
return Result.success();
}
/**
* 按月份和项目查询(不分页)
* @param month 月份格式yyyy-MM
* @param projectId 产品项目 idzt_project.id可为空
* @return 需求扩展信息列表
*/
@RequestMapping(value = "/queryByMonth", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public Result<List<ZtStoryExpand>> queryByMonth(String month, Integer projectId) {
List<ZtStoryExpand> list = ztStoryExpandService.queryByMonth(month, projectId);
return Result.success(list);
}
/**
* 保存或更新(有数据了更新不新增)
* @param entity 需求扩展信息
* @return 操作结果
*/
@RequestMapping(value = "/saveOrUpdate", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result saveOrUpdate(@RequestBody ZtStoryExpand entity) {
ztStoryExpandService.saveOrUpdateExpand(entity);
return Result.success();
}
}

View File

@@ -0,0 +1,63 @@
package com.sa.zentao.controller;
import com.sa.zentao.dao.Result;
import com.sa.zentao.entity.ZtStoryMonthWorkload;
import com.sa.zentao.service.IZtStoryMonthWorkloadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.math.BigDecimal;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author gqb
* @since 2026-03-30
*/
@RestController
@RequestMapping("/zt-story-month-workload")
public class ZtStoryMonthWorkloadController {
@Autowired
private IZtStoryMonthWorkloadService ztStoryMonthWorkloadService;
/**
* 保存完成度
*/
@RequestMapping(value = "/saveCompletionDegree", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result saveCompletionDegree(@RequestBody ZtStoryMonthWorkload entity) {
ztStoryMonthWorkloadService.saveCompletionDegree(entity);
return Result.success();
}
/**
* 获取所有不重复的月份列表
*/
@RequestMapping(value = "/listMonths", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public Result<List<String>> listMonths() {
return Result.success(ztStoryMonthWorkloadService.listMonths());
}
/**
* 按 storyId + 月份查询单条记录
*/
@RequestMapping(value = "/getByMonth", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public Result<ZtStoryMonthWorkload> getByMonth(Integer storyId, String month) {
return Result.success(ztStoryMonthWorkloadService.getByStoryIdAndMonth(storyId, month));
}
/**
* 查询某需求在指定月份之前的历史最高完成度
*/
@RequestMapping(value = "/maxWorkloadBefore", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public Result<BigDecimal> maxWorkloadBefore(Integer storyId, String month) {
return Result.success(ztStoryMonthWorkloadService.getMaxWorkloadBefore(storyId, month));
}
}

View File

@@ -631,4 +631,16 @@ public class ZtTaskController {
return Result.success();
}
//更新任务deadline
@RequestMapping(value = "/updateDeadline", method = RequestMethod.GET, produces = "application/json; charset=UTF-8")
public Result updateDeadline(@RequestParam("id") Integer id,
@RequestParam("date") String date) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
ZtTask ztTask = new ZtTask();
ztTask.setId(id);
ztTask.setDeadline(sdf.parse(date));
ztTaskService.updateById(ztTask);
return Result.success();
}
}

View File

@@ -0,0 +1,104 @@
package com.sa.zentao.entity;
import java.math.BigDecimal;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author gqb
* @since 2026-03-30
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class ZtStoryExpand implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private Integer storyId;
/**
* 单元数量
*/
private Integer numberUnits;
/**
* 单元业务复杂度
*/
private String unitBusinessComplexity;
/**
* 技术复杂度系数
*/
private String technicalComplexityCoefficient;
/**
* AI效率系数
*/
private String aiEfficiencyCoefficient;
/**
* 评估工时
*/
private BigDecimal evaluationTime;
/**
* 工作量指数
*/
private String workloadIndex;
/**
* 需求状态 未开始 进行中(需求开始) 需求验收->已完成 / inProgress 进行中 finished 完成
*/
private String requirementStatus;
/**
* 需求完成度
*/
private String requirementCompletionDegree;
private Date createTime;
private Date updateTime;
private String createUser;
private String updateUser;
/**
* 需求名称(关联 zt_story.title非数据库字段
*/
@TableField(exist = false)
private String storyTitle;
/**
* 创建人昵称(关联 zt_user.nickname非数据库字段
*/
@TableField(exist = false)
private String createUserNickname;
/**
* 提交月份,格式 yyyy-MM非数据库字段用于进度提交
*/
@TableField(exist = false)
private String month;
/**
* 本月完成工时(关联 zt_story_month_workload.evaluation_time非数据库字段
*/
@TableField(exist = false)
private BigDecimal monthEvaluationTime;
}

View File

@@ -0,0 +1,56 @@
package com.sa.zentao.entity;
import java.math.BigDecimal;
import java.util.Date;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author gqb
* @since 2026-03-30
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class ZtStoryMonthWorkload implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 月度
*/
private String time;
/**
* 完成度 %
*/
private BigDecimal workload;
private String createUser;
private Date createTime;
private Date updateTime;
private String updateUser;
private Integer storyId;
/**
* 评估工时(评估工时 × 完成度比例)
*/
private BigDecimal evaluationTime;
/**
* 评估工时(评估工时 × 完成度比例)
*/
private BigDecimal workloadIndex;
}

View File

@@ -0,0 +1,26 @@
package com.sa.zentao.mapper;
import com.sa.zentao.entity.ZtStoryExpand;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* Mapper 接口
* </p>
*
* @author gqb
* @since 2026-03-30
*/
public interface ZtStoryExpandMapper extends BaseMapper<ZtStoryExpand> {
/**
* 按月份和项目查询,关联 zt_story 获取需求名称
* @param month 月份格式yyyy-MM
* @param projectId 产品项目 idzt_project.id为 null 时不过滤
* @return 需求扩展信息列表(含 storyTitle
*/
List<ZtStoryExpand> queryByMonthWithTitle(@Param("month") String month, @Param("projectId") Integer projectId);
}

View File

@@ -0,0 +1,16 @@
package com.sa.zentao.mapper;
import com.sa.zentao.entity.ZtStoryMonthWorkload;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* <p>
* Mapper 接口
* </p>
*
* @author gqb
* @since 2026-03-30
*/
public interface ZtStoryMonthWorkloadMapper extends BaseMapper<ZtStoryMonthWorkload> {
}

View File

@@ -18,6 +18,10 @@ public class StoryQo extends BaseQo {
private String assignedTo;
private String userName;
private String module;
/**
* 多个模块,逗号分割
*/
private String modules;
private String searchVal;
private Integer productId;
private String openedby;

View File

@@ -120,4 +120,8 @@ public class ZtProjectQo extends BaseQo {
private String account;
//1 延期 2不延期
private Integer delayFlag=0 ;
/**
* 验收人
*/
private String ysUser;
}

View File

@@ -0,0 +1,38 @@
package com.sa.zentao.service;
import com.sa.zentao.entity.ZtStoryExpand;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author gqb
* @since 2026-03-30
*/
public interface IZtStoryExpandService extends IService<ZtStoryExpand> {
/**
* 保存或更新(有数据了更新不新增)
* @param entity 需求扩展信息
*/
void saveOrUpdateExpand(ZtStoryExpand entity);
/**
* 按月份和项目查询(不分页,含需求名称)
* @param month 月份格式yyyy-MM
* @param projectId 产品项目 id为 null 时不过滤
* @return 需求扩展信息列表(含 storyTitle
*/
List<ZtStoryExpand> queryByMonth(String month, Integer projectId);
/**
* 打分接口
* @param entity 需求扩展信息
*/
void saveScore(ZtStoryExpand entity);
}

View File

@@ -0,0 +1,40 @@
package com.sa.zentao.service;
import com.sa.zentao.entity.ZtStoryMonthWorkload;
import com.baomidou.mybatisplus.extension.service.IService;
import java.math.BigDecimal;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author gqb
* @since 2026-03-30
*/
public interface IZtStoryMonthWorkloadService extends IService<ZtStoryMonthWorkload> {
/**
* 保存完成度
* @param entity 月度工作量信息
*/
void saveCompletionDegree(ZtStoryMonthWorkload entity);
/**
* 获取所有不重复的月份列表
* @return 月份列表,格式 yyyy-MM
*/
List<String> listMonths();
/**
* 按 storyId + 月份查询单条记录
*/
ZtStoryMonthWorkload getByStoryIdAndMonth(Integer storyId, String month);
/**
* 查询某需求在指定月份之前(不含)的历史最高完成度
*/
BigDecimal getMaxWorkloadBefore(Integer storyId, String month);
}

View File

@@ -1139,7 +1139,7 @@ public class IZtCountService {
return BigDecimal.ZERO;
}
List<ZtMeeting> list = this.meetingService.list(new QueryWrapper<ZtMeeting>().lambda().in(ZtMeeting::getProductId, pIds)
.like(ZtMeeting::getUsers, u.getAccount())
.and(w -> w.like(ZtMeeting::getUsers, u.getAccount()).or().like(ZtMeeting::getUsers, u.getNickname()))
.ge(ZtMeeting::getMeetingDate, start).le(ZtMeeting::getMeetingDate, end));
if (CollectionUtils.isEmpty(list)) {
return BigDecimal.ZERO;
@@ -1257,7 +1257,7 @@ public class IZtCountService {
return dto;
}
List<ZtMeeting> list = this.meetingService.list(new QueryWrapper<ZtMeeting>().lambda().in(ZtMeeting::getProductId, pIds)
.like(ZtMeeting::getUsers, u.getAccount())
.and(w -> w.like(ZtMeeting::getUsers, u.getAccount()).or().like(ZtMeeting::getUsers, u.getNickname()))
.ge(ZtMeeting::getMeetingDate, start).le(ZtMeeting::getMeetingDate, end));
if (CollectionUtils.isEmpty(list)) {
return dto;

View File

@@ -4,11 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sa.zentao.conf.RiskUserThreadLocal;
import com.sa.zentao.dao.*;
import com.sa.zentao.entity.*;
import com.sa.zentao.enums.ActionStatus;
import com.sa.zentao.enums.ActionType;
import com.sa.zentao.enums.KanbanCellType;
import com.sa.zentao.enums.KanbanColumnType;
import com.sa.zentao.enums.ProjectTypeEnums;
import com.sa.zentao.enums.*;
import com.sa.zentao.utils.KanbanStageMapping;
import com.sa.zentao.mapper.ZtKanbancolumnMapper;
import com.sa.zentao.mapper.ZtKanbanlaneMapper;
@@ -383,6 +379,13 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
}else if ("verified".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("verified")).collect(Collectors.toList()).get(0);
}else if (StoryStageEnums.productVerified.getValue().equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals(StoryStageEnums.productVerified.getValue())).collect(Collectors.toList()).get(0);
}else if ( StoryStageEnums.productWaitVerified.getValue().equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals(StoryStageEnums.productWaitVerified.getValue())).collect(Collectors.toList()).get(0);
}else{
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals(st.getStage())).collect(Collectors.toList()).get(0);
}
ZtKanbancell kanbancell = this.kanbancellService.getOne(new QueryWrapper<ZtKanbancell>().lambda()
.eq(ZtKanbancell::getKanban, id).eq(ZtKanbancell::getColumn, ztKanbancolumnDTO.getId()));

View File

@@ -0,0 +1,148 @@
package com.sa.zentao.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sa.zentao.entity.ZtStoryExpand;
import com.sa.zentao.entity.ZtStoryMonthWorkload;
import com.sa.zentao.mapper.ZtStoryExpandMapper;
import com.sa.zentao.service.IZtStoryExpandService;
import com.sa.zentao.service.IZtStoryMonthWorkloadService;
import com.sa.zentao.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author gqb
* @since 2026-03-30
*/
@Service
public class ZtStoryExpandServiceImpl extends ServiceImpl<ZtStoryExpandMapper, ZtStoryExpand> implements IZtStoryExpandService {
@Autowired
private IZtStoryMonthWorkloadService ztStoryMonthWorkloadService;
@Autowired
private IZtStoryExpandService ztStoryExpandService;
@Override
@Transactional(rollbackFor = Exception.class)
public void saveOrUpdateExpand(ZtStoryExpand entity) {
if (entity == null || entity.getStoryId() == null) {
return;
}
QueryWrapper<ZtStoryExpand> wrapper = new QueryWrapper<>();
wrapper.eq("story_id", entity.getStoryId());
ZtStoryExpand exist = this.getOne(wrapper);
// 已完成的记录不允许再更新
if (exist != null && "finished".equals(exist.getRequirementStatus())) {
throw new RuntimeException("该需求已完成,不可再修改");
}
if (exist != null) {
entity.setId(exist.getId());
entity.setUpdateTime(new Date());
this.updateById(entity);
} else {
// 新增默认 inProgress
if (entity.getRequirementStatus() == null) {
entity.setRequirementStatus("inProgress");
}
entity.setCreateTime(new Date());
entity.setUpdateTime(new Date());
this.save(entity);
}
// finished 时强制完成度100计算剩余工作量写入 workload
if ("finished".equals(entity.getRequirementStatus())) {
entity.setMonth(DateUtils.formatDate(new Date(), "yyyy-MM"));
entity.setRequirementCompletionDegree("100");
writeWorkload(entity, exist);
}
// inProgress 时:不计算 workload
}
@Override
public List<ZtStoryExpand> queryByMonth(String month, Integer projectId) {
return baseMapper.queryByMonthWithTitle(month, projectId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void saveScore(ZtStoryExpand entity) {
if (entity.getStoryId() == null) {
return;
}
// 根据完成度设置需求状态
if (entity.getRequirementCompletionDegree() != null) {
String degree = entity.getRequirementCompletionDegree().trim();
entity.setRequirementStatus("100".equals(degree) ? "finished" : "inProgress");
}
// 保存/更新 zt_story_expand
QueryWrapper<ZtStoryExpand> expandWrapper = new QueryWrapper<>();
expandWrapper.eq("story_id", entity.getStoryId());
ZtStoryExpand exist = this.getOne(expandWrapper);
if (exist != null) {
entity.setId(exist.getId());
entity.setUpdateTime(new Date());
this.updateById(entity);
} else {
entity.setCreateTime(new Date());
entity.setUpdateTime(new Date());
this.save(entity);
}
// 同步写 zt_story_month_workload
if (entity.getRequirementCompletionDegree() != null && entity.getMonth() != null) {
writeWorkload(entity, exist);
}
}
/**
* 计算增量工作量并写入 zt_story_month_workload
* 增量 = workloadIndex × (本月完成度 - 历史最高) / 100
*/
private void writeWorkload(ZtStoryExpand entity, ZtStoryExpand exist) {
BigDecimal degree = new BigDecimal(entity.getRequirementCompletionDegree().trim());
// 取工作量指数(优先用 DB 已有值)
String workloadIndexStr = (exist != null && exist.getWorkloadIndex() != null)
? exist.getWorkloadIndex()
: entity.getWorkloadIndex();
BigDecimal baseWorkloadIndex = null;
if (workloadIndexStr != null && !workloadIndexStr.trim().isEmpty()) {
try {
baseWorkloadIndex = new BigDecimal(workloadIndexStr.trim());
} catch (NumberFormatException ignored) {}
}
// 历史最高完成度
BigDecimal maxBefore = ztStoryMonthWorkloadService.getMaxWorkloadBefore(entity.getStoryId(), entity.getMonth());
BigDecimal prevDegree = maxBefore != null ? maxBefore : BigDecimal.ZERO;
ZtStoryMonthWorkload workload = new ZtStoryMonthWorkload();
workload.setStoryId(entity.getStoryId());
workload.setWorkload(degree);
workload.setTime(entity.getMonth());
if (baseWorkloadIndex != null) {
BigDecimal increment = degree.subtract(prevDegree);
//暂时保留,冗余字段
workload.setEvaluationTime(
increment.compareTo(BigDecimal.ZERO) > 0
? baseWorkloadIndex.multiply(increment).divide(new BigDecimal("100"), 2, java.math.RoundingMode.HALF_UP)
: BigDecimal.ZERO
);
workload.setWorkloadIndex(increment.compareTo(BigDecimal.ZERO) > 0
? baseWorkloadIndex.multiply(increment).divide(new BigDecimal("100"), 2, java.math.RoundingMode.HALF_UP)
: BigDecimal.ZERO);
}
ztStoryMonthWorkloadService.saveCompletionDegree(workload);
entity.setRequirementCompletionDegree(degree.toString());
this.ztStoryExpandService.updateById(entity);
}
}

View File

@@ -0,0 +1,97 @@
package com.sa.zentao.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sa.zentao.entity.ZtStoryMonthWorkload;
import com.sa.zentao.mapper.ZtStoryMonthWorkloadMapper;
import com.sa.zentao.service.IZtStoryMonthWorkloadService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author gqb
* @since 2026-03-30
*/
@Service
public class ZtStoryMonthWorkloadServiceImpl extends ServiceImpl<ZtStoryMonthWorkloadMapper, ZtStoryMonthWorkload> implements IZtStoryMonthWorkloadService {
@Override
@Transactional(rollbackFor = Exception.class)
public void saveCompletionDegree(ZtStoryMonthWorkload entity) {
if (entity == null || entity.getStoryId() == null || entity.getTime() == null) {
return;
}
// 规则1完成度不超过100
if (entity.getWorkload() != null && entity.getWorkload().compareTo(new BigDecimal("100")) > 0) {
throw new RuntimeException("完成度不能超过100%");
}
// 规则2本月不能低于历史最高完成度
BigDecimal maxBefore = getMaxWorkloadBefore(entity.getStoryId(), entity.getTime());
if (maxBefore != null && entity.getWorkload() != null
&& entity.getWorkload().compareTo(maxBefore) < 0) {
throw new RuntimeException("本月完成度(" + entity.getWorkload() + "%)不能低于历史最高(" + maxBefore + "%");
}
// 规则3按 storyId + time 唯一,同月覆盖
QueryWrapper<ZtStoryMonthWorkload> wrapper = new QueryWrapper<>();
wrapper.eq("story_id", entity.getStoryId()).eq("time", entity.getTime());
ZtStoryMonthWorkload exist = this.getOne(wrapper);
if (exist != null) {
entity.setId(exist.getId());
entity.setUpdateTime(new Date());
this.updateById(entity);
} else {
entity.setCreateTime(new Date());
entity.setUpdateTime(new Date());
this.save(entity);
}
}
@Override
public List<String> listMonths() {
QueryWrapper<ZtStoryMonthWorkload> wrapper = new QueryWrapper<>();
wrapper.select("DISTINCT time").isNotNull("time").ne("time", "").orderByDesc("time");
return this.list(wrapper).stream()
.map(ZtStoryMonthWorkload::getTime)
.collect(java.util.stream.Collectors.toList());
}
@Override
public ZtStoryMonthWorkload getByStoryIdAndMonth(Integer storyId, String month) {
QueryWrapper<ZtStoryMonthWorkload> wrapper = new QueryWrapper<>();
wrapper.eq("story_id", storyId).eq("time", month);
return this.getOne(wrapper);
}
@Override
public BigDecimal getMaxWorkloadBefore(Integer storyId, String month) {
QueryWrapper<ZtStoryMonthWorkload> wrapper = new QueryWrapper<>();
wrapper.eq("story_id", storyId)
.lt("time", month)
.orderByDesc("workload")
.last("LIMIT 1");
ZtStoryMonthWorkload record = this.getOne(wrapper);
return record != null ? record.getWorkload() : null;
}
private String getLastMonth(String yearMonth) {
String[] parts = yearMonth.split("-");
int year = Integer.parseInt(parts[0]);
int month = Integer.parseInt(parts[1]);
if (month == 1) {
year--;
month = 12;
} else {
month--;
}
return String.format("%d-%02d", year, month);
}
}

View File

@@ -650,6 +650,9 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
if (ztTask.getDeadline() == null) {
throw new BusinessException("当前环境异常请联系管理员");
}
if("test".equals(ztTask.getType())&&"reviewing".equals(ztTask.getStatus())){
ztTask.setStatus("wait");
}
this.baseMapper.insert(ztTask);
if (ztTask.getDeadline() != null && ztTask.getStory() != null && ztTask.getStory() != 0) {
ZtStory ztStory = this.storyService.getById(ztTask.getStory());

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sa.zentao.mapper.ZtStoryExpandMapper">
<resultMap id="BaseResultMap" type="com.sa.zentao.entity.ZtStoryExpand">
<result column="id" property="id" />
<result column="story_id" property="storyId" />
<result column="number_units" property="numberUnits" />
<result column="unit_business_complexity" property="unitBusinessComplexity" />
<result column="technical_complexity_coefficient" property="technicalComplexityCoefficient" />
<result column="ai_efficiency_coefficient" property="aiEfficiencyCoefficient" />
<result column="evaluation_time" property="evaluationTime" />
<result column="workload_index" property="workloadIndex" />
<result column="requirement_status" property="requirementStatus" />
<result column="requirement_completion_degree" property="requirementCompletionDegree" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="create_user" property="createUser" />
<result column="update_user" property="updateUser" />
<result column="story_title" property="storyTitle" />
<result column="create_user_nickname" property="createUserNickname" />
<result column="month_evaluation_time" property="monthEvaluationTime" />
</resultMap>
<select id="queryByMonthWithTitle" resultMap="BaseResultMap">
SELECT
e.*,
s.title AS story_title,
u.nickname AS create_user_nickname,
mw.evaluation_time AS month_evaluation_time
FROM
zt_story_expand e
LEFT JOIN zt_story s ON e.story_id = s.id
LEFT JOIN zt_product zp on s.product = zp.id
LEFT JOIN zt_project zpt on zp.program = zpt.id
LEFT JOIN zt_user u ON e.create_user = u.account
LEFT JOIN zt_story_month_workload mw ON mw.story_id = e.story_id AND mw.time = #{month}
WHERE
zpt.id = #{projectId}
AND (
DATE_FORMAT(e.create_time, '%Y-%m') = #{month}
OR mw.time = #{month}
)
</select>
</mapper>

View File

@@ -407,7 +407,11 @@
left join zt_project pj on pstory.project = pj.id
left join zt_product pt on s.product = pt.id
left join zt_projectstory ps on s.id = ps.story
left join zt_user zu on s.ys_user = zu.account
WHERE 1=1
<if test="qo.ysUser != null and qo.ysUser != '' ">
and zu.nickname like concat('%', #{qo.ysUser}, '%')
</if>
<if test="qo.pri != null and qo.pri != '' ">
and s.pri = #{qo.pri}
</if>
@@ -417,7 +421,9 @@
<if test="qo.title != null and qo.title != '' ">
and s.title like concat('%', #{qo.title}, '%')
</if>
<if test="qo.ysUser != null and qo.ysUser != '' ">
and s.nickname like concat('%', #{qo.ysUser}, '%')
</if>
<if test="qo.searchVal != null and qo.searchVal == 'WYS' ">
and s.ys_user = #{qo.userName}
</if>
@@ -932,7 +938,7 @@
from zt_story s
left join zt_product pt on s.product = pt.id
left join zt_storyreview v on s.id = v.story and s.version = v.version
left join zt_user zu on s.ys_user = zu.account
<if test="qo.project != null or qo.execution != null">
left join zt_projectstory ps on s.id = ps.story
</if>
@@ -940,7 +946,9 @@
WHERE 1=1
<if test="qo.ysUser != null and qo.ysUser != '' ">
and zu.nickname like concat('%', #{qo.ysUser}, '%')
</if>
<if test="qo.testUser != null and qo.testUser != '' ">
and s.test_user like concat('%', #{qo.testUser}, '%')
</if>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sa.zentao.mapper.ZtStoryMonthWorkloadMapper">
<resultMap id="BaseResultMap" type="com.sa.zentao.entity.ZtStoryMonthWorkload">
<result column="id" property="id" />
<result column="time" property="time" />
<result column="workload" property="workload" />
<result column="create_user" property="createUser" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="update_user" property="updateUser" />
</resultMap>
</mapper>

View File

@@ -141,7 +141,9 @@
s.old_status,
s.ys_user,
s.product_user,
pt.name productName from zt_story_user s LEFT JOIN zt_product pt on s.product = pt.id WHERE 1=1
pt.name productName
from zt_story_user s
LEFT JOIN zt_product pt on s.product = pt.id WHERE 1=1
<if test="qo.productIds != null and qo.productIds.size() > 0">
and s.product in
@@ -228,6 +230,9 @@
<if test="qo.module != null and qo.module != '' ">
and s.module = #{qo.module}
</if>
<if test="qo.modules != null and qo.modules != '' ">
and FIND_IN_SET(s.module, #{qo.modules})
</if>
<if test="qo.productId != null ">
and s.product = #{qo.productId}
</if>