Huawei Cloud Yaoyun Server L instance evaluation | Docker version of Minio installation & use in Springboot project & image storage combined with vue

Insert image description here

Preface

Recently, Huawei Cloud Yaoyun Server L instance was launched, and I also built one to play with. During this period, I encountered attacks on MySQL database and Redis. The lesson is that the password cannot be too simple. When using the server, I learned a lot of knowledge related to operation and maintenance.

This blog introduces how to install minio in Linux, use it in spring, and upload and echo images in vue.

The list of other related Huawei Cloud Yaoyun Server L instance evaluation articles is as follows:

Insert image description here

lead out


1. Installation and use of the docker version of minio;
2. Use minio as a database for image storage in the spring project;
3. Use element-ui in conjunction with vue to upload and echo images;

Insert image description here
Related URLs

Java Client API Reference reference documentation

Official website

Various versions of minio

1. Installation and use of docker version of minio

1.Installation of docker version

Execute the following command, please note that there are username and password requirements.

docker run -itd --name minio_9091 \
-p 9001:9000 -p 9091:9090 \
-e "MINIO_ACCESS_KEY=minioadmin" \
-e "MINIO_SECRET_KEY=minioadmin123" \
e31e0721a96b server \
/data --console-address ":9090" -address ":9000"

Insert image description here

View running log

Insert image description here

2. Port open

Insert image description here

3. Browser access console

http://124.70.138.34:9091/login

Insert image description here

4. Create a bucket and grant permissions

Create bucket

Insert image description here

public access

Insert image description here

5. Upload pictures and visit

Insert image description here

http://124.70.138.34:9000/hello/123.jpg

Insert image description here

2. The configuration of spring project uses minio

1.Introduce dependencies

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.8.1</version>
            <!-- minio 依赖于 okhttp 且版本较高。注意,spring-boot-dependencies 中的不够高 -->
        </dependency>

        <!--        minio的依赖-->
        <dependency>
            <groupId>io.minio</groupId>
            <artifactId>minio</artifactId>
            <version>8.3.9</version>
        </dependency>

2. Configuration file

Insert image description here

# minio 文件存储配置信息,配置类引入
minio:
  endpoint: http://124.70.138.34:9000
  username: minioadmin
  password: minioadmin
  # 图片的前缀配置,数据库存图片名称,前缀是ip+端口+buckets名字
  imgPrefix: http://124.70.138.34:9000/hello/

3.Write configuration class

Write a configuration class to configure minio

Insert image description here

The user obtains the attribute value in the configuration file

package com.tianju.fresh.config.minio;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "minio")

public class MinioPro {
    
    
    // 如果用@Value("${}")只能一个一个获取
    private String endpoint;
    private String username;
    private String password;
}

Generate MinioClient client and put it in spring container

package com.tianju.fresh.config.minio;

import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * 获取minio的客户端
 * (通过客户端,就可以创建通,上传图片这类。。。)
 */

@Configuration
@EnableConfigurationProperties(MinioPro.class)

public class MinioConfig {
    
    
    @Autowired
    private MinioPro minioPro;
    @Bean
    public MinioClient minioClient() throws Exception {
    
    
        return MinioClient.builder().endpoint(minioPro.getEndpoint())
                .credentials(minioPro.getUsername(), minioPro.getPassword()).build();
    }
}

4. Write an interface to upload pictures

Insert image description here

package com.tianju.fresh.controller.api;

import com.alibaba.fastjson.JSONObject;

import com.tianju.fresh.Resp.dto.HttpResp;
import com.tianju.fresh.util.MinioUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/img")
@Slf4j
public class ImagController {
    
    

    @Autowired
    private MinioUtils minioUtils;

    @PostMapping("/upload")
    public HttpResp uploadImg(MultipartFile file){
    
    
        JSONObject jsonObject = null;
        try {
    
    
            jsonObject = minioUtils.uploadFile(file, "hello");
        } catch (Exception e) {
    
    
            throw new RuntimeException(e);
        }
        log.debug("uploadFile>>>>>"+jsonObject.toJSONString());
        return HttpResp.ok(jsonObject);
    }

}

Minio tools

package com.tianju.fresh.util;

import com.alibaba.fastjson.JSONObject;

import com.tianju.fresh.config.minio.MinioPro;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;

