提示:记录项目中遇到的问题,仅供参考
项目需求是在表格中嵌套一个上传图片的功能,并且回显选择的图片和已上传的图片,再通过点击操作列中上传按钮才开始上传,使用的方法是实际是通过表单上传实现的
这里就只展示主要代码,对elementui的函数方法不熟系的,可以对照elementui文档来理解
提示:下面的 scope.row.status 是指状态,为 9 时才可以上传图片,为 0 时图片已经上传
<template>
<el-table v-loading="loading" :data="formRefundRecordList" v-if="showTable">
<div slot="empty" style="text-align: left;">暂无数据</div>
<el-table-column label="退充截图" align="center" prop="screenshot" :key="Math.random()" width="150px">
<template slot-scope="scope">
<el-upload :class="{hideUpload:dialogImageUrls[`i${scope.row.id}`] != null}"
:action="upData.host" :ref="`reScreenshot${scope.row.id}`" :limit="1"
:accept="accept.join(',')" :auto-upload="false" list-type="picture-card"
:on-preview="(file)=>{return handlePreview(file, scope.row.id)}"
:on-remove="(file,fileList)=>{return handleRemove(file, fileList, scope.row.id)}"
:on-change="(file,fileList)=>{return handleChange(file, fileList, scope.row.id)}"
v-if="scope.row.status == 9">
<i class="el-icon-plus"></i>
</el-upload>
<!-- 上传成功后图片预览 -->
<!-- src 为图片预览前显示的内容 -->
<!-- preview-src-list 为图片预览时显示的内容 -->
<el-image v-if="dialogImageUrls[`i${scope.row.id}`] != null && scope.row.status != 9"
class="hideUpload" :src="dialogImageUrls[`i${scope.row.id}`]"
:preview-src-list="[dialogImageUrls[`i${scope.row.id}`]]">
</el-image>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right"
width="200px">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="UpdateStatus(scope.row, 0)" :disabled="scope.row.status != 9">通过</el-button>
</template>
</el-table-column>
</el-table>
<!-- 上传前图片预览 -->
<el-image-viewer v-if="showViewer" :on-close="closeViewer" :url-list="srcList" />
<template>
<script>
import { updateFormRefundRecord, getOssPolicy, uploadOss } from "@/api/bol/refundInternalMedia";
import SparkMD5 from "spark-md5";
import ElImageViewer from 'element-ui/packages/image/src/image-viewer';
export default {
name: "refundInternalMedia",
components: { ElImageViewer },
data() {
return {
// 图片详情放大列表(上传前)
srcList: [],
// 图片详情放大是否显示
showViewer: false,
// 上传前文件列表
fileList: {},
// 上传成功后回显时文件的域名(例:https://xxxxxx.xxxx.com)
fileDominName: process.env.VUE_APP_File_SHOW_DOMAIN_NAME,
// 上传截图携带的参数(实际上不需要这个,但没有又会报错)
upData: {
host: ''
},
// 允许上传截图的格式
accept: ['.png', '.jpg', '.jpeg'],
// 截图弹窗显示与隐藏
dialogVisibles: {},
// 截图文件路径(表格所有的)
dialogImageUrls: {},
// 表格显示
showTable: true,
// 遮罩层
loading: true,
// 表格数据
formRefundRecordList: [],
}
},
methods: {
// 关闭图片放大(上传前的)
closeViewer() {
this.srcList = [];
this.showViewer = false;
},
// 删除截图的事件
handleRemove(file, fileList, id) {
this.$set(this.dialogImageUrls, `i${id}`, null)
this.$delete(this.fileList, `f${id}`)
// 刷新表格
this.showTable = false
this.showTable = true
},
// 点击已上传的截图时的事件
handlePreview(file, id) {
this.srcList = [file.url];
this.showViewer = true;
},
// 截图状态改变时的钩子,添加文件、上传成功和上传失败时的事件
handleChange(file, fileList, id) {
this.$set(this.dialogImageUrls, `i${id}`, file.url)
this.$set(this.fileList, `f${id}`, file.raw)
// 刷新表格
this.showTable = false
this.showTable = true
},
// 上传截图
async uploadFile(file, id) {
// 文件md5值
let md5
await this.fileMd5(file).then((res) => {
md5 = res
})
// 文件后缀名
var suffix = file.name.substring(file.name.lastIndexOf(".")); //.xxx
// 上传oss的文件名
let fileName = md5 + suffix
// 生成一个以年月作为文件夹名(例:'20230703/')
let fileDirName = this.getDirName()
// 存放文件的路径(放到bol项目文件夹下的 refundScreenshot 退款截图文件夹下)
let filePath = 'bol/refundScreenshot/' + fileDirName + '/'
// 限制允许上传文件类型
if (!this.accept.includes(suffix)) {
this.$message.warning('上传文件格式有误,请检查后重新上传。')
return false
}
getOssPolicy({}).then((res) => {
// 拿到签名信息后,组装表单数据,作参考,具体的字段找后台要
let config = res.data
let fd = new FormData()
fd.append('key', filePath + fileName)
fd.append('success_action_status', '200')
fd.append('x-oss-object-acl', 'public-read')
fd.append('x-oss-meta-fullname', fileName)
fd.append('OSSAccessKeyId', config.accessid)
fd.append('policy', config.policy)
fd.append('signature', config.signature)
fd.append('file', file)
if (config.host.indexOf('http:') > -1) {
var protocol = window.location.protocol || 'http:'
var subUrl = config.host.substring(5, config.host.length)
config.host = protocol + subUrl
}
// 组装请求参数
let pre = {
url: config.host,
data: fd
}
uploadOss(pre).then(() => {
// 组装数据
let data = {
id: id,
screenshot: filePath + fileName,
status: 0
}
// 执行通过
updateFormRefundRecord(data).then((res) => {
this.getList();
this.$modal.msgSuccess("成功通过");
}).catch(() => {
this.$message.error(res.msg);
})
}).catch(err => {
this.$message.warning('图片上传失败')
})
}).catch((err) => {
this.$message.warning('验签获取失败')
})
},
// 生成一个以年月为文件名的字符
getDirName() {
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
if (month >= 1 && month <= 9) {
month = "0" + month;
}
var DirName = year + '' + month;
return DirName;
},
// 返回文件md5值
async fileMd5(file) {
var fileReader = new FileReader();
var spark = new SparkMD5.ArrayBuffer();
// 获取文件二进制数据
// fileReader.readAsArrayBuffer(event.target.files[0]);
fileReader.readAsArrayBuffer(file);
return new Promise((resolve, reject) => {
fileReader.onload = function (e) {
spark.append(e.target.result);
var md5 = spark.end();
resolve(md5)
};
})
},
/** 通过操作 */
UpdateStatus(row, status) {
// 组装数据
const data = {
id: row.id,
status
}
let that = this
this.$modal.confirm(`是否确认 通过 xxxx单编号为 “${row.id}” 的数据项?`).then(() => {
// 判断点击的是通过按钮,点击通过按钮要先上传图片
if (status == 0) {
// 判断是否上传了图片
if (this.dialogImageUrls[`i${row.id}`]) {
this.uploadFile(this.fileList[`f${row.id}`], row.id);
} else {
this.$message('请先上传图片');
}
} else {
........;
}
}).catch(() => { });
},
},
}
</script>
<style lang="scss" scoped>
::v-deep .el-upload--picture-card {
margin: 5px 0;
width: 120px;
height: 80px;
line-height: 80px;
}
::v-deep .el-upload-list--picture-card .el-upload-list__item {
width: 120px;
height: 80px;
margin-top: 0;
}
.hideUpload {
margin: 5px 0;
width: 120px;
height: 80px;
}
.hideUpload ::v-deep .el-upload {
display: none;
/* 上传按钮隐藏 */
}
</style>
提示:下面的请求接口是进行封装过的,就不进行具体展示了
import request from '@/utils/request'
// 更新退款媒介内部单数据
export function updateFormRefundRecord(data) {
return request({
url: 'xxxxxxxxxx',
method: 'put',
data: data
})
}
// 获取阿里OSS签名
export function getOssPolicy(data) {
return request({
url: 'xxxxxxx',
method: 'get',
params: data
})
}
// 上传到阿里OSS
export function uploadOss(pre) {
return request({
url: pre.url,
method: 'post',
data: pre.data
})
}