Browse Source

Merge branch 'test2' into test

anderx 6 months ago
parent
commit
3dc9deb370
31 changed files with 2061 additions and 619 deletions
  1. 12 0
      pom.xml
  2. 26 0
      src/main/java/com/goafanti/common/controller/PublicController.java
  3. 85 0
      src/main/java/com/goafanti/common/dao/LegalHolidaysMapper.java
  4. 8 0
      src/main/java/com/goafanti/common/dao/TOrderNewMapper.java
  5. 3 0
      src/main/java/com/goafanti/common/dao/TOrderTaskMapper.java
  6. 118 0
      src/main/java/com/goafanti/common/mapper/LegalHolidaysMapper.xml
  7. 250 557
      src/main/java/com/goafanti/common/mapper/TOrderNewMapper.xml
  8. 30 0
      src/main/java/com/goafanti/common/mapper/TOrderTaskMapper.xml
  9. 54 0
      src/main/java/com/goafanti/common/model/LegalHolidays.java
  10. 14 2
      src/main/java/com/goafanti/common/model/TOrderNew.java
  11. 20 12
      src/main/java/com/goafanti/common/utils/DateUtils.java
  12. 68 0
      src/main/java/com/goafanti/common/utils/DocumentToPDFMerger.java
  13. 106 0
      src/main/java/com/goafanti/common/utils/WordToPDFMerger.java
  14. 384 4
      src/main/java/com/goafanti/common/utils/pdf/PDFUtils.java
  15. 361 0
      src/main/java/com/goafanti/customer/bo/OutSelectUserChannelArchives.java
  16. 17 2
      src/main/java/com/goafanti/customer/service/impl/UserArchivesServiceImpl.java
  17. 9 0
      src/main/java/com/goafanti/expenseAccount/bo/OutExpenseAccountDetailsList.java
  18. 69 4
      src/main/java/com/goafanti/expenseAccount/service/impl/ExpenseAccountServiceImpl.java
  19. 71 0
      src/main/java/com/goafanti/order/bo/InputOrderNewSignBo.java
  20. 128 0
      src/main/java/com/goafanti/order/bo/outStatistics/OutOrderNewSignBo.java
  21. 0 9
      src/main/java/com/goafanti/order/controller/AdminNewOrderApiController.java
  22. 1 1
      src/main/java/com/goafanti/order/controller/AdminOrderReceivablesApiController.java
  23. 18 0
      src/main/java/com/goafanti/order/controller/StatisticsApiController.java
  24. 5 1
      src/main/java/com/goafanti/order/service/OrderNewService.java
  25. 5 0
      src/main/java/com/goafanti/order/service/UserStaticticsService.java
  26. 1 0
      src/main/java/com/goafanti/order/service/impl/FundManagerOrderServiceImpl.java
  27. 1 0
      src/main/java/com/goafanti/order/service/impl/OrderChangeServiceImpl.java
  28. 80 2
      src/main/java/com/goafanti/order/service/impl/OrderNewServiceImpl.java
  29. 2 0
      src/main/java/com/goafanti/order/service/impl/OrderProjectServiceImpl.java
  30. 58 3
      src/main/java/com/goafanti/order/service/impl/UserStatisticsServiceImpl.java
  31. 57 22
      src/main/java/com/goafanti/techproject/service/impl/TaskDetailsServiceImpl.java

+ 12 - 0
pom.xml

@@ -353,6 +353,18 @@
 			<version>3.17</version>
 		</dependency>
 		<dependency>
+			<groupId>org.docx4j</groupId>
+			<artifactId>docx4j-export-fo</artifactId>
+			<version>8.3.9</version>
+		</dependency>
+		<dependency>
+			<groupId>org.docx4j</groupId>
+			<artifactId>docx4j-JAXB-Internal</artifactId>
+			<version>8.3.9</version>
+		</dependency>
+
+
+		<dependency>
 			<groupId>com.aliyun</groupId>
 			<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
 			<version>1.0.0</version>

+ 26 - 0
src/main/java/com/goafanti/common/controller/PublicController.java

@@ -15,6 +15,7 @@ import com.goafanti.common.service.PovertyService;
 import com.goafanti.common.utils.*;
 import com.goafanti.common.utils.excel.FileUtils;
 import com.goafanti.common.utils.excel.NewExcelUtil;
+import com.goafanti.common.utils.pdf.PDFUtils;
 import com.goafanti.core.mybatis.JDBCIdGenerator;
 import com.goafanti.core.shiro.token.TokenManager;
 import com.goafanti.core.websocket.SystemWebSocketHandler;
@@ -23,6 +24,7 @@ import com.goafanti.expenseAccount.service.ExpenseAccountService;
 import com.goafanti.order.service.OrderNewService;
 import com.goafanti.order.service.OrderProjectService;
 import com.goafanti.user.service.UserService;
+import com.itextpdf.text.DocumentException;
 import org.apache.commons.collections4.map.HashedMap;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.Cell;
@@ -1018,4 +1020,28 @@ public class PublicController extends CertifyApiController {
 	public Result pushUserFirstInterview(){
 		return new Result<>().data(userArchivesInterviewService.pushUserFirstInterview());
 	}
+
+	/**
+	 * 处理客户最早面谈数据
+	 * @return
+	 */
+	@RequestMapping(value = "/pushUserFirstInterview", method = RequestMethod.GET)
+	public Result pushOrderNewUser(){
+		return new Result<>().data(orderNewService.pushOrderNewUser());
+	}
+
+
+	@RequestMapping(value = "/mergeDocumentsToPdf",method = RequestMethod.GET)
+	public Result mergeDocumentsToPdf(HttpServletResponse  response) throws DocumentException, IOException {
+		// 转换Word为PDF文件
+//		PDFUtils.convertWordToPDF("E:/4.docx", "E:/4-PDF.pdf");
+		PDFUtils.newConvertWordToPDF("E:/tmp/0814.docx", "E:/tmp/0814-PDF.pdf");
+//		PDFUtils.convertXlsxToPDF("E:/tmp/0811.xlsx", "E:/tmp/0811-PDF.pdf");
+//		List<String> list = Arrays.asList(
+//				"E:/tmp/4-PDF.pdf",
+//				"E:/tmp/0811-PDF.pdf"
+//		);
+//		DocumentToPDFMerger.mergePdfFiles(list,  "E:/tmp/"+System.currentTimeMillis()+".pdf");
+		return new Result<>();
+	}
 }

+ 85 - 0
src/main/java/com/goafanti/common/dao/LegalHolidaysMapper.java

@@ -0,0 +1,85 @@
+package com.goafanti.common.dao;
+
+import com.goafanti.common.model.LegalHolidays;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 法定节假日(LegalHolidays)表数据库访问层
+ *
+ * @author makejava
+ * @since 2025-08-06 17:04:31
+ */
+public interface LegalHolidaysMapper {
+
+    /**
+     * 通过ID查询单条数据
+     *
+     * @param id 主键
+     * @return 实例对象
+     */
+    LegalHolidays selectById(Integer id);
+
+
+    /**
+     * 查询指定行数据
+     *
+     * @param legalHolidays 查询条件
+     * @param pageable      分页对象
+     * @return 对象列表
+     */
+    List<LegalHolidays> findLegalHolidaysList(LegalHolidays legalHolidays);
+
+    /**
+     * 统计总行数
+     *
+     * @param legalHolidays 查询条件
+     * @return 总行数
+     */
+    int findLegalHolidaysCount(LegalHolidays legalHolidays);
+
+    /**
+     * 新增数据
+     *
+     * @param legalHolidays 实例对象
+     * @return 影响行数
+     */
+    int insert(LegalHolidays legalHolidays);
+
+    /**
+     * 批量新增数据(MyBatis原生foreach方法)
+     *
+     * @param entities List<LegalHolidays> 实例对象列表
+     * @return 影响行数
+     */
+    int insertBatch(@Param("entities") List<LegalHolidays> entities);
+
+    /**
+     * 批量新增或按主键更新数据(MyBatis原生foreach方法)
+     *
+     * @param entities List<LegalHolidays> 实例对象列表
+     * @return 影响行数
+     * @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参
+     */
+    int insertOrUpdateBatch(@Param("entities") List<LegalHolidays> entities);
+
+    /**
+     * 修改数据
+     *
+     * @param legalHolidays 实例对象
+     * @return 影响行数
+     */
+    int update(LegalHolidays legalHolidays);
+
+    /**
+     * 通过主键删除数据
+     *
+     * @param id 主键
+     * @return 影响行数
+     */
+    int deleteById(Integer id);
+
+    List<LegalHolidays> selectAll();
+}
+

+ 8 - 0
src/main/java/com/goafanti/common/dao/TOrderNewMapper.java

@@ -177,5 +177,13 @@ public interface TOrderNewMapper {
     List<String> selectByDepAndProcess(@Param("depId") String depId, @Param("processStatus") Integer processStatus);
 
     TOrderNew selectByTid(Integer tid);
+
+    /**
+     *
+     * @param buyerId   用户编号
+     * @param signTime  签单时间
+     * @param type   0=小于签单时间,1=大于签单时间
+     */
+    List<TOrderNew> selectBuyerIdAndSignTime(@Param("buyerId") String buyerId, @Param("signTime") Date signTime, @Param("type") Integer type);
 }
 

+ 3 - 0
src/main/java/com/goafanti/common/dao/TOrderTaskMapper.java

@@ -5,6 +5,7 @@ import com.goafanti.common.bo.UserOrderTask;
 import com.goafanti.common.model.TChangeTask;
 import com.goafanti.common.model.TOrderTask;
 import com.goafanti.order.bo.*;
+import com.goafanti.order.bo.outStatistics.OutOrderNewSignBo;
 import com.goafanti.organization.bo.ProjectTypePuls;
 import org.apache.ibatis.annotations.Param;
 import org.springframework.data.domain.Pageable;
@@ -163,5 +164,7 @@ public interface TOrderTaskMapper {
 
     List<TOrderTaskBo> selectAdminTaskByTid(Integer tid);
     List<TOrderTaskBo> selectAdminTaskByAid(String aid);
+
+    List<OutOrderNewSignBo> orderNewSignToList(InputOrderNewSignBo in);
 }
 

+ 118 - 0
src/main/java/com/goafanti/common/mapper/LegalHolidaysMapper.xml

