Browse Source

根据日期选择结论表数据

liuguofeng 5 months ago
parent
commit
96a579b4f6

+ 16 - 0
datadas/mydatadas/src/main.js

@@ -2,8 +2,24 @@ import { createApp } from 'vue'
 import App from './App.vue'
 import './style/index.scss';
 import router from './router/index'
+import ElementPlus from 'element-plus';
+
+import zhCn from 'element-plus/es/locale/lang/zh-cn';
+import {createI18n} from 'vue-i18n';
+
+const i18n = new createI18n({
+    locale: 'zh-cn',
+    messages: {
+      'zh-cn': zhCn
+    }
+})
 
 
 const app = createApp(App);
+
+app.use(ElementPlus, {
+    locale: zhCn
+  });
+  app.use(i18n);
 app.use(router);
 app.mount('#app')

+ 173 - 69
datadas/mydatadas/src/views/datadas/index.vue

@@ -2,33 +2,46 @@
     <div class="page-container main-view">
 
          <el-row :gutter="10" class="page-query-box" v-if="result_tabel.value">
+            <el-col>
+                统计截止时间为: {{currentDate }}
+                <el-date-picker
+                    v-model="selected_date"
+                    type="date"
+                    placeholder="年-月-日"
+                    :disabled-date="disabledDate"
+                    :size="size"
+                    :calendar-change="changeResultTable()"
+                    :clear="clearResultTable()"
+                />
+            </el-col>
+
             <el-col :span="6" :xs="6">
-                <el-statistic title="客户表去水ID个数" :value="result_tabel.value.customer_num" />
+                <el-statistic group-separator="" title="客户表去水ID个数" :value="result_tabel.value.customer_num" />
             </el-col>
             <el-col :span="6" :xs="6">
-                <el-statistic title="累计社群人数" :value="result_tabel.value.community_num"  />
+                <el-statistic group-separator="" title="累计社群人数" :value="result_tabel.value.community_num"  />
             </el-col>
             <el-col :span="6" :xs="6">
-                <el-statistic title="已退群的ID个数" :value="result_tabel.value.withdrawed_num"  />
+                <el-statistic group-separator="" title="已退群的ID个数" :value="result_tabel.value.withdrawed_num"  />
             </el-col>
             <el-col :span="6" :xs="6">
-                <el-statistic title="目前社群内人数" :value="result_tabel.value.in_community_num"  />
+                <el-statistic group-separator="" title="目前社群内人数" :value="result_tabel.value.in_community_num"  />
             </el-col>
 
             <el-col :span="6" :xs="6">
-                <el-statistic title="重复在群的ID的数量" :value="result_tabel.value.in_many_group_num"  />
+                <el-statistic group-separator="" title="重复在群的ID的数量" :value="result_tabel.value.in_many_group_num"  />
             </el-col>
             <el-col :span="6" :xs="6">
-                <el-statistic title="今日新增客户人数" :value="result_tabel.value.number_of_new_customers_added_today"  />
+                <el-statistic group-separator="" title="今日新增客户人数" :value="result_tabel.value.number_of_new_customers_added_today"  />
             </el-col>
             <el-col :span="6" :xs="6">
-                <el-statistic title="7日内新增客户人数" :value="result_tabel.value.number_of_new_customers_added_within_7_days"  />
+                <el-statistic group-separator="" title="7日内新增客户人数" :value="result_tabel.value.number_of_new_customers_added_within_7_days"  />
             </el-col>
             <el-col :span="6" :xs="6">
-                <el-statistic title="30日内新增客户人数" :value="result_tabel.value.number_of_new_customers_added_within_30_days" />
+                <el-statistic group-separator="" title="30日内新增客户人数" :value="result_tabel.value.number_of_new_customers_added_within_30_days" />
             </el-col>
          </el-row> 
-     
+    
          <el-row :gutter="0" class="page-query-box">
               <DifinCollapse
                   :show="dataContainer.showSearch"
