package com.ycl.service.impl;
|
|
import cn.hutool.core.io.IORuntimeException;
|
import cn.hutool.core.util.CharsetUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.ZipUtil;
|
import com.alibaba.excel.EasyExcel;
|
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.ycl.common.base.Result;
|
import com.ycl.common.config.SysConfig;
|
import com.ycl.common.constant.Constants;
|
import com.ycl.common.core.domain.BaseEntity;
|
import com.ycl.common.core.domain.entity.SysDictData;
|
import com.ycl.common.enums.YesOrNo;
|
import com.ycl.common.enums.business.FileTypeEnum;
|
import com.ycl.common.enums.business.ImportanceTypeEnum;
|
import com.ycl.common.enums.business.ProjectCategoryEnum;
|
import com.ycl.common.enums.business.ProjectStatusEnum;
|
import com.ycl.common.exception.base.BaseException;
|
import com.ycl.common.utils.CopyUtils;
|
import com.ycl.common.utils.DateUtils;
|
import com.ycl.common.utils.SecurityUtils;
|
import com.ycl.common.utils.StringUtils;
|
import com.ycl.common.utils.bean.BeanUtils;
|
import com.ycl.common.utils.excel.OutputExcelUtils;
|
import com.ycl.common.utils.file.FileUploadUtils;
|
import com.ycl.common.utils.file.FileUtils;
|
import com.ycl.common.utils.poi.ExcelUtil;
|
import com.ycl.constant.ProjectConstant;
|
import com.ycl.domain.entity.*;
|
import com.ycl.domain.excel.ProjectExcelTemplate;
|
import com.ycl.domain.form.*;
|
import com.ycl.domain.query.ProjectExportQuery;
|
import com.ycl.domain.query.ProjectInfoQuery;
|
import com.ycl.domain.vo.*;
|
import com.ycl.framework.utils.PageUtil;
|
import com.ycl.listener.excel.ProjectImportListener;
|
import com.ycl.mapper.*;
|
import com.ycl.service.*;
|
import com.ycl.system.mapper.SysDeptMapper;
|
import com.ycl.system.service.ISysDeptService;
|
import com.ycl.system.service.ISysDictDataService;
|
import lombok.RequiredArgsConstructor;
|
import org.apache.commons.codec.Charsets;
|
import org.springframework.aop.framework.AopContext;
|
import org.springframework.stereotype.Service;
|
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.util.Assert;
|
import org.springframework.util.CollectionUtils;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import javax.servlet.ServletOutputStream;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.FileInputStream;
|
import java.io.FileOutputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.net.URLEncoder;
|
import java.nio.file.Files;
|
import java.nio.file.Path;
|
import java.nio.file.StandardCopyOption;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
import java.util.stream.Stream;
|
|
/**
|
* 项目管理基础信息表 服务实现类
|
*
|
* @author flq
|
* @since 2024-11-22
|
*/
|
@Service
|
@RequiredArgsConstructor
|
public class ProjectInfoServiceImpl extends ServiceImpl<ProjectInfoMapper, ProjectInfo> implements ProjectInfoService {
|
|
private final ProjectInfoMapper projectInfoMapper;
|
private final ProjectInfoWinUnitService projectInfoWinUnitService;
|
private final ProjectInfoYearPlanService projectInfoYearPlanService;
|
private final ProjectInvestmentFundingMapper investmentFundingMapper;
|
private final ProjectInvestmentInfoMapper investmentInfoMapper;
|
private final ProjectInvestmentPolicyComplianceMapper policyMapper;
|
private final ProjectUnitRegistrationInfoMapper unitRegistrationInfoMapper;
|
private final FileService fileService;
|
private final FileMapper fileMapper;
|
private final PlanMapper planMapper;
|
private final ProjectInvestmentInfoServiceImpl projectInvestmentInfoServiceImpl;
|
private final ProjectInvestmentFundingServiceImpl projectInvestmentFundingServiceImpl;
|
private final ProjectInvestmentPolicyComplianceServiceImpl projectInvestmentPolicyComplianceServiceImpl;
|
private final ProjectUnitRegistrationInfoServiceImpl projectUnitRegistrationInfoServiceImpl;
|
private final SysDeptMapper sysDeptMapper;
|
private final ISysDictDataService dictDataService;
|
|
|
/**
|
* 添加
|
*
|
* @param form
|
* @return
|
*/
|
@Override
|
public Result add(ProjectInfoForm form) {
|
//添加基本信息
|
ProjectInfo entity = ProjectInfoForm.getEntityByForm(form, null);
|
Long userId = SecurityUtils.getUserId();
|
entity.setCreateBy(userId);
|
entity.setUpdateBy(userId);
|
//如果是储备项目(未开工项目)不需要审核
|
if (ProjectConstant.COMMIT.equals(entity.getUsedStatus()) && ProjectStatusEnum.PENDDING.getType().equals(entity.getProjectStatus())) {
|
entity.setUsedStatus(ProjectConstant.PASS);
|
}
|
if(!checkProjectNameAndIdIsUnique(entity,null)){
|
throw new RuntimeException("项目重复,项目名称、项目码已存在");
|
}
|
baseMapper.insert(entity);
|
addPlan(entity.getId()); //添加计划表
|
//添加项目中标单位
|
List<ProjectInfoWinUnit> projectInfoWinUnits = new ArrayList<>();
|
for (ProjectInfoWinUnitForm winUnitForm : form.getWinUnitList()) {
|
ProjectInfoWinUnit projectInfoWinUnit = ProjectInfoWinUnitForm.getEntityByForm(winUnitForm, null);
|
projectInfoWinUnit.setId(null);
|
projectInfoWinUnit.setProjectInfoId(entity.getId());
|
projectInfoWinUnits.add(projectInfoWinUnit);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoWinUnits)) {
|
projectInfoWinUnitService.saveBatch(projectInfoWinUnits);
|
}
|
//添加年度投资计划
|
List<ProjectInfoYearPlan> projectInfoYearPlans = new ArrayList<>();
|
for (ProjectInfoYearPlanForm yearPlanForm : form.getYearPlanList()) {
|
ProjectInfoYearPlan yearPlan = ProjectInfoYearPlanForm.getEntityByForm(yearPlanForm, null);
|
yearPlan.setId(null);
|
yearPlan.setProjectInfoId(entity.getId());
|
projectInfoYearPlans.add(yearPlan);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoYearPlans)) {
|
projectInfoYearPlanService.saveBatch(projectInfoYearPlans);
|
}
|
return Result.ok("添加成功").data(entity.getId());
|
}
|
|
/**
|
* 判断项目名和项目码是否唯一
|
* @param entity from true 来自add() false 来自edit()
|
* @return
|
*/
|
public boolean checkProjectNameAndIdIsUnique(ProjectInfo entity,Long updateId){
|
QueryWrapper<ProjectInfo> queryWrapper = new QueryWrapper<ProjectInfo>();
|
if (updateId == null) {
|
List<ProjectInfo> list = new LambdaQueryChainWrapper<>(baseMapper)
|
.eq(ProjectInfo::getProjectName, entity.getProjectName())
|
.eq(ProjectInfo::getProjectCode, entity.getProjectCode())
|
.list();
|
return list == null || list.isEmpty();
|
} else {
|
List<ProjectInfo> list = new LambdaQueryChainWrapper<>(baseMapper)
|
.eq(ProjectInfo::getProjectName, entity.getProjectName())
|
.eq(ProjectInfo::getProjectCode, entity.getProjectCode())
|
.ne(ProjectInfo::getId, updateId)
|
.list();
|
return list == null || list.isEmpty();
|
}
|
|
}
|
|
public void addPlan(Long projectInfoId) {
|
Plan plan = new Plan();
|
plan.setProjectInfoId(projectInfoId);
|
plan.setReportStatus(1);
|
plan.setMonthStatus(1);
|
plan.setSeasonStatus(1);
|
plan.setYearStatus(1);
|
plan.setDeleted(0);
|
planMapper.insert(plan);
|
}
|
|
/**
|
* 修改
|
*
|
* @param form
|
* @return
|
*/
|
@Override
|
public Result update(ProjectInfoForm form) {
|
ProjectInfo entity = baseMapper.selectById(form.getId());
|
|
// 为空抛IllegalArgumentException,做全局异常处理
|
Assert.notNull(entity, "记录不存在");
|
ProjectInfoForm.getEntityByForm(form, entity);
|
Long userId = SecurityUtils.getUserId();
|
entity.setUpdateBy(userId);
|
//如果是储备项目(未开工项目)不需要审核
|
if (ProjectConstant.COMMIT.equals(entity.getUsedStatus()) && ProjectStatusEnum.PENDDING.getType().equals(entity.getProjectStatus())) {
|
entity.setUsedStatus(ProjectConstant.PASS);
|
}
|
// 管理员修改的直接通过
|
if (SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
|
entity.setUsedStatus(ProjectConstant.PASS);
|
}
|
if(!checkProjectNameAndIdIsUnique(entity,form.getId())){
|
throw new RuntimeException("项目重复,项目名称、项目码已存在");
|
}
|
//更新项目信息
|
baseMapper.updateById(entity);
|
//修改项目中标单位
|
//删除原数据
|
new LambdaUpdateChainWrapper<>(projectInfoWinUnitService.getBaseMapper())
|
.eq(ProjectInfoWinUnit::getProjectInfoId, entity.getId())
|
.remove();
|
//添加项目中标单位
|
List<ProjectInfoWinUnit> projectInfoWinUnits = new ArrayList<>();
|
for (ProjectInfoWinUnitForm winUnitForm : form.getWinUnitList()) {
|
ProjectInfoWinUnit projectInfoWinUnit = ProjectInfoWinUnitForm.getEntityByForm(winUnitForm, null);
|
projectInfoWinUnit.setId(null);
|
projectInfoWinUnit.setProjectInfoId(entity.getId());
|
projectInfoWinUnits.add(projectInfoWinUnit);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoWinUnits)) {
|
projectInfoWinUnitService.saveBatch(projectInfoWinUnits);
|
}
|
|
//修改年度投资计划
|
//删除原数据
|
new LambdaUpdateChainWrapper<>(projectInfoYearPlanService.getBaseMapper())
|
.eq(ProjectInfoYearPlan::getProjectInfoId, entity.getId())
|
.remove();
|
//添加年度投资计划
|
List<ProjectInfoYearPlan> projectInfoYearPlans = new ArrayList<>();
|
for (ProjectInfoYearPlanForm yearPlanForm : form.getYearPlanList()) {
|
ProjectInfoYearPlan yearPlan = ProjectInfoYearPlanForm.getEntityByForm(yearPlanForm, null);
|
yearPlan.setId(null);
|
yearPlan.setProjectInfoId(entity.getId());
|
projectInfoYearPlans.add(yearPlan);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoYearPlans)) {
|
projectInfoYearPlanService.saveBatch(projectInfoYearPlans);
|
}
|
return Result.ok("修改成功");
|
}
|
|
private void saveUnit(Long id, List<ProjectInfoWinUnitForm> projectInfoWinUnitForm) {
|
List<ProjectInfoWinUnit> projectInfoWinUnits = new ArrayList<>();
|
for (ProjectInfoWinUnitForm winUnitForm : projectInfoWinUnitForm) {
|
ProjectInfoWinUnit projectInfoWinUnit = ProjectInfoWinUnitForm.getEntityByForm(winUnitForm, null);
|
projectInfoWinUnit.setId(null);
|
projectInfoWinUnit.setProjectInfoId(id);
|
projectInfoWinUnits.add(projectInfoWinUnit);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoWinUnits)) {
|
projectInfoWinUnitService.saveBatch(projectInfoWinUnits);
|
}
|
}
|
|
private void saveYearPlan(Long id, List<ProjectInfoYearPlanForm> yearPlanList) {
|
List<ProjectInfoYearPlan> projectInfoYearPlans = new ArrayList<>();
|
for (ProjectInfoYearPlanForm yearPlanForm : yearPlanList) {
|
ProjectInfoYearPlan yearPlan = ProjectInfoYearPlanForm.getEntityByForm(yearPlanForm, null);
|
yearPlan.setId(null);
|
yearPlan.setProjectInfoId(id);
|
projectInfoYearPlans.add(yearPlan);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoYearPlans)) {
|
projectInfoYearPlanService.saveBatch(projectInfoYearPlans);
|
}
|
}
|
|
/**
|
* 批量删除
|
*
|
* @param ids
|
* @return
|
*/
|
@Override
|
public Result remove(List<String> ids) {
|
baseMapper.deleteBatchIds(ids);
|
return Result.ok("删除成功");
|
}
|
|
/**
|
* id删除
|
*
|
* @param id
|
* @return
|
*/
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Result removeById(Long id) {
|
investmentFundingMapper.delete(new QueryWrapper<ProjectInvestmentFunding>().eq("project_id", id));
|
investmentInfoMapper.delete(new QueryWrapper<ProjectInvestmentInfo>().eq("project_id", id));
|
policyMapper.delete(new QueryWrapper<ProjectInvestmentPolicyCompliance>().eq("project_id", id));
|
unitRegistrationInfoMapper.delete(new QueryWrapper<ProjectUnitRegistrationInfo>().eq("project_id", id));
|
projectInfoWinUnitService.remove(new QueryWrapper<ProjectInfoWinUnit>().eq("project_info_id", id));
|
projectInfoYearPlanService.remove(new QueryWrapper<ProjectInfoYearPlan>().eq("project_info_id", id));
|
|
List<String> types = new ArrayList<>();
|
types.add(FileTypeEnum.PROJECT_INFO.getType());
|
types.add(FileTypeEnum.INVEST_POLICY.getType());
|
types.add(FileTypeEnum.DOCUMENT_INFO.getType());
|
fileMapper.delete(new QueryWrapper<File>().eq("bus_id", id).in("type", types));
|
baseMapper.deleteById(id);
|
return Result.ok("删除成功");
|
}
|
|
/**
|
* 分页查询,TODO 项目中心的分页使用单独的接口,去掉写死的逻辑换成dept or查询
|
*
|
* @param query
|
* @return
|
*/
|
@Override
|
public Result page(ProjectInfoQuery query) {
|
if (query.getProjectStartTime() != null) {
|
query.setProjectStartTime(DateUtils.getDayStart(query.getProjectStartTime()));
|
}
|
if (query.getProjectEndTime() != null) {
|
query.setProjectEndTime(DateUtils.getDayEnd(query.getProjectEndTime()));
|
}
|
if (YesOrNo.YES.getCode().equals(query.getCenter())) {
|
query.setProjectPhase("6");
|
}
|
// 异常项目暂时返回空
|
if (YesOrNo.YES.getCode().equals(query.getExe())) {
|
return Result.ok().data(new ArrayList<>()).total(0);
|
}
|
Long userId = SecurityUtils.getUserId();
|
String ancestors = sysDeptMapper.selectAncestors(userId);
|
String[] ancestorArr = ancestors.split(",");
|
List<String> ancestorList = Arrays.stream(ancestorArr).collect(Collectors.toList());
|
ancestorList.add(SecurityUtils.getDeptId() + "");
|
if (!CollectionUtils.isEmpty(ancestorList) && ancestorList.contains("101")) {
|
query.setProjectOwnerUnit(SecurityUtils.getDeptId());
|
//业主
|
query.setRole(0);
|
} else if ((!CollectionUtils.isEmpty(ancestorList) && ancestorList.contains("102"))) {
|
query.setCompetentDepartment(SecurityUtils.getDeptId());
|
//审批 对应主管部门
|
query.setRole(1);
|
} else if (SecurityUtils.isAdmin(userId)) {
|
query.setRole(3);
|
}
|
|
IPage<ProjectInfoVO> page = PageUtil.getPage(query, ProjectInfoVO.class);
|
baseMapper.getPage(query, page);
|
List<ProjectInfoVO> records = page.getRecords();
|
List<ProjectVO> list = new ArrayList<>();
|
records.forEach(vo -> {
|
ProjectInfoVO.transform(vo);
|
ProjectVO projectVO = new ProjectVO();
|
copyToProjectVO(vo, projectVO);
|
String competentDepartment = vo.getCompetentDepartment();
|
projectVO.setAuditRole(SecurityUtils.isAdmin(SecurityUtils.getUserId()) || (StringUtils.isNotEmpty(competentDepartment) && competentDepartment.equals(SecurityUtils.getDeptId() + "")));
|
// 翻译项目阶段
|
String phase = ProjectCategoryEnum.getPhaseByProjectStatus(projectVO.getProjectPhase());
|
projectVO.setProjectPhase(phase);
|
if (StringUtils.isNotEmpty(projectVO.getProjectSubType())) {
|
// 翻译项目子类型
|
SysDictData dictData = dictDataService.selectDictDataByValue(projectVO.getProjectType(), projectVO.getProjectSubType(), "sys_project_type");
|
if (Objects.nonNull(dictData)) {
|
projectVO.setProjectSubType(dictData.getDictLabel());
|
}
|
}
|
list.add(projectVO);
|
});
|
return Result.ok().data(list).total(page.getTotal());
|
}
|
|
private void copyToProjectVO(ProjectInfoVO vo, ProjectVO projectVO) {
|
//忽略null值的复制
|
CopyUtils.copyNoNullProperties(vo, projectVO);
|
if (vo.getProjectInvestmentInfo() != null)
|
CopyUtils.copyNoNullProperties(vo.getProjectInvestmentInfo(), projectVO);
|
if (vo.getProjectUnitRegistrationInfo() != null)
|
CopyUtils.copyNoNullProperties(vo.getProjectUnitRegistrationInfo(), projectVO);
|
if (vo.getProjectInvestmentPolicyCompliance() != null)
|
CopyUtils.copyNoNullProperties(vo.getProjectInvestmentPolicyCompliance(), projectVO);
|
if (vo.getProjectInvestmentFunding() != null)
|
CopyUtils.copyNoNullProperties(vo.getProjectInvestmentFunding(), projectVO);
|
}
|
|
/**
|
* 根据id查找
|
*
|
* @param id
|
* @return
|
*/
|
@Override
|
public Result detail(Integer id) {
|
ProjectInfo entity = baseMapper.getById(id);
|
Assert.notNull(entity, "记录不存在");
|
ProjectInfoVO vo = ProjectInfoVO.getVoByEntity(entity, null);
|
String competentDepartment = vo.getCompetentDepartment();
|
vo.setAuditRole(SecurityUtils.isAdmin(SecurityUtils.getUserId()) || (StringUtils.isNotEmpty(competentDepartment) && competentDepartment.equals(SecurityUtils.getDeptId() + "")));
|
QueryWrapper<File> fileQueryWrapper = new QueryWrapper<>();
|
fileQueryWrapper.eq("type", FileTypeEnum.PROJECT_INFO.getType());
|
fileQueryWrapper.eq("bus_id", vo.getId());
|
|
//中标单位
|
List<ProjectInfoWinUnitVO> unitVOS = new ArrayList<>();
|
List<ProjectInfoWinUnit> unitList = projectInfoWinUnitService.list(new QueryWrapper<ProjectInfoWinUnit>().eq("project_info_id", id));
|
for (ProjectInfoWinUnit projectInfoWinUnit : unitList) {
|
ProjectInfoWinUnitVO unitVO = ProjectInfoWinUnitVO.getVoByEntity(projectInfoWinUnit, null);
|
unitVO.setId(null);
|
unitVOS.add(unitVO);
|
}
|
vo.setWinUnitList(unitVOS);
|
//年度投资计划
|
List<ProjectInfoYearPlanVO> yearPlanVOS = new ArrayList<>();
|
List<ProjectInfoYearPlan> yearPlaList = projectInfoYearPlanService.list(new QueryWrapper<ProjectInfoYearPlan>().eq("project_info_id", id));
|
for (ProjectInfoYearPlan yearPlan : yearPlaList) {
|
ProjectInfoYearPlanVO yearPlanVO = ProjectInfoYearPlanVO.getVoByEntity(yearPlan, null);
|
yearPlanVO.setId(null);
|
yearPlanVOS.add(yearPlanVO);
|
}
|
vo.setYearPlanList(yearPlanVOS);
|
return Result.ok().data(vo);
|
}
|
|
/**
|
* 列表
|
*
|
* @return
|
*/
|
@Override
|
public Result all() {
|
List<ProjectInfo> entities = baseMapper.selectList(null);
|
List<ProjectInfoVO> vos = entities.stream()
|
.map(entity -> ProjectInfoVO.getVoByEntity(entity, null))
|
.collect(Collectors.toList());
|
return Result.ok().data(vos);
|
}
|
|
@Override
|
public IndexCountVO getIndexCount(IndexDTO indexDTO) {
|
// {"proPhaseCountVO":[{"type":"储备规划阶段","count":0,"amount":"0.00","text":"储"},
|
// {"type":"项目前期阶段","count":0,"amount":"0.00","text":"新"},
|
// {"type":"实施阶段","count":0,"amount":"0.00","text":"建"},{"type":"竣工投用阶段","count":0,"amount":"0.00","text":"竣"}],
|
// "impTypeCountVO":[{"type":"一般项目","count":0,"amount":"0.00","text":"普"},
|
// {"type":"县重点项目","count":0,"amount":"0.00","text":"县"},{"type":"市重点项目","count":0,"amount":"0.00","text":"市"},
|
// {"type":"省重点项目","count":0,"amount":"0.00","text":"省"}]}}
|
IndexCountVO indexCountVO = new IndexCountVO();
|
List<IndexProPhaseCountVO> proPhaseCountVO = new ArrayList<>();
|
List<ProjectVO> projectVOS = baseMapper.homeCount(new BaseEntity());
|
List<ProjectVO> reserve = new ArrayList<>();
|
List<ProjectVO> previous = new ArrayList<>();
|
List<ProjectVO> implement = new ArrayList<>();
|
List<ProjectVO> finish = new ArrayList<>();
|
List<ProjectVO> normal = new ArrayList<>();
|
List<ProjectVO> province = new ArrayList<>();
|
List<ProjectVO> city = new ArrayList<>();
|
List<ProjectVO> county = new ArrayList<>();
|
projectVOS.forEach(item -> {
|
if (ProjectCategoryEnum.RESERVE.getDesc().equals(ProjectCategoryEnum.getPhaseByProjectStatus(item.getProjectPhase()))) {
|
reserve.add(item);
|
} else if (ProjectCategoryEnum.PREVIOUS.getDesc().equals(ProjectCategoryEnum.getPhaseByProjectStatus(item.getProjectPhase()))) {
|
previous.add(item);
|
} else if (ProjectCategoryEnum.IMPLEMENT.getDesc().equals(ProjectCategoryEnum.getPhaseByProjectStatus(item.getProjectPhase()))) {
|
implement.add(item);
|
} else if (ProjectCategoryEnum.FINISH.getDesc().equals(ProjectCategoryEnum.getPhaseByProjectStatus(item.getProjectPhase()))) {
|
finish.add(item);
|
}
|
|
if (StringUtils.isBlank(item.getImportanceType())) {
|
normal.add(item);
|
// 使用contains,因为重点分类可多选,使用,分割存储的
|
} else {
|
if (item.getImportanceType().contains(ImportanceTypeEnum.PROVINCIAL_KEY.getType())) {
|
province.add(item);
|
}
|
if (item.getImportanceType().contains(ImportanceTypeEnum.SUINING_KEY.getType())) {
|
city.add(item);
|
}
|
if (item.getImportanceType().contains(ImportanceTypeEnum.SHEHONG_KEY.getType())) {
|
county.add(item);
|
}
|
if (item.getImportanceType().contains(ImportanceTypeEnum.NORMAL.getType())) {
|
normal.add(item);
|
}
|
}
|
});
|
//单位先默认为元
|
proPhaseCountVO.add(new IndexProPhaseCountVO("储备规划阶段", reserve.size(), reserve.stream().
|
filter(item -> !StringUtils.isEmpty(item.getTotalInvestment()))
|
.map(item -> new BigDecimal(item.getTotalInvestment()).setScale(2, RoundingMode.HALF_UP))
|
.reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP).toString(), "储"));
|
|
proPhaseCountVO.add(new IndexProPhaseCountVO("项目前期阶段", previous.size(), previous.stream().
|
filter(item -> !StringUtils.isEmpty(item.getTotalInvestment()))
|
.map(item -> new BigDecimal(item.getTotalInvestment()).setScale(2, RoundingMode.HALF_UP))
|
.reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP).toString(), "新"));
|
|
proPhaseCountVO.add(new IndexProPhaseCountVO("实施阶段", implement.size(), implement.stream().
|
filter(item -> !StringUtils.isEmpty(item.getTotalInvestment()))
|
.map(item -> new BigDecimal(item.getTotalInvestment()).setScale(2, RoundingMode.HALF_UP))
|
.reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP).toString(), "建"));
|
|
proPhaseCountVO.add(new IndexProPhaseCountVO("竣工投用阶段", finish.size(), finish.stream().
|
filter(item -> !StringUtils.isEmpty(item.getTotalInvestment()))
|
.map(item -> new BigDecimal(item.getTotalInvestment()).setScale(2, RoundingMode.HALF_UP))
|
.reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP).toString(), "竣"));
|
|
indexCountVO.setProPhaseCountVO(proPhaseCountVO);
|
|
List<IndexImpTypeCountVO> impTypeCountVO = new ArrayList<>();
|
impTypeCountVO.add(new IndexImpTypeCountVO("一般项目", normal.size(), normal.stream().
|
filter(item -> !StringUtils.isEmpty(item.getTotalInvestment()))
|
.map(item -> new BigDecimal(item.getTotalInvestment()).setScale(2, RoundingMode.HALF_UP))
|
.reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP).toString(), "普"));
|
|
impTypeCountVO.add(new IndexImpTypeCountVO("县重点项目", county.size(), county.stream().
|
filter(item -> !StringUtils.isEmpty(item.getTotalInvestment()))
|
.map(item -> new BigDecimal(item.getTotalInvestment()).setScale(2, RoundingMode.HALF_UP))
|
.reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP).toString(), "县"));
|
|
impTypeCountVO.add(new IndexImpTypeCountVO("市重点项目", city.size(), city.stream().
|
filter(item -> !StringUtils.isEmpty(item.getTotalInvestment()))
|
.map(item -> new BigDecimal(item.getTotalInvestment()).setScale(2, RoundingMode.HALF_UP))
|
.reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP).toString(), "市"));
|
|
impTypeCountVO.add(new IndexImpTypeCountVO("省重点项目", province.size(), province.stream().
|
filter(item -> !StringUtils.isEmpty(item.getTotalInvestment()))
|
.map(item -> new BigDecimal(item.getTotalInvestment()).setScale(2, RoundingMode.HALF_UP))
|
.reduce(BigDecimal.ZERO, BigDecimal::add).divide(new BigDecimal("10000"), 2, RoundingMode.HALF_UP).toString(), "省"));
|
indexCountVO.setImpTypeCountVO(impTypeCountVO);
|
return indexCountVO;
|
}
|
|
@Override
|
public Map<String, Integer> countExceptionProject(IndexDTO indexDTO) {
|
Map<String, Integer> map = new HashMap<>();
|
map.put("processExceptionProject", 0);
|
return map;
|
}
|
|
@Override
|
public Result docDetail(Integer id) {
|
DocumentInfoForm documentInfoForm = new DocumentInfoForm();
|
QueryWrapper<File> fileQueryWrapper = new QueryWrapper<>();
|
fileQueryWrapper.eq("type", FileTypeEnum.DOCUMENT_INFO.getType());
|
fileQueryWrapper.eq("bus_id", id);
|
List<File> files = fileMapper.selectList(fileQueryWrapper);
|
documentInfoForm.setFileList(files);
|
return Result.ok().data(documentInfoForm);
|
}
|
|
@Override
|
public Result addDoc(DocumentInfoForm form) {
|
List<File> fileList = form.getFileList();
|
fileList.forEach(item -> {
|
item.setId(null);
|
item.setBusId(form.getProjectId());
|
item.setType(FileTypeEnum.DOCUMENT_INFO);
|
});
|
//删除原有文件
|
QueryWrapper<File> fileQueryWrapper = new QueryWrapper<>();
|
fileQueryWrapper.eq("type", FileTypeEnum.DOCUMENT_INFO.getType());
|
fileQueryWrapper.eq("bus_id", form.getProjectId());
|
fileMapper.delete(fileQueryWrapper);
|
//替换成现有
|
fileService.saveBatch(fileList);
|
return Result.ok();
|
}
|
|
@Override
|
public Result getManagerFlag(Integer recordId) {
|
ProjectInfo projectInfo = baseMapper.selectById(recordId);
|
// 判断当前用户id是否在主管列表中
|
String competentDepartment = projectInfo.getCompetentDepartment();
|
if (StringUtils.isEmpty(competentDepartment)) {
|
return Result.ok().data(false);
|
}
|
List<String> list = Arrays.asList(competentDepartment.split(","));
|
// 获得当前用户id
|
Long userId = SecurityUtils.getUserId();
|
if (list.contains(userId.toString())) {
|
return Result.ok().data(true);
|
} else {
|
return Result.ok().data(false);
|
}
|
}
|
|
@Override
|
public void export(HttpServletResponse response, ProjectExportQuery query) throws IOException {
|
List<ProjectVO> data = baseMapper.selectProjectDetailByIds(query.getDataIdList());
|
List<ProjectExcelTemplate> excelList = new ArrayList<>();
|
//字典作翻译
|
data.forEach(item -> {
|
ProjectExcelTemplate excel = new ProjectExcelTemplate();
|
BeanUtils.copyProperties(item, excel);
|
//项目阶段
|
excel.setProjectPhase(ProjectCategoryEnum.getPhaseByProjectStatus(item.getProjectPhase()));
|
excelList.add(excel);
|
});
|
Set<Integer> indexes = OutputExcelUtils.getSelectFields(query.getFieldList(), ProjectExcelTemplate.class);
|
//不需要附件
|
if (!query.getRequireFile()) {
|
try (ServletOutputStream outputStream = response.getOutputStream()) {
|
EasyExcel.write(outputStream, ProjectExcelTemplate.class).includeColumnIndexes(indexes).sheet("项目列表").doWrite(excelList);
|
} catch (Exception e) {
|
log.error(e.getMessage(), e);
|
throw new BaseException("导出失败:" + e.getMessage());
|
}
|
} else {
|
//需要附件,导出为zip
|
response.setContentType("application/zip");
|
response.setCharacterEncoding(Charsets.UTF_8.name());
|
String fileName = URLEncoder.encode("项目列表", Charsets.UTF_8);
|
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".zip");
|
|
java.io.File tempDir = null;
|
try {
|
//查出附件
|
List<File> projectInfoFiles = fileMapper.selectList(new QueryWrapper<File>()
|
.in("bus_id", data.stream().map(ProjectVO::getId).collect(Collectors.toList()))
|
.and(q -> q.eq("type", FileTypeEnum.PROJECT_INFO.getType()).or().eq("type", FileTypeEnum.DOCUMENT_INFO.getType()))
|
);
|
List<File> policyFiles = fileMapper.selectList(new QueryWrapper<File>()
|
.in("bus_id", data.stream().map(ProjectVO::getPolicyId).collect(Collectors.toList()))
|
.eq("type", FileTypeEnum.INVEST_POLICY.getType())
|
);
|
projectInfoFiles.addAll(policyFiles);
|
projectInfoFiles.forEach(file -> {
|
data.forEach(item -> {
|
if (FileTypeEnum.PROJECT_INFO.equals(file.getType())) {
|
if (file.getBusId().equals(item.getId())) {
|
//审批计划书
|
item.setApprovalPlan(file.getOriginalName());
|
}
|
} else if (FileTypeEnum.DOCUMENT_INFO.equals(file.getType())) {
|
if (file.getBusId().equals(item.getId())) {
|
//相关文书
|
item.setDocuments(file.getOriginalName());
|
}
|
} else if (FileTypeEnum.INVEST_POLICY.equals(file.getType())) {
|
if (file.getBusId().equals(item.getPolicyId())) {
|
//符合产业政策附件
|
item.setPolicyComplianceAttachment(file.getOriginalName());
|
}
|
}
|
});
|
|
});
|
// 创建临时目录
|
tempDir = Files.createTempDirectory("temp").toFile();
|
|
java.io.File templateDir = new java.io.File(tempDir, "template");
|
if (!templateDir.exists()) {
|
templateDir.mkdirs();
|
}
|
|
// 创建 Excel 文件
|
java.io.File excelFile = new java.io.File(templateDir, "excel.xlsx");
|
if (!excelFile.exists()) {
|
excelFile.createNewFile();
|
}
|
|
// 写入 Excel 模板数据
|
try (FileOutputStream fileOutputStream = new FileOutputStream(excelFile, false)) {
|
EasyExcel.write(fileOutputStream, ProjectExcelTemplate.class).sheet("项目列表").doWrite(excelList);
|
}
|
|
// 创建附件目录
|
java.io.File attachmentDir = new java.io.File(templateDir, "attachment");
|
if (!attachmentDir.exists()) {
|
attachmentDir.mkdirs();
|
}
|
|
//将附件复制导目录下
|
for (File item : projectInfoFiles) {
|
String url = item.getUrl();
|
if (StringUtils.isBlank(url)) continue;
|
url = url.replaceFirst(Constants.RESOURCE_PREFIX, SysConfig.getProfile());
|
// 直接使用File类处理系统路径
|
java.io.File sourceFile = new java.io.File(url);
|
if (!sourceFile.exists() || !sourceFile.isFile()) {
|
// 处理文件不存在或不是文件的情况
|
continue; // 或者记录日志、抛出异常等
|
}
|
// 目标文件路径,使用attachmentDir作为父目录,并保持原文件名
|
java.io.File targetFile = new java.io.File(attachmentDir, sourceFile.getName());
|
// 复制文件
|
try {
|
Files.copy(sourceFile.toPath(), targetFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
} catch (IOException e) {
|
log.error(e.getMessage());
|
}
|
}
|
// 打包 ZIP 文件
|
java.io.File zipFile = ZipUtil.zip(templateDir);
|
byte[] zipBytes = Files.readAllBytes(zipFile.toPath());
|
|
// 将 ZIP 文件写入响应
|
try (ServletOutputStream outputStream = response.getOutputStream()) {
|
outputStream.write(zipBytes);
|
}
|
} finally {
|
OutputExcelUtils.deleteDirectoryOrFile(tempDir);
|
}
|
}
|
}
|
|
@Override
|
public Result updateUsedStatus(Integer id, Integer usedStatus) {
|
ProjectInfo entity = baseMapper.selectById(id);
|
// 为空抛IllegalArgumentException,做全局异常处理
|
Assert.notNull(entity, "记录不存在");
|
entity.setUsedStatus(usedStatus);
|
baseMapper.updateById(entity);
|
return Result.ok("删除成功");
|
}
|
|
@Transactional
|
@Override
|
public void importProject(MultipartFile file) {
|
java.io.File tempZip = null;
|
java.io.File tempDir = null;
|
try {
|
tempZip = java.io.File.createTempFile("temp", ".zip");
|
try (InputStream inputStream = file.getInputStream()) {
|
Files.copy(inputStream, tempZip.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
}
|
|
tempDir = Files.createTempDirectory("temp-dir").toFile();
|
|
try {
|
ZipUtil.unzip(tempZip, tempDir, CharsetUtil.CHARSET_UTF_8);
|
} catch (IORuntimeException e) {
|
log.error("解压失败,尝试使用GBK编码解压...");
|
ZipUtil.unzip(tempZip, tempDir, CharsetUtil.CHARSET_GBK);
|
}
|
|
Path path = tempDir.toPath();
|
ProjectImportListener projectImportListener = new ProjectImportListener();
|
//需要存入数据库
|
ArrayList<File> attachments = new ArrayList<>();
|
//实际的文件
|
List<java.io.File> files = new ArrayList<>();
|
try (Stream<Path> pathStream = Files.walk(path)) {
|
pathStream.forEach(filePath -> {
|
if (Files.isDirectory(filePath) && filePath.getFileName().toString().equals("attachment")) {
|
//附件处理
|
try (Stream<Path> stream = Files.walk(filePath)) {
|
stream.forEach(attachmentPath -> {
|
if (Files.isRegularFile(attachmentPath)) {
|
files.add(attachmentPath.toFile());
|
}
|
});
|
} catch (IOException e) {
|
log.error(e.getMessage());
|
throw new RuntimeException(e);
|
}
|
} else if (Files.isRegularFile(filePath) && filePath.getFileName().toString().equals("excel.xlsx")) {
|
//导入数据处理
|
try (FileInputStream fileInputStream = new FileInputStream(filePath.toFile())) {
|
ExcelUtil.importExcel(fileInputStream, ProjectExcelTemplate.class, projectImportListener);
|
} catch (IOException e) {
|
log.error(e.getMessage());
|
throw new RuntimeException(e);
|
}
|
}
|
});
|
}
|
/* 把附件存入上传路径 */
|
//上传文件路径
|
String filePath = SysConfig.getUploadPath();
|
files.forEach(attachmentFile -> {
|
try {
|
//上传
|
String url = FileUploadUtils.uploadIOFile(filePath, attachmentFile);
|
//存放的文件名会加上_时间戳的后缀
|
String newName = FileUtils.getName(url);
|
attachments.add(new File()
|
.setUrl(url)
|
.setName(newName)
|
.setOriginalName(attachmentFile.getName()));
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
});
|
|
Map<String, Long> projectInfoMap = projectImportListener.getProjectInfoMap();
|
Map<String, Long> investmentProjectPolicyComplianceMap = projectImportListener.getInvestmentProjectPolicyComplianceMap();
|
Map<String, Long> documentsMap = projectImportListener.getDocumentsMap();
|
//补充type和busId字段
|
attachments.forEach(attachment -> {
|
String fileName = attachment.getOriginalName();
|
if (ObjectUtil.isNotNull(projectInfoMap.get(fileName))) {
|
attachment.setBusId(projectInfoMap.get(fileName));
|
attachment.setType(FileTypeEnum.PROJECT_INFO);
|
} else if (ObjectUtil.isNotNull(investmentProjectPolicyComplianceMap.get(fileName))) {
|
attachment.setBusId(investmentProjectPolicyComplianceMap.get(fileName));
|
attachment.setType(FileTypeEnum.INVEST_POLICY);
|
} else if (ObjectUtil.isNotNull(documentsMap.get(fileName))) {
|
attachment.setBusId(documentsMap.get(fileName));
|
attachment.setType(FileTypeEnum.DOCUMENT_INFO);
|
}
|
});
|
|
// 添加项目附件关联表
|
fileService.saveBatch(attachments);
|
} catch (IOException e) {
|
log.error(e.getMessage());
|
throw new RuntimeException(e);
|
} finally {
|
deleteDirectoryOrFile(tempZip);
|
deleteDirectoryOrFile(tempDir);
|
}
|
}
|
|
@Override
|
@Transactional(rollbackFor = Exception.class)
|
public Result editProject(ProjectForm form) {
|
Long projectId = form.getProjectInfoForm().getId();
|
if (ObjectUtil.isNotNull(form.getProjectInfoForm())) {
|
if (ObjectUtil.isNull(form.getProjectInfoForm().getId())) {
|
//新增
|
ProjectInfo entity = ProjectInfoForm.getEntityByForm(form.getProjectInfoForm(), null);
|
Long userId = SecurityUtils.getUserId();
|
entity.setCreateBy(userId);
|
entity.setUpdateBy(userId);
|
//如果是储备项目(未开工项目)不需要审核
|
if (ProjectCategoryEnum.RESERVE.getType().equals(entity.getProjectPhase())) {
|
entity.setUsedStatus(ProjectConstant.PASS);
|
}
|
// 管理员修改的直接通过
|
if (SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
|
entity.setUsedStatus(ProjectConstant.PASS);
|
}
|
if(!checkProjectNameAndIdIsUnique(entity,null)){
|
throw new RuntimeException("项目重复,项目名称、项目码已存在");
|
}
|
baseMapper.insert(entity);
|
projectId = entity.getId();
|
addPlan(entity.getId()); //添加计划表
|
//添加项目中标单位
|
List<ProjectInfoWinUnit> projectInfoWinUnits = new ArrayList<>();
|
for (ProjectInfoWinUnitForm winUnitForm : form.getProjectInfoForm().getWinUnitList()) {
|
ProjectInfoWinUnit projectInfoWinUnit = ProjectInfoWinUnitForm.getEntityByForm(winUnitForm, null);
|
projectInfoWinUnit.setId(null);
|
projectInfoWinUnit.setProjectInfoId(entity.getId());
|
projectInfoWinUnits.add(projectInfoWinUnit);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoWinUnits)) {
|
projectInfoWinUnitService.saveBatch(projectInfoWinUnits);
|
}
|
//添加年度投资计划
|
List<ProjectInfoYearPlan> projectInfoYearPlans = new ArrayList<>();
|
for (ProjectInfoYearPlanForm yearPlanForm : form.getProjectInfoForm().getYearPlanList()) {
|
ProjectInfoYearPlan yearPlan = ProjectInfoYearPlanForm.getEntityByForm(yearPlanForm, null);
|
yearPlan.setId(null);
|
yearPlan.setProjectInfoId(entity.getId());
|
projectInfoYearPlans.add(yearPlan);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoYearPlans)) {
|
projectInfoYearPlanService.saveBatch(projectInfoYearPlans);
|
}
|
} else {
|
//更新
|
ProjectInfo entity = baseMapper.selectById(form.getProjectInfoForm().getId());
|
|
// 为空抛IllegalArgumentException,做全局异常处理
|
Assert.notNull(entity, "记录不存在");
|
ProjectInfoForm.getEntityByForm(form.getProjectInfoForm(), entity);
|
Long userId = SecurityUtils.getUserId();
|
entity.setUpdateBy(userId);
|
//如果是储备项目(未开工项目)不需要审核
|
if (ProjectCategoryEnum.RESERVE.getType().equals(entity.getProjectPhase())) {
|
entity.setUsedStatus(ProjectConstant.PASS);
|
}
|
// 管理员修改的直接通过
|
if (SecurityUtils.isAdmin(SecurityUtils.getUserId())) {
|
entity.setUsedStatus(ProjectConstant.PASS);
|
}
|
if(!checkProjectNameAndIdIsUnique(entity, entity.getId())){
|
throw new RuntimeException("项目重复,项目名称、项目码已存在");
|
}
|
//更新项目信息
|
baseMapper.updateById(entity);
|
//修改项目中标单位
|
//删除原数据
|
new LambdaUpdateChainWrapper<>(projectInfoWinUnitService.getBaseMapper())
|
.eq(ProjectInfoWinUnit::getProjectInfoId, entity.getId())
|
.remove();
|
//添加项目中标单位
|
List<ProjectInfoWinUnit> projectInfoWinUnits = new ArrayList<>();
|
for (ProjectInfoWinUnitForm winUnitForm : form.getProjectInfoForm().getWinUnitList()) {
|
ProjectInfoWinUnit projectInfoWinUnit = ProjectInfoWinUnitForm.getEntityByForm(winUnitForm, null);
|
projectInfoWinUnit.setId(null);
|
projectInfoWinUnit.setProjectInfoId(entity.getId());
|
projectInfoWinUnits.add(projectInfoWinUnit);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoWinUnits)) {
|
projectInfoWinUnitService.saveBatch(projectInfoWinUnits);
|
}
|
|
//修改年度投资计划
|
//删除原数据
|
new LambdaUpdateChainWrapper<>(projectInfoYearPlanService.getBaseMapper())
|
.eq(ProjectInfoYearPlan::getProjectInfoId, entity.getId())
|
.remove();
|
//添加年度投资计划
|
List<ProjectInfoYearPlan> projectInfoYearPlans = new ArrayList<>();
|
for (ProjectInfoYearPlanForm yearPlanForm : form.getProjectInfoForm().getYearPlanList()) {
|
ProjectInfoYearPlan yearPlan = ProjectInfoYearPlanForm.getEntityByForm(yearPlanForm, null);
|
yearPlan.setId(null);
|
yearPlan.setProjectInfoId(entity.getId());
|
projectInfoYearPlans.add(yearPlan);
|
}
|
if (!CollectionUtils.isEmpty(projectInfoYearPlans)) {
|
projectInfoYearPlanService.saveBatch(projectInfoYearPlans);
|
}
|
}
|
|
// 更新其它项目信息表
|
if (Objects.nonNull(form.getProjectInvestmentFundingForm())) {
|
if (Objects.nonNull(form.getProjectInvestmentFundingForm().getId())) {
|
projectInvestmentFundingServiceImpl.update(form.getProjectInvestmentFundingForm());
|
} else {
|
form.getProjectInvestmentFundingForm().setProjectId(projectId);
|
projectInvestmentFundingServiceImpl.add(form.getProjectInvestmentFundingForm());
|
}
|
}
|
if (Objects.nonNull(form.getProjectUnitRegistrationInfoForm())) {
|
if (Objects.nonNull(form.getProjectUnitRegistrationInfoForm().getId())) {
|
projectUnitRegistrationInfoServiceImpl.update(form.getProjectUnitRegistrationInfoForm());
|
} else {
|
form.getProjectUnitRegistrationInfoForm().setProjectId(projectId);
|
projectUnitRegistrationInfoServiceImpl.add(form.getProjectUnitRegistrationInfoForm());
|
}
|
|
}
|
}
|
return Result.ok("保存成功");
|
}
|
|
@Override
|
public Result searchByKey(String wordKey) {
|
Wrapper wrapper = null;
|
if (!StringUtils.isEmpty(wordKey)) {
|
wrapper = Wrappers.<ProjectInfo>lambdaQuery().like(ProjectInfo::getProjectName, wordKey).or().like(ProjectInfo::getProjectCode, wordKey);
|
}
|
List<ProjectInfo> list = baseMapper.selectList(wrapper);
|
return Result.ok().data(list);
|
}
|
|
private static void deleteDirectoryOrFile(java.io.File file) {
|
if (ObjectUtil.isNull(file)) {
|
return;
|
}
|
|
if (file.isDirectory()) {
|
java.io.File[] files = file.listFiles();
|
if (files != null) {
|
for (java.io.File f : files) {
|
deleteDirectoryOrFile(f);
|
}
|
}
|
}
|
file.delete();
|
}
|
|
/**
|
* 项目名称校验重复
|
*
|
* @return
|
*/
|
public void checkProjectNameUnique(ProjectInfo projectInfo) {
|
if (StrUtil.isBlank(projectInfo.getProjectName())) {
|
throw new BaseException("项目名称不能为空");
|
}
|
Assert.isTrue(baseMapper.selectCount(Wrappers.<ProjectInfo>lambdaQuery().eq(ProjectInfo::getProjectName, projectInfo.getProjectName())) == 0, "项目名称重复");
|
}
|
|
}
|