Springboot3 + MyBatis-Plus + MySql + Uniapp 实现商品规格选择sku(附带自设计数据库,最新保姆级教程)

news2024/9/22 9:38:39

Springboot3 + MyBatis-Plus + MySql + Uniapp 实现商品规格选择sku(附带自设计数据库,最新保姆级教程)

  • 1、效果展示
  • 2、数据库设计
    • 2.1 商品表
    • 2.2 商品价格和规格中间表
    • 2.3 商品规格表
  • 3、后端代码
    • 3.1 model
    • 3.2 vo
    • 3.3 mapper、server、serverImp
    • 3.4 controller
  • 4、前端代码
    • 4.1 request.js
    • 4.2 index.js
    • 4.3 shop-info.vue
    • 4.4 ShopBottomButton.vue

1、效果展示


在这里插入图片描述

2、数据库设计

2.1 商品表


/*
 Navicat Premium Data Transfer

 Source Server         : Test1
 Source Server Type    : MySQL
 Source Server Version : 80200
 Source Host           : localhost:3306
 Source Schema         : yunshangshequ

 Target Server Type    : MySQL
 Target Server Version : 80200
 File Encoding         : 65001

 Date: 21/09/2024 12:59:26
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for shop
-- ----------------------------
DROP TABLE IF EXISTS `shop`;
CREATE TABLE `shop`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '商品ID',
  `business_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标签/自营?',
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商品简介',
  `sale_number` int NULL DEFAULT NULL COMMENT '已售数量',
  `old_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '旧价格',
  `new_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '现售价',
  `in_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '进货价',
  `inventory_num` int NULL DEFAULT NULL COMMENT '库存',
  `main_image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商品主图',
  `shop_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商品分类',
  `shop_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '店铺名称',
  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
  `is_deleted` tinyint NULL DEFAULT NULL COMMENT '逻辑删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of shop
-- ----------------------------
INSERT INTO `shop` VALUES (1, '自营', '新货【三只松鼠_量贩碧根果500g】特大健康坚果零食奶油味长寿果', 138, 39.90, 29.90, 19.90, 200, 'https://gw.alicdn.com/imgextra/i3/2218288872763/O1CN01rN6Cn91WHVIflhWLg_!!2218288872763.jpg', '1', '三只松鼠旗舰店', NULL, NULL, 0);
INSERT INTO `shop` VALUES (2, '', '新货【三只松鼠_量贩碧根果1500g】特大健康坚果零食奶油味长寿果', 28, 59.90, 49.90, 39.90, 2000, 'https://gw.alicdn.com/imgextra/i3/2218288872763/O1CN01rN6Cn91WHVIflhWLg_!!2218288872763.jpg', '2', '三只耗子', NULL, NULL, 0);

SET FOREIGN_KEY_CHECKS = 1;

2.2 商品价格和规格中间表

/*
 Navicat Premium Data Transfer

 Source Server         : Test1
 Source Server Type    : MySQL
 Source Server Version : 80200
 Source Host           : localhost:3306
 Source Schema         : yunshangshequ

 Target Server Type    : MySQL
 Target Server Version : 80200
 File Encoding         : 65001

 Date: 21/09/2024 12:59:16
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for shop_specs
-- ----------------------------
DROP TABLE IF EXISTS `shop_specs`;
CREATE TABLE `shop_specs`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `goods_id` int NULL DEFAULT NULL COMMENT '规格对应的商品id',
  `price` decimal(10, 2) NULL DEFAULT NULL COMMENT '对应规格的价格',
  `sku1` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '对应的规格',
  `sku2` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '对应的规格',
  `sku3` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '对应的规格',
  `sku4` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '对应的规格',
  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
  `is_deleted` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '逻辑删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of shop_specs
-- ----------------------------
INSERT INTO `shop_specs` VALUES (1, 1, 39.90, '1', '2', NULL, NULL, NULL, NULL, '0');
INSERT INTO `shop_specs` VALUES (2, 1, 29.90, '1', '4', NULL, NULL, NULL, NULL, '0');
INSERT INTO `shop_specs` VALUES (3, 1, 59.90, '3', '2', NULL, NULL, NULL, NULL, '0');
INSERT INTO `shop_specs` VALUES (4, 1, 49.00, '3', '4', NULL, NULL, NULL, NULL, '0');

SET FOREIGN_KEY_CHECKS = 1;

2.3 商品规格表

/*
 Navicat Premium Data Transfer

 Source Server         : Test1
 Source Server Type    : MySQL
 Source Server Version : 80200
 Source Host           : localhost:3306
 Source Schema         : yunshangshequ

 Target Server Type    : MySQL
 Target Server Version : 80200
 File Encoding         : 65001

 Date: 21/09/2024 12:59:04
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for shop_sku
-- ----------------------------
DROP TABLE IF EXISTS `shop_sku`;
CREATE TABLE `shop_sku`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `attr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '属性名',
  `attr_value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '属性值',
  `create_time` datetime NULL DEFAULT NULL,
  `update_time` datetime NULL DEFAULT NULL,
  `is_deleted` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of shop_sku
-- ----------------------------
INSERT INTO `shop_sku` VALUES (1, '重量', '1kg', NULL, NULL, '0');
INSERT INTO `shop_sku` VALUES (2, '大小', '大果', NULL, NULL, '0');
INSERT INTO `shop_sku` VALUES (3, '重量', '2kg', NULL, NULL, '0');
INSERT INTO `shop_sku` VALUES (4, '大小', '中果', NULL, NULL, '0');

SET FOREIGN_KEY_CHECKS = 1;

3、后端代码

3.1 model


BaseEntity 所有表字段的基本组成字段

package com.zhong.model.entity;


import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

@Data
public class BaseEntity implements Serializable {

    @Schema(description = "主键")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @Schema(description = "创建时间")
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    @JsonIgnore
    private Date createTime;

    @Schema(description = "更新时间")
    @TableField(value = "update_time", fill = FieldFill.UPDATE)
    @JsonIgnore
    private Date updateTime;

    @Schema(description = "逻辑删除")
    @TableField("is_deleted")
    @JsonIgnore
    private Byte isDeleted;

}

shop 表

package com.zhong.model.entity.shop;

import java.io.Serializable;
import java.math.BigDecimal;

import com.zhong.model.entity.BaseEntity;
import lombok.Data;

/**
 * 
 * @TableName shop 商品信息
 */
