| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506 |
- <!--
- * @Author: wanglj 471442253@qq.com
- * @Date: 2022-12-15 15:38:21
- * @LastEditors: niezch@dashoo.cn
- * @LastEditTime: 2023-04-03 13:49:41
- * @Description: file content
- * @FilePath: \opms_frontend\src\views\customer\follow.vue
- -->
- <template>
- <div class="follow-container">
- <el-row :gutter="10" style="margin-bottom: 10px">
- <el-col :span="3">
- <el-input v-model="queryForm.custName" placeholder="客户" @keyup.enter.native="search" />
- </el-col>
- <!-- <el-col :span="4">
- <el-input v-model="queryForm.custName" placeholder="客户" />
- </el-col> -->
- <!-- <el-col :span="4">
- <el-input v-model.number="queryForm.daysBeforeToday" placeholder="查询天数">
- <template slot="append">天</template>
- </el-input>
- </el-col> -->
- <el-col :span="3">
- <el-select v-model="queryForm.followType" clearable placeholder="跟进方式" style="width: 100%">
- <el-option v-for="item in FollowTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
- </el-select>
- </el-col>
- <el-col :span="5">
- <!-- <el-select v-model="queryForm.targetType" clearable placeholder="跟进对象类型" style="width: 100%">
- <el-option v-for="item in targetTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
- </el-select> -->
- <el-input
- v-model="queryForm.targetName"
- class="input-with-select"
- clearable
- placeholder="跟进对象"
- @keyup.enter.native="search">
- <el-select v-model="queryForm.targetType" clearable placeholder="跟进对象类型" slot="prepend">
- <el-option v-for="item in targetTypeOptions" :key="item.key" :label="item.value" :value="item.key" />
- </el-select>
- </el-input>
- </el-col>
- <!-- <el-col :span="4">
- <el-input v-model.number="queryForm.targetName" placeholder="跟进对象" />
- </el-col> -->
- <el-col :span="3">
- <el-input v-model="queryForm.createdName" placeholder="跟进人" @keyup.enter.native="search" />
- </el-col>
- <el-col :span="6">
- <el-date-picker
- v-model="queryForm.date"
- end-placeholder="跟进结束时间"
- range-separator="至"
- start-placeholder="跟进开始时间"
- style="width: 100%"
- type="daterange"
- value-format="yyyy-MM-dd" />
- </el-col>
- <el-col :span="4">
- <el-button icon="el-icon-plus" type="primary" @click="search">查询</el-button>
- <!-- <el-button @click="addFollowUp">添加</el-button> -->
- <el-button icon="el-icon-refresh-right" @click="reset">重置</el-button>
- </el-col>
- </el-row>
- <div class="follow" :style="{ height: $baseTableHeight(0) }">
- <ul
- v-infinite-scroll="load"
- class="records infinite-list"
- :infinite-scroll-disabled="loadFlag"
- :infinite-scroll-immediate-check="false">
- <li v-for="(date, index) in records" :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" @click="showComment(item.id)">
- <!-- <el-avatar class="user-avatar"
- :src="avatar" />-->
- <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 class="content">
- <span>{{ item.followContent }}</span>
- </p>
- <div class="footer">
- <p>
- 来自{{ selectDictLabel(targetTypeOptions, item.targetType) }}:
- <span @click="jumpTo(item)">{{ item.targetName }}</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.id)">
- <!-- <vab-icon icon="chat-3-fill" /> -->
- 评论({{ item.commentNumber }})
- </el-button>
- </div>
- </div>
- </div>
- </li>
- </ul>
- </li>
- </ul>
- <div class="comment">
- <ul>
- <li v-for="item in comments" :key="item.id">
- <vab-icon class="user-avatar" icon="account-circle-fill" />
- <div class="text">
- <p>{{ item.createdName }}</p>
- <p>{{ item.content }}</p>
- <p>{{ item.createdTime }}</p>
- </div>
- </li>
- </ul>
- <div class="form">
- <el-input v-model="comment" maxlength="300" resize="none" :rows="5" show-word-limit type="textarea" />
- <el-button size="mini" type="primary" @click="handleComment">评论</el-button>
- </div>
- </div>
- </div>
- <!-- 跟进详情 -->
- <FollowDetail ref="followDetail" />
- </div>
- </template>
- <script>
- import to from 'await-to-js'
- import api from '@/api/customer/follow'
- import FollowDetail from './components/FollowDetail.vue'
- export default {
- name: 'Follow',
- components: {
- FollowDetail,
- },
- data() {
- return {
- listLoading: false,
- queryForm: {
- custId: '',
- custName: '',
- targetType: '',
- targetName: '',
- createdName: '',
- targetId: '',
- managerId: '',
- daysBeforeToday: 20,
- date: [],
- followType: '',
- },
- loadFlag: true,
- records: [],
- followId: '',
- comment: '',
- comments: [],
- visible: false,
- form: {
- id: '',
- followType: '',
- followDate: '',
- followContent: '',
- targetId: '',
- targetType: '',
- targetName: '',
- custId: '',
- custName: '',
- contactsId: 0,
- contactsName: '',
- reminders: '',
- nextTime: '',
- remark: '',
- createdBy: '',
- createdName: '',
- createdTime: '',
- updatedBy: '',
- updatedName: '',
- updatedTime: '',
- deletedTime: '',
- },
- targetTypeOptions: [],
- FollowTypeOptions: [],
- }
- },
- mounted() {
- this.fetchData()
- this.getOptions()
- this.getFollowOptions()
- },
- methods: {
- getOptions() {
- Promise.all([this.getDicts('follow_target_type')])
- .then(([targetType]) => {
- this.targetTypeOptions = targetType.data.values || []
- })
- .catch((err) => console.log(err))
- },
- //跟进类型
- getFollowOptions() {
- Promise.all([this.getDicts('plat_follow_method')])
- .then(([targetType]) => {
- this.FollowTypeOptions = targetType.data.values || []
- })
- .catch((err) => console.log(err))
- },
- search() {
- // this.queryForm.daysBeforeToday = 20
- this.fetchData()
- },
- async fetchData() {
- let params = { ...this.queryForm }
- if (this.queryForm.date && this.queryForm.date.length === 2) {
- params.beginTime = this.queryForm.date[0]
- params.endTime = this.queryForm.date[1]
- params.daysBeforeToday = undefined
- } else {
- params.daysBeforeToday = 20
- }
- const [err, res] = await to(api.getListByDay(params))
- if (err) return console.log(err, 'err')
- this.records = res.data.list || []
- await this.$nextTick()
- this.loadFlag = false
- if (this.records.length) {
- if (!this.followId) this.showComment(this.records[0].followupList[0].id)
- } else {
- this.comments = []
- this.followId = ''
- }
- },
- load() {
- this.queryForm.daysBeforeToday += 20
- this.fetchData()
- },
- reset() {
- this.queryForm = {
- custId: '',
- custName: '',
- targetType: '',
- targetName: '',
- createdName: '',
- targetId: '',
- managerId: '',
- daysBeforeToday: 20,
- date: [],
- followType: '',
- }
- this.fetchData()
- },
- jumpTo(row) {
- let pageName = ''
- switch (row.targetType) {
- case '10':
- pageName = 'CustomerDetail'
- break
- case '20':
- pageName = 'BusinessDetail'
- break
- case '30':
- pageName = 'ContractDetail'
- break
- case '40':
- pageName = ''
- break
- case '50':
- pageName = 'DistributorDetail'
- break
- }
- if (pageName) {
- this.$router.push({
- name: pageName,
- query: {
- id: row.targetId,
- },
- })
- }
- },
- // 详情
- showDetail(row) {
- this.$refs.followDetail.init({ ...row })
- },
- async showComment(id) {
- this.followId = id
- const [err, res] = await to(api.getComment({ followId: id + '' }))
- if (err) return
- this.comments = res.data.list || []
- },
- formatType(val) {
- let str = ''
- if (val == 10) str = '电话'
- else if (val == 20) str = '邮件'
- else if (val == 30) str = '拜访'
- return str
- },
- // 评论
- async handleComment() {
- let str = ''
- if (!this.followId) str = '请选择跟进记录'
- else if (!this.comment) str = '请输入评论'
- if (str) return this.$message.warning(str)
- let params = {
- followId: this.followId + '',
- content: this.comment,
- remark: '',
- }
- const [err, res] = await to(api.addComment(params))
- if (err) return
- this.$message.success(res.msg)
- this.showComment(this.followId)
- this.comment = ''
- this.fetchData()
- },
- addFollowUp() {
- let params = {
- followType: '20',
- followDate: '2022-10-29',
- followContent: '跟进内容',
- targetId: 1,
- targetType: '20',
- targetName: 'dashoo',
- custId: 26,
- custName: '测试客户1348',
- contactsId: 55,
- contactsName: 'wanglj',
- reminders: '',
- nextTime: this.parseTime(new Date()),
- remark: '',
- }
- api.addFollowUp(params)
- },
- },
- }
- </script>
- <style lang="scss" scoped>
- $base: '.follow';
- ::v-deep .el-input-group__prepend {
- width: 40%;
- }
- .follow {
- display: flex;
- .comment {
- width: 300px;
- display: flex;
- flex-direction: column;
- border-radius: 4px;
- border: 1px solid rgb(215, 232, 244);
- ul {
- flex: 1;
- overflow-y: auto;
- padding: 10px;
- li {
- display: flex;
- border-bottom: 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;
- }
- }
- }
- .user-avatar {
- font-size: 30px;
- }
- }
- .form {
- padding: 4px;
- text-align: right;
- .el-textarea {
- margin-bottom: 4px;
- }
- }
- }
- .records {
- flex: 1;
- margin: 0;
- height: 100%;
- padding: 10px 20px;
- list-style: none;
- 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 {
- display: flex;
- cursor: pointer;
- border: 1px solid rgb(215, 232, 244);
- background: rgb(247, 251, 254);
- border-radius: 4px;
- padding: 8px;
- + 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;
- }
- }
- .content {
- display: flex;
- justify-content: space-between;
- span {
- font-weight: bold;
- color: #333;
- }
- }
- .footer {
- display: flex;
- justify-content: space-between;
- align-items: center;
- }
- }
- }
- }
- }
- </style>
|