@@ -144,7 +157,7 @@
             
             <el-button plain type="primary" @click="downloadJoinGuoptTable">
               <SvgIcon :style="'width:23px;height:23px;'" name="svg:download.svg"></SvgIcon>
-              入群表
+              入群表
             </el-button>
         
             <el-button plain type="primary" @click="downloadDeleteFriendTable">
@@ -152,11 +165,26 @@
               删除朋友表
             </el-button>
 
-            <el-button plain type="primary" @click="downloadDeleteFriendTable">
+            <el-button plain type="primary" @click="downloadGroupUserTable">
               <SvgIcon :style="'width:23px;height:23px;'" name="svg:download.svg"></SvgIcon>
-              删除朋友
+              用户
             </el-button>
-            
+
+            <el-button plain type="primary" @click="downloadResultTable">
+              <SvgIcon :style="'width:23px;height:23px;'" name="svg:download.svg"></SvgIcon>
+              结论表
+            </el-button>
+
+            <el-button plain type="primary" @click="downloadTrollsTable">
+              <SvgIcon :style="'width:23px;height:23px;'" name="svg:download.svg"></SvgIcon>
+              水军表
+            </el-button>
+
+            <el-button plain type="primary" @click="downloadWithdrawalGroupTable">
+              <SvgIcon :style="'width:23px;height:23px;'" name="svg:download.svg"></SvgIcon>
+              退群表
+            </el-button>
+           
           </div>
           <div class="table-container">
             <el-table :data="tableData" stripe style="width: 100%" border fit v-loading="loading">
@@ -169,53 +197,6 @@
               <el-table-column prop="status" width="100" label="客户状态" />
               <el-table-column prop="createTime" width="180" label="创建时间" />
               <el-table-column prop="updateTime" width="180" label="更新时间" />
-              <el-table-column label="操作" width = "230">
-                    <template #default="scope">
-                        <el-button
-                            :text="true"
-                            type="primary"
-                            @click="
-                                handleEdit(scope.row, {
-                                    isShow: false,
-                                    afterTitle: ' - 编辑',
-                                })
-                            "
-                        >
-                            编辑
-                        </el-button>
-                        <el-button
-                            :text="true"
-                            type="success"
-                            @click="
-                                handleEdit(scope.row, {
-                                    isShow: false,
-                                    afterTitle: ' - 编辑',
-                                })
-                            "
-                        >
-                            增加积分
-                        </el-button>
-                        <el-button
-                            :text="true"
-                            type="danger"
-                            @click="
-                                handleEdit(scope.row, {
-                                    isShow: false,
-                                    afterTitle: ' - 编辑',
-                                })
-                            "
-                        >
-                            扣减积分
-                        </el-button>
-                        <el-button
-                            :text="true"
-                            type="danger"
-                            @click="handleDetails([scope.row])"
-                        >
-                            禁用
-                        </el-button>
-                    </template>
-              </el-table-column>
             </el-table>
           </div>
           <div class="pagination-container">
@@ -245,25 +226,34 @@
         </div>
    </div>
   </template>
-  
+
+
+
+
+
   <script setup>
     import {
         defineComponent,
         onBeforeUnmount,
         ref,
         reactive,
+        nextTick ,
+        onMounted,
         getCurrentInstance,
         onActivated,
     } from 'vue';
-    // import axios from 'axios';
-    import { useRouter } from 'vue-router';
+  import { useRouter } from 'vue-router';
   import { debounceFn } from '@/common/debounceAndThrottle';
-  import { messageSuccess } from '@/action/messagePrompt.js';
+  import { messageSuccess,messageError} from '@/action/messagePrompt.js';
   import { saveAs } from 'file-saver';
   import {service} from '@/http/request.js'
   const size = ref('default')
   const router = useRouter()
   const result_tabel = reactive({})//获取结论表
