OSS(Object Storage Service)进行上传图片,下载图片(详细看文档可以完成操作)

1.单体前后端项目上传

1.上传流程

在这里插入图片描述
这样有利于保护自己的账号和密码不被泄露,通过账号密码生成的防伪笔名进行验证是否正确

2. BuckName 和EndPoint

在这里插入图片描述

3. AccessKey 和Access Secret(创建RAM(Resource Access Manage)的子账号,然后可以获得Accesskey和Acess Secret)

在这里插入图片描述
在这里插入图片描述

3.根据创建的子账号分配OSS的所有权限(可以对文件进行上传,下载,删除的权限)

在这里插入图片描述

4.采用上传的方式(服务器直传,服务器得签名后后端直传,前端直传)

前端直传:不好,用户可以直接f12找到我们的endpoint,bucketName,和重要的Acesskey,AccessSecret,不安全,导致我们的信息泄露。
服务器直传:会造成性能瓶颈,给服务器造成压力。
服务器得签名后后端直传:这种方法可以,可以加密我们的签名之后进行上传。如果想了解用户上传了什么东西可以设计 上传回调
在这里插入图片描述

5. 出现跨域问题解决

在这里插入图片描述

在这里插入图片描述

引入依赖

    <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.15.0</version>
        </dependency>
        <dependency>

6.前端实现code

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>oss测试上传</title>
    <script src="static/js/vue.min.js"></script>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
 <!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
  
</head>
<body>
    <div id="app">
          <!-- <form action="/upload/oss" method="post" enctype="multipart/form-data">
        <input type="file" name="file" value="选择文件上传">
        <input type="submit" name="提交"/>
    </form> -->
    <el-upload
    draggable="true"
  class="upload-demo"
  :action="obj.host"
  :before-upload="ossPolicy"
  :on-success="onsuccess"
  //上传时绑定的数据
  :data="obj"
  :limit="2"
  :file-list="fileList"
  list-type="picture">
  <el-button size="small" type="primary">点击上传</el-button>
  <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
    </div>
  
    <script src="static/js/axios.min.js"></script>  
<script type="text/javascript ">
    var vm=new Vue({
    el:"#app",
    data:{
        fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}],
        obj:{
            OSSAccessKeyId:"",
            policy:"",
            signature:"",
            key:"",
            host:"",
            dir:"",
        }
    },
    methods: {
  
      ossPolicy(file){
        // 上传前,获取服务器给的签名
        axios({
				url:"http://localhost:8080/oss/policy",
				method:"get",
			}).then(res=>{
                console.log("come in ---------",res.data)
                this.obj.OSSAccessKeyId = res.data.accessId;
                this.obj.policy = res.data.policy;
                this.obj.dir = res.data.dir;
                this.obj.signature = res.data.signature; 
                //传到oss的服务器地址
                this.obj.host = res.data.host;
                this.obj.key =res.data.dir + "${filename}";

      })
    },
    //文件上传成功时调用
    onsuccess(response, file, fileList){
        console.log("response",response)
        console.log(file)
        
    },

}


})
</script>

</body>
</html>

6.1 单个文件上传
<template> 
  <div>
    <el-upload
      :action="dataObj.host"
      :data="dataObj"
      list-type="picture"
      :multiple="false" :show-file-list="showFileList"
      :file-list="fileList"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      :on-success="handleUploadSuccess"
      :on-preview="handlePreview">
      <el-button size="small" type="primary">点击上传</el-button>
      <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过10MB</div>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="fileList[0].url" alt="">
    </el-dialog>
  </div>
</template>
<script>
   import {policy} from './policy'
   import { getUUID } from '@/utils'

  export default {
    name: 'singleUpload',
    props: {
      value: String
    },
    computed: {
      imageUrl() {
        return this.value;
      },
      imageName() {
        if (this.value != null && this.value !== '') {
          return this.value.substr(this.value.lastIndexOf("/") + 1);
        } else {
          return null;
        }
      },
      fileList() {
        return [{
          name: this.imageName,
          url: this.imageUrl
        }]
      },
      showFileList: {
        get: function () {
          return this.value !== null && this.value !== ''&& this.value!==undefined;
        },
        set: function (newValue) {
        }
      }
    },
    data() {
      return {
        dataObj: {
          policy: '',
          signature: '',
          key: '',
          ossaccessKeyId: '',
          dir: '',
          host: '',
          // callback:'',
        },
        dialogVisible: false,
        url:'',
      };
    },
    methods: {
      emitInput(val) {
        this.$emit('input', val)
      },
      handleRemove(file, fileList) {
        this.emitInput('');
      },
      handlePreview(file) {
        this.dialogVisible = true;
      },
      beforeUpload(file) {
        let _self = this;
        return new Promise((resolve, reject) => {
          policy().then(response => {
            console.log("响应的数据",response);
            _self.dataObj.policy = response.data.policy;
            _self.dataObj.signature = response.data.signature;
            _self.dataObj.ossaccessKeyId = response.data.accessid;
            _self.dataObj.key = response.data.dir +getUUID()+'_${filename}';
            _self.dataObj.dir = response.data.dir;
            _self.dataObj.host = response.data.host;
            console.log("响应的数据222。。。",_self.dataObj);
            resolve(true)
          }).catch(err => {
            reject(false)
          })
        })
      },
      handleUploadSuccess(res, file) {
        console.log("上传成功...")
        this.showFileList = true;
        this.fileList.pop();
        this.fileList.push({name: file.name, url: this.dataObj.host + '/' + this.dataObj.key.replace("${filename}",file.name) });
        this.url = this.fileList[0].url;
        this.emitInput(this.fileList[0].url);
      }
    }
  }
