day22_用户授权 头像上传

day22_用户授权 头像上传

1用户授权

场景分析
sql分析
复制代码
-- 展示树型菜单 和 根据用户编号选中已有菜单选项
select am2.*,
               am1.mid as submid,am1.menuname as submenuname,am1.url as suburl
​
        from admin_menu am1  inner join admin_menu am2 on am1.pid = am2.mid
                
                
                
select mid from rel_admin_user_menu where uid = 7
​
​
-- 删除旧的权限信息 添加新的信息
delete from rel_admin_user_menu where uid = 3
​
​
insert into rel_admin_user_menu (uid,mid) values (3,11001),(3,12001),(3,13001)
编码

调用多个dao时 需要注意事务控制

复制代码
    @Override
    public Boolean changeUserMid(Long uid, List<Long> listMid) {
        //未开启自动提交
        SqlSession sqlSession = MyBatisHealper.getSqlSession();
        AdminMenuDao mapper = sqlSession.getMapper(AdminMenuDao.class);
        Boolean flag = false;
​
        try{
            //需要一起成功 再提交
            mapper.deleteUserMId(uid);
            //如果listMid没值 跳过添加环节
            if(listMid.size()>0){
                mapper.insertUserMId(uid,listMid);
            }
            //成功再提交
            sqlSession.commit();
            flag = true;
        } catch (Exception e) {
            //异常 不提交
            throw new RuntimeException(e);
        }finally {
            //只还连接
            //自动回滚
            MyBatisHealper.backSqlSession(sqlSession);
            return flag;
        }
​
    }

tree组件

复制代码
        <el-tree
            ref="treeRef"
            style="max-width: 600px"
            :data="treeData.treeList"
            show-checkbox
            default-expand-all
            node-key="mid"
            highlight-current
            :props="defaultProps"
        />
复制代码
//tree组件对象
const treeRef = ref()
//tree组件数据
const treeData = reactive({treeList:[]})
//默认key value 对应关系
const defaultProps = {
  children: 'subMenu',
  label: 'menuname',
}

tree组件混合form使用

复制代码
const authVisable = ref(false)
const authForm = reactive({
    username:'',
    uid:'',
    listMid:''
})
​
//授权开框
const openAuthDialog = async(currentRow)=>{
    console.log(currentRow);
    
    // 打开授权对话框
     authVisable.value = true
    //uid和usernmae赋值
    authForm.username = currentRow.username
    authForm.uid = currentRow.uid
    //tree组件展示和赋值
    let resp = await myGet('/users/listAllMenuByUId',{uid:currentRow.uid})
    console.log(resp.data.returnData);
    //tree组件赋值
    treeData.treeList = resp.data.returnData.listAllMenu
    //tree组件选中选项
    treeRef.value.setCheckedKeys(resp.data.returnData.listMId)
}
//授权提交
const authSubmit = async ()=>{
    //把选中的菜单编号 给authForm赋值
    authForm.listMid = treeRef.value.getCheckedKeys(true).join(",")
     // 关授权对话框
     authVisable.value = false
    //操作数据公共函数
    operationData('/users/changeUserMid',authForm)
    
​
}

2文件上传

前端发送文件的基本要求
复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <input id="myFile" type="file" onchange="testSend()">
</body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
​
    /*
    * 1 使用文件框选文件
    * 2 文件放入FormData对象中 支持字符串key value  支持文件  key blob
    * 3 通过post请求发送FormData
    *
    * */
​
    const testSend = ()=>{
        let currentFile = document.getElementById("myFile").files[0]
        console.log(currentFile)
         let formData = new FormData();
        //在请求体中的key
         formData.append("myFile",currentFile)
         axios.post("/baseProj/upload",formData)
​
    }
​
​
​
​
</script>
</html>
服务端接收和保存
复制代码
package com.javasm.controller;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
​
/**
 * @className: UploadDemoServlet
 * @author: gfs
 * @date: 2025/10/30 14:33
 * @version: 0.1
 * @since: jdk17
 * @description:
 */
@WebServlet("/upload")
//解析字节数据
@MultipartConfig
public class UploadDemoServlet extends HttpServlet {
​
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.接收
        //取到文件对象
        Part myFile = req.getPart("myFile");
​
        System.out.println(myFile.getSize());
        System.out.println(myFile.getSubmittedFileName());
        //2保存
        //向本地写文件
        myFile.write("d:\\"+myFile.getSubmittedFileName());
​
    }
}
​
2.1存到本地 可以访问的目录

上传接口

