手把手制作Vue3+Flask全栈项目 全栈开发之路实战篇 问卷网站(五)数据处理

news2024/11/24 14:48:09

全栈开发一条龙——前端篇
第一篇:框架确定、ide设置与项目创建
第二篇:介绍项目文件意义、组件结构与导入以及setup的引入。
第三篇:setup语法,设置响应式数据。
第四篇:数据绑定、计算属性和watch监视
第五篇 : 组件间通信及知识补充
第六篇:生命周期和自定义hooks
第七篇:路由
第八篇:传参
第九篇:插槽,常用api和全局api。
全栈开发一条龙——全栈篇
第一篇:初识Flask&MySQL实现前后端通信
第二篇: sql操作、发送http请求和邮件发送
第三篇:全栈实现发送验证码注册账号
第四篇:图片验证码及知识补充
全栈开发一条龙——实战篇

第一篇:项目建立与login页面
第二篇:建立管理员后台和添加题目功能实现
第三篇:完善管理员后台
第四篇:用户视图

本篇将完成数据处理页面

文章目录

  • 后端
    • 数据处理工具
    • 蓝图
  • 前端
    • 模板
    • 脚本
    • 完整前端代码
  • 效果展示

后端

数据处理工具

我们先来写数据处理的工具,我们的思路是从数据库中取出我们之前存储的答案序列,然后分析到达不同阶段的人数和相关系数等等。
我们先从数据库中获取数据

                raw_list = db.session.execute( text("select * from data_analysis") ).fetchall()
                answer_list = list_row2list_dic(raw_list)
                temp = sql_ex()
                question_info = temp.search()

接下来进行基础的数据统计,各个题目的答题次数,平均分等

                # 初始化每道题的选项计数和分数统计
                question_stats = []
                for question in question_info:
                    question_stats.append({
                        'question': question['questions'],
                        'choice_counts': {'A': 0, 'B': 0, 'C': 0, 'D': 0},
                        'total_score': 0,
                        'response_count': 0,
                        'points': {
                            'A': question['point_a'],
                            'B': question['point_b'],
                            'C': question['point_c'],
                            'D': question['point_d']
                        }
                    })

                # 统计每个选项的选择次数和总分
                for answer in answer_list:
                    answer_str = answer['answer']
                    for i, char in enumerate(answer_str):
                        if char in 'ABCD':
                            question_stats[i]['choice_counts'][char] += 1
                            question_stats[i]['total_score'] += question_stats[i]['points'][char]
                            question_stats[i]['response_count'] += 1

                # 计算每道题的平均分
                for stats in question_stats:
                    if stats['response_count'] > 0:
                        stats['average_score'] = stats['total_score'] / stats['response_count']
                    else:
                        stats['average_score'] = 0

