您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

714 行
18 KiB

  1. <template>
  2. <view class="box">
  3. <!-- 选择器 -->
  4. <view class="boxtittab">
  5. <view class="tabbox" @click="timeshow=true">
  6. {{ time }}
  7. <u-icon name="arrow-down" size="24" style="padding-left: 12rpx;"></u-icon>
  8. </view>
  9. <view class="tabbox" @click="deptshow=true">
  10. {{ dept}}
  11. <u-icon name="arrow-down" size="24" style="padding-left: 12rpx;"></u-icon>
  12. </view>
  13. <view class="tabbox" @click="guwenshow=true">
  14. {{ guwen}}
  15. <u-icon name="arrow-down" size="24" style="padding-left: 12rpx;"></u-icon>
  16. </view>
  17. </view>
  18. <view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view>
  19. <view class="boxzonglan" style="min-height: 400rpx;">
  20. <view class="zonglantitle">简报 <text @click="showDesc=true">统计说明</text></view>
  21. <view class="zonglanbox">
  22. <view class="grid" style="height: auto;" v-for="(item,index) in numlist" :key="index">
  23. <view class="audonum">{{item.name}}</view>
  24. <view class="num">{{item.firstnum||0}}</view>
  25. <view class="bottom">
  26. <view class="leftnum">对比:{{item.endnum||0}}</view>
  27. <view class="rightnum" :class="item.duibinum>0?'red':'green'">{{item.duibinum||0}}
  28. <image v-if="item.duibinum>0" src="https://static.quhouse.com/c4145f84cc3c49769ee2ec11465c085b.png" mode="" />
  29. <image v-else src="https://static.quhouse.com/c5dbf780e09a4da0b0bab2d7fa58accd.png" mode="" />
  30. </view>
  31. </view>
  32. </view>
  33. </view>
  34. </view>
  35. <!-- 统计说明 -->
  36. <view class="black-bg" v-if="showDesc" >
  37. <view class="tongjiDesc">
  38. <view class="tongji-title">统计说明</view>
  39. <view class="text">
  40. <view><text class="bold">平均需求挖掘率:</text>筛选时间内,有效接待中已标记顾问的需求挖掘执行率的平均值;</view>
  41. <view><text class="bold">未标记:</text>筛选时间内,有效接待中未标记顾问的接待数;</view>
  42. <view><text class="bold">有效接待:</text>筛选时间内,标记为有效的接待数,不包含待接单;</view>
  43. <view><text class="bold">未挖掘需求数:</text>筛选时间内,需求挖掘平均执行率为0的需求数;</view>
  44. </view>
  45. </view>
  46. <view class="close" @click="showDesc=false">X</view>
  47. </view>
  48. <view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view>
  49. <view class="single">
  50. <view class="title">
  51. <view class="title1">平均需求挖掘率趋势</view>
  52. </view>
  53. <view class="uchaserbox">
  54. <qiun-data-charts type="line" :chartData="lineOptsect" :opts="lineOpts" background="none"
  55. :ontouch="true" canvasId="wangxiaohuaerlingilingwuyiba2" :canvas2d="true" />
  56. </view>
  57. </view>
  58. <view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view>
  59. <view class="single">
  60. <view class="title">
  61. <view class="title1">平均需求挖掘分布</view>
  62. </view>
  63. <view class="uchaserbox">
  64. <qiun-data-charts
  65. type="ring"
  66. :chartData="ringChartData"
  67. :canvas2d="true"
  68. canvasId="ChartBoxIdwangxiaohuaerlingilingwuyiba1"
  69. :opts='opts'
  70. background="none" />
  71. </view>
  72. </view>
  73. <view style="width: 100%;height: 20rpx;background: #FAFAFA;"></view>
  74. <view class="single">
  75. <view class="title">
  76. <view class="title1">需求挖掘排名</view>
  77. </view>
  78. <view class="tabdada">
  79. <view class="tabth">
  80. <view>排名</view>
  81. <view>需求类型/挖掘执行接待数</view>
  82. <view>执行率</view>
  83. <view>操作</view>
  84. </view>
  85. <view v-if="total==0" style="color: #999999;width: 100%;height: 500rpx;line-height: 500rpx;text-align: center;" >暂无数据</view>
  86. <view class="tabtd" v-for="(item,i) in rankList" :key="i">
  87. <view>
  88. <image v-if="i==0" class="ranking" src="../../../static/images/ranking1.png" mode=""></image>
  89. <image v-else-if="i==1" class="ranking" src="../../../static/images/ranking2.png" mode=""></image>
  90. <image v-else-if="i==2" class="ranking" src="../../../static/images/ranking3.png" mode=""></image>
  91. <view class="ranking1" v-else>{{i+1}}</view>
  92. </view>
  93. <view class="u-line-1">{{item.name}}({{item.selected}})</view>
  94. <view>{{item.fraction}}%</view>
  95. <view @click="Toview(item,i)">查看</view>
  96. </view>
  97. </view>
  98. </view>
  99. <u-popup v-model="timeshow" mode="bottom">
  100. <view class="timeview" :style="{ color: activeTotal == 5 ? '#2B6EFF' : '#333333' }"
  101. @click="tabtimetap(5, '接待时间')">
  102. 全部</view>
  103. <view class="timeview" :style="{ color: activeTotal == 2 ? '#2B6EFF' : '#333333' }"
  104. @click="tabtimetap(2, '近7天')">
  105. 近7天</view>
  106. <view class="timeview" :style="{ color: activeTotal == 3 ? '#2B6EFF' : '#333333' }"
  107. @click="tabtimetap(3, '近15天')">
  108. 近15天</view>
  109. <view class="timeview" :style="{ color: activeTotal == 6 ? '#2B6EFF' : '#333333' }"
  110. @click="tabtimetap(6, '近30天')">
  111. 近30天</view>
  112. <view class="timeview" :style="{ color: activeTotal == 4 ? '#2B6EFF' : '#333333' }" @click="tabtimetap(4,'自定义')">
  113. 自定义</view>
  114. </u-popup>
  115. <u-calendar v-model="calendarShow" mode="range" @change="calendarTimeChange"></u-calendar>
  116. <u-select v-model="guwenshow" :list="staffList" @confirm="guwenCallback"
  117. :default-value='selindex'></u-select>
  118. <u-select v-model="deptshow" :list="teamList" @confirm="deptCallback"
  119. :default-value='selindex'></u-select>
  120. <!-- 加载组件 -->
  121. <loading v-model="LOADING"></loading>
  122. </view>
  123. </template>
  124. <script>
  125. var app = getApp();
  126. var config = require("../../../config");
  127. import loading from "@/components/loading/index.vue"
  128. export default {
  129. components: {
  130. loading
  131. },
  132. data() {
  133. return {
  134. selindex: '',
  135. guwenshow: false,
  136. timeshow: false,
  137. selectshow: false,
  138. deptshow: false,
  139. deptVal: '',
  140. huashuVal: '',
  141. guwenVal: '',
  142. // 筛选文字展示
  143. time: '近7天',
  144. dept: '部门',
  145. guwen: '顾问',
  146. huashu: '业务话术',
  147. showDesc: false,
  148. rankList: [],//排名列表
  149. ringChartData: {
  150. },
  151. // ring图 分布图
  152. opts: {
  153. rotate: false,
  154. rotateLock: false,
  155. color: ['#F8A12B','#07B79D','#E7483C','#2671E1'],
  156. padding: [5,5,5,5],
  157. dataLabel: true,
  158. legend: {
  159. show: true,
  160. position: "right",
  161. lineHeight: 25
  162. },
  163. title: {
  164. name: "",
  165. fontSize: 15,
  166. color: "#666666"
  167. },
  168. subtitle: {
  169. name: "",
  170. fontSize: 25,
  171. color: "#7cb5ec"
  172. },
  173. extra: {
  174. ring: {
  175. ringWidth: 60,
  176. activeOpacity: 0.5,
  177. activeRadius: 10,
  178. offsetAngle: 0,
  179. labelWidth: 15,
  180. border: false,
  181. borderWidth: 3,
  182. borderColor: "#FFFFFF"
  183. }
  184. }
  185. },
  186. activeTotal: 5,
  187. houseId: '',
  188. // hushuList: [],// 业务话术
  189. staffList: [],// 员工列表
  190. teamList: [],// 团队列表
  191. team: {
  192. value: '',
  193. label: ''
  194. },
  195. startDate: '',
  196. endDate: '',
  197. calendarShow: false,
  198. numlist: [{
  199. name: '平均需求挖掘率',
  200. firstnum: '',
  201. endnum: '',
  202. duibinum: '',
  203. setName: 'wordFraction'
  204. }, {
  205. name: '未挖掘需求',
  206. firstnum: '',
  207. endnum: '',
  208. duibinum: '',
  209. setName: 'noFinishWord'
  210. },
  211. {
  212. name: '有效接待',
  213. firstnum: '',
  214. endnum: '',
  215. duibinum: '',
  216. setName: 'activeCustomer'
  217. },
  218. {
  219. name: '未标记',
  220. firstnum: '',
  221. endnum: '',
  222. duibinum: '',
  223. setName: 'markAdvisor'
  224. },
  225. ],
  226. lineOptsect: {
  227. "categories": [],
  228. "series": [{
  229. "name": "起始时间",
  230. "data": []
  231. },{
  232. "name": "对比时间",
  233. "data": []
  234. }]
  235. },
  236. lineOpts: {
  237. yAxis: {
  238. data: [{
  239. max: 100,
  240. min: 0,
  241. }]
  242. }
  243. },
  244. };
  245. },
  246. onShow() {
  247. // 获取项目id
  248. this.houseId = uni.getStorageSync('buildingID').id;
  249. // 获取员工
  250. this.getStaffList()
  251. // 获取团队
  252. this.getSectionList()
  253. this.getdata()
  254. },
  255. onReady: function(){
  256. // 获取项目id
  257. this.houseId = uni.getStorageSync('buildingID').id;
  258. // 获取员工
  259. this.getStaffList()
  260. // 获取团队
  261. this.getSectionList()
  262. this.getdata()
  263. },
  264. methods: {
  265. getdata(){
  266. // 需求挖掘分析-简报
  267. this.wordMiningAnalyze()
  268. //需求挖掘排行
  269. this.getwordMiningRank()
  270. // 挖掘趋势图
  271. this.getwordMiningAnalyzePercentage()
  272. // 需求挖掘f分布图
  273. this.getRingData()
  274. },
  275. // 需求挖掘排行
  276. getwordMiningRank(){
  277. this.$u.post('/cusLvStatistics/wordMiningRank', {
  278. "houseId": this.houseId,
  279. "deptId": this.deptVal,
  280. "createUser": this.guwenVal,
  281. "dateType":this.activeTotal,
  282. "firstStartDate":!this.activeTotal?this.startDate:'',
  283. "firstEndDate":!this.activeTotal?this.endDate:''
  284. })
  285. .then(res => {
  286. // console.log(res)
  287. if(res.length){
  288. this.rankList = res.map(item=>{
  289. return {
  290. name: item.name,
  291. id: item.id,
  292. fraction: item.fraction,
  293. selected: item.selected
  294. }
  295. })
  296. }else{
  297. this.rankList = []
  298. }
  299. })
  300. },
  301. // 需求挖掘分布图
  302. getRingData(){
  303. this.$u.post('/cusLvStatistics/wordMiningAnalyzeFenbu', {
  304. "houseId": this.houseId,
  305. "deptId": this.deptVal,
  306. "createUser": this.guwenVal,
  307. "firstStartDate":!this.activeTotal?this.startDate:'',
  308. "firstEndDate":!this.activeTotal?this.endDate:'',
  309. "dateType":this.activeTotal
  310. })
  311. .then(res => {
  312. // console.log(res)
  313. this.ringChartData = { series: [
  314. {
  315. data: [
  316. {"name":"30%以下","value":res.a},
  317. {"name":"30%~50%","value":res.b},
  318. {"name":"50%~70%","value":res.c},
  319. {"name":"70%以上","value":res.d},
  320. ]
  321. }
  322. ]}
  323. })
  324. },
  325. //跳转到接待记录
  326. Toview(){
  327. uni.navigateTo({
  328. url: '/pages/center/records/index?refresh=refresh&activeTotal='+this.activeTotal+'&staTime='+ this.startDate + '&endTime'+this.endDate+'&validInvalid=0'
  329. });
  330. },
  331. // 需求挖掘分析-简报
  332. wordMiningAnalyze() {
  333. let params = {
  334. "houseId":this.houseId,
  335. "deptId": this.deptVal,
  336. "userId": this.guwenVal,
  337. "dateType": this.activeTotal,
  338. "firstStartDate":!this.activeTotal?this.startDate:'',
  339. "firstEndDate":!this.activeTotal?this.endDate:''
  340. }
  341. this.$u.post("/cusLvStatistics/wordMiningAnalyze",params).then(res => {
  342. // console.log(res.contrast)
  343. res.contrast.wordFraction = (res.contrast.wordFraction || 0) + '%'
  344. res.first.wordFraction = (res.first.wordFraction || 0) + '%'
  345. res.end.wordFraction = (res.end.wordFraction || 0) + '%'
  346. this.numlist.forEach(item => {
  347. item.duibinum = res.contrast[item.setName]
  348. item.endnum = res.end[item.setName]
  349. item.firstnum = res.first[item.setName]
  350. })
  351. })
  352. },
  353. // 获取员工列表
  354. getStaffList() {
  355. this.$u.post('/cusLvStatistics/selectAllAccountIdByHouseId', {
  356. houseId: this.houseId
  357. })
  358. .then(res => {
  359. // console.log(res)
  360. if(res.length){
  361. this.staffList = res.map(item => {
  362. return {
  363. label: item.name,
  364. value: item.accountId
  365. }
  366. })
  367. this.staffList.unshift({
  368. label: '全部',
  369. value: ''
  370. })
  371. }
  372. })
  373. },
  374. // 需求挖掘率趋势图
  375. getwordMiningAnalyzePercentage() {
  376. let categories1 = []
  377. let categories2 = []
  378. let categories3 = []
  379. this.$u.post('/cusLvStatistics/wordMiningAnalyzePercentage', {
  380. "houseId": this.houseId,
  381. "deptId": this.deptVal,
  382. "createUser": this.guwenVal,
  383. "dateType": this.activeTotal,
  384. "firstStartDate":!this.activeTotal?this.startDate:'',
  385. "firstEndDate":!this.activeTotal?this.endDate:''
  386. })
  387. .then(res => {
  388. if(res.first&&res.first.length){
  389. categories1 = res.first.map(item=> item.statDate.substring(0,10))
  390. this.lineOptsect.series[0].data=res.first.map(item=> item.wordFraction)
  391. }else{
  392. categories1= []
  393. this.lineOptsect.series[0].data = []
  394. }
  395. if(res.end&&res.end.length){
  396. this.lineOptsect.series[1].data=res.end.map(item=> item.wordFraction)
  397. categories2 = res.end.map(item => item.statDate.substring(0,10))
  398. }else{
  399. categories2 = []
  400. this.lineOptsect.series[1].data = []
  401. }
  402. for(let i=0;i<categories1.length;i++){
  403. categories3.push(categories1[i]+'/'+categories2[i])
  404. }
  405. // console.log(categories3)
  406. this.lineOptsect.categories = categories3
  407. })
  408. },
  409. // 获取团队列表
  410. getSectionList() {
  411. this.$u.post('/cusLvStatistics/findAllDeptIdByHouseId', {
  412. houseId: this.houseId
  413. })
  414. .then(res => {
  415. this.teamList = []
  416. if(res.length){
  417. this.teamList = res.map(item=> {
  418. return {
  419. label: item.deptName,
  420. value: item.deptId
  421. }
  422. })
  423. this.teamList.unshift({
  424. label: '全部',
  425. value: ''
  426. })
  427. }
  428. })
  429. },
  430. //时间切换
  431. tabtimetap(index, text) {
  432. if (index == 3) {
  433. this.calendarShow = true;
  434. this.activeTotal = null
  435. } else {
  436. this.activeTotal = index;
  437. this.endDate = ''
  438. this.startDate = ''
  439. this.time = text
  440. this.getdata()
  441. }
  442. this.timeshow = false
  443. },
  444. // 顾问选择
  445. guwenCallback(e){
  446. // console.log(e)
  447. this.guwenVal = e[0].value
  448. this.guwen = e[0].label
  449. this.getdata()
  450. },
  451. // 部门选择
  452. deptCallback(e){
  453. // console.log(e)
  454. this.deptVal = e[0].value
  455. this.dept = e[0].label
  456. this.getdata()
  457. },
  458. // 话术选择
  459. huashuCallback(e){
  460. // console.log(e)
  461. this.huashuVal = e[0].value
  462. this.huashu = e[0].label
  463. this.getdata()
  464. },
  465. //自定义时间
  466. calendarTimeChange(e) {
  467. // console.log(e.startDate, e.endDate)
  468. this.activeTotal = null;
  469. this.endDate = e.endDate
  470. this.startDate = e.startDate
  471. this.time = '自定义'
  472. this.getdata()
  473. }
  474. }
  475. };
  476. </script>
  477. <style lang="scss" scoped>
  478. .box {
  479. width: 100%;
  480. height: 100%;
  481. background: #FAFAFA;
  482. }
  483. //时间切换的样式
  484. .boxtittab {
  485. position: sticky;
  486. top: var(--window-top);
  487. z-index: 999;
  488. width: 100;
  489. height: 92rpx;
  490. background: #FFFFFF;
  491. border: 1px solid #E0E0E0;
  492. display: flex;
  493. align-items: center;
  494. .tabbox {
  495. flex: 1;
  496. height: 100%;
  497. text-align: center;
  498. line-height: 92rpx;
  499. color: #666666;
  500. font-size: 28rpx;
  501. overflow: hidden;
  502. text-overflow: ellipsis;
  503. display: -webkit-box;
  504. /* 将对象作为弹性伸缩盒子模型显示 */
  505. -webkit-line-clamp: 1;
  506. /* 控制最多显示几行 */
  507. -webkit-box-orient: vertical;
  508. /* 设置或检索伸缩盒对象的子元素的排列方式 */
  509. }
  510. }
  511. .timeview {
  512. height: 80rpx;
  513. line-height: 80rpx;
  514. width: 100%;
  515. text-align: center;
  516. border-bottom: 1px solid #F8F8F8;
  517. }
  518. .black-bg{
  519. position: fixed;
  520. background: rgba(0,0,0,0.6);
  521. left: 0;
  522. right: 0;
  523. top: 0;
  524. bottom: 0;
  525. display: flex;
  526. flex-direction: column;
  527. justify-content: center;
  528. align-items: center;
  529. z-index: 9999;
  530. .tongjiDesc{
  531. width: 80%;
  532. background: #FFFFFF;
  533. border-radius: 12rpx;
  534. padding: 30rpx;
  535. }
  536. .close{
  537. background: #fff;
  538. border-radius: 50%;
  539. width: 80rpx;
  540. height: 80rpx;
  541. margin-top: 30rpx;
  542. display: flex;
  543. justify-content: center;
  544. align-items: center;
  545. }
  546. .tongji-title{
  547. text-align: center;
  548. font-size: 30rpx;
  549. margin-bottom: 20rpx;
  550. }
  551. .text view{
  552. margin-bottom: 24rpx;
  553. }
  554. .bold{
  555. font-weight: bold;
  556. }
  557. }
  558. .grid:nth-child(1) {
  559. border-right: none;
  560. border-bottom: none;
  561. }
  562. .grid:nth-child(2) {
  563. border-bottom: none;
  564. }
  565. .grid:nth-child(3) {
  566. border-right: none;
  567. }
  568. .grid .bottom{
  569. display: flex;
  570. align-items: center;
  571. padding-left: 20rpx;
  572. margin: 10rpx 0 20rpx;
  573. .leftnum{
  574. height: 36rpx;
  575. font-size: 26rpx;
  576. font-family: PingFangSC-Regular, PingFang SC;
  577. font-weight: 400;
  578. color: #666666;
  579. line-height: 36rpx;
  580. margin-right: 20rpx;
  581. }
  582. .rightnum{
  583. height: 36rpx;
  584. font-size: 26rpx;
  585. font-family: PingFangSC-Semibold, PingFang SC;
  586. font-weight: 600;
  587. color: #666;
  588. line-height: 36rpx;
  589. display: flex;
  590. align-items: center;
  591. &.red{
  592. color: #E6273A;
  593. }
  594. &.green{
  595. color: #43CD80;
  596. }
  597. image{
  598. width: 18rpx;
  599. height: 14rpx;
  600. margin-left: 6rpx;
  601. }
  602. }
  603. }
  604. .zonglantitle{
  605. display: flex;
  606. justify-content: space-between;
  607. align-items: center;
  608. text{
  609. color: #666666;
  610. }
  611. }
  612. .uchaserbox{
  613. width: 100%;
  614. height: 500rpx;
  615. }
  616. .tabdada {
  617. width: 100%;
  618. height: 580rpx;
  619. overflow-y: auto;
  620. padding-bottom: 20rpx;
  621. .tabth {
  622. width: 100%;
  623. height: 28rpx;
  624. display: flex;
  625. font-size: 28rpx;
  626. line-height: 28rpx;
  627. color: #666666;
  628. margin-top: 28rpx;
  629. }
  630. .tabth>view:nth-of-type(1) {
  631. width: 10%;
  632. text-align: center;
  633. }
  634. .tabth>view:nth-of-type(2) {
  635. width: 46%;
  636. text-align: center;
  637. }
  638. .tabth>view:nth-of-type(3) {
  639. width: 22%;
  640. text-align: center;
  641. }
  642. .tabth>view:nth-of-type(4) {
  643. width: 22%;
  644. text-align: center;
  645. }
  646. .tabtd {
  647. width: 100%;
  648. height: 30rpx;
  649. display: flex;
  650. font-size: 26rpx;
  651. line-height: 30rpx;
  652. margin-top: 32rpx;
  653. }
  654. .tabtd>view:nth-of-type(1) {
  655. width: 10%;
  656. text-align: center;
  657. line-height: 30rpx;
  658. }
  659. .tabtd>view:nth-of-type(2) {
  660. width: 46%;
  661. max-width: 400rpx;
  662. text-align: center;
  663. color: #333333;
  664. }
  665. .tabtd>view:nth-of-type(3) {
  666. width: 22%;
  667. text-align: center;
  668. color: #333333;
  669. }
  670. .tabtd>view:nth-of-type(4) {
  671. width: 22%;
  672. text-align: center;
  673. color: #2671E2;
  674. }
  675. .ranking {
  676. width: 34rpx;
  677. height: 34rpx;
  678. }
  679. .ranking1 {
  680. width: 30rpx;
  681. height: 30rpx;
  682. background: #ECF1FF;
  683. color: #424D64;
  684. font-size: 18rpx;
  685. text-align: center;
  686. line-height: 30rpx;
  687. border-radius: 50%;
  688. margin: 0 auto;
  689. }
  690. .tabech {
  691. width: 100%;
  692. height: 600rpx;
  693. }
  694. }
  695. </style>