</script>
<style>

</style>
可以用一个url变量接收我们的上传之后成功的图片路径,点击保存的时间可以将这个url传到数据库中去,前端在直接通过单向绑定:src =“显示数据库中保存的url”
6.2多个文件上传
<template>
  <div>
    <el-upload
      action="http://+`你的bucketName` + '.' +'你的endpoint'"
      :data="dataObj"
      :list-type="listType"
      :file-list="fileList"
      :before-upload="beforeUpload"
      :on-remove="handleRemove"
      :on-success="handleUploadSuccess"
      :on-preview="handlePreview"
      :limit="maxCount"
      :on-exceed="handleExceed"
      :show-file-list="showFile"
    >
      <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
      <img width="100%" :src="dialogImageUrl" alt />
    </el-dialog>
  </div>
</template>
<script>
import { policy } from "./policy";
import { getUUID } from '@/utils'
export default {
  name: "multiUpload",
  props: {
    //图片属性数组
    value: Array,
    //最大上传图片数量
    maxCount: {
      type: Number,
      default: 30
    },
    listType:{
      type: String,
      default: "picture-card"
    },
    showFile:{
      type: Boolean,
      default: true
    }

  },
  data() {
    return {
      dataObj: {
        policy: "",
        signature: "",
        key: "",
        ossaccessKeyId: "",
        dir: "",
        host: "",
        uuid: ""
      },
      dialogVisible: false,
      dialogImageUrl: null
    };
  },
  computed: {
    fileList() {
      let fileList = [];
      for (let i = 0; i < this.value.length; i++) {
        fileList.push({ url: this.value[i] });
      }

      return fileList;
    }
  },
  mounted() {},
  methods: {
    emitInput(fileList) {
      let value = [];
      for (let i = 0; i < fileList.length; i++) {
        value.push(fileList[i].url);
      }
      this.$emit("input", value);
    },
    handleRemove(file, fileList) {
      this.emitInput(fileList);
    },
    handlePreview(file) {
      this.dialogVisible = true;
      this.dialogImageUrl = file.url;
    },
    beforeUpload(file) {
      let _self = this;
      return new Promise((resolve, reject) => {
        policy()
          .then(response => {
            console.log("这是什么${filename}");
            _self.dataObj.policy = response.data.policy;
            _self.dataObj.signature = response.data.signature;
            _self.dataObj.ossaccessKeyId = response.data.accessid;
            _self.dataObj.key = response.data.dir +getUUID()+"_${filename}";
            _self.dataObj.dir = response.data.dir;
            _self.dataObj.host = response.data.host;
            resolve(true);
          })
          .catch(err => {
            console.log("出错了...",err)
            reject(false);
          });
      });
    },
    handleUploadSuccess(res, file) {
      this.fileList.push({
        name: file.name,
        // url: this.dataObj.host + "/" + this.dataObj.dir + "/" + file.name; 替换${filename}为真正的文件名
        url: this.dataObj.host + "/" + this.dataObj.key.replace("${filename}",file.name)
      });
      this.emitInput(this.fileList);
    },
    handleExceed(files, fileList) {
      this.$message({
        message: "最多只能上传" + this.maxCount + "张图片",
        type: "warning",
        duration: 1000
      });
    }
  }
};
</script>
<style>
</style>





7.后端code实现

package com.qfedu.fmmall.controller;/*
 **
 *@author SmallMonkey
 *@Date 2023/2/10 13:07
 *
 *
 **/

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

@RestController
@CrossOrigin
@RequestMapping("/oss")
public class OssController {
    @RequestMapping("/policy")
    public Map<String,String> policy(){
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessId = "LTAI5tRNby21a72dAhf4NbPa";
        String accessKey = "LTWOauYIuCkNF2O9zgU0Mm7HCuV5BE";
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";
        // 填写Bucket名称,例如examplebucket。
        String bucket = "fmmallrebuild";
        // 填写Host地址,格式为https://bucketname.endpoint。
        String host = "https://" + bucket + "." + endpoint;
        // 设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。
       // String callbackUrl = "https://192.168.0.0:8888";
        // 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。
        //可以加上当前的日期
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String dir = simpleDateFormat.format(new Date()) + "/";

        //String objectName = dir + UUID.randomUUID().toString()+".png";


        // 创建ossClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessId, accessKey);
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessId", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));

            return respMap;
//服务进行上线之后,有一个外网可以访问的地址可以设置回调
  /*

       JSONObject jasonCallback = new JSONObject();
            jasonCallback.put("callbackUrl", callbackUrl);
            jasonCallback.put("callbackBody",
                    "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
            jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
            String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
            respMap.put("callback", base64CallbackBody);

            JSONObject ja1 = JSONObject.fromObject(respMap);*/

        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        }
        return null;
    }

}





2.SpringCloud形式OSS上传

1.引入依赖

    <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>



2.后端实现code

@RestController
public class OssController {

    @Autowired
    OSS ossClient;
    @Value ("${spring.cloud.alicloud.oss.endpoint}")
    String endpoint ;