我们可以使用以下代码来查看处理的情况,当然,最后需要把他们注释掉。


                # 输出结果 question_stats
                # for stats in question_stats:
                #     print(f"Question: {stats['question']}")
                #     print(f"Choice Counts: {stats['choice_counts']}")
                #     print(f"Average Score: {stats['average_score']:.2f}")
                #     print('-' + '-' * 50)
                #输出格式:[{'question': '惺惺惜惺惺哈哈哈哈和和和和和和和和谢谢谢谢选项下下下下下下下下下下下下下下下下', 'choice_counts': {'A': 4, 'B': 0, 'C': 0, 'D': 1}, 'total_score': 3, 'response_count': 5, 'points': {'A': 0, 'B': 1, 'C': 2, 'D': 3}, 'average_score': 0.6}, {'question': 'csy——beautiful!!', 'choice_counts': {'A': 1, 'B': 1, 'C': 1, 'D': 2}, 'total_score': 9, 'response_count': 5, 'points': {'A': 0, 'B': 1, 'C': 2, 'D': 3}, 'average_score': 1.8}, {'question': '1', 'choice_counts': {'A': 0, 'B': 0, 'C': 1, 'D': 1}, 'total_score': 5, 'response_count': 2, 'points': {'A': 0, 'B': 1, 'C': 2, 'D': 3}, 'average_score': 2.5}, {'question': 'huaidan no', 'choice_counts': {'A': 1, 'B': 0, 'C': 0, 'D': 1}, 'total_score': 3, 'response_count': 2, 'points': {'A': 0, 'B': 1, 'C': 2, 'D': 3}, 'average_score': 1.5}, {'question': '8的合伙人发', 'choice_counts': {'A': 0, 'B': 0, 'C': 0, 'D': 1}, 'total_score': 3, 'response_count': 1, 'points': {'A': 0, 'B': 1, 'C': 2, 'D': 3}, 'average_score': 3.0}, {'question': '9ehwc', 'choice_counts': {'A': 0, 'B': 0, 'C': 0, 'D': 1}, 'total_score': 3, 'response_count': 1, 'points': {'A': 0, 'B': 1, 'C': 2, 'D': 3}, 'average_score': 3.0}, {'question': '接口', 'choice_counts': {'A': 0, 'B': 0, 'C': 0, 'D': 1}, 'total_score': 4, 'response_count': 1, 'points': {'A': 1, 'B': 2, 'C': 3, 'D': 4}, 'average_score': 4.0}]

然后我们统计达到各个stage的人数,逻辑是只要回答了任意一道stage3的题目,这个人就达到了stage3的阶段,counter++

                #统计stage人数
                # 初始化每个阶段的回答人数统计
                stage_answer_counts = {1: 0, 2: 0, 3: 0, 4: 0}

                # 统计每个阶段回答了至少一个问题的人数
                for answer in answer_list:
                    answer_str = answer['answer']
                    answered_stages = set()
                    for i, char in enumerate(answer_str):
                        if char in 'ABCD':
                            stage = question_info[i]['stage']
                            answered_stages.add(stage)
                    for stage in answered_stages:
                        stage_answer_counts[stage] += 1
                 
                 #  stage_answer_counts  output:{1: 5, 2: 2, 3: 1, 4: 1}

最后,我们进行相关性分析,这里我们需要使用numpy和pandas


                answer_matrix = []
                for answer in answer_list:
                    answer_str = answer['answer']
                    answer_row = []
                    for char in answer_str:
                        if char == 'A':
                            answer_row.append(1)
                        elif char == 'B':
                            answer_row.append(2)
                        elif char == 'C':
                            answer_row.append(3)
                        elif char == 'D':
                            answer_row.append(4)
                        else:
                            answer_row.append(0)
                    answer_matrix.append(answer_row)

                # 转换为DataFrame
                df = pd.DataFrame(answer_matrix, columns=[f'Q{i+1}' for i in range(len(answer_matrix[0]))])

                # 计算相关性矩阵
                correlation_matrix = df.corr()

这里我们需要先把内容转为pandas特定的格式,然后调用库。最后输出的结果是output type <class ‘pandas.core.frame.DataFrame’>格式的,内容是

                #     Q1        Q2        Q3        Q4        Q5        Q6        Q7
                # Q1  1.000000  0.514496  0.745601  0.968246  1.000000  1.000000  1.000000
                # Q2  0.514496  1.000000  0.826234  0.664211  0.514496  0.514496  0.514496
                # Q3  0.745601  0.826234  1.000000  0.888523  0.745601  0.745601  0.745601
                # Q4  0.968246  0.664211  0.888523  1.000000  0.968246  0.968246  0.968246
                # Q5  1.000000  0.514496  0.745601  0.968246  1.000000  1.000000  1.000000
                # Q6  1.000000  0.514496  0.745601  0.968246  1.000000  1.000000  1.000000
                # Q7  1.000000  0.514496  0.745601  0.968246  1.000000  1.000000  1.000000
                

这样的矩阵,至此,我们的处理工具就做好了,接下来我们需要完善后端节后,使得前端可以访问并获取到处理好的数据。

