Lin Qilong 1 неделя назад
Родитель
Сommit
2c4ff3de11
34 измененных файлов с 588 добавлено и 243 удалено
  1. 4 2
      gw-common/src/main/java/com/goldenwater/common/core/domain/entity/RelEngOrg.java
  2. 6 0
      gw-common/src/main/java/com/goldenwater/common/core/domain/vo/RelTendOrgDetailVO.java
  3. 12 6
      gw-slaj/src/main/resources/mapper/slaj/hidd/AttEngBaseMapper.xml
  4. 1 0
      gw-system/src/main/java/com/goldenwater/system/mapper/RelProjOrgMapper.java
  5. 1 0
      gw-system/src/main/java/com/goldenwater/system/service/IRelProjOrgService.java
  6. 26 3
      gw-system/src/main/java/com/goldenwater/system/service/impl/AttProjBaseServiceImpl.java
  7. 1 0
      gw-system/src/main/java/com/goldenwater/system/service/impl/ObjTendServiceImpl.java
  8. 5 0
      gw-system/src/main/java/com/goldenwater/system/service/impl/RelEngOrgServiceImpl.java
  9. 5 0
      gw-system/src/main/java/com/goldenwater/system/service/impl/RelEngOrgUwatServiceImpl.java
  10. 14 5
      gw-system/src/main/java/com/goldenwater/system/service/impl/RelProjOrgServiceImpl.java
  11. 7 0
      gw-system/src/main/java/com/goldenwater/system/service/impl/RelTendOrgServiceImpl.java
  12. 5 0
      gw-system/src/main/java/com/goldenwater/system/service/impl/RelUserTendServiceImpl.java
  13. 6 0
      gw-system/src/main/resources/mapper/system/RelEngOrgUwatMapper.xml
  14. 10 0
      gw-system/src/main/resources/mapper/system/RelProjOrgMapper.xml
  15. 9 1
      gw-system/src/main/resources/mapper/system/RelTendOrgMapper.xml
  16. 6 0
      gw-system/src/main/resources/mapper/system/RelUserTendMapper.xml
  17. 42 0
      gw-ui/src/components/CoordPicker/index.vue
  18. 71 0
      gw-ui/src/components/EngSelect/index.vue
  19. 71 0
      gw-ui/src/components/ProjSelect/index.vue
  20. 3 0
      gw-ui/src/main.js
  21. 13 5
      gw-ui/src/views/slaj/eng/attengcws/index.vue
  22. 9 3
      gw-ui/src/views/slaj/eng/attengdike/index.vue
  23. 10 2
      gw-ui/src/views/slaj/eng/attenghyst/index.vue
  24. 13 1
      gw-ui/src/views/slaj/eng/attengirr/index.vue
  25. 11 1
      gw-ui/src/views/slaj/eng/attengothe/index.vue
  26. 11 1
      gw-ui/src/views/slaj/eng/attengpust/index.vue
  27. 13 5
      gw-ui/src/views/slaj/eng/attengres/index.vue
  28. 11 1
      gw-ui/src/views/slaj/eng/attengsd/index.vue
  29. 26 2
      gw-ui/src/views/slaj/eng/attengwadi/index.vue
  30. 11 1
      gw-ui/src/views/slaj/eng/attengwaga/index.vue
  31. 31 31
      gw-ui/src/views/system/orgext/index.vue
  32. 86 49
      gw-ui/src/views/system/projbase/eng/index.vue
  33. 0 6
      gw-ui/src/views/system/projbase/index.vue
  34. 38 118
      gw-ui/src/views/system/projbase/tend/index.vue

+ 4 - 2
gw-common/src/main/java/com/goldenwater/common/core/domain/entity/RelEngOrg.java

@@ -3,6 +3,8 @@ package com.goldenwater.common.core.domain.entity;
 import com.goldenwater.common.annotation.Excel;
 import lombok.Data;
 
+import java.util.Date;
+
 /**
  * 工程机构关联 rel_eng_org
  */
@@ -14,7 +16,7 @@ public class RelEngOrg {
     @Excel(name = "机构guid", width = 36)
     private String orgGuid;
     @Excel(name = "开始日期", width = 20, dateFormat = "yyyy-MM-dd HH:mm:ss")
-    private String fromDate;
+    private Date fromDate;
     @Excel(name = "结束日期", width = 20, dateFormat = "yyyy-MM-dd HH:mm:ss")
-    private String toDate;
+    private Date toDate;
 }

+ 6 - 0
gw-common/src/main/java/com/goldenwater/common/core/domain/vo/RelTendOrgDetailVO.java

@@ -18,4 +18,10 @@ public class RelTendOrgDetailVO {
 
     /** 参建单位名称(后台 JOIN 拼接) */
     private String orgName;
+
+    /** 参建单位代码(后台 JOIN 拼接) */
+    private String orgCode;
+
+    /** 参建单位类型(后台 JOIN 拼接) */
+    private String orgType;
 }

+ 12 - 6
gw-slaj/src/main/resources/mapper/slaj/hidd/AttEngBaseMapper.xml

@@ -62,13 +62,19 @@
         where guid = #{guid}
     </select>
     <select id="selectAttEngBaseList" parameterType="com.goldenwater.slaj.hidd.domain.AttEngBase" resultMap="AttEngBaseResult">
-        <include refid="selectAttEngBaseVo"/>
+        select b.guid, b.pguid, b.ad_guid, b.ad_code, b.lk_guid, b.eng_name, b.eng_guid, b.org_rest, b.org_jurd,
+               b.old_code, b.impo_grad, b.eng_scal, b.appr_budg, b.if_rein_force, b.eng_grad, b.tot_cap, b.res_code,
+               b.start_long, b.start_lat, b.end_long, b.end_lat, b.start_loc, b.end_loc, b.firs_poin_ad_guid,
+               b.end_ad_guid, b.rv_guid, b.des_fl_stand, b.oflp_code, b.proj_guid, b.cen_long, b.cen_lat, b.stat,
+               b.start_date, b.comp_date, b.eng_stat, b.org_guid, b.eng_rein_force_guid, b.note, b.coll_time,
+               b.upd_time, b.from_date, b.to_date, b.rec_pers, b.eng_code, b.eng_type
+        from att_eng_base b
         <where>
-            <if test="engName != null and engName != ''">AND eng_name like '%' || #{engName} || '%'</if>
-            <if test="engCode != null and engCode != ''">AND eng_code = #{engCode}</if>
-            <if test="engGuid != null and engGuid != ''">AND eng_guid = #{engGuid}</if>
-            <if test="projGuid != null and projGuid != ''">AND proj_guid = #{projGuid}</if>
-            <if test="orgGuid != null and orgGuid != ''">AND org_guid = #{orgGuid}</if>
+            <if test="engName != null and engName != ''">AND b.eng_name like '%' || #{engName} || '%'</if>
+            <if test="engCode != null and engCode != ''">AND b.eng_code = #{engCode}</if>
+            <if test="engGuid != null and engGuid != ''">AND b.eng_guid = #{engGuid}</if>
+            <if test="projGuid != null and projGuid != ''">AND EXISTS (SELECT 1 FROM rel_proj_org r WHERE r.org_guid = b.guid AND r.proj_guid = #{projGuid})</if>
+            <if test="orgGuid != null and orgGuid != ''">AND b.org_guid = #{orgGuid}</if>
         </where>
     </select>
     <insert id="insertAttEngBase" parameterType="com.goldenwater.slaj.hidd.domain.AttEngBase">

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

@@ -17,4 +17,5 @@ public interface RelProjOrgMapper
     public int updateRelProjOrg(RelProjOrg relProjOrg);
     public int deleteRelProjOrgById(String guid);
     public int deleteRelProjOrgByIds(String[] guids);
+    public int deleteRelProjOrgByProjGuid(String projGuid);
 }

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

@@ -16,4 +16,5 @@ public interface IRelProjOrgService
     public int updateRelProjOrg(RelProjOrg relProjOrg);
     public int deleteRelProjOrgById(String guid);
     public int deleteRelProjOrgByIds(String[] guids);
+    public int deleteRelProjOrgByProjGuid(String projGuid);
 }

+ 26 - 3
gw-system/src/main/java/com/goldenwater/system/service/impl/AttProjBaseServiceImpl.java

@@ -1,12 +1,14 @@
 package com.goldenwater.system.service.impl;
 
 import com.goldenwater.common.core.domain.entity.AttProjBase;
+import com.goldenwater.common.core.domain.entity.RelProjOrg;
 import com.goldenwater.common.core.mapper.ObjSyncMapper;
 import com.goldenwater.common.core.domain.obj.ObjProj;
 import com.goldenwater.common.utils.SecurityUtils;
 import com.goldenwater.common.utils.uuid.IdUtils;
 import com.goldenwater.system.mapper.AttProjBaseMapper;
 import com.goldenwater.system.service.IAttProjBaseService;
