25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

637 satır
15 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" v-for="(item,index) in numlist" :key="index">
  30. <view class="audonum">{{item.name}}</view>
  31. <view class="num">{{item.num}}</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="wangxiaohuaerlingilingwuyiba1" :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 sortList" :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 == 4 ? '#2B6EFF' : '#333333' }"
  101. @click="tabtimetap(4, '近7天')">
  102. 近7天</view>
  103. <view class="timeview" :style="{ color: activeTotal == 5 ? '#2B6EFF' : '#333333' }"
  104. @click="tabtimetap(5, '近15天')">
  105. 近15天</view>
  106. <view class="timeview" :style="{ color: activeTotal == 6 ? '#2B6EFF' : '#333333' }"
  107. @click="tabtimetap(6, '近30天')">
  108. 近30天</view>
  109. <view class="timeview" :style="{ color: activeTotal == 3 ? '#2B6EFF' : '#333333' }" @click="tabtimetap(3,'自定义')">
  110. 自定义</view>
  111. </u-popup>
  112. <u-calendar v-model="calendarShow" mode="range" @change="calendarTimeChange"></u-calendar>
  113. <u-select v-model="guwenshow" :list="staffList" @confirm="staffSelectCallback($event,0)"
  114. :default-value='selindex'></u-select>
  115. <u-select v-model="deptshow" :list="teamList" @confirm="staffSelectCallback($event,1)"
  116. :default-value='selindex'></u-select>
  117. <!-- 加载组件 -->
  118. <loading v-model="LOADING"></loading>
  119. </view>
  120. </template>
  121. <script>
  122. var app = getApp();
  123. var config = require("../../../config");
  124. import loading from "@/components/loading/index.vue"
  125. export default {
  126. components: {
  127. loading
  128. },
  129. data() {
  130. return {
  131. selindex: '',
  132. guwenshow: false,
  133. timeshow: false,
  134. selectshow: false,
  135. deptshow: false,
  136. deptVal: '',
  137. guwenVal: '',
  138. // 筛选文字展示
  139. time: '近7天',
  140. dept: '部门',
  141. guwen: '顾问',
  142. huashu: '话术',
  143. showDesc: false,
  144. sortList: [],
  145. ringChartData: {
  146. },
  147. // ring图 分布图
  148. opts: {
  149. rotate: false,
  150. rotateLock: false,
  151. color: ["#1890FF","#91CB74","#FAC858","#EE6666"],
  152. padding: [5,5,5,5],
  153. dataLabel: true,
  154. legend: {
  155. show: true,
  156. position: "right",
  157. lineHeight: 25
  158. },
  159. title: {
  160. name: "",
  161. fontSize: 15,
  162. color: "#666666"
  163. },
  164. subtitle: {
  165. name: "",
  166. fontSize: 25,
  167. color: "#7cb5ec"
  168. },
  169. extra: {
  170. ring: {
  171. ringWidth: 60,
  172. activeOpacity: 0.5,
  173. activeRadius: 10,
  174. offsetAngle: 0,
  175. labelWidth: 15,
  176. border: false,
  177. borderWidth: 3,
  178. borderColor: "#FFFFFF"
  179. }
  180. }
  181. },
  182. activeTotal: 4,
  183. houseId: '',
  184. // 员工列表
  185. staffList: [],
  186. // 团队列表
  187. teamList: [],
  188. team: {
  189. value: '',
  190. label: ''
  191. },
  192. startDate: '',
  193. endDate: '',
  194. calendarShow: false,
  195. activeTab: 0,
  196. numlist: [{
  197. name: '平均需求挖掘率',
  198. num: '',
  199. setName: 'wordFraction'
  200. }, {
  201. name: '未挖掘需求',
  202. num: '',
  203. setName: 'noFinishWord'
  204. },
  205. {
  206. name: '有效接待',
  207. num: '',
  208. setName: 'activeCustomer'
  209. },
  210. {
  211. name: '未标记',
  212. num: '',
  213. setName: 'markAdvisor'
  214. },
  215. ],
  216. lineOptsect: {
  217. "categories": [],
  218. "series": [{
  219. "name": "第一段",
  220. "data": []
  221. },{
  222. "name": "第二段",
  223. "data": []
  224. }
  225. ]
  226. },
  227. Theteamcomparedisshow: false,
  228. Groupcontrastisshow: false,
  229. allList: [],
  230. lineOpts: {
  231. yAxis: {
  232. data: [{
  233. max: 100,
  234. min: 0,
  235. }]
  236. }
  237. },
  238. };
  239. },
  240. onShow() {
  241. // this.LOADING = true
  242. // 获取项目id
  243. this.houseId = uni.getStorageSync('buildingID').id;
  244. // 获取员工
  245. this.getStaffList()
  246. // 获取团队
  247. this.getSectionList()
  248. this.getdata()
  249. },
  250. onReady: function(){
  251. this.getRingData()
  252. },
  253. onPullDownRefresh() {
  254. },
  255. methods: {
  256. getdata(){
  257. // 需求挖掘分析-简报
  258. this.wordMiningAnalyze()
  259. // 挖掘趋势图
  260. this.getwordMiningAnalyzePercentage()
  261. //需求挖掘排行
  262. this.getwordMiningRank()
  263. },
  264. // 需求挖掘排行
  265. getwordMiningRank(){
  266. this.$u.post('/cusLvStatistics/wordMiningRank', {
  267. houseId: this.houseId,
  268. "dateType":this.activeTotal,
  269. "firstStartDate":!this.activeTotal?this.startDate:'',
  270. "firstEndDate":!this.activeTotal?this.endDate:''
  271. })
  272. .then(res => {
  273. console.log(res)
  274. if(res.length){
  275. this.sortList = res.map(item=>{
  276. return {
  277. name: item.name,
  278. id: item.id,
  279. fraction: item.fraction,
  280. selected: item.selected
  281. }
  282. })
  283. }
  284. })
  285. },
  286. // 需求挖掘分布图
  287. getRingData(){
  288. this.$u.post('/cusLvStatistics/wordMiningAnalyzeFenbu', {
  289. houseId: this.houseId,
  290. "firstStartDate":!this.activeTotal?this.startDate:'',
  291. "firstEndDate":!this.activeTotal?this.endDate:'',
  292. "dateType":this.activeTotal
  293. })
  294. .then(res => {
  295. console.log(res)
  296. this.ringChartData = { series: [
  297. {
  298. data: [
  299. {"name":"30%以下","value":res.a},
  300. {"name":"30%~50%","value":res.b},
  301. {"name":"50%~70%","value":res.c},
  302. {"name":"70%以上","value":res.d},
  303. ]
  304. }
  305. ]}
  306. })
  307. },
  308. Toview(){
  309. //跳转到接待记录
  310. uni.navigateTo({
  311. url: '/pages/center/records/index'
  312. });
  313. },
  314. // 需求挖掘分析-简报
  315. wordMiningAnalyze() {
  316. let params = {
  317. "houseId":this.houseId,
  318. "deptId":this.deptVal,
  319. "userId":this.guwenVal,
  320. "dateType": this.activeTotal,
  321. "firstStartDate":!this.activeTotal?this.startDate:'',
  322. "firstEndDate":!this.activeTotal?this.endDate:''
  323. }
  324. this.$u.post("/cusLvStatistics/wordMiningAnalyze",params).then(res => {
  325. console.log(res.contrast)
  326. res.contrast.wordFraction = (res.contrast.fraction || 0) + '%'
  327. this.numlist.forEach(item => {
  328. item.num = res.contrast[item.setName]
  329. })
  330. })
  331. },
  332. // 获取员工列表
  333. getStaffList() {
  334. this.$u.post('/cusLvStatistics/selectAllAccountIdByHouseId', {
  335. houseId: this.houseId
  336. })
  337. .then(res => {
  338. // console.log(res)
  339. if(res.length){
  340. this.staffList = res.map(item => {
  341. return {
  342. label: item.name,
  343. value: item.accountId
  344. }
  345. })
  346. }
  347. })
  348. },
  349. // 需求挖掘率趋势图
  350. getwordMiningAnalyzePercentage() {
  351. this.$u.post('/cusLvStatistics/wordMiningAnalyzePercentage', {
  352. houseId: this.houseId,
  353. "dateType": this.activeTotal,
  354. "firstStartDate":!this.activeTotal?this.startDate:'',
  355. "firstEndDate":!this.activeTotal?this.endDate:''
  356. })
  357. .then(res => {
  358. let categories1 = []
  359. let categories2 = []
  360. if(res.first&&res.first.length){
  361. categories1 = res.first.map(item=> item.statDate.substring(0,10))
  362. this.lineOptsect.series[0].data=res.first.map(item=> item.wordFraction)
  363. }else{
  364. categories1= []
  365. this.lineOptsect.series[0] = []
  366. }
  367. if(res.end&&res.end.length){
  368. this.lineOptsect.series[1].data=res.end.map(item=> item.wordFraction)
  369. categories2 = res.end.map(item => item.statDate.substring(0,10))
  370. }else{
  371. categories2 = []
  372. }
  373. let categories3 =[]
  374. categories1.forEach(item1=>{
  375. categories2.forEach(item2=>{
  376. categories3.push(item1+ 'vs' + item2)
  377. })
  378. })
  379. this.lineOptsect.categories = categories3
  380. console.log(this.lineOptsect.categories)
  381. })
  382. },
  383. // 获取团队列表
  384. getSectionList() {
  385. this.$u.post('/cusLvStatistics/findAllDeptIdByHouseId', {
  386. houseId: this.houseId
  387. })
  388. .then(res => {
  389. this.teamList = []
  390. if(res.length){
  391. this.teamList = res.map(item=> {
  392. return {
  393. label: item.deptName,
  394. value: item.deptId
  395. }
  396. })
  397. }
  398. })
  399. },
  400. //时间切换
  401. tabtimetap(index, text) {
  402. if (index == 3) {
  403. this.calendarShow = true;
  404. this.activeTotal = null
  405. } else {
  406. this.activeTotal = index;
  407. this.endDate = ''
  408. this.startDate = ''
  409. this.time = text
  410. }
  411. this.timeshow = false
  412. this.getdata()
  413. },
  414. staffSelectCallback(e, idx) {
  415. if (idx == 0) {
  416. this.guwenVal = e[0].value
  417. this.guwen = e[0].label
  418. } else { // 部门
  419. this.dept = e[0].label
  420. this.deptVal = e[0].value
  421. }
  422. this.getdata()
  423. },
  424. //自定义时间
  425. calendarTimeChange(e) {
  426. // console.log(e.startDate, e.endDate)
  427. this.activeTotal = null;
  428. this.endDate = e.endDate
  429. this.startDate = e.startDate
  430. this.time = '自定义'
  431. this.getdata()
  432. }
  433. }
  434. };
  435. </script>
  436. <style lang="scss" scoped>
  437. .box {
  438. width: 100%;
  439. height: 100%;
  440. background: #FAFAFA;
  441. }
  442. //时间切换的样式
  443. .boxtittab {
  444. position: sticky;
  445. top: var(--window-top);
  446. z-index: 999;
  447. width: 100;
  448. height: 92rpx;
  449. background: #FFFFFF;
  450. border: 1px solid #E0E0E0;
  451. display: flex;
  452. align-items: center;
  453. .tabbox {
  454. flex: 1;
  455. height: 100%;
  456. text-align: center;
  457. line-height: 92rpx;
  458. color: #666666;
  459. font-size: 28rpx;
  460. overflow: hidden;
  461. text-overflow: ellipsis;
  462. display: -webkit-box;
  463. /* 将对象作为弹性伸缩盒子模型显示 */
  464. -webkit-line-clamp: 1;
  465. /* 控制最多显示几行 */
  466. -webkit-box-orient: vertical;
  467. /* 设置或检索伸缩盒对象的子元素的排列方式 */
  468. }
  469. }
  470. .timeview {
  471. height: 80rpx;
  472. line-height: 80rpx;
  473. width: 100%;
  474. text-align: center;
  475. border-bottom: 1px solid #F8F8F8;
  476. }
  477. .black-bg{
  478. position: fixed;
  479. background: rgba(0,0,0,0.6);
  480. left: 0;
  481. right: 0;
  482. top: 0;
  483. bottom: 0;
  484. display: flex;
  485. flex-direction: column;
  486. justify-content: center;
  487. align-items: center;
  488. z-index: 9999;
  489. .tongjiDesc{
  490. width: 80%;
  491. background: #FFFFFF;
  492. border-radius: 4rpx;
  493. padding: 30rpx;
  494. }
  495. .close{
  496. background: #fff;
  497. border-radius: 50%;
  498. width: 80rpx;
  499. height: 80rpx;
  500. margin-top: 30rpx;
  501. display: flex;
  502. justify-content: center;
  503. align-items: center;
  504. }
  505. .tongji-title{
  506. text-align: center;
  507. font-size: 30rpx;
  508. margin-bottom: 20rpx;
  509. }
  510. .text view{
  511. margin-bottom: 24rpx;
  512. }
  513. .bold{
  514. font-weight: bold;
  515. }
  516. }
  517. .grid:nth-child(1) {
  518. border-right: none;
  519. border-bottom: none;
  520. }
  521. .grid:nth-child(2) {
  522. border-bottom: none;
  523. }
  524. .grid:nth-child(3) {
  525. border-right: none;
  526. }
  527. .zonglantitle{
  528. display: flex;
  529. justify-content: space-between;
  530. align-items: center;
  531. text{
  532. color: #666666;
  533. }
  534. }
  535. .uchaserbox{
  536. width: 100%;
  537. height: 500rpx;
  538. }
  539. .tabdada {
  540. width: 100%;
  541. height: 580rpx;
  542. overflow-y: auto;
  543. padding-bottom: 20rpx;
  544. .tabth {
  545. width: 100%;
  546. height: 28rpx;
  547. display: flex;
  548. font-size: 28rpx;
  549. line-height: 28rpx;
  550. color: #666666;
  551. margin-top: 28rpx;
  552. }
  553. .tabth>view:nth-of-type(1) {
  554. width: 10%;
  555. text-align: center;
  556. }
  557. .tabth>view:nth-of-type(2) {
  558. width: 46%;
  559. text-align: center;
  560. }
  561. .tabth>view:nth-of-type(3) {
  562. width: 22%;
  563. text-align: center;
  564. }
  565. .tabth>view:nth-of-type(4) {
  566. width: 22%;
  567. text-align: center;
  568. }
  569. .tabtd {
  570. width: 100%;
  571. height: 30rpx;
  572. display: flex;
  573. font-size: 26rpx;
  574. line-height: 30rpx;
  575. margin-top: 32rpx;
  576. }
  577. .tabtd>view:nth-of-type(1) {
  578. width: 10%;
  579. text-align: center;
  580. line-height: 30rpx;
  581. }
  582. .tabtd>view:nth-of-type(2) {
  583. width: 46%;
  584. max-width: 400rpx;
  585. text-align: center;
  586. color: #333333;
  587. }
  588. .tabtd>view:nth-of-type(3) {
  589. width: 22%;
  590. text-align: center;
  591. color: #333333;
  592. }
  593. .tabtd>view:nth-of-type(4) {
  594. width: 22%;
  595. text-align: center;
  596. color: #2671E2;
  597. }
  598. .ranking {
  599. width: 34rpx;
  600. height: 34rpx;
  601. }
  602. .ranking1 {
  603. width: 30rpx;
  604. height: 30rpx;
  605. background: #ECF1FF;
  606. color: #424D64;
  607. font-size: 18rpx;
  608. text-align: center;
  609. line-height: 30rpx;
  610. border-radius: 50%;
  611. margin: 0 auto;
  612. }
  613. .tabech {
  614. width: 100%;
  615. height: 600rpx;
  616. }
  617. }
  618. </style>