@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.goafanti.common.dao.LegalHolidaysMapper">
+
+    <resultMap type="com.goafanti.common.model.LegalHolidays" id="LegalHolidaysMap">
+        <result property="id" column="id" jdbcType="INTEGER"/>
+        <result property="holidays" column="holidays" jdbcType="TIMESTAMP"/>
+        <result property="status" column="status" jdbcType="INTEGER"/>
+    </resultMap>
+
+    <sql id="LegalHolidaysAllSql">
+        id, holidays, status
+    </sql>
+
+    <!--查询单个-->
+    <select id="selectById" resultMap="LegalHolidaysMap">
+        select
+        <include refid="LegalHolidaysAllSql"/>
+        from legal_holidays
+        where id = #{id}
+    </select>
+
+    <!--新增所有列-->
+    <insert id="insert" keyProperty="id" useGeneratedKeys="true">
+        insert into legal_holidays(holidays, status)
+        values (#{holidays}, #{status})
+    </insert>
+
+    <insert id="insertBatch">
+        insert into legal_holidays(holidays, status)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.holidays}, #{entity.status})
+        </foreach>
+    </insert>
+
+    <insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
+        insert into legal_holidays(holidays, status)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.holidays}, #{entity.status})
+        </foreach>
+        on duplicate key update
+        holidays = values(holidays),
+        status = values(status)
+    </insert>
+
+    <!--通过主键修改数据-->
+    <update id="update">
+        update legal_holidays
+        <set>
+            <if test="holidays != null">
+                holidays = #{holidays},
+            </if>
+            <if test="status != null">
+                status = #{status},
+            </if>
+        </set>
+        where id = #{id}
+    </update>
+
+    <!--查询指定行数据-->
+    <select id="findLegalHolidaysList" resultMap="LegalHolidaysMap">
+        select
+        <include refid="LegalHolidaysAllSql"/>
+
+        from legal_holidays
+        <where>
+            <if test="id != null">
+                and id = #{id}
+            </if>
+            <if test="holidays != null">
+                and holidays = #{holidays}
+            </if>
+            <if test="status != null">
+                and status = #{status}
+            </if>
+        </where>
+        <if test="page_sql != null">
+            ${page_sql}
+        </if>
+    </select>
+
+    <!--统计总行数-->
+    <select id="findLegalHolidaysCount" resultType="java.lang.Integer">
+        select count(1)
+        from legal_holidays
+        <where>
+            <if test="id != null">
+                and id = #{id}
+            </if>
+            <if test="holidays != null">
+                and holidays = #{holidays}
+            </if>
+            <if test="status != null">
+                and status = #{status}
+            </if>
+        </where>
+    </select>
+
+
+    <!--通过主键删除-->
+    <delete id="deleteById">
+        delete
+        from legal_holidays
+        where id = #{id}
+    </delete>
+
+
+
+    <select id="selectAll" resultMap="LegalHolidaysMap">
+        select
+        <include refid="LegalHolidaysAllSql"/>
+        from legal_holidays
+    </select>
+
+</mapper>
+

File diff suppressed because it is too large
+ 250 - 557
src/main/java/com/goafanti/common/mapper/TOrderNewMapper.xml


+ 30 - 0
src/main/java/com/goafanti/common/mapper/TOrderTaskMapper.xml

@@ -3087,6 +3087,12 @@
         <if test="shiro ==1">
             and c.salesman_id =#{aid}
         </if>
+          <if test="shiro ==2">
+            and c.order_dep in
+              <foreach close=")" collection="myDeps" item="dep" open="(" separator=",">
+                  #{dep}
+              </foreach>
+        </if>
         <if test="deps  !=null">
             and c.order_dep  in
             <foreach close=")" collection="deps" item="dep" open="(" separator=",">
@@ -3145,10 +3151,17 @@
         from task_stop a left join t_order_task b on a.tid=b.id
         left join t_order_new  c on b.order_no =c.order_no
         left join t_order_mid tom on c.order_no =tom.order_no
+
         where 1=1
         <if test="shiro ==1">
             and c.salesman_id =#{aid}
         </if>
+        <if test="shiro ==2">
+            and c.order_dep in
+            <foreach close=")" collection="myDeps" item="dep" open="(" separator=",">
+                #{dep}
+            </foreach>
+        </if>
         <if test="deps  !=null">
             and c.order_dep  in
             <foreach close=")" collection="deps" item="dep" open="(" separator=",">
@@ -3239,5 +3252,22 @@
         where c.sort in (3,6,9) and a.task_distribution_time>'2024-01-01' and a.split_status in (0,2)
           and a.task_receiver = #{aid}
     </select>
+    <select id="orderNewSignToList" resultType="com.goafanti.order.bo.outStatistics.OutOrderNewSignBo">
+        select a.name,department.name depName,(newCounts+counts)allCounts,(newAmount+amount) allAmount,
+               newCounts,newAmount,(newCounts/(newCounts+counts)) newCountProportion,(newAmount/(newAmount+amount))newAmountProportion,
+               counts,amount,(counts/(newCounts+counts)) countProportion,(amount/(newAmount+amount))amountProportion
+        from (SELECT b.salesman_id,
+                     sum(if(b.new_sign_user=0,1,0))newCounts ,
+                     sum(if(b.new_sign_user=0,b.total_amount,0))newAmount,
+                     sum(if(b.new_sign_user=1,1,0))counts ,
+                     sum(if(b.new_sign_user=1,b.total_amount,0))amount
+              from  t_order_new b
+              where  b.process_status >0 and b.delete_sign in (0,2)
+                and sign_time BETWEEN #{startTime} and #{endTime}
+              group by b.salesman_id
+             )x
+        left join admin a on x.salesman_id =a.id
+        left join department on a.department_id =department.id
+    </select>
 </mapper>
 

+ 54 - 0
src/main/java/com/goafanti/common/model/LegalHolidays.java

