@@ -114,7 +114,6 @@ public class DashboardExpertManage { | |||
// 评审次数 | |||
List<Meeting> normalMeetingList = iMeetingService.list(Wrappers.lambdaQuery(Meeting.class) | |||
.eq(StringUtils.isNotBlank(queryRegionCode), Meeting::getRegionCode, queryRegionCode) | |||
.ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode())); | |||
Integer meetingCnt = normalMeetingList.size(); | |||
@@ -1,206 +0,0 @@ | |||
package com.hz.pm.api.dashboard.manage; | |||
import cn.hutool.core.collection.CollUtil; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.google.common.collect.Lists; | |||
import com.hz.pm.api.common.constant.RegionConst; | |||
import com.hz.pm.api.common.helper.RegionCacheHelper; | |||
import com.hz.pm.api.common.model.entity.DataDTO; | |||
import com.hz.pm.api.dashboard.model.vo.MeetingStatisticsVO; | |||
import com.hz.pm.api.ding.constants.DingOrganizationContant; | |||
import com.hz.pm.api.expert.constant.ReviewResultEnum; | |||
import com.hz.pm.api.expert.model.entity.ExpertReview; | |||
import com.hz.pm.api.expert.model.enumeration.ReviewTemplateTypeEnum; | |||
import com.hz.pm.api.expert.service.IExpertReviewService; | |||
import com.hz.pm.api.meeting.entity.domain.Meeting; | |||
import com.hz.pm.api.meeting.service.IMeetingService; | |||
import com.hz.pm.api.organization.model.entity.DingOrganization; | |||
import com.hz.pm.api.organization.service.IDingOrganizationService; | |||
import com.hz.pm.api.projectlib.model.entity.Project; | |||
import com.hz.pm.api.projectlib.service.IProjectService; | |||
import com.hz.pm.api.sys.model.dto.RegionDTO; | |||
import lombok.RequiredArgsConstructor; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.springframework.stereotype.Component; | |||
import java.math.BigDecimal; | |||
import java.math.RoundingMode; | |||
import java.util.Comparator; | |||
import java.util.List; | |||
import java.util.Objects; | |||
import java.util.stream.Collectors; | |||
/** | |||
* @Classname MeetingStatisticsManage | |||
* @Description | |||
* @Date 2023/12/05 17:44 | |||
* @Author PoffyZhang | |||
*/ | |||
@Component | |||
@RequiredArgsConstructor | |||
@Slf4j | |||
public class MeetingStatisticsManage { | |||
private final IMeetingService meetingService; | |||
private final IExpertReviewService expertReviewService; | |||
private final RegionCacheHelper regionCacheHelper; | |||
private final IDingOrganizationService dingOrganizationService; | |||
private final IProjectService projectService; | |||
public MeetingStatisticsVO statistics(Integer year) { | |||
MeetingStatisticsVO res = new MeetingStatisticsVO(); | |||
List<Meeting> meetings = meetingService.list(Wrappers.lambdaQuery(Meeting.class)); | |||
//查出 年份的 会议数据 | |||
meetings = meetings.stream().filter(m -> { | |||
if(Objects.nonNull(m.getStartTime()) && | |||
(Objects.isNull(year) || year.equals(m.getStartTime().getYear()))){ | |||
return Boolean.TRUE; | |||
} | |||
return Boolean.FALSE; | |||
}).collect(Collectors.toList()); | |||
List<Long> meetingIds = meetings.stream().map(Meeting::getId) | |||
.collect(Collectors.toList()); | |||
//会议总数 | |||
res.setMeetingTotal(meetings.size()); | |||
//评审数 | |||
List<ExpertReview> expertReviews = Lists.newArrayList(); | |||
Integer reviewsTotal = 0; | |||
if(CollUtil.isNotEmpty(meetingIds)){ | |||
expertReviews = expertReviewService.list(Wrappers.lambdaQuery(ExpertReview.class) | |||
.eq(ExpertReview::getIsFinal, Boolean.TRUE) | |||
.in(ExpertReview::getMeetingId,meetingIds)); | |||
reviewsTotal = expertReviews.size(); | |||
} | |||
//通过的评审 | |||
List<ExpertReview> passExpertReviews = expertReviews.stream() | |||
.filter(r -> Objects.nonNull(r.getReviewResult()) && | |||
r.getReviewResult().equals(ReviewResultEnum.PASSED.getCode())) | |||
.collect(Collectors.toList()); | |||
//不通过的评审 | |||
List<ExpertReview> notpassExpertReviews = expertReviews.stream() | |||
.filter(r -> Objects.nonNull(r.getReviewResult()) && | |||
r.getReviewResult().equals(ReviewResultEnum.REFUSED.getCode())) | |||
.collect(Collectors.toList()); | |||
res.setPassReview(passExpertReviews.size()); | |||
res.setNotPassRate(reviewsTotal.compareTo(0) == 0 ? BigDecimal.ZERO : | |||
BigDecimal.valueOf(notpassExpertReviews.size()).multiply(BigDecimal.valueOf(100) | |||
.divide(BigDecimal.valueOf(reviewsTotal), RoundingMode.HALF_UP))); | |||
//各区域 | |||
List<RegionDTO> regions = regionCacheHelper.listChildren(RegionConst.RC_LS, RegionConst.RL_CITY) | |||
.stream().filter(r -> r.getRegionLevel().equals(RegionConst.RL_COUNTY)) | |||
.sorted(Comparator.comparing(RegionDTO::getRegionCode)).collect(Collectors.toList()); | |||
List<DataDTO> regionMeetngs = Lists.newArrayList(); | |||
for(RegionDTO region : regions){ | |||
regionMeetngs.add(DataDTO.of(region.getRegionName(),region.getRegionCode(),meetings.stream().filter(m -> { | |||
if(StringUtils.isNotBlank(m.getRegionCode()) && | |||
m.getRegionCode().equals(region.getRegionCode())){ | |||
return Boolean.TRUE; | |||
} | |||
return Boolean.FALSE; | |||
}).collect(Collectors.toList()).size())); | |||
} | |||
res.setRegionMeetings(regionMeetngs); | |||
//预审 验收 会议 | |||
List<DataDTO> meetingTypes = Lists.newArrayList(); | |||
meetingTypes.add(DataDTO.of("预审会议",ReviewTemplateTypeEnum.PRELIMINARY_SCHEME_REVIEW.getCode().toString(), | |||
meetings.stream().filter(m -> { | |||
if(StringUtils.isNotBlank(m.getType()) && | |||
m.getType().equals(ReviewTemplateTypeEnum.PRELIMINARY_SCHEME_REVIEW.getCode() | |||
.toString())){ | |||
return Boolean.TRUE; | |||
} | |||
return Boolean.FALSE; | |||
}).collect(Collectors.toList()).size())); | |||
Long yanshouCount = meetings.stream().filter(m -> { | |||
if (StringUtils.isNotBlank(m.getType()) && | |||
m.getType().equals(ReviewTemplateTypeEnum.ACCEPTANCE_SCHEME_REVIEW.getCode() | |||
.toString())) { | |||
return Boolean.TRUE; | |||
} | |||
return Boolean.FALSE; | |||
}).count(); | |||
meetingTypes.add(DataDTO.of("验收会议",ReviewTemplateTypeEnum.ACCEPTANCE_SCHEME_REVIEW.getCode().toString(), | |||
yanshouCount.intValue())); | |||
res.setMeetingTypes(meetingTypes); | |||
//各区县评审 不通过率 | |||
List<DataDTO> regionNotpassReview = Lists.newArrayList(); | |||
for(RegionDTO region : regions){ | |||
DataDTO data = new DataDTO(); | |||
data.setCode(region.getRegionCode()); | |||
data.setName(region.getRegionName()); | |||
//先求出 此区域会议 | |||
List<Long> regionMeetingIds = meetings.stream().filter(m -> { | |||
if (StringUtils.isNotBlank(m.getRegionCode()) && | |||
m.getRegionCode().equals(region.getRegionCode())) { | |||
return Boolean.TRUE; | |||
} | |||
return Boolean.FALSE; | |||
}).map(Meeting::getId).collect(Collectors.toList()); | |||
List<ExpertReview> regionReviews = expertReviews.stream().filter(r -> { | |||
if (Objects.nonNull(r.getMeetingId()) && | |||
regionMeetingIds.contains(r.getMeetingId())) { | |||
return Boolean.TRUE; | |||
} | |||
return Boolean.FALSE; | |||
}).collect(Collectors.toList()); | |||
long regionNotpass = regionReviews.stream().filter(r -> Objects.nonNull(r.getReviewResult()) && | |||
r.getReviewResult().equals(ReviewResultEnum.REFUSED.getCode())) | |||
.count(); | |||
data.setRate(CollUtil.isEmpty(regionReviews) ? BigDecimal.ZERO : | |||
BigDecimal.valueOf(regionNotpass).multiply(BigDecimal.valueOf(100)) | |||
.divide(BigDecimal.valueOf(regionReviews.size()),BigDecimal.ROUND_CEILING,RoundingMode.HALF_UP)); | |||
regionNotpassReview.add(data); | |||
} | |||
res.setNotPassRegionMeetings(regionNotpassReview); | |||
//各部门 不通过项目TOP10 | |||
List<DingOrganization> organizations = dingOrganizationService.list(Wrappers.lambdaQuery(DingOrganization.class) | |||
.in(DingOrganization::getTypeCode, Lists.newArrayList(DingOrganizationContant.UNIT_TYPE, | |||
DingOrganizationContant.GOV_TEMPORARY))); | |||
List<Project> projects = projectService.list(Wrappers.lambdaQuery(Project.class) | |||
.eq(Project::getNewest, Boolean.TRUE)); | |||
//TOP10 | |||
List<ExpertReview> finalExpertReviews = expertReviews; | |||
List<DataDTO> notpassTop10 = organizations.stream() | |||
.map(o -> { | |||
DataDTO data = new DataDTO(); | |||
data.setCode(o.getOrganizationCode()); | |||
data.setName(o.getOrganizationName()); | |||
List<Project> orgProjects = projects.stream().filter(p -> Objects.nonNull(p.getBuildOrgCode()) && | |||
p.getBuildOrgCode().equals(o.getOrganizationCode())) | |||
.collect(Collectors.toList()); | |||
List<String> projectCodes = orgProjects.stream().map(Project::getProjectCode) | |||
.collect(Collectors.toList()); | |||
if(CollUtil.isEmpty(projectCodes)){ | |||
data.setRate(BigDecimal.ZERO); | |||
return data; | |||
} | |||
List<ExpertReview> reviews = finalExpertReviews.stream().filter(r -> Objects.nonNull(r.getProjectCode()) && | |||
projectCodes.contains(r.getProjectCode())).collect(Collectors.toList()); | |||
long orgNotpass = reviews.stream().filter(r -> Objects.nonNull(r.getReviewResult()) && | |||
r.getReviewResult().equals(ReviewResultEnum.REFUSED.getCode())) | |||
.count(); | |||
data.setRate(CollUtil.isEmpty(reviews) ? BigDecimal.ZERO : | |||
BigDecimal.valueOf(orgNotpass).multiply(BigDecimal.valueOf(100)) | |||
.divide(BigDecimal.valueOf(reviews.size()),BigDecimal.ROUND_CEILING,RoundingMode.HALF_UP)); | |||
return data; | |||
}) | |||
.sorted(Comparator.comparing(DataDTO::getRate).reversed()) | |||
.limit(10).collect(Collectors.toList()); | |||
res.setNotPassTop10(notpassTop10); | |||
return res; | |||
} | |||
} |
@@ -203,6 +203,13 @@ public class MeetingController { | |||
meetingManage.uploadMeetingResult(req); | |||
} | |||
@PostMapping("/project/result/upload") | |||
@ApiOperation("评审结果上传") | |||
@WebLog("评审结果上传") | |||
public void uploadProjectReviewResult(@RequestBody @Valid ProjectReviewResultUploadReq req) { | |||
meetingManage.uploadProjectReviewResult(req); | |||
} | |||
@GetMapping("/{meetingId}/listExpertJudge") | |||
@ApiOperation("查询会议专家评价信息") | |||
@WebLog("查询会议专家评价信息") | |||
@@ -0,0 +1,33 @@ | |||
package com.hz.pm.api.meeting.controller; | |||
import com.hz.pm.api.meeting.entity.enumeration.MeetingSettingsTypeEnum; | |||
import com.hz.pm.api.meeting.entity.req.MeetingSettingsSaveReq; | |||
import com.hz.pm.api.meeting.manage.MeetingSettingsManage; | |||
import lombok.AllArgsConstructor; | |||
import org.springframework.web.bind.annotation.GetMapping; | |||
import org.springframework.web.bind.annotation.PathVariable; | |||
import org.springframework.web.bind.annotation.RequestMapping; | |||
import org.springframework.web.bind.annotation.RestController; | |||
/** | |||
* <p> | |||
* 前端控制器 | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 2023-12-27 | |||
*/ | |||
@RestController | |||
@AllArgsConstructor | |||
@RequestMapping("/api/v1/meeting/settings") | |||
public class MeetingSettingsController { | |||
private final MeetingSettingsManage meetingSettingsManage; | |||
@GetMapping("/{settingsType}") | |||
public MeetingSettingsSaveReq getSettings(@PathVariable MeetingSettingsTypeEnum settingsType) { | |||
return meetingSettingsManage.getSettings(settingsType); | |||
} | |||
} |
@@ -27,30 +27,18 @@ public class Meeting implements Serializable { | |||
@TableId(type = IdType.AUTO) | |||
private Long id; | |||
@ApiModelProperty("事务名称") | |||
@ApiModelProperty("会议名称") | |||
private String name; | |||
@ApiModelProperty("事务类型") | |||
@ApiModelProperty("会议类型") | |||
private String type; | |||
@ApiModelProperty("评审耗时:1 半天、2 一天") | |||
private Integer meetingUsageTime; | |||
@ApiModelProperty("开始时间") | |||
private LocalDateTime startTime; | |||
@ApiModelProperty("结束时间") | |||
private LocalDateTime endTime; | |||
@ApiModelProperty("评委出席时间") | |||
private LocalDateTime judgesAttendanceTime; | |||
@ApiModelProperty("地区编码") | |||
private String regionCode; | |||
@ApiModelProperty("地区层级") | |||
private Integer regionLevel; | |||
@ApiModelProperty("联系人") | |||
private String connecter; | |||
@@ -71,9 +59,6 @@ public class Meeting implements Serializable { | |||
@ApiModelProperty("是否确认名单") | |||
private Boolean confirmedRoster; | |||
@ApiModelProperty("短信通知签名") | |||
private String smsNotifySign; | |||
@ApiModelProperty("举办单位") | |||
private String holdOrg; | |||
@@ -95,6 +80,12 @@ public class Meeting implements Serializable { | |||
@ApiModelProperty("备注") | |||
private String remark; | |||
@ApiModelProperty("会议结果说明") | |||
private String resultDescription; | |||
@ApiModelProperty("相关材料") | |||
private String resultAttachFiles; | |||
@ApiModelProperty("创建人ID") | |||
@TableField(fill = FieldFill.INSERT) | |||
private Long createBy; | |||
@@ -0,0 +1,48 @@ | |||
package com.hz.pm.api.meeting.entity.domain; | |||
import com.baomidou.mybatisplus.annotation.*; | |||
import java.io.Serializable; | |||
import java.time.LocalDateTime; | |||
import com.hz.pm.api.meeting.entity.enumeration.MeetingSettingsTypeEnum; | |||
import io.swagger.annotations.ApiModel; | |||
import lombok.Data; | |||
/** | |||
* <p> | |||
* | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 2023-12-27 | |||
*/ | |||
@Data | |||
@TableName("MEETING_SETTINGS") | |||
@ApiModel(value = "MeetingSettings对象") | |||
public class MeetingSettings implements Serializable { | |||
private static final long serialVersionUID = 1L; | |||
@TableId(value = "ID", type = IdType.AUTO) | |||
private Long id; | |||
private Boolean enable; | |||
private String settingsContent; | |||
private MeetingSettingsTypeEnum settingsType; | |||
@TableField(fill = FieldFill.INSERT) | |||
private LocalDateTime createOn; | |||
@TableField(fill = FieldFill.INSERT) | |||
private Long createBy; | |||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||
private LocalDateTime updateOn; | |||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||
private Long updateBy; | |||
} |
@@ -0,0 +1,22 @@ | |||
package com.hz.pm.api.meeting.entity.dto; | |||
import lombok.Data; | |||
import java.time.LocalTime; | |||
/** | |||
* <p> | |||
* MeetingInviteIgnoreTmeContentDTO | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 00:27 2023/12/27 | |||
*/ | |||
@Data | |||
public class ExpertInviteIgnoreTimeContentDTO { | |||
private LocalTime startTime; | |||
private LocalTime stopTime; | |||
} |
@@ -0,0 +1,18 @@ | |||
package com.hz.pm.api.meeting.entity.dto; | |||
import lombok.Data; | |||
/** | |||
* <p> | |||
* ExpertJudgeTimeLimitContentDTO | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 09:24 2023/12/27 | |||
*/ | |||
@Data | |||
public class ExpertJudgeTimeLimitContentDTO { | |||
private Integer days; | |||
} |
@@ -0,0 +1,23 @@ | |||
package com.hz.pm.api.meeting.entity.enumeration; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Getter; | |||
/** | |||
* <p> | |||
* MeetingSettingsTypeEnum | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 00:06 2023/12/27 | |||
*/ | |||
@Getter | |||
@AllArgsConstructor | |||
public enum MeetingSettingsTypeEnum { | |||
MEETING_INVITE_IGNORE_TIME("专家抽取免打扰时段配置"), | |||
EXPERT_JUDGE_TIME_LIMIT("专家星级评分时间配置"); | |||
private final String name; | |||
} |
@@ -45,12 +45,6 @@ public class MeetingListReq extends PagePo { | |||
@ApiModelProperty("项目名称") | |||
private String projectName; | |||
@ApiModelProperty("区域编码") | |||
private String regionCode; | |||
@ApiModelProperty("区域层级") | |||
private Integer regionLevel; | |||
@ApiModelProperty("参会名单是否确认") | |||
private Boolean confirmedRoster; | |||
@@ -4,7 +4,6 @@ import io.swagger.annotations.ApiModelProperty; | |||
import lombok.Data; | |||
import javax.validation.constraints.NotNull; | |||
import java.math.BigDecimal; | |||
/** | |||
* <p> | |||
@@ -21,29 +20,10 @@ public class MeetingResultUploadReq { | |||
@NotNull(message = "会议ID不能为空") | |||
private Long meetingId; | |||
@ApiModelProperty("项目关联会议ID") | |||
@NotNull(message = "项目关联会议ID不能为空") | |||
private Long meetingProjectId; | |||
@ApiModelProperty("会议结果说明") | |||
private String resultDescription; | |||
@ApiModelProperty("建设必要性") | |||
private String buildNecessity; | |||
@ApiModelProperty("需求合理性") | |||
private String needRationality; | |||
@ApiModelProperty("技术方案可行性") | |||
private String techFeasibility; | |||
@ApiModelProperty("审核结果:1 通过、0 不通过") | |||
private Integer reviewResult; | |||
@ApiModelProperty("其他意见") | |||
private String otherAdvices; | |||
@ApiModelProperty("投资测算合理性") | |||
private String investRationality; | |||
@ApiModelProperty("建议资金(单位:万元)") | |||
private BigDecimal suggestedFunding; | |||
@ApiModelProperty("相关材料") | |||
private String resultAttachFiles; | |||
} |
@@ -0,0 +1,42 @@ | |||
package com.hz.pm.api.meeting.entity.req; | |||
import com.hz.pm.api.meeting.entity.dto.ExpertInviteIgnoreTimeContentDTO; | |||
import com.hz.pm.api.meeting.entity.dto.ExpertJudgeTimeLimitContentDTO; | |||
import com.hz.pm.api.meeting.entity.enumeration.MeetingSettingsTypeEnum; | |||
import io.swagger.annotations.ApiModelProperty; | |||
import lombok.Data; | |||
/** | |||
* <p> | |||
* MeetingSettingsSaveReq | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 09:53 2023/12/27 | |||
*/ | |||
@Data | |||
public class MeetingSettingsSaveReq { | |||
@ApiModelProperty("是否启用") | |||
private Boolean enable; | |||
@ApiModelProperty("配置内容") | |||
private Object settingsContent; | |||
@ApiModelProperty("配置类型") | |||
private MeetingSettingsTypeEnum settingsType; | |||
@ApiModelProperty("仅做参数展示") | |||
private SettingsContentPackageDTO settingsContentPackage; | |||
public static class SettingsContentPackageDTO { | |||
@ApiModelProperty("专家邀请免打扰时段设置") | |||
private ExpertInviteIgnoreTimeContentDTO expertInviteIgnoreTimeContent; | |||
@ApiModelProperty("专家评价时间设置") | |||
private ExpertJudgeTimeLimitContentDTO expertJudgeTimeLimitContent; | |||
} | |||
} |
@@ -50,16 +50,6 @@ public class MeetingDetailBasicVO { | |||
@JSONField(format = "yyyy-MM-dd HH:mm") | |||
private LocalDateTime endTime; | |||
@ApiModelProperty("评委到场时间") | |||
@JSONField(format = "yyyy-MM-dd HH:mm") | |||
private LocalDateTime judgesAttendanceTime; | |||
@ApiModelProperty("会议耗时") | |||
private Integer meetingUsageTime; | |||
@ApiModelProperty("短信通知单位签名") | |||
private String smsNotifySign; | |||
@ApiModelProperty("联系人") | |||
private String connecter; | |||
@@ -111,4 +101,10 @@ public class MeetingDetailBasicVO { | |||
@ApiModelProperty("相关材料") | |||
private String attachFiles; | |||
@ApiModelProperty("会议结果说明") | |||
private String resultDescription; | |||
@ApiModelProperty("会议结果附件") | |||
private String resultAttachFiles; | |||
} |
@@ -121,11 +121,6 @@ public class MeetingManageHelper { | |||
} | |||
public void buildMeetingQuery(LambdaQueryWrapper<Meeting> query, MeetingListReq req) { | |||
if (StrUtils.isNotBlank(req.getRegionCode())) { | |||
List<RegionDTO> regions = regionCacheHelper.listChildren(req.getRegionCode(), req.getRegionLevel()); | |||
List<String> regionCodes = CollUtils.fieldList(regions, RegionDTO::getRegionCode); | |||
query.in(Meeting::getRegionCode, regionCodes).ge(Meeting::getRegionLevel, req.getRegionLevel()); | |||
} | |||
if (StrUtil.isNotBlank(req.getName())) { | |||
query.like(Meeting::getName, req.getName()); | |||
} | |||
@@ -195,7 +195,6 @@ public class ExpertExportManage { | |||
Meeting meeting = meetingService.getById(meetingId); | |||
LaborFeeAuditTableDTO data = new LaborFeeAuditTableDTO(); | |||
data.setMeetingTime(DateUtil.localDateTimeFormat(meeting.getStartTime(), "yyyy-MM-dd HH:mm")); | |||
data.setMeetingUsageTime(meetingUsageTime.apply(meeting.getMeetingUsageTime())); | |||
List<String> projectNames = new ArrayList<>(); | |||
if (meeting.getIsInnerProject()) { | |||
List<MeetingInnerProject> inners = meetingInnerProjectService.listByMeetingId(meetingId); | |||
@@ -243,7 +242,6 @@ public class ExpertExportManage { | |||
Meeting meeting = meetingService.getById(meetingId); | |||
ExpertInviteTableDTO data = new ExpertInviteTableDTO(); | |||
data.setMeetingTime(DateUtil.localDateTimeFormat(meeting.getStartTime(), "yyyy-MM-dd HH:mm")); | |||
data.setMeetingUsageTime(meetingUsageTime.apply(meeting.getMeetingUsageTime())); | |||
data.setMeetingCreateBy(meeting.getCreator()); | |||
data.setMeetingAddress(meeting.getMeetingAddress()); | |||
if (meeting.getIsInnerProject()) { | |||
@@ -7,12 +7,12 @@ import cn.hutool.core.util.StrUtil; | |||
import cn.hutool.crypto.SecureUtil; | |||
import cn.hutool.json.JSONUtil; | |||
import com.alibaba.fastjson.JSON; | |||
import com.baomidou.mybatisplus.core.conditions.Wrapper; | |||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | |||
import com.hz.pm.api.common.helper.RegionCacheHelper; | |||
import com.hz.pm.api.common.model.entity.ViewRegionDTO; | |||
import com.hz.pm.api.expert.entity.ExpertUserFullInfo; | |||
import com.hz.pm.api.expert.service.IExpertReviewService; | |||
import com.hz.pm.api.expert.service.IExpertUserFullInfoService; | |||
@@ -132,8 +132,6 @@ public class MeetingManage { | |||
meeting.setStatus(MeetingStatusEnum.NORMAL.getCode()); | |||
meeting.setHoldOrg(userDetail.getOrganizationName()); | |||
meeting.setHoldOrgCode(userDetail.getOrganizationCode()); | |||
meeting.setRegionCode(userDetail.getRegionCode()); | |||
meeting.setRegionLevel(userDetail.getRegionLevel()); | |||
meeting.setCreator(userDetail.getUsername()); | |||
meeting.setInviteStatus(Boolean.FALSE); | |||
meeting.setConfirmedRoster(Boolean.FALSE); | |||
@@ -356,7 +354,7 @@ public class MeetingManage { | |||
item.setMeetingExpertId(info.getMeetingExpertId()); | |||
item.setExpertStatus(info.getStatus()); | |||
MeetingExpertJudge judge = expertJudgeMap.get(info.getMeetingExpertId()); | |||
item.setHasJudge(judge!= null); | |||
item.setHasJudge(judge != null); | |||
if (judge != null) { | |||
item.setJudgeScore(judge.getScore()); | |||
} | |||
@@ -404,19 +402,9 @@ public class MeetingManage { | |||
* @author WendyYang | |||
*/ | |||
public PageVo<MeetingByManagerVO> meetingListForManager(MeetingListReq req) { | |||
ViewRegionDTO viewRegions = meetingDataScopeHelper.meetingListViewRegions(); | |||
Collection<String> regions; | |||
if ((regions = viewRegions.getRegions()) != null && regions.isEmpty()) { | |||
return PageVo.empty(); | |||
} | |||
LambdaQueryWrapper<Meeting> query = new LambdaQueryWrapper<Meeting>() | |||
.eq(req.getStatus() != null, Meeting::getStatus, req.getStatus()) | |||
.orderByDesc(Meeting::getCreateOn); | |||
// 补充逻辑 如果拥有超级管理员权限可以看到所有事务 | |||
if (regions != null) { | |||
query.in(Meeting::getRegionCode, regions); | |||
query.ge(Meeting::getRegionLevel, viewRegions.getRegionLevel()); | |||
} | |||
query.eq(req.getStatus() != null, Meeting::getStatus, req.getStatus()); | |||
meetingManageHelper.buildMeetingQuery(query, req); | |||
Page<Meeting> page = meetingService.page(req.page(), query); | |||
if (page.getTotal() == 0) { | |||
@@ -435,15 +423,12 @@ public class MeetingManage { | |||
Assert.notNull(meeting, "会议不存在"); | |||
MeetingDetailBasicVO detail = MeetingDetailBasicVO.builder() | |||
.meetingId(meeting.getId()) | |||
.regionCode(meeting.getRegionCode()) | |||
.meetingName(meeting.getName()) | |||
.meetingType(meeting.getType()) | |||
.meetingAddress(meeting.getMeetingAddress()) | |||
.typeName(getDictName(meeting.getType())) | |||
.startTime(meeting.getStartTime()) | |||
.endTime(meeting.getEndTime()) | |||
.judgesAttendanceTime(meeting.getJudgesAttendanceTime()) | |||
.meetingUsageTime(meeting.getMeetingUsageTime()) | |||
.contact(meeting.getContact()) | |||
.connecter(meeting.getConnecter()) | |||
.status(meeting.getStatus()) | |||
@@ -456,7 +441,8 @@ public class MeetingManage { | |||
.invitedStopped(meeting.getInviteStatus()) | |||
.attachFiles(meeting.getAttachFiles()) | |||
.description(meeting.getDescription()) | |||
.smsNotifySign(meeting.getSmsNotifySign()) | |||
.resultDescription(meeting.getResultDescription()) | |||
.resultAttachFiles(meeting.getResultAttachFiles()) | |||
.remark(meeting.getRemark()) | |||
.build(); | |||
if (meeting.getIsInnerProject() != null) { | |||
@@ -935,7 +921,32 @@ public class MeetingManage { | |||
} | |||
public void uploadMeetingResult(MeetingResultUploadReq req) { | |||
String key = "meeting_result_upload:" + req.getMeetingProjectId(); | |||
String key = "meeting_result_upload:" + req.getMeetingId(); | |||
if (!distributedLock.lock(key, RETRY_TIMES)) { | |||
throw BizException.wrap("正在上传会议结果,请勿重复操作"); | |||
} | |||
try { | |||
Meeting meeting = meetingService.getById(req.getMeetingId()); | |||
if (meeting == null || MeetingStatusEnum.CANCELED.eq(meeting.getStatus())) { | |||
throw BizException.wrap("会议不存在或已取消"); | |||
} | |||
LocalDateTime now = LocalDateTime.now(); | |||
if (meeting.getEndTime().isAfter(now)) { | |||
throw BizException.wrap("会议未结束"); | |||
} | |||
Wrapper<Meeting> update = Wrappers.lambdaUpdate(Meeting.class) | |||
.set(Meeting::getResultDescription, req.getResultDescription()) | |||
.set(Meeting::getResultAttachFiles, req.getResultAttachFiles()) | |||
.set(Meeting::getUpdateOn, now) | |||
.eq(Meeting::getId, req.getMeetingId()); | |||
meetingService.update(update); | |||
} finally { | |||
distributedLock.releaseLock(key); | |||
} | |||
} | |||
public void uploadProjectReviewResult(ProjectReviewResultUploadReq req) { | |||
String key = "meeting_project_result_upload:" + req.getMeetingProjectId(); | |||
if (!distributedLock.lock(key, RETRY_TIMES)) { | |||
throw BizException.wrap("正在上传会议结果,请勿重复操作"); | |||
} | |||
@@ -0,0 +1,60 @@ | |||
package com.hz.pm.api.meeting.manage; | |||
import cn.hutool.json.JSONUtil; | |||
import com.baomidou.mybatisplus.core.conditions.Wrapper; | |||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||
import com.hz.pm.api.meeting.entity.domain.MeetingSettings; | |||
import com.hz.pm.api.meeting.entity.enumeration.MeetingSettingsTypeEnum; | |||
import com.hz.pm.api.meeting.entity.req.MeetingSettingsSaveReq; | |||
import com.hz.pm.api.meeting.service.IMeetingSettingsService; | |||
import lombok.AllArgsConstructor; | |||
import org.springframework.stereotype.Component; | |||
/** | |||
* <p> | |||
* MeetingSettingSmanage | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 09:48 2023/12/27 | |||
*/ | |||
@Component | |||
@AllArgsConstructor | |||
public class MeetingSettingsManage { | |||
private final IMeetingSettingsService meetingSettingsService; | |||
private MeetingSettings getBySettingsType(MeetingSettingsTypeEnum settingsType){ | |||
Wrapper<MeetingSettings> query = Wrappers.lambdaQuery(MeetingSettings.class) | |||
.eq(MeetingSettings::getSettingsType, settingsType); | |||
return meetingSettingsService.getOne(query); | |||
} | |||
public static <T> T parseContent(String content,Class<T> tClass){ | |||
return JSONUtil.toBean(content, tClass); | |||
} | |||
public MeetingSettingsSaveReq getSettings(MeetingSettingsTypeEnum settingsType){ | |||
MeetingSettings settings = getBySettingsType(settingsType); | |||
if (settings == null) { | |||
return null; | |||
} | |||
MeetingSettingsSaveReq result = new MeetingSettingsSaveReq(); | |||
result.setEnable(settings.getEnable()); | |||
result.setSettingsType(settings.getSettingsType()); | |||
result.setSettingsContent(settings.getSettingsContent()); | |||
return result; | |||
} | |||
public synchronized void saveSettings(MeetingSettingsSaveReq req) { | |||
MeetingSettings settings = getBySettingsType(req.getSettingsType()); | |||
if (settings == null) { | |||
settings = new MeetingSettings(); | |||
settings.setSettingsContent(req.getSettingsType().name()); | |||
settings.setEnable(req.getEnable()); | |||
settings.setSettingsContent(JSONUtil.toJsonStr(req.getSettingsContent())); | |||
} | |||
meetingSettingsService.saveOrUpdate(settings); | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
package com.hz.pm.api.meeting.mapper; | |||
import com.hz.pm.api.meeting.entity.domain.MeetingSettings; | |||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||
/** | |||
* <p> | |||
* Mapper 接口 | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 2023-12-27 | |||
*/ | |||
public interface MeetingSettingsMapper extends BaseMapper<MeetingSettings> { | |||
} |
@@ -0,0 +1,5 @@ | |||
<?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.hz.pm.api.meeting.mapper.MeetingSettingsMapper"> | |||
</mapper> |
@@ -0,0 +1,16 @@ | |||
package com.hz.pm.api.meeting.service; | |||
import com.hz.pm.api.meeting.entity.domain.MeetingSettings; | |||
import com.baomidou.mybatisplus.extension.service.IService; | |||
/** | |||
* <p> | |||
* 服务类 | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 2023-12-27 | |||
*/ | |||
public interface IMeetingSettingsService extends IService<MeetingSettings> { | |||
} |
@@ -0,0 +1,20 @@ | |||
package com.hz.pm.api.meeting.service.impl; | |||
import com.hz.pm.api.meeting.entity.domain.MeetingSettings; | |||
import com.hz.pm.api.meeting.mapper.MeetingSettingsMapper; | |||
import com.hz.pm.api.meeting.service.IMeetingSettingsService; | |||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||
import org.springframework.stereotype.Service; | |||
/** | |||
* <p> | |||
* 服务实现类 | |||
* </p> | |||
* | |||
* @author WendyYang | |||
* @since 2023-12-27 | |||
*/ | |||
@Service | |||
public class MeetingSettingsServiceImpl extends ServiceImpl<MeetingSettingsMapper, MeetingSettings> implements IMeetingSettingsService { | |||
} |
@@ -55,7 +55,7 @@ public class CodeGen { | |||
} | |||
public static void main(String[] args) { | |||
generate("CMM", "user", PATH_YYD, "mh_unit"); | |||
generate("WendyYang", "meeting", PATH_YYD, "meeting_settings"); | |||
} | |||
} |