Przeglądaj źródła

财务-报销审批

wangqiang 2 lat temu
rodzic
commit
fa6f255b34
20 zmienionych plików z 1807 dodań i 0 usunięć
  1. 133 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/controller/CwReimbursementInfoController.java
  2. 45 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/domain/CwReimbursementAmountInfo.java
  3. 85 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/domain/CwReimbursementDetailInfo.java
  4. 66 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/domain/CwReimbursementInfo.java
  5. 11 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/mapper/CwReimbursementAmountInfoMapper.java
  6. 11 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/mapper/CwReimbursementDetailInfoMapper.java
  7. 40 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/mapper/CwReimbursementInfoMapper.java
  8. 247 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/mapper/xml/CwReimbursementInfoMapper.xml
  9. 413 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/CwReimbursementInfoService.java
  10. 53 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/dto/QueryListDto.java
  11. 100 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/dto/RetureListDto.java
  12. 75 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/dto/SaveInfoDto.java
  13. 19 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/dto/TreeUserDto.java
  14. 93 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/controller/CwReimbursementTypeController.java
  15. 85 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/domain/CwReimbursementTypeInfo.java
  16. 25 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/mapper/CwReimbursementTypeMapper.java
  17. 32 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/mapper/xml/CwReimbursementTypeMapper.xml
  18. 116 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/service/CwReimbursementTypeForTreeDataService.java
  19. 137 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/service/CwReimbursementTypeService.java
  20. 21 0
      jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/service/dto/CwReimbursementTypeDto.java

+ 133 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/controller/CwReimbursementInfoController.java

@@ -0,0 +1,133 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeeplus.common.utils.ResponseUtil;
+import com.jeeplus.core.excel.utils.EasyPoiUtil;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.CwReimbursementInfoService;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.QueryListDto;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.RetureListDto;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.SaveInfoDto;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.TreeUserDto;
+import com.jeeplus.test.program.configuration.projectList.domain.ProgramProjectListInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.http.ResponseEntity;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-24 16:44
+ **/
+@RestController
+@Api(tags ="财务-报销申请")
+@RequestMapping(value = "/reimbursementApproval/info")
+public class CwReimbursementInfoController {
+
+    @Resource
+    private CwReimbursementInfoService service;
+
+    /**
+     * 列表查询
+     * @param dto
+     * @return
+     */
+    @ApiOperation(value = "列表查询")
+    @GetMapping("/list")
+    public ResponseEntity<IPage<RetureListDto>> list(Page<RetureListDto> page, QueryListDto dto) throws Exception{
+        IPage<RetureListDto> iPage = service.list(page, dto);
+        return ResponseEntity.ok(iPage);
+    }
+
+    /**
+     * 项目登记列表
+     * @param info
+     * @param page
+     * @return
+     * @throws Exception
+     */
+    @ApiOperation(value = "项目登记列表")
+    @GetMapping(value = "/projectList")
+    public ResponseEntity<IPage<ProgramProjectListInfo>> projectList(ProgramProjectListInfo info, Page<ProgramProjectListInfo> page) throws Exception {
+        IPage<ProgramProjectListInfo> list = service.projectList(page, info, "1");
+        return ResponseEntity.ok (list);
+    }
+
+    /**
+     * 新增/修改
+     * @param dto
+     * @return
+     */
+    @ApiOperation(value = "新增、修改")
+    @PostMapping("/save")
+    public ResponseEntity<String> save(@RequestBody SaveInfoDto dto) throws Exception{
+        String s = service.save(dto);
+        return ResponseUtil.newInstance().add("businessTable", "cw_reimbursement_info").add("businessId", s).ok ("操作成功");
+    }
+
+    /**
+     * 删除
+     * @param id
+     * @return
+     */
+    @ApiOperation(value = "删除")
+    @GetMapping("/remove")
+    public ResponseEntity<String> remove(@RequestParam String id){
+        String s = service.remove(id);
+        return ResponseEntity.ok(s);
+    }
+
+    /**
+     * 查询
+     * @param id
+     * @return
+     */
+    @ApiOperation(value = "查询")
+    @GetMapping("/findById")
+    public ResponseEntity<SaveInfoDto> findById(@RequestParam String id) throws Exception{
+        SaveInfoDto dto = service.findById(id);
+        return ResponseEntity.ok(dto);
+    }
+
+    @ApiOperation(value = "发票号判断")
+    @GetMapping("/checkNumber")
+    public ResponseEntity<Boolean> checkNumber(@RequestParam String number) {
+        Boolean is = service.checkNumber(number);
+        return ResponseEntity.ok(is);
+    }
+
+    /**
+     * 根据id修改状态status
+     */
+    @ApiOperation(value = "根据id修改状态status")
+    @PostMapping(value = "updateStatusById")
+    public void updateStatusById(@RequestBody RetureListDto dto) {
+        service.updateStatusById(dto);
+    }
+
+    @ApiOperation(value = "用户树形")
+    @GetMapping(value = "/userTree")
+    public ResponseEntity<List<TreeUserDto>> userTree(@RequestParam String name) {
+        List<TreeUserDto> list = service.userTree(name);
+        return ResponseEntity.ok(list);
+    }
+
+    @ApiOperation(value = "文件下载")
+    @GetMapping(value = "/exportFile")
+    public void exportFileUploadList(QueryListDto dto, HttpServletResponse response) throws Exception {
+        List<RetureListDto> infos = service.exportList(dto);
+        EasyPoiUtil.exportExcel(infos, "报销申请列表信息",  "报销申请列表信息", RetureListDto.class, "", response );
+    }
+
+    @ApiOperation(value = "关联报销")
+    @GetMapping(value = "/relationReimbursementList")
+    public ResponseEntity<IPage<RetureListDto>> relationReimbursementList(Page<RetureListDto> page, @RequestParam("id") String id) {
+        IPage<RetureListDto> listDtoIPage = service.relationReimbursementList(page, id);
+        return ResponseEntity.ok(listDtoIPage);
+    }
+
+}

+ 45 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/domain/CwReimbursementAmountInfo.java

@@ -0,0 +1,45 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import lombok.Data;
+
+/**
+ * 财务-报销专用发票信息表
+ * @author: 王强
+ * @create: 2022-11-24 15:49
+ **/
+@Data
+@TableName(value = "cw_reimbursement_amount_info")
+public class CwReimbursementAmountInfo extends BaseEntity {
+
+    /**
+     * 关联id
+     */
+    private String infoId;
+
+    /**
+     * 发票代码
+     */
+    private String code;
+
+    /**
+     * 发票编号
+     */
+    private String number;
+
+    /**
+     * 金额
+     */
+    private String amount;
+
+    /**
+     * 税额
+     */
+    private String taxAmount;
+
+    /**
+     * 价税合计
+     */
+    private String count;
+}

+ 85 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/domain/CwReimbursementDetailInfo.java