蓝图

    def post(self):
        temp = answer_ex()
        question,stage,rela = temp.search()
        response = {
        'question': question,
        'stage': stage,
        'rela': rela.to_dict()
                    }
        return jsonify({"errcode": 0, "msg": response})

如上就做好了,这里我们将举证转化为dict,方便我们前端展示数据。

前端

前端我们需要做以下几件事,展示基础数据,根据相关性数据绘制图表。这需要用到chart.js 我们可以用npm i一键安装。
我们的展示思路就是把一个个问题做成card,一一展示。

模板

<template>
  <div class="container">


    <div class="header">
      <button class="custom-button" @click="rt">返回编辑页</button>
    </div>


    <h1>数据统计</h1>

    <div class="card">
      <h2>数据总览</h2>
      <div class="data-row"><strong>总问卷数:</strong> {{ stage[1] }}</div>
      <h3>累计人数统计</h3>
      <div class="data-row"><strong>二阶段以上:</strong> {{ stage[2] }}</div>
      <div class="data-row"><strong>三阶段以上:</strong> {{ stage[3] }}</div>
      <div class="data-row"><strong>四阶段以上:</strong> {{ stage[4] }}</div>
      <h3>阶段人数统计</h3>
      <div class="data-row"><strong>一阶段人数:</strong> {{ stage[1]-stage[2] }}</div>
      <div class="data-row"><strong>二阶段人数:</strong> {{ stage[2] - stage[3]}}</div>
      <div class="data-row"><strong>三阶段人数:</strong> {{ stage[3] - stage[4] }}</div>
      <div class="data-row"><strong>四阶段人数:</strong> {{ stage[4] }}</div>
      <h2>人数分布图表</h2>
      <div class="chart-container">
        <canvas id="stage-chart"></canvas>
      </div>
    </div>
    <h1>题目详情</h1>
    <div class="card" v-for="(item, index) in question" :key="index">
      <h2>{{ index + 1 }}. {{ item.question }}</h2>
      <div class="data-row"><strong>答题统计:</strong></div>
      <div class="choice">
        <div>A: {{ item.choice_counts.A }}</div>
        <div>B: {{ item.choice_counts.B }}</div>
        <div>C: {{ item.choice_counts.C }}</div>
        <div>D: {{ item.choice_counts.D }}</div>
      </div>
      <div class="data-row"><strong>回答次数:</strong> {{ item.response_count }}</div>
      <div class="data-row"><strong>均分(期望为1.5):</strong> {{ item.average_score }}</div>
      <h3>题目相关性
        <button @click="toggleRelaVisibility(index)" class="bt">
          {{ relaVisible[index] ? '隐藏相关系数' : '显示相关系数' }}
        </button>
      </h3>
      <ul v-if="relaVisible[index]">
        <li v-for="(value, key) in getRelaValues(index)" :key="key">与{{ key }}的相关系数为: {{ value }}</li>
      </ul>
      <canvas :id="'chart-' + index"></canvas>
    </div>
  </div>
</template>

这里,我们定义了一个标题,枚举了各个问题的card以展示。

脚本

<script setup>
import { ref, onMounted, nextTick } from 'vue';
import axios from 'axios';
import { Chart, CategoryScale, BarController, BarElement, PointElement, LinearScale, Title, PieController, ArcElement, Tooltip, Legend } from 'chart.js';
import { useRouter } from 'vue-router';
import { useUrlStore } from '@/store/urlStore'; // 确保路径正确
const urlStore = useUrlStore(); // 使用URL Store

const router = useRouter();
Chart.register(
  CategoryScale,
  BarController,
  BarElement,
  PointElement,
  LinearScale,
  Title,
  PieController,
  ArcElement,
  Tooltip,
  Legend
);

const question = ref([]);
const stage = ref({});
const rela = ref({});
const relaVisible = ref([]);