@Data
public class Shop extends BaseEntity {

    /**
     * 标签/自营?
     */
    private String businessName;

    /**
     * 商品简介
     */
    private String title;

    /**
     * 已售数量
     */
    private Integer saleNumber;

    /**
     * 旧价格
     */
    private BigDecimal oldPrice;

    /**
     * 现售价
     */
    private BigDecimal newPrice;

    /**
     * 进货价
     */
    private BigDecimal inPrice;

    /**
     * 库存
     */
    private Integer inventoryNum;

    /**
     * 商品主图
     */
    private String mainImage;

    /**
     * 商品分类
     */
    private String shopType;

    /**
     * 店铺名称
     */
    private String shopName;

    private static final long serialVersionUID = 1L;
}

shop_img_swiper 表 轮播图

package com.zhong.model.entity.shop;

import java.io.Serializable;

import com.zhong.model.entity.BaseEntity;
import lombok.Data;

/**
 * 
 * @TableName shop_img_swiper
 */
@Data
public class ShopImgSwiper extends BaseEntity {

    /**
     * 图片地址
     */
    private String url;

    /**
     * 商品id
     */
    private Integer fatherId;

    private static final long serialVersionUID = 1L;
}

shop_img_info表 商品详情图片

package com.zhong.model.entity.shop;

import java.io.Serializable;

import com.zhong.model.entity.BaseEntity;
import lombok.Data;

/**
 * 
 * @TableName shop_img_info
 */
@Data
public class ShopImgInfo extends BaseEntity {


    /**
     * 图片地址
     */
    private String url;

    /**
     * 商品id
     */
    private Integer fatherId;

    private static final long serialVersionUID = 1L;
}

shop_specs 表 商品规格与商品中间表

package com.zhong.model.entity.shop;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;

import com.zhong.model.entity.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

/**
 * 
 * @TableName shop_specs
 */
@TableName(value ="shop_specs")
@Data
public class ShopSpecs extends BaseEntity {
    @Schema(description = "主键")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 规格对应的商品id
     */
    private Integer goodsId;

    /**
     * 对应规格的价格
     */
    private BigDecimal price;

    /**
     * 对应的规格
     */
    private String sku1;

    /**
     * 对应的规格
     */
    private String sku2;

    /**
     * 对应的规格
     */
    private String sku3;

    /**
     * 对应的规格
     */
    private String sku4;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

shop_sku 商品规格

package com.zhong.model.entity.shop;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zhong.model.entity.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

/**
 * 
 * @TableName shop_sku
 */
@TableName(value ="shop_sku")
@Data
public class ShopSku extends BaseEntity {
    @Schema(description = "主键")
    @TableId(value = "id", type = IdType.AUTO)
    @JsonIgnore
    private Long id;
    /**
     * 属性名
     */
    private String attr;

    /**
     * 属性值
     */
    private String attrValue;


    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

3.2 vo


ShopVo

package com.zhong.vo.shop;

import com.zhong.model.entity.shop.Shop;
import com.zhong.model.entity.shop.ShopSpecs;
import lombok.Data;

import java.util.List;

/**
 * @ClassName : ShopVo
 * @Description :
 * @Author : zhx
 * @Date: 2024-09-15 18:55
 */
@Data
public class ShopVo extends Shop {
    private List<String> shopImgSwiper;
    private List<String> shopImgInfo;
    private List<ShopSpecs> shopSpecs;
}

ShopInfoVo

package com.zhong.vo.shop;

import com.zhong.model.entity.shop.Shop;
import com.zhong.model.entity.shop.ShopSku;
import com.zhong.model.entity.shop.ShopSpecs;
import lombok.Data;

import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @ClassName : ShopVo
 * @Description :
 * @Author : zhx
 * @Date: 2024-09-15 18:55
 */
@Data
public class ShopInfoVo extends Shop {
    private List<String> shopImgSwiper;
    private List<String> shopImgInfo;
    // 所有规格信息 方便渲染
    private List<Map<String, Object>> skuGroup;
    // 规格信息对应价格
    private List<ShopSkuVo> shopSpecs;
}

ShopSkuVo

package com.zhong.vo.shop;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.zhong.model.entity.shop.ShopSku;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import java.math.BigDecimal;
import java.util.List;

/**
 * @ClassName : ShopSkuVo
 * @Description :
 * @Author : zhx
 * @Date: 2024-09-20 10:46
 */
@Data
public class ShopSkuVo {
    @Schema(description = "主键")
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    private BigDecimal price;

