zhoulisky 8 months ago
parent
commit
1a1e0bd859

+ 1 - 5
kd-service-api/kd-scientific-api/src/main/java/org/sky/scientific/pojo/entity/SettingEntity.java

@@ -31,8 +31,7 @@ public class SettingEntity {
 	private String tenantId;
 
 	@Schema(description = "所属年份")
-//	@NotBlank(message = "参数yearAndMonth不能为空")
-	private String yearAndMonth;
+ 	private String yearAndMonth;
 
 	@Schema(description = "出勤时长")
 	private Double workHours;
@@ -40,9 +39,6 @@ public class SettingEntity {
 	@Schema(description = "高企证书url")
 	private String highTechUrl;
 
-	@Schema(description = "火炬发展年报")
-	private String torchDevUrl;
-
 	@Schema(description = "类型,读取上年度数据时需要传这个值,1:出勤时长,2:高企证书")
 	@TableField(exist = false)
 	private Integer type;

+ 0 - 7
kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/ArchiveCenterController.java

@@ -42,13 +42,6 @@ public class ArchiveCenterController extends KdController {
 		return R.status(service.fjbczlUpdate(attach));
 	}
 
-	@GetMapping("fjbczl/export")
-	@ApiOperationSupport(order = 3)
-	@Operation(summary = "附件补充资料-导出")
-	public void exportFjbczl(HttpServletResponse response, String year) {
-		service.exportFjbczl(response, year);
-	}
-
 	@GetMapping("fjbczl/download")
 	@ApiOperationSupport(order = 5)
 	@Operation(summary = "附件补充资料-一键下载")

+ 0 - 2
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/AssetMapper.xml

@@ -59,8 +59,6 @@
         <where>
             <if test="ew.zcbm != null and ew.zcbm != ''">and t.zcbm like concat('%',#{ew.zcbm},'%')</if>
             <if test="ew.zcmc != null and ew.zcmc != ''">and t.zcmc like concat('%',#{ew.zcmc},'%')</if>
-<!--            <if test="ew.zclb != null and ew.zclb != ''">and t.zclb = #{ew.zclb}</if>-->
-
             <if test="ew.zclbList!=null">
                 and t.zclb in
                 <foreach collection="ew.zclbList" item="item" open="(" separator="," close=")">

+ 10 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmTechnicianMapper.java

@@ -1,6 +1,7 @@
 
 package org.sky.scientific.mapper;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.annotations.Param;
@@ -105,4 +106,13 @@ public interface XmTechnicianMapper extends BaseMapper<XmTechnicianEntity> {
 	 * @return
 	 */
 	List<XmSalaryVO> meiyueyanfaxiangmurengongfenpeihuizongbiaoByYear(IPage<XmSalaryVO> page, @Param("ew") XmSalaryDto dto);
+
+	/**
+	 * 考勤和工时统计
+	 * @param tenantId 租户id
+	 * @param year 年份
+	 * @return
+	 */
+	@TenantIgnore
+	List<JSONObject> statisticsWorkHoursByXmAndUnicodeAndMonth(@Param("tenantId") String tenantId, @Param("year") String year);
 }

+ 16 - 1
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmTechnicianMapper.xml

@@ -354,4 +354,19 @@
         WHERE xm.tenant_id = #{ew.tenantId} and LEFT(xm.year_and_month,4) = #{ew.yearAndMonth}
         <if test="ew.xmmc!=null and ew.xmmc!=''">and m.XMMC like concat('%',#{ew.xmmc},'%')</if>
         GROUP BY xm.xm_id
-    </select></mapper>
+    </select>
+
+    <select id="statisticsWorkHoursByXmAndUnicodeAndMonth" resultType="com.alibaba.fastjson.JSONObject">
+        SELECT
+            m.xm_id as xmId,
+            m.unicode as unicode,
+            m.year_and_month as yearAndMonth,
+            (SELECT sum(r.work_hours) FROM kd_attendance_records r WHERE r.unicode = m.unicode and DATE_FORMAT(r.work_date,'%Y%m') = m.year_and_month) as attendanceHours,
+            (SELECT sum(h.work_hours) FROM kd_xm_technician_hours h WHERE h.xm_id = m.xm_id and h.unicode = m.unicode and DATE_FORMAT(h.work_date,'%Y%m') = m.year_and_month) as workHours
+        FROM
+            kd_xm_technician m
+        WHERE
+            m.tenant_id = #{tenantId} and LEFT(m.year_and_month,4)= #{year}
+        GROUP BY m.xm_id, m.unicode,m.year_and_month
+    </select>
+</mapper>

+ 0 - 7
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/IArchiveService.java

@@ -20,13 +20,6 @@ public interface IArchiveService {
 	 */
 	boolean fjbczlUpdate(ArchiveAttachEntity attach);
 
-	/**
-	 * 科研档案-附件资料补充-导出
-	 * @param response
-	 * @param year
-	 */
-	void exportFjbczl(HttpServletResponse response, String year);
-
 	void downloadFjbczlZipFiles(HttpServletRequest request, HttpServletResponse response, String year);
 
 	void downloadCenterZipFiles(HttpServletRequest request, HttpServletResponse response, String year);

+ 386 - 4
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/ArchiveServiceImpl.java

@@ -1,23 +1,37 @@
 package org.sky.scientific.service.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.AllArgsConstructor;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
 import org.sky.core.log.exception.ServiceException;
 import org.sky.core.secure.utils.SecureUtil;
 import org.sky.core.tool.utils.Func;
 import org.sky.scientific.mapper.ArchiveAttachMapper;
+import org.sky.scientific.mapper.SettingMapper;
 import org.sky.scientific.pojo.entity.ArchiveAttachEntity;
 import org.sky.scientific.service.IArchiveService;
+import org.sky.scientific.utils.ZipDir;
+import org.sky.scientific.utils.ZipDownloadUtils;
+import org.sky.scientific.utils.ZipFileRef;
 import org.springframework.stereotype.Service;
 
+import java.io.BufferedOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.zip.Deflater;
+
 @Service
 @AllArgsConstructor
 public class ArchiveServiceImpl implements IArchiveService {
 
 	private final ArchiveAttachMapper attachMapper;
+	private final SettingMapper settingMapper;
 
 	@Override
 	public ArchiveAttachEntity fjbczl(String year) {
@@ -55,30 +69,398 @@ public class ArchiveServiceImpl implements IArchiveService {
 		}
 	}
 
-	@Override
-	public void exportFjbczl(HttpServletResponse response, String year) {
-		ArchiveAttachEntity fjbczl = this.fjbczl(year);
-
+	public void configZipDir(ZipDir dir, String content) {
+		if (Func.notNull(content)) {
+			List<JSONObject> files = JSON.parseArray(content, JSONObject.class);
+			List<ZipFileRef> fileRefs = new ArrayList<>();
+			for (JSONObject file : files) {
+				fileRefs.add(new ZipFileRef(file.getString("label"), null, file.getString("value")));
+			}
+			dir.setFileRefs(fileRefs);
+		}
 	}
 
 	@Override
 	public void downloadFjbczlZipFiles(HttpServletRequest request, HttpServletResponse response, String year) {
+		List<ZipDir> data = new ArrayList<>();
+
+		ArchiveAttachEntity attach = fjbczl(year);
+
+		ZipDir d = new ZipDir();
+		d.setDirName("高新项目技术鉴定资料");
+		configZipDir(d, attach.getD1());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("加计扣除项目技术鉴定资料");
+		configZipDir(d, attach.getD2());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("高新技术企业认定资料");
+		configZipDir(d, attach.getD3());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("年度主要产品(服务)发挥核心支持作用的技术属于《国家重点支持的高新技术领域》规定范围的说明");
+		configZipDir(d, attach.getD4());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("高新技术产品(服务)及对应收入资料");
+		configZipDir(d, attach.getD5());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("年度职工和科技人员情况说明");
+		configZipDir(d, attach.getD6());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("当年和前两个会计年度研发费用总额及占同期销售收入比例的说明");
+		configZipDir(d, attach.getD7());
+		data.add(d);
 
+		d = new ZipDir();
+		d.setDirName("研发管理制度");
+		configZipDir(d, attach.getD8());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("研发费用结构明细表");
+		configZipDir(d, attach.getD9());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("加计扣除情况说明");
+		configZipDir(d, attach.getD10());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("其他高新备查资料");
+		configZipDir(d, attach.getD11());
+		data.add(d);
+
+		d = new ZipDir();
+		d.setDirName("其他加计扣除备查资料");
+		configZipDir(d, attach.getD12());
+		data.add(d);
+
+
+		try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(bos)) {
+			String fileName = year + "年附件补充" + ".zip";
+			ZipDownloadUtils.setResponse(request, response, fileName);
+			// 快速压缩
+			zipOut.setLevel(Deflater.BEST_SPEED);
+			for (ZipDir group : data) {
+				String dir = ZipDownloadUtils.safeName(group.getDirName()) + "/";
+				if(Func.isEmpty(group.getFileRefs())){
+					ZipDownloadUtils.writeEmptyDirToZip(zipOut, dir);
+				}else {
+					for (ZipFileRef fileRef : group.getFileRefs()) {
+						if (fileRef.getLocalPath() != null && !fileRef.getLocalPath().isEmpty()) {
+							ZipDownloadUtils.writeLocalFileToZip(zipOut, fileRef.getLocalPath(), dir + ZipDownloadUtils.safeName(fileRef.getName()));
+						} else if (fileRef.getHttpUrl() != null && !fileRef.getHttpUrl().isEmpty()) {
+							ZipDownloadUtils.writeHttpFileToZip(zipOut, fileRef.getHttpUrl(), dir + ZipDownloadUtils.safeName(fileRef.getName()));
+						}
+					}
+				}
+			}
+			zipOut.finish();
+			zipOut.flush();
+			response.flushBuffer();
+		} catch (Exception e) {
+			throw new RuntimeException("打包下载失败", e);
+		}
+	}
+
+	private ZipDir generateD1(String year) {
+		ZipDir dir = new ZipDir("高新技术企业资格证书");
+
+		return dir;
+	}
+
+	private ZipDir generateD2(String year) {
+		ZipDir dir = new ZipDir("高新技术企业认定资料");
+		return dir;
+	}
+
+	private ZipDir generateD3(String year) {
+		ZipDir dir = new ZipDir("加计扣除情况说明");
+		return dir;
+	}
+
+	private ZipDir generateD4(String year) {
+		ZipDir dir = new ZipDir("研发立项决议文件");
+		return dir;
+	}
+
+	private ZipDir generateD5(String year) {
+		ZipDir dir = new ZipDir("高新研发项目汇总表");
+		return dir;
+	}
+
+	private ZipDir generateD6(String year) {
+		ZipDir dir = new ZipDir("加计扣除研发项目汇总表");
+		return dir;
+	}
+
+	private ZipDir generateD7(String year) {
+		ZipDir dir = new ZipDir("高新研发项目全套技术资料");
+		return dir;
+	}
+
+	private ZipDir generateD8(String year) {
+		ZipDir dir = new ZipDir("加计扣除研发项目全套技术资料");
+		return dir;
+	}
+
+	private ZipDir generateD9(String year) {
+		ZipDir dir = new ZipDir("高新研发人员与科技人员资料");
+		return dir;
+	}
+
+	private ZipDir generateD10(String year) {
+		ZipDir dir = new ZipDir("加计扣除研发人员与科技人员资料");
+		return dir;
+	}
+
+	private ZipDir generateD11(String year) {
+		ZipDir dir = new ZipDir("全部知识产权资料(汇总表、证书)");
+		return dir;
+	}
+
+	private ZipDir generateD12(String year) {
+		ZipDir dir = new ZipDir("高新项目知识产权资料(汇总表、证书)");
+		return dir;
+	}
+
+	private ZipDir generateD13(String year) {
+		ZipDir dir = new ZipDir("加计扣除项目知识产权资料(汇总表、证书)");
+		return dir;
+	}
+
+	private ZipDir generateD14(String year) {
+		ZipDir dir = new ZipDir("高新口径研发费用辅助账");
+
+		return dir;
+	}
+
+	private ZipDir generateD15(String year) {
+		ZipDir dir = new ZipDir("加计扣除口径研发费用辅助账");
+		return dir;
+	}
+
+	private ZipDir generateD16(String year) {
+		ZipDir dir = new ZipDir("会计口径研发费用辅助账");
+		return dir;
+	}
+
+	private ZipDir generateD17(String year) {
+		ZipDir dir = new ZipDir("会计口径研发费用附件凭证资料及相关说明(二级菜单列表需财务提供)");
+		return dir;
+	}
+
+	private ZipDir generateD18(String year) {
+		ZipDir dir = new ZipDir("高新研发费用附件凭证资料及相关说明(二级菜单列表需财务提供)");
+		return dir;
+	}
+
+	private ZipDir generateD19(String year) {
+		ZipDir dir = new ZipDir("加计扣除研发费用附件凭证资料及相关说明(二级菜单列表需财务提供)");
+		return dir;
+	}
+
+	private ZipDir generateD20(String year) {
+		ZipDir dir = new ZipDir("A107012研发费用加计扣除优惠明细表");
+		return dir;
+	}
+
+	private ZipDir generateD21(String year) {
+		ZipDir dir = new ZipDir("当年和前两个会计年度研发费用总额及占同期销售收入比例的说明");
+		return dir;
+	}
+
+	private ZipDir generateD22(String year) {
+		ZipDir dir = new ZipDir("年度主要产品(服务)发挥核心支持作用的技术属于《国家重点支持的高新技术领域》规定范围的说明");
+		return dir;
+	}
+
+	private ZipDir generateD23(String year) {
+		ZipDir dir = new ZipDir("高新技术产品(服务)及对应收入资料");
+		return dir;
+	}
+
+	private ZipDir generateD24(String year) {
+		ZipDir dir = new ZipDir("研发管理制度");
+		return dir;
+	}
+
+	private ZipDir generateD25(String year) {
+		ZipDir dir = new ZipDir("高新项目技术鉴定资料");
+		return dir;
+	}
+
+	private ZipDir generateD26(String year) {
+		ZipDir dir = new ZipDir("加计扣除项目技术鉴定资料");
+		return dir;
+	}
+
+	private ZipDir generateD27(String year) {
+		ZipDir dir = new ZipDir("其他高新备查资料");
+		return dir;
+	}
+
+	private ZipDir generateD28(String year) {
+		ZipDir dir = new ZipDir("其他加计扣除备查资料");
+		return dir;
 	}
 
 	@Override
 	public void downloadCenterZipFiles(HttpServletRequest request, HttpServletResponse response, String year) {
+		if (Func.isBlank(year)) {
+			throw new ServiceException("参数year不能为空");
+		}
+		List<ZipDir> data = new ArrayList<>();
+
+		data.add(generateD1(year));
+		data.add(generateD2(year));
+		data.add(generateD3(year));
+		data.add(generateD4(year));
+		data.add(generateD5(year));
+		data.add(generateD6(year));
+		data.add(generateD7(year));
+		data.add(generateD8(year));
+		data.add(generateD9(year));
+		data.add(generateD10(year));
+		data.add(generateD11(year));
+		data.add(generateD12(year));
+		data.add(generateD13(year));
+		data.add(generateD14(year));
+		data.add(generateD15(year));
+		data.add(generateD16(year));
+		data.add(generateD17(year));
+		data.add(generateD18(year));
+		data.add(generateD19(year));
+		data.add(generateD20(year));
+		data.add(generateD21(year));
+		data.add(generateD22(year));
+		data.add(generateD23(year));
+		data.add(generateD24(year));
+		data.add(generateD25(year));
+		data.add(generateD26(year));
+		data.add(generateD27(year));
+		data.add(generateD28(year));
 
+		try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(bos)) {
+			String fileName = year + "年档案中心" + ".zip";
+			ZipDownloadUtils.setResponse(request, response, fileName);
+			// 快速压缩
+			zipOut.setLevel(Deflater.BEST_SPEED);
+			for (ZipDir group : data) {
+				String dir = ZipDownloadUtils.safeName(group.getDirName()) + "/";
+				List<ZipDir> subDirs = group.getSubDirs();
+				if (subDirs == null || subDirs.isEmpty()) {
+					ZipDownloadUtils.writeEmptyDirToZip(zipOut, dir);
+					continue;
+				}
+				for (ZipFileRef fileRef : group.getFileRefs()) {
+					if (fileRef.getLocalPath() != null && !fileRef.getLocalPath().isEmpty()) {
+						ZipDownloadUtils.writeLocalFileToZip(zipOut, fileRef.getLocalPath(), dir + ZipDownloadUtils.safeName(fileRef.getName()));
+					} else if (fileRef.getHttpUrl() != null && !fileRef.getHttpUrl().isEmpty()) {
+						ZipDownloadUtils.writeHttpFileToZip(zipOut, fileRef.getHttpUrl(), dir + ZipDownloadUtils.safeName(fileRef.getName()));
+					}
+				}
+			}
+			zipOut.finish();
+			zipOut.flush();
+			response.flushBuffer();
+		} catch (Exception e) {
+			throw new RuntimeException("打包下载失败", e);
+		}
 	}
 
 	@Override
 	public void downloadHighTechZipFiles(HttpServletRequest request, HttpServletResponse response, String year) {
+		if (Func.isBlank(year)) {
+			throw new ServiceException("参数year不能为空");
+		}
+
+		List<ZipDir> data = new ArrayList<>(Arrays.asList(generateD1(year), generateD2(year), generateD4(year), generateD5(year), generateD7(year), generateD9(year), generateD11(year), generateD14(year), generateD21(year), generateD22(year), generateD23(year), generateD25(year), generateD27(year)));
 
+		try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(bos)) {
+			String fileName = year + "年档案中心高新备查" + ".zip";
+			ZipDownloadUtils.setResponse(request, response, fileName);
+			// 快速压缩
+			zipOut.setLevel(Deflater.BEST_SPEED);
+			for (ZipDir group : data) {
+				String dir = ZipDownloadUtils.safeName(group.getDirName()) + "/";
+				List<ZipDir> subDirs = group.getSubDirs();
+				if (subDirs == null || subDirs.isEmpty()) {
+					ZipDownloadUtils.writeEmptyDirToZip(zipOut, dir);
+					continue;
+				}
+				for (ZipFileRef fileRef : group.getFileRefs()) {
+					if (fileRef.getLocalPath() != null && !fileRef.getLocalPath().isEmpty()) {
+						ZipDownloadUtils.writeLocalFileToZip(zipOut, fileRef.getLocalPath(), dir + ZipDownloadUtils.safeName(fileRef.getName()));
+					} else if (fileRef.getHttpUrl() != null && !fileRef.getHttpUrl().isEmpty()) {
+						ZipDownloadUtils.writeHttpFileToZip(zipOut, fileRef.getHttpUrl(), dir + ZipDownloadUtils.safeName(fileRef.getName()));
+					}
+				}
+			}
+			zipOut.finish();
+			zipOut.flush();
+			response.flushBuffer();
+		} catch (Exception e) {
+			throw new RuntimeException("打包下载失败", e);
+		}
 	}
 
 	@Override
 	public void downloadDeductionZipFiles(HttpServletRequest request, HttpServletResponse response, String year) {
+		if (Func.isBlank(year)) {
+			throw new ServiceException("参数year不能为空");
+		}
+		List<ZipDir> data = new ArrayList<>();
 
+		data.add(generateD3(year));
+		data.add(generateD4(year));
+		data.add(generateD6(year));
+		data.add(generateD8(year));
+		data.add(generateD10(year));
+		data.add(generateD13(year));
+		data.add(generateD15(year));
+		data.add(generateD19(year));
+		data.add(generateD20(year));
+		data.add(generateD26(year));
+		data.add(generateD28(year));
+
+		try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(bos)) {
+			String fileName = year + "年档案中心加计备查" + ".zip";
+			ZipDownloadUtils.setResponse(request, response, fileName);
+			// 快速压缩
+			zipOut.setLevel(Deflater.BEST_SPEED);
+			for (ZipDir group : data) {
+				String dir = ZipDownloadUtils.safeName(group.getDirName()) + "/";
+				List<ZipDir> subDirs = group.getSubDirs();
+				if (subDirs == null || subDirs.isEmpty()) {
+					ZipDownloadUtils.writeEmptyDirToZip(zipOut, dir);
+					continue;
+				}
+				for (ZipFileRef fileRef : group.getFileRefs()) {
+					if (fileRef.getLocalPath() != null && !fileRef.getLocalPath().isEmpty()) {
+						ZipDownloadUtils.writeLocalFileToZip(zipOut, fileRef.getLocalPath(), dir + ZipDownloadUtils.safeName(fileRef.getName()));
+					} else if (fileRef.getHttpUrl() != null && !fileRef.getHttpUrl().isEmpty()) {
+						ZipDownloadUtils.writeHttpFileToZip(zipOut, fileRef.getHttpUrl(), dir + ZipDownloadUtils.safeName(fileRef.getName()));
+					}
+				}
+			}
+			zipOut.finish();
+			zipOut.flush();
+			response.flushBuffer();
+		} catch (Exception e) {
+			throw new RuntimeException("打包下载失败", e);
+		}
 	}
 
 }

+ 31 - 10
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/EnterpriseInfoServiceImpl.java

@@ -47,6 +47,7 @@ import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 
 /**
  * 企业基础信息表 服务实现类
@@ -79,7 +80,7 @@ public class EnterpriseInfoServiceImpl extends BaseServiceImpl<EnterpriseInfoMap
 	private final ISysClient sysClient;
 	private final FreeMarkerConfigurer freeMarkerConfigurer;
 	private final XmFixedAssetMapper xmFixedAssetMapper;
-	private final SettingMapper settingMapper;
+	private final XmTechnicianMapper xmTechnicianMapper;
 
 
 	@Override
@@ -143,11 +144,30 @@ public class EnterpriseInfoServiceImpl extends BaseServiceImpl<EnterpriseInfoMap
 		if (year.length() != 4) {
 			throw new ServiceException("参数year为年份,如2025");
 		}
+
+		List<JSONObject> tempList = xmTechnicianMapper.statisticsWorkHoursByXmAndUnicodeAndMonth(SecureUtil.getTenantId(), year);
+
+		Map<String, List<JSONObject>> mapByXmId = new HashMap<>();
+		if(Func.isNotEmpty(tempList)){
+			mapByXmId = tempList.stream().collect(Collectors.groupingBy(item -> item.getString("xmId")));
+		}
+
 		List<A107_1VO> list = a107_1Mapper.qyyjkfxmqk(year, SecureUtil.getTenantId());
 		for (A107_1VO vo : list) {
 
-//			TODO 项目人员实际工作时间(人月)
-//			vo.setWorkTime();
+//			项目人员实际工作时间(人月)
+			double workTime = 0d;
+			List<JSONObject> listByXmId = mapByXmId.get(vo.getXmId() + "");
+			if(Func.isNotEmpty(listByXmId)){
+				for (JSONObject o : listByXmId) {
+					double workHours = o.getDouble("workHours") == null ? 0d : o.getDouble("workHours");
+					double attendanceHours = o.getDouble("attendanceHours") == null ? 0d : o.getDouble("attendanceHours");
+
+					workTime += (workHours == 0 || attendanceHours == 0) ? 0d : workHours / attendanceHours;
+				}
+			}
+
+			vo.setWorkTime(BigDecimal.valueOf(workTime).setScale(2, RoundingMode.HALF_UP).doubleValue());
 
 			//当列15等于基础研究时,列14=P088中对应研发项目的受托方类型的前5项的委外金额合计。当列15不等于基础研究时,列14等于0
 			if (Func.equals(vo.getYjlx(), "基础研究")) {
@@ -291,8 +311,8 @@ public class EnterpriseInfoServiceImpl extends BaseServiceImpl<EnterpriseInfoMap
 		vo.setD6(d6);
 
 		//二、研究开发费用情况
-		statisticsCost( vo, year);
-		if(Func.isNull(vo.getD26()) || vo.getD26().compareTo(BigDecimal.ZERO) <=0){
+		statisticsCost(vo, year);
+		if (Func.isNull(vo.getD26()) || vo.getD26().compareTo(BigDecimal.ZERO) <= 0) {
 			vo.setD26(vo.getD7());
 		}
 
@@ -363,9 +383,9 @@ public class EnterpriseInfoServiceImpl extends BaseServiceImpl<EnterpriseInfoMap
 		//九、本年研发费用加计扣除总额(47-48-49)×50,50为固定的100%
 		//如果当年是高企,就税率为15%,如非高企,税率为25%
 		vo.setD44(a107012_d47.subtract(a107012_d48).subtract(a107012_d49));
-		if(enterpriseInfoMapper.selectCount(Wrappers.<EnterpriseInfoEntity>lambdaQuery().eq(EnterpriseInfoEntity::getHighTechYear, year)) > 0){
+		if (enterpriseInfoMapper.selectCount(Wrappers.<EnterpriseInfoEntity>lambdaQuery().eq(EnterpriseInfoEntity::getHighTechYear, year)) > 0) {
 			vo.setD44(vo.getD44().multiply(new BigDecimal("0.15")).multiply(new BigDecimal("0.001")).setScale(2, RoundingMode.HALF_UP));
-		}else {
+		} else {
 			vo.setD44(vo.getD44().multiply(new BigDecimal("0.25")).multiply(new BigDecimal("0.001")).setScale(2, RoundingMode.HALF_UP));
 		}
 
@@ -433,7 +453,7 @@ public class EnterpriseInfoServiceImpl extends BaseServiceImpl<EnterpriseInfoMap
 		return vo;
 	}
 
-	private void statisticsCost(A107_2VO vo, String year){
+	private void statisticsCost(A107_2VO vo, String year) {
 		CostSummaryDTO costSummaryDTO = new CostSummaryDTO();
 		costSummaryDTO.setStartYearMonth(year + "01");
 		costSummaryDTO.setMonthCount(12);
@@ -490,6 +510,7 @@ public class EnterpriseInfoServiceImpl extends BaseServiceImpl<EnterpriseInfoMap
 		vo.setD7(vo.getD8().add(vo.getD9()).add(vo.getD10()).add(vo.getD11()).add(vo.getD12()).add(vo.getD13()).add(vo.getD14()).add(vo.getD19()));
 
 	}
+
 	@Override
 	public boolean updateQyyjkfhdjxgfy107_2(A107_2 a1072) {
 		LambdaQueryWrapper<A107_2> eq = Wrappers.<A107_2>lambdaQuery().eq(A107_2::getYearAndMonth, a1072.getYearAndMonth());
@@ -1000,9 +1021,9 @@ public class EnterpriseInfoServiceImpl extends BaseServiceImpl<EnterpriseInfoMap
 
 		//取数:对外报表:107.2表,六、企业办研究开发机构(境内)情况,机构研究开发费用
 		A107_2 a1072 = a107_2Mapper.selectOne(Wrappers.<A107_2>lambdaQuery().eq(A107_2::getYearAndMonth, year));
-		if(Func.isNull(a1072)){
+		if (Func.isNull(a1072)) {
 			vo.setD28(a107_2VO.getD7().toPlainString());
-		}else {
+		} else {
 			vo.setD28(a1072.getD26().toPlainString());
 		}
 

+ 6 - 8
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/YfzdServiceImpl.java

@@ -67,7 +67,6 @@ public class YfzdServiceImpl extends BaseServiceImpl<YfzdMapper, YfzdEntity> imp
 
 	@Override
 	public void downloadZipFiles(HttpServletRequest request, HttpServletResponse response, String year) {
-		// ==== 示例数据 ====
 		List<ZipDir> data = new ArrayList<>();
 
 		YfzdEntity yfzd = new YfzdEntity();
@@ -108,9 +107,8 @@ public class YfzdServiceImpl extends BaseServiceImpl<YfzdMapper, YfzdEntity> imp
 			data.add(group);
 		}
 
-		try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
-			 ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(bos)) {
-			String fileName =  year +"年研发制度"+ ".zip";
+		try (BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); ZipArchiveOutputStream zipOut = new ZipArchiveOutputStream(bos)) {
+			String fileName = year + "年研发制度" + ".zip";
 			ZipDownloadUtils.setResponse(request, response, fileName);
 			// 快速压缩
 			zipOut.setLevel(Deflater.BEST_SPEED);
@@ -118,7 +116,7 @@ public class YfzdServiceImpl extends BaseServiceImpl<YfzdMapper, YfzdEntity> imp
 				String groupDir = ZipDownloadUtils.safeName(group.getDirName()) + "/";
 				List<ZipDir> subDirs = group.getSubDirs();
 				if (subDirs == null || subDirs.isEmpty()) {
- 					ZipDownloadUtils.writeEmptyDirToZip(zipOut, groupDir);
+					ZipDownloadUtils.writeEmptyDirToZip(zipOut, groupDir);
 					continue;
 				}
 				for (ZipDir subDir : subDirs) {
@@ -130,10 +128,10 @@ public class YfzdServiceImpl extends BaseServiceImpl<YfzdMapper, YfzdEntity> imp
 					}
 					for (ZipFileRef fileRef : fileRefs) {
 						if (fileRef.getLocalPath() != null && !fileRef.getLocalPath().isEmpty()) {
-  							ZipDownloadUtils.writeLocalFileToZip(zipOut, fileRef.getLocalPath(), subDirPath + ZipDownloadUtils.safeName(fileRef.getName()));
+							ZipDownloadUtils.writeLocalFileToZip(zipOut, fileRef.getLocalPath(), subDirPath + ZipDownloadUtils.safeName(fileRef.getName()));
 						} else if (fileRef.getHttpUrl() != null && !fileRef.getHttpUrl().isEmpty()) {
-  							ZipDownloadUtils.writeHttpFileToZip(zipOut, fileRef.getHttpUrl(), subDirPath + ZipDownloadUtils.safeName(fileRef.getName()));
- 						}
+							ZipDownloadUtils.writeHttpFileToZip(zipOut, fileRef.getHttpUrl(), subDirPath + ZipDownloadUtils.safeName(fileRef.getName()));
+						}
 					}
 				}
 			}

+ 6 - 4
kd-service/kd-scientific/src/main/java/org/sky/scientific/utils/ZipDir.java

@@ -1,14 +1,11 @@
 package org.sky.scientific.utils;
 
-import lombok.AllArgsConstructor;
 import lombok.Data;
-import lombok.NoArgsConstructor;
 
 import java.util.List;
 
 @Data
-@AllArgsConstructor
-@NoArgsConstructor
+
  public class ZipDir {
 	//目录名
 	private String dirName;
@@ -17,4 +14,9 @@ import java.util.List;
 	//文件集合
 	private List<ZipFileRef> fileRefs;
 
+	public ZipDir() {}
+
+	public ZipDir(String dirName) {
+		this.dirName = dirName;
+	}
 }