    @Value("${spring.cloud.alicloud.oss.bucket}")
    String bucket ;

    @Value("${spring.cloud.alicloud.access-key}")
    String accessId ;
    @Value("${spring.cloud.alicloud.secret-key}")
    String accessKey ;
    @RequestMapping("/oss/policy")
    public Map<String, String> policy(){

        String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint

        String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
        String dir = format; // 用户上传文件时指定的前缀。

        Map<String, String> respMap=null;
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            respMap= new LinkedHashMap<String, String>();
            respMap.put("accessid", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));

        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return respMap;
    }
}


3.前端实现code

2. 商品管理系统OSS实现图片显示和图片上传

1.前端Code

<!DOCTYPE html>
<html>

<head>
	<meta charset="UTF-8">
	<title></title>
	<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">


	<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
	<!-- 引入样式 -->
	<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
	<!-- 引入组件库 -->
	<script src="https://unpkg.com/element-ui/lib/index.js">

	</script>
</head>

<body>








	<div class="fillcontain" id="app">
		<template>
			<!-- <el-alert
		title="商品管理页面"
		type="success"
		
	
		show-icon>
	  </el-alert>
	 -->

		</template>
		<h2 class="ui teal header" style="text-align: center;margin-top: 10px;">欢迎来到商品管理页面</h2>
		<el-form :model="dataForm" class="search_container" label-width="100px" @keyup.enter.native="submit(1)">
			<el-row>
				<el-col :span="8">
					<el-form-item label="农产品类别">
						<!-- <el-select filterable style="width: 220px;" v-model="dataForm.categoryName" default-first-option
							filterable allow-create clearable size="small" placeholder="选择商品一级分类"
							@change="changeSubCategory" >
							<el-option v-for="(item,index) in this.parentCategoryList" :key="index" :label="item.label"
								:value="item.value" />
						</el-select> -->

						<el-cascader filterable :show-all-levels="false" size="small" clearable
							v-model="dataForm.categoryIds" :options="options" :props="props" @change="handleChange"
							@getCheckedNodes="getCheckedNodes">
							<!-- 自定义显示的列 -->
							<template slot-scope="{ node,data }">

								<span>{{data.categoryId}}、{{ data.categoryName}}</span>
							</template>
						</el-cascader>

					</el-form-item>




				</el-col>

				<!-- <el-col :span="5">
					<el-form-item label="二级">
						<el-select style="width: 120px;" filterable allow-create @change="change" placeholder="二级分类"
							clearable size="small" v-model="dataForm.categoryName1">
							<el-option v-for="(item,index) in this.subOptions" :key="index" :label="item.label"
								:value="item.value">
							</el-option>




						</el-select>
					</el-form-item>

				</el-col> -->

				<el-col :span="8">
					<el-form-item label="商品名称" label-width="120px">
						<el-input v-model="dataForm.product_name" placeholder="输入商品名称" clearable size="small">
						</el-input>
					</el-form-item>
				</el-col>


				<el-col :span="8">
					<el-form-item label="商品的状态">
						<el-select v-model="dataForm.isup" clearable size="small">
							<el-option label="上架" value="1" style="color: teal;"> </el-option>
							<el-option label="下架" value="0" style="color: red;"> </el-option>


						</el-select>
						<!-- <el-switch style="display: block"  v-model="dataForm.isup" active-value="1"
						inactive-value="0" active-color="#13ce66"
							inactive-color="#ff4949" active-text="上架" inactive-text="下架" @change="changeProductStatus(scope.row)">
						</el-switch>
		 -->


					</el-form-item>
				</el-col>



				<el-col :span="18">
					<el-form-item label="商品上架日期">
						<el-date-picker v-model="dataForm.submistrdte" type="date" placeholder="开始日期"
							value-format="yyyy-MM-dd" clearable size="small">
						</el-date-picker>
						<span class="spanline">&nbsp;-&nbsp;</span>
						<el-date-picker v-model="dataForm.submienddte" type="date" placeholder="结束日期"
							value-format="yyyy-MM-dd" @blur='dataBlur' clearable size="small">
						</el-date-picker>
					</el-form-item>
				</el-col>


				<el-col :span="6" class="text_center">
					<el-button type="primary" icon="el-icon-search" @click="intDataList(1)" size="small"></el-button>
					<el-button icon="el-icon-refresh" @click="resetForm" size="small"></el-button>
					<el-button type="success" size="small" @click="addHandle">新增商品</el-button>
				</el-col>
			</el-row>
		</el-form>




		<!-- 查询结果列表 -->
		<div class="listbox">

			<!-- 列表 -->
			<el-table ref="multipleTable" :data="dataList" border :fit="true" style="width: 100%" disabled>
				<el-table-column sortable type="index" label="序号" header-align="center" width="45"></el-table-column>
				<el-table-column v-if="false" sortable prop="product_id" label="商品id" show-overflow-tooltip
					min-width="100" disabled>
					<template slot-scope="scope">



						<span> {{ scope.row.product_id || '--' }} </span>
					</template>
				</el-table-column>


				<el-table-column sortable prop="product_name" label="商品名称" show-overflow-tooltip min-width="100"
					disabled>
					<template slot-scope="scope">

						<span> {{ scope.row.product_name || '--' }} </span>
					</template>
				</el-table-column>

				<el-table-column sortable prop="sell_price" label="商品销售价格" show-overflow-tooltip min-width="100"
					disabled>
					<template slot-scope="scope">

						<span> {{ scope.row.sell_price || '--' }} </span>
					</template>
				</el-table-column>

				<el-table-column sortable prop="sku_name" label="商品套餐名" show-overflow-tooltip min-width="80" disabled>
					<template slot-scope="scope">



						<span> {{ scope.row.sku_name || '--' }} </span>
					</template>
				</el-table-column>

				<el-table-column sortable prop="untitled" label="商品套餐" show-overflow-tooltip min-width="180" disabled>
					<template slot-scope="scope">



						<span> {{ scope.row.untitled || '--' }} </span>
					</template>
				</el-table-column>


				<el-table-column sortable prop="url" label="商品图片显示" show-overflow-tooltip min-width="100"
					disabled>
					<template slot-scope="scope">
						
						<!-- 通过oss显示图片 -->
						<img width="80px" height="25px" :src="scope.row.url" style="border-radius: 5px;">
					</template>
				</el-table-column>

				<el-table-column sortable prop="category_name" label="商品分类名称" show-overflow-tooltip min-width="100">
					<template slot-scope="scope"> {{ scope.row.category_name || '--' }} </template>
				</el-table-column>
				<el-table-column prop="isup" label="商品的状态" show-overflow-tooltip min-width="130" sortable>
					<template slot-scope="scope">
						<!-- <span v-if="scope.row.isup==1" style="color:teal">上架</span>
						<span v-if="scope.row.isup==0" style="color:red">下架</span> -->
						<el-switch style="display: block" v-model="scope.row.isup" active-value="1" inactive-value="0"
							active-color="#13ce66" inactive-color="#ff4949" active-text="上架" inactive-text="下架"
							@change="changeProductStatus(scope.row)">
						</el-switch>

					</template>
				</el-table-column>

				<el-table-column prop="sold_num" label="销售数量" show-overflow-tooltip min-width="100" sortable>
					<template slot-scope="scope"> {{ scope.row.sold_num || '--' }} </template>
				</el-table-column>
				<el-table-column prop="content" label="商品说明" show-overflow-tooltip min-width="110" sortable>
					<template slot-scope="scope">


						<span>{{ scope.row.content || '--' }}</span>

					</template>
				</el-table-column>


				<el-table-column prop="create_time" label="商品创建时间" show-overflow-tooltip min-width="100" sortable>
					<template slot-scope="scope"> {{ scope.row.create_time || '--' }} </template>
				</el-table-column>


				<el-table-column prop="update_time" label="商品更新时间" show-overflow-tooltip min-width="100" sortable>
					<template slot-scope="scope"> {{ scope.row.update_time || '--' }} </template>
				</el-table-column>


				<el-table-column label="操作" show-overflow-tooltip min-width="180" fixed="right">


					<template slot-scope="scope">
						<el-button type="text" size="small" @click="copyHandle(scope.row)">复制</el-button>
						<el-button type="text" size="small" @click="UpdateHandle(scope.row)">修改</el-button>
						<!-- <el-button
						  type="text"
						  size="small"
						  @click="saveHandle(scope.row, scope.$index, scope.row.id)"
						  v-if="!scope.row.disabled"
						  >保存</el-button
						> -->
						<el-button type="text" size="small" @click="deleteHandle(scope.row, scope.$index)">删除
						</el-button>
					</template>




				</el-table-column>
				<el-button type="danger"> 新增</el-button>
			</el-table>

			<!-- 分页 -->
			<el-row>
				<el-col :span="24">
					<div class="pagination">
						<!-- 分页 -->
						<el-pagination background @size-change="sizeChangeHandle" @current-change="currentChangeHandle"
							:current-page="page.pageIndex" :page-sizes="[10, 20, 50, 100]"
							:page-size="page.pageformSize" :total="page.totalPage"
							layout="total, sizes, prev, pager, next, jumper">
						</el-pagination>
					</div>
				</el-col>
			</el-row>


		</div>
		<br><br><br><br><br>


		<el-dialog title="商品信息修改" :visible.sync="dialogFormVisible">
			<el-form :model="form">
				<el-form-item label="商品名称" :label-width="formLabelWidth">
					<el-input v-model="form.product_name" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="商品价格" :label-width="formLabelWidth">
					<el-input v-model="form.sell_price" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="商品套餐名" :label-width="formLabelWidth">
					<el-input v-model="form.sku_name" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="商品套餐" :label-width="formLabelWidth">
					<el-input v-model="form.untitled" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="商品图片" :label-width="formLabelWidth">
					<!-- <el-upload ref="doctypeCrfile" class="upload-demo" drag :limit="3"
						action="http://localhost:8080/upload/uploadFile1" multiple :file-list="fileList"
						:on-success="handleSucess" :show-file-list="true" v-model="form.pics" :auto-upload="false"
						:before-upload="beforeAvatarUpload" list-type="picture">
						<i class="el-icon-upload"></i>
						<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>

						<img v-if="imageUrl" :src="imageUrl" class="avatar" />
					</el-upload> -->
					
					
					<el-upload
					draggable="true"
				  class="upload-demo"
				  :action="obj.host"
				  :before-upload="ossPolicy"
				  :on-success="handleUploadSuccess"
				  //上传时绑定的数据
				  :data="obj"
				  :limit="1"
				  :file-list="fileList"
				  list-type="picture">
				  <el-button size="small" type="primary">点击上传</el-button>
				  <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
				</el-upload>
				<el-dialog :visible.sync="dialogVisible">
					<img width="100%" :src="form.url" alt="">
				  </el-dialog>

				</el-form-item>

				<el-form-item label="商品分类名称">

					<!-- <el-select filterable v-model="form.category_id" default-first-option filterable allow-create
						clearable size="small" placeholder="" @change="changeSubCategory" >
						<el-option v-for="(item,index) in this.parentCategoryList" :key="index" :label="item.label"
							:value="item.value" />
					</el-select> -->
					<el-cascader clearable v-model="form.categoryIds" :options="options" :props="props"
						@change="handleChange">
						<template slot-scope="{ node,data }">

							<span>{{data.categoryId}}、{{ data.categoryName}}</span>
						</template>
					</el-cascader>
				</el-form-item>

				</el-form-item>


				<!--  -->
				<el-form-item label="商品的状态" :label-width="formLabelWidth">
					<!-- <el-select v-model="form.isup" autocomplete="off">
						<el-option label="上架" value="1" style="color: teal;" checked></el-option>
						<el-option label="下架" value="0" style="color: red;"></el-option>

					</el-select> -->
					<el-switch style="display: block" v-model="form.isup" active-value="1" inactive-value="0"
						active-color="#13ce66" inactive-color="#ff4949" active-text="上架" inactive-text="下架">
					</el-switch>
				</el-form-item>
				<el-form-item label="商品说明" :label-width="formLabelWidth">
					<el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="form.content" autocomplete="off">

					</el-input>


				</el-form-item>
			</el-form>

			<div slot="footer" class="dialog-footer">
				<el-button @click="dialogFormVisible = false">取 消</el-button>
				<el-button type="primary" @click="updateProduct(form)" :disabled="confirm">修 改</el-button>
			</div>
		</el-dialog>

		<!-- 商品信息的保存 -->


		<el-dialog title="商品添加" :visible.sync="dialogFormVisibleSave">
			<el-steps :space="800" :active="active" finish-status="success">
				<el-step title="步骤 1">




				</el-step>
				<el-step title="步骤 2"></el-step>

			</el-steps>

			<el-form :label-position="labelPosition" :model="form" v-show="show">
				<h2>商品信息添加 </h2>
				<el-form-item label="商品名称" :label-width="formLabelWidth">
					<el-input v-model="form.product_name" autocomplete="off"></el-input>
				</el-form-item>

				<el-form-item label="商品图片" :label-width="formLabelWidth">
					<!-- <el-upload ref="doctypeCrfile" class="upload-demo" drag :limit="3"
						action="http://localhost:8080/upload/uploadFile1" multiple :file-list="fileList"
						:on-success="handleSucess" :show-file-list="true" v-model="form.url" :auto-upload="false"
						list-type="picture" :before-upload="beforeAvatarUpload">
						<i class="el-icon-upload"></i>

						<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>

						<img v-if="imageUrl" :src="imageUrl" class="avatar" />
					</el-upload> -->
					<el-upload
					draggable="true"
				  class="upload-demo"
				  :action="obj.host"
				  :before-upload="ossPolicy"
				  :on-success="handleUploadSuccess"
				  //上传时绑定的数据
				  :data="obj"
				  :limit="2"
				  :file-list="fileList"
				  list-type="picture">
				  <el-button size="small" type="primary">点击上传</el-button>
				  <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
				</el-upload>
				<el-dialog :visible.sync="dialogVisible">
					<img width="100%" :src="fileList[0].url" alt="">
				  </el-dialog>



				</el-form-item>
				<el-form-item label="商品分类名称" :label-width="formLabelWidth">
					<!-- 
		<el-cascader
		:props="defaultParams"
	
		:options="this.parentCategoryList"
		v-model="subOptions1"
		@change="changeSubCategory">
	  </el-cascader> -->

					<!-- 
					<el-select clearable v-model="form.category_id" placeholder="请选择活动区域">


						<el-option v-for="item in this.parentCategoryList" :key="item.value" :label="item.label"
							:value="item.value">
						</el-option>

					</el-select> -->

					<el-cascader clearable v-model="form.categoryIds" :options="options" :props="props"
						@change="handleChange"></el-cascader>
				</el-form-item>


				<!--  -->
				<el-form-item label="商品的状态" :label-width="formLabelWidth">
					<!-- <el-select v-model="form.isup" autocomplete="off">
						<el-option label="上架" value="1" style="color: teal;" checked></el-option>
						<el-option label="下架" value="0" style="color: red;"></el-option>

					</el-select> -->

					<el-switch style="display: block" v-model="form.isup" active-value="1" inactive-value="0"
						active-color="#13ce66" inactive-color="#ff4949" active-text="上架" inactive-text="下架">
					</el-switch>

				</el-form-item>
				<el-form-item label="商品说明" :label-width="formLabelWidth">
					<el-input type="textarea" :rows="2" placeholder="请输入内容" v-model="form.content" autocomplete="off"
						@input="passInput"></el-input>
				</el-form-item>
				<p style="margin-left:66px;font-size:9px;text-align:center"> 还可以输入<strong
						style="color:red">{{numRemark}}</strong>个字 </p>



			</el-form>

			<el-form :label-position="labelPosition" :model="form" v-show="!show">
				<h2>商品属性信息添加 </h2>
				<el-form-item label="商品套餐名称">
					<el-input v-model="form.sku_name" autocomplete="off"></el-input>
				</el-form-item>
				<el-form-item label="商品口味">


					<el-input v-model="form.untitled">

					</el-input>

				</el-form-item>
				<el-form-item label="商品原价">
					<el-input v-model="form.originPrice"></el-input>

				</el-form-item>
				<el-form-item label="商品售价">
					<el-input v-model="form.sellPrice"></el-input>

				</el-form-item>

				<el-form-item label="商品库存">
					<el-input type="number" v-model.number="form.stock">
						<template slot="append"></template>
					</el-input>

				</el-form-item>
				<el-row>
					<el-col :span="18">

					</el-col>
					<el-col :span="12">
						<el-form-item style="float: right;">


							<el-button @click="dialogFormVisibleSave = false">取 消</el-button>
							<el-button type="primary" @click="saveProduct(form)">保存</el-button>




						</el-form-item>



					</el-col>




				</el-row>

			</el-form>





			<div slot="footer" class="dialog-footer">
				<el-button style="margin-top: 12px;" @click="pre">上一步</el-button>
				<el-button style="margin-top: 12px;" @click="next">下一步</el-button>

			</div>
		</el-dialog>







	</div>

	</div>




	<script src="https://cdn.jsdelivr.net/npm/jquery@3.2/dist/jquery.min.js"> </script>
	<script src="static/js/base.js"></script>
	<script src="static/js/axios.min.js"></script>
	<script src="static/js/cookie_utils.js"></script>

	<script>

		var userId = getCookieValue("userId");
		var token = getCookieValue("token");
		new Vue({
			el: '#app',
			data: {
				labelPosition: 'right',
				active: 0,
				illcodeInputShow: true,
				show: true,
				numRemark: 400,
				url: "",

				formLabelWidth: '120px',
				dialogFormVisible: false,
				imageUrl: "",
				dialogFormVisibleSave: false,
				dataForm: {
					submienddte: "",
					submistrdte: "",
					isup: "",
					categoryIds: [],

					product_name: "",
					categoryName: "",
					categoryName1: "",


				},
				dataList: [{}, {}],
				//  图片的定义的数组
				fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}],
         obj:{
            OSSAccessKeyId:"",
            policy:"",
            signature:"",
            key:"",
            host:"",
            dir:"",
        },
        dialogVisible: false,
				// 分类数据
				categorydataList: [],
				options: [{
					value: 'zhinan',
					label: '指南',
					children: [{
						value: 'shejiyuanze',
						label: '设计原则',
						children: [{
							value: "",
							lable: ""
						}]
					}]
				}],

				parentCategoryList: [],
				subOptions1: [],
				subOptions: [],
				flag: false,
				props: {
					expandTrigger: 'hover',
					//multiple:true,          //这里设置为多选模式
					value: "categoryId",
					label: "categoryName",      //展示的lable名字
					children: "categories"    //展示子级
				},


				defaultParams: {
					value: 'value',
					label: 'label',
					children: this.subOptions

				},
				parenId: "",
				sbusiorgMap: [{
					sorgname: '1',


				}],
				category_id: 0,
				submistrdte: "",
				submienddte: "",
				disabled: true,
				page: {
					pageIndex: 1,
					pageSize: 10,
					totalPage: 0,
				},

				form: {
					pictureName: "",
					sell_price: "",
					url: "",
					//图片数组
					pics: [],
					categoryIds: [],//分类id
				},
				// 公共数据
				commonData: {

				},
				confirm: false,
				//  商品分类查询的id
				selectCategory_id1: 0,
				selectCategory_id2: 0,

			},


			methods: {
				handleChange(value) {
					console.log("", value);
					console.log("选中的值:", this.dataForm.categoryIds)
				},
				getCheckedNodes(leafOnly) {
					console.log("选中节点数组", leafOnly)
				},
				passInput(value) {
					// alert(value);
					console.log(value, "value");
					this.numRemark = 400 - value.length;
					if (this.numRemark < 0) {
						this.numRemark = 0;
					}
					if (value.length > 400) {

						this.form.content = this.form.content.substring(0, 400);
						this.$message({
							message: "输入的说明不可以大于400字",
							type: "error",
							showClose: true,
						});
						return;
					}



				},


				changeProductStatus(value) {
					console.log("最新商品信息", value);
					axios({
						url: baseUrl + "product/updateProductStatus",
						method: "post",
						data: value,

					}).then(res => {
						console.log("商品状态返回数据", res.data);
						if (res.data.code == 2) {
							ELEMENT.Message.success(res.data.msg);
							this.intDataList();
						}



					})
				},



			

				change(val) {
					console.log(val, "Category2")


				},

				next() {
					this.show = false;
					if (this.active++ > 2) this.active = 0;

				},
				pre() {
					this.show = true;
					if (this.active-- < 0) this.active = 0;

				},

				changeSubCategory(val) {
					// let label=this.$refs['cascaderAddr'].currentLabels;
					// console.log(label);


					this.dataForm.categoryName1 = null;





					axios({
						url: baseUrl + "index/subList",
						method: "post",
						headers: {
							token: token
						},
						data: val,

					}).then(res => {
						this.subOptions = res.data.data;
						console.log(this.subOptions);
						console.log(res.data, "parent")
						// ELEMENT.Message.success("更新商品信息成功");
					})


				},
				queryParenList() {
					axios({
						url: baseUrl + "index/parentlist",
						method: "post",
						headers: {
							token: token
						},
						data: userId,

					}).then(res => {
						this.parentCategoryList = res.data.data;
						console.log(res.data, "parent")
						// ELEMENT.Message.success("更新商品信息成功");
					})



				},

				saveProduct(val) {

					//    点击保存按钮---------- 图片的手动上传代码
					// var vm = this;
					// vm.$refs.doctypeCrfile.submit();



					console.log("商品地址---------",this.form.url);







					if (val.product_name == null || val.product_name.length == 0) {
						ELEMENT.Message.error("商品名称不可以为空");
						return;
					}
					if (val.categoryIds == null || val.categoryIds.length == 0) {
						ELEMENT.Message.error("商品分类名称必须选择");
						return;
					}
					if (val.originPrice.trim() == null) {
						ELEMENT.Message.error("商品原价不可以为空");
						return;
					}

					axios({
						url: baseUrl + "product/add",
						method: "post",
						data: val,

					}).then(res => {
						// console.log(res.data.msg);
						ELEMENT.Message.success(res.data.msg);
						this.intDataList();
					})




				},
				showCategorires() {
					console.log("3333333333333333333")
					var userId = getCookieValue("userId");
					var url2 = baseUrl + "index/categorylist";
					axios({
						method: "post",
						data: userId,
						url: url2,

					}).then(res => {
						console.log("商品分类数据111111111111:", res.data.data);

						this.categorydataList = res.data.data;
						this.options = this.getTreeData(res.data.data);
						this.options.children = res.data.data.categories;
						this.options.value = res.data.data.categoryId;
						this.options.label = res.data.data.categoryName;



						console.log(this.options, "----------CategoriesdataList")




					})
				},

				//递归判断列表,把最后的children设为undefined
				getTreeData(data) {
					for (var i = 0; i < data.length; i++) {
						if (data[i].categories.length < 1) {
							// children若为空数组,则将children设为undefined
							data[i].categories = undefined;
						} else {
							// children若不为空数组,则继续 递归调用 本方法
							this.getTreeData(data[i].categories);
						}
					}
					return data;
				},




				// 商品保存
				updateProduct(row) {
					if (row.categoryIds == null || row.categoryIds.length == 0) {
						ELEMENT.Message.error("商品分类不可以为空");
						return;

					}

					axios({
						url: baseUrl + "product/update",
						method: "post",
						data: row,

					}).then(res => {
						ELEMENT.Message.success("更新商品信息成功");
						this.intDataList();


					})


				},
				// 删除
				deleteHandle(row, index) {


					let params = {
						product_id: row.product_id,
						sku_id: row.sku_id,
					};
					this.$confirm(`确定进行删除操作?`, "提示", {
						confirmButtonText: "确定",
						cancelButtonText: "取消",
						type: "warning",
					}).then(() => {

						axios({
							url: baseUrl + "product/delete",
							method: 'post',
							data: params

						}).then((res) => {
							console.log(res.data);

							ELEMENT.Message.success(res.data.msg);
							this.intDataList();

						});
					});
				},

				// // 公共代码段-复制、修改
				// commenFn(row) {
				//   let copyObj = {
				//   product_name:row.product_name, 
				//     category_name: row.category_name, 
				// 	content:row.content,
				// 	isup:row.isup,
				// 	soldNum:0,

				//   };
				//   this.commonData = copyObj;
				//   this.dataList.push(this.commonData);
				//   this.commonData = {};
				// },

				// 复制
				copyHandle(row) {
					// 功能代码
					//   this.commenFn(row);

					this.dialogFormVisibleSave = true;
					this.form = row;
					this.illcodeInputShow = false;
					ELEMENT.Message.success('复制成功');
				},
				addHandle(row) {
					// 功能代码
					//   this.commenFn(row);
					this.numRemark = 400;
					this.form = {};


					this.dialogFormVisibleSave = true;

				},

				// 修改功能
				UpdateHandle(row) {
					// 功能代码
					this.category_id = row.category_id;
					row.disabled = false;
					this.confirm = false;
					this.form = row;

					this.dialogFormVisible = true;
				},


				dataBlur() {
					if (this.dataForm.submistrdte > this.dataForm.submienddte) {
						this.dataForm.submienddte = "";

						ELEMENT.Message.error(
							'开始日期不可以大于结束日期');
					}


				},
				// 每页数
				sizeChangeHandle(val) {
					this.page.pageSize = val;
					this.page.pageIndex = 1;
					this.intDataList(2);
				},
				// 当前页
				currentChangeHandle(val) {
					this.page.pageIndex = val;
					this.intDataList(2);
				},

				//  前往末页
				toLastPage() {
					let max = Math.ceil(this.tablePage.totalResult / this.tablePage.pageSize);
					this.handleCurrentChange(max);
				},
				// 重置
				resetForm() {
					this.dataForm.category_id = "",
						this.dataForm.product_name = "",
						this.dataForm.submistrdte = "",
						this.dataForm.submienddte = "",
						this.dataForm.categoryName = "",
						this.dataForm.categoryName1 = "",
						this.dataForm.categoryIds = [];
					this.dataForm.isup = "",
						this.intDataList(1);

				},



				// 支持enter键查询
				submit(val) {
					// console.log(this.dataForm.branchname );
					this.intDataList(val);
				},

				// 点击搜索按钮,请求数据
				intDataList(val) {

					// this.$store.dispatch("loading/CHANGE_LOADING", true);
					let userId = getCookieValue("userId");
					var params = {
						pageNum: this.page.pageIndex,
						pageSize: this.page.pageSize,
						categoryIds: this.dataForm.categoryIds,
						product_name: this.dataForm.product_name,
						createTime: this.dataForm.submistrdte,
						createTime1: this.dataForm.submienddte,
						isup: this.dataForm.isup,
						userId: userId
					}
					if (val === 1) {


						//起始日期为空,截止日期赋值起始日期
						if (this.submistrdte == '') {
							this.submistrdte = this.submienddte
						}
						//截止日期为空,起始日期赋值截止日期
						if (this.submienddte == '') {
							this.submienddte = this.submistrdte
						}
						// 666

						sessionStorage.setItem("datumTasks", JSON.stringify(params))
					}
					let token = getCookieValue("token");

					var url5 = baseUrl + "product/list";

					axios({
						url: url5,
						method: "post",
						headers: {
							token: token
						},
						data: params
					}).then(res => {



						this.dataList = [];
						console.log(res.data, "dataList-------------");
						this.dataList = res.data.list;
						// this.page.pageNum=1

						this.page.totalPage = res.data.total;
						this.pageIndex = res.data.pageNum;







					}).catch((err) => {


					});
				},

				//oss实现文件上传
				emitInput(val) {
        this.$emit('input', val)
      },
      handleRemove(file, fileList) {
        this.emitInput('');
      },
  
      ossPolicy(file){
        // 上传前,获取服务器给的签名
        axios({
				url:"http://localhost:8080/oss/policy",
				method:"get",
			}).then(res=>{
                console.log("come in ---------",res.data)
                this.obj.OSSAccessKeyId = res.data.accessId;
                this.obj.policy = res.data.policy;
                this.obj.dir = res.data.dir;
                this.obj.signature = res.data.signature; 
                //传到oss的服务器地址
                this.obj.host = res.data.host;
                this.obj.key =res.data.dir + "${filename}";

      })
    },
    //文件上传成功时调用
    handleUploadSuccess(res, file) {
        console.log("上传成功...")
        this.showFileList = true;
        this.fileList.pop();
        this.fileList.push({name: file.name, url: this.obj.host + '/' + this.obj.key.replace("${filename}",file.name) });
        this.emitInput(this.fileList[0].url);
        console.log("图片上传oss后的地址",this.fileList[0].url);
		//赋值图片地址
		this.form.url = this.fileList[0].url;
		console.log(this.form.url);
      },
			},
			created() {
				this.intDataList();
				this.showCategorires();
				this.queryParenList();

			}

		})
	</script>