+  const selected_date = ref('') //这个日期用来控制结论表数据看板的展示当前选中的日期进行展示
+  const formattedDate = ref('');
+  let currentDate = ref('')
+  let isFromDatePicker = false;
   const dataContainer = reactive({
               loading: false,
               showSearch: true,
@@ -335,6 +325,11 @@
   const config= reactive({
         total: 38,
     }) 
+
+//只能选择当天以前的日期
+const disabledDate = (time) => {
+     return time.getTime() > Date.now()
+}
   
       /** 获取数据列表 */
       const getDataList = debounceFn(function () {
@@ -356,17 +351,37 @@
       }, 70);
        getDataList();
 
-       //获取结论表数据
-       const getDataResultTabe   = ()=>{
-            service("/data/info").then((res)=>{
+    const  setCurrentDate = ()=> {
+      const now = new Date();
+      const year = now.getFullYear();
+      const month = (now.getMonth() + 1).toString().padStart(2, '0');
+      const day = now.getDate().toString().padStart(2, '0');
+      currentDate.value = `${year}年${month}月${day}日23:59:59`;
+    }
+    setCurrentDate();
+
+       //默认获取当天结论表数据
+       const getDataResultTabe  = ()=>{
+        if (!isFromDatePicker) { // 根据标识变量判断是否执行
+        let now = new Date();
+        let month = (now.getMonth() + 1).toString().padStart(2, '0');
+        let day = now.getDate().toString().padStart(2, '0');
+        let formattedDate = `${month}${day}`;
+            service("/data/result_info",{
+                params:{
+                    date:formattedDate
+                }
+            }).then((res)=>{
             
             const dataObj = res[0];
             result_tabel.value = convertToNumber(dataObj)
 
             console.log(result_tabel);
             })
+        }
        }
-        getDataResultTabe();
+       getDataResultTabe();
+       
 
         // 定义一个函数用于递归地将对象中的数字字符串转为数字类型
         const convertToNumber = (obj) => {
@@ -382,7 +397,43 @@
                     typeof value === 'string' && /^\d+$/.test(value)? Number(value) : convertToNumber(value)
                 ])
             );
-        }; 
+        };
+
+        //选择日期展示当天的结论表看板数据
+      function changeResultTable () {
+
+        if(selected_date.value === null)return
+        if(typeof selected_date.value === "string")return
+        console.log("changeResultTable方法被调用了");
+        isFromDatePicker = true; // 在日期组件触发时设置为true
+        if(typeof selected_date.value === "object"){
+            const dateObj = selected_date.value;
+            const month = (dateObj.getMonth() + 1).toString().padStart(2, '0');
+            const day = dateObj.getDate().toString().padStart(2, '0');
+            formattedDate.value = `${month}${day}`;
+        }
+        console.log( formattedDate.value);
+        service('/data/result_info',{
+            params:{
+                date:formattedDate.value
+            }
+        }).then((res)=>{
+            const dataObj = res[0];
+            result_tabel.value = convertToNumber(dataObj)
+            console.log(result_tabel);
+            isFromDatePicker = false; // 请求完成后重置为false
+        }).catch((err)=>{
+            if(err){
+                messageError("没有数据,请选着其他日期")
+                isFromDatePicker = false; 
+            }
+        })
+      }
+
+      //清除日期后回复当天的结论表数据看板信息
+        function  clearResultTable(){
+            getDataResultTabe();
+        }
 
 
         //下载入群表格excel
@@ -413,6 +464,57 @@
                 console.error('下载文件出错:', error);
             })
       }