@@ -0,0 +1,85 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.jeeplus.core.domain.BaseEntity;
+import lombok.Data;
+
+/**
+ * 财务-报销详情信息表
+ * @author: 王强
+ * @create: 2022-11-24 15:51
+ **/
+@Data
+@TableName(value = "cw_reimbursement_detail_info")
+public class CwReimbursementDetailInfo extends BaseEntity {
+
+    /**
+     * 关联id
+     */
+    private String infoId;
+
+    /**
+     * 报销人
+     */
+    private String userId;
+
+    /**
+     * 报销人名称
+     */
+    private String userName;
+
+    /**
+     * 报销部门
+     */
+    private String deptId;
+
+    /**
+     * 报销部门名称
+     */
+    private String deptName;
+
+    /**
+     * 报销类型
+     */
+    private String typeId;
+
+    /**
+     * 报销类型名称
+     */
+    private String typeName;
+
+    /**
+     * 报销项目
+     */
+    private String projectId;
+
+    /**
+     * 报销项目名称
+     */
+    private String projectName;
+
+    /**
+     * 报告号
+     */
+    private String reportNumber;
+
+    /**
+     * 费用(元)
+     */
+    private String number;
+
+    /**
+     * 收据张数
+     */
+    private Integer receiptNumber;
+
+    /**
+     * 出差天数
+     */
+    private Integer days;
+
+    /**
+     * 内容
+     */
+    private String content;
+}

+ 66 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/domain/CwReimbursementInfo.java

@@ -0,0 +1,66 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.jeeplus.core.domain.BaseEntity;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 财务-报销单基础信息表
+ * @author: 王强
+ * @create: 2022-11-24 15:55
+ **/
+@Data
+@TableName(value = "cw_reimbursement_info")
+public class CwReimbursementInfo extends BaseEntity {
+
+    /**
+     * 经办人id
+     */
+    private String userId;
+
+    /**
+     * 经办人名称
+     */
+    private String userName;
+
+    /**
+     * 报销编号
+     */
+    private String no;
+
+    /**
+     * 所属部门
+     */
+    private String department;
+
+    /**
+     * 报销日期
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
+    private Date reimDate;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 状态
+     */
+    private String type;
+
+    /**
+     * 流程id
+     */
+    private String procInsId;
+
+    /**
+     *
+     */
+    private String processDefinitionId;
+}

+ 11 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/mapper/CwReimbursementAmountInfoMapper.java

@@ -0,0 +1,11 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain.CwReimbursementAmountInfo;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-24 16:25
+ **/
+public interface CwReimbursementAmountInfoMapper extends BaseMapper<CwReimbursementAmountInfo>  {
+}

+ 11 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/mapper/CwReimbursementDetailInfoMapper.java

@@ -0,0 +1,11 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain.CwReimbursementDetailInfo;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-24 16:31
+ **/
+public interface CwReimbursementDetailInfoMapper extends BaseMapper<CwReimbursementDetailInfo> {
+}

+ 40 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/mapper/CwReimbursementInfoMapper.java

@@ -0,0 +1,40 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain.CwReimbursementInfo;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.RetureListDto;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.TreeUserDto;
+import com.jeeplus.test.program.configuration.projectList.domain.ProgramProjectListInfo;
+import com.jeeplus.test.workContract.service.dto.WorkAttachmentDto;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-24 16:09
+ **/
+public interface CwReimbursementInfoMapper extends BaseMapper<CwReimbursementInfo> {
+
+    IPage<ProgramProjectListInfo> findProjectList(Page<ProgramProjectListInfo> page, @Param(Constants.WRAPPER) QueryWrapper<ProgramProjectListInfo> wrapper);
+
+    String selectInvoiceFlag(@Param("id") String id);
+
+    IPage<RetureListDto> findList (Page<RetureListDto> page, @Param(Constants.WRAPPER) QueryWrapper queryWrapper);
+
+    List<WorkAttachmentDto> findFiles(@Param("id") String id);
+
+    void updateStatusById(@Param("id") String id, @Param("type") String type);
+
+    List<TreeUserDto> findOfficeList();
+
+    List<TreeUserDto> findUserList(@Param("name") String name);
+
+    List<RetureListDto> findExportList (@Param(Constants.WRAPPER) QueryWrapper queryWrapper);
+
+    IPage<RetureListDto> relationReimbursementList (Page<RetureListDto> page, @Param("id") String id);
+}

+ 247 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/mapper/xml/CwReimbursementInfoMapper.xml