    private List<ShopSku> skus;
}

SkuGroupVo

package com.zhong.vo.shop;

import lombok.Data;


import java.util.List;

/**
 * @ClassName : skuGroupVo
 * @Description :
 * @Author : zhx
 * @Date: 2024-09-20 13:49
 */
@Data
public class SkuGroupVo {
    private String skuKey;
    private List<String> skuValue;
}

3.3 mapper、server、serverImp

依赖mybatis自动生成,生成后将文件剪贴到对应位置即可。model 也可以自动生成 只不过要稍加修改

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4 controller


ShopController

package com.zhong.controller.shop;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhong.model.entity.shop.Shop;
import com.zhong.result.Result;
import com.zhong.service.ShopService;
import com.zhong.vo.shop.ShopInfoVo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @ClassName : ShopController
 * @Description :
 * @Author : zhx
 * @Date: 2024-09-15 18:23
 */

@RestController
@RequestMapping("/app/shop/")
@Tag(name = "商品信息")
public class ShopController {

    @Autowired
    private ShopService service;

    @Operation(summary = "分页获取商品信息")
    @GetMapping("listItem")
    public Result<Page<Shop>> listItem(@RequestParam long current, @RequestParam long size) {
        LambdaQueryWrapper<Shop> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Shop::getIsDeleted, "0");
        Page<Shop> shopPage = new Page<>(current, size);
        Page<Shop> page = service.page(shopPage, queryWrapper);
        return Result.ok(page);
    }

    @Operation(summary = "根据id获取商品详细信息")
    @GetMapping("getDetailById")
    public Result<ShopInfoVo> getDetailById(@RequestParam Long id) {
        ShopInfoVo shopInfoVo = service.getDetailById(id);
        return Result.ok(shopInfoVo);
    }
}

ShopService

package com.zhong.service;


import com.baomidou.mybatisplus.extension.service.IService;
import com.zhong.model.entity.shop.Shop;
import com.zhong.vo.shop.ShopInfoVo;
import com.zhong.vo.shop.ShopVo;

/**
* @author zhong
* @description 针对表【shop】的数据库操作Service
* @createDate 2024-09-15 18:18:13
*/
public interface ShopService extends IService<Shop> {

