Przeglądaj źródła

事故隐患 危险源

77681 2 dni temu
rodzic
commit
1188288282
21 zmienionych plików z 554 dodań i 100 usunięć
  1. 15 4
      gw-slaj/src/main/java/com/goldenwater/slaj/acci/controller/BisAcciMontController.java
  2. 5 1
      gw-slaj/src/main/java/com/goldenwater/slaj/acci/controller/ObjAcciController.java
  3. 2 0
      gw-slaj/src/main/java/com/goldenwater/slaj/acci/domain/ObjAcciVo.java
  4. 23 0
      gw-slaj/src/main/java/com/goldenwater/slaj/hazard/controller/ObjHachController.java
  5. 28 2
      gw-slaj/src/main/java/com/goldenwater/slaj/hazard/controller/ObjHazController.java
  6. 25 1
      gw-slaj/src/main/java/com/goldenwater/slaj/hazard/controller/TBusiHazCountController.java
  7. 24 1
      gw-slaj/src/main/java/com/goldenwater/slaj/hidd/controller/BisMajHiddSupController.java
  8. 31 3
      gw-slaj/src/main/java/com/goldenwater/slaj/hidd/controller/ObjHiddController.java
  9. 12 1
      gw-slaj/src/main/java/com/goldenwater/slaj/hidd/controller/TBusiHiddCountController.java
  10. 16 11
      gw-slaj/src/main/java/com/goldenwater/slaj/hidd/service/impl/BisOrgMonRepPeriServiceImpl.java
  11. 7 2
      gw-slaj/src/main/resources/mapper/slaj/acci/BisAcciMontMapper.xml
  12. 55 0
      gw-slaj/src/main/resources/mapper/slaj/acci/ObjAcciMapper.xml
  13. 9 1
      gw-slaj/src/main/resources/mapper/slaj/hazard/ObjHachMapper.xml
  14. 3 2
      gw-slaj/src/main/resources/mapper/slaj/hazard/TBusiHazCountMapper.xml
  15. 9 1
      gw-slaj/src/main/resources/mapper/slaj/hidd/AttOrgBaseMapper.xml
  16. 32 21
      gw-slaj/src/main/resources/mapper/slaj/hidd/ObjHiddMapper.xml
  17. 2 0
      gw-ui/src/api/slaj/acci.js
  18. 8 5
      gw-ui/src/views/slaj/acci/manage.vue
  19. 92 32
      gw-ui/src/views/slaj/acci/month.vue
  20. 5 2
      gw-ui/src/views/slaj/hazard/manage.vue
  21. 151 10
      gw-ui/src/views/slaj/hidd/month.vue

+ 15 - 4
gw-slaj/src/main/java/com/goldenwater/slaj/acci/controller/BisAcciMontController.java

