Echarts实现订单数据统计,前端+后端 代码

news2024/10/8 22:25:05

以下是静态统计图可以直接看到统计图,复制粘贴即可看到效果,但是数据是死的。下面我会介绍一种动态的方法 ,后端动态返回,基于订单页面的数据,来渲染统计图。

 Vue 安装 Echarts

npm i echarts -S

静态 :

<template>
  <div>
    <el-row :gutter="10">
      <el-col :span="12">
        <el-card>
          <div style="width: 100%; height: 400px" id="line"></div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card>
          <div style="width: 100%; height: 400px" id="bar"></div>
        </el-card>
      </el-col>
    </el-row>

    <el-row :gutter="10" style="margin: 10px 0">
      <el-col :span="12">
        <el-card>
          <div style="width: 100%; height: 400px" id="pie"></div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import * as echarts from 'echarts'

const option = {
  title: {
    text: '订单销售的趋势图',
    left: 'center'
  },
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    left: 'left'
  },
  xAxis: {
    type: 'category',
    data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: '金额',
      data: [820, 932, 901, 934, 1290, 1330, 1320],
      type: 'line',
      smooth: true
    },
    {
      name: '库存',
      data: [356, 987, 457, 768, 390, 680, 1920],
      type: 'line',
      smooth: true
    }
  ]
}

const option1 = {
  title: {
    text: '订单销售的柱状图',
    left: 'center'
  },
  tooltip: {
    trigger: 'axis'
  },
  legend: {
    left: 'left'
  },
  xAxis: {
    type: 'category',
    data: ['水果', '零食', '饮料', '奶制品', '生活用品']
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      name: '金额',
      data: [820, 932, 901, 934, 1290, 1330, 1320],
      type: 'bar',
      smooth: true
    },
    {
      name: '销量',
      data: [100, 200, 204, 209, 590, 698, 700],
      type: 'bar',
      smooth: true
    }
  ]
}

const option2 = {
  title: {
    text: '订单销售统计',
    subtext: '比例图',
    left: 'center'
  },
  tooltip: {
    trigger: 'item'
  },
  legend: {
    orient: 'vertical',
    left: 'left'
  },
  series: [
    {
      name: 'Access From',
      type: 'pie',
      center: ['50%', '60%'],
      radius: '50%',
      data: [
        { value: 1048, name: 'Search Engine' },
        { value: 735, name: 'Direct' },
        { value: 580, name: 'Email' },
        { value: 484, name: 'Union Ads' },
        { value: 300, name: 'Video Ads' }
      ],
      emphasis: {
        itemStyle: {
          shadowBlur: 10,
          shadowOffsetX: 0,
          shadowColor: 'rgba(0, 0, 0, 0.5)'
        }
      }
    }
  ]
}

export default {
  name: "Charts",
  data() {
    return {}
  },
  mounted() {  // 等待页面的元素全部加载完成之后再初始化

    // 折线图
    let linetDom = document.getElementById('line');
    let lineChart = echarts.init(linetDom);
    lineChart.setOption(option)

    // 柱状图
    let barDom = document.getElementById('bar');
    let barChart = echarts.init(barDom);
    barChart.setOption(option1)

    // 饼图
    let pieDom = document.getElementById('pie');
    let pieChart = echarts.init(pieDom);
    pieChart.setOption(option2)
  },
  methods: {}
}
</script>

<style scoped>

</style>

 

动态: 

 前端:创建charts.vue  显示统计图页面

