customer.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. <template>
  2. <view class="uni-app">
  3. <view class="status-bar" />
  4. <view class="main-container">
  5. <wk-nav-bar title="客户统计" />
  6. <view class="filter-tab">
  7. <view class="filter-box user" @click="handleOpenFilter('userOrDept')">
  8. <text class="text">
  9. {{ filterDataTypeLabel }}
  10. </text>
  11. <text class="icon" />
  12. </view>
  13. <view class="line" />
  14. <view class="filter-box time" @click="handleOpenFilter('time')">
  15. <text class="text">
  16. {{ filterTimeLabel }}
  17. </text>
  18. <text class="icon" />
  19. </view>
  20. </view>
  21. <scroll-view
  22. scroll-y
  23. class="container">
  24. <view class="statistics">
  25. <view class="row">
  26. <view class="column">
  27. <view class="text">
  28. <text class="number">
  29. {{ statisticsData.allCustomer }}
  30. </text>
  31. <text class="unit">
  32. </text>
  33. </view>
  34. <view class="desc">
  35. 新增客户数
  36. </view>
  37. </view>
  38. <view class="line" />
  39. <view class="column">
  40. <view class="text">
  41. <text class="number">
  42. {{ statisticsData.dealCustomer }}
  43. </text>
  44. <text class="unit">
  45. </text>
  46. </view>
  47. <view class="desc">
  48. 成交客户数
  49. </view>
  50. </view>
  51. </view>
  52. <view class="row">
  53. <view class="column">
  54. <view class="text">
  55. <text class="number">
  56. {{ statisticsData.activityNum }}
  57. </text>
  58. <text class="unit">
  59. </text>
  60. </view>
  61. <view class="desc">
  62. 跟进客户数
  63. </view>
  64. </view>
  65. <view class="line" />
  66. <view class="column">
  67. <view class="text">
  68. <text class="number">
  69. {{ statisticsData.putInPoolNum }}
  70. </text>
  71. <text class="unit">
  72. </text>
  73. </view>
  74. <view class="desc">
  75. 进入公海客户数
  76. </view>
  77. </view>
  78. </view>
  79. <view class="row">
  80. <view class="column">
  81. <view class="text">
  82. <text class="number">
  83. {{ statisticsData.receiveNum }}
  84. </text>
  85. <text class="unit">
  86. </text>
  87. </view>
  88. <view class="desc">
  89. 公海池领取客户数
  90. </view>
  91. </view>
  92. <view class="line" />
  93. <view class="column" style="visibility: hidden;" />
  94. </view>
  95. </view>
  96. </scroll-view>
  97. <uni-popup
  98. ref="filterPopup"
  99. :mask-click="filterPopupMaskFlag"
  100. radius="20rpx 20rpx 0 0"
  101. type="bottom"
  102. @mask-close="filterMaskClick">
  103. <workbench-filter
  104. ref="workbenchFilter"
  105. :filter-data="filterObj"
  106. :default-tab="filterDefaultTab"
  107. @popup-change="childPopupChange"
  108. @change="handleChangeFilter"
  109. @close="handleCloseFilter" />
  110. </uni-popup>
  111. </view>
  112. </view>
  113. </template>
  114. <script>
  115. import { QueryDataInfo } from 'API/crm/work'
  116. import WorkbenchFilter from '@/components/base/workbench-filter.vue'
  117. import mixins from './mixins.js'
  118. import uCharts from '@/components/u-charts/u-charts.js'
  119. let customerStatisticsChart = null
  120. export default {
  121. name: 'CustomerStatistics',
  122. components: {
  123. WorkbenchFilter
  124. },
  125. mixins: [mixins],
  126. data() {
  127. return {
  128. statisticsData: {}
  129. }
  130. },
  131. mounted() {
  132. const _self = this;
  133. // #ifdef MP-ALIPAY
  134. uni.getSystemInfo({
  135. success: function(res) {
  136. if (res.pixelRatio > 1) {
  137. // 正常这里给2就行,如果pixelRatio=3性能会降低一点
  138. // _self.pixelRatio =res.pixelRatio;
  139. _self.pixelRatio = 2;
  140. }
  141. }
  142. });
  143. // #endif
  144. this.cWidth = uni.upx2px(686)
  145. this.cHeight = uni.upx2px(450)
  146. this.getData()
  147. },
  148. methods: {
  149. getData() {
  150. if (this.loading) return
  151. this.loading = true
  152. QueryDataInfo({
  153. ...this.filterData
  154. }).then(res => {
  155. this.loading = false
  156. this.statisticsData = res
  157. }).catch(() => {
  158. this.loading = false
  159. })
  160. // const data = [
  161. // { type: '3-11', money: '500', achievement: '355' },
  162. // { type: '3-12', money: '550', achievement: '2255' },
  163. // ]
  164. // this.initChart('customerStatistics', data)
  165. },
  166. initChart(canvasId, chartData) {
  167. const _self = this
  168. const options = {
  169. $this: _self,
  170. canvasId: canvasId,
  171. width: _self.cWidth * _self.pixelRatio,
  172. height: _self.cHeight * _self.pixelRatio,
  173. type: 'column',
  174. pixelRatio: _self.pixelRatio,
  175. background: '#FFFFFF',
  176. fontSize: 11,
  177. animation: true,
  178. dataLabel: false,
  179. padding: [15, 0, 0, 0],
  180. legend: { // 图例
  181. show: true,
  182. position: 'bottom',
  183. float: 'center'
  184. },
  185. xAxis: {
  186. axisLine: false,
  187. disableGrid: true,
  188. itemCount: 9,
  189. scrollShow: true,
  190. scrollAlign: 'left'
  191. },
  192. yAxis: {
  193. gridType: 'dash',
  194. min: 0
  195. },
  196. enableScroll: true,
  197. extra: {
  198. column: {
  199. type: 'group',
  200. width: 15
  201. }
  202. },
  203. categories: chartData.map(o => o.type),
  204. series: [
  205. {
  206. name: '成交客户',
  207. color: '#6ca2ff',
  208. data: chartData.map(o => o.money),
  209. type: 'column'
  210. },
  211. {
  212. name: '新增客户',
  213. color: '#FF7300',
  214. data: chartData.map(o => o.achievement),
  215. type: 'column'
  216. },
  217. ]
  218. }
  219. // #ifdef MP-WEIXIN
  220. this.$nextTick(function() {
  221. const query = uni.createSelectorQuery().in(this)
  222. query.select('#' + canvasId)
  223. .fields({ node: true, size: true })
  224. .exec(res => {
  225. // console.log('res: ', res[0])
  226. const data = res[0]
  227. const canvas = res[0].node
  228. const ctx = canvas.getContext('2d')
  229. options.context = ctx
  230. options.canvas2d = true
  231. const dpr = wx.getSystemInfoSync().pixelRatio
  232. options.width = _self.cWidth * dpr
  233. options.height = _self.cHeight * dpr
  234. options.pixelRatio = dpr
  235. options.extra.column.width = options.extra.column.width * dpr
  236. canvas.width = options.width
  237. canvas.height = options.height
  238. // eslint-disable-next-line new-cap
  239. customerStatisticsChart = new uCharts(options)
  240. })
  241. })
  242. // #endif
  243. // #ifndef MP-WEIXIN
  244. // eslint-disable-next-line new-cap
  245. customerStatisticsChart = new uCharts(options)
  246. // #endif
  247. },
  248. touchMix(e) {
  249. customerStatisticsChart.scrollStart(e);
  250. },
  251. moveMix(e) {
  252. customerStatisticsChart.scroll(e);
  253. },
  254. touchEndMix(e) {
  255. customerStatisticsChart.scrollEnd(e);
  256. customerStatisticsChart.touchLegend(e);
  257. // 下面是toolTip事件,如果滚动后不需要显示,可不填写
  258. customerStatisticsChart.showToolTip(e, {
  259. format: function(item, category) {
  260. // console.log(item)
  261. return category + ' ' + item.name + ':' + item.data + '个'
  262. }
  263. });
  264. }
  265. }
  266. }
  267. </script>
  268. <style scoped lang="scss">
  269. @import "./style.scss";
  270. </style>