FileUpload.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <!--文件上传组件封装 2019.3.05 姚政伟创建
  2. ====================调用说明================
  3. <fileUpload
  4. :limit="10" //最大上传数量 默认1
  5. :fileList="form.videos" //初始化文件列表 默认为空
  6. ref="uploadVideosControl" //组件声明别名
  7. flag="routineWork" //文件标识
  8. :multiple="true" //是否支持多选文件 默认为false
  9. :styleType="2" //样式类型(1:图片类型 2.附件类型) 默认1
  10. v-if="!loading"></fileUpload>
  11. ===================回调方法(获取上传文件列表)==========
  12. var listStr = ref[声明别名].getFileListStr();//多张图片逗号分隔
  13. -->
  14. <template>
  15. <div>
  16. <el-upload
  17. v-loading="uploadConfig.loading"
  18. element-loading-text="正在上传..."
  19. element-loading-background="rgba(0, 0, 0, 0.6)"
  20. :action="uploadConfig.uploadFileApiUrl"
  21. :show-file-list="true"
  22. :on-success="handleImageSuccess"
  23. :before-upload="beforeImageUpload"
  24. :list-type="styleType == 1 ? 'picture-card':'text'"
  25. :limit="limit"
  26. :on-preview="handleImagePreview"
  27. :on-remove="handleImageUploadRemove"
  28. :file-list="uploadConfig.initFileList"
  29. :class="{'yao-upload':true,'uploadDisabled':uploadConfig.succeedFileList.length>=limit}"
  30. :multiple="multiple"
  31. :on-exceed="handleExceed"
  32. :on-error="handleImageError"
  33. :headers="headers"
  34. ref="uploadCtl"
  35. :disabled="isdisabled"
  36. :data=" {type:this.certType}"
  37. >
  38. <i class="el-icon-plus" v-show="styleType == 1"></i>
  39. <el-button size="small" type="primary" v-show="styleType == 2">点击上传</el-button>
  40. <el-button size="small" type="primary" v-show="styleType == 3">证件识别</el-button>
  41. </el-upload>
  42. <div class="el-upload__tip">{{tipMessage}}</div>
  43. <el-dialog :visible.sync="uploadConfig.dialogVisible" :append-to-body="true">
  44. <el-row v-show="styleType == 1" style="text-align: center;"><img style="max-width: 100%;" :src="uploadConfig.previewImageUrl" alt=""></el-row>
  45. <el-row v-show="styleType == 2">
  46. <el-col>
  47. <el-row>
  48. <el-col :span="6">
  49. <el-button @click="openLinkUrl(uploadConfig.previewImageUrl)">下载文件</el-button>
  50. </el-col>
  51. <el-col :span="18">
  52. <el-alert
  53. title="点击下载打开页面,右键保存即可!"
  54. type="info"
  55. show-icon
  56. :closable="false">
  57. </el-alert>
  58. </el-col>
  59. </el-row>
  60. <el-row>
  61. <el-col>&nbsp;</el-col>
  62. </el-row>
  63. <el-row>
  64. <el-col :span="6">
  65. <el-button @click="showPlay = !showPlay" :disabled="!(showVideo || showAudio)">在线播放</el-button>
  66. </el-col>
  67. <el-col :span="18">
  68. <el-alert
  69. title="该文件支持在线播放!"
  70. type="success"
  71. show-icon
  72. :closable="false"
  73. v-if="showVideo || showAudio">
  74. </el-alert>
  75. <el-alert
  76. title="该文件不支持在线播放!"
  77. type="warning"
  78. show-icon
  79. :closable="false"
  80. v-else>
  81. </el-alert>
  82. </el-col>
  83. </el-row>
  84. <el-row>
  85. <el-col>&nbsp;</el-col>
  86. </el-row>
  87. <el-row>
  88. <el-col>
  89. <transition name="el-fade-in">
  90. <div v-show="showPlay" class="transition-box">
  91. <video width="100%" controls v-if="showVideo">
  92. <source :src="uploadConfig.previewImageUrl" type="video/mp4">
  93. <source :src="uploadConfig.previewImageUrl" type="video/ogg">
  94. <source :src="uploadConfig.previewImageUrl" type="video/webm">
  95. 您的浏览器不支持 视频播放。
  96. </video>
  97. <audio :src="uploadConfig.previewImageUrl" controls v-if="showAudio">
  98. 您的浏览器不支持 音频播放。
  99. </audio>
  100. </div>
  101. </transition>
  102. </el-col>
  103. </el-row>
  104. </el-col>
  105. </el-row>
  106. <el-row v-show="styleType == 3">
  107. <el-col>
  108. <el-row>
  109. <el-col :span="6">
  110. {{uploadConfig.previewImageUrl}}}
  111. <el-button @click="openLinkUrl(uploadConfig.previewImageUrl)">下载文件1</el-button>
  112. </el-col>
  113. </el-row>
  114. </el-col>
  115. </el-row>
  116. </el-dialog>
  117. </div>
  118. </template>
  119. <script>
  120. import { getToken } from '@/utils/auth'
  121. export default {
  122. data () {
  123. return {
  124. headers:{},
  125. video: ".mp4|.ogg|.webm|.AVI|.WMV",
  126. audio: ".mp3|.ogg|.wav",
  127. //上传文件配置属性
  128. uploadConfig: {
  129. loading: false,
  130. prefixServerFileUrl: "",//this.$config.prefixServerFileUrl,
  131. uploadFileApiUrl: process.env.VUE_APP_BASE_API + (this.styleType == 3 ? 'identification': 'upload'),//this.$config.uploadFileApiUrl,
  132. previewImageUrl: "",
  133. succeedFileList: [],
  134. dialogVisible: false,
  135. initFileList: []
  136. },
  137. showPlay: false,
  138. showVideo: false,
  139. showAudio: false
  140. }
  141. },
  142. //接收参数
  143. props: {
  144. //最大上传数量 默认1
  145. limit: {
  146. type: Number,
  147. required: false,
  148. default: 1
  149. },
  150. isdisabled:{
  151. type: Boolean,
  152. required: false,
  153. default: false
  154. },
  155. //初始化文件列表 默认为空
  156. fileList: {
  157. type: Array,
  158. required: false,
  159. default:function (){
  160. return []
  161. }
  162. },
  163. //文件标识(本项目不支持)
  164. flag: {
  165. type: String,
  166. // required: true
  167. },
  168. //是否支持多选文件 默认为false
  169. multiple: {
  170. type: Boolean,
  171. required: false,
  172. default: false
  173. },
  174. //样式类型(1:图片类型 2.附件类型) 默认1
  175. styleType: {
  176. type: Number,
  177. required: false,
  178. default: 1
  179. },
  180. //样式类型(1:图片类型 2.附件类型) 默认1
  181. certType: {
  182. type: String,
  183. required: false,
  184. default: ''
  185. },
  186. //tip备注提示
  187. tipMessage: {
  188. type: String,
  189. required: false
  190. },
  191. //允许上传文件类型后缀白名单(例如:".jpg|.png",|分隔)
  192. allowFileTypes: {
  193. type: String,
  194. required: false,
  195. default: ".jpg|.jpeg|.png"
  196. },
  197. //缩略图大小(宽高 例如:100x100)(本项目不支持)
  198. thumbnailSize: {
  199. type: String,
  200. required: false,
  201. default: ""
  202. }
  203. },
  204. created(){
  205. this.headers = { token: getToken() }
  206. },
  207. computed: {
  208. uploadPath() {
  209. return this.fileList.map(m=>m.path).join(',');
  210. }
  211. },
  212. watch:{
  213. uploadPath(newValue, oldValue){
  214. this.$options.methods.initFileList.bind(this)(this.fileList);
  215. }
  216. },
  217. mounted(){
  218. this.$options.methods.initFileList.bind(this)(this.fileList);
  219. },
  220. methods: {
  221. handleImageSuccess(res, file) {
  222. var that = this;
  223. that.uploadConfig.loading = false;
  224. if (res && res.code == 200){
  225. if (file.response.data) {
  226. that.uploadConfig.succeedFileList.push(file.response.data);
  227. if(this.styleType == 3) {
  228. this.$emit('successAction', file.response.data)
  229. }
  230. }
  231. } else{
  232. that.clearFileUpload()
  233. that.$message.error(res.msg);
  234. }
  235. },
  236. beforeImageUpload(file) {
  237. var that = this;
  238. var checkFile = false;
  239. const fileNameSuffix = file.name.substring(file.name.lastIndexOf("."));
  240. const allowFileTypes = that.allowFileTypes.split("|");
  241. console.log("fileNameSuffix"+fileNameSuffix)
  242. console.log("allowFileTypes"+allowFileTypes.length)
  243. const isLt2M = file.size / 1024 / 1024 < 20;
  244. if (allowFileTypes && allowFileTypes.length > 0) {
  245. for (var i = 0; i < allowFileTypes.length; i++) {
  246. if (allowFileTypes[i].toUpperCase() == fileNameSuffix.toUpperCase()) {
  247. checkFile = true;
  248. break;
  249. }
  250. }
  251. }
  252. if (!checkFile) {
  253. that.$message.error('上传文件格式错误!');
  254. return false;
  255. }
  256. if (that.styleType == 1 && !isLt2M) {
  257. that.$message.error('上传图片大小不能超过 20MB!');
  258. return false;
  259. }
  260. that.uploadConfig.loading = true;
  261. return true;
  262. },
  263. handleImageUploadRemove(file, fileList){
  264. var that = this;
  265. that.uploadConfig.succeedFileList.splice(0, that.uploadConfig.succeedFileList.length);
  266. if (fileList.length > 0) {
  267. for (var i = 0; i < fileList.length; i++) {
  268. var fileItem = fileList[i];
  269. that.uploadConfig.succeedFileList.push(fileItem.response.data);
  270. }
  271. }
  272. },
  273. handleImagePreview(file){
  274. if (file.url.lastIndexOf("_") > -1) {
  275. this.uploadConfig.previewImageUrl = file.url.substring(0, file.url.lastIndexOf("_"));
  276. } else {
  277. this.uploadConfig.previewImageUrl = file.url;
  278. }
  279. var fileNameSuffix = file.name.substring(file.name.lastIndexOf("."));
  280. //判断是否支持视频播放
  281. var allowVideoFileTypes = this.video.split("|");
  282. if (allowVideoFileTypes && allowVideoFileTypes.length > 0) {
  283. for (var i = 0; i < allowVideoFileTypes.length; i++) {
  284. if (allowVideoFileTypes[i].toUpperCase() == fileNameSuffix.toUpperCase()) {
  285. this.showVideo = true;
  286. break;
  287. }
  288. }
  289. }
  290. //判断是否支持音频播放
  291. var allowAudioFileTypes = this.audio.split("|");
  292. if (allowAudioFileTypes && allowAudioFileTypes.length > 0) {
  293. for (var i = 0; i < allowAudioFileTypes.length; i++) {
  294. if (allowAudioFileTypes[i].toUpperCase() == fileNameSuffix.toUpperCase()) {
  295. this.showAudio = true;
  296. break;
  297. }
  298. }
  299. }
  300. this.uploadConfig.dialogVisible = true;
  301. },
  302. initFileList(fileList){
  303. var that = this;
  304. that.uploadConfig.initFileList = [];
  305. that.uploadConfig.succeedFileList = [];
  306. if (fileList != null && fileList.length>0) {
  307. var model = {};
  308. var file ={};
  309. for (var i = 0; i < fileList.length; i++) {
  310. file = fileList[i];
  311. if (!file || !file.path) {
  312. continue;
  313. }
  314. model = {};
  315. model.name = file.path.substring(file.path.lastIndexOf("/") + 1);
  316. if (file.path.indexOf("http") != -1) {
  317. if (that.thumbnailSize){
  318. model.url = file.path + "_" + that.thumbnailSize;
  319. } else{
  320. model.url = file.path;
  321. }
  322. } else {
  323. if (that.thumbnailSize){
  324. model.url = that.uploadConfig.prefixServerFileUrl + file.path + "_" + that.thumbnailSize;
  325. } else{
  326. model.url = that.uploadConfig.prefixServerFileUrl + file.path;
  327. }
  328. }
  329. model.response = {data: file};
  330. that.uploadConfig.initFileList.push(model);
  331. that.uploadConfig.succeedFileList.push(file);
  332. }
  333. }
  334. },
  335. getFileList(){
  336. var that = this;
  337. return that.uploadConfig.succeedFileList;
  338. },
  339. handleExceed(files, fileList){
  340. var that = this;
  341. that.$message.warning(`当前最多上传 ${that.limit} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
  342. },
  343. openLinkUrl(url){
  344. location.href = url;
  345. },
  346. clearFileUpload(){
  347. var that = this;
  348. that.$refs.uploadCtl.clearFiles();
  349. that.uploadConfig.succeedFileList.splice(0, that.uploadConfig.succeedFileList.length);
  350. },
  351. handleImageError(err, file, fileList){
  352. let that = this;
  353. that.$message.error('上传文件发生错误!');
  354. that.uploadConfig.loading = false;
  355. }
  356. }
  357. }
  358. </script>
  359. <style>
  360. /*文件上传样式重写 2018.3.24 姚政伟 新增*/
  361. .uploadDisabled .el-upload {
  362. display: none !important;
  363. }
  364. .el-upload-list.is-disabled {
  365. margin-top: -40px;
  366. }
  367. .el-upload-list.is-disabled:before {
  368. content: '';
  369. position: absolute;
  370. top: 0;
  371. left: 0;
  372. width: 100%;
  373. height: 100%;
  374. background-color: #fff;
  375. }
  376. .el-upload-list.is-disabled .el-upload-list__item-status-label, .el-upload-list.is-disabled .el-upload-list__item.is-success .el-upload-list__item-status-label {
  377. display: none;
  378. }
  379. .yao-upload .el-progress{
  380. display: none;
  381. }
  382. </style>