day09_商品管理订单管理SpringTaskEcharts

文章目录

  • 1 商品管理
    • 1.1 添加功能
      • 1.1.1 需求说明
      • 1.1.2 核心概念
        • SPU
        • SKU
      • 1.1.3 加载品牌数据
        • CategoryBrandController
        • CategoryBrandService
        • CategoryBrandMapper
        • CategoryBrandMapper.xml
      • 1.1.4 加载商品单元数据
        • ProductUnit
        • ProductUnitController
        • ProductUnitService
        • ProductUnitMapper
        • ProductUnitMapper.xml
      • 1.1.5 加载商品规格数据
        • ProductSpecController
        • ProductSpecService
        • ProductSpecMapper
        • ProductSpecMapper.xml
      • 1.1.6 保存商品数据接口
        • 思路分析
        • Product
        • ProductSku
        • ProductDetails
        • ProductController
        • ProductService
        • ProductMapper
        • ProductMapper.xml
        • ProductSkuMapper
        • ProductSkuMapper.xml
        • ProductDetailsMapper
        • ProductDetailsMapper.xml
    • 1.2 修改功能
      • 1.2.1 需求说明
      • 1.2.2 查询商品详情
        • ProductController
        • ProductService
        • ProductMapper
        • ProductMapper.xml
        • ProductSkuMapper
        • ProductSkuMapper.xml
        • ProductDetailsMapper
        • ProductDetailsMapper.xml
      • 1.2.3 保存修改数据接口
        • ProductController
        • ProductService
        • ProductMapper
        • ProductMapper.xml
        • ProductSkuMapper
        • ProductSkuMapper.xml
        • ProductDetailsMapper
        • ProductDetailsMapper.xml
    • 1.3 删除商品
      • 1.3.1 需求说明
      • 1.3.2 后端接口
        • ProductController
        • ProductService
        • ProductMapper
        • ProductMapper.xml
        • ProductSkuMapper
        • ProductSkuMapper.xml
        • ProductDetailsMapper
        • ProductDetailsMapper.xml
    • 1.4 商品审核
      • 1.4.1 需求说明
      • 1.4.2 后端接口
        • ProductController
        • ProductService
    • 1.5 商品上下架
      • 1.5.1 需求说明
      • 1.5.2 后端接口
        • ProductController
        • ProductService
  • 2 订单管理
    • 2.1 订单数据统计需求说明
    • 2.2 Echarts
      • 2.2.1 Echarts简介
      • 2.2.2 Echarts入门
    • 2.3 订单相关数据库表介绍
    • 2.4 订单数据统计实现思路
    • 2.5 Spring Task
      • 2.5.1 Spring Task简介
      • 2.5.2 Spring Task入门案例
      • 2.5.3 cron表达式
    • 2.6 订单数据统计
      • 2.6.1 数据库表介绍
      • 2.6.3 代码实现
        • OrderStatistics
        • OrderInfo
        • OrderStatisticsTask
        • OrderInfoMapper
        • OrderInfoMapper.xml
        • OrderStatisticsMapper
        • OrderStatisticsMapper.xml
    • 2.7 统计查询
      • 2.7.1 后端接口
        • OrderStatisticsDto
        • OrderStatisticsVo
        • OrderInfoController
        • OrderInfoService
        • OrderStatisticsMapper
        • OrderStatisticsMapper.xml
      • 2.7.2 前端对接

1 商品管理

商品管理就是对电商项目中所涉及到的商品数据进行维护。

1.1 添加功能

1.1.1 需求说明

当用户点击添加按钮的时候,那么此时就弹出对话框,在该对话框中需要展示添加商品的表单。当用户在该表单中点击提交按钮的时候那么此时就需要将表单进行提交,在后端需要将提交过来的表单数据保存到数据库中即可。

如下所示:

在这里插入图片描述

1.1.2 核心概念

在完成商品添加功能之前,必须先要了解电商系统中常见的两个核心的概念。

SPU

SPU = Standard Product Unit (标准化产品单元), SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合,该集合描述了一个产品的特性。通俗点讲就是泛指一类商品,这种商品具有相同的属性。

SKU

SKU = stock keeping unit(库存量单位) SKU即库存进出计量的单位(买家购买、商家进货、供应商备货、工厂生产都是依据SKU进行的)。是和具体的属性值有直接的关联关系。SKU是物理上不可分割的最小存货单元。也就是说一款商品,可以根据SKU来确定具体的货物存量。

以手机为例,假设有一款名为 “XPhone” 的手机品牌,它推出了一款型号为 “X10” 的手机。这款手机一共有以下几种属性:

1、颜色:黑色、白色、金色

2、存储容量:64GB、128GB

3、内存大小:4GB、6GB

那么,“X10” 这款手机就是这个商品的 SPU,它包含所有属性。而根据不同的属性组合,可以形成多个不同的 SKU。如下所示:

SPUSKU颜色存储容量内存大小
X10SKU1黑色64GB4GB
X10SKU2白色64GB4GB
X10SKU3金色64GB4GB
X10SKU4黑色128GB4GB
X10SKU5白色128GB4GB
X10SKU6金色128GB4GB
X10SKU7黑色64GB6GB
X10SKU8白色64GB6GB
X10SKU9金色64GB6GB
X10SKU10黑色128GB6GB
X10SKU11白色128GB6GB
X10SKU12金色128GB6GB

再以衣服为例,假设有一家服装网店推出了一款名为 “A衬衫” 的衣服。这款衣服一共有以下几种属性:

1、尺寸:S、M、L、XL

2、颜色:白色、黑色、灰色、蓝色

那么,“A衬衫” 这款衣服就是这个商品的 SPU,它包含所有属性。而根据不同的属性组合,可以形成多个不同的 SKU。如下所示:

SPUSKU尺寸颜色
A衬衫SKU1S白色
A衬衫SKU2M白色
A衬衫SKU3L白色
A衬衫SKU4XL白色
A衬衫SKU5S黑色
A衬衫SKU6M黑色
A衬衫SKU7L黑色
A衬衫SKU8XL黑色
A衬衫SKU9S灰色
A衬衫SKU10M灰色
A衬衫SKU11L灰色
A衬衫SKU12XL灰色
A衬衫SKU13S蓝色
A衬衫SKU14M蓝色
A衬衫SKU15L蓝色
A衬衫SKU16XL蓝色

1.1.3 加载品牌数据

需求:当用户选择了三级分类以后,此时需要将三级分类所对应的品牌数据查询出来在品牌下拉框中进行展示

