AI销管
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 

769 рядки
18 KiB

  1. <template>
  2. <view class="pages">
  3. <view class="boxtittab">
  4. <view class="tabbox">
  5. <view :class="{ activecllasscet: activeTotal == 4 }" @click="tabtimetap(4)">近七天</view>
  6. </view>
  7. <view class="tabbox">
  8. <view :class="{ activecllasscet: activeTotal == 5 }" @click="tabtimetap(5)">近15天</view>
  9. </view>
  10. <view class="tabbox">
  11. <view :class="{ activecllasscet: activeTotal == 6 }" @click="tabtimetap(6)">近30天</view>
  12. </view>
  13. <view class="tabbox">
  14. <view :class="{ activecllasscet: activeTotal == 3 }" @click="tabtimetap(3)">自定义</view>
  15. </view>
  16. </view>
  17. <view class="container">
  18. <scroll-view style="height: calc(100vh - 92rpx - 32rpx);" class="lside" scroll-y="true">
  19. <view class="lside-scrollbox">
  20. <block v-for="(data, index) in lsideList">
  21. <view class="lside-scrollbox-items" @tap="chooseLside(data, index)"
  22. :class="{active: index === lsideListIndex}" :key="index">
  23. {{ data.title }}
  24. </view>
  25. </block>
  26. </view>
  27. </scroll-view>
  28. <scroll-view style="height: calc(100vh - 92rpx - 32rpx);" class="rside" scroll-y="true">
  29. <view class="rside-scrollbox">
  30. <!-- 接待量 -->
  31. <template v-if="lsideListIndex === 0">
  32. <view class="single">
  33. <view class="title">
  34. <view class="title1">接待量(TOP10)</view>
  35. </view>
  36. <view class="hejisan">
  37. <view class="sanbox1">
  38. <view class="text1-2">{{newTeam1||0}}</view>
  39. <view class="text1-1">项目</view>
  40. </view>
  41. <view class="sanbox1">
  42. <view class="text1-2">{{newAvg1||0}}</view>
  43. <view class="text1-1">均值</view>
  44. </view>
  45. </view>
  46. <block v-for="(item,index) in newlisttabinfo1">
  47. <view class="box">
  48. <view class="box-lside">
  49. <template v-if="index < 2">
  50. <image class="img"
  51. :src="'../../../static/images/ranking/ranking'+ (index+1) +'.png'"
  52. mode=""></image>
  53. </template>
  54. <template v-else>
  55. <view class="ranking">{{ index + 1 }}</view>
  56. </template>
  57. </view>
  58. <view class="box-rside">
  59. <view class="box-top">
  60. <view class="percent-name">{{item.name}}</view>
  61. <view class="percent-zxl">{{ !item.zxl ? 0 : item.zxl}}</view>
  62. </view>
  63. <view class="percent-box">
  64. <view class="percent" :style="'width:'+ getPercent(item.zxl,1) + '%'">
  65. </view>
  66. </view>
  67. </view>
  68. </view>
  69. </block>
  70. </view>
  71. </template>
  72. <!-- 接待时长 -->
  73. <template v-if="lsideListIndex === 1">
  74. <view class="single">
  75. <view class="title">
  76. <view class="title1">接待时长(TOP10)</view>
  77. </view>
  78. <view class="hejisan">
  79. <view class="sanbox1">
  80. <view class="text1-2">{{newTeam2||0}}</view>
  81. <view class="text1-1">项目</view>
  82. </view>
  83. <view class="sanbox1">
  84. <view class="text1-2">{{newAvg2||0}}</view>
  85. <view class="text1-1">均值</view>
  86. </view>
  87. </view>
  88. <block v-for="(item,index) in newlisttabinfo2">
  89. <view class="box">
  90. <view class="box-lside">
  91. <template v-if="index < 2">
  92. <image class="img"
  93. :src="'../../../static/images/ranking/ranking'+ (index+1) +'.png'"
  94. mode=""></image>
  95. </template>
  96. <template v-else>
  97. <view class="ranking">{{ index + 1 }}</view>
  98. </template>
  99. </view>
  100. <view class="box-rside">
  101. <view class="box-top">
  102. <view class="percent-name">{{item.name}}</view>
  103. <view class="percent-zxl">{{ !item.zxl ? 0 : item.zxl}}</view>
  104. </view>
  105. <view class="percent-box">
  106. <view class="percent" :style="'width:'+ getPercent(item.zxl,2) + '%'">
  107. </view>
  108. </view>
  109. </view>
  110. </view>
  111. </block>
  112. </view>
  113. </template>
  114. <!-- 销讲执行排名 -->
  115. <template v-if="lsideListIndex === 2">
  116. <view class="single">
  117. <view class="title">
  118. <view class="title1" style="flex: 1;">销讲执行排名(TOP10)</view>
  119. </view>
  120. <view class="hejisan">
  121. <view class="sanbox1">
  122. <view class="text1-2">{{newTeam3||0}}</view>
  123. <view class="text1-1">项目</view>
  124. </view>
  125. <view class="sanbox1">
  126. <view class="text1-2">{{newAvg3||0}}%</view>
  127. <view class="text1-1">均值</view>
  128. </view>
  129. </view>
  130. <block v-for="(item,index) in newlisttabinfo3">
  131. <view class="box">
  132. <view class="box-lside">
  133. <template v-if="index < 2">
  134. <image class="img"
  135. :src="'../../../static/images/ranking/ranking'+ (index+1) +'.png'"
  136. mode=""></image>
  137. </template>
  138. <template v-else>
  139. <view class="ranking">{{ index + 1 }}</view>
  140. </template>
  141. </view>
  142. <view class="box-rside">
  143. <view class="box-top">
  144. <view class="percent-name">{{item.name}}</view>
  145. <view class="percent-zxl">{{ !item.zxl ? 0 : item.zxl}}</view>
  146. </view>
  147. <view class="percent-box">
  148. <view class="percent" :style="'width:'+ getPercent1(item.zxl) + '%'">
  149. </view>
  150. </view>
  151. </view>
  152. </view>
  153. </block>
  154. </view>
  155. </template>
  156. <!-- 顾问执行排名 -->
  157. <template v-if="lsideListIndex === 3">
  158. <view class="single">
  159. <view class="title">
  160. <view class="title1" style="flex: 1;">顾问执行排名(TOP10)</view>
  161. </view>
  162. <block v-for="(item,index) in newlisttabinfo4">
  163. <view class="box">
  164. <view class="box-lside">
  165. <template v-if="index < 2">
  166. <image class="img"
  167. :src="'../../../static/images/ranking/ranking'+ (index+1) +'.png'"
  168. mode=""></image>
  169. </template>
  170. <template v-else>
  171. <view class="ranking">{{ index + 1 }}</view>
  172. </template>
  173. </view>
  174. <view class="box-rside">
  175. <view class="box-top">
  176. <view class="percent-name">{{item.name}}</view>
  177. <view class="percent-zxl">{{ !item.zxl ? 0 : item.zxl}}</view>
  178. </view>
  179. <view class="percent-box">
  180. <view class="percent" :style="'width:'+ getPercent1(item.zxl) + '%'">
  181. </view>
  182. </view>
  183. </view>
  184. </view>
  185. </block>
  186. </view>
  187. </template>
  188. <template v-if="lsideListIndex === 4">
  189. <view class="single">
  190. <view class="title" style="padding-right: 30rpx;">
  191. <view class="title1" style="flex: 1;">销讲能力</view>
  192. <view class="title2" style="flex: 1;justify-content: flex-end;" @click="staffShow=true">
  193. <view class="title2-che" style="width: auto;">{{staff.label}}
  194. <image class="righttochoose" src="@/static/images/down.png" mode="">
  195. </image>
  196. </view>
  197. </view>
  198. </view>
  199. <view class="uchaserbox">
  200. <view v-if="!emptyCharData" class="uchaserbox" style="display: flex;
  201. align-items: center;justify-content: center;">
  202. <u-empty style="margin: 09 0 0 0;" mode="data"></u-empty>
  203. </view>
  204. <qiun-data-charts v-else class="qiudatacharts" type="radar" :chartData="chartData"
  205. :canvas2d="true" canvasId="wangxiaohuaerlingeryilingwuyib88" background="none"
  206. :loadingType="0" :opts="opts" />
  207. </view>
  208. </view>
  209. </template>
  210. </view>
  211. </scroll-view>
  212. </view>
  213. <!-- 日期选择器 -->
  214. <u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar>
  215. <!-- 选择项目 -->
  216. <u-select v-model="staffShow" :list="staffList" @confirm="staffSelectCallback" :default-value='selindex'>
  217. </u-select>
  218. <!-- 加载组件 -->
  219. <u-loadings v-model="LOADING"></u-loadings>
  220. </view>
  221. </template>
  222. <script>
  223. var app = getApp();
  224. var util = require("../../../utils/util.js");
  225. var config = require("../../../config");
  226. export default {
  227. data() {
  228. return {
  229. activeTotal: 4, // 时间选择下标
  230. // 日期选择器
  231. totalTimeShow: false, // 日期选择器
  232. lastStartDate: '', // 开始时间
  233. lastEndDate: '', // 结束时间
  234. // 项目选择器
  235. staffShow: false, // 展示项目选择器
  236. staffList: [], // 可选项目列表
  237. staff: {
  238. value: '',
  239. label: '',
  240. }, // 选择的项目数据
  241. houseId: '', // 项目id
  242. lsideList: [{
  243. title: '接待量',
  244. method: 'receptionCountList',
  245. methodParams: "1,groupComparisonReception",
  246. },
  247. {
  248. title: '接待时长',
  249. method: 'receptionCountList',
  250. methodParams: "2,groupComparisonReceptionTime"
  251. },
  252. {
  253. title: '销讲排名',
  254. method: 'receptionCountList',
  255. methodParams: "3,groupComparisonTalkRank"
  256. },
  257. {
  258. title: '顾问排名',
  259. method: 'receptionCountList',
  260. methodParams: "4,groupComparisonTalkRankByConsultant"
  261. },
  262. {
  263. title: '销讲能力',
  264. method: 'getPowerList',
  265. methodParams: ''
  266. },
  267. ],
  268. lsideListIndex: 0, // 默认选中下标
  269. // 右侧存放数据变量
  270. newlisttabinfo1: [{
  271. name: '接待量',
  272. zxl: '0'
  273. },
  274. {
  275. name: '平均执行率',
  276. zxl: '0'
  277. },
  278. {
  279. name: '接待客户',
  280. zxl: '0'
  281. },
  282. ], // 接待量
  283. // 接待量
  284. newTeam1: '',
  285. newAvg1: '',
  286. newlisttabinfo2: [{
  287. name: '接待量',
  288. zxl: '0'
  289. },
  290. {
  291. name: '平均执行率',
  292. zxl: '0'
  293. },
  294. {
  295. name: '接待客户',
  296. zxl: '0'
  297. },
  298. ], // 接待时长
  299. // 接待时长
  300. newTeam2: '',
  301. newAvg2: '',
  302. newlisttabinfo3: [{
  303. name: '接待量',
  304. zxl: '0'
  305. },
  306. {
  307. name: '平均执行率',
  308. zxl: '0'
  309. },
  310. {
  311. name: '接待客户',
  312. zxl: '0'
  313. },
  314. ], // 销讲排名
  315. // 销讲排名
  316. newTeam3: '',
  317. newAvg3: '',
  318. newlisttabinfo4: [{
  319. name: '接待量',
  320. zxl: '0'
  321. },
  322. {
  323. name: '平均执行率',
  324. zxl: '0'
  325. },
  326. {
  327. name: '接待客户',
  328. zxl: '0'
  329. },
  330. ], // 顾问排名
  331. // 顾问排名
  332. newTeam4: '',
  333. newAvg4: '',
  334. chartData: {
  335. categories: [],
  336. series: []
  337. }, // 销讲能力
  338. opts: {
  339. type: "radar",
  340. width: 300,
  341. fontSize: 10,
  342. extra: {
  343. radar: {
  344. max: 100
  345. }
  346. }
  347. },
  348. emptyCharData: false,
  349. };
  350. },
  351. onLoad() {
  352. this.LOADING = true
  353. uni.$on('updateGroup', (data) => {
  354. this.houseId = data.arr.join(',')
  355. // 获取销奖能力
  356. this.getPowerList()
  357. })
  358. this.getSectionList()
  359. },
  360. onPullDownRefresh() {},
  361. methods: {
  362. // 获取部门列表
  363. getSectionList() {
  364. this.$u.post('/user/getHouseByToken', )
  365. .then(res => {
  366. // console.log(res)
  367. this.staffList = []
  368. res.map((item, index) => {
  369. let obj = {}
  370. obj.value = item.id
  371. obj.label = item.propertyName
  372. this.staffList.push(obj)
  373. })
  374. this.houseId = this.staffList[0].value
  375. this.staff = this.staffList[0]
  376. this.getdata()
  377. })
  378. },
  379. // 获取数据
  380. getdata() {
  381. let params = this.lsideList[this.lsideListIndex].methodParams.split(',')
  382. this[this.lsideList[this.lsideListIndex].method](params[0], params[1])
  383. },
  384. // 转换百分比
  385. getPercent(num, type) {
  386. if (this.newlisttabinfo1 && this.newlisttabinfo1.length && type == 1) {
  387. let index0 = this.newlisttabinfo1[0]
  388. let percent = num / (index0.zxl) * 100
  389. return percent.toFixed(2)
  390. } else if (this.newlisttabinfo2 && this.newlisttabinfo2.length && type == 2) {
  391. let index0 = this.newlisttabinfo2[0]
  392. let percent = num / (index0.zxl) * 100
  393. return percent.toFixed(2)
  394. } else if (this.newlisttabinfo3 && this.newlisttabinfo3.length && type == 3) {
  395. let index0 = this.newlisttabinfo3[0]
  396. let percent = num / (index0.zxl) * 100
  397. return percent.toFixed(2)
  398. } else {
  399. return 0
  400. }
  401. },
  402. // 取数值
  403. getPercent1(num) {
  404. console.log(num)
  405. return num || 0
  406. },
  407. // 接待时长
  408. receptionCountList(index, url) {
  409. this.$u.post(`/cusLvStatistics/${url}`, {
  410. timeType: this.lastEndDate ? null : this.activeTotal + '',
  411. lastEndDate: this.lastEndDate,
  412. lastStartDate: this.lastStartDate
  413. })
  414. .then(res => {
  415. this.LOADING = false
  416. // console.log(res)
  417. let result = res.result
  418. this['newTeam' + index] = res.avg[0]
  419. this['newAvg' + index] = res.avg[1]
  420. this['newlisttabinfo' + index] = []
  421. // 当选择全部时
  422. let arr = []
  423. // 当两个都选择的时候
  424. result.map(item => {
  425. let obj = {}
  426. obj.name = item.houseName
  427. obj.zxl = item.data
  428. arr.push(obj)
  429. })
  430. arr = this.dealData(arr)
  431. this['newlisttabinfo' + index] = arr
  432. }).catch(() => {
  433. this.LOADING = false
  434. })
  435. },
  436. // 获取销奖能力
  437. getPowerList() {
  438. this.chartData = {
  439. categories: [],
  440. series: []
  441. }
  442. this.$u.post('/cusLvStatistics/groupComparisonMarketingAbility', {
  443. houseIds: this.houseId,
  444. timeType: this.lastEndDate ? null : this.activeTotal + '',
  445. lastEndDate: this.lastEndDate,
  446. lastStartDate: this.lastStartDate
  447. })
  448. .then(res => {
  449. this.LOADING = false
  450. let allobj = {
  451. categories: [],
  452. series: []
  453. }
  454. if (res.result.length > 0) {
  455. console.log(res, 'asdjkasl')
  456. res.result.map((item, index) => {
  457. let obj = {
  458. name: item.length > 0 ? item[0].houseName : '',
  459. data: []
  460. }
  461. item.map(item1 => {
  462. if (index == 0) {
  463. allobj.categories.push(item1.name)
  464. }
  465. obj.data.push(item1.avgExecutionRate)
  466. })
  467. allobj.series.push(obj)
  468. })
  469. this.chartData = allobj
  470. this.emptyCharData = true;
  471. } else {
  472. this.emptyCharData = false;
  473. }
  474. console.log(this.emptyCharData)
  475. this.$forceUpdate()
  476. }).catch(e => {
  477. this.LOADING = false
  478. })
  479. },
  480. //时间切换
  481. tabtimetap(index) {
  482. this.activeTotal = index;
  483. if (index == 3) {
  484. this.totalTimeShow = true;
  485. } else {
  486. this.lastEndDate = ''
  487. this.lastStartDate = ''
  488. this.getdata()
  489. }
  490. },
  491. //自定义时间
  492. totalTimeChange(e) {
  493. console.log(e.startDate, e.endDate)
  494. this.activeTotal = 3;
  495. this.lastEndDate = e.endDate
  496. this.lastStartDate = e.startDate
  497. this.getdata()
  498. },
  499. // 定义一个公共方法对数据进行处理
  500. dealData(arr) {
  501. // 获取最大值
  502. let num = Math.max.apply(Math, arr.map(function(o) {
  503. return o.zxl
  504. })) //结果:3
  505. if (num > 100) {
  506. // 获取最大值的下标
  507. arr.map(item => {
  508. item.zxl1 = Math.floor(item.zxl / num * 100)
  509. })
  510. return arr
  511. } else {
  512. arr.map(item => {
  513. item.zxl1 = item.zxl
  514. })
  515. return arr
  516. }
  517. },
  518. // 选择项目后更新数据
  519. staffSelectCallback(e) {
  520. this.staff = e[0]
  521. this.houseId = e[0].value
  522. this.getPowerList()
  523. },
  524. // 左侧菜单选中
  525. chooseLside(data, index) {
  526. this.lsideListIndex = index
  527. console.log(index)
  528. this.getdata()
  529. },
  530. },
  531. };
  532. </script>
  533. <style lang="scss" scoped>
  534. .pages {
  535. width: 100%;
  536. height: 100vh;
  537. display: flex;
  538. flex-direction: column;
  539. background: #F8F8F8;
  540. .boxtittab {}
  541. .container {
  542. padding: 16rpx 0;
  543. width: 100%;
  544. height: calc(100% - 92rpx - var(--window-top));
  545. display: grid;
  546. grid-template-columns: 160rpx calc(100vw - 160rpx);
  547. .lside {
  548. width: 100%;
  549. background: #F6F7FB;
  550. .lside-scrollbox {
  551. width: 100%;
  552. display: flex;
  553. flex-direction: column;
  554. .lside-scrollbox-items {
  555. width: 100%;
  556. height: 72rpx;
  557. display: flex;
  558. justify-content: center;
  559. align-items: center;
  560. font-size: 24rpx;
  561. font-family: PingFangSC-Regular, PingFang SC;
  562. font-weight: 400;
  563. color: #666666;
  564. overflow: hidden;
  565. text-overflow: ellipsis;
  566. white-space: nowrap;
  567. &.active {
  568. font-weight: 600;
  569. color: #2671E2;
  570. background: #FFFFFF;
  571. }
  572. }
  573. }
  574. }
  575. }
  576. .rside {
  577. width: 100%;
  578. .rside-scrollbox {
  579. width: 100%;
  580. background: #fff;
  581. display: flex;
  582. flex-direction: column;
  583. .single {
  584. width: 100%;
  585. display: flex;
  586. flex-direction: column;
  587. .hejisan {
  588. margin: 0 auto 28rpx;
  589. width: 542rpx;
  590. height: 120rpx;
  591. display: flex;
  592. background: #F6F7FB;
  593. border-radius: 8rpx;
  594. .sanbox1 {
  595. position: relative;
  596. flex-grow: 1;
  597. display: flex;
  598. flex-direction: column;
  599. justify-content: center;
  600. align-items: center;
  601. &:last-child::after {
  602. content: '';
  603. position: absolute;
  604. left: 0;
  605. top: 50%;
  606. transform: translateY(-50%);
  607. width: 1rpx;
  608. height: 80rpx;
  609. background: #E0E0E0;
  610. }
  611. }
  612. .text1-1 {
  613. font-size: 24rpx;
  614. font-family: PingFangSC-Regular, PingFang SC;
  615. font-weight: 400;
  616. color: #333333;
  617. line-height: 32rpx;
  618. }
  619. .text1-2 {
  620. color: #333333;
  621. font-size: 40rpx;
  622. line-height: 46rpx;
  623. font-family: PingFangSC-Regular, PingFang SC;
  624. margin-bottom: 10rpx;
  625. }
  626. }
  627. .uchaserbox {
  628. width: 100%;
  629. height: 470rpx;
  630. display: flex;
  631. flex-direction: column;
  632. #wangxiaohuaerlingeryilingwuyib88 {
  633. flex-grow: 1;
  634. }
  635. .qiudatacharts {
  636. flex-grow: 1;
  637. }
  638. }
  639. .box {
  640. margin: 0 0 28rpx;
  641. padding: 0 24rpx;
  642. width: 100%;
  643. display: flex;
  644. .box-lside {
  645. margin: 0 24rpx 0 0;
  646. flex-shrink: 0;
  647. display: flex;
  648. justify-content: center;
  649. align-items: center;
  650. .img {
  651. width: 42rpx;
  652. height: 44rpx;
  653. }
  654. .ranking {
  655. width: 42rpx;
  656. height: 44rpx;
  657. font-size: 24rpx;
  658. font-family: SFPro-SemiboldItalic, SFPro;
  659. font-weight: normal;
  660. color: #8A8D9F;
  661. }
  662. }
  663. .box-rside {
  664. flex-grow: 1;
  665. .box-top {
  666. margin-bottom: 14rpx;
  667. width: 470rpx;
  668. display: flex;
  669. .percent-name {
  670. flex-grow: 1;
  671. width: calc(100% - 42rpx);
  672. overflow: hidden;
  673. white-space: nowrap;
  674. text-overflow: ellipsis;
  675. }
  676. .percent-zxl {
  677. flex-shrink: 0;
  678. }
  679. }
  680. .percent-box {
  681. width: 100%;
  682. height: 30rpx;
  683. .percent {
  684. height: 100%;
  685. background: #2671E2;
  686. border-radius: 15px;
  687. }
  688. }
  689. }
  690. }
  691. }
  692. }
  693. }
  694. }
  695. </style>