<template>
  <div>
    <!-- 创建一个包含两个列的行,列之间有10px的间距 -->
    <el-row :gutter="10">
      <!-- 左侧的列,宽度为12个栅格 -->
      <el-col :span="12">
        <el-card>
          <!-- 用于显示折线图的容器,设置宽高 -->
          <div style="width: 100%; height: 400px" id="line"></div>
        </el-card>
      </el-col>
      <!-- 右侧的列,宽度为12个栅格 -->
      <el-col :span="12">
        <el-card>
          <!-- 用于显示柱状图的容器,设置宽高 -->
          <div style="width: 100%; height: 400px" id="bar"></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 创建一个包含一个列的行,列之间有10px的间距 -->
    <el-row :gutter="10" style="margin: 10px 0">
      <!-- 唯一的列,宽度为12个栅格 -->
      <el-col :span="12">
        <el-card>
          <!-- 用于显示饼图的容器,设置宽高 -->
          <div style="width: 100%; height: 400px" id="pie"></div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
// 导入 ECharts 库
import * as echarts from 'echarts';

// 定义折线图的配置选项
const option = {
  title: {
    text: '订单销售的趋势图', // 折线图的标题
    left: 'center' // 标题居中
  },
  tooltip: {
    trigger: 'axis' // 鼠标悬浮时显示的提示框,按坐标轴触发
  },
  legend: {
    left: 'left' // 图例放置在左侧
  },
  xAxis: {
    type: 'category', // 横轴为类目轴
    data: [] // 存放横轴数据的数组
  },
  yAxis: {
    type: 'value' // 纵轴为数值轴
  },
  series: [
    {
      name: '金额', // 系列名称
      data: [], // 存放数据的数组
      type: 'line', // 图表类型为折线图
      smooth: true // 平滑曲线
    },
  ]
}

// 定义柱状图的配置选项
const option1 = {
  title: {
    text: '订单销售的柱状图', // 柱状图的标题
    left: 'center' // 标题居中
  },
  tooltip: {
    trigger: 'axis' // 鼠标悬浮时显示的提示框,按坐标轴触发
  },
  legend: {
    left: 'left' // 图例放置在左侧
  },
  xAxis: {
    type: 'category', // 横轴为类目轴
    data: [] // 存放横轴数据的数组
  },
  yAxis: {
    type: 'value' // 纵轴为数值轴
  },
  series: [
    {
      name: '金额', // 系列名称
      data: [], // 存放数据的数组
      type: 'bar', // 图表类型为柱状图
      smooth: true // 平滑曲线(对于柱状图无实际效果)
    }
  ]
}

// 定义饼图的配置选项
const option2 = {
  title: {
    text: '订单销售统计', // 饼图的标题
    subtext: '比例图', // 饼图的副标题
    left: 'center' // 标题居中
  },
  tooltip: {
    trigger: 'item' // 鼠标悬浮时显示的提示框,按项目触发
  },
  legend: {
    orient: 'vertical', // 图例方向为垂直
    left: 'left' // 图例放置在左侧
  },
  series: [
    {
      name: '金额', // 系列名称
      type: 'pie', // 图表类型为饼图
      center: ['50%', '60%'], // 饼图中心位置
      radius: '50%', // 饼图半径
      data: [], // 存放数据的数组
      label: {
        show: true, // 显示标签
        formatter(param) {
          return param.name + ' (' + param.percent + '%)'; // 标签格式化
        }
      },
      emphasis: {
        itemStyle: {
          shadowBlur: 10, // 鼠标悬浮时的阴影模糊程度
          shadowOffsetX: 0, // 鼠标悬浮时的阴影横向偏移
          shadowColor: 'rgba(0, 0, 0, 0.5)' // 鼠标悬浮时的阴影颜色
        }
      }
    }
  ]
}

