zhoulisky пре 8 месеци
родитељ
комит
11550ba392
21 измењених фајлова са 396 додато и 202 уклоњено
  1. 6 14
      kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/XmController.java
  2. 13 48
      kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/YfzdController.java
  3. 0 19
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmMapper.java
  4. 0 4
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmMapper.xml
  5. 2 24
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/YfzdMapper.java
  6. 0 10
      kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/YfzdMapper.xml
  7. 7 10
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/IXmService.java
  8. 12 23
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/IYfzdService.java
  9. 0 12
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/EnterpriseInfoServiceImpl.java
  10. 3 1
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/XmLeaseServiceImpl.java
  11. 15 11
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/XmServiceImpl.java
  12. 99 25
      kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/YfzdServiceImpl.java
  13. 168 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/utils/ZipDownloadUtils.java
  14. 25 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/utils/ZipFileRef.java
  15. 17 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/utils/ZipGroup.java
  16. 22 0
      kd-service/kd-scientific/src/main/java/org/sky/scientific/utils/ZipSubDir.java
  17. BIN
      kd-service/kd-scientific/src/main/resources/templates/1-项目立项-立项申请资料.doc
  18. 3 0
      kd-service/kd-scientific/src/main/resources/templates/1-项目立项-立项申请资料.ftl
  19. 3 0
      kd-service/kd-scientific/src/main/resources/templates/1-项目立项-立项申请资料.xml
  20. BIN
      kd-service/kd-scientific/src/main/resources/templates/3-项目实施-阶段性报告.doc
  21. 1 1
      kd-service/kd-system/src/main/java/org/sky/system/rule/tenant/TenantUserRule.java

+ 6 - 14
kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/XmController.java

@@ -2,7 +2,6 @@
 package org.sky.scientific.controller;
 
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.v3.oas.annotations.Operation;
@@ -12,14 +11,10 @@ import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.Valid;
 import lombok.AllArgsConstructor;
 import org.sky.core.boot.ctrl.KdController;
-import org.sky.core.excel.util.ExcelUtil;
 import org.sky.core.mp.support.Condition;
 import org.sky.core.mp.support.Query;
-import org.sky.core.secure.KdUser;
 import org.sky.core.tool.api.R;
-import org.sky.core.tool.utils.DateUtil;
 import org.sky.core.tool.utils.Func;
-import org.sky.scientific.excel.XmExcel;
 import org.sky.scientific.pojo.dto.XmDTO;
 import org.sky.scientific.pojo.dto.XmUpdateDto;
 import org.sky.scientific.pojo.entity.XmEntity;
