htz-image-upload.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. <template>
  2. <view class="htz-image-upload-list">
  3. <view class="htz-image-upload-Item" v-for="(item,index) in uploadLists" :key="index">
  4. <view class="htz-image-upload-Item-video" v-if="isVideo(item)">
  5. <!-- #ifndef APP-PLUS -->
  6. <video :disabled="false" :controls="false" :src="getFileUrl(item)">
  7. <cover-view class="htz-image-upload-Item-video-fixed" @click="previewVideo(getFileUrl(item))">
  8. </cover-view>
  9. <cover-view class="htz-image-upload-Item-del-cover" v-if="remove && previewVideoSrc==''"
  10. @click="imgDel(index)">×</cover-view>
  11. </video>
  12. <!-- #endif -->
  13. <!-- #ifdef APP-PLUS -->
  14. <view class="htz-image-upload-Item-video-fixed" @click="previewVideo(getFileUrl(item))"></view>
  15. <image class="htz-image-upload-Item-video-app-poster" mode="widthFix" :src="appVideoPoster"></image>
  16. <!-- #endif -->
  17. </view>
  18. <image v-else :src="getFileUrl(item)" @click="imgPreview(getFileUrl(item))"></image>
  19. <view class="htz-image-upload-Item-del" v-if="remove" @click="imgDel(index)">×</view>
  20. </view>
  21. <view class="htz-image-upload-Item htz-image-upload-Item-add" v-if="uploadLists.length<max && add"
  22. @click="chooseFile">
  23. +
  24. </view>
  25. <view class="preview-full" v-if="previewVideoSrc!=''">
  26. <video :autoplay="true" :src="previewVideoSrc" :show-fullscreen-btn="false">
  27. <cover-view class="preview-full-close" @click="previewVideoClose"> ×
  28. </cover-view>
  29. </video>
  30. </view>
  31. <!-- -->
  32. </view>
  33. </template>
  34. <style>
  35. .ceshi {
  36. width: 100%;
  37. height: 100%;
  38. position: relative;
  39. top: 0;
  40. left: 0;
  41. bottom: 0;
  42. right: 0;
  43. background-color: #FFFFFF;
  44. color: #2C405A;
  45. opacity: 0.5;
  46. z-index: 100;
  47. }
  48. </style>
  49. <script>
  50. export default {
  51. name: 'htz-image-upload',
  52. props: {
  53. max: { //展示图片最大值
  54. type: Number,
  55. default: 1,
  56. },
  57. chooseNum: { //选择图片数
  58. type: Number,
  59. default: 9,
  60. },
  61. name: { //发到后台的文件参数名
  62. type: String,
  63. default: 'file',
  64. },
  65. dataType: { //v-model的数据结构类型
  66. type: Number,
  67. default: 0, // 0: ['http://xxxx.jpg','http://xxxx.jpg'] 1:[{type:0,url:'http://xxxx.jpg'}] type 0 图片 1 视频 url 文件地址 此类型是为了给没有文件后缀的状况使用的
  68. },
  69. remove: { //是否展示删除按钮
  70. type: Boolean,
  71. default: true,
  72. },
  73. add: { //是否展示添加按钮
  74. type: Boolean,
  75. default: true,
  76. },
  77. disabled: { //是否禁用
  78. type: Boolean,
  79. default: false,
  80. },
  81. sourceType: { //选择照片来源 【ps:H5就别费劲了,设置了也没用。不是我说的,官方文档就这样!!!】
  82. type: Array,
  83. default: () => ['album', 'camera'],
  84. },
  85. action: { //上传地址 如需使用uniCloud服务,设置为uniCloud即可
  86. type: String,
  87. default: '',
  88. },
  89. headers: { //上传的请求头部
  90. type: Object,
  91. default: () => {},
  92. },
  93. formData: { //HTTP 请求中其他额外的 form data
  94. type: Object,
  95. default: () => {},
  96. },
  97. compress: { //是否需要压缩
  98. type: Boolean,
  99. default: true,
  100. },
  101. quality: { //压缩质量,范围0~100
  102. type: Number,
  103. default: 80,
  104. },
  105. value: { //受控图片列表
  106. type: Array,
  107. default: () => [],
  108. },
  109. uploadSuccess: {
  110. default: (res) => {
  111. return {
  112. success: false,
  113. url: ''
  114. }
  115. },
  116. },
  117. mediaType: { //文件类型 image/video/all
  118. type: String,
  119. default: 'image',
  120. },
  121. maxDuration: { //拍摄视频最长拍摄时间,单位秒。最长支持 60 秒。 (只针对拍摄视频有用)
  122. type: Number,
  123. default: 60,
  124. },
  125. camera: { //'front'、'back',默认'back'(只针对拍摄视频有用)
  126. type: String,
  127. default: 'back',
  128. },
  129. appVideoPoster: { //app端视频展示封面 只对app有效
  130. type: String,
  131. default: '/static/htz-image-upload/play.png',
  132. },
  133. },
  134. data() {
  135. return {
  136. uploadLists: [],
  137. mediaTypeData: ['image', 'video', 'all'],
  138. previewVideoSrc: '',
  139. }
  140. },
  141. mounted: function() {
  142. this.$nextTick(function() {
  143. this.uploadLists = this.value;
  144. if (this.mediaTypeData.indexOf(this.mediaType) == -1) {
  145. uni.showModal({
  146. title: '提示',
  147. content: 'mediaType参数不正确',
  148. showCancel: false,
  149. success: function(res) {
  150. if (res.confirm) {
  151. //console.log('用户点击确定');
  152. } else if (res.cancel) {
  153. //console.log('用户点击取消');
  154. }
  155. }
  156. });
  157. }
  158. });
  159. },
  160. watch: {
  161. value(val, oldVal) {
  162. //console.log('value',val, oldVal)
  163. this.uploadLists = val;
  164. },
  165. },
  166. methods: {
  167. isVideo(item) {
  168. let isPass = false
  169. if ((!/.(gif|jpg|jpeg|png|gif|jpg|png)$/i.test(item) && this.dataType == 0) || (this.dataType == 1 && item
  170. .type == 1)) {
  171. isPass = true
  172. }
  173. return isPass
  174. },
  175. getFileUrl(item) {
  176. var url = item;
  177. if (this.dataType == 1) {
  178. url = item.url
  179. }
  180. //console.log('url', url)
  181. return url
  182. },
  183. previewVideo(src) {
  184. this.previewVideoSrc = src;
  185. // this.previewVideoSrc =
  186. // 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-fbd63a76-dc76-485c-b711-f79f2986daeb/ba804d82-860b-4d1a-a706-5a4c8ce137c3.mp4'
  187. },
  188. previewVideoClose() {
  189. this.previewVideoSrc = ''
  190. //console.log('previewVideoClose', this.previewVideoSrc)
  191. },
  192. imgDel(index) {
  193. uni.showModal({
  194. title: '提示',
  195. content: '您确定要删除么?',
  196. success: (res) => {
  197. if (res.confirm) {
  198. // this.uploadLists.splice(index, 1)
  199. // this.$emit("input", this.uploadLists);
  200. // this.$emit("imgDelete", this.uploadLists);
  201. let delUrl = this.uploadLists[index]
  202. this.uploadLists.splice(index, 1)
  203. this.$emit("input", this.uploadLists);
  204. this.$emit("imgDelete", {
  205. del: delUrl,
  206. tempFilePaths: this.uploadLists
  207. });
  208. } else if (res.cancel) {}
  209. }
  210. });
  211. },
  212. imgPreview(index) {
  213. var imgData = []
  214. this.uploadLists.forEach(item => {
  215. if (!this.isVideo(item)) {
  216. imgData.push(this.getFileUrl(item))
  217. }
  218. })
  219. //console.log('imgPreview', imgData)
  220. uni.previewImage({
  221. urls: imgData,
  222. current: index,
  223. loop: true,
  224. });
  225. },
  226. chooseFile() {
  227. if (this.disabled) {
  228. return false;
  229. }
  230. switch (this.mediaTypeData.indexOf(this.mediaType)) {
  231. case 1: //视频
  232. this.videoAdd();
  233. break;
  234. case 2: //全部
  235. uni.showActionSheet({
  236. itemList: ['相册', '视频'],
  237. success: (res) => {
  238. if (res.tapIndex == 1) {
  239. this.videoAdd();
  240. } else if (res.tapIndex == 0) {
  241. this.imgAdd();
  242. }
  243. },
  244. fail: (res) => {
  245. console.log(res.errMsg);
  246. }
  247. });
  248. break;
  249. default: //图片
  250. this.imgAdd();
  251. break;
  252. }
  253. //if(this.mediaType=='image'){
  254. },
  255. videoAdd() {
  256. //console.log('videoAdd')
  257. let nowNum = Math.abs(this.uploadLists.length - this.max);
  258. let thisNum = (this.chooseNum > nowNum ? nowNum : this.chooseNum) //可选数量
  259. uni.chooseVideo({
  260. compressed: this.compress,
  261. sourceType: this.sourceType,
  262. camera: this.camera,
  263. maxDuration: this.maxDuration,
  264. success: (res) => {
  265. // console.log('videoAdd', res)
  266. // console.log(res.tempFilePath)
  267. this.chooseSuccessMethod([res.tempFilePath], 1)
  268. //this.imgUpload([res.tempFilePath]);
  269. //console.log('tempFiles', res)
  270. // if (this.action == '') { //未配置上传路径
  271. // this.$emit("chooseSuccess", res.tempFilePaths);
  272. // } else {
  273. // if (this.compress && (res.tempFiles[0].size / 1024 > 1025)) { //设置了需要压缩 并且 文件大于1M,进行压缩上传
  274. // this.imgCompress(res.tempFilePaths);
  275. // } else {
  276. // this.imgUpload(res.tempFilePaths);
  277. // }
  278. // }
  279. }
  280. });
  281. },
  282. imgAdd() {
  283. //console.log('imgAdd')
  284. let nowNum = Math.abs(this.uploadLists.length - this.max);
  285. let thisNum = (this.chooseNum > nowNum ? nowNum : this.chooseNum) //可选数量
  286. //console.log('nowNum', nowNum)
  287. //console.log('thisNum', thisNum)
  288. // #ifdef APP-PLUS
  289. if (this.sourceType.length > 1) {
  290. uni.showActionSheet({
  291. itemList: ['拍摄', '从手机相册选择'],
  292. success: (res) => {
  293. if (res.tapIndex == 1) {
  294. this.appGallery(thisNum);
  295. } else if (res.tapIndex == 0) {
  296. this.appCamera();
  297. }
  298. },
  299. fail: (res) => {
  300. console.log(res.errMsg);
  301. }
  302. });
  303. }
  304. if (this.sourceType.length == 1 && this.sourceType.indexOf('album') > -1) {
  305. this.appGallery(thisNum);
  306. }
  307. if (this.sourceType.length == 1 && this.sourceType.indexOf('camera') > -1) {
  308. this.appCamera();
  309. }
  310. // #endif
  311. //#ifndef APP-PLUS
  312. uni.chooseImage({
  313. count: thisNum,
  314. sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
  315. sourceType: this.sourceType,
  316. success: (res) => {
  317. this.chooseSuccessMethod(res.tempFilePaths, 0)
  318. //console.log('tempFiles', res)
  319. // if (this.action == '') { //未配置上传路径
  320. // this.$emit("chooseSuccess", res.tempFilePaths);
  321. // } else {
  322. // if (this.compress && (res.tempFiles[0].size / 1024 > 1025)) { //设置了需要压缩 并且 文件大于1M,进行压缩上传
  323. // this.imgCompress(res.tempFilePaths);
  324. // } else {
  325. // this.imgUpload(res.tempFilePaths);
  326. // }
  327. // }
  328. }
  329. });
  330. // #endif
  331. },
  332. appCamera() {
  333. var cmr = plus.camera.getCamera();
  334. var res = cmr.supportedImageResolutions[0];
  335. var fmt = cmr.supportedImageFormats[0];
  336. //console.log("Resolution: " + res + ", Format: " + fmt);
  337. cmr.captureImage((path) => {
  338. //alert("Capture image success: " + path);
  339. this.chooseSuccessMethod([path], 0)
  340. },
  341. (error) => {
  342. //alert("Capture image failed: " + error.message);
  343. console.log("Capture image failed: " + error.message)
  344. }, {
  345. resolution: res,
  346. format: fmt
  347. }
  348. );
  349. },
  350. appGallery(maxNum) {
  351. plus.gallery.pick((res) => {
  352. this.chooseSuccessMethod(res.files, 0)
  353. }, function(e) {
  354. //console.log("取消选择图片");
  355. }, {
  356. filter: "image",
  357. multiple: true,
  358. maximum: maxNum
  359. });
  360. },
  361. chooseSuccessMethod(filePaths, type) {
  362. if (this.action == '') { //未配置上传路径
  363. this.$emit("chooseSuccess", filePaths, type); //filePaths 路径 type 0 为图片 1为视频
  364. } else {
  365. if (type == 1) {
  366. this.imgUpload(filePaths, type);
  367. } else {
  368. if (this.compress) { //设置了需要压缩
  369. this.imgCompress(filePaths, type);
  370. } else {
  371. this.imgUpload(filePaths, type);
  372. }
  373. }
  374. }
  375. },
  376. imgCompress(tempFilePaths, type) { //type 0 为图片 1为视频
  377. uni.showLoading({
  378. title: '压缩中...'
  379. });
  380. let compressImgs = [];
  381. let results = [];
  382. tempFilePaths.forEach((item, index) => {
  383. compressImgs.push(new Promise((resolve, reject) => {
  384. // #ifndef H5
  385. uni.compressImage({
  386. src: item,
  387. quality: this.quality,
  388. success: res => {
  389. //console.log('compressImage', res.tempFilePath)
  390. results.push(res.tempFilePath);
  391. resolve(res.tempFilePath);
  392. },
  393. fail: (err) => {
  394. //console.log(err.errMsg);
  395. reject(err);
  396. },
  397. complete: () => {
  398. //uni.hideLoading();
  399. }
  400. })
  401. // #endif
  402. // #ifdef H5
  403. this.canvasDataURL(item, {
  404. quality: this.quality / 100
  405. }, (base64Codes) => {
  406. //this.imgUpload(base64Codes);
  407. results.push(base64Codes);
  408. resolve(base64Codes);
  409. })
  410. // #endif
  411. }))
  412. })
  413. Promise.all(compressImgs) //执行所有需请求的接口
  414. .then((results) => {
  415. uni.hideLoading();
  416. //console.log('imgCompress', type)
  417. this.imgUpload(results, type);
  418. })
  419. .catch((res, object) => {
  420. uni.hideLoading();
  421. });
  422. },
  423. imgUpload(tempFilePaths, type) { //type 0 为图片 1为视频
  424. // if (this.action == '') {
  425. // uni.showToast({
  426. // title: '未配置上传地址',
  427. // icon: 'none',
  428. // duration: 2000
  429. // });
  430. // return false;
  431. // }
  432. if (this.action == 'uniCloud') {
  433. this.uniCloudUpload(tempFilePaths, type)
  434. return
  435. }
  436. uni.showLoading({
  437. title: '上传中'
  438. });
  439. //console.log('imgUpload', tempFilePaths)
  440. let uploadImgs = [];
  441. tempFilePaths.forEach((item, index) => {
  442. uploadImgs.push(new Promise((resolve, reject) => {
  443. //console.log(index, item)
  444. const uploadTask = uni.uploadFile({
  445. url: this.action, //仅为示例,非真实的接口地址
  446. filePath: item,
  447. name: this.name,
  448. fileType: 'image',
  449. formData: this.formData,
  450. header: this.headers,
  451. success: (uploadFileRes) => {
  452. //uni.hideLoading();
  453. //console.log(typeof this.uploadSuccess)
  454. //console.log('')
  455. uploadFileRes.fileType = type
  456. if (typeof this.uploadSuccess == 'function') {
  457. let thisUploadSuccess = this.uploadSuccess(
  458. uploadFileRes)
  459. if (thisUploadSuccess.success) {
  460. if (this.dataType == 0) {
  461. this.value.push(thisUploadSuccess.url)
  462. } else {
  463. this.value.push({
  464. type: type,
  465. url: thisUploadSuccess.url
  466. })
  467. }
  468. this.$emit("input", this.uploadLists);
  469. }
  470. }
  471. resolve(uploadFileRes);
  472. this.$emit("uploadSuccess", uploadFileRes);
  473. },
  474. fail: (err) => {
  475. console.log(err);
  476. //uni.hideLoading();
  477. reject(err);
  478. this.$emit("uploadFail", err);
  479. },
  480. complete: () => {
  481. //uni.hideLoading();
  482. }
  483. });
  484. }))
  485. })
  486. Promise.all(uploadImgs) //执行所有需请求的接口
  487. .then((results) => {
  488. uni.hideLoading();
  489. })
  490. .catch((res, object) => {
  491. uni.hideLoading();
  492. this.$emit("uploadFail", res);
  493. });
  494. // uploadTask.onProgressUpdate((res) => {
  495. // //console.log('',)
  496. // uni.showLoading({
  497. // title: '上传中' + res.progress + '%'
  498. // });
  499. // if (res.progress == 100) {
  500. // uni.hideLoading();
  501. // }
  502. // });
  503. },
  504. uniCloudUpload(tempFilePaths, type) {
  505. uni.showLoading({
  506. title: '上传中'
  507. });
  508. console.log('uniCloudUpload', tempFilePaths);
  509. let uploadImgs = [];
  510. tempFilePaths.forEach((item, index) => {
  511. uploadImgs.push(new Promise((resolve, reject) => {
  512. uniCloud.uploadFile({
  513. filePath: item,
  514. cloudPath: this.guid() + '.' + this.getFileType(item, type),
  515. success(uploadFileRes) {
  516. if (uploadFileRes.success) {
  517. resolve(uploadFileRes.fileID);
  518. }
  519. },
  520. fail(err) {
  521. console.log(err);
  522. reject(err);
  523. },
  524. complete() {}
  525. });
  526. }))
  527. })
  528. Promise.all(uploadImgs) //执行所有需请求的接口
  529. .then((results) => {
  530. uni.hideLoading();
  531. // console.log('then', results)
  532. uniCloud.getTempFileURL({
  533. fileList: results,
  534. success: (res) => {
  535. //console.log('success',res.fileList)
  536. res.fileList.forEach(item => {
  537. //console.log(item.tempFileURL)
  538. this.value.push(item.tempFileURL)
  539. })
  540. },
  541. fail() {},
  542. complete() {}
  543. });
  544. })
  545. .catch((res, object) => {
  546. uni.hideLoading();
  547. });
  548. },
  549. getFileType(path, type) { //手机端默认图片为jpg 视频为mp4
  550. // #ifdef H5
  551. var result = type == 0 ? 'jpg' : 'mp4';
  552. // #endif
  553. // #ifndef H5
  554. var result = path.split('.').pop().toLowerCase();
  555. // #ifdef MP
  556. if (this.compress) {//微信小程序压缩完没有后缀
  557. result = type == 0 ? 'jpg' : 'mp4';
  558. }
  559. // #endif
  560. // #endif
  561. return result;
  562. },
  563. guid() {
  564. return 'xxxxxxxx-date-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  565. var r = Math.random() * 16 | 0,
  566. v = c == 'x' ? r : (r & 0x3 | 0x8);
  567. return v.toString(16);
  568. }).replace(/date/g, function(c) {
  569. return Date.parse(new Date());
  570. });
  571. },
  572. canvasDataURL(path, obj, callback) {
  573. var img = new Image();
  574. img.src = path;
  575. img.onload = function() {
  576. var that = this;
  577. // 默认按比例压缩
  578. var w = that.width,
  579. h = that.height,
  580. scale = w / h;
  581. w = obj.width || w;
  582. h = obj.height || (w / scale);
  583. var quality = 0.8; // 默认图片质量为0.8
  584. //生成canvas
  585. var canvas = document.createElement('canvas');
  586. var ctx = canvas.getContext('2d');
  587. // 创建属性节点
  588. var anw = document.createAttribute("width");
  589. anw.nodeValue = w;
  590. var anh = document.createAttribute("height");
  591. anh.nodeValue = h;
  592. canvas.setAttributeNode(anw);
  593. canvas.setAttributeNode(anh);
  594. ctx.drawImage(that, 0, 0, w, h);
  595. // 图像质量
  596. if (obj.quality && obj.quality <= 1 && obj.quality > 0) {
  597. quality = obj.quality;
  598. }
  599. // quality值越小,所绘制出的图像越模糊
  600. var base64 = canvas.toDataURL('image/jpeg', quality);
  601. // 回调函数返回base64的值
  602. callback(base64);
  603. }
  604. },
  605. }
  606. }
  607. </script>
  608. <style>
  609. .preview-full {
  610. position: fixed;
  611. top: 0;
  612. left: 0;
  613. bottom: 0;
  614. width: 100%;
  615. height: 100%;
  616. z-index: 1002;
  617. }
  618. .preview-full video {
  619. width: 100%;
  620. height: 100%;
  621. z-index: 1002;
  622. }
  623. .preview-full-close {
  624. position: fixed;
  625. right: 32rpx;
  626. top: 25rpx;
  627. width: 80rpx;
  628. height: 80rpx;
  629. line-height: 60rpx;
  630. text-align: center;
  631. z-index: 1003;
  632. /* background-color: #808080; */
  633. color: #fff;
  634. font-size: 65rpx;
  635. font-weight: bold;
  636. text-shadow: 1px 2px 5px rgb(0 0 0);
  637. }
  638. /* .preview-full-close-before,
  639. .preview-full-close-after {
  640. position: absolute;
  641. top: 50%;
  642. left: 50%;
  643. content: '';
  644. height: 60rpx;
  645. margin-top: -30rpx;
  646. width: 6rpx;
  647. margin-left: -3rpx;
  648. background-color: #FFFFFF;
  649. z-index: 20000;
  650. }
  651. .preview-full-close-before {
  652. transform: rotate(45deg);
  653. }
  654. .preview-full-close-after {
  655. transform: rotate(-45deg);
  656. } */
  657. .htz-image-upload-list {
  658. display: flex;
  659. flex-wrap: wrap;
  660. }
  661. .htz-image-upload-Item {
  662. width: 160rpx;
  663. height: 160rpx;
  664. margin: 13rpx;
  665. border-radius: 10rpx;
  666. position: relative;
  667. }
  668. .htz-image-upload-Item image {
  669. width: 100%;
  670. height: 100%;
  671. border-radius: 10rpx;
  672. }
  673. .htz-image-upload-Item-video {
  674. width: 100%;
  675. height: 100%;
  676. border-radius: 10rpx;
  677. position: relative;
  678. }
  679. .htz-image-upload-Item-video-fixed {
  680. position: absolute;
  681. top: 0;
  682. left: 0;
  683. bottom: 0;
  684. width: 100%;
  685. height: 100%;
  686. border-radius: 10rpx;
  687. z-index: 996;
  688. }
  689. .htz-image-upload-Item video {
  690. width: 100%;
  691. height: 100%;
  692. border-radius: 10rpx;
  693. }
  694. .htz-image-upload-Item-add {
  695. font-size: 105rpx;
  696. /* line-height: 160rpx; */
  697. text-align: center;
  698. border: 1px dashed #d9d9d9;
  699. color: #d9d9d9;
  700. }
  701. .htz-image-upload-Item-del {
  702. background-color: #f5222d;
  703. font-size: 24rpx;
  704. position: absolute;
  705. width: 35rpx;
  706. height: 35rpx;
  707. line-height: 35rpx;
  708. text-align: center;
  709. top: 0;
  710. right: 0;
  711. z-index: 997;
  712. color: #fff;
  713. }
  714. .htz-image-upload-Item-del-cover {
  715. background-color: #f5222d;
  716. font-size: 24rpx;
  717. position: absolute;
  718. width: 35rpx;
  719. height: 35rpx;
  720. text-align: center;
  721. top: 0;
  722. right: 0;
  723. color: #fff;
  724. /* #ifdef APP-PLUS */
  725. line-height: 25rpx;
  726. /* #endif */
  727. /* #ifndef APP-PLUS */
  728. line-height: 35rpx;
  729. /* #endif */
  730. z-index: 997;
  731. }
  732. .htz-image-upload-Item-video-app-poster {
  733. width: 100%;
  734. height: 100%;
  735. }
  736. </style>