deepchart后台管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
11 KiB

  1. <template>
  2. <div class="user-activity-stats-container">
  3. <!-- 顶部全局筛选 -->
  4. <div class="search-bar global-search">
  5. <div class="search-label">地区</div>
  6. <el-select v-model="globalRegion" placeholder="请选择所属地区" style="width: 200px; margin-right: 20px;">
  7. <el-option label="全部" value="all" />
  8. <el-option label="中国" value="cn" />
  9. </el-select>
  10. <div class="search-label">时间段查询</div>
  11. <el-date-picker
  12. v-model="globalDateRange"
  13. type="daterange"
  14. range-separator="至"
  15. start-placeholder="开始时间"
  16. end-placeholder="结束时间"
  17. size="default"
  18. />
  19. <el-button type="primary" class="search-btn">搜索</el-button>
  20. <el-button type="primary" class="reset-btn">重置</el-button>
  21. <el-button type="danger" class="export-btn">数据导出</el-button>
  22. </div>
  23. <!-- 用户活跃度趋势图 -->
  24. <div class="content-card">
  25. <div class="card-header">
  26. <el-icon class="header-icon"><TrendCharts /></el-icon>
  27. <span class="header-title">用户活跃度趋势图</span>
  28. </div>
  29. <div class="card-filter-row">
  30. <div class="filter-left">
  31. <span class="filter-label">时间段查询</span>
  32. <el-date-picker
  33. v-model="chartDateRange"
  34. type="daterange"
  35. range-separator="至"
  36. start-placeholder="开始时间"
  37. end-placeholder="结束时间"
  38. size="default"
  39. />
  40. </div>
  41. <div class="filter-right">
  42. <el-button-group>
  43. <el-button type="danger">每日</el-button>
  44. <el-button>近七日</el-button>
  45. <el-button>近三十日</el-button>
  46. </el-button-group>
  47. </div>
  48. </div>
  49. <div class="chart-container" ref="chartRef"></div>
  50. </div>
  51. <!-- DeepChart活跃用户明细 -->
  52. <div class="content-card">
  53. <div class="card-header">
  54. <el-icon class="header-icon"><DataLine /></el-icon>
  55. <span class="header-title">DeepChart活跃用户明细</span>
  56. </div>
  57. <div class="table-filter-row">
  58. <el-input v-model="tableAccount" placeholder="请输入账号" style="width: 150px" />
  59. <el-select v-model="tableRegion" placeholder="请选择所属地区" style="width: 150px">
  60. <el-option label="全部" value="all" />
  61. </el-select>
  62. <el-date-picker
  63. v-model="tableDateRange"
  64. type="daterange"
  65. range-separator="至"
  66. start-placeholder="开始时间"
  67. end-placeholder="结束时间"
  68. size="default"
  69. style="width: 240px"
  70. />
  71. <el-button type="primary" class="search-btn-small">搜索</el-button>
  72. <el-button type="primary" class="reset-btn-small">重置</el-button>
  73. <el-button type="danger" class="export-btn-small">数据导出</el-button>
  74. <el-button type="danger" class="export-list-btn">查看导出列表</el-button>
  75. </div>
  76. <el-table :data="tableData" style="width: 100%" :header-cell-style="headerCellStyle">
  77. <el-table-column prop="index" label="序号" width="80" align="center" />
  78. <el-table-column prop="account" label="账号" min-width="120" />
  79. <el-table-column prop="name" label="姓名" min-width="120" />
  80. <el-table-column prop="region" label="地区" width="100" />
  81. <el-table-column prop="loginCount" label="登录次数" width="100" align="center" />
  82. <el-table-column prop="totalDuration" label="总停留时长" min-width="150" align="center" />
  83. <el-table-column prop="avgDuration" label="平均停留时长" min-width="150" align="center" />
  84. <el-table-column prop="deepMate" label="DeepMate" min-width="150" align="center" />
  85. <el-table-column prop="deepExplore" label="深度探索" min-width="150" align="center" />
  86. </el-table>
  87. <div class="pagination-container">
  88. <div class="total-count">共400条</div>
  89. <el-pagination
  90. background
  91. layout="sizes, prev, pager, next, jumper"
  92. :total="400"
  93. :page-sizes="[10, 20, 50, 100]"
  94. v-model:current-page="currentPage"
  95. v-model:page-size="pageSize"
  96. />
  97. </div>
  98. </div>
  99. </div>
  100. </template>
  101. <script setup>
  102. import { ref, onMounted, nextTick } from 'vue';
  103. import * as echarts from 'echarts';
  104. // 全局筛选
  105. const globalRegion = ref('');
  106. const globalDateRange = ref('');
  107. // 图表筛选
  108. const chartDateRange = ref('');
  109. const chartRef = ref(null);
  110. // 表格筛选
  111. const tableAccount = ref('');
  112. const tableRegion = ref('');
  113. const tableDateRange = ref('');
  114. const currentPage = ref(1);
  115. const pageSize = ref(50);
  116. // 表格数据
  117. const tableData = ref([
  118. { index: 1, account: 'DC900480004', name: 'Thea Elowen Hale', region: '中国', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  119. { index: 2, account: 'DC900480004', name: '欧帝三萃', region: '美国', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  120. { index: 3, account: 'DC900480004', name: 'Thea Elowen Hale', region: '新加坡', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  121. { index: 4, account: 'DC900480004', name: 'viên แก้ว หลาว', region: '泰国', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  122. { index: 5, account: 'DC900480004', name: 'viên แก้ว หลาว', region: '越南', loginCount: 99, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  123. { index: 6, account: 'DC900480004', name: 'Cien Yong Hao', region: '中国', loginCount: 9999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  124. { index: 7, account: 'DC900480004', name: 'Cien Yong Hao', region: '美国', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  125. { index: 8, account: 'DC900480004', name: 'Tiên Linh Vinh Hảo', region: '新加坡', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  126. { index: 9, account: 'DC900480004', name: 'Tiên Linh Vinh Hảo', region: '新加坡', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  127. { index: 10, account: 'DC900480004', name: 'Tiên Linh Vinh Hảo', region: '香港', loginCount: 999, totalDuration: '99小时99分钟99秒', avgDuration: '99小时99分钟99秒', deepMate: '99小时99分钟99秒', deepExplore: '99小时99分钟99秒' },
  128. ]);
  129. const headerCellStyle = {
  130. background: '#f5f7fa',
  131. color: '#333',
  132. fontWeight: 'bold'
  133. };
  134. const initChart = () => {
  135. if (chartRef.value) {
  136. const chart = echarts.init(chartRef.value);
  137. chart.setOption({
  138. tooltip: {
  139. trigger: 'axis',
  140. axisPointer: { type: 'cross' }
  141. },
  142. legend: {
  143. data: ['DeepChart活跃人数', 'DeepChart使用次数'],
  144. top: 'top',
  145. left: 'center',
  146. itemWidth: 35,
  147. itemHeight: 18,
  148. textStyle: {
  149. fontSize: 14
  150. }
  151. },
  152. grid: {
  153. left: '3%',
  154. right: '4%',
  155. bottom: '3%',
  156. containLabel: true
  157. },
  158. xAxis: {
  159. type: 'category',
  160. boundaryGap: false,
  161. data: ['六天前', '五天前', '四天前', '三天前', '两天前', '昨天', '今天']
  162. },
  163. yAxis: [
  164. {
  165. type: 'value',
  166. min: 0,
  167. max: 1400,
  168. position: 'left',
  169. axisLabel: { formatter: '{value}' }
  170. },
  171. {
  172. type: 'value',
  173. min: 0,
  174. max: 1400,
  175. position: 'right',
  176. axisLabel: { formatter: '{value}' }
  177. }
  178. ],
  179. series: [
  180. {
  181. name: 'DeepChart活跃人数',
  182. type: 'line',
  183. yAxisIndex: 0,
  184. data: [300, 600, 320, 320, 400, 550, 650],
  185. itemStyle: { color: '#e74c3c' },
  186. symbol: 'circle',
  187. symbolSize: 8,
  188. lineStyle: { width: 3 }
  189. },
  190. {
  191. name: 'DeepChart使用次数',
  192. type: 'line',
  193. yAxisIndex: 1,
  194. data: [1350, 1250, 1100, 1050, 1050, 1300, 1000],
  195. itemStyle: { color: '#2ecc71' },
  196. symbol: 'circle',
  197. symbolSize: 8,
  198. lineStyle: { width: 3 }
  199. }
  200. ]
  201. });
  202. }
  203. };
  204. onMounted(() => {
  205. nextTick(() => {
  206. initChart();
  207. });
  208. });
  209. </script>
  210. <style scoped>
  211. .user-activity-stats-container {
  212. padding: 20px;
  213. background-color: #fee6e6;
  214. min-height: calc(100vh - 40px);
  215. }
  216. /* Global Search */
  217. .search-bar {
  218. background: #fff;
  219. padding: 15px;
  220. border-radius: 8px;
  221. display: flex;
  222. align-items: center;
  223. gap: 10px;
  224. margin-bottom: 20px;
  225. border: 1px solid #f0f0f0;
  226. }
  227. .search-label {
  228. font-weight: bold;
  229. margin-right: 5px;
  230. }
  231. .search-btn, .reset-btn {
  232. width: 80px;
  233. }
  234. .search-btn { background-color: #409eff; }
  235. .reset-btn { background-color: #a0cfff; border-color: #a0cfff; }
  236. .export-btn { margin-left: auto; background-color: #ff7875; border-color: #ff7875; }
  237. /* Content Cards */
  238. .content-card {
  239. background: #fff;
  240. border-radius: 8px;
  241. padding: 20px;
  242. margin-bottom: 20px;
  243. border: 1px solid #f0f0f0;
  244. }
  245. .card-header {
  246. display: flex;
  247. align-items: center;
  248. gap: 8px;
  249. margin-bottom: 20px;
  250. }
  251. .header-icon {
  252. color: #409eff;
  253. font-size: 20px;
  254. }
  255. .header-title {
  256. font-size: 18px;
  257. font-weight: bold;
  258. color: #333;
  259. }
  260. /* Chart Section */
  261. .card-filter-row {
  262. display: flex;
  263. justify-content: space-between;
  264. align-items: center;
  265. margin-bottom: 20px;
  266. background: #fafafa;
  267. padding: 10px;
  268. border-radius: 4px;
  269. }
  270. .filter-left {
  271. display: flex;
  272. align-items: center;
  273. gap: 10px;
  274. }
  275. .filter-label {
  276. font-size: 14px;
  277. font-weight: bold;
  278. }
  279. .chart-container {
  280. width: 100%;
  281. height: 400px;
  282. }
  283. /* Table Section */
  284. .table-filter-row {
  285. display: flex;
  286. align-items: center;
  287. gap: 10px;
  288. margin-bottom: 20px;
  289. }
  290. .search-btn-small { background-color: #409eff; width: 70px; }
  291. .reset-btn-small { background-color: #a0cfff; border-color: #a0cfff; width: 70px; }
  292. .export-btn-small { background-color: #ff7875; border-color: #ff7875; width: 90px; }
  293. .export-list-btn { background-color: #ff7875; border-color: #ff7875; width: 110px; }
  294. /* Pagination */
  295. .pagination-container {
  296. display: flex;
  297. justify-content: center;
  298. align-items: center;
  299. margin-top: 20px;
  300. }
  301. .total-count {
  302. font-size: 14px;
  303. color: #606266;
  304. margin-right: 20px;
  305. }
  306. </style>