const fetchData = async () => {
  try {
    const response = await axios.post(urlStore.urls.data);
    if (response.data.errcode === 0) {
      question.value = response.data.msg.question;
      stage.value = response.data.msg.stage;
      rela.value = response.data.msg.rela;
      relaVisible.value = new Array(question.value.length).fill(false);
      await nextTick();
      renderCharts();
      renderStageChart();
    } else {
      console.error('Error fetching data:', response.data.msg);
    }
  } catch (error) {
    console.error('Error fetching data:', error);
  }
};

const formatNumber = (number) => number.toFixed(3);

const getRelaValues = (index) => {
  const key = `Q${index + 1}`;
  const values = rela.value[key] || {};
  const formattedValues = {};
  Object.keys(values).forEach(k => {
    formattedValues[k] = formatNumber(values[k]);
  });
  return formattedValues;
};

const toggleRelaVisibility = (index) => {
  relaVisible.value[index] = !relaVisible.value[index];
};

const renderCharts = () => {
  question.value.forEach((item, index) => {
    const ctx = document.getElementById('chart-' + index).getContext('2d');
    const correlations = getRelaValues(index);
    const correlationValues = Object.values(correlations).map(value => parseFloat(value));
    const backgroundColors = correlationValues.map(value =>
      value < 0 ? 'rgba(255, 99, 132, 0.5)' : 'rgba(75, 192, 192, 0.5)'
    );
    new Chart(ctx, {
      type: 'bar',
      data: {
        labels: Object.keys(correlations),
        datasets: [{
          label: `Correlations for Q${index + 1}`,
          data: correlationValues,
          backgroundColor: backgroundColors,
          borderColor: 'rgba(75, 192, 192, 1)',
          borderWidth: 1
        }]
      },
      options: {
        responsive: true,
        scales: {
          x: {
            type: 'category',
            display: true,
            title: {
              display: true,
              text: 'Questions'
            }
          },
          y: {
            type: 'linear',
            beginAtZero: true,
            display: true,
            title: {
              display: true,
              text: 'Correlation Value'
            }
          }
        }
      }
    });
  });
};

const renderStageChart = () => {
  const ctx = document.getElementById('stage-chart').getContext('2d');
  const stageData = [
    stage.value['1'] - stage.value['2'],
    stage.value['2'] - stage.value['3'],
    stage.value['3'] - stage.value['4'],
    stage.value['4']
  ];
  new Chart(ctx, {
    type: 'pie',
    data: {
      labels: ['stage1', 'stage2', 'stage3', 'stage4'],
      datasets: [{
        data: stageData,
        backgroundColor: [
          'rgba(255, 99, 132, 0.6)',
          'rgba(54, 162, 235, 0.6)',
          'rgba(255, 206, 86, 0.6)',
          'rgba(75, 192, 192, 0.6)'
        ],
        borderColor: [
          'rgba(255, 99, 132, 1)',
          'rgba(54, 162, 235, 1)',
          'rgba(255, 206, 86, 1)',
          'rgba(75, 192, 192, 1)'
        ],
        borderWidth: 1
      }]
    },
    options: {
      responsive: true,
      plugins: {
        legend: {
          position: 'right'
        },
        tooltip: {
          enabled: true
        }
      }
    }
  });
};

function rt(){
  alert("切换成功,一秒后跳转编辑页面");
  setTimeout(() => { router.push({ path: "/home" }) }, 1000);
}

onMounted(fetchData);
</script>

我们脚本实现的逻辑就是先访问后端接口获取数据,然后解析数据,绘制图表。我们绘制了一个pie图,用于展示各个阶段人数。也制作了一个柱状图来展示各个题目之间的相关性。

完整前端代码

