ranking.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <template>
  2. <view>
  3. <view class="uni-header">
  4. <view class="uni-group">
  5. <uni-stat-breadcrumb />
  6. </view>
  7. <view class="uni-group">
  8. <button class="uni-button" type="default" size="mini" @click="search">搜索</button>
  9. <download-excel class="hide-on-phone" :fields="exportExcel.fields" :data="exportExcelData" :type="exportExcel.type" :name="exportExcel.filename">
  10. <button class="uni-button" type="primary" size="mini">导出 Excel</button>
  11. </download-excel>
  12. </view>
  13. </view>
  14. <view class="uni-container">
  15. <view class="uni-stat--x flex p-1015">
  16. <view class="uni-stat--app-select">
  17. <uni-data-select collection="opendb-app-list" field="appid as value, name as text" orderby="text asc" :defItem="1" label="应用选择" v-model="query.appid" :clear="false" />
  18. <uni-data-select collection="opendb-app-versions" :where="versionQuery" class="ml-m" field="_id as value, version as text, uni_platform as label, create_date as date" format="{label} - {text}" orderby="date desc" label="版本选择" v-model="query.version_id" />
  19. </view>
  20. </view>
  21. <view class="uni-stat--x" style="margin-bottom: 0;">
  22. <uni-stat-tabs label="平台选择" type="boldLine" mode="platform" v-model="query.platform_id" @change="platformChange" />
  23. <uni-data-select ref="version-select" v-if="query.platform_id && query.platform_id.indexOf('==') === -1" collection="uni-stat-app-channels" :where="channelQuery" class="p-channel" field="channel_code as value, channel_name as text" orderby="text asc" label="渠道/场景值选择" v-model="query.channel_code" />
  24. </view>
  25. <!-- 时间纬度 -->
  26. <view class="flex">
  27. <uni-stat-tabs type="box" :current="dateTabs.index" :tabs="dateTabs.list" @change="dateTabsChange" />
  28. <uni-datetime-picker type="datetimerange" v-model="query.pay_date" :end="Date.now()" return-type="timestamp" :clear-icon="true" class="uni-stat-datetime-picker" @change="dateTabs.index=null"/>
  29. </view>
  30. <unicloud-db ref="udb" :collection="collectionList" field="user_id,nickname,uni_platform,status,total_fee,refund_fee,appid,pay_date"
  31. :where="where" page-data="replace" :orderby="orderby" :getcount="true" :page-size="options.pageSize"
  32. :page-current="options.pageCurrent" groupby="user_id"
  33. group-field="sum(total_fee) as total_fee,sum(refund_fee) as refund_fee, sum(subtract(total_fee,refund_fee)) as reality_fee, sum(1) as count,last(nickname) as nickname"
  34. v-slot:default="{data,pagination,loading,error,options}" :options="options" loadtime="manual" @load="onqueryload">
  35. <uni-table ref="table" :loading="loading" :emptyText="error.message || loading ? '请求中...' : '没有更多数据'" border stripe type="" style="min-height: 900px;"
  36. @selection-change="selectionChange">
  37. <uni-tr>
  38. <uni-th align="center">排名</uni-th>
  39. <uni-th align="center" sortable @sort-change="sortChange($event, 'user_id')">用户</uni-th>
  40. <uni-th align="center" sortable @sort-change="sortChange($event, 'reality_fee')">支付金额(不含退款)</uni-th>
  41. <uni-th align="center" sortable @sort-change="sortChange($event, 'count')">订单数量</uni-th>
  42. </uni-tr>
  43. <uni-tr v-for="(item,index) in data" :key="index">
  44. <uni-td align="center">{{ parseInt((index+1) + (pagination.current-1) * pagination.size) }} </uni-td>
  45. <uni-td align="center"><text class="text-btn" @click="pageToUser(item)">{{ nameFormat(item) }}</text> </uni-td>
  46. <uni-td align="center">{{ (item.reality_fee / 100).toFixed(2) }}</uni-td>
  47. <uni-td align="center"> <text class="text-btn" @click="pageToOrder(item)"> {{ item.count }} </text> </uni-td>
  48. </uni-tr>
  49. </uni-table>
  50. <view class="uni-pagination-box">
  51. <uni-pagination show-icon :page-size="pagination.size" v-model="pagination.current" :total="pagination.count"
  52. @change="onPageChanged" />
  53. </view>
  54. </unicloud-db>
  55. </view>
  56. </view>
  57. </template>
  58. <script>
  59. import {
  60. enumConverter,
  61. filterToWhere
  62. } from '../../../../js_sdk/validator/uni-pay-orders.js';
  63. const db = uniCloud.database()
  64. // 表查询配置
  65. const dbOrderBy = 'total_fee desc' // 排序字段
  66. // 分页配置
  67. const pageSize = 20
  68. const pageCurrent = 1
  69. const orderByMapping = {
  70. "ascending": "asc",
  71. "descending": "desc"
  72. }
  73. import {
  74. mapfields,
  75. stringifyQuery,
  76. stringifyField,
  77. stringifyGroupField,
  78. getTimeOfSomeDayAgo,
  79. division,
  80. format,
  81. formatDate,
  82. parseDateTime,
  83. getFieldTotal,
  84. debounce
  85. } from '@/js_sdk/uni-stat/util.js'
  86. import timeUtil from "@/js_sdk/uni-stat/timeUtil.js"
  87. export default {
  88. data() {
  89. return {
  90. collectionList: "uni-pay-orders",
  91. query: {
  92. appid: '',
  93. platform_id: '',
  94. uni_platform: '',
  95. version: '',
  96. pay_date: [],
  97. channel_code:""
  98. },
  99. where: '',
  100. orderby: dbOrderBy,
  101. orderByFieldName: "",
  102. selectedIndexs: [],
  103. options: {
  104. pageSize,
  105. pageCurrent,
  106. filterData: {
  107. },
  108. ...enumConverter
  109. },
  110. imageStyles: {
  111. width: 64,
  112. height: 64
  113. },
  114. exportExcel: {
  115. "filename": "价值用户排行.xls",
  116. "type": "xls",
  117. "fields": {
  118. "用户ID": "user_id",
  119. "用户昵称": "nickname",
  120. "支付金额": "total_fee",
  121. "订单数量":"count"
  122. }
  123. },
  124. exportExcelData: [],
  125. // 时间选项
  126. dateTabs: {
  127. time: [],
  128. timeStr:"",
  129. index: null,
  130. list: [
  131. { _id: 0, name: '今天' },
  132. { _id: 1, name: '昨天' },
  133. { _id: 7, name: '最近七天' },
  134. { _id: 30, name: '最近30天' },
  135. { _id: 90, name: '最近90天' },
  136. ]
  137. },
  138. }
  139. },
  140. onLoad() {
  141. this._filter = {}
  142. },
  143. onReady() {
  144. //this.$refs.udb.loadData()
  145. },
  146. methods: {
  147. payDatePicker(val) {
  148. this.query.pay_date = val;
  149. this.search();
  150. },
  151. onqueryload(data) {
  152. this.exportExcelData = data
  153. },
  154. getWhere() {
  155. let where = "status>0";
  156. let {
  157. pay_date,
  158. appid,
  159. version,
  160. uni_platform,
  161. channel_code
  162. } = this.query;
  163. if (pay_date && pay_date.length == 2) {
  164. where += ` && pay_date>=${pay_date[0]} && pay_date<=${pay_date[1]}`;
  165. }
  166. if (appid) {
  167. where += ` && appid=='${appid}'`;
  168. }
  169. if (version) {
  170. where += ` && stat_data.app_version=='${version}'`;
  171. }
  172. if (uni_platform) {
  173. where += ` && stat_data.platform=='${uni_platform}'`;
  174. }
  175. if (channel_code) {
  176. where += ` && stat_data.channel=='${channel_code}'`;
  177. }
  178. //where = where.substring(3).trim();
  179. where = where.trim();
  180. console.log('where: ', where)
  181. return where;
  182. },
  183. search() {
  184. if (!this.query.appid) return;
  185. const newWhere = this.getWhere()
  186. this.where = newWhere
  187. this.$nextTick(() => {
  188. this.loadData()
  189. })
  190. },
  191. loadData(clear = true) {
  192. this.$refs.udb.loadData({
  193. clear
  194. })
  195. },
  196. onPageChanged(e) {
  197. this.selectedIndexs.length = 0
  198. this.$refs.table.clearSelection()
  199. this.$refs.udb.loadData({
  200. current: e.current
  201. })
  202. },
  203. navigateTo(url, clear) {
  204. // clear 表示刷新列表时是否清除页码,true 表示刷新并回到列表第 1 页,默认为 true
  205. uni.navigateTo({
  206. url,
  207. events: {
  208. refreshData: () => {
  209. this.loadData(clear)
  210. }
  211. }
  212. })
  213. },
  214. // 多选处理
  215. selectedItems() {
  216. let dataList = this.$refs.udb.dataList
  217. return this.selectedIndexs.map(i => dataList[i]._id)
  218. },
  219. // 批量删除
  220. delTable() {
  221. this.$refs.udb.remove(this.selectedItems(), {
  222. success: (res) => {
  223. this.$refs.table.clearSelection()
  224. }
  225. })
  226. },
  227. // 多选
  228. selectionChange(e) {
  229. this.selectedIndexs = e.detail.index
  230. },
  231. sortChange(e, name) {
  232. this.orderByFieldName = name;
  233. if (e.order) {
  234. this.orderby = name + ' ' + orderByMapping[e.order]
  235. } else {
  236. this.orderby = ''
  237. }
  238. this.$refs.table.clearSelection()
  239. this.$nextTick(() => {
  240. this.$refs.udb.loadData()
  241. })
  242. },
  243. filterChange(e, name) {
  244. this._filter[name] = {
  245. type: e.filterType,
  246. value: e.filter
  247. }
  248. let newWhere = filterToWhere(this._filter, db.command)
  249. if (Object.keys(newWhere).length) {
  250. this.where = newWhere
  251. } else {
  252. this.where = ''
  253. }
  254. this.$nextTick(() => {
  255. this.$refs.udb.loadData()
  256. })
  257. },
  258. platformChange(id, index, name, item) {
  259. this.query.version = 0
  260. this.query.uni_platform = item.code
  261. },
  262. nameFormat(item){
  263. if (!item.user_id) {
  264. return "匿名用户";
  265. } else if (item.nickname) {
  266. return `${item.user_id}(${item.nickname})`
  267. } else {
  268. return item.user_id;
  269. }
  270. },
  271. pageToUser(item){
  272. let { user_id } = item;
  273. uni.navigateTo({
  274. url:`/pages/system/user/list?id=${user_id}`
  275. });
  276. },
  277. pageToOrder(item){
  278. let { user_id } = item;
  279. uni.navigateTo({
  280. url:`/pages/uni-stat/pay-order/list/list?user_id=${user_id}`
  281. });
  282. },
  283. // 监听 - 日期选择更改
  284. dateTabsChange(id, index) {
  285. this.dateTabs.index = index;
  286. let start = getTimeOfSomeDayAgo(id);
  287. let end = timeUtil.getOffsetStartAndEnd("day", 0).endTime; // end默认=今天的截止时间
  288. if (id == 1) {
  289. // 如果是查昨天,则特殊处理下,end=昨天的截止时间
  290. end = timeUtil.getOffsetStartAndEnd("day",0,start).endTime;
  291. }
  292. this.query.pay_date = [start, end];
  293. },
  294. },
  295. watch: {
  296. query: {
  297. deep: true,
  298. handler(val) {
  299. this.search()
  300. }
  301. }
  302. },
  303. computed: {
  304. versionQuery() {
  305. const {
  306. appid,
  307. uni_platform
  308. } = this.query
  309. const query = stringifyQuery({
  310. appid,
  311. uni_platform
  312. })
  313. return query
  314. },
  315. channelQuery() {
  316. const {
  317. appid,
  318. platform_id,
  319. } = this.query
  320. const query = stringifyQuery({
  321. appid,
  322. platform_id
  323. })
  324. return query
  325. },
  326. },
  327. }
  328. </script>
  329. <style lang="scss" scoped>
  330. .text-btn{
  331. color: $uni-color-primary;
  332. cursor: pointer;
  333. margin: 0 5px;
  334. }
  335. </style>