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:
Article directory
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;
Related URLs
Java Client API Reference reference documentation
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"
View running log
2. Port open
3. Browser access console
http://124.70.138.34:9091/login
4. Create a bucket and grant permissions
Create bucket
public access
5. Upload pictures and visit
http://124.70.138.34:9000/hello/123.jpg
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
# 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
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
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
<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
7. Image echo
3. Picture related effect demonstration
Display product information in pages
Modify product information and modify pictures
Modification successful, return to the paging page
Add new products and upload images
Pictures in minio
modified database
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;