Browse Source

Merge branch 'test' of jishutao/kede-server into prod

anderx 6 months ago
parent
commit
388a74442c

+ 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>

+ 88 - 0
src/main/java/com/goafanti/businessCard/controller/AdminBusinessCardController.java

@@ -0,0 +1,88 @@
+package com.goafanti.businessCard.controller;
+
+import com.goafanti.businessCard.service.AdminBusinessCardService;
+import com.goafanti.common.bo.Result;
+import com.goafanti.common.controller.BaseController;
+import com.goafanti.common.model.AdminBusinessCard;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 用户名片表(AdminBusinessCard)表控制层
+ *
+ * @author makejava
+ * @since 2025-06-27 15:10:04
+ */
+@RestController
+@RequestMapping("/api/admin/adminBusinessCard")
+public class AdminBusinessCardController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private AdminBusinessCardService adminBusinessCardService;
+
+
+    /**
+     * 新增数据
+     *
+     * @param adminBusinessCard 实体
+     * @return 新增结果
+     */
+    @PostMapping("/add")
+    public Result add(AdminBusinessCard adminBusinessCard) {
+        return new Result<>().data(this.adminBusinessCardService.insert(adminBusinessCard));
+    }
+
+
+    /**
+     * 通过主键查询单条数据
+     *
+     * @param id 主键
+     * @return 单条数据
+     */
+    @GetMapping("/get")
+    public Result<AdminBusinessCard> queryById(Integer id) {
+        return new Result<>().data(this.adminBusinessCardService.queryById(id));
+    }
+
+
+    /**
+     * 编辑数据
+     *
+     * @param adminBusinessCard 实体
+     * @return 编辑结果
+     */
+    @PostMapping("/update")
+    public Result edit(AdminBusinessCard adminBusinessCard) {
+        return new Result<>().data(this.adminBusinessCardService.update(adminBusinessCard));
+    }
+
+    /**
+     * 删除数据
+     *
+     * @param id 主键
+     * @return 删除是否成功
+     */
+    @GetMapping("/delete")
+    public Result deleteById(Integer id) {
+        return new Result<>().data(this.adminBusinessCardService.deleteById(id));
+    }
+
+    /**
+     * 列表查询
+     *
+     * @param in 参数
+     * @return
+     */
+    @GetMapping("/list")
+    public Result<AdminBusinessCard> list(AdminBusinessCard in, Integer pageNo, Integer pageSize) {
+        return new Result<>().data(this.adminBusinessCardService.list(in, pageNo, pageSize));
+    }
+
+}
+

+ 54 - 0
src/main/java/com/goafanti/businessCard/service/AdminBusinessCardService.java

@@ -0,0 +1,54 @@
+package com.goafanti.businessCard.service;
+
+import com.goafanti.common.model.AdminBusinessCard;
+
+/**
+ * 用户名片表(AdminBusinessCard)表服务接口
+ *
+ * @author makejava
+ * @since 2025-06-27 15:10:05
+ */
+public interface AdminBusinessCardService {
+
+    /**
+     * 通过ID查询单条数据
+     *
+     * @param id 主键
+     * @return 实例对象
+     */
+    AdminBusinessCard queryById(Integer id);
+
+
+    /**
+     * 新增数据
+     *
+     * @param adminBusinessCard 实例对象
+     * @return 实例对象
+     */
+    AdminBusinessCard insert(AdminBusinessCard adminBusinessCard);
+
+    /**
+     * 修改数据
+     *
+     * @param adminBusinessCard 实例对象
+     * @return 实例对象
+     */
+    AdminBusinessCard update(AdminBusinessCard adminBusinessCard);
+
+    /**
+     * 通过主键删除数据
+     *
+     * @param id 主键
+     * @return 是否成功
+     */
+    boolean deleteById(Integer id);
+
+    /**
+     * 列表数据
+     *
+     * @param in 参数
+     * @return 是否成功
+     */
+    Object list(AdminBusinessCard in, Integer pageNo, Integer pageSize);
+
+}

+ 84 - 0
src/main/java/com/goafanti/businessCard/service/impl/AdminBusinessCardServiceImpl.java

