栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

《谷粒商城》开发实录:059-069 商品服务-品牌管理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

《谷粒商城》开发实录:059-069 商品服务-品牌管理

059 品牌管理-增删改查

品牌表:pms_brand

1 创建品牌管理菜单

2 前端代码

在之前使用renren-generator生成的代码中,包含了一些.vue文件。

在gulimall-product/src/main/resources/src/views/modules/product/路径下,可以找到品牌管理的相关代码。

将brand.vue和brand-add-or-update.vue两个文件复制到前端项目renren-fast-vue的src/views/modules/product/路径下。

重启renren-fast-vue项目(ctrl c停止运行项目) ,品牌管理页面出现内容。

此时在品牌管理页面上并没有新增和批量删除的接口,实际上代码里是有的,只是因为权限问题没有显示出来。 

修改src/utils/index.js文件中的isAuth方法,使权限总是为true。

刷新页面,页面上出现新增和批量删除接口。

简单测试了一下,生成代码的新增、修改、删除功能都没问题。

060 品牌管理-使用开关表示布尔值

品牌的显示状态字段值为0或1,可以使用ElmentUI中的Switch开关组件来表示。

代码见 069 品牌管理-完整前端代码

061-064 品牌管理-云存储的开通与使用

新增或修改品牌时,我们希望将品牌logo地址一栏改为直接上传文件。

上传文件的存储架构为:

本项目使用阿里云对象存储(OSS)来实现。 

OSS官网

1 准备工作

OSS服务是一个第三方服务,我们以后可能会用到许多第三方服务,所以可以创建一个微服务gulimall-third-party来整合。

在pom.xml文件中添加对gulimall-common的依赖:


    com.atguigu.gulimall
    gulimall-common
    0.0.1-SNAPSHOT
    
        
            com.baomidou
            mybatis-plus-boot-starter
        
    

然后添加对OSS服务的依赖:


    com.alibaba.cloud
    spring-cloud-alicloud-oss
    2.2.0.RELEASE

包括dependencyManagement部分:


    com.alibaba.cloud
    spring-cloud-alibaba-dependencies
    2021.1
    pom
    import

在gulimall-third-party/src/main/resources/路径下添加配置文件:

bootstrap.properties

spring.application.name=gulimall-third-party
spring.cloud.nacos.config.server-addr=127.0.0.1:8848

application.yml

spring:
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
  application:
    name: gulimall-third-party

server:
  port: 30000

在gulimall-third-party/src/main/java/com/atguigu/gulimall/thirdparty/GulimallThirdPartyApplication类上添加注解:

@EnableDiscoveryClient

2 调用OSS服务

开通OSS服务后,创建一个bucket。(bucket名称自拟)

在页面右上角的菜单中选择AccessKey管理,创建一个用户。

​​​​​​

 给创建的用户添加管理OSS的权限。

然后在gulimall-third-party/src/main/resources/application.yml中添加配置:(其中access-key和secret-key是创建用户时生成的)

我们有许多种方式可以将文件提交给OSS,最终选择的方案是服务端签名后直传。

在gulimall-third-party/src/main/java/com/atguigu/gulimall/thirdparty/路径下创建目录controller/,并在该目录中创建OssController类(参照官方文档)。

package com.atguigu.gulimall.thirdparty.controller;

import com.aliyun.oss.OSS;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.linkedHashMap;
import java.util.Map;

@RestController
public class OssController {

    @Autowired
    OSS ossClient;

    @Value("${spring.cloud.alicloud.oss.endpoint}")
    private String endpoint;

    @Value("${spring.cloud.alicloud.oss.bucket}")
    private String bucket;

    @Value("${spring.cloud.alicloud.access-key}")
    private String accessId;

    @RequestMapping("/oss/policy")
    public R policy() {
        String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
        // callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
        //String callbackUrl = "http://88.88.88.88:8888";
        String format = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String dir = format + "/"; // 用户上传文件时指定的前缀。

        Map respMap = null;
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            // PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.tobase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            respMap = new linkedHashMap();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            // respMap.put("expire", formatISO8601Date(expiration));
        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return R.ok().put("data", respMap);
    }
}

启动gulimall-third-party服务。

访问:http://localhost:30000/oss/policy

  • accessid:访问ID
  • policy:策略
  • signature:签名
  • dir:上传到的文件夹
  • host:上传到的主机地址
  • expire:签名过期时间

配置网关:gulimall-gateway/src/main/resources/application.yml

- id: third_party_route
  uri: lb://gulimall-third-party
  predicates:
    - Path=/api/thirdparty
@Slf4j
@RestControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
public class GulimallExceptionControllerAdvice {

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleVaildException(MethodArgumentNotValidException e) {
        
        Map errorMap = new HashMap<>();
        BindingResult bindingResult = e.getBindingResult();
        bindingResult.getFieldErrors().forEach((fieldError) ->
        {
            errorMap.put(fieldError.getField(), fieldError.getDefaultMessage());
        });

        return R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(), BizCodeEnum.VAILD_EXCEPTION.getMsg()).put("data", errorMap);
    }

    @ExceptionHandler(value = Throwable.class)
    public R handleException(Throwable throwable) {
        return R.error(BizCodeEnum.UNKNOWN_EXCEPTION.getCode(), BizCodeEnum.UNKNOWN_EXCEPTION.getMsg());
    }
}

然后为品牌管理实体类gulimall-product/src/main/java/com/atguigu/gulimall/product/entity/BrandEntity添加校验注解。

最后,给新增/修改的接口方法的入参添加@Valid注解。

 使用postman进行测试。

3 分组校验

使用JSR-303实现分组校验,实际上就是group属性的用法,不实现了。

4 自定义校验

我觉得这部分内容对产品质量的提升不大,但是学习写自定义注解是有价值的。

品牌的显示状态字段showStatus的值必须是0或1。我们创建一个@ListValue注解来校验它。

  1. 编写一个自定义的校验注解
  2. 编写一个自定义的校验器
  3. 关联自定义的校验器和自定义的校验注解

在gulimall-common/src/main/java/com/atguigu/common/路径下创建valid/目录,在该目录下创建注解ListValue。

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@documented
// 指明该注解使用的校验器
@Constraint(validatedBy = {ListValueConstraintValidator.class})
// 指明该注解可以标注的位置
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
// 指明该注解生效的时机
@Retention(RetentionPolicy.RUNTIME)
public @interface ListValue {

    // 指明默认的错误信息
    String message() default "{com.atguigu.common.valid.ListValue.message}";

    // 支持分组校验功能
    Class[] groups() default {};

    // 自定义负载信息
    Class[] payload() default {};

    int[] values() default {};
}

在valid/目录下创建ListValueConstraintValidator类。

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;

public class ListValueConstraintValidator implements ConstraintValidator {

    private Set set = new HashSet<>();

    // 初始化方法
    @Override
    public void initialize(ListValue constraintAnnotation) {
        int[] values = constraintAnnotation.values();
        for (int val : values) {
            set.add(val);
        }
    }

    
    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return set.contains(value);
    }
}

在gulimall-common/src/main/resources/路径下创建配置文件ValidationMessages.properties。

com.atguigu.common.valid.ListValue.message=只能提交列举的值

重启gulimall-product服务,使用postman验证通过。

069 品牌管理-完整前端代码

brand.vue



brand-add-or-update.vue



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/630982.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号