实战 11 用户管理

目录

1、查询用户列表

1.1 查询用户列表接口实现

1.2 查询用户列表前端实现

2、新增用户

2.1 效果图

2.2 新增用户后端接口实现

2.3 新增用户前端页面实现

2.4 选择所属部门

3、阿里云对象存储OSS服务

3.1 开通阿里云对象存储OSS服务

3.1.1 申请阿里云账号

3.1.2 实名认证

3.1.3 开通OSS对象存储

3.2 使用阿里云OSS对象存储

3.2.1 创建Bucket存储空间

​3.2.2  文件管理

3.2.3 使用Java SDK操作OSS

​4、使用OSS实现文件上传

4.1 添加OSS依赖

4.2 编写application.properties阿里云配置文件

4.3 读取配置文件信息

4.4 编写文件上传代码

4.5 文件上传控制器 

4.6 上传用户头像

4.6.1 定义页面组件模版

4.6.2 定义页面组件脚本代码


1、查询用户列表

1.1 查询用户列表接口实现

    /**
     * 分页查询用户信息
     *
     * @param page
     * @param userQueryVo
     * @return
     */
    @Override
    public IPage<User> findUserListByPage(IPage<User> page, UserQueryVo userQueryVo) {
        //创建条件构造器对象
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        //部门编号
        queryWrapper.eq(!ObjectUtils.isEmpty(userQueryVo.getDepartmentId()),"department_id",userQueryVo.getDepartmentId());
        //用户名
        queryWrapper.like(!ObjectUtils.isEmpty(userQueryVo.getUsername()),"username",userQueryVo.getUsername());
        //真实姓名
        queryWrapper.like(!ObjectUtils.isEmpty(userQueryVo.getRealName()),"real_name",userQueryVo.getRealName());
        //电话
        queryWrapper.like(!ObjectUtils.isEmpty(userQueryVo.getPhone()),"phone",userQueryVo.getPhone());
        //查询并返回数据
        return baseMapper.selectPage(page,queryWrapper);
    }

    /**
     * 查询用户列表
     * @param userQueryVo
     * @return
     */
    @GetMapping("/list")
    public Result list(UserQueryVo userQueryVo) {
        //创建分页信息
        IPage<User> page = new Page<User>(userQueryVo.getPageNo(), userQueryVo.getPageSize());
        //调用分页查询方法
        userService.findUserListByPage(page, userQueryVo);
        //返回数据
        return Result.ok(page);
    }

1.2 查询用户列表前端实现

   <!-- 左侧部门树形菜单列表 -->
    <el-aside style="padding: 10px 0px 0px 0px;background: #fff;border-right: 1px solid #dfe6ec;" width="220px">
      <el-tree
        style="font-size: 14px"
        ref="leftTree"
        :data="deptList"
        node-key="id"
        :props="defaultProps"
        default-expand-all
        empty-text="暂无数据"
        :show-checkbox="false"
        :highlight-current="true"
        :expand-on-click-node="false"
        @node-click="handleNodeClick">
        <div class="custom-tree-node" slot-scope="{ node, data }">
          <div>
            <span v-if="data.children.length == 0">
              <i class="el-icon-document"></i>
            </span>
            <span v-else @click.stop="changeIcon(data)">
              <svg-icon v-if="data.open" icon-class="add-s"/>
              <svg-icon v-else icon-class="sub-s"/>
            </span>
            <!-- 名称 -->
            <span style="margin-left: 3px">{{ node.label }}</span>
          </div>
        </div>
      </el-tree>
    </el-aside>
    <!-- 右侧用户数据 -->
    <!-- 表格数据 -->
    <el-main>
      <!-- 查询条件 -->
      <el-form :model="searchModel" ref="searchForm" label-width="80px" :inline="true" size="small">
        <el-form-item>
          <el-input v-model="searchModel.username" placeholder="请输入用户名"/>
        </el-form-item>
        <el-form-item>
          <el-input v-model="searchModel.realName" placeholder="请输入真实姓名"/>
        </el-form-item>
        <el-form-item>
          <el-input v-model="searchModel.phone" placeholder="请输入电话"/>
        </el-form-item>
        <el-form-item>
          <el-button icon="el-icon-search" type="primary" @click="search(departmentId, pageNo, pageSize)">查询</el-button>
          <el-button icon="el-icon-delete" @click="resetValue()">重置</el-button>
          <el-button icon="el-icon-plus" size="small" type="success" @click="openAddWindow()" v-if="hasPermission('sys:user:add')">新增</el-button>
        </el-form-item>
      </el-form>
      <!-- 用户表格数据 -->
      <el-table :height="tableHeight" :data="userList" border stripe style="width: 100%; margin-bottom: 10px">
        <el-table-column prop="username" label="用户名"></el-table-column>
        <el-table-column prop="realName" label="姓名"></el-table-column>
        <el-table-column prop="departmentName" label="所属部门"></el-table-column>
        <el-table-column prop="phone" label="电话"></el-table-column>
        <el-table-column prop="email" label="邮箱"></el-table-column>
        <el-table-column align="center" width="290" label="操作">
          <template slot-scope="scope">
            <el-button icon="el-icon-edit" type="primary" size="mini" @click="handleEdit(scope.row)" v-if="hasPermission('sys:user:edit')" >编辑</el-button>
            <el-button icon="el-icon-delete" type="danger" size="mini" @click="handleDelete(scope.row)" v-if="hasPermission('sys:user:delete')">删除</el-button>
            <el-button icon="el-icon-setting" type="primary" size="mini" @click="assignRole(scope.row)" v-if="hasPermission('sys:user:assign')">分配角色</el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页工具栏 -->
      <el-pagination
      background
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pageNo"
      :page-sizes="[10, 20, 30, 40, 50]"
      :page-size="10"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total" />