@@ -0,0 +1,84 @@
+package com.goafanti.businessCard.service.impl;
+
+import com.goafanti.businessCard.service.AdminBusinessCardService;
+import com.goafanti.common.dao.AdminBusinessCardMapper;
+import com.goafanti.common.model.AdminBusinessCard;
+import com.goafanti.core.mybatis.BaseMybatisDao;
+import com.goafanti.core.mybatis.page.Pagination;
+import com.goafanti.core.shiro.token.TokenManager;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 用户名片表(AdminBusinessCard)表服务实现类
+ *
+ * @author makejava
+ * @since 2025-06-27 15:10:05
+ */
+@Service("adminBusinessCardService")
+public class AdminBusinessCardServiceImpl extends BaseMybatisDao<AdminBusinessCardMapper> implements AdminBusinessCardService {
+    @Resource
+    private AdminBusinessCardMapper adminBusinessCardMapper;
+
+
+    @Override
+    public Pagination<AdminBusinessCard> list(AdminBusinessCard adminBusinessCard, Integer pageNo, Integer pageSize) {
+        Map<String, Object> params = new HashMap<>();
+        params.put("in", adminBusinessCard);
+        return (Pagination<AdminBusinessCard>) findPage("findAdminBusinessCardList",
+                "findAdminBusinessCardCount", params, pageNo, pageSize);
+    }
+
+    /**
+     * 通过ID查询单条数据
+     *
+     * @param id 主键
+     * @return 实例对象
+     */
+    @Override
+    public AdminBusinessCard queryById(Integer id) {
+        return this.adminBusinessCardMapper.selectById(id);
+    }
+
+
+    /**
+     * 新增数据
+     *
+     * @param adminBusinessCard 实例对象
+     * @return 实例对象
+     */
+    @Override
+    public AdminBusinessCard insert(AdminBusinessCard adminBusinessCard) {
+        adminBusinessCard.setAid(TokenManager.getAdminId());
+        adminBusinessCard.setCreateTime(new Date());
+        this.adminBusinessCardMapper.insert(adminBusinessCard);
+        return adminBusinessCard;
+    }
+
+    /**
+     * 修改数据
+     *
+     * @param adminBusinessCard 实例对象
+     * @return 实例对象
+     */
+    @Override
+    public AdminBusinessCard update(AdminBusinessCard adminBusinessCard) {
+        this.adminBusinessCardMapper.update(adminBusinessCard);
+        return this.queryById(adminBusinessCard.getId());
+    }
+
+    /**
+     * 通过主键删除数据
+     *
+     * @param id 主键
+     * @return 是否成功
+     */
+    @Override
+    public boolean deleteById(Integer id) {
+        return this.adminBusinessCardMapper.deleteById(id) > 0;
+    }
+}

+ 17 - 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;
@@ -1027,4 +1029,19 @@ public class PublicController extends CertifyApiController {
 	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<>();
+	}
 }

+ 84 - 0
src/main/java/com/goafanti/common/dao/AdminBusinessCardMapper.java

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

+ 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();
+}
+

+ 203 - 0
src/main/java/com/goafanti/common/mapper/AdminBusinessCardMapper.xml