+      //下载群用户表格excel
+      function downloadGroupUserTable(){
+        service("/data/group_user",{
+                responseType: 'arraybuffer' // 设置响应类型为arraybuffer,用于接收二进制数据
+            }).then((res)=>{
+                const blob = new Blob([res], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
+                saveAs(blob, '用户表格.xlsx'); // 使用file-saver保存文件
+                messageSuccess('导出成功!');
+            }).catch((error)=>{
+                console.error('下载文件出错:', error);
+            })
+      }
+      //下载结论表格excel
+      function downloadResultTable(){
+        service("/data/result",{
+                responseType: 'arraybuffer' // 设置响应类型为arraybuffer,用于接收二进制数据
+            }).then((res)=>{
+                const blob = new Blob([res], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
+                saveAs(blob, '结论表格.xlsx'); // 使用file-saver保存文件
+                messageSuccess('导出成功!');
+            }).catch((error)=>{
+                console.error('下载文件出错:', error);
+            })
+      }
+
+      //下载水军表格excel
+      function downloadTrollsTable(){
+        service("/data/trolls",{
+                responseType: 'arraybuffer' // 设置响应类型为arraybuffer,用于接收二进制数据
+            }).then((res)=>{
+                const blob = new Blob([res], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
+                saveAs(blob, '水军表格.xlsx'); // 使用file-saver保存文件
+                messageSuccess('导出成功!');
+            }).catch((error)=>{
+                console.error('下载文件出错:', error);
+            })
+      }
+
+            //下载退群表格excel
+        function downloadWithdrawalGroupTable(){
+        service("/data/withdrawal",{
+                responseType: 'arraybuffer' // 设置响应类型为arraybuffer,用于接收二进制数据
+            }).then((res)=>{
+                const blob = new Blob([res], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
+                saveAs(blob, '退群表格.xlsx'); // 使用file-saver保存文件
+                messageSuccess('导出成功!');
+            }).catch((error)=>{
+                console.error('下载文件出错:', error);
+            })
+      }
+      
 
       const handleEdit = (rows,list)=>{
         let {username,contact,weibanId, city} = rows
@@ -434,6 +536,8 @@
         dataContainer.form = {};
         handleQuery();
     }
+
+
   </script>
   
   <style scoped lang='scss'>

+ 2 - 4
server/app.js

@@ -4,7 +4,6 @@ var path = require('path');
 var cookieParser = require('cookie-parser');
 var logger = require('morgan');
 var indexRouter = require('./routes/index');
-var usersRouter = require('./routes/users');
 require('./db/mysql')
 var app = express();
 
@@ -15,7 +14,7 @@ app.use((req, res, next) => {
   res.setHeader('Access-Control-Allow-Origin', '*');
   // 允许的请求方法
   res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
-  // 允许的请求头,根据实际需求调整
+  // 允许的请求头
   res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
   // 处理 OPTIONS 预检请求,直接返回 204 状态码
   if (req.method === 'OPTIONS') {
@@ -28,7 +27,6 @@ app.use((req, res, next) => {
 // view engine setup
 // app.set('views', path.join(__dirname, 'views'));
 // app.set('view engine', 'jade');
-
 app.use(logger('dev'));//日志
 app.use(express.json());//json格式传输
 app.use(express.urlencoded({ extended: false }));
@@ -36,7 +34,7 @@ app.use(cookieParser());
 // app.use(express.static(path.join(__dirname, 'public')));
 
 app.use('/data', indexRouter);
-app.use('/users', usersRouter);
+
 
 // catch 404 and forward to error handler
 app.use(function(req, res, next) {

+ 25 - 19
server/db/mysql.js

@@ -1,31 +1,37 @@
 const mysql = require('mysql');
 // 创建数据库连接对象
-const connection = mysql.createConnection({
-    host: '47.112.185.207', // 数据库主机地址,通常本地开发时为'localhost'
-    user: 'weiban_census',      // 数据库用户名,可根据实际情况修改
-    password: 'GZy6SLJGPRbNLABe', // 对应的密码
-    database: 'weiban_census',  // 要连接的数据库名称
+
+
+const pool = mysql.createPool({
+    connectionLimit: 10,
+    host: '47.112.185.207',
+    user: 'weiban_census',
+    password: 'GZy6SLJGPRbNLABe',
+    database: 'weiban_census',
     charset: 'utf8mb4'
-});
-// 连接数据库
-connection.connect((err) => {
-    if (err) {
-        console.error('数据库连接出错:', err);
-        return;
-    }
-    console.log('成功连接到数据库');
+
 });
 
 function queryDatabase(sql, callback) {
-    
-    connection.query(sql, (err, results) => {
+
+    pool.getConnection((err,connection)=>{
         if (err) {
-            console.error('查询数据出错:', err);
-            callback(err, null);
+            console.error('获取连接出现错误:', err);
             return;
         }
-        callback(null, results);
-    });
+        console.log("连接数据库成功");
+
+        connection.query(sql, (err, results) => {
+            connection.release();
+            if (err) {
+                console.error('查询数据出错:', err);
+                callback(err, null);
+                return;
+            }
+            callback(null, results);
+        });
+        
+    })
 }
 
 

+ 172 - 4
server/routes/index.js

@@ -3,18 +3,20 @@ const XLSX = require('xlsx');
 var router = express.Router();
 const {queryDatabase } = require('../db/mysql')
 /* GET home page. */
-router.get('/info', function(req, res, next) {
-  
-  const sql = 'SELECT * FROM result_table_1210';
+router.get('/result_info', function(req, res, next) {
+  let strDate = req.query.date
+  console.log(strDate);
+  const sql = `SELECT * FROM result_table_${strDate}`;
     queryDatabase(sql,(err,results)=>{
       if(err){
         res.status(500).json({ error: '查询数据失败' });
         return;
       }
       res.json(results);
+      console.log(results);
+      
     })
 
-
   // res.render('index', { title: 'Express' });
 });
 
@@ -101,4 +103,170 @@ router.get('/delete_friend',function(req,res,next){
 
 })
 
+//下载群用户表格的excel接口
+router.get('/group_user',function(req,res,next){
+  const sql = 'SELECT * FROM group_user_table';
+  queryDatabase(sql,(err,results)=>{
+
+    if(err){
+      res.status(500).json({ error: '查询数据失败' });
+      return;
+    }
+    
+    // 定义表头数组,与数据库字段对应
+    const headers = ["序号", "群用户名称", "群用户id", "群内容", "群时间"];
+
+    // 将查询结果处理为包含表头的二维数组形式,方便转换为Excel工作表
+    const dataWithHeaders = [headers].concat(results.map(item => [
+      item.id,
+      item.group_user_name,
+      item.group_user_id,
+      item.group_content,
+      // 将时间戳转换为年月日格式
+      new Date(item.group_time * 1000).toLocaleDateString()
+  ]));
+  
+    // 使用xlsx库将处理后的数据转换为Excel工作簿对象
+    const worksheet = XLSX.utils.aoa_to_sheet(dataWithHeaders);
+    const workbook = XLSX.utils.book_new();
+    XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
+
+  // 将工作簿对象转换为二进制数据
+  const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
+
+  // 设置响应头,告知浏览器这是一个Excel文件下载
+  res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+  res.setHeader('Content-Disposition', 'attachment; filename="join_group_table.xlsx"');
+
+  // 将Excel文件数据发送给浏览器
+  res.send(excelBuffer);
+
+  })
+
+})
+
+//下载结论表格的excel接口
+router.get('/result',function(req,res,next){
+  const sql = 'SELECT * FROM result_table_1210';
+  queryDatabase(sql,(err,results)=>{
+
+    if(err){
+      res.status(500).json({ error: '查询数据失败' });
+      return;
+    }
+    
+    // 定义表头数组,与数据库字段对应
+    const headers = ["序号", "客户表去水ID个数", "累计社群人数", "已退群的ID个数", "目前社群内人数","重复在群的ID的数量","今日新增客户人数","7日内新增客户人数","30日内新增客户人数"];
+
+    // 将查询结果处理为包含表头的二维数组形式,方便转换为Excel工作表
+    const dataWithHeaders = [headers].concat(results.map(item => [
+      item.id,
+      item.customer_num,
+      item.community_num,
+      item.withdrawed_num,
+      item.in_community_num,
+      item.in_many_group_num,
+      item.number_of_new_customers_added_today,
+      item.number_of_new_customers_added_within_7_days,
+      item.number_of_new_customers_added_within_30_days,
+  ]));
+  
+    // 使用xlsx库将处理后的数据转换为Excel工作簿对象
+    const worksheet = XLSX.utils.aoa_to_sheet(dataWithHeaders);
+    const workbook = XLSX.utils.book_new();
+    XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
+
+  // 将工作簿对象转换为二进制数据
+  const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
+
+  // 设置响应头,告知浏览器这是一个Excel文件下载
+  res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+  res.setHeader('Content-Disposition', 'attachment; filename="join_group_table.xlsx"');
+
+  // 将Excel文件数据发送给浏览器
+  res.send(excelBuffer);
+
+  })
+
+})
+
+//下载水军表格的excel接口
+router.get('/trolls',function(req,res,next){
+  const sql = 'SELECT * FROM shang_and_di_table';
+  queryDatabase(sql,(err,results)=>{
+
+    if(err){
+      res.status(500).json({ error: '查询数据失败' });
+      return;
+    }
+    
+    // 定义表头数组,与数据库字段对应
+    const headers = ["序号", "水军名称","水军备注","水军ID"];
+
+    // 将查询结果处理为包含表头的二维数组形式,方便转换为Excel工作表
+    const dataWithHeaders = [headers].concat(results.map(item => [
+      item.id,
+      item.s_d_name,
+      item.s_d_remark,
+      item.s_d_id
+  ]));
+  
+    // 使用xlsx库将处理后的数据转换为Excel工作簿对象
+    const worksheet = XLSX.utils.aoa_to_sheet(dataWithHeaders);
+    const workbook = XLSX.utils.book_new();
+    XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
+
+  // 将工作簿对象转换为二进制数据
+  const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
+
+  // 设置响应头,告知浏览器这是一个Excel文件下载
+  res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+  res.setHeader('Content-Disposition', 'attachment; filename="join_group_table.xlsx"');
+
+  // 将Excel文件数据发送给浏览器
+  res.send(excelBuffer);
+  })
+})
+
+//下载退出群表格的excel接口
+router.get('/withdrawal',function(req,res,next){
+  const sql = 'SELECT * FROM withdrawal_group_table';
+  queryDatabase(sql,(err,results)=>{
+
+    if(err){
+      res.status(500).json({ error: '查询数据失败' });
+      return;
+    }
+    
+    // 定义表头数组,与数据库字段对应
+    const headers = ["序号", "退群的用户名称","退群的用户ID","退群内容","退群时间"];
+
+    // 将查询结果处理为包含表头的二维数组形式,方便转换为Excel工作表
+    const dataWithHeaders = [headers].concat(results.map(item => [
+      item.id,
+      item.withdrawal_user_name,
+      item.withdrawal_user_id,
+      item.withdrawal_content,
+      // 将时间戳转换为年月日格式
+      new Date(item.withdrawal_group_time * 1000).toLocaleDateString()
+  ]));
+  
+    // 使用xlsx库将处理后的数据转换为Excel工作簿对象
+    const worksheet = XLSX.utils.aoa_to_sheet(dataWithHeaders);
+    const workbook = XLSX.utils.book_new();
+    XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
+
+  // 将工作簿对象转换为二进制数据
+  const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'buffer' });
+
+  // 设置响应头,告知浏览器这是一个Excel文件下载
+  res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+  res.setHeader('Content-Disposition', 'attachment; filename="join_group_table.xlsx"');
+
+  // 将Excel文件数据发送给浏览器
+  res.send(excelBuffer);
+  })
+})
+
+
 module.exports = router;

+ 0 - 9
server/routes/users.js

@@ -1,9 +0,0 @@
-var express = require('express');
-var router = express.Router();
-
-/* GET users listing. */
-router.get('/', function(req, res, next) {
-  res.send('respond with a resource');
-});
-
-module.exports = router;