sangwenwei vor 1 Jahr
Ursprung
Commit
04104ec3b3
38 geänderte Dateien mit 1334 neuen und 67 gelöschten Zeilen
  1. 5 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/User.java
  2. 5 0
      jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/UserDTO.java
  3. 13 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/finance/controller/CwFinanceInvoiceController.java
  4. 2 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/finance/mapper/JyFinanceInvoiceMapper.java
  5. 13 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/finance/mapper/xml/JyFinanceInvoiceMapper.xml
  6. 21 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/finance/service/JyFinanceInvoiceService.java
  7. 9 4
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/humanResources/service/StaffDimissionService.java
  8. 4 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/humanResources/service/dto/StaffUserInfoDTO.java
  9. 14 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/payment/controller/PaymentController.java
  10. 2 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/payment/mapper/PaymentMapper.java
  11. 16 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/payment/mapper/xml/PaymentMapper.xml
  12. 56 9
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/payment/service/PaymentService.java
  13. 5 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/domain/JyProject.java
  14. 11 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/domain/JyProjectArchive.java
  15. 5 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/domain/JyProjectAudit.java
  16. 2 1
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/mapper/xml/JyProjectArchiveMapper.xml
  17. 2 1
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/mapper/xml/JyProjectAuditMapper.xml
  18. 4 1
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/mapper/xml/ProjectListMapper.xml
  19. 164 17
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/service/JyProjectService.java
  20. 10 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/service/dto/JyProjectArchiveDTO.java
  21. 5 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/service/dto/JyProjectAuditDTO.java
  22. 489 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/utils/FileUtils.java
  23. 64 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/utils/ImageUtil.java
  24. 12 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/controller/JyReimbursementInfoController.java
  25. 4 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/mapper/JyReimbursementInfoMapper.java
  26. 3 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/mapper/JyReimbursementInfoPaymentMapper.java
  27. 178 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/mapper/xml/JyReimbursementInfoMapper.xml
  28. 20 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/mapper/xml/JyReimbursementInfoPaymentMapper.xml
  29. 66 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/service/JyReimbursementInfoService.java
  30. 6 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/domain/Signet.java
  31. 2 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/mapper/SignetMapper.java
  32. 31 1
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/mapper/xml/SignetMapper.xml
  33. 9 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/service/SignetService.java
  34. 5 0
      jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/service/dto/SignetDTO.java
  35. 37 16
      jeeplus-modules/jeeplus-business/src/main/resources/freemarker/firstAudit.ftl
  36. 31 17
      jeeplus-modules/jeeplus-flowable/src/main/java/com/jeeplus/modules/flowable/listener/JyProjectArchiveListener.java
  37. 4 0
      jeeplus-modules/jeeplus-system/src/main/java/com/jeeplus/sys/mapper/xml/UserMapper.xml
  38. 5 0
      jeeplus-modules/jeeplus-system/src/main/java/com/jeeplus/sys/service/UserService.java

+ 5 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/domain/User.java

@@ -107,6 +107,11 @@ public class User extends BaseEntity {
      */
     private Boolean isAdmin;
 
+    //手签章url
+    private String handSignatureUrl;
+    //是否有手签章
+    private String isHandSignature;
+
     /**
      * 备注
      */

+ 5 - 0
jeeplus-api/jeeplus-system-api/src/main/java/com/jeeplus/sys/service/dto/UserDTO.java

@@ -82,6 +82,11 @@ public class UserDTO extends BaseDTO implements Serializable {
 
     private OfficeDTO corporationDTO;   //公司信息
 
+    //手签章url
+    private String handSignatureUrl;
+    //是否有手签章
+    private String isHandSignature;
+
 
     /**
      * 登录名

+ 13 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/finance/controller/CwFinanceInvoiceController.java

@@ -387,6 +387,19 @@ public class CwFinanceInvoiceController {
         return flag;
     }
 
+    /**
+     * 根据项目id查询项目关联发票
+     * @param projectId
+     * @return
+     * @throws Exception
+     */
+    @GetMapping("queryByProjectId")
+    @ApiOperation(value = "根据项目id查询项目关联发票")
+    public ResponseEntity<List<JyFinanceInvoiceDTO>> queryByProjectId(String projectId) throws Exception {
+        List<JyFinanceInvoiceDTO> cwFinanceDTO = cwFinanceInvoiceService.queryByProjectId(projectId);
+        return ResponseEntity.ok(cwFinanceDTO);
+    }
+
 
 
 

+ 2 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/finance/mapper/JyFinanceInvoiceMapper.java

@@ -42,6 +42,8 @@ public interface JyFinanceInvoiceMapper extends BaseMapper<JyFinanceInvoice> {
      */
     @InterceptorIgnore(tenantLine = "true")
     void updateInfoById(JyFinanceInvoice cwFinanceInvoice);
+
+    List<JyFinanceInvoiceDTO> queryByProjectId(@Param(Constants.WRAPPER)QueryWrapper<JyFinanceInvoice> queryWrapper);
 }
 
 

+ 13 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/finance/mapper/xml/JyFinanceInvoiceMapper.xml

@@ -417,4 +417,17 @@
         remarks = #{remarks}
         where id = #{id}
     </update>
+
+    <select id="queryByProjectId" resultMap="BaseResultMap">
+        select
+        <include refid="Base_Column_List"></include>,
+        su.name as operator,
+        so.name as operator_office,
+        cfid.number as "number"
+        from jy_finance_invoice fi
+        left join sys_user su on fi.create_by_id = su.id and su.del_flag = '0'
+        left join sys_office so on su.office_id = so.id and so.del_flag = '0'
+        left join jy_finance_invoice_detail cfid on cfid.invoice_id = fi.id and cfid.del_flag = '0'
+        ${ew.customSqlSegment}
+    </select>
 </mapper>

+ 21 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/finance/service/JyFinanceInvoiceService.java

@@ -670,4 +670,25 @@ public class JyFinanceInvoiceService extends ServiceImpl<JyFinanceInvoiceMapper,
         }
         return new ArrayList<>();
     }
+
+    /**
+     * 根据项目id查询发票信息
+     * @param projectId
+     * @return
+     */
+    public List<JyFinanceInvoiceDTO> queryByProjectId(String projectId) {
+        if(StringUtils.isNotBlank(projectId)){
+            List<String> idByProjectId = cwFinanceInvoiceMapper.getIdByProjectId(projectId);
+            if (CollectionUtil.isNotEmpty(idByProjectId)){
+                QueryWrapper<JyFinanceInvoice> queryWrapper = new QueryWrapper<>();
+                queryWrapper.in("fi.id", idByProjectId);
+                queryWrapper.eq("fi.del_flag","0");
+                queryWrapper.eq("fi.status","5"); // 发票申请流程已通过
+                queryWrapper.orderByDesc("fi.create_time");
+                queryWrapper.eq("fi.invalid_status","0"); // 未作废
+                return cwFinanceInvoiceMapper.queryByProjectId(queryWrapper);
+            }
+        }
+        return new ArrayList<>();
+    }
 }

+ 9 - 4
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/humanResources/service/StaffDimissionService.java

@@ -8,8 +8,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.google.common.collect.Lists;
 import com.jeeplus.business.goOut.mapper.GoOutMapper;
-import com.jeeplus.business.holiday.domain.Holiday;
 import com.jeeplus.business.humanResources.domain.JyDimissionProcess;
 import com.jeeplus.business.humanResources.domain.StaffDimission;
 import com.jeeplus.business.humanResources.domain.StaffHeir;
@@ -18,7 +18,6 @@ import com.jeeplus.business.humanResources.mapper.StaffDimissionMapper;
 import com.jeeplus.business.humanResources.mapper.StaffHeirMapper;
 import com.jeeplus.business.humanResources.service.dto.StaffDimissionDTO;
 import com.jeeplus.business.humanResources.service.dto.StaffHeirDTO;
-import com.jeeplus.business.monthly.domain.JyProcess;
 import com.jeeplus.business.project.domain.JyProjectMembers;
 import com.jeeplus.business.project.mapper.JyProjectMemberMapper;
 import com.jeeplus.business.project.service.JyProjectService;
@@ -31,7 +30,7 @@ import com.jeeplus.sys.domain.WorkAttachmentInfo;
 import com.jeeplus.sys.feign.IUserApi;
 import com.jeeplus.sys.feign.IWorkAttachmentApi;
 import com.jeeplus.sys.service.dto.UserDTO;
-import com.jeeplus.sys.utils.UserUtils;
+
 import com.jeeplus.utils.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