+import com.goldenwater.system.service.IRelProjOrgService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -26,6 +28,9 @@ public class AttProjBaseServiceImpl implements IAttProjBaseService {
     @Autowired
     private ObjSyncMapper objSyncMapper;
 
+    @Autowired
+    private IRelProjOrgService relProjOrgService;
+
     @Override
     public List<AttProjBase> selectAttProjBaseList(AttProjBase attProjBase) {
         return attProjBaseMapper.selectAttProjBaseList(attProjBase);
@@ -42,7 +47,17 @@ public class AttProjBaseServiceImpl implements IAttProjBaseService {
         e.setCollTime(new Date());
         e.setRecPers(SecurityUtils.getUserId());
         int rows = attProjBaseMapper.insertAttProjBase(e);
-        if (rows > 0) syncObj(e);
+        if (rows > 0) {
+            syncObj(e);
+            // 自动创建 REL_PROJ_ORG,把当前用户所在机构与项目关联
+            String deptId = SecurityUtils.getDeptId();
+            if (deptId != null) {
+                RelProjOrg rel = new RelProjOrg();
+                rel.setProjGuid(e.getGuid());
+                rel.setOrgGuid(deptId);
+                relProjOrgService.insertRelProjOrg(rel);
+            }
+        }
         return rows;
     }
 
@@ -57,7 +72,10 @@ public class AttProjBaseServiceImpl implements IAttProjBaseService {
     @Override
     public int deleteAttProjBaseById(String guid) {
         int rows = attProjBaseMapper.deleteAttProjBaseById(guid);
-        if (rows > 0) objSyncMapper.deleteObjProj(guid);
+        if (rows > 0) {
+            objSyncMapper.deleteObjProj(guid);
+            relProjOrgService.deleteRelProjOrgByProjGuid(guid);
+        }
         return rows;
     }
 
@@ -70,7 +88,12 @@ public class AttProjBaseServiceImpl implements IAttProjBaseService {
     @Override
     public int deleteAttProjBaseByIds(String[] guids) {
         int rows = attProjBaseMapper.deleteAttProjBaseByIds(guids);
-        if (rows > 0) { for (String guid : guids) objSyncMapper.deleteObjProj(guid); }
+        if (rows > 0) {
+            for (String guid : guids) {
+                objSyncMapper.deleteObjProj(guid);
+                relProjOrgService.deleteRelProjOrgByProjGuid(guid);
+            }
+        }
         return rows;
     }
 }

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

@@ -45,6 +45,7 @@ public class ObjTendServiceImpl implements IObjTendService {
     @Override
     public int insertObjTend(ObjTend objTend) {
         objTend.setGuid(IdUtils.fastSimpleUUID());
+        objTend.setCollTime(new Date());
         objTend.setRecPers(String.valueOf(SecurityUtils.getUserId()));
         return objTendMapper.insertObjTend(objTend);
     }

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

@@ -1,6 +1,9 @@
 package com.goldenwater.system.service.impl;
 
+import java.util.Date;
 import java.util.List;
+
+import com.goldenwater.common.utils.uuid.IdUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.goldenwater.common.core.domain.entity.RelEngOrg;
@@ -29,6 +32,8 @@ public class RelEngOrgServiceImpl implements IRelEngOrgService {
 
     @Override
     public int insertRelEngOrg(RelEngOrg relEngOrg) {
+        relEngOrg.setGuid(IdUtils.fastSimpleUUID());
+        relEngOrg.setFromDate(new Date());
         return relEngOrgMapper.insertRelEngOrg(relEngOrg);
     }
 

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

@@ -1,6 +1,9 @@
 package com.goldenwater.system.service.impl;
 
+import java.util.Date;
 import java.util.List;
+
+import com.goldenwater.common.utils.uuid.IdUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.goldenwater.common.core.domain.entity.RelEngOrgUwat;
@@ -30,6 +33,8 @@ public class RelEngOrgUwatServiceImpl implements IRelEngOrgUwatService
 
     @Override
     public int insertRelEngOrgUwat(RelEngOrgUwat relEngOrgUwat) {
+        relEngOrgUwat.setGuid(IdUtils.fastSimpleUUID());
+        relEngOrgUwat.setFromDate(new Date());
         return relEngOrgUwatMapper.insertRelEngOrgUwat(relEngOrgUwat);
     }
 

+ 14 - 5
gw-system/src/main/java/com/goldenwater/system/service/impl/RelProjOrgServiceImpl.java

@@ -1,11 +1,14 @@
 package com.goldenwater.system.service.impl;
 
-import java.util.List;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
 import com.goldenwater.common.core.domain.entity.RelProjOrg;
+import com.goldenwater.common.utils.uuid.IdUtils;
 import com.goldenwater.system.mapper.RelProjOrgMapper;
 import com.goldenwater.system.service.IRelProjOrgService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Date;
+import java.util.List;
 
 /**
  * 项目与机构关系表 服务实现
@@ -13,8 +16,7 @@ import com.goldenwater.system.service.IRelProjOrgService;
  * @author goldenwater
  */
 @Service
-public class RelProjOrgServiceImpl implements IRelProjOrgService
-{
+public class RelProjOrgServiceImpl implements IRelProjOrgService {
     @Autowired
     private RelProjOrgMapper relProjOrgMapper;
 
@@ -30,6 +32,8 @@ public class RelProjOrgServiceImpl implements IRelProjOrgService
 
     @Override
     public int insertRelProjOrg(RelProjOrg relProjOrg) {
+        relProjOrg.setGuid(IdUtils.fastSimpleUUID());
+        relProjOrg.setFromDate(new Date());
         return relProjOrgMapper.insertRelProjOrg(relProjOrg);
     }
 
@@ -47,4 +51,9 @@ public class RelProjOrgServiceImpl implements IRelProjOrgService
     public int deleteRelProjOrgByIds(String[] guids) {
         return relProjOrgMapper.deleteRelProjOrgByIds(guids);
     }
+
+    @Override
+    public int deleteRelProjOrgByProjGuid(String projGuid) {
+        return relProjOrgMapper.deleteRelProjOrgByProjGuid(projGuid);
+    }
 }

+ 7 - 0
gw-system/src/main/java/com/goldenwater/system/service/impl/RelTendOrgServiceImpl.java

@@ -1,6 +1,9 @@
 package com.goldenwater.system.service.impl;
 
+import java.util.Date;
 import java.util.List;
+
+import com.goldenwater.common.utils.uuid.IdUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.goldenwater.common.core.domain.entity.RelTendOrg;
@@ -36,6 +39,10 @@ public class RelTendOrgServiceImpl implements IRelTendOrgService
 
     @Override
     public int insertRelTendOrg(RelTendOrg relTendOrg) {
+        relTendOrg.setGuid(IdUtils.fastSimpleUUID());
+        if (relTendOrg.getFromDate() == null) {
+            relTendOrg.setFromDate(new Date());
+        }
         return relTendOrgMapper.insertRelTendOrg(relTendOrg);
     }
 

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

@@ -1,6 +1,9 @@
 package com.goldenwater.system.service.impl;
 
+import java.util.Date;
 import java.util.List;
+
+import com.goldenwater.common.utils.uuid.IdUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.goldenwater.common.core.domain.entity.RelUserTend;
@@ -30,6 +33,8 @@ public class RelUserTendServiceImpl implements IRelUserTendService
 
     @Override
     public int insertRelUserTend(RelUserTend relUserTend) {
+        relUserTend.setGuid(IdUtils.fastSimpleUUID());
+        relUserTend.setFromDate(new Date());
         return relUserTendMapper.insertRelUserTend(relUserTend);
     }
 

+ 6 - 0
gw-system/src/main/resources/mapper/system/RelEngOrgUwatMapper.xml

@@ -34,15 +34,21 @@
 
     <insert id="insertRelEngOrgUwat" parameterType="RelEngOrgUwat">
         insert into REL_ENG_ORG_UWAT(
+        <trim suffixOverrides=",">
+            GUID,
             <if test="engGuid != null">ENG_GUID,</if>
             <if test="orgUwatGuid != null">ORG_UWAT_GUID,</if>
             <if test="fromDate != null">FROM_DATE,</if>
             <if test="toDate != null">TO_DATE</if>
+        </trim>
         )values(
+        <trim suffixOverrides=",">
+            #{guid},
             <if test="engGuid != null">#{engGuid},</if>
             <if test="orgUwatGuid != null">#{orgUwatGuid},</if>
             <if test="fromDate != null">#{fromDate},</if>
             <if test="toDate != null">#{toDate}</if>
+        </trim>
         )
     </insert>
 

+ 10 - 0
gw-system/src/main/resources/mapper/system/RelProjOrgMapper.xml

@@ -34,15 +34,21 @@
 
     <insert id="insertRelProjOrg" parameterType="RelProjOrg">
         insert into REL_PROJ_ORG(
+        <trim suffixOverrides=",">
+            GUID,
             <if test="projGuid != null">PROJ_GUID,</if>
             <if test="orgGuid != null">ORG_GUID,</if>
             <if test="fromDate != null">FROM_DATE,</if>
             <if test="toDate != null">TO_DATE</if>
+        </trim>
         )values(
+        <trim suffixOverrides=",">
+            #{guid},
             <if test="projGuid != null">#{projGuid},</if>
             <if test="orgGuid != null">#{orgGuid},</if>
             <if test="fromDate != null">#{fromDate},</if>
             <if test="toDate != null">#{toDate}</if>
+        </trim>
         )
     </insert>
 
@@ -68,4 +74,8 @@
         </foreach>
     </delete>
 
+    <delete id="deleteRelProjOrgByProjGuid" parameterType="String">
+        delete from REL_PROJ_ORG where PROJ_GUID = #{projGuid}
+    </delete>
+
 </mapper>

+ 9 - 1
gw-system/src/main/resources/mapper/system/RelTendOrgMapper.xml

@@ -35,7 +35,9 @@
     <!-- 融合查询:标段关系 + 参建单位名称,按 tendGuid 精确匹配 -->
     <select id="selectRelTendOrgDetailList" parameterType="RelTendOrg" resultType="com.goldenwater.common.core.domain.vo.RelTendOrgDetailVO">
         select r.GUID, r.TEND_GUID, r.ORG_UWAT_GUID, r.FROM_DATE, r.TO_DATE,
-               u.ORG_NAME as org_name
+               u.ORG_NAME as org_name,
+               u.ORG_CODE as org_code,
+               u.ORG_TYPE as org_type
         from REL_TEND_ORG r
         left join ATT_ORG_UWAT_BASE u on u.GUID = r.ORG_UWAT_GUID
         <where>
@@ -47,15 +49,21 @@
 
     <insert id="insertRelTendOrg" parameterType="RelTendOrg">
         insert into REL_TEND_ORG(
+        <trim suffixOverrides=",">
+            GUID,
             <if test="tendGuid != null">TEND_GUID,</if>
             <if test="orgUwatGuid != null">ORG_UWAT_GUID,</if>
             <if test="fromDate != null">FROM_DATE,</if>
             <if test="toDate != null">TO_DATE</if>
+        </trim>
         )values(
+        <trim suffixOverrides=",">
+            #{guid},
             <if test="tendGuid != null">#{tendGuid},</if>
             <if test="orgUwatGuid != null">#{orgUwatGuid},</if>
             <if test="fromDate != null">#{fromDate},</if>
             <if test="toDate != null">#{toDate}</if>
+        </trim>
         )
     </insert>
 

+ 6 - 0
gw-system/src/main/resources/mapper/system/RelUserTendMapper.xml

@@ -34,15 +34,21 @@
 
     <insert id="insertRelUserTend" parameterType="RelUserTend">
         insert into REL_USER_TEND(
+        <trim suffixOverrides=",">
+            GUID,
             <if test="userGuid != null">USER_GUID,</if>
             <if test="tendGuid != null">TEND_GUID,</if>
             <if test="fromDate != null">FROM_DATE,</if>
             <if test="toDate != null">TO_DATE</if>
+        </trim>
         )values(
+        <trim suffixOverrides=",">
+            #{guid},
             <if test="userGuid != null">#{userGuid},</if>
             <if test="tendGuid != null">#{tendGuid},</if>
             <if test="fromDate != null">#{fromDate},</if>
             <if test="toDate != null">#{toDate}</if>
+        </trim>
         )
     </insert>
 

+ 42 - 0
gw-ui/src/components/CoordPicker/index.vue

@@ -0,0 +1,42 @@
+<template>
+  <div class="coord-picker-btn">
+    <el-button icon="MapLocation" type="text" @click="openPicker">点击获取经纬度</el-button>
+
+    <el-dialog v-model="visible" title="选取经纬度" width="700px" append-to-body @closed="onClosed">
+      <TiandituMapPicker v-model="coords" :height="400"/>
+      <template #footer>
+        <el-button type="primary" @click="confirm">确 定</el-button>
+        <el-button @click="visible = false">取 消</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import TiandituMapPicker from '@/components/TiandituMapPicker'
+
+const props = defineProps({
+  modelValue: { type: Array, default: null }
+})
+
+const emit = defineEmits(['update:modelValue'])
+
+const visible = ref(false)
+const coords = ref(null)
+
+function openPicker() {
+  coords.value = props.modelValue ? [...props.modelValue] : null
+  visible.value = true
+}
+
+function confirm() {
+  if (coords.value && coords.value[0] != null && coords.value[1] != null) {
+    emit('update:modelValue', [...coords.value])
+  }
+  visible.value = false
+}
+
+function onClosed() {
+  coords.value = null
+}
+</script>

+ 71 - 0
gw-ui/src/components/EngSelect/index.vue

@@ -0,0 +1,71 @@
+<template>
+  <el-form-item
+    :label="label"
+    :prop="prop"
+    :rules="required ? [{ required: true, message: label + '不能为空', trigger: 'change' }] : undefined"
+  >
+    <el-select
+      :model-value="modelValue"
+      filterable
+      remote
+      clearable
+      reserve-keyword
+      :remote-method="remoteSearch"
+      :loading="loading"
+      :disabled="disabled"
+      :placeholder="placeholder"
+      style="width: 100%"
+      @update:model-value="handleChange"
+    >
+      <el-option
+        v-for="item in options"
+        :key="item.value"
+        :label="item.label"
+        :value="item.value"
+      />
+    </el-select>
+  </el-form-item>
+</template>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { listEngBase, getEngBase } from '@/api/slaj/eng'
+
+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 }
+})
+
+const emit = defineEmits(['update:modelValue'])
+
+const options = ref([])
+const loading = ref(false)
+
+function normalize(rows) {
+  return (rows || []).map(r => ({ value: r.guid, label: r.engName }))
+}
+
+function remoteSearch(query) {
+  if (!query) { options.value = []; return }
+  loading.value = true
+  listEngBase({ engName: query, pageNum: 1, pageSize: 20 })
+    .then(res => { options.value = normalize(res.rows) })
+    .finally(() => { loading.value = false })
+}
+
+function handleChange(val) { emit('update:modelValue', val) }
+
+// 编辑回显:modelValue 变化时,若不在 options 中则回填
+watch(() => props.modelValue, (val) => {
+  if (val && !options.value.some(o => o.value === val)) {
+    getEngBase(val).then(res => {
+      const d = res.data
+      if (d && d.guid) { options.value = [{ value: d.guid, label: d.engName }, ...options.value] }
+    }).catch(() => {})
+  }
+}, { immediate: true })
+</script>

+ 71 - 0
gw-ui/src/components/ProjSelect/index.vue

@@ -0,0 +1,71 @@
+<template>
+  <el-form-item
+    :label="label"
+    :prop="prop"
+    :rules="required ? [{ required: true, message: label + '不能为空', trigger: 'change' }] : undefined"
+  >
+    <el-select
+      :model-value="modelValue"
+      filterable
+      remote
+      clearable
+      reserve-keyword
+      :remote-method="remoteSearch"
+      :loading="loading"
+      :disabled="disabled"
+      :placeholder="placeholder"
+      style="width: 100%"
+      @update:model-value="handleChange"
+    >
+      <el-option
+        v-for="item in options"
+        :key="item.value"
+        :label="item.label"
+        :value="item.value"
+      />
+    </el-select>
+  </el-form-item>
+</template>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { listAttProjBase, getAttProjBase } from '@/api/system/attProjBase'
+
+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 }
+})
+
+const emit = defineEmits(['update:modelValue'])
+
+const options = ref([])
+const loading = ref(false)
+
+function normalize(rows) {
+  return (rows || []).map(r => ({ value: r.guid, label: r.projName }))
+}
+
+function remoteSearch(query) {
+  if (!query) { options.value = []; return }
+  loading.value = true
+  listAttProjBase({ projName: query, pageNum: 1, pageSize: 20 })
+    .then(res => { options.value = normalize(res.rows) })
+    .finally(() => { loading.value = false })
+}
+
+function handleChange(val) { emit('update:modelValue', val) }
+
+// 编辑回显:modelValue 变化时,若不在 options 中则回填
+watch(() => props.modelValue, (val) => {
+  if (val && !options.value.some(o => o.value === val)) {
+    getAttProjBase(val).then(res => {
+      const d = res.data
+      if (d && d.guid) { options.value = [{ value: d.guid, label: d.projName }, ...options.value] }
+    }).catch(() => {})
+  }
+}, { immediate: true })
+</script>

