You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

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