AI销管
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

Groupcontrast.vue 18 KiB

2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
2年前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  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 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 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" v-if="emptyCharData">
  200. <qiun-data-charts type="radar" :chartData="chartData" :canvas2d="true"
  201. canvasId="wangxiaohuaerlingeryilingwuyib88" background="none" :loadingType="0"
  202. :opts="opts" />
  203. </view>
  204. <view class="uchaserbox" v-else>
  205. <u-empty mode="data"></u-empty>
  206. </view>
  207. </view>
  208. </template>
  209. </view>
  210. </scroll-view>
  211. </view>
  212. <!-- 日期选择器 -->
  213. <u-calendar v-model="totalTimeShow" mode="range" @change="totalTimeChange"></u-calendar>
  214. <!-- 选择项目 -->
  215. <u-select v-model="staffShow" :list="staffList" @confirm="staffSelectCallback" :default-value='selindex'>
  216. </u-select>
  217. <!-- 加载组件 -->
  218. <u-loadings v-model="LOADING"></u-loadings>
  219. </view>
  220. </template>
  221. <script>
  222. var app = getApp();
  223. var util = require("../../../utils/util.js");
  224. var config = require("../../../config");
  225. export default {
  226. data() {
  227. return {
  228. activeTotal: 4, // 时间选择下标
  229. // 日期选择器
  230. totalTimeShow: false, // 日期选择器
  231. lastStartDate: '', // 开始时间
  232. lastEndDate: '', // 结束时间
  233. // 项目选择器
  234. staffShow: false, // 展示项目选择器
  235. staffList: [], // 可选项目列表
  236. staff: {
  237. value: '',
  238. label: '',
  239. }, // 选择的项目数据
  240. houseId: '', // 项目id
  241. lsideList: [{
  242. title: '接待量',
  243. method: 'receptionCountList',
  244. methodParams: "1,groupComparisonReception",
  245. },
  246. {
  247. title: '接待时长',
  248. method: 'receptionCountList',
  249. methodParams: "2,groupComparisonReceptionTime"
  250. },
  251. {
  252. title: '销讲排名',
  253. method: 'receptionCountList',
  254. methodParams: "3,groupComparisonTalkRank"
  255. },
  256. {
  257. title: '顾问排名',
  258. method: 'receptionCountList',
  259. methodParams: "4,groupComparisonTalkRankByConsultant"
  260. },
  261. {
  262. title: '销讲能力',
  263. method: 'getPowerList',
  264. methodParams: ''
  265. },
  266. ],
  267. lsideListIndex: 0, // 默认选中下标
  268. // 右侧存放数据变量
  269. newlisttabinfo1: [{
  270. name: '接待量',
  271. zxl: '0'
  272. },
  273. {
  274. name: '平均执行率',
  275. zxl: '0'
  276. },
  277. {
  278. name: '接待客户',
  279. zxl: '0'
  280. },
  281. ], // 接待量
  282. // 接待量
  283. newTeam1: '',
  284. newAvg1: '',
  285. newlisttabinfo2: [{
  286. name: '接待量',
  287. zxl: '0'
  288. },
  289. {
  290. name: '平均执行率',
  291. zxl: '0'
  292. },
  293. {
  294. name: '接待客户',
  295. zxl: '0'
  296. },
  297. ], // 接待时长
  298. // 接待时长
  299. newTeam2: '',
  300. newAvg2: '',
  301. newlisttabinfo3: [{
  302. name: '接待量',
  303. zxl: '0'
  304. },
  305. {
  306. name: '平均执行率',
  307. zxl: '0'
  308. },
  309. {
  310. name: '接待客户',
  311. zxl: '0'
  312. },
  313. ], // 销讲排名
  314. // 销讲排名
  315. newTeam3: '',
  316. newAvg3: '',
  317. newlisttabinfo4: [{
  318. name: '接待量',
  319. zxl: '0'
  320. },
  321. {
  322. name: '平均执行率',
  323. zxl: '0'
  324. },
  325. {
  326. name: '接待客户',
  327. zxl: '0'
  328. },
  329. ], // 顾问排名
  330. // 顾问排名
  331. newTeam4: '',
  332. newAvg4: '',
  333. chartData: {
  334. categories: [],
  335. series: []
  336. }, // 销讲能力
  337. };
  338. },
  339. onLoad() {
  340. this.LOADING = true
  341. uni.$on('updateGroup', (data) => {
  342. this.houseId = data.arr.join(',')
  343. // 获取销奖能力
  344. this.getPowerList()
  345. })
  346. this.getSectionList()
  347. },
  348. onPullDownRefresh() {},
  349. methods: {
  350. // 获取部门列表
  351. getSectionList() {
  352. this.$u.post('/user/getHouseByToken', )
  353. .then(res => {
  354. // console.log(res)
  355. this.staffList = []
  356. res.map((item, index) => {
  357. let obj = {}
  358. obj.value = item.id
  359. obj.label = item.propertyName
  360. this.staffList.push(obj)
  361. })
  362. this.houseId = this.staffList[0].value
  363. this.staff = this.staffList[0]
  364. this.getdata()
  365. })
  366. },
  367. // 获取数据
  368. getdata() {
  369. let params = this.lsideList[this.lsideListIndex].methodParams.split(',')
  370. this[this.lsideList[this.lsideListIndex].method](params[0], params[1])
  371. },
  372. // 转换百分比
  373. getPercent(num, type) {
  374. if (this.newlisttabinfo1 && this.newlisttabinfo1.length && type == 1) {
  375. let index0 = this.newlisttabinfo1[0]
  376. let percent = num / (index0.zxl) * 100
  377. return percent.toFixed(2)
  378. } else if (this.newlisttabinfo2 && this.newlisttabinfo2.length && type == 2) {
  379. let index0 = this.newlisttabinfo2[0]
  380. let percent = num / (index0.zxl) * 100
  381. return percent.toFixed(2)
  382. } else if (this.newlisttabinfo3 && this.newlisttabinfo3.length && type == 3) {
  383. let index0 = this.newlisttabinfo3[0]
  384. let percent = num / (index0.zxl) * 100
  385. return percent.toFixed(2)
  386. } else {
  387. return 0
  388. }
  389. },
  390. // 取数值
  391. getPercent1(num) {
  392. console.log(num)
  393. return num || 0
  394. },
  395. // 接待时长
  396. receptionCountList(index, url) {
  397. this.$u.post(`/cusLvStatistics/${url}`, {
  398. timeType: this.lastEndDate ? null : this.activeTotal + '',
  399. lastEndDate: this.lastEndDate,
  400. lastStartDate: this.lastStartDate
  401. })
  402. .then(res => {
  403. this.LOADING = false
  404. // console.log(res)
  405. let result = res.result
  406. this['newTeam' + index] = res.avg[0]
  407. this['newAvg' + index] = res.avg[1]
  408. this['newlisttabinfo' + index] = []
  409. // 当选择全部时
  410. let arr = []
  411. // 当两个都选择的时候
  412. result.map(item => {
  413. let obj = {}
  414. obj.name = item.houseName
  415. obj.zxl = item.data
  416. arr.push(obj)
  417. })
  418. arr = this.dealData(arr)
  419. this['newlisttabinfo' + index] = arr
  420. }).catch(() => {
  421. this.LOADING = false
  422. })
  423. },
  424. // 获取销奖能力
  425. getPowerList() {
  426. this.chartData = {
  427. categories: [],
  428. series: []
  429. }
  430. this.$u.post('/cusLvStatistics/groupComparisonMarketingAbility', {
  431. houseIds: this.houseId,
  432. timeType: this.lastEndDate ? null : this.activeTotal + '',
  433. lastEndDate: this.lastEndDate,
  434. lastStartDate: this.lastStartDate
  435. })
  436. .then(res => {
  437. this.LOADING = false
  438. let allobj = {
  439. categories: [],
  440. series: []
  441. }
  442. if (res.result.length != 0) {
  443. res.result.map((item, index) => {
  444. let obj = {
  445. name: item.length > 0 ? item[0].houseName : '',
  446. data: []
  447. }
  448. item.map(item1 => {
  449. if (index == 0) {
  450. allobj.categories.push(item1.name)
  451. }
  452. obj.data.push(item1.avgExecutionRate)
  453. })
  454. allobj.series.push(obj)
  455. })
  456. this.chartData = allobj
  457. this.$forceUpdate()
  458. this.emptyCharData = true;
  459. } else {
  460. this.emptyCharData = false;
  461. }
  462. }).catch(e => {
  463. this.LOADING = false
  464. })
  465. },
  466. //时间切换
  467. tabtimetap(index) {
  468. this.activeTotal = index;
  469. if (index == 3) {
  470. this.totalTimeShow = true;
  471. } else {
  472. this.lastEndDate = ''
  473. this.lastStartDate = ''
  474. this.getdata()
  475. }
  476. },
  477. //自定义时间
  478. totalTimeChange(e) {
  479. console.log(e.startDate, e.endDate)
  480. this.activeTotal = 3;
  481. this.lastEndDate = e.endDate
  482. this.lastStartDate = e.startDate
  483. this.getdata()
  484. },
  485. // 定义一个公共方法对数据进行处理
  486. dealData(arr) {
  487. // 获取最大值
  488. let num = Math.max.apply(Math, arr.map(function(o) {
  489. return o.zxl
  490. })) //结果:3
  491. if (num > 100) {
  492. // 获取最大值的下标
  493. arr.map(item => {
  494. item.zxl1 = Math.floor(item.zxl / num * 100)
  495. })
  496. return arr
  497. } else {
  498. arr.map(item => {
  499. item.zxl1 = item.zxl
  500. })
  501. return arr
  502. }
  503. },
  504. // 选择项目后更新数据
  505. staffSelectCallback(e) {
  506. this.staff = e[0]
  507. this.houseId = e[0].value
  508. this.getPowerList()
  509. },
  510. // 左侧菜单选中
  511. chooseLside(data, index) {
  512. this.lsideListIndex = index
  513. this.getdata()
  514. },
  515. },
  516. };
  517. </script>
  518. <style lang="scss" scoped>
  519. .pages {
  520. width: 100%;
  521. height: 100vh;
  522. display: flex;
  523. flex-direction: column;
  524. background: #F8F8F8;
  525. .boxtittab {}
  526. .container {
  527. padding: 16rpx 0;
  528. width: 100%;
  529. height: calc(100% - 92rpx);
  530. display: grid;
  531. grid-template-columns: 160rpx 1fr;
  532. .lside {
  533. width: 100%;
  534. height: 100%;
  535. background: #F6F7FB;
  536. .lside-scrollbox {
  537. width: 100%;
  538. display: flex;
  539. flex-direction: column;
  540. .lside-scrollbox-items {
  541. width: 100%;
  542. height: 72rpx;
  543. display: flex;
  544. justify-content: center;
  545. align-items: center;
  546. font-size: 24rpx;
  547. font-family: PingFangSC-Regular, PingFang SC;
  548. font-weight: 400;
  549. color: #666666;
  550. overflow: hidden;
  551. text-overflow: ellipsis;
  552. white-space: nowrap;
  553. &.active {
  554. font-weight: 600;
  555. color: #2671E2;
  556. background: #FFFFFF;
  557. }
  558. }
  559. }
  560. }
  561. }
  562. .rside {
  563. width: 100%;
  564. height: 100%;
  565. .rside-scrollbox {
  566. width: 100%;
  567. min-height: 100%;
  568. background: #fff;
  569. display: flex;
  570. flex-direction: column;
  571. .single {
  572. width: 100%;
  573. display: flex;
  574. flex-direction: column;
  575. .hejisan {
  576. margin: 0 auto 28rpx;
  577. width: 542rpx;
  578. height: 120rpx;
  579. display: flex;
  580. background: #F6F7FB;
  581. border-radius: 8rpx;
  582. .sanbox1 {
  583. position: relative;
  584. flex-grow: 1;
  585. display: flex;
  586. flex-direction: column;
  587. justify-content: center;
  588. align-items: center;
  589. &:last-child::after {
  590. content: '';
  591. position: absolute;
  592. left: 0;
  593. top: 50%;
  594. transform: translateY(-50%);
  595. width: 1rpx;
  596. height: 80rpx;
  597. background: #E0E0E0;
  598. }
  599. }
  600. .text1-1 {
  601. font-size: 24rpx;
  602. font-family: PingFangSC-Regular, PingFang SC;
  603. font-weight: 400;
  604. color: #333333;
  605. line-height: 32rpx;
  606. }
  607. .text1-2 {
  608. color: #333333;
  609. font-size: 40rpx;
  610. line-height: 46rpx;
  611. font-family: PingFangSC-Regular, PingFang SC;
  612. margin-bottom: 10rpx;
  613. }
  614. }
  615. .uchaserbox {
  616. width: 100%;
  617. height: 470rpx;
  618. }
  619. .box {
  620. margin: 0 0 28rpx;
  621. padding: 0 24rpx;
  622. width: 100%;
  623. display: flex;
  624. .box-lside {
  625. margin: 0 24rpx 0 0;
  626. flex-shrink: 0;
  627. display: flex;
  628. justify-content: center;
  629. align-items: center;
  630. .img {
  631. width: 42rpx;
  632. height: 44rpx;
  633. }
  634. .ranking {
  635. width: 42rpx;
  636. height: 44rpx;
  637. font-size: 24rpx;
  638. font-family: SFPro-SemiboldItalic, SFPro;
  639. font-weight: normal;
  640. color: #8A8D9F;
  641. }
  642. }
  643. .box-rside {
  644. flex-grow: 1;
  645. .box-top {
  646. margin-bottom: 14rpx;
  647. width: 470rpx;
  648. display: flex;
  649. .percent-name {
  650. flex-grow: 1;
  651. width: calc(100% - 42rpx);
  652. overflow: hidden;
  653. white-space: nowrap;
  654. text-overflow: ellipsis;
  655. }
  656. .percent-zxl {
  657. flex-shrink: 0;
  658. }
  659. }
  660. .percent-box {
  661. width: 100%;
  662. height: 30rpx;
  663. .percent {
  664. height: 100%;
  665. background: #F1F3FF;
  666. border-radius: 15px;
  667. }
  668. }
  669. }
  670. }
  671. }
  672. }
  673. }
  674. }
  675. </style>