Java --- 云尚优选项目

news2024/11/28 8:45:24

目录

一、项目工程搭建

二、配置项目相关maven依赖

2.1、cjc.ssyx父工程依赖 

 2.2、common模块pom依赖

2.3、common-util模块pom依赖

2.4、service-util模块pom依赖

2.5、model模块pom依赖

2.6、service模块pom依赖

三、编写相关工具类

3.1、mybatis-plus分页查询配置类 

3.2、统一返回结果类

3.3、统一异常处理类

3.4、编写Swagger配置类

四、尚上优先前端平台管理

4.1、node.js安装

4.2、安装vscode及相关插件 

 4.3、测试vue框架是否正常运行

4.4、导入前端项目并测试运行

五、后端登录功能

5.1、修改application.yml文件

5.2、修改application-dev.yml文件

5.3、后端登录功能接口编写

5.4、前端修改

5.5、运行报错解决

5.6、前后端跨域问题

5.7、测试访问

六、角色管理功能开发

6.1、分页条件查询 

6.2、增删改查功能

七、用户管理模块

7.1、用户的crud功能 

7.2、用户分配角色功能

八、菜单管理模块

8.1、查询菜单功能 

8.2、递归删除

8.3、添加与修改功能

8.4、为角色分配菜单

九、开通区域功能模块

9.1、使用代码生成器

9.2、查询区域开通列表功能

 9.3、添加开通区域及查询区域功能

9.4、取消与删除开通区域功能

十、配置nginx反向代理

十一、商品信息管理模块 

11.1、商品分类信息模块功能 

11.2、平台属性分组模块功能

11.3、平台属性管理模块功能

11.4、SKU列表模块 

11.4.1、SKU信息分页条件查询功能

11.4.2、开通阿里云对象存储OSS

11.4.2.1、创建自己的Bucket

11.4.2.2、创建自己的AccessKey

11.5.1、SKU图片上传功能


一、项目工程搭建

二、配置项目相关maven依赖

2.1、cjc.ssyx父工程依赖 