// 导出默认的 Vue 组件
export default {
  name: "Charts", // 组件名称
  data() {
    return {} // 返回的数据对象
  },
  mounted() {
    // 折线图的初始化
    let linetDom = document.getElementById('line'); // 获取折线图的 DOM 元素
    let lineChart = echarts.init(linetDom); // 初始化 ECharts 实例

    // 发送请求获取折线图的数据
    this.$request.get('/echarts/linecharts').then(res => {
      // 处理返回数据并设置到折线图的配置选项中
      option.xAxis.data = res.data?.line?.map(v => v.date) || []; // 设置横轴数据
      option.series[0].data = res.data?.line?.map(v => v.value) || []; // 设置纵轴数据
      lineChart.setOption(option); // 设置折线图的配置
    });

    // 柱状图的初始化
    let barDom = document.getElementById('bar'); // 获取柱状图的 DOM 元素
    let barChart = echarts.init(barDom); // 初始化 ECharts 实例
    barChart.setOption(option1); // 设置柱状图的配置

    // 发送请求获取柱状图的数据
    this.$request.get('/echarts/barcharts').then(res => {
      // 处理返回数据并设置到柱状图的配置选项中
      option1.xAxis.data = res.data?.bar?.map(v => v.name) || []; // 设置横轴数据
      option1.series[0].data = res.data?.bar?.map(v => v.value) || []; // 设置纵轴数据
      barChart.setOption(option1); // 设置柱状图的配置
    });

    // 饼图的初始化
    let pieDom = document.getElementById('pie'); // 获取饼图的 DOM 元素
    let pieChart = echarts.init(pieDom); // 初始化 ECharts 实例
    pieChart.setOption(option2); // 设置饼图的配置

    // 发送请求获取饼图的数据
    this.$request.get('/echarts/piecharts').then(res => {
      // 处理返回数据并设置到饼图的配置选项中
      option2.series[0].data = res.data?.bar || []; // 设置数据
      pieChart.setOption(option2); // 设置饼图的配置
    });
  },

  methods: {
    // 其他方法可以在这里定义
  }
}
</script>

代码结构说明

  1. 模板部分 (<template>)

    • 使用 el-row 和 el-col 组件来布局,包含三个图表:折线图、柱状图和饼图。
  2. 脚本部分 (<script>)

    • 导入 ECharts 库。
    • 定义不同类型图表的配置选项(折线图、柱状图和饼图)。
    • 在 mounted 钩子中初始化图表,并通过 API 请求填充数据。
    • 使用 this.$request.get 发送请求获取数据,并将数据更新到图表配置中。

后端:创建EchartsConteoller 前端页面的数据来源

@RestController // 标识该类为控制器,处理 HTTP 请求
@RequestMapping("/echarts") // 定义请求路径的前缀为 /echarts
public class EchartsController {

    @Resource // 自动注入 OrdersService 服务
    OrdersService ordersService;

    /**
     * 获取折线图的数据
     * @return 返回包含折线图数据的结果
     */
    @GetMapping("/linecharts") // 定义 GET 请求,路径为 /linecharts
    public Result LineCharts() {
        List<Orders> list = ordersService.list(); // 从服务中获取所有订单数据
        Set<String> dates = list.stream().map(Orders::getDate).collect(Collectors.toSet()); // 获取所有日期
        List<String> dateList = CollUtil.newArrayList(dates); // 将日期集合转为列表
        dateList.sort(Comparator.naturalOrder()); // 对日期进行自然顺序排序
        List<Dict> lineList = new ArrayList<>(); // 创建用于存放折线图数据的列表
        
        // 遍历所有日期,计算每个日期的订单总金额
        for (String date : dateList) {
            // 统计当前日期的所有金额总和
            BigDecimal sum = list.stream().filter(orders -> orders.getDate().equals(date)).map(Orders::getMoney)
                    .reduce(BigDecimal::add).orElse(BigDecimal.ZERO); // 计算总金额
            
            Dict dict = Dict.create(); // 创建一个字典对象
            Dict line = dict.set("date", date).set("value", sum); // 将日期和总金额存入字典
            lineList.add(line); // 将字典添加到折线图数据列表中
        }
        
        Dict res = Dict.create().set("line", lineList); // 创建结果字典,包含折线图数据
        return Result.success(res); // 返回成功的结果
    }

