Lin Qilong 1 day ago
parent
commit
c8c2431c7f
25 changed files with 811 additions and 212 deletions
  1. 33 0
      gw-admin/src/main/java/com/goldenwater/web/controller/system/AttOrgUwatBaseController.java
  2. 10 0
      gw-admin/src/main/java/com/goldenwater/web/controller/system/SysOrganizationExtController.java
  3. 13 0
      gw-admin/src/main/java/com/goldenwater/web/domain/OrgUwatBaseWithExtVO.java
  4. 25 8
      gw-admin/src/main/java/com/goldenwater/web/service/OrgCompositeService.java
  5. 127 14
      gw-admin/src/main/java/com/goldenwater/web/service/OrgUnifiedCompositeService.java
  6. 139 10
      gw-admin/src/main/java/com/goldenwater/web/service/OrgUwatCompositeService.java
  7. 23 8
      gw-admin/src/main/java/com/goldenwater/web/service/OrgWsubCompositeService.java
  8. 82 0
      gw-common/src/main/java/com/goldenwater/common/core/domain/vo/SysOrganizationInfoVO.java
  9. 4 1
      gw-slaj/src/main/java/com/goldenwater/slaj/hidd/service/impl/AttOrgExtServiceImpl.java
  10. 1 0
      gw-system/src/main/java/com/goldenwater/system/mapper/AttOrgUwatBaseMapper.java
  11. 1 0
      gw-system/src/main/java/com/goldenwater/system/service/IAttOrgUwatBaseService.java
  12. 5 0
      gw-system/src/main/java/com/goldenwater/system/service/impl/AttOrgUwatBaseServiceImpl.java
  13. 4 1
      gw-system/src/main/java/com/goldenwater/system/service/impl/AttOrgUwatExtServiceImpl.java
  14. 4 1
      gw-system/src/main/java/com/goldenwater/system/service/impl/AttOrgWsubServiceImpl.java
  15. 25 7
      gw-system/src/main/java/com/goldenwater/system/service/impl/SysOrganizationExtServiceImpl.java
  16. 39 2
      gw-system/src/main/resources/mapper/system/AttOrgUwatBaseMapper.xml
  17. 2 0
      gw-system/src/main/resources/mapper/system/AttOrgWsubMapper.xml
  18. 31 1
      gw-system/src/main/resources/mapper/system/SysOrganizationExtMapper.xml
  19. 15 0
      gw-ui/src/api/system/attOrgUwatBase.js
  20. 100 0
      gw-ui/src/components/OrgTreeSelect/index.vue
  21. 16 12
      gw-ui/src/views/system/dept/index.vue
  22. 91 16
      gw-ui/src/views/system/orgInfo/index.vue
  23. 4 47
      gw-ui/src/views/system/orgext/index.vue
  24. 15 83
      gw-ui/src/views/system/orguwatbase/index.vue
  25. 2 1
      gw-ui/src/views/system/orgwsub/index.vue

+ 33 - 0
gw-admin/src/main/java/com/goldenwater/web/controller/system/AttOrgUwatBaseController.java

@@ -33,6 +33,17 @@ public class AttOrgUwatBaseController extends BaseController
         return getDataTable(list);
     }
 
+    /**
+     * 参建单位页面列表:排除分包单位(分包单位只允许在分包页面管理)
+     */
+    @PreAuthorize("@ss.hasPermi('business:orguwatbase:list')")
+    @GetMapping("/list/exclude-wsub")
+    public TableDataInfo listExcludeWsub(AttOrgUwatBase attOrgUwatBase) {
+        startPage();
+        List<AttOrgUwatBase> list = attOrgUwatBaseService.selectAttOrgUwatBaseListExcludeWsub(attOrgUwatBase);
+        return getDataTable(list);
+    }
+
     @PreAuthorize("@ss.hasPermi('business:orguwatbase:query')")
     @GetMapping("/{guid}")
     public AjaxResult getInfo(@PathVariable String guid) {
@@ -56,6 +67,28 @@ public class AttOrgUwatBaseController extends BaseController
         return success(guid);
     }
 
+    /**
+     * 修改参建单位:单事务同步 sys_dept + att_org_uwat_base + att_org_uwat_ext + sys_organization_ext
+     */
+    @PreAuthorize("@ss.hasPermi('business:orguwatbase:edit')")
+    @Log(title = "参建单位信息表", businessType = BusinessType.UPDATE)
+    @PutMapping("/with-ext")
+    public AjaxResult editWithExt(@RequestBody OrgUwatBaseWithExtVO vo) {
+        orgUwatCompositeService.updateBaseWithExt(vo.getBase(), vo.getExt(), vo.getDept());
+        return success();
+    }
+
+    /**
+     * 按 base.guid(= dept_id)删除参建单位:扩展表 + 基础表 + sys_organization_ext + sys_dept 软删
+     */
+    @PreAuthorize("@ss.hasPermi('business:orguwatbase:remove')")
+    @Log(title = "参建单位信息表", businessType = BusinessType.DELETE)
+    @DeleteMapping("/with-ext/{guid}")
+    public AjaxResult removeWithExt(@PathVariable String guid) {
+        orgUwatCompositeService.deleteUwatWithBase(guid);
+        return success();
+    }
+
     @PreAuthorize("@ss.hasPermi('business:orguwatbase:edit')")
     @Log(title = "参建单位信息表", businessType = BusinessType.UPDATE)
     @PutMapping

+ 10 - 0
gw-admin/src/main/java/com/goldenwater/web/controller/system/SysOrganizationExtController.java

@@ -16,6 +16,7 @@ import com.goldenwater.common.core.domain.AjaxResult;
 import com.goldenwater.common.core.domain.vo.SysOrganizationInfoVO;
 import com.goldenwater.common.enums.BusinessType;
 import com.goldenwater.system.service.ISysOrganizationExtService;
+import com.goldenwater.system.service.ISysDeptService;
 import com.goldenwater.web.service.OrgUnifiedCompositeService;
 
 /**
@@ -33,6 +34,9 @@ public class SysOrganizationExtController extends BaseController
     @Autowired
     private OrgUnifiedCompositeService orgUnifiedCompositeService;
 
+    @Autowired
+    private ISysDeptService deptService;
+
     /**
      * 连表查询机构信息,返回一条数据
      */
@@ -40,6 +44,7 @@ public class SysOrganizationExtController extends BaseController
     @GetMapping("/{deptId}")
     public AjaxResult getInfo(@PathVariable String deptId)
     {
+        deptService.checkDeptDataScope(deptId);
         return success(sysOrganizationExtService.selectOrgInfoByDeptId(deptId));
     }
 
@@ -62,6 +67,10 @@ public class SysOrganizationExtController extends BaseController
     @PutMapping
     public AjaxResult edit(@RequestBody SysOrganizationInfoVO vo)
     {
+        if (vo != null && vo.getDeptId() != null)
+        {
+            deptService.checkDeptDataScope(vo.getDeptId());
+        }
         orgUnifiedCompositeService.updateOrgInfo(vo);
         return success();
     }
@@ -74,6 +83,7 @@ public class SysOrganizationExtController extends BaseController
     @DeleteMapping("/{deptId}")
     public AjaxResult remove(@PathVariable String deptId)
     {
+        deptService.checkDeptDataScope(deptId);
         orgUnifiedCompositeService.deleteOrgInfo(deptId);
         return success();
     }

+ 13 - 0
gw-admin/src/main/java/com/goldenwater/web/domain/OrgUwatBaseWithExtVO.java

@@ -2,6 +2,7 @@ package com.goldenwater.web.domain;
 
 import com.goldenwater.common.core.domain.entity.AttOrgUwatBase;
 import com.goldenwater.common.core.domain.entity.AttOrgUwatExt;
+import com.goldenwater.common.core.domain.entity.SysDept;
 
 /**
  * 参建单位基础信息与扩展信息联合提交 VO
@@ -14,6 +15,8 @@ public class OrgUwatBaseWithExtVO
     /** 参建单位扩展信息(att_org_uwat_ext) */
     private AttOrgUwatExt ext;
 
+    private SysDept dept;
+
     public AttOrgUwatBase getBase()
     {
         return base;
@@ -33,4 +36,14 @@ public class OrgUwatBaseWithExtVO
     {
         this.ext = ext;
     }
+
+    public SysDept getDept()
+    {
+        return dept;
+    }
+
+    public void setDept(SysDept dept)
+    {
+        this.dept = dept;
+    }
 }

+ 25 - 8
gw-admin/src/main/java/com/goldenwater/web/service/OrgCompositeService.java

@@ -7,6 +7,8 @@ import com.goldenwater.common.core.domain.entity.SysDept;
 import com.goldenwater.common.core.domain.entity.SysOrganizationExt;
 import com.goldenwater.common.exception.ServiceException;
 import com.goldenwater.common.utils.SecurityUtils;
+import com.goldenwater.common.utils.StringUtils;
+import com.goldenwater.common.utils.uuid.IdUtils;
 import com.goldenwater.slaj.hidd.domain.AttOrgBase;
 import com.goldenwater.slaj.hidd.domain.AttOrgExt;
 import com.goldenwater.slaj.hidd.service.IAttOrgBaseService;
@@ -46,11 +48,11 @@ public class OrgCompositeService
         return DATE_FORMAT.format(new Date());
     }
 
-    private SysOrganizationExt buildUnifiedExt(String guid, AttOrgExt ext)
+    private SysOrganizationExt buildUnifiedExt(String extGuid, String orgGuid, AttOrgExt ext)
     {
         SysOrganizationExt orgExt = new SysOrganizationExt();
-        orgExt.setGuid(guid);
-        orgExt.setOrgGuid(guid);
+        orgExt.setGuid(extGuid);
+        orgExt.setOrgGuid(orgGuid);
         orgExt.setStanGrad(ext.getStanGrad());
         orgExt.setFundSour(ext.getFundSour());
         orgExt.setAddr(ext.getAddr());
@@ -68,22 +70,33 @@ public class OrgCompositeService
         return orgExt;
     }
 
-    private void insertUnifiedExt(String guid, AttOrgExt ext)
+    private void insertUnifiedExt(String extGuid, String orgGuid, AttOrgExt ext)
     {
-        SysOrganizationExt orgExt = buildUnifiedExt(guid, ext);
+        SysOrganizationExt orgExt = buildUnifiedExt(extGuid, orgGuid, ext);
         orgExt.setCreateUser(SecurityUtils.getUserId());
         orgExt.setCreateTime(nowText());
         sysOrganizationExtMapper.insertSysOrganizationExt(orgExt);
     }
 
-    private void upsertUnifiedExt(String guid, AttOrgExt ext)
+    private void upsertUnifiedExt(String orgGuid, AttOrgExt ext)
     {
-        SysOrganizationExt orgExt = buildUnifiedExt(guid, ext);
+        String extGuid = resolveExtGuid(orgGuid, ext.getGuid());
+        SysOrganizationExt orgExt = buildUnifiedExt(extGuid, orgGuid, ext);
         orgExt.setModifyUser(SecurityUtils.getUserId());
         orgExt.setModifyTime(nowText());
         sysOrganizationExtMapper.upsertSysOrganizationExt(orgExt);
     }
 