<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <skipTests>true</skipTests>
        <java.version>1.8</java.version>
        <cloud.version>Hoxton.SR8</cloud.version>
        <alibaba.version>2.2.2.RELEASE</alibaba.version>
        <mybatis-plus.version>3.4.1</mybatis-plus.version>
        <mysql.version>8.0.30</mysql.version>
        <jwt.version>0.7.0</jwt.version>
        <fastjson.version>2.0.21</fastjson.version>
        <httpclient.version>4.5.6</httpclient.version>
        <easyexcel.version>2.1.6</easyexcel.version>
        <aliyun.version>4.4.1</aliyun.version>
        <oss.version>3.9.1</oss.version>
        <knife4j.version>2.0.8</knife4j.version>
        <jodatime.version>2.10.10</jodatime.version>
        <xxl-job.version>2.3.0</xxl-job.version>
    </properties>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.6.RELEASE</version>
    </parent>

    <!--配置dependencyManagement锁定依赖的版本-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--mybatis-plus 持久层-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
                <version>2.0.8</version>
            </dependency>
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>${jwt.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>${httpclient.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>${easyexcel.version}</version>
            </dependency>
            <dependency>
                <groupId>com.aliyun</groupId>
                <artifactId>aliyun-java-sdk-core</artifactId>
                <version>${aliyun.version}</version>
            </dependency>
            <!--日期时间工具-->
            <dependency>
                <groupId>joda-time</groupId>
                <artifactId>joda-time</artifactId>
                <version>${jodatime.version}</version>
            </dependency>
            <dependency>
                <groupId>com.xuxueli</groupId>
                <artifactId>xxl-job-core</artifactId>
                <version>${xxl-job.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
  

 2.2、common模块pom依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>provided </scope>
        </dependency>

        <!--lombok用来简化实体类:需要安装lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- https://doc.xiaominfo.com/knife4j/documentation/ -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
        </dependency>

        <!--用来转换json使用 {JavaObject - json | json - JavaObject}-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>

        <!-- 服务调用feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <scope>provided </scope>
        </dependency>
    </dependencies>

2.3、common-util模块pom依赖

<dependencies>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
        </dependency>

        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>

        <dependency>
            <groupId>com.cjc</groupId>
            <artifactId>model</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

2.4、service-util模块pom依赖

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <scope>provided </scope>
        </dependency>

        <!--lombok用来简化实体类:需要安装lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- https://doc.xiaominfo.com/knife4j/documentation/ -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
        </dependency>

        <!--用来转换json使用 {JavaObject - json | json - JavaObject}-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>

        <!-- 服务调用feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <scope>provided </scope>
        </dependency>
    </dependencies>

2.5、model模块pom依赖

<dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <scope>provided </scope>
        </dependency>

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <!--在引用时请在maven中央仓库搜索2.X最新版本号-->
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <scope>provided </scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <scope>provided </scope>
        </dependency>

        <!--创建索引库的-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <scope>provided </scope>
        </dependency>
    </dependencies>

2.6、service模块pom依赖

   <dependencies>
        <!--依赖服务的工具类-->
        <dependency>
            <groupId>com.cjc</groupId>
            <artifactId>service-util</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--数据载体-->
        <dependency>
            <groupId>com.cjc</groupId>
            <artifactId>model</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--web 需要启动项目-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <!-- 服务注册 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!-- 服务调用feign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

        <!-- 流量控制 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

        <!--开发者工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

三、编写相关工具类

3.1、mybatis-plus分页查询配置类 

@Configuration
@MapperScan("com.cjc.ssyx.*.mapper")
public class MybatisPlusConfig {
    /**
     * 分页插件
     */
    @Bean
    public MybatisPlusInterceptor optimisticLockerInnerInterceptor(){
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //向Mybatis过滤器链中添加分页拦截器
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
    @Bean
    public ConfigurationCustomizer configurationCustomizer(){
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }
}

3.2、统一返回结果类

@Getter
public enum ResultCodeEnum {

    SUCCESS(200,"成功"),
    FAIL(201, "失败"),
    SERVICE_ERROR(2012, "服务异常"),
    DATA_ERROR(204, "数据异常"),
    ILLEGAL_REQUEST(205, "非法请求"),
    REPEAT_SUBMIT(206, "重复提交"),

    LOGIN_AUTH(208, "未登陆"),
    PERMISSION(209, "没有权限"),

    ORDER_PRICE_ERROR(210, "订单商品价格变化"),
    ORDER_STOCK_FALL(204, "订单库存锁定失败"),
    CREATE_ORDER_FAIL(210, "创建订单失败"),

    COUPON_GET(220, "优惠券已经领取"),
    COUPON_LIMIT_GET(221, "优惠券已发放完毕"),

    URL_ENCODE_ERROR( 216, "URL编码失败"),
    ILLEGAL_CALLBACK_REQUEST_ERROR( 217, "非法回调请求"),
    FETCH_ACCESSTOKEN_FAILD( 218, "获取accessToken失败"),
    FETCH_USERINFO_ERROR( 219, "获取用户信息失败"),


    SKU_LIMIT_ERROR(230, "购买个数不能大于限购个数"),
    REGION_OPEN(240, "该区域已开通"),
    REGION_NO_OPEN(240, "该区域未开通"),
    ;

    private Integer code;

    private String message;

    private ResultCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}
@Data
public class Result<T> {
    //状态码
    private Integer code;
    //信息
    private String message;
    //返回数据
    private T data;
    //构造方法私有化
    private Result(){

    }
    //统一返回信息方法
    public static<T> Result<T> build(T data,ResultCodeEnum resultCodeEnum){
        //设置值
        Result<T> result = new Result<>();
        //判断是否返回数据
        if(data != null){
            result.setData(data);
        }
        //设置状态码与信息
        result.setCode(resultCodeEnum.getCode());
        result.setMessage(resultCodeEnum.getMessage());
        return result;
    }
    //成功的方法
    public static<T> Result<T> ok(T data){
        Result<T> result = build(data, ResultCodeEnum.SUCCESS);
        return result;
    }
    //失败方法
    public static<T> Result<T> fail(T data){
        Result<T> result = build(data, ResultCodeEnum.FAIL);
        return result;
    }
}

3.3、统一异常处理类

//自定义异常信息
@Data
@ToString
public class CustomException extends RuntimeException{
    //异常状态码
    private Integer code;
    //通过状态码和错误消息创建异常对象
    public CustomException(String message,Integer code){
        super(message);
        this.code = code;
    }
    /**
     * 接收枚举类型对象
     * @param resultCodeEnum
     */
    public CustomException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
    }
    
}
@ControllerAdvice
public class GlobalExceptionHandler {
    //全局异常处理
    @ExceptionHandler(Exception.class)//异常处理器
    @ResponseBody//返回json数据
    public Result error(Exception e){
        e.printStackTrace();
        return Result.fail(null);
    }
    //自定义异常处理
    @ExceptionHandler(CustomException.class)
    @ResponseBody
   public Result error(CustomException e){
       return Result.fail(null);
   }
}

3.4、编写Swagger配置类

@Configuration
@EnableSwagger2WebMvc
public class Swagger2Config {

    @Bean
    public Docket webApiConfig(){
        List<Parameter> pars = new ArrayList<>();
        ParameterBuilder tokenPar = new ParameterBuilder();
        tokenPar.name("userId")
                .description("用户token")
                //.defaultValue(JwtHelper.createToken(1L, "admin"))
                .defaultValue("1")
                .modelRef(new ModelRef("string"))
                .parameterType("header")
                .required(false)
                .build();
        pars.add(tokenPar.build());

        Docket webApi = new Docket(DocumentationType.SWAGGER_2)
                .groupName("webApi")
                .apiInfo(webApiInfo())
                .select()
                //只显示api路径下的页面
                .apis(RequestHandlerSelectors.basePackage("com.cjc.ssyx"))
                .paths(PathSelectors.regex("/api/.*"))
                .build()
                .globalOperationParameters(pars);
        return webApi;
    }

    @Bean
    public Docket adminApiConfig(){
        List<Parameter> pars = new ArrayList<>();
        ParameterBuilder tokenPar = new ParameterBuilder();
        tokenPar.name("adminId")
                .description("用户token")
                .defaultValue("1")
                .modelRef(new ModelRef("string"))
                .parameterType("header")
                .required(false)
                .build();
        pars.add(tokenPar.build());

        Docket adminApi = new Docket(DocumentationType.SWAGGER_2)
                .groupName("adminApi")
                .apiInfo(adminApiInfo())
                .select()
                //只显示admin路径下的页面
                .apis(RequestHandlerSelectors.basePackage("com.cjc.ssyx"))
                .paths(PathSelectors.regex("/admin/.*"))
                .build()
                .globalOperationParameters(pars);
        return adminApi;
    }

    private ApiInfo webApiInfo(){
        return new ApiInfoBuilder()
                .title("网站-API文档")
                .description("本文档描述了尚上优选网站微服务接口定义")
                .version("1.0")
                .contact(new Contact("cjc", "http://cjc.com", "cjc"))
                .build();
    }

    private ApiInfo adminApiInfo(){
        return new ApiInfoBuilder()
                .title("后台管理系统-API文档")
                .description("本文档描述了尚上优选后台系统服务接口定义")
                .version("1.0")
                .contact(new Contact("cjc", "http://cjc.com", "cjc"))
                .build();
    }
}

四、尚上优先前端平台管理

4.1、node.js安装

4.2、安装vscode及相关插件 

 

 4.3、测试vue框架是否正常运行

#全局安装命令行工具
npm install --location=global @vue/cli
#创建一个项目
vue create vue-test #选择vue2
#进入到项目目录
cd vue-test
#启动程序
npm run serve

PS D:\vue\cjc-ssyx\test> vue create vue-test
vue : 无法加载文件 D:\tools\nodejs\node_global\vue.ps1。未对文件 D:\tools\nodejs\node_global\vue.ps1 进行数字签名。无法在当前系统上运行该脚本。有关运行脚本和设置
执行策略的详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。
所在位置 行:1 字符: 1
+ vue create vue-test
+ ~~~
    + CategoryInfo          : SecurityError: (:) [],PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess 

解决办法:以管理员的方式运行即可

 最终效果

4.4、导入前端项目并测试运行

运行指令:npm run dev

五、后端登录功能

5.1、修改application.yml文件

spring:
  application:
    name: service-acl
  profiles:
    active: dev

5.2、修改application-dev.yml文件

server:
  port: 8081

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/shequ-acl?characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456

  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

5.3、后端登录功能接口编写

@Api(tags = "登录功能模块")
@RestController
@RequestMapping("/admin/acl/index")
public class IndexController {
    /**
     * 登录功能
     * @return map
     */
    @ApiOperation("登录功能")
    @PostMapping("/login")
    public Result login(){
        //返回token值
        HashMap<String,String> map = new HashMap<>();
        map.put("token","token-test");
        return Result.ok(map);
    }

    /**
     * 获取信息
     * @return
     */
    @ApiOperation("获取信息")
    @GetMapping("/info")
    public Result info(){
        HashMap<String, String> map = new HashMap<>();
        map.put("name","admin");
        map.put("avatar","https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        return Result.ok(map);
    }

    /**
     * 退出
     * @return
     */
    @ApiOperation("退出")
    @PostMapping("/logout")
    public Result logout(){
       return Result.ok(null);
    }
}

5.4、前端修改

5.5、运行报错解决

com.alibaba.nacos.api.exception.NacosException: failed to req API:/nacos/v1/ns/instance after all servers([localhost:8848]) tried: java.net.ConnectException: Connection refused: connect
    at com.alibaba.nacos.client.naming.net.NamingProxy.reqApi(NamingProxy.java:552) ~[nacos-client-1.3.2.jar:na]
    at com.alibaba.nacos.client.naming.net.NamingProxy.reqApi(NamingProxy.java:491) ~[nacos-client-1.3.2.jar:na]
    at com.alibaba.nacos.client.naming.net.NamingProxy.reqApi(NamingProxy.java:486) ~[nacos-client-1.3.2.jar:na]
    at com.alibaba.nacos.client.naming.net.NamingProxy.registerService(NamingProxy.java:239) ~[nacos-client-1.3.2.jar:na]
    at com.alibaba.nacos.client.naming.NacosNamingService.registerInstance(NacosNamingService.java:200) ~[nacos-client-1.3.2.jar:na] 

解决办法:注销相关依赖

 

5.6、前后端跨域问题

Access to XMLHttpRequest at 'http://localhost:8081/admin/acl/index/login' from origin 'http://localhost:9528' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. 

 解决方法:

5.7、测试访问

六、角色管理功能开发

6.1、分页条件查询 

 mapper接口

@Mapper
public interface RoleMapper extends BaseMapper<Role> {
}

 service接口

public interface RoleService extends IService<Role> {
    IPage<Role> selectRolePage(Page<Role> page, RoleQueryVo roleQueryVo);
}

service接口实现类

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    //分页条件查询
    @Override
    public IPage<Role> selectRolePage(Page<Role> page, RoleQueryVo roleQueryVo) {
        //获取查询条件值
        String roleName = roleQueryVo.getRoleName();
        //条件封装
        LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
        //判断是否为空
        if (!StringUtils.isEmpty(roleName)){
            wrapper.like(Role::getRoleName,roleName);
        }
        //调用方法查询
        Page<Role> rolePage = baseMapper.selectPage(page, wrapper);
        return rolePage;
    }
}

controller层

@Api(tags = "角色管理模块")
@RestController
@RequestMapping("/admin/acl/role")
@CrossOrigin
public class RoleController {
    @Autowired
    private RoleService roleService;

    /**
     *
     * @param current 当前页
     * @param limit 每页显示记录数
     * @param roleQueryVo 条件对象
     * @return
     */
    @ApiOperation("分页查询")
    @GetMapping("/{current}/{limit}")
    public Result pageList(@PathVariable("current") Long current,
                           @PathVariable("limit") Long limit,
                           RoleQueryVo roleQueryVo){
        //创建分页对象
        Page<Role> page = new Page<>(current,limit);
        //调用方法实现分页查询
        IPage<Role> roleIPage = roleService.selectRolePage(page,roleQueryVo);
        return Result.ok(roleIPage);
    }
}

测试结果:

6.2、增删改查功能

@ApiOperation("根据id查询")
    @GetMapping("/get/{id}")
    public Result selectRoleById(@PathVariable("id") Long id){
        Role role = roleService.getById(id);
        return Result.ok(role);
    }
    
    @ApiOperation("添加角色")
    @PostMapping("/save")
    public Result saveRole(@RequestBody Role role){
        boolean save = roleService.save(role);
        if (save){
            return Result.ok(null); 
        }else {
            return Result.fail(null);
        }
    }
    @ApiOperation("修改角色")
    @PutMapping("/update")
    public Result updateRole(@RequestBody Role role){
        boolean update = roleService.updateById(role);
        if (update){
            return Result.ok(null);
        }else {
            return Result.fail(null);
        }
    }
    @ApiOperation("根据id删除")
    @DeleteMapping("/remove/{id}")
    public Result removeRoleById(@PathVariable("id") Long id){
        boolean remove = roleService.removeById(id);
        if (remove){
            return Result.ok(null);
        }else {
            return Result.fail(null);
        }
    }
    @ApiOperation("根据id批量删除")
    @DeleteMapping("/batchRemove")
    public Result removeByList(@RequestBody List<Long> idList){
        boolean removeByIds = roleService.removeByIds(idList);
        if (removeByIds){
            return Result.ok(null);
        }else {
            return Result.fail(null);
        }
    }

 后端接口测试以添加为例:

七、用户管理模块

7.1、用户的crud功能 

 service实现类层

@Service
public class AdminServiceImpl extends ServiceImpl<AdminMapper, Admin> implements AdminService {
    //分页条件查询
    @Override
    public IPage<Admin> selectAdminPage(Page<Admin> page, AdminQueryVo adminQueryVo) {
        String name = adminQueryVo.getName();
        String username = adminQueryVo.getUsername();
        LambdaQueryWrapper<Admin> wrapper = new LambdaQueryWrapper<>();
        if (!StringUtils.isEmpty(name)){
            wrapper.like(Admin::getName,name);
        }
        if (!StringUtils.isEmpty(username)){
            wrapper.like(Admin::getUsername,username);
        }
        Page<Admin> adminPage = baseMapper.selectPage(page, wrapper);
        return adminPage;
    }
}

controller层

@Api(tags = "用户管理模块")
@RestController
@RequestMapping("/admin/acl/user")
@CrossOrigin
public class AdminController {
    @Autowired
    private AdminService adminService;

    @ApiOperation("分页查询用户")
    @GetMapping("/{current}/{limit}")
    public Result getAdmin(@PathVariable("current") Long current,
                           @PathVariable("limit") Long limit,
                           AdminQueryVo adminQueryVo){
        Page<Admin> page = new Page<>(current,limit);
        IPage<Admin> adminIPage = adminService.selectAdminPage(page,adminQueryVo);
        return Result.ok(adminIPage);
    }
    @ApiOperation("根据id查询")
    @GetMapping("/get/{id}")
    public Result getAdminById(@PathVariable("id") Long id){
        Admin admin = adminService.getById(id);
        return Result.ok(admin);
    }
    @ApiOperation("添加用户")
    @PostMapping("/save")
    public Result saveAdmin(@RequestBody Admin admin){
       //获取用户密码并进行加密处理
        admin.setPassword(MD5.encrypt(admin.getPassword()));
        boolean save = adminService.save(admin);
        if (save){
            return Result.ok(null);
        }else {
            return Result.fail(null);
        }
    }
    @ApiOperation("修改用户")
    @PutMapping("/update")
    public Result updateAdmin(@RequestBody Admin admin){
        //获取用户密码并进行加密处理
        admin.setPassword(MD5.encrypt(admin.getPassword()));
        boolean update = adminService.updateById(admin);
        if (update){
            return Result.ok(null);
        }else {
            return Result.fail(null);
        }
    }
    @ApiOperation("根据id删除用户")
    @DeleteMapping("/delete/{id}")
    public Result removeById(@PathVariable("id") Long id){
        boolean remove = adminService.removeById(id);
        if (remove){
            return Result.ok(null);
        }else {
            return Result.fail(null);
        }
    }
    @ApiOperation("根据id批量删除用户")
    @DeleteMapping("/batchRemove")
    public Result removeByBatch(@RequestBody List<Long> idList){
        boolean removeByIds = adminService.removeByIds(idList);
        if (removeByIds){
            return Result.ok(null);
        }else {
            return Result.fail(null);
        }
    }
}

接口测试以添加为例:

前端界面效果:

7.2、用户分配角色功能

 功能分析图:

功能实现:

service实现类 

 //查询所有角色和根据用户id查询分配角色
    @Override
    public Map<String, Object> getRoleByAdminId(Long adminId) {
        HashMap<String, Object> map = new HashMap<>();
        //查询所有角色
        List<Role> roles = baseMapper.selectList(null);
        //根据用户id查询用户分配角色列表
        LambdaQueryWrapper<AdminRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminRole::getAdminId,adminId);
        List<AdminRole> adminRoleList = adminRoleService.list(wrapper);
        //获取角色关系表里的所有角色id,封装为list集合
        List<Long> roleIdList = adminRoleList.stream().map(c -> c.getRoleId()).collect(Collectors.toList());
        //创建list集合,用于存储用户分配角色
        ArrayList<Role> roleList = new ArrayList<>();
        //判断所有角色中已经分配了的角色id
        for (Role role : roles) {
            //判断是否存在
            if(roleIdList.contains(role.getId())){
                roleList.add(role);
            }
        }
        //封装数据并返回
        map.put("allRolesList",roles);
        map.put("assignRoles",roleList);
        return map;
    }
    //为用户分配角色
    @Override
    public void saveAdminRole(Long adminId, Long[] roleIds) {
        //删除用户已经分配过的角色id
        LambdaQueryWrapper<AdminRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AdminRole::getAdminId,adminId);
        adminRoleService.remove(wrapper);
        ArrayList<AdminRole> arrayList = new ArrayList<>();
        //重新分配
        for (Long roleId : roleIds) {
            AdminRole adminRole = new AdminRole();
            adminRole.setAdminId(adminId);
            adminRole.setRoleId(roleId);
            arrayList.add(adminRole);
        }
        //批量添加
        adminRoleService.saveBatch(arrayList);
    }

controller层

@ApiOperation("获取用户角色")
    @GetMapping("/toAssign/{adminId}")
    public Result toAssign(@PathVariable("adminId") Long adminId){
        Map<String,Object> map = roleService.getRoleByAdminId(adminId);
        return Result.ok(map);
    }
    @ApiOperation("为用户分配角色")
    @PostMapping("/doAssign")
    public Result doAssign(@RequestParam Long adminId,
                           @RequestParam Long[] roleIds){
       roleService.saveAdminRole(adminId,roleIds);
        return Result.ok(null);
    }

前端效果图:

八、菜单管理模块

8.1、查询菜单功能 

数据格式工具类

public class PermissionHelper {
    //构建树形格式
    public static List<Permission> buildPermission(List<Permission> permissionList) {
        //存储最终数据格式
        List<Permission> trees = new ArrayList<>();
        for (Permission permission : permissionList) {
            //判断是否为第一层
            if (permission.getPid() == 0){
                permission.setLevel(1);
                //调用递归方法,并封装存放数据
                trees.add(findChildren(permission,permissionList));
            }
        }
        return trees;
    }

    /**
     *
     * @param permission 上级菜单
     * @param permissionList 所有菜单
     * @return
     */
    //递归查找子菜单
    private static Permission findChildren(Permission permission, List<Permission> permissionList) {
       permission.setChildren(new ArrayList<Permission>());
       //遍历所有菜单数据
        for (Permission p : permissionList) {
            //判断是否有下一级菜单
            if (permission.getId().equals(p.getPid())){
                int level = permission.getLevel() + 1;
                p.setLevel(level);
                if (permission.getChildren() == null){
                    permission.setChildren(new ArrayList<>());
                }
                //封装下一层数据,并递归查找
                permission.getChildren().add( findChildren(p,permissionList));

            }
        }
        return permission;
    }
}

 service实现类

 //查询所有菜单
    @Override
    public List<Permission> queryAllPermission() {
        //查询所有菜单
        List<Permission> permissionList = baseMapper.selectList(null);
        //转换数据格式
        List<Permission> result = PermissionHelper.buildPermission(permissionList);
        return result;
    }

controller层:

 @ApiOperation("查询所有菜单")
    @GetMapping()
    public Result queryAll(){
        List<Permission> list = permissionService.queryAllPermission();
        return Result.ok(list);
    }

接口测试:

8.2、递归删除

/**
     * 递归删除菜单
     * @param id 菜单id
     */
    @Override
    public void removeChildById(Long id) {
        //存放需要删除的菜单id
        ArrayList<Long> idList = new ArrayList<>();
        //递归查找子菜单
        this.getAllPermissionId(id,idList);
        //设置当前菜单id
        idList.add(id);
        //批量删除
        baseMapper.deleteBatchIds(idList);
    }

    /**
     * 递归查询当前菜单下的子菜单
     * @param id 当前菜单id
     * @param idList 所有菜单id集合
     */
    public void getAllPermissionId(Long id,List<Long> idList){
        //根据当前菜单id查询下面的子菜单
        LambdaQueryWrapper<Permission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Permission::getPid,id);
        List<Permission> childList = baseMapper.selectList(wrapper);
        //递归查询子菜单
        childList.stream().forEach(c -> {
            //封装菜单id
            idList.add(c.getId());
            //递归查询
            this.getAllPermissionId(c.getId(),idList);
        });
    }