+ 3 - 0
gw-ui/src/main.js

@@ -45,6 +45,8 @@ import ImagePreview from "@/components/ImagePreview"
 import DictTag from '@/components/DictTag'
 // 天地图选点组件
 import TiandituMapPicker from '@/components/TiandituMapPicker'
+// 经纬度填报组件(输入框+弹窗选点)
+import CoordPicker from '@/components/CoordPicker'
 
 const app = createApp(App)
 
@@ -68,6 +70,7 @@ app.component('ImagePreview', ImagePreview)
 app.component('RightToolbar', RightToolbar)
 app.component('Editor', Editor)
 app.component('TiandituMapPicker', TiandituMapPicker)
+app.component('CoordPicker', CoordPicker)
 
 app.use(router)
 app.use(store)

+ 13 - 5
gw-ui/src/views/slaj/eng/attengcws/index.vue

@@ -78,7 +78,7 @@
     <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
                 @pagination="getList"/>
     <el-dialog :title="title" v-model="open" width="750px" append-to-body class="eng-edit-dialog">
-      <el-form ref="formRef" :model="form" :rules="rules" label-width="140px">
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
         <el-tabs v-model="activeTab">
         <el-tab-pane label="基本信息" name="basic">
         <el-row>
@@ -108,11 +108,19 @@
           </el-col>
         </el-row>
         <el-row>
