소스 검색

1.大中型台账查询更改,调整为每一个产品都为一条独立的数据,新增产品类型筛选
2.新增批量保存产品质检信息接口
3.新增批量保存产品额外加减分接口
4.绩效扣分统计相关接口返回抽检扣分、内部投诉、外部投诉、以及额外加减分的统计
5.产品绩效扣分表新增索引,新增business_production_bonus_points额外加减分表

GouGengquan 1 개월 전
부모
커밋
a2f600da9f
20개의 변경된 파일875개의 추가작업 그리고 129개의 파일을 삭제
  1. 108 0
      biz-base/src/main/java/com/dayou/controller/BusinessProductionBonusPointsController.java
  2. 15 0
      biz-base/src/main/java/com/dayou/controller/BusinessProductionPerformanceController.java
  3. 23 1
      biz-base/src/main/java/com/dayou/controller/MajorStatisticalStatementController.java
  4. 16 0
      dao/src/main/java/com/dayou/mapper/BusinessProductionBonusPointsMapper.java
  5. 1 1
      dao/src/main/java/com/dayou/mapper/BusinessProductionPerformanceMapper.java
  6. 15 0
      dao/src/main/java/com/dayou/mapper/MajorStatisticalStatementMapper.java
  7. 28 0
      dao/src/main/resources/mapper/BusinessProductionBonusPointsMapper.xml
  8. 4 4
      dao/src/main/resources/mapper/BusinessProductionPerformanceMapper.xml
  9. 260 113
      dao/src/main/resources/mapper/MajorStatisticalStatementMapper.xml
  10. 5 0
      domain/src/main/java/com/dayou/dto/MajorStatisticalSelectDTO.java
  11. 62 0
      domain/src/main/java/com/dayou/entity/BusinessProductionBonusPoints.java
  12. 8 1
      domain/src/main/java/com/dayou/entity/BusinessProductionPerformance.java
  13. 99 0
      domain/src/main/java/com/dayou/vo/MajorBonusPointsDetailVO.java
  14. 13 2
      domain/src/main/java/com/dayou/vo/MajorLedgerVO.java
  15. 26 2
      domain/src/main/java/com/dayou/vo/MajorPerformanceDeductionVO.java
  16. 39 0
      service/src/main/java/com/dayou/service/IBusinessProductionBonusPointsService.java
  17. 15 0
      service/src/main/java/com/dayou/service/IMajorStatisticalStatementService.java
  18. 81 0
      service/src/main/java/com/dayou/service/impl/BusinessProductionBonusPointsServiceImpl.java
  19. 22 4
      service/src/main/java/com/dayou/service/impl/MajorStatisticalStatementServiceImpl.java
  20. 35 1
      sql/update_sql.sql

+ 108 - 0
biz-base/src/main/java/com/dayou/controller/BusinessProductionBonusPointsController.java

@@ -0,0 +1,108 @@
+package com.dayou.controller;
+
+import com.dayou.utils.LoginContext;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springframework.web.bind.annotation.RestController;
+import com.dayou.controller.BaseController;
+import com.dayou.service.IBusinessProductionBonusPointsService;
+import com.dayou.entity.BusinessProductionBonusPoints;
+import com.dayou.common.RestResponse;
+import org.springframework.web.bind.annotation.*;
+import com.dayou.utils.ConvertUtil;
+import com.dayou.utils.HttpKit;
+import com.dayou.exception.ErrorCode;
+import java.util.Date;
+import java.util.List;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import org.springframework.http.MediaType;
+import org.springframework.web.multipart.MultipartFile;
+/**
+ * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)
+ *
+ * @author wucl
+ * @since 2025-05-28
+ */
+@RestController
+@RequestMapping("businessProductionBonusPoints")
+@Slf4j
+public class BusinessProductionBonusPointsController extends BaseController {
+    @Autowired
+    private IBusinessProductionBonusPointsService businessProductionBonusPointsService;
+
+    /**
+    * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)列表
+    */
+    @GetMapping("")
+    public RestResponse<Page<BusinessProductionBonusPoints>> page(BusinessProductionBonusPoints businessProductionBonusPoints, Page page){
+        Page<BusinessProductionBonusPoints> pages=businessProductionBonusPointsService.selectPage(page,businessProductionBonusPoints);
+        return RestResponse.data(pages);
+    }
+
+    /**
+     * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)详情
+     */
+    @GetMapping("/{id}")
+    public RestResponse<BusinessProductionBonusPoints> detail(@PathVariable Long id){
+        BusinessProductionBonusPoints xBusinessProductionBonusPoints =businessProductionBonusPointsService.detail(id);
+        return RestResponse.data(xBusinessProductionBonusPoints);
+     }
+
+    /**
+     * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)新增
+     */
+    @PostMapping("")
+    public RestResponse<Boolean> save(@RequestBody BusinessProductionBonusPoints businessProductionBonusPoints) {
+        Boolean ret = businessProductionBonusPointsService.add(businessProductionBonusPoints);
+        return RestResponse.data(ret);
+    }
+
+    /**
+     * 批量新增或更新
+     * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)
+     */
+    @PostMapping("/saveOrUpdate")
+    public RestResponse<Boolean> saveOrUpdate(@RequestBody List<BusinessProductionBonusPoints> points) {
+        for (BusinessProductionBonusPoints businessProductionBonusPoints : points) {
+            businessProductionBonusPoints.setOperatorId(LoginContext.getCurrentUserId());
+        }
+        Boolean ret = businessProductionBonusPointsService.saveOrUpdateBatch(points);
+        return RestResponse.data(ret);
+    }
+
+    /**
+     * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)更新
+     */
+    @PutMapping("")
+    public RestResponse<Boolean> update(@RequestBody BusinessProductionBonusPoints businessProductionBonusPoints) {
+        Boolean ret = businessProductionBonusPointsService.update(businessProductionBonusPoints);
+        return RestResponse.data(ret);
+    }
+
+    /**
+     * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)删除
+     */
+    @DeleteMapping("/{id}")
+    public RestResponse<Boolean> delete(@PathVariable Long id) {
+        Boolean ret = businessProductionBonusPointsService.delete(id);
+        return RestResponse.data(ret);
+    }
+
+    /**
+     * 根据产品id与业务类型查询额外加减分信息集合
+     * @param productionId 产品id
+     * @param businessType 业务类型
+     * @return List<BusinessProductionBonusPoints>
+     */
+    @GetMapping("getList/{productionId}/{businessType}")
+    public RestResponse<List<BusinessProductionBonusPoints>> getList(@PathVariable Long productionId, @PathVariable String businessType) {
+        return RestResponse.data(businessProductionBonusPointsService.getList(productionId, businessType));
+    }
+
+
+}
+

+ 15 - 0
biz-base/src/main/java/com/dayou/controller/BusinessProductionPerformanceController.java

@@ -1,6 +1,7 @@
 package com.dayou.controller;
 
 import com.dayou.dto.TaskRecordDTO;
+import com.dayou.utils.LoginContext;
 import com.dayou.vo.BusinessProductionPerformanceVO;
 import com.dayou.workflow.annotation.FinishTask;
 import lombok.extern.slf4j.Slf4j;
@@ -14,6 +15,7 @@ import com.dayou.common.RestResponse;
 import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