@ApiOperation("删除菜单(递归删除)")
    @DeleteMapping("/remove/{id}")
    public Result deletePermission(@PathVariable("id") Long id){
        permissionService.removeChildById(id);
        return Result.ok(null);
    }

8.3、添加与修改功能

 @ApiOperation("添加菜单")
    @PostMapping("/save")
    public Result savePermission(@RequestBody Permission permission){
         permissionService.save(permission);
        return Result.ok(null);
    }
    @ApiOperation("修改菜单")
    @PutMapping("/update")
    public Result updatePermission(@RequestBody Permission permission){
        permissionService.updateById(permission);
        return Result.ok(null);
    }

前端效果图:

8.4、为角色分配菜单

service实现类

/**
     * 查询角色及所属菜单
     * @param roleId 角色id
     * @return
     */
    @Override
    public List<Permission> getPermissionByRoleId(Long roleId) {
        //查询所有菜单
        List<Permission> permissions = baseMapper.selectList(null);
        //根绝角色id查询菜单id
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId,roleId);
        List<RolePermission> rolePermissionList = rolePermissionService.list(wrapper);
        //获取到菜单id
        List<Long> permissionIdList = rolePermissionList.stream().map(c -> c.getPermissionId()).collect(Collectors.toList());
        permissions.stream().forEach(c->{
            if (permissionIdList.contains(c.getId())){
                c.setSelect(true);
            }else {
                c.setSelect(false);
            }
        });
        //封装为树形结构
        List<Permission> permissionList = PermissionHelper.buildPermission(permissions);
        return permissionList;
    }

    /**
     * 为角色分配菜单
     * @param roleId 角色id
     * @param permissionId 菜单id集合
     */
    @Override
    public void doAssign(Long roleId, Long[] permissionId) {
        //根据角色id删除菜单角色表里数据
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId,roleId);
        rolePermissionService.remove(wrapper);
        ArrayList<RolePermission> list = new ArrayList<>();
        //获取角色分配的菜单id,并存入
        for (Long id : permissionId) {
            if (id == null){
                continue;
            }
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(id);
            list.add(rolePermission);
        }
        //添加到表中
        rolePermissionService.saveBatch(list);
    }