</body>

</html>

1.后端Code

package com.qfedu.fmmall.controller;/*
 **
 *@author SmallMonkey
 *@Date 2023/2/10 13:07
 *
 *
 **/

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.UUID;

@RestController
@CrossOrigin
@RequestMapping("/oss")
public class OssController {
    @RequestMapping("/policy")
    public Map<String,String> policy(){
        // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
        String accessId = "";
        String accessKey = "yourkey";
        // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
        String endpoint = "oss-cn-hangzhou.aliyuncs.com";
        // 填写Bucket名称,例如examplebucket。
        String bucket = "fmmallrebuild";
        // 填写Host地址,格式为https://bucketname.endpoint。
        String host = "https://" + bucket + "." + endpoint;
        // 设置上传回调URL,即回调服务器地址,用于处理应用服务器与OSS之间的通信。OSS会在文件上传完成后,把文件上传信息通过此回调URL发送给应用服务器。
       // String callbackUrl = "https://192.168.0.0:8888";
        // 设置上传到OSS文件的前缀,可置空此项。置空后,文件将上传至Bucket的根目录下。
        //可以加上当前的日期
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String dir = simpleDateFormat.format(new Date()) + "/";

        //String objectName = dir + UUID.randomUUID().toString()+".png";


        // 创建ossClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessId, accessKey);
        try {
            long expireTime = 30;
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);

            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            Map<String, String> respMap = new LinkedHashMap<String, String>();
            respMap.put("accessId", accessId);
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("dir", dir);
            respMap.put("host", host);
            respMap.put("expire", String.valueOf(expireEndTime / 1000));

            return respMap;
//服务进行上线之后,有一个外网可以访问的地址可以设置回调
  /*

       JSONObject jasonCallback = new JSONObject();
            jasonCallback.put("callbackUrl", callbackUrl);
            jasonCallback.put("callbackBody",
                    "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}");
            jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded");
            String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes());
            respMap.put("callback", base64CallbackBody);

            JSONObject ja1 = JSONObject.fromObject(respMap);*/

        } catch (Exception e) {
            // Assert.fail(e.getMessage());
            System.out.println(e.getMessage());
        }
        return null;
    }

}



  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

有时间指导毕业设计

觉得写的好的话可以给我打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值