    /**
     * 获取柱状图的数据
     * @return 返回包含柱状图数据的结果
     */
    @GetMapping("/barcharts") // 定义 GET 请求,路径为 /barcharts
    public Result barCharts() {
        List<Orders> list = ordersService.list(); // 从服务中获取所有订单数据
        Set<String> dates = list.stream().map(Orders::getDate).collect(Collectors.toSet()); // 获取所有日期
        List<String> dateList = CollUtil.newArrayList(dates); // 将日期集合转为列表
        dateList.sort(Comparator.naturalOrder()); // 对日期进行自然顺序排序
        List<Dict> barList = new ArrayList<>(); // 创建用于存放柱状图数据的列表
        Set<String> categories = list.stream().map(Orders::getCategory).collect(Collectors.toSet()); // 获取所有分类
        
        // 遍历所有分类,计算每个分类的订单总金额
        for (String cate : categories) {
            // 统计当前分类的所有金额总和
            BigDecimal sum = list.stream().filter(orders -> orders.getCategory().equals(cate)).map(Orders::getMoney)
                    .reduce(BigDecimal::add).orElse(BigDecimal.ZERO); // 计算总金额
            
            Dict dict = Dict.create(); // 创建一个字典对象
            Dict bar = dict.set("name", cate).set("value", sum); // 将分类和总金额存入字典
            barList.add(bar); // 将字典添加到柱状图数据列表中
        }
        
        Dict res = Dict.create().set("bar", barList); // 创建结果字典,包含柱状图数据
        return Result.success(res); // 返回成功的结果
    }

    /**
     * 获取饼图的数据
     * @return 返回包含饼图数据的结果
     */
    @GetMapping("/piecharts") // 定义 GET 请求,路径为 /piecharts
    public Result pieCharts() {
        List<Orders> list = ordersService.list(); // 从服务中获取所有订单数据
        Set<String> dates = list.stream().map(Orders::getDate).collect(Collectors.toSet()); // 获取所有日期
        List<String> dateList = CollUtil.newArrayList(dates); // 将日期集合转为列表
        dateList.sort(Comparator.naturalOrder()); // 对日期进行自然顺序排序
        List<Dict> barList = new ArrayList<>(); // 创建用于存放饼图数据的列表
        Set<String> categories = list.stream().map(Orders::getCategory).collect(Collectors.toSet()); // 获取所有分类
        
        // 遍历所有分类,计算每个分类的订单总金额
        for (String cate : categories) {
            // 统计当前分类的所有金额总和
            BigDecimal sum = list.stream().filter(orders -> orders.getCategory().equals(cate)).map(Orders::getMoney)
                    .reduce(BigDecimal::add).orElse(BigDecimal.ZERO); // 计算总金额
            
            Dict dict = Dict.create(); // 创建一个字典对象
            Dict bar = dict.set("name", cate).set("value", sum); // 将分类和总金额存入字典
            barList.add(bar); // 将字典添加到饼图数据列表中
        }
        
        Dict res = Dict.create().set("bar", barList); // 创建结果字典,包含饼图数据
        return Result.success(res); // 返回成功的结果
    }
}

主要功能

  1. 折线图数据接口:计算每个日期的订单总金额,并以字典形式返回数据。
  2. 柱状图数据接口:计算每个分类的订单总金额,并以字典形式返回数据。
  3. 饼图数据接口:与柱状图接口相同,计算每个分类的订单总金额。

这些接口为前端的 Echarts 图表提供了所需的数据支持。以上为

 

订单管理页面

可以设计一个订单管理页面,用来对数据进行增删改查,并可以把数据返回给统计图,实时渲染我们想要的图表,这里我直接贴代码。

 

前端Orders.vue