@@ -66,10 +66,12 @@ public class BisAcciMontController extends BaseController {
     public AjaxResult submit(@RequestBody BisAcciMont bisAcciMont) {
         BisAcciMont existing = bisAcciMontService.selectBisAcciMontByGuid(bisAcciMont.getGuid());
         if (existing == null) {
-            bisAcciMont.setMontStat("1");
+            // 新记录:标记为已上报(rep_act 是实际存储的上报标记,mont_stat 为查询计算值)
+            bisAcciMont.setRepAct("1");
             return toAjax(bisAcciMontService.insertBisAcciMont(bisAcciMont));
         }
-        existing.setMontStat("1");
+        existing.setRepAct("1");
+        existing.setUpdTime(new java.util.Date());
         return toAjax(bisAcciMontService.updateBisAcciMont(existing));
     }
 
@@ -156,9 +158,14 @@ public class BisAcciMontController extends BaseController {
         mont.setEconLoss(acci.getEconLoss());
         mont.setRepAct("0");
         mont.setAcciWiunType(acci.getAcciWiunType());
-        mont.setRepWiunCode(acci.getSgdwName());
+        // 报送单位编码 = 事故单位GUID(旧版字段语义为编码;避免名称JOIN的单位改名/重名风险)
+        mont.setRepWiunCode(acci.getAcciWiunGuid());
         mont.setMont(acci.getOccuTime() != null ? new java.text.SimpleDateFormat("yyyy-MM").format(acci.getOccuTime()) : "");
         mont.setCollTime(new java.util.Date());
+        // 同步原事故对象状态:快报已转月报(rep_stat='2'),供快报/月报Tab按状态区分
+        acci.setRepStat("2");
+        acci.setUpdTime(new java.util.Date());
+        objAcciService.updateObjAcci(acci);
         return toAjax(bisAcciMontService.insertBisAcciMont(mont));
     }
 
@@ -288,7 +295,10 @@ public class BisAcciMontController extends BaseController {
      * 水利部(角色9)/管理员(角色1)看全部;其他角色只看本单位及下属单位数据。
      */
     private void fillDataScope(BisAcciMont vo) {
-        if (isAdmin()) return;
+                if (isAdmin()) {
+            vo.setOrgGuid(null);
+            return;
+        }
         vo.setOrgGuid(getDeptId());
     }
 
@@ -301,3 +311,4 @@ public class BisAcciMontController extends BaseController {
         return false;
     }
 }
+

+ 5 - 1
gw-slaj/src/main/java/com/goldenwater/slaj/acci/controller/ObjAcciController.java

@@ -281,7 +281,10 @@ public class ObjAcciController extends BaseController {
      * 水利部(角色9)看全部;其他角色只看本单位数据。
      */
     private void fillDataScope(ObjAcciVo vo) {
-        if (isAdmin()) return;
+                if (isAdmin()) {
+            vo.setOrgGuid(null);
+            return;
+        }
         vo.setOrgGuid(getDeptId());
     }
 
@@ -299,3 +302,4 @@ public class ObjAcciController extends BaseController {
         return false;
     }
 }
+

+ 2 - 0
gw-slaj/src/main/java/com/goldenwater/slaj/acci/domain/ObjAcciVo.java

@@ -24,4 +24,6 @@ public class ObjAcciVo extends ObjAcci {
     private String orgName;
     /** 单位主键(数据权限过滤用) */
     private String orgGuid;
+    /** 数据范围类型:sub=下级单位 cons=施工单位(本工程关联) 空=本单位及以下 */
+    private String scopeType;
 }

+ 23 - 0
gw-slaj/src/main/java/com/goldenwater/slaj/hazard/controller/ObjHachController.java

@@ -26,6 +26,7 @@ public class ObjHachController extends BaseController {
 
     @GetMapping("/list")
     public TableDataInfo list(ObjHachVo objHachVo) {
+                fillDataScope(objHachVo);
         startPage();
         List<ObjHachVo> list = objHachService.selectObjHachList(objHachVo);
         return getDataTable(list);
@@ -59,4 +60,26 @@ public class ObjHachController extends BaseController {
         ExcelUtil<ObjHachVo> util = new ExcelUtil<ObjHachVo>(ObjHachVo.class);
         util.exportExcel(response, list, "危化品对象数据");
     }
+
+    /**
+     * 数据范围过滤:水利部(9)/系统管理员(1) 看全量,其他角色限本单位
+     */
+    private void fillDataScope(ObjHachVo vo) {
+                if (isAdmin()) {
+            vo.setOrgGuid(null);
+            return;
+        }
+        vo.setOrgGuid(getDeptId());
+    }
+
+    private boolean isAdmin() {
+        String[] roleIds = getLoginUser().getUser().getRoleIds();
+        if (roleIds == null) return false;
+        for (String roleId : roleIds) {
+            if ("1".equals(roleId) || "9".equals(roleId)) return true;
+        }
+        return false;
+    }
 }
+
+

+ 28 - 2
gw-slaj/src/main/java/com/goldenwater/slaj/hazard/controller/ObjHazController.java

@@ -12,6 +12,7 @@ import com.goldenwater.common.core.domain.AjaxResult;
 import com.goldenwater.common.core.page.TableDataInfo;
 import com.goldenwater.common.enums.BusinessType;
 import com.goldenwater.common.utils.poi.ExcelUtil;
+import com.goldenwater.common.utils.SecurityUtils;
 import com.goldenwater.slaj.hazard.domain.ObjHaz;
 import com.goldenwater.slaj.hazard.domain.ObjHazVo;
 import com.goldenwater.slaj.hazard.service.IObjHazService;
@@ -27,6 +28,7 @@ public class ObjHazController extends BaseController {
 
     @GetMapping("/list")
     public TableDataInfo list(ObjHazVo objHazVo) {
+                fillDataScope(objHazVo);
         startPage();
         List<ObjHazVo> list = objHazService.selectObjHazList(objHazVo);
         return getDataTable(list);
@@ -34,7 +36,7 @@ public class ObjHazController extends BaseController {
 
     @GetMapping("/listWithScope")
     public TableDataInfo listWithScope(ObjHazVo objHazVo) {
-        objHazVo.setOrgGuid(getDeptId());
+                fillDataScope(objHazVo);
         startPage();
         List<ObjHazVo> list = objHazService.selectObjHazListWithScope(objHazVo);
         return getDataTable(list);
@@ -77,9 +79,33 @@ public class ObjHazController extends BaseController {
         params.put("hazSort", hazSort);
         params.put("engName", engName);
         params.put("orgName", orgName);
-        params.put("orgGuid", getDeptId());
+        params.put("orgGuid", isAdmin() ? null : getDeptId());
         startPage();
         List<Map<String, Object>> list = objHazService.selectHazGroupBy(params);
         return getDataTable(list);
     }
+
+    /**
+     * 数据范围过滤:水利部(9)/系统管理员(1) 看全量,其他角色限本单位
+     */
+    private void fillDataScope(ObjHazVo vo) {
+                if (isAdmin()) {
+            vo.setOrgGuid(null);
+            return;
+        }
+        vo.setOrgGuid(getDeptId());
+    }
+
+    private boolean isAdmin() {
+        String[] roleIds = getLoginUser().getUser().getRoleIds();
+        if (roleIds == null) return false;
+        for (String roleId : roleIds) {
+            if ("1".equals(roleId) || "9".equals(roleId)) return true;
+        }
+        return false;
+    }
 }
+
+
+
+

+ 25 - 1
gw-slaj/src/main/java/com/goldenwater/slaj/hazard/controller/TBusiHazCountController.java

@@ -11,6 +11,7 @@ import com.goldenwater.common.core.page.TableDataInfo;
 import com.goldenwater.slaj.hazard.domain.TBusiHazCount;
 import com.goldenwater.slaj.hazard.domain.TBusiHazCountMon;
 import com.goldenwater.slaj.hazard.service.ITBusiHazCountService;
+import com.goldenwater.common.utils.SecurityUtils;
 import com.goldenwater.slaj.hazard.service.ITBusiHazCountMonService;
 
 /**
@@ -34,7 +35,7 @@ public class TBusiHazCountController extends BaseController {
 
     @GetMapping("/listWithScope")
     public TableDataInfo listWithScope(TBusiHazCount tBusiHazCount) {
-        tBusiHazCount.setOrgGuid(getDeptId());
+                fillDataScope(tBusiHazCount);
         startPage();
         List<TBusiHazCount> list = tBusiHazCountService.selectTBusiHazCountListWithScope(tBusiHazCount);
         return getDataTable(list);
@@ -110,4 +111,27 @@ public class TBusiHazCountController extends BaseController {
         result.put("totalControlCount", totalYbGk + totalZdGk);
         return AjaxResult.success(result);
     }
+
+    /**
+     * 数据范围过滤:水利部(9)/系统管理员(1) 看全量,其他角色限本单位
+     */
+    private void fillDataScope(TBusiHazCount vo) {
+                if (isAdmin()) {
+            vo.setOrgGuid(null);
+            return;
+        }
+        vo.setOrgGuid(getDeptId());
+    }
+
+    private boolean isAdmin() {
+        String[] roleIds = getLoginUser().getUser().getRoleIds();
+        if (roleIds == null) return false;
+        for (String roleId : roleIds) {
+            if ("1".equals(roleId) || "9".equals(roleId)) return true;
+        }
+        return false;
+    }
 }
+
+
+

+ 24 - 1
gw-slaj/src/main/java/com/goldenwater/slaj/hidd/controller/BisMajHiddSupController.java

@@ -15,6 +15,7 @@ import com.goldenwater.common.core.domain.AjaxResult;
 import com.goldenwater.common.core.page.TableDataInfo;
 import com.goldenwater.common.enums.BusinessType;
 import com.goldenwater.common.utils.poi.ExcelUtil;
+import com.goldenwater.common.utils.SecurityUtils;
 import com.goldenwater.slaj.hidd.domain.BisMajHiddSup;
 import com.goldenwater.slaj.hidd.domain.BisMajHiddSupAddVo;
 import com.goldenwater.slaj.hidd.domain.BisMajHiddSupVo;
@@ -45,7 +46,7 @@ public class BisMajHiddSupController extends BaseController {
 
     @GetMapping("/list")
     public TableDataInfo list(BisMajHiddSupVo bisMajHiddSup) {
-        bisMajHiddSup.setOrgGuid(getDeptId());
+                fillDataScope(bisMajHiddSup);
         startPage();
         List<BisMajHiddSupVo> list = bisMajHiddSupService.selectBisMajHiddSupList(bisMajHiddSup);
         return getDataTable(list);
@@ -222,4 +223,26 @@ public class BisMajHiddSupController extends BaseController {
         }
         return toAjax(bisMajHiddSupService.deleteBisMajHiddSupByGuids(new String[]{guid}));
     }
+
+    /**
+     * 数据范围过滤:水利部(9)/系统管理员(1) 看全量,其他角色限本单位
+     */
+    private void fillDataScope(BisMajHiddSupVo vo) {
+                if (isAdmin()) {
+            vo.setOrgGuid(null);
+            return;
+        }
+        vo.setOrgGuid(getDeptId());
+    }
+
+    private boolean isAdmin() {
+        String[] roleIds = getLoginUser().getUser().getRoleIds();
+        if (roleIds == null) return false;
+        for (String roleId : roleIds) {
+            if ("1".equals(roleId) || "9".equals(roleId)) return true;
+        }
+        return false;
+    }
 }
+
+

+ 31 - 3
gw-slaj/src/main/java/com/goldenwater/slaj/hidd/controller/ObjHiddController.java

@@ -22,6 +22,7 @@ import com.goldenwater.common.annotation.Log;
 import com.goldenwater.common.enums.BusinessType;
 import org.springframework.web.multipart.MultipartFile;
 import com.goldenwater.common.utils.poi.ExcelUtil;
+import com.goldenwater.common.utils.SecurityUtils;
 
 /**
  * 隐患对象
@@ -40,6 +41,7 @@ public class ObjHiddController extends BaseController {
 
     @GetMapping("/list")
     public TableDataInfo list(ObjHidd objHidd) {
+        fillDataScope(objHidd);
         startPage();
         List<ObjHiddVo> list = objHiddService.selectObjHiddList(objHidd);
         return getDataTable(list);
@@ -79,6 +81,7 @@ public class ObjHiddController extends BaseController {
      */
     @GetMapping("/listByName")
     public TableDataInfo listByName(ObjHidd objHidd) {
+                fillDataScope(objHidd);
         startPage();
         List<ObjHiddVo> list = objHiddService.selectObjHiddListByName(objHidd);
         return getDataTable(list);
@@ -89,6 +92,7 @@ public class ObjHiddController extends BaseController {
      */
     @GetMapping("/nextDepList")
     public TableDataInfo nextDepList(ObjHidd objHidd) {
+                fillDataScope(objHidd);
         startPage();
         List<ObjHiddVo> list = objHiddService.selectNextDepHiddList(objHidd);
         return getDataTable(list);
@@ -161,7 +165,7 @@ public class ObjHiddController extends BaseController {
         params.put("orgName", orgName);
         params.put("collTime", collTime);
         params.put("hiddClas", hiddClas);
-        params.put("orgGuid", getDeptId());
+        params.put("orgGuid", isAdmin() ? null : getDeptId());
         startPage();
         // 非工程隐患按管理单位分组(不关联工程表),工程隐患按工程+单位分组
         List<Map<String, Object>> list;
@@ -186,7 +190,7 @@ public class ObjHiddController extends BaseController {
         params.put("orgName", orgName);
         params.put("collTime", collTime);
         params.put("hiddClas", hiddClas);
-        params.put("orgGuid", getDeptId());
+        params.put("orgGuid", isAdmin() ? null : getDeptId());
         startPage();
         List<ObjHiddVo> list = objHiddService.selectObjHiddDrillList(params);
         return getDataTable(list);
@@ -204,7 +208,7 @@ public class ObjHiddController extends BaseController {
         params.put("orgName", orgName);
         params.put("collTime", collTime);
         params.put("hiddClas", hiddClas);
-        params.put("orgGuid", getDeptId());
+        params.put("orgGuid", isAdmin() ? null : getDeptId());
         List<Map<String, Object>> list;
         if ("2".equals(hiddClas)) {
             list = objHiddService.selectHiddGroupByNonEng(params);
@@ -318,4 +322,28 @@ public class ObjHiddController extends BaseController {
         }
         return toAjax(count);
     }
+
+    /**
+     * 数据范围过滤:水利部(9)/系统管理员(1) 看全量,其他角色限本单位
+     */
+    private void fillDataScope(ObjHidd vo) {
+                if (isAdmin()) {
+            vo.setOrgGuid(null);
+            return;
+        }
+        vo.setOrgGuid(getDeptId());
+    }
+
+    private boolean isAdmin() {
+        String[] roleIds = getLoginUser().getUser().getRoleIds();
+        if (roleIds == null) return false;
+        for (String roleId : roleIds) {
+            if ("1".equals(roleId) || "9".equals(roleId)) return true;
+        }
+        return false;
+    }
 }
+
+
+
+

+ 12 - 1
gw-slaj/src/main/java/com/goldenwater/slaj/hidd/controller/TBusiHiddCountController.java

@@ -15,6 +15,7 @@ import org.springframework.security.access.prepost.PreAuthorize;
 import com.goldenwater.common.annotation.Log;
 import com.goldenwater.common.enums.BusinessType;
 import com.goldenwater.common.utils.poi.ExcelUtil;
+import com.goldenwater.common.utils.SecurityUtils;
 
 @RestController
 @RequestMapping("/hidd/count")
@@ -24,7 +25,7 @@ public class TBusiHiddCountController extends BaseController {
 
     @GetMapping("/list")
     public TableDataInfo list(TBusiHiddCountVo vo) {
-        vo.setOrgGuid(getDeptId());
+        vo.setOrgGuid(isAdmin() ? null : getDeptId());
         startPage();
         // 实时综合统计:不依赖 t_busi_hidd_count 预统计表,改为实时聚合
         List<TBusiHiddCountVo> list = tBusiHiddCountService.selectTBusiHiddCountRealtimeList(vo);
@@ -97,4 +98,14 @@ public class TBusiHiddCountController extends BaseController {
         List<Map<String, Object>> list = tBusiHiddCountService.selectRectifyRateChart(params);
         return AjaxResult.success(list);
     }
+
+    private boolean isAdmin() {
+        String[] roleIds = getLoginUser().getUser().getRoleIds();
+        if (roleIds == null) return false;
+        for (String roleId : roleIds) {
+            if ("1".equals(roleId) || "9".equals(roleId)) return true;
+        }
+        return false;
+    }
 }
+

+ 16 - 11
gw-slaj/src/main/java/com/goldenwater/slaj/hidd/service/impl/BisOrgMonRepPeriServiceImpl.java

@@ -179,20 +179,24 @@ public class BisOrgMonRepPeriServiceImpl implements IBisOrgMonRepPeriService {
      * 规则:每月7日-次月6日为上报窗口期
      * 不在窗口期内需要解锁才能上报
      */
-    private void validateReportTimeWindow(BisOrgMonRepPeri period) {
-        LocalDate today = LocalDate.now();
-        int dayOfMonth = today.getDayOfMonth();
-        
-        // 检查是否在上报时间窗口内(7日-次月6日)
-        // 如果是1-6日,说明是在上报上个月的月报,允许
-        // 如果是7-31日,说明是在上报当月的月报,允许
-        // 但是需要检查月报期间的lockStatus
+        private void validateReportTimeWindow(BisOrgMonRepPeri period) {
+        // 上报时间窗:每月7日 - 下月6日
+        // 1-6日:上报上个月的月报;7-31日:上报本月的月报
+        // 通过期间 startDate/endDate 判断当前日期是否在窗口内
         if ("1".equals(period.getLockStatus())) {
-            throw new RuntimeException("该月报已被锁定,请联系上级单位解锁后再上报");
+            throw new RuntimeException("该月报已锁定,请联系上级单位处理后上报");
+        }
+        if (period.getStartDate() == null || period.getEndDate() == null) {
+            return;
+        }
+        LocalDate today = LocalDate.now();
+        LocalDate start = new java.sql.Date(period.getStartDate().getTime()).toLocalDate();
+        LocalDate end = new java.sql.Date(period.getEndDate().getTime()).toLocalDate();
+        if (today.isBefore(start) || today.isAfter(end)) {
+            throw new RuntimeException("当前不在上报时间窗口内(" + start + " 至 " + end + "),请勿上报");
         }
     }
-
-    @Override
+@Override
     public int returnMonth(String guid, String returnDesc) {
         BisOrgMonRepPeri period = new BisOrgMonRepPeri();
         period.setGuid(guid);
@@ -289,3 +293,4 @@ public class BisOrgMonRepPeriServiceImpl implements IBisOrgMonRepPeriService {
         return parentReported == 0;
     }
 }
+

+ 7 - 2
gw-slaj/src/main/resources/mapper/slaj/acci/BisAcciMontMapper.xml

@@ -67,7 +67,8 @@
                        else '0' end as mont_stat,
                        case when m.monthly_audit_result is not null then '1' else '0' end as lock_status
                 from bis_acci_mont m
-                inner join att_org_base o on m.rep_wiun_code = o.org_name
+                -- rep_wiun_code 存报送单位GUID(与旧版字段"编码"语义一致),按 guid 关联单位
+                inner join att_org_base o on m.rep_wiun_code = o.guid
                 inner join subOrgs s on o.guid = s.guid
             </when>
             <otherwise>
@@ -81,6 +82,9 @@
             <if test="acciGrad != null and acciGrad != ''">AND acci_grad = #{acciGrad}</if>
             <if test="occuTime != null and occuTime != ''">AND occu_time = #{occuTime}</if>
             <if test="acciWiunType != null and acciWiunType != ''">AND acci_wiun_type = #{acciWiunType}</if>
+            <if test="monthlyAudit != null and monthlyAudit != ''">AND monthly_audit = #{monthlyAudit}</if>
+            <if test="monthlyAuditResult != null and monthlyAuditResult != ''">AND monthly_audit_result = #{monthlyAuditResult}</if>
+            <if test="repAct != null and repAct != ''">AND rep_act = #{repAct}</if>
             <if test="recPers != null and recPers != ''">AND rec_pers = #{recPers}</if>
         </where>
     </select>
@@ -115,6 +119,7 @@
             <if test="returninfo != null">returninfo = #{returninfo},</if>
             <if test="revocationAudit != null">revocation_audit = #{revocationAudit},</if>
             <if test="revocationAuditResult != null">revocation_audit_result = #{revocationAuditResult},</if>
+            <if test="lockStatus != null">lock_status = #{lockStatus},</if>
             <if test="collTime != null">coll_time = #{collTime},</if>
             <if test="updTime != null">upd_time = #{updTime},</if>
             <if test="recPers != null">rec_pers = #{recPers},</if>
@@ -133,7 +138,7 @@
     </delete>
 
     <update id="batchUnlock">
-        update bis_acci_mont set monthly_audit_result = null, rep_act = '0' where guid in
+        update bis_acci_mont set monthly_audit_result = null, rep_act = '0', lock_status = '0' where guid in
         <foreach item="guid" collection="array" open="(" separator="," close=")">
             #{guid}
         </foreach>

+ 55 - 0
gw-slaj/src/main/resources/mapper/slaj/acci/ObjAcciMapper.xml

@@ -51,6 +51,61 @@
     </select>
     <select id="selectObjAcciList" parameterType="com.goldenwater.slaj.acci.domain.ObjAcciVo" resultMap="ObjAcciResult">
         <choose>
+            <!-- 下级单位数据(scopeType=sub):直接下级(组织树pguid) + 行政下属,排除本单位 -->
+            <when test="scopeType != null and scopeType == 'sub'.toString()">
+                WITH RECURSIVE subOrgs AS (
+                    SELECT b.guid, b.org_name FROM att_org_base b
+                    WHERE b.pguid = #{orgGuid}
+                    UNION ALL
+                    SELECT e.org_guid, o.org_name FROM att_org_ext e
+                    LEFT JOIN att_org_base o ON o.guid = e.org_guid
+                    WHERE e.admin_wiun_guid = #{orgGuid}
+                )
+                select a.guid, a.p_guid, a.acci_wiun_guid, a.acci_wiun_type, a.acci_cate, a.occu_time,
+                       a.occu_loc, a.miss_num, a.ser_inj_num, a.cas_num, a.econ_loss, a.otlcol_guui_vicm,
+                       a.resc_trea_meas, a.conta_pers, a.offi_tel, a.rep_stat, a.note, a.coll_time,
+                       a.upd_time, a.rec_pers, a.sgdw_name, a.acci_grad, a.eng_guid, a.to_date, a.tend_guid,
+                       a.sgdw_name || '事故' as acci_name,
+                       e.eng_name, t.tend_name, bi.if_resp_acci as if_duty, bi.if_pho_rep as if_phone, bi.acci_cause
+                from obj_acci a
+                inner join subOrgs s on a.acci_wiun_guid = s.guid
+                left join att_eng_base e on a.eng_guid = e.guid
+                left join obj_tend t on a.tend_guid = t.guid
+                left join bis_acci_inve bi on a.guid = bi.acci_guid
+            </when>
+            <!-- 施工单位数据(scopeType=cons):本单位工程的参建施工单位(rel_tend_org 关联) -->
+            <when test="scopeType != null and scopeType == 'cons'.toString()">
+                select a.guid, a.p_guid, a.acci_wiun_guid, a.acci_wiun_type, a.acci_cate, a.occu_time,
+                       a.occu_loc, a.miss_num, a.ser_inj_num, a.cas_num, a.econ_loss, a.otlcol_guui_vicm,
+                       a.resc_trea_meas, a.conta_pers, a.offi_tel, a.rep_stat, a.note, a.coll_time,
+                       a.upd_time, a.rec_pers, a.sgdw_name, a.acci_grad, a.eng_guid, a.to_date, a.tend_guid,
+                       a.sgdw_name || '事故' as acci_name,
+                       e.eng_name, t.tend_name, bi.if_resp_acci as if_duty, bi.if_pho_rep as if_phone, bi.acci_cause
+                from obj_acci a
+                inner join (
+                    select uext.org_guid from att_org_uwat_ext uext
+                    where uext.org_type = '1'
+                    and uext.org_guid in (
+                        select r.org_uwat_guid from rel_tend_org r
+                        join obj_tend ot on ot.guid = r.tend_guid
+                        where ot.eng_guid in (
+                            -- 当前单位的工程
+                            select e2.eng_guid from att_eng_base e2 where e2.org_guid = #{orgGuid}
+                            union
+                            -- 当前单位经标段关联的工程
+                            select ot2.eng_guid from obj_tend ot2
+                            where ot2.guid in (
+                                select r2.tend_guid from rel_tend_org r2
+                                where r2.org_uwat_guid = #{orgGuid}
+                            )
+                        )
+                    )
+                ) cons on a.acci_wiun_guid = cons.org_guid
+                left join att_eng_base e on a.eng_guid = e.guid
+                left join obj_tend t on a.tend_guid = t.guid
+                left join bis_acci_inve bi on a.guid = bi.acci_guid
+            </when>
+            <!-- 默认:本单位及以下(fillDataScope注入orgGuid) -->
             <when test="orgGuid != null and orgGuid != ''">
                 WITH RECURSIVE subOrgs AS (
                     SELECT guid, org_name FROM att_org_base WHERE guid = #{orgGuid}

+ 9 - 1
gw-slaj/src/main/resources/mapper/slaj/hazard/ObjHachMapper.xml

@@ -39,7 +39,14 @@
             <if test="chemName != null and chemName != ''">AND h.chem_name like '%' || #{chemName} || '%'</if>
             <if test="guid != null and guid != ''">AND h.guid = #{guid}</if>
             <if test="orgName != null and orgName != ''">AND o.org_name like '%' || #{orgName} || '%'</if>
-            <if test="wiunProp != null and wiunProp != ''">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = h.org_guid AND ext.wiun_prop = #{wiunProp})</if>
+            <!-- 单位类型过滤: 6/7为前端Tab约定(7=施工 6=监理/参建),映射到 att_org_uwat_ext.org_type(1=施工 2=监理) -->
+            <if test="wiunProp != null and wiunProp != '' and (wiunProp == '6'.toString() or wiunProp == '7'.toString())">AND EXISTS (
+                SELECT 1 FROM att_org_uwat_ext uext
+                WHERE uext.org_guid = h.org_guid
+                AND uext.org_type = (case when #{wiunProp}::text = '7' then '1' else '2' end)
+            )</if>
+            <!-- 兼容旧数据/其他业务: 非6/7时按原单位性质字段过滤 -->
+            <if test="wiunProp != null and wiunProp != '' and wiunProp != '6'.toString() and wiunProp != '7'.toString()">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = h.org_guid AND ext.wiun_prop = #{wiunProp})</if>
             <if test="beginCollTime != null and beginCollTime != ''">AND h.coll_time >= #{beginCollTime}</if>
             <if test="endCollTime != null and endCollTime != ''">AND h.coll_time &lt;= #{endCollTime}</if>
         </where>
@@ -84,3 +91,4 @@
         </foreach>
     </delete>
 </mapper>
+

+ 3 - 2
gw-slaj/src/main/resources/mapper/slaj/hazard/TBusiHazCountMapper.xml

@@ -41,7 +41,7 @@
             <if test="orgGuid != null and orgGuid != ''">AND c.org_guid = #{orgGuid}</if>
             <if test="guid != null and guid != ''">AND c.guid = #{guid}</if>
             <if test="orgName != null and orgName != ''">AND o.org_name like '%' || #{orgName} || '%'</if>
-            <if test="wiunProp != null and wiunProp != ''">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = c.org_guid AND ext.wiun_prop = #{wiunProp})</if>
+            <if test="wiunProp != null and wiunProp != '' and (wiunProp == '6'.toString() or wiunProp == '7'.toString())">AND EXISTS (SELECT 1 FROM att_org_uwat_ext uext WHERE uext.org_guid = c.org_guid AND uext.org_type = (case when #{wiunProp}::text = '7' then '1' else '2' end))</if><if test="wiunProp != null and wiunProp != '' and wiunProp != '6'.toString() and wiunProp != '7'.toString()">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = c.org_guid AND ext.wiun_prop = #{wiunProp})</if>
             <if test="beginCreateTime != null and beginCreateTime != ''">AND c.create_time >= #{beginCreateTime}</if>
             <if test="endCreateTime != null and endCreateTime != ''">AND c.create_time &lt;= #{endCreateTime}</if>
         </where>
@@ -110,9 +110,10 @@
         LEFT JOIN t_busi_haz_count c ON c.org_guid = s.guid
         <where>
             <if test="orgName != null and orgName != ''">AND s.org_name like '%' || #{orgName} || '%'</if>
-            <if test="wiunProp != null and wiunProp != ''">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = c.org_guid AND ext.wiun_prop = #{wiunProp})</if>
+            <if test="wiunProp != null and wiunProp != '' and (wiunProp == '6'.toString() or wiunProp == '7'.toString())">AND EXISTS (SELECT 1 FROM att_org_uwat_ext uext WHERE uext.org_guid = c.org_guid AND uext.org_type = (case when #{wiunProp}::text = '7' then '1' else '2' end))</if><if test="wiunProp != null and wiunProp != '' and wiunProp != '6'.toString() and wiunProp != '7'.toString()">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = c.org_guid AND ext.wiun_prop = #{wiunProp})</if>
             <if test="createTime != null and createTime != ''">AND c.create_time &gt;= CAST(#{createTime} AS date) AND c.create_time &lt; CAST(#{createTime} AS date) + INTERVAL '1 day'</if>
         </where>
         ORDER BY c.create_time DESC
     </select>
 </mapper>
+

+ 9 - 1
gw-slaj/src/main/resources/mapper/slaj/hidd/AttOrgBaseMapper.xml

@@ -38,7 +38,14 @@
             <if test="orgCode != null and orgCode != ''">AND b.org_code = #{orgCode}</if>
             <if test="orgType != null and orgType != ''">AND b.org_type = #{orgType}</if>
             <if test="pguid != null and pguid != ''">AND b.pguid = #{pguid}</if>
-            <if test="wiunProp != null and wiunProp != ''">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = b.guid AND ext.wiun_prop = #{wiunProp})</if>
+            <!-- 单位类型过滤: 6/7为前端Tab约定(7=施工 6=监理/参建),映射到 att_org_uwat_ext.org_type(1=施工 2=监理) -->
+            <if test="wiunProp != null and wiunProp != '' and (wiunProp == '6'.toString() or wiunProp == '7'.toString())">AND EXISTS (
+                SELECT 1 FROM att_org_uwat_ext uext
+                WHERE uext.org_guid = b.guid
+                AND uext.org_type = (case when #{wiunProp}::text = '7' then '1' else '2' end)
+            )</if>
+            <!-- 兼容旧数据/其他业务: 非6/7时按原单位性质字段过滤 -->
+            <if test="wiunProp != null and wiunProp != '' and wiunProp != '6'.toString() and wiunProp != '7'.toString()">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = b.guid AND ext.wiun_prop = #{wiunProp})</if>
         </where>
     </select>
     <insert id="insertAttOrgBase" parameterType="com.goldenwater.slaj.hidd.domain.AttOrgBase">
@@ -77,3 +84,4 @@
         </foreach>
     </delete>
 </mapper>
+

+ 32 - 21
gw-slaj/src/main/resources/mapper/slaj/hidd/ObjHiddMapper.xml

@@ -80,28 +80,29 @@
             <if test="hiddStat != null and hiddStat != ''">AND h.hidd_stat = #{hiddStat}::text</if>
             <if test="orgGuid != null and orgGuid != ''">
                 <choose>
-                    <!-- consEng(7)/partEng(6): 两角度归并 - 自己的 + 关联施工单位/参建单位的 -->
+                    <!-- consEng(7=施工单位)/partEng(6=监理单位): 自己的 + 关联施工单位/监理单位的
+                         规范: ATT_ORG_UWAT_EXT.ORG_TYPE 1=施工单位 2=监理单位
+                         关联链: h.org_guid = dept_id = att_org_uwat_base.guid = att_org_uwat_ext.org_guid
+                                 rel_tend_org.org_uwat_guid = att_org_uwat_base.guid -->
                     <when test="wiunProp == '6'.toString() or wiunProp == '7'.toString()">
                         AND (
                             h.org_guid = #{orgGuid}::text
                             OR h.org_guid IN (
-                                -- 关联单位: rel_tend_org(标段关联) → att_org_uwat_base → org_code → att_org_base
-                                select b.guid from att_org_base b
-                                where b.org_code in (
-                                    select u.org_code from att_org_uwat_base u
-                                    where u.guid in (
-                                        select r.org_uwat_guid from rel_tend_org r
-                                        join obj_tend t on t.guid = r.tend_guid
-                                        where t.eng_guid in (
-                                            -- 当前用户(法人)的工程: att_eng_base.org_guid
-                                            select e.eng_guid from att_eng_base e where e.org_guid = #{orgGuid}::text
-                                            union
-                                            -- 当前用户(监理/施工)经标段关联的工程
-                                            select t2.eng_guid from obj_tend t2
-                                            where t2.guid in (
-                                                select r2.tend_guid from rel_tend_org r2
-                                                where r2.org_uwat_guid = #{orgGuid}::text
-                                            )
+                                -- 关联单位: 同一工程下经 rel_tend_org 关联、且 org_type 匹配(施工/监理)的参建单位
+                                select uext.org_guid from att_org_uwat_ext uext
+                                where uext.org_type = (case when #{wiunProp}::text = '7' then '1' else '2' end)
+                                and uext.org_guid in (
+                                    select r.org_uwat_guid from rel_tend_org r
+                                    join obj_tend t on t.guid = r.tend_guid
+                                    where t.eng_guid in (
+                                        -- 当前用户(法人)的工程: att_eng_base.org_guid
+                                        select e.eng_guid from att_eng_base e where e.org_guid = #{orgGuid}::text
+                                        union
+                                        -- 当前用户(监理/施工)经标段关联的工程
+                                        select t2.eng_guid from obj_tend t2
+                                        where t2.guid in (
+                                            select r2.tend_guid from rel_tend_org r2
+                                            where r2.org_uwat_guid = #{orgGuid}::text
                                         )
                                     )
                                 )
@@ -125,7 +126,14 @@
                 </choose>
             </if>
             <if test="collTime != null and collTime != ''">AND h.coll_time >= CAST(#{collTime}::text AS timestamp) AND h.coll_time &lt; CAST(#{collTime}::text AS timestamp) + INTERVAL '1 day'</if>
-            <if test="wiunProp != null and wiunProp != ''">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = h.org_guid AND ext.wiun_prop = #{wiunProp}::text)</if>
+            <!-- 单位类型过滤: 6/7 为前端Tab约定(6=监理/参建 7=施工),映射到 att_org_uwat_ext.org_type(1=施工 2=监理) -->
+            <if test="wiunProp != null and wiunProp != '' and (wiunProp == '6'.toString() or wiunProp == '7'.toString())">AND EXISTS (
+                SELECT 1 FROM att_org_uwat_ext uext
+                WHERE uext.org_guid = h.org_guid
+                AND uext.org_type = (case when #{wiunProp}::text = '7' then '1' else '2' end)
+            )</if>
+            <!-- 兼容旧数据/其他业务: 非6/7时按原单位性质字段过滤 -->
+            <if test="wiunProp != null and wiunProp != '' and wiunProp != '6'.toString() and wiunProp != '7'.toString()">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = h.org_guid AND ext.wiun_prop = #{wiunProp}::text)</if>
         </where>
     </select>
     <!-- 钻取明细查询:CTE范围 + 工程名称/单位名称精确过滤 -->
@@ -210,7 +218,8 @@
             <if test="hiddStat != null and hiddStat != ''">AND hidd_stat = #{hiddStat}</if>
             <if test="orgGuid != null and orgGuid != ''">AND org_guid = #{orgGuid}</if>
             <if test="engGuid != null and engGuid != ''">AND eng_guid = #{engGuid}</if>
-            <if test="wiunProp != null and wiunProp != ''">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = org_guid AND ext.wiun_prop = #{wiunProp})</if>
+            <if test="wiunProp != null and wiunProp != '' and (wiunProp == '6'.toString() or wiunProp == '7'.toString())">AND EXISTS (SELECT 1 FROM att_org_uwat_ext uext WHERE uext.org_guid = org_guid AND uext.org_type = (case when #{wiunProp}::text = '7' then '1' else '2' end))</if>
+            <if test="wiunProp != null and wiunProp != '' and wiunProp != '6'.toString() and wiunProp != '7'.toString()">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = org_guid AND ext.wiun_prop = #{wiunProp})</if>
         </where>
         order by coll_time desc
     </select>
@@ -222,7 +231,8 @@
             <if test="hiddName != null and hiddName != ''">AND hidd_name like '%' || #{hiddName} || '%'</if>
             <if test="hiddGrad != null and hiddGrad != ''">AND hidd_grad = #{hiddGrad}</if>
             <if test="hiddStat != null and hiddStat != ''">AND hidd_stat = #{hiddStat}</if>
-            <if test="wiunProp != null and wiunProp != ''">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = h.org_guid AND ext.wiun_prop = #{wiunProp})</if>
+            <if test="wiunProp != null and wiunProp != '' and (wiunProp == '6'.toString() or wiunProp == '7'.toString())">AND EXISTS (SELECT 1 FROM att_org_uwat_ext uext WHERE uext.org_guid = h.org_guid AND uext.org_type = (case when #{wiunProp}::text = '7' then '1' else '2' end))</if>
+            <if test="wiunProp != null and wiunProp != '' and wiunProp != '6'.toString() and wiunProp != '7'.toString()">AND EXISTS (SELECT 1 FROM att_org_ext ext WHERE ext.org_guid = h.org_guid AND ext.wiun_prop = #{wiunProp})</if>
         </where>
         order by coll_time desc
     </select>
@@ -291,3 +301,4 @@
         ORDER BY "totalCount" DESC
     </select>
 </mapper>
+

+ 2 - 0
gw-ui/src/api/slaj/acci.js

@@ -44,6 +44,7 @@ export function listBisAcciMont(query) { return request({ url: '/acci/bisaccimon
 export function getBisAcciMont(guid) { return request({ url: '/acci/bisaccimont/' + guid, method: 'get' }) }
 export function addBisAcciMont(data) { return request({ url: '/acci/bisaccimont', method: 'post', data: data }) }
 export function updateBisAcciMont(data) { return request({ url: '/acci/bisaccimont', method: 'put', data: data }) }
+export function submitBisAcciMont(data) { return request({ url: '/acci/bisaccimont/submit', method: 'post', data: data }) }
 export function delBisAcciMont(guids) { return request({ url: '/acci/bisaccimont/' + guids, method: 'delete' }) }
 export function checkBisAcciMont(data) { return request({ url: '/acci/bisaccimont/check', method: 'put', data: data }) }
 export function returnBisAcciMont(data) { return request({ url: '/acci/bisaccimont/return', method: 'put', data: data }) }
@@ -149,3 +150,4 @@ export function getAcciRevokReason(guid) { return request({ url: '/acci/bisaccim
 
 // 事故统计报表
 export function listAcciStat(query) { return request({ url: '/acci/objacci/statList', method: 'get', params: query }) }
+

+ 8 - 5
gw-ui/src/views/slaj/acci/manage.vue

@@ -634,7 +634,7 @@ const dateRange5 = ref([])
 const queryParams5 = reactive({ pageNum: 1, pageSize: 10, orgName: undefined, acciGrad: undefined })
 
 function getList1() {
-  const p = { ...queryParams1 }
+  const p = { ...queryParams1, repStat: '0' }
   if (dateRange1.value && dateRange1.value.length === 2) { p.beginTime = dateRange1.value[0]; p.endTime = dateRange1.value[1] }
   listObjAcci(p).then(res => { list1.value = res.rows || []; total1.value = res.total || 0 })
 }
@@ -761,7 +761,7 @@ function submitSuppForm() {
   })
 }
 function getList2() {
-  const p = { ...queryParams2 }
+  const p = { ...queryParams2, repStat: '2' }
   if (dateRange2.value && dateRange2.value.length === 2) { p.beginTime = dateRange2.value[0]; p.endTime = dateRange2.value[1] }
   listObjAcci(p).then(res => { list2.value = res.rows || []; total2.value = res.total || 0 })
 }
@@ -805,20 +805,20 @@ function filterDuty() {
   getList2()
 }
 function getList3() {
-  const p = { ...queryParams3 }
+  const p = { ...queryParams3, repStat: '0', scopeType: 'sub' }
   if (dateRange3.value && dateRange3.value.length === 2) { p.beginTime = dateRange3.value[0]; p.endTime = dateRange3.value[1] }
   listObjAcci(p).then(res => { list3.value = res.rows || []; total3.value = res.total || 0 })
 }
 function handleQuery3() { queryParams3.pageNum = 1; getList3() }
 function getList4() {
-  const p = { ...queryParams4 }
+  const p = { ...queryParams4, repStat: '2', scopeType: 'sub' }
   if (dateRange4.value && dateRange4.value.length === 2) { p.beginTime = dateRange4.value[0]; p.endTime = dateRange4.value[1] }
   listObjAcci(p).then(res => { list4.value = res.rows || []; total4.value = res.total || 0 })
 }
 function handleQuery4() { queryParams4.pageNum = 1; getList4() }
 
 function getList5() {
-  const p = { ...queryParams5 }
+  const p = { ...queryParams5, repStat: '2', scopeType: 'cons' }
   if (dateRange5.value && dateRange5.value.length === 2) { p.beginTime = dateRange5.value[0]; p.endTime = dateRange5.value[1] }
   listObjAcci(p).then(res => { list5.value = res.rows || []; total5.value = res.total || 0 })
 }
@@ -926,3 +926,6 @@ function handleTabChange() {
 }
 </style>
 
+
+
+

+ 92 - 32
gw-ui/src/views/slaj/acci/month.vue

@@ -131,39 +131,48 @@
         </div>
         <div style="flex:1; min-width:0;">
           <div style="font-weight:bold; font-size:14px; padding-bottom:8px; border-bottom:1px solid #e4e7ed; margin-bottom:12px;">基本档案</div>
-          <el-table :data="detailList" border size="small" height="400" style="width:100%">
+          <el-table :data="detailList" border size="small" height="400" style="width:100%" @selection-change="(rows) => { detailSelectedIds.value = rows.map(r => r.guid) }">
+            <el-table-column type="selection" width="50" align="center" />
             <el-table-column label="序号" align="center" type="index" width="50" />
-            <el-table-column label="发生事故单位" align="center" min-width="140" :show-overflow-tooltip="true">
+            <el-table-column label="事故类别" align="center" prop="acciCate" width="100" />
+            <el-table-column label="发生时间" align="center" prop="occuTime" width="160" />
+            <el-table-column label="死亡人数(人)" align="center" prop="casNum" width="100" />
+            <el-table-column label="重伤人数(人)" align="center" prop="serInjNum" width="100" />
+            <el-table-column label="直接经济损失(万元)" align="center" prop="econLoss" width="140" />
+            <el-table-column label="上报状态" align="center" width="100">
               <template #default="scope">
-                {{ scope.row.acciWiunName || '--' }}&nbsp;
-                <el-tag size="small">{{ scope.row.acciWiunType === '1' ? '直属' : scope.row.acciWiunType === '2' ? '下级' : scope.row.acciWiunType === '3' ? '流域' : '' }}</el-tag>
+                <el-tag size="small" :type="scope.row.montStat === '1' || scope.row.repAct === '1' ? 'success' : 'warning'">
+                  {{ scope.row.montStat === '1' || scope.row.repAct === '1' ? '已上报' : '未上报' }}
+                </el-tag>
               </template>
             </el-table-column>
-            <el-table-column label="死亡人数(人)" align="center" prop="casNum" width="100" />
-            <el-table-column label="重伤人数(人)" align="center" prop="serInjNum" width="100" />
-            <el-table-column label="直接经济损失(万元)" align="center" prop="econLoss" width="140" />
-            <el-table-column label="事故类别" align="center" prop="acciCate" width="90" />
           </el-table>
           <div class="pagination">
             <el-pagination v-show="detailTotal > 0" v-model:current-page="detailQuery.pageNum" v-model:page-size="detailQuery.pageSize" :total="detailTotal" layout="total, prev, pager, next" @size-change="loadDetailList" @current-change="loadDetailList" />
           </div>
-          <div style="margin-top:12px; padding-top:8px; border-top:1px solid #e4e7ed;">
-            <span style="font-weight:bold;">相关资料:</span>
-            <span v-if="detailList.length === 0" style="color:#999;">暂无</span>
-          </div>
-        </div>
-      </div>
-      <template #footer>
-        <el-button @click="detailOpen = false">关 闭</el-button>
-      </template>
+           <div style="margin-top:12px; padding-top:8px; border-top:1px solid #e4e7ed;">
+             <span style="font-weight:bold;">附件上传:</span>
+             <span v-if="uploadFileList.length === 0" style="color:#999;">暂无</span>
+             <el-upload :action="uploadUrl" :headers="uploadHeaders" :file-list="uploadFileList" :on-success="handleUploadSuccess" :on-remove="handleUploadRemove" :limit="5" :on-exceed="() => proxy.$modal.msgWarning('最多上传5个文件')" multiple accept=".pdf,.doc,.docx,.xls,.xlsx,.jpg,.png" style="display:inline-block; margin-left:8px;">
+               <el-button size="small" type="primary">添加文件</el-button>
+               <template #tip><div style="color:#999;font-size:12px;">支持 pdf/doc/xls/jpg 格式,最多5个</div></template>
+             </el-upload>
+           </div>
+         </div>
+       </div>
+       <template #footer>
+         <el-button type="primary" @click="handleDetailSubmit" :disabled="detailSelectedIds.value.length === 0">上报</el-button>
+         <el-button @click="detailOpen = false">关闭</el-button>
+       </template>
     </el-dialog>
   </div>
 </template>
 
 <script setup name="AcciMonth">
 import { Refresh, Document } from '@element-plus/icons-vue'
-import { listBisAcciMont, getAcciTreeData, getAcciMontSummary, revokeBisAcciMont, returnBisAcciMont, updateBisAcciMont, batchUnlockAcciMont, urgeAcciMont } from "@/api/slaj/acci"
-import { listObjAcci } from "@/api/slaj/acci"
+import { listBisAcciMont, getAcciTreeData, getAcciMontSummary, revokeBisAcciMont, returnBisAcciMont, updateBisAcciMont, batchUnlockAcciMont, urgeAcciMont, submitBisAcciMont } from "@/api/slaj/acci"
+import { addAttMedBase, listAttMedBase, delAttMedBase } from "@/api/slaj/hidd"
+import { getToken } from "@/utils/auth"
 
 const { proxy } = getCurrentInstance()
 
@@ -208,6 +217,7 @@ const detailTree = ref([])
 const detailTreeProps = { children: 'children', label: 'orgName' }
 const detailList = ref([]); const detailTotal = ref(0)
 const detailQuery = reactive({ pageNum: 1, pageSize: 10 })
+const detailSelectedIds = ref([]); const detailCurOrgGuid = ref(''); const uploadFileList = ref([]); const uploadUrl = `${import.meta.env.VITE_APP_BASE_URL}system/file/upload`; const uploadHeaders = { Authorization: 'Bearer ' + getToken() }
 
 const monthOptions = ref([])
 function buildMonthOptions() {
@@ -228,6 +238,8 @@ function handleMonthChange(val) {
   selectedMonth.value = val
   loadStats()
   loadPromptStats()
+  // 联动左侧树:高亮所选月份节点
+  treeRef.value?.setCurrentKey(val)
 }
 
 function loadTree() {
@@ -294,26 +306,67 @@ function loadStats() {
 }
 
 function handleReport() {
-  if (!selectedMonth.value) { proxy.$modal.msgWarning('请先在左侧选择月份'); return }
-  proxy.$router.push({ path: '/slaj/acci/monthDetail', query: { month: selectedMonth.value, year: selectedYear.value } })
+  if (!selectedMonth.value) { proxy.$modal.msgWarning('请先选择月份'); return }
+  // 打开上报弹窗:左侧单位树 + 右侧月报记录列表 + 附件上传 + 上报按钮
+  detailOpen.value = true
+  detailTree.value = [{ guid: 'root', orgName: '全部单位', children: treeData.value }]
+  detailList.value = []
+  detailTotal.value = 0
+  uploadFileList.value = []
+  detailCurOrgGuid.value = ''
+  loadDetailList()
 }
 
 function handleOrgDetail(row) {
   detailOpen.value = true
-  detailTree.value = [{ guid: row.orgGuid || '0', orgName: row.orgName || '本单位', children: [] }]
+  detailTree.value = [{ guid: 'root', orgName: '全部单位', children: treeData.value }]
+  detailList.value = []
+  detailTotal.value = 0
+  uploadFileList.value = []
+  detailCurOrgGuid.value = row.orgGuid || ''
   loadDetailList()
 }
+
+function handleDetailSubmit() {
+  if (detailSelectedIds.value.length === 0) { proxy.$modal.msgWarning('请先勾选需要上报的记录'); return }
+  const unreported = detailList.value.filter(r => detailSelectedIds.value.includes(r.guid) && r.repAct !== '1')
+  if (unreported.length === 0) { proxy.$modal.msgWarning('勾选的记录已全部上报'); return }
+  proxy.$modal.confirm('确认上报选中的' + unreported.length + '条事故月报记录?').then(() => {
+    const reqs = unreported.map(r => submitBisAcciMont({ guid: r.guid }))
+    Promise.all(reqs).then(() => {
+      proxy.$modal.msgSuccess('上报成功')
+      detailOpen.value = false
+      loadStats(); loadPromptStats()
+    }).catch(() => { proxy.$modal.msgError('上报失败,请重试') })
+  }).catch(() => {})
+}
+
+function handleUploadSuccess(response, file) {
+  if (response.code === 200) {
+    addAttMedBase({ medName: file.name, medPath: response.fileName, bizType: 'acci_month' }).then(() => {
+      proxy.$modal.msgSuccess('附件上传成功')
+    })
+  }
+}
+
+function handleUploadRemove(file) {
+  if (file.guid) {
+    delAttMedBase(file.guid)
+  }
+}
 function loadDetailList() {
-  listObjAcci({ mont: selectedMonth.value, pageNum: detailQuery.pageNum, pageSize: detailQuery.pageSize }).then(res => {
+  // 加载本月已生成、未上报的月报记录(bis_acci_mont)
+  const params = { mont: selectedMonth.value, pageNum: detailQuery.pageNum, pageSize: detailQuery.pageSize }
+  if (detailCurOrgGuid.value) { params.orgGuid = detailCurOrgGuid.value }
+  listBisAcciMont(params).then(res => {
     detailList.value = res.rows || []; detailTotal.value = res.total || 0
-  })
+  }).catch(() => {})
 }
 function handleDetailTreeClick(data) {
-  listObjAcci({ orgGuid: data.guid, mont: selectedMonth.value, pageNum: detailQuery.pageNum, pageSize: detailQuery.pageSize }).then(res => {
-    detailList.value = res.rows || []; detailTotal.value = res.total || 0
-  })
+  if (!data.guid || data.guid === "root") { detailCurOrgGuid.value = ""; loadDetailList(); return }
+  detailCurOrgGuid.value = data.guid
+  loadDetailList()
 }
-
 function handleRevocApply(row) {
   revocForm.value = { guid: row.guid, revocDesc: '' }
   revocOpen.value = true
@@ -322,7 +375,7 @@ function handleRevocApply(row) {
 function submitRevoc() {
   proxy.$refs.revocRef.validate(valid => {
     if (valid) {
-      revokeBisAcciMont({ guid: revocForm.value.guid, revocationAudit: '0', revocationAuditResult: revocForm.value.revocDesc, repAct: '4' }).then(() => {
+      revokeBisAcciMont({ guid: revocForm.value.guid, revocationAudit: '0', revocationAuditResult: revocForm.value.revocDesc }).then(() => {
         proxy.$modal.msgSuccess('撤回申请已提交')
         revocOpen.value = false
         loadStats(); loadPromptStats()
@@ -369,7 +422,7 @@ function handleBatchUnlock() {
 }
 
 function handlePendingApproval() {
-  listBisAcciMont({ montStat: '4', pageSize: 999 }).then(res => {
+  listBisAcciMont({ monthlyAudit: '1', pageSize: 999 }).then(res => {
     pendingList.value = res.rows || []
     pendingCount.value = pendingList.value.length
     pendingOpen.value = true
@@ -377,7 +430,7 @@ function handlePendingApproval() {
 }
 function handleApprove(row) {
   proxy.$modal.confirm('同意该申请后,该单位可进行上报、撤销操作。确认同意?').then(() => {
-    updateBisAcciMont({ guid: row.guid, repAct: '0', revocationAudit: '1', revocationAuditResult: '同意' }).then(() => {
+    updateBisAcciMont({ guid: row.guid, monthlyAuditResult: '1', repAct: '1' }).then(() => {
       proxy.$modal.msgSuccess('已同意')
       pendingList.value = pendingList.value.filter(r => r.guid !== row.guid)
       pendingCount.value = pendingList.value.length
@@ -387,7 +440,7 @@ function handleApprove(row) {
 }
 function handleReject(row) {
   proxy.$modal.confirm('驳回后该单位不能进行上报、撤销操作。确认驳回?').then(() => {
-    updateBisAcciMont({ guid: row.guid, repAct: '3', revocationAudit: '2', revocationAuditResult: '驳回' }).then(() => {
+    updateBisAcciMont({ guid: row.guid, monthlyAuditResult: '0', returninfo: '驳回' }).then(() => {
       proxy.$modal.msgSuccess('已驳回')
       pendingList.value = pendingList.value.filter(r => r.guid !== row.guid)
       pendingCount.value = pendingList.value.length
@@ -523,3 +576,10 @@ onMounted(() => { loadTree(); buildMonthOptions() })
 }
 </style>
 
+
+
+
+
+
+
+

+ 5 - 2
gw-ui/src/views/slaj/hazard/manage.vue

@@ -695,8 +695,11 @@ function submitRecForm() {
   })
 }
 function handleSubmit(row) {
-  proxy.$confirm('确认将该危险源报送至水行政主管部门?', '提示', { type: 'warning' }).then(() => {
-    updateObjHaz({ guid: row.guid, hazStat: '1' }).then(() => {
+  proxy.$confirm('确认将该危险源报送到水行政主管部门?', '提示', { type: 'warning' }).then(() => {
+    const now = new Date()
+    const pad = n => String(n).padStart(2, '0')
+    const regTime = `${now.getFullYear()}-${pad(now.getMonth()+1)}-${pad(now.getDate())} ${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`
+    updateObjHaz({ guid: row.guid, hazStat: '1', regTime: regTime, regOrgGuid: userStore.orgGuid }).then(() => {
       row.hazStat = '1'
       proxy.$modal.msgSuccess('报送成功')
       if (activeTab.value === 'tend') getList2()

+ 151 - 10
gw-ui/src/views/slaj/hidd/month.vue

@@ -191,11 +191,43 @@
       </el-dialog>
 
       <el-dialog :title="detailTitle" v-model="detailOpen" width="85%" top="5vh" append-to-body destroy-on-close>
-        <div v-loading="detailLoading" style="min-height:400px;">
-          <iframe v-if="detailOpen && detailUrl" :src="detailUrl" style="width:100%;height:70vh;border:0;" />
+        <div style="display:flex; gap:10px;">
+          <div style="width:200px; min-width:200px; border:1px solid #e4e7ed; border-radius:4px; padding:8px; max-height:500px; overflow:auto;">
+            <el-tree :data="detailTree" :props="detailTreeProps" node-key="guid" highlight-current @node-click="handleDetailTreeClick" default-expand-all />
+          </div>
+          <div style="flex:1; min-width:0;">
+            <div style="font-weight:bold; font-size:14px; padding-bottom:8px; border-bottom:1px solid #e4e7ed; margin-bottom:12px;">隐患明细</div>
+            <el-table :data="detailList" border size="small" height="400" style="width:100%" @selection-change="(rows) => { detailSelectedIds.value = rows.map(r => r.guid) }">
+              <el-table-column type="selection" width="50" align="center" />
+              <el-table-column label="序号" align="center" type="index" width="60" />
+              <el-table-column label="所属单位" align="center" prop="orgName" min-width="140" :show-overflow-tooltip="true" />
+              <el-table-column label="隐患名称" align="center" prop="hiddName" min-width="160" :show-overflow-tooltip="true" />
+              <el-table-column label="隐患类别" align="center" prop="hiddClas" width="100" />
+              <el-table-column label="所属工程" align="center" prop="engName" min-width="140" :show-overflow-tooltip="true" />
+              <el-table-column label="整改状态" align="center" width="100">
+                <template #default="scope">
+                  <el-tag size="small" :type="scope.row.hiddStat === '2' || scope.row.hiddStat === '3' ? 'success' : 'warning'">
+                    {{ scope.row.hiddStat === '0' ? '未整改' : scope.row.hiddStat === '1' ? '整改中' : scope.row.hiddStat === '2' ? '已整改' : '已销号' }}
+                  </el-tag>
+                </template>
+              </el-table-column>
+            </el-table>
+            <div class="pagination">
+              <el-pagination v-show="detailTotal > 0" v-model:current-page="detailQuery.pageNum" v-model:page-size="detailQuery.pageSize" :total="detailTotal" layout="total, prev, pager, next" @size-change="loadHiddDetailList" @current-change="loadHiddDetailList" />
+            </div>
+            <div style="margin-top:12px; padding-top:8px; border-top:1px solid #e4e7ed;">
+              <span style="font-weight:bold;">附件上传:</span>
+              <span v-if="uploadFileList.length === 0" style="color:#999;">暂无</span>
+              <el-upload :action="uploadUrl" :headers="uploadHeaders" :file-list="uploadFileList" :on-success="handleUploadSuccess" :on-remove="handleUploadRemove" :limit="5" :on-exceed="() => proxy.$modal.msgWarning('最多上传5个文件')" multiple accept=".pdf,.doc,.docx,.xls,.xlsx,.jpg,.png" style="display:inline-block; margin-left:8px;">
+                <el-button size="small" type="primary">添加文件</el-button>
+                <template #tip><div style="color:#999;font-size:12px;">支持 pdf/doc/xls/jpg 格式,最多5个</div></template>
+              </el-upload>
+            </div>
+          </div>
         </div>
         <template #footer>
-          <el-button @click="detailOpen = false">关 闭</el-button>
+          <el-button type="primary" @click="handleDetailSubmit" :disabled="detailSelectedIds.value.length === 0">上报</el-button>
+          <el-button @click="detailOpen = false">关闭</el-button>
         </template>
       </el-dialog>
     </el-card>
@@ -204,7 +236,11 @@
 
 <script setup name="MonthReport">
 import { Document, Refresh } from '@element-plus/icons-vue'
-import { getRepTreeData, getMonthListStats, revokeMonth, returnMonth, approveRevoke, batchUnlock, urgeReport, revokeApproveList, checkCanRevoke, addBisOrgMonRepPeri } from "@/api/slaj/hidd"
+import { getRepTreeData, getMonthListStats, revokeMonth, returnMonth, approveRevoke, batchUnlock, urgeReport, revokeApproveList, checkCanRevoke, addBisOrgMonRepPeri, submitMonth, listObjHidd, addAttMedBase, listAttMedBase, delAttMedBase } from "@/api/slaj/hidd"
+import { getToken } from "@/utils/auth"
+import useUserStore from '@/store/modules/user'
+
+const userStore = useUserStore()
 
 const { proxy } = getCurrentInstance()
 
@@ -254,9 +290,20 @@ const periodForm = ref({ year: new Date().getFullYear(), month: new Date().getMo
 const availableYears = [new Date().getFullYear() - 2, new Date().getFullYear() - 1, new Date().getFullYear()]
 
 const detailOpen = ref(false)
-const detailTitle = ref('隐患月报详情')
-const detailLoading = ref(false)
-const detailUrl = ref('')
+const detailTitle = ref('')
+const detailTree = ref([])
+const detailTreeProps = { children: 'children', label: 'orgName' }
+const detailList = ref([])
+const detailTotal = ref(0)
+const detailQuery = reactive({ pageNum: 1, pageSize: 10 })
+const detailSelectedIds = ref([])
+const detailRepGuid = ref('')
+const detailCurOrgGuid = ref('')
+const uploadFileList = ref([])
+const uploadUrl = `${import.meta.env.VITE_APP_BASE_URL}system/file/upload`; const uploadHeaders = { Authorization: 'Bearer ' + getToken() }
+
+
+
 
 const monthOptions = ref([])
 function buildMonthOptions() {
@@ -278,6 +325,8 @@ function handleMonthChange(val) {
   loadStats()
   loadPromptStats()
   loadPendingCount()
+  // 联动左侧树:高亮所选月份节点
+  treeRef.value?.setCurrentKey(val)
 }
 
 function loadPendingCount() {
@@ -357,16 +406,100 @@ function loadStats() {
 }
 
 function handleReport() {
-  if (!selectedMonth.value) { proxy.$modal.msgWarning('请先在左侧选择月份'); return }
-  proxy.$router.push({ path: '/slaj/hidd/monthDetail', query: { month: selectedMonth.value, year: selectedYear.value } })
+  if (!selectedMonth.value) { proxy.$modal.msgWarning('请先选择月份'); return }
+  // 打开上报弹窗:左树 + 隐患列表 + 附件 + 上报
+  detailTitle.value = '隐患月报上报'
+  detailOpen.value = true
+  detailSelectedIds.value = []
+  uploadFileList.value = []
+  detailList.value = []
+  detailTotal.value = 0
+  // 加载单位树
+  getRepTreeData().then(res => {
+    detailTree.value = [{ guid: 'root', orgName: '全部单位', children: res.data || [] }]
+  })
+  // 初始化月报期间(存在则复用,不存在则创建)
+  const parts = selectedMonth.value.split('-')
+  const startDate = selectedYear.value + '-' + parts[1] + '-07'
+  let endYear = parseInt(parts[0]); let endMonth = parseInt(parts[1])
+  if (endMonth === 12) { endYear = endYear + 1; endMonth = 1 } else { endMonth = endMonth + 1 }
+  const endDate = endYear + '-' + String(endMonth).padStart(2, '0') + '-06'
+  getMonthListStats({ repTime: selectedMonth.value, unitType: '0' }).then(res => {
+    const data = res.data || res.rows || []
+    const existing = data.find(d => d.repTime === selectedMonth.value)
+    if (existing) {
+      if (existing.repAct === '1') { proxy.$modal.msgWarning('该月报已上报,不能重复上报') }
+      detailRepGuid.value = existing.guid
+    } else {
+      addBisOrgMonRepPeri({
+        repName: selectedMonth.value + '隐患月报期间',
+        repAct: '2', repType: '0',
+        repTime: selectedMonth.value,
+        startDate: startDate, endDate: endDate,
+        lockStatus: '1'
+      }).then(addRes => {
+        detailRepGuid.value = addRes.data && addRes.data.guid ? addRes.data.guid : ''
+      }).catch(() => {})
+    }
+  }).catch(() => {})
+  loadHiddDetailList()
+}
+
+function loadHiddDetailList() {
+  // 加载隐患列表(orgGuid 为空时取本单位)
+  const orgGuid = detailCurOrgGuid.value || userStore.orgGuid || undefined
+  listObjHidd({ orgGuid: orgGuid, pageNum: 1, pageSize: 1000 }).then(res => {
+    const allData = res.rows || res.data || []
+    detailTotal.value = allData.length
+    const start = (detailQuery.pageNum - 1) * detailQuery.pageSize
+    const end = start + detailQuery.pageSize
+    detailList.value = allData.slice(start, end)
+  }).catch(() => {})
+}
+
+function handleDetailTreeClick(data) {
+  if (!data.guid || data.guid === 'root') { detailCurOrgGuid.value = ''; loadHiddDetailList(); return }
+  detailCurOrgGuid.value = data.guid
+  loadHiddDetailList()
+}
+
+function handleDetailSubmit() {
+  if (detailSelectedIds.value.length === 0) { proxy.$modal.msgWarning('请先勾选需要上报的隐患'); return }
+  if (!detailRepGuid.value) { proxy.$modal.msgWarning('月报期间尚未创建,请重试'); return }
+  proxy.$modal.confirm('确认上报选中的' + detailSelectedIds.value.length + '条隐患记录?').then(() => {
+    submitMonth(detailRepGuid.value, detailSelectedIds.value).then(() => {
+      proxy.$modal.msgSuccess('上报成功')
+      detailOpen.value = false
+      loadStats(); loadPromptStats()
+    }).catch(() => { proxy.$modal.msgError('上报失败,请重试') })
+  }).catch(() => {})
+}
+
+function handleUploadSuccess(response, file) {
+  if (response.code === 200) {
+    addAttMedBase({ medName: file.name, medPath: response.fileName, bizType: 'hidd_month' }).then(() => {
+      proxy.$modal.msgSuccess('附件上传成功')
+    })
+  }
+}
+
+function handleUploadRemove(file) {
+  if (file.guid) { delAttMedBase(file.guid) }
 }
 
 function handleOrgDetail(row) {
   const orgGuid = row.repOrgGuid || row.orgGuid
   const orgName = row.repName || ''
   detailTitle.value = '隐患月报详情'
-  detailUrl.value = `${import.meta.env.BASE_URL}slaj/hidd/monthDetail?guid=${row.guid}&month=${selectedMonth.value}&orgName=${encodeURIComponent(orgName)}`
   detailOpen.value = true
+  detailSelectedIds.value = []
+  uploadFileList.value = []
+  detailRepGuid.value = row.guid
+  detailCurOrgGuid.value = orgGuid
+  getRepTreeData().then(res => {
+    detailTree.value = [{ guid: 'root', orgName: '全部单位', children: res.data || [] }]
+  })
+  loadHiddDetailList()
 }
 
 function handleRevocApply(row) {
@@ -717,3 +850,11 @@ onMounted(() => { loadTree(); buildMonthOptions(); loadPendingCount() })
 }
 </style>
 
+
+
+
+
+
+
+
+