@@ -32,7 +27,6 @@ import org.sky.scientific.service.IXmService;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * 科研项目 控制器
@@ -122,18 +116,16 @@ public class XmController extends KdController {
 
 	@GetMapping("/approval")
 	@ApiOperationSupport(order = 6)
-	@Operation(summary = "查询立项信息")
+	@Operation(summary = "立项信息-查询")
 	public R<XmVO> selectApprovalInfo(Long xmId){
 		return R.data(service.selectApprovalInfo(xmId));
 	}
 
-	@GetMapping("/export-xm")
-	@ApiOperationSupport(order = 9)
-	@Operation(summary = "导出数据", description  = "传入xm")
-	public void exportXm(@Parameter(hidden = true) @RequestParam Map<String, Object> xm, KdUser kdUser, HttpServletResponse response) {
-		QueryWrapper<XmEntity> queryWrapper = Condition.getQueryWrapper(xm, XmEntity.class);
-		List<XmExcel> list = service.exportXm(queryWrapper);
-		ExcelUtil.export(response, "科研项目数据" + DateUtil.time(), "科研项目数据表", list, XmExcel.class);
+	@GetMapping("/approval/print")
+	@ApiOperationSupport(order = 7)
+	@Operation(summary = "立项信息-打印")
+	public void printApprovalInfo(HttpServletResponse response,Long xmId){
+		service.printApprovalInfo(response,xmId);
 	}
 
 	@GetMapping("yszb")

+ 13 - 48
kd-service/kd-scientific/src/main/java/org/sky/scientific/controller/YfzdController.java

@@ -1,37 +1,23 @@
 
 package org.sky.scientific.controller;
 
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import io.swagger.v3.oas.annotations.tags.Tag;
+import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
-import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
-import lombok.AllArgsConstructor;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.Valid;
-
-import org.sky.core.excel.util.ExcelUtil;
-import org.sky.core.mp.support.Condition;
-import org.sky.core.mp.support.Query;
-import org.sky.core.secure.KdUser;
-import org.sky.core.secure.annotation.IsAdmin;
+import lombok.AllArgsConstructor;
+import org.sky.core.boot.ctrl.KdController;
 import org.sky.core.tool.api.R;
-import org.sky.core.tool.utils.DateUtil;
 import org.sky.core.tool.utils.Func;
-import org.springframework.web.bind.annotation.*;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.sky.scientific.pojo.entity.YfzdEntity;
-import org.sky.scientific.pojo.vo.YfzdVO;
-import org.sky.scientific.excel.YfzdExcel;
-import org.sky.scientific.wrapper.YfzdWrapper;
 import org.sky.scientific.service.IYfzdService;
-import org.sky.core.boot.ctrl.KdController;
+import org.springframework.web.bind.annotation.*;
 
-import java.util.Map;
 import java.util.List;
-
-import jakarta.servlet.http.HttpServletResponse;
+import java.util.Map;
 
 /**
  * 研发制度 控制器
@@ -69,32 +55,11 @@ public class YfzdController extends KdController {
 		return R.status(service.physicalDeleteByIds(Func.toLongList(ids)));
 	}
 
- 	@GetMapping("/export-yfzd")
-	@ApiOperationSupport(order = 9)
-	@Operation(summary = "导出数据", description = "传入yfzd")
-	public void exportYfzd(@Parameter(hidden = true) @RequestParam Map<String, Object> yfzd, KdUser kdUser, HttpServletResponse response) {
-		QueryWrapper<YfzdEntity> queryWrapper = Condition.getQueryWrapper(yfzd, YfzdEntity.class);
-		List<YfzdExcel> list = service.exportYfzd(queryWrapper);
-		ExcelUtil.export(response, "研发制度数据" + DateUtil.time(), "研发制度数据表", list, YfzdExcel.class);
+	@GetMapping("/download")
+	@ApiOperationSupport(order = 10)
+	@Operation(summary = "一键下载")
+	public void downloadZipFiles(HttpServletRequest request, HttpServletResponse response, String year){
+		service.downloadZipFiles(request,response, year);
 	}
 
-//	public static void main(String[] args) {
-//		JSONArray jsonArray = new JSONArray();
-//		JSONObject jsonObject = new JSONObject();
-//		jsonObject.put("url", "http://sxdhyig3c.hn-bkt.clouddn.com/upload/20250702/864da644cc7041f5414c55c1a6f625c7.png");
-//		jsonObject.put("fileName", "111.png");
-//		jsonArray.add(jsonObject);
-//		jsonObject = new JSONObject();
-//		jsonObject.put("url", "http://sxdhyig3c.hn-bkt.clouddn.com/upload/20250702/864da644cc7041f5414c55c1a6f625c7.png");
-//		jsonObject.put("fileName", "222.png");
-//		jsonArray.add(jsonObject);
-//		jsonObject = new JSONObject();
-//		jsonObject.put("url", "http://sxdhyig3c.hn-bkt.clouddn.com/upload/20250702/864da644cc7041f5414c55c1a6f625c7.png");
-//		jsonObject.put("fileName", "333.png");
-//		jsonArray.add(jsonObject);
-//		System.out.println(jsonArray.toJSONString());
-//
-////		"[{\"fileName\":\"111.png\",\"url\":\"http://sxdhyig3c.hn-bkt.clouddn.com/upload/20250702/864da644cc7041f5414c55c1a6f625c7.png\"},{\"fileName\":\"222.png\",\"url\":\"http://sxdhyig3c.hn-bkt.clouddn.com/upload/20250702/864da644cc7041f5414c55c1a6f625c7.png\"},{\"fileName\":\"333.png\",\"url\":\"http://sxdhyig3c.hn-bkt.clouddn.com/upload/20250702/864da644cc7041f5414c55c1a6f625c7.png\"}]\n"
-//	}
-
 }

+ 0 - 19
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmMapper.java

@@ -2,12 +2,10 @@
 package org.sky.scientific.mapper;
 
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.annotations.Param;
 import org.sky.core.tenant.annotation.TenantIgnore;
-import org.sky.scientific.excel.XmExcel;
 import org.sky.scientific.pojo.dto.XmDTO;
 import org.sky.scientific.pojo.dto.XmUpdateDto;
 import org.sky.scientific.pojo.entity.XmEntity;
@@ -42,15 +40,6 @@ public interface XmMapper extends BaseMapper<XmEntity> {
 	 */
 	List<XmEntity> selectXmListByYear(@Param("year") String year);
 
-
-	/**
-	 * 获取导出数据
-	 *
-	 * @param queryWrapper 查询条件
-	 * @return List<XmExcel>
-	 */
-	List<XmExcel> exportXm(@Param("ew") Wrapper<XmEntity> queryWrapper);
-
 	/**
 	 * 获取汇总表
 	 *
@@ -77,14 +66,6 @@ public interface XmMapper extends BaseMapper<XmEntity> {
 	XmVO selectByXmIdAndYearMonth(Map map);
 
 	/**
-	 * 根据项目id和年月查询项目最新信息
-	 * @param xmId
-	 * @param yearAndMonth
-	 * @return
-	 */
-	XmVO selectByXmIdAndDay(Map map);
-
-	/**
 	 * 查询项目信息,结合变更
 	 * @param xmId
 	 * @return

+ 0 - 4
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/XmMapper.xml

@@ -72,10 +72,6 @@
         WHERE #{year} between DATE_FORMAT(XMKSSJ, '%Y') and DATE_FORMAT(XMJSSJ, '%Y')
     </select>
 
-    <select id="exportXm" resultType="org.sky.scientific.excel.XmExcel">
-        SELECT * FROM kd_xm ${ew.customSqlSegment}
-    </select>
-
     <select id="summaryPage" resultType="org.sky.scientific.pojo.vo.XmSummary">
         SELECT
             xm.id, xm.xmbh,

+ 2 - 24
kd-service/kd-scientific/src/main/java/org/sky/scientific/mapper/YfzdMapper.java

@@ -1,13 +1,9 @@
 
 package org.sky.scientific.mapper;
 
-import org.sky.scientific.pojo.entity.YfzdEntity;
-import org.sky.scientific.pojo.vo.YfzdVO;
-import org.sky.scientific.excel.YfzdExcel;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import org.apache.ibatis.annotations.Param;
+import org.sky.scientific.pojo.entity.YfzdEntity;
+
 import java.util.List;
 
 /**
@@ -18,24 +14,6 @@ import java.util.List;
  */
 public interface YfzdMapper extends BaseMapper<YfzdEntity> {
 
-	/**
-	 * 自定义分页
-	 *
-	 * @param page 分页参数
-	 * @param yfzd 查询参数
-	 * @return List<YfzdVO>
-	 */
-	List<YfzdVO> selectYfzdPage(IPage page, YfzdVO yfzd);
-
-
-	/**
-	 * 获取导出数据
-	 *
-	 * @param queryWrapper 查询条件
-	 * @return List<YfzdExcel>
-	 */
-	List<YfzdExcel> exportYfzd(@Param("ew") Wrapper<YfzdEntity> queryWrapper);
-
 	List<String> selectWJLXType();
 
 	boolean physicalDeleteByIds(List<Long> ids);

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

@@ -29,16 +29,6 @@
         </foreach>
     </delete>
 
-
-    <select id="selectYfzdPage" resultMap="yfzdResultMap">
-        select * from c where is_deleted = 0
-    </select>
-
-
-    <select id="exportYfzd" resultType="org.sky.scientific.excel.YfzdExcel">
-        SELECT * FROM kd_yfzd ${ew.customSqlSegment}
-    </select>
-
     <select id="selectWJLXType">
         select WJLX from kd_yfzd_type
     </select>

+ 7 - 10
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/IXmService.java

@@ -2,11 +2,9 @@
 package org.sky.scientific.service;
 
 import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import jakarta.servlet.http.HttpServletResponse;
 import org.sky.core.mp.base.BaseService;
-import org.sky.scientific.excel.XmExcel;
 import org.sky.scientific.pojo.dto.XmDTO;
 import org.sky.scientific.pojo.dto.XmUpdateDto;
 import org.sky.scientific.pojo.entity.XmEntity;
@@ -40,14 +38,6 @@ public interface IXmService extends BaseService<XmEntity> {
 	List<XmEntity> selectXmListByYear(String year);
 
 	/**
-	 * 导出数据
-	 *
-	 * @param queryWrapper 查询条件
-	 * @return List<XmExcel>
-	 */
-	List<XmExcel> exportXm(Wrapper<XmEntity> queryWrapper);
-
-	/**
 	 * 立项
 	 * @param xm
 	 * @return 项目id
@@ -106,4 +96,11 @@ public interface IXmService extends BaseService<XmEntity> {
 	 * @return
 	 */
 	XmVO selectApprovalInfo(Long xmId);
+
+	/**
+	 * 立项信息-打印
+	 * @param response
+	 * @param xmId
+	 */
+	void printApprovalInfo(HttpServletResponse response, Long xmId);
 }

+ 12 - 23
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/IYfzdService.java

@@ -1,13 +1,11 @@
 
 package org.sky.scientific.service;
 
-import com.alibaba.fastjson.JSONObject;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import org.sky.scientific.pojo.entity.YfzdEntity;
-import org.sky.scientific.pojo.vo.YfzdVO;
-import org.sky.scientific.excel.YfzdExcel;
-import com.baomidou.mybatisplus.core.metadata.IPage;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
 import org.sky.core.mp.base.BaseService;
+import org.sky.scientific.pojo.entity.YfzdEntity;
+
 import java.util.List;
 import java.util.Map;
 
@@ -18,23 +16,6 @@ import java.util.Map;
  * @since 2025-06-29
  */
 public interface IYfzdService extends BaseService<YfzdEntity> {
-	/**
-	 * 自定义分页
-	 *
-	 * @param page 分页参数
-	 * @param yfzd 查询参数
-	 * @return IPage<YfzdVO>
-	 */
-	IPage<YfzdVO> selectYfzdPage(IPage<YfzdVO> page, YfzdVO yfzd);
-
-
-	/**
-	 * 导出数据
-	 *
-	 * @param queryWrapper 查询条件
-	 * @return List<YfzdExcel>
-	 */
-	List<YfzdExcel> exportYfzd(Wrapper<YfzdEntity> queryWrapper);
 
 	/**
 	 * 修改数据
@@ -58,4 +39,12 @@ public interface IYfzdService extends BaseService<YfzdEntity> {
 	 * @return
 	 */
 	boolean physicalDeleteByIds(List<Long> ids);
+
+	/**
+	 * 一键下载
+	 *
+	 * @param response
+	 * @param year
+	 */
+	void downloadZipFiles(HttpServletRequest request, HttpServletResponse response, String year);
 }

+ 0 - 12
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/EnterpriseInfoServiceImpl.java

@@ -1048,18 +1048,6 @@ public class EnterpriseInfoServiceImpl extends BaseServiceImpl<EnterpriseInfoMap
 	@Override
 	public void exportGqnb(HttpServletResponse response, String year) {
 		HighTechYBVO techYBVO = gqnb(year);
-
-//		Map<String, Object> map = new HashMap<>();
-//		BeanUtil.copyProperties(techYBVO, map);
-//		R<Tenant> tenant = sysClient.getTenant(SecureUtil.getTenantId());
-//		if (tenant.isSuccess()) {
-//			Tenant data = tenant.getData();
-//			map.put("enterpriseName", Func.toStr(data.getTenantName(), ""));
-//			map.put("uscc", Func.toStr(data.getUscc(), ""));
-//			map.put("regionName", Func.toStr(data.getAddress(), ""));
-//			map.put("linkman", Func.toStr(data.getLinkman(), ""));
-//			map.put("contactNumber", Func.toStr(data.getContactNumber(), ""));
-//		}
 		Template template = freeMarkerConfigurer.getConfiguration().getTemplate("年度高新技术企业发展情况报表.ftl");
 		response.setHeader("Content-disposition",
 			"attachment;filename=" + URLEncoder.encode("年度高新技术企业发展情况报表.doc", StandardCharsets.UTF_8));

+ 3 - 1
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/XmLeaseServiceImpl.java

@@ -147,7 +147,9 @@ public class XmLeaseServiceImpl extends BaseServiceImpl<XmLeaseMapper, XmLeaseEn
 		}
 
 		List<XmLeaseEntity> list = baseMapper.yanfazulinzichanfeiyongfenpeibiao(dto);
-
+		for (XmLeaseEntity lease : list) {
+			lease.setAmount(BigDecimal.valueOf(lease.getQuantity()).multiply(lease.getUnitPrice()));
+		}
 		List<JSONObject> result = new ArrayList<>();
 		if(CollectionUtil.isEmpty(list)){
 			return result;

+ 15 - 11
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/XmServiceImpl.java

@@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import freemarker.template.Template;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.AllArgsConstructor;
 import lombok.SneakyThrows;
@@ -35,11 +36,14 @@ import org.sky.scientific.pojo.vo.XmVO;
 import org.sky.scientific.pojo.vo.XmYszbVO;
 import org.sky.scientific.service.IXmService;
 import org.springframework.stereotype.Service;
+import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
 
 import java.io.InputStream;
+import java.io.OutputStreamWriter;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -56,12 +60,12 @@ public class XmServiceImpl extends BaseServiceImpl<XmMapper, XmEntity> implement
 	private final TechnicianMapper technicianMapper;
 	private final DepartmentMapper departmentMapper;
 	private final XmCostDetailsMapper xmCostDetailsMapper;
+	private final FreeMarkerConfigurer freeMarkerConfigurer;
 
 	@Override
 	public IPage<XmEntity> selectXmList(IPage<XmEntity> page, XmDTO xm) {
 		if (StringUtil.isBlank(xm.getYearAndMonth())) {
-//			throw new ServiceException("参数yearAndMonth不能为空");
-			xm.setYearAndMonth(DateUtil.format(new Date(), DateUtil.PATTERN_YYYYMM));
+ 			xm.setYearAndMonth(DateUtil.format(new Date(), DateUtil.PATTERN_YYYYMM));
 		}
 		return page.setRecords(baseMapper.selectXmPage(page, xm));
 	}
@@ -75,15 +79,6 @@ public class XmServiceImpl extends BaseServiceImpl<XmMapper, XmEntity> implement
 	}
 
 	@Override
-	public List<XmExcel> exportXm(Wrapper<XmEntity> queryWrapper) {
-		List<XmExcel> xmList = baseMapper.exportXm(queryWrapper);
-		//xmList.forEach(xm -> {
-		//	xm.setTypeName(DictCache.getValue(DictEnum.YES_NO, Xm.getType()));
-		//});
-		return xmList;
-	}
-
-	@Override
 	public Long approval(XmDTO xm) {
 
 		this.judgeXmmcAvailable(xm.getXmmc());
@@ -121,6 +116,15 @@ public class XmServiceImpl extends BaseServiceImpl<XmMapper, XmEntity> implement
 	}
 
 	@Override
+	public void printApprovalInfo(HttpServletResponse response, Long xmId) {
+//		Template template = freeMarkerConfigurer.getConfiguration().getTemplate("1-项目立项-立项申请资料.ftl");
+//		response.setHeader("Content-disposition",
+//			"attachment;filename=" + URLEncoder.encode("项目立项-立项申请资料.doc", StandardCharsets.UTF_8));
+//		response.setContentType("application/msword");// 定义输出类型
+//		template.process(techYBVO, new OutputStreamWriter(response.getOutputStream()));
+	}
+
+	@Override
 	public boolean updateXm(XmUpdateDto dto) {
 		return baseMapper.updateXm(dto);
 	}

+ 99 - 25
kd-service/kd-scientific/src/main/java/org/sky/scientific/service/impl/YfzdServiceImpl.java

@@ -1,25 +1,30 @@
 
 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 org.apache.commons.lang3.ArrayUtils;
+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.tool.utils.CollectionUtil;
+import org.sky.core.mp.base.BaseServiceImpl;
 import org.sky.core.tool.utils.StringUtil;
-import org.sky.scientific.pojo.entity.YfzdEntity;
-import org.sky.scientific.pojo.vo.YfzdVO;
-import org.sky.scientific.excel.YfzdExcel;
 import org.sky.scientific.mapper.YfzdMapper;
+import org.sky.scientific.pojo.entity.YfzdEntity;
 import org.sky.scientific.service.IYfzdService;
+import org.sky.scientific.utils.ZipDownloadUtils;
+import org.sky.scientific.utils.ZipFileRef;
+import org.sky.scientific.utils.ZipGroup;
+import org.sky.scientific.utils.ZipSubDir;
 import org.springframework.stereotype.Service;
-import com.baomidou.mybatisplus.core.conditions.Wrapper;
-import com.baomidou.mybatisplus.core.metadata.IPage;
-import org.sky.core.mp.base.BaseServiceImpl;
 
+import java.io.BufferedOutputStream;
 import java.util.*;
 import java.util.stream.Collectors;
+import java.util.zip.Deflater;
 
 /**
  * 研发制度 服务实现类
@@ -28,38 +33,24 @@ import java.util.stream.Collectors;
  * @since 2025-06-29
  */
 @Service
+@AllArgsConstructor
 public class YfzdServiceImpl extends BaseServiceImpl<YfzdMapper, YfzdEntity> implements IYfzdService {
 
 	@Override
-	public IPage<YfzdVO> selectYfzdPage(IPage<YfzdVO> page, YfzdVO yfzd) {
-		return page.setRecords(baseMapper.selectYfzdPage(page, yfzd));
-	}
-
-
-	@Override
-	public List<YfzdExcel> exportYfzd(Wrapper<YfzdEntity> queryWrapper) {
-		List<YfzdExcel> yfzdList = baseMapper.exportYfzd(queryWrapper);
-		//yfzdList.forEach(yfzd -> {
-		//	yfzd.setTypeName(DictCache.getValue(DictEnum.YES_NO, Yfzd.getType()));
-		//});
-		return yfzdList;
-	}
-
-	@Override
 	public boolean editYfzd(YfzdEntity yfzd) {
 		return this.saveOrUpdate(yfzd);
 	}
 
 	@Override
 	public Map<String, List<YfzdEntity>> selectYfzd(YfzdEntity yfzd) {
-		if(StringUtil.isBlank(yfzd.getYearAndMonth())){
+		if (StringUtil.isBlank(yfzd.getYearAndMonth())) {
 			throw new ServiceException("请选择年份");
 		}
 		List<String> wjlxTypeList = baseMapper.selectWJLXType();
 		LambdaQueryWrapper<YfzdEntity> queryWrapper = Wrappers.<YfzdEntity>lambdaQuery().eq(YfzdEntity::getYearAndMonth, yfzd.getYearAndMonth());
 		List<YfzdEntity> yfzdList = baseMapper.selectList(queryWrapper);
 		Map<String, List<YfzdEntity>> collected = yfzdList.stream().collect(Collectors.groupingBy(YfzdEntity::getWjlx));
-		if(collected.isEmpty()){
+		if (collected.isEmpty()) {
 			collected = new HashMap<>();
 		}
 		for (String wjlxType : wjlxTypeList) {
@@ -75,4 +66,87 @@ public class YfzdServiceImpl extends BaseServiceImpl<YfzdMapper, YfzdEntity> imp
 		return baseMapper.physicalDeleteByIds(ids);
 	}
 
+	@Override
+	public void downloadZipFiles(HttpServletRequest request, HttpServletResponse response, String year) {
+		// ==== 示例数据 ====
+		List<ZipGroup> data = new ArrayList<>();
+
+		YfzdEntity yfzd = new YfzdEntity();
+		yfzd.setYearAndMonth(year);
+		Map<String, List<YfzdEntity>> map = selectYfzd(yfzd);
+		for (String type : map.keySet()) {
+			ZipGroup group = new ZipGroup();
+			group.setDirName(type);
+
+			List<YfzdEntity> list = map.get(type);
+			//企业制度
+			ZipSubDir qiyezhiduDir = new ZipSubDir();
+			qiyezhiduDir.setSubDirName("企业制度");
+			qiyezhiduDir.setFileRefs(new ArrayList<>());
+			//实施证明
+			ZipSubDir shishizhengmDir = new ZipSubDir();
+			shishizhengmDir.setSubDirName("企业制度实施证明");
+			shishizhengmDir.setFileRefs(new ArrayList<>());
+
+			for (YfzdEntity entity : list) {
+				List<JSONObject> zdwjdz = JSON.parseArray(entity.getZdwjdz(), JSONObject.class);
+				for (JSONObject obj : zdwjdz) {
+					ZipFileRef ref = new ZipFileRef();
+					ref.setName(obj.getString("label"));
+					ref.setHttpUrl(obj.getString("value"));
+					qiyezhiduDir.getFileRefs().add(ref);
+				}
+
+				List<JSONObject> zdszm = JSON.parseArray(entity.getZdsszm(), JSONObject.class);
+				for (JSONObject obj : zdszm) {
+					ZipFileRef ref = new ZipFileRef();
+					ref.setName(obj.getString("label"));
+					ref.setHttpUrl(obj.getString("value"));
+					shishizhengmDir.getFileRefs().add(ref);
+				}
+
+			}
+
+			group.setSubDirs(Arrays.asList(qiyezhiduDir, shishizhengmDir));
+			data.add(group);
+
+		}
+
+		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 (ZipGroup group : data) {
+				String groupDir = ZipDownloadUtils.safeName(group.getDirName()) + "/";
+				List<ZipSubDir> subDirs = group.getSubDirs();
+				if (subDirs == null || subDirs.isEmpty()) {
+ 					ZipDownloadUtils.writeEmptyDirToZip(zipOut, groupDir);
+					continue;
+				}
+				for (ZipSubDir subDir : subDirs) {
+					String subDirPath = groupDir + ZipDownloadUtils.safeName(subDir.getSubDirName()) + "/";
+					List<ZipFileRef> fileRefs = subDir.getFileRefs();
+					if (fileRefs == null || fileRefs.isEmpty()) {
+						ZipDownloadUtils.writeEmptyDirToZip(zipOut, subDirPath);
+						continue;
+					}
+					for (ZipFileRef fileRef : fileRefs) {
+						if (fileRef.getLocalPath() != null && !fileRef.getLocalPath().isEmpty()) {
+  							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()));
+ 						}
+					}
+				}
+			}
+			zipOut.finish();
+			zipOut.flush();
+			response.flushBuffer();
+		} catch (Exception e) {
+			throw new RuntimeException("打包下载失败", e);
+		}
+	}
+
 }

+ 168 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/utils/ZipDownloadUtils.java

@@ -0,0 +1,168 @@
+package org.sky.scientific.utils;
+
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
+import org.springframework.util.StringUtils;
+
+import java.io.*;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDate;
+
+public class ZipDownloadUtils {
+
+	private static final String SUFFIX_ZIP = ".zip";
+	private static final String UNNAMED = "未命名";
+	/**
+	 * 安全处理文件名/目录名
+	 * @param name
+	 * @return
+	 */
+	public static String safeName(String name) {
+		if (name == null) return "null";
+		return name.replaceAll("[\\\\/:*?\"<>|]", "_");
+	}
+
+	/**
+	 * HTTP下载写入Zip
+	 * @param zipOut
+	 * @param fileUrl
+	 * @param zipEntryName
+	 * @throws IOException
+	 */
+	public static void writeHttpFileToZip(ZipArchiveOutputStream zipOut, String fileUrl, String zipEntryName) throws IOException {
+		ZipArchiveEntry entry = new ZipArchiveEntry(zipEntryName);
+		zipOut.putArchiveEntry(entry);
+		try (InputStream in = openHttpStream(fileUrl, 8000, 20000)) {
+			byte[] buffer = new byte[4096];
+			int len;
+			while ((len = in.read(buffer)) != -1) {
+				zipOut.write(buffer, 0, len);
+			}
+		} catch (Exception e) {
+			zipOut.write(("下载失败: " + fileUrl).getBytes(StandardCharsets.UTF_8));
+		}
+		zipOut.closeArchiveEntry();
+	}
+
+	/**
+	 * 本地文件写入Zip
+	 * @param zipOut
+	 * @param localFilePath
+	 * @param zipEntryName
+	 * @throws IOException
+	 */
+	public static void writeLocalFileToZip(ZipArchiveOutputStream zipOut, String localFilePath, String zipEntryName) throws IOException {
+		File file = new File(localFilePath);
+		if (!file.exists() || file.isDirectory()) {
+			writeTextToZip(zipOut, zipEntryName + "_empty.txt", "文件不存在或是目录: " + localFilePath);
+			return;
+		}
+
+		ZipArchiveEntry entry = new ZipArchiveEntry(zipEntryName);
+		zipOut.putArchiveEntry(entry);
+		try (InputStream fis = new FileInputStream(file)) {
+			byte[] buffer = new byte[4096];
+			int len;
+			while ((len = fis.read(buffer)) != -1) {
+				zipOut.write(buffer, 0, len);
+			}
+		}
+		zipOut.closeArchiveEntry();
+	}
+
+	/**
+	 * 写入空目录到Zip
+	 * @param zipOut
+	 * @param zipEntryName
+ 	 * @throws IOException
+	 */
+	public static void writeEmptyDirToZip(ZipArchiveOutputStream zipOut, String zipEntryName) throws IOException {
+		ZipArchiveEntry entry = new ZipArchiveEntry(zipEntryName);
+		zipOut.putArchiveEntry(entry);
+ 		zipOut.closeArchiveEntry();
+	}
+
+	/**
+	 * 写入文本文件到Zip(如empty.txt)
+	 * @param zipOut
+	 * @param zipEntryName
+	 * @param content
+	 * @throws IOException
+	 */
+	public static void writeTextToZip(ZipArchiveOutputStream zipOut, String zipEntryName, String content) throws IOException {
+		ZipArchiveEntry entry = new ZipArchiveEntry(zipEntryName);
+		zipOut.putArchiveEntry(entry);
+		zipOut.write(content.getBytes(StandardCharsets.UTF_8));
+		zipOut.closeArchiveEntry();
+	}
+
+	/**
+	 * 打开HTTP文件流
+	 * @param url
+	 * @param connectTimeout
+	 * @param readTimeout
+	 * @return
+	 * @throws IOException
+	 */
+	public static InputStream openHttpStream(String url, int connectTimeout, int readTimeout) throws IOException {
+		URLConnection conn = new URL(url).openConnection();
+		conn.setConnectTimeout(connectTimeout);
+		conn.setReadTimeout(readTimeout);
+		return conn.getInputStream();
+	}
+
+	/**
+	 * 从url获取文件名
+	 * @param url
+	 * @return
+	 * @throws IOException
+	 */
+	public static String getFileName(String url)  {
+		return url.substring(url.lastIndexOf('/')+1);
+	}
+
+	/**
+	 * 设置response
+	 * @param request
+	 * @param response
+	 * @param fileName
+	 * @throws UnsupportedEncodingException
+	 */
+	public static void setResponse(HttpServletRequest request, HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
+		if (!StringUtils.hasText(fileName)) {
+			fileName = LocalDate.now() + UNNAMED;
+		}
+		if (!fileName.endsWith(SUFFIX_ZIP)) {
+			fileName = fileName + SUFFIX_ZIP;
+		}
+		response.setHeader("Connection", "close");
+		response.setHeader("Content-Type", "application/octet-stream;charset=UTF-8");
+		String filename = encodeFileName(request, fileName);
+		response.setHeader("Content-Disposition", "attachment;filename=" + filename);
+	}
+
+	/**
+	 * 文件名在不同浏览器兼容处理
+	 * @param request 请求信息
+	 * @param fileName 文件名
+	 * @return
+	 * @throws UnsupportedEncodingException
+	 */
+	public static String encodeFileName(HttpServletRequest request, String fileName) throws UnsupportedEncodingException {
+		String userAgent = request.getHeader("USER-AGENT");
+		// 火狐浏览器
+		if (userAgent.contains("Firefox") || userAgent.contains("firefox")) {
+			fileName = new String(fileName.getBytes(), "ISO8859-1");
+		} else {
+			// 其他浏览器
+			fileName = URLEncoder.encode(fileName, "UTF-8");
+		}
+		return fileName;
+	}
+
+}

+ 25 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/utils/ZipFileRef.java

@@ -0,0 +1,25 @@
+package org.sky.scientific.utils;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ZipFileRef {
+
+	/**
+	 * 文件名
+	 */
+	private String name;
+	/**
+	 * 本地路径
+	 */
+	private String localPath;
+	/**
+	 * http路径
+	 */
+	private String httpUrl;
+
+}

+ 17 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/utils/ZipGroup.java

@@ -0,0 +1,17 @@
+package org.sky.scientific.utils;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+ public class ZipGroup {
+
+	private String dirName;
+	private List<ZipSubDir> subDirs;
+
+}

+ 22 - 0
kd-service/kd-scientific/src/main/java/org/sky/scientific/utils/ZipSubDir.java

@@ -0,0 +1,22 @@
+package org.sky.scientific.utils;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class ZipSubDir {
+
+	/**
+	 * 子目录
+	 */
+	private String subDirName;
+
+	private List<ZipFileRef> fileRefs;
+
+
+}

BIN
kd-service/kd-scientific/src/main/resources/templates/1-项目立项-立项申请资料.doc


Разлика између датотеке није приказан због своје велике величине
+ 3 - 0
kd-service/kd-scientific/src/main/resources/templates/1-项目立项-立项申请资料.ftl


Разлика између датотеке није приказан због своје велике величине
+ 3 - 0
kd-service/kd-scientific/src/main/resources/templates/1-项目立项-立项申请资料.xml


BIN
kd-service/kd-scientific/src/main/resources/templates/3-项目实施-阶段性报告.doc


+ 1 - 1
kd-service/kd-system/src/main/java/org/sky/system/rule/tenant/TenantUserRule.java

@@ -33,7 +33,7 @@ public class TenantUserRule extends RuleComponent {
 		user.setTenantId(tenant.getTenantId());
 //		user.setName("admin");
 //		user.setRealName("admin");
-		user.setAccount("admin");
+//		user.setAccount("admin");
 		user.setName("admin");
 		user.setRealName("admin");
 		user.setAccount(tenant.getUscc());