Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 

700 linhas
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'
  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. categories1.forEach(item1=>{
  402. categories2.forEach(item2=>{
  403. categories3.push(item1+ '/' + item2)
  404. })
  405. })
  406. this.lineOptsect.categories = categories3
  407. console.log(this.lineOptsect.categories)
  408. })
  409. },
  410. // 获取团队列表
  411. getSectionList() {
  412. this.$u.post('/cusLvStatistics/findAllDeptIdByHouseId', {
  413. houseId: this.houseId
  414. })
  415. .then(res => {
  416. this.teamList = []
  417. if(res.length){
  418. this.teamList = res.map(item=> {
  419. return {
  420. label: item.deptName,
  421. value: item.deptId
  422. }
  423. })
  424. }
  425. })
  426. },
  427. //时间切换
  428. tabtimetap(index, text) {
  429. if (index == 3) {
  430. this.calendarShow = true;
  431. this.activeTotal = null
  432. } else {
  433. this.activeTotal = index;
  434. this.endDate = ''
  435. this.startDate = ''
  436. this.time = text
  437. this.getdata()
  438. }
  439. this.timeshow = false
  440. },
  441. staffSelectCallback(e, idx) {
  442. if (idx == 0) {
  443. this.guwenVal = e[0].value
  444. this.guwen = e[0].label
  445. } else { // 部门
  446. this.dept = e[0].label
  447. this.deptVal = e[0].value
  448. }
  449. this.getdata()
  450. },
  451. //自定义时间
  452. calendarTimeChange(e) {
  453. // console.log(e.startDate, e.endDate)
  454. this.activeTotal = null;
  455. this.endDate = e.endDate
  456. this.startDate = e.startDate
  457. this.time = '自定义'
  458. this.getdata()
  459. }
  460. }
  461. };
  462. </script>
  463. <style lang="scss" scoped>
  464. .box {
  465. width: 100%;
  466. height: 100%;
  467. background: #FAFAFA;
  468. }
  469. //时间切换的样式
  470. .boxtittab {
  471. position: sticky;
  472. top: var(--window-top);
  473. z-index: 999;
  474. width: 100;
  475. height: 92rpx;
  476. background: #FFFFFF;
  477. border: 1px solid #E0E0E0;
  478. display: flex;
  479. align-items: center;
  480. .tabbox {
  481. flex: 1;
  482. height: 100%;
  483. text-align: center;
  484. line-height: 92rpx;
  485. color: #666666;
  486. font-size: 28rpx;
  487. overflow: hidden;
  488. text-overflow: ellipsis;
  489. display: -webkit-box;
  490. /* 将对象作为弹性伸缩盒子模型显示 */
  491. -webkit-line-clamp: 1;
  492. /* 控制最多显示几行 */
  493. -webkit-box-orient: vertical;
  494. /* 设置或检索伸缩盒对象的子元素的排列方式 */
  495. }
  496. }
  497. .timeview {
  498. height: 80rpx;
  499. line-height: 80rpx;
  500. width: 100%;
  501. text-align: center;
  502. border-bottom: 1px solid #F8F8F8;
  503. }
  504. .black-bg{
  505. position: fixed;
  506. background: rgba(0,0,0,0.6);
  507. left: 0;
  508. right: 0;
  509. top: 0;
  510. bottom: 0;
  511. display: flex;
  512. flex-direction: column;
  513. justify-content: center;
  514. align-items: center;
  515. z-index: 9999;
  516. .tongjiDesc{
  517. width: 80%;
  518. background: #FFFFFF;
  519. border-radius: 12rpx;
  520. padding: 30rpx;
  521. }
  522. .close{
  523. background: #fff;
  524. border-radius: 50%;
  525. width: 80rpx;
  526. height: 80rpx;
  527. margin-top: 30rpx;
  528. display: flex;
  529. justify-content: center;
  530. align-items: center;
  531. }
  532. .tongji-title{
  533. text-align: center;
  534. font-size: 30rpx;
  535. margin-bottom: 20rpx;
  536. }
  537. .text view{
  538. margin-bottom: 24rpx;
  539. }
  540. .bold{
  541. font-weight: bold;
  542. }
  543. }
  544. .grid:nth-child(1) {
  545. border-right: none;
  546. border-bottom: none;
  547. }
  548. .grid:nth-child(2) {
  549. border-bottom: none;
  550. }
  551. .grid:nth-child(3) {
  552. border-right: none;
  553. }
  554. .grid .bottom{
  555. display: flex;
  556. align-items: center;
  557. padding-left: 20rpx;
  558. margin: 10rpx 0 20rpx;
  559. .leftnum{
  560. height: 36rpx;
  561. font-size: 26rpx;
  562. font-family: PingFangSC-Regular, PingFang SC;
  563. font-weight: 400;
  564. color: #666666;
  565. line-height: 36rpx;
  566. margin-right: 20rpx;
  567. }
  568. .rightnum{
  569. height: 36rpx;
  570. font-size: 26rpx;
  571. font-family: PingFangSC-Semibold, PingFang SC;
  572. font-weight: 600;
  573. color: #666;
  574. line-height: 36rpx;
  575. display: flex;
  576. align-items: center;
  577. &.red{
  578. color: #E6273A;
  579. }
  580. &.green{
  581. color: #43CD80;
  582. }
  583. image{
  584. width: 18rpx;
  585. height: 14rpx;
  586. margin-left: 6rpx;
  587. }
  588. }
  589. }
  590. .zonglantitle{
  591. display: flex;
  592. justify-content: space-between;
  593. align-items: center;
  594. text{
  595. color: #666666;
  596. }
  597. }
  598. .uchaserbox{
  599. width: 100%;
  600. height: 500rpx;
  601. }
  602. .tabdada {
  603. width: 100%;
  604. height: 580rpx;
  605. overflow-y: auto;
  606. padding-bottom: 20rpx;
  607. .tabth {
  608. width: 100%;
  609. height: 28rpx;
  610. display: flex;
  611. font-size: 28rpx;
  612. line-height: 28rpx;
  613. color: #666666;
  614. margin-top: 28rpx;
  615. }
  616. .tabth>view:nth-of-type(1) {
  617. width: 10%;
  618. text-align: center;
  619. }
  620. .tabth>view:nth-of-type(2) {
  621. width: 46%;
  622. text-align: center;
  623. }
  624. .tabth>view:nth-of-type(3) {
  625. width: 22%;
  626. text-align: center;
  627. }
  628. .tabth>view:nth-of-type(4) {
  629. width: 22%;
  630. text-align: center;
  631. }
  632. .tabtd {
  633. width: 100%;
  634. height: 30rpx;
  635. display: flex;
  636. font-size: 26rpx;
  637. line-height: 30rpx;
  638. margin-top: 32rpx;
  639. }
  640. .tabtd>view:nth-of-type(1) {
  641. width: 10%;
  642. text-align: center;
  643. line-height: 30rpx;
  644. }
  645. .tabtd>view:nth-of-type(2) {
  646. width: 46%;
  647. max-width: 400rpx;
  648. text-align: center;
  649. color: #333333;
  650. }
  651. .tabtd>view:nth-of-type(3) {
  652. width: 22%;
  653. text-align: center;
  654. color: #333333;
  655. }
  656. .tabtd>view:nth-of-type(4) {
  657. width: 22%;
  658. text-align: center;
  659. color: #2671E2;
  660. }
  661. .ranking {
  662. width: 34rpx;
  663. height: 34rpx;
  664. }
  665. .ranking1 {
  666. width: 30rpx;
  667. height: 30rpx;
  668. background: #ECF1FF;
  669. color: #424D64;
  670. font-size: 18rpx;
  671. text-align: center;
  672. line-height: 30rpx;
  673. border-radius: 50%;
  674. margin: 0 auto;
  675. }
  676. .tabech {
  677. width: 100%;
  678. height: 600rpx;
  679. }
  680. }
  681. </style>