From 8caafbd49d90ca47055dd62cf99da7b616a9e4b6 Mon Sep 17 00:00:00 2001 From: V26772074 Date: Fri, 6 Sep 2024 10:01:52 +0800 Subject: [PATCH] update --- .../java/jnpf/mapper/LotteryReviewMapper.java | 3 + .../main/java/jnpf/service/ExpertService.java | 3 + .../jnpf/service/ILotteryProjectService.java | 24 + .../jnpf/service/ILotteryReviewService.java | 2 + .../BiddingProjectSubscribeServiceImpl.java | 15 + .../jnpf/service/impl/ExpertServiceImpl.java | 123 ++- .../impl/LotteryProjectServiceImpl.java | 729 +++++++++++++++++- .../impl/LotteryReviewServiceImpl.java | 31 + .../impl/RedisSerialNumberGenerator.java | 6 + .../main/resources/mapper/ExpertMapper.xml | 13 +- .../resources/mapper/LotteryProjectMapper.xml | 29 +- .../resources/mapper/LotteryReviewMapper.xml | 18 + .../BiddingProjectSubscribeController.java | 8 +- .../jnpf/controller/ExpertController.java | 11 +- .../controller/LotteryProjectController.java | 84 +- .../src/main/java/jnpf/entity/Expert.java | 10 +- .../main/java/jnpf/entity/LotteryProject.java | 17 +- .../main/java/jnpf/entity/LotteryReview.java | 21 +- .../model/ContactInformationTypeHandler.java | 62 ++ .../model/ExpertGroupInfoTypeHandler.java | 63 ++ .../model/ExtractExpertsInfoTypeHandler.java | 64 ++ .../java/jnpf/model/JsonArrayTypeHandler.java | 62 ++ .../main/java/jnpf/model/dto/ExpertDto.java | 71 +- .../jnpf/model/dto/LotteryProjectDto.java | 192 ++++- .../jnpf/templete/招投标公司打印.docx | Bin 0 -> 10718 bytes ...份有限公司ERP系统建设项目.docx | Bin 0 -> 10688 bytes pom.xml | 28 + 27 files changed, 1616 insertions(+), 73 deletions(-) create mode 100644 jnpf-tendering-entity/src/main/java/jnpf/model/ContactInformationTypeHandler.java create mode 100644 jnpf-tendering-entity/src/main/java/jnpf/model/ExpertGroupInfoTypeHandler.java create mode 100644 jnpf-tendering-entity/src/main/java/jnpf/model/ExtractExpertsInfoTypeHandler.java create mode 100644 jnpf-tendering-entity/src/main/java/jnpf/model/JsonArrayTypeHandler.java create mode 100644 jnpf-tendering-server/src/main/resources/jnpf/templete/招投标公司打印.docx create mode 100644 jnpf-tendering-server/src/main/resources/jnpf/templete/浙江出版传媒股份有限公司ERP系统建设项目.docx diff --git a/jnpf-tendering-biz/src/main/java/jnpf/mapper/LotteryReviewMapper.java b/jnpf-tendering-biz/src/main/java/jnpf/mapper/LotteryReviewMapper.java index 4386aab..f1f601d 100644 --- a/jnpf-tendering-biz/src/main/java/jnpf/mapper/LotteryReviewMapper.java +++ b/jnpf-tendering-biz/src/main/java/jnpf/mapper/LotteryReviewMapper.java @@ -2,6 +2,8 @@ package jnpf.mapper; import jnpf.entity.LotteryReview; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import jnpf.model.dto.LotteryProjectDto; +import org.apache.ibatis.annotations.Param; /** *

@@ -13,4 +15,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; */ public interface LotteryReviewMapper extends BaseMapper { + LotteryProjectDto.QueryReviewResponse queryReviewInfo(@Param("id") String id); } diff --git a/jnpf-tendering-biz/src/main/java/jnpf/service/ExpertService.java b/jnpf-tendering-biz/src/main/java/jnpf/service/ExpertService.java index 5510f01..0e85512 100644 --- a/jnpf-tendering-biz/src/main/java/jnpf/service/ExpertService.java +++ b/jnpf-tendering-biz/src/main/java/jnpf/service/ExpertService.java @@ -6,6 +6,7 @@ import jnpf.entity.Expert; import jnpf.model.dto.ExpertDto; import jnpf.permission.model.organize.OrganizeListVO; import jnpf.permission.model.organize.PaginationOrganize; +import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -22,4 +23,6 @@ public interface ExpertService extends IService { Page queryList(ExpertDto.ListParam param); ExpertDto.ListResponse queryInfo(String id); + + void expertImport(MultipartFile file); } diff --git a/jnpf-tendering-biz/src/main/java/jnpf/service/ILotteryProjectService.java b/jnpf-tendering-biz/src/main/java/jnpf/service/ILotteryProjectService.java index a5db481..c968917 100644 --- a/jnpf-tendering-biz/src/main/java/jnpf/service/ILotteryProjectService.java +++ b/jnpf-tendering-biz/src/main/java/jnpf/service/ILotteryProjectService.java @@ -1,10 +1,14 @@ package jnpf.service; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import jnpf.base.vo.DownloadVO; +import jnpf.entity.Expert; import jnpf.entity.LotteryProject; import com.baomidou.mybatisplus.extension.service.IService; import jnpf.model.dto.LotteryProjectDto; +import java.util.List; + /** *

* 抽签项目表 服务类 @@ -24,4 +28,24 @@ public interface ILotteryProjectService extends IService { Page queryList(LotteryProjectDto.QueryListParam param); LotteryProjectDto.QueryResponse queryInfo(String id); + + void addReview(LotteryProjectDto.AddReviewParam param); + + void editReview(LotteryProjectDto.EditReviewParam param); + + void participateInConfirmation(LotteryProjectDto.ParticipateInConfirmationParam param); + + LotteryProjectDto.QueryReviewResponse queryReviewInfo(String id); + + void deleteReview(LotteryProjectDto.DeleteReviewParam param); + + void saveExtractionResults(LotteryProjectDto.SaveExtractionResultsParam param); + + List getExpertsByType(String reviewId, String expertGroup); + + DownloadVO resultPrinting(String reviewId); + + void uploadExtractionResults(LotteryProjectDto.UploadExtractionResults param); + + List getCompanyByReview(String reviewId); } diff --git a/jnpf-tendering-biz/src/main/java/jnpf/service/ILotteryReviewService.java b/jnpf-tendering-biz/src/main/java/jnpf/service/ILotteryReviewService.java index 141b6ae..6acae3b 100644 --- a/jnpf-tendering-biz/src/main/java/jnpf/service/ILotteryReviewService.java +++ b/jnpf-tendering-biz/src/main/java/jnpf/service/ILotteryReviewService.java @@ -2,6 +2,7 @@ package jnpf.service; import jnpf.entity.LotteryReview; import com.baomidou.mybatisplus.extension.service.IService; +import jnpf.model.dto.LotteryProjectDto; /** *

@@ -13,4 +14,5 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface ILotteryReviewService extends IService { + LotteryProjectDto.QueryReviewResponse queryReviewInfo(String id); } diff --git a/jnpf-tendering-biz/src/main/java/jnpf/service/impl/BiddingProjectSubscribeServiceImpl.java b/jnpf-tendering-biz/src/main/java/jnpf/service/impl/BiddingProjectSubscribeServiceImpl.java index 84fc533..78131bf 100644 --- a/jnpf-tendering-biz/src/main/java/jnpf/service/impl/BiddingProjectSubscribeServiceImpl.java +++ b/jnpf-tendering-biz/src/main/java/jnpf/service/impl/BiddingProjectSubscribeServiceImpl.java @@ -878,6 +878,15 @@ public class BiddingProjectSubscribeServiceImpl extends ServiceImpl implements ExpertService { private final OrganizeService organizeService; private final UserProvider userProvider; + private final DictionaryDataApi dictionaryDataApi; private final RedisSerialNumberGenerator redisSerialNumberGenerator; private static final String EXPERTS_KEY = "experts:"; private static final String PREFIX = "EXPERT"; + private static final String COMPANY_KEY = "company:"; + private static final String COM_PREFIX = "COMPANY"; + @Override public List getOrganizationList(PaginationOrganize pagination) { // 获取所有组织 @@ -92,18 +109,50 @@ public class ExpertServiceImpl extends ServiceImpl impleme expert.setDelFlag("0"); expert.setCreateTime(LocalDateTime.now()); expert.setUpdateTime(LocalDateTime.now()); - expert.setCreateId(userInfo.getId()); + expert.setCreateId(userInfo.getUserId()); expert.setCreateName(userInfo.getUserName()); expert.setUpdateName(userInfo.getUserName()); - expert.setUpdateId(userInfo.getId()); - long number = redisSerialNumberGenerator.generateSerialNumber(EXPERTS_KEY); - expert.setId(String.format("%s%05d", PREFIX, number)); - if(this.lambdaQuery().eq(Expert::getId, expert.getId()).exists()){ + expert.setUpdateId(userInfo.getUserId()); + long number = 0; + switch (param.getDataType()) { + case "2": + number = redisSerialNumberGenerator.generateSerialNumber(COMPANY_KEY); + expert.setId(String.format("%s%05d", COM_PREFIX, number)); + break; + case "1": + default: + number = redisSerialNumberGenerator.generateSerialNumber(EXPERTS_KEY); + expert.setId(String.format("%s%05d", PREFIX, number)); + } + + if (this.lambdaQuery().eq(Expert::getId, expert.getId()).exists()) { throw new DataException("编号生成异常,请稍后再试!"); } this.save(expert); } + + public static void main(String[] args) throws Exception { + String path = "/Users/yangzhenli/Documents/项目/jnpf/专家导入.xlsx"; + + try (InputStream inputStream = new FileInputStream(path); + Workbook workbook = WorkbookFactory.create(inputStream)) { + + Sheet sheet = workbook.getSheetAt(0); + + for (Row row : sheet) { + if (row.getRowNum() <= 1) { + // 跳过表头 + continue; + } + + String name = row.getCell(0).getStringCellValue(); + Integer age = (int) row.getCell(1).getNumericCellValue(); + + } + } + } + @Override public void edit(ExpertDto.EditParam param) { if (StrUtil.isBlank(param.getId())) { @@ -169,15 +218,13 @@ public class ExpertServiceImpl extends ServiceImpl impleme } break; case "2": - if (StrUtil.isBlank(param.getExpertName())) { - throw new DataException("联系人不能为空"); - } - if (StrUtil.isBlank(param.getPhoneNumber())) { - throw new DataException("联系电话不能为空"); + if (CollectionUtil.isEmpty(param.getContactInformation())) { + throw new DataException("联系人信息不能为空"); } if (StrUtil.isBlank(param.getCompanyName())) { throw new DataException("公司名称不能为空"); } + param.setStatus("0"); break; default: throw new DataException("新增类型错误"); @@ -203,7 +250,7 @@ public class ExpertServiceImpl extends ServiceImpl impleme @Override public Page queryList(ExpertDto.ListParam param) { checkParam(param); - return this.getBaseMapper().queryList(new Page<>(param.getPageNum(),param.getPageSize()),param); + return this.getBaseMapper().queryList(new Page<>(param.getPageNum(), param.getPageSize()), param); } private void checkParam(ExpertDto.ListParam param) { @@ -222,4 +269,58 @@ public class ExpertServiceImpl extends ServiceImpl impleme } return this.getBaseMapper().queryInfo(id); } + + @Override + public void expertImport(MultipartFile file) { + List addParamList=new ArrayList<>(); + + try (InputStream inputStream = file.getInputStream(); + Workbook workbook = WorkbookFactory.create(inputStream)) { + + Sheet sheet = workbook.getSheetAt(0); + + List groupNameList = dictionaryDataApi.getDicList("539395626211742999"); + for (Row row : sheet) { + if (row.getRowNum() <= 1) { + // 跳过表头 + continue; + } + ExpertDto.AddParam addParam=new ExpertDto.AddParam(); + addParam.setDataType("1"); + String stringCellValue = row.getCell(0).getStringCellValue(); + if (StrUtil.equals(stringCellValue,"姓名示例")){ + throw new DataException("请删除示例数据行"); + } + addParam.setExpertName(stringCellValue); + String groupName = row.getCell(1).getStringCellValue(); + Optional first = groupNameList.stream().filter(d -> d.getFullName().contains(groupName)).findFirst(); + if (!first.isPresent()){ + throw new DataException("第"+(row.getRowNum()+1)+"行数据,专家组别信息不正确,请检查"); + } + first.ifPresent(dictionaryDataEntity -> addParam.setExpertGroup(dictionaryDataEntity.getId())); + addParam.setPhoneNumber(row.getCell(2).getStringCellValue()); + String birthday = row.getCell(3).getStringCellValue(); + if (StrUtil.isNotBlank(birthday)){ + addParam.setBirthday(LocalDateTimeUtil.format(LocalDateTimeUtil.parse(birthday,"yyyyMMdd"),"yyyy-MM-dd")); + } + addParam.setExpertSources(row.getCell(4).getStringCellValue()); + addParam.setWorkUnit(row.getCell(5).getStringCellValue()); + addParam.setPost(row.getCell(6).getStringCellValue()); + addParam.setTechnicalPosition(row.getCell(7).getStringCellValue()); + addParam.setProfessionalExpertise(row.getCell(8).getStringCellValue()); + addParam.setSex(StrUtil.equals(row.getCell(9).getStringCellValue(),"男")?"1" : "2"); + if (StrUtil.isNotBlank(row.getCell(10).getStringCellValue())){ + addParam.setWorkingYears(row.getCell(10).getStringCellValue()); + } + addParam.setStatus("1"); + addParamList.add(addParam); + } + for (ExpertDto.AddParam addParam : addParamList) { + this.add(addParam); + } + }catch (Exception e){ + e.printStackTrace(); + throw new DataException(e.getMessage()); + } + } } diff --git a/jnpf-tendering-biz/src/main/java/jnpf/service/impl/LotteryProjectServiceImpl.java b/jnpf-tendering-biz/src/main/java/jnpf/service/impl/LotteryProjectServiceImpl.java index 20e5358..65de35b 100644 --- a/jnpf-tendering-biz/src/main/java/jnpf/service/impl/LotteryProjectServiceImpl.java +++ b/jnpf-tendering-biz/src/main/java/jnpf/service/impl/LotteryProjectServiceImpl.java @@ -1,17 +1,28 @@ package jnpf.service.impl; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.xuyanwu.spring.file.storage.FileInfo; +import cn.xuyanwu.spring.file.storage.MockMultipartFile; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.google.protobuf.ServiceException; import jnpf.base.UserInfo; +import jnpf.base.vo.DownloadVO; +import jnpf.constant.FileTypeConstant; +import jnpf.entity.Expert; import jnpf.entity.LotteryProject; +import jnpf.entity.LotteryReview; import jnpf.exception.DataException; +import jnpf.file.FileApi; +import jnpf.file.FileUploadApi; import jnpf.mapper.LotteryProjectMapper; +import jnpf.model.dto.ExpertDto; import jnpf.model.dto.IndicatorStatisticsDto; import jnpf.model.dto.LotteryProjectDto; import jnpf.permission.OrganizeApi; @@ -19,16 +30,28 @@ import jnpf.permission.entity.OrganizeEntity; import jnpf.permission.model.authorize.AuthorizeConditionModel; import jnpf.permission.service.OrganizeService; import jnpf.service.CustomAuthService; +import jnpf.service.ExpertService; import jnpf.service.ILotteryProjectService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jnpf.service.ILotteryReviewService; +import jnpf.util.UploaderUtil; import jnpf.util.UserProvider; import lombok.AllArgsConstructor; import org.apache.poi.ss.formula.functions.T; +import org.apache.poi.xwpf.usermodel.*; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.io.*; +import java.math.BigInteger; import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** *

@@ -45,6 +68,12 @@ public class LotteryProjectServiceImpl extends ServiceImpl getAuthWrapper(String menuId) { @@ -107,6 +136,7 @@ public class LotteryProjectServiceImpl extends ServiceImpl queryList(LotteryProjectDto.QueryListParam param) { if (param.getPageNum() == null) { @@ -121,14 +151,693 @@ public class LotteryProjectServiceImpl extends ServiceImpl(); } assert queryWhere != null; - return this.getBaseMapper().queryList(new Page<>(param.getPageNum(),param.getPageSize()),param, queryWhere.getParamNameValuePairs(),queryWhere.getSqlSegment().replace("paramNameValuePairs.", "")); + return this.getBaseMapper().queryList(new Page<>(param.getPageNum(), param.getPageSize()), param, queryWhere.getParamNameValuePairs(), queryWhere.getSqlSegment().replace("paramNameValuePairs.", "")); } @Override public LotteryProjectDto.QueryResponse queryInfo(String id) { - if (StrUtil.isBlank(id)){ + if (StrUtil.isBlank(id)) { throw new DataException("id不能为空"); } return this.getBaseMapper().queryInfo(id); } + + @Override + public void addReview(LotteryProjectDto.AddReviewParam param) { + if (StrUtil.isBlank(param.getId())) { + throw new DataException("抽签项目不能为空"); + } + if (!this.lambdaQuery() + .eq(LotteryProject::getId, param.getId()) + .exists()) { + throw new DataException("抽签项目不存在"); + } + LotteryReview lotteryReview = new LotteryReview(); + lotteryReview.setExpertGroupInfo(param.getExpertGroupInfo()); + lotteryReview.setCreateTime(LocalDateTime.now()); + lotteryReview.setRelationId(param.getId()); + lotteryReview.setDelFlag("0"); + //查询评审次数 + Long count = iLotteryReviewService.lambdaQuery() + .eq(LotteryReview::getRelationId, param.getId()) + .eq(LotteryReview::getDelFlag, "0") + .count(); + lotteryReview.setCount((count + 1) + ""); + iLotteryReviewService.save(lotteryReview); + } + + @Override + public void editReview(LotteryProjectDto.EditReviewParam param) { + if (StrUtil.isBlank(param.getId())) { + throw new DataException("评审id不能为空"); + } + LotteryReview lotteryReview = iLotteryReviewService.getById(param.getId()); + lotteryReview.setExpertGroupInfo(param.getExpertGroupInfo()); + iLotteryReviewService.saveOrUpdate(lotteryReview); + } + + + @Override + public void participateInConfirmation(LotteryProjectDto.ParticipateInConfirmationParam param) { + if (StrUtil.isBlank(param.getStatus())) { + throw new DataException("状态不能为空"); + } + if (StrUtil.isBlank(param.getId())) { + throw new DataException("评审id不能为空"); + } + LotteryReview lotteryReview = iLotteryReviewService.getById(param.getId()); + if (null == lotteryReview) { + throw new DataException("评审不存在"); + } + if (StrUtil.isBlank(param.getExpertId())) { + throw new DataException("评审专家id不能为空"); + } + List extractExpertsInfo = lotteryReview.getExtractExpertsInfo(); + if (null == extractExpertsInfo) { + throw new DataException("请先保存评审信息"); + } + Optional expertsInfo = extractExpertsInfo.stream().filter(e -> e.getId().equals(param.getExpertId())).findFirst(); + if (!expertsInfo.isPresent()) { + throw new DataException("评审专家未被抽取"); + } + UserInfo userInfo = userProvider.get(); + LotteryProjectDto.ExtractExpertsInfo extractExpertsInfoComfirm = expertsInfo.get(); + String status = param.getStatus(); + //确认参加修改组别确认人数 + if (StrUtil.equals(status, "1") && null != lotteryReview.getExpertGroupInfo()) { + List expertGroupInfo = lotteryReview.getExpertGroupInfo(); + for (LotteryProjectDto.ExpertGroupInfo groupInfo : expertGroupInfo) { + if (!groupInfo.getGroupCode().equals(extractExpertsInfoComfirm.getExpertGroup())) { + continue; + } + groupInfo.setNumberOfParticipants((Integer.parseInt(groupInfo.getNumberOfParticipants()) + 1) + ""); + } + } + extractExpertsInfoComfirm.setStatus(status); + extractExpertsInfoComfirm.setRemark(param.getRemark()); + extractExpertsInfoComfirm.setConfirmTime(LocalDateTime.now()); + extractExpertsInfoComfirm.setConfirmId(userInfo.getUserId()); + extractExpertsInfoComfirm.setConfirmName(userInfo.getUserName()); + extractExpertsInfoComfirm.setShowJoinButton(false); + iLotteryReviewService.updateById(lotteryReview); + + } + + @Override + public LotteryProjectDto.QueryReviewResponse queryReviewInfo(String id) { + if (StrUtil.isBlank(id)) { + throw new DataException("评审信息id不能为空"); + } + return iLotteryReviewService.queryReviewInfo(id); + } + + @Override + public void deleteReview(LotteryProjectDto.DeleteReviewParam param) { + if (StrUtil.isBlank(param.getId())) { + throw new DataException("评审信息id不能为空"); + } + iLotteryReviewService.lambdaUpdate() + .set(LotteryReview::getDelFlag, "1") + .eq(LotteryReview::getId, param.getId()) + .update(); + } + + @Override + public void saveExtractionResults(LotteryProjectDto.SaveExtractionResultsParam param) { + if (StrUtil.isBlank(param.getId())) { + throw new DataException("评审信息id不能为空"); + } + LotteryReview lotteryReview = iLotteryReviewService.getById(param.getId()); + //获取抽取轮次 + long round = redisSerialNumberGenerator.generateSerialNumber(ROUND_KEY + lotteryReview.getId(), 1L); + //组别删除按钮不再展示 + if (round >= 1L && null != lotteryReview.getExpertGroupInfo()) { + + for (LotteryProjectDto.ExpertGroupInfo expertGroupInfo : lotteryReview.getExpertGroupInfo()) { + expertGroupInfo.setShowDelButton(false); + } + } + List oldExpertIdList = null; + if (null != lotteryReview.getExtractExpertsInfo()) { + oldExpertIdList = lotteryReview.getExtractExpertsInfo().stream().map(LotteryProjectDto.ExtractExpertsInfo::getId).collect(Collectors.toList()); + } + //配置抽取轮次 + for (LotteryProjectDto.ExtractExpertsInfo extractExpertsInfo : param.getExtractExpertsInfo()) { + if (CollectionUtil.isNotEmpty(oldExpertIdList)) { + if (oldExpertIdList.contains(extractExpertsInfo.getId())) { + continue; + } + } + if (StrUtil.isBlank(extractExpertsInfo.getExtractionRounds())) { + extractExpertsInfo.setExtractionRounds(round + ""); + } + if (null == lotteryReview.getExtractExpertsInfo()) { + lotteryReview.setExtractExpertsInfo(new ArrayList<>()); + } + lotteryReview.getExtractExpertsInfo().add(extractExpertsInfo); + } + iLotteryReviewService.updateById(lotteryReview); + } + + @Override + public List getExpertsByType(String reviewId, String expertGroup) { + if (StrUtil.isBlank(reviewId) || StrUtil.isBlank(expertGroup)) { + throw new DataException("评审信息id和抽取类型不能为空"); + } + //获取评审信息 + LotteryReview lotteryReview = iLotteryReviewService.getById(reviewId); + + //获取已专家编号列表抽取 + List expertIdList = null; + if (null != lotteryReview.getExtractExpertsInfo()) { + expertIdList = lotteryReview.getExtractExpertsInfo().stream().map(LotteryProjectDto.ExtractExpertsInfo::getId).collect(Collectors.toList()); + } + return expertService.lambdaQuery() + .eq(Expert::getStatus, "0") + .eq(Expert::getDelFlag, "0") + .eq(Expert::getDataType, "1") + .eq(Expert::getExpertGroup, expertGroup) + .notIn(CollectionUtil.isNotEmpty(expertIdList), Expert::getId, expertIdList) + .list(); + } + + @Override + public DownloadVO resultPrinting(String reviewId) { + if (StrUtil.isBlank(reviewId)) { + throw new DataException("评审信息id不能为空"); + } + LotteryReview lotteryReview = iLotteryReviewService.getById(reviewId); + if (null == lotteryReview.getExtractExpertsInfo()) { + throw new DataException("未抽取专家,无法打印"); + } + //校验打印类型 + LotteryProject lotteryProject = this.getById(lotteryReview.getRelationId()); + if (null==lotteryReview.getExtractExpertsInfo()){ + throw new DataException("未抽取专家,无法打印[2]"); + } + List extractExpertsInfo = lotteryReview.getExtractExpertsInfo().stream().filter(e->e.getStatus().equals(LotteryProjectDto.ConfirmEnum.JOIN.getCode())).collect(Collectors.toList()); + DownloadVO vo = DownloadVO.builder().build(); + switch (lotteryProject.getLotteryType()){ + case "1": + if (CollectionUtil.isEmpty(extractExpertsInfo)){ + throw new DataException("暂未有确认专家,无法打印"); + } + try { + MockMultipartFile mockMultipartFile = expertPrinting("专家抽取结果打印.docx", extractExpertsInfo); + String temporaryFilePath = fileApi.getPath(FileTypeConstant.TEMPORARY); + FileInfo fileInfo = fileUploadApi.uploadFile(mockMultipartFile, temporaryFilePath, "专家抽取结果打印.docx"); + vo.setName(fileInfo.getFilename()); + vo.setUrl(UploaderUtil.uploaderFile(fileInfo.getFilename() + "#" + "Temporary") + "&name=" + "专家抽取结果打印.docx"); + } catch (Exception e) { + log.error("专家抽取结果打印异常", e); + } + break; + case "2": + try { + if (CollectionUtil.isEmpty(extractExpertsInfo)){ + throw new DataException("暂未有确认公司,无法打印"); + } + MockMultipartFile mockMultipartFile = companyPrinting("招投标公司抽取结果打印.docx", extractExpertsInfo); + String temporaryFilePath = fileApi.getPath(FileTypeConstant.TEMPORARY); + FileInfo fileInfo = fileUploadApi.uploadFile(mockMultipartFile, temporaryFilePath, "招投标公司抽取结果打印.docx"); + vo.setName(fileInfo.getFilename()); + vo.setUrl(UploaderUtil.uploaderFile(fileInfo.getFilename() + "#" + "Temporary") + "&name=" + "招投标公司抽取结果打印.docx"); + } catch (Exception e) { + log.error("专家抽取结果打印异常", e); + } + break; + } + + + return vo; + } + + private MockMultipartFile expertPrinting(String fileName, List data) throws Exception { + + try (InputStream inputStream = ResourceUtil.getStream("jnpf/templete/浙江出版传媒股份有限公司ERP系统建设项目.docx"); + XWPFDocument doc = new XWPFDocument(inputStream)) { + + // 找到标记位置的段落 + XWPFParagraph placeholderParagraph = null; + for (XWPFParagraph paragraph : doc.getParagraphs()) { + if (paragraph.getText().contains("{{table_here}}")) { + placeholderParagraph = paragraph; + break; + } + } + + if (placeholderParagraph == null) { + throw new IllegalStateException("Cannot find placeholder in the document."); + } + + // 删除包含占位符的段落 + XWPFRun run = placeholderParagraph.getRuns().get(0); + run.setText(run.getText(0).replace("{{table_here}}", ""), 0); + + // 在占位符位置插入表格 + // 插入表格到占位符位置后 +// XWPFTable table = doc.createTable(); + XWPFTable table = doc.insertNewTbl(placeholderParagraph.getCTP().newCursor()); + table.setWidth("100%"); + + // 创建表头 + XWPFTableRow headerRow = table.getRow(0); + headerRow.getCell(0).setText("专家编号"); + headerRow.addNewTableCell().setText("专家姓名"); + headerRow.addNewTableCell().setText("出版集团"); + headerRow.addNewTableCell().setText("联系方式"); + headerRow.addNewTableCell().setText("备注"); + + // 填充表格数据 + for (LotteryProjectDto.ExtractExpertsInfo datum : data) { + + XWPFTableRow row = table.createRow(); + row.getCell(0).setText(datum.getId()); + row.getCell(1).setText(datum.getExpertName()); + row.getCell(2).setText(datum.getWorkUnit()); + row.getCell(3).setText(datum.getPhoneNumber()); + row.getCell(4).setText(datum.getRemark()); + } + XWPFTableRow rowEnd = table.createRow(); + rowEnd.getCell(3).setText("总人数:" + data.size()); + + + for (XWPFTableRow row : table.getRows()) { + for (XWPFTableCell tableCell : row.getTableCells()) { + List paragraphs = tableCell.getParagraphs(); + for (XWPFParagraph paragraph : paragraphs) { + List runs = paragraph.getRuns(); + for (XWPFRun xwpfRun : runs) { + xwpfRun.setFontFamily("仿宋"); + xwpfRun.setFontSize(10); + } + } + } + } + // 保存Word文档 +// try (FileOutputStream fos = new FileOutputStream("/Users/yangzhenli/Documents/项目/jnpf/结果打印_out.docx")) { +// doc.write(fos); +// } + + // 将XWPFDocument写入ByteArrayOutputStream + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + MockMultipartFile mockMultipartFile = null; + try { + doc.write(byteArrayOutputStream); + // 将ByteArrayOutputStream转换为MockMultipartFile + mockMultipartFile = new MockMultipartFile( + fileName, // 文件名 + fileName, // 原始文件名 + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", // ContentType + byteArrayOutputStream.toByteArray() // 文件内容 + ); + } finally { + if (null != byteArrayOutputStream) { + byteArrayOutputStream.close(); + } + } + + + return mockMultipartFile; + } + } + + private MockMultipartFile companyPrinting(String fileName, List data) throws Exception { + + try (InputStream inputStream = ResourceUtil.getStream("jnpf/templete/招投标公司打印.docx"); + XWPFDocument doc = new XWPFDocument(inputStream)) { + + // 找到标记位置的段落 + XWPFParagraph placeholderParagraph = null; + for (XWPFParagraph paragraph : doc.getParagraphs()) { + if (paragraph.getText().contains("{{table_here}}")) { + placeholderParagraph = paragraph; + break; + } + } + + if (placeholderParagraph == null) { + throw new IllegalStateException("Cannot find placeholder in the document."); + } + + // 删除包含占位符的段落 + XWPFRun run = placeholderParagraph.getRuns().get(0); + run.setText(run.getText(0).replace("{{table_here}}", ""), 0); + + // 在占位符位置插入表格 + // 插入表格到占位符位置后 +// XWPFTable table = doc.createTable(); + XWPFTable table = doc.insertNewTbl(placeholderParagraph.getCTP().newCursor()); + table.setWidth("100%"); + + XWPFTableRow headerRow = table.getRow(0); + headerRow.getCell(0).setText("公司编号"); + headerRow.addNewTableCell().setText("招投标公司"); + headerRow.addNewTableCell().setText("联系人"); + headerRow.addNewTableCell().setText("联系方式"); + headerRow.addNewTableCell().setText("备注"); + + + // // 填充表格数据 + for (LotteryProjectDto.ExtractExpertsInfo datum : data) { + int i = 0; + int startRowNum=1; + for (ExpertDto.ContactInformation contactInformation : datum.getContactInformation()) { + XWPFTableRow row = table.createRow(); + row.getCell(0).setText(datum.getId()); + row.getCell(1).setText(datum.getCompanyName()); + + row.getCell(2).setText(contactInformation.getContactName()); + row.getCell(3).setText(contactInformation.getContactPhone()); + row.getCell(4).setText(datum.getRemark()); + if (i == 0) { + startRowNum=table.getRows().indexOf(row); + datum.setId(""); + datum.setCompanyName(""); + } + i++; + } + mergeCellsVertically(table,0,startRowNum,(datum.getContactInformation().size()-1)+startRowNum); + mergeCellsVertically(table,1,startRowNum,(datum.getContactInformation().size()-1)+startRowNum); + mergeCellsVertically(table,4,startRowNum,(datum.getContactInformation().size()-1)+startRowNum); + + } + // 保存Word文档 +// try (FileOutputStream fos = new FileOutputStream("/Users/yangzhenli/Documents/项目/jnpf/结果打印_out.docx")) { +// doc.write(fos); +// } + + // 将XWPFDocument写入ByteArrayOutputStream + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + MockMultipartFile mockMultipartFile = null; + try { + doc.write(byteArrayOutputStream); + // 将ByteArrayOutputStream转换为MockMultipartFile + mockMultipartFile = new MockMultipartFile( + fileName, // 文件名 + fileName, // 原始文件名 + "application/vnd.openxmlformats-officedocument.wordprocessingml.document", // ContentType + byteArrayOutputStream.toByteArray() // 文件内容 + ); + } finally { + byteArrayOutputStream.close(); + } + + + return mockMultipartFile; + } + } + + + @Override + public void uploadExtractionResults(LotteryProjectDto.UploadExtractionResults param) { + if (StrUtil.isBlank(param.getId())) { + throw new DataException("id不能为空"); + } + LotteryProject lotteryProject = this.getById(param.getId()); + lotteryProject.setUploadResultsInfo(param.getUploaderVO()); + lotteryProject.setStatus(LotteryProjectDto.StatusEnum.ALREADY_EXTRACTED.getCode()); + lotteryProject.setStatusName(LotteryProjectDto.StatusEnum.ALREADY_EXTRACTED.getDescribe()); + this.saveOrUpdate(lotteryProject); + + } + + @Override + public List getCompanyByReview(String reviewId) { + if (StrUtil.isBlank(reviewId)) { + throw new DataException("评审ID不能为空"); + } + //获取评审信息 + LotteryReview lotteryReview = iLotteryReviewService.getById(reviewId); + //获取已专家编号列表抽取 + List expertIdList = null; + if (null != lotteryReview.getExtractExpertsInfo()) { + expertIdList = lotteryReview.getExtractExpertsInfo().stream().map(LotteryProjectDto.ExtractExpertsInfo::getId).collect(Collectors.toList()); + } + return expertService.lambdaQuery() + .eq(Expert::getStatus, "0") + .eq(Expert::getDelFlag, "0") + .eq(Expert::getDataType, "2") + .notIn(CollectionUtil.isNotEmpty(expertIdList), Expert::getId, expertIdList) + .list(); + } + + public static void main(String[] args) throws IOException { + + + String s = "[\n" + + " {\n" + + " \"id\": \"EXPERT00010\",\n" + + " \"expertName\": \"测试专家\",\n" + + " \"expertGroup\": \"\",\n" + + " \"phoneNumber\": \"13467167538\",\n" + + " \"workUnit\": \"工作单位\",\n" + + " \"confirmTime\": \"2024-09-03 15:09:50\",\n" + + " \"confirmName\": \"一级\",\n" + + " \"confirmId\": \"568797187002084037\",\n" + + " \"status\": \"1\",\n" + + " \"remark\": \"同意\",\n" + + " \"showJoinButton\": false,\n" + + " \"extractionRounds\": \"4\"\n" + + " },\n" + + " {\n" + + " \"id\": \"EXPERT00011\",\n" + + " \"expertName\": \"测试专家2\",\n" + + " \"expertGroup\": \"\",\n" + + " \"phoneNumber\": \"13467167539\",\n" + + " \"workUnit\": \"工作单位2\",\n" + + " \"confirmTime\": \"2024-09-03 15:10:38\",\n" + + " \"confirmName\": \"一级\",\n" + + " \"confirmId\": \"568797187002084037\",\n" + + " \"status\": \"1\",\n" + + " \"remark\": \"同意\",\n" + + " \"showJoinButton\": false,\n" + + " \"extractionRounds\": \"5\"\n" + + " }\n" + + " ]"; + String s2 = "[\n" + + " {\n" + + " \"id\": \"COMPANY00002\",\n" + + " \"expertName\": null,\n" + + " \"expertGroup\": null,\n" + + " \"phoneNumber\": null,\n" + + " \"workUnit\": null,\n" + + " \"confirmTime\": \"2024-09-04 11:08:31\",\n" + + " \"confirmName\": \"一级\",\n" + + " \"confirmId\": \"568797187002084037\",\n" + + " \"status\": \"1\",\n" + + " \"remark\": \"通过\",\n" + + " \"showJoinButton\": false,\n" + + " \"contactInformation\":\n" + + " [\n" + + " {\n" + + " \"contactName\": \"杨振立\",\n" + + " \"contactPhone\": \"18177857446\"\n" + + " }\n" + + + " ],\n" + + " \"companyName\": \"测试公司名称\",\n" + + " \"extractionRounds\": \"1\"\n" + + " },\n" + + " {\n" + + " \"id\": \"COMPANY00002\",\n" + + " \"expertName\": null,\n" + + " \"expertGroup\": null,\n" + + " \"phoneNumber\": null,\n" + + " \"workUnit\": null,\n" + + " \"confirmTime\": \"2024-09-04 11:08:31\",\n" + + " \"confirmName\": \"一级\",\n" + + " \"confirmId\": \"568797187002084037\",\n" + + " \"status\": \"1\",\n" + + " \"remark\": \"通过\",\n" + + " \"showJoinButton\": false,\n" + + " \"contactInformation\":\n" + + " [\n" + + " {\n" + + " \"contactName\": \"杨振立\",\n" + + " \"contactPhone\": \"18177857446\"\n" + + " },\n" + + " {\n" + + " \"contactName\": \"联系姓名1\",\n" + + " \"contactPhone\": \"18104627731\"\n" + + " }\n" + + " ],\n" + + " \"companyName\": \"测试公司名称\",\n" + + " \"extractionRounds\": \"1\"\n" + + " }\n" + + "]"; +// List data = JSON.parseArray(s, LotteryProjectDto.ExtractExpertsInfo.class); + List data = JSON.parseArray(s2, LotteryProjectDto.ExtractExpertsInfo.class); + try (InputStream inputStream = new FileInputStream(new File("/Users/yangzhenli/Documents/项目/jnpf/浙江出版传媒股份有限公司ERP系统建设项目.docx")); + XWPFDocument doc = new XWPFDocument(inputStream)) { + + // 找到标记位置的段落 + XWPFParagraph placeholderParagraph = null; + for (XWPFParagraph paragraph : doc.getParagraphs()) { + if (paragraph.getText().contains("{{table_here}}")) { + placeholderParagraph = paragraph; + break; + } + } + + if (placeholderParagraph == null) { + throw new IllegalStateException("Cannot find placeholder in the document."); + } + + // 删除包含占位符的段落 + XWPFRun run = placeholderParagraph.getRuns().get(0); + run.setText(run.getText(0).replace("{{table_here}}", ""), 0); + + // 在占位符位置插入表格 + // 插入表格到占位符位置后 +// XWPFTable table = doc.createTable(); + XWPFTable table = doc.insertNewTbl(placeholderParagraph.getCTP().newCursor()); + table.setWidth("100%"); + XWPFTableRow headerRow = table.getRow(0); + headerRow.getCell(0).setText("公司编号"); + headerRow.addNewTableCell().setText("招投标公司"); + headerRow.addNewTableCell().setText("联系人"); + headerRow.addNewTableCell().setText("联系方式"); + headerRow.addNewTableCell().setText("备注"); + + + // // 填充表格数据 + for (LotteryProjectDto.ExtractExpertsInfo datum : data) { + int i = 0; + int startRowNum=1; + for (ExpertDto.ContactInformation contactInformation : datum.getContactInformation()) { + XWPFTableRow row = table.createRow(); + row.getCell(0).setText(datum.getId()); + row.getCell(1).setText(datum.getCompanyName()); + + row.getCell(2).setText(contactInformation.getContactName()); + row.getCell(3).setText(contactInformation.getContactPhone()); + row.getCell(4).setText(datum.getRemark()); + if (i == 0) { + startRowNum=table.getRows().indexOf(row); + datum.setId(""); + datum.setCompanyName(""); + } + i++; + } + mergeCellsVertically(table,0,startRowNum,(datum.getContactInformation().size()-1)+startRowNum); + mergeCellsVertically(table,1,startRowNum,(datum.getContactInformation().size()-1)+startRowNum); + mergeCellsVertically(table,4,startRowNum,(datum.getContactInformation().size()-1)+startRowNum); + + } +// // 在该行中添加三个单元格 +// row.createCell(); +// row.createCell(); +// +// // 假设我们要拆分第一个单元格 +// int cellIndexToSplit = 0; +// +// // 获取要拆分的单元格 +// XWPFTableCell cellToSplit = row.getCell(cellIndexToSplit); +// +// // 获取原始单元格的内容 +// String originalText = cellToSplit.getText(); +// +// // 移除第一个单元格 +// row.removeCell(cellIndexToSplit); +// +// // 创建两个新单元格 +// XWPFTableCell newCell1 = row.createCell(); +// XWPFTableCell newCell2 = row.createCell(); +// +// // 设置新单元格的内容 +// newCell1.setText("First part of split"); +// newCell2.setText("Second part of split"); +// +// // 将新的单元格移到正确的位置 +// // POI中不能直接在特定位置插入新单元格,只能依次添加。 +// // 因此,我们需要重新调整所有单元格的顺序。 +// +// // 调整现有单元格的顺序,确保表格结构正确 +// XWPFTableCell thirdCell = row.getCell(2); // 获取原始的第三个单元格 +// row.removeCell(2); // 移除第三个单元格 +// row.addNewTableCell(); // 重新创建第二个单元格(此时是新创建的空单元格) +// row.addNewTableCell(); // 创建第三个单元格(空) + + // 将原始第三个单元格的内容移动到最后 +// row.getCell(2).setText(thirdCell.getText()); + +// // 创建表头 +// XWPFTableRow headerRow = table.getRow(0); +// headerRow.getCell(0).setText("专家编号"); +// headerRow.addNewTableCell().setText("专家姓名"); +// headerRow.addNewTableCell().setText("出版集团"); +// headerRow.addNewTableCell().setText("联系方式"); +// headerRow.addNewTableCell().setText("备注"); +// +// // 填充表格数据 +// for (LotteryProjectDto.ExtractExpertsInfo datum : data) { +// +// XWPFTableRow row = table.createRow(); +// row.getCell(0).setText(datum.getId()); +// row.getCell(1).setText(datum.getExpertName()); +// row.getCell(2).setText(datum.getWorkUnit()); +// row.getCell(3).setText(datum.getPhoneNumber()); +// row.getCell(4).setText(datum.getRemark()); +// } +// XWPFTableRow rowEnd = table.createRow(); +// XWPFTableCell cell = rowEnd.getCell(0); +// // 设置单元格的文本 +// // 获取或创建 TcPr(单元格属性) +// if (cell.getCTTc().getTcPr() == null) { +// cell.getCTTc().addNewTcPr(); +// } +// cell.setText("总人数: "+data.size()+" "); +// // 合并第一行的单元格,从第一个单元格到第5个单元格 +// for (int colIndex = 0; colIndex <= 4; colIndex++) { +// XWPFTableCell cell1 = rowEnd.getCell(colIndex); +// if (cell1.getCTTc().getTcPr() == null) { +// cell1.getCTTc().addNewTcPr(); +// } +// if (colIndex == 0) { +// // 设置起始单元格跨越的列数 +// cell1.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.RESTART); +// } else { +// // 其他单元格设为继续合并 +// cell1.getCTTc().getTcPr().addNewHMerge().setVal(STMerge.CONTINUE); +// } +// } +// +// // 设置单元格文本向右对齐 +// cell.getParagraphs().get(0).setAlignment(ParagraphAlignment.RIGHT); +// +// for (XWPFTableRow row : table.getRows()) { +// for (XWPFTableCell tableCell : row.getTableCells()) { +// List paragraphs = tableCell.getParagraphs(); +// for (XWPFParagraph paragraph : paragraphs) { +// List runs = paragraph.getRuns(); +// for (XWPFRun xwpfRun : runs) { +// xwpfRun.setFontFamily("仿宋"); +// xwpfRun.setFontSize(10); +// } +// } +// } +// } + // 保存Word文档 + try (FileOutputStream fos = new FileOutputStream("/Users/yangzhenli/Documents/项目/jnpf/结果打印_out.docx")) { + doc.write(fos); + } + } + } + + private static void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) { + for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) { + XWPFTableCell cell = table.getRow(rowIndex).getCell(col); + if (rowIndex == fromRow) { + // 设置合并的起始单元格的属性 + cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.Enum.forString("restart")); + } else { + // 设置被合并的单元格的属性 + cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.Enum.forString("continue")); + } + } + } } + diff --git a/jnpf-tendering-biz/src/main/java/jnpf/service/impl/LotteryReviewServiceImpl.java b/jnpf-tendering-biz/src/main/java/jnpf/service/impl/LotteryReviewServiceImpl.java index 8a5c09c..b5a81cc 100644 --- a/jnpf-tendering-biz/src/main/java/jnpf/service/impl/LotteryReviewServiceImpl.java +++ b/jnpf-tendering-biz/src/main/java/jnpf/service/impl/LotteryReviewServiceImpl.java @@ -1,11 +1,16 @@ package jnpf.service.impl; +import cn.hutool.core.util.StrUtil; import jnpf.entity.LotteryReview; +import jnpf.exception.DataException; import jnpf.mapper.LotteryReviewMapper; +import jnpf.model.dto.LotteryProjectDto; import jnpf.service.ILotteryReviewService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; +import java.util.List; + /** *

* 评审次数 服务实现类 @@ -16,5 +21,31 @@ import org.springframework.stereotype.Service; */ @Service public class LotteryReviewServiceImpl extends ServiceImpl implements ILotteryReviewService { + @Override + public LotteryProjectDto.QueryReviewResponse queryReviewInfo(String id) { + LotteryProjectDto.QueryReviewResponse queryReviewResponse = this.getBaseMapper().queryReviewInfo(id); + if (null==queryReviewResponse){ + throw new DataException("未找到评审次数信息"); + } + int extractExperts = 0; + if (null != queryReviewResponse.getExpertGroupInfo()) { + //抽取专家计算 + List expertGroupInfo = queryReviewResponse.getExpertGroupInfo(); + for (LotteryProjectDto.ExpertGroupInfo groupInfo : expertGroupInfo) { + String numberOfExtract = groupInfo.getNumberOfExtract(); + if (StrUtil.isBlank(numberOfExtract)) { + continue; + } + extractExperts += Integer.parseInt(numberOfExtract); + } + queryReviewResponse.setExtractExperts(extractExperts); + } + //确认参加计算 + if (null != queryReviewResponse.getExtractExpertsInfo()) { +// queryReviewResponse.setExtractExperts(queryReviewResponse.getExtractExpertsInfo().size()); + queryReviewResponse.setConfirmParticipation(Integer.parseInt(queryReviewResponse.getExtractExpertsInfo().stream().filter(item -> StrUtil.equals(item.getStatus(), LotteryProjectDto.ConfirmEnum.JOIN.getCode())).count()+"")); + } + return queryReviewResponse; + } } diff --git a/jnpf-tendering-biz/src/main/java/jnpf/service/impl/RedisSerialNumberGenerator.java b/jnpf-tendering-biz/src/main/java/jnpf/service/impl/RedisSerialNumberGenerator.java index 63b6e00..8949323 100644 --- a/jnpf-tendering-biz/src/main/java/jnpf/service/impl/RedisSerialNumberGenerator.java +++ b/jnpf-tendering-biz/src/main/java/jnpf/service/impl/RedisSerialNumberGenerator.java @@ -24,4 +24,10 @@ public class RedisSerialNumberGenerator { // 使用Redis的INCR命令原子递增 return redisTemplate.opsForValue().increment(redisKey); } + + public long generateSerialNumber(String key,long defaultValue){ + String redisKey = SERIAL_KEY_PREFIX + key; + // 使用Redis的INCR命令原子递增 + return redisTemplate.opsForValue().increment(redisKey,defaultValue); + } } \ No newline at end of file diff --git a/jnpf-tendering-biz/src/main/resources/mapper/ExpertMapper.xml b/jnpf-tendering-biz/src/main/resources/mapper/ExpertMapper.xml index eed54ea..a276696 100644 --- a/jnpf-tendering-biz/src/main/resources/mapper/ExpertMapper.xml +++ b/jnpf-tendering-biz/src/main/resources/mapper/ExpertMapper.xml @@ -25,11 +25,12 @@ + id - ,expert_name ,expert_group ,company_name ,phone_number ,birthday ,expert_sources ,work_unit ,post ,technical_position ,professional_expertise ,sex ,working_years ,del_flag ,status ,data_type ,create_time ,create_id ,create_name ,update_time ,update_id ,update_name + ,expert_name ,expert_group ,company_name ,phone_number ,birthday ,expert_sources ,work_unit ,post ,technical_position ,professional_expertise ,sex ,working_years ,del_flag ,status ,data_type ,create_time ,create_id ,create_name ,update_time ,update_id ,update_name,contact_information select @@ -38,9 +39,13 @@ AND project_number like '%' #{query.projectNumber} '%' + + AND lottery_type = #{query.lotteryType} + and ${sql} + order by create_time desc @@ -64,7 +69,29 @@ + + + + + + + + + + + + + + + + id ,count ,relation_id ,expert_group_info ,extract_experts_info ,create_time ,del_flag + + + + select + from t_lottery_review + where del_flag = '0' and id = #{id} + diff --git a/jnpf-tendering-controller/src/main/java/jnpf/controller/BiddingProjectSubscribeController.java b/jnpf-tendering-controller/src/main/java/jnpf/controller/BiddingProjectSubscribeController.java index 697e3e9..9b62ee5 100644 --- a/jnpf-tendering-controller/src/main/java/jnpf/controller/BiddingProjectSubscribeController.java +++ b/jnpf-tendering-controller/src/main/java/jnpf/controller/BiddingProjectSubscribeController.java @@ -137,7 +137,9 @@ public class BiddingProjectSubscribeController { entity.setIsApproval(true); } entity.setFlowtaskid(mainId); - entity.setBidOpeningTime(new Date(Long.parseLong(oldBidOpeningTime))); + if (StrUtil.isNotBlank(oldBidOpeningTime)) { + entity.setBidOpeningTime(new Date(Long.parseLong(oldBidOpeningTime))); + } entity.setCreateTime(LocalDateTime.now()); entity.setUpdateTime(LocalDateTime.now()); checkProjectAmount(entity); @@ -245,7 +247,9 @@ public class BiddingProjectSubscribeController { bidding_project_subscribeForm = JsonUtil.getJsonToBean( generaterSwapUtil.swapDatetime(BiddingProjectSubscribeConstant.getFormData(), bidding_project_subscribeForm), BiddingProjectSubscribeForm.class); BiddingProjectSubscribeEntity subentity = JsonUtil.getJsonToBean(bidding_project_subscribeForm, BiddingProjectSubscribeEntity.class); - subentity.setBidOpeningTime(new Date(oldBidOpeningTime)); + if (StrUtil.isNotBlank(oldBidOpeningTime)) { + entity.setBidOpeningTime(new Date(Long.parseLong(oldBidOpeningTime))); + } subentity.setUpdateTime(LocalDateTime.now()); subentity.setCreateTime(entity.getCreateTime()); checkProjectAmount(subentity); diff --git a/jnpf-tendering-controller/src/main/java/jnpf/controller/ExpertController.java b/jnpf-tendering-controller/src/main/java/jnpf/controller/ExpertController.java index 55df49f..08cdffa 100644 --- a/jnpf-tendering-controller/src/main/java/jnpf/controller/ExpertController.java +++ b/jnpf-tendering-controller/src/main/java/jnpf/controller/ExpertController.java @@ -7,6 +7,7 @@ import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.parser.Feature; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jnpf.base.ActionResult; @@ -27,11 +28,12 @@ import jnpf.util.treeutil.SumTree; import jnpf.util.treeutil.newtreeutil.TreeDotUtils; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import java.util.*; @RestController -@Tag(name = "专家抽取相关接口", description = "example") +@Api("专家管理相关接口") @RequestMapping("/expert") @AllArgsConstructor public class ExpertController { @@ -54,6 +56,13 @@ public class ExpertController { return ActionResult.success(); } + @Operation(summary = "专家导入") + @PostMapping("/expertImport") + public ActionResult expertImport(@RequestParam(name = "file") MultipartFile file) { + expertService.expertImport(file); + return ActionResult.success(); + } + @Operation(summary = "修改专家/公司") @PostMapping("/edit") public ActionResult update(@RequestBody ExpertDto.EditParam param) { diff --git a/jnpf-tendering-controller/src/main/java/jnpf/controller/LotteryProjectController.java b/jnpf-tendering-controller/src/main/java/jnpf/controller/LotteryProjectController.java index 5bd3769..b0253ad 100644 --- a/jnpf-tendering-controller/src/main/java/jnpf/controller/LotteryProjectController.java +++ b/jnpf-tendering-controller/src/main/java/jnpf/controller/LotteryProjectController.java @@ -2,9 +2,12 @@ package jnpf.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jnpf.base.ActionResult; +import jnpf.base.vo.DownloadVO; +import jnpf.entity.Expert; import jnpf.entity.LotteryProject; import jnpf.model.dto.ExpertDto; import jnpf.model.dto.LotteryProjectDto; @@ -14,9 +17,11 @@ import org.springframework.web.bind.annotation.*; import org.springframework.stereotype.Controller; +import java.util.List; + @RestController -@Tag(name = "项目抽签相关接口", description = "example") +@Api("项目抽签相关接口") @RequestMapping("/lottery-project") @AllArgsConstructor public class LotteryProjectController { @@ -59,10 +64,75 @@ public class LotteryProjectController { } -// @Operation(summary = "添加评审") -// @PostMapping("/addReview") -// public ActionResult addReview(@RequestBody LotteryProjectDto.AddReviewParam param) { -// iLotteryProjectService.addReview(param); -// return ActionResult.success(); -// } + @Operation(summary = "添加评审") + @PostMapping("/addReview") + public ActionResult addReview(@RequestBody LotteryProjectDto.AddReviewParam param) { + iLotteryProjectService.addReview(param); + return ActionResult.success(); + } + + + @Operation(summary = "修改专家组别评审") + @PostMapping("/editReview") + public ActionResult editReview(@RequestBody LotteryProjectDto.EditReviewParam param) { + iLotteryProjectService.editReview(param); + return ActionResult.success(); + } + + @Operation(summary = "删除评审") + @PostMapping("/deleteReview") + public ActionResult deleteReview(@RequestBody LotteryProjectDto.DeleteReviewParam param) { + iLotteryProjectService.deleteReview(param); + return ActionResult.success(); + } + + @Operation(summary = "评审详情查询") + @GetMapping("/queryReviewInfo") + public ActionResult queryReviewInfo(@RequestParam String id) { + return ActionResult.success(iLotteryProjectService.queryReviewInfo(id)); + } + + + @Operation(summary = "抽取结果保存") + @PostMapping("/saveExtractionResults") + public ActionResult saveExtractionResults(@RequestBody LotteryProjectDto.SaveExtractionResultsParam param) { + iLotteryProjectService.saveExtractionResults(param); + return ActionResult.success(); + } + + + @Operation(summary = "抽取结果参加确认") + @PostMapping("/participateInConfirmation") + public ActionResult participateInConfirmation(@RequestBody LotteryProjectDto.ParticipateInConfirmationParam param) { + iLotteryProjectService.participateInConfirmation(param); + return ActionResult.success(); + } + + + @Operation(summary = "根据类型获取某评审下专家列表") + @GetMapping("/getExpertsByExpertGroup") + public ActionResult> getExpertsByType(@RequestParam String reviewId, @RequestParam String expertGroup){ + return ActionResult.success(iLotteryProjectService.getExpertsByType(reviewId,expertGroup)); + } + + + @Operation(summary = "根据评审查询招标公司列表") + @GetMapping("/getCompanyByReview") + public ActionResult> getCompanyByReview(@RequestParam String reviewId){ + return ActionResult.success(iLotteryProjectService.getCompanyByReview(reviewId)); + } + + + @Operation(summary = "结果打印") + @GetMapping("/resultPrinting") + public ActionResult resultPrinting(@RequestParam String reviewId){ + return ActionResult.success(iLotteryProjectService.resultPrinting(reviewId)); + } + + @Operation(summary = "上传抽取结果") + @PostMapping("/uploadExtractionResults") + public ActionResult uploadExtractionResults(@RequestBody LotteryProjectDto.UploadExtractionResults param){ + iLotteryProjectService.uploadExtractionResults(param); + return ActionResult.success(); + } } diff --git a/jnpf-tendering-entity/src/main/java/jnpf/entity/Expert.java b/jnpf-tendering-entity/src/main/java/jnpf/entity/Expert.java index 469e3c5..a6c58a8 100644 --- a/jnpf-tendering-entity/src/main/java/jnpf/entity/Expert.java +++ b/jnpf-tendering-entity/src/main/java/jnpf/entity/Expert.java @@ -4,8 +4,11 @@ import com.baomidou.mybatisplus.annotation.*; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.List; import com.fasterxml.jackson.annotation.JsonFormat; +import jnpf.model.ContactInformationTypeHandler; +import jnpf.model.dto.ExpertDto; import lombok.Getter; import lombok.Setter; @@ -19,7 +22,7 @@ import lombok.Setter; */ @Getter @Setter -@TableName("t_expert") +@TableName(value = "t_expert",autoResultMap = true) //@ApiModel(value = "Expert对象", description = "") public class Expert implements Serializable { @@ -45,6 +48,11 @@ public class Expert implements Serializable { @TableField(value = "phone_number") private String phoneNumber; + + // @ApiModelProperty("联系人信息(json)") + @TableField(value = "contact_information",typeHandler = ContactInformationTypeHandler.class) + private List contactInformation; + // @ApiModelProperty("出生日期") @TableField(value = "birthday") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") diff --git a/jnpf-tendering-entity/src/main/java/jnpf/entity/LotteryProject.java b/jnpf-tendering-entity/src/main/java/jnpf/entity/LotteryProject.java index 33a318a..4115271 100644 --- a/jnpf-tendering-entity/src/main/java/jnpf/entity/LotteryProject.java +++ b/jnpf-tendering-entity/src/main/java/jnpf/entity/LotteryProject.java @@ -7,8 +7,12 @@ import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.time.LocalDate; import java.time.LocalDateTime; + +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; +import jnpf.model.JsonTypeHandler; +import jnpf.model.dto.LotteryProjectDto; import lombok.Getter; import lombok.Setter; @@ -22,7 +26,7 @@ import lombok.Setter; */ @Getter @Setter -@TableName("t_lottery_project") +@TableName(value = "t_lottery_project",autoResultMap = true) @ApiModel(value = "LotteryProject对象", description = "抽签项目表") public class LotteryProject implements Serializable { @@ -40,6 +44,10 @@ public class LotteryProject implements Serializable { @TableField(value = "relation_id") private String relationId; + @ApiModelProperty("抽签类型 1-专家(默认) 2-公司") + @TableField(value = "lottery_type") + private String lotteryType; + @ApiModelProperty("项目编号") @TableField(value = "project_number") private String projectNumber; @@ -54,6 +62,7 @@ public class LotteryProject implements Serializable { @ApiModelProperty("评标时间") @TableField(value = "bid_evaluation_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime bidEvaluationTime; @ApiModelProperty("评标地点") @@ -86,6 +95,7 @@ public class LotteryProject implements Serializable { @ApiModelProperty("创建时间") @TableField(value = "create_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; @ApiModelProperty("创建人姓名") @@ -98,6 +108,7 @@ public class LotteryProject implements Serializable { @ApiModelProperty("更新时间") @TableField(value = "update_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime; @ApiModelProperty("更新人名称") @@ -112,5 +123,9 @@ public class LotteryProject implements Serializable { @TableField(value = "del_flag") private String delFlag; + @ApiModelProperty("结果信息") + @TableField(value ="upload_results_info",typeHandler = JsonTypeHandler.class) + private LotteryProjectDto.FileInfo uploadResultsInfo; + } diff --git a/jnpf-tendering-entity/src/main/java/jnpf/entity/LotteryReview.java b/jnpf-tendering-entity/src/main/java/jnpf/entity/LotteryReview.java index 7efc0bf..d391033 100644 --- a/jnpf-tendering-entity/src/main/java/jnpf/entity/LotteryReview.java +++ b/jnpf-tendering-entity/src/main/java/jnpf/entity/LotteryReview.java @@ -4,9 +4,12 @@ import com.baomidou.mybatisplus.annotation.*; import java.io.Serializable; import java.time.LocalDateTime; +import java.util.List; + +import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; -import jnpf.model.JsonTypeHandler; +import jnpf.model.*; import jnpf.model.dto.LotteryProjectDto; import lombok.Getter; import lombok.Setter; @@ -40,19 +43,21 @@ public class LotteryReview implements Serializable { private String relationId; @ApiModelProperty("专家组别信息json") - @TableField(value = "expert_group_info",typeHandler = JsonTypeHandler.class) - private LotteryProjectDto.ExpertGroupInfo expertGroupInfo; + @TableField(value = "expert_group_info",typeHandler = ExpertGroupInfoTypeHandler.class) + private List expertGroupInfo; @ApiModelProperty("抽取专家信息json") - @TableField(value = "extract_experts_info",typeHandler = JsonTypeHandler.class) - private String extractExpertsInfo; + @TableField(value = "extract_experts_info",typeHandler = ExtractExpertsInfoTypeHandler.class) + private List extractExpertsInfo; + + @TableField(value ="create_time") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime createTime; - @ApiModelProperty("结果信息") - @TableField(value ="upload_results_info",typeHandler = JsonTypeHandler.class) - private String uploadResultsInfo; + @TableField(value ="del_flag") + private String delFlag; } diff --git a/jnpf-tendering-entity/src/main/java/jnpf/model/ContactInformationTypeHandler.java b/jnpf-tendering-entity/src/main/java/jnpf/model/ContactInformationTypeHandler.java new file mode 100644 index 0000000..5c33741 --- /dev/null +++ b/jnpf-tendering-entity/src/main/java/jnpf/model/ContactInformationTypeHandler.java @@ -0,0 +1,62 @@ +package jnpf.model; + +import com.alibaba.fastjson.JSON; +import jnpf.model.dto.ExpertDto; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class ContactInformationTypeHandler extends BaseTypeHandler> { + + private final Class type; + + public ContactInformationTypeHandler(Class type) { + if (type == null) throw new IllegalArgumentException("Type argument cannot be null"); + this.type = type; + } + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException { + ps.setString(i, toJson(parameter)); + } + + @Override + public List getNullableResult(ResultSet rs, String columnName) throws SQLException { + return toObject(rs.getString(columnName)); + } + + @Override + public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return toObject(rs.getString(columnIndex)); + } + + @Override + public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return toObject(cs.getString(columnIndex)); + } + + private String toJson(List object) { + try { + return JSON.toJSONString(object); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private List toObject(String content) { + if (content == null || content.isEmpty()) { + return null; + } + try { + return JSON.parseArray(content,ExpertDto.ContactInformation.class); +// return objectMapper.readValue(content, new TypeReference>() {}); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/jnpf-tendering-entity/src/main/java/jnpf/model/ExpertGroupInfoTypeHandler.java b/jnpf-tendering-entity/src/main/java/jnpf/model/ExpertGroupInfoTypeHandler.java new file mode 100644 index 0000000..30c7b6f --- /dev/null +++ b/jnpf-tendering-entity/src/main/java/jnpf/model/ExpertGroupInfoTypeHandler.java @@ -0,0 +1,63 @@ +package jnpf.model; + +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import jnpf.model.dto.LotteryProjectDto; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; +import org.apache.poi.ss.formula.functions.T; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class ExpertGroupInfoTypeHandler extends BaseTypeHandler> { + private final Class type; + + public ExpertGroupInfoTypeHandler(Class type) { + if (type == null) throw new IllegalArgumentException("Type argument cannot be null"); + this.type = type; + } + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException { + ps.setString(i, toJson(parameter)); + } + + @Override + public List getNullableResult(ResultSet rs, String columnName) throws SQLException { + return toObject(rs.getString(columnName)); + } + + @Override + public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return toObject(rs.getString(columnIndex)); + } + + @Override + public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return toObject(cs.getString(columnIndex)); + } + + private String toJson(List object) { + try { + return JSON.toJSONString(object); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private List toObject(String content) { + if (content == null || content.isEmpty()) { + return null; + } + try { + return JSON.parseArray(content,LotteryProjectDto.ExpertGroupInfo.class); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/jnpf-tendering-entity/src/main/java/jnpf/model/ExtractExpertsInfoTypeHandler.java b/jnpf-tendering-entity/src/main/java/jnpf/model/ExtractExpertsInfoTypeHandler.java new file mode 100644 index 0000000..cfdd46e --- /dev/null +++ b/jnpf-tendering-entity/src/main/java/jnpf/model/ExtractExpertsInfoTypeHandler.java @@ -0,0 +1,64 @@ +package jnpf.model; + +import com.alibaba.fastjson.JSON; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import jnpf.model.dto.LotteryProjectDto; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class ExtractExpertsInfoTypeHandler extends BaseTypeHandler> { + + private final Class type; + + public ExtractExpertsInfoTypeHandler(Class type) { + if (type == null) throw new IllegalArgumentException("Type argument cannot be null"); + this.type = type; + } + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException { + ps.setString(i, toJson(parameter)); + } + + @Override + public List getNullableResult(ResultSet rs, String columnName) throws SQLException { + return toObject(rs.getString(columnName)); + } + + @Override + public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return toObject(rs.getString(columnIndex)); + } + + @Override + public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return toObject(cs.getString(columnIndex)); + } + + private String toJson(List object) { + try { + return JSON.toJSONString(object); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private List toObject(String content) { + if (content == null || content.isEmpty()) { + return null; + } + try { + return JSON.parseArray(content,LotteryProjectDto.ExtractExpertsInfo.class); +// return objectMapper.readValue(content, new TypeReference>() {}); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/jnpf-tendering-entity/src/main/java/jnpf/model/JsonArrayTypeHandler.java b/jnpf-tendering-entity/src/main/java/jnpf/model/JsonArrayTypeHandler.java new file mode 100644 index 0000000..a86fd96 --- /dev/null +++ b/jnpf-tendering-entity/src/main/java/jnpf/model/JsonArrayTypeHandler.java @@ -0,0 +1,62 @@ +package jnpf.model; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.ibatis.type.BaseTypeHandler; +import org.apache.ibatis.type.JdbcType; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +public class JsonArrayTypeHandler extends BaseTypeHandler> { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + private final Class type; + + public JsonArrayTypeHandler(Class type) { + if (type == null) throw new IllegalArgumentException("Type argument cannot be null"); + this.type = type; + } + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, List parameter, JdbcType jdbcType) throws SQLException { + ps.setString(i, toJson(parameter)); + } + + @Override + public List getNullableResult(ResultSet rs, String columnName) throws SQLException { + return toObject(rs.getString(columnName)); + } + + @Override + public List getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + return toObject(rs.getString(columnIndex)); + } + + @Override + public List getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + return toObject(cs.getString(columnIndex)); + } + + private String toJson(List object) { + try { + return objectMapper.writeValueAsString(object); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private List toObject(String content) { + if (content == null || content.isEmpty()) { + return null; + } + try { + return objectMapper.readValue(content, new TypeReference>() {}); + } catch (Exception e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/jnpf-tendering-entity/src/main/java/jnpf/model/dto/ExpertDto.java b/jnpf-tendering-entity/src/main/java/jnpf/model/dto/ExpertDto.java index 91457e4..905e76a 100644 --- a/jnpf-tendering-entity/src/main/java/jnpf/model/dto/ExpertDto.java +++ b/jnpf-tendering-entity/src/main/java/jnpf/model/dto/ExpertDto.java @@ -2,6 +2,7 @@ package jnpf.model.dto; import cn.hutool.core.date.LocalDateTimeUtil; import com.github.pagehelper.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; import jnpf.entity.Expert; import jnpf.exception.DataException; import lombok.Data; @@ -15,61 +16,62 @@ import java.util.List; public class ExpertDto { @Data public static class BaseParam { - /** - * 新增类型 1-专家 2-公司 - */ + @Schema(description = "新增类型 1-专家 2-公司 默认专家") private String dataType = "1"; - /** - * 专家姓名 - */ + @Schema(description = "专家姓名") private String expertName; - - /** - * @ApiModelProperty("专家组别(字典表id)") - */ + @Schema(description = "专家组别(字典表id)") private String expertGroup; - // @ApiModelProperty("公司名称(招投标类型)") + @Schema(description = "公司名称(招投标类型)") private String companyName; - // @ApiModelProperty("联系方式") + @Schema(description = "联系信息(招投标类型)") + private List contactInformation; + + + @Schema(description = "联系方式") private String phoneNumber; - // @ApiModelProperty("出生日期") - private String birthdayString; - // @ApiModelProperty("出生日期") + +// @Schema(description = "出生日期") +// private String birthdayString; + + @Schema(description = "出生日期") private LocalDateTime birthday; - // @ApiModelProperty("专家来源 1-内部专家 2-外部专家") + + @Schema(description = "专家来源 1-内部专家 2-外部专家") private String expertSources; - // @ApiModelProperty("工作单位名称") + @Schema(description = "工作单位名称") private String workUnit; - // @ApiModelProperty("职务") + + @Schema(description = "职务") private String post; - // @ApiModelProperty("专业技术职称") + @Schema(description = "专业技术职称") private String technicalPosition; - // @ApiModelProperty("专业专长") + @Schema(description = "专业专长") private String professionalExpertise; - // @ApiModelProperty("性别 1-男 2-女") + @Schema(description = "性别 1-男 2-女") private String sex; - // @ApiModelProperty("工龄") + @Schema(description = "工龄") private String workingYears; - // @ApiModelProperty("状态0-有效 1-无效") + @Schema(description = "状态0-有效 1-无效") private String status; public void setBirthday(String birthdayString) { try { - this.birthday = LocalDateTimeUtil.parse(birthdayString, "yyyy-MM-dd HH:mm:ss"); - }catch (Exception e){ - throw new DataException("日期格式错误,请使用yyyy-MM-dd HH:mm:ss格式"); + this.birthday = LocalDateTimeUtil.parse(birthdayString, "yyyy-MM-dd"); + } catch (Exception e) { + throw new DataException("日期格式错误,请使用yyyy-MM-dd格式"); } } } @@ -84,6 +86,16 @@ public class ExpertDto { private String id; } + + @Data + public static class ContactInformation { + //联系人姓名 + private String contactName; + //联系人手机号 + private String contactPhone; + } + + @Data public static class DeleteParam { //主键ID @@ -106,6 +118,13 @@ public class ExpertDto { // @ApiModelProperty("联系方式") private String phoneNumber; + + private String concatPerson; + private String expertGroup; + + @Schema(description = "新增类型 1-专家 2-公司 默认专家") + private String dataType = "1"; + } @Data diff --git a/jnpf-tendering-entity/src/main/java/jnpf/model/dto/LotteryProjectDto.java b/jnpf-tendering-entity/src/main/java/jnpf/model/dto/LotteryProjectDto.java index de520cd..e736134 100644 --- a/jnpf-tendering-entity/src/main/java/jnpf/model/dto/LotteryProjectDto.java +++ b/jnpf-tendering-entity/src/main/java/jnpf/model/dto/LotteryProjectDto.java @@ -2,9 +2,16 @@ package jnpf.model.dto; import cn.hutool.core.date.LocalDateTimeUtil; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; import com.github.pagehelper.PageParam; import io.swagger.annotations.ApiModelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import jnpf.entity.Expert; import jnpf.entity.LotteryProject; +import jnpf.entity.LotteryReview; import jnpf.exception.DataException; import lombok.Data; @@ -80,7 +87,6 @@ public class LotteryProjectDto { } - @Data public static class BaseParam { @ApiModelProperty("项目编号") @@ -97,12 +103,14 @@ public class LotteryProjectDto { @ApiModelProperty("代理机构") private String agency; + @ApiModelProperty("抽签类型 1-专家 2-公司(默认专家)") + private String lotteryType = "1"; public void setBidEvaluationTime(String bidEvaluationTime) { try { this.bidEvaluationTime = LocalDateTimeUtil.parse(bidEvaluationTime, "yyyy-MM-dd HH:mm:ss"); - }catch (Exception e){ + } catch (Exception e) { throw new DataException("日期格式错误,请使用yyyy-MM-dd HH:mm:ss格式"); } } @@ -134,15 +142,20 @@ public class LotteryProjectDto { @ApiModelProperty("项目名称") private String projectName; + @ApiModelProperty("抽签类型 1-专家 2-公司(默认专家)") + private String lotteryType = "1"; + /** * 权限控制 */ - private String menuId="572406059134626629"; + private String menuId = "572406059134626629"; } @Data public static class QueryResponse extends LotteryProject { + @ApiModelProperty("评审列表") + private List lotteryReviewList; } @@ -151,11 +164,124 @@ public class LotteryProjectDto { @ApiModelProperty("抽签项目id") private String id; + @ApiModelProperty("专家组别信息Json,该字段仅用于专家抽签") + private List expertGroupInfo; + +// @ApiModelProperty("抽取专家信息json") +// private List extractExpertsInfo; + + } + + @Data + public static class QueryReviewResponse extends LotteryReview { + + @ApiModelProperty("抽取专家数") + private Integer extractExperts; + @ApiModelProperty("确认参加数") + private Integer confirmParticipation; + } + + @Data + public static class EditReviewParam { + @ApiModelProperty("评审id") + private String id; + @ApiModelProperty("专家组别信息Json") private List expertGroupInfo; +// @ApiModelProperty("抽取专家信息json") +// private List extractExpertsInfo; + } + @Data + public static class DeleteReviewParam { + @ApiModelProperty("评审id") + private String id; + + } + + + public enum ConfirmEnum { + //发布类型 + JOIN("1", "参加"), + NOT_JOIN("2", "不参加"), + TO_BE_CONFIRMED("0", "待确认"), + ; + + private String code; + private String describe; + + ConfirmEnum(String code, String describe) { + this.code = code; + this.describe = describe; + + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getDescribe() { + return describe; + } + + public void setDescribe(String describe) { + this.describe = describe; + } + } + + @Data + public static class ExtractExpertsInfo { + + @ApiModelProperty("专家编号/公司编号") + private String id; + + + + @ApiModelProperty("专家姓名") + private String expertName; + @ApiModelProperty("专家组别") + private String expertGroup; + @ApiModelProperty("联系方式") + private String phoneNumber; + @ApiModelProperty("工作单位名称") + private String workUnit; + + + + //公共字段 + @ApiModelProperty("确认时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private LocalDateTime confirmTime; + @ApiModelProperty("确认人姓名") + private String confirmName; + @ApiModelProperty("确认人id") + private String confirmId; + @ApiModelProperty("抽取轮次") + private String ExtractionRounds; + @ApiModelProperty("确认状态") + private String status = ConfirmEnum.TO_BE_CONFIRMED.getCode(); + @ApiModelProperty("备注") + private String remark; + @ApiModelProperty("参加确认按钮展示") + private Boolean showJoinButton = true; + + + //招标公司相关字段 + @ApiModelProperty("联系人信息") + private List contactInformation; + + @ApiModelProperty("公司名称") + private String companyName; + + } + + @Data public static class ExpertGroupInfo { @ApiModelProperty("组别code") @@ -170,7 +296,65 @@ public class LotteryProjectDto { private String numberOfExtract; @ApiModelProperty("确认参加人数") - private String numberOfParticipants; + private String numberOfParticipants = "0"; + @ApiModelProperty("删除按钮展示") + private Boolean showDelButton = true; + + } + + + @Data + public static class ParticipateInConfirmationParam { + @ApiModelProperty("评审id") + private String id; + + @ApiModelProperty("专家编码") + private String expertId; + + @ApiModelProperty("确认状态 1-参加 2-不参加") + private String status; + + @ApiModelProperty("备注") + private String remark; + + + } + + @Data + public static class SaveExtractionResultsParam { + @ApiModelProperty("评审id") + private String id; + + @ApiModelProperty("抽取专家信息json") + private List extractExpertsInfo; + } + + @Data + public static class UploadExtractionResults { + @ApiModelProperty("抽签项目id") + private String id; + + @ApiModelProperty("抽取结果") + private FileInfo uploaderVO; + + + } + + @Data + public static class FileInfo { + @Schema(description = "名称") + private String name; + @Schema(description = "请求接口") + private String url; + @Schema(description = "预览文件id") + private String fileVersionId; + @Schema(description = "文件大小") + private Long fileSize; + @Schema(description = "文件后缀") + private String fileExtension; + @Schema(description = "缩略图") + private String thumbUrl; + } } diff --git a/jnpf-tendering-server/src/main/resources/jnpf/templete/招投标公司打印.docx b/jnpf-tendering-server/src/main/resources/jnpf/templete/招投标公司打印.docx new file mode 100644 index 0000000000000000000000000000000000000000..2ba1b659f45d92932ba57d4c856360225fec17fa GIT binary patch literal 10718 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 literal 0 HcmV?d00001 diff --git a/pom.xml b/pom.xml index 81b56dc..6eab0b4 100644 --- a/pom.xml +++ b/pom.xml @@ -24,6 +24,34 @@ + + + org.apache.poi + poi + 5.2.3 + + + + + org.apache.poi + poi-ooxml + 5.2.3 + + + + + org.apache.poi + poi-ooxml-schemas + 4.1.2 + + + + + org.apache.poi + poi-scratchpad + 5.2.3 + + io.springfox springfox-swagger2