+    private String resolveExtGuid(String orgGuid, String fallbackGuid)
+    {
+        SysOrganizationExt existing = sysOrganizationExtMapper.selectByOrgGuid(orgGuid);
+        if (existing != null && StringUtils.isNotEmpty(existing.getGuid()))
+        {
+            return existing.getGuid();
+        }
+        return StringUtils.isNotEmpty(fallbackGuid) ? fallbackGuid : IdUtils.fastSimpleUUID();
+    }
+
     /**
      * 新增水利机构及其基础信息、扩展信息(同一事务)
      *
@@ -126,12 +139,14 @@ public class OrgCompositeService
         attOrgBaseService.insertAttOrgBase(base);
 
         // 3) att_org_ext 机构扩展信息,从 dept 同步冗余字段
+        String extGuid = IdUtils.fastSimpleUUID();
+        ext.setGuid(extGuid);
         ext.setOrgGuid(guid);
         ext.setWiunName(dept.getDeptName());
         attOrgExtService.insertAttOrgExt(ext);
 
         // 4) sys_organization_ext 统一扩展表(与 sys_dept 一一对应)
-        insertUnifiedExt(guid, ext);
+        insertUnifiedExt(extGuid, guid, ext);
 
         return guid;
     }
@@ -171,6 +186,7 @@ public class OrgCompositeService
         deptService.updateDept(dept);
 
         // 3) att_org_ext 机构扩展信息,从 dept 同步冗余字段保证数据一致
+        String extGuid = resolveExtGuid(dept.getDeptId(), ext.getGuid());
         AttOrgExt oldExt = attOrgExtService.selectAttOrgExtByOrgGuid(dept.getDeptId());
         if (oldExt != null){
             ext.setGuid(oldExt.getGuid());
@@ -178,6 +194,7 @@ public class OrgCompositeService
             ext.setWiunName(dept.getDeptName());
             attOrgExtService.updateAttOrgExt(ext);
         } else {
+            ext.setGuid(extGuid);
             ext.setOrgGuid(dept.getDeptId());
             ext.setWiunName(dept.getDeptName());
             attOrgExtService.insertAttOrgExt(ext);

+ 127 - 14
gw-admin/src/main/java/com/goldenwater/web/service/OrgUnifiedCompositeService.java

@@ -14,6 +14,7 @@ import com.goldenwater.common.core.domain.entity.SysOrganizationExt;
 import com.goldenwater.common.core.domain.vo.SysOrganizationInfoVO;
 import com.goldenwater.common.utils.SecurityUtils;
 import com.goldenwater.common.utils.StringUtils;
+import com.goldenwater.common.utils.uuid.IdUtils;
 import com.goldenwater.slaj.hidd.domain.AttOrgBase;
 import com.goldenwater.slaj.hidd.domain.AttOrgExt;
 import com.goldenwater.slaj.hidd.service.IAttOrgBaseService;
@@ -147,7 +148,7 @@ public class OrgUnifiedCompositeService
             return;
         }
         SysOrganizationExt orgExt = new SysOrganizationExt();
-        orgExt.setGuid(deptId);
+        orgExt.setGuid(IdUtils.fastSimpleUUID());
         orgExt.setOrgGuid(deptId);
         orgExt.setCreateUser(SecurityUtils.getUserId());
         orgExt.setCreateTime(nowText());
@@ -249,34 +250,54 @@ public class OrgUnifiedCompositeService
     private void insertLegacyByType(String deptId, SysOrganizationInfoVO vo)
     {
         String orgType = resolveOrgType(vo);
+        String extGuid = resolveExtGuid(deptId);
         if (OrgTypeConst.WATER.equals(orgType))
         {
             insertWaterBase(deptId, vo);
-            attOrgExtService.insertAttOrgExt(buildWaterExt(deptId, vo, true));
+            attOrgExtService.insertAttOrgExt(buildWaterExt(extGuid, deptId, vo, true));
         }
         else if (OrgTypeConst.UWAT.equals(orgType))
         {
             insertUwatBase(deptId, vo);
-            attOrgUwatExtService.insertAttOrgUwatExt(buildUwatExt(deptId, vo, true));
+            attOrgUwatExtService.insertAttOrgUwatExt(buildUwatExt(extGuid, deptId, vo, true));
         }
         else if (OrgTypeConst.WSUB.equals(orgType))
         {
             insertUwatBase(deptId, vo);
             AttOrgWsub wsub = new AttOrgWsub();
-            wsub.setGuid(deptId);
+            wsub.setGuid(extGuid);
             wsub.setOrgGuid(deptId);
             wsub.setWiunWsubName(vo.getDeptName());
             wsub.setSocCreCode(vo.getCode());
+            wsub.setContrQualGrad(vo.getContrQualGrad());
             wsub.setLegPers(vo.getLegPers());
             wsub.setLegPersTel(vo.getLegPersTel());
+            wsub.setSafePers(vo.getSafePers());
+            wsub.setSafeProdLiceCode(vo.getSafeProdLiceCode());
             wsub.setCollTime(new Date());
             attOrgWsubService.insertAttOrgWsub(wsub);
         }
     }
 
+    /**
+     * 扩展表主键(E)与 dept_id 相互独立:新增时在 sys_organization_ext 上生成,
+     * 其余扩展表(att_org_ext / att_org_uwat_ext / att_org_wsub)沿用同一 E。
+     * 旧数据中 E 已存在,更新时必须复用,绝不能用 dept_id 覆盖。
+     */
+    private String resolveExtGuid(String deptId)
+    {
+        SysOrganizationExt existing = sysOrganizationExtMapper.selectByOrgGuid(deptId);
+        if (existing != null && StringUtils.isNotEmpty(existing.getGuid()))
+        {
+            return existing.getGuid();
+        }
+        return IdUtils.fastSimpleUUID();
+    }
+
     private void syncLegacyByType(String deptId, SysOrganizationInfoVO vo)
     {
         String orgType = resolveOrgType(vo);
+        String extGuid = resolveExtGuid(deptId);
         if (OrgTypeConst.WATER.equals(orgType))
         {
             AttOrgBase base = attOrgBaseService.selectAttOrgBaseByGuid(deptId);
@@ -286,6 +307,7 @@ public class OrgUnifiedCompositeService
                 up.setGuid(deptId);
                 up.setOrgName(vo.getDeptName());
                 up.setStatus(vo.getStatus());
+                up.setOrgType(vo.getType());
                 up.setModifier(SecurityUtils.getUserId());
                 attOrgBaseService.updateAttOrgBase(up);
             }
@@ -296,13 +318,13 @@ public class OrgUnifiedCompositeService
             AttOrgExt ext = attOrgExtService.selectAttOrgExtByOrgGuid(deptId);
             if (ext != null)
             {
-                AttOrgExt up = buildWaterExt(deptId, vo, false);
+                AttOrgExt up = buildWaterExt(extGuid, deptId, vo, false);
                 up.setGuid(ext.getGuid());
                 attOrgExtService.updateAttOrgExt(up);
             }
             else
             {
-                attOrgExtService.insertAttOrgExt(buildWaterExt(deptId, vo, true));
+                attOrgExtService.insertAttOrgExt(buildWaterExt(extGuid, deptId, vo, true));
             }
         }
         else if (OrgTypeConst.UWAT.equals(orgType))
@@ -314,6 +336,16 @@ public class OrgUnifiedCompositeService
                 up.setGuid(deptId);
                 up.setOrgName(vo.getDeptName());
                 up.setStatus(vo.getStatus());
+                up.setOrgType(vo.getType());
+                up.setOrgCode(vo.getOrgCode());
+                up.setOrgLevel(vo.getOrgLevel());
+                up.setOrdernum(vo.getOrderNum() == null ? null : vo.getOrderNum().longValue());
+                up.setAdCode(vo.getAdCode());
+                up.setJurd(vo.getJurd());
+                up.setAreaType(vo.getAreaType());
+                up.setNodeCode(vo.getNodeCode());
+                up.setOrgGrad(vo.getOrgGrad());
+                up.setNote(vo.getNote());
                 up.setModifier(SecurityUtils.getUserId());
                 attOrgUwatBaseService.updateAttOrgUwatBase(up);
             }
@@ -326,13 +358,13 @@ public class OrgUnifiedCompositeService
             List<AttOrgUwatExt> exts = attOrgUwatExtService.selectAttOrgUwatExtList(extQuery);
             if (exts != null && !exts.isEmpty())
             {
-                AttOrgUwatExt up = buildUwatExt(deptId, vo, false);
+                AttOrgUwatExt up = buildUwatExt(extGuid, deptId, vo, false);
                 up.setGuid(exts.get(0).getGuid());
                 attOrgUwatExtService.updateAttOrgUwatExt(up);
             }
             else
             {
-                attOrgUwatExtService.insertAttOrgUwatExt(buildUwatExt(deptId, vo, true));
+                attOrgUwatExtService.insertAttOrgUwatExt(buildUwatExt(extGuid, deptId, vo, true));
             }
         }
         else if (OrgTypeConst.WSUB.equals(orgType))
@@ -344,6 +376,16 @@ public class OrgUnifiedCompositeService
                 up.setGuid(deptId);
                 up.setOrgName(vo.getDeptName());
                 up.setStatus(vo.getStatus());
+                up.setOrgType(vo.getType());
+                up.setOrgCode(vo.getOrgCode());
+                up.setOrgLevel(vo.getOrgLevel());
+                up.setOrdernum(vo.getOrderNum() == null ? null : vo.getOrderNum().longValue());
+                up.setAdCode(vo.getAdCode());
+                up.setJurd(vo.getJurd());
+                up.setAreaType(vo.getAreaType());
+                up.setNodeCode(vo.getNodeCode());
+                up.setOrgGrad(vo.getOrgGrad());
+                up.setNote(vo.getNote());
                 up.setModifier(SecurityUtils.getUserId());
                 attOrgUwatBaseService.updateAttOrgUwatBase(up);
             }
@@ -361,19 +403,25 @@ public class OrgUnifiedCompositeService
                 up.setOrgGuid(deptId);
                 up.setWiunWsubName(vo.getDeptName());
                 up.setSocCreCode(vo.getCode());
+                up.setContrQualGrad(vo.getContrQualGrad());
                 up.setLegPers(vo.getLegPers());
                 up.setLegPersTel(vo.getLegPersTel());
+                up.setSafePers(vo.getSafePers());
+                up.setSafeProdLiceCode(vo.getSafeProdLiceCode());
                 attOrgWsubService.updateAttOrgWsub(up);
             }
             else
             {
                 AttOrgWsub wsub = new AttOrgWsub();
-                wsub.setGuid(deptId);
+                wsub.setGuid(extGuid);
                 wsub.setOrgGuid(deptId);
                 wsub.setWiunWsubName(vo.getDeptName());
                 wsub.setSocCreCode(vo.getCode());
+                wsub.setContrQualGrad(vo.getContrQualGrad());
                 wsub.setLegPers(vo.getLegPers());
                 wsub.setLegPersTel(vo.getLegPersTel());
+                wsub.setSafePers(vo.getSafePers());
+                wsub.setSafeProdLiceCode(vo.getSafeProdLiceCode());
                 wsub.setCollTime(new Date());
                 attOrgWsubService.insertAttOrgWsub(wsub);
             }
@@ -385,31 +433,61 @@ public class OrgUnifiedCompositeService
         AttOrgBase base = new AttOrgBase();
         base.setGuid(deptId);
         base.setPguid(vo.getParentId());
-        base.setOrgCode(StringUtils.isEmpty(vo.getCode()) ? "" : vo.getCode());
+        base.setOrgCode(StringUtils.isEmpty(vo.getOrgCode()) ? "" : vo.getOrgCode());
         base.setOrgName(vo.getDeptName());
+        base.setOrgLevel(vo.getOrgLevel());
         base.setOrgType(StringUtils.isEmpty(vo.getType()) ? "1" : vo.getType());
         base.setStatus(StringUtils.isEmpty(vo.getStatus()) ? "1" : vo.getStatus());