controller层

@ApiOperation("获取菜单列表")
    @GetMapping("/toAssign/{roleId}")
    public Result toAssign(@PathVariable("roleId") Long roleId){
        List<Permission> list = permissionService.getPermissionByRoleId(roleId);
        return Result.ok(list);
    }
    @ApiOperation("角色分配菜单")
    @PostMapping("/doAssign")
    public Result doAssign(@RequestParam("roleId") Long roleId,
                           @RequestParam("permissionId") Long[] permissionId){

        permissionService.doAssign(roleId,permissionId);
        return Result.ok(null);
    }

前端效果图:

九、开通区域功能模块

需要的表

 

9.1、使用代码生成器

 导入pom依赖

	<dependency>
		<groupId>com.baomidou</groupId>
		<artifactId>mybatis-plus-generator</artifactId>
		<version>3.4.1</version>
	</dependency>

	<dependency>
		<groupId>org.apache.velocity</groupId>
		<artifactId>velocity-engine-core</artifactId>
		<version>2.0</version>
	</dependency>
public class CodeGet {

    public static void main(String[] args) {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir("D:\\java17\\cjc-ssyx\\service\\service-sys"+"/src/main/java");

        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setAuthor("cjc");
        gc.setOpen(false);
        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/shequ-sys?serverTimezone=GMT%2B8&useSSL=false");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.cjc.ssyx");
        pc.setModuleName("sys"); //模块名
        pc.setController("controller");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();

