CustomerMerchandiseReport.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <template>
  2. <view>
  3. <view class="home">
  4. <view class="content_top">
  5. <view class="search-icon" @click="openSearch"><text class="custom-icon custom-icon-shaixuan"></text></view>
  6. <view class="view-subsection"><u-subsection active-color="#2979ff" @change="tabChange" :list="list" :current="tab_current"></u-subsection></view>
  7. </view>
  8. <view class="charts-box"><qiun-data-charts type="mix" :chartData="chartData" :echartsH5="true" :echartsApp="true" background="none" :animation="false" /></view>
  9. </view>
  10. <view class="top-view">
  11. <view class="thead">
  12. <view class="flex1 sort-li">客户</view>
  13. <view class="flex1 staff-li">商品数量</view>
  14. <view class="flex1 cutomer-li">商品金额</view>
  15. </view>
  16. <scroll-view class="cont-ul" scroll-y="true">
  17. <view class="flex" v-for="(item, index) in goods_list" :key="index">
  18. <view class="flex1 sort-li">{{ item.title }}</view>
  19. <view class="flex1 staff-li">{{ item.goodsNum }}</view>
  20. <view class="flex1 cutomer-li">{{ item.goodsAmount }}</view>
  21. </view>
  22. <u-loadmore :status="load_status" :load-text="loadText" @loadmore="loadmoreData" />
  23. </scroll-view>
  24. </view>
  25. <u-popup v-model="search_show" mode="right" >
  26. <view class="search-pop">
  27. <view class="form-view">
  28. <u-form label-width="160rpx" label-position="left">
  29. <u-form-item label-position="top" label="下单日期">
  30. <view class="date-li">
  31. <picker mode="date" @change="bindDateStartChange">
  32. <text class="date-li">{{ search_data.start ? $u.timeFormat(search_data.start, 'yyyy-mm-dd') : '开始日期' }}</text>
  33. </picker>
  34. </view>
  35. <view class="date-line">-</view>
  36. <view class="date-li">
  37. <picker mode="date" @change="bindDateEndChange">
  38. <text class="date-li">{{ search_data.end ? $u.timeFormat(search_data.end, 'yyyy-mm-dd') : '结束日期' }}</text>
  39. </picker>
  40. </view>
  41. </u-form-item>
  42. <u-form-item label="商品分类">
  43. <view class="clearfix form-val" @click="openSel('cate_show')">
  44. <text class="float_left ellipsis">{{ search_data.category_name ? search_data.category_name : '请选择' }}</text>
  45. <view class="float_right"><u-icon :name="!search_data.categoryId ? 'arrow-right' : 'close-circle-fill'" size="28" color="#999999"></u-icon></view>
  46. </view>
  47. </u-form-item>
  48. </u-form>
  49. </view>
  50. <view class="search-btn">
  51. <view class="btn-li" @click="clearValue()">重置</view>
  52. <view class="btn-li" @click="searchConfirm">确定</view>
  53. </view>
  54. </view>
  55. </u-popup>
  56. <tki-tree style="z-index: 99;" ref="tkitree" :selectParent="true" :range="cate_list" rangeKey="title" @confirm="cateConfirm"></tki-tree>
  57. </view>
  58. </template>
  59. <script>
  60. import tkiTree from '@/components/tki-tree/tki-tree.vue';
  61. export default {
  62. components: {
  63. tkiTree
  64. },
  65. data() {
  66. return {
  67. loadText: {
  68. loadmore: '点击加载更多',
  69. loading: '努力加载中',
  70. nomore: '没有更多了'
  71. },
  72. list: [
  73. {
  74. name: '客户'
  75. },
  76. {
  77. name: '客户类型'
  78. }
  79. ],
  80. tab_current: 0,
  81. page: 1,
  82. pageSize: 10,
  83. total: 0,
  84. type: 1,
  85. chartData: {
  86. categories: [],
  87. series: []
  88. },
  89. goods_list: {},
  90. search_data: {
  91. start: '',
  92. end: '',
  93. category_name: '',
  94. categoryId: ''
  95. },
  96. search_show: false,
  97. cate_list: [],
  98. load_status: 'nomore'
  99. };
  100. },
  101. onLoad() {
  102. this.customerGoods();
  103. this.getAllCategory();
  104. },
  105. onPullDownRefresh() {
  106. this.page = 1;
  107. this.customerGoods();
  108. },
  109. methods: {
  110. loadmoreData() {
  111. if (this.total / this.pageSize > this.page) {
  112. this.page += 1;
  113. this.customerGoods();
  114. }
  115. },
  116. openSearch() {
  117. this.search_show = true;
  118. },
  119. tabChange(index) {
  120. this.search_data = {
  121. start: '',
  122. end: '',
  123. category_name: '',
  124. categoryId: ''
  125. };
  126. this.tab_current = index;
  127. this.type = index + 1;
  128. this.page = 1;
  129. this.customerGoods();
  130. },
  131. customerGoods() {
  132. this.load_status = 'loading';
  133. this.$u.api
  134. .customerGoods({
  135. page: this.page,
  136. pageSize: this.pageSize,
  137. categoryId: this.search_data.categoryId,
  138. startTime: this.search_data.start,
  139. endTime: this.search_data.end,
  140. type: this.type
  141. })
  142. .then(res => {
  143. uni.stopPullDownRefresh();
  144. if (this.page === 1) {
  145. this.goods_list = res.data;
  146. } else {
  147. this.goods_list = this.goods_list.concat(res.data);
  148. }
  149. this.total = res.pageTotal;
  150. this.load_status = this.$utils.loadStatus(this.page, this.pageSize, this.total);
  151. const goodsName = [];
  152. const goodsNum = [];
  153. const goodsMoney = [];
  154. this.$nextTick(()=>{
  155. res.data.forEach(value => {
  156. goodsName.push(value.title);
  157. goodsNum.push(Number(value.goodsNum));
  158. goodsMoney.push(Number(value.goodsAmount));
  159. });
  160. this.setChartData(goodsName, goodsNum, goodsMoney);
  161. })
  162. });
  163. },
  164. setChartData(goodsName, goodsNum, goodsMoney) {
  165. this.chartData = {
  166. categories: goodsName,
  167. series: [
  168. {
  169. name: '商品数量',
  170. data: goodsNum,
  171. // #ifdef APP-PLUS
  172. type: 'bar',
  173. // #endif
  174. // #ifdef MP-WEIXIN
  175. type: 'column',
  176. // #endif
  177. index: 1
  178. },
  179. {
  180. name: '商品金额',
  181. data: goodsMoney,
  182. type: 'line',
  183. style: 'curve',
  184. // #ifdef APP-PLUS
  185. yAxisIndex: 1,
  186. smooth: true,
  187. // #endif
  188. disableLegend: true
  189. }
  190. ]
  191. };
  192. },
  193. bindDateStartChange(e) {
  194. this.search_data.start = this.$utils.timeByTimestamp(e.detail.value + ' 00:00:00');
  195. },
  196. bindDateEndChange(e) {
  197. this.search_data.end = this.$utils.timeByTimestamp(e.detail.value + ' 23:59:59');
  198. },
  199. openSel(key) {
  200. if (key === 'cate_show') {
  201. this.$refs.tkitree._show();
  202. return;
  203. }
  204. },
  205. // 获取所有商品分类
  206. getAllCategory() {
  207. this.$u.api
  208. .getAllCategory({
  209. enableStatus: 5
  210. })
  211. .then(res => {
  212. this.cate_list = res.data;
  213. });
  214. },
  215. clearValue() {
  216. this.search_data = {
  217. start: '',
  218. end: '',
  219. category_name: '',
  220. categoryId: ''
  221. };
  222. this.searchConfirm();
  223. },
  224. searchConfirm() {
  225. this.search_show = false;
  226. this.page = 1;
  227. this.customerGoods();
  228. },
  229. cateConfirm(arr) {
  230. this.search_data.category_name = arr[0].title;
  231. this.search_data.categoryId = arr[0].id;
  232. }
  233. }
  234. };
  235. </script>
  236. <style lang="scss" scoped>
  237. .charts-box {
  238. width: 730rpx;
  239. /* #ifdef MP-WEIXIN */
  240. height: 450rpx;
  241. /* #endif */
  242. /* #ifdef APP-PLUS */
  243. height: 550rpx;
  244. /* #endif */
  245. margin: 0 auto;
  246. }
  247. .home {
  248. position: relative;
  249. /* #ifdef MP-WEIXIN */
  250. padding-top: 100rpx;
  251. /* #endif */
  252. .content_top {
  253. position: absolute;
  254. width: 100%;
  255. z-index: 1;
  256. left: 0;
  257. top: 20rpx;
  258. .view-subsection {
  259. width: 300rpx;
  260. margin: 0 auto;
  261. }
  262. .search-icon {
  263. position: absolute;
  264. right: 20rpx;
  265. width: 80rpx;
  266. top: 16rpx;
  267. text-align: center;
  268. }
  269. }
  270. }
  271. .top-view {
  272. width: 100%;
  273. z-index: 9;
  274. .thead {
  275. line-height: 60rpx;
  276. height: 60rpx;
  277. font-size: 24rpx;
  278. background-color: #f5f5f5;
  279. display: flex;
  280. width: 100%;
  281. }
  282. .search-view {
  283. width: 100%;
  284. }
  285. }
  286. .flex1 {
  287. display: table-cell;
  288. text-align: center;
  289. position: relative;
  290. height: 100%;
  291. vertical-align: middle;
  292. &.staff-li {
  293. width: 33%;
  294. }
  295. &.sort-li {
  296. width: 33%;
  297. }
  298. &.cutomer-li {
  299. width: 33%;
  300. }
  301. }
  302. .cont-ul {
  303. height: calc(100vh - 620rpx);
  304. background-color: #ffffff;
  305. .flex {
  306. height: 70rpx;
  307. }
  308. }
  309. .flex {
  310. display: table;
  311. width: 750rpx;
  312. font-size: 24rpx;
  313. }
  314. </style>