statPanelTotal.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <template>
  2. <view class="uni-stat--x p-m" >
  3. <view class="uni-stat-card-header">概况</view>
  4. <uni-table :loading="loading" border stripe emptyText="暂无更多数据" style="min-height: 100px;">
  5. <!-- 表头行 -->
  6. <uni-tr>
  7. <uni-th align="center" class="th"></uni-th>
  8. <uni-th align="center" class="th">今日</uni-th>
  9. <uni-th align="center" class="th">昨日</uni-th>
  10. <uni-th align="center" class="th">前日</uni-th>
  11. <uni-th align="center" class="th">本周</uni-th>
  12. <uni-th align="center" class="th">本月</uni-th>
  13. <uni-th align="center" class="th">本季度</uni-th>
  14. <uni-th align="center" class="th">本年度</uni-th>
  15. <uni-th align="center" class="th">累计</uni-th>
  16. </uni-tr>
  17. <!-- 表格数据行 -->
  18. <uni-tr v-for="(item,index) in fieldsMap" :key="index">
  19. <uni-td align="center" class="td">
  20. <uni-tooltip>
  21. <view class="uni-stat--sum-item-title">
  22. {{ item.title }}
  23. <uni-icons class="ml-s" type="help" color="#666" />
  24. </view>
  25. <template v-slot:content v-if="item.tooltip">
  26. <view class="uni-stat-tooltip-s">
  27. {{ item.tooltip }}
  28. </view>
  29. </template>
  30. </uni-tooltip>
  31. </uni-td>
  32. <uni-td align="center" class="td">{{ panelData.today[item.field] }}</uni-td>
  33. <uni-td align="center" class="td">{{ panelData.yesterday[item.field] }}</uni-td>
  34. <uni-td align="center" class="td">{{ panelData.beforeyesterday[item.field] }}</uni-td>
  35. <uni-td align="center" class="td">{{ panelData.week[item.field] }}</uni-td>
  36. <uni-td align="center" class="td">{{ panelData.month[item.field] }}</uni-td>
  37. <uni-td align="center" class="td">{{ panelData.quarter[item.field] }}</uni-td>
  38. <uni-td align="center" class="td">{{ panelData.year[item.field] }}</uni-td>
  39. <uni-td align="center" class="td">{{ panelData.total[item.field] }}</uni-td>
  40. </uni-tr>
  41. </uni-table>
  42. </view>
  43. </template>
  44. <script>
  45. import {
  46. formatterData,
  47. stringifyQuery,
  48. stringifyField,
  49. stringifyGroupField,
  50. getTimeOfSomeDayAgo,
  51. formatDate,
  52. parseDateTime,
  53. debounce,
  54. } from '@/js_sdk/uni-stat/util.js'
  55. import timeUtil from "@/js_sdk/uni-stat/timeUtil.js"
  56. import {
  57. statPanelTodayFieldsMap,
  58. } from '../fieldsMap.js'
  59. let fieldsMap = statPanelTodayFieldsMap;
  60. export default {
  61. props: {
  62. query: {
  63. type: [Object],
  64. default: function(){
  65. return {}
  66. }
  67. },
  68. },
  69. data() {
  70. return {
  71. tableName: 'uni-stat-pay-result',
  72. fieldsMap,
  73. panelData: {
  74. today:{pay_total_amount:"-",pay_order_count:"-"},
  75. yesterday:{pay_total_amount:"-",pay_order_count:"-"},
  76. beforeyesterday:{pay_total_amount:"-",pay_order_count:"-"},
  77. week:{pay_total_amount:"-",pay_order_count:"-"},
  78. month:{pay_total_amount:"-",pay_order_count:"-"},
  79. quarter:{pay_total_amount:"-",pay_order_count:"-"},
  80. year:{pay_total_amount:"-",pay_order_count:"-"},
  81. total:{pay_total_amount:"-",pay_order_count:"-"},
  82. },
  83. loading:false,
  84. }
  85. },
  86. created() {
  87. this.getCloudDataDebounce = debounce(() => {
  88. this.getCloudData();
  89. }, 300);
  90. this.getCloudDataDebounce();
  91. },
  92. methods: {
  93. // 获取云端数据
  94. getCloudData() {
  95. let query = this.query;
  96. if (!query.appid) return;
  97. this.loading = true;
  98. query = stringifyQuery(query, true, ['uni_platform']);
  99. let where = this.getWhere(query);
  100. if (query) {
  101. where = `${query} && (${where})`;
  102. }
  103. //console.log('where: ', where)
  104. const db = uniCloud.database();
  105. db.collection(this.tableName)
  106. .where(where)
  107. .field(`${stringifyField(fieldsMap)}, dimension, stat_date.date_str as stat_time, start_time`)
  108. .groupBy(`stat_time, dimension`)
  109. .groupField(stringifyGroupField(fieldsMap)+",last(start_time) as start_time")
  110. //.field(`pay_total_amount,pay_order_count, dimension, start_time`)
  111. .get()
  112. .then(res => {
  113. let data = res.result.data;
  114. data.map((item, index) => {
  115. if (!item.actual_total_amount) item.actual_total_amount = item.pay_total_amount - item.refund_total_amount;
  116. });
  117. // 数据格式化
  118. data = formatterData({
  119. fieldsMap,
  120. data
  121. });
  122. this.loading = false;
  123. //console.log('data: ', data)
  124. Object.assign(this.panelData, this.setPanelData(data));
  125. //console.log('this.panelData: ', this.panelData)
  126. });
  127. // 再单独获取下总金额
  128. let totalWhere = `${query} && dimension == "year"`;
  129. //console.log('totalWhere: ', totalWhere)
  130. db.collection(this.tableName)
  131. .where(totalWhere)
  132. .field(`${stringifyField(fieldsMap)}, dimension`)
  133. .groupBy(`dimension`)
  134. .groupField(stringifyGroupField(fieldsMap))
  135. .get()
  136. .then(res => {
  137. let data = res.result.data;
  138. data.map((item, index) => {
  139. item.actual_total_amount = item.pay_total_amount - item.refund_total_amount;
  140. });
  141. // 数据格式化
  142. data = formatterData({
  143. fieldsMap,
  144. data
  145. });
  146. Object.assign(this.panelData, {
  147. total: data[0] || { pay_total_amount:0, pay_order_count:0, create_total_amount:0, refund_total_amount:0, actual_total_amount:0 }
  148. });
  149. })
  150. },
  151. // 获取查询条件
  152. getWhere(query){
  153. let where;
  154. // 昨日的条件 or 今日的条件 or 本周的条件 or 本月的条件 or 本季度的条件 or 本年度的条件
  155. let nowTime = Date.now();
  156. let today = timeUtil.getOffsetStartAndEnd("day",0,nowTime);
  157. let yesterday = timeUtil.getOffsetStartAndEnd("day",-1,nowTime);
  158. let beforeyesterday = timeUtil.getOffsetStartAndEnd("day",-2,nowTime);
  159. let week = timeUtil.getOffsetStartAndEnd("week",0,nowTime);
  160. let month = timeUtil.getOffsetStartAndEnd("month",0,nowTime);
  161. let quarter = timeUtil.getOffsetStartAndEnd("quarter",0,nowTime);
  162. let year = timeUtil.getOffsetStartAndEnd("year",0,nowTime);
  163. where = `(dimension=="day" && start_time==${today.startTime} && end_time==${today.endTime}) || (dimension=="day" && start_time==${yesterday.startTime} && end_time==${yesterday.endTime}) || (dimension=="day" && start_time==${beforeyesterday.startTime} && end_time==${beforeyesterday.endTime}) || (dimension=="week" && start_time==${week.startTime} && end_time==${week.endTime}) || (dimension=="month" && start_time==${month.startTime} && end_time==${month.endTime}) || (dimension=="quarter" && start_time==${quarter.startTime} && end_time==${quarter.endTime}) || (dimension=="year" && start_time==${year.startTime} && end_time==${year.endTime})`;
  164. return where;
  165. },
  166. // 设置面板数据
  167. setPanelData(data){
  168. let nowTime = Date.now();
  169. let todayData = timeUtil.getOffsetStartAndEnd("day", 0,nowTime);
  170. let yesterdayData = timeUtil.getOffsetStartAndEnd("day",-1,nowTime);
  171. let beforeyesterdayData = timeUtil.getOffsetStartAndEnd("day",-2,nowTime);
  172. let today = data.find((item) => {
  173. return item.dimension === 'day' && item.start_time === todayData.startTime;
  174. });
  175. let yesterday = data.find((item) => {
  176. return item.dimension === 'day' && item.start_time === yesterdayData.startTime;
  177. });
  178. let beforeyesterday = data.find((item) => {
  179. return item.dimension === 'day' && item.start_time === beforeyesterdayData.startTime;
  180. });
  181. let week = data.find((item) => {
  182. return item.dimension === 'week';
  183. });
  184. let month = data.find((item) => {
  185. return item.dimension === 'month';
  186. });
  187. let quarter = data.find((item) => {
  188. return item.dimension === 'quarter';
  189. });
  190. let year = data.find((item) => {
  191. return item.dimension === 'year';
  192. });
  193. let defaultData = { pay_total_amount:0, pay_order_count:0, create_total_amount:0, refund_total_amount:0, actual_total_amount:0 };
  194. return {
  195. today: today || defaultData,
  196. yesterday: yesterday || defaultData,
  197. beforeyesterday: beforeyesterday || defaultData,
  198. week: week || defaultData,
  199. month: month || defaultData,
  200. quarter: quarter || defaultData,
  201. year: year || defaultData,
  202. };
  203. }
  204. },
  205. watch: {
  206. query: {
  207. deep: true,
  208. handler(val) {
  209. this.getCloudDataDebounce()
  210. }
  211. }
  212. },
  213. }
  214. </script>
  215. <style lang="scss" scoped>
  216. .uni-stat-tooltip-s {
  217. width: 400px;
  218. white-space: normal;
  219. }
  220. .uni-stat--sum {
  221. &-x {
  222. display: flex;
  223. align-items: center;
  224. justify-content: center;
  225. flex-wrap: wrap;
  226. border-radius: 4px;
  227. padding: 15px;
  228. box-shadow: -1px -1px 5px 0 rgba(0, 0, 0, 0.1);
  229. }
  230. &-item {
  231. white-space: nowrap;
  232. text-align: center;
  233. margin: 10px 18px;
  234. &-width {
  235. width: 100px
  236. }
  237. }
  238. &-item-title {
  239. display: flex;
  240. align-items: center;
  241. justify-content: center;
  242. min-height: 17px;
  243. font-size: 12px;
  244. color: #666;
  245. }
  246. &-item-value {
  247. font-size: 24px;
  248. line-height: 48px;
  249. font-weight: 700;
  250. color: #333;
  251. }
  252. &-item-contrast {
  253. font-size: 14px;
  254. color: #666;
  255. }
  256. }
  257. /* #ifndef APP-NVUE */
  258. @media screen and (max-width: 500px) {
  259. .uni-stat--sum-x {
  260. padding: 15px 0;
  261. align-items: center;
  262. justify-content: center;
  263. flex-wrap: unset;
  264. overflow-x: auto !important;
  265. }
  266. ::-webkit-scrollbar {
  267. display: none;
  268. }
  269. }
  270. /* #endif */
  271. .uni-stat--sum-flex{
  272. flex:1;
  273. display: flex;
  274. justify-content: flex-start;
  275. flex-wrap: wrap;
  276. border-radius: 4px;
  277. padding: 15px;
  278. .uni-stat--sum-item{
  279. min-width: 300rpx;
  280. max-width: 500rpx;
  281. flex:1;
  282. }
  283. }
  284. .uni-stat-card-header {
  285. justify-content: space-between;
  286. color: #555;
  287. font-size: 14px;
  288. font-weight: 600;
  289. padding: 10px 0;
  290. margin-bottom: 15px;
  291. }
  292. .td.main{
  293. color:#e43d33;
  294. }
  295. </style>