CategoryBrandController

表现层代码实现:

// com.atguigu.spzx.manager.controller
@GetMapping("/findBrandByCategoryId/{categoryId}")
public Result findBrandByCategoryId(@PathVariable Long categoryId) {List<Brand> brandList =   categoryBrandService.findBrandByCategoryId(categoryId);return Result.build(brandList , ResultCodeEnum.SUCCESS) ;
}
CategoryBrandService

业务层代码实现:

// com.atguigu.spzx.manager.service.impl
@Override
public List<Brand> findBrandByCategoryId(Long categoryId) {return categoryBrandMapper.findBrandByCategoryId(categoryId);
}
CategoryBrandMapper

持久层代码实现:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface CategoryBrandMapper {public abstract List<Brand> findBrandByCategoryId(Long categoryId);
}
CategoryBrandMapper.xml

在CategoryBrandMapper.xml映射文件中添加如下sql语句:

<resultMap id="brandMap" type="com.atguigu.spzx.model.entity.product.Brand" autoMapping="true"></resultMap>
<select id="findBrandByCategoryId" resultMap="brandMap">selectb.*from category_brand cbleft join brand b  on b.id = cb.brand_idwhere cb.category_id = #{categoryId} and cb.is_deleted = 0order by cb.id desc
</select>

1.1.4 加载商品单元数据

需求:当添加商品的表单对话框展示出来以后,此时就需要从数据库中查询出来所有的商品单元数据,并将查询到的商品单元数据在商品单元下拉框中进行展示。

ProductUnit
//com.atguigu.spzx.model.entity.product@Data
public class ProductUnit extends BaseEntity {private String name;
}
ProductUnitController

表现层代码实现:

// com.atguigu.spzx.manager.controller
@GetMapping("findAll")
public Result<List<ProductUnit>> findAll() {List<ProductUnit> productUnitList = productUnitService.findAll();return Result.build(productUnitList , ResultCodeEnum.SUCCESS) ;
}
ProductUnitService

业务层代码实现:

// com.atguigu.spzx.manager.service.impl
@Override
public List<ProductUnit> findAll() {return productUnitMapper.findAll() ;
}
ProductUnitMapper

持久层代码实现:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface ProductUnitMapper {public abstract List<ProductUnit> findAll();
}
ProductUnitMapper.xml

在ProductUnitMapper.xml映射文件中添加如下的sql语句:

<select id="findAll" resultMap="productUnitMap">select <include refid="columns" />from product_unitwhere is_deleted = 0order by id
</select>

1.1.5 加载商品规格数据

需求:当添加商品的表单对话框展示出来以后,此时就需要从数据库中查询出来所有的商品规格数据,并将查询到的商品规格数据在商品规格下拉框中进行展示。

ProductSpecController

表现层代码实现:

// com.atguigu.spzx.manager.controller
@GetMapping("findAll")
public Result findAll() {List<ProductSpec> list = productSpecService.findAll();return Result.build(list , ResultCodeEnum.SUCCESS) ;
}
ProductSpecService

业务层代码实现:

// com.atguigu.spzx.manager.service.impl;
@Override
public List<ProductSpec> findAll() {return productSpecMapper.findAll();;
}
ProductSpecMapper

持久层代码实现:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface ProductSpecMapper {public abstract List<ProductSpec> findAll();
}
ProductSpecMapper.xml

在ProductSpecMapper.xml映射文件中添加如下sql语句:

<select id="findAll" resultMap="productSpecMap">select <include refid="columns" />from product_specorder by id desc
</select>

1.1.6 保存商品数据接口

思路分析

思路分析:

1、前端提交过来的数据,包含了SPU的基本数据,SKU的列表数据,商品详情数据

2、后端可以直接使用Product接收请求参数,但是需要扩展对应的属性

3、保存数据的时候需要操作三张表:product、product_sku、product_detail

Product

修改Product实体类,添加接收sku列表和商品详情的属性,如下所示:

