zs 10 months ago
parent
commit
bf2f259703

+ 5 - 0
src/router/index.js

@@ -192,6 +192,11 @@ const router = createRouter({
           meta: { title: '产学研用协同创新平台-中试平台' },
           component: () => import('@/views/platform/detail.vue')
         },
+        {
+          path: '/server/detail',
+          meta: { title: '产学研用协同创新平台-服务支撑' },
+          component: () => import('@/views/server/detail.vue')
+        },
         {
           path: '/release',
           meta: { title: '产学研用协同创新平台-发布' },

+ 0 - 3
src/views/achievement/index.vue

@@ -3,7 +3,6 @@
     <el-row>
       <el-col :span="24" class="main animate__animated animate__backInRight">
         <el-col :span="24" class="iachievement">
-          <el-image class="image" :src="achievement" fit="fill" />
           <div class="select">
             <el-row class="select_1">
               <el-col class="over" :span="4" v-if="oneList.length > 0">
@@ -299,9 +298,7 @@ const store = AchievementStore()
 const dictDataStore = DictDataStore()
 // 路由
 const router = useRouter()
-const route = useRoute()
 // 图片引入
-import achievement from '/images/bg.png'
 // 加载中
 const loading = ref(false)
 // 列表

+ 8 - 1
src/views/main/eight.vue

@@ -8,7 +8,7 @@
         <el-col :span="24" class="two">
           <div class="w_1200">
             <a-row :gutter="[16, 30]">
-              <a-col :span="6" v-for="(item, index) in list" :key="index">
+              <a-col :span="6" v-for="(item, index) in list" :key="index" @click="onSearch">
                 <div class="list">{{ item.label }}</div>
               </a-col>
             </a-row>
@@ -20,6 +20,8 @@
 </template>
 
 <script setup>
+// 路由
+const router = useRouter()
 // 图片引入
 import news from '/images/news.png'
 // 加载中
@@ -45,6 +47,11 @@ onMounted(async () => {
   loading.value = false
 })
 const search = async () => {}
+// 搜索
+const onSearch = () => {
+  const query = { type: 'search' }
+  router.push({ path: '/search', query })
+}
 </script>
 <style scoped lang="scss">
 .main {

+ 7 - 1
src/views/main/nine.vue

@@ -7,7 +7,7 @@
         </el-col>
         <el-col :span="24" class="two">
           <div class="w_1200">
-            <el-image class="image" :src="chengguo" fit="fill" />
+            <el-image @click="toView" class="image" :src="chengguo" fit="fill" />
           </div>
         </el-col>
       </el-col>
@@ -16,6 +16,8 @@
 </template>
 
 <script setup>
+// 路由
+const router = useRouter()
 // 图片引入
 import news from '/images/news.png'
 import chengguo from '/images/chengguo.png'
@@ -28,6 +30,10 @@ onMounted(async () => {
   loading.value = false
 })
 const search = async () => {}
+// 查询
+const toView = () => {
+  router.push({ path: '/achievement' })
+}
 </script>
 <style scoped lang="scss">
 .main {

+ 19 - 1
src/views/main/seven.vue

@@ -29,7 +29,15 @@
               </el-row>
             </el-col>
             <el-col :span="24" class="two_2">
-              <a-table :columns="columns" :data-source="data" bordered> </a-table>
+              <a-table :columns="columns" :data-source="data" bordered>
+                <template #bodyCell="{ column, text, record }">
+                  <template v-if="column.dataIndex === 'operation'">
+                    <a-popconfirm>
+                      <a @click="toView(record.key)">查看</a>
+                    </a-popconfirm>
+                  </template>
+                </template>
+              </a-table>
             </el-col>
           </div>
         </el-col>
@@ -41,6 +49,8 @@
 <script setup>
 // 图片引入
 import news from '/images/news.png'
+// 路由
+const router = useRouter()
 // 加载中
 const loading = ref(false)
 const typeList = ref([
@@ -73,6 +83,10 @@ const columns = [
   {
     title: '登记时间',
     dataIndex: 'time'
+  },
+  {
+    title: '操作',
+    dataIndex: 'operation'
   }
 ]
 
@@ -121,6 +135,10 @@ onMounted(async () => {
   loading.value = false
 })
 const search = async () => {}
+// 查看
+const toView = (item) => {
+  router.push({ path: '/server/detail', query: { id: item.id || item._id } })
+}
 </script>
 <style scoped lang="scss">
 .main {

+ 10 - 10
src/views/platform/detail.vue

@@ -194,16 +194,16 @@ const searchAchieve = async (query = { skip: 0, limit }) => {
   }
 }
 const searchOther = async () => {
-  let result
-  // 合作方式
-  result = await dictDataStore.query({ code: 'method', is_use: '0' })
-  if ($checkRes(result)) methodList.value = result.data
-  // 需求紧急度
-  result = await dictDataStore.query({ code: 'urgent', is_use: '0' })
-  if ($checkRes(result)) urgentList.value = result.data
-  // 技术领域
-  result = await dictDataStore.query({ code: 'field', is_use: '0' })
-  if ($checkRes(result)) fieldList.value = result.data
+  // let result
+  // // 合作方式
+  // result = await dictDataStore.query({ code: 'method', is_use: '0' })
+  // if ($checkRes(result)) methodList.value = result.data
+  // // 需求紧急度
+  // result = await dictDataStore.query({ code: 'urgent', is_use: '0' })
+  // if ($checkRes(result)) urgentList.value = result.data
+  // // 技术领域
+  // result = await dictDataStore.query({ code: 'field', is_use: '0' })
+  // if ($checkRes(result)) fieldList.value = result.data
 }
 // 字典数据转换
 const getDict = (data, model) => {

+ 495 - 0
src/views/server/detail.vue

@@ -0,0 +1,495 @@
+<template>
+  <div id="index">
+    <el-row>
+      <el-col :span="24" class="main animate__animated animate__backInRight" v-loading="loading">
+        <div class="w_1200">
+          <el-col :span="24" class="one">
+            <el-row :span="24" class="one_1">
+              <el-col :span="22" class="title">{{ info.name || '暂无标题' }}</el-col>
+              <el-col :span="2" class="file" @click="toCollection(0)" v-if="info.is_collection">
+                <el-icon :size="16"><StarFilled /></el-icon>
+                <span>已收藏</span>
+              </el-col>
+              <el-col :span="2" class="file" @click="toCollection(1)" v-else>
+                <el-icon :size="16"><Star /></el-icon>
+                <span>收藏</span>
+              </el-col>
+            </el-row>
+          </el-col>
+          <el-col :span="24" class="two">
+            <a-descriptions bordered>
+              <a-descriptions-item label="服务领域">
+                {{ info.field || '暂无服务领域' }}
+              </a-descriptions-item>
+              <a-descriptions-item label="登记时间">
+                {{ info.time || '暂无登记时间' }}
+              </a-descriptions-item>
+            </a-descriptions>
+          </el-col>
+          <el-col :span="24" class="thr">
+            <el-col :span="24" class="thr_1">
+              <p>单位信息</p>
+            </el-col>
+            <el-row :span="24" class="thr_2">
+              <el-col :span="17" class="left">
+                <el-col :span="24" class="name">
+                  {{ formatName(userInfo.name) || '暂无单位' }}
+                </el-col>
+                <el-col :span="24" class="other">
+                  <span>联系人</span>
+                  {{ formatName(userInfo.name) || '暂无联系人' }}
+                </el-col>
+              </el-col>
+              <el-col :span="4" class="right" v-if="info.status == '1'">
+                <a-button type="primary" @click="toChat">
+                  <template #icon>
+                    <MessageOutlined />
+                  </template>
+                  点击在线洽谈
+                </a-button>
+              </el-col>
+            </el-row>
+          </el-col>
+          <a-divider />
+          <el-col :span="24" class="four">
+            <el-col :span="24" class="four_1">
+              <p>服务详情</p>
+            </el-col>
+            <el-col :span="24" class="four_2">{{ info.brief || '暂无' }}</el-col>
+          </el-col>
+          <el-col :span="24" class="four">
+            <el-col :span="24" class="four_1">
+              <p>相关推荐</p>
+            </el-col>
+            <el-col :span="24" class="four_3">
+              <a-list :loading="loading" :grid="{ gutter: 16, column: 4 }" :data-source="list">
+                <template #renderItem="{ item }">
+                  <el-col :span="24" class="list">
+                    <el-col :span="24" class="name textOver">
+                      <el-tooltip effect="dark" :content="item.name" placement="top">
+                        {{ item.name || '暂无名称' }}
+                      </el-tooltip>
+                    </el-col>
+                    <el-col :span="24" class="two_1">
+                      <span>行业领域:</span>{{ getDict(item.field, 'field') }}
+                    </el-col>
+                    <el-col :span="24" class="two_1">
+                      <span>需求地区:</span>{{ getArea(item.area) }}
+                    </el-col>
+                    <el-col :span="24" class="two_1">
+                      <span>单位:</span> {{ formatName(item.userName) || '暂无单位' }}
+                    </el-col>
+                    <el-col :span="24" class="bottom">
+                      <a-button size="small" type="primary" @click="toView(item)">
+                        查看详情
+                      </a-button>
+                    </el-col>
+                  </el-col>
+                </template>
+              </a-list>
+              <el-col :span="24" class="page">
+                <el-pagination
+                  background
+                  layout="total, prev, pager, next"
+                  :page-sizes="[10, 20, 50, 100, 200]"
+                  :total="total"
+                  :page-size="limit"
+                  v-model:current-page="currentPage"
+                  @current-change="changePage"
+                  @size-change="sizeChange"
+                >
+                </el-pagination>
+              </el-col>
+            </el-col>
+          </el-col>
+        </div>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import moment from 'moment'
+// 基础
+import { MessageOutlined } from '@ant-design/icons-vue'
+import { get } from 'lodash-es'
+const $checkRes = inject('$checkRes')
+// 接口
+import { DemandStore } from '@/store/api/platform/demand'
+import { CollectionStore } from '@/store/api/platform/collection'
+import { DictDataStore } from '@/store/api/system/dictData'
+const store = DemandStore()
+const dictDataStore = DictDataStore()
+const collectionStore = CollectionStore()
+
+import { UserStore } from '@/store/user'
+const userStore = UserStore()
+const user = computed(() => userStore.user)
+// 路由
+const route = useRoute()
+const router = useRouter()
+// 加载中
+const loading = ref(false)
+const info = ref({
+  key: '1',
+  name: '长春市XXX有限公司',
+  field: '科技金融',
+  time: '2020-07-01'
+})
+const userInfo = ref({})
+// 字典表
+const methodList = ref([])
+const urgentList = ref([])
+const fieldList = ref([])
+const demandList = ref([])
+// 成果列表
+const list = ref([])
+let skip = 0
+let limit = inject('limit')
+const total = ref(0)
+// 请求
+onMounted(async () => {
+  loading.value = true
+  await searchOther()
+  await search()
+  await searchAchieve({ skip, limit })
+  loading.value = false
+})
+const search = async () => {
+  let id = route.query.id
+  if (id) {
+    // let res = await store.detail(id)
+    // if (res.errcode == '0') {
+    //   info.value = res.data
+    //   userInfo.value = res.data.userInfo
+    // }
+  }
+}
+const searchAchieve = async (query = { skip: 0, limit }) => {
+  const info = {
+    skip: query.skip,
+    limit: query.limit,
+    is_use: '0',
+    status: '1'
+  }
+  const res = await store.list(info)
+  if (res.errcode == '0') {
+    list.value = res.data
+    total.value = res.total
+  }
+}
+const searchOther = async () => {
+  // let result
+  // // 合作方式
+  // result = await dictDataStore.query({ code: 'method', is_use: '0' })
+  // if ($checkRes(result)) methodList.value = result.data
+  // // 需求紧急度
+  // result = await dictDataStore.query({ code: 'urgent', is_use: '0' })
+  // if ($checkRes(result)) urgentList.value = result.data
+  // // 技术领域
+  // result = await dictDataStore.query({ code: 'field', is_use: '0' })
+  // if ($checkRes(result)) fieldList.value = result.data
+}
+// 字典数据转换
+const getDict = (data, model) => {
+  let res
+  if (model == 'method') res = methodList.value.find((f) => f.value == data)
+  else if (model == 'urgent') res = urgentList.value.find((f) => f.value == data)
+  else if (model == 'field') res = fieldList.value.find((f) => f.value == data)
+  else if (model == 'demand') res = demandList.value.find((f) => f.value == data)
+  return get(res, 'label')
+}
+// 时间
+const getTime = (data) => {
+  if (data) return `${data[0]} 至 ${data[1]}`
+}
+// 地区
+const getArea = (data) => {
+  if (data) return data.join(',')
+  else return '暂无地区'
+}
+// 在线洽谈
+const toChat = () => {
+  router.push({ path: '/chat', query: { id: info.value.user } })
+}
+// 我要对接
+const toDocking = () => {
+  console.log('我要对接')
+}
+// 收藏
+const toCollection = async (status) => {
+  if (user.value._id) {
+    let res
+    let message
+    const data = {
+      user: user.value._id,
+      source: info.value._id,
+      type: 'demand',
+      time: moment().format('YYYY-MM-DD')
+    }
+    if (status == '1') {
+      message = '收藏成功'
+      res = await collectionStore.create(data)
+    } else {
+      message = '取消收藏成功'
+      res = await collectionStore.cancel(data)
+    }
+    if (res.errcode === 0) {
+      ElMessage({
+        message,
+        type: 'success'
+      })
+      await search()
+    }
+  } else {
+    ElMessage({
+      message: '未登录无法进行收藏 请登录',
+      type: 'warning'
+    })
+  }
+}
+// 查看
+const toView = (item) => {
+  router.push({ path: '/demand/detail', query: { id: item.id || item._id } })
+}
+const formatName = (str) => {
+  if (str) return str.substr(0, 1) + new Array(str.length).join('*')
+}
+const currentPage = ref(1)
+// 分页
+const changePage = (page = currentPage.value) => {
+  searchAchieve({ skip: (page - 1) * limit, limit: limit })
+}
+const sizeChange = (limits) => {
+  console.log(limits)
+  limit = limits
+  currentPage.value = 1
+  searchAchieve({ skip: 0, limit: limit })
+}
+</script>
+<style scoped lang="scss">
+.main {
+  .one {
+    margin: 10px 0 0 0;
+    background: #f7f7f7;
+    padding: 24px;
+    border-top: 6px solid #2374ff;
+    overflow: hidden;
+    border-radius: 0 0 5px 5px;
+
+    .one_1 {
+      margin: 0 0 10px 0;
+
+      .title {
+        font-size: 18px;
+        font-weight: 700;
+        color: #383b40;
+      }
+
+      .file {
+        display: flex;
+        align-items: center;
+        justify-content: flex-end;
+        font-family: PingFangSC-Regular;
+        font-size: 14px;
+        color: #2374ff;
+        text-align: right;
+        span {
+          margin: 0 0 0 5px;
+        }
+      }
+    }
+
+    .one_2 {
+      display: inline-block;
+      font-size: 12px;
+      background: rgba(18, 172, 117, 0.05);
+      color: #12ac75;
+      padding: 0 15px;
+      height: 20px;
+      line-height: 20px;
+      border-radius: 10px;
+      margin-bottom: 2px;
+    }
+  }
+
+  .two {
+    background: #f9fafb;
+    border-radius: 2px;
+    padding: 30px;
+    margin: 34px 0 20px;
+    font-family: PingFangSC-Medium;
+    font-size: 14px;
+    color: #383b40;
+    line-height: 14px;
+  }
+
+  .thr {
+    margin: 0 0 10px 0;
+
+    .thr_1 {
+      width: 100%;
+      height: 40px;
+      line-height: 40px;
+      border-bottom: 2px solid #2374ff;
+      margin: 20px 0;
+      background: #f7f7f7;
+
+      p {
+        float: left;
+        padding: 0 20px;
+        height: 40px;
+        border-bottom: 2px solid #2374ff;
+        color: #fff;
+        font-size: 18px;
+        background: #2374ff;
+      }
+    }
+
+    .thr_2 {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      background: #fff;
+      border: 1px solid #edeff2;
+      box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.03);
+      border-radius: 2px;
+      padding: 30px 20px;
+
+      .left {
+        .name {
+          height: 20px;
+          font-family: PingFangSC-Semibold;
+          font-size: 18px;
+          color: #383b40;
+          line-height: 20px;
+          font-weight: 700;
+          margin-bottom: 8px;
+        }
+
+        .other {
+          height: 14px;
+          font-family: PingFangSC-Medium;
+          font-size: 14px;
+          color: #383b40;
+          line-height: 14px;
+          font-weight: 700;
+
+          span {
+            height: 14px;
+            font-family: PingFangSC-Regular;
+            font-size: 14px;
+            color: #7e8288;
+            line-height: 14px;
+            font-weight: 400;
+            margin-right: 10px;
+          }
+        }
+      }
+
+      .right {
+        display: flex;
+        justify-content: space-between;
+      }
+    }
+  }
+
+  .four {
+    margin: 0 0 10px 0;
+
+    .four_1 {
+      width: 100%;
+      height: 40px;
+      line-height: 40px;
+      border-bottom: 2px solid #2374ff;
+      margin: 20px 0;
+      background: #f7f7f7;
+
+      p {
+        float: left;
+        padding: 0 20px;
+        height: 40px;
+        border-bottom: 2px solid #2374ff;
+        color: #fff;
+        font-size: 18px;
+        background: #2374ff;
+      }
+    }
+    .four_3 {
+      margin: 20px;
+
+      .list {
+        border: 1px solid #edeff2;
+        background: #fff;
+        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.03);
+        border-radius: 2px;
+        width: 280px;
+        height: 180px;
+        margin-bottom: 15px;
+        cursor: pointer;
+        transition: all 0.3s;
+        padding: 15px;
+        .name {
+          font-size: 16px;
+          color: #121834;
+          height: 16px;
+          line-height: 13px;
+          font-weight: 500;
+          margin: 10px 0;
+        }
+
+        .name:hover {
+          color: #2374ff;
+        }
+
+        .two_1 {
+          font-size: 12px;
+          text-align: justify;
+          line-height: 12px;
+          font-weight: 400;
+          letter-spacing: 0;
+          color: #8f97a3;
+          margin-top: 15px;
+
+          span:last-child {
+            color: #525a68;
+          }
+        }
+        .bottom {
+          margin: 10px 0 0 0;
+          text-align: right;
+        }
+      }
+
+      .list:hover {
+        background: #f0f7ff;
+        box-shadow: 0 0 16px rgba(205, 205, 205, 0.6);
+      }
+
+      .page {
+        display: flex;
+        flex-direction: row-reverse;
+        padding: 20px;
+      }
+    }
+  }
+  .pointer {
+    display: flex;
+    align-items: center;
+    justify-content: flex-end;
+    font-family: PingFangSC-Regular;
+    font-size: 14px;
+    color: #7e8288;
+    margin: 10px 0 0 0;
+    .money {
+      margin: 0 10px 0 0;
+      span {
+        font-family: PingFangSC-Semibold;
+        font-size: 20px;
+        color: #e94643;
+        line-height: 20px;
+      }
+    }
+  }
+}
+</style>