+import java.util.List;
 
 /**
  * 业务产品绩效分配
@@ -85,6 +87,19 @@ public class BusinessProductionPerformanceController extends BaseController {
         return RestResponse.data(businessProductionPerformanceService.getProductionPerformance(dto));
     }
 
+    /**
+     * 批量新增或更新质检信息
+     * @param performances 质检信息
+     * @return RestResponse<BusinessProductionPerformance>
+     */
+    @PostMapping("/saveOrUpdate")
+    public RestResponse<Boolean> saveOrUpdate(@RequestBody List<BusinessProductionPerformance> performances) {
+        for (BusinessProductionPerformance performance : performances) {
+            performance.setCheckId(LoginContext.getCurrentUserId());
+        }
+        return RestResponse.data(businessProductionPerformanceService.saveOrUpdateBatch(performances));
+    }
+
 
 }
 

+ 23 - 1
biz-base/src/main/java/com/dayou/controller/MajorStatisticalStatementController.java

@@ -167,7 +167,7 @@ public class MajorStatisticalStatementController extends BaseController{
     @GetMapping("/getMajorPerformanceDeductionDetailVO/export")
     public void exportMajorPerformanceDeductionDetailVO(MajorStatisticalSelectDTO dto, HttpServletResponse response) throws IOException {
         List<MajorPerformanceDeductionDetailVO> result = majorStatisticalStatementService.exportMajorPerformanceDeductionDetailVO(dto);
-        String fileName = "资产评估部绩效扣分详情_" + dto.getCheckLoop();
+        String fileName = "评估部绩效扣分详情_" + dto.getCheckLoop();
         switch (dto.getMistakeType()) {
             case "normal":
                 fileName += "_" + "一般错误";
@@ -183,6 +183,28 @@ public class MajorStatisticalStatementController extends BaseController{
     }
 
     /**
+     * 查询额外加减分详情列表
+     * @param page 分页
+     * @param dto 查询dto
+     * @return Page<MajorPerformanceDeductionDetailVO>
+     */
+    @GetMapping("/getMajorBonusPointsDetailVO")
+    public RestResponse<Page<MajorBonusPointsDetailVO>> getMajorBonusPointsDetailVO(Page page, MajorStatisticalSelectDTO dto) {
+        return RestResponse.data(majorStatisticalStatementService.getMajorBonusPointsDetailVO(page, dto));
+    }
+
+    /**
+     * 导出额外加减分详情列表
+     * @param dto 查询dto
+     */
+    @GetMapping("/getMajorBonusPointsDetailVO/export")
+    public void exportMajorBonusPointsDetailVO(MajorStatisticalSelectDTO dto, HttpServletResponse response) throws IOException {
+        List<MajorBonusPointsDetailVO> result = majorStatisticalStatementService.exportMajorBonusPointsDetailVO(dto);
+        String fileName = "评估部额外加减分详情_" + dto.getCheckLoop();
+        exportPlus(response, fileName, result, MajorBonusPointsDetailVO.class);
+    }
+
+    /**
      * 评估部效率查询
      * @param dto 查询dto
      * @return List<MajorEvaluateEfficiencyVO>

+ 16 - 0
dao/src/main/java/com/dayou/mapper/BusinessProductionBonusPointsMapper.java

@@ -0,0 +1,16 @@
+package com.dayou.mapper;
+
+import com.dayou.entity.BusinessProductionBonusPoints;
+import com.dayou.dao.CustomBaseMapper;
+
+/**
+ * <p>
+ * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等) Mapper 接口
+ * </p>
+ *
+ * @author wucl
+ * @since 2025-05-28
+ */
+public interface BusinessProductionBonusPointsMapper extends CustomBaseMapper<BusinessProductionBonusPoints> {
+
+}

+ 1 - 1
dao/src/main/java/com/dayou/mapper/BusinessProductionPerformanceMapper.java

@@ -24,5 +24,5 @@ public interface BusinessProductionPerformanceMapper extends CustomBaseMapper<Bu
      * @param dto 查询条件
      * @return BusinessProductionPerformance
      */
-    BusinessProductionPerformance getProductionPerformance(BusinessProductionPerformance dto);
+    BusinessProductionPerformance getProductionPerformance(@Param("dto") BusinessProductionPerformance dto);
 }

+ 15 - 0
dao/src/main/java/com/dayou/mapper/MajorStatisticalStatementMapper.java

@@ -84,6 +84,21 @@ public interface MajorStatisticalStatementMapper {
     List<MajorPerformanceDeductionDetailVO> exportMajorPerformanceDeductionDetailVO(@Param("dto") MajorStatisticalSelectDTO dto);
 
     /**
+     * 查询额外加减分详情列表
+     * @param page 分页
+     * @param dto 查询dto
+     * @return Page<MajorPerformanceDeductionDetailVO>
+     */
+    Page<MajorBonusPointsDetailVO> getMajorBonusPointsDetailVO(@Param("page") Page page, @Param("dto") MajorStatisticalSelectDTO dto);
+
+    /**
+     * 导出额外加减分详情列表
+     * @param dto 查询dto
+     * @return List<MajorPerformanceDeductionDetailVO>
+     */
+    List<MajorBonusPointsDetailVO> exportMajorBonusPointsDetailVO(@Param("dto") MajorStatisticalSelectDTO dto);
+
+    /**
      * 评估部效率查询
      * @param dto 查询dto
      * @return List<MajorEvaluateEfficiencyVO>

+ 28 - 0
dao/src/main/resources/mapper/BusinessProductionBonusPointsMapper.xml

@@ -0,0 +1,28 @@
+<?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.dayou.mapper.BusinessProductionBonusPointsMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.dayou.entity.BusinessProductionBonusPoints">
+        <result column="id" property="id" />
+        <result column="deleted" property="deleted" />
+        <result column="created" property="created" />
+        <result column="modified" property="modified" />
+        <result column="business_type" property="businessType" />
+        <result column="production_id" property="productionId" />
+        <result column="type" property="type" />
+        <result column="score" property="score" />
+        <result column="reason" property="reason" />
+        <result column="operator_id" property="operatorId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id,
+        deleted,
+        created,
+        modified,
+        business_type, production_id, type, score, reason, operator_id
+    </sql>
+
+</mapper>

+ 4 - 4
dao/src/main/resources/mapper/BusinessProductionPerformanceMapper.xml

@@ -23,10 +23,10 @@
 
     <!--根据业务类型,产品id及checkLoop获取质检信息-->
     <select id="getProductionPerformance" resultType="com.dayou.entity.BusinessProductionPerformance">
-        SELECT id, fatal_mistake, hard_mistake, normal_mistake, reason
+        SELECT id, fatal_mistake, hard_mistake, normal_mistake, service_attitude, reason
         FROM business_production_performance
-        WHERE production_id = #{productionId}
-        AND check_loop = #{CheckLoop}
-        AND business_type = #{BusinessType}
+        WHERE production_id = #{dto.productionId}
+        AND check_loop = #{dto.CheckLoop}
+        AND business_type = #{dto.BusinessType}
     </select>
 </mapper>

+ 260 - 113
dao/src/main/resources/mapper/MajorStatisticalStatementMapper.xml

@@ -3,119 +3,60 @@
 <mapper namespace="com.dayou.mapper.MajorStatisticalStatementMapper">
 
     <sql id="majorLedgerQuery">
-        SELECT (@i :=  @i + 1) AS id,
-               major.order_id AS orderId,
-               report.report_no AS reportNo,
-               department.name AS departmentName,
-               major.name AS projectName,
-               customer.name AS customerName,
-               customer_sub.name AS customerSubName,
-               manager.name AS clientManagerName,
-               principal.name AS principalName,
-               major.members AS members,
-               major.owner AS owner,
-               major.bailor AS bailor,
-               major.bailor_contact_tel AS bailorContactTel,
-               major.bailor_address AS bailorAddress,
-               major.evaluate_aim AS evaluateAim,
-               report.value_timing AS valueTiming,
-               GROUP_CONCAT(target.located SEPARATOR ';') AS located,
-               GROUP_CONCAT(target.land_use SEPARATOR ';') AS landUse,
-               GROUP_CONCAT(target.build_acreage SEPARATOR ';') AS buildAcreage,
-               GROUP_CONCAT(target.land_acreage SEPARATOR ';') AS landAcreage,
-               GROUP_CONCAT(DATE(target.created) SEPARATOR ';') AS reconnaissanceDate,
-               report.evaluate_price AS evaluatePrice,
-               report.evaluate_amount AS evaluateAmount,
-               fund.real_amount AS productionRealAmount,
-               report.repertory_out_time AS repertoryOutTime,
-               report.main_worker AS firstReporter,
-               report.minor_worker AS secReporter,
-               (
-                   SELECT user.name
-                   FROM work_flow_node_instance AS instance,
-                        work_task_record        AS record,
-                        work_node               AS node,
-                        user
-                   WHERE instance.id = record.instance_id
-                     AND record.handler_id = user.id
-                     AND node.id = instance.node_id
-                     AND instance.business_id = major.id
-                     AND instance.business_sub_id = statement.report_no
-                     AND node.code = 'RECHECK_STATEMENT'
-                     AND instance.deleted = 0
-               ) AS secStatementChecker,
-               (
-                   SELECT user.name
-                   FROM work_flow_node_instance AS instance,
-                        work_task_record        AS record,
-                        work_node               AS node,
-                        user
-                   WHERE instance.id = record.instance_id
-                     AND record.handler_id = user.id
-                     AND node.id = instance.node_id
-                     AND instance.business_id = major.id
-                     AND instance.business_sub_id = statement.report_no
-                     AND node.code = 'THIRD_CHECK_STATEMENT'
-                     AND instance.deleted = 0
-               ) AS thirdStatementChecker,
-               (
-                   SELECT user.name
-                   FROM work_flow_node_instance AS instance,
-                        work_task_record        AS record,
-                        work_node               AS node,
-                        user
-                   WHERE instance.id = record.instance_id
-                     AND record.handler_id = user.id
-                     AND node.id = instance.node_id
-                     AND instance.business_id = major.id
-                     AND instance.business_min_id = report.report_no
-                     AND node.code = 'RECHECK_REPORT'
-                     AND instance.deleted = 0
-               ) AS secReportChecker,
-               (
-                   SELECT user.name
-                   FROM work_flow_node_instance AS instance,
-                        work_task_record        AS record,
-                        work_node               AS node,
-                        user
-                   WHERE instance.id = record.instance_id
-                     AND record.handler_id = user.id
-                     AND node.id = instance.node_id
-                     AND instance.business_id = major.id
-                     AND instance.business_min_id = report.report_no
-                     AND node.code = 'THIRD_CHECK_REPORT'
-                     AND instance.deleted = 0
-               ) AS thirdReportReChecker,
-            major.remark AS comments
-        FROM  (SELECT @i := 0) AS sort,major
-        LEFT JOIN major_target AS target ON target.major_id = major.id
-        LEFT JOIN major_production AS statement ON statement.report_no = target.statement_no AND statement.production = 'STATEMENT'
-        LEFT JOIN major_production AS report ON report.report_no = target.report_no AND report.production != 'STATEMENT'
-        LEFT JOIN production_fund AS fund ON fund.production_no = report.report_no
+        SELECT (@i := @i + 1)                            AS id,
+        major.order_id                                   AS orderId,
+        pro.id                                           AS productionId,
+        pro.report_no                                    AS reportNo,
+        (CASE WHEN pro.production = 'LETTER' THEN '复评函' WHEN pro.production = 'REPORT' THEN '报告' WHEN pro.production = 'STATEMENT' THEN '意见书' ELSE '-' END) AS productionType,
+        department.name                                  AS departmentName,
+        major.name                                       AS projectName,
+        customer.name                                    AS customerName,
+        customer_sub.name                                AS customerSubName,
+        manager.name                                     AS clientManagerName,
+        principal.name                                   AS principalName,
+        major.members                                    AS members,
+        major.owner                                      AS owner,
+        major.bailor                                     AS bailor,
+        major.bailor_contact_tel                         AS bailorContactTel,
+        major.bailor_address                             AS bailorAddress,
+        major.evaluate_aim                               AS evaluateAim,
+        pro.value_timing                                 AS valueTiming,
+        GROUP_CONCAT(target.located SEPARATOR ';')       AS located,
+        GROUP_CONCAT(target.land_use SEPARATOR ';')      AS landUse,
+        GROUP_CONCAT(target.build_acreage SEPARATOR ';') AS buildAcreage,
+        GROUP_CONCAT(target.land_acreage SEPARATOR ';')  AS landAcreage,
+        GROUP_CONCAT(DATE(target.created) SEPARATOR ';') AS reconnaissanceDate,
+        pro.evaluate_price                               AS evaluatePrice,
+        pro.evaluate_amount                              AS evaluateAmount,
+        fund.real_amount                                 AS productionRealAmount,
+        pro.repertory_out_time                           AS repertoryOutTime,
+        pro.main_worker                                  AS firstReporter,
+        pro.minor_worker                                 AS secReporter,
+        major.remark                                     AS comments
+        FROM (SELECT @i := 0) AS sort,
+        major
+        LEFT JOIN major_production AS pro
+        ON pro.major_id = major.id AND pro.deleted = 0
+        # 连接查询产品对应的评估对象, 不同产品类型连接字段不一样
+        LEFT JOIN major_target AS target ON CASE
+        WHEN pro.production = 'LETTER' THEN pro.report_no = target.letter_no
+        WHEN pro.production = 'REPORT' THEN pro.report_no = target.report_no
+        WHEN pro.production = 'STATEMENT' THEN pro.report_no = target.statement_no
+        ELSE FALSE
+        END
+        LEFT JOIN production_fund AS fund ON fund.production_no = pro.report_no
         LEFT JOIN user AS manager ON manager.id = major.client_manager_id
         LEFT JOIN user AS principal ON principal.id = major.principal_id
         LEFT JOIN department ON department.id = major.department_id
         LEFT JOIN customer_company AS customer ON customer.id = major.clientele_id
         LEFT JOIN customer_company AS customer_sub ON customer_sub.id = major.clientele_sub_id
-        LEFT JOIN (
-            SELECT node.`name`,instance.business_id,instance.business_sub_id,instance.business_min_id,instance.state
-            FROM work_flow_node_instance AS instance,
-                 work_node AS node
-            WHERE instance.node_id = node.id
-              AND node.deleted = 0
-              AND instance.deleted = 0
-              AND (instance.state = 'PENDING' OR instance.state = 'CLOSED' OR
-                   (instance.state = 'FINISHED' AND node.`code` = 'BUSINESS_ARCHIVING'))
-        ) AS nodeInfo ON nodeInfo.business_id = major.id
-            AND (IF(report.report_no IS NULL, nodeInfo.business_min_id IS NULL,
-                    report.report_no = nodeInfo.business_min_id))
-        WHERE major.deleted = 0 and major.financial is not null
+        WHERE major.deleted = 0
         <if test="dto != null and dto.keyWord != null and dto.keyWord != '' ">
             AND (
             major.order_id LIKE CONCAT('%',#{dto.keyWord},'%') OR
             major.name LIKE CONCAT('%',#{dto.keyWord},'%') OR
-            report.name LIKE CONCAT('%',#{dto.keyWord},'%') OR
-            report.report_no LIKE CONCAT('%',#{dto.keyWord},'%') OR
+            pro.name LIKE CONCAT('%',#{dto.keyWord},'%') OR
+            pro.report_no LIKE CONCAT('%',#{dto.keyWord},'%') OR
             principal.name LIKE CONCAT('%',#{dto.keyWord},'%') OR
             major.business_object_type LIKE CONCAT('%',#{dto.keyWord},'%') OR
             major.allot_type LIKE CONCAT('%',#{dto.keyWord},'%') OR
@@ -135,13 +76,13 @@
         <if test="dto != null and dto.memberId != null">
             AND JSON_CONTAINS(major.members, CAST(#{dto.memberId} AS JSON))
         </if>
-        <if test="dto != null and dto.nodeCode != null">
-            AND nodeInfo.node = #{dto.nodeCode}
-        </if>
         <if test="dto != null and dto.startTime != null and dto.endTime!= null">
             AND (major.created BETWEEN #{dto.startTime} AND #{dto.endTime})
         </if>
-        GROUP BY reportNo,major.id
+        <if test="dto != null and dto.productionType != null and dto.productionType != '' ">
+            AND pro.production = #{dto.productionType}
+        </if>
+        GROUP BY pro.report_no,major.id
         ORDER BY major.created DESC
     </sql>
 
@@ -163,7 +104,38 @@
         COALESCE ( SUM( reCheckPer.normal_mistake ), 0 ) * 3 AS reCheckNormalMistakeScore,
         COALESCE ( SUM( reCheckPer.hard_mistake ), 0 ) * 8 AS reCheckHardMistakeScore,
         COALESCE ( SUM( reCheckPer.fatal_mistake ), 0 ) * 41 AS reCheckFatalMistakeScore,
-        COALESCE ( (COALESCE ( SUM( reCheckPer.normal_mistake ), 0 ) *3 ) + (COALESCE ( SUM( reCheckPer.hard_mistake ), 0 ) * 8) + (COALESCE ( SUM( reCheckPer.fatal_mistake ), 0 ) * 41) , 0) AS allMistakeScore
+        COALESCE ( SUM( spotCheckPer.normal_mistake ), 0 ) * 3 AS spotCheckNormalMistakeScore,
+        COALESCE ( SUM( spotCheckPer.hard_mistake ), 0 ) * 8 AS spotCheckHardMistakeScore,
+        COALESCE ( SUM( spotCheckPer.fatal_mistake ), 0 ) * 41 AS spotCheckFatalMistakeScore,
+        COALESCE ( SUM( insideCheckPer.normal_mistake ), 0 ) * 3 AS internalComplaintNormalMistakeScore,
+        COALESCE ( SUM( insideCheckPer.hard_mistake ), 0 ) * 8 AS internalComplaintHardMistakeScore,
+        COALESCE ( SUM( insideCheckPer.fatal_mistake ), 0 ) * 41 AS internalComplaintFatalMistakeScore,
+        COALESCE ( SUM( insideCheckPer.service_attitude ), 0 ) * 8 AS internalComplaintBadServiceAttitude,
+        COALESCE ( SUM( outsideCheckPer.normal_mistake ), 0 ) * 3 AS externalComplaintNormalMistakeScore,
+        COALESCE ( SUM( outsideCheckPer.hard_mistake ), 0 ) * 8 AS externalComplaintHardMistakeScore,
+        COALESCE ( SUM( outsideCheckPer.fatal_mistake ), 0 ) * 41 AS externalComplaintFatalMistakeScore,
+        COALESCE ( SUM( outsideCheckPer.service_attitude ), 0 ) * 8 AS externalComplaintBadServiceAttitude,
+        (COALESCE ( SUM( difficult.score ), 0 )) AS difficultScore,
+        (COALESCE ( SUM( generalManager.score ), 0 )) AS generalManagerScore,
+        (COALESCE ( SUM( integrated.score ), 0 )) AS integratedScore,
+        COALESCE ( (COALESCE ( SUM( reCheckPer.normal_mistake ), 0 ) * 3 ) +
+                   (COALESCE ( SUM( reCheckPer.hard_mistake ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( reCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                   (COALESCE ( SUM( spotCheckPer.normal_mistake ), 0 ) * 3 ) +
+                   (COALESCE ( SUM( spotCheckPer.hard_mistake ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( spotCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                   (COALESCE ( SUM( insideCheckPer.normal_mistake ), 0 ) * 3 ) +
+                   (COALESCE ( SUM( insideCheckPer.hard_mistake ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( insideCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                   (COALESCE ( SUM( insideCheckPer.service_attitude ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( outsideCheckPer.normal_mistake ), 0 ) * 3 ) +
+                   (COALESCE ( SUM( outsideCheckPer.hard_mistake ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( outsideCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                   (COALESCE ( SUM( outsideCheckPer.service_attitude ), 0 ) * 8 ) -
+                   (COALESCE ( SUM( difficult.score ), 0 )) -
+                   (COALESCE ( SUM( generalManager.score ), 0 )) -
+                   (COALESCE ( SUM( integrated.score ), 0 ))
+        , 0) AS allMistakeScore
         FROM
         (
         SELECT
@@ -193,6 +165,42 @@
             AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
         </if>
         ) AS reCheckPer ON reCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, fatal_mistake, hard_mistake, normal_mistake FROM
+        business_production_performance WHERE business_type = 'MAJOR_BUSINESS' AND check_loop = '抽检'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS spotCheckPer ON spotCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, fatal_mistake, hard_mistake, normal_mistake, service_attitude FROM
+        business_production_performance WHERE business_type = 'MAJOR_BUSINESS' AND check_loop = '内部'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS insideCheckPer ON insideCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, fatal_mistake, hard_mistake, normal_mistake, service_attitude FROM
+        business_production_performance WHERE business_type = 'MAJOR_BUSINESS' AND check_loop = '外部'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS outsideCheckPer ON outsideCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, score FROM
+        business_production_bonus_points WHERE business_type = 'MAJOR_BUSINESS' AND type = '疑难项目'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_bonus_points.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS difficult ON difficult.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, score FROM
+        business_production_bonus_points WHERE business_type = 'MAJOR_BUSINESS' AND type = '总经理'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_bonus_points.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS generalManager ON generalManager.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, score FROM
+        business_production_bonus_points WHERE business_type = 'MAJOR_BUSINESS' AND type = '部门综合'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_bonus_points.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS integrated ON integrated.production_id = orderInfo.production_id
         <where>
             <if test="dto != null and dto.departmentId != null">
                 AND department.id = #{dto.departmentId}
@@ -210,7 +218,32 @@
         COALESCE ( SUM( reCheckPer.normal_mistake ), 0 ) * 3 AS reCheckNormalMistakeScore,
         COALESCE ( SUM( reCheckPer.hard_mistake ), 0 ) * 8 AS reCheckHardMistakeScore,
         COALESCE ( SUM( reCheckPer.fatal_mistake ), 0 ) * 41 AS reCheckFatalMistakeScore,
-        COALESCE ( (COALESCE ( SUM( reCheckPer.normal_mistake ), 0 ) *3 ) + (COALESCE ( SUM( reCheckPer.hard_mistake ), 0 ) * 8) + (COALESCE ( SUM( reCheckPer.fatal_mistake ), 0 ) * 41) , 0) AS allMistakeScore
+        COALESCE ( SUM( spotCheckPer.normal_mistake ), 0 ) * 3 AS spotCheckNormalMistakeScore,
+        COALESCE ( SUM( spotCheckPer.hard_mistake ), 0 ) * 8 AS spotCheckHardMistakeScore,
+        COALESCE ( SUM( spotCheckPer.fatal_mistake ), 0 ) * 41 AS spotCheckFatalMistakeScore,
+        COALESCE ( SUM( insideCheckPer.normal_mistake ), 0 ) * 3 AS internalComplaintNormalMistakeScore,
+        COALESCE ( SUM( insideCheckPer.hard_mistake ), 0 ) * 8 AS internalComplaintHardMistakeScore,
+        COALESCE ( SUM( insideCheckPer.fatal_mistake ), 0 ) * 41 AS internalComplaintFatalMistakeScore,
+        COALESCE ( SUM( insideCheckPer.service_attitude ), 0 ) * 8 AS internalComplaintBadServiceAttitude,
+        COALESCE ( SUM( outsideCheckPer.normal_mistake ), 0 ) * 3 AS externalComplaintNormalMistakeScore,
+        COALESCE ( SUM( outsideCheckPer.hard_mistake ), 0 ) * 8 AS externalComplaintHardMistakeScore,
+        COALESCE ( SUM( outsideCheckPer.fatal_mistake ), 0 ) * 41 AS externalComplaintFatalMistakeScore,
+        COALESCE ( SUM( outsideCheckPer.service_attitude ), 0 ) * 8 AS externalComplaintBadServiceAttitude,
+        COALESCE ( (COALESCE ( SUM( reCheckPer.normal_mistake ), 0 ) * 3 ) +
+                   (COALESCE ( SUM( reCheckPer.hard_mistake ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( reCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                   (COALESCE ( SUM( spotCheckPer.normal_mistake ), 0 ) * 3 ) +
+                   (COALESCE ( SUM( spotCheckPer.hard_mistake ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( spotCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                   (COALESCE ( SUM( insideCheckPer.normal_mistake ), 0 ) * 3 ) +
+                   (COALESCE ( SUM( insideCheckPer.hard_mistake ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( insideCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                   (COALESCE ( SUM( insideCheckPer.service_attitude ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( outsideCheckPer.normal_mistake ), 0 ) * 3 ) +
+                   (COALESCE ( SUM( outsideCheckPer.hard_mistake ), 0 ) * 8 ) +
+                   (COALESCE ( SUM( outsideCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                   (COALESCE ( SUM( outsideCheckPer.service_attitude ), 0 ) * 8 )
+        , 0) AS allMistakeScore
         FROM (SELECT user.id AS id,
         user.`name` AS userName,
         department.name AS departmentName,
@@ -241,6 +274,24 @@
             AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
         </if>
         ) AS reCheckPer ON reCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, fatal_mistake, hard_mistake, normal_mistake FROM
+        business_production_performance WHERE business_type = 'MAJOR_BUSINESS' AND check_loop = '抽检'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS spotCheckPer ON spotCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, fatal_mistake, hard_mistake, normal_mistake, service_attitude FROM
+        business_production_performance WHERE business_type = 'MAJOR_BUSINESS' AND check_loop = '内部'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS insideCheckPer ON insideCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, fatal_mistake, hard_mistake, normal_mistake, service_attitude FROM
+        business_production_performance WHERE business_type = 'MAJOR_BUSINESS' AND check_loop = '外部'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS outsideCheckPer ON outsideCheckPer.production_id = orderInfo.production_id
         <where>
             <if test="dto != null and dto.departmentId != null">
                 AND user.departmentId = #{dto.departmentId}
@@ -264,7 +315,35 @@
         COALESCE ( SUM( reCheckPer.normal_mistake ), 0 ) AS reCheckNormalMistakeScore,
         COALESCE ( SUM( reCheckPer.hard_mistake ), 0 ) AS reCheckHardMistakeScore,
         COALESCE ( SUM( reCheckPer.fatal_mistake ), 0 ) AS reCheckFatalMistakeScore,
-        COALESCE ( (COALESCE ( SUM( checkPer.normal_mistake ), 0 ) * 3) + (COALESCE ( SUM( checkPer.hard_mistake ), 0 ) * 8) + (COALESCE ( SUM( checkPer.fatal_mistake ), 0 ) * 41) + (COALESCE ( SUM( reCheckPer.normal_mistake ), 0 ) *3 ) + (COALESCE ( SUM( reCheckPer.hard_mistake ), 0 ) * 8) + (COALESCE ( SUM( reCheckPer.fatal_mistake ), 0 ) * 41) , 0) AS allMistakeScore
+        COALESCE ( SUM( spotCheckPer.normal_mistake ), 0 ) AS spotCheckNormalMistakeScore,
+        COALESCE ( SUM( spotCheckPer.hard_mistake ), 0 ) AS spotCheckHardMistakeScore,
+        COALESCE ( SUM( spotCheckPer.fatal_mistake ), 0 ) AS spotCheckFatalMistakeScore,
+        COALESCE ( SUM( insideCheckPer.normal_mistake ), 0 ) AS internalComplaintNormalMistakeScore,
+        COALESCE ( SUM( insideCheckPer.hard_mistake ), 0 ) AS internalComplaintHardMistakeScore,
+        COALESCE ( SUM( insideCheckPer.fatal_mistake ), 0 ) AS internalComplaintFatalMistakeScore,
+        COALESCE ( SUM( insideCheckPer.service_attitude ), 0 ) AS internalComplaintBadServiceAttitude,
+        COALESCE ( SUM( outsideCheckPer.normal_mistake ), 0 ) AS externalComplaintNormalMistakeScore,
+        COALESCE ( SUM( outsideCheckPer.hard_mistake ), 0 ) AS externalComplaintHardMistakeScore,
+        COALESCE ( SUM( outsideCheckPer.fatal_mistake ), 0 ) AS externalComplaintFatalMistakeScore,
+        COALESCE ( SUM( outsideCheckPer.service_attitude ), 0 ) AS externalComplaintBadServiceAttitude,
+        COALESCE ( (COALESCE ( SUM( checkPer.normal_mistake ), 0 ) * 3 ) +
+                 (COALESCE ( SUM( checkPer.hard_mistake ), 0 ) * 8 ) +
+                 (COALESCE ( SUM( checkPer.fatal_mistake ), 0 ) * 41 ) +
+                 (COALESCE ( SUM( reCheckPer.normal_mistake ), 0 ) * 3 ) +
+                 (COALESCE ( SUM( reCheckPer.hard_mistake ), 0 ) * 8 ) +
+                 (COALESCE ( SUM( reCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                 (COALESCE ( SUM( spotCheckPer.normal_mistake ), 0 ) * 3 ) +
+                 (COALESCE ( SUM( spotCheckPer.hard_mistake ), 0 ) * 8 ) +
+                 (COALESCE ( SUM( spotCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                 (COALESCE ( SUM( insideCheckPer.normal_mistake ), 0 ) * 3 ) +
+                 (COALESCE ( SUM( insideCheckPer.hard_mistake ), 0 ) * 8 ) +
+                 (COALESCE ( SUM( insideCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                 (COALESCE ( SUM( insideCheckPer.service_attitude ), 0 ) * 8 ) +
+                 (COALESCE ( SUM( outsideCheckPer.normal_mistake ), 0 ) * 3 ) +
+                 (COALESCE ( SUM( outsideCheckPer.hard_mistake ), 0 ) * 8 ) +
+                 (COALESCE ( SUM( outsideCheckPer.fatal_mistake ), 0 ) * 41 ) +
+                 (COALESCE ( SUM( outsideCheckPer.service_attitude ), 0 ) * 8 )
+        , 0) AS allMistakeScore
         FROM (SELECT user.id AS id,
         user.`name` AS userName,
         department.name AS departmentName,
@@ -301,6 +380,24 @@
             AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
         </if>
         ) AS reCheckPer ON reCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, fatal_mistake, hard_mistake, normal_mistake FROM
+        business_production_performance WHERE business_type = 'MAJOR_BUSINESS' AND check_loop = '抽检'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS spotCheckPer ON spotCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, fatal_mistake, hard_mistake, normal_mistake, service_attitude FROM
+        business_production_performance WHERE business_type = 'MAJOR_BUSINESS' AND check_loop = '内部'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS insideCheckPer ON insideCheckPer.production_id = orderInfo.production_id
+        LEFT JOIN ( SELECT production_id, fatal_mistake, hard_mistake, normal_mistake, service_attitude FROM
+        business_production_performance WHERE business_type = 'MAJOR_BUSINESS' AND check_loop = '外部'
+        <if test="dto != null and dto.startTime != null and dto.endTime!= null">
+            AND (business_production_performance.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        </if>
+        ) AS outsideCheckPer ON outsideCheckPer.production_id = orderInfo.production_id
         <where>
             <if test="dto != null and dto.departmentId != null">
                 AND user.departmentId = #{dto.departmentId}
@@ -787,20 +884,22 @@
         WHEN 'normal' THEN performance.normal_mistake
         WHEN 'hard' THEN performance.hard_mistake
         WHEN 'fatal' THEN performance.fatal_mistake
+        WHEN 'service' THEN performance.service_attitude
         ELSE '-'
         END)                  AS mistakeCount,
         (CASE #{dto.mistakeType}
         WHEN 'normal' THEN performance.normal_mistake * 3
         WHEN 'hard' THEN performance.hard_mistake * 8
         WHEN 'fatal' THEN performance.fatal_mistake * 41
+        WHEN 'service' THEN performance.service_attitude * 8
         ELSE '-'
         END)                  AS mistakeScore,
         production.evaluate_amount AS evaluateAmount,
         performance.modified       AS checkTime,
         performance.reason         AS reason
         FROM major
-        LEFT JOIN major_production AS production ON major.id = production.major_id
-        LEFT JOIN business_production_performance AS performance ON production.id = performance.production_id
+        LEFT JOIN major_production AS production ON major.id = production.major_id AND production.deleted = 0
+        LEFT JOIN business_production_performance AS performance ON production.id = performance.production_id AND business_type = 'MAJOR_BUSINESS'
         LEFT JOIN customer_company AS customer ON customer.id = major.clientele_id
         LEFT JOIN user AS principal ON principal.id = major.principal_id
         LEFT JOIN user AS checker ON checker.id = performance.check_id
@@ -819,6 +918,9 @@
         <if test="dto.mistakeType == 'fatal' ">
             AND performance.fatal_mistake > 0
         </if>
+        <if test="dto.mistakeType == 'service' ">
+            AND performance.service_attitude > 0
+        </if>
     </sql>
 
     <!--查询错误详情列表-->
@@ -831,6 +933,51 @@
         <include refid="majorPerformanceDeductionDetailQuery" />
     </select>
 
+    <!--查询额外加减分详情SQL-->
+    <sql id="majorBonusPointsDetailQuery">
+        SELECT bonus.id,
+        major.order_id             AS orderId,
+        major.financial            AS financial,
+        major.members              AS members,
+        major.evaluate_aim         AS evaluateAim,
+        production.name            AS projectName,
+        customer.name              AS customerName,
+        production.report_no       AS productionNo,
+        (CASE production.production
+        WHEN 'STATEMENT' THEN '意见书'
+        WHEN 'LETTER' THEN '意见函'
+        WHEN 'REPORT' THEN '评估报告'
+        END)                       AS productionType,
+        principal.name             AS principalName,
+        bonus.score                AS score,
+        operator.name              AS operatorName,
+        production.evaluate_amount AS evaluateAmount,
+        bonus.modified             AS operationDate,
+        bonus.reason               AS reason
+        FROM major
+        LEFT JOIN major_production AS production ON major.id = production.major_id AND production.deleted = 0
+        LEFT JOIN business_production_bonus_points AS bonus ON production.id = bonus.production_id AND business_type = 'MAJOR_BUSINESS'
+        LEFT JOIN customer_company AS customer ON customer.id = major.clientele_id
+        LEFT JOIN user AS principal ON principal.id = major.principal_id
+        LEFT JOIN user AS operator ON operator.id = bonus.operator_id
+        WHERE major.department_id = #{dto.departmentId}
+        AND bonus.type = #{dto.checkLoop}
+        AND (bonus.modified BETWEEN #{dto.startTime} AND #{dto.endTime})
+        <if test="dto.principalId != null">
+            AND major.principal_id = #{dto.principalId}
+        </if>
+    </sql>
+
+    <!--查询额外加减分详情列表-->
+    <select id="getMajorBonusPointsDetailVO" resultType="com.dayou.vo.MajorBonusPointsDetailVO">
+        <include refid="majorBonusPointsDetailQuery" />
+    </select>
+
+    <!--导出额外加减分详情列表-->
+    <select id="exportMajorBonusPointsDetailVO" resultType="com.dayou.vo.MajorBonusPointsDetailVO">
+        <include refid="majorBonusPointsDetailQuery" />
+    </select>
+
     <!--评估部效率查询-->
     <!--大中型指定需要看了现场才算有效的接单数-->
     <select id="getMajorEvaluateDepEfficiencyVO" resultType="com.dayou.vo.MajorEvaluateEfficiencyVO">

+ 5 - 0
domain/src/main/java/com/dayou/dto/MajorStatisticalSelectDTO.java

@@ -125,4 +125,9 @@ public class MajorStatisticalSelectDTO {
      */
     private Boolean financialIsNull;
 
+    /**
+     * 产品类型
+     */
+    private String productionType;
+
 }

+ 62 - 0
domain/src/main/java/com/dayou/entity/BusinessProductionBonusPoints.java

@@ -0,0 +1,62 @@
+package com.dayou.entity;
+import com.dayou.common.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import com.dayou.annotation.ExcelSheet;
+import com.dayou.annotation.ExportCell;
+import com.dayou.annotation.ImportCell;
+/**
+ * <p>
+ * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)
+ * </p>
+ *
+ * @author GouGengquan
+ * @since 2025-05-28
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ExcelSheet(sheetName = "业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)")
+public class BusinessProductionBonusPoints extends BaseEntity {
+
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 业务类型
+     */
+    @ImportCell
+    @ExportCell(columnName = "业务类型")
+    private String businessType;
+
+    /**
+     * 产品id
+     */
+    private Long productionId;
+
+    /**
+     * 加减分类型(疑难项目\总经理\部门综合)
+     */
+    @ImportCell
+    @ExportCell(columnName = "加减分类型(疑难项目、总经理、部门综合)")
+    private String type;
+
+    /**
+     * 加减的分数
+     */
+    @ImportCell
+    @ExportCell(columnName = "加减的分数")
+    private Integer score;
+
+    /**
+     * 加减分原因
+     */
+    @ImportCell
+    @ExportCell(columnName = "加减分原因")
+    private String reason;
+
+    /**
+     * 操作人id
+     */
+    private Long operatorId;
+
+
+}

+ 8 - 1
domain/src/main/java/com/dayou/entity/BusinessProductionPerformance.java

@@ -35,7 +35,7 @@ public class BusinessProductionPerformance extends BaseEntity {
     private Long productionId;
 
     /**
-     * 审核轮次
+     * 审核轮次(三审\初审\四审\复审\抽检\内部\外部)
      */
     private String CheckLoop;
 
@@ -73,6 +73,13 @@ public class BusinessProductionPerformance extends BaseEntity {
      */
     private Long checkId;
 
+    /**
+     * 服务态度恶劣
+     */
+    @ImportCell
+    @ExportCell(columnName = "服务态度恶劣")
+    private Integer serviceAttitude;
+
     @TableField(exist = false)
     private String principal;
     @TableField(exist = false)

+ 99 - 0
domain/src/main/java/com/dayou/vo/MajorBonusPointsDetailVO.java

@@ -0,0 +1,99 @@
+package com.dayou.vo;
+
+import com.dayou.annotation.Excel;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+
+@Data
+public class MajorBonusPointsDetailVO {
+
+    private Integer id;
+
+    /**
+     * 项目编号
+     */
+    @Excel(name = "项目编号")
+    private String orderId;
+
+    /**
+     * 是否金融(金融/非金融)
+     */
+    @Excel(name = "是否金融")
+    private String financial;
+
+    /**
+     * 项目名称
+     */
+    @Excel(name = "项目名称")
+    private String projectName;
+
+    /**
+     * 客户名称
+     */
+    @Excel(name = "银行/单位")
+    private String customerName;
+
+    /**
+     * 产品类型
+     */
+    @Excel(name = "产品类型")
+    private String productionType;
+
+    /**
+     * 产品号
+     */
+    @Excel(name = "产品号")
+    private String productionNo;
+
+
+    /**
+     * 项目负责人
+     */
+    @Excel(name = "项目负责人")
+    private String principalName;
+
+    /**
+     * 参与人
+     */
+    @Excel(name = "参与人")
+    private String members;
+
+    /**
+     * 评估金额(万元)
+     */
+    @Excel(name = "评估金额(万元)")
+    private BigDecimal evaluateAmount;
+
+    /**
+     * 评估目的
+     */
+    @Excel(name = "评估目的")
+    private String evaluateAim;
+
+    /**
+     * 操作人
+     */
+    @Excel(name = "操作人")
+    private String operatorName;
+
+    /**
+     * 加减分
+     */
+    @Excel(name = "加减分")
+    private Integer score;
+
+    /**
+     * 操作时间
+     */
+    @Excel(name = "操作时间")
+    private LocalDate operationDate;
+
+    /**
+     * 加减分原因
+     */
+    @Excel(name = "加减分原因")
+    private String reason;
+
+}

+ 13 - 2
domain/src/main/java/com/dayou/vo/MajorLedgerVO.java

@@ -18,12 +18,23 @@ public class MajorLedgerVO {
     private String orderId;
 
     /**
-     * 报告号
+     * 产品id
      */
-    @Excel(name = "报告号")
+    private Long productionId;
+
+    /**
+     * 产品号
+     */
+    @Excel(name = "产品号")
     private String reportNo;
 
     /**
+     * 产品类型
+     */
+    @Excel(name = "产品类型")
+    private String productionType;
+
+    /**
      * 项目部名称
      */
     @Excel(name = "项目部名称")

+ 26 - 2
domain/src/main/java/com/dayou/vo/MajorPerformanceDeductionVO.java

@@ -65,6 +65,24 @@ public class MajorPerformanceDeductionVO {
     private Integer reCheckFatalMistakeScore;
 
     /**
+     * 抽检一般错误扣分
+     */
+    @Excel(name = "抽检一般错误")
+    private Integer spotCheckNormalMistakeScore;
+
+    /**
+     * 抽检较大错误扣分
+     */
+    @Excel(name = "抽检较大错误")
+    private Integer spotCheckHardMistakeScore;
+
+    /**
+     * 抽检严重错误扣分
+     */
+    @Excel(name = "抽检严重错误")
+    private Integer spotCheckFatalMistakeScore;
+
+    /**
      * 外部投诉一般错误扣分
      */
     @Excel(name = "外部投诉一般错误")
@@ -85,8 +103,8 @@ public class MajorPerformanceDeductionVO {
     /**
      * 外部投诉服务态度恶劣
      */
-    @Excel(name = "服务态度恶劣")
-    private Integer badServiceAttitude;
+    @Excel(name = "外部投诉服务态度恶劣")
+    private Integer externalComplaintBadServiceAttitude;
 
     /**
      * 内部投诉一般错误扣分
@@ -107,6 +125,12 @@ public class MajorPerformanceDeductionVO {
     private Integer internalComplaintFatalMistakeScore;
 
     /**
+     * 内部投诉服务态度恶劣
+     */
+    @Excel(name = "内部投诉服务态度恶劣")
+    private Integer internalComplaintBadServiceAttitude;
+
+    /**
      * 疑难项目加减分
      */
     @Excel(name = "疑难项目加减分")

+ 39 - 0
service/src/main/java/com/dayou/service/IBusinessProductionBonusPointsService.java

@@ -0,0 +1,39 @@
+package com.dayou.service;
+import com.dayou.entity.BusinessProductionBonusPoints;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等) 服务类
+ * </p>
+ *
+ * @author wucl
+ * @since 2025-05-28
+ */
+public interface IBusinessProductionBonusPointsService extends IService<BusinessProductionBonusPoints> {
+
+        Page<BusinessProductionBonusPoints> selectPage(Page page,BusinessProductionBonusPoints businessProductionBonusPoints);
+
+        BusinessProductionBonusPoints detail(Long id);
+
+        Boolean add(BusinessProductionBonusPoints businessProductionBonusPoints);
+
+        Boolean update(BusinessProductionBonusPoints businessProductionBonusPoints);
+
+        Boolean delete(Long id);
+
+        /**
+         * 根据产品id与业务类型查询额外加减分信息集合
+         * @param productionId 产品id
+         * @param businessType 业务类型
+         * @return List<BusinessProductionBonusPoints>
+         */
+        List<BusinessProductionBonusPoints> getList(Long productionId, String businessType);
+
+}

+ 15 - 0
service/src/main/java/com/dayou/service/IMajorStatisticalStatementService.java

@@ -82,6 +82,21 @@ public interface IMajorStatisticalStatementService {
     List<MajorPerformanceDeductionDetailVO> exportMajorPerformanceDeductionDetailVO(MajorStatisticalSelectDTO dto);
 
     /**
+     * 查询额外加减分详情列表
+     * @param page 分页
+     * @param dto 查询dto
+     * @return Page<MajorPerformanceDeductionDetailVO>
+     */
+    Page<MajorBonusPointsDetailVO> getMajorBonusPointsDetailVO(Page page, MajorStatisticalSelectDTO dto);
+
+    /**
+     * 导出额外加减分详情列表
+     * @param dto 查询dto
+     * @return List<MajorPerformanceDeductionDetailVO>
+     */
+    List<MajorBonusPointsDetailVO> exportMajorBonusPointsDetailVO(MajorStatisticalSelectDTO dto);
+
+    /**
      * 评估部效率查询
      * @param dto 查询dto
      * @return List<MajorEvaluateEfficiencyVO>

+ 81 - 0
service/src/main/java/com/dayou/service/impl/BusinessProductionBonusPointsServiceImpl.java

@@ -0,0 +1,81 @@
+package com.dayou.service.impl;
+
+import com.dayou.common.BaseEntity;
+import com.dayou.entity.BusinessProductionBonusPoints;
+import com.dayou.mapper.BusinessProductionBonusPointsMapper;
+import com.dayou.service.IBusinessProductionBonusPointsService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.dayou.utils.ExcelUtil;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.web.multipart.MultipartFile;
+import java.util.List;
+import java.util.ArrayList;
+import org.springframework.transaction.annotation.Transactional;
+import com.dayou.enums.BatchTaskTypeEnum;
+
+/**
+ * <p>
+ * 业务产品额外加减分(如疑难项目、总经理、部门综合加减分等) 服务实现类
+ * </p>
+ *
+ * @author wucl
+ * @since 2025-05-28
+ */
+@Service
+public class BusinessProductionBonusPointsServiceImpl extends ServiceImpl<BusinessProductionBonusPointsMapper, BusinessProductionBonusPoints> implements IBusinessProductionBonusPointsService {
+
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Page<BusinessProductionBonusPoints> selectPage(Page page,BusinessProductionBonusPoints businessProductionBonusPoints){
+        return this.page(page, new QueryWrapper<BusinessProductionBonusPoints>(businessProductionBonusPoints));
+    }
+
+
+    @Override
+    public BusinessProductionBonusPoints detail(Long id){
+        return this.getById(id);
+    }
+
+    @Override
+    public Boolean add(BusinessProductionBonusPoints businessProductionBonusPoints){
+        return  this.save(businessProductionBonusPoints);
+    }
+
+    @Override
+    public Boolean update(BusinessProductionBonusPoints businessProductionBonusPoints){
+        return  this.updateById(businessProductionBonusPoints);
+    }
+
+    @Override
+    public Boolean delete(Long id){
+        //逻辑删除
+        return this.removeById(id);
+    }
+
+    /**
+     * 根据产品id与业务类型查询额外加减分信息集合
+     * @param productionId 产品id
+     * @param businessType 业务类型
+     * @return List<BusinessProductionBonusPoints>
+     */
+    @Override
+    public List<BusinessProductionBonusPoints> getList(Long productionId, String businessType) {
+        return this.list(new LambdaQueryWrapper<BusinessProductionBonusPoints>()
+                .eq(BaseEntity::getDeleted, 0)
+                .eq(BusinessProductionBonusPoints::getProductionId, productionId)
+                .eq(BusinessProductionBonusPoints::getBusinessType, businessType));
+    }
+}

+ 22 - 4
service/src/main/java/com/dayou/service/impl/MajorStatisticalStatementServiceImpl.java

@@ -21,10 +21,7 @@ import com.dayou.vo.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Optional;
+import java.util.*;
 
 @Service
 public class MajorStatisticalStatementServiceImpl implements IMajorStatisticalStatementService {
@@ -173,6 +170,27 @@ public class MajorStatisticalStatementServiceImpl implements IMajorStatisticalSt
     }
 
     /**
+     * 查询额外加减分详情列表
+     * @param page 分页
+     * @param dto 查询dto
+     * @return Page<MajorPerformanceDeductionDetailVO>
+     */
+    @Override
+    public Page<MajorBonusPointsDetailVO> getMajorBonusPointsDetailVO(Page page, MajorStatisticalSelectDTO dto) {
+        return majorStatisticalStatementMapper.getMajorBonusPointsDetailVO(page, dto);
+    }
+
+    /**
+     * 导出额外加减分详情列表
+     * @param dto 查询dto
+     * @return List<MajorPerformanceDeductionDetailVO>
+     */
+    @Override
+    public List<MajorBonusPointsDetailVO> exportMajorBonusPointsDetailVO(MajorStatisticalSelectDTO dto) {
+        return majorStatisticalStatementMapper.exportMajorBonusPointsDetailVO(dto);
+    }
+
+    /**
      * 评估部效率查询
      * @param dto 查询dto
      * @return List<MajorEvaluateEfficiencyVO>

+ 35 - 1
sql/update_sql.sql

@@ -894,4 +894,38 @@ ALTER TABLE assets_production ADD COLUMN validate_code VARCHAR ( 255 ) COMMENT '
   修改人:苟耕铨
   未更新到test-env
  */
-ALTER TABLE `finance_fine` MODIFY `status` bit ( 1 ) DEFAULT 1 NOT NULL COMMENT '罚款记录确认状态(默认1已确认)';
+ALTER TABLE `finance_fine` MODIFY `status` bit ( 1 ) DEFAULT 1 NOT NULL COMMENT '罚款记录确认状态(默认1已确认)';
+
+/**
+  日期:2025-05-29
+  修改人:苟耕铨
+  未更新到test-env
+ */
+#  新增字段
+ALTER TABLE business_production_performance COMMENT = '业务产品绩效扣分';
+ALTER TABLE business_production_performance ADD service_attitude INT ( 32 ) DEFAULT NULL COMMENT '服务态度恶劣';
+# 新增索引
+ALTER TABLE business_production_performance ADD KEY `check_loop` (`check_loop`) USING BTREE;
+ALTER TABLE business_production_performance ADD KEY `production_id` (`production_id`) USING BTREE;
+ALTER TABLE business_production_performance ADD KEY `business_type` (`business_type`) USING BTREE;
+# 新增表
+CREATE TABLE `business_production_bonus_points`
+(
+    `id`            bigint(20)                                             NOT NULL AUTO_INCREMENT COMMENT '主键',
+    `business_type` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL COMMENT '业务类型',
+    `production_id` bigint(20)                                             NOT NULL COMMENT '产品id',
+    `type`          varchar(50)                                            NOT NULL COMMENT '加减分类型(疑难项目\\总经理\\部门综合)',
+    `score`         int(11)                                                         DEFAULT NULL COMMENT '加减的分数',
+    `reason`        text CHARACTER SET utf8 COLLATE utf8_unicode_ci COMMENT '加减分原因',
+    `operator_id`   bigint(20)                                             NOT NULL COMMENT '操作人id',
+    `deleted`       bit(1)                                                 NOT NULL DEFAULT b'0' COMMENT '逻辑删除标识:1:删除 0:未删除',
+    `created`       datetime                                               NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+    `modified`      timestamp(6)                                           NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) COMMENT '修改时间',
+    PRIMARY KEY (`id`),
+    KEY `type` (`type`) USING BTREE,
+    KEY `production_id` (`production_id`) USING BTREE,
+    KEY `business_type` (`business_type`) USING BTREE,
+    KEY `modified` (`modified`) USING BTREE
+) ENGINE = InnoDB
+  AUTO_INCREMENT = 4
+  DEFAULT CHARSET = utf8mb4 COMMENT ='业务产品额外加减分(如疑难项目、总经理、部门综合加减分等)';