浏览代码

增加项目详情中查看地图,AI生成技术标接口调用及下载标书功能

mork 3 周之前
父节点
当前提交
9482749d90

+ 97 - 1
package-lock.json

@@ -24,7 +24,8 @@
         "qs": "^6.15.2",
         "vue": "^3.4.21",
         "vue-clipboard3": "^2.0.0",
-        "vue-router": "^4.3.0"
+        "vue-router": "^4.3.0",
+        "wellknown": "^0.5.0"
       },
       "devDependencies": {
         "@types/jsoneditor": "^9.9.6",
@@ -4209,6 +4210,20 @@
       "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
       "license": "MIT"
     },
+    "node_modules/concat-stream": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz",
+      "integrity": "sha512-H6xsIBfQ94aESBG8jGHXQ7i5AEpy5ZeVaLDOisDICiTCKpqEfr34/KmTrspKQNoLKNu9gTkovlpQcUi630AKiQ==",
+      "engines": [
+        "node >= 0.8"
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "~2.0.1",
+        "readable-stream": "~2.0.0",
+        "typedarray": "~0.0.5"
+      }
+    },
     "node_modules/concaveman": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/concaveman/-/concaveman-1.2.1.tgz",
@@ -4221,6 +4236,12 @@
         "tinyqueue": "^2.0.3"
       }
     },
+    "node_modules/core-util-is": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+      "license": "MIT"
+    },
     "node_modules/csstype": {
       "version": "3.2.3",
       "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
@@ -4676,6 +4697,18 @@
         "node": ">= 6"
       }
     },
+    "node_modules/inherits": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+      "license": "ISC"
+    },
+    "node_modules/isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+      "license": "MIT"
+    },
     "node_modules/javascript-natural-sort": {
       "version": "0.7.1",
       "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
@@ -4898,6 +4931,15 @@
         "url": "https://github.com/sponsors/isaacs"
       }
     },
+    "node_modules/minimist": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/moment": {
       "version": "2.30.1",
       "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz",
@@ -5056,6 +5098,12 @@
         "node": "^10 || ^12 || >=14"
       }
     },
+    "node_modules/process-nextick-args": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+      "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==",
+      "license": "MIT"
+    },
     "node_modules/proxy-from-env": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz",
@@ -5113,6 +5161,20 @@
         "quickselect": "^2.0.0"
       }
     },
+    "node_modules/readable-stream": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+      "integrity": "sha512-TXcFfb63BQe1+ySzsHZI/5v1aJPCShfqvWJ64ayNImXMsN1Cd0YGk/wm8KB7/OeessgPc9QvS9Zou8QTkFzsLw==",
+      "license": "MIT",
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.1",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~1.0.6",
+        "string_decoder": "~0.10.x",
+        "util-deprecate": "~1.0.1"
+      }
+    },
     "node_modules/robust-predicates": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-2.0.4.tgz",
@@ -5263,6 +5325,12 @@
       "integrity": "sha512-0kGecIZNIReCSiznK3uheYB8sbstLjCZLiwcQwbmLhgHJj2gz6OnSPkVzJQCMnmEz1BQ4gPK59ylhBoEWOhGNA==",
       "license": "BDS-3-Clause"
     },
+    "node_modules/string_decoder": {
+      "version": "0.10.31",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+      "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==",
+      "license": "MIT"
+    },
     "node_modules/sweepline-intersections": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/sweepline-intersections/-/sweepline-intersections-1.5.0.tgz",
@@ -5316,6 +5384,15 @@
       "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
       "license": "0BSD"
     },
+    "node_modules/typedarray": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.7.tgz",
+      "integrity": "sha512-ueeb9YybpjhivjbHP2LdFDAjbS948fGEPj+ACAMs4xCMmh72OCOMQWBQKlaN4ZNQ04yfLSDLSx1tGRIoWimObQ==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/typescript": {
       "version": "5.9.3",
       "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
@@ -5352,6 +5429,12 @@
         "punycode": "^2.1.0"
       }
     },
+    "node_modules/util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+      "license": "MIT"
+    },
     "node_modules/vanilla-picker": {
       "version": "2.12.3",
       "resolved": "https://registry.npmjs.org/vanilla-picker/-/vanilla-picker-2.12.3.tgz",
@@ -5522,6 +5605,19 @@
         "typescript": ">=5.0.0"
       }
     },
+    "node_modules/wellknown": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/wellknown/-/wellknown-0.5.0.tgz",
+      "integrity": "sha512-za5vTLuPF9nmrVOovYQwNEWE/PwJCM+yHMAj4xN1WWUvtq9OElsvKiPL0CR9rO8xhrYqL7NpI7IknqR8r6eYOg==",
+      "license": "BSD",
+      "dependencies": {
+        "concat-stream": "~1.5.0",
+        "minimist": "~1.2.0"
+      },
+      "bin": {
+        "wellknown": "cli.js"
+      }
+    },
     "node_modules/wgs84": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/wgs84/-/wgs84-0.0.0.tgz",

+ 2 - 1
package.json

@@ -24,7 +24,8 @@
     "qs": "^6.15.2",
     "vue": "^3.4.21",
     "vue-clipboard3": "^2.0.0",