// com.atguigu.spzx.model.entity.product;
@Data
public class Product extends BaseEntity {private String name;					// 商品名称private Long brandId;					// 品牌IDprivate Long category1Id;				// 一级分类idprivate Long category2Id;				// 二级分类idprivate Long category3Id;				// 三级分类idprivate String unitName;				// 计量单位private String sliderUrls;				// 轮播图private String specValue;				// 商品规格值json串private Integer status;					// 线上状态:0-初始值,1-上架,-1-自主下架private Integer auditStatus;			// 审核状态private String auditMessage;			// 审核信息// 扩展的属性,用来封装响应的数据private String brandName;				// 品牌private String category1Name;			// 一级分类private String category2Name;			// 二级分类private String category3Name;			// 三级分类private List<ProductSku> productSkuList;		// sku列表集合private String detailsImageUrls;				// 图片详情列表}
ProductSku

商品sku实体类定义:

// com.atguigu.spzx.model.entity.product;
@Data
public class ProductSku extends BaseEntity { private String skuCode;private String skuName;private Long productId;private String thumbImg;private BigDecimal salePrice;private BigDecimal marketPrice;private BigDecimal costPrice;private Integer stockNum;private Integer saleNum;private String skuSpec;private String weight;private String volume;private Integer status;}
ProductDetails

商品详情实体类:

// com.atguigu.spzx.model.entity.product;
@Data
public class ProductDetails extends BaseEntity {private Long productId;private String imageUrls;}
ProductController

表现层代码:

// com.atguigu.spzx.manager.controller;
@PostMapping("/save")
public Result save(@RequestBody Product product) {productService.save(product);return Result.build(null , ResultCodeEnum.SUCCESS) ;
}
ProductService

业务层代码:

// com.atguigu.spzx.manager.service.impl;
@Transactional
@Override
public void save(Product product) {// 保存商品数据product.setStatus(0);              // 设置上架状态为0product.setAuditStatus(0);         // 设置审核状态为0productMapper.save(product);// 保存商品sku数据List<ProductSku> productSkuList = product.getProductSkuList();for(int i=0,size=productSkuList.size(); i<size; i++) {// 获取ProductSku对象ProductSku productSku = productSkuList.get(i);productSku.setSkuCode(product.getId() + "_" + i);       // 构建skuCodeproductSku.setProductId(product.getId());               // 设置商品idproductSku.setSkuName(product.getName() + productSku.getSkuSpec());productSku.setSaleNum(0);                               // 设置销量productSku.setStatus(0);productSkuMapper.save(productSku);                    // 保存数据}// 保存商品详情数据ProductDetails productDetails = new ProductDetails();productDetails.setProductId(product.getId());productDetails.setImageUrls(product.getDetailsImageUrls());productDetailsMapper.save(productDetails);}
ProductMapper

商品持久层代码:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface ProductMapper {public abstract void save(Product product);
}
ProductMapper.xml

在ProductMapper.xml文件中添加如下的SQL语句:

<insert id="save" useGeneratedKeys="true" keyProperty="id">insert into product (id,name,brand_id,category1_id,category2_id,category3_id,unit_name,slider_urls,spec_value,status,audit_status,audit_message,create_time,update_time,is_deleted) values (#{id},#{name},#{brandId},#{category1Id},#{category2Id},#{category3Id},#{unitName},#{sliderUrls},#{specValue},#{status},#{auditStatus},#{auditMessage},now(),now() ,0)
</insert>
ProductSkuMapper

商品SKU的持久层代码:

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface ProductSkuMapper {public abstract void save(ProductSku productSku);
}
ProductSkuMapper.xml

在ProductSkuMapper.xml映射文件中添加如下的SQL语句:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.spzx.manager.mapper.ProductSkuMapper"><insert id="save" useGeneratedKeys="true" keyProperty="id">insert into product_sku (id,sku_code,sku_name,product_id,thumb_img,sale_price,market_price,cost_price,stock_num,sku_spec,weight,volume,status,sale_num,create_time,update_time,is_deleted) values (#{id},#{skuCode},#{skuName},#{productId},#{thumbImg},#{salePrice},#{marketPrice},#{costPrice},#{stockNum},#{skuSpec},#{weight},#{volume},#{status},#{saleNum},now(),now(),0)</insert></mapper>
ProductDetailsMapper

商品详情的持久层代码:

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface ProductDetailsMapper {public abstract void save(ProductDetails productDetails);
}
ProductDetailsMapper.xml

在ProductDetailsMapper.xml映射文件中添加如下的SQL语句:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.spzx.manager.mapper.ProductDetailsMapper"><insert id="save" useGeneratedKeys="true" keyProperty="id">insert into product_details (id,product_id,image_urls,create_time,update_time,is_deleted) values (#{id},#{productId},#{imageUrls},now(),now(),0)</insert></mapper>

1.2 修改功能

1.2.1 需求说明

当用户点击修改按钮的时候,那么此时就弹出对话框,在该对话框的商品表单中回显商品相关数据,此时用户对商品数据进行修改,修改完毕以后点击

提交按钮将表单进行提交,后端服务修改数据库中数据即可。

效果如下所示:

在这里插入图片描述

修改功能实现的时候需要开发两个接口:

1、根据id查询商品详情

2、保存修改数据接口

1.2.2 查询商品详情

ProductController

表现层代码:

// com.atguigu.spzx.manager.controller;
@GetMapping("/getById/{id}")
public Result<Product> getById(@PathVariable Long id) {Product product = productService.getById(id);return Result.build(product , ResultCodeEnum.SUCCESS) ;
}
ProductService

业务层代码:

// com.atguigu.spzx.manager.service.impl;
@Override
public Product getById(Long id) {// 根据id查询商品数据Product product = productMapper.selectById(id);// 根据商品的id查询sku数据List<ProductSku> productSkuList = productSkuMapper.selectByProductId(id);product.setProductSkuList(productSkuList);// 根据商品的id查询商品详情数据ProductDetails productDetails = productDetailsMapper.selectByProductId(product.getId());product.setDetailsImageUrls(productDetails.getImageUrls());// 返回数据return product;
}
ProductMapper

商品持久层代码:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface ProductMapper {public abstract Product selectById(Long id);
}
ProductMapper.xml

在ProductMapper.xml文件中添加如下的SQL语句:

<select id="selectById" resultMap="productMap">selectp.id, p.name , p.brand_id , p.category1_id , p.category2_id , p.category3_id, p.unit_name,p.slider_urls , p.spec_value , p.status , p.audit_status , p.audit_message , p.create_time , p.update_time , p.is_deleted ,b.name brandName , c1.name category1Name , c2.name category2Name , c2.name category3Namefrom product pLEFT JOIN brand b on b.id = p.brand_idLEFT JOIN category c1 on c1.id = p.category1_idLEFT JOIN category c2 on c2.id = p.category2_idLEFT JOIN category c3 on c3.id = p.category2_idwherep.id = #{id}
</select>
ProductSkuMapper

商品SKU的持久层代码:

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface ProductSkuMapper {public abstract List<ProductSku> selectByProductId(Long id);
}
ProductSkuMapper.xml

在ProductSkuMapper.xml映射文件中添加如下的SQL语句:

<resultMap id="productSkuMap" type="com.atguigu.spzx.model.entity.product.ProductSku" autoMapping="true"></resultMap><!-- 用于select查询公用抽取的列 -->
<sql id="columns">id,sku_code,sku_name,product_id,thumb_img,sale_price,market_price,cost_price,stock_num,sku_spec,weight,volume,status,create_time,update_time,is_deleted
</sql><select id="selectByProductId" resultMap="productSkuMap">select <include refid="columns" />from product_skuwhere product_id = #{productId}and is_deleted = 0order by id desc
</select>
ProductDetailsMapper

商品详情的持久层代码:

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface ProductDetailsMapper {public abstract ProductDetails selectByProductId(Long id);
}
ProductDetailsMapper.xml

在ProductDetailsMapper.xml映射文件中添加如下的SQL语句:

<resultMap id="productDetailsMap" type="com.atguigu.spzx.model.entity.product.ProductDetails" autoMapping="true"></resultMap><!-- 用于select查询公用抽取的列 -->
<sql id="columns">id,product_id,image_urls,create_time,update_time,is_deleted
</sql><select id="selectByProductId" resultMap="productDetailsMap">select <include refid="columns" />from product_detailswhereproduct_id = #{productId}
</select>

1.2.3 保存修改数据接口

ProductController

表现层代码:

// com.atguigu.spzx.manager.controller;
@PutMapping("/updateById")
public Result updateById(@Parameter(name = "product", description = "请求参数实体类", required = true) @RequestBody Product product) {productService.updateById(product);return Result.build(null , ResultCodeEnum.SUCCESS) ;
}
ProductService

业务层代码:

// com.atguigu.spzx.manager.service.impl;
@Transactional
@Override
public void updateById(Product product) {// 修改商品基本数据productMapper.updateById(product);// 修改商品的sku数据List<ProductSku> productSkuList = product.getProductSkuList();productSkuList.forEach(productSku -> {productSkuMapper.updateById(productSku);});// 修改商品的详情数据ProductDetails productDetails = productDetailsMapper.selectByProductId(product.getId());productDetails.setImageUrls(product.getDetailsImageUrls());productDetailsMapper.updateById(productDetails);}
ProductMapper

商品持久层代码:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface ProductMapper {public abstract  void updateById(Product product);
}
ProductMapper.xml

在ProductMapper.xml文件中添加如下的SQL语句:

<update id="updateById" >update product set<if test="name != null and name != ''">name = #{name},</if><if test="brandId != null and brandId != ''">brand_id = #{brandId},</if><if test="category1Id != null and category1Id != ''">category1_id = #{category1Id},</if><if test="category2Id != null and category2Id != ''">category2_id = #{category2Id},</if><if test="category3Id != null and category3Id != ''">category3_id = #{category3Id},</if><if test="unitName != null and unitName != ''">unit_name = #{unitName},</if><if test="sliderUrls != null and sliderUrls != ''">slider_urls = #{sliderUrls},</if><if test="specValue != null and specValue != ''">spec_value = #{specValue},</if><if test="status != null and status != ''">status = #{status},</if><if test="auditStatus != null and auditStatus != ''">audit_status = #{auditStatus},</if><if test="auditMessage != null and auditMessage != ''">audit_message = #{auditMessage},</if>update_time =  now()whereid = #{id}
</update>
ProductSkuMapper

商品SKU的持久层代码:

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface ProductSkuMapper {public abstract  void updateById(ProductSku productSku);
}
ProductSkuMapper.xml

在ProductSkuMapper.xml映射文件中添加如下的SQL语句:

<update id="updateById" >update product_sku set<if test="skuCode != null and skuCode != ''">sku_code = #{skuCode},</if><if test="skuName != null and skuName != ''">sku_name = #{skuName},</if><if test="productId != null and productId != ''">product_id = #{productId},</if><if test="thumbImg != null and thumbImg != ''">thumb_img = #{thumbImg},</if><if test="salePrice != null and salePrice != ''">sale_price = #{salePrice},</if><if test="marketPrice != null and marketPrice != ''">market_price = #{marketPrice},</if><if test="costPrice != null and costPrice != ''">cost_price = #{costPrice},</if><if test="stockNum != null and stockNum != ''">stock_num = #{stockNum},</if><if test="skuSpec != null and skuSpec != ''">sku_spec = #{skuSpec},</if><if test="weight != null and weight != ''">weight = #{weight},</if><if test="volume != null and volume != ''">volume = #{volume},</if><if test="status != null and status != ''">status = #{status},</if>update_time =  now()whereid = #{id}
</update>
ProductDetailsMapper

商品详情的持久层代码:

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface ProductDetailsMapper {public abstract void updateById(ProductDetails productDetails);
}
ProductDetailsMapper.xml

在ProductDetailsMapper.xml映射文件中添加如下的SQL语句:

<update id="updateById" >update product_details set<if test="productId != null and productId != ''">product_id = #{productId},</if><if test="imageUrls != null and imageUrls != ''">image_urls = #{imageUrls},</if>update_time =  now()whereid = #{id}
</update>

1.3 删除商品

1.3.1 需求说明

当点击删除按钮的时候此时需要弹出一个提示框,询问是否需要删除数据?如果用户点击是,那么此时向后端发送请求传递id参数,后端接收id参数进

行逻辑删除。

效果如下所示:

在这里插入图片描述

1.3.2 后端接口

ProductController

表现层代码:

// com.atguigu.spzx.manager.controller;
@DeleteMapping("/deleteById/{id}")
public Result deleteById(@Parameter(name = "id", description = "商品id", required = true) @PathVariable Long id) {productService.deleteById(id);return Result.build(null , ResultCodeEnum.SUCCESS) ;
}
ProductService

业务层代码:

// com.atguigu.spzx.manager.service.impl;
@Transactional
@Override
public void deleteById(Long id) {productMapper.deleteById(id);                   // 根据id删除商品基本数据productSkuMapper.deleteByProductId(id);         // 根据商品id删除商品的sku数据productDetailsMapper.deleteByProductId(id);     // 根据商品的id删除商品的详情数据
}
ProductMapper

商品持久层代码:

// com.atguigu.spzx.manager.mapper
@Mapper
public interface ProductMapper {public abstract void deleteById(Long id);
}
ProductMapper.xml

在ProductMapper.xml文件中添加如下的SQL语句:

<update id="deleteById">update product setupdate_time = now() ,is_deleted = 1whereid = #{id}
</update>
ProductSkuMapper

商品SKU的持久层代码:

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface ProductSkuMapper {public abstract void deleteByProductId(Long id);
}
ProductSkuMapper.xml

在ProductSkuMapper.xml映射文件中添加如下的SQL语句:

<update id="deleteByProductId">update product_sku setupdate_time = now() ,is_deleted = 1whereproduct_id = #{productId}
</update>
ProductDetailsMapper

商品详情的持久层代码:

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface ProductDetailsMapper {public abstract void deleteByProductId(Long id);
}
ProductDetailsMapper.xml

在ProductDetailsMapper.xml映射文件中添加如下的SQL语句:

<update id="deleteByProductId">update product_details setupdate_time = now() ,is_deleted = 1whereproduct_id = #{productId}
</update>

1.4 商品审核

1.4.1 需求说明

当点击审核按钮的时候此时需要弹出一个对话框,在该对话框中展示商品的详情信息,用户可以在该对话框中点击通过或者驳回按钮对商品进行审核操

作。

效果如下所示:

在这里插入图片描述

1.4.2 后端接口

ProductController

表现层代码:

// com.atguigu.spzx.manager.controller;
@GetMapping("/updateAuditStatus/{id}/{auditStatus}")
public Result updateAuditStatus(@PathVariable Long id, @PathVariable Integer auditStatus) {productService.updateAuditStatus(id, auditStatus);return Result.build(null , ResultCodeEnum.SUCCESS) ;
}
ProductService

业务层代码:

// com.atguigu.spzx.manager.service.impl;
@Override
public void updateAuditStatus(Long id, Integer auditStatus) {Product product = new Product();product.setId(id);if(auditStatus == 1) {product.setAuditStatus(1);product.setAuditMessage("审批通过");} else {product.setAuditStatus(-1);product.setAuditMessage("审批不通过");}productMapper.updateById(product);
}

1.5 商品上下架

1.5.1 需求说明

当用户点击上架按钮的时候对商品进行上架操作,点击下架按钮的时候对商品进行下架操作。

实现思路:更改商品的上下架状态

效果如下所示:

在这里插入图片描述

1.5.2 后端接口

ProductController

表现层代码:

// com.atguigu.spzx.manager.controller;
@GetMapping("/updateStatus/{id}/{status}")
public Result updateStatus(@PathVariable Long id, @PathVariable Integer status) {productService.updateStatus(id, status);return Result.build(null , ResultCodeEnum.SUCCESS) ;
}
ProductService

业务层代码:

// com.atguigu.spzx.manager.service.impl;
@Override
public void updateStatus(Long id, Integer status) {Product product = new Product();product.setId(id);if(status == 1) {product.setStatus(1);} else {product.setStatus(-1);}productMapper.updateById(product);
}

2 订单管理

用户在前台系统中购买完商品以后生成对应的订单统计数据,在后台管理系统中就可以查看到订单数据,在后台管理系统中也可以对订单数据进行统计,形成图形化报表【柱状图、饼状图、曲线图、散点图…】用于数据分析。

2.1 订单数据统计需求说明

需求说明:统计指定时间段每一天订单的总金额,并且以柱状图的形式进行展示。

效果如下所示:

在这里插入图片描述

2.2 Echarts

要想将统计的数据以图表的方式进行展示,那么就需要使用到一些图形报表工具。常见的图形报表工具:Echarts

2.2.1 Echarts简介

官网地址:https://echarts.apache.org/zh/index.html

在这里插入图片描述

Echarts是一个基于JavaScript的开源可视化图表库,由百度前端开发团队研发和维护。它提供了丰富的图表类型、数据统计分析、动态数据更新、多

维数据展示等功能,可以帮助开发人员在 Web 应用、大屏展示、移动端等各种场景下,快速构建出高度定制化的交互式可视化图表。

Echarts支持多种图表类型,如线图、柱状图、饼图、雷达图、散点图等,还支持动态数据显示、图表联动、混搭图表等复杂功能。同时,ECharts还支持多种数据格式、数据预处理和自定义附加组件等扩展功能,让用户能够方便地实现各种需求和定制化要求。

ECharts易于上手,提供了丰富的API,以及完善的文档和示例,使得开发人员可以更快速、更便捷地使用它来进行数据可视化。

2.2.2 Echarts入门

需求:使用Echarts的柱状图展示每一天的商品的订单总金额。

效果如下所示:在这里插入图片描述

实现步骤:

1、安装Echarts,官网地址:https://echarts.apache.org/handbook/zh/basics/import

npm install echarts --save

2、添加订单管理菜单

通过系统管理的菜单管理,添加订单管理菜单,如下所示:

在这里插入图片描述

给管理员角色分配订单管理访问权限如下所示:

在这里插入图片描述

在src/views目录下创建orderStatistics.vue文件,如下所示:

在这里插入图片描述

在src/router/modules目录下创建order.js文件,配置路由:

const Layout = () => import('@/layout/index.vue')
const orderStatistics = () => import('@/views/order/orderStatistics.vue')export default [{path: '/order',component: Layout,name: 'order',meta: {title: '订单管理',},icon: 'Operation',children: [{path: '/orderStatistics',name: 'orderStatistics',component: orderStatistics,meta: {title: '订单统计',},}],},]

在src/router/index.js中添加订单管理路由:

import order from './modules/order'// 动态菜单
export const asyncRoutes = [...system,...base,...product,...order]

3、参考官方文档示例代码,完成入门案例,代码如下所示:

<template><div ref="orderTotalAmountDiv" style="width: 100%; height: 100%;"></div>
</template><script setup>
import { ref , onMounted } from 'vue'
import * as echarts from 'echarts';         // 导入Echart库中所有的图形报表组件// 定义chart数据模型,用来选中div组件
const orderTotalAmountDiv = ref() // 需要在onMounted钩子函数中对div区域使用echarts进行初始化
onMounted( () => {// 基于准备好的dom,初始化echarts实例var orderTotalAmountChart = echarts.init(orderTotalAmountDiv.value);// 绘制图表orderTotalAmountChart.setOption({title: {text: '订单数据统计'},tooltip: {},xAxis: {data: ['2023-06-01', '2023-06-02', '2023-06-03', '2023-06-04', '2023-06-05', '2023-06-06']},yAxis: {},series: [{name: '订单总金额(万元)',type: 'bar',data: [20, 40, 30, 100, 50, 25]}]});})</script><style scoped></style>

其他的常见的配置项以及属性介绍可以参看官方文档:https://echarts.apache.org/zh/option.html#tooltip.axisPointer

2.3 订单相关数据库表介绍

要进行订单数据的统计,首先就需要了解一下和订单相关的数据库表,如下所示:

-- 订单信息表
CREATE TABLE `order_info` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',`user_id` bigint NOT NULL DEFAULT '0' COMMENT '会员_id',`nick_name` varchar(200) DEFAULT NULL COMMENT '昵称',`order_no` char(64) NOT NULL DEFAULT '' COMMENT '订单号',`coupon_id` bigint DEFAULT NULL COMMENT '使用的优惠券',`total_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '订单总额',`coupon_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '优惠券',`original_total_amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '原价金额',`feight_fee` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '运费',`pay_type` tinyint DEFAULT NULL COMMENT '支付方式【1->微信】',`order_status` tinyint NOT NULL DEFAULT '0' COMMENT '订单状态【0->待付款;1->待发货;2->已发货;3->待用户收货,已完成;-1->已取消】',`receiver_name` varchar(100) DEFAULT NULL COMMENT '收货人姓名',`receiver_phone` varchar(32) DEFAULT NULL COMMENT '收货人电话',`receiver_post_code` varchar(32) DEFAULT NULL COMMENT '收货人邮编',`receiver_province` bigint DEFAULT NULL COMMENT '省份/直辖市',`receiver_city` bigint DEFAULT NULL COMMENT '城市',`receiver_district` bigint DEFAULT NULL COMMENT '区',`receiver_address` varchar(200) DEFAULT NULL COMMENT '详细地址',`payment_time` datetime DEFAULT NULL COMMENT '支付时间',`delivery_time` datetime DEFAULT NULL COMMENT '发货时间',`receive_time` datetime DEFAULT NULL COMMENT '确认收货时间',`remark` varchar(500) DEFAULT NULL COMMENT '订单备注',`cancel_time` datetime DEFAULT NULL COMMENT '取消订单时间',`cancel_reason` varchar(255) DEFAULT NULL COMMENT '取消订单原因',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8mb3 COMMENT='订单';-- 订单明细表
CREATE TABLE `order_item` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',`order_id` bigint DEFAULT NULL COMMENT 'order_id',`sku_id` bigint DEFAULT NULL COMMENT '商品sku编号',`sku_name` varchar(255) DEFAULT NULL COMMENT '商品sku名字',`thumb_img` varchar(500) DEFAULT NULL COMMENT '商品sku图片',`sku_price` decimal(10,2) DEFAULT NULL COMMENT '商品sku价格',`sku_num` int DEFAULT NULL COMMENT '商品购买的数量',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=364 DEFAULT CHARSET=utf8mb3 COMMENT='订单项信息';

注意:订单和订单明细之间的关系是一对多

2.4 订单数据统计实现思路

在入门案例中展示柱状图所需要的数据是假数据,现在就需要将数据换成真实统计数据。

数据统计的实现方案:

方案一:每一次展示数据的时候都从订单数据库中进行一次统计查询,对应的SQL语句如下所示

select DATE_FORMAT(oi.create_time ,'%Y-%m-%d') date , sum(oi.total_amount)  totalAmount from order_info oi GROUP BY DATE_FORMAT(oi.create_time ,'%Y-%m-%d');

弊端:在进行分组查询时,如果数据量较大,直接进行分组查询的效率会受到一定影响,因为需要对所有数据进行聚合计算,耗费时间和资源。

方案二:将分组结果计算好,写入到一张数据统计结果表中,然后从该表中直接查询统计以后的结果数据,不需要进行额外的计算,提高了查询效率。

实现思路如下图所示:

在这里插入图片描述

流程说明:

1、定时任务程序每天凌晨2点运行一次,从order_info表中查询出前一天的订单总金额数据,然后将总金额数据写入到统计结果表中

2、当用户发起查询订单统计结果请求的时候,此时后端系统从统计结果表中查询到对应的数据返回给前端系统

3、前端系统通过Echarts的柱状图展示数据

2.5 Spring Task

2.5.1 Spring Task简介

官网地址:https://docs.spring.io/spring-framework/reference/6.1-SNAPSHOT/integration/scheduling.html

Spring Task是Spring框架中的一个定时任务调度模块,它提供了一种简单的方式来实现基于时间的调度任务。

使用Spring Task,可以通过Java代码配置或注解的方式定义定时任务,并设置任务的执行时间、间隔周期、触发条件等。当达到指定的时间或条件

时,Spring Task会自动触发任务的执行,可以执行任何有意义的操作,例如数据备份、缓存清理、邮件发送等。

Spring Task还具有以下特点:

1、简单易用:简单的XML或注解配置即可实现定时任务调度。

2、易于集成:与Spring框架集成无缝,支持Spring Boot应用快速启动。

3、可靠性高:支持在分布式环境下进行任务调度,并支持并发控制和异常管理。

4、监控调试:支持日志记录、任务执行状态监控和调试,方便排除问题。

总之,Spring Task是一种非常有效和灵活的定时任务调度方案,适用于各种规模的Web应用和后台系统。

2.5.2 Spring Task入门案例

需求:每5秒在控制台输出一次"HelloWorld"

代码实现:

1、定义一个任务方法,在该方法上使用**@Scheduled**注解,并通常cron属性来指定该方法的执行的时间规则

@Component
@Slf4j
public class OrderStatisticsTask {@Scheduled(cron = "0/5 * * * * ?")  // 定义定时任务,使用@Scheduled注解指定调度时间表达式public void helloWorldTask() {log.info("HelloWorld");}}

2、在启动类上添加**@EnableScheduling**注解开启定时任务功能

...
@EnableScheduling
public class ManagerApplication {public static void main(String[] args) {SpringApplication.run(ManagerApplication.class , args) ;}}

启动程序进行测试。

2.5.3 cron表达式

cron表达式

定时任务触发时间的一个字符串表达形式,分为6或7个域,每一个域代表一个含义。

cron的结构从左到右(用空格隔开):秒 分 小时 月份中的日期 月份 星期中的日期 年份

这些字段的取值范围如下所示:

字段允许的值允许的特殊字符
秒(Seconds)0-59, - * /
分(Minutes)0-59, - * /
时(Hours)0-23, - * /
日(DayofMonth)1-31, - * ? / L W
月(Month)1-12 or JAN-DEC, - * /
周(DayofWeek)0-6 or SUN-SAT (0表示星期天), - * ? / L #
年(Year)留空或1970-2099, - * /

注:如日和月同时维护,例如:3 50 18 15 2 4,需要注意二月的星期四,不一定是15号,此时星期和日是有冲突的,通常需要舍掉一个,被舍掉的参数用**?**占位

Cron表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功能。

可查看阿里云开发者社区手册:https://developer.aliyun.com/article/942392

2.6 订单数据统计

2.6.1 数据库表介绍

统计数据结果表结构如下所示:

CREATE TABLE `order_statistics` (`id` bigint NOT NULL AUTO_INCREMENT,`order_date` date DEFAULT NULL COMMENT '订单统计日期',`total_amount` decimal(10,2) DEFAULT NULL COMMENT '总金额',`total_num` int DEFAULT NULL COMMENT '订单总数',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',`is_deleted` tinyint NOT NULL DEFAULT '0' COMMENT '删除标记(0:不可用 1:可用)',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=191 DEFAULT CHARSET=utf8mb3 COMMENT='订单统计';

2.6.3 代码实现

OrderStatistics

创建一个与订单统计结果表相对应的实体类:

// com.atguigu.spzx.model.entity.order;
@Data
public class OrderStatistics extends BaseEntity {private Date orderDate;private BigDecimal totalAmount;private Integer totalNum;}
OrderInfo

创建一个与订单数据库表对应的实体类:

// com.atguigu.spzx.model.entity.order;
@Data
@Schema(description = "OrderInfo")
public class OrderInfo extends BaseEntity {private Long userId;private String nickName;private String orderNo;private Long couponId;private BigDecimal totalAmount;private BigDecimal couponAmount;private BigDecimal originalTotalAmount;private BigDecimal feightFee;private Integer payType;private Integer orderStatus;private String receiverName;private String receiverPhone;private String receiverTagName;private String receiverProvince;private String receiverCity;private String receiverDistrict;private String receiverAddress;private Date paymentTime;private Date deliveryTime;private Date receiveTime;private String remark;private Date cancelTime;private String cancelReason;}
OrderStatisticsTask

定时任务程序代码实现:

// com.atguigu.spzx.manager.task
@Component
@Slf4j
public class OrderStatisticsTask {@Autowiredprivate OrderInfoMapper orderInfoMapper;@Autowiredprivate OrderStatisticsMapper orderStatisticsMapper;@Scheduled(cron = "0 0 2 * * ?")public void orderTotalAmountStatistics() {String createTime = DateUtil.offsetDay(new Date(), -1).toString(new SimpleDateFormat("yyyy-MM-dd"));OrderStatistics orderStatistics = orderInfoMapper.selectOrderStatistics(createTime);if(orderStatistics != null) {orderStatisticsMapper.insert(orderStatistics) ;}}}
OrderInfoMapper

OrderInfo持久层代码

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface OrderInfoMapper {// 查询指定日期产生的订单数据public abstract OrderStatistics selectOrderStatistics(String creatTime);}
OrderInfoMapper.xml

在OrderInfoMapper.xml映射文件中添加如下的SQL语句:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.spzx.manager.mapper.OrderInfoMapper"><select id="selectOrderStatistics" resultType="com.atguigu.spzx.model.entity.order.OrderStatistics">select DATE_FORMAT(oi.create_time ,'%Y-%m-%d') orderDate, sum(oi.total_amount)  totalAmount , count(oi.id) totalNumfrom order_info oi where DATE_FORMAT(oi.create_time ,'%Y-%m-%d') = #{createTime}GROUP BY DATE_FORMAT(oi.create_time ,'%Y-%m-%d')</select></mapper>
OrderStatisticsMapper

OrderStatisticsMapper持久层代码

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface OrderStatisticsMapper {public abstract void insert(OrderStatistics orderStatistics);}
OrderStatisticsMapper.xml

在OrderStatisticsMapper.xml映射文件中添加如下的SQL语句:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.spzx.manager.mapper.OrderStatisticsMapper"><!-- 用于select查询公用抽取的列 --><sql id="columns">id,order_date,total_amount,total_num,create_time,update_time,is_deleted</sql><insert id="insert" useGeneratedKeys="true" keyProperty="id">insert into order_statistics (id,order_date,total_amount,total_num) values (#{id},#{orderDate},#{totalAmount},#{totalNum})</insert></mapper>

2.7 统计查询

2.7.1 后端接口

OrderStatisticsDto

创建封装查询参数的实体类:

// com.atguigu.spzx.model.dto.order;
@Data
public class OrderStatisticsDto {private String createTimeBegin;private String createTimeEnd;}
OrderStatisticsVo

创建封装响应结果的实体类:

// com.atguigu.spzx.model.vo.order;
@Data
public class OrderStatisticsVo {private List<String> dateList ;private List<BigDecimal> amountList ;
}
OrderInfoController

表现层代码实现:

// com.atguigu.spzx.manager.controller;
@RestController
@RequestMapping(value="/admin/order/orderInfo")
public class OrderInfoController {@Autowiredprivate OrderInfoService orderInfoService ;@GetMapping("/getOrderStatisticsData")public Result<OrderStatisticsVo> getOrderStatisticsData( OrderStatisticsDto orderStatisticsDto) {OrderStatisticsVo orderStatisticsVo = orderInfoService.getOrderStatisticsData(orderStatisticsDto) ;return Result.build(orderStatisticsVo , ResultCodeEnum.SUCCESS) ;}}
OrderInfoService

业务层代码实现:

// com.atguigu.spzx.manager.service.impl;
@Service
public class OrderInfoServiceImpl implements OrderInfoService {@Autowiredprivate OrderStatisticsMapper orderStatisticsMapper ;@Overridepublic OrderStatisticsVo getOrderStatisticsData(OrderStatisticsDto orderStatisticsDto) {// 查询统计结果数据List<OrderStatistics> orderStatisticsList = orderStatisticsMapper.selectList(orderStatisticsDto) ;//日期列表List<String> dateList = orderStatisticsList.stream().map(orderStatistics -> DateUtil.format(orderStatistics.getOrderDate(), "yyyy-MM-dd")).collect(Collectors.toList());//统计金额列表List<BigDecimal> amountList = orderStatisticsList.stream().map(OrderStatistics::getTotalAmount).collect(Collectors.toList());// 创建OrderStatisticsVo对象封装响应结果数据OrderStatisticsVo orderStatisticsVo = new OrderStatisticsVo() ;orderStatisticsVo.setDateList(dateList);orderStatisticsVo.setAmountList(amountList);// 返回数据return orderStatisticsVo;}
}
OrderStatisticsMapper

持久层代码实现:

// com.atguigu.spzx.manager.mapper;
@Mapper
public interface OrderStatisticsMapper {List<OrderStatistics> selectList(OrderStatisticsDto orderStatisticsDto);
}
OrderStatisticsMapper.xml

在OrderStatisticsMapper.xml映射文件中添加如下的sql语句:

<resultMap id="orderStatisticsMap" type="com.atguigu.spzx.model.entity.order.OrderStatistics" autoMapping="true"></resultMap><select id="selectList" resultMap="orderStatisticsMap">select <include refid="columns" />from order_statistics<where><if test="createTimeBegin != null and createTimeBegin != ''">and order_date >= #{createTimeBegin}</if><if test="createTimeEnd != null and createTimeEnd != ''">and order_date &lt;= #{createTimeEnd}</if></where>order by order_date
</select>

2.7.2 前端对接

导入课程资料中所提供的orderInfo.js和orderStatistics.vue到指定的目录下。

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

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

相关文章

数据结构与算法-冒泡排序

引言 在数据结构与算法的世界里&#xff0c;冒泡排序作为基础排序算法之一&#xff0c;以其直观易懂的原理和实现方式&#xff0c;为理解更复杂的数据处理逻辑提供了坚实的入门阶梯。尽管在实际应用中由于其效率问题不常被用于大规模数据的排序任务&#xff0c;但它对于每一位初…

【C++】set、multiset与map、multimap的使用

目录 一、关联式容器二、键值对三、树形结构的关联式容器3.1 set3.1.1 模板参数列表3.1.2 构造3.1.3 迭代器3.1.4 容量3.1.5 修改操作 3.2 multiset3.3 map3.3.1 模板参数列表3.3.2 构造3.3.3 迭代器3.3.4 容量3.3.5 修改操作3.3.6 operator[] 3.4 multimap 一、关联式容器 谈…

Hololens 2应用开发系列(1)——使用MRTK在Unity中设置混合现实场景并进行程序模拟

Hololens 2应用开发系列&#xff08;1&#xff09;——使用MRTK在Unity中进行程序模拟 一、前言二、创建和设置MR场景三、MRTK输入模拟的开启 一、前言 在前面的文章中&#xff0c;我介绍了Hololens 2开发环境搭建和项目生成部署等相关内容&#xff0c;使我们能生成一个简单Ho…

matlab 写入格式化文本文件

目录 一、save函数 二、fprintf函数 matlab 写入文本文件可以使用save和fprintf函数 save输出结果: fprintf输出结果: 1.23, 2.34, 3.45 4.56, 5.67, 6.78 7.89, 8.90, 9.01 可以看出fprintf输出结果更加人性化,符合要求,下面分别介绍。 一、save函数 …

MQL5-MT5连接上国内期货

主要原因是昨天在学习MACD时发现给的基础代码感觉不对&#xff0c;但无法证明&#xff0c;因为MT5接的都是外汇交易&#xff0c;数据和国内的文华啥的全对不上&#xff0c;便找了一些国内接CTP的&#xff0c;直接写代码有点麻烦&#xff0c;虽然之前对接过国内CTP的东西&#x…

AI入门笔记(三)

神经网络是如何工作的 神经网络又是如何工作的呢&#xff1f;我们用一个例子来解释。我们看下面这张图片&#xff0c;我们要识别出这些图片都是0并不难&#xff0c;要怎么交给计算机&#xff0c;让计算机和我们得出同样的结果&#xff1f;难点就在于模式识别的答案不标准&…

十二、Nacos源码系列:Nacos配置中心原理(四)- RefreshEvent 事件处理

前面文章&#xff0c;我们说到回调监听器的方法中&#xff0c;主要就是发布了一个RefreshEvent事件&#xff0c;这个事件主要由 SpringCloud 相关类来处理。今天我们继续分析后续的流程。 RefreshEvent 事件会由 RefreshEventListener 来处理&#xff0c;该 listener 含有一个 …

武器大师——操作符详解(下)

目录 六、单目操作符 七、逗号表达式 八、下标引用以及函数调用 8.1.下标引用 8.2.函数调用 九、结构体 9.1.结构体 9.1.1结构的声明 9.1.2结构体的定义和初始化 9.2.结构成员访问操作符 9.2.1直接访问 9.2.2间接访问 十、操作符的属性 10.1.优先性 10.2.结合性 …

sql基本语法+实验实践

sql语法 注释&#xff1a; 单行 --注释内容# 注释内容多行 /* 注释内容 */数据定义语言DDL 查询所有数据库 show databases;注意是databases而不是database。 查询当前数据库 select database();创建数据库 create database [if not exists] 数据库名 [default charset 字符…

备战蓝桥杯Day22 - 计数排序

计数排序问题描述 对列表进行排序&#xff0c;已知列表中的数范围都在0-100之间。设计时间复杂度为O(n)的算法。 比如列表中有一串数字&#xff0c;2 5 3 1 6 3 2 1 &#xff0c;需要将他们按照从小到大的次序排列&#xff0c;得到1 1 2 2 3 3 5 6 的结果。那么此时计数排序是…

Jetson Xavier NX 开发板Ubuntu18.04 安装arduino IDE详细步骤

Jetson 平台是arch架构&#xff0c;官网上面几乎都是x86或者arm64的这两种错误版本都存在匹配问题无法使用&#xff0c;不要下载不要下载&#xff01; uname -a #版本查询1.正确下载打开方式 https://downloads.arduino.cc/arduino-1.8.19-linuxaarch64.tar.xz选择自己想要下…

LeetCode #104 二叉树的最大深度

104. 二叉树的最大深度 题目 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3 示例 2&#xff1a; 输入&#xff1a;root [1,null,2] 输出&#xff1a;2 分析 …

【Godot4自学手册】第十九节敌人的血量显示及掉血特效

这一节&#xff0c;我主要学习敌人的血量显示、掉血显示和死亡效果。敌人的血量显示和主人公的血量显示有所不同&#xff0c;主要是在敌人头顶有个红色的血条&#xff0c;受到攻击敌人的血条会减少&#xff0c;并且有掉血数量的文字显示&#xff0c;效果如下&#xff1a; 一、…

基于springboot+vue的医院后台管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

SMBGhost漏洞技术分析与防御方案

事件分析 最近国内外各安全厂商都发布了SMBGhost(CVE-2020-0796)漏洞的预警报告和分析报告&#xff0c;笔者利用周末休息时间也研究了一下&#xff0c;就算是做一个笔记了&#xff0c;分享给大家一起学习下&#xff0c;目前外面研究的POC大部分是通过SMB压缩数据包长度整数溢出…

如何根据玩家数量和游戏需求选择最合适的服务器配置?

根据玩家数量和游戏需求选择最合适的服务器配置&#xff0c;首先需要考虑游戏的类型、玩家数量、预计的在线时间以及对内存和CPU性能的需求综合考虑。对于大型多人在线游戏&#xff0c;如MMORPG或MOBA等&#xff0c;由于需要更多的CPU核心数来支持更复杂的游戏逻辑和处理大量数…

操作系统|概述|系统分类——笔记

1.1_1操作系统的概念和功能 操作系统的概念 操作系统&#xff08;Operating System&#xff0c; OS&#xff09; 是指控制和管理整个计算机系统的 硬件和软件 资源&#xff0c;并合理地组织调度计算机和工作和资源的分配&#xff1b; 1操作系统是系统资源的管理者 以提供给用…

文件的顺序读写函数举例介绍

目录 例1&#xff1a;&#xff08;使用字符输出函数fputc&#xff09;例2&#xff1a;&#xff08;使用字符输入函数fgetc&#xff09;例3&#xff1a;&#xff08;使用文本行输出函数fputs &#xff09;例4&#xff1a;&#xff08;使用文本行输入函数fgets &#xff09;例5&a…

Docker基础教程 - 2 Docker安装

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 2 Docker安装 Docker 的官网地址&#xff1a;https://www.docker.com/&#xff0c;在官网可以找到 Docker Engine 的安装步骤。 下面进行 Docker 环境的安装&#xff0c;正常情况下 Docker …

服务发现:CP or AP?

1 服务发现的意义 为高可用&#xff0c;生产环境中服务提供方都以集群对外提供服务&#xff0c;集群里这些IP随时可能变化&#xff0c;也需要用一本“通信录”及时获取对应服务节点&#xff0c;这获取过程即“服务发现”。 对服务调用方和服务提供方&#xff0c;其契约就是接…