复制代码
package com.javasm.controller;
​
import com.alibaba.fastjson.JSON;
import com.javasm.entity.ReturnCode;
import com.javasm.entity.ReturnResult;
​
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.PrintWriter;
​
/**
 * @className: UploadDemoServlet
 * @author: gfs
 * @date: 2025/10/30 14:33
 * @version: 0.1
 * @since: jdk17
 * @description:
 */
@WebServlet("/upload")
//解析字节数据
@MultipartConfig
public class UploadDemoServlet extends HttpServlet {
​
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.接收
        //取到文件对象
        Part myFile = req.getPart("myFile");
​
        System.out.println(myFile.getSize());
        System.out.println(myFile.getSubmittedFileName());
        //2保存
        //获取部署的根目录
        String basePath = req.getServletContext().getRealPath("/");
        System.out.println(basePath);
        //存入指定目录
        String folderName = "uploadTest/";
​
        //向本地写文件
        myFile.write(basePath+folderName+myFile.getSubmittedFileName());
​
        ReturnResult returnResult = new ReturnResult();
​
        returnResult.setCode(ReturnCode.DATA_OPERATION_SUCCESS.getCode());
        returnResult.setMsg(ReturnCode.DATA_OPERATION_SUCCESS.getMsg());
        //返回前端显示时使用的路径
        returnResult.setReturnData("http://localhost:8080/baseProj/"+folderName+myFile.getSubmittedFileName());
        //输出json数据
        resp.setContentType("application/json;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print(JSON.toJSONString(returnResult));
        writer.close();
​
​
    }
}
​

防止文件重复的策略

复制代码
        //防止文件重复
        //1 文件名不重要 配合UUID 重置文件名
        //2 改目录名 读登录的用户信息 或者时间戳 建出不同的目录
复制代码
package com.javasm.controller;

import com.alibaba.fastjson.JSON;
import com.javasm.entity.ReturnCode;
import com.javasm.entity.ReturnResult;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.UUID;

/**
 * @className: UploadDemoServlet
 * @author: gfs
 * @date: 2025/10/30 14:33
 * @version: 0.1
 * @since: jdk17
 * @description:
 */
@WebServlet("/upload")
//解析字节数据
@MultipartConfig
public class UploadDemoServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.接收
        //取到文件对象
        Part myFile = req.getPart("myFile");

        System.out.println(myFile.getSize());
        System.out.println(myFile.getSubmittedFileName());
        //2保存
        //获取部署的根目录
        String basePath = req.getServletContext().getRealPath("/");
        System.out.println(basePath);

        //防止文件重复
        //1 文件名不重要 配合UUID 重置文件名
        //2 改目录名 读登录的用户信息 或者时间戳 建出不同的目录

        //存入指定目录
        String folderName = "uploadTest/";

        //文件名
        String newFileName = UUID.randomUUID()+myFile.getSubmittedFileName().substring(myFile.getSubmittedFileName().lastIndexOf("."));  // myFile.getSubmittedFileName();

        //向本地写文件
        myFile.write(basePath+folderName+newFileName);

        ReturnResult returnResult = new ReturnResult();

        returnResult.setCode(ReturnCode.DATA_OPERATION_SUCCESS.getCode());
        returnResult.setMsg(ReturnCode.DATA_OPERATION_SUCCESS.getMsg());
        //返回前端显示时使用的路径
        returnResult.setReturnData("http://localhost:8080/baseProj/"+folderName+newFileName);
        //输出json数据
        resp.setContentType("application/json;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print(JSON.toJSONString(returnResult));
        writer.close();


    }
}

存本地的接口

复制代码
package com.javasm.controller;

import com.alibaba.fastjson.JSON;
import com.javasm.entity.ReturnCode;
import com.javasm.entity.ReturnResult;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.UUID;

/**
 * @className: UploadServlet
 * @author: gfs
 * @date: 2025/10/30 15:02
 * @version: 0.1
 * @since: jdk17
 * @description:
 */
@WebServlet("/upload")
@MultipartConfig
public class UploadServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.取文件
        Part myFile = req.getPart("myFile");
        //2.拼出保存到本地的路径
        String basePath = req.getServletContext().getRealPath("/");
        String folderName = "uploadTest/";
        String newFileName = UUID.randomUUID()+myFile.getSubmittedFileName().substring(myFile.getSubmittedFileName().lastIndexOf("."));  // myFile.getSubmittedFileName();
        //保存到本地
        myFile.write(basePath+folderName+newFileName);

        //3.给页面操作反馈和预览地址
        String domain = "http://localhost:8080/baseProj/";

        ReturnResult returnResult = new ReturnResult();
        //返回操作成功
        returnResult.setCode(ReturnCode.DATA_OPERATION_SUCCESS.getCode());
        returnResult.setMsg(ReturnCode.DATA_OPERATION_SUCCESS.getMsg());
        //返回前端显示时使用的路径
        returnResult.setReturnData(domain+folderName+newFileName);
        //输出json数据
        resp.setContentType("application/json;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print(JSON.toJSONString(returnResult));
        writer.close();

    }
}
2.2上传头像的页面