-          <el-col :span="24">
-            <el-form-item label="点位坐标">
-              <TiandituMapPicker v-model="mapCoords" :height="300"/>
+          <el-col :span="8">
+            <el-form-item label="经度(°)" prop="cenLong">
+              <el-input v-model="form.cenLong" placeholder="请输入经度"/>
             </el-form-item>
           </el-col>
+          <el-col :span="8">
+            <el-form-item label="纬度(°)" prop="cenLat">
+              <el-input v-model="form.cenLat" placeholder="请输入纬度"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+              <CoordPicker style="margin-left: 10px;" v-model="mapCoords"/>
+          </el-col>
         </el-row>
         <el-row>
           <el-col :span="12">
@@ -229,7 +237,7 @@
   </div>
 </template>
 <script setup>
-import {addAttEngCws, delAttEngCws, getAttEngCws, listAttEngCws, updateAttEngCws} from "@/api/slaj/eng"
+import { addAttEngCws, delAttEngCws, getAttEngCws, listAttEngCws, updateAttEngCws } from "@/api/slaj/eng"
 
 const {proxy} = getCurrentInstance()
 const {

+ 9 - 3
gw-ui/src/views/slaj/eng/attengdike/index.vue

@@ -44,7 +44,7 @@
     </el-table>
     <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
     <el-dialog :title="title" v-model="open" width="750px" append-to-body class="eng-edit-dialog">
-      <el-form ref="formRef" :model="form" :rules="rules" label-width="140px">
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
         <el-tabs v-model="activeTab">
         <el-tab-pane label="基本信息" name="basic">
         <el-row>
@@ -67,8 +67,14 @@
             <el-col :span="12"><el-form-item label="终点位置" prop="endLoc"><el-input v-model="form.endLoc" placeholder="请输入" /></el-form-item></el-col>
           </el-row>
           <el-row>
-            <el-col :span="24"><el-form-item label="起点坐标"><TiandituMapPicker v-model="startCoords" :height="300"/></el-form-item></el-col>
-            <el-col :span="24"><el-form-item label="终点坐标"><TiandituMapPicker v-model="endCoords" :height="300"/></el-form-item></el-col>
+            <el-col :span="8"><el-form-item label="起点经度(°)" prop="startLong"><el-input v-model="form.startLong" placeholder="请输入经度"/></el-form-item></el-col>
+            <el-col :span="8"><el-form-item label="起点纬度(°)" prop="startLat"><el-input v-model="form.startLat" placeholder="请输入纬度"/></el-form-item></el-col>
+            <el-col :span="8"><CoordPicker style="margin-left: 10px;" v-model="startCoords"/></el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="8"><el-form-item label="终点经度(°)" prop="endLong"><el-input v-model="form.endLong" placeholder="请输入经度"/></el-form-item></el-col>
+            <el-col :span="8"><el-form-item label="终点纬度(°)" prop="endLat"><el-input v-model="form.endLat" placeholder="请输入纬度"/></el-form-item></el-col>
+            <el-col :span="8"><CoordPicker style="margin-left: 10px;" v-model="endCoords"/></el-col>
           </el-row>
         </el-tab-pane>
         <el-tab-pane label="堤防参数" name="dike">

+ 10 - 2
gw-ui/src/views/slaj/eng/attenghyst/index.vue

@@ -47,7 +47,7 @@
     </el-table>
     <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
     <el-dialog :title="title" v-model="open" width="750px" append-to-body class="eng-edit-dialog">
-      <el-form ref="formRef" :model="form" :rules="rules" label-width="140px">
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
         <el-tabs v-model="activeTab">
         <el-tab-pane label="基本信息" name="basic">
         <el-row>
@@ -59,7 +59,15 @@
           <el-col :span="12"><el-form-item label="重要程度" prop="impoGrad"><el-select v-model="form.impoGrad" placeholder="请选择" style="width:100%"><el-option v-for="d in slaj_impo_grad" :key="d.value" :label="d.label" :value="d.value" /></el-select></el-form-item></el-col>
         </el-row>
         <el-row>
-          <el-col :span="24"><el-form-item label="点位坐标"><TiandituMapPicker v-model="mapCoords" :height="300"/></el-form-item></el-col>
+          <el-col :span="8"><el-form-item label="中心经度(°)" prop="cenLong">
+                <el-input v-model="form.cenLong" placeholder="请输入经度"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8"><el-form-item label="中心纬度(°)" prop="cenLat">
+                <el-input v-model="form.cenLat" placeholder="请输入纬度"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8"><CoordPicker style="margin-left: 10px;" v-model="mapCoords"/></el-col>
         </el-row>
         <el-row>
           <el-col :span="12"><el-form-item label="批复投资(万元)" prop="apprBudg"><el-input v-model="form.apprBudg" placeholder="请输入" /></el-form-item></el-col>

+ 13 - 1
gw-ui/src/views/slaj/eng/attengirr/index.vue

@@ -100,10 +100,22 @@
                 </el-form-item>
               </el-col>
             </el-row>
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="中心经度(°)" prop="cenLong">
+                  <el-input v-model="form.cenLong" placeholder="请输入经度"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="中心纬度(°)" prop="cenLat">
+                  <el-input v-model="form.cenLat" placeholder="请输入纬度"/>
+                </el-form-item>
+              </el-col>
+            </el-row>
             <el-row>
               <el-col :span="24">
                 <el-form-item label="点位坐标">
-                  <TiandituMapPicker v-model="mapCoords" :height="300"/>
+                  <CoordPicker v-model="mapCoords"/>
                 </el-form-item>
               </el-col>
             </el-row>

+ 11 - 1
gw-ui/src/views/slaj/eng/attengothe/index.vue

@@ -50,7 +50,17 @@
           <el-col :span="12"><el-form-item label="重要程度" prop="impoGrad"><el-select v-model="form.impoGrad" placeholder="请选择" style="width:100%"><el-option v-for="d in slaj_impo_grad" :key="d.value" :label="d.label" :value="d.value" /></el-select></el-form-item></el-col>
         </el-row>
         <el-row>
-          <el-col :span="24"><el-form-item label="点位坐标"><TiandituMapPicker v-model="mapCoords" :height="300"/></el-form-item></el-col>
+          <el-col :span="12"><el-form-item label="中心经度(°)" prop="cenLong">
+                <el-input v-model="form.cenLong" placeholder="请输入经度"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12"><el-form-item label="中心纬度(°)" prop="cenLat">
+                <el-input v-model="form.cenLat" placeholder="请输入纬度"/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24"><el-form-item label="点位坐标"><CoordPicker v-model="mapCoords"/></el-form-item></el-col>
         </el-row>
         <el-row>
           <el-col :span="12"><el-form-item label="批复投资(万元)" prop="apprBudg"><el-input v-model="form.apprBudg" placeholder="请输入" /></el-form-item></el-col>

+ 11 - 1
gw-ui/src/views/slaj/eng/attengpust/index.vue

@@ -52,7 +52,17 @@
           <el-col :span="12"><el-form-item label="重要程度" prop="impoGrad"><el-select v-model="form.impoGrad" placeholder="请选择" style="width:100%"><el-option v-for="d in slaj_impo_grad" :key="d.value" :label="d.label" :value="d.value" /></el-select></el-form-item></el-col>
         </el-row>
         <el-row>
-          <el-col :span="24"><el-form-item label="点位坐标"><TiandituMapPicker v-model="mapCoords" :height="300"/></el-form-item></el-col>
+          <el-col :span="12"><el-form-item label="中心经度(°)" prop="cenLong">
+                <el-input v-model="form.cenLong" placeholder="请输入经度"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12"><el-form-item label="中心纬度(°)" prop="cenLat">
+                <el-input v-model="form.cenLat" placeholder="请输入纬度"/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24"><el-form-item label="点位坐标"><CoordPicker v-model="mapCoords"/></el-form-item></el-col>
         </el-row>
         <el-row>
           <el-col :span="12"><el-form-item label="批复投资(万元)" prop="apprBudg"><el-input v-model="form.apprBudg" placeholder="请输入" /></el-form-item></el-col>

+ 13 - 5
gw-ui/src/views/slaj/eng/attengres/index.vue

@@ -80,7 +80,7 @@
     <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
                 @pagination="getList"/>
     <el-dialog :title="title" v-model="open" width="750px" append-to-body class="eng-edit-dialog">
-      <el-form ref="formRef" :model="form" :rules="rules" label-width="140px">
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
         <el-tabs v-model="activeTab">
         <el-tab-pane label="基本信息" name="basic">
         <el-row>
@@ -110,11 +110,19 @@
           </el-col>
         </el-row>
         <el-row>
-          <el-col :span="24">
-            <el-form-item label="点位坐标">
-              <TiandituMapPicker v-model="mapCoords" :height="300"/>
+          <el-col :span="8">
+            <el-form-item label="经度(°)" prop="cenLong">
+              <el-input v-model="form.cenLong" placeholder="请输入经度"/>
             </el-form-item>
           </el-col>
+          <el-col :span="8">
+            <el-form-item label="纬度(°)" prop="cenLat">
+              <el-input v-model="form.cenLat" placeholder="请输入纬度"/>
+            </el-form-item>
+          </el-col>
+          <el-col :span="4">
+              <CoordPicker style="margin-left: 10px;" v-model="mapCoords"/>
+          </el-col>
         </el-row>
         <el-row>
           <el-col :span="12">
@@ -291,7 +299,7 @@
   </div>
 </template>
 <script setup>
-import {addAttEngRes, delAttEngRes, getAttEngRes, listAttEngRes, updateAttEngRes} from "@/api/slaj/eng"
+import { addAttEngRes, delAttEngRes, getAttEngRes, listAttEngRes, updateAttEngRes } from "@/api/slaj/eng"
 
 const {proxy} = getCurrentInstance()
 const {

+ 11 - 1
gw-ui/src/views/slaj/eng/attengsd/index.vue

@@ -51,7 +51,17 @@
           <el-col :span="12"><el-form-item label="重要程度" prop="impoGrad"><el-select v-model="form.impoGrad" placeholder="请选择" style="width:100%"><el-option v-for="d in slaj_impo_grad" :key="d.value" :label="d.label" :value="d.value" /></el-select></el-form-item></el-col>
         </el-row>
         <el-row>
-          <el-col :span="24"><el-form-item label="点位坐标"><TiandituMapPicker v-model="mapCoords" :height="300"/></el-form-item></el-col>
+          <el-col :span="12"><el-form-item label="中心经度(°)" prop="cenLong">
+                <el-input v-model="form.cenLong" placeholder="请输入经度"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12"><el-form-item label="中心纬度(°)" prop="cenLat">
+                <el-input v-model="form.cenLat" placeholder="请输入纬度"/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24"><el-form-item label="点位坐标"><CoordPicker v-model="mapCoords"/></el-form-item></el-col>
         </el-row>
         <el-row>
           <el-col :span="12"><el-form-item label="批复投资(万元)" prop="apprBudg"><el-input v-model="form.apprBudg" placeholder="请输入" /></el-form-item></el-col>

+ 26 - 2
gw-ui/src/views/slaj/eng/attengwadi/index.vue

@@ -86,17 +86,41 @@
                 </el-form-item>
               </el-col>
             </el-row>
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="起点经度(°)" prop="startLong">
+                  <el-input v-model="form.startLong" placeholder="请输入经度"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="起点纬度(°)" prop="startLat">
+                  <el-input v-model="form.startLat" placeholder="请输入纬度"/>
+                </el-form-item>
+              </el-col>
+            </el-row>
             <el-row>
               <el-col :span="24">
                 <el-form-item label="起点坐标">
-                  <TiandituMapPicker v-model="startCoords" :height="300"/>
+                  <CoordPicker v-model="startCoords"/>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row>
+              <el-col :span="12">
+                <el-form-item label="终点经度(°)" prop="endLong">
+                  <el-input v-model="form.endLong" placeholder="请输入经度"/>
+                </el-form-item>
+              </el-col>
+              <el-col :span="12">
+                <el-form-item label="终点纬度(°)" prop="endLat">
+                  <el-input v-model="form.endLat" placeholder="请输入纬度"/>
                 </el-form-item>
               </el-col>
             </el-row>
             <el-row>
               <el-col :span="24">
                 <el-form-item label="终点坐标">
-                  <TiandituMapPicker v-model="endCoords" :height="300"/>
+                  <CoordPicker v-model="endCoords"/>
                 </el-form-item>
               </el-col>
             </el-row>

+ 11 - 1
gw-ui/src/views/slaj/eng/attengwaga/index.vue

@@ -51,7 +51,17 @@
           <el-col :span="12"><el-form-item label="重要程度" prop="impoGrad"><el-select v-model="form.impoGrad" placeholder="请选择" style="width:100%"><el-option v-for="d in slaj_impo_grad" :key="d.value" :label="d.label" :value="d.value" /></el-select></el-form-item></el-col>
         </el-row>
         <el-row>
-          <el-col :span="24"><el-form-item label="点位坐标"><TiandituMapPicker v-model="mapCoords" :height="300"/></el-form-item></el-col>
+          <el-col :span="12"><el-form-item label="中心经度(°)" prop="cenLong">
+                <el-input v-model="form.cenLong" placeholder="请输入经度"/>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12"><el-form-item label="中心纬度(°)" prop="cenLat">
+                <el-input v-model="form.cenLat" placeholder="请输入纬度"/>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="24"><el-form-item label="点位坐标"><CoordPicker v-model="mapCoords"/></el-form-item></el-col>
         </el-row>
         <el-row>
           <el-col :span="12"><el-form-item label="批复投资(万元)" prop="apprBudg"><el-input v-model="form.apprBudg" placeholder="请输入" /></el-form-item></el-col>

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

@@ -63,7 +63,7 @@
          <el-form ref="formRef" :model="form" :rules="rules" label-width="130px">
             <el-row>
                <!-- 上级机构放最上面,不填即为顶级机构 -->
-               <el-col :span="12">
+               <el-col :span="24">
                   <OrgSelect v-model="form.proOrgGuid" label="上级机构" placeholder="请输入机构名称搜索(不填即为顶级机构)" />
                </el-col>
                <el-col :span="12">
@@ -76,38 +76,15 @@
                      <el-input v-model="form.orgCode" placeholder="请输入机构代码" />
                   </el-form-item>
                </el-col>
-               <el-col :span="12">
-                  <el-form-item label="负责人" prop="leader">
-                     <el-input v-model="form.leader" placeholder="请输入负责人" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="联系电话" prop="phone">
-                     <el-input v-model="form.phone" placeholder="请输入联系电话" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="邮箱" prop="email">
-                     <el-input v-model="form.email" placeholder="请输入邮箱" />
-                  </el-form-item>
-               </el-col>
-               <el-col :span="12">
-                  <el-form-item label="状态" prop="status">
-                     <el-select v-model="form.status" placeholder="请选择状态" style="width:100%">
-                        <el-option label="正常" value="0" />
-                        <el-option label="停用" value="1" />
-                     </el-select>
-                  </el-form-item>
-               </el-col>
                <el-col :span="12">
                   <el-form-item label="社会信用代码" prop="socCreCode">
                      <el-input v-model="form.socCreCode" placeholder="请输入社会信用代码" />
                   </el-form-item>
                </el-col>
-               <el-col :span="12">
-                  <el-form-item label="单位类型(客户端)" prop="orgClienType">
-                     <el-select v-model="form.orgClienType" placeholder="请选择单位类型(客户端)" style="width:100%">
-                        <el-option v-for="dict in slaj_org_clien_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+                              <el-col :span="12">
+                  <el-form-item label="单位规格" prop="orgLevel">
+                     <el-select v-model="form.orgLevel" placeholder="请选择单位规格" style="width:100%">
+                        <el-option v-for="dict in slaj_org_level" :key="dict.value" :label="dict.label" :value="dict.value" />
                      </el-select>
                   </el-form-item>
                </el-col>
@@ -119,9 +96,9 @@
                   </el-form-item>
                </el-col>
                <el-col :span="12">
-                  <el-form-item label="单位规格" prop="orgLevel">
-                     <el-select v-model="form.orgLevel" placeholder="请选择单位规格" style="width:100%">
-                        <el-option v-for="dict in slaj_org_level" :key="dict.value" :label="dict.label" :value="dict.value" />
+                  <el-form-item label="单位类型(客户端)" prop="orgClienType">
+                     <el-select v-model="form.orgClienType" placeholder="请选择单位类型(客户端)" style="width:100%">
+                        <el-option v-for="dict in slaj_org_clien_type" :key="dict.value" :label="dict.label" :value="dict.value" />
                      </el-select>
                   </el-form-item>
                </el-col>
@@ -166,6 +143,29 @@
                   <el-form-item label="注册地址" prop="regLoc">
                      <el-input v-model="form.regLoc" placeholder="请输入注册地址" />
                   </el-form-item>
+               </el-col>
+                 <el-col :span="12">
+                  <el-form-item label="负责人" prop="leader">
+                     <el-input v-model="form.leader" placeholder="请输入负责人" />
+                  </el-form-item>
+               </el-col>
+               <el-col :span="12">
+                  <el-form-item label="联系电话" prop="phone">
+                     <el-input v-model="form.phone" placeholder="请输入联系电话" />
+                  </el-form-item>
+               </el-col>
+               <el-col :span="12">
+                  <el-form-item label="邮箱" prop="email">
+                     <el-input v-model="form.email" placeholder="请输入邮箱" />
+                  </el-form-item>
+               </el-col>
+               <el-col :span="12">
+                  <el-form-item label="状态" prop="status">
+                     <el-select v-model="form.status" placeholder="请选择状态" style="width:100%">
+                        <el-option label="正常" value="0" />
+                        <el-option label="停用" value="1" />
+                     </el-select>
+                  </el-form-item>
                </el-col>
                <el-col :span="24">
                   <el-form-item label="备注" prop="note">

+ 86 - 49
gw-ui/src/views/system/projbase/eng/index.vue

@@ -1,43 +1,40 @@
 <template>
   <div ref="containerRef" class="app-container">
-    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="80px" class="search-form">
-      <div class="search-form-left">
-        <el-form-item label="工程名称" prop="engName">
-          <el-input v-model="queryParams.engName" placeholder="请输入工程名称" clearable @keyup.enter="handleQuery"/>
+    <!-- 顶部信息栏 -->
+    <div class="top-bar">
+      <el-alert v-if="projName" :title="'当前项目:' + projName" type="info" :closable="false" class="proj-alert"/>
+      <el-button icon="Back" @click="goBack">返回项目列表</el-button>
+    </div>
+
+    <!-- 工程列表 -->
+    <div class="search-bar">
+      <el-form :model="queryParams" :inline="true" @submit.prevent>
+        <el-form-item label="工程名称">
+          <el-input v-model="queryParams.engName" placeholder="工程名称" clearable style="width:160px"
+                    @keyup.enter="handleQuery"/>
         </el-form-item>
         <el-form-item>
           <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
           <el-button icon="Refresh" @click="resetQuery">重置</el-button>
         </el-form-item>
-      </div>
-      <div class="search-form-right">
-        <el-button type="warning" plain icon="Link" @click="handleEngLink">关联工程</el-button>
-        <el-button icon="Back" @click="goBack">返回项目列表</el-button>
-      </div>
-    </el-form>
-
-    <el-alert v-if="projName" :title="'当前项目:' + projName" type="info" :closable="false" class="proj-alert"/>
+        <el-form-item>
+          <el-button type="warning" plain icon="Link" @click="handleEngLink"
+                     v-hasPermi="['business:projbase:edit']">关联工程</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
 
     <div class="table-wrapper">
       <el-table :height="tableHeight" v-loading="loading" :data="engList">
         <el-table-column label="工程编码" align="center" prop="engCode" :show-overflow-tooltip="true"/>
         <el-table-column label="工程名称" align="center" prop="engName" :show-overflow-tooltip="true"/>
         <el-table-column label="工程类型" align="center" prop="engType" :show-overflow-tooltip="true"/>
-        <el-table-column label="工程规模" align="center" prop="engScal" :show-overflow-tooltip="true"/>
-        <el-table-column label="开工日期" align="center" prop="startDate" :show-overflow-tooltip="true"/>
-        <el-table-column label="备注" align="center" prop="note" :show-overflow-tooltip="true"/>
-
-        <el-table-column label="操作" align="center" width="120">
-          <template #default="scope">
-            <el-button link type="primary" icon="Tickets" @click="handleViewTend(scope.row)">标段</el-button>
-          </template>
-        </el-table-column>
       </el-table>
     </div>
+    <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum"
+                v-model:limit="queryParams.pageSize" @pagination="getList"/>
 
-    <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList"/>
-
-    <!-- 关联工程 Dialog -->
+    <!-- ====== 关联工程 Dialog ====== -->
     <el-dialog title="关联工程" v-model="engLinkOpen" width="800px" append-to-body :close-on-click-modal="false">
       <el-form :model="linkParams" :inline="true" @submit.prevent>
         <el-form-item label="工程编码">
@@ -48,11 +45,16 @@
         </el-form-item>
         <el-form-item label="工程类型">
           <el-select v-model="linkParams.engType" placeholder="请选择" clearable style="width:120px">
-            <el-option label="水库" value="01"/><el-option label="水闸" value="02"/>
-            <el-option label="泵站" value="03"/><el-option label="水电站" value="04"/>
-            <el-option label="堤防" value="05"/><el-option label="灌区" value="06"/>
-            <el-option label="引调水" value="07"/><el-option label="淤地坝" value="08"/>
-            <el-option label="农村供水" value="09"/><el-option label="其他" value="10"/>
+            <el-option label="水库" value="01"/>
+            <el-option label="水闸" value="02"/>
+            <el-option label="泵站" value="03"/>
+            <el-option label="水电站" value="04"/>
+            <el-option label="堤防" value="05"/>
+            <el-option label="灌区" value="06"/>
+            <el-option label="引调水" value="07"/>
+            <el-option label="淤地坝" value="08"/>
+            <el-option label="农村供水" value="09"/>
+            <el-option label="其他" value="10"/>
             <el-option label="农村小水电" value="11"/>
           </el-select>
         </el-form-item>
@@ -61,15 +63,19 @@
           <el-button icon="Refresh" @click="resetLinkParams">重置</el-button>
         </el-form-item>
       </el-form>
-      <el-table :data="linkEngList" @selection-change="handleLinkSelection" ref="linkTableRef" max-height="360" style="margin-top:12px">
+      <el-table :data="linkEngList" @selection-change="handleLinkSelection" ref="linkTableRef" max-height="360"
+                style="margin-top:12px">
         <el-table-column type="selection" width="50"/>
         <el-table-column label="工程编码" prop="engCode"/>
         <el-table-column label="工程名称" prop="engName" :show-overflow-tooltip="true"/>
         <el-table-column label="工程类型" prop="engType" width="100"/>
       </el-table>
-      <pagination v-show="linkTotal>0" :total="linkTotal" v-model:page="linkParams.pageNum" v-model:limit="linkParams.pageSize" @pagination="searchEngLink" />
+      <pagination v-show="linkTotal>0" :total="linkTotal" v-model:page="linkParams.pageNum"
+                  v-model:limit="linkParams.pageSize" @pagination="searchEngLink"/>
       <template #footer>
-        <el-button type="primary" @click="submitEngLink" :disabled="linkSelected.length===0">关联选中工程 ({{ linkSelected.length }})</el-button>
+        <el-button type="primary" @click="submitEngLink" :disabled="linkSelected.length===0">关联选中工程
+          ({{ linkSelected.length }})
+        </el-button>
         <el-button @click="engLinkOpen=false">取消</el-button>
       </template>
     </el-dialog>
@@ -78,7 +84,8 @@
 
 <script setup name="ProjBaseEng">
 import { useRoute } from 'vue-router'
-import { listEngBase, updateEngBase, listObjEng } from "@/api/slaj/eng"
+import { listEngBase } from "@/api/slaj/eng"
+import { addRelProjOrg } from "@/api/system/relProjOrg"
 import { getAttProjBase } from "@/api/system/attProjBase"
 import { useTableHeight } from '@/hooks/useTableHeight'
 
@@ -89,9 +96,9 @@ const route = useRoute()
 const projGuid = ref(route.params.projGuid)
 const projName = ref("")
 
+// ---- 工程列表 ----
 const engList = ref([])
 const loading = ref(true)
-const showSearch = ref(true)
 const total = ref(0)
 
 const data = reactive({
@@ -121,16 +128,21 @@ function getList() {
   })
 }
 
-function handleQuery() { queryParams.value.pageNum = 1; getList() }
-function resetQuery() { proxy.resetForm("queryRef"); handleQuery() }
+function handleQuery() {
+  queryParams.value.pageNum = 1
+  getList()
+}
 
-function handleViewTend(row) {
-  proxy.$router.push('/system/projbase-tend/index/' + projGuid.value + '?engGuid=' + (row.engGuid || row.guid))
+function resetQuery() {
+  queryParams.value.engName = undefined
+  handleQuery()
 }
 
-function goBack() { proxy.$router.back() }
+function goBack() {
+  proxy.$router.back()
+}
 
-// ====== 关联工程(多选列表) ======
+// ---- 关联工程(多选列表) ----
 const engLinkOpen = ref(false)
 const linkTableRef = ref(null)
 const linkEngList = ref([])
@@ -146,26 +158,38 @@ function handleEngLink() {
 }
 
 function resetLinkParams() {
-  linkParams.engCode = undefined; linkParams.engName = undefined; linkParams.engType = undefined
+  linkParams.engCode = undefined
+  linkParams.engName = undefined
+  linkParams.engType = undefined
   linkParams.pageNum = 1
 }
 
 function searchEngLink() {
-  listObjEng({ ...linkParams, pageNum: linkParams.pageNum, pageSize: linkParams.pageSize }).then(res => {
+  listEngBase({ ...linkParams, pageNum: linkParams.pageNum, pageSize: linkParams.pageSize }).then(res => {
     linkEngList.value = res.rows || []
     linkTotal.value = res.total || 0
   })
 }
 
-function handleLinkSelection(sel) { linkSelected.value = sel }
+function handleLinkSelection(sel) {
+  linkSelected.value = sel
+}
 
 function submitEngLink() {
-  if (linkSelected.value.length === 0) { proxy.$modal.msgWarning("请至少选择一个工程"); return }
-  const tasks = linkSelected.value.map(e => updateEngBase({ guid: e.guid, projGuid: projGuid.value }))
+  if (linkSelected.value.length === 0) {
+    proxy.$modal.msgWarning("请至少选择一个工程")
+    return
+  }
+  const tasks = linkSelected.value.map(e => addRelProjOrg({
+    projGuid: projGuid.value,
+    orgGuid: e.guid
+  }))
   Promise.all(tasks).then(() => {
     proxy.$modal.msgSuccess(`成功关联 ${linkSelected.value.length} 个工程`)
     engLinkOpen.value = false
     getList()
+  }).catch(() => {
+    proxy.$modal.msgError("关联失败,可能已存在关联关系")
   })
 }
 
@@ -174,8 +198,21 @@ getList()
 </script>
 
 <style scoped>
-.search-form { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; }
-.search-form-left { display: flex; align-items: center; flex-wrap: wrap; flex: 1; }
-.search-form-right { display: flex; align-items: center; gap: 6px; white-space: nowrap; flex-shrink: 0; }
-.proj-alert { margin-bottom: 12px; }
+/* 顶部信息栏 */
+.top-bar {
+  display: flex;
+  align-items: center;
+  gap: 12px;
+  margin-bottom: 12px;
+}
+
+.top-bar .proj-alert {
+  flex: 1;
+  margin-bottom: 0;
+}
+
+/* 搜索栏 */
+.search-bar {
+  margin-bottom: 12px;
+}
 </style>

+ 0 - 6
gw-ui/src/views/system/projbase/index.vue

@@ -64,12 +64,6 @@
             <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
                        v-hasPermi="['business:projbase:edit']">修改
             </el-button>
-            <el-button link type="success" icon="Monitor" @click="handleViewEng(scope.row)"
-                       v-hasPermi="['business:objeng:list']">工程
-            </el-button>
-            <el-button link type="primary" icon="Tickets" @click="handleViewTend(scope.row)"
-                       v-hasPermi="['business:objtend:list']">标段
-            </el-button>
             <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
                        v-hasPermi="['business:projbase:remove']">删除
             </el-button>

+ 38 - 118
gw-ui/src/views/system/projbase/tend/index.vue

@@ -19,21 +19,25 @@
       </div>
     </el-form>
 
-    <el-alert v-if="projName" :title="'当前项目:' + projName" type="info" :closable="false" class="proj-alert"/>
-
     <div class="table-wrapper">
       <el-table :height="tableHeight" v-loading="loading" :data="objTendList" @selection-change="handleSelectionChange">
         <el-table-column type="selection" width="50" align="center"/>
         <el-table-column label="标段名称" align="center" prop="tendName" :show-overflow-tooltip="true"/>
-        <el-table-column label="所属工程" align="center" prop="engName" :show-overflow-tooltip="true"/>
-        <el-table-column label="所属单位" align="center" prop="orgName" :show-overflow-tooltip="true"/>
-        <el-table-column label="负责人" align="center" prop="legPers" :show-overflow-tooltip="true"/>
-        <el-table-column label="联系电话" align="center" prop="legTel" :show-overflow-tooltip="true"/>
-        <el-table-column label="合同金额" align="center" prop="conAmout" :show-overflow-tooltip="true"/>
-        <el-table-column label="完工状态" align="center" prop="stat" :show-overflow-tooltip="true"/>
-        <el-table-column label="备注" align="center" prop="note" :show-overflow-tooltip="true"/>
+        <el-table-column label="所属工程" align="center" prop="engName" :show-overflow-tooltip="true" min-width="140"/>
+        <el-table-column label="所属单位" align="center" prop="orgName" :show-overflow-tooltip="true" min-width="140"/>
+        <el-table-column label="负责人" align="center" prop="legPers" :show-overflow-tooltip="true" min-width="100"/>
+        <el-table-column label="联系电话" align="center" prop="legTel" :show-overflow-tooltip="true" min-width="120"/>
+        <el-table-column label="合同金额" align="center" prop="conAmout" :show-overflow-tooltip="true" min-width="120"/>
+        <el-table-column label="完工状态" align="center" prop="stat" min-width="90">
+          <template #default="scope">
+            <el-tag v-if="scope.row.stat === '1'" type="warning">在建</el-tag>
+            <el-tag v-else-if="scope.row.stat === '2'" type="success">已完工</el-tag>
+            <span v-else>{{ scope.row.stat }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="备注" align="center" prop="note" :show-overflow-tooltip="true" min-width="120"/>
 
-        <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="220">
+        <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="260">
           <template #default="scope">
             <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)"
                        v-hasPermi="['business:objtend:edit']">修改
@@ -52,7 +56,8 @@
     <pagination v-show="total>0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
                 @pagination="getList"/>
 
-    <el-dialog :title="title" v-model="open" width="760px" append-to-body>
+    <!-- ====== 标段新增/编辑 Dialog ====== -->
+    <el-dialog :title="title" v-model="open" width="760px" append-to-body @closed="cancel">
       <el-form ref="objTendRef" :model="form" :rules="rules" label-width="120px" class="tend-form">
         <el-row :gutter="20">
           <el-col :span="12">
@@ -61,33 +66,13 @@
             </el-form-item>
           </el-col>
           <el-col :span="12">
-            <el-form-item label="所属工程" prop="engGuid">
-              <el-select
-                v-model="form.engGuid"
-                filterable remote clearable reserve-keyword
-                :remote-method="remoteSearchEng"
-                :loading="engLoading"
-                placeholder="请输入工程名称搜索"
-                style="width:100%">
-                <el-option v-for="item in engOptions" :key="item.guid" :label="item.engName" :value="item.guid"/>
-              </el-select>
-            </el-form-item>
+            <EngSelect v-model="form.engGuid" label="关联工程" prop="engGuid" placeholder="请输入工程名称搜索" required />
           </el-col>
           <el-col :span="12">
-            <OrgSelect v-model="form.orgGuid" label="所属单位" placeholder="请输入单位名称搜索"/>
+            <ProjSelect v-model="form.orgProjDeptGuid" label="关联项目" prop="orgProjDeptGuid" placeholder="请输入项目名称搜索" required />
           </el-col>
           <el-col :span="12">
-            <el-form-item label="项目部" prop="orgProjDeptGuid">
-              <el-select
-                v-model="form.orgProjDeptGuid"
-                filterable remote clearable reserve-keyword
-                :remote-method="remoteSearchProjDept"
-                :loading="projDeptLoading"
-                placeholder="请输入参建单位名称搜索"
-                style="width:100%">
-                <el-option v-for="item in projDeptOptions" :key="item.guid" :label="item.orgName" :value="item.guid"/>
-              </el-select>
-            </el-form-item>
+            <OrgSelect v-model="form.orgGuid" label="关联单位" placeholder="请输入单位名称搜索"/>
           </el-col>
           <el-col :span="12">
             <el-form-item label="负责人" prop="legPers">
@@ -138,7 +123,7 @@
     </el-dialog>
 
     <!-- ====== 标段参建单位关系 Dialog ====== -->
-    <el-dialog title="标段参建单位" v-model="relOpen" width="760px" append-to-body>
+    <el-dialog title="标段参建单位" v-model="relOpen" width="900px" append-to-body>
       <el-alert v-if="relTendRow.tendName" :title="'当前标段:' + relTendRow.tendName" type="info" :closable="false" style="margin-bottom:12px"/>
       <el-row class="mb8">
         <el-col :span="24">
@@ -151,22 +136,23 @@
                 :loading="relOrgLoading"
                 placeholder="请输入参建单位名称搜索"
                 style="width:240px">
-                <el-option v-for="item in relOrgOptions" :key="item.guid" :label="item.orgName" :value="item.guid"/>
+                <el-option v-for="item in relOrgOptions" :key="item.guid" :label="item.orgCode + ' - ' + item.orgName" :value="item.guid"/>
               </el-select>
             </el-form-item>
-            <el-form-item label="建立时间">
-              <el-date-picker v-model="relForm.fromDate" type="date" value-format="YYYY-MM-DD" style="width:150px"/>
-            </el-form-item>
             <el-form-item>
-              <el-button type="primary" icon="Plus" @click="submitRelForm">添加关系</el-button>
+              <el-button type="primary" icon="Plus" @click="submitRelForm">添加参建单位</el-button>
             </el-form-item>
           </el-form>
         </el-col>
       </el-row>
       <el-table v-loading="relLoading" :data="relOrgList" border>
-        <el-table-column label="参建单位名称" align="center" prop="orgName" :show-overflow-tooltip="true"/>
-        <el-table-column label="关系建立时间" align="center" prop="fromDate" width="160"/>
-        <el-table-column label="关系终止时间" align="center" prop="toDate" width="160"/>
+        <el-table-column label="参建单位代码" align="center" prop="orgCode" :show-overflow-tooltip="true" min-width="120"/>
+        <el-table-column label="参建单位名称" align="center" prop="orgName" :show-overflow-tooltip="true" min-width="150"/>
+        <el-table-column label="参建单位类型" align="center" prop="orgType" :show-overflow-tooltip="true" min-width="100">
+          <template #default="scope">
+            <dict-tag :options="slaj_uwat_org_type" :value="scope.row.orgType"/>
+          </template>
+        </el-table-column>
         <el-table-column label="操作" align="center" width="100">
           <template #default="scope">
             <el-button link type="danger" icon="Delete" @click="handleRelDelete(scope.row)">解除</el-button>
@@ -180,19 +166,19 @@
 <script setup name="ProjBaseTend">
 import { useRoute } from 'vue-router'
 import { listObjTend, getObjTend, delObjTend, addObjTend, updateObjTend } from "@/api/system/objTend"
-import { getAttProjBase } from "@/api/system/attProjBase"
-import { listEngBase, getEngBase } from "@/api/slaj/eng"
-import { listAttOrgUwatBase, getAttOrgUwatBase } from "@/api/system/attOrgUwatBase"
+import { listAttOrgUwatBase } from "@/api/system/attOrgUwatBase"
 import { listRelTendOrg, addRelTendOrg, delRelTendOrg } from "@/api/system/relTendOrg"
 import OrgSelect from "@/components/OrgSelect"
+import EngSelect from "@/components/EngSelect"
+import ProjSelect from "@/components/ProjSelect"
 import { useTableHeight } from '@/hooks/useTableHeight'
 
 const { tableHeight, containerRef } = useTableHeight()
 const { proxy } = getCurrentInstance()
+const { slaj_uwat_org_type } = proxy.useDict("slaj_uwat_org_type")
 const route = useRoute()
 
-const projGuid = ref(route.params.projGuid)
-const projName = ref("")
+const projGuid = ref(route.params.projGuid || undefined)
 
 const objTendList = ref([])
 const open = ref(false)
@@ -204,13 +190,6 @@ const multiple = ref(true)
 const total = ref(0)
 const title = ref("")
 
-// 所属工程远程搜索(OBJ_ENG)
-const engOptions = ref([])
-const engLoading = ref(false)
-// 项目部远程搜索(参建单位 att_org_uwat_base)
-const projDeptOptions = ref([])
-const projDeptLoading = ref(false)
-
 const data = reactive({
   form: {
     tendName: undefined,
@@ -227,8 +206,6 @@ const data = reactive({
   },
   queryParams: {
     tendName: undefined,
-    projGuid: undefined,
-    engGuid: undefined,
     pageNum: 1,
     pageSize: 10
   },
@@ -239,60 +216,9 @@ const data = reactive({
 
 const { queryParams, form, rules } = toRefs(data)
 
-/** 远程搜索所属工程(限当前项目下,按 projGuid 过滤) */
-function remoteSearchEng(query) {
-  if (!query) { engOptions.value = []; return }
-  engLoading.value = true
-  listEngBase({ projGuid: projGuid.value, engName: query, pageNum: 1, pageSize: 20 }).then(res => {
-    engOptions.value = (res.rows || []).map(r => ({ guid: r.guid, engName: r.engName }))
-  }).finally(() => { engLoading.value = false })
-}
-
-/** 编辑回显:根据 engGuid 预加载工程名称 */
-function loadEngOption(guid) {
-  if (!guid) return
-  getEngBase(guid).then(res => {
-    const d = res.data
-    if (d && d.guid) engOptions.value = [{ guid: d.guid, engName: d.engName }, ...engOptions.value]
-  }).catch(() => {})
-}
-
-/** 远程搜索项目部(参建单位) */
-function remoteSearchProjDept(query) {
-  if (!query) { projDeptOptions.value = []; return }
-  projDeptLoading.value = true
-  listAttOrgUwatBase({ orgName: query, pageNum: 1, pageSize: 20 }).then(res => {
-    projDeptOptions.value = (res.rows || []).map(r => ({ guid: r.guid, orgName: r.orgName }))
-  }).finally(() => { projDeptLoading.value = false })
-}
-
-/** 编辑回显:根据 orgProjDeptGuid 预加载参建单位名称 */
-function loadProjDeptOption(guid) {
-  if (!guid) return
-  getAttOrgUwatBase(guid).then(res => {
-    const d = res.data
-    if (d && d.guid) projDeptOptions.value = [{ guid: d.guid, orgName: d.orgName }, ...projDeptOptions.value]
-  }).catch(() => {})
-}
-
-function loadProj() {
-  if (!projGuid.value) return
-  getAttProjBase(projGuid.value).then(res => {
-    projName.value = res.data && res.data.projName ? res.data.projName : ""
-  }).catch(() => {})
-}
-
 function getList() {
   loading.value = true
-  // 工程页跳转时带 engGuid 查询参数,直接按工程筛选
-  if (route.query.engGuid) {
-    queryParams.value.engGuid = route.query.engGuid
-    queryParams.value.projGuid = undefined
-  } else {
-    queryParams.value.projGuid = projGuid.value
-    queryParams.value.engGuid = undefined
-  }
-  listObjTend(queryParams.value).then(response => {
+  listObjTend({ ...queryParams.value, projGuid: projGuid.value }).then(response => {
     objTendList.value = response.rows
     total.value = response.total
     loading.value = false
@@ -318,8 +244,6 @@ function reset() {
     note: undefined,
     stat: undefined
   }
-  engOptions.value = []
-  projDeptOptions.value = []
   proxy.resetForm("objTendRef")
 }
 
@@ -350,9 +274,6 @@ function handleUpdate(row) {
   const guid = row.guid || ids.value
   getObjTend(guid).then(response => {
     form.value = response.data
-    // 回显所属工程、项目部名称
-    if (form.value.engGuid) engOptions.value = [{ guid: form.value.engGuid, engName: form.value.engName }]
-    loadProjDeptOption(form.value.orgProjDeptGuid)
     open.value = true
     title.value = "修改标段"
   })
@@ -420,7 +341,7 @@ function loadRelOrgList() {
   }).finally(() => { relLoading.value = false })
 }
 
-/** 远程搜索参建单位(复用 att_org_uwat_base) */
+/** 远程搜索参建单位 */
 function remoteSearchRelOrg(query) {
   if (!query) { relOrgOptions.value = []; return }
   relOrgLoading.value = true
@@ -444,6 +365,8 @@ function submitRelForm() {
     relForm.value = { orgUwatGuid: undefined, fromDate: undefined }
     relOrgOptions.value = []
     loadRelOrgList()
+  }).catch(() => {
+    proxy.$modal.msgError("添加失败,请重试")
   })
 }
 
@@ -455,7 +378,6 @@ function handleRelDelete(row) {
   }).catch(() => {})
 }
 
-loadProj()
 getList()
 </script>
 
@@ -463,7 +385,5 @@ getList()
 .search-form { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; }
 .search-form-left { display: flex; align-items: center; flex-wrap: wrap; flex: 1; }
 .search-form-right { display: flex; align-items: center; gap: 6px; white-space: nowrap; flex-shrink: 0; }
-.proj-alert { margin-bottom: 12px; }
 .tend-form .el-textarea__inner { resize: none; }
-
 </style>