        strategy.setInclude("region","ware","region_ware");

        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式操作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        mpg.setStrategy(strategy);

        // 6、执行
        mpg.execute();
    }
}

9.2、查询区域开通列表功能

service实现类

/**
     * 查询开通区域列表
     * @param warePage 分页条件
     * @param regionWareQueryVo  条件搜索
     * @return
     */
    @Override
    public IPage<RegionWare> selectAllRegionWare(Page<RegionWare> warePage, RegionWareQueryVo regionWareQueryVo) {
        LambdaQueryWrapper<RegionWare> wrapper = new LambdaQueryWrapper<>();
        String keyword = regionWareQueryVo.getKeyword();
        //判断输入条件是否为空
        if (!StringUtils.isEmpty(keyword)){
            //封装条件 or()表示或者
            wrapper.like(RegionWare::getRegionName,keyword).or().like(RegionWare::getWareName,keyword);
        }
        //分页查询
        Page<RegionWare> regionWarePage = baseMapper.selectPage(warePage, wrapper);
        return regionWarePage;
    }

 controller层

 /**
     *
     * @param page 页数
     * @param limit 条数
     * @param regionWareQueryVo 搜索条件
     * @return
     */
    @ApiOperation("分页查询开通区域列表")
    @GetMapping("/{page}/{limit}")
    public Result getAll(@PathVariable("page") Long page,
                         @PathVariable("limit") Long limit,
                         RegionWareQueryVo regionWareQueryVo){
        Page<RegionWare> warePage = new Page<>(page,limit);
        IPage<RegionWare> list = regionWareService.selectAllRegionWare(warePage,regionWareQueryVo);
        return Result.ok(list);
    }

 接口测试:

 9.3、添加开通区域及查询区域功能

 service实现类

 /**
     * 添加开通区域
     * @param regionWare
     */
    @Override
    public void saveRegionWare(RegionWare regionWare) {
        //判断区域是否开通
        LambdaQueryWrapper<RegionWare> wrapper = new LambdaQueryWrapper<>();
        //一个区域可以开通多个仓库
        wrapper.eq(RegionWare::getWareId,regionWare.getWareId()).eq(RegionWare::getRegionId,regionWare.getRegionId());
        Integer count = baseMapper.selectCount(wrapper);
        //已经开通
        if (count > 0){
            //抛出自定义异常
          throw new CustomException(ResultCodeEnum.REGION_OPEN);
        }
        //报存信息
        baseMapper.insert(regionWare);
    }
/**
     * 根据条件查询区域
     * @param keyword
     * @return
     */
    @Override
    public List<Region> findRegionByKeyword(String keyword) {
        LambdaQueryWrapper<Region> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Region::getName,keyword);
        List<Region> regionList = baseMapper.selectList(wrapper);
        return regionList;
    }

