From 7113b4f2dd47a313c6fbc85c21f4756da42b212a Mon Sep 17 00:00:00 2001 From: queenwuli <942534046@qq.com> Date: Mon, 11 Jan 2021 17:06:18 +0800 Subject: [PATCH] gx --- hive-app/common/jssdk/utils.js | 9 + hive-app/App.vue | 2 hive-app/pages/workbench/followRecords/index.vue | 240 +++++++++++++++++++++----- hive-app/pages/manager/employeeReport.vue | 3 hive-app/pages/manager/selectEmployee.vue | 64 +++++-- hive-app/pages/member/selectCustomer.vue | 62 ++++-- hive-app/pages/member/editMember.vue | 8 hive-app/pages/workbench/followRecords/filter.vue | 139 ++++++++++++--- 8 files changed, 408 insertions(+), 119 deletions(-) diff --git a/hive-app/App.vue b/hive-app/App.vue index fa35cba..d7a3683 100644 --- a/hive-app/App.vue +++ b/hive-app/App.vue @@ -23,5 +23,5 @@ /*每个页面公共css */ @import url("./common/styles/index"); @import url("./static/iconfont/iconfont.css"); -@import url("//at.alicdn.com/t/font_2263696_ghdgvj09btt.css"); +@import url("//at.alicdn.com/t/font_2263696_djh7biga0an.css"); </style> diff --git a/hive-app/common/jssdk/utils.js b/hive-app/common/jssdk/utils.js index bb9b196..9f3c75b 100644 --- a/hive-app/common/jssdk/utils.js +++ b/hive-app/common/jssdk/utils.js @@ -126,6 +126,15 @@ var time = date.getFullYear() + "-" + month + "-" + day return time; }, + // 比较两个日期大小, 若第一个日期大于第二个日期,返回true + compareData(prev, next){ + let oDate1 = new Date(prev); + let oDate2 = new Date(next); + if(oDate1.getTime() > oDate2.getTime()){ + return true + } + return false + }, // 加密账号 encryptAccount(val) { if (/^1[3456789]\d{9}$/.test(val)) { diff --git a/hive-app/pages/manager/employeeReport.vue b/hive-app/pages/manager/employeeReport.vue index 89cca28..a9dfd21 100644 --- a/hive-app/pages/manager/employeeReport.vue +++ b/hive-app/pages/manager/employeeReport.vue @@ -245,7 +245,8 @@ } }) }, - setData(item){ + setData(selectItem){ + let item = selectItem[0]; this.staffId = item.id; this.reloadData(); setTimeout(() => { diff --git a/hive-app/pages/manager/selectEmployee.vue b/hive-app/pages/manager/selectEmployee.vue index 2750887..8eb2b5e 100644 --- a/hive-app/pages/manager/selectEmployee.vue +++ b/hive-app/pages/manager/selectEmployee.vue @@ -17,7 +17,7 @@ </view> <no-record :isShow="!list.length"></no-record> <view class="footer"> - <text>已选:{{selectId?1:0}}人</text> + <text>已选:{{selectItems.length?selectItems.length:0}}人</text> <button class="blue-btn btn mr-0" @click="confirm">确定</button> </view> </view> @@ -33,13 +33,18 @@ return { queryKey: '', list: [], - selectId: '', - selectName: '' + selectIds: '', + selectItems: [], + multiSelect: false, //单选/多选,默认多选 }; }, onLoad(options) { + // 选中的id,逗号分隔 if(options.selectId!='null'){ - this.selectId = options.selectId + this.selectIds = options.selectId + } + if(options.multiSelect){ + this.multiSelect = new Boolean(options.multiSelect); } this.loadMemberList() }, @@ -54,8 +59,13 @@ }, 'POST').then((res) => { if(res.status == 200){ this.list = res.rows.map((item) => { - if(this.selectId && this.selectId == item.id){ - this.selectName = item.name + let index = this.selectItems.findIndex((op) => { + return op.id == item.id + }); + if(this.selectIds && this.selectIds.indexOf(item.id) > -1){ + if(index == -1){ + this.selectItems.push(item); + } return Object.assign(item, {isCheck: true}) } return Object.assign(item, {isCheck: false}) @@ -64,26 +74,42 @@ }) }, checkOnchange(item){ + if(this.multiSelect){ + this.multiChange(item) + }else{ + this.singChange(item) + } + }, + singChange(item){ if(!item.isCheck){ - this.list.forEach((item) => { - item.isCheck = false; + this.list.forEach((op) => { + op.isCheck = false; }); - item.isCheck = true - this.selectId = item.id; - this.selectName = item.name; + item.isCheck = true; + this.selectItems = [item]; }else{ item.isCheck = false; - this.selectId = ''; - this.selectName = ''; + this.selectItems = []; + } + }, + multiChange(item){ + let index = this.selectItems.findIndex((op) => { + return op.id == item.id + }); + if(!item.isCheck){ + item.isCheck = true; + this.selectItems.push(item); + }else{ + item.isCheck = false; + this.selectItems.splice(index,1); } }, confirm(){ - let pages = getCurrentPages(); - let prevPage = pages[ pages.length - 2 ]; - prevPage.$vm.setData && prevPage.$vm.setData({ - name: this.selectName, - id: this.selectId - }); + let pages = getCurrentPages(); + let prevPage = pages[ pages.length - 2 ]; + if(this.selectItems.length){ + prevPage.$vm.setData && prevPage.$vm.setData(this.selectItems); + } uni.navigateBack() } }, diff --git a/hive-app/pages/member/editMember.vue b/hive-app/pages/member/editMember.vue index 53619ca..fc4d83e 100644 --- a/hive-app/pages/member/editMember.vue +++ b/hive-app/pages/member/editMember.vue @@ -258,9 +258,11 @@ this.isDisabled = false; }) }, - setData(item){ - this.recommendName = item.name; - this.formData.recommendId = item.id; + setData(selectItem){ + selectItem.forEach((item) => { + this.recommendName = item.vipName; + this.formData.recommendId = item.id; + }); } } } diff --git a/hive-app/pages/member/selectCustomer.vue b/hive-app/pages/member/selectCustomer.vue index f452697..df1f8a7 100644 --- a/hive-app/pages/member/selectCustomer.vue +++ b/hive-app/pages/member/selectCustomer.vue @@ -20,7 +20,7 @@ </view> <no-record :isShow="!list.length"></no-record> <view class="footer"> - <text>已选:{{selectId?1:0}}人</text> + <text>已选:{{selectItems.length?selectItems.length:0}}人</text> <button class="blue-btn btn mr-0" @click="confirm">确定</button> </view> </view> @@ -37,13 +37,18 @@ colors: ['#CCC6B4', '#C0CCB4', '#B4C2CC', '#BEB4CC', '#B4CCBE', '#B4CCCA', '#CCB4C6', '#CCB4B4'], queryKey: '', list: [], - selectId: '', - selectName: '' + selectIds: '', + selectItems: [], + multiSelect: false, //单选/多选,默认多选 }; }, onLoad(options) { + // 选中的id,逗号分隔 if(options.selectId!='null'){ - this.selectId = options.selectId + this.selectIds = options.selectId + } + if(options.multiSelect){ + this.multiSelect = new Boolean(options.multiSelect); } this.loadMemberList() }, @@ -61,8 +66,13 @@ }, 'POST').then((res) => { if(res.status == 200){ this.list = res.rows.map((item) => { - if(this.selectId && this.selectId == item.id){ - this.selectName = item.vipName + let index = this.selectItems.findIndex((op) => { + return op.id == item.id + }); + if(this.selectIds && this.selectIds.indexOf(item.id) > -1){ + if(index == -1){ + this.selectItems.push(item); + } return Object.assign(item, {isCheck: true}) } return Object.assign(item, {isCheck: false}) @@ -71,26 +81,42 @@ }) }, checkOnchange(item){ + if(this.multiSelect){ + this.multiChange(item) + }else{ + this.singChange(item) + } + }, + singChange(item){ if(!item.isCheck){ - this.list.forEach((item) => { - item.isCheck = false; + this.list.forEach((op) => { + op.isCheck = false; }); - item.isCheck = true - this.selectId = item.id; - this.selectName = item.vipName; + item.isCheck = true; + this.selectItems = [item]; }else{ item.isCheck = false; - this.selectId = ''; - this.selectName = ''; + this.selectItems = []; + } + }, + multiChange(item){ + let index = this.selectItems.findIndex((op) => { + return op.id == item.id + }); + if(!item.isCheck){ + item.isCheck = true; + this.selectItems.push(item); + }else{ + item.isCheck = false; + this.selectItems.splice(index,1); } }, confirm(){ let pages = getCurrentPages(); - let prevPage = pages[ pages.length - 2 ]; - prevPage.$vm.setData && prevPage.$vm.setData({ - name: this.selectName, - id: this.selectId - }); + let prevPage = pages[ pages.length - 2 ]; + if(this.selectItems.length){ + prevPage.$vm.setData && prevPage.$vm.setData(this.selectItems); + } uni.navigateBack() } }, diff --git a/hive-app/pages/workbench/followRecords/filter.vue b/hive-app/pages/workbench/followRecords/filter.vue index 39e1745..9fb48c8 100644 --- a/hive-app/pages/workbench/followRecords/filter.vue +++ b/hive-app/pages/workbench/followRecords/filter.vue @@ -5,19 +5,21 @@ <view class="popup-content"> <view class="filter-content-time"> <text>开始时间</text> - <picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange"> - <view class="gray flex align-center"> - <text>请选择</text> - <text class="iconfont iconarrow-backimg"></text> + <picker mode="date" @change="bindStartTimeChange" :end="endDate"> + <view class=" flex align-center"> + <text v-if="startTime">{{startTime}}</text> + <text v-else class="gray">请选择</text> + <text class="iconfont iconarrow-backimg gray"></text> </view> </picker> </view> <view class="filter-content-time"> <text>结束时间</text> - <picker mode="date" :value="date" :start="startDate" :end="endDate" @change="bindDateChange"> - <view class="gray flex align-center"> - <text>请选择</text> - <text class="iconfont iconarrow-backimg"></text> + <picker mode="date" @change="bindEndTimeChange" :start="startTime" :end="endDate"> + <view class="flex align-center"> + <text v-if="endTime">{{endTime}}</text> + <text v-else class="gray">请选择</text> + <text class="iconfont iconarrow-backimg gray"></text> </view> </picker> </view> @@ -26,9 +28,13 @@ <text>客户</text> </view> <view class="img-box"> - <image class="header-img mr-20" src="../../../static/images/default-avatar.png"></image> - <navigator url="../../member/selectCustomer" hover-class="none"> - <text class="iconfont iconjia gray-outline-btn-circle ml-5"></text> + <view v-for="item in vipList" class="flex align-center flex-v mr-10"> + <image v-if="item.photo" class="header-img" :src="item.photo"></image> + <text v-else class="first-name">{{item.vipName | formatName}}</text> + <text class="font-12 gray ellipsis">{{item.vipName || '-'}}</text> + </view> + <navigator :url="'../../member/selectCustomer?multiSelect=true&selectId='+vipIds" hover-class="none"> + <text class="iconfont iconjia gray-outline-btn-circle ml-5" :class="vipList.length?'mb-20':''"></text> </navigator> </view> </view> @@ -37,16 +43,20 @@ <text>员工</text> </view> <view class="img-box"> - <image class="header-img mr-20" src="../../../static/images/default-avatar.png"></image> - <navigator url="../../manager/selectEmployee" hover-class="none"> - <text class="iconfont iconjia gray-outline-btn-circle ml-5"></text> + <view v-for="item in staffList" class="flex align-center flex-v mr-10"> + <image v-if="item.photo" class="header-img" :src="item.photo"></image> + <text v-else class="first-name">{{item.name | formatName}}</text> + <text class="font-12 gray ellipsis">{{item.name || '-'}}</text> + </view> + <navigator :url="'../../manager/selectEmployee?multiSelect=true&selectId='+staffIds" hover-class="none"> + <text class="iconfont iconjia gray-outline-btn-circle ml-5" :class="staffList.length?'mb-20':''"></text> </navigator> </view> </view> </view> <view class="btn-group"> - <button class="white-btn flex-1">重置</button> - <button class="blue-btn flex-1 ml-10">确定</button> + <button class="white-btn flex-1" @click="_reset()">重置</button> + <button class="blue-btn flex-1 ml-10" @click="_confirm()">确定</button> </view> </view> </uni-popup> @@ -60,14 +70,22 @@ uniPopup, DateTimePicker }, - data() { - return{ - windowHeight: "200px", - } - }, props:{ isShow: { default: false + }, + staffList: { + default: [] + }, + vipList: { + default:[] + } + }, + data() { + return{ + windowHeight: "200px", + startTime: '', + endTime: '' } }, watch:{ @@ -79,15 +97,60 @@ } } }, + computed:{ + vipIds(){ + let idArr = this.vipList.map((item) => { + return item.id; + }); + return idArr.join(',') + }, + staffIds(){ + let idArr = this.staffList.map((item) => { + return item.id; + }); + return idArr.join(',') + } + }, + created() { + this.endDate = this.$utils.formmatTime('YY-mm-dd') + }, mounted() { uni.getSystemInfo({ success: (res) => { this.windowHeight = res.windowHeight+"px"; - } }) + }}) }, methods:{ - showTime () { - this.$refs['date-time'].show(); + bindStartTimeChange(e){ + this.startTime = e.detail.value; + if(this.$utils.compareData(this.startTime, this.endTime)){ + this.endTime = ''; + } + }, + bindEndTimeChange(e){ + this.endTime = e.detail.value; + }, + _reset(){ + this.startTime = ''; + this.endTime = ''; + this.$emit('reset') + this.$refs.popup.close() + }, + _confirm(){ + this.$refs.popup.close(); + this.$emit('change', { + startTime: this.startTime, + endTime: this.endTime + }) + } + }, + filters:{ + formatName(val){ + if(!val){ + return '无' + } + val = val.trim(); + return val.substr(0, 1) } } } @@ -107,21 +170,43 @@ justify-content: space-between; border-bottom: 1px solid #EDEAF4; padding: 10px 0; + font-size: 14px; } .filter-content-row{ padding: 10px 0; + font-size: 14px; border-bottom: 1px solid #EDEAF4; } .img-box{ display: flex; + flex-wrap: wrap; align-items: center; - padding: 0 10px; margin-top: 10px; } .header-img{ - width: 45px; - height: 45px; + width: 42px; + height: 42px; border-radius: 50%; + margin-bottom: 5px; + } + .first-name{ + display: inline-block; + width: 42px; + height: 42px; + line-height: 42px; + margin-bottom: 5px; + border-radius: 50%; + text-align: center; + background: #518EFF; + color: #FFFFFF; + font-size: 16px; + } + .ellipsis{ + max-width: 40px; + overflow: hidden; + text-overflow:ellipsis; + white-space: nowrap; + margin-bottom: 6px; } .btn-group{ display: flex; diff --git a/hive-app/pages/workbench/followRecords/index.vue b/hive-app/pages/workbench/followRecords/index.vue index 5aec9b2..9ea4d6f 100644 --- a/hive-app/pages/workbench/followRecords/index.vue +++ b/hive-app/pages/workbench/followRecords/index.vue @@ -1,6 +1,6 @@ <template> <!-- 跟进记录 --> - <view> + <view class="container" @click="isShowComments = false"> <view> <h-tabs class="tab" @@ -13,60 +13,65 @@ fontSize: '28', underLineWidth: 60, }" - @tabClick="tabClick($event)" + @tabClick="changeType" /> </view> - <view class="content-row font-14" v-for="item in 2"> + <view class="content-row font-14" v-for="item in list"> <view class="flex align-center"> <image class="header-img" src="../../../static/images/default-avatar.png"></image> <view class="flex flex-v ml-10"> - <text>杨明</text> - <text>2020-12 12:34</text> + <text>{{item.staffName}}</text> + <text class="gray font-12">{{item.createTime}}</text> </view> </view> <view class="mt-10"> - <text>截图服务了杨姐,她的面部比较干燥暗沉色斑较多,约下次来做一个面部护理</text> + <text>{{item.content}}</text> </view> - <view class="mt-10 flex" :start="num"> - <image v-for="(item,index) in imgList" @click="previewImg(index)" class="content-img mr-10" :src="item"></image> + <view class="mt-10 mb-10 flex" :start="imgIndex"> + <image v-for="(op,index) in item.albums" @click="previewImg(item.albums,index)" class="content-img mr-10" :src="op.img"></image> </view> - <view class="flex align-center justify-between mt-5"> - <text>客户:杨依依</text> - <view class="flex align-center"> + <view class="flex align-center justify-between mt-5 gray font-13"> + <text>客户: {{item.vipName}}</text> + <view class="flex align-center" v-if="item.nextNotifyTime"> <text class="iconfont iconzhong mr-5"></text> - <text>2020-12-31 12:34</text> + <text>{{item.nextNotifyTime}}</text> </view> </view> - <view class="mt-5"> - <text>订单:面部护理等</text> + <view class="mt-5 gray font-13"> + <text>订单:{{item.orderAbstract}}</text> </view> <view class="right mt-5"> - <text class="iconfont iconxin"></text> - <text class="iconfont iconliuyan1 ml-20" @click="showMessage"></text> + <text class="iconfont" :class="item.zans && item.zans.indexOf(userInfo.id)>-1?'red iconxin1':'iconxin2'" @click="thumbsUp(item)"></text> + <text class="iconfont iconliuyan1 ml-15" @click.stop="showComment(item.id)"></text> </view> - <view class="content-row-notes flex align-center blue"> - <text class="iconfont iconxin mr-10"></text> - <text>李贝,拉拉</text> + <view class="content-row-notes flex align-center blue" v-if="item.zanUsers && item.zanUsers.length"> + <text class="iconfont iconxin2 mr-10"></text> + <text v-for="(op, i) in item.zanUsers">{{op.suName}}<text v-if="i!=item.zanUsers.length-1">,</text></text> </view> - <view class="content-row-notes flex align-center blue"> - <text>李贝: 好的,继续跟进</text> + <view class="content-row-notes blue" v-if="item.followupComments && item.followupComments.length"> + <view v-for="op in item.followupComments">{{op.createBy}}: {{op.content}}</view> </view> </view> - <fillter :isShow="isShowFilter" @change="changeFilter"></fillter> - <view v-show="messageShow" class="message-row"> - <input type="text" cursor-spacing="10" :focus="messageShow" class="message-input" placeholder="评论" placeholder-class="placeholder"/> - <button class="green-btn message-btn">发送</button> + <view v-if="list.length"> + <uni-load-more :status="loadStatus" color="#a5abaf"></uni-load-more> </view> + <view v-if="isShowComments" class="message-row" @click.stop=""> + <input type="text" v-model="comment" cursor-spacing="10" :focus="isShowComments" class="message-input" placeholder="评论" placeholder-class="placeholder"/> + <button class="green-btn message-btn" :disabled="!comment" @click="addFollowupComment">发送</button> + </view> + <fillter :isShow="isShowFilter" :staffList="staffList" :vipList="vipList" @reset="resetFilter" @change="changeFilter"></fillter> </view> </template> <script> import HTabs from "@/components/liuyuno-tabs/liuyuno-tabs.vue"; import fillter from './filter' + import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue'; export default { components: { HTabs, - fillter + fillter, + uniLoadMore }, data() { return { @@ -84,40 +89,162 @@ name: '我的团队' } ], - imgList:[ - '../../../static/images/banner.jpg', - '../../../static/images/product.jpg' - ], - messageShow:false, + type: 1, + list: [], + imgIndex: 0, + isShowComments:false, isShowFilter: false, - num:0 + pageNum: 0, + loadStatus: 'more', + userInfo: {}, + comment: '', + follId: '', + staffList: [], + vipList: [], + startTime: '', + endTime: '' } }, + onNavigationBarButtonTap(e){ + if(e.index==0){ + uni.navigateTo({ + url:"./addRecord" + }) + } + if(e.index==1){ + this.isShowFilter = !this.isShowFilter; + } + }, + onLoad() { + this.getUserInfo() + this.reloadList() + }, + onPullDownRefresh(){ + this.reloadData(); + let timer = setTimeout(function () { + uni.startPullDownRefresh(); + clearTimeout(timer); + timer = null; + }, 800); + }, + onReachBottom(){ + this.loadList() + }, methods:{ + getUserInfo(){ + let roleInfo = this.$httpUtils.getRoleInfo(); + if(roleInfo){ + this.userInfo = roleInfo; + } + }, + reloadList(){ + this.pageNum = 0; + this.loadStatus = 'more'; + this.loadList(true) + }, + loadList(isRest){ + if(this.loadStatus!=='more'){ + return; + } + let staffIds = this.staffList.map((item) => { + return item.id; + }); + let vipIds = this.vipList.map((item) => { + return item.id; + }); + this.$httpUtils.request('/api/followup/findFollowup', { + startTime: this.startTime, + endTime: this.endTime, + limit: 10, + offset: this.pageNum, + queryType: this.type, + staffIds: staffIds, + vipIds: vipIds + }, 'POST').then((res) => { + if(res.status == 200){ + let result = res.rows; + if(result.length < 10){ + this.loadStatus = 'noMore'; + } else { + this.pageNum ++ ; + this.loadStatus = 'more'; + } + if(isRest){ + this.list = result + }else{ + this.list = this.list.concat(result); + } + } + }) + }, + changeType(index){ + this.type = index+1; + this.reloadList() + }, // 预览图片 - previewImg(index) { - // let imgArr=[] - // imgArr.push(image) - //预览图片 + previewImg(imgList, index) { + if(!imgList.length){ + return; + } + this.imgIndex = index; + imgList = imgList.map((item) => { + return item.img; + }); uni.previewImage({ - urls: this.imgList, - indicator:'default', + urls: imgList, + indicator: 'default', loop:true }) }, - onNavigationBarButtonTap(e){ - if(e.index==0){ - uni.navigateTo({ - url:"./addRecord" - }) - } - if(e.width && e.index==1){ - this.isShowFilter = !this.isShowFilter; + // 点赞 + thumbsUp(item){ + this.$httpUtils.request('/api/followup/zanFollowup/'+item.id).then((res) => { + if(res.status == 200){ + this.reloadList() + } + }) + }, + // 评论 + addFollowupComment(){ + this.$httpUtils.request('/api/followup/addFollowupComment', { + follId: this.follId, + content: this.comment + }, 'POST').then((res) => { + if(res.status == 200){ + this.reloadList(); + this.isShowComments = false; + this.comment = ''; + }else{ + this.$toast.info(res.info) + } + }) + }, + showComment(id){ + this.follId = id; + this.isShowComments=true; + }, + setData(selectItem){ + let pages = getCurrentPages(); + let prevPage = pages[ pages.length - 1 ]; + if(prevPage.route.indexOf('selectCustomer') > -1){ + this.vipList = selectItem; + }else{ + this.staffList = selectItem; } }, - showMessage(){ - this.messageShow=!this.messageShow + // 重置筛选条件 + resetFilter(){ + this.startTime = ''; + this.endTime = ''; + this.staffList = []; + this.vipList = []; + this.reloadList(); }, + changeFilter(data){ + this.startTime = data.startTime; + this.endTime = data.endTime; + this.reloadList(); + } } } </script> @@ -125,6 +252,10 @@ <style> page{ background: #F6F6F8; + height: 100%; + } + .container{ + height: 100%; } .tab{ background: #FFFFFF; @@ -144,10 +275,11 @@ height: 80px; } .content-row-notes{ - line-height: 20px; + line-height: 22px; background: #F6F6F8; padding: 5px; - margin-top: 10px; + margin-top: 5px; + font-size: 13px; } .message-row{ display: flex; @@ -161,10 +293,18 @@ background: #FFFFFF; height: 30px; margin-right: 5px; + padding-left: 5px; + padding-right: 5px; } .message-btn{ margin: 0; line-height: 30px; border-radius: 0; + font-size: 14px; + } + uni-button[disabled]:not([type]), uni-button[disabled][type=default]{ + color: #FFFFFF; + background-color: rgb(31 183 19 / 0.4); + border: 0; } </style> -- Gitblit v1.9.1