@@ -0,0 +1,54 @@
+package com.goafanti.common.model;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 法定节假日(LegalHolidays)实体类
+ *
+ * @author makejava
+ * @since 2025-08-06 17:04:31
+ */
+public class LegalHolidays implements Serializable {
+    private static final long serialVersionUID = -87380437999170496L;
+    /**
+     * 编号
+     */
+    private Integer id;
+    /**
+     * 日期时间
+     */
+    private Date holidays;
+    /**
+     * 项目状态 1=法定节假日,2=补班
+     */
+    private Integer status;
+
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public Date getHolidays() {
+        return holidays;
+    }
+
+    public void setHolidays(Date holidays) {
+        this.holidays = holidays;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+}
+

+ 14 - 2
src/main/java/com/goafanti/common/model/TOrderNew.java

@@ -9,10 +9,10 @@ import java.util.Date;
  * 订单表(TOrderNew)实体类
  *
  * @author makejava
- * @since 2024-09-27 16:04:11
+ * @since 2025-07-21 10:45:15
  */
 public class TOrderNew implements Serializable {
-    private static final long serialVersionUID = 136119537408285619L;
+    private static final long serialVersionUID = -96001184610112478L;
     /**
      * 订单编号
      */
@@ -214,6 +214,10 @@ public class TOrderNew implements Serializable {
      * 0=无,1=待评分,2=部分评分,3=全部评分
      */
     private Integer scoreStatus;
+    /**
+     * 新购客户 0=是,1=否(未签单或者三年内未签单为新)
+     */
+    private Integer newSignUser;
 
 
     public String getOrderNo() {
@@ -616,5 +620,13 @@ public class TOrderNew implements Serializable {
         this.scoreStatus = scoreStatus;
     }
 
+    public Integer getNewSignUser() {
+        return newSignUser;
+    }
+
+    public void setNewSignUser(Integer newSignUser) {
+        this.newSignUser = newSignUser;
+    }
+
 }
 

+ 20 - 12
src/main/java/com/goafanti/common/utils/DateUtils.java

@@ -9,8 +9,10 @@ import java.text.SimpleDateFormat;
 import java.time.*;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.Date;
+import java.util.List;
 
 public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
 
@@ -420,8 +422,12 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
 		return format.format(date);
 	}
 
-	public static String formatDateYYYYMMdd(Date date, String pattern) {
-		SimpleDateFormat format = new SimpleDateFormat(parsePatterns[1]);
+	public static String formatDateYYYYMMdd(Date date) {
+		SimpleDateFormat format = new SimpleDateFormat(parsePatterns[0]);
+		return format.format(date);
+	}
+	public static String formatDateChineseYYYYMMdd(Date date) {
+		SimpleDateFormat format = new SimpleDateFormat(parsePatterns[12]);
 		return format.format(date);
 	}
 
@@ -572,17 +578,19 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
 
 
 	public static void main(String[] args) {
-		Date date = StringToDate("2023-08-08 09:00:00", AFTConstants.YYYYMMDDHHMMSS);
-		Date date1 = StringToDate("2023-08-12 06:00:00", AFTConstants.YYYYMMDDHHMMSS);
-		long daysBetween = getDaysBetween(date, date1);
-		daysBetween+=1;
-		System.out.println(daysBetween);
-		for (int i = 0; i <daysBetween; i++) {
-			LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
-			LocalDate localDate1 = localDate.plusDays(i);
-			System.out.println(localDate1);
+		Date start =DateUtils.StringToDate("2025-08-05 09:00:00", AFTConstants.YYYYMMDDHHMMSS);
+		Date end =DateUtils.StringToDate("2025-08-08 06:00:00", AFTConstants.YYYYMMDDHHMMSS);
+		long holidays = DateUtils.getDaysBetween(start,end);
+		System.out.println("holidays="+holidays);
+		List<Date> list = new ArrayList<>();
+		for (int i = 0; i <= holidays; i++) {
+			LocalDate date = LocalDate.from(start.toInstant().atZone(ZoneId.systemDefault()));
+			LocalDate localDate = date.plusDays(i);
+			System.out.println(localDate);
+			System.out.println(localDate.getDayOfWeek().getValue()-1);
+			list.add(Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()));
+			//获取星期
 		}
-
 	}
 
 }

+ 68 - 0
src/main/java/com/goafanti/common/utils/DocumentToPDFMerger.java

@@ -0,0 +1,68 @@
+package com.goafanti.common.utils;
+
+import com.itextpdf.text.Document;
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.pdf.PdfCopy;
+import com.itextpdf.text.pdf.PdfReader;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * 多种文档格式合并为PDF工具类
+ * 支持Word、Excel和PDF文档的合并
+ */
+public class DocumentToPDFMerger{
+
+
+        /**
+         * 将多个PDF文件合并成一个PDF文件
+         *
+         * @param inputPdfPaths 输入的PDF文件路径列表
+         * @param outputPdfPath 输出的PDF文件路径
+         * @throws IOException
+         * @throws DocumentException
+         */
+        public static void mergePdfFiles(List<String> inputPdfPaths, String outputPdfPath)
+                throws IOException, DocumentException {
+
+            // 创建文档和输出流
+            Document document = new Document();
+            FileOutputStream outputStream = new FileOutputStream(outputPdfPath);
+            PdfCopy copy = new PdfCopy(document, outputStream);
+
+            // 打开文档
+            document.open();
+
+            // 遍历所有PDF文件并合并
+            for (String pdfPath : inputPdfPaths) {
+                PdfReader reader = new PdfReader(pdfPath);
+                // 将每个页面添加到输出文档
+                for (int i = 1; i <= reader.getNumberOfPages(); i++) {
+                    copy.addPage(copy.getImportedPage(reader, i));
+                }
+                // 关闭当前PDF文件的reader以释放资源
+                reader.close();
+            }
+
+            // 关闭文档和输出流
+            document.close();
+            outputStream.close();
+        }
+
+        /**
+         * 将多个PDF文件合并成一个PDF文件(简化版)
+         *
+         * @param inputPdfPaths 输入的PDF文件路径数组
+         * @param outputPdfPath 输出的PDF文件路径
+         * @throws IOException
+         * @throws DocumentException
+         */
+        public static void mergePdfFiles(String[] inputPdfPaths, String outputPdfPath)
+                throws IOException, DocumentException {
+            mergePdfFiles(java.util.Arrays.asList(inputPdfPaths), outputPdfPath);
+        }
+}
+
+

+ 106 - 0
src/main/java/com/goafanti/common/utils/WordToPDFMerger.java

@@ -0,0 +1,106 @@
+package com.goafanti.common.utils;
+
+import com.goafanti.common.utils.excel.FileUtils;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.DocumentException;
+import com.itextpdf.text.PageSize;
+import com.itextpdf.text.Paragraph;
+import com.itextpdf.text.pdf.PdfWriter;
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
+import org.apache.poi.xwpf.usermodel.XWPFTable;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+/**
+ * Word文档合并为PDF工具类
+ */
+public class WordToPDFMerger {
+
+    /**
+     * 将两个Word文档合并为一个PDF文件并提供下载
+     * 
+     * @param wordFile1 第一个Word文件路径
+     * @param wordFile2 第二个Word文件路径
+     * @param response  HttpServletResponse对象
+     * @param pdfFileName 生成的PDF文件名
+     * @param uploadPath 上传路径
+     */
+    public static void mergeWordDocumentsToPdf(String wordFile1, String wordFile2, 
+                                               HttpServletResponse response, String pdfFileName, String uploadPath) {
+        String realFileName = uploadPath + "/tmp/" + System.currentTimeMillis() + ".pdf";
+        
+        Document document = new Document(PageSize.A4);
+        
+        try {
+            // 设置响应头,用于文件下载
+            FileUtils.setAttachmentResponseHeader(response, pdfFileName, pdfFileName + ".pdf");
+            
+            // 创建PDF写入器
+            FileOutputStream outputStream = new FileOutputStream(realFileName);
+            PdfWriter.getInstance(document, outputStream);
+            
+            document.open();
+            
+            // 处理第一个Word文档
+            processWordDocument(wordFile1, document);
+            
+            // 添加分页
+            document.newPage();
+            
+            // 处理第二个Word文档
+            processWordDocument(wordFile2, document);
+            
+            document.close();
+            outputStream.close();
+            
+            // 提供文件下载
+            FileUtils.writeBytes(realFileName, response.getOutputStream());
+            FileUtils.deleteFile(realFileName);
+            
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    
+    /**
+     * 处理单个Word文档并将其内容添加到PDF文档中
+     * 
+     * @param wordFilePath Word文件路径
+     * @param document PDF文档对象
+     * @throws IOException
+     * @throws DocumentException
+     */
+    private static void processWordDocument(String wordFilePath, Document document) 
+            throws IOException, DocumentException {
+        
+        try (InputStream in = new FileInputStream(wordFilePath)) {
+            XWPFDocument xwpfDocument = new XWPFDocument(in);
+            
+            // 获取文档中的所有段落
+            List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();
+            
+            for (XWPFParagraph paragraph : paragraphs) {
+                // 创建PDF段落
+                String text = paragraph.getText();
+                if (text != null && !text.isEmpty()) {
+                    document.add(new Paragraph(text));
+                }
+            }
+            
+            // 处理表格(如果有)
+            List<XWPFTable> tables = xwpfDocument.getTables();
+            for (XWPFTable table : tables) {
+                // 添加表格标识(实际项目中可以进一步处理表格内容)
+                document.add(new Paragraph("[表格内容]"));
+            }
+        }
+    }
+
+
+}

+ 384 - 4
src/main/java/com/goafanti/common/utils/pdf/PDFUtils.java

@@ -5,20 +5,394 @@ import com.goafanti.common.constant.AFTConstants;
 import com.goafanti.common.utils.DateUtils;
 import com.goafanti.common.utils.excel.FileUtils;
 import com.goafanti.expenseAccount.bo.MainExpenseAccount;
+import com.itextpdf.text.Document;
+import com.itextpdf.text.Font;
 import com.itextpdf.text.*;
 import com.itextpdf.text.pdf.BaseFont;
+import com.itextpdf.text.pdf.PdfPCell;
+import com.itextpdf.text.pdf.PdfPTable;
 import com.itextpdf.text.pdf.PdfWriter;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.apache.poi.xwpf.usermodel.*;
+import org.docx4j.Docx4J;
+import org.docx4j.openpackaging.exceptions.Docx4JException;
+import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
 import org.springframework.http.MediaType;
 
 import javax.servlet.http.HttpServletResponse;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
+import java.io.*;
 import java.util.Date;
 
 public class PDFUtils {
 
 
+    /**
+     * 删除临时目录及其内容
+     *
+     * @param dir 临时目录
+     */
+    private static void deleteTempDirectory(File dir) {
+        if (dir.exists() && dir.isDirectory()) {
+            File[] files = dir.listFiles();
+            if (files != null) {
+                for (File file : files) {
+                    if (file.isDirectory()) {
+                        deleteTempDirectory(file);
+                    } else {
+                        file.delete();
+                    }
+                }
+            }
+            dir.delete();
+        }
+    }
+
+
+
+
+
+    /**
+     * 将Word文档转换为PDF文件
+     *
+     * @param wordFilePath Word文件路径
+     * @param pdfFilePath 生成的PDF文件路径
+     * @throws IOException
+     * @throws DocumentException
+     */
+    public static void convertWordToPDF(String wordFilePath, String pdfFilePath)
+            throws IOException, DocumentException {
+
+        Document document = new Document(PageSize.A4);
+
+        try (InputStream in = new FileInputStream(wordFilePath)) {
+            // 创建PDF写入器
+            FileOutputStream outputStream = new FileOutputStream(pdfFilePath);
+            PdfWriter.getInstance(document, outputStream);
+
+            document.open();
+
+            // 处理Word文档内容
+            processWordDocument(wordFilePath, document);
+
+            document.close();
+            outputStream.close();
+        }
+    }
+
+    /**
+     * 将XLSX文件转换为PDF文件
+     *
+     * @param xlsxFilePath XLSX文件路径
+     * @param pdfFilePath  生成的PDF文件路径
+     * @throws IOException
+     * @throws DocumentException
+     */
+    public static void convertXlsxToPDF(String xlsxFilePath, String pdfFilePath)
+            throws IOException, DocumentException {
+
+        Document document = new Document(PageSize.A4.rotate()); // 使用横向页面以适应更多列
+
+        try (InputStream in = new FileInputStream(xlsxFilePath)) {
+            Workbook workbook = new XSSFWorkbook(in);
+
+            // 创建PDF写入器
+            FileOutputStream outputStream = new FileOutputStream(pdfFilePath);
+            PdfWriter.getInstance(document, outputStream);
+
+            document.open();
+
+            // 处理Excel工作簿内容
+            processExcelWorkbook(workbook, document);
+
+            document.close();
+            outputStream.close();
+            workbook.close();
+        }
+    }
+
+    /**
+     * 将Word文档转换为PDF并提供下载
+     *
+     * @param wordFilePath Word文件路径
+     * @param response HttpServletResponse对象
+     * @param pdfFileName 生成的PDF文件名
+     * @param uploadPath 上传路径
+     * @throws IOException
+     * @throws DocumentException
+     */
+    public static void convertWordToPDFForDownload(String wordFilePath,
+                                                   HttpServletResponse response,
+                                                   String pdfFileName,
+                                                   String uploadPath)
+            throws IOException, DocumentException {
+
+        String realFileName = uploadPath + "/tmp/" + System.currentTimeMillis() + ".pdf";
+        Document document = new Document(PageSize.A4);
+
+        try (InputStream in = new FileInputStream(wordFilePath)) {
+            // 设置响应头,用于文件下载
+            FileUtils.setAttachmentResponseHeader(response, pdfFileName, pdfFileName + ".pdf");
+
+            // 创建PDF写入器
+            FileOutputStream outputStream = new FileOutputStream(realFileName);
+            PdfWriter.getInstance(document, outputStream);
+
+            document.open();
+
+            // 处理Word文档内容
+            processWordDocument(wordFilePath, document);
+
+            document.close();
+            outputStream.close();
+
+            // 提供文件下载
+            FileUtils.writeBytes(realFileName, response.getOutputStream());
+            FileUtils.deleteFile(realFileName);
+        }
+    }
+
+    /**
+     * 处理Word文档并将其内容添加到PDF文档中
+     *
+     * @param wordFilePath Word文件路径
+     * @param document PDF文档对象
+     * @throws IOException
+     * @throws DocumentException
+     */
+    private static void processWordDocument(String wordFilePath, Document document)
+            throws IOException, DocumentException {
+
+        try (InputStream in = new FileInputStream(wordFilePath)) {
+            XWPFDocument xwpfDocument = new XWPFDocument(in);
+            // 获取文档中的所有段落
+            java.util.List<XWPFParagraph> paragraphs = xwpfDocument.getParagraphs();
+            for (XWPFParagraph paragraph : paragraphs) {
+                // 创建PDF段落
+                Paragraph pdfParagraph = new Paragraph();
+                paragraph.getRuns().forEach(run -> {
+                    System.out.println(run.getPictureText());
+                    System.out.println(run.getFontSize());
+                });
+                // 设置段落对齐方式
+                switch (paragraph.getAlignment()) {
+                    case CENTER:
+                        pdfParagraph.setAlignment(Element.ALIGN_CENTER);
+                        break;
+                    case RIGHT:
+                        pdfParagraph.setAlignment(Element.ALIGN_RIGHT);
+                        break;
+                    case LEFT:
+                    case BOTH:
+                    default:
+                        pdfParagraph.setAlignment(Element.ALIGN_LEFT);
+                        break;
+                }
+                // 处理段落中的所有文本块(XWPFRun)
+                for (XWPFRun run : paragraph.getRuns()) {
+                    String text = run.getText(0);
+                    if (text != null) {
+                        // 创建带样式的PDF字体
+                        Font pdfFont = createPDFFontFromRun(run);
+                        Chunk chunk = new Chunk(text, pdfFont);
+                        pdfParagraph.add(chunk);
+                    }
+                }
+
+                // 只有当段落有内容时才添加到文档中
+                if (pdfParagraph.size() > 0 && !pdfParagraph.getContent().toString().trim().isEmpty()) {
+                    document.add(pdfParagraph);
+                }
+            }
+
+            // 处理表格(如果有)
+            java.util.List<XWPFTable> tables = xwpfDocument.getTables();
+            for (XWPFTable table : tables) {
+                // 处理表格中的每一行
+                java.util.List<XWPFTableRow> rows = table.getRows();
+                for (XWPFTableRow row : rows) {
+                    StringBuilder rowText = new StringBuilder();
+                    java.util.List<XWPFTableCell> cells = row.getTableCells();
+                    for (XWPFTableCell cell : cells) {
+                        String cellText = cell.getText();
+                        rowText.append(cellText).append(" | ");
+                    }
+                    if (rowText.length() > 0) {
+                        document.add(new Paragraph(rowText.toString()));
+                    }
+                }
+            }
+        }
+    }
+
+
+    /**
+     * 处理Excel工作簿并将其内容添加到PDF文档中
+     *
+     * @param workbook Excel工作簿对象
+     * @param document PDF文档对象
+     * @throws DocumentException
+     */
+    private static void processExcelWorkbook(Workbook workbook, Document document)
+            throws DocumentException {
+
+        // 添加文档标题(文件名)
+        document.add(Chunk.NEWLINE);
+
+        // 处理每个工作表
+        for (int i = 0; i < workbook.getNumberOfSheets(); i++) {
+            Sheet sheet = workbook.getSheetAt(i);
+
+            // 添加工作表名称
+//            Paragraph sheetTitle = new Paragraph("工作表: " + sheet.getSheetName(), PDFUtils.getBigFont());
+//            document.add(sheetTitle);
+//            document.add(Chunk.NEWLINE);
+
+            // 计算需要的列数
+            int columnCount = 0;
+            for (Row row : sheet) {
+                int lastCellNum = row.getLastCellNum();
+                if (lastCellNum > columnCount) {
+                    columnCount = lastCellNum;
+                }
+            }
+
+            if (columnCount > 0) {
+                // 创建表格
+                PdfPTable table = new PdfPTable(columnCount);
+                table.setWidthPercentage(100);
+                float[] columnWidths = new float[columnCount];
+                for (int j = 0; j < columnCount; j++) {
+                    if (j==1||j==0){
+                        columnWidths[j] = 30f;
+                    }else {
+                        columnWidths[j] = 10f;
+                    }
+                }
+                table.setWidths(columnWidths);
+                // 处理行数据
+                int rowCount = 0;
+                for (Row row : sheet) {
+                    // 处理每行的单元格
+                    for (int colIndex = 0; colIndex < columnCount; colIndex++) {
+                        Cell cell = row.getCell(colIndex);
+                        String cellValue = getCellValue(cell);
+                        Font font = PDFUtils.getFont(10);
+                        PdfPCell pdfCell = new PdfPCell(new Phrase(cellValue, font));
+                        pdfCell.setPadding(1);
+
+                        // 设置表头样式
+                        if (rowCount == 0) {
+                            pdfCell.setBackgroundColor(BaseColor.LIGHT_GRAY);
+                            pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER);
+                            //第一行合并
+                            pdfCell.setColspan(columnCount);
+                        }
+
+                        table.addCell(pdfCell);
+                    }
+                    rowCount++;
+
+                    // 限制处理的行数,避免内容过多
+//                    if (rowCount > 100) {
+//                        PdfPCell pdfCell = new PdfPCell(new Phrase("... (内容过多,省略剩余部分)", PDFUtils.getFont()));
+//                        pdfCell.setColspan(columnCount);
+//                        pdfCell.setHorizontalAlignment(Element.ALIGN_CENTER);
+//                        table.addCell(pdfCell);
+//                        break;
+//                    }
+                }
+
+                document.add(table);
+            }
+
+            document.add(Chunk.NEWLINE);
+        }
+    }
+
+
+    /**
+     * 获取单元格的值
+     *
+     * @param cell Excel单元格
+     * @return 单元格内容字符串
+     */
+    private static String getCellValue(Cell cell) {
+        if (cell == null) {
+            return "";
+        }
+
+        switch (cell.getCellType()) {
+            case Cell.CELL_TYPE_STRING:
+                return cell.getStringCellValue();
+            case Cell.CELL_TYPE_NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    return cell.getDateCellValue().toString();
+                } else {
+                    // 避免科学计数法显示数字
+                    return String.valueOf(cell.getNumericCellValue());
+                }
+            case Cell.CELL_TYPE_BOOLEAN:
+                return String.valueOf(cell.getBooleanCellValue());
+            case Cell.CELL_TYPE_FORMULA:
+                return cell.getCellFormula();
+            default:
+                return "";
+        }
+    }
+
+
+
+    /**
+     * 根据Word文档中的Run样式创建PDF字体
+     *
+     * @param run Word文档中的文本块
+     * @return PDF字体
+     */
+    private static Font createPDFFontFromRun(XWPFRun run) {
+        // 获取字体大小,默认为12
+        int fontSize = 12;
+        if (run.getFontSize() != -1) {
+            fontSize = run.getFontSize();
+        }
+
+        // 设置字体样式
+        int fontStyle = Font.NORMAL;
+        if (run.isBold() && run.isItalic()) {
+            fontStyle = Font.BOLDITALIC;
+        } else if (run.isBold()) {
+            fontStyle = Font.BOLD;
+        } else if (run.isItalic()) {
+            fontStyle = Font.ITALIC;
+        }
+
+        // 创建字体
+        Font font = PDFUtils.getFont(fontSize);
+        font.setStyle(fontStyle);
+
+        // 处理字体颜色
+        if (run.getColor() != null) {
+            // 注意:Word中的颜色格式与PDF中的颜色格式可能不同
+            // 这里简化处理,实际应用中可能需要转换颜色格式
+        }
+
+        return font;
+    }
+
+    public static void newConvertWordToPDF(String s, String s1) {
+        try (FileOutputStream fos = new FileOutputStream(s1)) {
+            WordprocessingMLPackage wordMLPackage = Docx4J.load(new File(s));
+            Docx4J.toPDF(wordMLPackage, fos);
+        } catch (Docx4JException e) {
+            throw new RuntimeException("转换Word文档到PDF失败: " + s, e);
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException("找不到文件: " + s + " 或 " + s1, e);
+        } catch (IOException e) {
+            throw new RuntimeException("写入PDF文件时发生IO错误: " + s1, e);
+        }
+    }
+
+
     public  void pushRd(OutWordRdDetails data, HttpServletResponse response,String uploadPath) {
         String attName = data.getRdName()+new Date().getTime() + ".pdf";
         String realFileName = uploadPath+"/tmp/"+new Date().getTime() + ".pdf";
@@ -68,6 +442,13 @@ public class PDFUtils {
         document.add(Chunk.NEWLINE);
     }
 
+    private static  void addPDFDocument(Document document,  String value) throws DocumentException {
+        Phrase phrase = new Phrase(value, getFont());
+        phrase.setLeading(40);
+        if(value!=null)document.add(phrase);
+        document.add(Chunk.NEWLINE);
+    }
+
     private void addPDFContent(Document document,  String value) throws DocumentException {
         Phrase phrase = new Phrase(value, getFont());
         phrase.setLeading(25);
@@ -162,5 +543,4 @@ public class PDFUtils {
         Paragraph tile2=new Paragraph(builder.toString(),getFont(8));
         document.add(tile2);
     }
-
 }

+ 361 - 0
src/main/java/com/goafanti/customer/bo/OutSelectUserChannelArchives.java

@@ -0,0 +1,361 @@
+package com.goafanti.customer.bo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.goafanti.common.utils.excel.Excel;
+
+import java.util.Date;
+
+public class OutSelectUserChannelArchives {
+    private String id;
+    @Excel(name = "客户名称")
+    private String nickname;
+    @Excel(name = "客户类型",readConverterExp = "0=私有渠道,1=公共渠道,2=签单渠道,3=外联渠道",width = 8)
+    private Integer shareType;
+    private Integer signBills;
+    private String businessScope;
+    @Excel(name = "渠道类型",readConverterExp = "1=其他,2=民主党派,3=园区,4=民间组织,5=战略合作单位",width = 8)
+    private Integer channelType;
+    @Excel(name = "企业数",width = 8)
+    private Integer enterpriseCount;
+
+    private String industry;
+    @Excel(name = "联系人")
+    private String contactName;
+    private String contactMobile;
+    @Excel(name = "所属人")
+    private String adminName;
+    @Excel(name = "面谈项目")
+    private String intendedProject;
+    @Excel(name = "考核指标")
+    private String channelIndicators;
+    @Excel(name = "面谈思路及目的")
+    private String interviewIdeas;
+    @Excel(name = "面谈人及分工")
+    private String interviewDistribution;
+    private Integer  patentCount;
+    private Integer inventionPatentCount;
+    private Integer utilityModelCount;
+    private Integer appearancePatentCount;
+    private Integer softwareWorksCount;
+    private Integer otherCount;
+    private Integer standard;
+
+    private String financialData;
+
+    private String earlyCommunication;
+
+    /**
+     * 母/子公司数
+     */
+    private Integer companyCount;
+    /**
+     * 社保人数
+     */
+    private Integer socialSecurityCount;
+    /**
+     * 对外投资控股的企业数
+     */
+    private Integer externalInvestCount;
+    /**
+     * 对外投资控股的行业
+     */
+
+    private String externalInvestIndustryName;
+    /**
+     * 对外投资控股的企业名称
+     */
+    /**
+     * 对外投资控股的企业编号
+     */
+//    @Excel(name = "对外投资控股的企业编号")
+//    private String externalInvestId;
+    /**
+     * 对外投资控股的行业名称
+     */
+
+    @Excel(name = "所属部门")
+    private String depName;
+    @Excel(name = "修改时间",dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date updateTime;
+    @Excel(name = "省",width = 8)
+    private String province;
+    @Excel(name = "市",width = 8)
+    private String city;
+    @Excel(name = "区",width = 8)
+    private String area;
+    @Excel(name = "公出面谈信息")
+    private String publicContent;
+
+    public Integer getStandard() {
+        return standard;
+    }
+
+    public void setStandard(Integer standard) {
+        this.standard = standard;
+    }
+
+    public Integer getCompanyCount() {
+        return companyCount;
+    }
+
+    public void setCompanyCount(Integer companyCount) {
+        this.companyCount = companyCount;
+    }
+
+    public Integer getSocialSecurityCount() {
+        return socialSecurityCount;
+    }
+
+    public void setSocialSecurityCount(Integer socialSecurityCount) {
+        this.socialSecurityCount = socialSecurityCount;
+    }
+
+    public Integer getExternalInvestCount() {
+        return externalInvestCount;
+    }
+
+    public void setExternalInvestCount(Integer externalInvestCount) {
+        this.externalInvestCount = externalInvestCount;
+    }
+
+    public String getExternalInvestIndustryName() {
+        return externalInvestIndustryName;
+    }
+
+    public void setExternalInvestIndustryName(String externalInvestIndustryName) {
+        this.externalInvestIndustryName = externalInvestIndustryName;
+    }
+
+
+    public String getContactMobile() {
+        return contactMobile;
+    }
+
+    public void setContactMobile(String contactMobile) {
+        this.contactMobile = contactMobile;
+    }
+
+    public String getPublicContent() {
+        return publicContent;
+    }
+
+    public void setPublicContent(String publicContent) {
+        this.publicContent = publicContent;
+    }
+
+    public Integer getSignBills() {
+        return signBills;
+    }
+
+    public void setSignBills(Integer signBills) {
+        this.signBills = signBills;
+    }
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getNickname() {
+        return nickname;
+    }
+
+    public void setNickname(String nickname) {
+        this.nickname = nickname;
+    }
+
+    public String getProvince() {
+        return province;
+    }
+
+    public void setProvince(String province) {
+        this.province = province;
+    }
+
+    public String getCity() {
+        return city;
+    }
+
+    public void setCity(String city) {
+        this.city = city;
+    }
+
+    public String getArea() {
+        return area;
+    }
+
+    public void setArea(String area) {
+        this.area = area;
+    }
+
+    public Integer getShareType() {
+        return shareType;
+    }
+
+    public void setShareType(Integer shareType) {
+        this.shareType = shareType;
+    }
+
+    public Integer getChannelType() {
+        return channelType;
+    }
+
+    public void setChannelType(Integer channelType) {
+        this.channelType = channelType;
+    }
+
+    public Integer getEnterpriseCount() {
+        return enterpriseCount;
+    }
+
+    public void setEnterpriseCount(Integer enterpriseCount) {
+        this.enterpriseCount = enterpriseCount;
+    }
+
+    public String getContactName() {
+        return contactName;
+    }
+
+    public void setContactName(String contactName) {
+        this.contactName = contactName;
+    }
+
+    public String getAdminName() {
+        return adminName;
+    }
+
+    public void setAdminName(String adminName) {
+        this.adminName = adminName;
+    }
+
+    public String getChannelIndicators() {
+        return channelIndicators;
+    }
+
+    public void setChannelIndicators(String channelIndicators) {
+        this.channelIndicators = channelIndicators;
+    }
+
+    public String getInterviewIdeas() {
+        return interviewIdeas;
+    }
+
+    public void setInterviewIdeas(String interviewIdeas) {
+        this.interviewIdeas = interviewIdeas;
+    }
+
+    public String getIntendedProject() {
+        return intendedProject;
+    }
+
+    public void setIntendedProject(String intendedProject) {
+        this.intendedProject = intendedProject;
+    }
+
+    public String getInterviewDistribution() {
+        return interviewDistribution;
+    }
+
+    public void setInterviewDistribution(String interviewDistribution) {
+        this.interviewDistribution = interviewDistribution;
+    }
+
+    public String getDepName() {
+        return depName;
+    }
+
+    public void setDepName(String depName) {
+        this.depName = depName;
+    }
+
+    public String getIndustry() {
+        return industry;
+    }
+
+    public void setIndustry(String industry) {
+        this.industry = industry;
+    }
+
+    public String getBusinessScope() {
+        return businessScope;
+    }
+
+    public void setBusinessScope(String businessScope) {
+        this.businessScope = businessScope;
+    }
+
+    public String getFinancialData() {
+        return financialData;
+    }
+
+    public void setFinancialData(String financialData) {
+        this.financialData = financialData;
+    }
+
+    public String getEarlyCommunication() {
+        return earlyCommunication;
+    }
+
+    public void setEarlyCommunication(String earlyCommunication) {
+        this.earlyCommunication = earlyCommunication;
+    }
+
+    public Integer getPatentCount() {
+        return patentCount;
+    }
+
+    public void setPatentCount(Integer patentCount) {
+        this.patentCount = patentCount;
+    }
+
+    public Integer getInventionPatentCount() {
+        return inventionPatentCount;
+    }
+
+    public void setInventionPatentCount(Integer inventionPatentCount) {
+        this.inventionPatentCount = inventionPatentCount;
+    }
+
+    public Integer getUtilityModelCount() {
+        return utilityModelCount;
+    }
+
+    public void setUtilityModelCount(Integer utilityModelCount) {
+        this.utilityModelCount = utilityModelCount;
+    }
+
+    public Integer getAppearancePatentCount() {
+        return appearancePatentCount;
+    }
+
+    public void setAppearancePatentCount(Integer appearancePatentCount) {
+        this.appearancePatentCount = appearancePatentCount;
+    }
+
+    public Integer getSoftwareWorksCount() {
+        return softwareWorksCount;
+    }
+
+    public void setSoftwareWorksCount(Integer softwareWorksCount) {
+        this.softwareWorksCount = softwareWorksCount;
+    }
+
+    public Integer getOtherCount() {
+        return otherCount;
+    }
+
+    public void setOtherCount(Integer otherCount) {
+        this.otherCount = otherCount;
+    }
+}

+ 17 - 2
src/main/java/com/goafanti/customer/service/impl/UserArchivesServiceImpl.java

@@ -11,6 +11,7 @@ import com.goafanti.core.mybatis.page.Pagination;
 import com.goafanti.core.shiro.token.TokenManager;
 import com.goafanti.customer.bo.InputSelectUserArchives;
 import com.goafanti.customer.bo.OutSelectUserArchives;
+import com.goafanti.customer.bo.OutSelectUserChannelArchives;
 import com.goafanti.customer.bo.UserArchivesDetails;
 import com.goafanti.customer.service.CustomerService;
 import com.goafanti.customer.service.UserArchivesService;
@@ -395,8 +396,22 @@ public class UserArchivesServiceImpl extends BaseMybatisDao< UserArchivesMapper>
             List<selectByUidAidBo> userArchivesInterviews = userArchivesInterviewMapper.selectByUidAid(e.getId(), null);
             e.setPublicContent(pushContent(userArchivesInterviews));
         });
-        NewExcelUtil<OutSelectUserArchives> newExcelUtil = new NewExcelUtil<>(OutSelectUserArchives.class);
-        return newExcelUtil.exportExcel( list,"用户档案",uploadPath);
+        String sheetName = "用户档案";
+        if (in.getNewChannel()==1){
+            sheetName="渠道档案";
+            NewExcelUtil<OutSelectUserChannelArchives> newExcelUtil = new NewExcelUtil<>(OutSelectUserChannelArchives.class);
+            List<OutSelectUserChannelArchives> newList = new ArrayList<>();
+            //将类型转换
+            list.stream().forEach(e ->{
+                OutSelectUserChannelArchives outSelectUserChannelArchives = new OutSelectUserChannelArchives();
+                BeanUtils.copyProperties(e,outSelectUserChannelArchives);
+                newList.add(outSelectUserChannelArchives);
+            });
+            return newExcelUtil.exportExcel( newList,sheetName,uploadPath);
+        }else {
+            NewExcelUtil<OutSelectUserArchives> newExcelUtil = new NewExcelUtil<>(OutSelectUserArchives.class);
+            return newExcelUtil.exportExcel( list,sheetName,uploadPath);
+        }
     }
 
 

+ 9 - 0
src/main/java/com/goafanti/expenseAccount/bo/OutExpenseAccountDetailsList.java

@@ -22,6 +22,9 @@ public class OutExpenseAccountDetailsList {
     private Double duration ;
     @Excel(name = "天数",width = 5)
     private Integer days;
+    @Excel(name = "节假日",width = 5)
+    private Integer statutoryDays;
+
     private Integer sonId;
     private Integer sonType;
     private String  sonTypeOther;
@@ -94,7 +97,13 @@ public class OutExpenseAccountDetailsList {
     private Date releaseStart;
     private Date releaseEnd;
 
+    public Integer getStatutoryDays() {
+        return statutoryDays;
+    }
 
+    public void setStatutoryDays(Integer statutoryDays) {
+        this.statutoryDays = statutoryDays;
+    }
 
     public String getReleaseTimeStr() {
         return releaseTimeStr;

+ 69 - 4
src/main/java/com/goafanti/expenseAccount/service/impl/ExpenseAccountServiceImpl.java

@@ -53,6 +53,8 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -100,6 +102,8 @@ public class ExpenseAccountServiceImpl extends BaseMybatisDao<ExpenseAccountMapp
     private TOrderMidMapper tOrderMidMapper;
     @Resource
     private AdminPublicReviewerMapper adminPublicReviewerMapper;
+    @Resource
+    private LegalHolidaysMapper legalHolidaysMapper;
 
 
 
@@ -258,9 +262,25 @@ public class ExpenseAccountServiceImpl extends BaseMybatisDao<ExpenseAccountMapp
             addExpenseAccountLog(in.getId(),1,in.getProcessStatus(),aid,str2,date,2);
             in.setProcessStatus(in.getProcessStatus()+1);
         }else {
-            if (admin.getSuperiorId()==null||admin.getId().equals(admin.getSuperiorId())){
+            List<AdminPublicReviewerBo> adminPublicReviewerBos = adminPublicReviewerMapper.selectByAid(aid);
+            //获取上级
+            List<AdminPublicReviewerBo> superList=adminPublicReviewerBos.stream().filter(e -> e.getType() == 2).collect(Collectors.toList());
+            //无上级
+            boolean success = false;
+            if (superList.isEmpty())success=true;
+            //我也是我的上级
+            boolean success2 = false;
+            if (!superList.isEmpty()){
+                for (AdminPublicReviewerBo e : superList) {
+                    if (e.getReviewerId().equals(admin.getId())){
+                        success2=true;
+                        break;
+                    }
+                }
+            }
+            if (success||success2){
 
-                String str2=String.format("%s跳过[%s]。",admin.getSuperiorId()==null?"发起人无上级":"发起人与上级同人",EAProcessStatus.getDesc(in.getProcessStatus()));
+                String str2=String.format("%s跳过[%s]。",success?"发起人无上级":"发起人与上级同人",EAProcessStatus.getDesc(in.getProcessStatus()));
                 Date date=new Date();
                 date.setTime(date.getTime()+1000L);
                 addExpenseAccountLog(in.getId(),1,in.getProcessStatus(),aid,str2,date,2);
@@ -402,6 +422,10 @@ public class ExpenseAccountServiceImpl extends BaseMybatisDao<ExpenseAccountMapp
     public Object detailsListExport(InputDetailsListBo in) {
         List<OutExpenseAccountDetailsList> list = (List<OutExpenseAccountDetailsList>) detailsList(in).getList();
         for (OutExpenseAccountDetailsList e : list) {
+            //新增计算法定
+            Integer statutoryDays = pushDtailsDays(e);
+            e.setStatutoryDays(statutoryDays);
+
             if (e.getTargetType()!=null){
                 if (e.getTargetType()==0){
                     e.setTargetName("固定费用");
@@ -432,6 +456,49 @@ public class ExpenseAccountServiceImpl extends BaseMybatisDao<ExpenseAccountMapp
         return excelUtil.exportExcel(list,"费用详细列表",uploadPath);
     }
 
+    private Integer pushDtailsDays(OutExpenseAccountDetailsList e) {
+        Integer statutoryDays = 0;
+        //获取俩个日期之间的所有日期
+        long days = DateUtils.getDaysBetween(e.getReleaseStart(),e.getReleaseEnd());
+            List<LegalHolidays> legalHolidays = legalHolidaysMapper.selectAll();
+            //法定节假日
+            Set<String> holidaysSet = legalHolidays.stream()
+                    .filter(et -> et.getStatus() == 1)
+                    .map(holiday -> DateUtils.formatDateYYYYMMdd(holiday.getHolidays()))
+                    .collect(Collectors.toSet());
+            //需要补班
+            Set<String> workDaysSet = legalHolidays.stream()
+                    .filter(et -> et.getStatus() == 2)
+                    .map(holiday -> DateUtils.formatDateYYYYMMdd(holiday.getHolidays()))
+                    .collect(Collectors.toSet());
+
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+            LocalDate startDate = LocalDate.from(e.getReleaseStart().toInstant().atZone(ZoneId.systemDefault()));
+
+            for (int i = 0; i <= days; i++) {
+                LocalDate currentDate = startDate.plusDays(i);
+                int dayOfWeek = currentDate.getDayOfWeek().getValue();
+                String dateString = currentDate.format(formatter);
+
+                // 周六(6)和周日(7)默认为节假日
+                if (dayOfWeek > 5) {
+                    // 如果是补班日,则不是节假日
+                    if (!workDaysSet.contains(dateString)) {
+                        statutoryDays++;
+                    }
+                } else {
+                    // 工作日如果是法定节假日,则是节假日
+                    if (holidaysSet.contains(dateString)) {
+                        statutoryDays++;
+                    }
+                }
+            }
+
+        return statutoryDays;
+    }
+
+
+
     @Override
     public Object getDepDetails(Integer id) {
         OutExpenseAccount outExpenseAccount = expenseAccountMapper.selectByid(id);
@@ -1536,9 +1603,7 @@ public class ExpenseAccountServiceImpl extends BaseMybatisDao<ExpenseAccountMapp
                             useOyd = yearMaxDurationList.get(i);
                         }
                     }
-
                 }
-
                 //获取未归集的订单
                 List<BigDecimal> orderNoNotCountAmount = expenseAccountMapper.getOrderNoNotCountAmount(e.getOrderNo());
                 BigDecimal countAmount = orderNoNotCountAmount.stream().reduce(BigDecimal.ZERO, BigDecimal::add);

+ 71 - 0
src/main/java/com/goafanti/order/bo/InputOrderNewSignBo.java

@@ -0,0 +1,71 @@
+package com.goafanti.order.bo;
+
+import java.util.Date;
+
+public class InputOrderNewSignBo {
+
+    private Integer type;
+    private Date startTime;
+    private Date endTime;
+    private String startTimeStr;
+    private String endTimeStr;
+
+    private Integer pageSize;
+    private Integer pageNo;
+
+    public String getStartTimeStr() {
+        return startTimeStr;
+    }
+
+    public void setStartTimeStr(String startTimeStr) {
+        this.startTimeStr = startTimeStr;
+    }
+
+    public String getEndTimeStr() {
+        return endTimeStr;
+    }
+
+    public void setEndTimeStr(String endTimeStr) {
+        this.endTimeStr = endTimeStr;
+    }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+
+    public Integer getPageSize() {
+        return pageSize;
+    }
+
+    public void setPageSize(Integer pageSize) {
+        this.pageSize = pageSize;
+    }
+
+    public Integer getPageNo() {
+        return pageNo;
+    }
+
+    public void setPageNo(Integer pageNo) {
+        this.pageNo = pageNo;
+    }
+
+    public Integer getType() {
+        return type;
+    }
+
+    public void setType(Integer type) {
+        this.type = type;
+    }
+}

+ 128 - 0
src/main/java/com/goafanti/order/bo/outStatistics/OutOrderNewSignBo.java

@@ -0,0 +1,128 @@
+package com.goafanti.order.bo.outStatistics;
+
+import com.goafanti.common.utils.excel.Excel;
+
+import java.math.BigDecimal;
+
+public class OutOrderNewSignBo {
+    @Excel(name = "签单人")
+    private String name;
+    @Excel(name = "部门")
+    private String depName;
+    @Excel(name = "总签单数",isStatistics = true)
+    private String allCounts;
+    @Excel(name = "总签单金额",isStatistics = true)
+    private BigDecimal allAmount;
+    @Excel(name = "新客户签单数",isStatistics = true)
+    private String newCounts;
+    @Excel(name = "新客户签单金额",isStatistics = true)
+    private BigDecimal newAmount;
+    @Excel(name = "新客户签单数占比", percentage = 1,scale = 2)
+    private String newCountProportion;
+    @Excel(name = "新客户签单金额占比", percentage = 1,scale = 2)
+    private String newAmountProportion;
+    @Excel(name = "旧客户签单数",isStatistics = true)
+    private String counts;
+    @Excel(name = "旧客户签单金额",isStatistics = true)
+    private BigDecimal amount;
+    @Excel(name = "旧客户签单数占比",percentage = 1,scale = 2)
+    private String countProportion;
+    @Excel(name = "旧客户签单金额占比", percentage = 1,scale = 2)
+    private String amountProportion;
+
+    public String getAllCounts() {
+        return allCounts;
+    }
+
+    public void setAllCounts(String allCounts) {
+        this.allCounts = allCounts;
+    }
+
+    public BigDecimal getAllAmount() {
+        return allAmount;
+    }
+
+    public void setAllAmount(BigDecimal allAmount) {
+        this.allAmount = allAmount;
+    }
+
+    public String getDepName() {
+        return depName;
+    }
+
+    public void setDepName(String depName) {
+        this.depName = depName;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getNewCounts() {
+        return newCounts;
+    }
+
+    public void setNewCounts(String newCounts) {
+        this.newCounts = newCounts;
+    }
+
+    public BigDecimal getNewAmount() {
+        return newAmount;
+    }
+
+    public void setNewAmount(BigDecimal newAmount) {
+        this.newAmount = newAmount;
+    }
+
+    public String getNewCountProportion() {
+        return newCountProportion;
+    }
+
+    public void setNewCountProportion(String newCountProportion) {
+        this.newCountProportion = newCountProportion;
+    }
+
+    public String getNewAmountProportion() {
+        return newAmountProportion;
+    }
+
+    public void setNewAmountProportion(String newAmountProportion) {
+        this.newAmountProportion = newAmountProportion;
+    }
+
+    public String getCounts() {
+        return counts;
+    }
+
+    public void setCounts(String counts) {
+        this.counts = counts;
+    }
+
+    public BigDecimal getAmount() {
+        return amount;
+    }
+
+    public void setAmount(BigDecimal amount) {
+        this.amount = amount;
+    }
+
+    public String getCountProportion() {
+        return countProportion;
+    }
+
+    public void setCountProportion(String countProportion) {
+        this.countProportion = countProportion;
+    }
+
+    public String getAmountProportion() {
+        return amountProportion;
+    }
+
+    public void setAmountProportion(String amountProportion) {
+        this.amountProportion = amountProportion;
+    }
+}

+ 0 - 9
src/main/java/com/goafanti/order/controller/AdminNewOrderApiController.java

@@ -50,7 +50,6 @@ public class AdminNewOrderApiController extends CertifyApiController {
 	 * @param salesType 销售类型
 	 * @param channelId 渠道编号
 	 * @param other 备注
-	 * @return
 	 */
 	@RequestMapping(value = "/createOrder",method = RequestMethod.POST)
 	public Result createOrder(String uid,Integer orderType,Integer userType,
@@ -241,8 +240,6 @@ public class AdminNewOrderApiController extends CertifyApiController {
 
 	/**
 	 * 订单详情
-	 * @param orderNo
-	 * @return
 	 */
 	@RequestMapping(value = "/getOrderNewDetail", method = RequestMethod.GET)
 	public Result getOrderNewDetail(String orderNo){
@@ -258,8 +255,6 @@ public class AdminNewOrderApiController extends CertifyApiController {
 
 	/**
 	 * 订单审核列表
-	 * @param orderNo
-	 * @return
 	 */
 	@RequestMapping(value = "/getProcessName", method = RequestMethod.GET)
 	public Result getProcessName(String orderNo){
@@ -332,7 +327,6 @@ public class AdminNewOrderApiController extends CertifyApiController {
 	 *  specially 0 个人 1 营销员管理 2 驳回 3 特批 4 咨询师管理 5部门订单查询 6客服查询 7统计签单订单 8客户订单列表 9 复审订单 10 营销经理 11运营保障 12 公出最大值待审核
 	 *  distribution (咨询师管理列表 0 未分配 1部分 2全部
 	 *  amountStatus  0 10万元以下 1 10万~20万 2 20万~30万 3 30万~40万  4 40万以上
-	 * @return
 	 */
 	@RequestMapping(value="/orderNewList", method = RequestMethod.GET)
 	public Result orderNewList(InputOrderNewListBo in){
@@ -346,7 +340,6 @@ public class AdminNewOrderApiController extends CertifyApiController {
 	 *  specially 0 个人 1 营销员管理 2 驳回 3 特批 4 咨询师管理 5部门订单查询 6客服查询 7统计签单订单 8客户订单列表 9 复审订单 10 营销经理
 	 *  distribution (咨询师管理列表 0 未分配 1部分 2全部
 	 *  amountStatus  0 10万元以下 1 10万~20万 2 20万~30万 3 30万~40万  4 40万以上
-	 * @return
 	 */
 	@RequestMapping(value="/orderNewListDownload", method = RequestMethod.GET)
 	public Result orderNewListDownload(InputOrderNewListBo in,HttpServletResponse response){
@@ -361,8 +354,6 @@ public class AdminNewOrderApiController extends CertifyApiController {
 
 	/**
 	 * 销售来源订单列表
-	 * @param in
-	 * @return
 	 */
 	@RequestMapping(value="/statistics/orderList", method = RequestMethod.GET)
 	public Result orderNewList(InputStatisticsOrderList in ){

+ 1 - 1
src/main/java/com/goafanti/order/controller/AdminOrderReceivablesApiController.java

@@ -232,7 +232,7 @@ public class AdminOrderReceivablesApiController extends CertifyApiController {
 					index++;
 					if (index==8)index=0;
 				}
-				e.setType(str.substring(0,str.length()-1));
+				if(str.length()>0)e.setType(str.substring(0,str.length()-1));
 			}
 		}
     	NewExcelUtil<OrderListBo>excel=new NewExcelUtil<>(OrderListBo.class);

+ 18 - 0
src/main/java/com/goafanti/order/controller/StatisticsApiController.java

@@ -8,6 +8,7 @@ import com.goafanti.common.utils.excel.NewExcelUtil;
 import com.goafanti.core.mybatis.page.Pagination;
 import com.goafanti.core.shiro.token.TokenManager;
 import com.goafanti.order.bo.*;
+import com.goafanti.order.bo.outStatistics.OutOrderNewSignBo;
 import com.goafanti.order.bo.outStatistics.OutOrderSalesSourceAmount;
 import com.goafanti.order.service.OrderStatisticsService;
 import com.goafanti.order.service.ProjectStatisticsService;
@@ -213,6 +214,23 @@ public class StatisticsApiController extends CertifyApiController {
 	}
 
 
+	/**
+	 * 新老订单统计导出
+	 */
+	@RequestMapping(value = "/orderNewSign/export",method = RequestMethod.GET)
+	public Result orderNewSignExport(InputOrderNewSignBo in,HttpServletResponse response){
+		in.setPageSize(999999);
+		in.setPageNo(1);
+		String str=userStaticticsService.getOrderNewSignTime(in);
+		List<OutOrderNewSignBo> list = userStaticticsService.orderNewSignToList(in);
+		NewExcelUtil<OutOrderNewSignBo> excelUtil=new NewExcelUtil<>(OutOrderNewSignBo.class);
+
+
+		return excelUtil.exportExcel(list,str,response);
+//		return excelUtil.TestExportExcel(list,"订单项目数据统计表",uploadPath);
+	}
+
+
 
 
 }

+ 5 - 1
src/main/java/com/goafanti/order/service/OrderNewService.java

@@ -229,7 +229,9 @@ public interface OrderNewService {
 
 	void orderNewListDownload(InputOrderNewListBo in, HttpServletResponse response);
 
-	void pushOrderPublicReleaseCount(TOrderNew e);
+    void pushNewSignUser(TOrderNew t2);
+
+    void pushOrderPublicReleaseCount(TOrderNew e);
 
 	List<TOrderNew> selectGetAll();
 
@@ -245,4 +247,6 @@ public interface OrderNewService {
 
 
     Object updateAddGroupChat(TOrderMid us);
+
+    Object pushOrderNewUser();
 }

+ 5 - 0
src/main/java/com/goafanti/order/service/UserStaticticsService.java

@@ -2,6 +2,7 @@ package com.goafanti.order.service;
 
 import com.goafanti.core.mybatis.page.Pagination;
 import com.goafanti.order.bo.*;
+import com.goafanti.order.bo.outStatistics.OutOrderNewSignBo;
 
 import java.util.List;
 
@@ -18,4 +19,8 @@ public interface UserStaticticsService {
     List<OutSignStatistics> signStatisticsGetList(InputSignStatistics in);
 
     Pagination<OutOrderProject> orderProject(InputOrderProject in);
+
+    List<OutOrderNewSignBo> orderNewSignToList(InputOrderNewSignBo in);
+
+    String getOrderNewSignTime(InputOrderNewSignBo in);
 }

+ 1 - 0
src/main/java/com/goafanti/order/service/impl/FundManagerOrderServiceImpl.java

@@ -217,6 +217,7 @@ public class FundManagerOrderServiceImpl extends BaseMybatisDao<TOrderNewMapper>
 		}
 		Admin admin=adminMapper.selectFinanceAdminByOrderDep(t.getOrderDep());
 		orderNewService.financeCountOrderUnauditedSubtraction(t,1);
+		orderNewService.pushNewSignUser(t);
 		return c;
 	}
 	public void pushGeneralSendNoticeAndEmail(List<String> alist, Integer type,TOrderNewBo o,String adminId,Integer approval){

+ 1 - 0
src/main/java/com/goafanti/order/service/impl/OrderChangeServiceImpl.java

@@ -781,6 +781,7 @@ public class OrderChangeServiceImpl extends BaseMybatisDao<NewOrderChangeMapper>
 			noc.setVoucherUrl(t.getVoucherUrl());
 			noc.setTotalAmount(t.getTotalAmount());
 			noc.setSettlementAmount(t.getSettlementAmount());
+			noc.setFirstAmount(t.getFirstAmount());
 			noc.setChangeAmount(t.getChangeAmount());
 			noc.setApplicant(t.getApplicant());
 			noc.setStatus(1);//订单置为正常

+ 80 - 2
src/main/java/com/goafanti/order/service/impl/OrderNewServiceImpl.java

@@ -652,10 +652,43 @@ public class OrderNewServiceImpl extends BaseMybatisDao<TOrderNewMapper> impleme
 		pushOrderDunContent(t2);
 		//计算公出统计
 		pushOrderPublicReleaseCount(t2);
-
+		//处理新旧订单问题
+		if (isSubmit==1)pushNewSignUser(t);
 		return 1;
 	}
 
+	@Override
+	public void pushNewSignUser(TOrderNew t2) {
+		//看有没有时间后的订单,有则先处理后订单
+		List<TOrderNew> tOrderNews = tOrderNewMapper.selectBuyerIdAndSignTime(t2.getBuyerId(), t2.getSignTime(), 1);
+		for (TOrderNew tOrderNew : tOrderNews) {
+			pushOrderNewSignUser(tOrderNew);
+		}
+		pushOrderNewSignUser(t2);
+	}
+
+	private void pushOrderNewSignUser(TOrderNew t) {
+		//最大年限设置3年
+		int max=365*3;
+		List<TOrderNew> tOrderNews = tOrderNewMapper.selectBuyerIdAndSignTime(t.getBuyerId(), t.getSignTime(), 0);
+		TOrderNew updater = new TOrderNew();
+		updater.setOrderNo(t.getOrderNo());
+		if (tOrderNews.size()>0){
+			TOrderNew tOrderNew = tOrderNews.get(tOrderNews.size() - 1);
+			Date signTime = tOrderNew.getSignTime();
+			long daysBetween = DateUtils.getDaysBetween(signTime,t.getSignTime());
+			System.out.println(daysBetween);
+			if (daysBetween<max){
+				updater.setNewSignUser(1);
+			}else {
+				updater.setNewSignUser(0);
+			}
+		}else {
+			updater.setNewSignUser(0);
+		}
+			tOrderNewMapper.update(updater);
+	}
+
 	private void pushApprovalType(TOrderNewWithBLOBs t) {
 		if (StringUtils.isBlank(t.getType())|| Objects.equals(t.getApproval(), ApprovalNewState.FTP.getCode())){
 			tOrderApprovalMapper.deleteByOderNo(t.getOrderNo());
@@ -931,7 +964,13 @@ public class OrderNewServiceImpl extends BaseMybatisDao<TOrderNewMapper> impleme
 		}
 		addOrderLog(tl,reason);
 		pushGeneralSendNoticeAndEmail(aids, noticeType,order, TokenManager.getAdminId(),t2.getApproval());
-		return tOrderNewMapper.update(t);
+		tOrderNewMapper.update(t);
+		if (type==0){
+			t.setBuyerId(t2.getBuyerId());
+			t.setSignTime(t2.getSignTime());
+			pushNewSignUser(t);
+		}
+		return 1;
 	}
 
 
@@ -1446,6 +1485,11 @@ public class OrderNewServiceImpl extends BaseMybatisDao<TOrderNewMapper> impleme
 		}
 		TOrderNewBo order = tOrderNewMapper.getSaleIdByOno(t2.getOrderNo());
 		pushGeneralSendNoticeAndEmail(aids, type,order, TokenManager.getAdminId(),t2.getApproval());
+		if (orderStatus.equals(OrderNewState.QDSHJJ.getCode())) {
+			t.setBuyerId(t2.getBuyerId());
+			t.setSignTime(t2.getSignTime());
+			pushNewSignUser(t);
+		}
 		return 1;
 	}
 
@@ -1810,6 +1854,11 @@ public class OrderNewServiceImpl extends BaseMybatisDao<TOrderNewMapper> impleme
 		pushGeneralSendNoticeAndEmail(aids, type,order, TokenManager.getAdminId(),t2.getApproval());
 		//新增特批催款信息
 		tOrderNewMapper.update(t);
+		if (confirm==3){
+			t.setBuyerId(t2.getBuyerId());
+			t.setSignTime(t2.getSignTime());
+			pushNewSignUser(t);
+		}
 		return 1;
 	}
 
@@ -2075,6 +2124,7 @@ public class OrderNewServiceImpl extends BaseMybatisDao<TOrderNewMapper> impleme
 		pushGeneralSendNoticeAndEmail(aids, NoticeStatus.ORDER_NO.getCode(),order, TokenManager.getAdminId(),t.getApproval());
 		tOrderNewMapper.update(t);
 		financeCountOrderUnauditedSubtraction(t,2);
+		pushNewSignUser(t);
 		return 1;
 	}
 
@@ -2663,4 +2713,32 @@ public class OrderNewServiceImpl extends BaseMybatisDao<TOrderNewMapper> impleme
 		return 1;
 	}
 
+	@Override
+	public Object pushOrderNewUser() {
+		List<TOrderNew> tOrderNews = tOrderNewMapper.selectgetAll();
+		//最大年限设置3年
+		int max=365*3;
+		List<String> list=new ArrayList<>();
+		for (TOrderNew e : tOrderNews) {
+			String buyerId = e.getBuyerId();
+			List<TOrderNew> tOrderNews1 = tOrderNewMapper.selectBuyerIdAndSignTime(buyerId, e.getSignTime(), 0);
+			if (tOrderNews1.size()>0){
+				TOrderNew tOrderNew = tOrderNews1.get(tOrderNews1.size() - 1);
+				Date signTime = tOrderNew.getSignTime();
+				long daysBetween = DateUtils.getDaysBetween(signTime,e.getSignTime());
+				System.out.println(daysBetween);
+				if (daysBetween<max){
+					list.add(e.getOrderNo());
+				}
+			}
+		}
+		for (String s : list) {
+			TOrderNew tOrderNew = new TOrderNew();
+			tOrderNew.setOrderNo(s);
+			tOrderNew.setNewSignUser(1);
+			tOrderNewMapper.update(tOrderNew);
+		}
+		return 1;
+	}
+
 }

+ 2 - 0
src/main/java/com/goafanti/order/service/impl/OrderProjectServiceImpl.java

@@ -2043,6 +2043,8 @@ public class OrderProjectServiceImpl extends BaseMybatisDao<TOrderTaskMapper> im
 
 			}else  if (TokenManager.hasRole(AFTConstants.SALESMAN_ADMIN)){
 				params.put("shiro",2);
+				List<String> myDeps = departmentService.selectMyDeps();
+				params.put("myDeps",myDeps);
 			}
 		}else {
 			return new Pagination<>();

+ 58 - 3
src/main/java/com/goafanti/order/service/impl/UserStatisticsServiceImpl.java

@@ -1,22 +1,30 @@
 package com.goafanti.order.service.impl;
 
 import com.goafanti.admin.service.DepartmentService;
+import com.goafanti.common.dao.TOrderNewMapper;
 import com.goafanti.common.dao.TOrderTaskMapper;
 import com.goafanti.common.dao.UserMidMapper;
 import com.goafanti.common.error.BusinessException;
+import com.goafanti.common.utils.DateUtils;
 import com.goafanti.common.utils.StringUtils;
 import com.goafanti.core.mybatis.BaseMybatisDao;
 import com.goafanti.core.mybatis.page.Pagination;
 import com.goafanti.order.bo.*;
+import com.goafanti.order.bo.outStatistics.OutOrderNewSignBo;
 import com.goafanti.order.enums.NewProjectStatus;
 import com.goafanti.order.service.UserStaticticsService;
 import groovy.util.logging.Log4j;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
 import java.lang.reflect.Field;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.time.DayOfWeek;
+import java.time.LocalDate;
+import java.time.ZoneId;
+import java.time.temporal.TemporalAdjusters;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -25,10 +33,12 @@ import java.util.Map;
 @Log4j
 public class UserStatisticsServiceImpl extends BaseMybatisDao<UserMidMapper> implements UserStaticticsService {
 
-	@Autowired
+	@Resource
 	private DepartmentService departmentService;
-	@Autowired
+	@Resource
 	private TOrderTaskMapper tOrderTaskMapper;
+	@Resource
+	private TOrderNewMapper tOrderNewMapper;
 
 	@Override
 	public Pagination<OutSignSummary> signSummary(InputSignSummary in) {
@@ -191,6 +201,51 @@ public class UserStatisticsServiceImpl extends BaseMybatisDao<UserMidMapper> imp
 		return page;
 	}
 
+
+
+	@Override
+	public String getOrderNewSignTime(InputOrderNewSignBo in) {
+		if(in.getType()==null||in.getType()==0){
+			in.setStartTime(DateUtils.parseDate(in.getStartTimeStr()));
+			in.setEndTime(DateUtils.parseDate(in.getEndTimeStr()));
+		}else if(in.getType()==1){
+			//获取本周起止时间开始时间和结束时间
+			// 获取当前日期
+			LocalDate today = LocalDate.now();
+
+			// 获取本周的开始时间(星期一)
+			LocalDate startOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
+			// 获取下周的周一作为结束时间
+			LocalDate endOfWeek = today.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
+			Date startDate = Date.from(startOfWeek.atStartOfDay(ZoneId.systemDefault()).toInstant());
+			Date endDate = Date.from(endOfWeek.atStartOfDay(ZoneId.systemDefault()).toInstant());
+			in.setStartTime(startDate);
+			in.setEndTime(endDate);
+		}else if(in.getType()==2){
+			//获取本月第一天和下月第一天
+			// 获取当前日期
+			LocalDate today = LocalDate.now();
+			// 获取本月的第一天
+			LocalDate firstDayOfMonth = today.withDayOfMonth(1);
+			// 获取下月的第一天
+			LocalDate firstDayOfNextMonth = firstDayOfMonth.plusMonths(1);
+			Date startDate = Date.from(firstDayOfMonth.atStartOfDay(ZoneId.systemDefault()).toInstant());
+			Date endDate = Date.from(firstDayOfNextMonth.atStartOfDay(ZoneId.systemDefault()).toInstant());
+			in.setStartTime(startDate);
+			in.setEndTime(endDate);
+		}
+		String str=DateUtils.formatDateChineseYYYYMMdd(in.getStartTime())
+				+"-"+DateUtils.formatDateChineseYYYYMMdd(in.getEndTime())
+				+"订单新老客签单统计";
+		return str;
+	}
+
+	@Override
+	public List<OutOrderNewSignBo> orderNewSignToList(InputOrderNewSignBo in) {
+		List<OutOrderNewSignBo> list=tOrderTaskMapper.orderNewSignToList(in);
+		return list;
+	}
+
 	private void pushOrderProjectParam(InputOrderProject in, Map<String, Object> map) {
 		Class<InputOrderProject> clazz= (Class<InputOrderProject>) in.getClass();
 		Field[] declaredFields = clazz.getDeclaredFields();

+ 57 - 22
src/main/java/com/goafanti/techproject/service/impl/TaskDetailsServiceImpl.java

@@ -136,7 +136,11 @@ public class TaskDetailsServiceImpl extends BaseMybatisDao<TaskDetailsMapper> im
             }
         }
         TTaskMember tTaskMember = ttaskMemberMapper.selectByTid(tOrderTask.getId());
-        String serviceYear = getServiceYer(tTaskMember.getServiceYear());
+        String serviceYear ="";
+        if (tTaskMember != null){
+            serviceYear =  tTaskMember.getServiceYear();
+            serviceYear = getServiceYer(serviceYear);
+        }
         if (StringUtils.isEmpty(bo.getTaskName())){
             bo.setTaskName(mid.getSalesmanName());
         }
@@ -320,37 +324,54 @@ public class TaskDetailsServiceImpl extends BaseMybatisDao<TaskDetailsMapper> im
         //计算人员占比
         if (taskDetails.getWorkersNumber()!=null||
                 taskDetails.getTechnologyNumber()!=null){
-            BigDecimal wn = BigDecimal.valueOf(taskDetails.getWorkersNumber());
-            BigDecimal tn = BigDecimal.valueOf(taskDetails.getTechnologyNumber());
-            BigDecimal res = tn.divide(wn,4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
-            taskDetails.setWorkersRate(res.doubleValue());
+            if(taskDetails.getWorkersNumber()==0||taskDetails.getTechnologyNumber()==0){
+                taskDetails.setWorkersRate(0.0);
+            }else{
+                BigDecimal wn = BigDecimal.valueOf(taskDetails.getWorkersNumber());
+                BigDecimal tn = BigDecimal.valueOf(taskDetails.getTechnologyNumber());
+                BigDecimal res = tn.divide(wn,4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+                taskDetails.setWorkersRate(res.doubleValue());
+            }
+
         }
         //计算研发预算完成进度    已归集研发费用总额÷年度研发预算总额X100%
         if (taskDetails.getActualRdAmount()!=null &&taskDetails.getRdBudget()!=null){
-            BigDecimal multiply = taskDetails.getActualRdAmount().divide(taskDetails.getRdBudget(), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
-            taskDetails.setRdCompletionProgress(multiply.doubleValue());
+            if(taskDetails.getRdBudget().compareTo(BigDecimal.ZERO)==0||taskDetails.getActualRdAmount().compareTo(BigDecimal.ZERO)==0){
+                taskDetails.setRdCompletionProgress(0.0);
+            }else {
+                BigDecimal multiply = taskDetails.getActualRdAmount().divide(taskDetails.getRdBudget(), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+                taskDetails.setRdCompletionProgress(multiply.doubleValue());
+            }
         }
         //计算年度研发占比
         //计算三年度的研发占比
             if (taskDetails.getRdBudget() != null && taskDetails.getRdSalesAmount() != null){
                 BigDecimal rdBudget = taskDetails.getRdBudget();
                 BigDecimal rdSalesAmount = taskDetails.getRdSalesAmount();
-                BigDecimal res = rdBudget.divide(rdSalesAmount, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
-                taskDetails.setRdBudgetRate(res.doubleValue());
+                if (taskDetails.getRdBudget().compareTo(BigDecimal.ZERO)==0||taskDetails.getRdSalesAmount().compareTo(BigDecimal.ZERO)==0){
+                    taskDetails.setRdBudgetRate(0.0);
+                }else {
+                    BigDecimal res = rdBudget.divide(rdSalesAmount, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+                    taskDetails.setRdBudgetRate(res.doubleValue());
+                }
                 //计算三年度的研发占比
                 if (taskDetails.getLastRdSalesAmount()!=null && taskDetails.getLastRdBudget()!=null&&
-                taskDetails.getBeforeLastRdSalesAmount()!=null && taskDetails.getBeforeLastRdBudget()!=null){
+                        taskDetails.getBeforeLastRdSalesAmount()!=null && taskDetails.getBeforeLastRdBudget()!=null){
                     BigDecimal res2 = getBigDecimal(rdSalesAmount, rdBudget, taskDetails);
                     taskDetails.setThreeYearsRdBudgetRate(res2.doubleValue());
                 }
             }
         //计算实际研发占比
-        if(taskDetails.getActualRdNumber() !=null &&
+        if(taskDetails.getActualSalesAmount() !=null &&
                 taskDetails.getActualRdAmount() !=null){
             BigDecimal actualSalesAmount = taskDetails.getActualSalesAmount();
             BigDecimal actualRdAmount = taskDetails.getActualRdAmount();
-            BigDecimal res3 = actualRdAmount.divide(actualSalesAmount, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
-            taskDetails.setActualRdRate(res3.doubleValue());
+            if (taskDetails.getActualSalesAmount().compareTo(BigDecimal.ZERO)==0||taskDetails.getActualRdAmount().compareTo(BigDecimal.ZERO)==0){
+                taskDetails.setActualRdRate(0.0);
+            }else {
+                BigDecimal res3 = actualRdAmount.divide(actualSalesAmount, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+                taskDetails.setActualRdRate(res3.doubleValue());
+            }
             if (taskDetails.getLastRdSalesAmount()!=null && taskDetails.getLastRdBudget()!=null&&
                     taskDetails.getBeforeLastRdSalesAmount()!=null && taskDetails.getBeforeLastRdBudget()!=null){
                 BigDecimal res4 = getBigDecimal(actualRdAmount, actualSalesAmount, taskDetails);
@@ -358,10 +379,14 @@ public class TaskDetailsServiceImpl extends BaseMybatisDao<TaskDetailsMapper> im
             }
         }
         //计算立项资料占比
-        if (taskDetails.getProjectApprovalWriteNumber()!=null){
-            BigDecimal projectApprovalWriteNumber = BigDecimal.valueOf(taskDetails.getProjectApprovalWriteNumber());
-            BigDecimal res5 = projectApprovalWriteNumber.divide(new BigDecimal(taskDetails.getProjectApprovalNumber()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
-            taskDetails.setProjectApprovalWriteRate(res5.doubleValue());
+        if (taskDetails.getProjectApprovalWriteNumber()!=null&& taskDetails.getProjectApprovalNumber()!=null){
+            if (taskDetails.getProjectApprovalWriteNumber()==0||taskDetails.getProjectApprovalNumber()==0){
+                taskDetails.setProjectApprovalWriteRate(0.0);
+            }else {
+                BigDecimal projectApprovalWriteNumber = BigDecimal.valueOf(taskDetails.getProjectApprovalWriteNumber());
+                BigDecimal res5 = projectApprovalWriteNumber.divide(new BigDecimal(taskDetails.getProjectApprovalNumber()), 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+                taskDetails.setProjectApprovalWriteRate(res5.doubleValue());
+            }
         }
         //计算项目会员等级
         TOrderNew tOrderNew = tOrderNewMapper.selectByTid(taskDetails.getTid());
@@ -378,11 +403,21 @@ public class TaskDetailsServiceImpl extends BaseMybatisDao<TaskDetailsMapper> im
     }
 
     private BigDecimal getBigDecimal(BigDecimal rdSalesAmount, BigDecimal rdBudget, TaskDetails taskDetails) {
-        BigDecimal threeYearsRdSalesAmount = rdSalesAmount;
-        BigDecimal threeYearsRdBudget = rdBudget;
-        threeYearsRdSalesAmount = threeYearsRdSalesAmount.add(taskDetails.getLastRdSalesAmount()).add(taskDetails.getBeforeLastRdSalesAmount());
-        threeYearsRdBudget = threeYearsRdBudget.add(taskDetails.getLastRdBudget()).add(taskDetails.getBeforeLastRdBudget());
-        return threeYearsRdBudget.divide(threeYearsRdSalesAmount, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+        BigDecimal threeYearsRdSalesAmount = BigDecimal.ZERO;
+        BigDecimal threeYearsRdBudget = BigDecimal.ZERO;
+        threeYearsRdSalesAmount = threeYearsRdSalesAmount
+                .add(rdSalesAmount)
+                .add(taskDetails.getLastRdSalesAmount())
+                .add(taskDetails.getBeforeLastRdSalesAmount());
+        threeYearsRdBudget = threeYearsRdBudget
+                .add(rdBudget)
+                .add(taskDetails.getLastRdBudget())
+                .add(taskDetails.getBeforeLastRdBudget());
+        if (threeYearsRdSalesAmount.compareTo(BigDecimal.ZERO)==0||threeYearsRdBudget.compareTo(BigDecimal.ZERO)==0){
+            return BigDecimal.ZERO;
+        }else {
+            return threeYearsRdBudget.divide(threeYearsRdSalesAmount, 4, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
+        }
     }
 
     /**