<template>
<div>
        <div>
            <el-input style="width: 200px" placeholder="订单名称查询" v-model="name"></el-input>
            <el-input style="width: 200px" placeholder="购买人查询" v-model="userid"></el-input>
            <el-button type="primary" style="margin-left: 10px" @click="load(1)">查询</el-button>
            <el-button type="info" @click="reset">重置</el-button>
        </div>
        <div style="margin: 10px 0">
      <el-button type="primary" plain @click="handleAdd">新增</el-button>
      <el-button type="danger" plain @click="delBatch">批量删除</el-button>
    </div>
    <el-table :data="tableData" stripe :header-cell-style="{ backgroundColor: 'aliceblue', color: '#666' }" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center"></el-table-column>
        <el-table-column prop="id" label="序号" width="70" align="center"></el-table-column>
        <el-table-column prop="no" label="订单编号"></el-table-column>
        <el-table-column prop="name" label="订单名称"></el-table-column>
        <el-table-column prop="money" label="订单金额" show-overflow-tooltip></el-table-column>
        <el-table-column prop="user" label="用户"></el-table-column>
        <el-table-column prop="date" label="创建时间"></el-table-column>
        <el-table-column label="操作" align="center" width="180">
        <template v-slot="scope">
          <el-button size="mini" type="primary" plain @click="handleEdit(scope.row)">编辑</el-button>
          <el-button size="mini" type="danger" plain @click="del(scope.row.id)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <div style="margin: 10px 0">
      <el-pagination
          @current-change="handleCurrentChange"
          :current-page="pageNum"
          :page-size="pageSize"
          layout="total, prev, pager, next"
          :total="total">
      </el-pagination>
    </div>

    <el-dialog title="信息" :visible.sync="fromVisible" width="40%" :close-on-click-modal="false">
      <el-form :model="form" label-width="80px" style="padding-right: 20px"  :rules="rules" ref="formRef">
        <el-form-item label="订单名称" prop="name">
          <el-input v-model="form.name" placeholder="名称"></el-input>
        </el-form-item>
        <el-form-item label="订单金额" prop="money">
          <el-input v-model="form.money" placeholder="金额"></el-input>
        </el-form-item>
        <el-form-item label="分类" prop="category">
          <el-select style="width: 100%" v-model="form.category">
            <el-option v-for="item in ['水果', '蔬菜', '零食', '饮料', '奶制品', '糕点']" :key="item" :value="item"></el-option>
          </el-select>
        </el-form-item>
      </el-form>

      <div slot="footer" class="dialog-footer">
        <el-button @click="fromVisible = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>
</div>
</template>

