content_info.vue 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. <template>
  2. <view class="page" v-if="fetch && fetch.content && fetch.content.name">
  3. <!-- 顶部导航栏 -->
  4. <use-tabbar :tabbar="false"></use-tabbar>
  5. <!-- 标题 -->
  6. <view class="title">{{ fetch.content.name }}</view>
  7. <view class="content" v-if="fetch.content.media && fetch.content.media.length > 0">
  8. <u-swiper height="200px" :list="fetch.content.media" :autoplay="false" circular indicator
  9. indicatorMode="line" @change="onSwiperChange"></u-swiper>
  10. <!-- 标题 -->
  11. <view class="media-title">
  12. {{ currentTitle }}
  13. </view>
  14. </view>
  15. <!-- 富文本内容 -->
  16. <view class="content" v-if="fetch.content.content">
  17. <!--
  18. <view class="flex-center">
  19. <u-tabs :list="tab" @click="setTab"></u-tabs>
  20. </view>-->
  21. <u-parse :content="fetch.content.content"></u-parse>
  22. </view>
  23. <!-- 外部链接 -->
  24. <view class="attachment" v-if="fetch.content.link && fetch.content.link.length > 0">
  25. <view class="attachment-title">链接</view>
  26. <view>
  27. <view class="file-item" v-for="(item, index) in fetch.content.link" :key="index"
  28. @click="copy(item.link)">
  29. <u-icon :name="getFileIcon(item.name)" size="22" color="#007aff"></u-icon>
  30. <text class="file-name">{{ item.name }}</text>
  31. <view @click.stop="openLink(item.link)">
  32. <u-icon name="arrow-right" size="18" color="#ccc" style="margin-left:auto;"></u-icon>
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. <!-- 附件区域 -->
  38. <view class="attachment" v-if="fetch.content.data && fetch.content.data.length > 0">
  39. <view class="attachment-title">附件</view>
  40. <view>
  41. <view class="file-item" v-for="(item, index) in fetch.content.data" :key="index"
  42. @click="copy(item.file)">
  43. <u-icon :name="getFileIcon(item.name)" size="22" color="#007aff"></u-icon>
  44. <text class="file-name">{{ item.name }}</text>
  45. <view @click.stop="openFile(item.file)">
  46. <u-icon name="arrow-right" size="18" color="#ccc" style="margin-left:auto;"></u-icon>
  47. </view>
  48. </view>
  49. </view>
  50. </view>
  51. </view>
  52. </template>
  53. <script>
  54. export default {
  55. data() {
  56. return {
  57. fetch: {},
  58. tab: [{
  59. name: '详情'
  60. },
  61. {
  62. name: '列表'
  63. },
  64. ],
  65. currentIndex: 0,
  66. currentTitle: ''
  67. }
  68. },
  69. onLoad(options) {
  70. this.id = options.id
  71. let title = '资源内容';
  72. if (options.title) {
  73. title = options.title;
  74. }
  75. uni.setNavigationBarTitle({
  76. title: title
  77. })
  78. this.loadData()
  79. },
  80. onPullDownRefresh() {
  81. this.loadData()
  82. },
  83. watch: {
  84. 'fetch.content.media': {
  85. immediate: true,
  86. handler(val) {
  87. if (val && val.length > 0) {
  88. this.currentTitle = val[0].title || ''
  89. }
  90. }
  91. }
  92. },
  93. methods: {
  94. onSwiperChange(e) {
  95. this.currentIndex = e.current
  96. this.currentTitle = this.fetch.content.media[e.current]?.title || ''
  97. },
  98. loadData() {
  99. this.DeverApi.get(this, "source.contentInfo", {
  100. id: this.id
  101. })
  102. },
  103. getFileIcon(filename) {
  104. const ext = filename.split('.').pop().toLowerCase()
  105. if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(ext)) return 'photo'
  106. if (['mp4', 'avi', 'mov', 'mkv', 'webm'].includes(ext)) return 'play-circle'
  107. if (['mp3', 'wav', 'aac', 'flac', 'ogg'].includes(ext)) return 'kefu-ermai'
  108. return 'file-text'
  109. },
  110. openFile(file) {
  111. if (this.Dever.env <= 3) {
  112. window.open(file, '_blank')
  113. } else if (this.Dever.env == 4) {
  114. plus.runtime.openURL(file)
  115. } else if (this.Dever.env == 5) {
  116. uni.downloadFile({
  117. file,
  118. success: (res) => {
  119. if (res.statusCode === 200) {
  120. uni.openDocument({
  121. filePath: res.tempFilePath,
  122. showMenu: true
  123. })
  124. }
  125. }
  126. })
  127. }
  128. },
  129. openLink(value) {
  130. if (this.Dever.env <= 3) {
  131. window.open(value, '_blank')
  132. } else {
  133. this.copy(value);
  134. }
  135. },
  136. copy(value) {
  137. uni.setClipboardData({
  138. data: value,
  139. success: () => {
  140. uni.showToast({
  141. title: '已复制,可在浏览器中打开',
  142. icon: 'none'
  143. })
  144. }
  145. })
  146. }
  147. }
  148. }
  149. </script>
  150. <style lang="scss" scoped>
  151. .page {
  152. background-color: #f8f8f8;
  153. min-height: 100vh;
  154. padding: 14rpx;
  155. }
  156. .title {
  157. font-size: 40rpx;
  158. font-weight: bold;
  159. text-align: center;
  160. margin: 30rpx 0;
  161. color: #333;
  162. }
  163. .content {
  164. background-color: #fff;
  165. border-radius: 12rpx;
  166. padding: 30rpx;
  167. font-size: 28rpx;
  168. color: #444;
  169. line-height: 1.7;
  170. box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
  171. margin-bottom: 30rpx;
  172. }
  173. .link {
  174. display: flex;
  175. align-items: center;
  176. padding: 20rpx;
  177. margin-bottom: 30rpx;
  178. border-radius: 12rpx;
  179. background-color: #fff;
  180. box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
  181. }
  182. .link-text {
  183. margin-left: 12rpx;
  184. font-size: 28rpx;
  185. color: #007aff;
  186. }
  187. .attachment {
  188. background-color: #fff;
  189. border-radius: 12rpx;
  190. padding: 24rpx;
  191. box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
  192. }
  193. .attachment-title {
  194. font-size: 32rpx;
  195. font-weight: bold;
  196. margin-bottom: 20rpx;
  197. border-left: 6rpx solid #007aff;
  198. padding-left: 12rpx;
  199. color: #333;
  200. }
  201. .file-item {
  202. display: flex;
  203. align-items: center;
  204. padding: 20rpx;
  205. border-radius: 8rpx;
  206. background-color: #f9f9f9;
  207. margin-bottom: 16rpx;
  208. }
  209. .file-name {
  210. margin-left: 12rpx;
  211. font-size: 28rpx;
  212. color: #007aff;
  213. white-space: normal;
  214. word-break: break-all;
  215. flex: 1;
  216. }
  217. .flex-center {
  218. display: flex;
  219. justify-content: center;
  220. }
  221. .media-title {
  222. margin-top: 10rpx;
  223. font-size: 28rpx;
  224. font-weight: bold;
  225. text-align: center;
  226. }
  227. </style>