imageUploadPhp.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. <template>
  2. <div>
  3. <el-upload
  4. :action="upload_host"
  5. :data="dataObj"
  6. :multiple="uploadNum > 1?true:false"
  7. :show-file-list="false"
  8. :before-upload="beforeUpload"
  9. :on-remove="handleRemove"
  10. :on-success="handleUploadSuccess"
  11. :on-preview="handlePreview"
  12. :disabled="!isDisabled"
  13. :class="name"
  14. class="avatar-uploader2"
  15. >
  16. </el-upload>
  17. <div class="images">
  18. <div class="item" v-for="(item, index) in fileList" :key="index">
  19. <div class="img" @mouseover="item.hover = true;" @mouseout="item.hover = false;">
  20. <el-image @click.stop="handleClickItem" ref="img" v-if="isImageUrl(item.url)" :src="item.url" :preview-src-list="previewImages()" style="width: 120px; height: 120px" fit="cover"></el-image>
  21. <video v-else :src="item.url" controls style="width: 120px; height: 120px; display: block"></video>
  22. <div class="mask" v-show="item.hover">
  23. <i class="el-icon-zoom-in" @click="previewImage(item.url)" v-if="isImageUrl(item.url)"></i>
  24. <i class="el-icon-zoom-in" @click="previewVideo(item.url)" v-else></i>
  25. <i class="el-icon-upload2" @click="uploadImage(item.url)" v-if="!isDisabled"></i>
  26. <i class="el-icon-delete" @click="deleteImage(item.url)" v-if="!isDisabled"></i>
  27. </div>
  28. </div>
  29. </div>
  30. <div class="add" v-if="fileList.length < uploadNum" @click="uploadImage()"><i class="el-icon-plus"></i></div>
  31. </div>
  32. <!-- <el-dialog :visible.sync="dialogVisible" :append-to-body="true"><img width="100%" :src="showImage" alt="" /></el-dialog> -->
  33. </div>
  34. </template>
  35. <script>
  36. import request from '@/utils/request';
  37. import { findElem } from '@/utils/util'
  38. export default {
  39. name: 'ImageUploadPhp',
  40. props: {
  41. isDisabled: Boolean,
  42. fileType: String,
  43. name: String,
  44. // fileList: Array,
  45. uploadNum: {
  46. type: Number,
  47. default: 1,
  48. },
  49. index: {
  50. type: Number,
  51. default: 0,
  52. },
  53. },
  54. data() {
  55. return {
  56. dataObj: {
  57. policy: '',
  58. signature: '',
  59. key: '',
  60. ossaccessKeyId: '',
  61. },
  62. aliosstoken: '',
  63. upload_host: '',
  64. showImage: '',
  65. dialogVisible: false,
  66. uploadImageId: '',
  67. fileList: [],
  68. list: []
  69. };
  70. },
  71. created() {
  72. request({
  73. url: '/qviKHUYsyN.php/index/getAliOssToken',
  74. method: 'get',
  75. params: {}
  76. }).then(res => {
  77. this.aliosstoken = res.data.aliosstoken;
  78. this.upload_host = res.data.upload_host
  79. });
  80. },
  81. computed: {
  82. showFileList: {
  83. get: function() {
  84. if (this.fileList.length > 0 && this.fileList[0].url) {
  85. return true;
  86. } else {
  87. return false;
  88. }
  89. },
  90. set: function(newValue) {}
  91. }
  92. },
  93. methods: {
  94. emitInput(val) {
  95. this.$emit('input', val);
  96. },
  97. handleClickItem(){
  98. // 获取遮罩层dom
  99. setTimeout(function(){
  100. let domImageMask = document.querySelector(".el-image-viewer__wrapper");
  101. if (!domImageMask) {
  102. return;
  103. }
  104. domImageMask.addEventListener("click", (e) => {
  105. if(e.target.parentNode.className == 'el-image-viewer__actions__inner') {
  106. return; //如果点击底部菜单,不关闭
  107. }
  108. // 点击遮罩层时调用关闭按钮的 click 事件
  109. document.querySelector(".el-image-viewer__close").click();
  110. });
  111. },300)
  112. },
  113. handleRemove(file, fileList) {
  114. if (fileList.length == 0) {
  115. this.fileList = [{ name: '', url: '' }];
  116. // this.showFileList = false;
  117. } else {
  118. this.fileList = fileList;
  119. }
  120. },
  121. handlePreview(file) {
  122. // const fileExtension = file.name.substring(file.name.lastIndexOf('.') + 1);
  123. // if (fileExtension == 'png' || fileExtension == 'jpg' || fileExtension == 'jpeg') {
  124. // this.showImage = file.url;
  125. // // this.showImage = file.full_url;
  126. // this.dialogVisible = true;
  127. // } else {
  128. // window.open(file.url);
  129. // // window.open(file.full_url);
  130. // }
  131. },
  132. getUUID() {
  133. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
  134. return (c === 'x' ? (Math.random() * 16) | 0 : 'r&0x3' | '0x8').toString(16);
  135. });
  136. },
  137. beforeUpload(file) {
  138. if(this.fileType == 'image'){
  139. if(!file.type.includes('image')){
  140. return this.$message.warning('该选项只支持上传图片格式的文件!');
  141. }
  142. }else if(this.fileType == 'video'){
  143. if(!file.type.includes('video')){
  144. return this.$message.warning('该选项只支持上传视频格式的文件!');
  145. }
  146. }else if(this.fileType == 'image/video'){
  147. if(!file.type.includes('image') && !file.type.includes('video')){
  148. return this.$message.warning('该选项只支持上传视频或图片格式的文件!');
  149. }
  150. }
  151. this.list.push(file.name)
  152. if(this.list.length > this.uploadNum){
  153. this.$message.warning('最多上传' + this.uploadNum +'个文件!');
  154. return false
  155. }
  156. const that = this;
  157. return new Promise((resolve, reject) => {
  158. request({
  159. url: '/addons/alioss/index/params',
  160. method: 'post',
  161. data: {
  162. method: 'POST',
  163. md5: file.name.substring(0, file.name.indexOf('.')),
  164. name: file.name,
  165. type: file.type,
  166. size: file.size,
  167. aliosstoken: this.aliosstoken
  168. }
  169. })
  170. .then(res => {
  171. that.dataObj = res.data;
  172. resolve(true);
  173. })
  174. .catch(err => {
  175. reject(false);
  176. });
  177. });
  178. },
  179. handleUploadSuccess(res, file, fileList) {
  180. console.log(this.fileList)
  181. // if (this.fileList.length == 1 && !this.fileList[0].url) {
  182. // this.fileList.pop();
  183. // }
  184. // this.showFileList = true;
  185. this.fileList.push({
  186. name: file.name,
  187. hover: false,
  188. url: process.env.VUE_APP_BASE_API + 'qviKHUYsyN.php/index/getOssSign?object=' + this.dataObj.key.replace('${filename}', file.name)
  189. });
  190. this.$emit('editUrl', {
  191. name: file.name,
  192. hover: false,
  193. url: this.dataObj.key.replace('${filename}', file.name)
  194. },this.name,this.index);
  195. // this.fileList.push({
  196. // name: file.name,
  197. // url: this.dataObj.key.replace('${filename}', file.name),
  198. // full_url: process.env.VUE_APP_BASE_API + 'qviKHUYsyN.php/index/getOssSign?object=' + this.dataObj.key.replace('${filename}', file.name)
  199. // });
  200. },
  201. previewImages() {
  202. let images = [];
  203. if(this.fileList && this.fileList.length > 0) {
  204. this.fileList.forEach(item => {
  205. if(this.isImageUrl(item.url)) {
  206. images.push(item.url);
  207. }
  208. })
  209. }
  210. return images;
  211. },
  212. // 预览图片
  213. previewImage(url) {
  214. let images = [];
  215. this.fileList.forEach(item => {
  216. if(this.isImageUrl(item.url)) {
  217. images.push(item);
  218. }
  219. })
  220. let index = findElem(images, 'url', url);
  221. this.$refs.img[index].showViewer = true;
  222. },
  223. // 预览视频
  224. previewVideo(url) {
  225. // this.previewVideoUrl = url;
  226. // this.previewVideoDialog = true;
  227. },
  228. isImageUrl(url) {
  229. const fileSuffix = url.substring(url.lastIndexOf(".") + 1);
  230. const whiteList = ['jpg', 'jpeg', 'png'];
  231. if (whiteList.indexOf(fileSuffix) === -1) {
  232. return false;
  233. }else {
  234. return true;
  235. }
  236. },
  237. uploadImage(id) {
  238. this.list = []
  239. this.uploadImageId = id;
  240. document.querySelector(`.${this.name} input`).click();
  241. },
  242. // 删除图片
  243. deleteImage(url) {
  244. let index = findElem(this.fileList, 'url', url);
  245. this.fileList.splice(index, 1);
  246. },
  247. }
  248. };
  249. </script>
  250. <style type="text/css" lang="scss">
  251. .images {
  252. display: flex;
  253. flex-wrap: wrap;
  254. .item {
  255. display: flex;
  256. flex-direction: column;
  257. justify-content: center;
  258. align-items: center;
  259. width: 120px;
  260. margin-right: 20px;
  261. .img {
  262. border: 1px dashed #eaeaea;
  263. border-radius: 5px;
  264. overflow: hidden;
  265. position: relative;
  266. .el-image {
  267. display: block;
  268. }
  269. .mask {
  270. position: absolute;
  271. left: 0;
  272. top: 0;
  273. width: 120px;
  274. height: 120px;
  275. background: rgba($color: #000000, $alpha: 0.3);
  276. display: flex;
  277. align-items: center;
  278. justify-content: center;
  279. i {
  280. font-size: 20px;
  281. color: #ffffff;
  282. cursor: pointer;
  283. margin: 0 8px;
  284. }
  285. }
  286. }
  287. .add {
  288. border: 1px solid #dddddd;
  289. border-radius: 5px;
  290. cursor: pointer;
  291. }
  292. .text {
  293. font-size: 14px;
  294. color: #666666;
  295. }
  296. }
  297. .add {
  298. width: 120px;
  299. height: 120px;
  300. border: 1px solid #dddddd;
  301. border-radius: 5px;
  302. cursor: pointer;
  303. display: flex;
  304. align-items: center;
  305. justify-content: center;
  306. i {
  307. font-size: 30px;
  308. color: #999;
  309. }
  310. }
  311. }
  312. .avatar-uploader2 {
  313. height: 0;
  314. }
  315. </style>