<script>
    export default{
        name:'Orders',
        data(){
            return{
                tableData:[],
                user: JSON.parse(localStorage.getItem('userToken') || '{}'),
                pageNum: 1, 
                pageSize: 10,  
                username: '',
                name: '',
                userid:'',
                total: 0,
                fromVisible: false,
                form: {},
                ids: [],
                content: '',
                rules: {
                    name: [
                    { required: true, message: '请输入名称', trigger: 'blur' },
                    ],
                    money: [
                    { required: true, message: '请输入金额', trigger: 'blur' },
                    ],
                    category: [
                    { required: true, message: '请输入分类', trigger: 'blur' },
                    ]
        },
            }
        },
        created() {
                this.load()
        },
        methods:{
            handleEdit(row) {
                this.form = JSON.parse(JSON.stringify(row)) 
                this.fromVisible = true
            },
            del(id) {
                this.$confirm('您确认删除吗?', '确认删除', {type: "warning"}).then(response => {
                    this.$request.delete('/orders/delete/' + id).then(res => {
                    if (res.code === '200') {   // 表示操作成功
                        this.$message.success('操作成功')
                        this.load(1)
                        } else {
                            this.$message.error(res.msg)  // 弹出错误的信息
                    }})
                    }).catch(() => {})
    },
            delBatch(){
                if (!this.ids.length) {
                    this.$message.warning('请选择数据')
                    return
                }
                this.$confirm('您确认批量删除这些数据吗?', '确认删除', {type: "warning"}).then(response => {
                this.$request.delete('/orders/delete/batch', { data: this.ids }).then(res => {
                if (res.code === '200') {   // 表示操作成功
                    this.$message.success('操作成功')
                    this.load(1)
                } else {
                    this.$message.error(res.msg)  // 弹出错误的信息
                        }
                    })
                }).catch(() => {})
            },
            handleSelectionChange(rows) {   // 当前选中的所有的行数据
            this.ids = rows.map(v => v.id)
            },
            save(){
        // 保存按钮触发的逻辑  它会触发新增或者更新
            this.$refs.formRef.validate((valid) =>{
                if(valid){ this.sendSaveRequest() }
            })
            },
            sendSaveRequest(){
                this.$request({
                    url:this.form.id ? 'orders/update': '/orders/add',
                    method: this.form.id ? 'PUT' : 'POST',
                    data : this.form
                }).then(res =>{
                    if(res.code === '200'){
                        this.$message.success('保存成功')
                        this.load(1)
                        this.fromVisible = false
                    }else{
                        this.$message.error(res.msg)
                    }
                })
            },
            handleAdd(){
                this.form = {}  // 新增数据的时候清空数据
                this.fromVisible = true   // 打开弹窗
            },
            reset() {
                this.name = ''
                this.load()
            },
            load(pageNum){
                if (pageNum)  this.pageNum = pageNum
                this.$request.get('/orders/selectByPage',{
                    params:{
                        pageNum: this.pageNum,
                        pageSize: this.pageSize,
                        name: this.name
                    }
                }).then(res =>{
                    this.tableData = res.data.records
                    this.total = res.data.total
                })},
                handleCurrentChange(pageNum) {
                        this.load(pageNum)
                    },
            },
           
    }

</script>

<style scoped>

</style>

 后端OrdersController 

@RestController
@RequestMapping("/orders")
public class OrdersController {

    @Autowired
    OrdersService ordersService;
    @Autowired
    UserService userService;

    /**
     * 新增订单
     * @return
     */
    @PostMapping("add")
    public Result add(@RequestBody Orders orders){
        User currentUser = TokenUtils.getCurrentUser();
        orders.setUserid(currentUser.getId());
        orders.setDate(DateUtil.today());
        orders.setNo(IdUtil.fastSimpleUUID());
        ordersService.save(orders);
        return Result.success();
    }

    /**
     * 修改信息
     */

    @PutMapping("/update")
    public Result update(@RequestBody Orders orders) {
        ordersService.updateById(orders);
        return Result.success();
    }

    /**
     * 删除信息
     * @param id
     * @return
     */
    @DeleteMapping("/delete/{id}")
    public Result delete(@PathVariable Integer id) {
        ordersService.removeById(id);
        return Result.success();
    }

    /**
     * 批量删除信息
     * @param ids
     * @return
     */
    @DeleteMapping("/delete/batch")
    public Result batchDelete(@RequestBody List<Integer> ids) {
        ordersService.removeByIds(ids);
        return Result.success();
    }
    /**
     * 查询全部信息
     */
    @GetMapping("/selectAll")
    public Result selectAll() {
        List<Orders> ordersList = ordersService.list(new QueryWrapper<Orders>().orderByDesc("id"));
        return Result.success(ordersList);
    }

