Selaa lähdekoodia

静态首页 + 用户详情

hjr 1 viikko sitten
vanhempi
commit
306d4f16f3

+ 4 - 4
src/views/main/dashboard/components/card/index.vue

@@ -10,10 +10,10 @@ import Row from './row.vue'
 import { statisticsHome } from '@/api/dashboard.js'
 
 const list = ref([
-  { id: 1, name: '用户数', data: '31258', color: '#4e73df', icon: 'sfont system-yonghu' },
-  // { id: 2, name: '封禁人数', data: '5542', color: '#1cc88a', icon: 'sfont system-xiaoxi' },
-  { id: 3, name: '消费总额', data: '108827', color: '#36b9cc', icon: 'sfont system-shuliang_mianxing' },
-  { id: 4, name: '预估收益', data: '64581.04', color: '#f6c23e', icon: 'sfont system-jindutiaoshouyidaozhang' }
+  { id: 1, name: '用户数', data: '31258', color: '#4e73df', icon: 'sfont system-yonghu' },
+  // { id: 2, name: '当日增长用户数', data: '5542', color: '#1cc88a', icon: 'sfont system-xiaoxi' },
+  { id: 3, name: '消费总额(元)', data: '108827', color: '#36b9cc', icon: 'sfont system-shuliang_mianxing' },
+  { id: 4, name: '预估收益(元)', data: '64581.04', color: '#f6c23e', icon: 'sfont system-jindutiaoshouyidaozhang' }
 ])
 
 const getTopCountData = async () => {

+ 243 - 0
src/views/main/dashboard/components/chartsModule/index.vue

@@ -0,0 +1,243 @@
+<template>
+  <div class="dashboard-container">
+    <!-- 顶部两个图表 -->
+    <div class="chart-row">
+      <!-- 用户增长数量柱状图 -->
+      <div class="chart-card">
+        <div class="chart-header">
+          <span class="table-header">用户增长数量</span>
+          <el-date-picker
+            v-model="userDateRange"
+            type="daterange"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            size="small"
+            style="font-size: 12px;max-width: 220px;"
+          />
+        </div>
+        <div class="chart-content" ref="userChartRef" style="height: 220px;"></div>
+      </div>
+
+      <!-- 收益金额折线图 -->
+      <div class="chart-card">
+        <div class="chart-header">
+          <span class="table-header">收益金额</span>
+          <el-date-picker
+            v-model="incomeDateRange"
+            type="daterange"
+            range-separator="至"
+            start-placeholder="开始日期"
+            end-placeholder="结束日期"
+            size="small"
+            style="font-size: 12px;max-width: 220px;"
+          />
+        </div>
+        <div class="chart-content" ref="incomeChartRef" style="height: 220px;"></div>
+      </div>
+    </div>
+
+    <!-- 底部两个表格 -->
+    <div class="table-row">
+      <!-- 付费收益表格 -->
+      <div class="table-card">
+        <div class="table-header">付费收益</div>
+        <el-table :data="payIncomeList" border style="width: 100%; font-size: 12px;">
+          <el-table-column prop="name" label="名称" >
+			  <template #default="scope">
+				  <div style="display: flex;">
+					  <el-image style="width: 60px;height: 60px;border-radius: 50%;"></el-image>
+					  <div style="margin-left: 10px;">
+						  <div>
+							  昵称:{{ scope.row.userName }}
+						  </div>
+						  <div>
+							  ID:{{ scope.row.userId }}
+						  </div>
+					  </div>
+				  </div>
+			  </template>
+		  </el-table-column>
+          <el-table-column prop="orderName" label="订单名称" />
+          <el-table-column prop="time" width="160" label="时间" />
+          <el-table-column prop="amount" width="100" label="收益金额(元)" />
+        </el-table>
+      </div>
+
+      <!-- 任务收益表格 -->
+      <div class="table-card">
+        <div class="table-header">任务收益</div>
+        <el-table :data="taskIncomeList" border style="width: 100%; font-size: 12px;">
+		  <el-table-column prop="name" label="名称" >
+			  <template #default="scope">
+				  <div style="display: flex;">
+					  <el-image style="width: 60px;height: 60px;border-radius: 50%;"></el-image>
+					  <div style="margin-left: 10px;">
+						  <div>
+							  昵称:{{ scope.row.userName }}
+						  </div>
+						  <div>
+							  ID:{{ scope.row.userId }}
+						  </div>
+					  </div>
+				  </div>
+			  </template>
+		  </el-table-column>
+          <el-table-column prop="type" width="100" label="类型" />
+          <el-table-column prop="taskName" label="任务名称" />
+          <el-table-column prop="time" width="160" label="时间" />
+          <el-table-column prop="amount" width="100" label="收益金额(元)" />
+        </el-table>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted } from 'vue';
+import * as echarts from 'echarts';
+import { ElDatePicker, ElTable, ElTableColumn } from 'element-plus';
+
+// 日期范围数据
+const userDateRange = ref(['2026-01-08', '2026-01-08']);
+const incomeDateRange = ref(['2026-01-08', '2026-01-08']);
+
+// 图表容器ref
+const userChartRef = ref(null);
+const incomeChartRef = ref(null);
+
+// 付费收益表格数据
+const payIncomeList = ref([
+  {
+	userName: '用户名001',
+	userId: 'a123456',
+    orderName: '购买会员',
+    time: '2026.1.22 16:16',
+    amount: 99.32
+  },
+  {
+	userName: '用户名001',
+	userId: 'a123456',
+    orderName: '购买工具-刷新',
+    time: '2026.1.22 16:16',
+    amount: 99.32
+  },
+  {
+	userName: '用户名001',
+	userId: 'a123456',
+    orderName: '购买工具-置顶',
+    time: '2026.1.22 16:16',
+    amount: 99.32
+  }
+]);
+
+// 任务收益表格数据
+const taskIncomeList = ref([
+  {
+	userName: '用户名001',
+	userId: 'a123456',
+    type: '悬赏',
+    taskName: '拼多多砍一刀...',
+    time: '2026.1.22 16:16',
+    amount: 1.00
+  },
+  {
+	userName: '用户名001',
+	userId: 'a123456',
+    type: '提现',
+    taskName: '-',
+    time: '2026.1.22 16:16',
+    amount: 1.20
+  }
+]);
+
+// 初始化用户增长柱状图
+const initUserChart = () => {
+  const chart = echarts.init(userChartRef.value);
+  chart.setOption({
+    tooltip: { trigger: 'axis' },
+    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
+    xAxis: {
+      type: 'category',
+      data: ['1号', '2号', '3号', '4号', '5号', '6号', '7号']
+    },
+    yAxis: { type: 'value', min: 0 },
+    series: [
+      {
+        data: [100, 150, 230, 100, 130, 160, 200],
+        type: 'bar',
+        itemStyle: { color: '#3370FF' }
+      }
+    ]
+  });
+  // 自适应窗口变化
+  window.addEventListener('resize', () => chart.resize());
+};
+
+// 初始化收益金额折线图
+const initIncomeChart = () => {
+  const chart = echarts.init(incomeChartRef.value);
+  chart.setOption({
+    tooltip: { trigger: 'axis' },
+    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
+    xAxis: {
+      type: 'category',
+      data: ['1号', '2号', '3号', '4号', '5号', '6号', '7号']
+    },
+    yAxis: { type: 'value', min: 0 },
+    series: [
+      {
+        data: [0, 230, 100, 130, 150, 170, 200],
+        type: 'line',
+        itemStyle: { color: '#3370FF' },
+        lineStyle: { color: '#3370FF' },
+        areaStyle: { color: 'rgba(51, 112, 255, 0.2)' }
+      }
+    ]
+  });
+  window.addEventListener('resize', () => chart.resize());
+};
+
+// 页面挂载后初始化图表
+onMounted(() => {
+  initUserChart();
+  initIncomeChart();
+});
+</script>
+
+<style scoped>
+.dashboard-container {
+  /* padding: 20px; */
+  /* background: #F5F7FA; */
+  min-height: 100vh;
+}
+
+.chart-row, .table-row {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 20px;
+}
+
+.chart-card, .table-card {
+  flex: 1;
+  background: #fff;
+  border-radius: 8px;
+  padding: 16px;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
+}
+
+.chart-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+  font-weight: 500;
+}
+
+.table-header {
+  font-weight: 600;
+  font-size: 18px;
+  margin-bottom: 12px;
+  text-align: left;
+}
+</style>

