瑶都万能墙
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

204 lines
4.2 KiB

1 year ago
1 year ago
1 year ago
11 months ago
1 year ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. <template>
  2. <view>
  3. <view class="dynamics" v-html="$utils.stringFormatHtml(item.title)">
  4. </view>
  5. <view class="Artworkimages" :class="layoutClass">
  6. <view class="wrokimg" @click.stop="previewMedia(media, i)" :key="i" v-for="(media, i) in mediaList">
  7. <image v-if="media.type === 'image'" :src="media.url" mode="aspectFill"></image>
  8. <video v-else-if="media.type === 'video'" :src="media.url"
  9. controls
  10. :poster="media.poster || ''"
  11. :style="videoStyle"></video>
  12. <!-- <view v-if="media.type === 'video'" class="video-overlay">
  13. <uv-icon name="play-circle-fill" size="60rpx" color="#fff"></uv-icon>
  14. </view> -->
  15. </view>
  16. </view>
  17. <addressSpot
  18. :address="item.address"
  19. :latitude="item.latitude"
  20. :longitude="item.longitude"
  21. />
  22. </view>
  23. </template>
  24. <script>
  25. export default {
  26. props: {
  27. item: {},
  28. },
  29. computed : {
  30. images(){
  31. if(!this.item.image){
  32. return []
  33. }
  34. let arr = this.item.image.split(',')
  35. if(this.item.wxImage){
  36. arr.unshift(this.item.wxImage)
  37. }
  38. return arr
  39. },
  40. mediaList(){
  41. let mediaArray = []
  42. // 添加微信二维码图片
  43. if(this.item.wxImage){
  44. mediaArray.push({
  45. url: this.item.wxImage,
  46. type: 'image'
  47. })
  48. }
  49. // 从 image 字段解析所有文件(图片和视频)
  50. if(this.item.image){
  51. this.item.image.split(',').forEach(url => {
  52. if(url.trim()){
  53. // 根据文件扩展名判断类型
  54. const isVideo = this.isVideoFile(url.trim())
  55. mediaArray.push({
  56. url: url.trim(),
  57. type: isVideo ? 'video' : 'image'
  58. })
  59. }
  60. })
  61. }
  62. return mediaArray
  63. },
  64. // 根据媒体数量决定布局类型
  65. layoutClass(){
  66. const count = this.mediaList.length
  67. if(count === 1){
  68. return 'single-layout'
  69. } else if(count === 2 || count === 4){
  70. return 'grid-layout-2x2'
  71. } else {
  72. return 'grid-layout-3x3'
  73. }
  74. },
  75. // 动态视频样式
  76. videoStyle(){
  77. const count = this.mediaList.length
  78. let style = 'border-radius: 20rpx;'
  79. if(count === 1){
  80. // 单个视频占满宽度
  81. style += 'width: 100%; height: 400rpx;'
  82. } else if(count === 2 || count === 4){
  83. // 4宫格布局
  84. style += 'width: calc(50% - 10rpx); height: 200rpx;'
  85. } else {
  86. // 9宫格布局
  87. style += 'width: calc(33.33% - 10rpx); height: 150rpx;'
  88. }
  89. return style
  90. }
  91. },
  92. data() {
  93. return {
  94. }
  95. },
  96. methods: {
  97. previewMedia(media, index){
  98. if(media.type === 'image'){
  99. // 只预览图片
  100. const imageUrls = this.mediaList.filter(item => item.type === 'image').map(item => item.url)
  101. const imageIndex = this.mediaList.slice(0, index).filter(item => item.type === 'image').length
  102. uni.previewImage({
  103. urls: imageUrls,
  104. current: imageIndex
  105. })
  106. } else if(media.type === 'video'){
  107. // 视频点击播放(已经有controls属性,无需额外处理)
  108. console.log('播放视频:', media.url)
  109. }
  110. },
  111. isVideoFile(url) {
  112. const videoExtensions = ['.mp4', '.avi', '.mov', '.wmv', '.flv', '.webm', '.m4v']
  113. const lowerUrl = url.toLowerCase()
  114. return videoExtensions.some(ext => lowerUrl.includes(ext))
  115. }
  116. }
  117. }
  118. </script>
  119. <style scoped lang="scss">
  120. .dynamics {
  121. margin-top: 20rpx;
  122. font-size: 28rpx;
  123. letter-spacing: 3rpx;
  124. }
  125. .Artworkimages {
  126. display: flex;
  127. flex-wrap: wrap;
  128. margin-top: 20rpx;
  129. // 单图布局 - 占满宽度
  130. &.single-layout {
  131. .wrokimg {
  132. width: 100%;
  133. margin: 0;
  134. image {
  135. width: 100%;
  136. height: 400rpx;
  137. border-radius: 20rpx;
  138. }
  139. }
  140. }
  141. // 4宫格布局 - 2x2
  142. &.grid-layout-2x2 {
  143. .wrokimg {
  144. width: calc(50% - 10rpx);
  145. margin: 5rpx;
  146. image {
  147. width: 100%;
  148. height: 200rpx;
  149. border-radius: 20rpx;
  150. }
  151. }
  152. }
  153. // 9宫格布局 - 3x3
  154. &.grid-layout-3x3 {
  155. .wrokimg {
  156. width: calc(33.33% - 10rpx);
  157. margin: 5rpx;
  158. image {
  159. width: 100%;
  160. height: 150rpx;
  161. border-radius: 20rpx;
  162. }
  163. }
  164. }
  165. .wrokimg {
  166. position: relative;
  167. video {
  168. border-radius: 20rpx;
  169. }
  170. .video-overlay {
  171. position: absolute;
  172. top: 50%;
  173. left: 50%;
  174. transform: translate(-50%, -50%);
  175. pointer-events: none;
  176. z-index: 1;
  177. }
  178. }
  179. }
  180. </style>