    /**
     * 分页查询
     * @param pageNum
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/selectByPage")
    public Result selectByPage(@RequestParam Integer pageNum,
                               @RequestParam Integer pageSize,
                               @RequestParam String name) {
        QueryWrapper<Orders> queryWrapper  = new QueryWrapper<Orders>().orderByDesc("id");
        queryWrapper.like(StrUtil.isNotBlank(name),"name",name);
        Page<Orders> page = ordersService.page(new Page<>(pageNum, pageSize), queryWrapper);
        List<Orders> records = page.getRecords();
        for(Orders record : records){
            Integer authorid = record.getUserid();
            User user = userService.getById(authorid);
            if(user != null){
                record.setUser(user.getUsername());
            }
        }
        return Result.success(page);
    }

}

 订单数据库代码

CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单编号',
  `name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单名称',
  `money` decimal(10,2) DEFAULT NULL COMMENT '订单金额',
  `userid` int(11) DEFAULT NULL COMMENT '用户ID',
  `category` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单分类',
  `date` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '订单日期',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='订单表';

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

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

相关文章

粉碎玉米的机器:水滴式饲料粉碎机

水滴式饲料粉碎机的主要工作原理是利用高速旋转的锤片将饲料原料进行粉碎&#xff0c;同时将粉碎后的饲料颗粒进行搅拌和混合。这种设备结构紧凑、操作简单、维护方便&#xff0c;可以满足不同养殖场的需求。 水滴式粉碎机特点&#xff1a; 水滴式粉碎机是一款高效、多功能的机…

无人机之飞行算法篇

无人机的飞行算法是一个复杂而精细的系统&#xff0c;它涵盖了多个关键技术和算法&#xff0c;以确保无人机能够稳定、准确地执行飞行任务。 一、位置估计 无人机在空中飞行过程中需要实时获取其位置信息&#xff0c;以便进行路径规划和控制。这通常通过以下传感器实现&#…

(计算机毕设)基于Vue和Spring Boot的宠物救助网站设计与实现

博主可接毕设&#xff01;&#xff01;&#xff01; 毕业设计&#xff08;论文&#xff09; 基于Vue和Spring Boot的宠物救助网站设计与实现 摘 要 随着中国互联网的迅猛发展&#xff0c;传统宠物救助领域面临着信息管理繁琐、辐射范围有限、信息传播受限、丢失宠物找回几率较…

PAT甲级-1004 Counting Leaves

题目 题目大意 给定一棵树&#xff0c;每个节点从01到n编号&#xff0c;规定01为根节点&#xff0c;求每层叶子节点的个数。 思路 用二维数组存储树。每层叶子节点的个数&#xff0c;只能用dfs深度遍历&#xff0c;用一个数组存储所有层数的叶子节点个数。相同层数并且是叶子…

蓝桥杯—STM32G431RBT6(IIC通信--EEPROM(AT24C02)存储器进行通信)

一、什么是IIC&#xff1f;24C02存储器有什么用&#xff1f; IIC &#xff08;IIC 是半双工通信总线。半双工意味着数据在某一时刻只能沿一个方向传输&#xff0c;即发送数据的时候不能接收数据&#xff0c;接收数据的时候不能发送数据&#xff09;即集成电路总线&#xff08;…

力扣hot100--链表

链表 1. 2. 两数相加 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff…

不知道是你的损失,盘点8个可能被忽略的极空间宝藏功能与使用技巧

不知道是你的损失&#xff0c;盘点8个可能被忽略的极空间宝藏功能与使用技巧 哈喽小伙伴们好&#xff0c;我是Stark-C~ 极空间作为后起之秀的新势力NAS&#xff0c;它的产品不管是做工、性能、用户体验等方面都表现非常出色&#xff0c;它独家搭载的ZOS系统不管是功能性还是可…

计算机毕业设计 基于Python的食品销售数据分析系统的设计与实现 Python毕业设计 Python毕业设计选题 数据分析 Vue【附源码+安装调试】

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

easyconnect配置wireshark抓包

文章目录 概述过程配置Wireshark抓包 概述 过程 配置Wireshark抓包 首先需要配置虚拟网卡SangforVPN可被Wireshark识别 重启 sc stop npcap sc start npcap# 清空路由表 netsh int ipv4 reset # 查看路由表 route print

自动化测试 | XPath的使用和CSS选择器的使用

XPath的使用 1.在谷歌浏览器中&#xff0c;按F12后&#xff0c;点击Elements。然后按CtrlF&#xff0c;出现搜索框&#xff0c;输入定位字符串后&#xff0c;会提示与定位字符串匹配的元素。 小技巧&#xff1a; 在谷歌浏览器里面可以点中你选择的元素标签&#xff0c;然后右…

反向旅游、住国宾馆,这届年轻人变了

“假期怎么过那么快啊&#xff0c;一转眼就没有了。”Cloe在群里疯狂地吐槽着。“刚从景点回来&#xff0c;还没缓缓呢&#xff0c;就要开始上班了。” 旅游已然成为了现在每个假期的必备课题。 据携程发布的《2024年国庆旅游消费报告》显示&#xff0c;国庆假期&#xff0c;…

Chromium 如何查找前端 Browser, Screen等对象定义在c++中的实现

以前端Navigator 对象为例&#xff1a; 1、直接在vscode里面搜索"Navigator" 过滤条件*.idl&#xff0c;这样可以搜到Navigator.idl对象文件。 2、打开Navigator.idl 可以看到平级目录对应的Navigator.h 和Navigator.cc定义 3、Navigator.idl会在out\Debug\gen\thir…

10到16bit、内置参考振荡器 R/D转换器-MS5910PA

MS5910PA 是一款可配置 10bit 到 16bit 分辨率的旋 变数字转换器。片上集成正弦波激励电路&#xff0c;正弦和余弦 允许输入峰峰值幅度为 2.3V 到 4.0V &#xff0c;频率范围为 2kHz 至 20kHz 。 转换器可并行或串行输出角度和速度对应的 数字量。 MS5910PA 采…

银河麒麟V10安装ToDesk远程控制

银河麒麟V10安装ToDesk远程控制 ARM版本安装 1.下载arm的deb包 wget https://dl.todesk.com/linux/todesk_4.0.3_aarch64.deb2.安装 sudo apt-get install ./todesk_4.0.3_aarch64.deb3.启动todesk todesk

PCI支付卡产业第三方服务供应商TPSP的管理与实践

1.引言 在这个互联网技术日新月异的时代&#xff0c;云服务的普及让机构&#xff08;实体&#xff09;越来越倾向于借助第三方服务提供商来实现核心业务流程的外包&#xff0c;比如基础设施即服务&#xff08;IaaS: Infrastructure as a Service&#xff09;、平台即服务&…

【C语言】指针和数组的内存使用详解

目录 一、sizeof操作符 二、一维数组的练习 三、字符数组的练习 四、字符串数组 五、指针指向字符串 六、二维数组 一、sizeof操作符 在深入学习指针和数组的内存使用详情前&#xff0c;我们需要深入了解一下sizeof操作符的使用 1.1 sizeof操作符是计算括号内最终结果的…

python中zip()与zip(*)的用法解析

zip在英文中有拉链的意思&#xff0c;我们由此可以形象的理解它的作用&#xff1a;将可迭代的对象作为参数&#xff0c;将对象中对应的元素打包成一个个元组&#xff0c;然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致&#xff0c;则返回列表长度与最短的对象相…

Sharding-JDBC笔记04-分库分表实战

文章目录 前言一、需求描述二、数据库设计三、环境说明四、环境准备4.1.mysql主从同步(windows)4.2.初始化数据库 五、实现步骤5.1 搭建maven工程引入maven依赖 5.2 实体类5.3 dao层5.4 服务类5.5 测试类总结 5.6 查询商品DaoService单元测试输出小结 5.7 统计商品Dao单元测试统…

力扣 中等 46.全排列

文章目录 题目介绍题解 题目介绍 题解 代码如下&#xff1a; class Solution {List<List<Integer>> res new ArrayList<>();// 存放符合条件结果的集合List<Integer> path new ArrayList<>();// 用来存放符合条件结果boolean[] used; // 标记…

计算机毕业设计 基于Django的在线考试系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…