+ 4 - 0
src/views/main/dashboard/index.vue

@@ -2,6 +2,7 @@
   <div class="box">
     <Card />
     <!-- <Charts /> -->
+	<charts-module />
   </div>
 </template>
 
@@ -9,10 +10,13 @@
 import { defineComponent } from 'vue'
 import Card from './components/card/index.vue'
 import Charts from './components/charts/index.vue'
+import ChartsModule from './components/chartsModule/index.vue'
+
 export default defineComponent({
   components: {
     Card,
     Charts,
+	ChartsModule,
   }
 })
 </script>

+ 315 - 3
src/views/main/userModule/userList.vue

@@ -17,7 +17,8 @@
 		<el-table-column prop="userId" label="用户ID" />
 		<el-table-column prop="headImage" label="用户头像" >
 			<template #default="scope">
-				<el-image :src="scope.row.headImage" :preview-src-list="[scope.row.headImage]" fit="cover" preview-teleported="true"   preview-z-index="9999"></el-image>
+				<el-image style="width: 80px;height: 80px;border-radius: 50%;"
+				 :src="scope.row.headImage" :preview-src-list="[scope.row.headImage]" fit="cover" preview-teleported="true"   preview-z-index="9999"></el-image>
 			</template>
 		</el-table-column>
 		<el-table-column prop="nickName" label="用户昵称" />
