|
|
@@ -0,0 +1,509 @@
|
|
|
+<!--
|
|
|
+ * @Author: wanglj 471442253@qq.com
|
|
|
+ * @Date: 2022-12-26 09:30:47
|
|
|
+ * @LastEditors: liuzhenlin
|
|
|
+ * @LastEditTime: 2023-06-03 10:51:58
|
|
|
+ * @Description: file content
|
|
|
+ * @FilePath: \订单全流程管理系统\src\views\customer\inviteTenders\details.vue
|
|
|
+-->
|
|
|
+<template>
|
|
|
+ <div class="detail">
|
|
|
+ <div class="side-layout">
|
|
|
+ <div class="info">
|
|
|
+ <div class="title">
|
|
|
+ <p>招标</p>
|
|
|
+ <h3>
|
|
|
+ {{ detail.title }}
|
|
|
+ </h3>
|
|
|
+ </div>
|
|
|
+ <header>
|
|
|
+ <el-descriptions :colon="false" :column="7" direction="vertical">
|
|
|
+ <el-descriptions-item content-class-name="my-content" label="招标产品名称" label-class-name="my-label">
|
|
|
+ {{ detail.productName }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item content-class-name="my-content" label="发布招标日期" label-class-name="my-label">
|
|
|
+ {{ parseTime(detail.publishedTime, '{y}-{m}-{d}') }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item content-class-name="my-content" label="项目预算" label-class-name="my-label">
|
|
|
+ {{ detail.budget }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item content-class-name="my-content" label="客户名称" label-class-name="my-label">
|
|
|
+ {{ detail.cuctName }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item content-class-name="my-content" label="信息分类" label-class-name="my-label">
|
|
|
+ {{ bidInfoTypeOptions[detail.infoType] }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item content-class-name="my-content" label="中标单位" label-class-name="my-label">
|
|
|
+ {{ detail.bidder }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item content-class-name="my-content" label="创建招标日期" label-class-name="my-label">
|
|
|
+ {{ parseTime(detail.biddingTime, '{y}-{m}-{d}') }}
|
|
|
+ </el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </header>
|
|
|
+ <el-tabs v-model="activeName" @tab-click="handleClick">
|
|
|
+ <el-tab-pane label="跟进记录" name="follow">
|
|
|
+ <ul v-if="followList.length" class="follow">
|
|
|
+ <li v-for="(date, index) in followList" :key="index">
|
|
|
+ <div class="date">
|
|
|
+ <h2>{{ date.followDay.split('-')[2] }}</h2>
|
|
|
+ <h3>
|
|
|
+ {{ date.followDay.split('-').splice(0, 2).join('.') }}
|
|
|
+ </h3>
|
|
|
+ </div>
|
|
|
+ <ul class="content">
|
|
|
+ <li v-for="(item, idx) in date.followupList" :key="idx">
|
|
|
+ <!-- <el-avatar class="user-avatar"
|
|
|
+ :src="avatar" />-->
|
|
|
+ <div class="text-container">
|
|
|
+ <vab-icon class="user-avatar" icon="account-circle-fill" />
|
|
|
+ <div class="text">
|
|
|
+ <p class="action">
|
|
|
+ <span>{{ item.createdName }} 跟进({{ formatType(item.followType) }})</span>
|
|
|
+ <span>
|
|
|
+ <vab-icon icon="time-line" />
|
|
|
+ {{ item.followDate }}
|
|
|
+ </span>
|
|
|
+ </p>
|
|
|
+ <p>{{ item.followContent }}</p>
|
|
|
+ <div class="footer">
|
|
|
+ <p>
|
|
|
+ 来自客户:
|
|
|
+ <span>{{ item.custName }}</span>
|
|
|
+ </p>
|
|
|
+ <div>
|
|
|
+ <el-button size="mini" @click="showDetail(item)">
|
|
|
+ <vab-icon icon="arrow-right-circle-fill" />
|
|
|
+ 详情
|
|
|
+ </el-button>
|
|
|
+ <el-button size="mini" @click="showComment(item)">评论({{ item.commentNumber }})</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <transition name="height">
|
|
|
+ <ul v-if="item.showComment" class="comments">
|
|
|
+ <li v-for="comment in item.comments" :key="comment.id">
|
|
|
+ <vab-icon class="user-avatar" icon="account-circle-fill" />
|
|
|
+ <div class="text">
|
|
|
+ <p>{{ comment.createdName }}</p>
|
|
|
+ <p>{{ comment.content }}</p>
|
|
|
+ <p>{{ comment.createdTime }}</p>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </transition>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ <div v-else class="no-follow">暂无跟进记录</div>
|
|
|
+ </el-tab-pane>
|
|
|
+ </el-tabs>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 跟进详情 -->
|
|
|
+ <FollowDetail ref="followDetail" />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import follow from '@/api/customer/follow'
|
|
|
+ import to from 'await-to-js'
|
|
|
+ import FollowDetail from '../components/FollowDetail.vue'
|
|
|
+ import bidApi from '@/api/customer/bid'
|
|
|
+
|
|
|
+ export default {
|
|
|
+ name: 'CustomerDetail',
|
|
|
+ components: {
|
|
|
+ FollowDetail,
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ id: '',
|
|
|
+ detail: {
|
|
|
+ custCode: '', //客户编码
|
|
|
+ abbrName: '', //助记名
|
|
|
+ level: '', //客户级别
|
|
|
+ indusTry: '', //客户类型
|
|
|
+ custStatus: '', //客户状态
|
|
|
+ followUpDate: '', //最后跟进时间
|
|
|
+ },
|
|
|
+ activeName: 'follow',
|
|
|
+ followList: [],
|
|
|
+ bidInfoTypeOptions: {},
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.id = this.$route.query.id
|
|
|
+ this.init()
|
|
|
+ this.handleClick({ name: 'follow' })
|
|
|
+ this.getOptions()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getOptions() {
|
|
|
+ this.getDicts('bid_info_type').then((response) => {
|
|
|
+ this.bidInfoTypeOptions = {}
|
|
|
+ response.data.values.filter((i) => {
|
|
|
+ this.bidInfoTypeOptions[i.key] = i.value
|
|
|
+ })
|
|
|
+ })
|
|
|
+ },
|
|
|
+ async init() {
|
|
|
+ const [err, res] = await to(bidApi.get({ id: parseInt(this.id) }))
|
|
|
+ if (err) return
|
|
|
+ if (res.code == 200) {
|
|
|
+ this.detail = res.data
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ async handleClick(tab) {
|
|
|
+ let err, res
|
|
|
+ if (tab.name == 'follow') {
|
|
|
+ let params = {
|
|
|
+ targetId: '' + this.id,
|
|
|
+ targetType: '60',
|
|
|
+ DaysBeforeToday: 99999,
|
|
|
+ }
|
|
|
+ ;[err, res] = await to(follow.getListByDay(params))
|
|
|
+ if (err) return
|
|
|
+ this.followList = res.data.list || []
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ formatType(val) {
|
|
|
+ let str = ''
|
|
|
+ if (val == 10) str = '电话'
|
|
|
+ else if (val == 20) str = '邮件'
|
|
|
+ else if (val == 30) str = '拜访'
|
|
|
+ return str
|
|
|
+ },
|
|
|
+ // 跟进记录详情
|
|
|
+ showDetail(row) {
|
|
|
+ this.$refs.followDetail.init({ ...row })
|
|
|
+ },
|
|
|
+ // 展开评论
|
|
|
+ showComment(row) {
|
|
|
+ if (!row.comments.length) return this.$message.warning('暂无评论')
|
|
|
+ row.showComment = !row.showComment
|
|
|
+ this.$forceUpdate()
|
|
|
+ },
|
|
|
+ },
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ $base: '.detail';
|
|
|
+ #{$base} {
|
|
|
+ height: calc(100vh - 60px - 12px * 2 - 40px);
|
|
|
+ display: flex;
|
|
|
+ padding: 20px 40px;
|
|
|
+
|
|
|
+ > .el-row {
|
|
|
+ flex: 1;
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ > .el-col {
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .title {
|
|
|
+ p,
|
|
|
+ h3 {
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ p {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 22px;
|
|
|
+ }
|
|
|
+
|
|
|
+ h3 {
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 36px;
|
|
|
+ color: #333;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ header {
|
|
|
+ height: 74px;
|
|
|
+ background: rgba(196, 196, 196, 0.5);
|
|
|
+ border-radius: 4px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 20px;
|
|
|
+ margin-top: 16px;
|
|
|
+
|
|
|
+ ::v-deep .el-descriptions__body {
|
|
|
+ background: transparent;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .my-label {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #1d66dc;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .my-content {
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #333;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-tabs {
|
|
|
+ height: calc(100% - 148px);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ ::v-deep .el-tabs__content {
|
|
|
+ flex: 1;
|
|
|
+
|
|
|
+ .el-tab-pane {
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ .el-descriptions {
|
|
|
+ table-layout: fixed;
|
|
|
+
|
|
|
+ .is-bordered {
|
|
|
+ table-layout: fixed;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .buttons {
|
|
|
+ padding-top: 28px;
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+
|
|
|
+ .records {
|
|
|
+ margin: 0;
|
|
|
+ padding: 10px 20px;
|
|
|
+ list-style: none;
|
|
|
+ height: calc(100% - 60px);
|
|
|
+ overflow-y: auto;
|
|
|
+
|
|
|
+ > li {
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+ & + li {
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .date {
|
|
|
+ width: 100px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ h2,
|
|
|
+ h3 {
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ h2 {
|
|
|
+ font-size: 26px;
|
|
|
+ line-height: 32px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ flex: 1;
|
|
|
+ list-style: none;
|
|
|
+
|
|
|
+ li {
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+ & + li {
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-avatar {
|
|
|
+ font-size: 40px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .text {
|
|
|
+ flex: 1;
|
|
|
+ padding-left: 20px;
|
|
|
+
|
|
|
+ p {
|
|
|
+ font-weight: 500;
|
|
|
+ margin: 0;
|
|
|
+ line-height: 20px;
|
|
|
+
|
|
|
+ span {
|
|
|
+ color: #1d66dc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ p:nth-child(2) {
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .action {
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .follow {
|
|
|
+ height: 100%;
|
|
|
+ padding: 10px 20px;
|
|
|
+ overflow: auto;
|
|
|
+
|
|
|
+ > li {
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+ + li {
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .date {
|
|
|
+ width: 100px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ h2,
|
|
|
+ h3 {
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ h2 {
|
|
|
+ font-size: 26px;
|
|
|
+ line-height: 32px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ flex: 1;
|
|
|
+ list-style: none;
|
|
|
+
|
|
|
+ > li {
|
|
|
+ border: 1px solid rgb(215, 232, 244);
|
|
|
+ background: rgb(247, 251, 254);
|
|
|
+ border-radius: 4px;
|
|
|
+ padding: 8px;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .text-container {
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+
|
|
|
+ .comments {
|
|
|
+ padding-left: 60px;
|
|
|
+ margin-top: 10px;
|
|
|
+ max-height: 190px;
|
|
|
+ overflow: auto;
|
|
|
+
|
|
|
+ li {
|
|
|
+ display: flex;
|
|
|
+ border-top: 1px solid #e3e5e7;
|
|
|
+
|
|
|
+ .text {
|
|
|
+ flex: 1;
|
|
|
+ padding: 0 10px;
|
|
|
+
|
|
|
+ p {
|
|
|
+ font-weight: 500;
|
|
|
+ margin: 0;
|
|
|
+ line-height: 32px;
|
|
|
+ }
|
|
|
+
|
|
|
+ p:first-child {
|
|
|
+ line-height: 30px;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+
|
|
|
+ p:last-child {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #9499a0;
|
|
|
+ text-align: right;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ + li {
|
|
|
+ margin-top: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .user-avatar {
|
|
|
+ font-size: 40px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .text {
|
|
|
+ flex: 1;
|
|
|
+ padding-left: 20px;
|
|
|
+ padding-right: 10px;
|
|
|
+
|
|
|
+ p {
|
|
|
+ font-weight: 500;
|
|
|
+ margin: 0;
|
|
|
+ line-height: 32px;
|
|
|
+
|
|
|
+ span {
|
|
|
+ color: #1d66dc;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .action {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+
|
|
|
+ span:first-child {
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .footer {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .no-follow {
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ font-size: 12px;
|
|
|
+ color: rgba(0, 0, 0, 0.65);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .height-enter-active,
|
|
|
+ .height-leave-active {
|
|
|
+ transition: all 0.5s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .height-enter-to,
|
|
|
+ .height-leave {
|
|
|
+ height: 190px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .height-enter, .height-leave-to /* .fade-leave-active below version 2.1.8 */ {
|
|
|
+ height: 0;
|
|
|
+ }
|
|
|
+</style>
|