controller层

@ApiOperation("根据条件查询区域")
    @GetMapping("/findRegionByKeyword/{keyword}")
    public Result findRegionByKeyword(@PathVariable("keyword") String keyword){
        List<Region> regionList =  regionService.findRegionByKeyword(keyword);
        return Result.ok(regionList);
    }
 @ApiOperation("添加开通区域")
    @PostMapping("/save")
    public Result saveRegionWare(@RequestBody RegionWare regionWare){
        regionWareService.saveRegionWare(regionWare);
        return Result.ok(null);
    }
 @ApiOperation("查询所有仓库")
    @GetMapping("/findAllList")
    public Result allWare(){
        List<Ware> list = wareService.list();
        return Result.ok(list);
    }

接口测试:

9.4、取消与删除开通区域功能

/**
     * 取消开通区域
     * @param id
     * @param status
     */
    @Override
    public void updateStatus(Long id, Integer status) {
        RegionWare regionWare = baseMapper.selectById(id);
        regionWare.setStatus(status);
        baseMapper.updateById(regionWare);
    }
@ApiOperation("删除开通区域")
    @DeleteMapping("/remove/{id}")
    public Result removeRegionWare(@PathVariable("id") Long id){
        regionWareService.removeById(id);
        return Result.ok(null);
    }
    @ApiOperation("取消开通区域")
    @PostMapping("/updateStatus/{id}/{status}")
    public Result updateStatus(@PathVariable("id") Long id,
                               @PathVariable("status") Integer status){
        regionWareService.updateStatus(id,status);
        return Result.ok(null);
    }

十、配置nginx反向代理

在配置文件中配置

 文件内容:

server {
        listen       9001;
        server_name  192.168.200.110;

        location ~ /acl/ {
            proxy_pass http://192.168.200.1:8081;
        }

        location ~ /sys/ {
            proxy_pass http://192.168.200.1:8082;
        }
    }

修改前端:

测试效果:

十一、商品信息管理模块 

11.1、商品分类信息模块功能 

 service实现类:

/**
     * 查询商品分类列表
     * @param categoryPage 分页条件
     * @param categoryQueryVo 查询条件
     * @return
     */
    @Override
    public IPage<Category> selectCategoryPage(Page<Category> categoryPage, CategoryQueryVo categoryQueryVo) {
        LambdaQueryWrapper<Category> wrapper = new LambdaQueryWrapper<>();
        String name = categoryQueryVo.getName();
        if (!StringUtils.isEmpty(name)){
            wrapper.like(Category::getName,name);
        }
        Page<Category> category = baseMapper.selectPage(categoryPage, wrapper);
        return category;
    }

controller层 

@Api(tags = "商品信息分类管理模块")
@RestController
@RequestMapping("admin/product/category")
@CrossOrigin
public class CategoryController {
    @Autowired
    private CategoryService categoryService;

    @ApiOperation("商品分类列表")
    @GetMapping("/{page}/{limit}")
    public Result allCategoryPage(@PathVariable("page") Long page,
                                  @PathVariable("limit") Long limit,
                                  CategoryQueryVo categoryQueryVo){
        Page<Category> categoryPage = new Page<>(page,limit);
        IPage<Category> categoryIPage = categoryService.selectCategoryPage(categoryPage,categoryQueryVo);
        return Result.ok(categoryIPage);
    }
    @ApiOperation("根据id查询商品分类信息")
    @GetMapping("/get/{id}")
    public Result getById(@PathVariable("id") Long id){
        Category category = categoryService.getById(id);
        return Result.ok(category);
    }
    @ApiOperation("添加商品分类")
    @PostMapping("/save")
    public Result saveCategory(@RequestBody Category category){
        categoryService.save(category);
        return Result.ok(null);
    }
    @ApiOperation("修改商品分类")
    @PutMapping("/update")
    public Result updateById(@RequestBody Category category){
        categoryService.updateById(category);
        return Result.ok(null);
    }
    @ApiOperation("删除商品分类")
    @DeleteMapping("/remove/{id}")
    public Result removeById(@PathVariable("id") Long id){
        categoryService.removeById(id);
        return Result.ok(null);
    }
    @ApiOperation("根据id批量删除")
    @DeleteMapping("/batchRemove")
    public Result batchRemove(@RequestBody List<Long> idList){
        categoryService.removeByIds(idList);
        return Result.ok(null);
    }
    @ApiOperation("查询所有商品分类")
    @GetMapping("/findAllList")
    public Result findAllList(){
        List<Category> list = categoryService.list();
        return Result.ok(list);
    }
}

配置nginx反向代理

前端测试效果:

11.2、平台属性分组模块功能

service实现类

/**
     * 分页查询平台属性分组
     * @param groupPage
     * @param attrGroupQueryVo
     * @return
     */
    @Override
    public IPage<AttrGroup> selectAttrGroupPage(Page<AttrGroup> groupPage, AttrGroupQueryVo attrGroupQueryVo) {
        LambdaQueryWrapper<AttrGroup> wrapper = new LambdaQueryWrapper<>();
        String name = attrGroupQueryVo.getName();
        if (!StringUtils.isEmpty(name)){
            wrapper.like(AttrGroup::getName,name);
        }
        Page<AttrGroup> attrGroupPage = baseMapper.selectPage(groupPage, wrapper);
        return attrGroupPage;
    }

    /**
     * 根据id降序查询所有平台属性分组
     * @return
     */
    @Override
    public List<AttrGroup> findAllList() {
        QueryWrapper<AttrGroup> wrapper = new QueryWrapper<>();
        //根据id降序查询
        wrapper.orderByAsc("id");
        List<AttrGroup> attrGroupList = baseMapper.selectList(wrapper);
        return attrGroupList;
    }

controller层

