page-content.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. <template>
  2. <!-- 对应页面: 内容统计 -->
  3. <view class="fix-top-window">
  4. <view class="uni-header">
  5. <uni-stat-breadcrumb class="uni-stat-breadcrumb-on-phone" />
  6. <view class="uni-group">
  7. </view>
  8. </view>
  9. <view class="uni-container">
  10. <view class="uni-stat--x flex p-1015">
  11. <view class="uni-stat--app-select">
  12. <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" />
  13. <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" />
  14. </view>
  15. </view>
  16. <view class="uni-stat--x flex">
  17. <uni-stat-tabs label="日期选择" :current="currentDateTab" mode="date" @change="changeTimeRange" />
  18. <uni-datetime-picker type="datetimerange" :end="new Date().getTime()" v-model="query.start_time"
  19. returnType="timestamp" :clearIcon="false" class="uni-stat-datetime-picker"
  20. :class="{'uni-stat__actived': currentDateTab < 0 && !!query.start_time.length}"
  21. @change="useDatetimePicker" />
  22. </view>
  23. <view class="uni-stat--x">
  24. <uni-stat-tabs label="平台选择" type="boldLine" mode="platform" v-model="query.platform_id" @change="changePlatform" />
  25. <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="_id as value, channel_name as text" orderby="text asc" label="渠道/场景值选择" v-model="query.channel_id" />
  26. </view>
  27. <uni-stat-panel :items="panelData" />
  28. <view class="uni-stat--x p-m">
  29. <view class="uni-stat-right-btn">
  30. <button type="primary" size="mini" @click="pageTo('/pages/uni-stat/page-rule/page-rule')">页面规则</button>
  31. </view>
  32. <uni-table :loading="loading" border stripe :emptyText="errorMessage || $t('common.empty')">
  33. <uni-tr>
  34. <block v-for="(mapper, index) in fieldsMap" :key="index">
  35. <uni-th v-if="mapper.title" :key="index" align="center">
  36. <!-- #ifdef MP -->
  37. {{mapper.title}}
  38. <!-- #endif -->
  39. <!-- #ifndef MP -->
  40. <uni-tooltip>
  41. {{mapper.title}}
  42. <uni-icons v-if="index === 0 && mapper.tooltip" type="help" color="#666" />
  43. <template v-if="index === 0 && mapper.tooltip" v-slot:content>
  44. <view class="uni-stat-tooltip-s">
  45. {{mapper.tooltip}}
  46. </view>
  47. </template>
  48. </uni-tooltip>
  49. <!-- #endif -->
  50. </uni-th>
  51. </block>
  52. </uni-tr>
  53. <uni-tr v-for="(item ,i) in tableData" :key="i">
  54. <block v-for="(mapper, index) in fieldsMap" :key="index">
  55. <uni-td v-if="index === 1" :key="mapper.field" class="uni-stat-edit--x">
  56. {{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
  57. <uni-icons type="compose" color="#2979ff" size="25" class="uni-stat-edit--btn"
  58. @click="inputDialogToggle(item.page_link, item.page_title)" />
  59. </uni-td>
  60. <uni-td v-else :key="mapper.field" :align="index === 0 ? 'left' : 'center'">
  61. {{item[mapper.field] !== undefined ? item[mapper.field] : '-'}}
  62. </uni-td>
  63. </block>
  64. </uni-tr>
  65. </uni-table>
  66. <view class="uni-pagination-box">
  67. <uni-pagination show-icon show-page-size :page-size="options.pageSize"
  68. :current="options.pageCurrent" :total="options.total" @change="changePageCurrent"
  69. @pageSizeChange="changePageSize" />
  70. </view>
  71. </view>
  72. </view>
  73. <uni-popup ref="inputDialog" type="dialog" :maskClick="true">
  74. <uni-popup-dialog ref="inputClose" mode="input" title="请编辑名称" v-model="updateValue" placeholder="请输入内容"
  75. @confirm="editName"></uni-popup-dialog>
  76. </uni-popup>
  77. <!-- #ifndef H5 -->
  78. <fix-window />
  79. <!-- #endif -->
  80. </view>
  81. </template>
  82. <script>
  83. import {
  84. mapfields,
  85. stringifyQuery,
  86. stringifyField,
  87. stringifyGroupField,
  88. getTimeOfSomeDayAgo,
  89. division,
  90. format,
  91. debounce
  92. } from '@/js_sdk/uni-stat/util.js'
  93. import fieldsMap from './fieldsMap.js'
  94. export default {
  95. data() {
  96. return {
  97. fieldsMap,
  98. query: {
  99. dimension: "day",
  100. appid: '',
  101. platform_id: '',
  102. uni_platform: '',
  103. version_id: '',
  104. channel_id: '',
  105. start_time: [],
  106. },
  107. options: {
  108. pageSize: 20,
  109. pageCurrent: 1, // 当前页
  110. total: 0, // 数据总量
  111. },
  112. loading: false,
  113. currentDateTab: 1,
  114. tableData: [],
  115. panelData: fieldsMap.filter(f => f.hasOwnProperty('value')),
  116. queryId: '',
  117. updateValue: '',
  118. channelData: [],
  119. errorMessage: ''
  120. }
  121. },
  122. computed: {
  123. channelQuery() {
  124. const platform_id = this.query.platform_id
  125. return stringifyQuery({
  126. platform_id
  127. })
  128. },
  129. versionQuery() {
  130. const {
  131. appid,
  132. uni_platform
  133. } = this.query
  134. const query = stringifyQuery({
  135. appid,
  136. uni_platform
  137. })
  138. return query
  139. }
  140. },
  141. created() {
  142. this.debounceGet = debounce(() => this.getAllData())
  143. this.getChannelData()
  144. },
  145. watch: {
  146. query: {
  147. deep: true,
  148. handler(val) {
  149. this.options.pageCurrent = 1 // 重置分页
  150. this.debounceGet()
  151. }
  152. }
  153. },
  154. methods: {
  155. pageTo(url){
  156. uni.redirectTo({
  157. url
  158. })
  159. },
  160. useDatetimePicker() {
  161. this.currentDateTab = -1
  162. },
  163. changeAppid(id) {
  164. this.getChannelData(id, false)
  165. },
  166. changePlatform(id, index, name, item) {
  167. this.getChannelData(null, id)
  168. this.query.version_id = 0
  169. this.query.uni_platform = item.code
  170. },
  171. changeTimeRange(id, index) {
  172. this.currentDateTab = index
  173. const start = getTimeOfSomeDayAgo(id),
  174. end = getTimeOfSomeDayAgo(0) - 1
  175. this.query.start_time = [start, end]
  176. },
  177. changePageCurrent(e) {
  178. this.options.pageCurrent = e.current
  179. this.getTableData(this.query)
  180. },
  181. changePageSize(pageSize) {
  182. this.options.pageSize = pageSize
  183. this.options.pageCurrent = 1 // 重置分页
  184. this.getTableData()
  185. },
  186. getAllData() {
  187. this.getPanelData()
  188. this.getTableData()
  189. },
  190. getTableData(query) {
  191. if (!this.query.appid){
  192. this.errorMessage = "请先选择应用";
  193. return;
  194. }
  195. this.errorMessage = "";
  196. query = stringifyQuery(this.query, null, ['uni_platform'])
  197. const {
  198. pageCurrent
  199. } = this.options
  200. this.loading = true
  201. const db = uniCloud.database()
  202. const filterAppid = stringifyQuery({
  203. appid: this.query.appid
  204. })
  205. const mainTableTemp = db.collection('uni-stat-page-details')
  206. .where(filterAppid)
  207. .getTemp()
  208. const subTableTemp = db.collection('uni-stat-page-detail-result')
  209. .where(query)
  210. .getTemp()
  211. db.collection(subTableTemp, mainTableTemp)
  212. .field(
  213. `${stringifyField(fieldsMap)}, stat_date, page_detail_id`
  214. )
  215. .groupBy("page_detail_id")
  216. .groupField(stringifyGroupField(fieldsMap))
  217. .orderBy('visit_times desc')
  218. .skip((pageCurrent - 1) * this.options.pageSize)
  219. .limit(this.options.pageSize)
  220. .get({
  221. getCount: true
  222. })
  223. .then(res => {
  224. const {
  225. count,
  226. data
  227. } = res.result
  228. this.options.total = count
  229. this.tableData = []
  230. for (const item of data) {
  231. const lines = item.page_detail_id
  232. if (Array.isArray(lines)) {
  233. delete(item.page_detail_id)
  234. const line = lines[0]
  235. if (line && Object.keys(line).length) {
  236. for (const key in line) {
  237. if (key !== '_id') {
  238. item[key] = line[key]
  239. }
  240. }
  241. }
  242. }
  243. mapfields(fieldsMap, item, item)
  244. this.tableData.push(item)
  245. }
  246. }).catch((err) => {
  247. console.error(err)
  248. // err.message 错误信息
  249. // err.code 错误码
  250. }).finally(() => {
  251. this.loading = false
  252. })
  253. },
  254. getPanelData(query = stringifyQuery(this.query, null, ['uni_platform'])) {
  255. let myFieldsMap = JSON.parse(JSON.stringify(fieldsMap));
  256. // 去除myFieldsMap中的visit_devices字段
  257. myFieldsMap = myFieldsMap.filter(item => item.field !== 'visit_devices');
  258. const db = uniCloud.database()
  259. const subTable = db.collection('uni-stat-page-detail-result')
  260. .where(query)
  261. .field(stringifyField(myFieldsMap))
  262. .groupBy('appid')
  263. .groupField(stringifyGroupField(myFieldsMap))
  264. .orderBy('start_time desc')
  265. .get()
  266. .then(res => {
  267. const items = res.result.data[0]
  268. this.panelData = []
  269. this.panelData = mapfields(myFieldsMap, items)
  270. })
  271. },
  272. inputDialogToggle(url, title) {
  273. this.queryId = url
  274. this.updateValue = title
  275. this.$refs.inputDialog.open()
  276. },
  277. // 修改页面名称
  278. editName(value="") {
  279. // 使用 clientDB 提交数据
  280. const db = uniCloud.database()
  281. uni.showLoading({
  282. title: '请求中...'
  283. })
  284. db.collection('uni-stat-page-details')
  285. .where({
  286. page_link: this.queryId
  287. })
  288. .update({
  289. page_title: value.trim()
  290. })
  291. .then((res) => {
  292. if (res.result.updated) {
  293. uni.showToast({
  294. title: '修改成功'
  295. })
  296. this.getTableData()
  297. } else {
  298. uni.showToast({
  299. title: '修改失败',
  300. icon: "none"
  301. })
  302. }
  303. }).catch((err) => {
  304. uni.showModal({
  305. content: err.message || '请求服务失败',
  306. showCancel: false
  307. })
  308. }).finally(() => {
  309. uni.hideLoading()
  310. })
  311. },
  312. getChannelData(appid, platform_id) {
  313. this.query.channel_id = ''
  314. const db = uniCloud.database()
  315. const condition = {}
  316. //对应应用
  317. appid = appid ? appid : this.query.appid
  318. if (appid) {
  319. condition.appid = appid
  320. }
  321. //对应平台
  322. platform_id = platform_id ? platform_id : this.query.platform_id
  323. if (platform_id) {
  324. condition.platform_id = platform_id
  325. }
  326. let platformTemp = db.collection('uni-stat-app-platforms')
  327. .field('_id, name')
  328. .getTemp()
  329. let channelTemp = db.collection('uni-stat-app-channels')
  330. .where(condition)
  331. .field('_id, channel_name, create_time, platform_id')
  332. .getTemp()
  333. db.collection(channelTemp, platformTemp)
  334. .orderBy('platform_id asc')
  335. .get()
  336. .then(res => {
  337. let data = res.result.data
  338. let channels = []
  339. if (data.length > 0) {
  340. let channelName
  341. for (let i in data) {
  342. channelName = data[i].channel_name ? data[i].channel_name : '默认'
  343. if (data[i].platform_id.length > 0) {
  344. channelName = data[i].platform_id[0].name + '-' + channelName
  345. }
  346. channels.push({
  347. value: data[i]._id,
  348. text: channelName
  349. })
  350. }
  351. }
  352. this.channelData = channels
  353. })
  354. .catch((err) => {
  355. console.error(err)
  356. // err.message 错误信息
  357. // err.code 错误码
  358. }).finally(() => {})
  359. }
  360. },
  361. }
  362. </script>
  363. <style>
  364. .uni-stat-edit--x {
  365. display: flex;
  366. justify-content: space-between;
  367. }
  368. .uni-stat-edit--btn {
  369. cursor: pointer;
  370. }
  371. .uni-stat-right-btn{
  372. text-align: right;margin-bottom: 10px;
  373. }
  374. </style>