-    "vue-router": "^4.3.0"
+    "vue-router": "^4.3.0",
+    "wellknown": "^0.5.0"
   },
   "devDependencies": {
     "@types/jsoneditor": "^9.9.6",

+ 2 - 0
public/static/config/config.js

@@ -10,6 +10,8 @@ window.CONFIG = {
   //1852:投标/续标栏目 1955:招标公告栏目 1930:招标监控 1854:开标监控 1954:意向公告 1948:澄清公告栏目 1950:续签项目栏目 1794:申勤项目数据
   MODELIDARR:[1852,1955,1930,1854,1954,1948,1950,1794],
 
+  FILEPATH: 'http://121.43.55.7:65456',
+
   TASKLIST: [
     { id: 1, seq:2, type: 1, text: '客户回访与续标意向确认', done: false,create_time:'',username:'',userid:''},
     { id: 2, seq:2, type: 1, text: '现场踏勘与服务评估', done: false,create_time:'',username:'',userid:''},

+ 17 - 18
src/components/bidResult/addContent.vue

@@ -9,12 +9,12 @@
               <el-option v-for="item in typeOptions" :key="item.value" :label="item.label" :value="item.value" />
             </el-select>
           </el-form-item>
-          <el-form-item label="项目名称" v-if="addForm.type == '监控中'">
+          <el-form-item label="项目名称" v-if="addForm.type == '监控中未中标'">
             <el-select v-model="addForm.title" placeholder="请选择项目名称" @change="handleProjectChange"  value-key="id">
               <el-option v-for="item in jkList" :key="item.id" :label="item.title" :value="item" />
             </el-select>
           </el-form-item>
-          <el-form-item label="项目名称" v-else-if="addForm.type == '投续标'">
+          <el-form-item label="项目名称" v-else-if="addForm.type == '投续标中登记'">
             <el-select v-model="addForm.title" placeholder="请选择项目名称" @change="handleProjectChange"  value-key="id">
               <el-option v-for="item in txbList" :key="item.id" :label="item.title" :value="item" />
             </el-select>
@@ -36,7 +36,7 @@
             </el-form-item>
           </div>
           <div v-else> -->
-            <div v-if="addForm.type == '新创建'">
+            <div v-if="addForm.type == '新登记'">
               <el-form-item label="是否续标">
                 <el-switch v-model="addForm.c_is_xb" inline-prompt active-text="是" inactive-text="否" style="background-color: unset;" @change="handleXBSwitchChange"/>
               </el-form-item>
@@ -45,7 +45,7 @@
               <el-input v-model="finishBidObjectTemp.url" placeholder="请输入中标结果URL"/>
             </el-form-item>
           <!-- </div> -->
-          <div  v-if="addForm.type != '监控中'">
+          <div  v-if="addForm.type != '监控中未中标'">
               <el-form-item label="管理区域" prop="c_glqy">
                 <el-cascader ref="areaCascader" v-model="addFormArea" :options="props.glArea" :show-all-levels="true"  @change="handleNodeAreaClick" style="width: 100%"></el-cascader>
               </el-form-item>
@@ -107,7 +107,7 @@
                 
           </div>
 
-          <div  v-if="addForm.type != '监控中'">
+          <div  v-if="addForm.type != '监控中未中标'">
               <el-form-item label="业态" prop="c_ytfw">
                 <el-tree-select
                       placeholder="请选择业态"
@@ -321,23 +321,23 @@ const buildTree = (data: any[]): any[] => {
 
 const typeOptions = ref([
 {
-    value: '新创建',
-    label: '新创建',
+    value: '新登记',
+    label: '新登记',
 },
 {
-    value: '监控中',
-    label: '监控中',
+    value: '监控中未中标',
+    label: '监控中未中标',
 },
 {
-    value: '投续标',
-    label: '投续标',
+    value: '投续标中登记',
+    label: '投续标中登记',
 },
 ])
 
 
 const addForm = ref({
   id: '',
-  type: '新创建',
+  type: '新登记',
   title: '',
   tb_date:'',
   tb_money:'',
@@ -359,7 +359,7 @@ const submitForm = (formEl: FormInstance | undefined) => {
   if (!formEl) return
   formEl.validate(async (valid) => {
     if (valid) {
-      if(addForm.value.type == '监控中'){
+      if(addForm.value.type == '监控中未中标'){
         //流程
         const id = 7  // 固定进度数值
         const rwlcqd = JSON.parse(txbBidObject.value.rwlcqd || '[]')
@@ -413,7 +413,7 @@ const submitForm = (formEl: FormInstance | undefined) => {
         })
         updateProject(CONFIG.COLUMNIDARR[6],CONFIG.MODELIDARR[3],content2)
 
-      }else if(addForm.value.type == '投续标'){
+      }else if(addForm.value.type == '投续标中登记'){
         //流程
         const rwlcqd = JSON.parse(selectedObject.value.rwlcqd || '[]')
         rwlcqd.forEach((p: any) => {
@@ -631,7 +631,7 @@ const handleProjectChange = async (val: any) => {
   jkBidObject.value = null
   txbBidObject.value = null
   finishBidObject.value = null
-  if(addForm.value.type == '监控中'){
+  if(addForm.value.type == '监控中未中标'){
     jkBidObject.value = val
     const res = await getTxbBidContent(CONFIG.COLUMNIDARR[2],val.id,"c_xgjk")
     txbBidObject.value = res || {}
@@ -706,9 +706,8 @@ const getTxbBidContent = async (columnId:number,search:string,type:string) => {
   return (res as any).content.data[0]
 }
 
-
-const handleNodeAreaClick = (value: any[])  => {
-  const val = value
+// const handleNodeAreaClick = (value: any[])  => {
+const handleNodeAreaClick = ()  => {
   const nodes = (areaCascader.value as any)?.getCheckedNodes?.() || []
   if(nodes.length) {
     const targetNode = nodes[nodes.length - 1]

+ 28 - 4
src/components/bidResult/addProject.vue

@@ -441,8 +441,9 @@ import UTIL from '@/utils/util'
 import MapDraw from '@/components/map/MapDraw.vue'
 import GeoJsonEditor from '@/components/view/GeoJsonEditor.vue'
 import * as turf from '@turf/turf'
-import { title } from 'process'
 
+const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
+const userName = userInfo?.username =='user_xtw' ? '徐天炜' : userInfo?.username || ''
 const mapRef = ref<InstanceType<typeof MapDraw>>()
 // const editRef = ref<InstanceType<typeof GeoJsonEditor>>()
 const geoData = ref<GeoJSON.Feature<GeoJSON.Polygon> | null>(null)
@@ -452,9 +453,6 @@ const dialogVisible = ref(false)
 const soureProjects = ref<any>({})
 const txbProjects = ref<any>({})
 
-// const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
-// const userName = userInfo?.username =='user_xtw' ? '徐天炜' : userInfo?.username || ''
-
 const props = defineProps({
   flag: {
     type: Boolean,
@@ -676,6 +674,7 @@ const addForm = ref({
   c_scbmc: '',
   c_polygon: '',
   c_bcdzb: '',
+  c_history_tender: '',
 })
 
 // interface ProjectItem {
@@ -796,6 +795,7 @@ const addProject = async () => {
   addForm.value.c_xfyt = addFormYT.value
   addForm.value.c_wtfs = addFormZgfw.value
   addForm.value.c_zbjgrzbdrhxsj = addFormZbjg.value
+  addForm.value.c_history_tender = txbProjects.value.c_ai_scbs || ''
   const params: any = {
     content: JSON.stringify(addForm.value),
     columnId: CONFIG.COLUMNIDARR[0],
@@ -805,14 +805,38 @@ const addProject = async () => {
   const res = await api.addContent(params)
   if ((res as any).code === 200) {
     // ElMessage.success('添加成功')
+    console.log(res)
+    const ids = (res as any).content
     dialogVisible.value = true
     updateProject(props.projectData,true)
+    updaterwlcqdProject({id:8},ids)
   }else{
     // ElMessage.error('添加失败')
     dialogVisible.value = false
   }
 }
 
+// 更新投续标项目流程状态
+const updaterwlcqdProject = async (item:any,ids:string) => {
+  txbProjects.value.rwlcqd = JSON.parse(txbProjects.value.rwlcqd)
+  txbProjects.value.rwlcqd.find((p: any) => p.id == item.id).done = true
+  txbProjects.value.rwlcqd.find((p: any) => p.id == item.id).create_time = moment().format('YYYY-MM-DD HH:mm')
+  txbProjects.value.rwlcqd.find((p: any) => p.id == item.id).username = userName
+  txbProjects.value.rwlcqd.find((p: any) => p.id == item.id).userid = userInfo?.id || ''
+  txbProjects.value.rwlcqd.find((p: any) => p.id == item.id).type = 0
+  const params: any = {
+    columnId: CONFIG.COLUMNIDARR[2],
+    modelId: CONFIG.MODELIDARR[0],
+    content: JSON.stringify({
+      id: txbProjects.value.id,
+      rwlcqd:txbProjects.value.rwlcqd,
+      c_sfwc: true,
+      c_scxxmglid: ids,
+    }),
+  }
+  await api.updateContent(params)
+}
+
 const getNewSoureProject = async (columnId:number,ids: string,type: string) =>{
   return await getSoureProjects(columnId,ids,type)
 }

+ 116 - 25
src/components/map/MapDraw.vue

@@ -29,6 +29,28 @@ const emit = defineEmits<{
   'geoJson-change': [geo: GeoJSON.Feature<GeoJSON.Polygon> | null, area: number]
 }>()
 
+// 监听外部传入GeoJSON,自动回显
+watch(() => props.geoJson, (val) => {
+  if (!map || !draw) return
+  draw.deleteAll()
+  if (val) draw.set({ type: 'FeatureCollection', features: [val] })
+}, { immediate: true })
+
+
+onMounted(() => {
+  //弹窗打开后,延迟执行resize
+  nextTick(()=>{
+    initMap()
+    // 关键!通知map重新计算大小
+    setTimeout(()=>{
+      map!.resize()
+    },50)
+  })
+})
+onUnmounted(() => {
+  map!.remove()
+})
+
 // 初始化地图
 const initMap = () => {
   mapboxgl.accessToken = CONFIG.MAPBOX_ACCESS_TOKEN
@@ -56,8 +78,97 @@ const initMap = () => {
         draw!.set({ type: 'FeatureCollection', features: [props.geoJson] })
     }
     isLoaded.value = true
+
+    
   })
 }
+
+// 通用渲染函数:支持 Geometry / Feature / FeatureCollection
+function renderGeoJson(geoData:any, styleConfig = {}) {
+  // 默认样式
+  const opt = Object.assign({
+    pointColor: '#ff4400',
+    pointSize: 8,
+    lineColor: '#0066ff',
+    lineWidth: 3,
+    fillColor: 'rgba(0,150,255,0.2)',
+    fillOutlineColor: '#0066ff'
+  }, styleConfig);
+
+  // 处理输入,统一转为 FeatureCollection
+  let fc;
+  if (geoData.type === 'FeatureCollection') {
+    fc = geoData;
+  } else if (geoData.type === 'Feature') {
+    fc = { type: 'FeatureCollection', features: [geoData] };
+  } else {
+    // 传入的是纯Geometry
+    fc = { type: 'FeatureCollection', features: [{ type: 'Feature', geometry: geoData, properties: {} }] };
+  }
+
+  const sourceId = 'geo-temp-source';
+  const layerPointId = 'geo-temp-layer-point';
+  const layerLineId = 'geo-temp-layer-line';
+  const layerFillId = 'geo-temp-layer-fill';
+
+  // 移除旧图层和源(重复渲染时清理)
+  if (map!.getLayer(layerPointId)) map!.removeLayer(layerPointId);
+  if (map!.getLayer(layerLineId)) map!.removeLayer(layerLineId);
+  if (map!.getLayer(layerFillId)) map!.removeLayer(layerFillId);
+  if (map!.getSource(sourceId)) map!.removeSource(sourceId);
+
+  // 添加数据源
+  map!.addSource(sourceId, {
+    type: 'geojson',
+    data: fc
+  });
+
+  // 点图层
+  map!.addLayer({
+    id: layerPointId,
+    type: 'circle',
+    source: sourceId,
+    filter: ['in', ['geometry-type'], ['literal', ['Point','MultiPoint']]],
+    paint: {
+      'circle-color': opt.pointColor,
+      'circle-radius': opt.pointSize
+    }
+  });
+
+  // 线图层
+  map!.addLayer({
+    id: layerLineId,
+    type: 'line',
+    source: sourceId,
+    filter: ['in', ['geometry-type'], ['literal', ['LineString','MultiLineString']]],
+    paint: {
+      'line-color': opt.lineColor,
+      'line-width': opt.lineWidth
+    }
+  });
+
+  // 面图层
+  map!.addLayer({
+    id: layerFillId,
+    type: 'fill',
+    source: sourceId,
+    filter: ['in', ['geometry-type'], ['literal', ['Polygon','MultiPolygon']]],
+    paint: {
+      'fill-color': opt.fillColor,
+      'fill-outline-color': opt.fillOutlineColor
+    }
+  });
+
+  // 可选:自动缩放到图形范围
+  // const bounds = new mapboxgl.LngLatBounds();
+  // fc.features.forEach((f:any) => {
+  //   if(f.geometry) bounds.extend(f.geometry.coordinates);
+  // });
+  // if(!bounds.isEmpty()){
+  //   map!.fitBounds(bounds, { padding: 40 });
+  // }
+}
+
 const initBaseMap = (type:string) => {
   let titleStyle = CONFIG.MAPBOX_TILES_NORMAL
   if (type == "zwb") {
@@ -156,7 +267,7 @@ const handleGeoChange = () => {
 // 手动开启绘制多边形
 const startDrawPolygon = () => {
   if (!draw) {
-    console.warn('MapDraw: 地图尚未加载完成,请稍后再试')
+    // console.warn('MapDraw: 地图尚未加载完成,请稍后再试')
     return
   }
   draw.changeMode('draw_polygon')
@@ -164,7 +275,7 @@ const startDrawPolygon = () => {
 // 清空绘制
 const clearDraw = () => {
   if (!draw) {
-    console.warn('MapDraw: 地图尚未加载完成,请稍后再试')
+    // console.warn('MapDraw: 地图尚未加载完成,请稍后再试')
     return
   }
   draw.deleteAll()
@@ -173,7 +284,7 @@ const clearDraw = () => {
 // 切换选择编辑模式
 const editMode = () => {
   if (!draw) {
-    console.warn('MapDraw: 地图尚未加载完成,请稍后再试')
+    // console.warn('MapDraw: 地图尚未加载完成,请稍后再试')
     return
   }
   draw.changeMode('simple_select')
@@ -240,30 +351,10 @@ defineExpose({
   clearDraw,
   editMode,
   isLoaded,
-  getBounds
+  getBounds,
+  renderGeoJson
 })
 
-// 监听外部传入GeoJSON,自动回显
-watch(() => props.geoJson, (val) => {
-  if (!map || !draw) return
-  draw.deleteAll()
-  if (val) draw.set({ type: 'FeatureCollection', features: [val] })
-}, { immediate: true })
-
-
-onMounted(() => {
-  //弹窗打开后,延迟执行resize
-  nextTick(()=>{
-    initMap()
-    // 关键!通知map重新计算大小
-    setTimeout(()=>{
-      map!.resize()
-    },50)
-  })
-})
-onUnmounted(() => {
-  map!.remove()
-})
 </script>
 
 <style scoped>

+ 58 - 31
src/components/renewal/BidRenewal.vue

@@ -300,13 +300,14 @@ const addForm = ref({
   c_fwlx: '',
   c_glqy: '',
   c_is_xb: false,
+  c_sfwc: false,
   rwlcqd:JSON.stringify(CONFIG.TASKLIST)
 })
 const renewalStats = ref([
   { label: '全部', value: '0', highlight: true },
   { label: '进行中', value: '0', highlight: false },
-  { label: '90天内到期', value: '0', highlight: false },
-  { label: '已完成', value: '0', highlight: false }
+  { label: '已完成', value: '0', highlight: false },
+  // { label: '今天到期', value: '0', highlight: false }
 ])
 
 const jdArr = ref([
@@ -347,14 +348,21 @@ const getTabName = (stat: { label: string; highlight: boolean }) => {
       item.highlight = false
     }
   })
+  // if(label === '全部'){
+  //   statsType.value = ""
+  // }else if(label === '30天内到期'){
+  //   // statsType.value = moment().add(30, 'days').format('YYYY-MM-DD HH:mm:ss');
+  // }else if(label === '90天内到期'){
+  //   statsType.value = moment().add(90, 'days').format('YYYY-MM-DD HH:mm:ss');
+  // }else if(label === '今天到期'){
+  //   statsType.value = moment().format('YYYY-MM-DD HH:mm:ss');
+  // }
   if(label === '全部'){
     statsType.value = ""
   }else if(label === '进行中'){
-    statsType.value = moment().add(30, 'days').format('YYYY-MM-DD HH:mm:ss');
-  }else if(label === '90天内到期'){
-    statsType.value = moment().add(90, 'days').format('YYYY-MM-DD HH:mm:ss');
+    statsType.value = "false"
   }else if(label === '已完成'){
-    statsType.value = moment().format('YYYY-MM-DD HH:mm:ss');
+    statsType.value = "true"
   }
   page.value = 1
   getProjects()
@@ -473,14 +481,21 @@ const initData = () => {
   getDmsTypes();
   renewalStats.value.forEach(async (element:any) => {
     let time=''
+    // if(element.label === '全部'){
+    //   time = ""
+    // }else if(element.label === '30天内到期'){
+    //   time = moment().add(30, 'days').format('YYYY-MM-DD HH:mm:ss');
+    // }else if(element.label === '90天内到期'){
+    //   time = moment().add(90, 'days').format('YYYY-MM-DD HH:mm:ss');
+    // }else if(element.label === '今天到期'){
+    //   time = moment().format('YYYY-MM-DD HH:mm:ss');
+    // }
     if(element.label === '全部'){
       time = ""
     }else if(element.label === '进行中'){
-      time = moment().add(30, 'days').format('YYYY-MM-DD HH:mm:ss');
-    }else if(element.label === '90天内到期'){
-      time = moment().add(90, 'days').format('YYYY-MM-DD HH:mm:ss');
+      time = "false"
     }else if(element.label === '已完成'){
-      time = moment().format('YYYY-MM-DD HH:mm:ss');
+      time = "true"
     }
     element.value = await getCountProjects(time).then(res => res.toString())
   });
@@ -564,17 +579,23 @@ const getProjects = async () => {
         ...(params.conditionsList ? JSON.parse(params.conditionsList) : []),
         {
           columnId: columnId,
-          columnName: "zbjzsj",
-          condition: "between",
-          value: ['2000-01-01 00:00:00', statsType.value]
-        },
-        {
-          columnId: columnId,
-          columnName: "c_dqsj",
-          condition: "between",
-          value: ['2000-01-01 00:00:00', statsType.value]
+          columnName: "c_sfwc",
+          condition: "=",
+          value: statsType.value
         },
-        "or"//条件之间的关系
+        // {
+        //   columnId: columnId,
+        //   columnName: "zbjzsj",
+        //   condition: "between",
+        //   value: ['2000-01-01 00:00:00', statsType.value]
+        // },
+        // {
+        //   columnId: columnId,
+        //   columnName: "c_dqsj",
+        //   condition: "between",
+        //   value: ['2000-01-01 00:00:00', statsType.value]
+        // },
+        // "or"//条件之间的关系
     ]);
   }
   const res = await api.getMultipleFormsOfJointInvestigation(params)
@@ -618,17 +639,23 @@ const getCountProjects = async (entTime: string) => {
         ...(params.conditionsList ? JSON.parse(params.conditionsList) : []),
         {
           columnId: columnId,
-          columnName: "zbjzsj",
-          condition: "between",
-          value: ['2000-01-01 00:00:00', entTime]
-        },
-        {
-          columnId: columnId,
-          columnName: "c_dqsj",
-          condition: "between",
-          value: ['2000-01-01 00:00:00', entTime]
+          columnName: "c_sfwc",
+          condition: "=",
+          value: entTime
         },
-        "or"//条件之间的关系
+        // {
+        //   columnId: columnId,
+        //   columnName: "zbjzsj",
+        //   condition: "between",
+        //   value: ['2000-01-01 00:00:00', entTime]
+        // },
+        // {
+        //   columnId: columnId,
+        //   columnName: "c_dqsj",
+        //   condition: "between",
+        //   value: ['2000-01-01 00:00:00', entTime]
+        // },
+        // "or"//条件之间的关系
     ]);
   }
   const res = await api.getMultipleFormsOfJointInvestigation(params)
@@ -875,7 +902,7 @@ const getAdminArea = async () => {
 
 .pool-stats {
   display: grid;
-  grid-template-columns: repeat(4, 1fr);
+  grid-template-columns: repeat(3, 1fr);
   gap: 10px;
   margin-bottom: 16px;
 }

+ 5 - 4
src/components/renewal/Renew.vue

@@ -40,8 +40,9 @@
             </div>
           </div>
           <div class="renewal-row-actions">
-            <span v-if="item.type != '已完成'" :class="['days-badge', item.daysClass]">{{ item.days }}</span>
-            <span :class="['days-badge', item.jdClass]">{{ item.type }}</span>
+            <!-- <span v-if="item.type != '已完成'" :class="['days-badge', item.daysClass]">{{ item.days }}</span> -->
+            <span v-if="!['已完成','已中标'].includes(item.type)" :class="['badge', item.daysClass]">{{ item.days }}</span>
+            <span :class="['badge', item.jdClass]">{{ item.type }}</span>
             <el-button type="primary" size="small" class="btn enter-btn" v-if="item.jdClass === 'ok'" @click="handleViewClick(item)">进入</el-button>
             <el-button type="primary" size="small" class="btn enter-btn" v-else @click="handleViewClick(item)">进入</el-button>
           </div>
@@ -186,9 +187,9 @@ const calculateRemaining = async (st: string, et: string, xmjd_json: any): Promi
     if (yearNum < 0) yearNum = 0
   }
   if (diffDays < 0) {
-    return { days: `已过期${Math.abs(diffDays)}天`, daysClass: 'grey', year: yearNum.toString(), type: jdArr.value[xmjd-1].label, jdClass: jdArr.value[xmjd-1].color}
+    return { days: `已过期${Math.abs(diffDays)}天`, daysClass: 'grey', year: yearNum.toString(), type: jdArr.value[xmjd-1].label, jdClass: jdArr.value[xmjd-1].color}
   } else if (diffDays === 0) {
-    return { days: '今天到期', daysClass: 'grey', year: yearNum.toString(), type: jdArr.value[xmjd-1].label, jdClass: jdArr.value[xmjd-1].color}
+    return { days: '今天到期', daysClass: 'red', year: yearNum.toString(), type: jdArr.value[xmjd-1].label, jdClass: jdArr.value[xmjd-1].color}
   } else if (diffDays <= 60) {
     return { days: `剩余${diffDays}天`, daysClass: 'red', year: yearNum.toString(), type: jdArr.value[xmjd-1].label, jdClass: jdArr.value[xmjd-1].color}
   } else if (diffDays <= 90) {

+ 2 - 0
src/components/tenderpool/Monitor.vue

@@ -918,6 +918,7 @@ const addProject = async (isType: boolean) => {
             c_xmbt: finishObject.value.c_xmmc,
             xmbh: finishObject.value.c_father_code? finishObject.value.c_father_code : finishObject.value.c_guid, //有父项目编码 则使用父项目编码 否则使用项目编码
             c_is_xb: isType,
+            c_sfwc: false,
             c_ytfw: addFormYT.value,
             c_fwlx: addFormFwlx.value.join(','),
             c_glqy: addForm.value.c_glqy,
@@ -953,6 +954,7 @@ const addProject = async (isType: boolean) => {
             c_xmbt: addForm.value.c_xmbt,
             xmbh: finishObject.value.c_father_code? finishObject.value.c_father_code : finishObject.value.c_guid, //有父项目编码 则使用父项目编码 否则使用项目编码
             c_is_xb: isType,
+            c_sfwc: false,
             c_ytfw: addFormYT.value,
             c_fwlx: addFormFwlx.value.join(','),
             c_glqy: addForm.value.c_glqy,

+ 3 - 0
src/env.d.ts

@@ -0,0 +1,3 @@
+declare module 'wellknown' {
+  export function parse(wkt: string): GeoJSON.Geometry;
+}

+ 1 - 0
src/types/window.d.ts

@@ -7,6 +7,7 @@ declare global {
       SQ_URL: string
       COLUMNIDARR: number[]
       MODELIDARR: number[]
+      FILEPATH: string
       TASKLIST:any[]
       MAPBOX_ACCESS_TOKEN: string
       MAPBOX_TILES_NORMAL: string

+ 2 - 0
src/utils/config.ts

@@ -7,6 +7,7 @@ declare global {
       SQ_URL: string
       COLUMNIDARR: number[]
       MODELIDARR: number[]
+      FILEPATH: string
       TASKLIST:any[]
       MAPBOX_ACCESS_TOKEN: string
       MAPBOX_TILES_NORMAL: string
@@ -23,6 +24,7 @@ const CONFIG = window.CONFIG || {
   SQ_URL: '',
   COLUMNIDARR: [],
   MODELIDARR: [],
+  FILEPATH: '',
   TASKLIST:[],
   MAPBOX_ACCESS_TOKEN: '',
   MAPBOX_TILES_NORMAL: '',

+ 234 - 47
src/views/bidPreparation/RenewalExpireDetail.vue

@@ -147,8 +147,7 @@
                   </el-button>
                   <el-button type="primary" size="small" :disabled="task.done" :plain="task.done" v-if="task.id == 7" :loading="task.type == 1">
                     <span v-if="task.done">已完成</span>
-                    <span v-else @click="confirmTask(task)">{{task.type == 1 ? '监控中' : task.type == 0 ? '待确认' :''}}</span>
-                    
+                    <span v-else @click="confirmTask(task)">{{task.type == 1 ? '监控中' : task.type == 2 ? '待确认' :''}}</span>
                   </el-button>
                   <el-button type="primary" size="small" :disabled="task.done" :plain="task.done" v-if="task.id != 3 && task.id != 7">
                     <span v-if="task.done">已完成</span>
@@ -173,17 +172,19 @@
                   <th>年份</th>
                   <th>结果</th>
                   <th>金额</th>
-                  <th>操作</th>
+                  <th>地址</th>
+                  <!-- <th>操作</th> -->
                 </tr>
               </thead>
               <tbody>
                 <tr v-for="item in historyBidList" :key="item.id">
                   <td>{{ item.year }}</td>
-                  <td> 中标</td>
+                  <td>{{ item.type }}</td>
                   <td>{{ UTIL.formatCurrency(item.money/10000) }} 万元</td>
-                  <td class="link-text" >
+                  <td>{{ item.address }}</td>
+                  <!-- <td class="link-text" >
                     查看
-                  </td>
+                  </td> -->
                 </tr>
               </tbody>
             </table>
@@ -400,6 +401,23 @@
         </template>
       </el-dialog> -->
 
+      <el-dialog v-model="dialogZBJKVisible" draggable title="提示信息" width="500">
+        <div style="height: auto;overflow: auto;">
+          <el-select v-model="ruleZBJKForm.c_project_jkname" placeholder="请选择匹配的项目"  value-key="value" @change="handleJKTypeChange" >
+              <el-option v-for="item in zbjkProject" :key="item.id" :label="item.name" :value="item.id" />
+          </el-select>
+        </div>
+        
+        <template #footer>
+          <div class="dialog-footer">
+            <!-- <el-button @click="dialogZBJKVisible = false" class="btn">取消</el-button> -->
+            <el-button type="primary" class="btn enter-btn" @click="handleJKZBJKSubmit()">
+              确认
+            </el-button>
+          </div>
+        </template>
+      </el-dialog>
+
     <el-dialog v-model="dialogZBVisible" draggable title="提示信息" width="500">
         <div style="overflow: auto;">
           <el-form
@@ -584,6 +602,21 @@
         </template>
       </el-dialog>
 
+      <el-dialog v-model="dialogFinishBidVisible2" draggable title="提示信息" width="350">
+        <div v-if="finishBidObject?.c_detail_url" style="padding-top: 20px;text-align: center;color: var(--primary);">
+          <strong  style="cursor: pointer;" @click="handleOpenViewClick('0')">点击查看招标结果文件</strong>
+        </div>
+      
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="dialogFinishBidVisible2 = false" class="btn">取消</el-button>
+            <el-button type="primary" class="btn enter-btn" @click="handleFinishBidSubmit()">
+              确认
+            </el-button>
+          </div>
+        </template>
+      </el-dialog>
+
       <el-dialog v-model="dialogBidFileVisible" draggable title="提示信息" width="300">
         <div>
           <strong style="cursor: pointer;" @click="handleOpenViewClick('1')">点击查看招标公告</strong>
@@ -644,9 +677,11 @@ import type { FormInstance, FormRules } from 'element-plus'
 const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
 const userName = userInfo?.username =='user_xtw' ? '徐天炜' : userInfo?.username || ''
 const projects = ref<any>({})
+const soureProjects = ref<any>({})
 const left_btn_disabled = ref(false)
 const right_btn_disabled = ref(false)
 const dialogZBVisible = ref(false)
+const dialogZBJKVisible = ref(false)
 const tempTask = ref<any>({})
 const dialogBidVisible = ref(false)
 const ruleBidFormRef = ref<FormInstance>()
@@ -666,36 +701,7 @@ const ruleBidForm = reactive<RuleForm>({
     file:null,
   },
 })
-const historyBidList = ref<any>([
-  {
-    year: '2019',
-    money: '8585360'
-  },
-  {
-    year: '2020',
-    money: '8585360'
-  },
-  {
-    year: '2021',
-    money: '8585360'
-  },
-  {
-    year: '2022',
-    money: '8499576'
-  },
-  {
-    year: '2023',
-    money: '8499576'
-  },
-  {
-    year: '2024',
-    money: '8499576'
-  },
-  {
-    year: '2025',
-    money: '8395152'
-  },
-])
+const historyBidList = ref<any>([])
 
 const dialogBidFileVisible = ref(false)
 const bidRules = reactive<FormRules<RuleForm>>({
@@ -849,6 +855,7 @@ const ruleKBJKForm = reactive<RuleForm>({
 })
 
 const dialogFinishBidVisible = ref(false)
+const dialogFinishBidVisible2 = ref(false)
 const finishBidObjectTemp = ref({
   flag:false,
   url:''
@@ -933,7 +940,12 @@ const confirmTask = async (task: any) => {
       ElMessage.error(msg)
     }else{
       tempTask.value = task
-      dialogZBVisible.value = true
+      if(task.type != 2){
+        dialogZBVisible.value = true
+      }else{
+        dialogZBJKVisible.value = true
+      }
+      
     }
   }else if(task.id == "4"){
     const msg = getMessage(4)
@@ -956,7 +968,11 @@ const confirmTask = async (task: any) => {
     const res = await getfinishProjects()
     if(res){
         finishBidOption.value = res
-        dialogFinishBidVisible.value = true
+        if(task.type != 2){
+          dialogFinishBidVisible.value = true
+        }else{
+         dialogFinishBidVisible2.value = true
+        }
       }else{
         finishBidOption.value = []
       }
@@ -973,7 +989,7 @@ const getMessage = (ids: any) => {
       return "请先执行完"+steps.value.filter((item: any) => item.n == stage.value)[0].label
     }
 }
-// 模拟点击进入下一步
+// 点击进入下一步
 const handleViewClick = (item: any,type: string) => {
     if(item.n == 1){
       updateProject()
@@ -1026,9 +1042,14 @@ const handleViewClick = (item: any,type: string) => {
         if(flag){
           updateTypeProject(3)
           // 生成招标文件
-          // api.getGenerateTender({
-          //   txbId: projects.value.id,
-          // })
+          api.getGenerateTender({txbId: projects.value.id}).then((res: any) => {
+            if ((res as any).code === 200) {
+              ElMessage.success("标书文件生成成功")
+            }else{
+              ElMessage.error((res as any).msg || "标书文件生成失败")
+            }
+          })
+          
         }else{
           ElMessage.error("请先确认标书需求拆解与生成")
         }
@@ -1167,8 +1188,152 @@ const getProjects = async () => {
      stepsType.value = projects.value.c_xmjd_json[projects.value.c_xmjd_json.length-1].type
     //  swb_status.value = projects.value.c_xmjd_json[projects.value.c_xmjd_json.length-1].typeObj?.swb || ''
     //  jsb_status.value = projects.value.c_xmjd_json[projects.value.c_xmjd_json.length-1].typeObj?.jsb || ''
+    historyBidList.value = []
+    soureProjects.value = await getSoureProjects(CONFIG.COLUMNIDARR[0],projects.value.xmbh,"c_guid")
+    historyBidList.value = [{
+      year: soureProjects.value.c_guid.substring(10,14),
+      name: soureProjects.value.c_xmmc,
+      type: "中标",
+      money: soureProjects.value.c_nhhtsr,
+      address: soureProjects.value.c_query_address || ''
+    }]
+  }
+  
+  if(projects.value.rwlcqd[2].done == false){//匹配招标监控
+    getzbjkPorject(projects.value.id)
+  }
+  if(projects.value.rwlcqd[5].done == true && projects.value.rwlcqd[6].done == false){//匹配开标监控
+    getkbjkPorject(projects.value.c_xgjk)
+  }
+}
+const zbjkProject = ref<any[]>([]);
+const getzbjkPorject = async (id:any) => {
+  const ret = await getTypeProjects(CONFIG.COLUMNIDARR[5],id,"c_gl_xm")
+  if(ret.c_result_json){
+    const reslust = JSON.parse(ret.c_result_json)
+    let arr:any[] = []
+    reslust.notices.forEach((item:any) => {
+      let str = {id:item.data.id,type:item.type,name:item.data.title || ''}
+      arr.push(str)
+    })
+    reslust.intents.forEach((item:any) => {
+      let str = {id:item.data.id,type:item.type,name:item.data.title || ''}
+      arr.push(str)
+    })
+    zbjkProject.value = arr
+    updaterwlcqdProject2(projects.value,2)//匹配招标监控成功,进行修改投续标流程状态
+  }
+}
+const getkbjkPorject = async (id:any) => {
+  const ret = await getTypeProjects(CONFIG.COLUMNIDARR[6],id,"id")
+  if(ret){
+    if(ret.c_jgjk_url){
+      let str = {c_detail_url:ret.c_jgjk_url}
+      finishBidObject.value = str
+      updaterwlcqdProject2(projects.value,6)//匹配开标监控成功,进行修改投续标流程状态
+    }
   }
 }
+// 匹配招标有数据进行更新项目流程状态
+const updaterwlcqdProject2 = async (item:any,lcid:any) => {
+  item.rwlcqd[lcid].type = 2
+  const params: any = {
+    columnId: CONFIG.COLUMNIDARR[2],
+    modelId: CONFIG.MODELIDARR[0],
+    content: JSON.stringify({
+      id: item.id,
+      rwlcqd:item.rwlcqd
+    }),
+  }
+  await api.updateContent(params)
+}
+
+// 项目类型改变时,进行更新项目类型
+const handleJKTypeChange = async (val:any) => {
+  console.log(val)
+  let opt = zbjkProject.value.find((item:any) => item.id == val)
+  console.log(opt)
+  if(opt){
+    if(opt.type == 'notice'){//公告
+        let ret = await getSoureProjects(CONFIG.COLUMNIDARR[3],opt.id,"id")
+        console.log(ret)
+        ruleZBForm.c_project_code = ret.c_project_code || ""
+        ruleZBForm.c_project_name = ret.c_project_name || ""
+        ruleZBForm.c_budget_amount = ret.c_budget_amount || ""
+        ruleZBForm.c_bid_open_time = ret.c_bid_open_time || "" 
+        ruleZBForm.c_bid_deadline = ret.c_bid_deadline || ""
+        ruleZBForm.c_source_name = ret.c_source_name || ""
+        ruleZBForm.c_author = ret.c_author || ""
+        ruleZBForm.c_publish_time = ret.c_publish_time || ""
+        ruleZBForm.c_detail_url = ret.c_detail_url || ""
+    }else{//意向
+        let ret = await getSoureProjects(CONFIG.COLUMNIDARR[4],opt.id,"id")
+        console.log(ret)
+        ruleZBForm.c_project_code = ret.id || ""
+        ruleZBForm.c_project_name = ret.title || ""
+        ruleZBForm.c_budget_amount = 0
+        ruleZBForm.c_bid_open_time = ret.c_publish_time || "" 
+        ruleZBForm.c_bid_deadline = ret.c_publish_time || ""
+        ruleZBForm.c_source_name = ret.c_source_name || ""
+        ruleZBForm.c_author = ret.c_author || ""
+        ruleZBForm.c_publish_time = ret.c_publish_time || ""
+        ruleZBForm.c_detail_url = ret.c_detail_url || ""
+    }
+  }
+}
+// 匹配招标监控
+const handleJKZBJKSubmit = async () => {
+  dialogZBJKVisible.value = false
+  let formData = {
+      c_project_code:ruleZBForm.c_project_code,
+      c_project_name:ruleZBForm.c_project_name,
+      c_budget_amount:ruleZBForm.c_budget_amount, 
+      c_bid_open_time:moment(ruleZBForm.c_bid_open_time, 'YYYY年MM月DD日 HH:mm').format('YYYY-MM-DD HH:mm'), 
+      c_bid_deadline:moment(ruleZBForm.c_bid_open_time, 'YYYY年MM月DD日 HH:mm').format('YYYY-MM-DD HH:mm'), 
+      c_source_name:ruleZBForm.c_source_name, 
+      c_author:ruleZBForm.c_author,
+      c_publish_time:ruleZBForm.c_publish_time,
+      c_detail_url:ruleZBForm.c_detail_url,
+    }
+    updateZBProject(tempTask.value,formData,ruleZBForm.c_project_code)
+    getProjectParams(projects.value.id,'c_gl_xm',CONFIG.COLUMNIDARR[5]).then(async res => {
+      const reslust = (res as any)[0]
+      const content = {  
+        id: reslust.id,
+        c_complete: true,
+        c_enable: false
+      }
+      updateProjectParams(CONFIG.COLUMNIDARR[5],CONFIG.MODELIDARR[2], content)
+    })
+}
+
+
+
+const getSoureProjects = async (columnId:number,ids: string,type: string) =>{
+  const params: any = {
+    columnId: columnId,
+    states: '0,1,2,3',
+    pageSize: 1,
+    page: 0
+  }
+  if (ids !== "") {
+    params.search = JSON.stringify([
+        ...(params.search ? JSON.parse(params.search) : []),
+        {
+          field: type,
+          searchType: 2,
+          content: { value: `%${ids}%` },
+        },
+    ]);
+  }
+  const res = await getDmsDataList(params)
+  if((res as any).code == 200){
+    return (res as any).content.data[0]
+  }else{
+    return ''
+  }
+  
+}
 
 const getDmsDataList = async (params: any) => {
   return await api.getDmsDataList(params)
@@ -1308,7 +1473,9 @@ const updateZBProject = async (item:any,formData:any,contentId:any) => {
   if ((res as any).code === 200) {
     ElMessage.success('更新成功')
     dialogZBVisible.value = false
-    initData()
+    setTimeout(() => {
+      initData()
+    }, 1000);
   }
 }
 const handleZBSubmit = async (formEl: FormInstance | undefined) => {
@@ -1618,7 +1785,7 @@ const getFIlePath = async (params: any) => {
 
 
 const bidFile = ref({
-  flag:false,
+  flag: sessionStorage.getItem('bidFileFlag') == 'true' ? true : false,
   swb:false,
   jsb:false,
 })
@@ -1631,9 +1798,28 @@ const getBidFile = async () => {
   setTimeout(() => {
     // const fileName = `杨浦区图书馆总馆物业管理服务项目投标文件.docx`
     // UTIL.downloadFile(fileName, filePath)
-    loading.close()
-    ElMessage.success('获取标书成功')
-    bidFile.value.flag = true
+    const aiscbs = projects.value.c_ai_scbs || "";
+    // let aiscbs = "/data/model/shenqin_data/57f7bf655e994fa8a8867e4bc55e8709/1779-杨浦区图书馆总馆物业管理服务项目招标文件.pdf-ca9d5daf-443b-44c6-a1f3-bf43890a55d8.docx"
+    if(aiscbs){
+      let filename = aiscbs.split('/').pop() || ''
+      filename = filename.replace(/\?.*$/, '')
+      if(filename.includes('.docx')){
+        UTIL.downloadFile(filename, CONFIG.FILEPATH + (aiscbs.replace("/data/model","")))
+        loading.close()
+        ElMessage.success('获取标书成功')
+        bidFile.value.flag = true
+        sessionStorage.setItem('bidFileFlag', "true")
+      }else{
+        sessionStorage.setItem('bidFileFlag', "false")
+        ElMessage.error('暂无标书文件')
+      }
+      
+    }else{
+      loading.close()
+      // bidFile.value.flag = true
+      ElMessage.error('获取标书失败')
+    }
+    
   }, 3000);
   
   // if(bittype == 'swb'){
@@ -1654,6 +1840,7 @@ const handleSwitchChange = (val: any) => {
 }
 const handleFinishBidSubmit = async () => {
   dialogFinishBidVisible.value = false
+  dialogFinishBidVisible2.value = false
   let str = {id: '7'} // 修改
   updaterwlcqdProject(str)
   // 修改中标监控

+ 73 - 13
src/views/bidPreparation/RenewalXQDetail.vue

@@ -5,7 +5,7 @@
       <div class="header-info">
         <div class="project-title">{{projects.title}}</div>
         <!-- <div class="project-subtitle">{{ projects.c_xmbtqc }}</div> -->
-        <div class="project-meta">{{projects.c_xmbt}} · {{projects.c_qx}} · 金额{{UTIL.formatCurrency(projects.c_htje || '0')}}元</div>
+        <div class="project-meta">{{projects.c_xmbt}} · {{projects.c_qx}} · 金额{{UTIL.formatCurrency(projects.c_htje/10000 || '0')}}元</div>
        </div>
       <div class="countdown-badge">
         <span class="countdown-number">{{projects.days}}</span>
@@ -66,17 +66,27 @@
                   <th>年份</th>
                   <th>结果</th>
                   <th>金额</th>
-                  <th>操作</th>
+                  <th>地址</th>
+                  <!-- <th>操作</th> -->
                 </tr>
               </thead>
               <tbody>
-                <tr v-for="item in tablelist" :key="item.id">
+                <!-- <tr v-for="item in tablelist" :key="item.id">
                   <td>{{ item.year }}</td>
                   <td>{{ item.status }}</td>
                   <td>{{ item.money }}</td>
                   <td class="link-text" >
                     查看
                   </td>
+                </tr> -->
+                <tr v-for="item in historyBidList" :key="item.id">
+                  <td>{{ item.year }}</td>
+                  <td>{{ item.type }}</td>
+                  <td>{{ UTIL.formatCurrency(item.money/10000) }} 万元</td>
+                  <td>{{ item.address }}</td>
+                  <!-- <td class="link-text" >
+                    查看
+                  </td> -->
                 </tr>
               </tbody>
             </table>
@@ -102,11 +112,12 @@
             </div>
             <div class="info-row">
               <span class="label">合同金额</span>
-              <span class="value">{{UTIL.formatCurrency(projects.c_htje)}}元</span>
+              <span class="value">{{UTIL.formatCurrency(projects.c_htje/10000 || '0')}}元</span>
             </div>
             <div class="info-row">
               <span class="label">委托服务</span>
-              <span class="value">{{projects.c_wtfs}}</span>
+              <span class="value">{{getWTFWLabel(projects.c_wtfs)}}</span>
+              
             </div>
           </div>
         </div>
@@ -244,6 +255,7 @@ import UTIL from '@/utils/util'
 import { ElMessage } from 'element-plus'
 import type { FormInstance, FormRules } from 'element-plus'
 const projects = ref<any>({})
+const soureProjects = ref<any>({})
 const dialogVisible = ref(false)
 
 const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
@@ -251,11 +263,11 @@ const userName = userInfo?.username =='user_xtw' ? '徐天炜' : userInfo?.usern
 
 const steps = ref<any[]>([]);
 const stage = ref(Number(sessionStorage.getItem('progres')) || 0);
-const tablelist = ref([
-  {id:1,year:"2025",status:"中标",money:"620.00万",url:""},
-  {id:2,year:"2024",status:"中标",money:"560.00万",url:""},
-]);
-
+// const tablelist = ref([
+//   {id:1,year:"2025",status:"中标",money:"620.00万",url:""},
+//   {id:2,year:"2024",status:"中标",money:"560.00万",url:""},
+// ]);
+const historyBidList = ref<any[]>([])
 
 interface RuleForm {
   [key: string]: any
@@ -315,7 +327,7 @@ const handleSubmit = async (formEl: FormInstance | undefined) => {
       })
         json.push({
           create_time: moment().format('YYYY-MM-DD HH:mm'),
-          desc: "确认中标",
+          desc: "续签已完成",
           username:userName,
           userid:userInfo?.id || '',
         })
@@ -331,6 +343,7 @@ const handleSubmit = async (formEl: FormInstance | undefined) => {
           c_glxm: projects.value.c_xmbh,
           c_lcsjx: json,
           c_type: '续签',
+          c_enable: true,
         }
         const res = await addContentParams(formData,CONFIG.COLUMNIDARR[6],CONFIG.MODELIDARR[3])
         if(res){
@@ -383,6 +396,9 @@ onMounted(() => {
   initData()
   getDmsTypes()
 })
+const getWTFWLabel = (value: string) => {
+  return zgfwOptions.value.find((item: any) => item.value == value)?.label || '-'
+}
 const getDmsTypes = () => {
   let params = {
     type:0,
@@ -439,8 +455,18 @@ const handleViewClick = (item: any) => {
     }else if(item.n == 2){
       getAdminArea()
       getytProjects()
-     dialogVisible.value = true
+      dialogVisible.value = true
     }else if(item.n == 3){
+      let xmjd_json = projects.value.c_xmjd_json;
+      xmjd_json[xmjd_json.length-1].create_time = moment().format('YYYY-MM-DD HH:mm')
+      xmjd_json[xmjd_json.length-1].author = userName
+      xmjd_json[xmjd_json.length-1].type = 0
+      let content = JSON.stringify({
+        id: projects.value.id,
+        c_xmjd_json: xmjd_json
+      })
+      updateProject(CONFIG.COLUMNIDARR[11],CONFIG.MODELIDARR[6],content)
+
       sessionStorage.setItem('activeTab','won')
       sessionStorage.setItem('jkId', projects.value.c_xgjk);
       goToPage(item.left_url)
@@ -497,9 +523,43 @@ const getProjects = async () => {
       }))
     )
     const result = await Promise.all(promises)
-     projects.value = result[0]
+    projects.value = result[0]
+    historyBidList.value = []
+    soureProjects.value = await getSoureProjects(CONFIG.COLUMNIDARR[0],projects.value.c_xmbh,"c_guid")
+    historyBidList.value = [{
+      year: soureProjects.value.c_guid.substring(10,14),
+      name: soureProjects.value.c_xmmc,
+      type: "中标",
+      money: soureProjects.value.c_nhhtsr,
+      address: soureProjects.value.c_query_address || ''
+    }]
   }
 }
+const getSoureProjects = async (columnId:number,ids: string,type: string) =>{
+  const params: any = {
+    columnId: columnId,
+    states: '0,1,2,3',
+    pageSize: 1,
+    page: 0
+  }
+  if (ids !== "") {
+    params.search = JSON.stringify([
+        ...(params.search ? JSON.parse(params.search) : []),
+        {
+          field: type,
+          searchType: 2,
+          content: { value: `%${ids}%` },
+        },
+    ]);
+  }
+  const res = await getDmsDataList(params)
+  if((res as any).code == 200){
+    return (res as any).content.data[0]
+  }else{
+    return ''
+  }
+  
+}
 
 const getDmsDataList = async (params: any) => {
   return await api.getDmsDataList(params)

+ 53 - 6
src/views/bidResult/BidResult.vue

@@ -199,6 +199,24 @@
         </template>
        </el-dialog>
 
+       <el-dialog
+            v-model="dialogVisible"
+            title="提示信息"
+            width="300"
+            align-center
+            draggable
+            show-close="false"
+        >
+            <span>本项目已推送至市场部负责人,后续将由市场部统一分发至各部门负责人,相关后续流程敬请期待。</span>
+            <template #footer>
+            <div class="dialog-footer">
+                <el-button type="primary" @click="handleConfirm">
+                确认
+                </el-button>
+            </div>
+            </template>
+        </el-dialog>
+
     </div>
   </div>
 </template>
@@ -231,7 +249,7 @@ const pageSize = ref(10)
 const page = ref(1)
 const total = ref(0)
 const md = ref<MarkdownIt>()
-
+const dialogVisible = ref(false)
 const finishTreeProjects = ref<any[]>([])
 const glArea = ref([{} as TreeItem])
 const areaProject = ref([{} as TreeItem])
@@ -348,6 +366,7 @@ const getTabName = (stat: { label: string; highlight: boolean }) => {
 const handleTabClick = (tab: string) => {
   activeTab.value = tab
   sessionStorage.setItem('activeTab',tab)
+  updateStatus()
   if(tab == 'won' && jkObject.value.project){
     openMD(jkObject.value.project.c_content_html_path || '')
   }
@@ -369,6 +388,7 @@ const handleBidRegistration = async () => {
 const handleFinishProjectChange = (val: any) => {
   if (val && typeof val === 'object' && val.project) {
     jkObject.value = val
+    updateStatus()
     // jkObject.value.c_lcsjx = JSON.parse(val.c_lcsjx || '[]')
     jkObject.value.c_lcsjx  = val.c_lcsjx || '[]'
     openMD(jkObject.value.project.c_content_html_path || '')
@@ -472,10 +492,7 @@ const getProjects = async (label:string,type:string) => {
       }else{
         jkObject.value = finishProjects.value[0] || {}
       }
-      pushStartsOptions.value.done = jkObject.value.c_sfts == true ? true : false
-      pushStartsOptions.value.data.forEach(item => {
-        item.time = jkObject.value.c_tssj || ''
-      })
+      updateStatus()
     }
   }else{
     if(label == ''){
@@ -485,6 +502,13 @@ const getProjects = async (label:string,type:string) => {
   }
 }
 
+const updateStatus = () => {
+    pushStartsOptions.value.done = jkObject.value.c_sfts == true ? true : false
+    pushStartsOptions.value.data.forEach(item => {
+      item.time = jkObject.value.c_tssj || ''
+    })
+}
+
 const getJGProjects = async (id:string) => {
   const params: any = {
     columnId: CONFIG.COLUMNIDARR[7],
@@ -551,7 +575,30 @@ const handleConfirmBidPush = async () => {
   // })
   // updateAudit(jkObject.value,4)
   // updateKBJKProject(jkObject.value,arr)
-  addProjectFormVisible.value = true
+  // console.log(jkObject.value)
+  if(jkObject.value.c_type == "续签"){
+    updateProject(jkObject.value,true)
+    dialogVisible.value = true
+    initData()
+  }else{//续标
+    addProjectFormVisible.value = true
+  }
+  
+}
+const updateProject = async (item: any,flag:boolean) => {
+  const params: any = {
+    columnId: CONFIG.COLUMNIDARR[6],
+    modelId: CONFIG.MODELIDARR[3],
+    content: JSON.stringify({
+      id: item.id,
+      c_sfts: flag,
+      c_tssj: moment().format('YYYY-MM-DD HH:mm:ss'),
+    }),
+  }
+  await api.updateContent(params)
+}
+const handleConfirm = () => {
+  dialogVisible.value = false
 }
 // const updateKBJKProject = async (item: any,arr:any[]) => {
 //   const params: any = {

+ 32 - 33
src/views/ledger/ProjectDetail.vue

@@ -155,7 +155,17 @@
         </div>
       </div>
     </div>
-
+    <!-- 地图 -->
+   <div class="renewal-section">
+      <div class="section-header">
+        <span class="section-title">地图中心</span>
+      </div>
+      <div class="section-body">
+        <div class="renewal-actions">
+            <Map ref="mapRef" />
+        </div>
+      </div>
+    </div>
     <!-- 续约入口 -->
     <!-- <div class="renewal-section">
       <div class="section-header">
@@ -180,6 +190,9 @@ import CONFIG from '@/utils/config'
 import { useRouter } from 'vue-router'
 const router = useRouter()
 import { ElMessage } from 'element-plus'
+import * as wellknown from 'wellknown';
+import Map from '@/components/map/MapDraw.vue'
+const mapRef = ref<InstanceType<typeof Map>>()
 
 const userInfo = JSON.parse(localStorage.getItem('userInfo') || '{}')
 const userName = userInfo?.username =='user_xtw' ? '徐天炜' : userInfo?.username || ''
@@ -196,36 +209,7 @@ const tempArr = ref<any>([])
 const wtfwOptions = ref<any>([])
 const jffsOptions = ref<any>([])
 
-const historyBidList = ref<any>([
-  {
-    year: '2019',
-    money: '8585360'
-  },
-  {
-    year: '2020',
-    money: '8585360'
-  },
-  {
-    year: '2021',
-    money: '8585360'
-  },
-  {
-    year: '2022',
-    money: '8499576'
-  },
-  {
-    year: '2023',
-    money: '8499576'
-  },
-  {
-    year: '2024',
-    money: '8499576'
-  },
-  {
-    year: '2025',
-    money: '8395152'
-  },
-])
+const historyBidList = ref<any>([])
 
 onMounted(() => {
   initCName()
@@ -293,6 +277,21 @@ const getProjects = async () => {
       ...item,
       ...calculateRemaining(item.c_zgxmhtksrq, item.c_zgxmhtdqrq)
     }))[0]
+    historyBidList.value = []
+    historyBidList.value = [{
+      year: projects.value.c_guid.substring(10,14),
+      name: projects.value.c_xmmc,
+      type: "中标",
+      money: projects.value.c_nhhtsr,
+      address: projects.value.c_query_address || ''
+    }]
+
+    if(projects.value.c_polygon){
+      const geojson = wellknown.parse(projects.value.c_polygon.value)
+      mapRef.value?.getBounds(geojson)
+      mapRef.value?.renderGeoJson(geojson)
+    }
+
   }
 }
 const calculateRemaining = (st: string, et: string): { days: string; daysClass: string; year: string } => {
@@ -456,8 +455,8 @@ const addProject = async () => {
         xmbh:projects.value.c_father_code?projects.value.c_father_code:projects.value.c_guid,
         c_glqy: projects.value.c_glqynbkj,
         c_is_xb: true,
-        rwlcqd:JSON.stringify(CONFIG.TASKLIST)
-        
+        rwlcqd:JSON.stringify(CONFIG.TASKLIST),
+        c_sfwc: false,
        }
   
   const params = {