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.
 
 
 

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