/**
 * 进行图片的上传
 */
@Slf4j
@Component
public class MinioUtils {
    
    

    @Autowired
    private MinioClient client;
    @Autowired
    private MinioPro minioPro;

    /**
     * 创建bucket
     */
    public void createBucket(String bucketName) {
    
    
        BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build();
        MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();
        try {
    
    
            if (client.bucketExists(bucketExistsArgs))
                return;
            client.makeBucket(makeBucketArgs);
        } catch (Exception e) {
    
    
            log.error("创建桶失败:{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }

    /**
     * @param file       文件
     * @param bucketName 存储桶
     * @return
     */
    public JSONObject uploadFile(MultipartFile file, String bucketName) throws Exception {
    
    
        JSONObject res = new JSONObject();
        res.put("code", 0);
        // 判断上传文件是否为空
        if (null == file || 0 == file.getSize()) {
    
    
            res.put("msg", "上传文件不能为空");
            return res;
        }
        // 判断存储桶是否存在
        createBucket(bucketName);
        // 文件名
        String originalFilename = file.getOriginalFilename();
        // 新的文件名 = 存储桶名称_时间戳.后缀名
        String fileName = bucketName + "_" + System.currentTimeMillis() +                              									originalFilename.substring(originalFilename.lastIndexOf("."));
        // 开始上传
        InputStream inputStream = file.getInputStream();
        PutObjectArgs args = PutObjectArgs.builder().bucket(bucketName).object(fileName)
                .stream(inputStream,inputStream.available(),-1).build();
        client.putObject(args);
        res.put("code", 1);
        res.put("msg", minioPro.getEndpoint() + "/" + bucketName + "/" + fileName);
        return res;
    }
}

5. Front-end uploads

Insert image description here

                  <el-form-item label="上传图片" label-width="120px">
                    <div style="margin-left: 23px; display: inline-block; border: 1px solid #ccc; padding: 16px;">
                      <el-upload class="avatar-uploader" action="/api/img/upload" :show-file-list="false"
                        :on-success="addGoodsUploadImgSuccess">
                        <div class="avatar-container">
                          <img v-if="goods.imgSrc" :src="goods.imgSrc" class="avatar" />
                          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                        </div>
                      </el-upload>
                    </div>
                  </el-form-item>
    // 图片上传成功,回调方法
    addGoodsUploadImgSuccess(res, file) {
    
    
      this.goods.imgSrc = res.results.msg
      // uploadFile>>>>>{"msg":"http://192.168.111.130:9000/hello/hello_1693810266596.jpg","code":1}
      console.log(res)
    },

6. Image upload path processing

Insert image description here

7. Image echo

Insert image description here

3. Picture related effect demonstration

Display product information in pages

Insert image description here

Modify product information and modify pictures

Insert image description here

Modification successful, return to the paging page

Insert image description here

Add new products and upload images

Insert image description here

Pictures in minio

Insert image description here

modified database

Insert image description here

Appendix: Complete front-end and back-end code

1. Backend code service

package com.tianju.fresh.service.goods.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tianju.fresh.Resp.dto.HttpResp;
import com.tianju.fresh.entity.goods.Goods;
import com.tianju.fresh.entity.goods.GoodsType;
import com.tianju.fresh.entity.goods.vo.GoodsManageVo;
import com.tianju.fresh.entity.page.FindGoods;
import com.tianju.fresh.entity.page.PageParam;
import com.tianju.fresh.mapper.goods.GoodsDao;
import com.tianju.fresh.mapper.goods.GoodsMapper;
import com.tianju.fresh.mapper.goods.GoodsTypeMapper;
import com.tianju.fresh.mapper.goods.UnitMapper;
import com.tianju.fresh.service.goods.IGoodsService;
import com.tianju.fresh.util.NoUtil;
import com.tianju.fresh.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

@Service
public class GoodsServiceImpl implements IGoodsService {
    
    

    @Autowired
    private GoodsDao goodsDao;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private GoodsTypeMapper typeMapper;

    @Autowired
    private UnitMapper unitMapper;

    @Value("${minio.imgPrefix}")
    private String imgPrefix;

    @Override
    public HttpResp findPageGoodsInfo(PageParam<FindGoods> param) {
    
    
        PageHelper.startPage(param.getPageNum(), param.getPageSize());
        FindGoods pa = param.getParam();
        if (StringUtils.isNotBlank(pa.getGoodsNo())){
    
    
            pa.setGoodsNo("%"+pa.getGoodsNo()+"%");
        }
        if (StringUtils.isNotBlank(pa.getName())){
    
    
            pa.setName("%"+pa.getName()+"%");
        }
        List<GoodsManageVo> list = goodsDao.findGoodsBy(
                pa.getName(),
                pa.getGoodsNo(),
                pa.getType(), pa.getUnit(), pa.getSupplier(),
                pa.getStatus(), pa.getPrice() + "", pa.getStock(), pa.getLevel()
        );

        // 图片的连接地址拼出来
        list.forEach(g->{
    
    
            g.setImg(imgPrefix+g.getImg());
        });

        PageInfo pageInfo = new PageInfo(list);
        return HttpResp.ok(pageInfo);
    }


    @Override
    public HttpResp addGoodsInfo(Goods goods) {
    
    

        // 生成商品的编号
        // TODO:这个根据id查类型能不能放到redis里面,已完成
        QueryWrapper<GoodsType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", goods.getTypeId());
        GoodsType goodsType = typeMapper.selectOne(queryWrapper);

        String goodsNo = goodsType.getPrefix() + NoUtil.getDateRandNo();

        // 设置图片名称
        goods.setImgSrc(dealImgSrc(goods));

        // 设置商品的编号,创建时间,修改时间等
        goods.setGoodsNo(goodsNo);
        goods.setCreateTime(new Date());
        goods.setUpdateTime(new Date());

        goodsMapper.insert(goods);
        return HttpResp.ok(goods);
    }

    /**
     * 处理修改和新增商品时图片名字的问题,
     * @param goods 新增或者修改的商品对象
     * @return 输出:hello_1695026372539.png
     */
    private String dealImgSrc(Goods goods){
    
    
        // http://124.70.138.34:9000/hello/hello_1695027224400.png
        String imgName = "";
        // 处理图片的问题
        if (StringUtils.isNotBlank(goods.getImgSrc())){
    
    
            int lastIndex = goods.getImgSrc().lastIndexOf("/");
            if (lastIndex != -1) {
    
    
                imgName = goods.getImgSrc().substring(lastIndex + 1);
            }
        }
        return imgName;
    }



    @Override
    public HttpResp<Goods> findById(Integer id) {
    
    
        QueryWrapper<Goods> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        Goods goods = goodsMapper.selectOne(queryWrapper);
        goods.setImgSrc(imgPrefix+goods.getImgSrc());
        return HttpResp.ok(goods);
    }

    @Override
    public HttpResp updateById(Goods goods) {
    
    
        Goods goodsDB = findById(goods.getId()).getResults();
        if (!goodsDB.getLevel().equals(goods.getLevel())){
    
    
            return HttpResp.fail("失败,不能修改商品级别");
        }
        goods.setUpdateTime(new Date());

        // 处理图片名称的问题
        goods.setImgSrc(dealImgSrc(goods));
        goodsMapper.updateById(goods);

        goodsDB = findById(goods.getId()).getResults();

        return HttpResp.ok(goodsDB);
    }

    @Override
    public HttpResp findAll() {
    
    
        List<Goods> goods = goodsMapper.selectList(null);
        return HttpResp.ok(goods);
    }


}

2. Front-end vue code

<template>
  <div class="text item">
    <el-row>
      <el-col :span="24">
        <!-- 查询条件列表 -->
        <div style="margin-left: 35px; display: inline-block;">
          <el-form :inline="true" ref="form" label-width="100px">

            <el-form-item label="商品名称">
              <el-input v-model="query.name" clearable style="width: 221px;margin-right:20px;margin-left:6px"></el-input>
            </el-form-item>



            <el-form-item label="商品编号">
              <el-input v-model="query.goodsNo" clearable
                style="width: 221px;margin-right:19px;margin-left:6px"></el-input>
            </el-form-item>



            <el-form-item label="商品类型" clearable style="width: px;margin-right:px;margin-left:6px">
              <el-select v-model="query.type" placeholder="请选择">
                <el-option v-for="item in data.results.type" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>




            <el-form-item label="商品单位" clearable style="width: px;margin-right:30px;margin-left:6px">
              <el-select v-model="query.unit" placeholder="请选择商品单位">
                <el-option v-for="item in data.results.unit" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>


            <el-form-item label="商品供应商" clearable style="width: px;margin-right:30px;margin-left:6px">
              <el-select v-model="query.supplier" placeholder="请选择">
                <el-option v-for="item in data.results.supplier" :key="item.value" :label="item.label"
                  :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>


            <el-form-item label="商品状态" clearable style="width: px;margin-right:px;margin-left:6px">
              <el-select v-model="query.status" placeholder="请选择">
                <el-option v-for="item in data.results.status" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>

            <el-form-item label="商品售价≥">
              <el-input v-model="query.price" clearable style="width: 221px;margin-right:18px;margin-left:6px"></el-input>
            </el-form-item>

            <el-form-item label="商品库存≥">
              <el-input v-model="query.stock" clearable style="width: 221px;margin-right:21px;margin-left:6px"></el-input>
            </el-form-item>



            <el-form-item label="商品级别" clearable style="width:px;margin-right:px;margin-left:6px">
              <el-select v-model="query.level" placeholder="请选择">
                <el-option v-for="item in data.results.level" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>

            <el-form-item>
              <el-button type="primary" icon="el-icon-search" @click=" queryPage()">查 询</el-button>
            </el-form-item>

            <el-form-item>
              <el-button type="warning" icon=" el-icon-refresh-left" @click="resetQuery()">清 空</el-button>
            </el-form-item>

            <div style="margin-left:845px">


            </div>
          </el-form>

          <el-button type="primary" icon=" el-icon-circle-plus" @click="open()">添加商品</el-button>
          <div class="table-container">

            <!-- 商品展示列表 -->
            <el-table :data="tableData" style="width: 150">
              <el-table-column prop="name" label="商品名称" width="180">
              </el-table-column>

              <el-table-column prop="type" label="类别" width="80">
              </el-table-column>

              <el-table-column prop="goodsNo" label="商品编号" width="240">
              </el-table-column>

              <el-table-column prop="lossRate" label="损耗率" width="80">
              </el-table-column>

              <el-table-column prop="nums" label="当前库存" width="80">
              </el-table-column>

              <el-table-column prop="unit" label="单位" width="90">
              </el-table-column>

              <el-table-column prop="level" label="成/次品" width="80">
                <template slot-scope="scope">
                  <span v-if="scope.row.level == '0'" style="color: rgb(31, 228, 126);">成品</span>
                  <span v-if="scope.row.level == '1'" style="color: rgb(229, 73, 52);">次品</span>
                </template>
              </el-table-column>

              <el-table-column prop="price" label="商品售价" width="80">
              </el-table-column>

              <el-table-column prop="supplier" label="供应商" width="250">
              </el-table-column>

              <el-table-column prop="img" label="图片" width="90">
                <template slot-scope="scope">
                  <img :src=scope.row.img style="width: 50%;">
                </template>
              </el-table-column>

              <el-table-column label="操作" width="250">
                <template slot-scope="scope">
                  <el-button type="danger" style="background-color:red;border: none">删除</el-button>
                  <el-button type="warning" @click="queryGoodsById(scope.row.id)"
                    style="background-color:rgb(255, 179, 0);border: none">编辑</el-button>
                  <el-button type="danger" style="background-color:rgb(224, 69, 66);border: none">停用</el-button>
                </template>
              </el-table-column>

            </el-table>

          </div>


          <!-- 新增商品弹窗 ******* -->
          <el-dialog title="新增商品" :visible.sync="b">
            <el-form>
              <el-row>
                <el-col :span="12">
                  <el-form-item label="商品名称" clearable :label-width="formLabelWidth">
                    <el-input v-model="goods.name"></el-input>
                  </el-form-item>

                  <el-form-item label="商品单位" clearable>
                    <el-select v-model="goods.unitId" placeholder="请选择商品单位"
                      style="width: 355px;margin-right:px;margin-left:px">
                      <el-option v-for="item in data.results.unit" :key="item.value" :label="item.label"
                        :value="item.value">
                      </el-option>
                    </el-select>
                  </el-form-item>

                  <el-form-item label="商品类型" clearable>
                    <el-select v-model="goods.typeId" placeholder="请选择"
                      style="width: 355px;margin-right:px;margin-left:px">
                      <el-option v-for="item in data.results.type" :key="item.value" :label="item.label"
                        :value="item.value">
                      </el-option>
                    </el-select>
                  </el-form-item>

                  <el-form-item label="商品供应商" clearable>
                    <el-select v-model="goods.supplierId" placeholder="请选择"
                      style="width: 355px;margin-right:px;margin-left:px">
                      <el-option v-for="item in data.results.supplier" :key="item.value" :label="item.label"
                        :value="item.value">
                      </el-option>
                    </el-select>
                  </el-form-item>
                  <el-form-item label="商品描述" :label-width="formLabelWidth">
                    <el-input type="textarea" :rows="4"
                     v-model="goods.detail" autocomplete="off"></el-input>
                  </el-form-item>

                  <el-form-item label="商品价格" :label-width="formLabelWidth">
                    <el-input v-model="goods.price" autocomplete="off"></el-input>
                  </el-form-item>

                  <el-form-item label="库存上限" :label-width="formLabelWidth">
                    <el-input v-model="goods.stockUp" autocomplete="off"></el-input>
                  </el-form-item>

                  <el-form-item label="库存下限" :label-width="formLabelWidth">
                    <el-input v-model="goods.stockLo" autocomplete="off"></el-input>
                  </el-form-item>

                  <el-form-item label="商品级别" clearable>
                    <el-select v-model="goods.level" placeholder="请选择"
                      style="width: 355px;margin-right:px;margin-left:px">
                      <el-option v-for="item in data.results.level" :key="item.value" :label="item.label"
                        :value="item.value">
                      </el-option>
                    </el-select>
                  </el-form-item>
                  <el-form-item label="上传图片" label-width="120px">
                    <div style="margin-left: 23px; display: inline-block; border: 1px solid #ccc; padding: 16px;">
                      <el-upload class="avatar-uploader" action="/api/img/upload" :show-file-list="false"
                        :on-success="addGoodsUploadImgSuccess">
                        <div class="avatar-container">
                          <img v-if="goods.imgSrc" :src="goods.imgSrc" class="avatar" />
                          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                        </div>
                      </el-upload>
                    </div>
                  </el-form-item>
                </el-col>
              </el-row>

            </el-form>

            <div slot="footer" class="dialog-footer">
              <el-button @click="b = false">取 消</el-button>
              <el-button type="primary" @click="addGoods()">确 定</el-button>
            </div>
          </el-dialog>

          <!-- 修改商品弹窗 ###################### -->
          <el-dialog title="修改商品" :visible.sync="c">
            <el-form>
              <el-row>
                <el-col :span="12">
                  <el-form-item label="商品名称" clearable :label-width="formLabelWidth">
                    <el-input v-model="queryGoods.name"></el-input>
                  </el-form-item>

                  <el-form-item label="商品单位" clearable>
                    <el-select v-model="queryGoods.unitId" placeholder="请选择商品单位"
                      style="width: 355px;margin-right:px;margin-left:px">
                      <el-option v-for="item in data.results.unit" :key="item.value" :label="item.label"
                        :value="item.value">
                      </el-option>
                    </el-select>
                  </el-form-item>

                  <el-form-item label="商品类型" clearable>
                    <el-select v-model="queryGoods.typeId" placeholder="请选择"
                      style="width: 355px;margin-right:px;margin-left:px">
                      <el-option v-for="item in data.results.type" :key="item.value" :label="item.label"
                        :value="item.value">
                      </el-option>
                    </el-select>
                  </el-form-item>

                  <el-form-item label="商品供应商" clearable>
                    <el-select v-model="queryGoods.supplierId" placeholder="请选择"
                      style="width: 355px;margin-right:px;margin-left:px">
                      <el-option v-for="item in data.results.supplier" :key="item.value" :label="item.label"
                        :value="item.value">
                      </el-option>
                    </el-select>
                  </el-form-item>

                  <el-form-item label="商品描述" :label-width="formLabelWidth">
                    <el-input type="textarea" :rows="4" v-model="queryGoods.detail" autocomplete="off"></el-input>
                  </el-form-item>

                  <el-form-item label="商品价格" :label-width="formLabelWidth">
                    <el-input v-model="queryGoods.price" autocomplete="off"></el-input>
                  </el-form-item>

                  <el-form-item label="库存上限" :label-width="formLabelWidth">
                    <el-input v-model="queryGoods.stockUp" autocomplete="off"></el-input>
                  </el-form-item>

                  <el-form-item label="库存下限" :label-width="formLabelWidth">
                    <el-input v-model="queryGoods.stockLo" autocomplete="off"></el-input>
                  </el-form-item>

                  <el-form-item label="商品级别" clearable>
                    <el-select v-model="queryGoods.level" placeholder="请选择"
                      style="width: 355px;margin-right:px;margin-left:px">
                      <el-option v-for="item in data.results.level" :key="item.value" :label="item.label"
                        :value="item.value">
                      </el-option>
                    </el-select>
                  </el-form-item>

                  <el-form-item label="更换图片" label-width="100px">
                    <el-upload class="avatar-uploader" action="/api/img/upload" :show-file-list="false"
                      :on-success="updateGoodsUploadImgSuccess">
                      <div style="width: 40%;">
                        <img v-if="queryGoods.imgSrc" :src="queryGoods.imgSrc" class="avatar" />
                        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                      </div>
                    </el-upload>
                  </el-form-item>


                </el-col>
              </el-row>
            </el-form>

            <div slot="footer" class="dialog-footer">
              <el-button @click="c = false">取 消</el-button>
              <el-button type="primary" @click="updateGoods()">确 定</el-button>
            </div>
          </el-dialog>
        </div>
      </el-col>
    </el-row>


    <el-row>
      <el-col :span="24">
        <!-- 放分页部分 -->
        <!-- :page-size="100" 指定每页多少条,默认10条-->
        <el-pagination background :page-sizes="[3, 5, 10]" :page-size="pageSize" :current-page="pageNum"
          layout="sizes,total,prev, pager, next" :total="total" @next-click="nextpage" @prev-click="prevpage"
          @size-change="sizePage" @current-change="currentPage">
        </el-pagination>

      </el-col>
    </el-row>
  </div>
</template>

<script>
export default {
      
      
  data() {
      
      
    return {
      
      
      // formLabelWidth: '120px',
      goods: {
      
      
        name: '',
        unitId: '',
        typeId: '',
        supplierId: '',
        detail: '',
        price: '',
        stockUp: '',
        stockLo: '',
        level: '',
        imgSrc: ''
      },

      // 根据id查出来的商品
      i: '1',

      // 查询商品的条件
      queryGoods: {
      
      
        name: '',
        unitId: '',
        typeId: '',
        supplierId: '',
        detail: '',
        price: '',
        stockUp: '',
        stockLo: '',
        level: '',
        imgSrc: ''
      },

      // 新增商品弹窗控制变量
      b: false,

      // 修改商品弹窗控制变量
      c: false,

      tableData: [],
      pageSize: 5,
      pageNum: 1,
      total: 0,
      // common的数据
      data: {
      
      
        "results": {
      
      
          "unit": [
            {
      
       "value": "1", "label": "千克" }
          ],
          "level": [
            {
      
       "value": "0", "label": "成品" },
            {
      
       "value": "1", "label": "次品" }
          ],
          "supplier": [
            {
      
       "value": "1", "label": "南京总部基地供应总店" },
          ],
          "type": [
            {
      
      
              "label": "2", "value": "新鲜水果/苹果"
            },
          ],
          "status": [
            {
      
       "value": "0", "label": "正常" },
          ]
        }
      },

      // 多条件查询的查询条件
      query: {
      
      
        // name: '', goodsNo: '', price: '', stock: '', supplier: '', unit: '', status: '', level: '', type: '' 
        "name": ""
        , "goodsNo": ""
        , "type": ""

        , "unit": ""
        , "supplier": ""
        , "status": ""
        , "price": ""
        , "stock": ""
        , "level": ""
      },
      formLabelWidth: '100px',
    }
  },
  methods: {
      
      

    // 图片上传成功,回调方法
    addGoodsUploadImgSuccess(res, file) {
      
      
      this.goods.imgSrc = res.results.msg
      // uploadFile>>>>>{"msg":"http://192.168.111.130:9000/hello/hello_1693810266596.jpg","code":1}
      console.log(res)
    },

    updateGoodsUploadImgSuccess(res, file) {
      
      
      this.queryGoods.imgSrc = res.results.msg
      // uploadFile>>>>>{"msg":"http://192.168.111.130:9000/hello/hello_1693810266596.jpg","code":1}
      console.log(res)
    },

    queryAllMenu() {
      
      
      this.$axios.get('api/common/goodsCommon')
        .then(res => {
      
      
          console.log(res.data)
          if (res.data.resultCode.code == 20000) {
      
      
            this.data = res.data
          }
        })
    },
    queryPage() {
      
      
      let param = {
      
      }
      param.pageNum = this.pageNum;
      param.pageSize = this.pageSize;
      param.param = this.query
      this.$axios.post('api/goods/mange/findPage', param)
        .then(res => {
      
      
          if (res.data.resultCode.code == 20000) {
      
      
            console.log(res.data.results.list)
            this.tableData = res.data.results.list;
            this.total = res.data.results.total;
            this.pageNum = res.data.results.pageNum;
            this.pageSize = res.data.results.pageSize;
          }
        })
    },

    addGoods() {
      
      
      this.b = false
      this.$axios.post('api/goods/mange/add', this.goods)
        .then(res => {
      
      
          if (res.data.resultCode.code == 20000) {
      
      
            this.queryPage();
            alert('添加成功')
          }
        })

    },

    updateGoods() {
      
      
      this.c = false
      this.$axios.put('api/goods/mange/update', this.queryGoods)
        .then(res => {
      
      
          if (res.data.resultCode.code == 20000) {
      
      
            this.queryPage();
            alert('修改成功')
          } else {
      
      
            this.queryPage();
            alert(res.data.results)
          }
        })
    },

    queryGoodsById(val) {
      
      
      this.c = true
      this.$axios.get("/api/goods/mange/findById?id=" + val)
        .then(res => {
      
      
          console.log(res.data)
          if (res.data.resultCode.code == 20000) {
      
      
            this.queryGoods = res.data.results.results
            console.log(this.queryGoods)
            this.queryGoods.typeId = this.queryGoods.typeId.toString();
            this.queryGoods.unitId = this.queryGoods.unitId.toString();
            this.queryGoods.level = this.queryGoods.level.toString();
            this.queryGoods.supplierId = this.queryGoods.supplierId.toString();
          }
        })
    },

    open() {
      
      
      this.b = true
    },

    resetQuery() {
      
       // 定义重置查询对象的方法
      this.query = {
      
      
        name: '',
        goodsNo: '',
        price: '',
        stock: '',
        supplier: '',
        unit: '',
        status: '',
        level: '',
        type: '',
      }
      this.queryPage()


    },
    prevpage(val) {
      
      
      //上一页
      this.pageNum = val;
      this.queryPage();
    },
    nextpage(val) {
      
      
      this.pageNum = val;
      //下一页
      this.queryPage();
    },
    sizePage(val) {
      
      
      //每页多少条改变时触发
      this.pageSize = val;
      this.pageNum = 1;
      this.queryPage();
    },

    //跳转
    currentPage(val) {
      
      
      this.pageNum = val;
      this.queryPage();
    },

    handleAvatarSuccess(res, flie) {
      
      
      // 上传图片回显
      this.goods.imageUrl = res.msg
    },
  },

  created() {
      
      
    this.queryPage()
    this.queryAllMenu();

  }
}
</script>

<style scoped>
.avatar-container {
      
      
  position: relative;
  width: 100px;
  height: 100px;
}

.avatar {
      
      
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-uploader-icon {
      
      
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 28px;
  color: #999;
}


.table-container {
      
      
  border: 0px solid #ccc;
  border-radius: 1px;
  overflow: hidden;
}

.el-table .el-table__row {
      
      
  border-bottom: 1px solid #ccc;
}

.el-table .el-table__column:not(:last-child) {
      
      
  border-right: 1px solid #ccc;
}
</style>

Summarize

1. Installation and use of the docker version of minio;
2. Use minio as a database for image storage in the spring project;
3. Use element-ui in conjunction with vue to upload and echo images;

Guess you like

Origin blog.csdn.net/Pireley/article/details/133200908