<template>
  <div class="container">


    <div class="header">
      <button class="custom-button" @click="rt">返回编辑页</button>
    </div>


    <h1>数据统计</h1>

    <div class="card">
      <h2>数据总览</h2>
      <div class="data-row"><strong>总问卷数:</strong> {{ stage[1] }}</div>
      <h3>累计人数统计</h3>
      <div class="data-row"><strong>二阶段以上:</strong> {{ stage[2] }}</div>
      <div class="data-row"><strong>三阶段以上:</strong> {{ stage[3] }}</div>
      <div class="data-row"><strong>四阶段以上:</strong> {{ stage[4] }}</div>
      <h3>阶段人数统计</h3>
      <div class="data-row"><strong>一阶段人数:</strong> {{ stage[1]-stage[2] }}</div>
      <div class="data-row"><strong>二阶段人数:</strong> {{ stage[2] - stage[3]}}</div>
      <div class="data-row"><strong>三阶段人数:</strong> {{ stage[3] - stage[4] }}</div>
      <div class="data-row"><strong>四阶段人数:</strong> {{ stage[4] }}</div>
      <h2>人数分布图表</h2>
      <div class="chart-container">
        <canvas id="stage-chart"></canvas>
      </div>
    </div>
    <h1>题目详情</h1>
    <div class="card" v-for="(item, index) in question" :key="index">
      <h2>{{ index + 1 }}. {{ item.question }}</h2>
      <div class="data-row"><strong>答题统计:</strong></div>
      <div class="choice">
        <div>A: {{ item.choice_counts.A }}</div>
        <div>B: {{ item.choice_counts.B }}</div>
        <div>C: {{ item.choice_counts.C }}</div>
        <div>D: {{ item.choice_counts.D }}</div>
      </div>
      <div class="data-row"><strong>回答次数:</strong> {{ item.response_count }}</div>
      <div class="data-row"><strong>均分(期望为1.5:</strong> {{ item.average_score }}</div>
      <h3>题目相关性
        <button @click="toggleRelaVisibility(index)" class="bt">
          {{ relaVisible[index] ? '隐藏相关系数' : '显示相关系数' }}
        </button>
      </h3>
      <ul v-if="relaVisible[index]">
        <li v-for="(value, key) in getRelaValues(index)" :key="key">{{ key }}的相关系数为: {{ value }}</li>
      </ul>
      <canvas :id="'chart-' + index"></canvas>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from 'vue';
import axios from 'axios';
import { Chart, CategoryScale, BarController, BarElement, PointElement, LinearScale, Title, PieController, ArcElement, Tooltip, Legend } from 'chart.js';
import { useRouter } from 'vue-router';
import { useUrlStore } from '@/store/urlStore'; // 确保路径正确
const urlStore = useUrlStore(); // 使用URL Store

const router = useRouter();
Chart.register(
  CategoryScale,
  BarController,
  BarElement,
  PointElement,
  LinearScale,
  Title,
  PieController,
  ArcElement,
  Tooltip,
  Legend
);

const question = ref([]);
const stage = ref({});
const rela = ref({});
const relaVisible = ref([]);

const fetchData = async () => {
  try {
    const response = await axios.post(urlStore.urls.data);
    if (response.data.errcode === 0) {
      question.value = response.data.msg.question;
      stage.value = response.data.msg.stage;
      rela.value = response.data.msg.rela;
      relaVisible.value = new Array(question.value.length).fill(false);
      await nextTick();
      renderCharts();
      renderStageChart();
    } else {
      console.error('Error fetching data:', response.data.msg);
    }
  } catch (error) {
    console.error('Error fetching data:', error);
  }
};

const formatNumber = (number) => number.toFixed(3);

const getRelaValues = (index) => {
  const key = `Q${index + 1}`;
  const values = rela.value[key] || {};
  const formattedValues = {};
  Object.keys(values).forEach(k => {
    formattedValues[k] = formatNumber(values[k]);
  });
  return formattedValues;
};

const toggleRelaVisibility = (index) => {
  relaVisible.value[index] = !relaVisible.value[index];
};

const renderCharts = () => {
  question.value.forEach((item, index) => {
    const ctx = document.getElementById('chart-' + index).getContext('2d');
    const correlations = getRelaValues(index);
    const correlationValues = Object.values(correlations).map(value => parseFloat(value));
    const backgroundColors = correlationValues.map(value =>
      value < 0 ? 'rgba(255, 99, 132, 0.5)' : 'rgba(75, 192, 192, 0.5)'
    );
    new Chart(ctx, {
      type: 'bar',
      data: {
        labels: Object.keys(correlations),
        datasets: [{
          label: `Correlations for Q${index + 1}`,
          data: correlationValues,
          backgroundColor: backgroundColors,
          borderColor: 'rgba(75, 192, 192, 1)',
          borderWidth: 1
        }]
      },
      options: {
        responsive: true,
        scales: {
          x: {
            type: 'category',
            display: true,
            title: {
              display: true,
              text: 'Questions'
            }
          },
          y: {
            type: 'linear',
            beginAtZero: true,
            display: true,
            title: {
              display: true,
              text: 'Correlation Value'
            }
          }
        }
      }
    });
  });
};

const renderStageChart = () => {
  const ctx = document.getElementById('stage-chart').getContext('2d');
  const stageData = [
    stage.value['1'] - stage.value['2'],
    stage.value['2'] - stage.value['3'],
    stage.value['3'] - stage.value['4'],
    stage.value['4']
  ];
  new Chart(ctx, {
    type: 'pie',
    data: {
      labels: ['stage1', 'stage2', 'stage3', 'stage4'],
      datasets: [{
        data: stageData,
        backgroundColor: [
          'rgba(255, 99, 132, 0.6)',
          'rgba(54, 162, 235, 0.6)',
          'rgba(255, 206, 86, 0.6)',
          'rgba(75, 192, 192, 0.6)'
        ],
        borderColor: [
          'rgba(255, 99, 132, 1)',
          'rgba(54, 162, 235, 1)',
          'rgba(255, 206, 86, 1)',
          'rgba(75, 192, 192, 1)'
        ],
        borderWidth: 1
      }]
    },
    options: {
      responsive: true,
      plugins: {
        legend: {
          position: 'right'
        },
        tooltip: {
          enabled: true
        }
      }
    }
  });
};

function rt(){
  alert("切换成功,一秒后跳转编辑页面");
  setTimeout(() => { router.push({ path: "/home" }) }, 1000);
}

onMounted(fetchData);
</script>

<style scoped>
.chart-container {
  width: 60%;
  margin: auto;
}

.header {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
}

.custom-button {
  position: absolute;
  top: 0;
  right: 0;
  background-color: #f0adcd;
  color: white;
  border: none;
  width: 120px;
  height: 30px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.custom-button:hover {
  background-color: #e5347d;
}

.bt {
  background-color: #77d6dd;
  width: 150px;
  height: 29%;
}

.container {
  padding: 20px;
  font-family: 'Arial', sans-serif;
  color: #333;
  display: flex;
  flex-direction: column;
  width: 700px;
  margin-left: 15vw;
}

h1 {
  font-size: 32px;
  text-align: center;
  margin-bottom: 40px;
  color: #2c3e50;
}

.card {
  background-color: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 40px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s, box-shadow 0.3s;
}

.card:hover {
  transform: scale(1.005);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.card h2 {
  font-size: 24px;
  color: #3498db;
  margin-bottom: 10px;
}

.data-row {
  font-size: 16px;
  margin: 8px 0;
}

.choice {
  margin-left: 20px;
}

.card h3 {
  font-size: 20px;
  color: #2c3e50;
  margin-top: 20px;
}

.card ul {
  list-style-type: none;
  padding: 0;
}

.card li {
  font-size: 14px;
  color: #555;
  margin-bottom: 5px;
}

canvas {
  margin-top: 20px;
}
</style>

以上是前端的完整代码,你可以自己修改样式。

效果展示

在questionlist里加入一个按钮,来跳转数据处理页面,很简单就不说了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1797680.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java学习中,如何理解注解的概念及常用注解的使用方法

一、简介 Java注解&#xff08;Annotation&#xff09;是一种元数据&#xff0c;提供了一种将数据与程序元素&#xff08;类、方法、字段等&#xff09;关联的方法。注解本身不改变程序的执行逻辑&#xff0c;但可以通过工具或框架进行处理&#xff0c;从而影响编译、运行时的…

Suryxin’s ACM退役记

序 我的记忆力很差&#xff0c;经历过的很多事情都已经记不太清了&#xff0c;其中有很多美好回忆也已经消散&#xff0c;我很惋惜没能留存一些照片和声音或是文字供我怀念&#xff0c;这就像《泰坦尼克号》一样&#xff0c;露丝和杰克感人肺腑的爱情故事&#xff0c;最后也仅…

东航携手抖音生活服务开启机票首播,推出国内、国际超值机票次卡

在民航暑运旺季到来之际&#xff0c;越来越多的用户选择提前做好旅行规划&#xff0c;囤下高性价比的出游商品。6月6日18点&#xff0c;中国东方航空&#xff08;以下简称“东航”&#xff09;将在抖音开启首次机票直播&#xff0c;推荐多款超值机票次卡及空中Wi-Fi等特色产品&…

SpringBoot发邮件服务如何配置?怎么使用?

SpringBoot发邮件需要的参数&#xff1f;邮件发送性能如何优化&#xff1f; 在SpringBoot项目中配置发邮件服务是一个常见的需求&#xff0c;它允许我们通过应用程序发送通知、验证邮件或其他类型的邮件。AokSend将详细介绍如何在SpringBoot中配置发邮件服务。 SpringBoot发邮…

nginx和proxy_protocol协议

目录 1. 引言2. HTTP server的配置3. Stream server的配置3.1 作为proxy_protocol的前端服务器3.2 作为proxy_protocol的后端服务器1. 引言 proxy_protocol 是haproxy开发的一种用于在代理服务器和后端服务器之间传递客户端连接信息的协议。使用 proxy_protocol 的主要优势是能…

QT获取最小化,最大化,关闭窗口事件

QT获取最小化&#xff0c;最大化&#xff0c;关闭窗口事件 主程序头文件&#xff1a; 实现&#xff1a; changeEvent&#xff0c;状态改变事件 closeEvent触发点击窗口关闭按钮事件 其代码它参考&#xff1a; /*重写该函数*/ void MainWindow::changeEvent(QEvent *event) {…

蚓链数字化营销生态的影响力分享!

​家人们&#xff0c;今天来给大家分享一些关于数字化平台生态化对数字营销影响的具体案例。 比如某电商平台&#xff0c;通过生态化的建设&#xff0c;实现了精准的推荐算法。根据用户的浏览历史和购买行为&#xff0c;为他们推荐最符合需求的商品&#xff0c;大大提高了购买…

JeeSite 快速开发平台 Vue3 前端版介绍

JeeSite 快速开发平台 Vue3 前端版介绍&#xff1a; 它构建于 Vue3、Vite、Ant-Design-Vue、TypeScript 以及 Vue Vben Admin 等最前沿的技术栈之上&#xff0c;能助力初学者迅速上手并顺利融入团队开发进程。涵盖的模块包括组织机构、角色用户、菜单授权、数据权限、系统参数…

小程序开发平台——超级万能DIY商城小程序源码系统 前后端分离 带完整的安装代码包以及搭建教程

系统概述 超级万能 DIY 商城小程序源码系统是一款集前端和后端分离的强大工具&#xff0c;为开发者提供了一站式的解决方案。它不仅具备完整的安装代码包&#xff0c;还附带详细的搭建教程&#xff0c;让即使是没有丰富技术经验的开发者也能轻松上手&#xff0c;快速构建自己的…

Vue3实战笔记(56)—实战:DefineModel的使用方法细节

文章目录 前言一、实战DefineModel二、思考原理总结 前言 今天写个小例子&#xff0c;实战DefineModel的使用方法细节 一、实战DefineModel 上文官方说的挺清楚&#xff0c;实战验证一下&#xff0c;新建DefineModel.vue&#xff08;这是儿子&#xff09;&#xff1a; <te…

珠海鸿瑞毛利率持续下滑:核心产品销量大降,偿债能力偏弱

《港湾商业观察》黄懿 日前&#xff0c;珠海市鸿瑞信息技术股份有限公司&#xff08;下称“珠海鸿瑞”&#xff09;收到了北京证券交易所发出的第三轮审核问询函。 此前&#xff0c;2020年11月&#xff0c;珠海鸿瑞曾向深交所报送上市申请。IPO申请文件获受理后&#xff0c;珠…

MySQL8 全文索引

文章目录 创建索引使用索引总结 创建索引 之前未尝试过使用MySQL8的全文索引&#xff0c;今天试一试看看什么效果&#xff0c;否则跟不上时代了都。   创建索引非常简单&#xff0c;写句SQL就行。 create table goods(id integer primary key auto_increment,name varchar(2…

知识图谱的应用---智能制造

文章目录 智能制造典型应用 智能制造 随着云计算、大数据、人工智能技术的快速发展&#xff0c;越来越多的新技术正在应用于传统工业领域&#xff0c;并在帮助企业实现产业转型、技术升级及效益提升方面起到了关键作用。目前在提升良品率方面&#xff0c;知识图谱通过深度计算所…

Selenium时间等待_显示等待

特点&#xff1a; 针对具体元素进行时间等待 可以自定义等待时长和间隔时间 按照设定的时间&#xff0c;不断定位元素&#xff0c;定位到了直接执行下一步操作 如在设定时间内没定位到元素&#xff0c;则报错&#xff08;TimeOutException&#xff09; 显示等待概念&#x…

【Python报错】已解决NameError: name ‘secrets‘ is not defined

解决Python报错&#xff1a;NameError: name ‘secrets’ is not defined 在使用Python进行安全编程时&#xff0c;我们经常需要使用secrets模块来生成安全的随机数。然而&#xff0c;如果你在尝试使用这个模块时遇到了NameError: name secrets is not defined的错误&#xff0…

【机器学习】机器学习与智能交通在智慧城市中的融合应用与性能优化新探索

文章目录 引言机器学习与智能交通的基本概念机器学习概述监督学习无监督学习强化学习 智能交通概述交通流量预测交通拥堵管理智能信号控制智能停车管理 机器学习与智能交通的融合应用实时交通数据分析数据预处理特征工程 交通流量预测与优化模型训练模型评估 智能信号控制与优化…

安装TPMmanager

sudo apt-get install qt4-qmake sudo apt-get install libqt4-dev下载TPMManager&#xff0c;解压之后拖入Ubuntu&#xff0c;进入目录 https://gitcode.com/Rohde-Schwarz/TPMManager/overview?utm_sourcecsdn_github_accelerator&isLogin1 cd tpmmanager-master qmake…

【Spring Cloud】Gateway 服务网关核心架构的执行流程和断言

文章目录 基本概念执行流程断言内置路由断言工厂自定义路由断言工厂 总结 基本概念 路由(Route)是gateway中最基本的组件之一&#xff0c;表示一个具体的路由信息载体。主要定义了下面的几个信息&#xff1a; id&#xff1a;路由标识符&#xff0c;区别于其他Route。uri&…

centos系统清理docker日志文件

centos系统清理docker日志文件 1.查看docker根目录位置2.清理日志 1.查看docker根目录位置 命令&#xff1a;docker info ,将Docker Root Dir 的值复制下来。如果目录中包含 等特殊符号的目录&#xff0c;需要转义 2.清理日志 创建文件&#xff1a;vim docker_logs_clean.…

对GNSS辐射测试有疑问?德思特为您解答!

一、问题背景 在我们真实的环境中&#xff0c;GNSS信号是无处不在的&#xff0c;他通过从卫星辐射的形式覆盖地表。当我们想要使用GNSS模拟器进行测试时&#xff0c;一般有两种方式&#xff1a; ● 通过线缆直接连接待测件&#xff0c;无需额外环境与配置&#xff0c;即可进行…