把上传组件替换之前的输入框

复制代码
      <el-form-item label="头像地址" prop="headImg">
        <!-- <el-input v-model="insertForm.headImg"  /> -->
        <el-upload
            class="avatar-uploader"
            action=""
            :show-file-list="false"
            :http-request="myUpload"
        >
            <img v-if="insertForm.headImg" :src="insertForm.headImg" class="avatar" />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
        </el-upload>


      </el-form-item>

配合一个自定义上传和响应处理的函数

复制代码
/**添加上传头像 */
const myUpload =  async (rowFile)=>{ 
    console.log(rowFile);
    //获取上传文件
    let myFile = rowFile.file
    //创建formData对象
    let formData = new FormData();
    formData.append('myFile',myFile);
    //发送post请求
    let resp = await axios.post("/upload",formData)
    insertForm.headImg = resp.data.returnData

}
2.3存到云存储
通过服务器传
七牛云工具类

accessKey和secretKey

bucketName 空间名

外网临时域名(有效期30天 免费)

复制代码
package com.javasm.utils;

import com.alibaba.fastjson.JSON;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;

import javax.servlet.http.Part;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * @className: QiniuUtils
 * @author: gfs
 * @date: 2025/10/30 15:59
 * @version: 0.1
 * @since: jdk17
 * @description:
 */
public class QiniuUtils {
	//根据登录的账号和使用的空间配置
    private static final String accessKey = "t0oUPjPwjqQiS2EM3vm5FIIGI8InWKOOXeNnFpZg";
    private static final String secretKey = "66Hd-TKVVbwRrHSTtiQqE8i8L-VOsUaJ1iWTO8rv";
    private static final String bucketName = "javasm69test";
    private static final String domain = "http://t4xpuhvhc.hn-bkt.clouddn.com/";

    /**
     * 获取七牛token,返回给客户端
     *
     * @return
     */
    public static String getToken() {
        //校验  AK 和 SK 是否正确
        Auth auth = Auth.create(accessKey, secretKey);
        //生成 服务端 Token
        String token = auth.uploadToken(bucketName);
        return token;
    }

    /**
     * 返回域名
     *
     * @return
     */
    public static String getDomain() {
        return domain;
    }


    public static String upload(String filePath) {
        return upload(new File(filePath));
    }

    public static String upload(File file) {
        //构造一个带指定 Region 对象的配置类
        /**
         * 华东	Region.region0(), Region.huadong()
         * 华北	Region.region1(), Region.huabei()
         * 华南	Region.region2(), Region.huanan()
         * 北美	Region.regionNa0(), Region.beimei()
         * 东南亚	Region.regionAs0(), Region.xinjiapo()
         */
        Configuration cfg = new Configuration(Region.region2());
        cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
        UploadManager uploadManager = new UploadManager(cfg);
        //默认不指定key的情况下,以文件内容的hash值作为文件名
        String key = null;
        String upToken = getToken();
        try {
            Response response = uploadManager.put(file, key, upToken);
            //解析上传成功的结果
            DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);
            return domain + putRet.hash;
        } catch (QiniuException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    public static String uploadStream(InputStream is,String key) {
        //构造一个带指定 Region 对象的配置类
        /**
         * 华东	Region.region0(), Region.huadong()
         * 华北	Region.region1(), Region.huabei()
         * 华南	Region.region2(), Region.huanan()
         * 北美	Region.regionNa0(), Region.beimei()
         * 东南亚	Region.regionAs0(), Region.xinjiapo()
         */
        Configuration cfg = new Configuration(Region.region2());
        cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
        UploadManager uploadManager = new UploadManager(cfg);
        //默认不指定key的情况下,以文件内容的hash值作为文件名
        String upToken = getToken();
        key = null;
        try {

            Response response = uploadManager.put(is, key, upToken,null,null);
            //解析上传成功的结果
            DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);
            return domain + putRet.hash;
        } catch (QiniuException ex) {
            ex.printStackTrace();
        }
        return null;
    }




    public static void main(String[] args) {
        String fileName = "D:\\尚马壁纸-03.png";

        String upload = QiniuUtils.upload(fileName);
        System.out.println(upload);

    }
}
java上传接口
复制代码
package com.javasm.controller;