@Api(tags = "平台属性分组模块")
@RestController
@RequestMapping("admin/product/attrGroup")
@CrossOrigin
public class AttrGroupController {
    @Autowired
    private AttrGroupService attrGroupService;
    @ApiOperation("分页查询平台属性分组")
    @GetMapping("/{page}/{limit}")
    public Result allAttrGroupPage(@PathVariable("page") Long page,
                                   @PathVariable("limit") Long limit,
                                   AttrGroupQueryVo attrGroupQueryVo){
        Page<AttrGroup> groupPage = new Page<>(page,limit);
        IPage<AttrGroup> attrGroupPage = attrGroupService.selectAttrGroupPage(groupPage,attrGroupQueryVo);
        return Result.ok(attrGroupPage);
    }
    @ApiOperation("查询所有平台属性")
    @GetMapping("/findAllList")
    public Result findAllList(){
        List<AttrGroup> list = attrGroupService.findAllList();
        return Result.ok(list);
    }
    @ApiOperation("根据id查询")
    @GetMapping("/get/{id}")
    public Result getById(@PathVariable("id") Long id){
        AttrGroup attrGroup = attrGroupService.getById(id);
        return Result.ok(attrGroup);
    }
    @ApiOperation("添加平台属性分组")
    @PostMapping("/save")
    public Result saveAttrGroup(@RequestBody AttrGroup attrGroup){
        attrGroupService.save(attrGroup);
        return Result.ok(null);
    }
    @ApiOperation("修改平台属性分组")
    @PutMapping("/update")
    public Result updateAttrGroup(@RequestBody AttrGroup attrGroup){
        attrGroupService.updateById(attrGroup);
        return Result.ok(null);
    }
    @ApiOperation("删除平台属性分组")
    @DeleteMapping("/remove/{id}")
    public Result remove(@PathVariable("id") Long id){
        attrGroupService.removeById(id);
        return Result.ok(null);
    }
    @ApiOperation("批量删除平台属性分组")
    @DeleteMapping("/batchRemove")
    public Result batchRemove(@RequestBody List<Long> idList){
        attrGroupService.removeByIds(idList);
        return Result.ok(null);
    }
}

前端效果图:

11.3、平台属性管理模块功能

service实现类

/**
     * 查询平台属性列表
     * @param groupId 平台属性分组id
     * @return
     */
    @Override
    public List<Attr> selectAttrByGroupId(Long groupId) {
        LambdaQueryWrapper<Attr> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Attr::getAttrGroupId, groupId);
        List<Attr> attrList = baseMapper.selectList(wrapper);
        return attrList;
    }

 controller层

@Api(tags = "平台属性管理模块")
@RestController
@RequestMapping("admin/product/attr")
@CrossOrigin
public class AttrController {
    @Autowired
    private AttrService attrService;

    @ApiOperation("根据平台属性分组id查询")
    @GetMapping("/{groupId}")
    public Result queryAttrByGroupId(@PathVariable("groupId") Long groupId){
        List<Attr> list = attrService.selectAttrByGroupId(groupId);
        return Result.ok(list);
    }
    @ApiOperation("根据id查询平台属性")
    @GetMapping("/get/{id}")
    public Result getById(@PathVariable("id") Long id){
        Attr attr = attrService.getById(id);
        return Result.ok(attr);
    }
    @ApiOperation("添加平台属性")
    @PostMapping("/save")
    public Result saveAttr(@RequestBody Attr attr){
        attrService.save(attr);
        return Result.ok(null);
    }
    @ApiOperation("修改平台属性")
    @PutMapping("/update")
    public Result updateAttr(@RequestBody Attr attr){
        attrService.updateById(attr);
        return Result.ok(null);
    }
    @ApiOperation("删除平台属性")
    @DeleteMapping("/remove/{id}")
    public Result removeById(@PathVariable("id") Long id){
        attrService.removeById(id);
        return Result.ok(null);
    }
    @ApiOperation("批量删除平台属性")
    @DeleteMapping("/batchRemove")
    public Result batchRemove(@RequestBody List<Long> id){
        attrService.removeByIds(id);
        return Result.ok(null);
    }
}

前端效果图:

11.4、SKU列表模块 

11.4.1、SKU信息分页条件查询功能

service实现类 

/**
     * 分页条件查询SKU信息
     * @param skuInfoPage
     * @param skuInfoQueryVo
     * @return
     */
    @Override
    public IPage<SkuInfo> selectAllSKUPage(Page<SkuInfo> skuInfoPage, SkuInfoQueryVo skuInfoQueryVo) {
        LambdaQueryWrapper<SkuInfo> wrapper = new LambdaQueryWrapper<>();
        Long categoryId = skuInfoQueryVo.getCategoryId();
        String skuType = skuInfoQueryVo.getSkuType();
        String keyword = skuInfoQueryVo.getKeyword();
        //封装查询条件
        if (!StringUtils.isEmpty(categoryId)){
            wrapper.like(SkuInfo::getCategoryId,categoryId);
        }
        if (!StringUtils.isEmpty(skuType)){
            wrapper.like(SkuInfo::getSkuType,skuType);
        }
        if (!StringUtils.isEmpty(keyword)){
            wrapper.like(SkuInfo::getSkuName,keyword);
        }
        Page<SkuInfo> skuInfoPageList = baseMapper.selectPage(skuInfoPage, wrapper);
        return skuInfoPageList;
    }

 controller层

@ApiOperation("sku信息分页条件查询")
    @GetMapping("/{page}/{limit}")
    public Result allSKUPage(@PathVariable Long page,
                             @PathVariable Long limit,
                             SkuInfoQueryVo skuInfoQueryVo){
        Page<SkuInfo> skuInfoPage = new Page<>(page,limit);
        IPage<SkuInfo> skuInfoIPage = skuInfoService.selectAllSKUPage(skuInfoPage,skuInfoQueryVo);
        return Result.ok(skuInfoIPage);
    }

前端效果图:

 

11.4.2、开通阿里云对象存储OSS

11.4.2.1、创建自己的Bucket

11.4.2.2、创建自己的AccessKey

11.5.1、SKU图片上传功能

导入pom依赖

<!--阿里云oss-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>
        <!--日期工具栏-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.3</version>
        </dependency>

 修改yml配置文件

aliyun:
  endpoint: 自己bucket地域节点
  keyid: 自己的AccessKey
  keysecret: 自己的AccessKey的secret
  bucketname: 自己的bucket名字

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

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

相关文章

SpringMVC学习笔记一

目录 一、SpringMVC概述二、入门案例1.导入相关依赖2.配置web.xml3.配置SpringMVC4.创建测试用的html页面5.编写Controller 三、请求映射规则RequestMapping1.RequestMapping注解标识的位置2.RequestMapping注解value属性3.RequestMapping注解的method属性4.RequestMapping注解…

Vector - CANoe - 测试报告配置

目录 一、测试报告格式设置 二、测试报告格式转换 1、Test Report Viewer format 转换为 PDF 格式

【ELK 企业级日志分析系统】