    ShopInfoVo getDetailById(Long id);
}

ShopServiceImpl

package com.zhong.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhong.mapper.shop.ShopMapper;
import com.zhong.model.entity.shop.Shop;
import com.zhong.model.entity.shop.ShopSku;
import com.zhong.model.entity.shop.ShopSpecs;
import com.zhong.service.ShopService;
import com.zhong.service.ShopSkuService;
import com.zhong.vo.shop.ShopInfoVo;
import com.zhong.vo.shop.ShopSkuVo;
import com.zhong.vo.shop.ShopVo;
import com.zhong.vo.shop.SkuGroupVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhong
 * @description 针对表【shop】的数据库操作Service实现
 * @createDate 2024-09-15 18:18:13
 */
@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop>
        implements ShopService {

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private ShopSkuService service;

    @Override
    public ShopInfoVo getDetailById(Long id) {
        // 返回的数据vo
        ShopInfoVo shopInfoVo = new ShopInfoVo();
        // 根据商品ID查询信息
        ShopVo detailById = shopMapper.getDetailById(id);
        // 获取查询到的商品信息的规格列表
        List<ShopSpecs> shopSpecs = detailById.getShopSpecs();
        // 新建一个vo对象保存 规格信息对应价格和列表
        List<ShopSkuVo> shopSkuLists = new ArrayList<>();
//        // 新建一个顶层数组 group vo 方便添加
//        List<List<SkuGroupVo>> skuGroupVos = new ArrayList<>();
        // 遍历每一个规格信息
        shopSpecs.forEach(x -> {
//            // 新建一个 二层数组 group vo 方便添加
//            List<SkuGroupVo> skuGroupList = new ArrayList<>();
//            // 新建一个 三层数组 group vo 方便添加
//            SkuGroupVo skuGroup = new SkuGroupVo();

            // 新建一个规格信息 Vo 方便后续添加到 listVo
            ShopSkuVo shopSkuVo = new ShopSkuVo();
            // 新建一个规格详情信息 Vo 方便后续添加到 shopSkuVo
            List<ShopSku> skuArrayList = new ArrayList<>();
            // 获取 skuGroupVo 的 key
            List<String> skuGroupKey = new ArrayList<>();
            // 获取 skuGroupVo 的 value
            List<String> skuGroupValue = new ArrayList<>();

            // 判断是否含有第一种规格
            if (x.getSku1() != null) {
                // 新建一个 shopSku 方便添加到 List<ShopSku>
                ShopSku shopSku = new ShopSku();
                // 根据规格ID获取规格详情
                ShopSku sku = service.getById(x.getSku1());
                // 将规格ID详情添加到 shopSkuVo
                shopSkuVo.setId(x.getId());
                // 将规格价格详情添加到 shopSkuVo
                shopSkuVo.setPrice(x.getPrice());
                // 将规格标题添加到 shopSku
                shopSku.setAttr(sku.getAttr());
                skuGroupKey.add(sku.getAttr());
                skuGroupValue.add(sku.getAttrValue());
                // 将规格值添加到 shopSku
                shopSku.setAttrValue(sku.getAttrValue());
                // 添加到规格详情List  List<ShopSku>
                skuArrayList.add(shopSku);
            }
            // 判断是否含有第二种规格
            if (x.getSku2() != null) {
                // 新建一个 shopSku 方便添加到 List<ShopSku>
                ShopSku shopSku = new ShopSku();
                // 根据规格ID获取规格详情
                ShopSku sku = service.getById(x.getSku2());
                // 将规格ID详情添加到 shopSkuVo
                shopSkuVo.setId(x.getId());
                // 将规格价格详情添加到 shopSkuVo
                shopSkuVo.setPrice(x.getPrice());
                // 将规格标题添加到 shopSku
                shopSku.setAttr(sku.getAttr());
                skuGroupKey.add(sku.getAttr());
                skuGroupValue.add(sku.getAttrValue());
                // 将规格值添加到 shopSku
                shopSku.setAttrValue(sku.getAttrValue());
                // 添加到规格详情List  List<ShopSku>
                skuArrayList.add(shopSku);
            }
            // 判断是否含有第三种规格
            if (x.getSku3() != null) {
                // 新建一个 shopSku 方便添加到 List<ShopSku>
                ShopSku shopSku = new ShopSku();
                // 根据规格ID获取规格详情
                ShopSku sku = service.getById(x.getSku3());
                // 将规格ID详情添加到 shopSkuVo
                shopSkuVo.setId(x.getId());
                // 将规格价格详情添加到 shopSkuVo
                shopSkuVo.setPrice(x.getPrice());
                // 将规格标题添加到 shopSku
                shopSku.setAttr(sku.getAttr());
                skuGroupKey.add(sku.getAttr());
                skuGroupValue.add(sku.getAttrValue());
                // 将规格值添加到 shopSku
                shopSku.setAttrValue(sku.getAttrValue());
                // 添加到规格详情List  List<ShopSku>
                skuArrayList.add(shopSku);
            }
            // 判断是否含有第四种规格
            if (x.getSku4() != null) {
                // 新建一个 shopSku 方便添加到 List<ShopSku>
                ShopSku shopSku = new ShopSku();
                // 根据规格ID获取规格详情
                ShopSku sku = service.getById(x.getSku4());
                // 将规格ID详情添加到 shopSkuVo
                shopSkuVo.setId(x.getId());
                // 将规格价格详情添加到 shopSkuVo
                shopSkuVo.setPrice(x.getPrice());
                // 将规格标题添加到 shopSku
                shopSku.setAttr(sku.getAttr());
                skuGroupKey.add(sku.getAttr());
                skuGroupValue.add(sku.getAttrValue());
                // 将规格值添加到 shopSku
                shopSku.setAttrValue(sku.getAttrValue());
                // 添加到规格详情List  List<ShopSku>
                skuArrayList.add(shopSku);
            }
            shopSkuVo.setSkus(skuArrayList);
            shopSkuLists.add(shopSkuVo);
        });

        BeanUtils.copyProperties(detailById, shopInfoVo);
        shopInfoVo.setShopSpecs(shopSkuLists);

        List<Map<String, Object>> skuGroup = computeSkuGroup(shopSkuLists);
        shopInfoVo.setSkuGroup(skuGroup);
        return shopInfoVo;
    }

    public List<Map<String, Object>> computeSkuGroup(List<ShopSkuVo> shopSpecs) {
        // 用于存放规格结果
        Map<String, Set<String>> resultMap = new LinkedHashMap<>();

        // 遍历每个商品的skus,提取属性和属性值
        for (ShopSkuVo item : shopSpecs) {
            for (ShopSku sku : item.getSkus()) {
                String attr = sku.getAttr();
                String attrValue = sku.getAttrValue();

                // 如果resultMap中不存在该属性,则初始化一个空的Set
                resultMap.putIfAbsent(attr, new LinkedHashSet<>());

                // 将属性值加入对应的Set
                resultMap.get(attr).add(attrValue);
            }
        }

        // 将结果格式化为所需的输出格式
        List<Map<String, Object>> finalResult = new ArrayList<>();
        for (Map.Entry<String, Set<String>> entry : resultMap.entrySet()) {
            Map<String, Object> temp = new HashMap<>();
            temp.put("key", entry.getKey());
            // 将Set转换为List并排序
            List<String> sortedValues = new ArrayList<>(entry.getValue());
            Collections.sort(sortedValues); // 对属性值进行排序

            // 创建一个包含info和isCheck的结构,假设第一个元素被选中
            List<Map<String, Object>> attrValueItems = new ArrayList<>();
            for (int i = 0; i < sortedValues.size(); i++) {
                Map<String, Object> valueMap = new HashMap<>();
                valueMap.put("info", sortedValues.get(i));
                valueMap.put("isCheck", i == 0); // 默认第一个值为true,其他为false
                attrValueItems.add(valueMap);
            }

            temp.put("value", attrValueItems);
            finalResult.add(temp);
        }

        // 输出结果
        System.out.println(finalResult);
        return finalResult;
    }
}

ShopMapper

package com.zhong.mapper.shop;


import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zhong.model.entity.shop.Shop;
import com.zhong.vo.shop.ShopVo;
import org.apache.ibatis.annotations.Mapper;

/**
* @author zhong
* @description 针对表【shop】的数据库操作Mapper
* @createDate 2024-09-15 18:18:13
* @Entity generator.domain.Shop
*/
@Mapper
public interface ShopMapper extends BaseMapper<Shop> {