+        base.setOrdernum(vo.getOrderNum() == null ? null : vo.getOrderNum().longValue());
+        base.setAdCode(vo.getAdCode());
+        base.setJurd(vo.getJurd());
+        base.setAreaType(vo.getAreaType());
+        base.setNodeCode(vo.getNodeCode());
+        base.setOrgGrad(vo.getOrgGrad());
+        base.setNote(vo.getNote());
         base.setModifier(SecurityUtils.getUserId());
         base.setFromDate(new Date());
         attOrgBaseService.insertAttOrgBase(base);
     }
 
-    private AttOrgExt buildWaterExt(String deptId, SysOrganizationInfoVO vo, boolean withCollTime)
+    private AttOrgExt buildWaterExt(String extGuid, String deptId, SysOrganizationInfoVO vo, boolean withCollTime)
     {
         AttOrgExt ext = new AttOrgExt();
+        ext.setGuid(extGuid);
         ext.setOrgGuid(deptId);
         ext.setWiunName(vo.getDeptName());
         ext.setSocCreCode(vo.getCode());
+        ext.setOrgClienType(vo.getOrgClienType());
+        ext.setOrgLevel(vo.getOrgLevel());
+        ext.setWiunCode(vo.getWiunCode());
+        ext.setRegName(vo.getRegName());
+        ext.setLegRep(vo.getLegRep());
+        ext.setWiunProp(vo.getWiunProp());
+        ext.setIfWateEnte(vo.getIfWateEnte());
+        ext.setIsLegEnti(vo.getIsLegEnti());
+        ext.setIfMiniDire(vo.getIfMiniDire());
+        ext.setContrQualGrad(vo.getContrQualGrad());
+        ext.setContrCertNum(vo.getContrCertNum());
+        ext.setSupQualGrad(vo.getSupQualGrad());
         ext.setAddr(vo.getAddr());
         ext.setRegLoc(vo.getRegLoc());
         ext.setStanGrad(vo.getStanGrad());
+        ext.setStanCertCode(vo.getStanCertCode());
+        ext.setSafeProdLiceCode(vo.getSafeProdLiceCode());
         ext.setFundSour(vo.getFundSour());
+        ext.setEstDate(vo.getEstDate());
+        if (vo.getRegiCapi() != null)
+        {
+            ext.setRegiCapi(vo.getRegiCapi().longValue());
+        }
         ext.setLegPers(vo.getLegPers());
         ext.setLegPersTel(vo.getLegPersTel());
         ext.setSafetyLegPers(vo.getSafetyLegPers());
         ext.setSafetyLegPersTel(vo.getSafetyLegPersTel());
         ext.setSafeProdConta(vo.getSafeProdConta());
         ext.setSafeProdContaTel(vo.getSafeProdContaTel());
+        ext.setNote(vo.getNote());
+        ext.setProOrgGuid(vo.getParentId());
         if (vo.getWorkPopNum() != null)
         {
             ext.setWorkPopNum(vo.getWorkPopNum().longValue());
@@ -426,32 +504,67 @@ public class OrgUnifiedCompositeService
         AttOrgUwatBase base = new AttOrgUwatBase();
         base.setGuid(deptId);
         base.setPguid(vo.getParentId());
-        base.setOrgCode(StringUtils.isEmpty(vo.getCode()) ? "" : vo.getCode());
+        base.setOrgCode(StringUtils.isEmpty(vo.getOrgCode()) ? "" : vo.getOrgCode());
         base.setOrgName(vo.getDeptName());
+        base.setOrgLevel(vo.getOrgLevel());
         base.setOrgType(StringUtils.isEmpty(vo.getType()) ? "3" : vo.getType());
         base.setStatus(StringUtils.isEmpty(vo.getStatus()) ? "1" : vo.getStatus());
+        base.setOrdernum(vo.getOrderNum() == null ? null : vo.getOrderNum().longValue());
+        base.setAdCode(vo.getAdCode());
+        base.setJurd(vo.getJurd());
+        base.setAreaType(vo.getAreaType());
+        base.setNodeCode(vo.getNodeCode());
+        base.setOrgGrad(vo.getOrgGrad());
+        base.setNote(vo.getNote());
         base.setModifier(SecurityUtils.getUserId());
         base.setFromDate(new Date());
         attOrgUwatBaseService.insertAttOrgUwatBase(base);
     }
 
-    private AttOrgUwatExt buildUwatExt(String deptId, SysOrganizationInfoVO vo, boolean withCollTime)
+    private AttOrgUwatExt buildUwatExt(String extGuid, String deptId, SysOrganizationInfoVO vo, boolean withCollTime)
     {
         AttOrgUwatExt ext = new AttOrgUwatExt();
-        ext.setGuid(deptId);
+        ext.setGuid(extGuid);
         ext.setOrgGuid(deptId);
         ext.setWiunName(vo.getDeptName());
         ext.setSocCreCode(vo.getCode());
+        ext.setOrgClienType(vo.getOrgClienType());
+        ext.setOrgLevel(vo.getOrgLevel());
+        ext.setWiunCode(vo.getWiunCode());
+        ext.setRegName(vo.getRegName());
+        ext.setLegRep(vo.getLegRep());
+        ext.setWiunProp(vo.getWiunProp());
+        ext.setIfWateEnte(vo.getIfWateEnte());
+        ext.setAdminWiunGuid(vo.getAdminWiunGuid());
+        ext.setProOrgGuid(vo.getParentId());
+        ext.setIsLegEnti(vo.getIsLegEnti());
+        ext.setIfMiniDire(vo.getIfMiniDire());
+        ext.setContrQualGrad(vo.getContrQualGrad());
+        ext.setContrCertNum(vo.getContrCertNum());
+        ext.setSupQualGrad(vo.getSupQualGrad());
         ext.setAddr(vo.getAddr());
         ext.setRegLoc(vo.getRegLoc());
         ext.setStanGrad(vo.getStanGrad());
+        ext.setStanCertCode(vo.getStanCertCode());
+        ext.setSafeProdLiceCode(vo.getSafeProdLiceCode());
         ext.setFundSour(vo.getFundSour());
+        ext.setEstDate(vo.getEstDate());
+        ext.setRegiCapi(vo.getRegiCapi());
         ext.setLegPers(vo.getLegPers());
         ext.setLegPersTel(vo.getLegPersTel());
         ext.setSafetyLegPers(vo.getSafetyLegPers());
         ext.setSafetyLegPersTel(vo.getSafetyLegPersTel());
         ext.setSafeProdConta(vo.getSafeProdConta());
         ext.setSafeProdContaTel(vo.getSafeProdContaTel());
+        ext.setNote(vo.getNote());
+        if ("3".equals(vo.getType()))
+        {
+            ext.setOrgType("1");
+        }
+        else if ("4".equals(vo.getType()))
+        {
+            ext.setOrgType("2");
+        }
         if (vo.getWorkPopNum() != null)
         {
             ext.setWorkPopNum(vo.getWorkPopNum().longValue());

+ 139 - 10
gw-admin/src/main/java/com/goldenwater/web/service/OrgUwatCompositeService.java

@@ -19,6 +19,7 @@ import com.goldenwater.web.domain.OrgTypeConst;
 
 import java.text.SimpleDateFormat;
 import java.util.Date;
+import java.util.List;
 
 /**
  * 参建单位联合服务:新增参建单位时同一事务写入
@@ -48,11 +49,11 @@ public class OrgUwatCompositeService
         return DATE_FORMAT.format(new Date());
     }
 
-    private SysOrganizationExt buildUnifiedExt(String guid, AttOrgUwatExt ext)
+    private SysOrganizationExt buildUnifiedExt(String extGuid, String orgGuid, AttOrgUwatExt ext)
     {
         SysOrganizationExt orgExt = new SysOrganizationExt();
-        orgExt.setGuid(guid);
-        orgExt.setOrgGuid(guid);
+        orgExt.setGuid(extGuid);
+        orgExt.setOrgGuid(orgGuid);
         orgExt.setStanGrad(ext.getStanGrad());
         orgExt.setFundSour(ext.getFundSour());
         orgExt.setAddr(ext.getAddr());
@@ -77,14 +78,33 @@ public class OrgUwatCompositeService
         return orgExt;
     }
 
-    private void insertUnifiedExt(String guid, AttOrgUwatExt ext)
+    private void insertUnifiedExt(String extGuid, String orgGuid, AttOrgUwatExt ext)
     {
-        SysOrganizationExt orgExt = buildUnifiedExt(guid, ext);
+        SysOrganizationExt orgExt = buildUnifiedExt(extGuid, orgGuid, ext);
         orgExt.setCreateUser(SecurityUtils.getUserId());
         orgExt.setCreateTime(nowText());
         sysOrganizationExtMapper.insertSysOrganizationExt(orgExt);
     }
 
+    private void upsertUnifiedExt(String orgGuid, AttOrgUwatExt ext)
+    {
+        String extGuid = resolveExtGuid(orgGuid, ext == null ? null : ext.getGuid());
+        SysOrganizationExt orgExt = buildUnifiedExt(extGuid, orgGuid, ext);
+        orgExt.setModifyUser(SecurityUtils.getUserId());
+        orgExt.setModifyTime(nowText());
+        sysOrganizationExtMapper.upsertSysOrganizationExt(orgExt);
+    }
+
+    private String resolveExtGuid(String orgGuid, String fallbackGuid)
+    {
+        SysOrganizationExt existing = sysOrganizationExtMapper.selectByOrgGuid(orgGuid);
+        if (existing != null && StringUtils.isNotEmpty(existing.getGuid()))
+        {
+            return existing.getGuid();
+        }
+        return StringUtils.isNotEmpty(fallbackGuid) ? fallbackGuid : IdUtils.fastSimpleUUID();
+    }
+
     /**
      * 新增参建单位基础信息、部门及扩展信息(同一事务)
      *
@@ -122,6 +142,8 @@ public class OrgUwatCompositeService
         baseService.insertAttOrgUwatBase(base);
 
         // 3) att_org_uwat_ext 参建单位扩展信息,从 dept 同步冗余字段
+        String extGuid = IdUtils.fastSimpleUUID();
+        ext.setGuid(extGuid);
         ext.setOrgGuid(guid);
         ext.setWiunName(dept.getDeptName());
         // att_org_uwat_ext.org_type 仅存 1施工/2监理:由单位类型(base.org_type 3施工/4监理)映射
@@ -133,14 +155,10 @@ public class OrgUwatCompositeService
         {
             ext.setOrgType("2");
         }
-        if (StringUtils.isEmpty(ext.getGuid()))
-        {
-            ext.setGuid(IdUtils.fastSimpleUUID());
-        }
         extService.insertAttOrgUwatExt(ext);
 
         // 4) sys_organization_ext 统一扩展表(与 sys_dept 一一对应)
-        insertUnifiedExt(guid, ext);
+        insertUnifiedExt(extGuid, guid, ext);
 
         return guid;
     }
@@ -166,4 +184,115 @@ public class OrgUwatCompositeService
         // 3) 删除机构表 sys_dept(软删除)
         deptService.deleteDeptById(orgGuid);
     }
+
+    /**
+     * 修改参建单位:单事务同步 sys_dept + att_org_uwat_base + att_org_uwat_ext + sys_organization_ext。
+     * ext 允许为空(dept 树页面只编辑基础字段时保留原扩展信息)。
+     *
+     * @param base att_org_uwat_base(base.guid = dept_id)
+     * @param ext  att_org_uwat_ext(可为空)
+     * @param dept sys_dept(可为空,为空时按 base 同步名称/状态/上级/排序)
+     */
+    @Transactional
+    public void updateBaseWithExt(AttOrgUwatBase base, AttOrgUwatExt ext, SysDept dept)
+    {
+        if (base == null || StringUtils.isEmpty(base.getGuid()))
+        {
+            throw new ServiceException("参建单位基础信息不能为空");
+        }
+        String deptId = base.getGuid();
+
+        // 1) sys_dept 同步(名称/状态/上级/排序等,保持树与 ATT 表一致)
+        SysDept deptUpdate = dept == null ? new SysDept() : dept;
+        deptUpdate.setDeptId(deptId);
+        if (dept == null || StringUtils.isEmpty(dept.getDeptName()))
+        {
+            deptUpdate.setDeptName(base.getOrgName());
+        }
+        if (dept == null || StringUtils.isEmpty(dept.getStatus()))
+        {
+            deptUpdate.setStatus(base.getStatus());
+        }
+        if (dept == null || StringUtils.isEmpty(dept.getParentId()))
+        {
+            deptUpdate.setParentId(base.getPguid());
+        }
+        deptUpdate.setOrgType(OrgTypeConst.UWAT);
+        deptUpdate.setOrgCheckType(OrgTypeConst.ORG_CHECK_NON_WATER);
+        if (StringUtils.isEmpty(deptUpdate.getType()))
+        {
+            deptUpdate.setType(base.getOrgType());
+        }
+        deptUpdate.setUpdateBy(SecurityUtils.getUserId());
+        if (!deptService.checkDeptNameUnique(deptUpdate))
+        {
+            throw new ServiceException("修改机构'" + deptUpdate.getDeptName() + "'失败,机构名称已存在");
+        }
+        deptService.updateDept(deptUpdate);
+
+        // 2) att_org_uwat_base
+        base.setOrgName(deptUpdate.getDeptName());
+        base.setPguid(deptUpdate.getParentId());
+        base.setStatus(deptUpdate.getStatus());
+        base.setModifier(SecurityUtils.getUserId());
+        baseService.updateAttOrgUwatBase(base);
+
+        // 3) att_org_uwat_ext + sys_organization_ext
+        if (ext != null)
+        {
+            AttOrgUwatExt extQuery = new AttOrgUwatExt();
+            extQuery.setOrgGuid(deptId);
+            List<AttOrgUwatExt> existingExts = extService.selectAttOrgUwatExtList(extQuery);
+            String extGuid = (existingExts != null && !existingExts.isEmpty())
+                    ? existingExts.get(0).getGuid() : resolveExtGuid(deptId, ext.getGuid());
+            ext.setGuid(extGuid);
+            ext.setOrgGuid(deptId);
+            ext.setWiunName(deptUpdate.getDeptName());
+            ext.setProOrgGuid(deptUpdate.getParentId());
+            if ("3".equals(base.getOrgType()))
+            {
+                ext.setOrgType("1");
+            }
+            else if ("4".equals(base.getOrgType()))
+            {
+                ext.setOrgType("2");
+            }
+            AttOrgUwatExt existing = extService.selectAttOrgUwatExtById(extGuid);
+            if (existing != null)
+            {
+                extService.updateAttOrgUwatExt(ext);
+            }
+            else
+            {
+                extService.insertAttOrgUwatExt(ext);
+            }
+            upsertUnifiedExt(deptId, ext);
+        }
+    }
+
+    /**
+     * 按 base.guid(= dept_id)删除参建单位:扩展表 + 基础表 + sys_organization_ext + sys_dept 软删。
+     */
+    @Transactional
+    public void deleteUwatWithBase(String baseGuid)
+    {
+        AttOrgUwatBase base = baseService.selectAttOrgUwatBaseById(baseGuid);
+        if (base == null)
+        {
+            return;
+        }
+        AttOrgUwatExt extQuery = new AttOrgUwatExt();
+        extQuery.setOrgGuid(baseGuid);
+        List<AttOrgUwatExt> exts = extService.selectAttOrgUwatExtList(extQuery);
+        if (exts != null)
+        {
+            for (AttOrgUwatExt ext : exts)
+            {
+                extService.deleteAttOrgUwatExtById(ext.getGuid());
+            }
+        }
+        baseService.deleteAttOrgUwatBaseById(baseGuid);
+        sysOrganizationExtMapper.deleteByOrgGuid(baseGuid);
+        deptService.deleteDeptById(baseGuid);
+    }
 }

+ 23 - 8
gw-admin/src/main/java/com/goldenwater/web/service/OrgWsubCompositeService.java

@@ -9,6 +9,8 @@ import com.goldenwater.common.core.domain.entity.AttOrgWsub;
 import com.goldenwater.common.core.domain.entity.AttOrgUwatBase;
 import com.goldenwater.common.exception.ServiceException;
 import com.goldenwater.common.utils.SecurityUtils;
+import com.goldenwater.common.utils.StringUtils;
+import com.goldenwater.common.utils.uuid.IdUtils;
 import com.goldenwater.system.mapper.SysOrganizationExtMapper;
 import com.goldenwater.system.service.ISysDeptService;
 import com.goldenwater.system.service.IAttOrgWsubService;
@@ -46,32 +48,43 @@ public class OrgWsubCompositeService
         return DATE_FORMAT.format(new Date());
     }
 
-    private SysOrganizationExt buildUnifiedExt(String guid, AttOrgWsub wsub)
+    private SysOrganizationExt buildUnifiedExt(String extGuid, String orgGuid, AttOrgWsub wsub)
     {
         SysOrganizationExt orgExt = new SysOrganizationExt();
-        orgExt.setGuid(guid);
-        orgExt.setOrgGuid(guid);
+        orgExt.setGuid(extGuid);
+        orgExt.setOrgGuid(orgGuid);
         orgExt.setLegPers(wsub.getLegPers());
         orgExt.setLegPersTel(wsub.getLegPersTel());
         return orgExt;
     }
 
-    private void insertUnifiedExt(String guid, AttOrgWsub wsub)
+    private void insertUnifiedExt(String extGuid, String orgGuid, AttOrgWsub wsub)
     {
-        SysOrganizationExt orgExt = buildUnifiedExt(guid, wsub);
+        SysOrganizationExt orgExt = buildUnifiedExt(extGuid, orgGuid, wsub);
         orgExt.setCreateUser(SecurityUtils.getUserId());
         orgExt.setCreateTime(nowText());
         sysOrganizationExtMapper.insertSysOrganizationExt(orgExt);
     }
 
-    private void upsertUnifiedExt(String guid, AttOrgWsub wsub)
+    private void upsertUnifiedExt(String orgGuid, AttOrgWsub wsub)
     {
-        SysOrganizationExt orgExt = buildUnifiedExt(guid, wsub);
+        String extGuid = resolveExtGuid(orgGuid, wsub == null ? null : wsub.getGuid());
+        SysOrganizationExt orgExt = buildUnifiedExt(extGuid, orgGuid, wsub);
         orgExt.setModifyUser(SecurityUtils.getUserId());
         orgExt.setModifyTime(nowText());
         sysOrganizationExtMapper.upsertSysOrganizationExt(orgExt);
     }
 
+    private String resolveExtGuid(String orgGuid, String fallbackGuid)
+    {
+        SysOrganizationExt existing = sysOrganizationExtMapper.selectByOrgGuid(orgGuid);
+        if (existing != null && StringUtils.isNotEmpty(existing.getGuid()))
+        {
+            return existing.getGuid();
+        }
+        return StringUtils.isNotEmpty(fallbackGuid) ? fallbackGuid : IdUtils.fastSimpleUUID();
+    }
+
     /**
      * 新增分包单位及其基础信息(同一事务)
      *
@@ -110,12 +123,14 @@ public class OrgWsubCompositeService
         baseService.insertAttOrgUwatBase(base);
 
         // 3) att_org_wsub 分包单位信息,从 dept 同步冗余字段
+        String extGuid = IdUtils.fastSimpleUUID();
+        wsub.setGuid(extGuid);
         wsub.setOrgGuid(guid);
         wsub.setWiunWsubName(dept.getDeptName());
         attOrgWsubService.insertAttOrgWsub(wsub);
 
         // 4) sys_organization_ext 统一扩展表(与 sys_dept 一一对应)
-        insertUnifiedExt(guid, wsub);
+        insertUnifiedExt(extGuid, guid, wsub);
 
         return guid;
     }

+ 82 - 0
gw-common/src/main/java/com/goldenwater/common/core/domain/vo/SysOrganizationInfoVO.java

@@ -50,6 +50,35 @@ public class SysOrganizationInfoVO
     private String reportReward;
     private String locAd;
 
+    // ========== type-specific redundant fields (flat VO, routed by org type) ==========
+    private String orgCode;
+    private String orgLevel;
+    private String adCode;
+    private String jurd;
+    private String areaType;
+    private String nodeCode;
+    private String orgGrad;
+    private String orgClienType;
+    private String wiunCode;
+    private String regName;
+    private String legRep;
+    private String wiunProp;
+    private String ifWateEnte;
+    private String isLegEnti;
+    private String ifMiniDire;
+    private String contrQualGrad;
+    private String contrCertNum;
+    private String supQualGrad;
+    private String stanCertCode;
+    private String safeProdLiceCode;
+    private String safePers;
+    @com.fasterxml.jackson.annotation.JsonFormat(pattern = "yyyy-MM-dd")
+    private java.util.Date estDate;
+    private java.math.BigDecimal regiCapi;
+    private String note;
+    private String proOrgGuid;
+    private String adminWiunGuid;
+
     public String getDeptId() { return deptId; }
     public void setDeptId(String deptId) { this.deptId = deptId; }
     public String getParentId() { return parentId; }
@@ -125,4 +154,57 @@ public class SysOrganizationInfoVO
     public void setReportReward(String reportReward) { this.reportReward = reportReward; }
     public String getLocAd() { return locAd; }
     public void setLocAd(String locAd) { this.locAd = locAd; }
+
+    public String getOrgCode() { return orgCode; }
+    public void setOrgCode(String orgCode) { this.orgCode = orgCode; }
+    public String getOrgLevel() { return orgLevel; }
+    public void setOrgLevel(String orgLevel) { this.orgLevel = orgLevel; }
+    public String getAdCode() { return adCode; }
+    public void setAdCode(String adCode) { this.adCode = adCode; }
+    public String getJurd() { return jurd; }
+    public void setJurd(String jurd) { this.jurd = jurd; }
+    public String getAreaType() { return areaType; }
+    public void setAreaType(String areaType) { this.areaType = areaType; }
+    public String getNodeCode() { return nodeCode; }
+    public void setNodeCode(String nodeCode) { this.nodeCode = nodeCode; }
+    public String getOrgGrad() { return orgGrad; }
+    public void setOrgGrad(String orgGrad) { this.orgGrad = orgGrad; }
+    public String getOrgClienType() { return orgClienType; }
+    public void setOrgClienType(String orgClienType) { this.orgClienType = orgClienType; }
+    public String getWiunCode() { return wiunCode; }
+    public void setWiunCode(String wiunCode) { this.wiunCode = wiunCode; }
+    public String getRegName() { return regName; }
+    public void setRegName(String regName) { this.regName = regName; }
+    public String getLegRep() { return legRep; }
+    public void setLegRep(String legRep) { this.legRep = legRep; }
+    public String getWiunProp() { return wiunProp; }
+    public void setWiunProp(String wiunProp) { this.wiunProp = wiunProp; }
+    public String getIfWateEnte() { return ifWateEnte; }
+    public void setIfWateEnte(String ifWateEnte) { this.ifWateEnte = ifWateEnte; }
+    public String getIsLegEnti() { return isLegEnti; }
+    public void setIsLegEnti(String isLegEnti) { this.isLegEnti = isLegEnti; }
+    public String getIfMiniDire() { return ifMiniDire; }
+    public void setIfMiniDire(String ifMiniDire) { this.ifMiniDire = ifMiniDire; }
+    public String getContrQualGrad() { return contrQualGrad; }
+    public void setContrQualGrad(String contrQualGrad) { this.contrQualGrad = contrQualGrad; }
+    public String getContrCertNum() { return contrCertNum; }
+    public void setContrCertNum(String contrCertNum) { this.contrCertNum = contrCertNum; }
+    public String getSupQualGrad() { return supQualGrad; }
+    public void setSupQualGrad(String supQualGrad) { this.supQualGrad = supQualGrad; }
+    public String getStanCertCode() { return stanCertCode; }
+    public void setStanCertCode(String stanCertCode) { this.stanCertCode = stanCertCode; }
+    public String getSafeProdLiceCode() { return safeProdLiceCode; }
+    public void setSafeProdLiceCode(String safeProdLiceCode) { this.safeProdLiceCode = safeProdLiceCode; }
+    public String getSafePers() { return safePers; }
+    public void setSafePers(String safePers) { this.safePers = safePers; }
+    public java.util.Date getEstDate() { return estDate; }
+    public void setEstDate(java.util.Date estDate) { this.estDate = estDate; }
+    public java.math.BigDecimal getRegiCapi() { return regiCapi; }
+    public void setRegiCapi(java.math.BigDecimal regiCapi) { this.regiCapi = regiCapi; }
+    public String getNote() { return note; }
+    public void setNote(String note) { this.note = note; }
+    public String getProOrgGuid() { return proOrgGuid; }
+    public void setProOrgGuid(String proOrgGuid) { this.proOrgGuid = proOrgGuid; }
+    public String getAdminWiunGuid() { return adminWiunGuid; }
+    public void setAdminWiunGuid(String adminWiunGuid) { this.adminWiunGuid = adminWiunGuid; }
 }

+ 4 - 1
gw-slaj/src/main/java/com/goldenwater/slaj/hidd/service/impl/AttOrgExtServiceImpl.java

@@ -64,7 +64,10 @@ public class AttOrgExtServiceImpl implements IAttOrgExtService {
      */
     @Override
     public int insertAttOrgExt(AttOrgExt attOrgExt) {
-        attOrgExt.setGuid(IdUtils.fastSimpleUUID());
+        if (attOrgExt.getGuid() == null || attOrgExt.getGuid().isEmpty())
+        {
+            attOrgExt.setGuid(IdUtils.fastSimpleUUID());
+        }
         return attOrgExtMapper.insertAttOrgExt(attOrgExt);
     }
 

+ 1 - 0
gw-system/src/main/java/com/goldenwater/system/mapper/AttOrgUwatBaseMapper.java

@@ -12,6 +12,7 @@ import com.goldenwater.common.core.domain.entity.AttOrgUwatBase;
 public interface AttOrgUwatBaseMapper
 {
     public List<AttOrgUwatBase> selectAttOrgUwatBaseList(AttOrgUwatBase attOrgUwatBase);
+    public List<AttOrgUwatBase> selectAttOrgUwatBaseListExcludeWsub(AttOrgUwatBase attOrgUwatBase);
     public AttOrgUwatBase selectAttOrgUwatBaseById(String guid);
     public int insertAttOrgUwatBase(AttOrgUwatBase attOrgUwatBase);
     public int updateAttOrgUwatBase(AttOrgUwatBase attOrgUwatBase);

+ 1 - 0
gw-system/src/main/java/com/goldenwater/system/service/IAttOrgUwatBaseService.java

@@ -11,6 +11,7 @@ import com.goldenwater.common.core.domain.entity.AttOrgUwatBase;
 public interface IAttOrgUwatBaseService
 {
     public List<AttOrgUwatBase> selectAttOrgUwatBaseList(AttOrgUwatBase attOrgUwatBase);
+    public List<AttOrgUwatBase> selectAttOrgUwatBaseListExcludeWsub(AttOrgUwatBase attOrgUwatBase);
     public AttOrgUwatBase selectAttOrgUwatBaseById(String guid);
     public int insertAttOrgUwatBase(AttOrgUwatBase attOrgUwatBase);
     public int updateAttOrgUwatBase(AttOrgUwatBase attOrgUwatBase);

+ 5 - 0
gw-system/src/main/java/com/goldenwater/system/service/impl/AttOrgUwatBaseServiceImpl.java

@@ -32,6 +32,11 @@ public class AttOrgUwatBaseServiceImpl implements IAttOrgUwatBaseService
         return attOrgUwatBaseMapper.selectAttOrgUwatBaseList(attOrgUwatBase);
     }
 
+    @Override
+    public List<AttOrgUwatBase> selectAttOrgUwatBaseListExcludeWsub(AttOrgUwatBase attOrgUwatBase) {
+        return attOrgUwatBaseMapper.selectAttOrgUwatBaseListExcludeWsub(attOrgUwatBase);
+    }
+
     @Override
     public AttOrgUwatBase selectAttOrgUwatBaseById(String guid) {
         return attOrgUwatBaseMapper.selectAttOrgUwatBaseById(guid);

+ 4 - 1
gw-system/src/main/java/com/goldenwater/system/service/impl/AttOrgUwatExtServiceImpl.java

@@ -44,8 +44,11 @@ public class AttOrgUwatExtServiceImpl implements IAttOrgUwatExtService
         {
             return;
         }
+        SysOrganizationExt existing = sysOrganizationExtMapper.selectByOrgGuid(ext.getOrgGuid());
+        String extGuid = existing != null && StringUtils.isNotEmpty(existing.getGuid())
+                ? existing.getGuid() : IdUtils.fastSimpleUUID();
         SysOrganizationExt orgExt = new SysOrganizationExt();
-        orgExt.setGuid(ext.getOrgGuid());
+        orgExt.setGuid(extGuid);
         orgExt.setOrgGuid(ext.getOrgGuid());
         orgExt.setStanGrad(ext.getStanGrad());
         orgExt.setFundSour(ext.getFundSour());

+ 4 - 1
gw-system/src/main/java/com/goldenwater/system/service/impl/AttOrgWsubServiceImpl.java

@@ -39,7 +39,10 @@ public class AttOrgWsubServiceImpl implements IAttOrgWsubService {
 
     @Override
     public int insertAttOrgWsub(AttOrgWsub attOrgWsub) {
-        attOrgWsub.setGuid(IdUtils.fastSimpleUUID());
+        if (attOrgWsub.getGuid() == null || attOrgWsub.getGuid().isEmpty())
+        {
+            attOrgWsub.setGuid(IdUtils.fastSimpleUUID());
+        }
         attOrgWsub.setCollTime(new Date());
         attOrgWsub.setUpdTime(new Date());
         attOrgWsub.setRecPers(SecurityUtils.getUserId());

+ 25 - 7
gw-system/src/main/java/com/goldenwater/system/service/impl/SysOrganizationExtServiceImpl.java

@@ -12,6 +12,7 @@ import com.goldenwater.common.core.domain.vo.SysOrganizationInfoVO;
 import com.goldenwater.common.exception.ServiceException;
 import com.goldenwater.common.utils.SecurityUtils;
 import com.goldenwater.common.utils.StringUtils;
+import com.goldenwater.common.utils.uuid.IdUtils;
 import com.goldenwater.system.mapper.SysOrganizationExtMapper;
 import com.goldenwater.system.service.ISysDeptService;
 import com.goldenwater.system.service.ISysOrganizationExtService;
@@ -82,7 +83,8 @@ public class SysOrganizationExtServiceImpl implements ISysOrganizationExtService
 
         // 以 sys_dept 实际生成的 deptId 作为两表统一主键/外键
         String guid = dept.getDeptId();
-        insertExt(guid, vo);
+        String extGuid = IdUtils.fastSimpleUUID();
+        insertExt(extGuid, guid, vo);
         return guid;
     }
 
@@ -93,24 +95,30 @@ public class SysOrganizationExtServiceImpl implements ISysOrganizationExtService
     {
         SysDept dept = new SysDept();
         dept.setDeptId(vo.getDeptId());
+        dept.setParentId(vo.getParentId());
         dept.setDeptName(vo.getDeptName());
         dept.setLeader(vo.getLeader());
         dept.setPhone(vo.getPhone());
         dept.setEmail(vo.getEmail());
         dept.setStatus(vo.getStatus());
+        dept.setOrderNum(vo.getOrderNum());
         dept.setOrgType(vo.getOrgType());
         dept.setOrgCheckType(vo.getOrgCheckType());
         dept.setType(vo.getType());
         dept.setCode(vo.getCode());
         dept.setUpdateBy(SecurityUtils.getUserId());
+        if (!deptService.checkDeptNameUnique(dept))
+        {
+            throw new ServiceException("修改机构'" + dept.getDeptName() + "'失败,机构名称已存在");
+        }
         deptService.updateDept(dept);
 
         upsertExt(vo.getDeptId(), vo);
     }
 
-    private void insertExt(String guid, SysOrganizationInfoVO vo)
+    private void insertExt(String extGuid, String orgGuid, SysOrganizationInfoVO vo)
     {
-        SysOrganizationExt ext = buildExt(guid, vo);
+        SysOrganizationExt ext = buildExt(extGuid, orgGuid, vo);
         ext.setCreateUser(SecurityUtils.getUserId());
         ext.setCreateTime(DATE_FORMAT.format(new Date()));
         sysOrganizationExtMapper.insertSysOrganizationExt(ext);
@@ -118,17 +126,27 @@ public class SysOrganizationExtServiceImpl implements ISysOrganizationExtService
 
     private void upsertExt(String guid, SysOrganizationInfoVO vo)
     {
-        SysOrganizationExt ext = buildExt(guid, vo);
+        SysOrganizationExt ext = buildExt(resolveExtGuid(guid), guid, vo);
         ext.setModifyUser(SecurityUtils.getUserId());
         ext.setModifyTime(DATE_FORMAT.format(new Date()));
         sysOrganizationExtMapper.upsertSysOrganizationExt(ext);
     }
 
-    private SysOrganizationExt buildExt(String guid, SysOrganizationInfoVO vo)
+    private String resolveExtGuid(String orgGuid)
+    {
+        SysOrganizationExt existing = sysOrganizationExtMapper.selectByOrgGuid(orgGuid);
+        if (existing != null && StringUtils.isNotEmpty(existing.getGuid()))
+        {
+            return existing.getGuid();
+        }
+        return IdUtils.fastSimpleUUID();
+    }
+
+    private SysOrganizationExt buildExt(String extGuid, String orgGuid, SysOrganizationInfoVO vo)
     {
         SysOrganizationExt ext = new SysOrganizationExt();
-        ext.setGuid(guid);
-        ext.setOrgGuid(guid);
+        ext.setGuid(extGuid);
+        ext.setOrgGuid(orgGuid);
         ext.setStanGrad(vo.getStanGrad());
         ext.setFundSour(vo.getFundSour());
         ext.setAddr(vo.getAddr());

+ 39 - 2
gw-system/src/main/resources/mapper/system/AttOrgUwatBaseMapper.xml

@@ -41,9 +41,46 @@
             <if test="status != null and status != ''">
                 AND STATUS like '%' || #{status} || '%'
             </if>
-            <if test="pguid != null and pguid != ''">
-                AND PGUID = #{pguid}
+            <choose>
+                <when test="pguid != null and pguid == ''">
+                    AND (PGUID IS NULL OR PGUID = '')
+                </when>
+                <when test="pguid != null and pguid != ''">
+                    AND PGUID = #{pguid}
+                </when>
+            </choose>
+        </where>
+        order by GUID
+    </select>
+
+    <!-- 参建单位页面列表:排除分包单位(sys_dept.org_type = '3' 才是参建单位,分包为 '2') -->
+    <select id="selectAttOrgUwatBaseListExcludeWsub" parameterType="AttOrgUwatBase" resultMap="AttOrgUwatBaseResult">
+        <include refid="selectAttOrgUwatBaseVo"/>
+        <where>
+            <if test="orgCode != null and orgCode != ''">
+                AND ORG_CODE like '%' || #{orgCode} || '%'
+            </if>
+            <if test="orgName != null and orgName != ''">
+                AND ORG_NAME like '%' || #{orgName} || '%'
+            </if>
+            <if test="orgType != null and orgType != ''">
+                AND ORG_TYPE like '%' || #{orgType} || '%'
+            </if>
+            <if test="status != null and status != ''">
+                AND STATUS like '%' || #{status} || '%'
             </if>
+            <choose>
+                <when test="pguid != null and pguid == ''">
+                    AND (PGUID IS NULL OR PGUID = '')
+                </when>
+                <when test="pguid != null and pguid != ''">
+                    AND PGUID = #{pguid}
+                </when>
+            </choose>
+            AND EXISTS (SELECT 1 FROM sys_dept d
+                        WHERE d.dept_id = ATT_ORG_UWAT_BASE.GUID
+                          AND d.org_type = '3'
+                          AND d.del_flag = '0')
         </where>
         order by GUID
     </select>

+ 2 - 0
gw-system/src/main/resources/mapper/system/AttOrgWsubMapper.xml

@@ -61,6 +61,7 @@
     <insert id="insertAttOrgWsub" parameterType="AttOrgWsub">
         insert into ATT_ORG_WSUB
         <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="guid != null">GUID,</if>
             <if test="socCreCode != null">SOC_CRE_CODE,</if>
             <if test="orgGuid != null">ORG_GUID,</if>
             <if test="wiunWsubName != null">WIUN_WSUB_NAME,</if>
@@ -75,6 +76,7 @@
         </trim>
         values
         <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="guid != null">#{guid},</if>
             <if test="socCreCode != null">#{socCreCode},</if>
             <if test="orgGuid != null">#{orgGuid},</if>
             <if test="wiunWsubName != null">#{wiunWsubName},</if>

+ 31 - 1
gw-system/src/main/resources/mapper/system/SysOrganizationExtMapper.xml

@@ -41,10 +41,40 @@
                e.proj_char_pers,
                e.proj_char_pers_tel,
                e.report_reward,
-               e.loc_ad
+               e.loc_ad,
+               coalesce(b.org_code, '') as org_code,
+               coalesce(b.org_level, e3.org_level, e2.org_level) as org_level,
+               b.ad_code as ad_code,
+               b.jurd as jurd,
+               b.area_type as area_type,
+               b.node_code as node_code,
+               b.org_grad as org_grad,
+               coalesce(e3.org_clien_type, e2.org_clien_type) as org_clien_type,
+               coalesce(e3.wiun_code, e2.wiun_code) as wiun_code,
+               coalesce(e3.reg_name, e2.reg_name) as reg_name,
+               coalesce(e3.leg_rep, e2.leg_rep) as leg_rep,
+               coalesce(e3.wiun_prop, e2.wiun_prop) as wiun_prop,
+               coalesce(e3.if_wate_ente, e2.if_wate_ente) as if_wate_ente,
+               coalesce(e3.is_leg_enti, e2.is_leg_enti) as is_leg_enti,
+               coalesce(e3.if_mini_dire, e2.if_mini_dire) as if_mini_dire,
+               coalesce(e3.contr_qual_grad, e2.contr_qual_grad, w.contr_qual_grad) as contr_qual_grad,
+               coalesce(e3.contr_cert_num, e2.contr_cert_num) as contr_cert_num,
+               coalesce(e3.sup_qual_grad, e2.sup_qual_grad) as sup_qual_grad,
+               coalesce(e3.stan_cert_code, e2.stan_cert_code) as stan_cert_code,
+               coalesce(e3.safe_prod_lice_code, e2.safe_prod_lice_code, w.safe_prod_lice_code) as safe_prod_lice_code,
+               w.safe_pers as safe_pers,
+               coalesce(e3.est_date, e2.est_date) as est_date,
+               coalesce(e3.regi_capi, e2.regi_capi) as regi_capi,
+               coalesce(e3.note, e2.note, b.note) as note,
+               coalesce(e3.pro_org_guid, e2.pro_org_guid) as pro_org_guid,
+               coalesce(e3.admin_wiun_guid, e2.admin_wiun_guid) as admin_wiun_guid
         from sys_dept d
                  left join sys_organization_ext e on e.org_guid = d.dept_id
                  left join sys_dept pd on pd.dept_id = d.parent_id
+                 left join att_org_uwat_base b on b.guid = d.dept_id
+                 left join att_org_uwat_ext e2 on e2.org_guid = d.dept_id
+                 left join att_org_ext e3 on e3.org_guid = d.dept_id
+                 left join att_org_wsub w on w.org_guid = d.dept_id
         where d.dept_id = #{deptId}
           and d.del_flag = '0'
     </select>

+ 15 - 0
gw-ui/src/api/system/attOrgUwatBase.js

@@ -5,6 +5,11 @@ export function listAttOrgUwatBase(query) {
   return request({ url: '/business/orguwatbase/list', method: 'get', params: query })
 }
 
+// 查询参建单位列表(排除分包单位,分包只在分包页面管理)
+export function listAttOrgUwatBaseExcludeWsub(query) {
+  return request({ url: '/business/orguwatbase/list/exclude-wsub', method: 'get', params: query })
+}
+
 // 查询参建单位信息表详细
 export function getAttOrgUwatBase(guid) {
   if (!guid || (typeof guid === 'string' && guid.trim() === '') || Array.isArray(guid)) {
@@ -23,6 +28,11 @@ export function addOrgUwatWithExt(data) {
   return request({ url: '/business/orguwatbase/with-ext', method: 'post', data: data })
 }
 
+// 修改参建单位基础信息及扩展信息(同一事务:sys_dept + att_org_uwat_base + att_org_uwat_ext + sys_organization_ext)
+export function updateOrgUwatWithExt(data) {
+  return request({ url: '/business/orguwatbase/with-ext', method: 'put', data: data })
+}
+
 // 修改参建单位信息表
 export function updateAttOrgUwatBase(data) {
   return request({ url: '/business/orguwatbase', method: 'put', data: data })
@@ -35,3 +45,8 @@ export function delAttOrgUwatBase(guids) {
   }
   return request({ url: '/business/orguwatbase/' + guids, method: 'delete' })
 }
+
+// 删除参建单位及关联数据(同一事务:扩展表 + 基础表 + sys_organization_ext + sys_dept 软删)
+export function delOrgUwatWithExt(guid) {
+  return request({ url: '/business/orguwatbase/with-ext/' + guid, method: 'delete' })
+}

+ 100 - 0
gw-ui/src/components/OrgTreeSelect/index.vue

@@ -0,0 +1,100 @@
+<template>
+  <el-form-item
+    :label="label"
+    :prop="prop"
+    :rules="required ? [{ required: true, message: label + '不能为空', trigger: 'change' }] : undefined"
+  >
+    <el-tree-select
+      ref="treeSelectRef"
+      :model-value="modelValue"
+      lazy
+      :load="loadNode"
+      :props="treeProps"
+      filterable
+      clearable
+      check-strictly
+      :render-after-expand="false"
+      :cache-data="cacheData"
+      :disabled="disabled"
+      :placeholder="placeholder"
+      :style="{ width }"
+      @update:model-value="handleChange"
+    />
+  </el-form-item>
+</template>
+
+<script setup name="OrgTreeSelect">
+import { computed, ref, watch } from 'vue'
+import { getDept, listDeptChildren } from '@/api/system/dept'
+import { getAttOrgUwatBase, listAttOrgUwatBase, listAttOrgUwatBaseExcludeWsub } from '@/api/system/attOrgUwatBase'
+
+const props = defineProps({
+  modelValue: { type: String, default: undefined },
+  label: { type: String, default: '上级机构' },
+  prop: { type: String, default: undefined },
+  placeholder: { type: String, default: '请选择上级机构' },
+  required: { type: Boolean, default: false },
+  disabled: { type: Boolean, default: false },
+  width: { type: String, default: '220px' },
+  // 数据源:water=水利机构树(sys_dept.org_type=1),uwat=参建单位树(排除分包),uwatAll=全部非水利机构(含分包)
+  scope: { type: String, default: 'uwat' },
+  excludeGuid: { type: String, default: undefined }
+})
+
+const emit = defineEmits(['update:modelValue'])
+
+const isWater = computed(() => props.scope === 'water')
+const isUwat = computed(() => props.scope === 'uwat')
+
+const treeProps = computed(() => isWater.value
+  ? { label: 'deptName', value: 'deptId', children: 'children', isLeaf: (data) => data.hasChildren === false }
+  : { label: 'orgName', value: 'guid', children: 'children', isLeaf: (data) => data.hasChildren === false })
+
+function filterExcluded(list) {
+  return (list || []).filter(r => !props.excludeGuid || (r.guid !== props.excludeGuid && r.deptId !== props.excludeGuid))
+}
+
+/** 逐层懒加载:根节点查顶级机构,展开节点按 parentId/pguid 查子级 */
+function loadNode(node, resolve) {
+  if (node.level === 0) {
+    if (isWater.value) {
+      listDeptChildren({ orgType: '1', pageNum: 1, pageSize: 1000 })
+        .then(res => resolve(filterExcluded(res.data.rows)))
+        .catch(() => resolve([]))
+    } else {
+      const req = isUwat.value ? listAttOrgUwatBaseExcludeWsub : listAttOrgUwatBase
+      req({ pguid: '', pageNum: 1, pageSize: 1000 })
+        .then(res => resolve(filterExcluded(res.rows)))
+        .catch(() => resolve([]))
+    }
+  } else if (isWater.value) {
+    listDeptChildren({ parentId: node.data.deptId, orgType: '1' })
+      .then(res => resolve(filterExcluded(res.data)))
+      .catch(() => resolve([]))
+  } else {
+    const req = isUwat.value ? listAttOrgUwatBaseExcludeWsub : listAttOrgUwatBase
+    req({ pguid: node.data.guid, pageNum: 1, pageSize: 1000 })
+      .then(res => resolve(filterExcluded(res.rows)))
+      .catch(() => resolve([]))
+  }
+}
+
+function handleChange(val) {
+  emit('update:modelValue', val)
+}
+
+/** 懒加载回显:已选节点放入 cache-data,未展开也能显示名称 */
+const cacheData = ref([])
+watch(() => props.modelValue, (val) => {
+  cacheData.value = []
+  if (!val) return
+  const fetch = isWater.value ? getDept(val) : getAttOrgUwatBase(val)
+  fetch.then(res => {
+    const d = res.data
+    if (!d) return
+    cacheData.value = isWater.value
+      ? [{ deptId: d.deptId || val, deptName: d.deptName || val, children: [] }]
+      : [{ guid: d.guid || val, orgName: d.orgName || val, children: [] }]
+  }).catch(() => {})
+}, { immediate: true })
+</script>

+ 16 - 12
gw-ui/src/views/system/dept/index.vue

@@ -197,7 +197,7 @@
 <script setup name="Dept">
 import { listDept, getDept, delDept, addDept, updateDept, updateDeptSort, listDeptExcludeChild, listDeptChildren } from "@/api/system/dept"
 import { addOrgWithDept, listAttOrgExt, updateOrgWithDept } from "@/api/system/attOrgExt"
-import { addOrgUwatWithExt, getAttOrgUwatBase, updateAttOrgUwatBase } from "@/api/system/attOrgUwatBase"
+import { addOrgUwatWithExt, getAttOrgUwatBase, updateOrgUwatWithExt } from "@/api/system/attOrgUwatBase"
 import { useTableHeight } from '@/hooks/useTableHeight'
 import { UNIT_TYPE_OPTIONS, UWAT_UNIT_TYPE_OPTIONS, unitTypeToUwatExtType } from '@/utils/orgUnitType'
 
@@ -400,17 +400,21 @@ function submitForm() {
           getList()
         })
       } else {
-        // 参建单位:sys_dept + att_org_uwat_base 同步更新
-        const baseUpdate = uwatBaseRow.value
-          ? updateAttOrgUwatBase({
-              guid: form.value.deptId, pguid: form.value.parentId,
-              orgCode: form.value.orgCode, orgName: form.value.deptName,
-              orgLevel: form.value.baseOrgLevel, orgType: form.value.unitType,
-              ordernum: form.value.baseOrdernum, adCode: form.value.baseAdCode,
-              status: form.value.status
-            })
-          : Promise.resolve()
-        Promise.all([updateDept(form.value), baseUpdate]).then(() => {
+        // 参建单位:单事务同步 sys_dept + att_org_uwat_base(扩展信息由后端保留)
+        const base = {
+          guid: form.value.deptId, pguid: form.value.parentId,
+          orgCode: form.value.orgCode, orgName: form.value.deptName,
+          orgLevel: form.value.baseOrgLevel, orgType: form.value.unitType,
+          ordernum: form.value.baseOrdernum, adCode: form.value.baseAdCode,
+          status: form.value.status
+        }
+        const dept = {
+          deptId: form.value.deptId, parentId: form.value.parentId, deptName: form.value.deptName,
+          leader: form.value.leader, phone: form.value.phone, email: form.value.email,
+          status: form.value.status, orderNum: form.value.orderNum,
+          orgType: '3', orgCheckType: '2', type: form.value.unitType
+        }
+        updateOrgUwatWithExt({ base, ext: null, dept }).then(() => {
           proxy.$modal.msgSuccess("修改成功")
           open.value = false
           getList()

+ 91 - 16
gw-ui/src/views/system/orgInfo/index.vue

@@ -818,9 +818,9 @@
 
                 <el-select v-model="form.status" :disabled="!editing" style="width:100%">
 
-                  <el-option label="正常" value="0"/>
+                  <el-option label="正常" value="1"/>
 
-                  <el-option label="停用" value="1"/>
+                  <el-option label="停用" value="9"/>
 
                 </el-select>
 
@@ -1095,7 +1095,8 @@ function loadData() {
     Object.assign(form, {...EMPTY_FORM})
     form.deptId = data.deptId || ''
     form.deptName = data.deptName || ''
-    form.orgType = data.orgType || ''
+    // 单位类型(1水行政/2企事业单位/3施工/4监理)取自 sys_dept.type,供参建/分包分区回显
+    form.orgType = data.type || data.orgType || ''
     form.orgCheckType = data.orgCheckType || ''
     form.leader = data.leader || ''
     form.phone = data.phone || ''
@@ -1119,6 +1120,32 @@ function loadData() {
     form.safetyLegPersTel = data.safetyLegPersTel || ''
     form.safeProdConta = data.safeProdConta || ''
     form.safeProdContaTel = data.safeProdContaTel || ''
+    // 参建/分包专属字段回显
+    form.orgCode = data.orgCode || ''
+    form.orgLevel = data.orgLevel || ''
+    form.ordernum = data.orderNum ?? ''
+    form.adCode = data.adCode || ''
+    form.jurd = data.jurd || ''
+    form.areaType = data.areaType || ''
+    form.nodeCode = data.nodeCode || ''
+    form.orgGrad = data.orgGrad || ''
+    form.orgClienType = data.orgClienType || ''
+    form.wiunCode = data.wiunCode || ''
+    form.regName = data.regName || ''
+    form.legRep = data.legRep || ''
+    form.wiunProp = data.wiunProp || ''
+    form.ifWateEnte = data.ifWateEnte || ''
+    form.isLegEnti = data.isLegEnti || ''
+    form.ifMiniDire = data.ifMiniDire || ''
+    form.contrQualGrad = data.contrQualGrad || ''
+    form.contrCertNum = data.contrCertNum || ''
+    form.supQualGrad = data.supQualGrad || ''
+    form.stanCertCode = data.stanCertCode || ''
+    form.safeProdLiceCode = data.safeProdLiceCode || ''
+    form.safePers = data.safePers || ''
+    form.estDate = data.estDate || ''
+    form.regiCapi = data.regiCapi ?? ''
+    form.note = data.note || ''
     // 页面分区:1 水利机构 / 2 参建单位 / 3 分包单位
     // 由 sys_dept.org_type 映射(1水利机构 2分包单位 3参建单位);org_type 为空时按 org_check_type/type 兜底
     const orgTypeMap = {'1': '1', '3': '2', '2': '3'}
@@ -1276,19 +1303,67 @@ function submitForm() {
         status: form.status,
         // 机构类型(sys_dept.org_type):由页面分区反推,1水利/2分包/3参建
         orgType: {'1': '1', '2': '3', '3': '2'}[form.type] || undefined,
-        code: form.socCreCode,
-        addr: form.addr,
-        regLoc: form.regLoc,
-        stanGrad: form.stanGrad,
-        fundSour: form.fundSour,
-        workPopNum: form.workPopNum,
-        reportReward: form.accReportMech,
-        legPers: form.legPers,
-        legPersTel: form.legPersTel,
-        safetyLegPers: form.safetyLegPers,
-        safetyLegPersTel: form.safetyLegPersTel,
-        safeProdConta: form.safeProdConta,
-        safeProdContaTel: form.safeProdContaTel
+        orgCheckType: form.type === '1' ? '1' : '2',
+        code: form.socCreCode
+      }
+      if (form.type === '1') {
+        Object.assign(data, {
+          addr: form.addr,
+          regLoc: form.regLoc,
+          stanGrad: form.stanGrad,
+          fundSour: form.fundSour,
+          workPopNum: form.workPopNum === '' ? null : form.workPopNum,
+          reportReward: form.accReportMech,
+          legPers: form.legPers,
+          legPersTel: form.legPersTel,
+          safetyLegPers: form.safetyLegPers,
+          safetyLegPersTel: form.safetyLegPersTel,
+          safeProdConta: form.safeProdConta,
+          safeProdContaTel: form.safeProdContaTel
+        })
+      } else if (form.type === '2') {
+        Object.assign(data, {
+          orgCode: form.orgCode,
+          orgLevel: form.orgLevel,
+          orderNum: form.ordernum === '' || form.ordernum == null ? null : Number(form.ordernum),
+          adCode: form.adCode,
+          jurd: form.jurd,
+          areaType: form.areaType,
+          nodeCode: form.nodeCode,
+          orgGrad: form.orgGrad,
+          type: form.orgType,
+          orgClienType: form.orgClienType,
+          wiunCode: form.wiunCode,
+          regName: form.regName,
+          legRep: form.legRep,
+          wiunProp: form.wiunProp,
+          ifWateEnte: form.ifWateEnte,
+          isLegEnti: form.isLegEnti,
+          ifMiniDire: form.ifMiniDire,
+          contrQualGrad: form.contrQualGrad,
+          contrCertNum: form.contrCertNum,
+          supQualGrad: form.supQualGrad,
+          stanGrad: form.stanGrad,
+          stanCertCode: form.stanCertCode,
+          safeProdLiceCode: form.safeProdLiceCode,
+          fundSour: form.fundSour,
+          estDate: form.estDate || null,
+          regiCapi: form.regiCapi === '' ? null : form.regiCapi,
+          addr: form.addr,
+          regLoc: form.regLoc,
+          note: form.note
+        })
+      } else if (form.type === '3') {
+        Object.assign(data, {
+          orgCode: form.orgCode,
+          orgLevel: form.orgLevel,
+          type: form.orgType,
+          contrQualGrad: form.contrQualGrad,
+          legPers: form.legPers,
+          legPersTel: form.legPersTel,
+          safePers: form.safePers,
+          safeProdLiceCode: form.safeProdLiceCode
+        })
       }
       if (locAd) {
         data.locAd = locAd

+ 4 - 47
gw-ui/src/views/system/orgext/index.vue

@@ -1,9 +1,6 @@
 <template>
-  <div class="app-container tree-sidebar-manage-wrap">
-    <tree-panel :key="deptTreeKey" title="组织机构" :tree-data="deptOptions" :tree-props="treeProps" search-placeholder="请输入机构名称" storage-key="orgext-sidebar-width" node-key="deptId" lazy :load="loadDeptNode" @node-click="handleNodeClick" @refresh="getDeptTree" ref="deptTreeRef" />
-    <div class="tree-sidebar-content">
-      <div class="content-inner" ref="containerRef" style="padding: 0;">
-        <el-card class="page-card" style="height: 100%;" :body-style="{height: '100%'}">
+  <div ref="containerRef" class="system-page config-page">
+    <el-card class="page-card">
           <template #header>
             <div class="card-header">
               <div class="header-left">
@@ -28,6 +25,7 @@
                   <el-option v-for="dict in UNIT_TYPE_OPTIONS" :key="dict.value" :label="dict.label" :value="dict.value" />
                 </el-select>
               </el-form-item>
+              <OrgTreeSelect v-model="queryParams.parentId" label="上级机构" scope="water" placeholder="请选择上级机构" />
 
               <el-form-item>
                 <el-button type="primary" @click="handleQuery"><el-icon><Search /></el-icon> 搜索</el-button>
@@ -448,16 +446,13 @@
             <el-button type="primary" @click="submitForm">确定</el-button>
          </template>
       </el-dialog>
-      </div>
-    </div>
   </div>
 </template>
 
 <script setup name="AttOrgExt">
 import { listAttOrgExt, getAttOrgExt, delOrgExtWithDept, addOrgWithDept, updateOrgWithDept } from "@/api/system/attOrgExt"
-import { listDeptChildren } from "@/api/system/user"
-import TreePanel from "@/components/TreePanel"
 import OrgSelect from "@/components/OrgSelect"
+import OrgTreeSelect from "@/components/OrgTreeSelect"
 import { useTableHeight } from '@/hooks/useTableHeight'
 import { Plus, Delete, Search, Refresh, OfficeBuilding } from '@element-plus/icons-vue'
 import { UNIT_TYPE_OPTIONS } from '@/utils/orgUnitType'
@@ -476,41 +471,6 @@ const single = ref(true)
 const multiple = ref(true)
 const total = ref(0)
 const title = ref("")
-const deptOptions = ref(undefined)
-const deptTreeKey = ref(0)
-const deptTreeRef = ref(null)
-const selectedDept = ref(null)
-
-// 树组件属性映射(SysDept 字段)
-const treeProps = { children: 'children', label: 'deptName', hasChildren: 'hasChildren' }
-
-/** 懒加载部门树节点 */
-function loadDeptNode(node, resolve) {
-  // 左侧树只展示水利机构(sys_dept.org_type = '1'),不展示参建单位等其它机构
-  const treeParams = { orgType: '1' }
-  if (node.level === 0) {
-    listDeptChildren(treeParams).then(res => {
-      resolve(res.data.rows)
-    })
-  } else {
-    listDeptChildren({ ...treeParams, parentId: node.data.deptId }).then(res => {
-      resolve(res.data)
-    })
-  }
-}
-
-/** 刷新部门树 */
-function getDeptTree() {
-  deptTreeKey.value++
-}
-
-/** 节点单击事件:搜索子机构(pro_org_guid = 选中节点 deptId)*/
-function handleNodeClick(data) {
-  selectedDept.value = { deptId: data.deptId, deptName: data.deptName }
-  queryParams.value.parentId = data.deptId
-  queryParams.value.orgGuid = undefined
-  handleQuery()
-}
 
 const data = reactive({
   form: {
@@ -697,7 +657,6 @@ function resetQuery() {
   proxy.resetForm("queryRef")
   queryParams.value.orgGuid = undefined
   queryParams.value.parentId = undefined
-  proxy.$refs.deptTreeRef?.setCurrentKey(null)
   handleQuery()
 }
 
@@ -709,8 +668,6 @@ function handleSelectionChange(selection) {
 
 function handleAdd() {
   reset()
-  form.value.proOrgGuid = selectedDept.value?.deptId
-  form.value.orgGuid = selectedDept.value?.deptId
   open.value = true
   title.value = "添加水利机构单位"
 }

+ 15 - 83
gw-ui/src/views/system/orguwatbase/index.vue

@@ -1,9 +1,6 @@
 <template>
-  <div class="app-container tree-sidebar-manage-wrap">
-    <tree-panel :key="deptTreeKey" title="参建单位" :tree-data="deptOptions" :tree-props="treeProps" search-placeholder="请输入机构名称" storage-key="orguwatbase-sidebar-width" node-key="guid" @node-click="handleNodeClick" @refresh="getDeptTree" ref="deptTreeRef" />
-    <div class="tree-sidebar-content">
-      <div class="content-inner" ref="containerRef" style="padding: 0;">
-        <el-card class="page-card" style="height: 100%;" :body-style="{height: '100%'}">
+  <div ref="containerRef" class="system-page config-page">
+    <el-card class="page-card">
           <template #header>
             <div class="card-header">
               <div class="header-left">
@@ -36,6 +33,7 @@
                   <el-option v-for="dict in slaj_org_status" :key="dict.value" :label="dict.label" :value="dict.value" />
                 </el-select>
               </el-form-item>
+              <OrgTreeSelect v-model="queryParams.pguid" label="上级机构" scope="uwat" placeholder="请选择上级机构" />
 
               <el-form-item>
                 <el-button type="primary" @click="handleQuery"><el-icon><Search /></el-icon> 搜索</el-button>
@@ -44,7 +42,7 @@
             </el-form>
           </div>
 
-          <el-table  height="calc(100% - 100px)" v-loading="loading" :data="attOrgUwatBaseList" @selection-change="handleSelectionChange">
+          <el-table :height="tableHeight" v-loading="loading" :data="attOrgUwatBaseList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="50" align="center" />
         <el-table-column label="机构代码" align="center" prop="orgCode" :show-overflow-tooltip="true" />
         <el-table-column label="机构名称" align="center" prop="orgName" :show-overflow-tooltip="true" />
@@ -348,17 +346,15 @@
             <el-button type="primary" @click="submitForm">确定</el-button>
          </template>
       </el-dialog>
-      </div>
-    </div>
   </div>
 </template>
 
 <script setup name="AttOrgUwatBase">
-import { listAttOrgUwatBase, getAttOrgUwatBase, delAttOrgUwatBase, updateAttOrgUwatBase, addOrgUwatWithExt } from "@/api/system/attOrgUwatBase"
+import { listAttOrgUwatBase, listAttOrgUwatBaseExcludeWsub, getAttOrgUwatBase, updateOrgUwatWithExt, addOrgUwatWithExt, delOrgUwatWithExt } from "@/api/system/attOrgUwatBase"
 import { listAttOrgUwatExt, delAttOrgUwatExt, addAttOrgUwatExt, updateAttOrgUwatExt } from "@/api/system/attOrgUwatExt"
 import { listAttOrgExt } from "@/api/system/attOrgExt"
 import { listAttAdBase, getAttAdBase } from "@/api/system/attAdBase"
-import TreePanel from "@/components/TreePanel"
+import OrgTreeSelect from "@/components/OrgTreeSelect"
 import { useTableHeight } from '@/hooks/useTableHeight'
 import { Plus, Delete, Search, Refresh, OfficeBuilding } from '@element-plus/icons-vue'
 import { UNIT_TYPE_OPTIONS, unitTypeToUwatExtType } from '@/utils/orgUnitType'
@@ -395,10 +391,6 @@ const single = ref(true)
 const multiple = ref(true)
 const total = ref(0)
 const title = ref("")
-const deptOptions = ref(undefined)
-const deptTreeKey = ref(0)
-const deptTreeRef = ref(null)
-const selectedParent = ref(null)
 // 水利机构远程搜索下拉(数据源:AttOrgExt,机构上万条需按名称检索)
 const wiunOptions = ref([])
 const wiunLoading = ref(false)
@@ -426,48 +418,6 @@ const adCascaderProps = {
   }
 }
 
-// 树组件属性映射(参建单位 ATT_ORG_UWAT_BASE 字段)
-const treeProps = { children: 'children', label: 'orgName', hasChildren: 'hasChildren' }
-
-/** 加载参建单位组织机构树(按 pguid 层级构建) */
-function loadOrgTree() {
-  listAttOrgUwatBase({ pageNum: 1, pageSize: 10000 }).then(res => {
-    deptOptions.value = buildOrgTree(res.rows || [])
-  })
-}
-
-/** 将扁平的参建单位列表按 pguid 构建为树形结构 */
-function buildOrgTree(list) {
-  const map = {}
-  const roots = []
-  list.forEach(item => {
-    map[item.guid] = { ...item, children: [], hasChildren: false }
-  })
-  list.forEach(item => {
-    const node = map[item.guid]
-    if (item.pguid && map[item.pguid]) {
-      map[item.pguid].children.push(node)
-      map[item.pguid].hasChildren = true
-    } else {
-      roots.push(node)
-    }
-  })
-  return roots
-}
-
-/** 刷新参建单位树 */
-function getDeptTree() {
-  loadOrgTree()
-  deptTreeKey.value++
-}
-
-/** 节点单击事件:按上级机构筛选并记录选中机构 */
-function handleNodeClick(data) {
-  selectedParent.value = { deptId: data.guid, deptName: data.orgName }
-  queryParams.value.pguid = data.guid
-  handleQuery()
-}
-
 const data = reactive({
   // 基础信息(ATT_ORG_UWAT_BASE)
   baseForm: {
@@ -633,7 +583,7 @@ function loadAdCascade(adCode) {
 
 function getList() {
   loading.value = true
-  listAttOrgUwatBase(queryParams.value).then(response => {
+  listAttOrgUwatBaseExcludeWsub(queryParams.value).then(response => {
     attOrgUwatBaseList.value = response.rows
     total.value = response.total
     loading.value = false
@@ -706,15 +656,12 @@ function reset() {
 
 function handleQuery() {
   queryParams.value.pageNum = 1
-  loadOrgTree()
-getList()
+  getList()
 }
 
 function resetQuery() {
   proxy.resetForm("queryRef")
   queryParams.value.pguid = undefined
-  selectedParent.value = null
-  proxy.$refs.deptTreeRef?.setCurrentKey(null)
   handleQuery()
 }
 
@@ -726,7 +673,6 @@ function handleSelectionChange(selection) {
 
 function handleAdd() {
   reset()
-  baseForm.value.pguid = selectedParent.value?.deptId
   open.value = true
   title.value = "添加参建单位"
 }
@@ -777,24 +723,17 @@ async function submitForm() {
   }
 
   if (isEdit) {
-    await updateAttOrgUwatBase(baseForm.value)
     extForm.value.orgGuid = baseForm.value.guid
-    if (extForm.value.guid) {
-      await updateAttOrgUwatExt(extForm.value)
-    } else {
-      await addAttOrgUwatExt(extForm.value)
-    }
+    await updateOrgUwatWithExt({ base: baseForm.value, ext: extForm.value })
     proxy.$modal.msgSuccess("修改成功")
     open.value = false
-    loadOrgTree()
-getList()
+    getList()
   } else {
     // 基础信息与扩展信息同一事务入库,要么都成功要么都回滚
     await addOrgUwatWithExt({ base: baseForm.value, ext: extForm.value })
     proxy.$modal.msgSuccess("新增成功")
     open.value = false
-    loadOrgTree()
-getList()
+    getList()
   }
 }
 
@@ -802,22 +741,15 @@ function handleDelete(row) {
   const guids = row.guid || ids.value
   const guidList = Array.isArray(guids) ? guids : [guids]
   proxy.$modal.confirm('是否确认删除该参建单位(含扩展信息)?').then(function() {
-    // 先删除每条基础信息关联的扩展信息,再删除基础信息
-    const tasks = guidList.map(g =>
-      listAttOrgUwatExt({ orgGuid: g, pageSize: 1000 }).then(r => {
-        const extRows = r.rows || []
-        return extRows.length ? delAttOrgUwatExt(extRows.map(e => e.guid).join(',')) : Promise.resolve()
-      })
-    )
-    return Promise.all(tasks).then(() => delAttOrgUwatBase(guids))
+    // 单事务删除:扩展表 + 基础表 + sys_organization_ext + sys_dept 软删
+    const tasks = guidList.map(g => delOrgUwatWithExt(g))
+    return Promise.all(tasks)
   }).then(() => {
-    loadOrgTree()
-getList()
+    getList()
     proxy.$modal.msgSuccess("删除成功")
   }).catch(() => {})
 }
 
-loadOrgTree()
 getList()
 </script>
 

+ 2 - 1
gw-ui/src/views/system/orgwsub/index.vue

@@ -20,7 +20,7 @@
               <el-form-item label="分包单位名称" prop="wiunWsubName">
                 <el-input v-model="queryParams.wiunWsubName" placeholder="请输入分包单位名称" clearable @keyup.enter="handleQuery" />
               </el-form-item>
-              <OrgSelect v-model="queryParams.parentId" label="上级机构" placeholder="请输入机构名称搜索" scope="uwat" />
+              <OrgTreeSelect v-model="queryParams.parentId" label="上级机构" scope="uwatAll" placeholder="请选择上级机构" />
 
               <el-form-item>
                 <el-button type="primary" @click="handleQuery"><el-icon><Search /></el-icon> 搜索</el-button>
@@ -163,6 +163,7 @@
 <script setup name="AttOrgWsub">
 import { listAttOrgWsub, getAttOrgWsub, delOrgWsubWithDept, addOrgWsubWithDept, updateOrgWsubWithDept } from "@/api/system/attOrgWsub"
 import OrgSelect from "@/components/OrgSelect"
+import OrgTreeSelect from "@/components/OrgTreeSelect"
 import { useTableHeight } from '@/hooks/useTableHeight'
 import { Plus, Delete, Search, Refresh, OfficeBuilding } from '@element-plus/icons-vue'
 import { UNIT_TYPE_OPTIONS } from '@/utils/orgUnitType'