@@ -0,0 +1,247 @@
+<?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.jeeplus.test.cw.reimbursementApproval.approvalInfo.mapper.CwReimbursementInfoMapper">
+	<update id="updateStatusById">
+		UPDATE cw_reimbursement_info SET type = #{type}
+		<if test="type == '3'.toString">
+			, proc_ins_id = NULL, process_definition_id = NULL
+		</if>
+		WHERE id = #{id}
+	</update>
+
+
+	<select id="findList"
+            resultType="com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.RetureListDto">
+        SELECT
+			a.id,
+			a.`no`,
+			b.type_id,
+			b.type_name,
+			b.project_id,
+			b.project_name,
+			b.report_number,
+			a.user_name,
+			b.user_name AS `name`,
+			b.dept_name,
+			a.reim_date,
+			b.`number`,
+			a.type,
+			a.proc_ins_id,
+			a.process_definition_id,
+			d.ID_ AS task_id
+		FROM
+			cw_reimbursement_info a
+			LEFT JOIN cw_reimbursement_detail_info b ON a.id = b.info_id AND b.del_flag = 0
+			LEFT JOIN sys_user c ON a.create_by =  c.id
+			LEFT JOIN act_ru_task d ON a.proc_ins_id = d.PROC_INST_ID_
+			${ew.customSqlSegment}
+		ORDER BY a.update_date DESC
+    </select>
+	<select id="findFiles" resultType="com.jeeplus.test.workContract.service.dto.WorkAttachmentDto">
+		SELECT
+			id,
+			url,
+			attachment_name AS `name`,
+			create_by AS `by`,
+			create_date
+		FROM
+			work_attachment
+		WHERE
+			del_flag = 0
+			AND attachment_id = #{id}
+	</select>
+	<select id="findOfficeList"
+			resultType="com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.TreeUserDto">
+		SELECT id,`name`,parent_id FROM sys_office WHERE del_flag = 0
+	</select>
+	<select id="findUserList"
+			resultType="com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.TreeUserDto">
+		SELECT
+		a.id,
+		a.`name`,
+		a.office_id AS parent_id,
+		b.`name` AS office_name,
+		true AS is_user
+		FROM
+		sys_user a
+		LEFT JOIN sys_office b ON a.office_id = b.id
+		WHERE
+		a.del_flag = 0
+		<if test="name != null and name != ''">
+			a.`name` LIKE CONCAT ('%', #{name}, '%')
+		</if>
+	</select>
+	<select id="findExportList"
+			resultType="com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.RetureListDto">
+		SELECT
+			a.id,
+			a.`no`,
+			b.type_id,
+			b.type_name,
+			b.project_id,
+			b.project_name,
+			b.report_number,
+			a.user_name,
+			b.user_name AS `name`,
+			b.dept_name,
+			a.reim_date,
+			b.`number`,
+			a.type,
+			a.proc_ins_id,
+			a.process_definition_id,
+			d.ID_ AS task_id
+		FROM
+			cw_reimbursement_info a
+			LEFT JOIN cw_reimbursement_detail_info b ON a.id = b.info_id AND b.del_flag = 0
+			LEFT JOIN sys_user c ON a.create_by =  c.id
+			LEFT JOIN act_ru_task d ON a.proc_ins_id = d.PROC_INST_ID_
+			${ew.customSqlSegment}
+		ORDER BY a.update_date DESC
+	</select>
+	<select id="relationReimbursementList"
+			resultType="com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.RetureListDto">
+		SELECT
+			a.id,
+			a.`no`,
+			b.type_id,
+			b.type_name,
+			b.project_id,
+			b.project_name,
+			b.report_number,
+			a.user_name,
+			b.user_name AS `name`,
+			b.dept_name,
+			a.reim_date,
+			b.`number`,
+			a.type,
+			a.proc_ins_id,
+			a.process_definition_id,
+			d.ID_ AS task_id
+		FROM
+			cw_reimbursement_info a
+			LEFT JOIN cw_reimbursement_detail_info b ON a.id = b.info_id AND b.del_flag = 0
+			LEFT JOIN sys_user c ON a.create_by =  c.id
+			LEFT JOIN act_ru_task d ON a.proc_ins_id = d.PROC_INST_ID_
+		WHERE
+			a.del_flag = 0
+			AND a.project_id IN (SELECT id FROM program_project_list_info WHERE del_flag = 0 AND contract_id = #{id})
+		ORDER BY a.update_date DESC
+	</select>
+    <select id="findProjectList"
+            resultType="com.jeeplus.test.program.configuration.projectList.domain.ProgramProjectListInfo">
+		SELECT
+           a.id,
+           b.name AS create_by,
+           b.office_id,
+           a.create_date,
+           a.update_by,
+           a.update_date,
+           a.del_flag,
+           a.contract_id,
+           a.contract_name,
+           a.client,
+           a.client_name,
+           a.amount,
+           a.contract_type,
+           a.name,
+           a.no,
+           a.project_type,
+           a.approval_no,
+           a.company,
+           a.project_mould,
+           a.property_holder,
+           a.property_holder_name,
+           a.location,
+           a.is_first,
+           a.year_num,
+           a.check_year,
+           a.project_manager,
+           c.name AS project_manager_name,
+           a.report_type,
+           a.industry,
+           a.enterprise_type,
+           a.risk_level,
+           a.project_source,
+           a.estimate,
+           a.plan_end_time,
+           a.use_num,
+           a.appointment,
+           a.work_hours,
+           a.remarks,
+           a.assessment_enterprise,
+           a.assessment_enterprise_name,
+           a.link_num,
+           a.relationship,
+           a.assessment_way,
+           a.assessment_objective,
+           a.assessment_date,
+           a.num,
+           a.project_development,
+           a.delegate_project_type,
+           a.assessment_object,
+           a.work_begin_date,
+           a.work_end_date,
+           a.reporting_date,
+           a.is_have,
+           a.is_influence,
+           a.mode,
+           a.status,
+           a.proc_ins_id,
+           a.process_definition_id,
+           prn.report_no,
+           pa1.status as status1,
+           pa1.id as auditId1,
+           pa1.proc_ins_id as procInsId1,
+           pa2.status as status2,
+           pa2.id as auditId2,
+           pa2.proc_ins_id as procInsId2,
+           pa3.status as status3,
+           pa3.id as auditId3,
+           pa3.proc_ins_id as procInsId3,
+           pa.status as archive_status,
+           pa.id as archive_id,
+           pa.proc_ins_id as procInsIdArchive,
+           d.id AS issued_id,
+           d.proc_ins_id AS procInsId4,
+           d.status AS issued_status,
+           wci.no AS contract_no
+        FROM
+            program_project_list_info a
+            LEFT JOIN sys_user b ON a.create_by = b.id
+            LEFT JOIN sys_user c ON a.project_manager = c.id
+            LEFT JOIN work_contract_info wci ON wci.id = a.contract_id and wci.del_flag = '0'
+            LEFT JOIN program_report_no prn ON prn.program_id = a.id and prn.del_flag = '0'
+            LEFT JOIN program_audit pa1 ON pa1.program_id = a.id and pa1.audit_level = '1' and pa1.del_flag = '0'
+            LEFT JOIN program_audit pa2 ON pa2.program_id = a.id and pa2.audit_level = '2' and pa2.del_flag = '0'
+            LEFT JOIN program_audit pa3 ON pa3.program_id = a.id and pa3.audit_level = '3' and pa3.del_flag = '0'
+            LEFT JOIN program_archive pa ON pa.program_id = a.id and pa.del_flag = '0'
+            LEFT JOIN proofread_issued d ON a.id = d.project_id
+            ${ew.customSqlSegment}
+            ORDER BY a.update_date DESC
+	</select>
+	<select id="selectInvoiceFlag" resultType="java.lang.String">
+		select
+         case
+             when ff.status = '1' then '开票中'
+             when ff.status = '2' then '开票中'
+             when ff.status = '3' then '开票中'
+             when ff.status = '4' then '开票中'
+             when ff.status = '5' then '已开票'
+             when ff.status = '6' then '已开票'
+             when ff.status = '7' then '已开票'
+             when ff.status = '8' then '已开票'
+         else '' end
+        from
+        (select
+        fib.program_name as program_name,
+        fi.`status` as status,
+        fib.program_id as program_id,
+        fi.create_date as create_date
+        from finance_invoice_base fib
+        inner join finance_invoice fi on fi.id = fib.invoice_id and fi.del_flag = '0'
+        where fib.del_flag = '0' and fi.status != '9'
+        order by fi.create_date desc) ff
+        where ff.program_id = #{id}
+        limit 1
+	</select>
+</mapper>

+ 413 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/CwReimbursementInfoService.java

@@ -0,0 +1,413 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service;
+
+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.extension.plugins.pagination.Page;
+import com.jeeplus.core.query.QueryWrapperGenerator;
+import com.jeeplus.sys.service.dto.UserDTO;
+import com.jeeplus.sys.utils.StringUtils;
+import com.jeeplus.sys.utils.UserUtils;
+import com.jeeplus.test.cw.contractRegistration.service.ContractInfoService;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain.CwReimbursementAmountInfo;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain.CwReimbursementDetailInfo;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain.CwReimbursementInfo;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.mapper.CwReimbursementAmountInfoMapper;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.mapper.CwReimbursementDetailInfoMapper;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.mapper.CwReimbursementInfoMapper;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.QueryListDto;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.RetureListDto;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.SaveInfoDto;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto.TreeUserDto;
+import com.jeeplus.test.mould.service.SerialnumTplService;
+import com.jeeplus.test.oss.domain.WorkAttachment;
+import com.jeeplus.test.oss.mapper.OssServiceMapper;
+import com.jeeplus.test.program.configuration.projectList.domain.ProgramProjectListInfo;
+import com.jeeplus.test.workContract.service.dto.WorkAttachmentDto;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-24 16:11
+ **/
+@Service
+public class CwReimbursementInfoService {
+
+    @Resource
+    private CwReimbursementInfoMapper infoMapper;
+
+    @Resource
+    private CwReimbursementDetailInfoMapper detailInfoMapper;
+
+    @Resource
+    private CwReimbursementAmountInfoMapper amountInfoMapper;
+
+    @Resource
+    private OssServiceMapper ossServiceMapper;
+
+    @Resource
+    private SerialnumTplService serialnumTplService;
+
+    @Resource
+    private ContractInfoService infoService;
+
+    /**
+     * 列表查询
+     */
+    public IPage<RetureListDto> list(Page<RetureListDto> page , QueryListDto dto) throws Exception{
+        QueryWrapper<QueryListDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, QueryListDto.class);
+        /**
+         * a表是reimbursementInfo
+         * b表是reimbursementDetailInfo
+         * c表是sysUser
+         */
+        queryWrapper.eq("a.del_flag", 0);
+        // 报销项目
+        if (StringUtils.isNotEmpty(dto.getProject())) {
+            queryWrapper.apply("(b.project_id = {0} OR b.project_name LIKE {1})", dto.getProject(), "%" + dto.getProject() + "%");
+        }
+        // 报销时间
+        if (dto.getDates() != null) {
+            queryWrapper.between("a.reim_date", dto.getDates()[0], dto.getDates()[1]);
+        }
+        // 经办人
+        if (StringUtils.isNotEmpty(dto.getHandled())) {
+            queryWrapper.apply("(a.create_by = {0} OR c.name LIKE {1})", dto.getHandled(), "%" + dto.getHandled() + "%");
+        }
+        // 报销人
+        if (StringUtils.isNotEmpty(dto.getReimBy())) {
+            queryWrapper.apply("( b.user_id = {0} OR b.user_name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");
+        }
+        // 报销状态
+        if (StringUtils.isNotEmpty(dto.getType())) {
+            queryWrapper.eq("a.type", dto.getType());
+        }
+        // 报销部门
+        if (StringUtils.isNotEmpty(dto.getDepartment())) {
+            queryWrapper.apply("( b.dept_id = {0} OR b.dept_name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
+        }
+        // 报销类别
+        if (StringUtils.isNotEmpty(dto.getRemiType())) {
+            queryWrapper.apply(" (b.type_id = {0} OR b.type_name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
+        }
+        // 报销金额
+        if (dto.getAmounts() != null) {
+            if (StringUtils.isNotEmpty(dto.getAmounts()[0])) {
+                queryWrapper.ge("b.number", Double.parseDouble(dto.getAmounts()[0]));
+            }
+            if (StringUtils.isNotEmpty(dto.getAmounts()[1])) {
+                queryWrapper.le("b.number", Double.parseDouble(dto.getAmounts()[1]));
+            }
+        }
+        // 报告号
+        if (StringUtils.isNotEmpty(dto.getReportNumber())) {
+            queryWrapper.like("b.report_number", dto.getReportNumber());
+        }
+        return infoMapper.findList(page, queryWrapper);
+    }
+
+    public IPage<ProgramProjectListInfo> projectList(Page<ProgramProjectListInfo> page, ProgramProjectListInfo info, String tabType) throws Exception{
+
+        //获取当前登录人信息
+        UserDTO userDTO = UserUtils.getCurrentUserDTO();
+
+        QueryWrapper<ProgramProjectListInfo> wrapper = QueryWrapperGenerator.buildQueryCondition(info, ProgramProjectListInfo.class);
+        wrapper.eq("a.del_flag", "0");
+        wrapper.eq("a.tab_type", tabType);
+        wrapper.eq("b.office_id", userDTO.getOfficeDTO().getId());
+        if (info.getCreateDates() != null) {
+            wrapper.between("a.create_date", info.getCreateDates()[0], info.getCreateDates()[1]);
+        }
+        IPage<ProgramProjectListInfo> pageList = infoMapper.findProjectList(page, wrapper);
+        pageList.getRecords().stream().forEach(item ->{
+            String isInvoice = infoMapper.selectInvoiceFlag(item.getId());
+            item.setIsInvoice(isInvoice);
+        });
+        return pageList;
+    }
+
+    public String save(SaveInfoDto dto) throws Exception{
+        // 获取当前登录人信息
+        UserDTO userDTO = UserUtils.getCurrentUserDTO();
+        if (StringUtils.isNotEmpty(dto.getId())) {
+            return update(dto, userDTO);
+        } else {
+            return add(dto, userDTO);
+        }
+    }
+
+    public String add(SaveInfoDto dto, UserDTO userDTO) throws Exception{
+        // 生成id
+        String id = UUID.randomUUID().toString().replace("-", "");
+        // 生成编号
+        String no = serialnumTplService.genSerialNum(userDTO.getCompanyDTO().getId(), dto.BIZ_CODE);
+        // 保存基础信息表信息
+        CwReimbursementInfo info = new CwReimbursementInfo();
+        BeanUtils.copyProperties(dto, info);
+        info.setId(id);
+        info.setNo(no);
+        info.setCreateBy(userDTO.getId());
+        info.setCreateDate(new Date());
+        info.setUpdateBy(userDTO.getId());
+        info.setUpdateDate(new Date());
+        info.setDelFlag(0);
+        infoMapper.insert(info);
+        // 保存详情列表信息
+        if (CollectionUtils.isNotEmpty(dto.getDetailInfos())) {
+            for (CwReimbursementDetailInfo detailInfo : dto.getDetailInfos()) {
+                // 生成id
+                String detailId = UUID.randomUUID().toString().replace("-", "");
+                detailInfo.setId(detailId);
+                detailInfo.setCreateBy(userDTO.getId());
+                detailInfo.setCreateDate(new Date());
+                detailInfo.setUpdateBy(userDTO.getId());
+                detailInfo.setUpdateDate(new Date());
+                detailInfo.setDelFlag(0);
+                // 保存基础表信息主键值
+                detailInfo.setInfoId(id);
+                detailInfoMapper.insert(detailInfo);
+            }
+        }
+        // 保存专用发票列表信息
+        if (CollectionUtils.isNotEmpty(dto.getAmountInfos())) {
+            for (CwReimbursementAmountInfo amountInfo : dto.getAmountInfos()) {
+                // 生成id
+                String amountId = UUID.randomUUID().toString().replace("-", "");
+                amountInfo.setId(amountId);
+                amountInfo.setCreateBy(userDTO.getId());
+                amountInfo.setCreateDate(new Date());
+                amountInfo.setUpdateBy(userDTO.getId());
+                amountInfo.setUpdateDate(new Date());
+                amountInfo.setDelFlag(0);
+                // 保存基础表信息主键值
+                amountInfo.setInfoId(id);
+                amountInfoMapper.insert(amountInfo);
+            }
+        }
+        // 保存附件列表信息
+        if (CollectionUtils.isNotEmpty(dto.getFiles())) {
+            infoService.saveFiles(dto.getFiles(), userDTO, id);
+        }
+        return id;
+    }
+
+    public String update(SaveInfoDto dto, UserDTO userDTO) {
+        // 修改基础信息
+        CwReimbursementInfo info = new CwReimbursementInfo();
+        BeanUtils.copyProperties(dto, info);
+        info.setUpdateBy(userDTO.getId());
+        info.setUpdateDate(new Date());
+        infoMapper.updateById(info);
+        // 修改报销详情列表信息
+        // 删除原有数据
+        LambdaQueryWrapper<CwReimbursementDetailInfo> detailWrapper = new LambdaQueryWrapper<>();
+        detailWrapper.eq(CwReimbursementDetailInfo::getInfoId, dto.getId());
+        detailInfoMapper.delete(detailWrapper);
+        if (CollectionUtils.isNotEmpty(dto.getDetailInfos())) {
+            for (CwReimbursementDetailInfo detailInfo : dto.getDetailInfos()) {
+                // 生成id
+                String detailId = UUID.randomUUID().toString().replace("-", "");
+                detailInfo.setId(detailId);
+                detailInfo.setCreateBy(userDTO.getId());
+                detailInfo.setCreateDate(new Date());
+                detailInfo.setUpdateBy(userDTO.getId());
+                detailInfo.setUpdateDate(new Date());
+                detailInfo.setDelFlag(0);
+                // 保存基础表信息主键值
+                detailInfo.setInfoId(dto.getId());
+                detailInfoMapper.insert(detailInfo);
+            }
+        }
+        // 修改专用发票信息列表
+        // 删除原有数据
+        LambdaQueryWrapper<CwReimbursementAmountInfo> amountWrapper = new LambdaQueryWrapper<>();
+        amountWrapper.eq(CwReimbursementAmountInfo::getInfoId, dto.getId());
+        amountInfoMapper.delete(amountWrapper);
+        if (CollectionUtils.isNotEmpty(dto.getAmountInfos())) {
+            for (CwReimbursementAmountInfo amountInfo : dto.getAmountInfos()) {
+                // 生成id
+                String amountId = UUID.randomUUID().toString().replace("-", "");
+                amountInfo.setId(amountId);
+                amountInfo.setCreateBy(userDTO.getId());
+                amountInfo.setCreateDate(new Date());
+                amountInfo.setUpdateBy(userDTO.getId());
+                amountInfo.setUpdateDate(new Date());
+                amountInfo.setDelFlag(0);
+                // 保存基础表信息主键值
+                amountInfo.setInfoId(dto.getId());
+                amountInfoMapper.insert(amountInfo);
+            }
+        }
+        // 修改附件信息列表
+        if (CollectionUtils.isNotEmpty(dto.getFiles())) {
+            infoService.updateFiles(dto.getFiles(), userDTO, dto.getId());
+        }
+        return dto.getId();
+    }
+
+    public String remove(String id) {
+        // 删除基础信息表
+        infoMapper.deleteById(id);
+        // 删除详情列表
+        LambdaQueryWrapper<CwReimbursementDetailInfo> detailInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        detailInfoLambdaQueryWrapper.eq(CwReimbursementDetailInfo::getInfoId, id);
+        detailInfoMapper.delete(detailInfoLambdaQueryWrapper);
+        // 删除专用发票信息列表
+        LambdaQueryWrapper<CwReimbursementAmountInfo> amountInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        amountInfoLambdaQueryWrapper.eq(CwReimbursementAmountInfo::getInfoId, id);
+        amountInfoMapper.delete(amountInfoLambdaQueryWrapper);
+        // 删除附件信息
+        LambdaQueryWrapper<WorkAttachment> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(WorkAttachment::getAttachmentId, id);
+        ossServiceMapper.delete(wrapper);
+        return "操作成功";
+    }
+
+    public SaveInfoDto findById(String id) {
+        SaveInfoDto dto = new SaveInfoDto();
+        // 查询基础信息表
+        CwReimbursementInfo info = infoMapper.selectById(id);
+        BeanUtils.copyProperties(info, dto);
+        // 查询详情列表
+        LambdaQueryWrapper<CwReimbursementDetailInfo> detailInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        detailInfoLambdaQueryWrapper.eq(CwReimbursementDetailInfo::getInfoId, id);
+        List<CwReimbursementDetailInfo> detailInfos = detailInfoMapper.selectList(detailInfoLambdaQueryWrapper);
+        dto.setDetailInfos(detailInfos);
+        // 查询专用发票信息列表
+        LambdaQueryWrapper<CwReimbursementAmountInfo> amountInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        amountInfoLambdaQueryWrapper.eq(CwReimbursementAmountInfo::getInfoId, id);
+        List<CwReimbursementAmountInfo> amountInfos = amountInfoMapper.selectList(amountInfoLambdaQueryWrapper);
+        dto.setAmountInfos(amountInfos);
+        // 查询附件信息
+        List<WorkAttachmentDto> files = infoMapper.findFiles(id);
+        if (CollectionUtils.isNotEmpty(files)) {
+            for (WorkAttachmentDto i : files) {
+                i.setCreateBy(UserUtils.get(i.getBy()));
+            }
+        }
+        dto.setFiles(files);
+        return dto;
+    }
+
+    public Boolean checkNumber(String number) {
+        LambdaQueryWrapper<CwReimbursementAmountInfo> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(CwReimbursementAmountInfo::getNumber, number);
+        List<CwReimbursementAmountInfo> infos = amountInfoMapper.selectList(wrapper);
+        if (CollectionUtils.isNotEmpty(infos)) {
+            return true;
+        }
+        return false;
+    }
+
+    public void updateStatusById(RetureListDto dto) {
+        infoMapper.updateStatusById(dto.getId(), dto.getType());
+    }
+
+    //用户树形
+    public List<TreeUserDto> userTree(String name) {
+        List<TreeUserDto> list = new ArrayList<>();
+        // 查询部门
+        List<TreeUserDto> officeList = infoMapper.findOfficeList();
+        if (CollectionUtils.isNotEmpty(officeList)) {
+            list.addAll(officeList);
+        }
+        // 查询用户
+        List<TreeUserDto> userList = infoMapper.findUserList(name);
+        if (CollectionUtils.isNotEmpty(userList)) {
+            list.addAll(userList);
+        }
+        return list;
+    }
+
+    /**
+     * 下载列表查询
+     */
+    public List<RetureListDto> exportList(QueryListDto dto) throws Exception{
+        QueryWrapper<QueryListDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, QueryListDto.class);
+        /**
+         * a表是reimbursementInfo
+         * b表是reimbursementDetailInfo
+         * c表是sysUser
+         */
+        queryWrapper.eq("a.del_flag", 0);
+        // 报销项目
+        if (StringUtils.isNotEmpty(dto.getProject())) {
+            queryWrapper.apply("(b.project_id = {0} OR b.project_name LIKE {1})", dto.getProject(), "%" + dto.getProject() + "%");
+        }
+        // 报销时间
+        if (dto.getDates() != null) {
+            queryWrapper.between("a.reim_date", dto.getDates()[0], dto.getDates()[1]);
+        }
+        // 经办人
+        if (StringUtils.isNotEmpty(dto.getHandled())) {
+            queryWrapper.apply("(a.create_by = {0} OR c.name LIKE {1})", dto.getHandled(), "%" + dto.getHandled() + "%");
+        }
+        // 报销人
+        if (StringUtils.isNotEmpty(dto.getReimBy())) {
+            queryWrapper.apply("( b.user_id = {0} OR b.user_name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");
+        }
+        // 报销状态
+        if (StringUtils.isNotEmpty(dto.getType())) {
+            queryWrapper.eq("a.type", dto.getType());
+        }
+        // 报销部门
+        if (StringUtils.isNotEmpty(dto.getDepartment())) {
+            queryWrapper.apply("( b.dept_id = {0} OR b.dept_name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
+        }
+        // 报销类别
+        if (StringUtils.isNotEmpty(dto.getRemiType())) {
+            queryWrapper.apply(" (b.type_id = {0} OR b.type_name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
+        }
+        // 报销金额
+        if (dto.getAmounts() != null) {
+            if (StringUtils.isNotEmpty(dto.getAmounts()[0])) {
+                queryWrapper.ge("b.number", dto.getAmounts()[0]);
+            }
+            if (StringUtils.isNotEmpty(dto.getAmounts()[1])) {
+                queryWrapper.le("b.number", dto.getAmounts()[1]);
+            }
+        }
+        // 报告号
+        if (StringUtils.isNotEmpty(dto.getReportNumber())) {
+            queryWrapper.like("b.report_number", dto.getReportNumber());
+        }
+        List<RetureListDto> exportList = infoMapper.findExportList(queryWrapper);
+        if (CollectionUtils.isNotEmpty(exportList)) {
+            for (RetureListDto retureListDto : exportList) {
+                if ("1".equals(retureListDto.getType())) {
+                    retureListDto.setType("暂存");
+                }
+                if ("2".equals(retureListDto.getType())) {
+                    retureListDto.setType("审批中");
+                }
+                if ("3".equals(retureListDto.getType())) {
+                    retureListDto.setType("撤回");
+                }
+                if ("4".equals(retureListDto.getType())) {
+                    retureListDto.setType("驳回");
+                }
+                if ("5".equals(retureListDto.getType())) {
+                    retureListDto.setType("已完成");
+                }
+            }
+        }
+        return exportList;
+    }
+
+    /**
+     * 关联报销
+     */
+    public IPage<RetureListDto> relationReimbursementList(Page<RetureListDto> page, String id) {
+        IPage<RetureListDto> iPage = infoMapper.relationReimbursementList(page, id);
+        return iPage;
+    }
+
+}

+ 53 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/dto/QueryListDto.java

@@ -0,0 +1,53 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto;
+
+import com.jeeplus.core.domain.BaseEntity;
+import lombok.Data;
+
+@Data
+public class QueryListDto extends BaseEntity {
+
+    /**
+     * 报销项目
+     */
+    private String project;
+
+    /**
+     * 报销时间
+     */
+    private String[] dates;
+
+    /**
+     * 经办人
+     */
+    private String handled;
+
+    /**
+     * 报销人
+     */
+    private String reimBy;
+
+    /**
+     * 报销状态
+     */
+    private String type;
+
+    /**
+     * 报销部门
+     */
+    private String department;
+
+    /**
+     * 报销类别
+     */
+    private String remiType;
+
+    /**
+     * 报销金额
+     */
+    private String[] amounts;
+
+    /**
+     * 报告号
+     */
+    private String reportNumber;
+}

+ 100 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/dto/RetureListDto.java

@@ -0,0 +1,100 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto;
+
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class RetureListDto {
+
+    /**
+     * 基础表主键值
+     */
+    private String id;
+
+    /**
+     * 报销编号
+     */
+    @Excel(name = "报销编号", width = 30, orderNum = "1")
+    private String no;
+
+    /**
+     * 报销类别id
+     */
+    private String typeId;
+
+    /**
+     * 报销类别
+     */
+    @Excel(name = "报销类别", width = 30, orderNum = "2")
+    private String typeName;
+
+    /**
+     * 报销项目id
+     */
+    private String projectId;
+
+    /**
+     * 报销项目
+     */
+    @Excel(name = "报销项目", width = 30, orderNum = "3")
+    private String projectName;
+
+    /**
+     * 报告号
+     */
+    @Excel(name = "报告号", width = 30, orderNum = "4")
+    private String reportNumber;
+
+    /**
+     * 经办人
+     */
+    @Excel(name = "经办人", width = 30, orderNum = "5")
+    private String userName;
+
+    /**
+     * 报销人
+     */
+    @Excel(name = "报销人", width = 30, orderNum = "6")
+    private String name;
+
+    /**
+     * 报销部门
+     */
+    @Excel(name = "报销部门", width = 30, orderNum = "7")
+    private String deptName;
+
+    /**
+     * 报销日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "报销日期", width = 30, orderNum = "8")
+    private Date reimDate;
+
+    /**
+     * 报销金额
+     */
+    @Excel(name = "报销金额", width = 30, orderNum = "9")
+    private BigDecimal number;
+
+    /**
+     * 报销状态
+     */
+    @Excel(name = "报销状态", width = 30, orderNum = "10")
+    private String type;
+
+    /**
+     * 流程id
+     */
+    private String procInsId;
+
+    /**
+     *
+     */
+    private String processDefinitionId;
+
+    private String taskId;
+}

+ 75 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/dto/SaveInfoDto.java

@@ -0,0 +1,75 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain.CwReimbursementAmountInfo;
+import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain.CwReimbursementDetailInfo;
+import com.jeeplus.test.reimbursement.reimbursementInfo.domain.ReimbursementAmountInfo;
+import com.jeeplus.test.reimbursement.reimbursementInfo.domain.ReimbursementDetailInfo;
+import com.jeeplus.test.workContract.service.dto.WorkAttachmentDto;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class SaveInfoDto extends BaseEntity {
+
+    //合同编号类型(字典值)
+    public static final String BIZ_CODE = "5";
+
+    /**
+     * 经办人id
+     */
+    private String userId;
+
+    /**
+     * 经办人名称
+     */
+    private String userName;
+
+    /**
+     * 报销编号
+     */
+    private String no;
+
+    /**
+     * 所属部门
+     */
+    private String department;
+
+    /**
+     * 报销日期
+     */
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "GMT+8")
+    private Date reimDate;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 状态
+     */
+    private String type;
+
+    /**
+     * 流程id
+     */
+    private String procInsId;
+
+    /**
+     *
+     */
+    private String processInstanceId;
+
+    private List<CwReimbursementDetailInfo> detailInfos;
+
+    private List<CwReimbursementAmountInfo> amountInfos;
+
+    private List<WorkAttachmentDto> files;
+
+}

+ 19 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalInfo/service/dto/TreeUserDto.java

@@ -0,0 +1,19 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalInfo.service.dto;
+
+import com.jeeplus.core.domain.BaseEntity;
+import lombok.Data;
+
+@Data
+public class TreeUserDto extends BaseEntity {
+
+    private String name;
+
+    private String parentId;
+
+    private String officeName;
+
+    private Boolean disable = false;
+
+    private Boolean isUser = false;
+
+}

+ 93 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/controller/CwReimbursementTypeController.java

@@ -0,0 +1,93 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalType.controller;
+
+import com.jeeplus.test.cw.reimbursementApproval.approvalType.domain.CwReimbursementTypeInfo;
+import com.jeeplus.test.cw.reimbursementApproval.approvalType.mapper.CwReimbursementTypeMapper;
+import com.jeeplus.test.cw.reimbursementApproval.approvalType.service.CwReimbursementTypeForTreeDataService;
+import com.jeeplus.test.cw.reimbursementApproval.approvalType.service.CwReimbursementTypeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-25 09:18
+ **/
+@RestController
+@Api(tags ="财务-报销类型管理")
+@RequestMapping(value = "/reimbursementApproval/type")
+public class CwReimbursementTypeController {
+
+    @Resource
+    private CwReimbursementTypeService service;
+
+    @Resource
+    private CwReimbursementTypeForTreeDataService treeService;
+
+    @Resource
+    private CwReimbursementTypeMapper mapper;
+
+    /**
+     * 列表查询
+     * @param info
+     * @return
+     */
+    @ApiOperation(value = "列表查询")
+    @GetMapping("/list")
+    public ResponseEntity<List<CwReimbursementTypeInfo>> list(CwReimbursementTypeInfo info) {
+        List<CwReimbursementTypeInfo> list = service.list(info);
+        return ResponseEntity.ok(list);
+    }
+
+    /**
+     * 新增/修改
+     * @param info
+     * @return
+     */
+    @ApiOperation(value = "新增/修改")
+    @PostMapping("/save")
+    public ResponseEntity<String> save(@RequestBody CwReimbursementTypeInfo info) {
+        String s = service.save(info);
+        return ResponseEntity.ok(s);
+    }
+
+    /**
+     * 根据id查询
+     * @param id
+     * @return
+     */
+    @ApiOperation(value = "根据id查询")
+    @GetMapping("/findById")
+    public ResponseEntity<CwReimbursementTypeInfo> findById(String id) {
+        CwReimbursementTypeInfo info = mapper.selectById(id);
+        return ResponseEntity.ok(info);
+    }
+
+    /**
+     * 根据id删除
+     * @param id
+     * @return
+     */
+    @ApiOperation(value = "根据id删除")
+    @GetMapping("/deleteById")
+    public ResponseEntity<String> deleteById(String id) {
+        mapper.deleteById(id);
+        return ResponseEntity.ok("操作完成");
+    }
+
+    /**
+     * 查询树形
+     * @param extId 排除的ID
+     * @return
+     */
+    @ApiOperation(value = "查询树形")
+    @GetMapping("/treeData")
+    public ResponseEntity<List<CwReimbursementTypeInfo>> treeData(@RequestParam(required = false) String extId, @RequestParam(required = false) String type) throws Exception{
+        List<CwReimbursementTypeInfo> infos = treeService.treeDataForType(extId, type);
+        return ResponseEntity.ok(infos);
+    }
+
+}

+ 85 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/domain/CwReimbursementTypeInfo.java

@@ -0,0 +1,85 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalType.domain;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.jeeplus.core.domain.TreeEntity;
+import com.jeeplus.core.query.Query;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 报销类型信息列表
+ * @author: 王强
+ * @create: 2022-11-25 08:59
+ **/
+@Data
+@TableName(value = "cw_reimbursement_type_info")
+public class CwReimbursementTypeInfo extends TreeEntity<CwReimbursementTypeInfo> {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 实体主键
+     */
+    @TableId
+    private String id;
+
+    /**
+     * 创建日期
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Date createDate;
+
+    /**
+     * 创建人
+     */
+    @Query
+    @TableField(fill = FieldFill.INSERT)
+    private String createBy;
+
+    /**
+     * 更新日期
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Date updateDate;
+
+    /**
+     * 更新人
+     */
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private String updateBy;
+
+    /**
+     * 逻辑删除标记
+     */
+    @TableLogic
+    @TableField(fill = FieldFill.INSERT)
+    private Integer delFlag;
+
+    /**
+     * 层级
+     */
+    private String level;
+
+    /**
+     * 报销类型名称
+     */
+    @Query
+    private String name;
+
+    /**
+     * 序号
+     */
+    @Query
+    private Integer sort;
+
+    /**
+     * 父节点id
+     */
+    private String parentId;
+
+    private String parentIds;
+
+    @TableField(exist = false)
+    private Boolean disabled = false;
+}

+ 25 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/mapper/CwReimbursementTypeMapper.java

@@ -0,0 +1,25 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalType.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.jeeplus.core.domain.TreeMapper;
+import com.jeeplus.test.cw.reimbursementApproval.approvalType.domain.CwReimbursementTypeInfo;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-25 09:02
+ **/
+public interface CwReimbursementTypeMapper extends BaseMapper<CwReimbursementTypeInfo>, TreeMapper<CwReimbursementTypeInfo> {
+
+    /**
+     * 根据name和parentId查询名称是否重复
+     * @param name
+     * @param parentId
+     * @return
+     */
+    Integer checkNameIsExist(@Param("name") String name, @Param("parentId") String parentId);
+
+    Integer getNo(@Param("parentId") String parentId);
+
+    Integer getLevel(@Param("parentId") String parentId);
+}

+ 32 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/mapper/xml/CwReimbursementTypeMapper.xml

@@ -0,0 +1,32 @@
+<?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.jeeplus.test.cw.reimbursementApproval.approvalType.mapper.CwReimbursementTypeMapper">
+    <select id="checkNameIsExist" resultType="java.lang.Integer">
+        SELECT
+			COUNT( 0 )
+		FROM
+			cw_reimbursement_type_info
+		WHERE
+			del_flag = 0
+			AND `name` = #{name}
+			AND parent_id = #{parentId}
+    </select>
+    <select id="getNo" resultType="java.lang.Integer">
+        SELECT
+			(MAX(`sort`) + 1) AS `sort`
+		FROM
+			cw_reimbursement_type_info
+		WHERE
+			del_flag = 0
+			AND parent_id = #{parentId}
+    </select>
+    <select id="getLevel" resultType="java.lang.Integer">
+        SELECT
+			(MAX(level) + 1) AS `level`
+		FROM
+			cw_reimbursement_type_info
+		WHERE
+			del_flag = 0
+			AND id = #{parentId}
+    </select>
+</mapper>

+ 116 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/service/CwReimbursementTypeForTreeDataService.java

@@ -0,0 +1,116 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalType.service;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeeplus.core.service.TreeService;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.jeeplus.core.service.dto.TreeDTO;
+import org.apache.commons.lang3.StringUtils;
+import com.jeeplus.test.cw.reimbursementApproval.approvalType.domain.CwReimbursementTypeInfo;
+import com.jeeplus.test.cw.reimbursementApproval.approvalType.mapper.CwReimbursementTypeMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-25 09:01
+ **/
+@Service
+public class CwReimbursementTypeForTreeDataService extends TreeService<CwReimbursementTypeMapper, CwReimbursementTypeInfo> {
+
+    @Resource
+    private CwReimbursementTypeMapper typeMapper;
+
+    /**
+     * 获取JSON树形数据。
+     *
+     * @param extId 排除的ID
+     * @param type 禁选类型
+     * @return
+     */
+    public List<CwReimbursementTypeInfo> treeDataForType(String extId, String type) throws Exception{
+        List<CwReimbursementTypeInfo> allList = super.list (new LambdaQueryWrapper<>( (Class <CwReimbursementTypeInfo>) entityClass ).orderByAsc ( CwReimbursementTypeInfo::getSort ));
+        CwReimbursementTypeInfo root = entityClass.getConstructor ( ).newInstance ( );
+        root.setId ( TreeDTO.getRootId () );
+        List <CwReimbursementTypeInfo> rootTree = this.formatListToTreeForType ( root, allList, extId, type );
+        return rootTree;
+    }
+
+    /**
+     * 以root为根节点, 将allList从线性列表转为树形列表
+     *
+     * @param root    根节点, 为空抛出空指针异常
+     * @param allList 所有需要参与构造为树的列表
+     * @param extId   需要排除在树之外的节点(子节点一并被排除)
+     * @return java.util.List<T>
+     * @Author 滕鑫源
+     * @Date 2020/10/23 17:04
+     **/
+    public List <CwReimbursementTypeInfo> formatListToTreeForType (CwReimbursementTypeInfo root, List <CwReimbursementTypeInfo> allList, String extId, String type) {
+        String rootId = root.getId ( );
+        // 最终的树形态
+        List <CwReimbursementTypeInfo> trees = Lists.newArrayList ( );
+
+        // 把需要构造树的所有列表, 根据以父id作为key, 整理为列表
+        Map<String, List <CwReimbursementTypeInfo>> treeMap = Maps.newHashMap ( );
+        for (CwReimbursementTypeInfo entity : allList) {
+            List <CwReimbursementTypeInfo> entities = treeMap.get ( entity.getParentId ( ) );
+            if ( entities == null ) {
+                entities = Lists.newLinkedList ( );
+            }
+
+            // 剔除排除项, 构造treeMap, 转递归为线性操作
+            if ( StrUtil.isBlank ( extId ) || (!extId.equals ( entity.getId ( ) ) && entity.getParentIds ( ).indexOf ( "," + extId + "," ) == -1) ) {
+                entities.add ( entity );
+                treeMap.put ( entity.getParentId ( ), entities );
+            }
+
+            if (StringUtils.isNotEmpty(type)) {
+                //禁选类型设置disable值为true
+                if (type.contains(entity.getLevel())) {
+                    entity.setDisabled(true);
+                }
+            }
+        }
+
+        // 没有给定的子树, 返回空树
+        if ( treeMap.get ( rootId ) == null || treeMap.get ( rootId ).isEmpty ( ) ) {
+            return trees;
+        }
+
+        // 开始递归格式化
+        List <CwReimbursementTypeInfo> children = treeMap.get ( rootId );
+        for (CwReimbursementTypeInfo parent : children) {
+            formatFillChildren ( parent, treeMap );
+            trees.add ( parent );
+        }
+        if ( StrUtil.equals ( rootId, TreeDTO.getRootId () ) ) {
+            return children;
+        } else {
+            root.setChildren ( trees );
+            return Lists.newArrayList ( root );
+        }
+    }
+    /**
+     * 从treeMap中取出子节点填入parent, 并递归此操作
+     *
+     * @param parent
+     * @param treeMap
+     * @return void
+     * @Author 滕鑫源
+     * @Date 2020/9/30 16:33
+     **/
+    private void formatFillChildren(CwReimbursementTypeInfo parent, Map <String, List <CwReimbursementTypeInfo>> treeMap) {
+        List <CwReimbursementTypeInfo> children = treeMap.get ( parent.getId ( ) );
+        parent.setChildren ( children );
+        if ( children != null && !children.isEmpty ( ) ) {
+            for (CwReimbursementTypeInfo child : children) {
+                formatFillChildren ( child, treeMap );
+            }
+        }
+    }
+}

+ 137 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/service/CwReimbursementTypeService.java

@@ -0,0 +1,137 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalType.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.jeeplus.core.domain.BaseEntity;
+import com.jeeplus.sys.service.dto.UserDTO;
+import com.jeeplus.sys.utils.StringUtils;
+import com.jeeplus.sys.utils.UserUtils;
+import com.jeeplus.test.cw.reimbursementApproval.approvalType.domain.CwReimbursementTypeInfo;
+import com.jeeplus.test.cw.reimbursementApproval.approvalType.mapper.CwReimbursementTypeMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.Date;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-25 09:13
+ **/
+@Service
+public class CwReimbursementTypeService {
+
+    @Resource
+    private CwReimbursementTypeMapper mapper;
+
+    public List<CwReimbursementTypeInfo> list(CwReimbursementTypeInfo info) {
+        LambdaQueryWrapper<CwReimbursementTypeInfo> wrapper = new LambdaQueryWrapper<>();
+        if (StringUtils.isNotEmpty(info.getName())) {
+            wrapper.like(CwReimbursementTypeInfo::getName, info.getName());
+        }
+        if (info.getSort() != null) {
+            wrapper.like(CwReimbursementTypeInfo::getSort, info.getSort());
+        }
+        wrapper.eq(BaseEntity::getDelFlag, 0);
+        wrapper.orderByAsc(CwReimbursementTypeInfo::getSort);
+        return mapper.selectList(wrapper);
+    }
+
+    public String save(CwReimbursementTypeInfo info) {
+        // parentId未传值,则表示一级菜单
+        if(StringUtils.isEmpty(info.getParentId())) {
+            info.setParentId("0");
+        }
+        // 判断名称是否已存在
+        Integer isExist = mapper.checkNameIsExist(info.getName(), info.getParentId());
+        if (isExist > 0) {
+            return "false";
+        }
+        // 保存数据
+        if (StringUtils.isNotEmpty(info.getId())) {
+            return update(info);
+        }
+        return add(info);
+    }
+
+    /**
+     * 新增
+     * @param info
+     * @return
+     */
+    public String add(CwReimbursementTypeInfo info) {
+        // 获取当前登录人信息
+        UserDTO userDto = UserUtils.getCurrentUserDTO();
+        // 生成id值
+        String id = UUID.randomUUID().toString().replace("-", "");
+        info.setId(id);
+        info.setCreateBy(userDto.getId());
+        info.setCreateDate(new Date());
+        info.setUpdateBy(userDto.getId());
+        info.setUpdateDate(new Date());
+        info.setDelFlag(0);
+        // 生成序号/层级
+        getNo(info);
+        mapper.insert(info);
+        return "操作完成";
+    }
+
+    /**
+     * 修改
+     * @param info
+     * @return
+     */
+    public String update(CwReimbursementTypeInfo info) {
+        // 获取当前登录人信息
+        UserDTO userDto = UserUtils.getCurrentUserDTO();
+        info.setUpdateBy(userDto.getId());
+        info.setUpdateDate(new Date());
+        mapper.updateById(info);
+        return "操作完成";
+    }
+
+    /**
+     * 生成序号/层级
+     * @param info
+     * @return
+     */
+    public CwReimbursementTypeInfo getNo(CwReimbursementTypeInfo info) {
+        CwReimbursementTypeInfo parentInfo = null;
+        if (!"0".equals(info.getParentId())) {
+            //根据parentId查询父节点信息
+            LambdaQueryWrapper<CwReimbursementTypeInfo> wrapper = new LambdaQueryWrapper<>();
+            wrapper.eq(BaseEntity::getDelFlag, 0);
+            wrapper.eq(BaseEntity::getId, info.getParentId());
+            parentInfo = mapper.selectOne(wrapper);
+        }
+        //查询序号
+        Integer no = mapper.getNo(info.getParentId());
+        // 该层级下有数据,正常返回序号值
+        if (no != null) {
+            info.setSort(no);
+        } else {
+            // 父节点存在,根据父节点序号生成;不存在,则表示无上级层级,从1开始
+            if (parentInfo != null) {
+                String s = parentInfo.getSort() + "01";
+                info.setSort(Integer.parseInt(s));
+            } else {
+                info.setSort(1);
+            }
+        }
+        // 生成层级
+        //查询层级
+        Integer level = mapper.getLevel(info.getParentId());
+        if (level != null) {
+            info.setLevel(level.toString());
+        } else {
+            // 父节点存在,根据父节点level生成,不存在,则表示无上级层级,从1开始
+            if (parentInfo != null) {
+                Integer i = Integer.parseInt(parentInfo.getLevel())+1;
+                info.setLevel(i.toString());
+            } else {
+                info.setLevel("1");
+            }
+        }
+        return info;
+    }
+}

+ 21 - 0
jeeplus-module/jeeplus-test/src/main/java/com/jeeplus/test/cw/reimbursementApproval/approvalType/service/dto/CwReimbursementTypeDto.java

@@ -0,0 +1,21 @@
+package com.jeeplus.test.cw.reimbursementApproval.approvalType.service.dto;
+
+import com.jeeplus.core.domain.BaseEntity;
+import lombok.Data;
+
+/**
+ * @author: 王强
+ * @create: 2022-11-25 09:04
+ **/
+@Data
+public class CwReimbursementTypeDto extends BaseEntity {
+
+    private String level;
+
+    private String name;
+
+    private Integer sort;
+
+    private String parentId;
+
+}