import com.alibaba.fastjson.JSON;
import com.javasm.entity.ReturnCode;
import com.javasm.entity.ReturnResult;
import com.javasm.utils.QiniuUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.UUID;

/**
 * @className: UploadServlet
 * @author: gfs
 * @date: 2025/10/30 15:02
 * @version: 0.1
 * @since: jdk17
 * @description:
 */
@WebServlet("/upload2")
@MultipartConfig
public class UploadServlet2 extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.取文件
        Part myFile = req.getPart("myFile");
        //上传文件的流数据
        InputStream inputStream = myFile.getInputStream();

        //2存储到七牛云存储中
        String filePath = QiniuUtils.uploadStream(inputStream, null);
        System.out.println(filePath);


        //3.给页面操作反馈和预览地址

        ReturnResult returnResult = new ReturnResult();
        //返回操作成功
        returnResult.setCode(ReturnCode.DATA_OPERATION_SUCCESS.getCode());
        returnResult.setMsg(ReturnCode.DATA_OPERATION_SUCCESS.getMsg());
        //返回前端显示时使用的路径
        returnResult.setReturnData(filePath);
        //输出json数据
        resp.setContentType("application/json;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print(JSON.toJSONString(returnResult));
        writer.close();

    }
}
直接从前端传
java接口 只传token和domain
复制代码
package com.javasm.controller;

import com.alibaba.fastjson.JSON;
import com.javasm.entity.ReturnCode;
import com.javasm.entity.ReturnResult;
import com.javasm.utils.QiniuUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;

/**
 * @className: GetQiniuToken
 * @author: gfs
 * @date: 2025/10/30 16:19
 * @version: 0.1
 * @since: jdk17
 * @description:
 */
@WebServlet("/getQiniuToken")
public class GetQiniuToken extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String token = QiniuUtils.getToken();
        String domain = QiniuUtils.getDomain();

        //3.给页面操作反馈和预览地址

        ReturnResult returnResult = new ReturnResult();
        //返回操作成功
        returnResult.setCode(ReturnCode.QUERY_SUCCESS.getCode());
        returnResult.setMsg(ReturnCode.QUERY_SUCCESS.getMsg());
        //返回前端显示时使用的路径
        HashMap<String, String> dataMap = new HashMap<>();
        dataMap.put("token",token);
        dataMap.put("domain",domain);
        returnResult.setReturnData(dataMap);
        //输出json数据
        resp.setContentType("application/json;charset=utf-8");
        PrintWriter writer = resp.getWriter();
        writer.print(JSON.toJSONString(returnResult));
        writer.close();

    }
}
前端 安装依赖
复制代码
pnpm i qiniu-js@^3.4.2

页面需要使用时 引入js

复制代码
import * as qiniu from 'qiniu-js'

上传方法改造

复制代码
// 直接上传到七牛云存储
const myUpload3 =  async (rowFile)=>{ 
     //访问自己的接口 获取token和domain
     let resp = await axios.get("/getQiniuToken")
     let token = resp.data.returnData.token;
     let domain = resp.data.returnData.domain;
     console.log(token,domain);

    //设置七牛云存储对象
    // //获取上传文件
    let myFile = rowFile.file
    let observable = qiniu.upload(myFile,null,token);
     //上传的一些设置
    let options = {
            //上传过程中
            next: (res)=>{
                //console.log(res)
            },
            //上传错误
            error: (err)=> {console.log(err)},
            //上传成功
            complete: (res)=>{
                 console.log("----------------------------上传成功-------------------------")
                console.log(res)
                updateForm.updateData.headImg = domain+res.hash
            }
          }
    //实际上传的方法
    observable.subscribe(options); 


}
相关推荐
小阳生煎2 小时前
Vue实现全局设置一个刷新按钮 只刷新当面路由页面 不跳转操作功能
vue.js·vue
小光学长2 小时前
基于Vue的儿童手工创意店管理系统as8celp7(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
meichaoWen2 小时前
【Vue】Vue框架的基础知识强化
前端·javascript·vue.js
西西学代码2 小时前
Flutter---DragTarget(颜色拖拽选择器)
前端·javascript·flutter
小光学长2 小时前
基于Vue的地铁综合服务管理系统7949eg04(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
阿蓝灬2 小时前
React中的stopPropagation和preventDefault
前端·javascript·react.js
天天向上10243 小时前
vue3 抽取el-dialog子组件
前端·javascript·vue.js
lecepin3 小时前
AI Coding 资讯 2025-11-05
前端·javascript
前端小咸鱼一条3 小时前
17.React获取DOM的方式
前端·javascript·react.js