@@ -0,0 +1,203 @@
+<?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.AdminBusinessCardMapper">
+
+    <resultMap type="com.goafanti.common.model.AdminBusinessCard" id="AdminBusinessCardMap">
+        <result property="id" column="id" jdbcType="INTEGER"/>
+        <result property="aid" column="aid" jdbcType="VARCHAR"/>
+        <result property="name" column="name" jdbcType="VARCHAR"/>
+        <result property="position" column="position" jdbcType="VARCHAR"/>
+        <result property="company" column="company" jdbcType="VARCHAR"/>
+        <result property="phone" column="phone" jdbcType="VARCHAR"/>
+        <result property="landLine" column="land_line" jdbcType="VARCHAR"/>
+        <result property="email" column="email" jdbcType="VARCHAR"/>
+        <result property="area" column="area" jdbcType="VARCHAR"/>
+        <result property="content" column="content" jdbcType="VARCHAR"/>
+        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
+    </resultMap>
+
+    <sql id="AdminBusinessCardAllSql">
+        id, aid, name, position, company, phone, land_line, email, area, content, create_time
+    </sql>
+
+    <!--查询单个-->
+    <select id="selectById" resultMap="AdminBusinessCardMap">
+        select
+        <include refid="AdminBusinessCardAllSql"/>
+        from admin_business_card
+        where id = #{id}
+    </select>
+
+    <!--新增所有列-->
+    <insert id="insert" keyProperty="id" useGeneratedKeys="true">
+        insert into admin_business_card(aid, name, position, company, phone, land_line, email, area, content,
+                                        create_time)
+        values (#{aid}, #{name}, #{position}, #{company}, #{phone}, #{landLine}, #{email}, #{area}, #{content},
+                #{createTime})
+    </insert>
+
+    <insert id="insertBatch">
+        insert into admin_business_card(aid, name, position, company, phone, land_line, email, area, content,
+        create_time)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.aid}, #{entity.name}, #{entity.position}, #{entity.company}, #{entity.phone}, #{entity.landLine},
+            #{entity.email}, #{entity.area}, #{entity.content}, #{entity.createTime})
+        </foreach>
+    </insert>
+
+    <insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
+        insert into admin_business_card(aid, name, position, company, phone, land_line, email, area, content,
+        create_time)
+        values
+        <foreach collection="entities" item="entity" separator=",">
+            (#{entity.aid}, #{entity.name}, #{entity.position}, #{entity.company}, #{entity.phone}, #{entity.landLine},
+            #{entity.email}, #{entity.area}, #{entity.content}, #{entity.createTime})
+        </foreach>
+        on duplicate key update
+        aid = values(aid),
+        name = values(name),
+        position = values(position),
+        company = values(company),
+        phone = values(phone),
+        land_line = values(land_line),
+        email = values(email),
+        area = values(area),
+        content = values(content),
+        create_time = values(create_time)
+    </insert>
+
+    <!--通过主键修改数据-->
+    <update id="update">
+        update admin_business_card
+        <set>
+            <if test="aid != null and aid != ''">
+                aid = #{aid},
+            </if>
+            <if test="name != null and name != ''">
+                name = #{name},
+            </if>
+            <if test="position != null and position != ''">
+                position = #{position},
+            </if>
+            <if test="company != null and company != ''">
+                company = #{company},
+            </if>
+            <if test="phone != null and phone != ''">
+                phone = #{phone},
+            </if>
+            <if test="landLine != null and landLine != ''">
+                land_line = #{landLine},
+            </if>
+            <if test="email != null and email != ''">
+                email = #{email},
+            </if>
+            <if test="area != null and area != ''">
+                area = #{area},
+            </if>
+            <if test="content != null and content != ''">
+                content = #{content},
+            </if>
+            <if test="createTime != null">
+                create_time = #{createTime},
+            </if>
+        </set>
+        where id = #{id}
+    </update>
+
+    <!--查询指定行数据-->
+    <select id="findAdminBusinessCardList" resultMap="AdminBusinessCardMap">
+        select
+        <include refid="AdminBusinessCardAllSql"/>
+
+        from admin_business_card
+        <where>
+            <if test="id != null">
+                and id = #{id}
+            </if>
+            <if test="aid != null and aid != ''">
+                and aid = #{aid}
+            </if>
+            <if test="name != null and name != ''">
+                and name = #{name}
+            </if>
+            <if test="position != null and position != ''">
+                and position = #{position}
+            </if>
+            <if test="company != null and company != ''">
+                and company = #{company}
+            </if>
+            <if test="phone != null and phone != ''">
+                and phone = #{phone}
+            </if>
+            <if test="landLine != null and landLine != ''">
+                and land_line = #{landLine}
+            </if>
+            <if test="email != null and email != ''">
+                and email = #{email}
+            </if>
+            <if test="area != null and area != ''">
+                and area = #{area}
+            </if>
+            <if test="content != null and content != ''">
+                and content = #{content}
+            </if>
+            <if test="createTime != null">
+                and create_time = #{createTime}
+            </if>
+        </where>
+        <if test="page_sql != null">
+            ${page_sql}
+        </if>
+    </select>
+
+    <!--统计总行数-->
+    <select id="findAdminBusinessCardCount" resultType="java.lang.Integer">
+        select count(1)
+        from admin_business_card
+        <where>
+            <if test="id != null">
+                and id = #{id}
+            </if>
+            <if test="aid != null and aid != ''">
+                and aid = #{aid}
+            </if>
+            <if test="name != null and name != ''">
+                and name = #{name}
+            </if>
+            <if test="position != null and position != ''">
+                and position = #{position}
+            </if>
+            <if test="company != null and company != ''">
+                and company = #{company}
+            </if>
+            <if test="phone != null and phone != ''">
+                and phone = #{phone}
+            </if>
+            <if test="landLine != null and landLine != ''">
+                and land_line = #{landLine}
+            </if>
+            <if test="email != null and email != ''">
+                and email = #{email}
+            </if>
+            <if test="area != null and area != ''">
+                and area = #{area}
+            </if>
+            <if test="content != null and content != ''">
+                and content = #{content}
+            </if>
+            <if test="createTime != null">
+                and create_time = #{createTime}
+            </if>
+        </where>
+    </select>
+
+    <!--通过主键删除-->
+    <delete id="deleteById">
+        delete
+        from admin_business_card
+        where id = #{id}
+    </delete>
+
+</mapper>
+

+ 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>
+

+ 151 - 0
src/main/java/com/goafanti/common/model/AdminBusinessCard.java

@@ -0,0 +1,151 @@
+package com.goafanti.common.model;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 用户名片表(AdminBusinessCard)实体类
+ *
+ * @author makejava
+ * @since 2025-06-27 15:10:05
+ */
+public class AdminBusinessCard implements Serializable {
+    private static final long serialVersionUID = 145518401317693724L;
+
+    private Integer id;
+    /**
+     * 卡片编号
+     */
+    private String aid;
+    /**
+     * 名称
+     */
+    private String name;
+    /**
+     * 职位
+     */
+    private String position;
+    /**
+     * 公司名称
+     */
+    private String company;
+    /**
+     * 电话
+     */
+    private String phone;
+    /**
+     * 座机
+     */
+    private String landLine;
+    /**
+     * 邮箱
+     */
+    private String email;
+    /**
+     * 地区
+     */
+    private String area;
+    /**
+     * 个人简介
+     */
+    private String content;
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createTime;
+
+
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getAid() {
+        return aid;
+    }
+
+    public void setAid(String aid) {
+        this.aid = aid;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPosition() {
+        return position;
+    }
+
+    public void setPosition(String position) {
+        this.position = position;
+    }
+
+    public String getCompany() {
+        return company;
+    }
+
+    public void setCompany(String company) {
+        this.company = company;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getLandLine() {
+        return landLine;
+    }
+
+    public void setLandLine(String landLine) {
+        this.landLine = landLine;
+    }
+
+    public String getEmail() {
+        return email;
+    }
+
+    public void setEmail(String email) {
+        this.email = email;
+    }
+
+    public String getArea() {
+        return area;
+    }
+
+    public void setArea(String area) {
+        this.area = area;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public void setContent(String content) {
+        this.content = content;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+}
+

+ 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;
+    }
+
+}
+

+ 2 - 0
src/main/java/com/goafanti/common/task/OrderDunTask.java

@@ -275,6 +275,7 @@ private void processList(List<TArrearsDun> tarrearsList, Date date) {
             BigDecimal arrears = tm.getOrderArrears();
             if (arrears.compareTo(BigDecimal.ZERO) > 0) {
                 // 欠款大于0则触发邮件并新建记录
+				//把旧的停止
                 ta.setDunStatus(3);
                 tArrearsDunMapper.updateByPrimaryKeySelective(ta);
                 ta.setId(null);
@@ -282,6 +283,7 @@ private void processList(List<TArrearsDun> tarrearsList, Date date) {
                 ta.setStartTime(date);
                 ta.setOrderArrears(arrears);
                 ta.setOrderReceivables(tm.getOrderReceivables());
+				//新建一条新的
                 tArrearsDunMapper.insertSelective(ta);
                 orderNewService.addNotic(NoticeStatus.ORDER_ARREARS_DUN.getCode(), b, null);
             } else if (arrears.compareTo(BigDecimal.ZERO) <= 0) {

+ 15 - 11
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 {
 
@@ -421,7 +423,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
 	}
 
 	public static String formatDateYYYYMMdd(Date date) {
-		SimpleDateFormat format = new SimpleDateFormat(parsePatterns[1]);
+		SimpleDateFormat format = new SimpleDateFormat(parsePatterns[0]);
 		return format.format(date);
 	}
 	public static String formatDateChineseYYYYMMdd(Date date) {
@@ -576,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);
     }
-
 }

+ 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 - 2
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);