@@ -33,11 +34,16 @@
 		<!-- <el-table-column prop="rewardBalance" label="悬赏余额" /> -->
 		<!-- <el-table-column prop="taskBalance" label="任务余额" /> -->
 		<el-table-column prop="totalIncome" label="总收益" />
-		<el-table-column prop="loginTime" label="最后登录时间" >
+		<el-table-column prop="loginTime" width="160" label="最后登录时间" >
 			<template #default="scope">
 				{{ formatDateFull(scope.row.loginTime) }}
 			</template>
 		</el-table-column>
+		<el-table-column prop="" width="100" label="操作" >
+			<template #default="scope">
+				<el-button type="text" @click="handleView(scope.row)"> <el-icon size="16"><View /></el-icon> </el-button>
+			</template>
+		</el-table-column>
       </Table>
     </div>
 
@@ -50,6 +56,126 @@
 				<el-table-column prop="serviceFee" label="平台收取的服务费/手续费" />
 		</Table>
     </Layer>
+	<!-- 查看详情 -->
+	<Layer :layer="layerView" @close="layerView.show = false">
+	  <div class="revenue-container">
+	    <!-- 1. 收益类型切换 + 日期筛选栏 -->
+	    <div class="revenue-header">
+	      <!-- 付费/任务收益切换按钮 -->
+	      <el-button-group class="revenue-type-btn">
+	        <el-button
+	          :type="activeRevenueType === 'pay' ? 'primary' : 'default'"
+	          @click="activeRevenueType = 'pay'"
+	        >
+	          付费收益
+	        </el-button>
+	        <el-button
+	          :type="activeRevenueType === 'task' ? 'primary' : 'default'"
+	          @click="activeRevenueType = 'task'"
+	        >
+	          任务收益
+	        </el-button>
+	      </el-button-group>
+	
+	      <!-- 快捷日期 + 日期范围筛选 -->
+	      <div class="date-filter-group">
+	        <el-button-group class="quick-date-btn">
+	          <el-button
+	            :type="activeQuickDate === 'today' ? 'primary' : 'default'"
+	            @click="handleQuickDate('today')"
+	          >
+	            当日
+	          </el-button>
+	          <el-button
+	            :type="activeQuickDate === 'yesterday' ? 'primary' : 'default'"
+	            @click="handleQuickDate('yesterday')"
+	          >
+	            昨天
+	          </el-button>
+	          <el-button
+	            :type="activeQuickDate === 'sevenDays' ? 'primary' : 'default'"
+	            @click="handleQuickDate('sevenDays')"
+	          >
+	            七天
+	          </el-button>
+	        </el-button-group>
+	
+	        <el-date-picker
+	          v-model="revenueDateRange"
+	          type="daterange"
+	          range-separator="至"
+	          start-placeholder="开始日期"
+	          end-placeholder="结束日期"
+	          style="width: 240px; margin-left: 12px;"
+	          @change="fetchRevenueData"
+	        />
+	      </div>
+	    </div>
+	
+	    <!-- 2. 收益表格(根据类型切换) -->
+	    <div class="revenue-table-wrap">
+	      <!-- 付费收益表格 -->
+	      <Table
+	        v-if="activeRevenueType === 'pay'"
+	        :data="payRevenueList"
+	        border
+	        class="revenue-table"
+	        empty-text="暂无付费收益记录"
+			@getTableData="changeTableDetailData"
+			v-model:page="pageDetail"
+			ref="table1"
+	        :header-cell-style="{ background: '#f5f7fa', color: '#606266', fontWeight: 500 }"
+	      >
+	        <el-table-column prop="orderName" label="订单名称" min-width="160" align="center" />
+	        <el-table-column prop="createTime" label="时间" min-width="180" align="center">
+	          <template #default="scope">
+	            {{ formatDateFull(scope.row.createTime) || '--' }}
+	          </template>
+	        </el-table-column>
+	        <el-table-column prop="amount" label="收益金额(元)" min-width="140" align="center">
+	          <template #default="scope">
+	            {{ scope.row.amount ? scope.row.amount.toFixed(2) : '0.00' }}
+	          </template>
+	        </el-table-column>
+	      </Table>
+	
+	      <!-- 任务收益表格 -->
+	      <Table
+	        v-if="activeRevenueType === 'task'"
+	        :data="taskRevenueList"
+	        border
+	        class="revenue-table"
+	        empty-text="暂无任务收益记录"
+			@getTableData="changeTableDetailData"
+			v-model:page="pageDetail"
+			ref="table2"
+	        :header-cell-style="{ background: '#f5f7fa', color: '#606266', fontWeight: 500 }"
+	      >
+	        <el-table-column prop="orderName" label="订单名称" min-width="160" align="center">
+	          <template #default="scope">
+	            {{ scope.row.taskType === 'reward' ? '悬赏' : '提现' }}
+	          </template>
+	        </el-table-column>
+	        <el-table-column prop="createTime" label="时间" min-width="180" align="center">
+	          <template #default="scope">
+	            {{ formatDateFull(scope.row.createTime) || '--' }}
+	          </template>
+	        </el-table-column>
+	        <el-table-column prop="amount" label="收益金额(元)" min-width="140" align="center">
+	          <template #default="scope">
+	            {{ scope.row.amount ? scope.row.amount.toFixed(2) : '0.00' }}
+	          </template>
+	        </el-table-column>
+	      </Table>
+	    </div>
+	
+	    <!-- 3. 合计收益统计行 -->
+	    <div class="revenue-total">
+	      <span class="total-label">合计收益:</span>
+	      <span class="total-amount">{{ activeRevenueType === 'pay' ? payTotalAmount : taskTotalAmount }}元</span>
+	    </div>
+	  </div>
+	</Layer>
   </div>
 </template>
 