    ShopVo getDetailById(Long id);
}

> ShopMapper.xml

```xml
<?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.zhong.mapper.shop.ShopMapper">
    <resultMap id="ShopVoMap" type="com.zhong.vo.shop.ShopVo" autoMapping="true">
        <id column="id" property="id"/>
        <collection property="shopImgSwiper" ofType="string">
            <result column="siu"/>
        </collection>
        <collection property="shopImgInfo" ofType="string" autoMapping="true">
            <result column="ssu"/>
        </collection>
        <collection property="shopSpecs" ofType="com.zhong.model.entity.shop.ShopSpecs" autoMapping="true">
            <id column="sssid" property="id"/>
        </collection>
    </resultMap>
    <select id="getDetailById" resultMap="ShopVoMap">
        select sp.id,
               sp.business_name,
               sp.title,
               sp.sale_number,
               sp.old_price,
               sp.new_price,
               sp.in_price,
               sp.inventory_num,
               sp.main_image,
               sp.shop_type,
               sp.shop_name,
               si.url siu,
               ss.url ssu,
               sss.id sssid,
               sss.sku1,
               sss.sku2,
               sss.sku3,
               sss.sku4,
               sss.price
        from shop sp
                 left join shop_img_info si on sp.id = si.father_id and si.is_deleted = 0
                 left join shop_img_swiper ss on sp.id = ss.father_id and ss.is_deleted = 0
                 left join shop_specs sss on sp.id = sss.goods_id and sss.is_deleted = 0
        where sp.is_deleted = 0
          and sp.id = #{id}
    </select>
</mapper>

4、前端代码

4.1 request.js

import axios from 'axios'

// 创建 axios 实例
const service = axios.create({
	// baseURL: import.meta.env.PROD ? import.meta.env.VITE_APP_BASE_URL : '/',  // 根据环境设置 baseURL
	baseURL: '/api', // 根据环境设置 baseURL
	// timeout: ResultEnum.TIMEOUT,
	timeout: 10000,
})

/**
 * @description: 请求拦截器
 */
service.interceptors.request.use(
	(config) => {
		// const userStore = useUserStore()
		// const token = userStore.token
		// if (token) {
		//   config.headers['access-token'] = token
		// }
		config.headers['access-token'] =
			"eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MzUwMzcyNjUsInN1YiI6IkxPR0lOX1VTRVIiLCJ1c2VySWQiOjgsInVzZXJuYW1lIjoiMTMwMzY0OTc1NjIifQ.BJudKwWdt48h4eQaYRte2aXZWDYFRG7SHopRYSMr7D4"
		return config
	},
	(error) => {
		// 使用 uni.showToast 替换 ElMessage.error
		uni.showToast({
			title: error.message,
			icon: 'none',
			duration: 2000
		})
		return Promise.reject(error)
	}
)

/**
 * @description: 响应拦截器
 */
service.interceptors.response.use(
	(response) => {
		const {
			data
		} = response
		// console.log(data.code);
		// // * 登陆失效
		// if (ResultEnum.EXPIRE.includes(data.code)) {
		// 	RESEETSTORE()
		// 	uni.showToast({
		// 		title: data.message || ResultEnum.ERRMESSAGE,
		// 		icon: 'none',
		// 		duration: 2000
		// 	})
		// 	router.replace(LOGIN_URL)
		// 	return Promise.reject(data)
		// }

		if (data.code && data.code !== 200) {
			uni.showToast({
				title: data.message || ResultEnum.ERRMESSAGE,
				icon: 'none',
				duration: 2000
			})
			return Promise.reject(data)
		}
		return data.data
	},
	(error) => {
		// 处理 HTTP 网络错误
		let message = ''
		const status = error.response?.status
		switch (status) {
		      case 400:
		        message = "请求错误";
		        break;
		      case 401:
		        message = "未授权,请登录";
		        break;
		      case 403:
		        message = "拒绝访问";
		        break;
		      case 404:
		        message = `请求地址出错: ${error.response?.config?.url}`;
		        break;
		      case 408:
		        message = "请求超时";
		        break;
		      case 500:
		        message = "服务器内部错误";
		        break;
		      case 501:
		        message = "服务未实现";
		        break;
		      case 502:
		        message = "网关错误";
		        break;
		      case 503:
		        message = "服务不可用";
		        break;
		      case 504:
		        message = "网关超时";
		        break;
		      case 505:
		        message = "HTTP版本不受支持";
		        break;
		      default:
		        message = "网络连接故障";
		    }

		// 使用 uni.showToast 提示错误信息
		uni.showToast({
			title: message,
			icon: 'none',
			duration: 2000
		})
		return Promise.reject(error)
	}
)

/**
 * @description: 导出封装的请求方法
 */
const http = {
	get(url, params) {
		return service.get(url, params)
	},

	post(url, data) {
		return service.post(url, data)
	},

	put(url, data) {
		return service.put(url, data)
	},

	delete(url, data) {
		return service.delete(url, {
			data
		})
	}
}

export default http

4.2 index.js

import http from '@/utils/request.js';

export const getAllShopApi = (params) => {
	return http.get(`/app/shop/listItem?current=${params.current}&size=${params.size}`)
}

export const getShopByIdApi = (id) => {
	return http.get(`/app/shop/getDetailById?id=${id}`)
}

4.3 shop-info.vue

<template>
	<view>
		<template v-for="(item, index) in [data]" :key="index">
			<view class="">
				<up-swiper :list="item.shopImgSwiper" circular :autoplay="true" bgColor="#ffffff" height="360rpx"
					imgMode="auto"></up-swiper>
			</view>

			<view class="connect card card-shadow">
				<view class="price">
					<view class="">
						<up-text mode="price" :text="item.newPrice" color="red" size="24"></up-text>
					</view>
					<view class="">
						<text>已售{{item.saleNumber}}</text>
					</view>
				</view>
				<!-- 标题 -->
				<view class="title">
					<up-row customStyle="margin-bottom: 10px">
						<up-col span="2" v-if="item.businessName">
							<view class="" style="display: flex;">
								<up-tag :text="item.businessName" size="mini" type="error"></up-tag>
							</view>
						</up-col>
						<up-col :span="item.businessName?10 :12">
							<text>{{item.title}}</text>
						</up-col>
					</up-row>
				</view>
				<!-- 发货 -->
				<view class="logistics flex" style=" position: relative;">
					<up-icon name="car"></up-icon>
					<view class="" style="width: 20rpx;"></view>
					<view class="font-lite-size">
						<text>承诺24小时内发货,晚发必赔</text>
					</view>
					<view class="" style="position: absolute;right: 10rpx;">
						<up-icon name="arrow-right"></up-icon>
					</view>
				</view>

				<!-- 破损 -->
				<view class="pock flex" style=" position: relative;">
					<up-icon name="car"></up-icon>
					<view class="" style="width: 20rpx;"></view>
					<view class="font-lite-size">
						<text>破损包退 | 退货运费险 | 极速退款 | 7天无理由退换</text>
					</view>
					<view class="" style="position: absolute;right: 10rpx;">
						<up-icon name="arrow-right" size="16"></up-icon>
					</view>
				</view>
			</view>

			<!-- 评价 -->
			<view class="card card-shadow">
				<ShopCommentVue></ShopCommentVue>
			</view>

			<!-- 店铺信息 -->
			<view class="card card-shadow">
				<StoreInformationVue></StoreInformationVue>
			</view>
			<!-- 商品详情图片 -->
			<view class="bb-info card card-shadow" v-if="data.shopImgInfo.length> 0">
				<ShopInfoImageListVue :imgList="data.shopImgInfo"></ShopInfoImageListVue>
			</view>
			<!-- 提示 -->
			<view class="tips card card-shadow">
				<ShopTipsVue></ShopTipsVue>
			</view>
			<!-- 底部tabbar安全距离 -->
			<view class="" style="height: 140rpx;">

			</view>
		</template>
		<!-- 加入购物车等操作 -->
		<view class="bottom">
			<ShopBottomButtonVue :data="data"></ShopBottomButtonVue>
		</view>
	</view>
</template>

<script setup>
	import {
		reactive,
		ref,
		onMounted
	} from 'vue';

	import ShopCommentVue from '@/pages/components/Home/ShopComment.vue';
	import StoreInformationVue from '@/pages/components/Home/StoreInformation.vue';
	import ShopInfoImageListVue from '@/pages/components/Home/ShopInfoImageList.vue';
	import ShopTipsVue from '@/pages/components/Home/ShopTips.vue';
	import ShopBottomButtonVue from '@/pages/components/Home/ShopBottomButton.vue';
	import {
		onLoad
	} from "@dcloudio/uni-app"
	import {
		getShopByIdApi
	} from "@/pages/api/shop/index.js"
	const shopId = ref();
	const data = ref();
	onLoad((options) => {
		shopId.value = options.id;
	})
	onMounted(async () => {
		console.log(shopId.value);
		let res = await getShopByIdApi(shopId.value);
		data.value = res;
		console.log(res);
	})
	// 父组件中的价格数据
	const price = ref(null);
	// 处理子组件传来的价格更新
	const handlePriceUpdate = (newPrice) => {
	  price.value = newPrice;
	};
</script>

<style lang="less" scoped>
	.card-shadow {
		border-radius: 20rpx;
		box-shadow: 10rpx 10rpx 10rpx 10rpx rgba(0.2, 0.1, 0.2, 0.2);
	}

	.card {
		margin: 20rpx;
		padding: 20rpx;
		background-color: #FFF;
		border-radius: 20rpx;
	}

	.font-lite-size {
		font-size: 26rpx;
	}

	.flex {
		display: flex;
		align-items: center;
	}

	.title {
		margin-top: 20rpx;
	}

	.pock {
		margin: 20rpx 0;
	}

	.price {
		padding-right: 20rpx;
		display: flex;
		justify-content: space-between;
		align-items: center;
	}
</style>

4.4 ShopBottomButton.vue

<template>
	<view class="mains">
		<view class="connect">
			<view class="letf-connect">
				<up-icon name="gift" size="40rpx"></up-icon>
				<text style="font-size: 26rpx;">店铺</text>
			</view>
			<view class="letf-connect">
				<up-icon name="kefu-ermai" size="40rpx"></up-icon>
				<text style="font-size: 26rpx;">客服</text>
			</view>
			<view class="letf-connect" @click="toShopCart">
				<up-icon name="shopping-cart" size="40rpx"></up-icon>
				<text style="font-size: 26rpx;">购物车</text>
			</view>

			<view class="" style="display: flex;flex: 1;padding-left: 20rpx;">
				<up-button text="加入购物车" type="warning" @click="show=true"></up-button>
				<up-button text="立即购买" type="success"></up-button>
			</view>
		</view>

		<!-- 弹出层选择商品规格 -->
		<up-popup :show="show" mode="bottom" :round="10" @close="close" @open="open">
			<view>
				<view class="top">
					<up-image :src="props.data.mainImage" width="200rpx" height="300rpx" radius="10"></up-image>
					<view style="padding-left: 40rpx;">
						<text style="flex: 1;overflow: hidden;">{{props.data.title}}</text>
						<view style="padding: 20rpx 0;">
							<up-text mode="price" :text="calculatedPrice" color="red" size="20"></up-text>
						</view>
						<view style="display: flex;padding-top: 20rpx;">
							<up-number-box v-model="shopNum" min="1"></up-number-box>
						</view>
					</view>
				</view>

				<!-- 渲染规格 -->
				<view class="">
					<template v-for="(item,index) in resSkuGroup">
						<view style="padding-left: 20rpx;">{{item.key}}</view>
						<view style="display: flex;">
							<template v-for="(tag,i) in item.value" :key="i">
								<view class="" style="display: flex;padding:20rpx;">
									<up-tag :text="tag.info" :plain="!tag.isCheck" :color="tag.isCheck?'#FFF':'#000'"
										:borderColor="tag.isCheck?'#FFF':'#000'" type="error"
										@click="changeTagIsCheckFun(tag,index)"></up-tag>
								</view>
							</template>
						</view>
					</template>
				</view>

				<view class="" style="padding: 20rpx;">
					<up-button text="加入购物车" shape="circle" type="error" @click="addCartFun"></up-button>
				</view>
			</view>
		</up-popup>
	</view>
</template>

<script setup>
	import {
		computed,
		onMounted,
		reactive,
		defineEmits,
		watch,
		ref
	} from 'vue';
	// 创建响应式数据
	const show = ref(false);
	const resData = ref();
	const resSkuData = ref();
	const resSkuGroup = ref();
	const resDataFun = async() => {
		resSkuGroup.value = await props.data.skuGroup;
		resSkuData.value = await props.data.shopSpecs;
		console.log(props.data.shopSpecs);
		console.log( resSkuData.value);
	}
	const changeTagIsCheckFun = (item, index) => {
		resSkuGroup.value[index].value.map(x => {
			if (x.info == item.info) {
				x.isCheck = true;
			} else {
				x.isCheck = false;
			}
		})
		console.log(resSkuGroup.value);
	}

	// 通过 computed 计算选中的属性值
	const checkedAttributes = computed(() => {
	  return resSkuGroup.value.map(option => ({
	    attr: option.key,
	    attrValue: option.value.find(item => item.isCheck)?.info || null
	  }));
	});
	// 商品数量
	const shopNum = ref(1);
	// 根据选中的属性值匹配 SKU,计算出价格
	const calculatedPrice = computed(() => {
		if (resSkuData.value) {
			// 找到与选中属性完全匹配的 SKU
			const matchingSku = resSkuData.value.find(sku => {
			  return sku.skus.every(skuAttr => {
			    return checkedAttributes.value.some(attr => 
			      attr.attr === skuAttr.attr && attr.attrValue === skuAttr.attrValue
			    );
			  });
			});
				
			// 返回匹配的价格,没有匹配的返回 null
			return matchingSku ? matchingSku.price * shopNum.value: null;
		}
	});
	// // 定义 emit
	// const emit = defineEmits(['updatePrice']);
	// // 监听计算的价格变化并向父组件传值
	// watch(calculatedPrice, (newPrice) => {
	
	// 	emit('updatePrice', newPrice);
	// });
	const toCartData = reactive({
		num: 1,
	})
	const props = defineProps({
		data: Object
	});

	onMounted(() => {
		console.log(props.data);
		resDataFun();
	})
	// 定义方法  
	const open = () => {
		// 打开逻辑,比如设置 show 为 true  
		show.value = true;
		// console.log('open');  
	}

	const close = () => {
		// 关闭逻辑,设置 show 为 false  
		show.value = false;
		// console.log('close');  
	}
	const toShopCart = () => {
		uni.navigateTo({
			url: "/pages/src/home/shop-cart/shop-cart"
		})
	}
	const addCartFun = () => {
		close();
	}
</script>

<style lang="scss" scoped>
	.top {
		display: flex;
		padding: 40rpx;
	}

	.mains {
		position: fixed;
		bottom: 0;
		left: 0;
		width: 100%;
		/* 占据全宽 */
		height: 120rpx;
		/* Tabbar 高度 */
		background-color: #FFF;
		border-top: 2rpx solid #7d7e80;
	}

	.connect {
		display: flex;
		justify-content: space-around;
		padding: 20rpx;
		align-items: center;
	}

	.letf-connect {
		padding: 0 10rpx;
		display: flex;
		flex-direction: column;
		align-items: center;
	}
</style>

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

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

相关文章

DNS是什么?怎么设置

NS是什么意思?有什么用呢?专业的说DNS就是域名系统 (Domain Name System)的简称&#xff0c;也就是IT人士常说的域名解析系统。主要是让用户在互联网上通过域名找到域名对应的IP地址&#xff0c;因为IP地址都是一串数字(例如&#xff1a;192.168.0.1)不方便记忆&#xff0c;便…

华为全联接大会HUAWEI Connect 2024印象(一):OpenEuler

因为和华为有课程合作&#xff0c;此次应邀参加了华为全联接大会 &#xff08;HUAWEI Connect 2024&#xff09;&#xff0c;分几次分享一下自己的见闻。 HUAWEI Connect 2024的规模很大&#xff0c;不过主要面向的应该是企业市场&#xff0c;我比较关注的嵌入式系统的内容很少…

学习笔记——RegNet:Designing Network Design Spaces

RegNet&#xff1a;Designing Network Design Spaces RegNet&#xff1a;设计一个网络设计空间 论文地址&#xff1a; https://arxiv.org/pdf/2003.13678 1、前言 在这项工作中&#xff0c;作者提出了一种新的网络设计范例。 作者的目标是帮助增进对网络设计的理解并发现跨设置…

Stable Diffusion Fooocus批量绘图脚本

当当当挡~&#xff0c;流动传热数值计算之余发布点AIGC相关文章&#xff0c;希望大家能喜欢~ 1 Stable Diffusion各种UI分析对比 提示&#xff1a;此部分主要是对SD各种界面的简要介绍和对比&#xff0c;只关注Fooocus批量绘图的读者可直接跳到第二部分。 Stable Diffusion …

进程间的通信4 共享内存

共享内存 1.共享内存简介 共享内存是将分配的物理空间直接映射到进程的用户虚拟地址空间中&#xff0c;减少数据在内核空间缓存共享内存是一种效率较高的进程间通讯的方式在 Linux 系统中通过 ipcs -m 查看所有的共享内存 共享内存模型图 2.共享内存的创建 1.函数头文件 #…

【6DRepNet360全范围头部姿态估计onnxruntime推理】

6DRepNet360全范围头部姿态估计 标题摘要关键词主要贡献方法概述实验结论模型转换和onnxruntime推理模型和代码下载可视化结果代码 这篇论文的核心内容是关于一种用于全范围旋转头部姿态估计的新方法。以下是关键点的总结&#xff1a; 标题 Towards Robust and Unconstrained…

输电线路数据集

输电线路数据集&#xff08;绝缘子自爆&#xff0c;破损&#xff0c;闪络&#xff0c;鸟巢&#xff0c;防震锤脱落五种缺陷&#xff09; 包括 1.绝缘子自爆 2.绝缘子破损绝、闪络 3.鸟巢 4.防震锤脱落 数据增强后的数量 对应数量&#xff1a;1828&#xff0c;1467&#xff0c;4…

【Godot4.3】剪贴板相关以及粘贴截图

概述 Godot4.3中更新了一些关于剪贴板的方法&#xff0c;获取图片赫然在列&#xff0c;这意味着可以在自己的应用中创建诸如粘贴截图的功能。 这些方法被包含在DisplaySever单例中&#xff0c;有兴趣的戈友可以自己去翻一下文档。或许可以实现Godot版本的屏幕截图工具。 相关…

Java | Leetcode Java题解之第414题第三大的数

题目&#xff1a; 题解&#xff1a; class Solution {public int thirdMax(int[] nums) {Integer a null, b null, c null;for (int num : nums) {if (a null || num > a) {c b;b a;a num;} else if (a > num && (b null || num > b)) {c b;b num;…

Maven笔记(二):进阶使用

Maven笔记&#xff08;二&#xff09;-进阶使用 一、Maven分模块开发 分模块开发对项目的扩展性强&#xff0c;同时方便其他项目引入相同的功能。 将原始模块按照功能拆分成若干个子模块&#xff0c;方便模块间的相互调用&#xff0c;接口共享(类似Jar包一样之间引用、复用)…

【LLM学习之路】9月16日 第六天

【LLM学习之路】9月16日 第六天 损失函数 L1Loss 可以取平均也可以求和 参数解析 input &#xff08;N&#xff0c;*&#xff09; N是batchsize&#xff0c;星号代表可以是任意维度 不是输入的参数&#xff0c;只是描述数据 target 形状要同上 MSELoss平方差 CrossEntr…

物理学基础精解【7】

文章目录 平面方程直角坐标及基本运算 参考文献 平面方程 直角坐标及基本运算 向量的四则运算 下面由文心一言自动生成 向量的四则运算主要包括加法、减法、数乘&#xff08;标量乘法&#xff09;和数量积&#xff08;点积或内积&#xff09;&#xff0c;但通常不直接称为“除…

python sql中带引号字符串(单双引号)转义处理

描述&#xff1a; 最近在爬取数据保存到数据库时&#xff0c;遇到有引号的字符串插入MySQL报错&#xff1a;1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 转义字符串…

线程(三) 线程的互斥

文章目录 线程线程的同步和互斥线程同步线程互斥为什么要使用线程互斥什么是线程同步示例--线程操作共享资源引发问题 线程互斥--互斥锁示例--使用互斥锁来保证取款操作 互斥锁的属性示例--创建不同的属性的互斥锁后进行加锁操作 线程互斥--读写锁示例--对读写锁进行使用以观察…

鸿蒙【项目打包】- .hap 和 .app;(测试如何安装发的hap包)(应用上架流程)

#打包成.hap需要用到真机 原因是&#xff1a;只有用上了真机才能在项目中配置 自动签名 #步骤: ##第一步:选择真机->选择项目结构->点Sigining Configs(签名配置) ##第二步:勾选Automatically generate signature(自动签名)->点击ok ##第三步:点击构建->点击 …

伊犁云计算22-1 rhel8 dhcp 配置

1 局域网搭建 2 yum 配置 这个参考前面 不说 3 dnf 安装dhcp 好我们废话不说开始安装。理论看书去 进入 dhcp.conf 配置 重启dhcpd 不能报错&#xff01;&#xff01;&#xff01;&#xff01; 我们在客户机上做测试 全局的dhcp关闭 很明显我们的客户机获取到192.16…

Why Is Prompt Tuning for Vision-Language Models Robust to Noisy Labels?

文章汇总 本文的作者针对了提示学习的结构设计进行了分析&#xff0c;发现了一些规律&#xff1a; 1)固定的类名令牌为模型的优化提供了强正则化&#xff0c;减少了由噪声样本引起的梯度。 2)从多样化和通用的web数据中学习到的强大的预训练图像文本嵌入为图像分类提供了强大…

李宏毅机器学习2023-HW11-Domain Adaptation

文章目录 TaskLinkBaselineSimple BaselineMedium BaselineStrong BaselineBoss Baseline Task Domain Adaptation 通过训练真实图片得到分类模型&#xff0c;并将其应用到涂鸦图片上进行分类&#xff0c;来获得更高的精准度。 Link kaggle colab Baseline Simple Baseli…

JVM(HotSpot):JVM简单介绍

文章目录 一、什么是JVM二、优点三、比较四、学习路线 一、什么是JVM 定义&#xff1a;java程序的运行环境 首先&#xff0c;我们要知道&#xff0c;JVM是一套规范&#xff0c;运行java程序的一套规范。 那么&#xff0c;我们学习过java的人都知道&#xff0c;接口规范的实现类…

软考高级:数据库关系模式推理规则 AI 解读

你提出的是关系模式中的一些经典推理规则&#xff0c;这些规则在数据库理论、函数依赖和范式相关的讨论中经常出现。我们可以通过以下方式深入理解这些规则&#xff0c;并且对其中的推理逻辑进行分解。 生活化例子 想象你在管理一家快递公司&#xff0c;货物需要从仓库&#…