|
@@ -0,0 +1,280 @@
|
|
|
|
+<template>
|
|
|
|
+ <ContentLayout class="project-info">
|
|
|
|
+ <div class="project-content-container">
|
|
|
|
+ <div class="project-header">
|
|
|
|
+ <div class="p-h-top">
|
|
|
|
+ <div class="p-h-title">{{ projectInfo.projectname }}</div>
|
|
|
|
+ <div class="p-h-actions" v-if="!isOver">
|
|
|
|
+ <el-button class="action-button" type="primary" icon="el-icon-jy-ai" @click="$router.push('/bidforecast')">中标企业预测</el-button>
|
|
|
|
+ <el-button class="action-button" type="primary" icon="el-icon-jy-analysis" @click="$router.push('/bidpolicy')">投标决策分析</el-button>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="p-h-bottom">
|
|
|
|
+ <div class="action-follow" @click="clickFollowButton">
|
|
|
|
+ <span :class="{
|
|
|
|
+ 'el-icon-jy-heart_solid': projectContent.isfollow,
|
|
|
|
+ 'el-icon-jy-heart_stroke': !projectContent.isfollow
|
|
|
|
+ }"></span>
|
|
|
|
+ <span class="text">{{ projectContent.isfollow ? '已关注' : '关注项目' }}</span>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="project-content">
|
|
|
|
+ <el-card class="project-content">
|
|
|
|
+ <div slot="header" class="p-h-title">项目摘要</div>
|
|
|
|
+ <div class="p-c-table">
|
|
|
|
+ <div class="p-c-row">
|
|
|
|
+ <div class="p-c-column">地区</div>
|
|
|
|
+ <div class="p-c-column">{{ projectInfo.area }} {{ projectInfo.city }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="p-c-row">
|
|
|
|
+ <div class="p-c-column">招标代理机构</div>
|
|
|
|
+ <div class="p-c-column">{{ projectInfo.agency ? projectInfo.agency : ' - ' }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="p-c-row">
|
|
|
|
+ <div class="p-c-column">采购单位</div>
|
|
|
|
+ <div class="p-c-column highlight-text">{{ projectInfo.buyer ? projectInfo.buyer : ' - ' }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="p-c-row">
|
|
|
|
+ <div class="p-c-column">采购联系人</div>
|
|
|
|
+ <div class="p-c-column">{{ projectInfo.buyerperson ? projectInfo.buyerperson : ' - ' }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="p-c-row">
|
|
|
|
+ <div class="p-c-column">采购电话</div>
|
|
|
|
+ <div class="p-c-column">{{ projectInfo.buyertel ? projectInfo.buyertel : ' - ' }}</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </el-card>
|
|
|
|
+ <el-card class="project-content">
|
|
|
|
+ <div slot="header" class="p-h-title">项目公告</div>
|
|
|
|
+ <div class="p-c-main">
|
|
|
|
+ <TimeLine :stepList="timeLineList" />
|
|
|
|
+ </div>
|
|
|
|
+ </el-card>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </ContentLayout>
|
|
|
|
+</template>
|
|
|
|
+
|
|
|
|
+<script>
|
|
|
|
+import { Card, Button } from 'element-ui'
|
|
|
|
+import ContentLayout from '@/components/common/ContentLayout.vue'
|
|
|
|
+import TimeLine from '@/components/time-line/TimeLine.vue'
|
|
|
|
+import { getFollowProjectDetail, followProjectAdd, followProjectCancel } from '@/api/modules/'
|
|
|
|
+import { replaceKeyword, dateFormatter } from '@/utils'
|
|
|
|
+
|
|
|
|
+export default {
|
|
|
|
+ name: 'projectInfo',
|
|
|
|
+ components: {
|
|
|
|
+ [Card.name]: Card,
|
|
|
|
+ [Button.name]: Button,
|
|
|
|
+ ContentLayout,
|
|
|
|
+ TimeLine
|
|
|
|
+ },
|
|
|
|
+ data () {
|
|
|
|
+ return {
|
|
|
|
+ sid: '', // 信息id
|
|
|
|
+ fid: '', // 关注id
|
|
|
|
+ projectContent: {
|
|
|
|
+ isfollow: false, // 是否关注
|
|
|
|
+ bidopentime: 1601082000, // 开标时间
|
|
|
|
+ remind: false, // 是否提醒 1提醒 0不提醒
|
|
|
|
+ remindtime: '' // 提醒时间
|
|
|
|
+ },
|
|
|
|
+ projectInfo: {
|
|
|
|
+ agency: '', // 招标代理机构
|
|
|
|
+ area: '', // 项目省份
|
|
|
|
+ city: '', // 项目城市
|
|
|
|
+ projectcode: '', // 项目code
|
|
|
|
+ projectname: '', // 项目名称
|
|
|
|
+ bidopentime: 0, // 开标时间
|
|
|
|
+ buyer: '', // 采购单位
|
|
|
|
+ buyerperson: '', // 采购单位联系人
|
|
|
|
+ buyertel: '', // 采购电话
|
|
|
|
+ list: [
|
|
|
|
+ // {
|
|
|
|
+ // s_id: '', // 信息id
|
|
|
|
+ // s_title: '', // 信息
|
|
|
|
+ // bidamount: 0, // 中标金额
|
|
|
|
+ // budget: 0, // 预算
|
|
|
|
+ // l_publishtime: 0, // 发布时间
|
|
|
|
+ // s_toptype: '', // 一级类别
|
|
|
|
+ // s_subtype: '' // 二级类别(若一级类别为空,则展示二级)
|
|
|
|
+ // }
|
|
|
|
+ ]
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ computed: {
|
|
|
|
+ isOver () {
|
|
|
|
+ return this.projectContent.bidopentime * 1000 < +new Date()
|
|
|
|
+ },
|
|
|
|
+ timeLineList () {
|
|
|
|
+ return this.projectInfo.list.map(item => {
|
|
|
|
+ const s = {
|
|
|
|
+ s_id: item.s_id,
|
|
|
|
+ tags: []
|
|
|
|
+ }
|
|
|
|
+ if (item.l_publishtime) {
|
|
|
|
+ s.time = dateFormatter(item.l_publishtime * 1000, 'yyyy-MM-dd')
|
|
|
|
+ }
|
|
|
|
+ if (item.s_title) {
|
|
|
|
+ s.content = replaceKeyword(item.s_title, this.projectInfo.projectname, `<span class="highlight-text">${this.projectInfo.projectname}</span>`)
|
|
|
|
+ }
|
|
|
|
+ if (item.s_subtype) {
|
|
|
|
+ s.tags.push(item.s_subtype)
|
|
|
|
+ }
|
|
|
|
+ if (item.s_toptype) {
|
|
|
|
+ s.tags.push(item.s_toptype)
|
|
|
|
+ }
|
|
|
|
+ return s
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ created () {
|
|
|
|
+ const query = this.$route.query
|
|
|
|
+ this.sid = query.sid
|
|
|
|
+ this.fid = query.fid
|
|
|
|
+ this.getFollowPInfo()
|
|
|
|
+ },
|
|
|
|
+ methods: {
|
|
|
|
+ async getFollowPInfo () {
|
|
|
|
+ const { sid, fid } = this
|
|
|
|
+ const { data, error_code: code } = await getFollowProjectDetail({ sid, fid })
|
|
|
|
+ if (code === 0 && data) {
|
|
|
|
+ Object.assign(this.projectContent, data)
|
|
|
|
+ Object.assign(this.projectInfo, data.projectInfo)
|
|
|
|
+ this.filterData()
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ async clickFollowButton () {
|
|
|
|
+ const { sid, fid } = this
|
|
|
|
+ const { isfollow } = this.projectContent
|
|
|
|
+ if (isfollow) {
|
|
|
|
+ const { data, error_code: code } = await followProjectCancel({ sid, fid })
|
|
|
|
+ if (code === 0 && data) {
|
|
|
|
+ this.projectContent.isfollow = false
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ const { data, error_code: code } = await followProjectAdd({ sid })
|
|
|
|
+ if (code === 0 && data) {
|
|
|
|
+ this.projectContent.isfollow = true
|
|
|
|
+ this.fid = data
|
|
|
|
+ this.$router.replace({ path: this.$route.path, query: { sid: this.sid, fid: this.fid } })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ filterData () {
|
|
|
|
+ const getAreas = ['北京', '天津', '重庆', '上海']
|
|
|
|
+ if (getAreas.includes(this.projectInfo.area)) {
|
|
|
|
+ this.projectInfo.area = ''
|
|
|
|
+ } else {
|
|
|
|
+ this.projectInfo.area = `${this.projectInfo.area}省`
|
|
|
|
+ }
|
|
|
|
+ console.log(this.timeLineList)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</script>
|
|
|
|
+
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.project-info {
|
|
|
|
+ width: 1200px;
|
|
|
|
+}
|
|
|
|
+@include diy-icon('ai', 20, 20);
|
|
|
|
+@include diy-icon('analysis', 20, 20);
|
|
|
|
+@include diy-icon('heart_solid', 20, 20);
|
|
|
|
+@include diy-icon('heart_stroke', 20, 20);
|
|
|
|
+::v-deep {
|
|
|
|
+ .el-button+.el-button {
|
|
|
|
+ margin-left: 20px;
|
|
|
|
+ }
|
|
|
|
+ .el-card__header {
|
|
|
|
+ padding: 24px 40px 16px;
|
|
|
|
+ border: none;
|
|
|
|
+ }
|
|
|
|
+ .el-card__body {
|
|
|
|
+ padding: 0 40px 32px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.action-button {
|
|
|
|
+ height: 36px;
|
|
|
|
+ padding: 4px 16px;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ background-color: $color-text--highlight;
|
|
|
|
+ border-color: $color-text--highlight;
|
|
|
|
+}
|
|
|
|
+$border-color: #ececec;
|
|
|
|
+.p-c-table {
|
|
|
|
+ .p-c-row {
|
|
|
|
+ display: flex;
|
|
|
|
+ border-top: 1px solid $border-color;
|
|
|
|
+ border-bottom: 1px solid $border-color;
|
|
|
|
+ &:not(:first-of-type) {
|
|
|
|
+ border-top: none;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .p-c-column {
|
|
|
|
+ padding: 12px 16px;
|
|
|
|
+ border-left: 1px solid $border-color;
|
|
|
|
+ border-right: 1px solid $border-color;
|
|
|
|
+ line-height: 24px;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ &:nth-of-type(1) {
|
|
|
|
+ width: 180px;
|
|
|
|
+ color: #686868;
|
|
|
|
+ background-color: #F9FAFB;
|
|
|
|
+ }
|
|
|
|
+ &:nth-of-type(2) {
|
|
|
|
+ flex: 1;
|
|
|
|
+ }
|
|
|
|
+ &:not(:first-of-type) {
|
|
|
|
+ border-left: none;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.project-header {
|
|
|
|
+ padding: 18px 40px;
|
|
|
|
+ background-color: #fff;
|
|
|
|
+ box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
|
|
|
+ .p-h-top {
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ .p-h-title {
|
|
|
|
+ font-size: 24px;
|
|
|
|
+ color: #171826;
|
|
|
|
+ line-height: 36px;
|
|
|
|
+ }
|
|
|
|
+ .p-h-actions {
|
|
|
|
+ margin-left: 46px;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .p-h-bottom {
|
|
|
|
+ margin-top: 12px;
|
|
|
|
+ display: flex;
|
|
|
|
+ justify-content: flex-end;
|
|
|
|
+ .action-follow {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ .text {
|
|
|
|
+ margin-left: 4px;
|
|
|
|
+ color: #686868;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ line-height: 24px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+.project-content {
|
|
|
|
+ margin: 16px auto;
|
|
|
|
+ .p-h-title {
|
|
|
|
+ color: #1D1D1D;
|
|
|
|
+ font-size: 18px;
|
|
|
|
+ line-height: 28px;
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+</style>
|