@@ -359,8 +358,14 @@ public class StaffDimissionService {
         staffHeirMapper.updateUserById(id,loginFlag);
 
         UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getById(id);
+        //获取在线员工信息
+        Set <String> keys = RedisUtils.getInstance ( ).keys ( CacheNames.USER_CACHE_ONLINE_USERS, "*" );
+        List <UserDTO> onlineUsers = Lists.newArrayList ( );
+        keys.forEach ( key -> {
+            onlineUsers.add ( (UserDTO) RedisUtils.getInstance ( ).get ( key ) );
+        } );
         //将该员工的信息从redis删除
-        UserUtils.getOnlineUsers().forEach(dto ->{
+        onlineUsers.forEach(dto ->{
             if (userDTO.getTenantDTO().getId().equals(dto.getTenantDTO().getId()) && userDTO.getName().equals(dto.getName())) {
                 RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_ONLINE_USERS, dto.getToken ( ) );
                 RedisUtils.getInstance ( ).delete ( CacheNames.USER_CACHE_TOKEN, dto.getToken ( ) );

+ 4 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/humanResources/service/dto/StaffUserInfoDTO.java

@@ -172,6 +172,10 @@ public class StaffUserInfoDTO extends BaseEntity {
     //是否顺延
     private String isPostpone;
 
+    //手签章url
+    private String handSignatureUrl;
+    //是否有手签章
+    private String isHandSignature;
 
 
 

+ 14 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/payment/controller/PaymentController.java

@@ -126,4 +126,18 @@ public class PaymentController {
     }
 
 
+    /**
+     * 根据项目id查找付款信息
+     * @param projectId
+     * @return
+     * @throws Exception
+     */
+    @ApiOperation(value = "根据项目id查找付款信息")
+    @GetMapping(value = "/queryByProjectId")
+    public ResponseEntity<List<PaymentDTO>> queryByProjectId(String projectId) throws Exception {
+        List<PaymentDTO> pageList=paymentService.queryByProjectId(projectId);
+        return ResponseEntity.ok(pageList);
+    }
+
+
 }

+ 2 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/payment/mapper/PaymentMapper.java

@@ -33,4 +33,6 @@ public interface PaymentMapper extends BaseMapper<Payment> {
     Integer findIsExit(@Param("id") String id, @Param("name")String name);
 
     List<WorkAttachmentInfo> findFiles(@Param("id") String id);
+
+    List<PaymentDTO> queryByProjectId(@Param("projectId")String projectId);
 }

+ 16 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/payment/mapper/xml/PaymentMapper.xml

@@ -138,4 +138,20 @@
 			AND attachment_id = #{id}
 	</select>
 
+    <select id="queryByProjectId" resultType="com.jeeplus.business.payment.service.dto.PaymentDTO">
+        select
+            a.id,
+            a.no,
+            a.payment_lower,
+            a.payment_time,
+            a.project_id,
+            su.name as payment_user,
+            so.name as paymentOffice
+        from jy_payment a
+        left join sys_user su on su.id = a.payment_user and su.del_flag = '0'
+        left join sys_office so on su.office_id = so.id and so.del_flag = '0'
+        where find_in_set (#{projectId},project_id) and a.del_flag = '0'
+        order by a.create_time DESC
+    </select>
+
 </mapper>

+ 56 - 9
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/payment/service/PaymentService.java

@@ -32,7 +32,9 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 public class PaymentService {
@@ -86,18 +88,21 @@ public class PaymentService {
             }
         }
         IPage<PaymentDTO> pageList=paymentMapper.findPageList(queryWrapper,page);
-        List<JyReimbursementDetailInfoPayment> list = jyReimbursementInfoPaymentMapper.getList();
-        list.stream().forEach(item->{
             pageList.getRecords().stream().forEach(data->{
-                if (item.getProjectId().equals(data.getId()) && item.getStatus().equals("5")){
-                    Float moneyLower=Float.parseFloat(data.getPaymentLower());
-                    Float number=Float.parseFloat(item.getNumber());
-                    Float money=moneyLower-number;
-                    data.setFinalMoney(money.toString());
-                    data.setRefund(item.getNumber());
+                List<JyReimbursementDetailInfoPayment> list = jyReimbursementInfoPaymentMapper.findByProjectId(data.getId());
+                Double total = 0.00;
+                if (CollectionUtils.isNotEmpty(list)){
+                    //将所有的报销金额汇总
+                    for (JyReimbursementDetailInfoPayment reim : list) {
+                        double parseDouble = Double.parseDouble(reim.getNumber());
+                        total += parseDouble;
+                    }
                 }
+                Double moneyLower=Double.parseDouble(data.getPaymentLower());
+                Double money=moneyLower-total;
+                data.setFinalMoney(money.toString());//剩余付款金额
+                data.setRefund(total.toString());//冲抵金额
             });
-        });
         return pageList;
 
 
@@ -385,4 +390,46 @@ public class PaymentService {
         IPage<Payment> moneyList = paymentMapper.listByUserId(queryWrapper,page);
         return moneyList;
     }
+
+    /**
+     * 根据项目id查询付款信息
+     * @param projectId
+     * @return
+     */
+    public List<PaymentDTO> queryByProjectId(String projectId) {
+        //根据项目id查找付款信息
+        List<PaymentDTO> paymentDTOList = paymentMapper.queryByProjectId(projectId);
+        //存放报销冲抵完成的集合
+        ArrayList<String> successList = new ArrayList<>();
+
+        if (CollectionUtils.isNotEmpty(paymentDTOList)){
+            for (PaymentDTO paymentDTO : paymentDTOList) {
+                //根据付款id查询报销信息
+                List<JyReimbursementDetailInfoPayment> list = jyReimbursementInfoPaymentMapper.findByProjectId(paymentDTO.getId());
+                Double total = 0.00;
+                if (CollectionUtils.isNotEmpty(list)){
+                    //将所有的报销金额汇总
+                    for (JyReimbursementDetailInfoPayment reim : list) {
+                        double parseDouble = Double.parseDouble(reim.getNumber());
+                        total += parseDouble;
+                    }
+                }
+                //付款金额
+                double payment = Double.parseDouble(paymentDTO.getPaymentLower());
+
+                //判断报销总金额与付款金额是否冲抵完成
+                if (payment == total){
+                    successList.add(paymentDTO.getId());
+                }else {
+                    Double money=payment-total;
+                    paymentDTO.setFinalMoney(money.toString());
+                    paymentDTO.setRefund(total.toString());
+                }
+            }
+        }
+        List<PaymentDTO> filteredPaymentDTOList = paymentDTOList.stream()
+                .filter(item -> !successList.contains(item.getId())) // 检查ID是否在successList中
+                .collect(Collectors.toList()); // 收集过滤后的元素到新列表中
+        return filteredPaymentDTOList;
+    }
 }

+ 5 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/domain/JyProject.java

@@ -99,6 +99,11 @@ public class JyProject extends BaseEntity implements Serializable {
      */
     private String special;
 
+    /**
+     * 审核时间
+     */
+    private Date auditTime;
+
 
     /*
     流程id

+ 11 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/domain/JyProjectArchive.java

@@ -6,6 +6,7 @@ import com.jeeplus.core.domain.BaseEntity;
 import com.jeeplus.sys.domain.WorkAttachmentInfo;
 import lombok.Data;
 
+import java.util.Date;
 import java.util.List;
 
 @Data
@@ -39,6 +40,16 @@ public class JyProjectArchive extends BaseEntity {
     @TableField(exist = false)
     private List<WorkAttachmentInfo> fileList;
 
+    /**
+     * 归档盒号
+     */
+    private String caseNumber;
+
+    /**
+     * 审核时间
+     */
+    private Date auditTime;
+
     private static final long serialVersionUID = 1L;
 
 

+ 5 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/domain/JyProjectAudit.java

@@ -70,6 +70,11 @@ public class JyProjectAudit extends BaseEntity {
     private String exceedTimeStatus;
 
     /**
+     * 审核通过意见
+     */
+    private String auditAgreeOpinion;
+
+    /**
      * 附件信息
      */
     @TableField(exist = false)

+ 2 - 1
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/mapper/xml/JyProjectArchiveMapper.xml

@@ -10,7 +10,8 @@
             status,
             remarks,
             proc_ins_id,
-            process_definition_id
+            process_definition_id,
+            case_number
         from jy_project_archive
         where id=#{id}
     </select>

+ 2 - 1
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/mapper/xml/JyProjectAuditMapper.xml

@@ -39,7 +39,8 @@
         pa.proc_ins_id,
         pa.process_definition_id,
         pa.status,
-        pa.exceed_time_status
+        pa.exceed_time_status,
+        pa.audit_agree_opinion
     </sql>
 
 

+ 4 - 1
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/mapper/xml/ProjectListMapper.xml

@@ -822,13 +822,16 @@
            (SELECT su.name from sys_user su where a.project_leader = su.id) as projectLeader,
            a.proc_ins_id,
            a.process_definition_id,
-           b.name AS create_by_id
+           b.name AS create_by_id,
+           wci.no as contractNo,
+           wci.contract_amount as contractAmount
         FROM
             jy_project_record a
             LEFT JOIN sys_user b ON a.create_by_id = b.id
             LEFT JOIN sys_user c ON a.project_leader = c.id
             left join jy_project_outinstance po on a.id=po.project_id
             left join jy_project_members pm on a.id = pm.project_id
+            left join jy_work_contract_info wci on wci.id = a.contract_id
              where (pm.user_id = #{id} or a.create_by_id = #{id}) and a.status = '5'
             ORDER BY a.update_time DESC
     </select>

+ 164 - 17
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/service/JyProjectService.java

@@ -8,14 +8,19 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.EncryptUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeeplus.business.finance.util.Global;
 import com.jeeplus.business.project.domain.*;
 import com.jeeplus.business.project.mapper.*;
 import com.jeeplus.business.project.service.dto.*;
 import com.jeeplus.business.project.service.mapstruct.*;
+import com.jeeplus.business.project.utils.FileUtils;
+import com.jeeplus.business.project.utils.ImageUtil;
 import com.jeeplus.business.useSeal.domain.Signet;
 import com.jeeplus.business.useSeal.mapper.SignetMapper;
+import com.jeeplus.business.useSeal.service.dto.SignetDTO;
 import com.jeeplus.business.workClientInfo.domain.JyWorkClientInfo;
 import com.jeeplus.business.workClientInfo.domain.JyWorkClientLinkman;
 import com.jeeplus.business.workClientInfo.mapper.JyWorkClientInfoMapper;
@@ -36,16 +41,19 @@ import com.jeeplus.sys.feign.IWorkAttachmentApi;
 import com.jeeplus.sys.service.dto.DictValueDTO;
 import com.jeeplus.sys.service.dto.UserDTO;
 import com.jeeplus.sys.service.dto.WorkAttachmentInfoDTO;
+
 import org.apache.commons.compress.utils.Lists;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import javax.annotation.Resource;
+import java.io.File;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -56,6 +64,25 @@ import java.util.stream.Collectors;
 
 @Service
 public class JyProjectService {
+    private final String base64Black = "iVBORw0KGgoAAAANSUhEUgAAAQkAAACDCAYAAACeNO5uAAAAAXN\n" +
+            "SR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5m\n" +
+            "H3gAAAGASURBVHhe7dSBAAAADASh+Uv/DI6gILoBBEkASRJAkgSQJAEkSQB\n" +
+            "JEkCSBJAkASRJAEkSQJIEkCQBJEkASRJAkgSQJAEkSQBJEkCSBJAkASRJ\n" +
+            "AEkSQJIEkCQBJEkASRJAkgSQJAEkSQBJEkCSBJAkASRJAEkSQJIEkCQBJE\n" +
+            "kASRJAkgSQJAEkSQBJEkCSBJAkASRJAEkSQJIEkCQBJEkASRJAkgSQJAEk\n" +
+            "SQBJEkCSBJAkASRJAEkSQJIEkCQBJEkASRJAkgSQJAEkSQBJEkCSBJAkAS\n" +
+            "RJAEkSQJIEkCQBJEkASRJAkgSQJAEkSQBJEkCSBJAkASRJAEkSQJIEkCQB\n" +
+            "JEkASRJAkgSQJAEkSQBJEkCSBJAkASRJAEkSQJIEkCQBJEkASRJAkgSQJA\n" +
+            "EkSQBJEkCSBJAkASRJAEkSQJIEkCQBJEkASRJAkgSQJAEkSQBJEkCSBJAkA\n" +
+            "SRJAEkSQJIEkCQBJEkASRJAkgSQJAEkSQBJEkCSBJAkASRJAEkSQNgeLFltOQ4ygBYAAAAASUVORK5CYII=";
+
+    /**
+     * 阿里云文件服务器前缀
+     */
+//    @Value("${config.accessory.aliyun.aliyunUrl}")
+//    private String aliyunUrl;
+//    @Value("${config.accessory.aliyun.aliyunDownloadUrl}")
+//    private String aliyunDownloadUrl;
 
     @Resource
     private JyProjectMapper jyProjectMapper;
@@ -687,6 +714,11 @@ public class JyProjectService {
            //设置项目登记通过的时间
             jyProjectAudit.setProjectAgreeTime(byId.getUpdateTime());
             jyProjectAuditMapper.updateById(jyProjectAudit);
+            //修改项目登记审核时间
+            JyProject jyProject = new JyProject();
+            jyProject.setAuditTime(new Date());
+            jyProject.setId(byId.getId());
+            jyProjectMapper.updateById(jyProject);
         }
     }
 
@@ -834,6 +866,12 @@ public class JyProjectService {
             jyProjectAudit.setInitialEditOpinion(edit);
             jyProjectAudit.setEditOpinion("");
         }
+        //审核通过时,将审核通过意见单独进行保存
+        if ("5".equals(jyProjectAuditDTO.getStatus())){
+            if (StringUtils.isNotBlank(jyProjectAuditDTO.getAuditOpinion())){
+                jyProjectAudit.setAuditAgreeOpinion(jyProjectAuditDTO.getAuditOpinion());
+            }
+        }
         jyProjectAudit.setAuditPeople(jyProjectAuditDTO.getAuditPeople());
         if (StringUtils.isNotBlank(jyProjectAudit.getId())){
             jyProjectAuditMapper.updateById(jyProjectAudit);
@@ -975,6 +1013,19 @@ public class JyProjectService {
             data.put("otherPeople","/");
         //根据项目id获取到所有的校审信息
         List<JyProjectAuditDTO> jyProjectAuditDTOS=jyProjectAuditMapper.getByProjectId(info.getProjectId());
+        //根据项目id查询报告签发信息
+        SignetDTO signet=signetMapper.getByProjectId(info.getProjectId());
+        String auditHandSignet = "";//报告签发最后一级节点审核人手签章
+        Date approvalTime = null;//审核通过时间
+        //signet 不为空时说明报告签发流程审核结束,此时可以获取到最后一个节点审核人及审核通过时间
+        if (ObjectUtil.isNotEmpty(signet)){
+            UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getById(signet.getUpdateById());
+            //判断审核人是否有手签章
+            if (StringUtils.isNotBlank(userDTO.getHandSignatureUrl())){
+                auditHandSignet =base64String(userDTO.getHandSignatureUrl());
+            }
+            approvalTime = signet.getApprovalTime();
+        }
         //如果存在审核意见则进行处理
         if(null != jyProjectAuditDTOS){
             if (jyProjectAuditDTOS.size()>=1){
@@ -998,8 +1049,11 @@ public class JyProjectService {
                 //审核人
                 if (StringUtils.isNotBlank(jyProjectAuditDTOS.get(0).getAuditPeople())){
                     data.put("firstAuditPeople",SpringUtil.getBean(IUserApi.class).getById(jyProjectAuditDTOS.get(0).getAuditPeople()).getName());
+                    data.put("firstAgreeName",SpringUtil.getBean(IUserApi.class).getById(jyProjectAuditDTOS.get(0).getAuditPeople()).getName());
                 }else {
                     data.put("firstAuditPeople","");
+                    data.put("firstAgreeName","");
+
 
                 }
                 //日期
@@ -1007,9 +1061,11 @@ public class JyProjectService {
                 if (null == jyProjectAuditDTOS.get(0).getUpdateTime()){
                     data.put("firstAuditDate","");
                     data.put("firstDate","");
+                    data.put("firstAgreeDate","");
                 }else {
                     data.put("firstAuditDate",format);
                     data.put("firstDate",format);
+                    data.put("firstAgreeDate",format);
                 }
                 //修改意见
                 ArrayList<String> strings1 = new ArrayList<>();
@@ -1035,9 +1091,11 @@ public class JyProjectService {
                     data.put("firstName","");
                 }
                 //校核修改结果认可意见及签名和日期
-                data.put("firstAgreeOpinion","");
-                data.put("firstAgreeName","");
-                data.put("firstAgreeDate","");
+                if (StringUtils.isNotBlank(jyProjectAuditDTOS.get(0).getAuditAgreeOpinion())){
+                    data.put("firstAgreeOpinion",jyProjectAuditDTOS.get(0).getAuditAgreeOpinion());
+                }else {
+                    data.put("firstAgreeOpinion","已复核");
+                }
 
                 //审核意见和修改意见长度比较,然后将双方长度变为一致
                 if (strings.size()<strings1.size()){
@@ -1078,17 +1136,22 @@ public class JyProjectService {
                 //审核人
                 if (StringUtils.isNotBlank(jyProjectAuditDTOS.get(1).getAuditPeople())){
                     data.put("secondAuditPeople",SpringUtil.getBean(IUserApi.class).getById(jyProjectAuditDTOS.get(1).getAuditPeople()).getName());
+                    data.put("secondAgreeName",SpringUtil.getBean(IUserApi.class).getById(jyProjectAuditDTOS.get(1).getAuditPeople()).getName());
                 }else {
                     data.put("secondAuditPeople","");
+                    data.put("secondAgreeName","");//审核人
+
                 }
                 //日期
                 String format = sdf.format(jyProjectAuditDTOS.get(1).getUpdateTime());
                 if (null == jyProjectAuditDTOS.get(1).getUpdateTime()){
                     data.put("secondAuditDate","");
                     data.put("secondDate","");
+                    data.put("secondAgreeDate","");
                 }else {
                     data.put("secondAuditDate",format);
                     data.put("secondDate",format);
+                    data.put("secondAgreeDate",format);//审核同意时间
                 }
                 //修改意见
                 ArrayList<String> strings1 = new ArrayList<>();
@@ -1113,9 +1176,12 @@ public class JyProjectService {
                     data.put("secondName","");
                 }
                 //校核修改结果认可意见
-                data.put("secondAgreeOpinion","");
-                data.put("secondAgreeName","");
-                data.put("secondAgreeDate","");
+                if (StringUtils.isNotBlank(jyProjectAuditDTOS.get(1).getAuditAgreeOpinion())){
+                    data.put("secondAgreeOpinion",jyProjectAuditDTOS.get(1).getAuditAgreeOpinion());
+                }else {
+                    data.put("secondAgreeOpinion","已复核");
+                }
+
 
                 //审核意见和修改意见长度比较,然后将双方长度变为一致
                 if (strings.size()<strings1.size()){
@@ -1155,17 +1221,25 @@ public class JyProjectService {
                 //审核人
                 if (StringUtils.isNotBlank(jyProjectAuditDTOS.get(2).getAuditPeople())){
                     data.put("thirdAuditPeople",SpringUtil.getBean(IUserApi.class).getById(jyProjectAuditDTOS.get(2).getAuditPeople()).getName());
+                    data.put("thirdAgreeName",SpringUtil.getBean(IUserApi.class).getById(jyProjectAuditDTOS.get(2).getAuditPeople()).getName());
+
                 }else {
                     data.put("thirdAuditPeople","");
+                    data.put("thirdAgreeName","");
+
                 }
                 //日期
                 String format = sdf.format(jyProjectAuditDTOS.get(2).getUpdateTime());
                 if (null == jyProjectAuditDTOS.get(2).getUpdateTime()){
                     data.put("thirdAuditDate","");
                     data.put("thirdDate","");
+                    data.put("thirdAgreeDate","");
+                }else {
+                    data.put("thirdAuditDate",format);
+                    data.put("thirdDate",format);
+                    data.put("thirdAgreeDate",format);
                 }
-                data.put("thirdAuditDate",format);
-                data.put("thirdDate",format);
+
                 //修改意见
                 ArrayList<String> strings1 = Lists.newArrayList();
                 if (StringUtils.isNotBlank(jyProjectAuditDTOS.get(2).getInitialEditOpinion())){
@@ -1190,9 +1264,12 @@ public class JyProjectService {
                     data.put("thirdName","");
                 }
                 //校核修改结果认可意见
-                data.put("thirdAgreeOpinion","");
-                data.put("thirdAgreeName","");
-                data.put("thirdAgreeDate","");
+                if (StringUtils.isNotBlank(jyProjectAuditDTOS.get(2).getAuditAgreeOpinion())){
+                    data.put("thirdAgreeOpinion",jyProjectAuditDTOS.get(2).getAuditAgreeOpinion());
+                }else {
+                    data.put("thirdAgreeOpinion","已复核");
+                }
+
 
                 //审核意见和修改意见长度比较,然后将双方长度变为一致
                 if (strings.size()<strings1.size()){
@@ -1211,9 +1288,20 @@ public class JyProjectService {
 
             }
             //签发人
-            data.put("submitPeople","");
+            if (StringUtils.isNotBlank(auditHandSignet)){
+                data.put("submitPeople",auditHandSignet);
+            }else {
+                data.put("submitPeople",base64Black);
+            }
             //签发日期
-            data.put("submitDate","");
+            if (ObjectUtil.isNotEmpty(approvalTime)){
+                String format = sdf.format(approvalTime);
+                data.put("submitDate",format);
+            }else {
+                data.put("submitDate","");
+            }
+
+
         }else{
             //一级复核意见
             data.put("firstAuditList","");
@@ -1278,6 +1366,57 @@ public class JyProjectService {
         return data;
     }
 
+
+    /**
+     *将用户手签章图片转换为base64字符串输出
+     */
+    public String base64String(String handSignature){
+        String imageStr = "";
+        String path = null;
+        String fileName = null;
+
+        String aliyunUrl = "http://cdn.gangwaninfo.com";
+        String aliDownloadUrl = "http://oss.gangwaninfo.com";
+
+        try {
+            String aliyunUrlStr = aliyunUrl + handSignature;
+            //下载文件
+            if(System.getProperty("os.name").toLowerCase().contains("win")){
+                path = "D:/attachment-file/handSignature/";
+            }else{
+                path = "/attachment-file/handSignature/";
+            }
+
+            String file = aliyunUrlStr;
+            file = file.replace("amp;","");
+            fileName = file.substring(file.lastIndexOf("/") + 1, file.length());
+            String cons = "";
+            if (file.contains(aliyunUrl)){
+                cons = aliyunUrl;
+            }else if (file.contains("http://gangwan-app.oss-cn-hangzhou.aliyuncs.com")){
+                cons = "http://gangwan-app.oss-cn-hangzhou.aliyuncs.com";
+            }else {
+                cons = aliDownloadUrl;
+            }
+            String ossKey = file.split(cons+"/")[1];
+            File filePath = new File(path);
+            if (!filePath.mkdirs()) {
+                filePath.mkdirs();
+            }
+            SpringUtil.getBean(IWorkAttachmentApi.class).downByStreamSaveLocal(ossKey,fileName,path+fileName);
+            imageStr = ImageUtil.getImageStr(path+fileName);
+        }catch (Exception e){
+            e.getMessage();
+        }finally {
+            FileUtils.delFile(path+fileName);
+        }
+        if(StringUtils.isBlank(imageStr)){
+            imageStr = base64Black;
+        }
+        return imageStr;
+    }
+
+
     /**
      * 根据id查询外审信息
      * @param id
@@ -1348,7 +1487,7 @@ public class JyProjectService {
                 String workAttachmentDtoInfo = JSON.toJSONString(workAttachmentDto);
                 String userDTOInfo = JSON.toJSONString(userDTO);
                 String attachmentId = jyProjectOutinstance.getId();
-                String attachmentFlag = "jyProjectOut";
+                String attachmentFlag = item.getAttachmentFlag();
                 String sortInfo = Integer.toString(sort.get());
                 map.put("workAttachmentDtoInfo",workAttachmentDtoInfo);
                 map.put("userDTOInfo",userDTOInfo);
@@ -1719,7 +1858,7 @@ public class JyProjectService {
      * @return
      */
     public JyProjectArchiveDTO findByIdArchive(String id) {
-        //根据id获取外审信息
+        //根据id获取归档信息
         JyProjectArchiveDTO jyProjectArchiveDTO=jyProjectArchiveMapper.findById(id);
 
         if (null != jyProjectArchiveDTO){
@@ -1750,12 +1889,20 @@ public class JyProjectService {
         //代码转化,将dto中的对象赋到实体类中
         JyProjectArchive jyProjectArchive = JyProjectArchiveWrapper.INSTANCE.toEntity(jyProjectArchiveDTO);
         //获取审核信息
-        JyProjectOutinstanceDTO byId = jyProjectOutinstanceMapper.findById(jyProjectArchive.getId());
+        JyProjectArchiveDTO byId = jyProjectArchiveMapper.findById(jyProjectArchive.getId());
         if (ObjectUtil.isNotEmpty(byId)){
             if (StringUtils.isNotBlank(jyProjectArchive.getRemarks())){
                 jyProjectArchive.setRemarks(jyProjectArchiveDTO.getRemarks());
             }
         }
+        //归档盒号
+        if (StringUtils.isNotBlank(jyProjectArchiveDTO.getCaseNumber())){
+            jyProjectArchive.setCaseNumber(jyProjectArchiveDTO.getCaseNumber());
+        }
+        //添加审核时间
+        if ("5".equals(jyProjectArchiveDTO.getStatus())){
+            jyProjectArchive.setAuditTime(new Date());
+        }
         if (StringUtils.isNotBlank(jyProjectArchive.getId())){
             jyProjectArchiveMapper.updateById(jyProjectArchive);
         }else{
@@ -1847,7 +1994,7 @@ public class JyProjectService {
         //代码转化,将dto中的对象赋到实体类中
         JyProjectEiaQualification jyProjectEiaQualification = JyProjectEiaQualificationWrapper.INSTANCE.toEntity(jyProjectEiaQualificationDTO);
         //获取审核信息
-        JyProjectOutinstanceDTO byId = jyProjectOutinstanceMapper.findById(jyProjectEiaQualification.getId());
+        JyProjectEiaQualificationDTO byId=jyProjectEiaQualificationMapper.findById(jyProjectEiaQualification.getId());
         if (ObjectUtil.isNotEmpty(byId)){
             if (StringUtils.isNotBlank(jyProjectEiaQualification.getRemarks())){
                 jyProjectEiaQualification.setRemarks(jyProjectEiaQualificationDTO.getRemarks());

+ 10 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/service/dto/JyProjectArchiveDTO.java

@@ -5,6 +5,7 @@ import com.jeeplus.core.service.dto.BaseDTO;
 import com.jeeplus.sys.service.dto.WorkAttachmentInfoDTO;
 import lombok.Data;
 
+import java.util.Date;
 import java.util.List;
 
 @Data
@@ -42,5 +43,14 @@ public class JyProjectArchiveDTO extends BaseDTO {
 
     private static final long serialVersionUID = 1L;
 
+    /**
+     * 归档盒号
+     */
+    private String caseNumber;
+
+    /**
+     * 审核时间
+     */
+    private Date auditTime;
 
 }

+ 5 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/service/dto/JyProjectAuditDTO.java

@@ -105,6 +105,11 @@ public class JyProjectAuditDTO extends BaseDTO {
     private String submitPeople;
     private Date submitDate;
 
+    /**
+     * 审核通过意见
+     */
+    private String auditAgreeOpinion;
+
 
 
 }

+ 489 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/utils/FileUtils.java

@@ -0,0 +1,489 @@
+/**
+ * Copyright &copy; 2021-2026 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
+ */
+package com.jeeplus.business.project.utils;
+
+import cn.hutool.core.util.StrUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+
+/**
+ * 文件操作工具类
+ * 实现文件的创建、删除、复制、压缩、解压以及目录的创建、删除、复制、压缩解压等功能
+ * @author jeeplus
+ * @version 2021-06-21
+ */
+public class FileUtils extends org.apache.commons.io.FileUtils {
+
+	private static Logger log = LoggerFactory.getLogger(FileUtils.class);
+
+
+
+	/**
+	 * 判断是否是文件
+	 * @param source
+	 */
+	public static boolean isFile(String source) {
+		return  new File(source).isFile();
+	}
+
+	/**
+	 * 判断是否是目录
+	 * @param source
+	 */
+	public static boolean isFolder(String source) {
+		return  new File(source).isDirectory();
+	}
+
+	/**
+	 * 复制单个文件,如果目标文件存在,则不覆盖
+	 * @param srcFileName 待复制的文件名
+	 * @param descFileName 目标文件名
+	 * @return 如果复制成功,则返回true,否则返回false
+	 */
+	public static boolean copyFile(String srcFileName, String descFileName) {
+		return FileUtils.copyFileCover(srcFileName, descFileName, false);
+	}
+
+	/**
+	 * 复制单个文件
+	 * @param srcFileName 待复制的文件名
+	 * @param descFileName 目标文件名
+	 * @param coverlay 如果目标文件已存在,是否覆盖
+	 * @return 如果复制成功,则返回true,否则返回false
+	 */
+	public static boolean copyFileCover(String srcFileName,
+			String descFileName, boolean coverlay) {
+		File srcFile = new File(srcFileName);
+		// 判断源文件是否存在
+		if (!srcFile.exists()) {
+			log.debug("复制文件失败,源文件 " + srcFileName + " 不存在!");
+			return false;
+		}
+		// 判断源文件是否是合法的文件
+		else if (!srcFile.isFile()) {
+			log.debug("复制文件失败," + srcFileName + " 不是一个文件!");
+			return false;
+		}
+		File descFile = new File(descFileName);
+		// 判断目标文件是否存在
+		if (descFile.exists()) {
+			// 如果目标文件存在,并且允许覆盖
+			if (coverlay) {
+				log.debug("目标文件已存在,准备删除!");
+				if (!FileUtils.delFile(descFileName)) {
+					log.debug("删除目标文件 " + descFileName + " 失败!");
+					return false;
+				}
+			} else {
+				log.debug("复制文件失败,目标文件 " + descFileName + " 已存在!");
+				return false;
+			}
+		} else {
+			if (!descFile.getParentFile().exists()) {
+				// 如果目标文件所在的目录不存在,则创建目录
+				log.debug("目标文件所在的目录不存在,创建目录!");
+				// 创建目标文件所在的目录
+				if (!descFile.getParentFile().mkdirs()) {
+					log.debug("创建目标文件所在的目录失败!");
+					return false;
+				}
+			}
+		}
+
+		// 准备复制文件
+		// 读取的位数
+		int readByte = 0;
+		InputStream ins = null;
+		OutputStream outs = null;
+		try {
+			// 打开源文件
+			ins = new FileInputStream(srcFile);
+			// 打开目标文件的输出流
+			outs = new FileOutputStream(descFile);
+			byte[] buf = new byte[1024];
+			// 一次读取1024个字节,当readByte为-1时表示文件已经读取完毕
+			while ((readByte = ins.read(buf)) != -1) {
+				// 将读取的字节流写入到输出流
+				outs.write(buf, 0, readByte);
+			}
+			log.debug("复制单个文件 " + srcFileName + " 到" + descFileName
+					+ "成功!");
+			return true;
+		} catch (Exception e) {
+			log.debug("复制文件失败:" + e.getMessage());
+			return false;
+		} finally {
+			// 关闭输入输出流,首先关闭输出流,然后再关闭输入流
+			if (outs != null) {
+				try {
+					outs.close();
+				} catch (IOException oute) {
+					oute.printStackTrace();
+				}
+			}
+			if (ins != null) {
+				try {
+					ins.close();
+				} catch (IOException ine) {
+					ine.printStackTrace();
+				}
+			}
+		}
+	}
+
+	/**
+	 * 复制整个目录的内容,如果目标目录存在,则不覆盖
+	 * @param srcDirName 源目录名
+	 * @param descDirName 目标目录名
+	 * @return 如果复制成功返回true,否则返回false
+	 */
+	public static boolean copyDirectory(String srcDirName, String descDirName) {
+		return FileUtils.copyDirectoryCover(srcDirName, descDirName,
+				false);
+	}
+
+	/**
+	 * 复制整个目录的内容
+	 * @param srcDirName 源目录名
+	 * @param descDirName 目标目录名
+	 * @param coverlay 如果目标目录存在,是否覆盖
+	 * @return 如果复制成功返回true,否则返回false
+	 */
+	public static boolean copyDirectoryCover(String srcDirName,
+			String descDirName, boolean coverlay) {
+		File srcDir = new File(srcDirName);
+		// 判断源目录是否存在
+		if (!srcDir.exists()) {
+			log.debug("复制目录失败,源目录 " + srcDirName + " 不存在!");
+			return false;
+		}
+		// 判断源目录是否是目录
+		else if (!srcDir.isDirectory()) {
+			log.debug("复制目录失败," + srcDirName + " 不是一个目录!");
+			return false;
+		}
+		// 如果目标文件夹名不以文件分隔符结尾,自动添加文件分隔符
+		String descDirNames = descDirName;
+		if (!descDirNames.endsWith(File.separator)) {
+			descDirNames = descDirNames + File.separator;
+		}
+		File descDir = new File(descDirNames);
+		// 如果目标文件夹存在
+		if (descDir.exists()) {
+			if (coverlay) {
+				// 允许覆盖目标目录
+				log.debug("目标目录已存在,准备删除!");
+				if (!FileUtils.delFile(descDirNames)) {
+					log.debug("删除目录 " + descDirNames + " 失败!");
+					return false;
+				}
+			} else {
+				log.debug("目标目录复制失败,目标目录 " + descDirNames + " 已存在!");
+				return false;
+			}
+		} else {
+			// 创建目标目录
+			log.debug("目标目录不存在,准备创建!");
+			if (!descDir.mkdirs()) {
+				log.debug("创建目标目录失败!");
+				return false;
+			}
+
+		}
+
+		boolean flag = true;
+		// 列出源目录下的所有文件名和子目录名
+		File[] files = srcDir.listFiles();
+		for (int i = 0; i < files.length; i++) {
+			// 如果是一个单个文件,则直接复制
+			if (files[i].isFile()) {
+				flag = FileUtils.copyFile(files[i].getAbsolutePath(),
+						descDirName + files[i].getName());
+				// 如果拷贝文件失败,则退出循环
+				if (!flag) {
+					break;
+				}
+			}
+			// 如果是子目录,则继续复制目录
+			if (files[i].isDirectory()) {
+				flag = FileUtils.copyDirectory(files[i]
+						.getAbsolutePath(), descDirName + files[i].getName());
+				// 如果拷贝目录失败,则退出循环
+				if (!flag) {
+					break;
+				}
+			}
+		}
+
+		if (!flag) {
+			log.debug("复制目录 " + srcDirName + " 到 " + descDirName + " 失败!");
+			return false;
+		}
+		log.debug("复制目录 " + srcDirName + " 到 " + descDirName + " 成功!");
+		return true;
+
+	}
+
+	/**
+	 *
+	 * 删除文件,可以删除单个文件或文件夹
+	 *
+	 * @param fileName 被删除的文件名
+	 * @return 如果删除成功,则返回true,否是返回false
+	 */
+	public static boolean delFile(String fileName) {
+ 		File file = new File(fileName);
+		if (!file.exists()) {
+			log.debug(fileName + " 文件不存在!");
+			return true;
+		} else {
+			if (file.isFile()) {
+				return FileUtils.deleteFile(fileName);
+			} else {
+				return FileUtils.deleteDirectory(fileName);
+			}
+		}
+	}
+
+	/**
+	 *
+	 * 删除单个文件
+	 *
+	 * @param fileName 被删除的文件名
+	 * @return 如果删除成功,则返回true,否则返回false
+	 */
+	public static boolean deleteFile(String fileName) {
+		File file = new File(fileName);
+		if (file.exists() && file.isFile()) {
+			if (file.delete()) {
+				log.debug("删除文件 " + fileName + " 成功!");
+				return true;
+			} else {
+				log.debug("删除文件 " + fileName + " 失败!");
+				return false;
+			}
+		} else {
+			log.debug(fileName + " 文件不存在!");
+			return true;
+		}
+	}
+
+	/**
+	 *
+	 * 删除目录及目录下的文件
+	 *
+	 * @param dirName 被删除的目录所在的文件路径
+	 * @return 如果目录删除成功,则返回true,否则返回false
+	 */
+	public static boolean deleteDirectory(String dirName) {
+		String dirNames = dirName;
+		if (!dirNames.endsWith(File.separator)) {
+			dirNames = dirNames + File.separator;
+		}
+		File dirFile = new File(dirNames);
+		if (!dirFile.exists() || !dirFile.isDirectory()) {
+			log.debug(dirNames + " 目录不存在!");
+			return true;
+		}
+		boolean flag = true;
+		// 列出全部文件及子目录
+		File[] files = dirFile.listFiles();
+		for (int i = 0; i < files.length; i++) {
+			// 删除子文件
+			if (files[i].isFile()) {
+				flag = FileUtils.deleteFile(files[i].getAbsolutePath());
+				// 如果删除文件失败,则退出循环
+				if (!flag) {
+					break;
+				}
+			}
+			// 删除子目录
+			else if (files[i].isDirectory()) {
+				flag = FileUtils.deleteDirectory(files[i]
+						.getAbsolutePath());
+				// 如果删除子目录失败,则退出循环
+				if (!flag) {
+					break;
+				}
+			}
+		}
+
+		if (!flag) {
+			log.debug("删除目录失败!");
+			return false;
+		}
+		// 删除当前目录
+		if (dirFile.delete()) {
+			log.debug("删除目录 " + dirName + " 成功!");
+			return true;
+		} else {
+			log.debug("删除目录 " + dirName + " 失败!");
+			return false;
+		}
+
+	}
+
+	/**
+	 * 创建单个文件
+	 * @param descFileName 文件名,包含路径
+	 * @return 如果创建成功,则返回true,否则返回false
+	 */
+	public static boolean createFile(String descFileName) {
+		File file = new File(descFileName);
+		if (file.exists()) {
+			log.debug("文件 " + descFileName + " 已存在!");
+			return false;
+		}
+		if (descFileName.endsWith(File.separator)) {
+			log.debug(descFileName + " 为目录,不能创建目录!");
+			return false;
+		}
+		if (!file.getParentFile().exists()) {
+			// 如果文件所在的目录不存在,则创建目录
+			if (!file.getParentFile().mkdirs()) {
+				log.debug("创建文件所在的目录失败!");
+				return false;
+			}
+		}
+
+		// 创建文件
+		try {
+			if (file.createNewFile()) {
+				log.debug(descFileName + " 文件创建成功!");
+				return true;
+			} else {
+				log.debug(descFileName + " 文件创建失败!");
+				return false;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			log.debug(descFileName + " 文件创建失败!");
+			return false;
+		}
+
+	}
+
+	/**
+	 * 创建目录
+	 * @param descDirName 目录名,包含路径
+	 * @return 如果创建成功,则返回true,否则返回false
+	 */
+	public static boolean createDirectory(String descDirName) {
+		String descDirNames = descDirName;
+		if (!descDirNames.endsWith(File.separator)) {
+			descDirNames = descDirNames + File.separator;
+		}
+		File descDir = new File(descDirNames);
+		if (descDir.exists()) {
+			log.debug("目录 " + descDirNames + " 已存在!");
+			return false;
+		}
+		// 创建目录
+		if (descDir.mkdirs()) {
+			log.debug("目录 " + descDirNames + " 创建成功!");
+			return true;
+		} else {
+			log.debug("目录 " + descDirNames + " 创建失败!");
+			return false;
+		}
+
+	}
+
+
+	/**
+	 * 获取可以创建的文件名(如果有同名文件存在,参照Windows系统重命名为xxx(2).xxx)
+	 * @param name
+	 * @param index
+	 * @return
+	 */
+	public static File getAvailableFile(String name, int index){
+		File newFile = null;
+
+        String suffix = StrUtil.subAfter (name, ".", true);
+        String filePath = StrUtil.subBefore (name, ".", true);
+		if(index == 0 ){
+			newFile = new File(filePath+"."+suffix);
+		}else{
+			newFile = new File(filePath+"("+index+")"+"."+suffix);
+		}
+		if(newFile.exists()){
+			return  getAvailableFile(name,index+1);
+		}else{
+			return  newFile;
+		}
+	};
+
+	/**
+	 * 获取可以创建的目录名(如果有同名目录存在,参照Windows系统重命名为xxx(2))
+	 * @param name
+	 * @param index
+	 * @return
+	 */
+	public static File getAvailableFolder(String name, int index){
+		File newFolder = null;
+		if(index == 0 ){
+			newFolder = new File(name);
+		}else{
+			newFolder = new File(name+"("+index+")");
+		}
+		if(newFolder.exists()){
+			return  getAvailableFolder(name,index+1);
+		}else{
+			return  newFolder;
+		}
+	};
+
+	/**
+	 * 写入文件
+	 */
+	public static void writeToFile(String fileName, String content, boolean append) {
+		try {
+			FileUtils.write(new File(fileName), content, "utf-8", append);
+			log.debug("文件 " + fileName + " 写入成功!");
+		} catch (IOException e) {
+			log.debug("文件 " + fileName + " 写入失败! " + e.getMessage());
+		}
+	}
+
+	/**
+	 * 写入文件
+	 */
+	public static void writeToFile(String fileName, String content, String encoding, boolean append) {
+		try {
+			FileUtils.write(new File(fileName), content, encoding, append);
+			log.debug("文件 " + fileName + " 写入成功!");
+		} catch (IOException e) {
+			log.debug("文件 " + fileName + " 写入失败! " + e.getMessage());
+		}
+	}
+
+
+	/**
+	 * 获取待压缩文件在ZIP文件中entry的名字,即相对于跟目录的相对路径名
+	 * @param dirPath 目录名
+	 * @param file entry文件名
+	 * @return
+	 */
+	private static String getEntryName(String dirPath, File file) {
+		String dirPaths = dirPath;
+		if (!dirPaths.endsWith(File.separator)) {
+			dirPaths = dirPaths + File.separator;
+		}
+		String filePath = file.getAbsolutePath();
+		// 对于目录,必须在entry名字后面加上"/",表示它将以目录项存储
+		if (file.isDirectory()) {
+			filePath += "/";
+		}
+		int index = filePath.indexOf(dirPaths);
+
+		return filePath.substring(index + dirPaths.length());
+	}
+
+
+
+
+
+}

+ 64 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/project/utils/ImageUtil.java

@@ -0,0 +1,64 @@
+package com.jeeplus.business.project.utils;
+
+import sun.misc.BASE64Encoder;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ImageUtil {
+    /**
+     * 将路径参数的文件转为Base64字符串
+     * @return
+     */
+    public static String getImageStr(String path){
+        // 1、校验是否为空
+        if (path == null || path.trim().length() <= 0) {
+            return "";
+        }
+
+        // 2、校验文件是否为目录或者是否存在
+        File picFile = new File(path);
+        if (picFile.isDirectory() || (!picFile.exists()))
+            return "";
+
+        // 3、校验是否为图片
+        try {
+            BufferedImage image = ImageIO.read(picFile);
+            if (image == null) {
+                return "";
+            }
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            return "";
+        }
+
+        // 4、转换成base64编码
+        String imageStr = "   ";
+        InputStream in = null;
+        try {
+            byte[] data = null;
+            in = new FileInputStream(path);
+            data = new byte[in.available()];
+            in.read(data);
+            BASE64Encoder encoder = new BASE64Encoder();
+            imageStr = encoder.encode(data);
+        } catch (Exception e) {
+            imageStr = "";
+            e.printStackTrace();
+        }finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return imageStr;
+    }
+}

+ 12 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/controller/JyReimbursementInfoController.java

@@ -138,6 +138,18 @@ public class JyReimbursementInfoController {
 
     }
 
+    /**
+     * 根据项目id查询报销信息
+     * @param ids
+     * @return
+     */
+    @ApiOperation(value = "根据项目id查询报销信息")
+    @GetMapping("/queryByProjectId")
+    public ResponseEntity<List<JyReimbursementInfoDTO>> queryByProjectId(String projectId){
+        List<JyReimbursementInfoDTO> jyReimbursementInfoDTOS = jyReimbursementInfoService.queryByProjectId(projectId);
+        return ResponseEntity.ok(jyReimbursementInfoDTOS);
+    }
+
 
 
 

+ 4 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/mapper/JyReimbursementInfoMapper.java

@@ -37,4 +37,8 @@ public interface JyReimbursementInfoMapper extends BaseMapper<JyReimbursementInf
     List<JyReimbursementDetailInfoProject> getProjectDetailList(@Param("id")String id);
 
     void updateStatusById(@Param("status") String status,@Param("id") String id);
+
+    List<JyReimbursementInfoDTO> queryByProjectId(@Param("projectId") String projectId);
+
+    JyReimbursementInfoDTO getById(@Param("id") String s);
 }

+ 3 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/mapper/JyReimbursementInfoPaymentMapper.java

@@ -5,10 +5,13 @@ import com.jeeplus.business.reimbursement.domain.JyReimbursementDetailInfoBorrow
 import com.jeeplus.business.reimbursement.domain.JyReimbursementDetailInfoPayment;
 import com.jeeplus.business.reimbursement.domain.JyReimbursementDetailInfoProject;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
 @Mapper
 public interface JyReimbursementInfoPaymentMapper extends BaseMapper<JyReimbursementDetailInfoPayment> {
     List<JyReimbursementDetailInfoPayment> getList();
+
+    List<JyReimbursementDetailInfoPayment> findByProjectId(@Param("projectId") String id);
 }

+ 178 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/mapper/xml/JyReimbursementInfoMapper.xml

@@ -256,5 +256,183 @@
 		WHERE id = #{id}
 	</update>
 
+	<select id="queryByProjectId"
+			resultType="com.jeeplus.business.reimbursement.service.dto.JyReimbursementInfoDTO">
+        SELECT
+		DISTINCT a.id,
+			a.`no`,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.type_id
+			WHEN a.apply_type = 2 THEN b2.type_id
+			WHEN a.apply_type = 3 THEN b3.type_id
+									ELSE b4.type_id END) AS type_id,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.type_name
+			WHEN a.apply_type = 2 THEN b2.type_name
+			WHEN a.apply_type = 3 THEN b3.type_name
+									ELSE b4.type_name END) AS type_name,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.project_id
+			WHEN a.apply_type = 2 THEN b2.project_id
+			WHEN a.apply_type = 3 THEN b3.project_id
+									ELSE b4.project_id END) AS project_id,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.project_name
+			WHEN a.apply_type = 2 THEN b2.project_name
+			WHEN a.apply_type = 3 THEN b3.project_name
+									ELSE b4.project_name END) AS project_name,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.report_number
+			WHEN a.apply_type = 2 THEN b2.report_number
+			WHEN a.apply_type = 3 THEN b3.report_number
+									ELSE b4.report_number END) AS report_number,
+			(CASE
+			WHEN a.apply_type = 1 THEN so.name
+			WHEN a.apply_type = 2 THEN so2.name
+			WHEN a.apply_type = 3 THEN so3.name
+									ELSE so4.name END) AS dept_name,
+			(CASE
+			WHEN a.apply_type = 1 THEN us.name
+			WHEN a.apply_type = 2 THEN us2.name
+			WHEN a.apply_type = 3 THEN us3.name
+									ELSE us4.name END) AS name,
+			(CASE
+			WHEN a.apply_type = 1 THEN trim(b.`number`)
+			WHEN a.apply_type = 2 THEN trim(b2.`number`)
+			WHEN a.apply_type = 3 THEN trim(b3.`number`)
+									ELSE trim(b4.`number`) END) AS `number`,
+			c.name as createName,
+			o.name as officeName,
+			a.create_time,
+			a.status,
+			(select dv.label from sys_dict_value dv LEFT JOIN sys_dict_type dt on dt.id=dv.dict_type_id where dv.value=a.status and dt.type='program_project_list_info_status') as infoStatus,
+			a.proc_ins_id,
+			a.process_definition_id,
+			d.ID_ AS task_id,
+			a.create_by_id as createById,
+			a.apply_type
+		FROM
+			jy_reimbursement_info a
+
+			LEFT JOIN jy_reimbursement_detail_info_borrow b ON a.id = b.info_id AND b.del_flag = 0
+			left join jy_reimbursement_type_info t on b.type_id = t.id and t.del_flag = 0
+			left join jy_borrow_money p on p.id = b.project_id and p.del_flag = 0
+			left join sys_office so on so.id = b.dept_id and so.del_flag = 0
+			left join sys_user us on us.id = b.user_id and us.del_flag = 0
+
+			LEFT JOIN jy_reimbursement_detail_info_payment b2 ON a.id = b2.info_id AND b2.del_flag = 0
+			left join jy_reimbursement_type_info t2 on b2.type_id = t2.id and t2.del_flag = 0
+			left join jy_payment p2 on p2.id = b2.project_id and p2.del_flag = 0
+			left join sys_office so2 on so2.id = b2.dept_id and so2.del_flag = 0
+			left join sys_user us2 on us2.id = b2.user_id and us2.del_flag = 0
+
+			LEFT JOIN jy_reimbursement_detail_info_other b3 ON a.id = b3.info_id AND b3.del_flag = 0
+			left join jy_reimbursement_type_info t3 on b3.type_id = t3.id and t3.del_flag = 0
+			left join jy_project_record p3 on p3.id = b3.project_id and p3.del_flag = 0
+			left join sys_office so3 on so3.id = b3.dept_id and so3.del_flag = 0
+			left join sys_user us3 on us3.id = b3.user_id and us3.del_flag = 0
+
+			LEFT JOIN jy_reimbursement_detail_info_project b4 ON a.id = b4.info_id AND b4.del_flag = 0
+			left join jy_reimbursement_type_info t4 on b4.type_id = t4.id and t4.del_flag = 0
+			left join jy_project_record p4 on p4.id = b4.project_id and p4.del_flag = 0
+			left join sys_office so4 on so4.id = b4.dept_id and so4.del_flag = 0
+			left join sys_user us4 on us4.id = b4.user_id and us4.del_flag = 0
+
+			LEFT JOIN sys_user c ON a.create_by_id =  c.id
+			left join sys_user_manage_office sumo on sumo.office_id = c.office_id
+			left join sys_office o on o.id = c.office_id and o.del_flag = 0
+			LEFT JOIN act_ru_task d ON a.proc_ins_id = d.PROC_INST_ID_
+			where (find_in_set (#{projectId},b4.project_id) or find_in_set (#{projectId},b2.project_id))and a.del_flag = '0'
+		ORDER BY a.update_time DESC
+    </select>
+
+	<select id="getById" resultType="com.jeeplus.business.reimbursement.service.dto.JyReimbursementInfoDTO">
+		select distinct
+			a.id,
+			a.`no`,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.type_id
+			WHEN a.apply_type = 2 THEN b2.type_id
+			WHEN a.apply_type = 3 THEN b3.type_id
+									ELSE b4.type_id END) AS type_id,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.type_name
+			WHEN a.apply_type = 2 THEN b2.type_name
+			WHEN a.apply_type = 3 THEN b3.type_name
+									ELSE b4.type_name END) AS type_name,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.project_id
+			WHEN a.apply_type = 2 THEN b2.project_id
+			WHEN a.apply_type = 3 THEN b3.project_id
+									ELSE b4.project_id END) AS project_id,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.project_name
+			WHEN a.apply_type = 2 THEN b2.project_name
+			WHEN a.apply_type = 3 THEN b3.project_name
+									ELSE b4.project_name END) AS project_name,
+			(CASE
+			WHEN a.apply_type = 1 THEN b.report_number
+			WHEN a.apply_type = 2 THEN b2.report_number
+			WHEN a.apply_type = 3 THEN b3.report_number
+									ELSE b4.report_number END) AS report_number,
+			(CASE
+			WHEN a.apply_type = 1 THEN so.name
+			WHEN a.apply_type = 2 THEN so2.name
+			WHEN a.apply_type = 3 THEN so3.name
+									ELSE so4.name END) AS dept_name,
+			(CASE
+			WHEN a.apply_type = 1 THEN us.name
+			WHEN a.apply_type = 2 THEN us2.name
+			WHEN a.apply_type = 3 THEN us3.name
+									ELSE us4.name END) AS name,
+			(CASE
+			WHEN a.apply_type = 1 THEN trim(b.`number`)
+			WHEN a.apply_type = 2 THEN trim(b2.`number`)
+			WHEN a.apply_type = 3 THEN trim(b3.`number`)
+									ELSE trim(b4.`number`) END) AS `number`,
+			c.name as createName,
+			o.name as officeName,
+			a.create_time,
+			a.status,
+			(select dv.label from sys_dict_value dv LEFT JOIN sys_dict_type dt on dt.id=dv.dict_type_id where dv.value=a.status and dt.type='program_project_list_info_status') as infoStatus,
+			a.proc_ins_id,
+			a.process_definition_id,
+			d.ID_ AS task_id,
+			a.create_by_id as createById,
+			a.apply_type
+		FROM
+			jy_reimbursement_info a
+
+			LEFT JOIN jy_reimbursement_detail_info_borrow b ON a.id = b.info_id AND b.del_flag = 0
+			left join jy_reimbursement_type_info t on b.type_id = t.id and t.del_flag = 0
+			left join jy_borrow_money p on p.id = b.project_id and p.del_flag = 0
+			left join sys_office so on so.id = b.dept_id and so.del_flag = 0
+			left join sys_user us on us.id = b.user_id and us.del_flag = 0
+
+			LEFT JOIN jy_reimbursement_detail_info_payment b2 ON a.id = b2.info_id AND b2.del_flag = 0
+			left join jy_reimbursement_type_info t2 on b2.type_id = t2.id and t2.del_flag = 0
+			left join jy_payment p2 on p2.id = b2.project_id and p2.del_flag = 0
+			left join sys_office so2 on so2.id = b2.dept_id and so2.del_flag = 0
+			left join sys_user us2 on us2.id = b2.user_id and us2.del_flag = 0
+
+			LEFT JOIN jy_reimbursement_detail_info_other b3 ON a.id = b3.info_id AND b3.del_flag = 0
+			left join jy_reimbursement_type_info t3 on b3.type_id = t3.id and t3.del_flag = 0
+			left join jy_project_record p3 on p3.id = b3.project_id and p3.del_flag = 0
+			left join sys_office so3 on so3.id = b3.dept_id and so3.del_flag = 0
+			left join sys_user us3 on us3.id = b3.user_id and us3.del_flag = 0
+
+			LEFT JOIN jy_reimbursement_detail_info_project b4 ON a.id = b4.info_id AND b4.del_flag = 0
+			left join jy_reimbursement_type_info t4 on b4.type_id = t4.id and t4.del_flag = 0
+			left join jy_project_record p4 on p4.id = b4.project_id and p4.del_flag = 0
+			left join sys_office so4 on so4.id = b4.dept_id and so4.del_flag = 0
+			left join sys_user us4 on us4.id = b4.user_id and us4.del_flag = 0
+
+			LEFT JOIN sys_user c ON a.create_by_id =  c.id
+			left join sys_user_manage_office sumo on sumo.office_id = c.office_id
+			left join sys_office o on o.id = c.office_id and o.del_flag = 0
+			LEFT JOIN act_ru_task d ON a.proc_ins_id = d.PROC_INST_ID_
+			where b2.id = #{id} and a.del_flag = '0'
+	</select>
+
 
 </mapper>

+ 20 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/mapper/xml/JyReimbursementInfoPaymentMapper.xml

@@ -19,4 +19,24 @@
     from jy_reimbursement_detail_info_payment a
     left join jy_reimbursement_info ri on a.info_id = ri.id
     </select>
+
+    <select id="findByProjectId" resultType="com.jeeplus.business.reimbursement.domain.JyReimbursementDetailInfoPayment">
+    select
+    a.id,
+    a.create_by_id,
+    a.create_time,
+    a.del_flag,
+    a.info_id,
+    a.user_id,
+    a.dept_id,
+    a.type_id,
+    a.project_id,
+    a.report_number,
+    a.number,
+    ri.status,
+    a.payment_lower
+    from jy_reimbursement_detail_info_payment a
+    left join jy_reimbursement_info ri on a.info_id = ri.id
+    where a.project_id = #{projectId} and a.del_flag = '0' and ri.status = '5'
+    </select>
 </mapper>

+ 66 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/reimbursement/service/JyReimbursementInfoService.java

@@ -10,6 +10,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeeplus.business.payment.mapper.PaymentMapper;
+import com.jeeplus.business.payment.service.dto.PaymentDTO;
 import com.jeeplus.business.project.domain.JyProject;
 import com.jeeplus.business.project.mapper.JyProjectMapper;
 import com.jeeplus.business.project.service.JyProjectService;
@@ -31,6 +33,8 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -60,6 +64,9 @@ public class JyReimbursementInfoService {
     @Resource
     private JyProjectMapper jyProjectMapper;
 
+    @Resource
+    private PaymentMapper paymentMapper;
+
 
     /**
      * 列表查询
@@ -546,4 +553,63 @@ public class JyReimbursementInfoService {
         }
         return projects;
     }
+
+    /**
+     * 根据项目id查询报销信息
+     * @param projectId
+     * @return
+     */
+    public List<JyReimbursementInfoDTO> queryByProjectId(String projectId) {
+        //查询项目报销数据
+        List<JyReimbursementInfoDTO> list = jyReimbursementInfoMapper.queryByProjectId(projectId);
+        //若报销为多项目报销,则需要对报销金额做一个平均处理
+        if (CollectionUtils.isNotEmpty(list)){
+            for (JyReimbursementInfoDTO infoDTO : list) {
+                if (infoDTO.getProjectId() != null && infoDTO.getProjectId().contains(",")) {
+                    // 先对项目id进行切割,获取项目数量
+                    String[] ids = infoDTO.getProjectId().split(",");
+                    int totalProjects = ids.length;
+
+                    // infoDTO.getNumber()返回一个BigDecimal对象
+                    BigDecimal originalNumber = infoDTO.getNumber();
+                    if (originalNumber != null) {
+                        // 对报销金额做平均处理
+                        BigDecimal size = BigDecimal.valueOf(totalProjects);
+                        // 使用setScale方法来保留两位小数,并四舍五入
+                        BigDecimal finalNumber = originalNumber.divide(size, 2, RoundingMode.HALF_UP);
+                        infoDTO.setNumber(finalNumber);
+                    }
+                }
+            }
+        }
+
+
+        //存放报销冲抵完成的集合
+        ArrayList<JyReimbursementInfoDTO> successList = new ArrayList<>();
+        //根据项目id查找付款信息
+        List<PaymentDTO> paymentDTOList = paymentMapper.queryByProjectId(projectId);
+        if (CollectionUtils.isNotEmpty(paymentDTOList)){
+            for (PaymentDTO paymentDTO : paymentDTOList) {
+                //付款金额
+                BigDecimal payment = new BigDecimal(paymentDTO.getPaymentLower());
+                //根据付款id查询报销信息
+                List<JyReimbursementInfoDTO> payReimList = jyReimbursementInfoMapper.queryByProjectId(paymentDTO.getId());
+                BigDecimal total = BigDecimal.ZERO;
+                if (CollectionUtils.isNotEmpty(payReimList)){
+                    //将所有的报销金额汇总
+                    for (JyReimbursementInfoDTO reim : payReimList) {
+                        BigDecimal originalNumber = reim.getNumber();
+                        total = total.add(originalNumber);
+                    }
+                }
+                //判断报销总金额与付款金额是否冲抵完成
+                if (payment.equals(total)){
+                    list.addAll(payReimList);
+                }
+            }
+        }
+        //去重,避免有重复的数据
+        List<JyReimbursementInfoDTO> infoDTOList = list.stream().distinct().collect(Collectors.toList());
+        return infoDTOList;
+    }
 }

+ 6 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/domain/Signet.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import com.jeeplus.core.domain.BaseEntity;
 import lombok.Data;
 
+import java.util.Date;
 import java.util.List;
 
 @Data
@@ -73,6 +74,11 @@ public class Signet extends BaseEntity {
     private String exceedTimeStatus;
 
     /**
+     * 审核通过时间
+     */
+    private Date approvalTime;
+
+    /**
      * 外审id
      */
     @TableField(exist = false)

+ 2 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/mapper/SignetMapper.java

@@ -35,4 +35,6 @@ public interface SignetMapper extends BaseMapper<Signet> {
 
     @InterceptorIgnore(tenantLine = "true")
     void updateStatusBySealId(String id);
+
+    SignetDTO getByProjectId(@Param("projectId") String projectId);
 }

+ 31 - 1
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/mapper/xml/SignetMapper.xml

@@ -138,6 +138,36 @@
             jy_user_signet
         set status='6' , exceed_time_status ='1' where id=#{id}
     </update>
-
+    <select id="getByProjectId" resultType="com.jeeplus.business.useSeal.service.dto.SignetDTO">
+        select
+            a.id,
+            a.create_by_id,
+            a.update_by_id,
+            a.update_time,
+            a.approval_time,
+            su.name as createByName,
+            a.create_time as createDate,
+            a.project_id,
+            a.project_name,
+            a.no,
+            a.type,
+            a.first_type,
+            a.number,
+            a.status,
+            a.remarks,
+            a.proc_ins_id,
+            a.type_status,
+            a.process_definition_id,
+            so.name as office,
+            so.id,
+            art.ID_ as task_id
+            from  jy_user_signet a
+            left join sys_user su on a.create_by_id = su.id
+            left join sys_office so on su.office_id=so.id
+            left join act_ru_task art ON a.proc_ins_id = art.PROC_INST_ID_
+            where (FIND_IN_SET(#{projectId},a.project_id) or a.project_id = #{projectId})
+                and a.type = (select dv.id from sys_dict_value dv where a.type=dv.id)
+                and a.status in ('5')
+    </select>
 
 </mapper>

+ 9 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/service/SignetService.java

@@ -438,6 +438,8 @@ public class SignetService {
      * @param status
      */
     public void updateStatusById(String id,String status) {
+        //当前登录人
+        UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken());
         signetMapper.updateStatusById(id,status);
         if (status.equals("5")){
             SignetDTO signetDTO = signetMapper.findById(id);
@@ -453,6 +455,13 @@ public class SignetService {
                     }
                 }
             }
+            //修改审核通过的时间
+            Signet signet = new Signet();
+            signet.setId(signetDTO.getId());
+            signet.setApprovalTime(new Date());
+            signet.setUpdateById(userDTO.getId());
+            signet.setUpdateTime(new Date());
+            signetMapper.updateById(signet);
         }
 
     }

+ 5 - 0
jeeplus-modules/jeeplus-business/src/main/java/com/jeeplus/business/useSeal/service/dto/SignetDTO.java

@@ -32,6 +32,11 @@ public class SignetDTO  {
     private String id;
 
     /**
+     * 审核通过时间
+     */
+    private Date approvalTime;
+
+    /**
      * 用印编号
      */
     @Excel(name = "用印编号",width = 16)

+ 37 - 16
jeeplus-modules/jeeplus-business/src/main/resources/freemarker/firstAudit.ftl

@@ -1630,7 +1630,7 @@
 								</w:rPr>
 							</w:pPr>
 						</w:p>
-						<w:p wsp:rsidR="00F6191F" wsp:rsidRPr="00D86B2B" wsp:rsidRDefault="00D86B2B" wsp:rsidP="00D86B2B">
+						<w:p wsp:rsidR="00342111" wsp:rsidRPr="00BE6408" wsp:rsidRDefault="00000000" wsp:rsidP="00BE6408">
 							<w:pPr>
 								<w:spacing w:before="130" w:line="219" w:line-rule="auto"/>
 								<w:ind w:left="125"/>
@@ -2093,7 +2093,7 @@
 									<w:sz w:val="23"/>
 									<w:sz-cs w:val="23"/>
 								</w:rPr>
-								<w:t>       </w:t>
+								<w:t>      </w:t>
 							</w:r>
 							<w:r wsp:rsidRPr="00D86B2B">
 								<w:rPr>
@@ -2119,14 +2119,16 @@
 								<w:rPr>
 									<w:rFonts w:ascii="宋体" w:fareast="宋体" w:h-ansi="宋体" w:cs="宋体" w:hint="fareast"/>
 									<wx:font wx:val="宋体"/>
+									<w:sz w:val="25"/>
+									<w:sz-cs w:val="25"/>
 								</w:rPr>
-								<w:t>       </w:t>
+								<w:t>  </w:t>
 							</w:r>
 							<w:r wsp:rsidRPr="00D86B2B">
 								<w:rPr>
 									<w:rFonts w:fareast="宋体" w:hint="fareast"/>
 								</w:rPr>
-								<w:t>   </w:t>
+								<w:t> </w:t>
 							</w:r>
 						</w:p>
 					</w:tc>
@@ -2177,8 +2179,7 @@
 						<w:p wsp:rsidR="00F6191F" wsp:rsidRPr="00D86B2B" wsp:rsidRDefault="00D86B2B" wsp:rsidP="00D86B2B">
 							<w:pPr>
 								<w:spacing w:before="162" w:line="220" w:line-rule="auto"/>
-								<w:ind w:left="84"/>
-								<w:jc w:val="center"/>
+								<w:jc w:val="both"/>
 								<w:rPr>
 									<w:rFonts w:ascii="宋体" w:fareast="宋体" w:h-ansi="宋体" w:cs="宋体"/>
 									<wx:font wx:val="宋体"/>
@@ -2187,15 +2188,35 @@
 									<w:sz-cs w:val="25"/>
 								</w:rPr>
 							</w:pPr>
-							<w:r wsp:rsidRPr="00D86B2B">
-								<w:rPr>
-									<w:rFonts w:ascii="宋体" w:fareast="宋体" w:h-ansi="宋体" w:cs="宋体" w:hint="fareast"/>
-									<wx:font wx:val="宋体"/>
-									<w:spacing w:val="13"/>
-									<w:sz w:val="25"/>
-									<w:sz-cs w:val="25"/>
-								</w:rPr>
-								<w:t>${submitPeople}</w:t>
+							<w:r>
+								<w:rPr>
+									<w:noProof/>
+								</w:rPr>
+								<w:pict>
+									<v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">
+										<v:stroke joinstyle="miter"/>
+										<v:formulas>
+											<v:f eqn="if lineDrawn pixelLineWidth 0"/>
+											<v:f eqn="sum @0 1 0"/>
+											<v:f eqn="sum 0 0 @1"/>
+											<v:f eqn="prod @2 1 2"/>
+											<v:f eqn="prod @3 21600 pixelWidth"/>
+											<v:f eqn="prod @3 21600 pixelHeight"/>
+											<v:f eqn="sum @0 0 1"/>
+											<v:f eqn="prod @6 1 2"/>
+											<v:f eqn="prod @7 21600 pixelWidth"/>
+											<v:f eqn="sum @8 21600 0"/>
+											<v:f eqn="prod @7 21600 pixelHeight"/>
+											<v:f eqn="sum @10 21600 0"/>
+										</v:formulas>
+										<v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/>
+										<o:lock v:ext="edit" aspectratio="t"/>
+									</v:shapetype>
+									<w:binData w:name="wordml://03000001.png" xml:space="preserve">${submitPeople}</w:binData>
+									<v:shape id="图片 1" o:spid="_x0000_s1026" type="#_x0000_t75" style="position:absolute;left:0;text-align:left;margin-left:8.9pt;margin-top:4.85pt;width:90.55pt;height:44.05pt;z-index:-1;visibility:visible;mso-wrap-style:square;mso-wrap-distance-left:9pt;mso-wrap-distance-top:0;mso-wrap-distance-right:9pt;mso-wrap-distance-bottom:0;mso-position-horizontal:absolute;mso-position-horizontal-relative:text;mso-position-vertical:absolute;mso-position-vertical-relative:text">
+										<v:imagedata src="wordml://03000001.png" o:title=""/>
+									</v:shape>
+								</w:pict>
 							</w:r>
 						</w:p>
 					</w:tc>
@@ -2275,4 +2296,4 @@
 			</w:sectPr>
 		</wx:sect>
 	</w:body>
-</w:wordDocument>
+</w:wordDocument>

+ 31 - 17
jeeplus-modules/jeeplus-flowable/src/main/java/com/jeeplus/modules/flowable/listener/JyProjectArchiveListener.java

@@ -10,8 +10,10 @@ import com.jeeplus.flowable.service.FlowTaskService;
 import com.jeeplus.flowable.service.MyNoticeService;
 import com.jeeplus.flowable.utils.StringUtils;
 import com.jeeplus.sys.feign.IOfficeApi;
+import com.jeeplus.sys.feign.IRoleApi;
 import com.jeeplus.sys.feign.IUserApi;
 import com.jeeplus.sys.service.dto.OfficeDTO;
+import com.jeeplus.sys.service.dto.RoleDTO;
 import com.jeeplus.sys.service.dto.UserDTO;
 import lombok.SneakyThrows;
 import org.flowable.engine.RuntimeService;
@@ -22,6 +24,7 @@ import org.springframework.stereotype.Component;
 
 
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.List;
 
 @Component("JyProjectArchiveListener")
@@ -72,13 +75,28 @@ public class JyProjectArchiveListener implements ExecutionListener {
                 }
 
                 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-
+                //用于存放被抄送人
+                ArrayList<UserDTO> list = new ArrayList<>();
+                //创建人
                 UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getById(flow.getAssigneeId());
                 //获取嘉溢所有人员信息
                 List<UserDTO> allUserInfo = SpringUtil.getBean(IUserApi.class).findListByCompanyId(userDTO.getCompanyDTO().getId());
                 String finalTitleName = titleName;
+                //获取市场部下的所有员工信息
+                OfficeDTO officeDTO = SpringUtil.getBean(IOfficeApi.class).getOfficeDTOByName("市场部");
+                List<UserDTO> listByOfficeId = SpringUtil.getBean(IUserApi.class).findListByOfficeId(officeDTO.getId());
+                for (UserDTO dto : listByOfficeId) {
+                    list.add(dto);
+                }
+                //获取总经理
+                RoleDTO roleDTO = SpringUtil.getBean(IRoleApi.class).getRoleDTOByName("总经理");
+                List<UserDTO> listByRoleId = SpringUtil.getBean(IUserApi.class).findListByRoleId(roleDTO.getId());
+                for (UserDTO dto : listByRoleId) {
+                    list.add(dto);
+                }
                 //将项目信息抄送给分管领导
                 for (UserDTO dto : allUserInfo) {
+                    //分管领导
                     if (StringUtils.isNotBlank(dto.getManageOfficeIds())){
                         String manageOfficeIds = dto.getManageOfficeIds();
                         if (manageOfficeIds.contains(",")){
@@ -87,29 +105,25 @@ public class JyProjectArchiveListener implements ExecutionListener {
                             for (String s : split) {
                                 //判断分管部门与项目创建人所在的部门是否一致
                                 if (s.equals(userDTO.getOfficeDTO().getId())) {
-                                    FlowCopy flowCopy = new FlowCopy();
-                                    flowCopy.setProcDefId(task.getProcDefId());
-                                    flowCopy.setProcInsName(finalTitleName);
-                                    flowCopy.setProcInsId(task.getProcInstId());
-                                    flowCopy.setUserId(dto.getId());
-                                    //将项目信息进行抄送
-                                    SpringUtil.getBean(FlowCopyService.class).save(flowCopy);
+                                    list.add(dto);
                                 }
                             }
                         }else {
                             if (manageOfficeIds.equals(userDTO.getOfficeDTO().getId())) {
-                                FlowCopy flowCopy = new FlowCopy();
-                                flowCopy.setProcDefId(task.getProcDefId());
-                                flowCopy.setProcInsName(finalTitleName);
-                                flowCopy.setProcInsId(task.getProcInstId());
-                                flowCopy.setUserId(dto.getId());
-                                //将项目信息进行抄送
-                                SpringUtil.getBean(FlowCopyService.class).save(flowCopy);
+                                list.add(dto);
                             }
                         }
-
                     }
-
+                }
+                //将集合中的人员发送抄送信息
+                for (UserDTO user : list) {
+                    FlowCopy flowCopy = new FlowCopy();
+                    flowCopy.setProcDefId(task.getProcDefId());
+                    flowCopy.setProcInsName(finalTitleName);
+                    flowCopy.setProcInsId(task.getProcInstId());
+                    flowCopy.setUserId(user.getId());
+                    //将项目信息进行抄送
+                    SpringUtil.getBean(FlowCopyService.class).save(flowCopy);
                 }
 
 

+ 4 - 0
jeeplus-modules/jeeplus-system/src/main/java/com/jeeplus/sys/mapper/xml/UserMapper.xml

@@ -27,6 +27,8 @@
         <result property="officeDTO.name" column="officeDTO.name"/>
         <result property="officeDTO.isPublic" column="officeDTO.isPublic"/>
         <result property="officeDTO.parentIds" column="officeDTO.parentIds"/>
+        <result property="handSignatureUrl" column="hand_signature_url"/>
+        <result property="isHandSignature" column="is_hand_signature"/>
         <collection property="roleDTOList" javaType="java.util.List" ofType="com.jeeplus.sys.service.dto.RoleDTO">
             <id property="id" column="roleDTO.id"/>
             <result property="name" column="roleDTO.name"/>
@@ -65,6 +67,8 @@
 		a.create_time,
 		a.update_by_id AS "updateBy.id",
 		a.manage_office_ids AS "manageOfficeIds",
+		a.hand_signature_url,
+		a.is_hand_signature,
 		a.update_time,
     	c.name AS "companyDTO.name",
     	c.parent_id AS "companyDTO.parent.id",

+ 5 - 0
jeeplus-modules/jeeplus-system/src/main/java/com/jeeplus/sys/service/UserService.java

@@ -349,6 +349,11 @@ public class UserService extends ServiceImpl <UserMapper, User> {
         if(StringUtils.isNotBlank(userDTO.getManageOfficeIds())){
             user.setManageOfficeIds(userDTO.getManageOfficeIds());
         }
+        //是否有手签章
+        if (StringUtils.isNotBlank(userDTO.getHandSignatureUrl())){
+            user.setHandSignatureUrl(userDTO.getHandSignatureUrl());
+            user.setIsHandSignature("1");
+        }
         super.saveOrUpdate ( user );
         // 更新用户与角色关联
         baseMapper.deleteUserRole ( userDTO.getId ( ) );