123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895 |
- <template>
- <view
- class="activity-list">
- <view
- v-if="dropList.length > 0"
- class="drop-wrapper">
- <view class="btn-group">
- <view
- :class="{active: queryType === 1}"
- class="btn-group-item"
- @click="queryType = 1">
- 跟进记录
- </view>
- <view
- :class="{active: queryType === 2}"
- class="btn-group-item"
- @click="queryType = 2">
- {{ activityTitle }}动态
- </view>
- </view>
- <view
- v-if="dropItem&&queryType === 2"
- class="filter"
- @click="handleToFilter">
- <image :src="$static(dropItem.img)" mode="" class="pic" />
- <text class="text">
- {{ dropItem.label }}
- </text>
- <text class="wk wk-arrow-right icon" />
- </view>
- <view
- v-else
- class="filter"
- @click="handleToFilter">
- <text class="text">
- 筛选时间
- </text>
- <text class="wk wk-arrow-right icon" />
- </view>
- </view>
- <view class="list-container">
- <view
- v-if="listData.length === 0"
- :style="{backgroundImage: bgUrl('images/no_data.png'), height: contentHeight + 'px'}"
- class="no-data" />
- <template v-if="queryType === 1&&listOver">
- <view
- v-for="(item, index) in listData"
- :key="index"
- class="activity-item">
- <view
- v-if="item.createUser"
- class="user-info">
- <wk-avatar
- :name="item.createUser.realname"
- :avatar="item.createUser.img"
- :size="14"
- class="avatar" />
- <view class="info">
- <view class="username">
- {{ item.createUser.realname }}
- </view>
- <view class="text">
- {{ formatTime(item.createTime) }}
- </view>
- </view>
- <view
- v-if="item.category"
- class="category">
- {{ item.category }}
- </view>
- </view>
- <view
- v-if="item.type === 1"
- class="log-content content">
- <log-item :log-data="item" />
- </view>
- <view
- v-else-if="item.type === 2"
- class="record content">
- <text>{{ item.realname }}创建了{{ activityMap[item.activityType].label }}:</text>
- <text
- class="special"
- @click="handleToDetail(item)">
- {{ item.activityTypeName || '查看详情' }}
- </text>
- </view>
- <view
- v-else-if="item.type === 3"
- class="record content">
- <text>{{ item.realname }}将商机:</text>
- <text
- class="special"
- @click="handleToDetail(item)">
- {{ item.activityTypeName }}
- </text>
- <text>
- 阶段变更为{{ item.content }}
- </text>
- </view>
- <view
- v-else-if="item.type === 4"
- class="legwork-content content">
- <log-item :log-data="item" />
- <!-- <text>{{ item.realname }}拜访了{{ activityMap[item.activityType].label }}:</text>
- <text
- class="special"
- @click="handleToDetail(item)">
- {{ item.activityTypeName }}
- </text> -->
- </view>
- </view>
- </template>
- <template v-if="queryType === 2&&listOver">
- <view
- v-for="(item, index) in listData"
- :key="index"
- >
- <view
- v-if="getShow(item)"
- class="activity-item"
- >
- <view
- class="user-info">
- <wk-avatar
- :name="item.createUser.realname"
- :avatar="item.createUser.img"
- :size="14"
- class="avatar" />
- <view class="info">
- <view class="username">
- <view>
- {{ item.createUser.realname }}
- </view>
- <view v-if="dynamicName[item.activityType]" class="dynamic-name">
- 创建了{{ dynamicName[item.activityType] }}
- </view>
- </view>
- <view class="text">
- {{ formatTime(item.createTime) }}
- </view>
- </view>
- <view
- v-if="item.category"
- class="category">
- {{ item.category }}
- </view>
- </view>
- <activity-list-item
- :item-data="item"
- />
- </view>
- </view>
- </template>
- </view>
- <wk-drag-button
- v-if="!hiddenAdd && addAuth"
- @click="handleToggleCommand">
- <view class="wk-drag-btn">
- <text class="wk wk-edit-pen icon" />
- <text class="text">
- 写跟进
- </text>
- </view>
- </wk-drag-button>
- <uni-popup
- ref="popup"
- radius="10rpx 10rpx 0 0"
- type="actionsheet">
- <wk-action-sheet
- :list="popList"
- label="label"
- value="value"
- @select="handleCommand" />
- </uni-popup>
- <uni-popup
- ref="popupBottom"
- radius="24rpx 24rpx 0 0"
- type="bottom">
- <view class="filter-popup">
- <view class="popup-header">
- <view class="text">
- {{ queryType===1?'时间':'筛选' }}
- </view>
- <text class="wk wk-close icon" @click="handleCloseFilter" />
- </view>
- <view class="popup-content">
- <template v-if="queryType === 1&&listOver">
- <view
- class="filter-time">
- <view class="time-container">
- <view
- v-for="(item, index) in timeOptions"
- :key="index"
- :class="{ active: dateFilter === item.value }"
- class="box-item"
- @click=" dateFilter = item.value ">
- {{ item.label }}
- </view>
- <view class="box-item empty" />
- </view>
- <view
- v-if="dateFilter === 'custom'"
- class="defined-filter">
- <view
- class="start time-box"
- @click="handleChooseDate('startDate')">
- <image
- :src="$static('images/icon/calendar_gray.png')"
- class="calendar-icon" />
- <text v-if="filterDate.startDate">
- {{ filterDate.startDate }}
- </text>
- <text v-else class="wk-placeholder">
- 开始时间
- </text>
- </view>
- <text class="ident">
- --
- </text>
- <view
- :class="{ active: !!filterDate.endDate }"
- class="end time-box"
- @click="handleChooseDate('endDate')">
- <image
- :src="$static('images/icon/calendar_gray.png')"
- class="calendar-icon" />
- <text v-if="filterDate.endDate">
- {{ filterDate.endDate }}
- </text>
- <text v-else class="wk-placeholder">
- 结束时间
- </text>
- </view>
- </view>
- <uni-popup ref="popupDate" type="picker">
- <wk-date-picker
- v-model="timeValue"
- type="date"
- @select="handleSelectTime" />
- </uni-popup>
- </view>
- <view
- class="btn-group">
- <button class="button" @click="handleFilter({})">
- 确定
- </button>
- </view>
- </template>
- <template v-if="queryType === 2&&listOver">
- <view
- v-for="item in dropList"
- :key="item.value"
- class="popup-content__item"
- @click="handleFilter(item)">
- <image :src="$static(item.img)" class="pic" />
- <text class="text">
- {{ item.label }}
- </text>
- </view>
- </template>
- </view>
- </view>
- </uni-popup>
- </view>
- </template>
- <script>
- import {GetCrmActivityPageList} from 'API/crm/crmActivity'
- import LogItem from '@/components/base/log-item.vue'
- import ActivityListItem from './activityListItem.vue'
- import { isObject } from '@/utils/types.js'
- import moment from 'moment'
- export default {
- name: 'ActivityList',
- components: {
- LogItem,
- ActivityListItem
- },
- props: {
- detailId: {
- type: [Number, String],
- required: true
- },
- type: {
- type: String,
- required: true
- },
- hiddenAdd: {
- type: Boolean,
- default: false
- },
- activityTitle: {
- type: String,
- default: ''
- }
- },
- data() {
- return {
- dropValue: -1,
- queryType: 1,
- dateFilter: 'all',
- filterDate: {
- endDate: '',
- startDate: '',
- },
- timeValue: '',
- dateField: null,
- typeMap: {
- crm_leads: 1,
- crm_customer: 2,
- crm_contacts: 3,
- crm_product: 4,
- crm_business: 5,
- crm_contract: 6,
- crm_receivables: 7
- },
- timeOptions: [
- { label: '全部', value: 'all' },
- { label: '最近七天', value: 'previous7day' },
- { label: '最近三十天', value: 'previous30day' },
- { label: '最近六十天', value: 'previous60day' },
- { label: '自定义', value: 'custom' }
- ],
- activityMap: {
- 1: {label: '线索', icon: '', color: '', path: '/pages_crm/leads/detail'},
- 2: {label: '客户', icon: 'wk-customer', color: '#487DFF', path: '/pages_crm/customer/detail'},
- 3: {label: '联系人', icon: 'wk-contacts', color: '#27BA4A', path: '/pages_crm/contacts/detail'},
- 4: {label: '产品', icon: '', color: '', path: '/pages_crm/product/detail'},
- 5: {label: '商机', icon: 'wk-business', color: '#FB9323', path: '/pages_crm/business/detail'},
- 6: {label: '合同', icon: 'wk-contract', color: '#FD5B4A', path: '/pages_crm/contract/detail'},
- 7: {label: '回款', icon: 'wk-receivables', color: '#FFB940', path: '/pages_crm/receivables/detail'},
- 8: {label: '日志', icon: 'wk-log', color: '#5864FF', path: '/pages_log/detail'},
- 9: {label: '审批', icon: 'wk-approve', color: '#9376FF', path: '/pages_examine/detail'},
- // 10: {label: '日程', icon: '', color: '', path: '/oa/event/detail'},
- 11: {label: '任务', icon: 'wk-o-task', color: '#D376FF', path: '/pages_task/detail'},
- },
- listData: [],
- listOver: false,
- page: 0,
- contentHeight: 0,
- popList: [
- { label: '新增跟进记录', value: 'record' },
- { label: '新增外勤签到', value: 'legwork' }
- ],
- dynamicName: {
- 1: '线索',
- 2: '客户',
- 3: '联系人',
- 4: '产品',
- 5: '商机',
- 6: '合同',
- 7: '回款',
- 8: '日志',
- 9: '审批',
- 10: '日程',
- 11: '任务',
- // 发邮件
- 12: '',
- 14: '回款计划'
- }
- }
- },
- computed: {
- // 下拉选项
- dropList() {
- const lib = [
- {label: '全部', value: -1, img: 'images/application/all.png'},
- {label: '客户', value: 2, img: 'images/application/customer.png'},
- {label: '任务', value: 11, img: 'images/application/task.png'},
- {label: '商机', value: 5, img: 'images/application/business.png'},
- {label: '合同', value: 6, img: 'images/application/contract.png'},
- {label: '联系人', value: 3, img: 'images/application/contacts.png'},
- {label: '回款', value: 7, img: 'images/application/receivables.png'},
- {label: '日志', value: 8, img: 'images/application/worklog.png'},
- {label: '审批', value: 9, img: 'images/application/examine.png'}
- ]
- const map = {
- crm_customer: [-1, 2, 11, 5, 6, 3, 7, 8, 9],
- crm_contacts: [-1, 3, 11, 8, 9],
- crm_business: [-1, 5, 11, 8, 9, 6, 7],
- crm_contract: [-1, 6, 7, 11, 8, 9]
- }
- const arr = map.hasOwnProperty(this.type) ? map[this.type] : []
- if (arr.length === 0) return []
- return lib.filter(o => arr.includes(o.value))
- },
- addAuth() {
- return this.$auth('crm.followRecord.save')
- },
- dropItem() {
- return this.dropList.find(o => o.value === this.dropValue)
- }
- },
- watch: {
- queryType: {
- handler(val) {
- this.getList(true)
- },
- immediate: true
- }
- },
- mounted() {
- const that = this
- uni.createSelectorQuery()
- .in(this)
- .select('.list-container')
- .boundingClientRect(data => {
- // 计算无数据时填充区域高度
- const clientHeight = uni.getSystemInfoSync().windowHeight
- this.contentHeight = clientHeight - data.top - uni.upx2px(38)
- })
- .exec()
- this.getList()
- },
- methods: {
- bgUrl(val) {
- return `url(${this.$static(val)})`
- },
- formatTime(time) {
- if (!time) return ''
- return moment(time).format('YYYY-MM-DD HH:mm')
- },
-
- /**
- * 判断字段是否展示
- * @param item
- * @return {boolean}
- */
- getShow(item) {
- return isObject(item.content)
- },
- /**
- * 获取列表数据
- */
- getList(refresh = false) {
- if (this.loading) return
- this.loading = true
- if (refresh) {
- this.listOver = false
- this.page = 0
- }
- let activityType = this.dropValue || ''
- if (activityType === -1) activityType = ''
- let params = {
- crmType: this.typeMap[this.type],
- activityTypeId: this.detailId,
- queryType: this.queryType
- }
- if (
- this.queryType === 2
- ) {
- params.activityType = activityType || ''
- }
- if (
- !this.$isEmpty(this.dateFilter) &&
- this.dateFilter != 'all' &&
- this.queryType === 1
- ) {
- params.dateFilter = this.dateFilter
- if (this.dateFilter === 'custom' &&
- !this.$isEmpty(this.filterDate.endDate) &&
- !this.$isEmpty(this.filterDate.startDate)) {
- params = {
- ...params,
- ...this.filterDate
- }
- }
- }
-
- this.page++
- GetCrmActivityPageList({
- page: this.page,
- ...params
- }).then(res => {
- this.loading = false
- this.listOver = res.lastPage || res.list.length === 0
- if (this.page === 1) {
- this.listData = []
- }
- this.listData = this.listData.concat(res.list)
- this.$nextTick(() => {
- this.calcScrollStatus()
- })
- }).catch(() => {
- this.loading = false
- this.listOver = true
- this.listData = []
- })
- },
- /**
- * 去自定义选择时间
- * @param {Object} field
- */
- handleChooseDate(field) {
- this.timeValue = this.filterDate[field]
- this.dateField = field
- this.$refs.popupDate.open()
- },
- /**
- * 选择时间回调
- * @param {Object} date
- * @param {Object} next
- */
- handleSelectTime(date, next) {
- next()
- this.filterDate[this.dateField] = date
- let start = this.filterDate.startDate || null
- let end = this.filterDate.endDate || null
- if (start && end) {
- if (start > end) {
- this.filterDate[this.dateField] = ''
- this.$toast('开始时间不能大于结束时间')
- }
- }
- },
- handleToFilter() {
- this.$refs.popupBottom.open()
- },
- handleCloseFilter() {
- this.$refs.popupBottom.close()
- },
- handleFilter(item) {
- let start = this.filterDate.startDate || null
- let end = this.filterDate.endDate || null
- if (this.dateFilter === 'custom') {
- if (!start || !end) {
- return this.$toast('请选择时间')
- }
- }
-
- if (!this.$isEmpty(item)) {
- this.dropValue = item.value
- }
- this.handleCloseFilter()
- this.getList(true)
- },
- calcScrollStatus() {
- const that = this
- uni.createSelectorQuery()
- .select('.scroll-view-hook')
- .fields({
- size: true,
- scrollOffset: true
- }, data => {
- console.log('scroll-view-hook info: ', data)
- // 如果不能滚动,并且还有下一页数据则立即去加载下一页
- if (!that.listOver && data.height >= data.scrollHeight) {
- that.getList()
- }
- })
- .exec()
- },
- getNext() {
- if (this.listOver) return
- this.getList()
- },
- handleCommand(index, command, next) {
- if (next) {
- next()
- }
- if (command.value === 'record') {
- this.$Router.navigateTo({
- url: '/pages_crm/addRecord',
- query: {
- id: this.detailId,
- type: this.type
- }
- })
- } else if (command.value === 'legwork') {
- this.$Router.navigateTo({
- url: '/pages_oa/legwork/add',
- query: {
- customerId: this.detailId
- }
- })
- }
- },
- handleToggleCommand() {
- if (this.type !== 'crm_customer') {
- this.handleCommand(null, { value: 'record' }, null)
- return
- }
- this.$refs.popup.open()
- },
- handleToDetail(item) {
- if (item.type === 1) return
- let d = this.activityMap[item.activityType] || null
- if (!d) return;
- this.$Router.navigateTo({
- url: d.path,
- query: {
- id: item.activityTypeId
- }
- })
- }
- }
- }
- </script>
- <style scoped lang="scss">
- .activity-list {
- width: 100%;
- background-color: white;
- box-sizing: border-box;
- padding: 38rpx 32rpx;
- border-radius: 18rpx 18rpx 0 0;
- .drop-wrapper {
- width: 100%;
- margin-bottom: 15rpx;
- @include left;
- .btn-group {
- flex: 1;
- @include left;
- .btn-group-item {
- padding: 5rpx 10rpx;
- margin: 0 5rpx;
- font-size: $wk-font-sm;
- border-radius: 5rpx;
- &.active {
- background-color: #344563;
- color: white;
- }
- }
- }
- .filter {
- font-size: $wk-font-sm;
- @include right;
- .pic {
- width: 32rpx;
- height: 32rpx;
- margin-right: 10rpx;
- }
- .text {
- margin-right: 10rpx;
- }
- .icon {
- font-size: $wk-font-sm;
- transform: rotate(90deg);
- }
- }
- }
- .list-container {
- .activity-item {
- border-bottom: 1rpx solid $border-color !important;
- padding: 15rpx 0 20rpx !important;
- margin-bottom: 20rpx;
- &:last-child {
- border-bottom: 0 none;
- padding-bottom: 0;
- }
- .user-info {
- @include left;
- .avatar {
- width: 65rpx;
- height: 65rpx;
- }
- .info {
- flex: 1;
- margin-left: 16rpx;
- .username {
- font-size: $wk-font-base;
- color: #333;
- @include left;
- .dynamic-name {
- margin-left: 10rpx;
- }
- }
- .text {
- font-size: $wk-font-mini;
- color: $light;
- }
- }
- .category {
- font-size: $wk-font-mini;
- color: $light;
- background-color: #EEEEEE;
- border-radius: 5rpx;
- padding: 5rpx 15rpx;
- }
- }
- .content {
- font-size: 26rpx;
- color: #666;
- margin-top: 20rpx;
- padding-left: 10rpx;
- &.record, &.legwork-content {
- .special {
- color: $theme-color;
- }
- }
- }
- }
- }
- .wk-drag-btn {
- .icon {
- font-size: 30rpx;
- line-height: 1.2;
- }
- .text {
- font-size: 22rpx;
- }
- }
- .no-data {
- width: 100%;
- text-align: center;
- font-size: 26rpx;
- color: #BBBBBB;
- background-position: center 200rpx;
- background-repeat: no-repeat;
- background-size: 36%;
- }
- .filter-popup {
- padding: 36rpx;
- .popup-header {
- position: relative;
- @include center;
- .text {
- font-size: $wk-font-large;
- }
- .icon {
- position: absolute;
- left: 0;
- top: 50%;
- transform: translateY(-50%);
- color: $gray;
- font-size: $wk-font-medium;
- }
- }
- .popup-content {
- width: 100%;
- flex-wrap: wrap;
- margin-top: 38rpx;
- @include left;
- .btn-group {
- width: 100%;
- @include center;
- position: absolute;
- bottom: 0rpx;
- left: 0;
- right: 0;
- padding:0 38rpx 30rpx;
- background: white;
- border-top: 1px solid white;
- .button {
- flex: 1;
- height: 80rpx;
- color: white;
- font-size: $wk-font-base;
- background-color: $theme-color;
- border-radius: 12rpx;
- @include center;
- }
- }
- .popup-content__item {
- width: 17%;
- flex-direction: column;
- margin: 25rpx 4%;
- @include center;
- .pic {
- width: 60rpx;
- height: 60rpx;
- }
- .text {
- color: $dark;
- font-size: $wk-font-base;
- margin-top: 10rpx;
- }
- }
- .filter-time {
- flex: 1;
- width: 100%;
- height: 560rpx;
- .title {
- font-size: $wk-font-base;
- font-weight: bold;
- color: $dark;
- }
- .time-container {
- width: 100%;
- display: flex;
- justify-content: space-between;
- flex-wrap: wrap;
- .box-item {
- width: 32%;
- height: 60rpx;
- color: #666;
- font-size: $wk-font-base;
- background-color: #f4f4f4;
- border-radius: 10rpx;
- margin-top: 20rpx;
- @include center;
- &.active {
- color: $theme-color;
- background-color: #E7F0FF;
- }
- &.empty {
- visibility: hidden;
- }
- }
- }
- .defined-filter {
- font-size: $wk-font-base;
- margin-top: 25rpx;
- @include left;
- .time-box {
- flex: 1;
- text-align: center;
- border: 1rpx solid #E1E1E1;
- border-radius: 6rpx;
- padding: 10rpx 15rpx;
- @include left;
- &.active {
- color: #333;
- }
- .calendar-icon {
- width: 38rpx;
- height: 38rpx;
- margin-right: 10rpx;
- }
- .wk-placeholder {
- font-size: inherit;
- }
- }
- .ident {
- color: #CDCDCD;
- padding: 0 30rpx;
- }
- }
- }
- }
- }
- }
- </style>
|