@@ -60,9 +186,11 @@ import Table from "@/components/table/index.vue";
 import Layer from '@/components/layer/index.vue'
 import { FullScreen } from '@element-plus/icons'
 import { ElMessage, ElLoading } from 'element-plus'
+import { View } from "@element-plus/icons-vue";
 import { invitationCodeUser,getUserList,orderPageList } from '@/api/userModule.js'
 import { convertUTCToBeijing, getTodayRangeLocal,formatDateFull } from '@/utils/index.js'
 import { useStore } from 'vuex'
+
 const store = useStore()
 const parentId = computed(() => store.state.user.info.parentId);
 console.log('parentId',parentId.value)
@@ -169,6 +297,88 @@ const changeTableDetailData = ()=>{
 	getDetailList();
 }
 
+// 1. 收益表格核心响应式变量
+const activeRevenueType = ref('pay'); // 当前选中收益类型:pay-付费收益,task-任务收益
+const activeQuickDate = ref('today'); // 当前快捷日期:today-当日,yesterday-昨天,sevenDays-七天
+const revenueDateRange = ref([]); // 日期范围选择器值
+const payRevenueList = ref([]); // 付费收益数据列表
+const taskRevenueList = ref([]); // 任务收益数据列表
+const payTotalAmount = ref('0.00'); // 付费收益合计
+const taskTotalAmount = ref('0.00'); // 任务收益合计
+const currentViewUserId = ref(''); // 当前查看详情的用户ID
+
+// 2. 快捷日期选择处理(匹配图片中的“当日/昨天/七天”)
+const handleQuickDate = (type) => {
+  activeQuickDate.value = type;
+  const today = new Date();
+  const yesterday = new Date(today);
+  yesterday.setDate(yesterday.getDate() - 1);
+  const sevenDaysAgo = new Date(today);
+  sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7);
+
+  // 格式化日期为 YYYY-MM-DD
+  const format = (date) => date.toISOString().split('T')[0];
+  
+  // 设置日期范围
+  switch (type) {
+    case 'today':
+      revenueDateRange.value = [format(today), format(today)];
+      break;
+    case 'yesterday':
+      revenueDateRange.value = [format(yesterday), format(yesterday)];
+      break;
+    case 'sevenDays':
+      revenueDateRange.value = [format(sevenDaysAgo), format(today)];
+      break;
+  }
+  // 重新拉取收益数据
+  fetchRevenueData();
+};
+
+// 3. 拉取收益数据(复用 orderPageList API,区分付费/任务类型)
+const fetchRevenueData = async () => {
+  if (!currentViewUserId.value || !revenueDateRange.value.length) return;
+
+  // 处理日期参数(格式:YYYY-MM-DD HH:mm:ss)
+  const [startDate, endDate] = revenueDateRange.value;
+  const params = {
+    userId: currentViewUserId.value,
+    startTime: `${startDate} 00:00:00`,
+    endTime: `${endDate} 23:59:59`,
+    pageNum: pageDetail.pageNum,
+    pageSize: pageDetail.pageSize
+  };
+
+  try {
+   
+
+  } catch (error) {
+    ElMessage.error('获取收益数据失败');
+    console.error('收益数据请求错误:', error);
+  }
+};
+
+// 4. 重写 handleView 方法(打开详情弹窗时初始化数据)
+const handleView = async (row) => {
+  currentViewUserId.value = row.userId; // 记录当前查看的用户ID
+  layerView.value.show = true; // 显示弹窗
+  
+  // 初始化日期(默认“当日”)
+  const today = new Date();
+  revenueDateRange.value = [today.toISOString().split('T')[0], today.toISOString().split('T')[0]];
+  
+  // 拉取初始收益数据
+  await fetchRevenueData();
+};
+
+// 5. 重写 changeTableDetailData 方法(表格分页适配)
+// const changeTableDetailData = () => {
+//   pageDetail.pageNum = pageDetail.pageNum;
+//   pageDetail.pageSize = pageDetail.pageSize;
+//   fetchRevenueData(); // 分页时重新拉取收益数据
+// };
+
+
 // 搜索
 const handleFormSubmitted = (formData) => {
   // console.log("接收到子组件传递的数据", formData);
@@ -275,7 +485,13 @@ const layer = ref({
   // width: '500px',
   isMulty: false
 });
-
+const layerView = ref({
+	show: false,
+	title: "查看详情",
+	showButton: false,
+	// width: '500px',
+	isMulty: false
+})
 const formEdit = ref({
   bannedLimit: undefined, //封禁期限
   bannedReason: undefined,//封禁原因
@@ -380,4 +596,100 @@ const submit = async (formEl) => {
   padding: 8px;
   border-radius: 5px;
 }
+
+/* 收益容器整体样式 */
+.revenue-container {
+  padding: 16px;
+}
+
+/* 收益类型切换与日期筛选栏样式 */
+.revenue-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 16px;
+  flex-wrap: wrap;
+  gap: 12px;
+}
+
+/* 收益类型切换按钮样式 */
+.revenue-type-btn :deep(.el-button) {
+  border-radius: 0;
+  &:first-child {
+    border-top-left-radius: 4px;
+    border-bottom-left-radius: 4px;
+  }
+  &:last-child {
+    border-top-right-radius: 4px;
+    border-bottom-right-radius: 4px;
+  }
+}
+
+/* 日期筛选组样式 */
+.date-filter-group {
+  display: flex;
+  align-items: center;
+  gap: 8px;
+}
+
+.quick-date-btn :deep(.el-button) {
+  padding: 6px 12px;
+  font-size: 12px;
+}
+
+/* 收益表格样式(穿透修改 Element Plus 表格) */
+.revenue-table-wrap {
+  margin-bottom: 12px;
+
+  :deep(.revenue-table) {
+    --el-table-border-color: #e5e7eb;
+    --el-table-text-color: #303133;
+    width: 100%;
+
+    /* 表格行样式优化 */
+    .el-table__body tr {
+      background-color: #fff;
+    }
+    .el-table__body tr:hover > td {
+      background-color: #f9fafb !important;
+    }
+
+    /* 表格单元格样式 */
+    td.el-table__cell {
+      border-bottom: 1px solid #f3f4f6 !important;
+      padding: 12px 0;
+      font-size: 13px;
+    }
+
+    /* 去除表格底部多余边框 */
+    &::before {
+      height: 0;
+    }
+  }
+}
+
+/* 合计收益行样式(匹配图片中的合计展示) */
+.revenue-total {
+  text-align: right;
+  padding: 10px 0;
+  margin-top: -8px;
+
+  .total-label {
+    color: #333;
+    font-size: 16px;
+    margin-right: 8px;
+  }
+
+  .total-amount {
+    color: #cf2d2d;
+    font-size: 20px;
+    font-weight: 500;
+  }
+}
+
+/* 适配弹窗宽度 */
+:deep(.el-dialog__body) {
+  padding: 16px;
+  overflow: hidden;
+}
 </style>

+ 4 - 4
vite.config.js

@@ -55,7 +55,7 @@ export default ({ command }) => {
 		},
 		'/pro-oauth-prod': {
 		  // target: 'https://test.admin.zcb.ytpm.net',
-		  target: 'https://agency.yqearns.com',
+		  target: 'http://agency.yqearns.com',
 		  changeOrigin: true,
 		  // secure: true,
 		  rewrite: (path) => {
@@ -64,7 +64,7 @@ export default ({ command }) => {
 		}, 
 		'/pro-api-prod': {
 		  // target: 'https://test.admin.zcb.ytpm.net',
-		  target: 'https://agency.yqearns.com',
+		  target: 'http://agency.yqearns.com',
 		  changeOrigin: true,
 		   // secure: true,
 			rewrite: (path) => {
@@ -73,8 +73,8 @@ export default ({ command }) => {
 		},
 		'/pro-agency-prod': {
 		  // target: 'https://test.admin.zcb.ytpm.net',
-		  target: 'https://agency.yqearns.com',
-		  changeOrigin: true,
+		  target: 'http://agency.yqearns.com',
+		  // changeOrigin: true,
 		  // secure: true,
 		  rewrite: (path) => {
 		    return path.replace(/^\/pro-agency-prod/, '/pro-agency-prod')