目录 一、ELK 概述1、ELK 简介1、可以添加的其它组件&#xff1a;2、filebeat 结合 logstash 带来好处&#xff1a; 2、为什么要使用 ELK3、完整日志系统基本特征4、ELK 的工作原理 二、实验操作1、ELK Elasticsearch 集群部署&#xff08;在Node1、Node2节点上操作&#xff09…

【SpringBoot_Error】关于SpringBoot项目中经常出现yml/xml识别不到的问题

Problems 关于关于SpringBoot项目中经常出现yml/xml识别不到的问题 Solution 在pom.xml文件的<build></build>标签中添加如下代码&#xff1a; > <build><resources><!--检测mapperxml&#xff0c;本项目数据访问层的SQL xml文件放在Java包…

雷达人体存在感应器成品,雷达探测感知联动,空间智能化控制应用

随着科技的日新月异&#xff0c;人机交互的方式也不断推陈出新。在科技的不断发展与创新的驱动下&#xff0c;人们的生活正逐渐变得更加智能化和便捷化。 智能雷达人体存在感应器&#xff0c;凭借其呼吸探测技术&#xff0c;实现真正的人体存在探测&#xff0c;将智慧酒店、办…

C# 位1的个数

191 位1的个数 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 ‘1’ 的个数&#xff08;也被称为汉明重量&#xff09;。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;…

浅谈虚拟DOM、Diff算法、Key机制

您好&#xff0c;如果喜欢我的文章&#xff0c;可以关注我的公众号「量子前端」&#xff0c;将不定期关注推送前端好文~ 虚拟DOM 我们都知道虚拟DOM带来的好处&#xff0c;多次更新数据层的数据&#xff0c;最后异步处理只进行一次页面重绘&#xff0c;而这中间的奥秘就是虚拟…

论文 | 一分钟快速找到自己研究领域的核心期刊

进入知网官网 https://www.cnki.net/ 点击搜索框右边的&#xff1a;出版物检索 鼠标放到顶部的 出版来源导航 旁边的倒三角上 选择期刊导航&#xff1a; 点击核心期刊导航 找到自己感兴趣的领域 点进去就可以看到该期刊中发表的论文&#xff1a;

postgresql regular lock常规锁 烤的内嫩外焦,入口即化

​专栏内容&#xff1a; postgresql内核源码分析 手写数据库toadb 并发编程 个人主页&#xff1a;我的主页 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 介绍 常规锁&#xff0c;主要用于数据库对象的加锁&#xff0c…

学Python还是学JAVA,千万别听机构瞎吹!

机构真的为了割韭菜&#xff0c;无所不用其极&#xff0c;过份夸大Python语言的能力或者贬低JAVA。 导致大家要么跟风被割韭菜&#xff0c;学完也用不到。 导致这一主要原因&#xff1a; 1.你不懂行业内需求。 2.你缺乏认知清楚自己的发展规划路线的途径。3.对于编程的优缺点…

Pandas理论与实战(二)

本文章续接上篇文章 目录 1.数据抽取 1.1 抽取一行数据 1.2 抽取多行数据 1.3 抽取指定列数据 1.4 抽取指定行、列数据 1.5 按指定条件抽取数据 2、数据的增加、删除和修改 2.1 数据增加 2.2 修改数据 2.3 删除数据 1.数据抽取 数据分析过程中&#xff0c;并不是所有的数…

CentOS 6 手动将OpenSSH升级到9.3

前言 收到通知说服务器组件存在漏洞 服务器版本:CentOS-6.8-x86_64 目前SSH版本:OpenSSH_5.3p1, OpenSSL 1.0.1e-fips 11 Feb 2013 前置操作 为了避免升级过程中出现的意外导致服务器无法进行连接,建议对重要的内容先进行备份 创建快照 在主机服务商那里为主机创建快照,防止最糟…

Android Studio无法打开问题解决记录

目录 1 问题起因2 发现问题3 解决问题 1 问题起因 问题的起因是我为了运行一个Kotlin项目&#xff0c;但是报了一个错误&#xff1a; Kotlin报错The binary version of its metadata is 1.5.1, expected version is 1.1.16 然后我就上百度去搜了以下&#xff0c;一篇博客让禁用…

GEE:多元线性回归

作者&#xff1a;CSDN _养乐多_ 本文记录了在NDVI、EVI和LAI作为自变量&#xff0c;precipitation作为因变量的条件下&#xff0c;使用linearRegression函数进行线性回归分析的代码&#xff0c;代码在Google Earth Engine&#xff08;GEE&#xff09;平台上实现。具体而言&am…

AI大数据智能视频融合平台EasyCVR新增Ehome黑白名单配置

EasyCVR视频融合平台基于云边端智能协同架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;平台支持海量视频汇聚管理&#xff0c;可支持多协议接入&#xff0c;包括市场主流标准协议与厂家私有协议及SDK&#xff0c;如&#xff1a;国标GB28181、RTMP、RTSP/Onvi…

Linux 学习记录50(QT篇)

Linux 学习记录50(QT篇) 本文目录 Linux 学习记录50(QT篇)一、基于QT的TCP客户端连接1. 代码实现2. 自制的客户端/服务器 二、QT数据库SQL1. QT将数据库分为三个层次2. 实现数据库操作的相关方法 思维导图练习1.2.3.4. 一、基于QT的TCP客户端连接 所需头文件 <QTcpSocket&g…

3G理论概述

文章目录 UMTS&#xff08;通用移动通信系统&#xff0c;Universal Mobile Telecommunications System&#xff09;UTRAN&#xff08;UMTS陆地无线接入网&#xff0c;UMTS Terrestrial Radio Access Network&#xff09;RNC&#xff08;无线网络控制器&#xff0c;Radio Networ…

music21 层级解析(了解次结构方可将任意曲谱与mid互相转换)

这段代码创建了一个音乐乐谱并将其保存为 MIDI 文件&#xff0c;其中包含一个乐器和多个小节。每个小节中包含四个音符或和弦&#xff0c;然后将小节添加到乐谱中。最后&#xff0c;将乐谱写入 MIDI 文件。 首先&#xff0c;通过导入 music21 库来使用它的功能。 import music2…

onvif库封装及qt工程调用onvif库实现设备搜索、获取码流地址等功能

一、前言&#xff1a; 本篇的OnvifManager工程是在vs2010下进行开发编译&#xff0c;它实现了对onvif库的封装调用&#xff0c;目前工程接口实现了对onvif的搜索、码流地址获取、设备重启接口&#xff0c;其他接口后续可以通过更改工程代码进行添加。qt工程myonvif是对OnvifMan…