123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365 |
- <template>
- <div>
- <el-upload
- ref="upload_com"
- :headers="headers"
- :action="action"
- :show-file-list="showFileList"
- :file-list="fileList"
- :on-success="_onSuccess"
- :on-preview="_onPreview"
- :http-request="oss_upload"
- :on-remove="_onRemove"
- :before-remove="_onBeforeRemove"
- :before-upload="_beforeUpload"
- :on-exceed="_onExceed"
- :limit="limit"
- :list-type="list_type"
- :accept="accept"
- :on-change="handleChange"
- :multiple="multiple">
- <slot></slot>
- <slot name="tip"></slot>
- </el-upload>
- <el-progress v-show="showProcess" :percentage="processLength" :stroke-width="2"></el-progress>
- </div>
- </template>
- <script>
- function noop() {
- }
- import moment from 'moment'
- import axios from 'axios'
- import { Loading } from 'element-ui';
- import axiosUpload from '@/utils/axiosUpload'
- export default {
- props: {
- action: {
- type: String,
- required: true
- },
- headers: {
- type: Object,
- default() {
- return {};
- }
- },
- data: Object,
- coursePath:{
- type:String,
- default:null
- },
- multiple: Boolean,
- list_type:{
- type: String,
- default: 'text'
- },
- name: {
- type: String,
- default: 'file'
- },
- drag: Boolean,
- dragger: Boolean,
- withCredentials: Boolean,
- showFileList: {
- type: Boolean,
- default: false
- },
- accept:{
- type:String,
- // default:'image/*'
- },
- type: {
- type: String,
- default: 'select'
- },
- beforeUpload: Function,
- beforeRemove: Function,
- onRemove: {
- type: Function,
- default: noop
- },
- onBeforeRemove:{
- type: Function,
- default: noop
- },
- onChange: {
- type: Function,
- default: noop
- },
- onPreview: {
- type: Function
- },
- onSuccess: {
- type: Function,
- default: noop
- },
- onProgress: {
- type: Function,
- default: noop
- },
- onError: {
- type: Function,
- default: noop
- },
- fileList: {
- type: Array,
- default() {
- return [];
- }
- },
- autoUpload: {
- type: Boolean,
- default: true
- },
- listType: {
- type: String,
- default: 'text' // text,picture,picture-card
- },
- httpRequest: Function,
- disabled: Boolean,
- limit: {
- type: Number,
- default: ()=>{
- return 1
- }
- },
- onExceed: {
- type: Function,
- default: noop
- }
- },
- name: "upload",
- data() {
- return {
- processLength:0,
- showProcess:false,
- files:{},
- config: null
- }
- },
- methods: {
- handleChange(file,fileList){
- this.files = file
- },
- handleChanges(file){
- if(file.status === 'ready'){
- this.processLength = 0
- this.showProcess = true
- const interval = setInterval(() => {
- if(this.processLength >= 99){
- clearInterval(interval)
- return
- }
- this.processLength += 1
- },20)
- }
- if(file.status === 'success'){
- this.processLength =100
- this.showProcess = false
- }
- },
- //清空图片
- // clearPictures(){
- // this.$refs.upload_com.clearFiles();
- // },
- get_sign(callback) {
- // 测试添加 'https://intesys.cms.g107.com'
- axiosUpload('get','https://intesys.cms.g107.com/integral.php/Api/get_signature').then(res => {
- this.config = res.data.data
- callback()
- })
- },
- _beforeUpload(file) {
- if(!this.beforeUpload(file)){
- return false
- }else{
- this.handleChanges(this.files)
- }
- },
- oss_upload(upload_obj){
- this.get_sign(()=>{
- // this.beforeUpload_all(upload_obj.file).then(res=>{
- // this.upload(res)
- // });
- this.upload(upload_obj.file)
- })
- },
- fileByBase64(file, callback){
- let reader = new FileReader();
- // 传入一个参数对象即可得到基于该参数对象的文本内容
- reader.readAsDataURL(file);
- reader.onload = function (e) {
- // target.result 该属性表示目标对象的DataURL
- callback(e.target.result)
- };
- },
- // 添加水印
- async beforeUpload_all(file) {
- return new Promise((resolve, reject) => {
- //把文件转换为base64
- this.fileByBase64(file, async (base64) => { // 1.调用方法1: 把文件转换为base64字符串
- // 把文件转换为Canvas
- let tempCanvas = await this.imgToCanvas(base64) // 2. 调用方法2:把base64转换为Canvas
- // 把水印写入
- const canvas = this.addWatermark(tempCanvas,this.$moment().format('YYYY-MM-DD HH:mm')) //3.调用方法3: 写入水印到Canvas
- // canvas转成img
- const img = this.convasToImg(canvas, file.type) //4. 调用方法4:把Canvas转换为image文件
- //被canvas转换为文件
- let newFile = this.base64ToFile(img.src, file.name) //5.调用方法5:被image转换为File文件
- resolve(newFile)
- })
- })
- },
- /**
- * Base64转成canvas
- * @param base64
- */
- async imgToCanvas(base64) {
- // 创建img元素
- const img = document.createElement('img')
- img.setAttribute('src', base64)
- await new Promise((resolve) => (img.onload = resolve))
- // 创建canvas DOM元素,并设置其宽高和图片一样
- const canvas = document.createElement('canvas')
- canvas.width = img.width
- canvas.height = img.height
- // 坐标(0,0) 表示从此处开始绘制,相当于偏移。
- canvas.getContext('2d').drawImage(img, 0, 0)
- return canvas
- },
- /**
- * canvas添加水印
- * @param canvas 对象
- * @param text 水印文字
- */
- addWatermark(canvas, text) {
- const ctx = canvas.getContext('2d')
- let fontSize=ctx.canvas.width / 36
- //设置文本画笔的样式
- ctx.textAlign = 'left';//设置文本对齐方式
- ctx.textBaseline = 'middle';//设置文本基线
- ctx.font =fontSize +"px Microsoft Yahei";//设置文本字体属性
- ctx.fillStyle = "rgba(255, 255, 255,0.3)"//设置文本字体颜色
- //在canvas画布上绘制文字 ctx.fillText(文字内容, x位置, y位置, 文本最大宽度)
- ctx.fillText(text,20, ctx.canvas.width / 36 + 20)//14为文字大小
- return canvas
- },
- /**
- * canvas转成img
- * @param {canvas对象} canvas
- */
- convasToImg(canvas) {
- // 新建Image对象,可以理解为DOM
- let image = new Image()
- // canvas.toDataURL 返回的是一串Base64编码的URL
- // 指定格式 PNG
- image.src = canvas.toDataURL('image/png')
- return image
- },
- /**
- * @param urlData base64
- * @param fileName 文件名称
- * @returns {File}
- */
- base64ToFile(urlData, fileName) {
- let arr = urlData.split(',');
- let mime = arr[0].match(/:(.*?);/)[1];
- let bytes = atob(arr[1]); // 解码base64
- let n = bytes.length
- let ia = new Uint8Array(n);
- while (n--) {
- ia[n] = bytes.charCodeAt(n);
- }
- return new File([ia], fileName, { type: mime });
- },
- _onExceed(files, fileList){
- this.$message.warning(`文件数量不能超过 ${this.limit} 个`)
- },
- _onSuccess(response, file, fileList) {
- this.onSuccess(response, file, fileList)
- },
- _onPreview(file) {
- this.onPreview(file)
- },
- _onRemove(file, fileList) {
- this.onRemove(file, fileList)
- },
- _onBeforeRemove(file, fileList){
- if(file.status == "success"){
- return this.$confirm(`确定移除此项?`)
- }
- },
- random_string(len) {
- len = len || 32
- var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
- var maxPos = chars.length
- var pwd = ''
- for (let i = 0; i < len; i++) {
- pwd += chars.charAt(Math.floor(Math.random() * maxPos))
- }
- return pwd
- },
- upload(item) {
- let self = this
- const photo = item // 获取图片对象
- const photoName = item.name // 原图片的名称
- const url = 'https://integralsys.oss-cn-shenzhen.aliyuncs.com'
- let date = moment().format('YYYY/MM/DD')
- let param = new FormData()
- let site_id
- if(this.coursePath){
- site_id = this.coursePath
- }else{
- site_id = this.$getCache('site_info').id
- }
- let randomStr = this.random_string(32)
- let key = 'intesys/' + site_id + '/' + date + '/' + randomStr +'/'+ photoName
- // let loadingInstance = Loading.service({});
- param.append('Filename', photoName)
- param.append('key', key)
- param.append('policy', this.config.policy)
- param.append('OSSAccessKeyId', this.config.accessid)
- param.append('success_action_status', '200') // 不要问为什么,照做
- param.append('callback', this.config.callback)
- param.append('signature', this.config.signature)
- param.append('file', photo) // 这个**切记**一定要放到最后去 append ,不然阿里云会一直报 key 的错误
- axios.post(url, param, {
- headers: {
- 'Content-Type': 'multipart/form-data'
- }
- }).then(response => {
- if(response.data.Status == 'Ok'){
- this.processLength = 100
- this.showProcess = false
- setTimeout(()=>{
- this.processLength = 0
- // this.$nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
- // loadingInstance.close();
- // });
- },200)
- self.fileList.push({name: randomStr + photoName, url: 'https://integralsys.oss-cn-shenzhen.aliyuncs.com/' + key, name: item.name, response:{
- url: 'https://integralsys.oss-cn-shenzhen.aliyuncs.com/' + key
- }})
- self._onSuccess({status: 1, url: 'https://integralsys.oss-cn-shenzhen.aliyuncs.com/' + key, file_name: randomStr + photoName}, item, self.fileList)
- }
- }).catch(err => {
- this.showProcess = false
- // this.$nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭
- // loadingInstance.close();
- // });
- })
- },
- }
- }
- </script>
- <style scoped>
- </style>
|