export default {
  name: 'userList',
    //注册组件
  components:{ SystemDialog },
  data() {
    //自定义验证规则
    let validatePhone = (rule, value, callback) => {
      if (!value) {
        callback(new Error("请输入手机号码"));
        //使用正则表达式进行验证手机号码
      }else if (!/^1[3456789]\d{9}$/.test(value)) {
        callback(new Error("手机号格式不正确"));
      }else{
        callback();
      }
    };
    return {
      containerHeight: 0, //容器高度
      deptList: [], //左侧部门树形菜单列表
      //树节点属性
      defaultProps: {
        children: 'children',
        label: 'departmentName'
      },
      //查询条件对象
      searchModel: {
        username: "",
        realName:"",
        phone: "",
        departmentId: "",
        pageNo: 1,
        pageSize: 10,
      },
      userList: [], //用户列表
      tableHeight: 0, //表格高度
      pageNo: 1, //当前页码
      pageSize: 10, //每页显示数量
      total: 0, //总数量
      departmentId: "", //部门编号
      //添加和修改用户窗口属性
      userDialog: {
        title: '',
        height: 410,
        width: 610,
        visible: false
      },
      //用户对象
      user: {
        id: '',
        departmentId: '',
        departmentName: '',
        email: '',
        realName: '',
        phone: '',
        nickName: '',
        password: '',
        username: '',
        gender: '',
        avatar:''
      },
      rules: {
        departmentName: [{ required: true, trigger: 'change', message: '请选择所属部门' }],
        realName: [{ required: true, trigger: 'blur', message: '请填写姓名' }],
        phone: [{ trigger: 'blur', validator: validatePhone }],
        username: [{ required: true, trigger: 'blur', message: '请填写登录名' }],
        password: [{ required: true, trigger: 'blur', message: '请填写登录密码' }],
        gender: [{ required: true, trigger: 'change', message: '请选择性别' }]
      },
      //选择所属部门窗口属性
      parentDialog: {
        title: '选择所属部门',
        width: 300,
        height: 450,
        visible: false
      },
      //树节点属性
      parentProps: {
        children: 'children',
        label: 'departmentName'
      },
      parentList: [], //所属部门节点数据
      //上传需要携带的数据
      uploadHeader:{"token":getToken()},
      //分配角色窗口属性
      assignDialog: {
        title: "",
        visible: false,
        width: 800,
        height: 410,
      },
      //角色对象
      roleVo: {
        pageNo: 1,
        pageSize: 10,
        userId: "",
        total: 0,
      },
      assignRoleList: [], //角色列表
      assignHeight: 0, //分配角色表格高度
      selectedIds: [], //被选中的角色id
      selectedUserId: "", //被分配角色的用户ID
    }
  },
  created() {
    //查询部门列表
    this.getDeptList();
    //调用查询用户列表
    this.search(this.departmentId);
  },
  mounted() {
    this.$nextTick(() => {
      //内容高度
      this.containerHeight = window.innerHeight - 85
      //表格高度
      this.tableHeight = window.innerHeight - 220
      //角色表格高度
      this.assignHeight = window.innerHeight - 350;
    })
  },
  methods: {
    /**
    * 查询部门列表
    */
    async getDeptList() {
      //发送查询请求
      let res = await departmentApi.getDepartmentList(null);
      //判断是否成功
      if (res.success) {
        this.deptList = res.data;
        //树加载完成后,默认点击第一个节点
        this.$nextTick(() => {
          const firstNode = document.querySelector(".el-tree-node");
          firstNode.click();
        });
      }
    },
    /**
    * 左侧树节点点击事件
    */
    handleNodeClick(data) {
      //给部门编号赋值
      this.departmentId = data.id;
      //查询数据
      this.search(this.departmentId);
    },
    /**
    * 查询用户列表
    */
    async search(departmentId, pageNo = 1, pageSize = 10) {
      this.searchModel.pageNo = pageNo;
      this.searchModel.pageSize = pageSize;
      this.searchModel.departmentId = departmentId;
      //发送查询请求
      let res = await userApi.getUserList(this.searchModel);
      if (res.success) {
        this.userList = res.data.records;
        this.total = res.data.total;
      }
    },
    /**
    * 当每页数量发生变化时触发该事件
    */
    handleSizeChange(size) {
      this.pageSize = size; //将每页显示的数量交给成员变量
      this.search(this.departmentId, this.pageNo, size);
    },
    /**
    * 当页码发生变化时触发该事件
    */
    handleCurrentChange(page) {
      this.pageNo = page;
      //调用查询方法
      this.search(this.departmentId, page, this.pageSize);
    },
    /**
    * 重置查询条件
    */
    resetValue() {
      //清空查询条件
      this.searchModel.username = ""
      this.searchModel.realName = ""
      this.searchModel.phone = ""
      this.searchModel.departmentId = ""
      this.searchModel.pageNo = 1
      this.searchModel.pageSize = 10
      //重新查询
      this.search(this.departmentId);
    },

<style lang="scss">
::v-deep .el-tree {
  .el-tree-node {
    position: relative;
    padding-left: 10px;
  }
  .el-tree-node__children {
    padding-left: 20px;
  }
  .el-tree-node :last-child:before {
    height: 40px;
  }
  .el-tree > .el-tree-node:before {
    border-left: none;
  }
  .el-tree > .el-tree-node:after {
    border-top: none;
  }
  .el-tree-node:before,
  .el-tree-node:after {
    content: "";
    left: -4px;
    position: absolute;
    right: auto;
    border-width: 1px;
  }
  .tree :first-child .el-tree-node:before {
    border-left: none;
  }
  .el-tree-node:before {
    border-left: 1px dotted #d9d9d9;
    bottom: 0px;
    height: 100%;
    top: -25px;
    width: 1px;
  }
  .el-tree-node:after {
    border-top: 1px dotted #d9d9d9;
    height: 20px;
    top: 14px;
    width: 24px;
  }
  .el-tree-node__expand-icon.is-leaf {
    width: 8px;
  }
  .el-tree-node__content > .el-tree-node__expand-icon {
    display: none;
  }
  .el-tree-node__content {
    line-height: 30px;
    height: 30px;
    padding-left: 10px !important;
  }
}
::v-deep .el-tree > div {
  &::before {
    display: none;
  }
  &::after {
    display: none;
  }
}

//用户头像
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9 !important;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409EFF;
}
.avatar-uploader .avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar-uploader img {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

2、新增用户

2.1 效果图

2.2 新增用户后端接口实现

   /**
     * 添加用户
     *
     * @param user
     * @return
     */
    @PostMapping("/add")
    @PreAuthorize("hasAuthority('sys:user:add')")
    public Result add(@RequestBody User user) {
        //查询用户
        User item = userService.findUserByUserName(user.getUsername());
        //判断对象是否为空
        if (item != null) {
            return Result.error().message("该登录名称已被使用,请重新输入!");
        }
        //密码加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        //调用保存用户信息的方法
        if(userService.save(user)){
            return Result.ok().message("用户添加成功");
        }
        return Result.error().message("用户添加失败");
    }

2.3 新增用户前端页面实现

  <!-- 添加和编辑用户窗口 -->
      <system-dialog
        :title="userDialog.title"
        :height="userDialog.height"
        :width="userDialog.width"
        :visible="userDialog.visible"
        @onClose="onClose"
        @onConfirm="onConfirm">
        <div slot="content">
          <el-form
            :model="user"
            ref="userForm"
            :rules="rules"
            label-width="80px"
            :inline="true"
            size="small">
            <el-form-item prop="username" label="用户名">
              <el-input v-model="user.username"></el-input>
            </el-form-item>
            <el-form-item prop="password" v-if="user.id === ''" label="密码">
              <el-input type="password" v-model="user.password"></el-input>
            </el-form-item>
            <el-form-item prop="departmentName" label="所属部门">
              <el-input v-model="user.departmentName" :readonly="true" @click.native="selectDepartment()"></el-input>
            </el-form-item>
            <el-form-item prop="realName" label="姓名">
              <el-input v-model="user.realName"></el-input>
            </el-form-item>
            <el-form-item prop="phone" label="电话">
              <el-input v-model="user.phone"></el-input>
            </el-form-item>
            <el-form-item label="昵称">
              <el-input v-model="user.nickName"></el-input>
            </el-form-item>
            <el-form-item label="邮箱">
              <el-input v-model="user.email"></el-input>
            </el-form-item>
            <el-form-item prop="gender" label="性别">
              <el-radio-group v-model="user.gender">
                <el-radio :label="0">男</el-radio>
                <el-radio :label="1">女</el-radio>
              </el-radio-group>
            </el-form-item>
            <br>
            <!-- 用户头像 -->
            <el-form-item label="头像">
              <el-upload
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload"
                class="avatar-uploader"
                :data="uploadHeader"
                action="http://localhost:8888/api/oss/file/upload?module=avatar">
                <img v-if="user.avatar" :src="user.avatar">
                <i v-else class="el-icon-plus avatar-uploader-icon"/>
              </el-upload>
            </el-form-item>
          </el-form>
        </div>
      </system-dialog>


 /**
    * 打开添加窗口
    */
    openAddWindow() {
      this.$resetForm('userForm', this.user) //清空表单
      this.userDialog.visible = true //显示窗口
      this.userDialog.title = '新增用户' //设置标题
    },
    /**
    * 新增或编辑取消事件
    */
    onClose() {
      this.userDialog.visible = false //关闭窗口
    },
    /**
    * 新增或编辑确认事件
    */
    onConfirm() {
      //表单验证
      this.$refs.userForm.validate(async (valid) => {
        if (valid) {
          let res = null
          // 判断是新增还是修改操作(user.id是否为空)
          if (this.user.id === ""){
              // 发送新增用户请求
              res = await userApi.addUser(this.user)
          }else{
              // 发送修改用户请求
              //res = await userApi.updateUser(this.user)
          }
          if (res.success){
            // 提示成功
            this.$message.success(res.message)
            // 刷新数据
            this.search(this.departmentId, this.pageNo, this.pageSize);
            //关闭窗口
            this.userDialog.visible = false;
          }else{
            this.$message.error(res.message)
          }
        }
      })
    },
   /**
    * 编辑用户
    * @param row
    */
    handleEdit(row) {
      //数据回显
      this.$objCopy(row, this.user);
      //设置窗口标题
      this.userDialog.title = "编辑用户";
      //显示编辑部门窗口
      this.userDialog.visible = true;
    },

2.4 选择所属部门

 <!-- 所属部门弹框 -->
      <system-dialog
        :title="parentDialog.title"
        :width="parentDialog.width"
        :height="parentDialog.height"
        :visible="parentDialog.visible"
        @onClose="onParentClose"
        @onConfirm="onParentConfirm">
        <div slot="content">
          <el-tree
            ref="parentTree"
            :data="parentList"
            default-expand-all
            node-key="id"
            :props="parentProps"
            :show-checkbox="false"
            :highlight-current="true"
            :expand-on-click-node="false"
            @node-click="parentClick">
            <div class="customer-tree-node" slot-scope="{ node, data }">
              <span v-if="data.children.length == 0">
                <i class="el-icon-document"/>
              </span>
              <span v-else @click.stop="changeIcon(data)">
                <svg-icon v-if="data.open"icon-class="add-s"/>
                <svg-icon v-else icon-class="sub-s" />
              </span>
              <span style="margin-left: 3px">{{ node.label }}</span>
            </div>
          </el-tree>
        </div>
      </system-dialog>
 /**
    * 打开选择所属部门窗口
    */
    async selectDepartment() {
      //查询上级部门数据
      let res = await departmentApi.getDepartmentList(null)
      //判断是否成功
      if (res.success) {
        this.parentList = res.data
      }
      //显示窗口
      this.parentDialog.visible = true
    },
    /**
    * 选择上级部门取消事件
    */
    onParentClose() {
      this.parentDialog.visible = false //关闭窗口
    },
    /**
    * 选择上级部门确认事件
    */
    onParentConfirm() {
      this.parentDialog.visible = false
    },
    //上级部门树节点点击事件
    parentClick(data) {
      this.user.departmentId = data.id
      this.user.departmentName = data.departmentName
    },
    /**
    * 新增或编辑确认事件
    */
    onConfirm() {
      this.$refs.userForm.validate(async(valid) => {
        if (valid) {
          let res = null
          //判断用户ID是否为空
          if (this.user.id === '') {
            //新增
            //发送添加请求
            res = await userApi.addUser(this.user)
          } else {
            //发送修改请求
            res = await userApi.updateUser(this.user)
          }
          //判断是否成功
          if (res.success) {
            this.$message.success(res.message)
            //刷新
            this.search(this.departmentId, this.pageNo, this.pageSize);
            //关闭窗口
            this.userDialog.visible = false
          } else {
            this.$message.error(res.message)
          }
        }
      })
    },
 

3、阿里云对象存储OSS服务

3.1 开通阿里云对象存储OSS服务

3.1.1 申请阿里云账号

3.1.2 实名认证

3.1.3 开通OSS对象存储

 

3.2 使用阿里云OSS对象存储

3.2.1 创建Bucket存储空间

 

 3.2.2  文件管理

3.2.3 使用Java SDK操作OSS

 

 4、使用OSS实现文件上传

4.1 添加OSS依赖

      <!-- 阿里云OSS文件上传开始 -->
        <!-- 阿里云 OSS -->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.14.1</version>
        </dependency>
        <!--日期时间工具-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.14</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.10.2</version>
        </dependency>
        <!-- 阿里云OSS文件上传结束 -->

4.2 编写application.properties阿里云配置文件

#阿里云OSS配置
spring.cloud.alicloud.secret-key=cGwJuRlPsS9eRvCijuLjA3wfxZ58aQ
spring.cloud.alicloud.access-key=LTAI5tLmxqCDAEVL9pXaBde4
spring.cloud.alicloud.oss.endpoint=oss-cn-hangzhou.aliyuncs.com
spring.cloud.alicloud.oss.bucket=gulimall-station
#bucket名称
aliyun.oss.file.bucketname=guli-school-online

4.3 读取配置文件信息

4.4 编写文件上传代码

package com.cizhu.service;

import org.springframework.web.multipart.MultipartFile;

/**
 * @author bingo
 * @description 功能描述
 * @date 2022-11-08
 */
public interface FileService {

    /**
     * 文件上传
     * @param file 文件上传对象
     * @param module 文件夹名称
     * @return
     */
    String upload(MultipartFile file, String module);

    /**
     * 删除文件
     * @param url
     */
    void deleteFile(String url);
}
package com.cizhu.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.cizhu.config.oss.OssProperties;
import com.cizhu.service.FileService;
import org.apache.commons.io.FilenameUtils;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;

/**
 * @author bingo
 * @description 功能描述
 * @date 2022-11-08
 */
@Service
@Transactional
public class FileServiceImpl implements FileService {

    /**
     * 文件上传
     *
     * @param file 文件上传对象
     * @param module 文件夹名称
     * @return
     */
    @Resource
    private OssProperties ossProperties;

    /**
     * 文件上传
     *
     * @param file   文件上传对象
     * @param module 文件夹名称
     * @return
     */
    @Override
    public String upload(MultipartFile file, String module) {
        //获取地域节点
        String endPoint = ossProperties.getEndPoint();
        //获取AccessKeyId
        String keyId = ossProperties.getKeyId();
        //获取AccessKeySecret
        String keySecret = ossProperties.getKeySecret();
        //获取BucketName
        String bucketName = ossProperties.getBucketName();
        try {
            //创建OSSClient实例
            OSS ossClient = new OSSClientBuilder().build(endPoint, keyId,
                    keySecret);
            //上传文件流
            InputStream inputStream = file.getInputStream();
            //获取旧名称
            String originalFilename = file.getOriginalFilename();
            //获取文件后缀名
            String extension = FilenameUtils.getExtension(originalFilename);
            //将文件名重命名
            String newFileName = UUID.randomUUID().toString().replace("-", "")+"."+extension;
            //使用当前日期进行分类管理
            String datePath = new DateTime().toString("yyyy/MM/dd");
            //构建文件名
            newFileName = module + "/" + datePath + "/" + newFileName;
            //调用OSS文件上传的方法
            ossClient.putObject(bucketName, newFileName, inputStream);
            //关闭OSSClient
            ossClient.shutdown();
            //返回文件地址
            return "https://"+bucketName+"."+endPoint+"/"+newFileName;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 删除文件
     *
     * @param url
     */
    @Override
    public void deleteFile(String url) {
        //获取地域节点
        String endPoint = ossProperties.getEndPoint();
        //获取AccessKeyId
        String keyId = ossProperties.getKeyId();
        //获取AccessKeySecret
        String keySecret = ossProperties.getKeySecret();
        //获取BucketName
        String bucketName = ossProperties.getBucketName();
        try {
            //创建OSSClient实例
            OSS ossClient = new OSSClientBuilder().build(endPoint, keyId, keySecret);
            //组装文件地址
            String host = "https://"+bucketName+"."+endPoint+"/";
            //获取文件名称
            String objectName = url.substring(host.length());
            //删除文件
            ossClient.deleteObject(bucketName,objectName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.5 文件上传控制器 

package com.cizhu.controller;

import com.cizhu.service.FileService;
import com.cizhu.utils.Result;
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 javax.annotation.Resource;

/**
 * @author bingo
 * @description 功能描述
 * @date 2022-11-08
 */
@RestController
@RequestMapping("/api/oss/file")
public class OSSController {
    @Resource
    private FileService fileService;

    /**
     * 文件上传
     * @param file
     * @param module
     * @return
     */
    @PostMapping("/upload")
    public Result upload(MultipartFile file, String module){
        //返回上传到oss的路径
        String url = fileService.upload(file,module);
        return Result.ok(url).message("文件上传成功");
    }
}

4.6 上传用户头像

4.6.1 定义页面组件模版

            <!-- 用户头像 -->
            <el-form-item label="头像">
              <el-upload
                :show-file-list="false"
                :on-success="handleAvatarSuccess"
                :before-upload="beforeAvatarUpload"
                class="avatar-uploader"
                :data="uploadHeader"
                action="http://localhost:8888/api/oss/file/upload?module=avatar">
                <img v-if="user.avatar" :src="user.avatar">
                <i v-else class="el-icon-plus avatar-uploader-icon"/>
              </el-upload>
            </el-form-item>

头像样式美化

//用户头像
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9 !important;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409EFF;
}
.avatar-uploader .avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}
.avatar-uploader img {
  width: 178px;
  height: 178px;
  display: block;
}

4.6.2 定义页面组件脚本代码

引入token

//导入token
import {getToken} from '@/utils/auth'

定义上传需要携带的token

 上传的事件方法

  /**
    * 上传成功回调
    * @param res
    * @param file
    */
    handleAvatarSuccess(res, file) {
      this.user.avatar = res.data
      // 强制重新渲染
      this.$forceUpdate()
    },
    /**
    * 上传校验
    * @param file
    * @returns {boolean}
    */
    beforeAvatarUpload(file) {
      const isJPG = file.type === 'image/jpeg'
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isJPG) {
        this.$message.error('上传头像图片只能是 JPG 格式!')
      }
      if (!isLt2M) {
        this.$message.error('上传头像图片大小不能超过 2MB!')
      }
      return isJPG && isLt2M
    },

  • 22
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值