uploadImgsName.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. <!--
  2. @param keysArr 承接数组
  3. @param readOnly 删除按钮是否显示,上传是否显示
  4. @param max 上传最大数限制
  5. @click change 承接数组发生变化时触发函数
  6. -->
  7. <template>
  8. <div id="sagaUploads" :style="{marginLeft:(isShow && imagesArr.length>2) ? '157px':'',marginTop:(isShow && imagesArr.length>2) ? '-25px':''}">
  9. <div class="saga-upload-images">
  10. <div v-if="type != 'video'" class="point-view" v-for="(item,index) in imagesArr">
  11. <div class="point-image">
  12. <i v-if="!readOnly" class="el-icon-delete" @click="delImage(index,item)"></i>
  13. <img @click="lookImg" :src="imageGetUrl + '&key=' +item.key" alt v-load>
  14. </div>
  15. <p v-if="readOnly" >{{item.name}}</p>
  16. <form-input v-else :label="''" @change="getName" :keys="index" :value="item.name" :width="10"></form-input>
  17. </div>
  18. <div v-if="type == 'video'" class="point-view" v-for="(item,index) in imagesArr">
  19. <div class="point-image">
  20. <i v-if="!readOnly" class="el-icon-delete" @click="delImage(index,item)"></i>
  21. <video
  22. width="100%"
  23. height="100%;"
  24. :src="imageGetUrl + '&key=' +item.key"
  25. controls="controls"
  26. >您的浏览器不支持 video 标签。</video>
  27. </div>
  28. <p v-if="readOnly" >{{item.name}}</p>
  29. <form-input v-else :label="''" @change="getName" :keys="index" :value="item.name" :width="10"></form-input>
  30. </div>
  31. <div v-if="!readOnly" style="float:left;">
  32. <el-upload
  33. class="avatar-uploader"
  34. :http-request="uploadAndSubmit"
  35. :show-file-list="false"
  36. :accept="accept"
  37. action
  38. drag
  39. style="position: relative"
  40. >
  41. <i class="el-icon-plus avatar-uploader-icon"></i>
  42. </el-upload>
  43. <video style="display:none;" id="video" controls/>
  44. </div>
  45. </div>
  46. <details-dialog :title="'图片'" :iframeSrc="iframeSrc" :dialog="dialog" :setData="imagesArr"></details-dialog>
  47. </div>
  48. </template>
  49. <script>
  50. import tools from "@/utils/scan/tools";
  51. import formInput from "@/components/business_space/lib/formInput"
  52. import detailsDialog from "@/components/business_space/lib/detailsDia"
  53. export default {
  54. components: {
  55. formInput,
  56. detailsDialog
  57. },
  58. props: {
  59. keysArr: {
  60. type: [Array, String]
  61. },
  62. readOnly: {
  63. type: Boolean,
  64. default: false
  65. },
  66. max: {
  67. type: [Number, String],
  68. default: 6
  69. },
  70. accept: {
  71. type: String,
  72. default: "image/*"
  73. },
  74. type: {
  75. type: String,
  76. default: "image"
  77. },
  78. contextKey: {
  79. type: [String, Object]
  80. },
  81. isShow: {
  82. type: [Number, String]
  83. },
  84. defined: null,
  85. videoPicArr: {
  86. type: Array,
  87. default: function () {
  88. return []
  89. }
  90. }
  91. },
  92. data() {
  93. return {
  94. baseUrl: "",
  95. imageGetUrl: "/image-service/common/image_get?systemId=dataPlatform",
  96. imageUploadUrl: "/image-service/common/image_upload?systemId=dataPlatform&secret=9e0891a7a8c8e885&overwrite=true",
  97. imagesArr: [],
  98. iframeSrc: "",
  99. dialog: {
  100. details: false
  101. }
  102. };
  103. },
  104. created() {
  105. this.imageFalg();
  106. },
  107. methods: {
  108. getName(name, index) {
  109. this.imagesArr[index].name = name
  110. if (this.isShow === 1) {
  111. let oFile = {}
  112. oFile[this.contextKey] = this.imagesArr
  113. this.$emit("change", oFile, this.defined, this.videoPicArr);
  114. } else {
  115. this.$emit("change", this.imagesArr, this.defined, this.videoPicArr);
  116. }
  117. },
  118. //判断是否为空
  119. imageFalg() {
  120. let type = typeof this.keysArr;
  121. if (type == "string") {
  122. this.imagesArr = [this.keysArr];
  123. } else {
  124. this.imagesArr = tools.copyArr(this.keysArr);
  125. }
  126. if (!this.keysArr) {
  127. this.imagesArr = [];
  128. }
  129. },
  130. //查看图片
  131. lookImg() {
  132. this.dialog.details = true
  133. this.iframeSrc = process.env.BASE_URL + ":8890/photo-View.html"
  134. },
  135. //删除图片
  136. delImage(i, key) {
  137. if (this.type == "video") {
  138. this.videoPicArr = this.videoPicArr.map(item => {
  139. if (item.key.substring(0, item.length - 3) == this.imagesArr[i].key.substring(0, this.imagesArr[i].length - 3)) {
  140. return undefined
  141. } else {
  142. return item
  143. }
  144. }).filter(p => p)
  145. }
  146. this.imagesArr.splice(i, 1);
  147. this.$emit("change", this.imagesArr, this.defined, this.videoPicArr);
  148. },
  149. //上传
  150. uploadAndSubmit(item, key) {
  151. // var form = document.forms["demoForm"];
  152. // if (form["file"].files.length > 0) {
  153. // 寻找表单域中的 <input type="file" ... /> 标签
  154. // var file = form["file"].files[0];
  155. let file = item.file;
  156. // try sending
  157. let reader = new FileReader();
  158. let vm = this;
  159. let fileType = file.name.split(".");
  160. let type = fileType[fileType.length - 1];
  161. let CreateTime = tools.formatDate(new Date(file.lastModified))
  162. let uploadKey = file.uid
  163. if (!!key) {
  164. uploadKey = key
  165. }
  166. reader.onloadstart = function () {
  167. // 这个事件在读取开始时触发
  168. };
  169. reader.onprogress = function (p) {
  170. // 这个事件在读取进行中定时触发
  171. };
  172. reader.onload = function () {
  173. // 这个事件在读取成功结束后触发
  174. };
  175. reader.onloadend = function () {
  176. // 这个事件在读取结束后,无论成功或者失败都会触发
  177. if (reader.error) {
  178. } else {
  179. // document.getElementById("bytesRead").textContent = file.size;
  180. // 构造 XMLHttpRequest 对象,发送文件 Binary 数据
  181. var xhr = new XMLHttpRequest();
  182. xhr.open(
  183. /* method */
  184. "POST",
  185. /* target url */
  186. vm.imageUploadUrl + "&key=" + uploadKey + "." + type
  187. /*, async, default to true */
  188. );
  189. //xhr.overrideMimeType("application/octet-stream");
  190. xhr.send(reader.result);
  191. xhr.onreadystatechange = function () {
  192. if (xhr.readyState == 4) {
  193. if (xhr.status == 200) {
  194. if (vm.type == 'image') {
  195. vm.imagesArr.push({
  196. name: uploadKey + '',
  197. key: uploadKey + "." + type,
  198. systemId: "dataPlatform",
  199. type: "image",
  200. createTime: CreateTime
  201. });
  202. }
  203. if (type == 'mp4') {
  204. vm.imagesArr.push({
  205. name: uploadKey + '',
  206. key: uploadKey + "." + type,
  207. systemId: "dataPlatform",
  208. type: "video",
  209. createTime: CreateTime
  210. });
  211. vm.creatImg(vm.imageGetUrl + "&key=" + uploadKey + "." + type, uploadKey)
  212. }
  213. if (vm.type == "video" && type == "png") {
  214. vm.videoPicArr.push({
  215. name: uploadKey + '',
  216. key: uploadKey + "." + type,
  217. systemId: "dataPlatform",
  218. type: "image_video",
  219. createTime: CreateTime
  220. })
  221. }
  222. if (vm.isShow === 1) {
  223. let oFile = {}
  224. oFile[vm.contextKey] = vm.imagesArr
  225. vm.$emit("change", oFile, vm.defined, vm.videoPicArr);
  226. } else {
  227. vm.$emit("change", vm.imagesArr, vm.defined, vm.videoPicArr);
  228. }
  229. }
  230. }
  231. };
  232. }
  233. };
  234. reader.readAsArrayBuffer(file);
  235. },
  236. dataURLtoBlob(dataURI, type) {
  237. var binary = atob(dataURI.split(',')[1]);
  238. var array = [];
  239. for (var i = 0; i < binary.length; i++) {
  240. array.push(binary.charCodeAt(i));
  241. }
  242. return new Blob([new Uint8Array(array)], { type: type });
  243. },
  244. creatImg(reader, key) {
  245. var videoDom = document.getElementById('video');
  246. videoDom.src = reader;
  247. let vm = this
  248. videoDom.onloadeddata = function () {
  249. // 这里可以打印视频时长
  250. // 这里取得视频封面
  251. var canvas = document.createElement('canvas');
  252. canvas.width = 300;
  253. canvas.height = 300 * this.videoHeight / this.videoWidth;
  254. canvas.getContext('2d').drawImage(this, 0, 0, canvas.width, canvas.height);
  255. //将canvas的base64位图片转换成图片png的file
  256. var blob = vm.dataURLtoBlob(canvas.toDataURL('image/png'), "image/png")
  257. //将其转换成file对象
  258. var file = new File([blob], "video_image.png", { type: "image/png", lastModified: Date.now() })//blob转file
  259. vm.uploadAndSubmit({ file: file }, key)
  260. }
  261. },
  262. },
  263. watch: {
  264. keysArr: function (val) {
  265. this.imageFalg();
  266. }
  267. },
  268. //自定义指令
  269. directives: {
  270. load: function (el) {
  271. let imgDom = document.createElement("img");
  272. imgDom.style.position = "absolute";
  273. imgDom.style.top = "-999px";
  274. imgDom.style.opacity = 0;
  275. imgDom.src = el.src;
  276. el.src = "";
  277. imgDom.onload = () => {
  278. let width = imgDom.width;
  279. let height = imgDom.height;
  280. if (width > height) {
  281. el.style.height = "100%";
  282. el.style.width = "auto";
  283. el.style.position = "absolute";
  284. el.style.left = "50%";
  285. el.style.top = "0";
  286. el.style.transform = "translateX(-50%)";
  287. el.style.webkitTransform = "translateX(-50%) translateY(0)";
  288. el.style.MozTransform = "translateX(-50%) translateY(0)";
  289. el.style.msTransform = "translateX(-50%) translateY(0)";
  290. el.style.OTransform = "translateX(-50%) translateY(0)";
  291. } else if (width < height) {
  292. el.src = imgDom.src;
  293. el.style.width = "100%";
  294. el.style.height = "auto";
  295. el.style.position = "absolute";
  296. el.style.top = "50%";
  297. el.style.left = "0";
  298. el.style.transform = "translateY(-50%) translateX(0)";
  299. el.style.webkitTransform = "translateY(-50%) translateX(0)";
  300. el.style.MozTransform = "translateY(-50%) translateX(0)";
  301. el.style.msTransform = "translateY(-50%) translateX(0)";
  302. el.style.OTransform = "translateY(-50%) translateX(0)";
  303. } else {
  304. el.style.width = "100%";
  305. el.style.height = "100%";
  306. el.style.position = "absolute";
  307. el.style.top = "0";
  308. el.style.left = "0";
  309. el.style.transform = "translateY(0) translateX(0)";
  310. el.style.webkitTransform = "translateY(0) translateX(0)";
  311. el.style.MozTransform = "translateY(0) translateX(0)";
  312. el.style.msTransform = "translateY(0) translateX(0)";
  313. el.style.OTransform = "translateY(0) translateX(0)";
  314. }
  315. el.src = imgDom.src;
  316. };
  317. }
  318. }
  319. };
  320. </script>
  321. <style lang="less">
  322. #sagaUploads {
  323. /deep/ .el-upload--text {
  324. box-sizing: border-box;
  325. }
  326. overflow: hidden;
  327. .avatar-uploader {
  328. /*height: 180px;*/
  329. /*width: 180px;*/
  330. /*overflow: hidden;*/
  331. .el-upload {
  332. /*width: 180px;*/
  333. /*height: 180px;*/
  334. .el-upload-dragger {
  335. width: 180px !important;
  336. height: 180px !important;
  337. .el-icon-plus {
  338. display: block;
  339. width: 20px;
  340. height: 20px;
  341. font-size: 20px;
  342. margin: 80px;
  343. }
  344. }
  345. }
  346. }
  347. .point-view {
  348. float: left;
  349. margin-right: 10px;
  350. margin-bottom: 10px;
  351. overflow: hidden;
  352. height: 240px;
  353. }
  354. .point-image {
  355. width: 180px;
  356. height: 180px;
  357. position: relative;
  358. border: 1px solid #ccc;
  359. overflow: hidden;
  360. img {
  361. z-index: 11;
  362. }
  363. i {
  364. position: absolute;
  365. bottom: 10px;
  366. right: 10px;
  367. background-color: #fff;
  368. padding: 5px;
  369. cursor: pointer;
  370. z-index: 66;
  371. }
  372. }
  373. }
  374. </style>