new.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. <template>
  2. <cwg-page-wrapper class="create-page" :isHeaderFixed="true">
  3. <view class="info-card">
  4. <!-- 标题栏 -->
  5. <view class="content-title">
  6. <view>{{ titleMap[title] }}</view>
  7. <view v-if="title == 7" class="btn crm-cursor" @click="backIndex">
  8. <uni-icons type="arrowleft" size="20" color="#666"></uni-icons>
  9. <text>{{ t('Custom.Settings.Title') }}</text>
  10. </view>
  11. </view>
  12. <!-- 内容区域 - 图文类型 -->
  13. <view v-if="[1, 2, 3, 5].includes(title)" class="content crm-border-radius">
  14. <view v-if="imgContentIf" class="img">
  15. <image :src="imgContent" mode="widthFix" class="content-image" @click="previewImage" />
  16. </view>
  17. <rich-text :nodes="Content" class="rich-text"></rich-text>
  18. </view>
  19. <!-- 内容区域 - 视频类型4 -->
  20. <view v-if="title == 4" class="content crm-border-radius" style="overflow: auto;">
  21. <text class="con-title">{{ info.title }}</text>
  22. <view class="con-time" style="display: flex; justify-content: space-between;">
  23. <text>{{ info.createTime }}</text>
  24. <image src="/static/images/img/acc_logo.png" mode="aspectFit" style="height: 40px; width: auto;" />
  25. </view>
  26. <view class="my_video" style="width: 100%;">
  27. <!-- 使用 video 组件 -->
  28. <video :src="info.url" controls style="width: 100%;" :show-fullscreen-btn="true"
  29. :enable-play-gesture="true"></video>
  30. </view>
  31. <text class="con-des">{{ info.description }}</text>
  32. </view>
  33. <!-- 内容区域 - 视频类型6 -->
  34. <view v-if="title == 6" class="content crm-border-radius" style="overflow: auto;">
  35. <text class="con-title">{{ info.title }}</text>
  36. <text class="con-time">{{ info.subTitle }}</text>
  37. <view class="my_video" style="width: 100%;">
  38. <video :src="imgContent" controls style="width: 100%;" :show-fullscreen-btn="true"
  39. :enable-play-gesture="true"></video>
  40. </view>
  41. <rich-text :nodes="info.content" class="con-des"></rich-text>
  42. </view>
  43. <!-- 内容区域 - 公告类型7 -->
  44. <view v-if="title == 7" class="content crm-border-radius" style="overflow: auto;">
  45. <text class="con-title">{{ info.subject }}</text>
  46. <rich-text :nodes="info.content" class="con-des"></rich-text>
  47. </view>
  48. <!-- 内容区域 - 交易观点8 / 财经日历9 -->
  49. <view v-if="title == 8 || title == 9" class="content crm-border-radius">
  50. <view style="width: 100%; min-height: 800px;">
  51. <!-- #ifdef H5 -->
  52. <iframe width="100%" height="100%" style="min-height: 800px; border: none;" :src="imgContent" />
  53. <!-- #endif -->
  54. <!-- #ifndef H5 -->
  55. <web-view :src="imgContent"></web-view>
  56. <!-- #endif -->
  57. </view>
  58. </view>
  59. <!-- 内容区域 - 电子书10 -->
  60. <view v-if="title == 10" class="content crm-border-radius" style="overflow: auto;">
  61. <view class="ebookBox">
  62. <image :src="imgUrl + info.coverImage" mode="aspectFill" />
  63. <view>
  64. <text class="news-title">{{ info.title }}</text>
  65. <rich-text :nodes="info.content" class="con-des"></rich-text>
  66. <view class="news-status">
  67. <!-- #ifdef H5 -->
  68. <a :href="imgUrl + info.bookUrl" target="_blank">{{ t('blockchain.item12') }}</a>
  69. <!-- #endif -->
  70. <!-- #ifndef H5 -->
  71. <button @click="downloadEbook" class="download-btn">{{ t('blockchain.item12') }}</button>
  72. <!-- #endif -->
  73. </view>
  74. </view>
  75. </view>
  76. </view>
  77. <!-- 内容区域 - 视频类型11 -->
  78. <view v-if="title == 11" class="content crm-border-radius">
  79. <view style="display: flex; justify-content: flex-end; margin-bottom: 15px;">
  80. <image src="/static/images/img/acc_logo.png" mode="aspectFit" style="height: 40px; width: auto;" />
  81. </view>
  82. <view style="width: 80%; min-height: 800px; margin: auto;">
  83. <view style="position: relative; overflow: hidden; padding-bottom: 56.25%;">
  84. <!-- #ifdef H5 -->
  85. <iframe :src="videoSrc" width="100%" height="100%" frameborder="0" scrolling="auto"
  86. style="position: absolute;" allowfullscreen></iframe>
  87. <!-- #endif -->
  88. <!-- #ifndef H5 -->
  89. <web-view :src="videoSrc"></web-view>
  90. <!-- #endif -->
  91. </view>
  92. </view>
  93. </view>
  94. </view>
  95. </cwg-page-wrapper>
  96. </template>
  97. <script setup>
  98. import { ref, computed, onMounted, watch } from 'vue'
  99. import { onLoad } from '@dcloudio/uni-app'
  100. import { useI18n } from 'vue-i18n'
  101. import { newsApi } from '@/service/news';
  102. import Config from '@/config/index'
  103. const { t } = useI18n()
  104. const { Code, Host80 } = Config
  105. const titleMap = computed(() => ({
  106. 1: t('News.ViewAnalysis'),
  107. 2: t('News.NewsInformation'),
  108. 3: t('News.Announcement'),
  109. 4: t('News.VideoCommentary'),
  110. 5: t('News.NewsInformation'),
  111. 6: t('News.VideoCommentary'),
  112. 7: t('News.Notice'),
  113. 8: t('News.TradeIdeas'),
  114. 9: t('News.FinancialCalendar'),
  115. 10: t('News.Ebook'),
  116. 11: t('News.VideoCommentary')
  117. }));
  118. // 路由参数
  119. const title = ref(null)
  120. const Id = ref(null)
  121. // 数据
  122. const Content = ref('')
  123. const imgContent = ref('')
  124. const imgContentIf = ref(false)
  125. const info = ref({})
  126. const imgUrl = Host80
  127. // 视频源计算属性
  128. const videoSrc = computed(() => {
  129. const lang = uni.getStorageSync('lang') || 'en'
  130. const isChinese = ['cn', 'zhHant'].includes(lang)
  131. return isChinese
  132. ? 'https://videos.tradingcentral.cn/players/H5quTuut-iodula4l.html'
  133. : 'https://videos.tradingcentral.cn/players/SHILp3nA-iodula4l.html'
  134. })
  135. // 预览图片
  136. const previewImage = () => {
  137. if (imgContent.value) {
  138. uni.previewImage({
  139. urls: [imgContent.value],
  140. current: 0
  141. })
  142. }
  143. }
  144. // 下载电子书
  145. const downloadEbook = () => {
  146. const url = imgUrl + info.value.bookUrl
  147. // #ifdef APP-PLUS
  148. plus.runtime.openURL(url)
  149. // #endif
  150. // #ifdef MP-WEIXIN
  151. uni.downloadFile({
  152. url: url,
  153. success: (res) => {
  154. if (res.statusCode === 200) {
  155. uni.openDocument({
  156. filePath: res.tempFilePath,
  157. success: () => {
  158. uni.showToast({
  159. title: t('common.success'),
  160. icon: 'success'
  161. })
  162. }
  163. })
  164. }
  165. }
  166. })
  167. // #endif
  168. }
  169. // 获取新闻详情
  170. const getNewsSingle = async () => {
  171. uni.showLoading({ title: t('common.loading') })
  172. try {
  173. if (title.value == 1) {
  174. const res = await newsApi.newsAnalysisSingle({ id: Id.value })
  175. if (res.code == 200) {
  176. if (res.data) {
  177. imgContent.value = res.data.media
  178. Content.value = res.data.content
  179. imgContentIf.value = !!res.data.media
  180. }
  181. } else {
  182. uni.showToast({ title: res.msg, icon: 'none' })
  183. }
  184. } else if (title.value == 3) {
  185. const res = await newsApi.newsInformationSingle({ id: Id.value })
  186. if (res.code == 200) {
  187. if (res.data) {
  188. imgContent.value = Host80 + res.data.coverImage
  189. Content.value = res.data.content
  190. imgContentIf.value = !!res.data.coverImage
  191. }
  192. } else {
  193. uni.showToast({ title: res.msg, icon: 'none' })
  194. }
  195. } else if (title.value == 7) {
  196. const res = await newsApi.newsNoticeSingle({ id: Id.value })
  197. if (res.code == 200) {
  198. if (res.data) {
  199. info.value = res.data
  200. }
  201. } else {
  202. uni.showToast({ title: res.msg, icon: 'none' })
  203. }
  204. } else if (title.value == 4) {
  205. const res = await newsApi.newsWebTvSearchSingle({ id: Id.value })
  206. if (res.code == 200) {
  207. if (res.data) {
  208. info.value = res.data
  209. }
  210. } else {
  211. uni.showToast({ title: res.msg, icon: 'none' })
  212. }
  213. } else if (title.value == 5) {
  214. const res = await newsApi.newsInformationNewsletterSingle({ id: Id.value })
  215. if (res.code == 200) {
  216. if (res.data) {
  217. imgContent.value = Host80 + res.data.coverImage
  218. Content.value = res.data.content
  219. imgContentIf.value = !!res.data.coverImage
  220. }
  221. } else {
  222. uni.showToast({ title: res.msg, icon: 'none' })
  223. }
  224. } else if (title.value == 6) {
  225. const res = await newsApi.newsVideoSingle({ id: Id.value })
  226. if (res.code == 200) {
  227. if (res.data) {
  228. info.value = res.data
  229. imgContent.value = res.data.videoUrl.indexOf('http') > -1
  230. ? res.data.videoUrl
  231. : (Host80 + res.data.videoUrl)
  232. }
  233. } else {
  234. uni.showToast({ title: res.msg, icon: 'none' })
  235. }
  236. } else if (title.value == 8) {
  237. const res = await newsApi.handShakeGet({})
  238. if (res.code == 200) {
  239. imgContent.value = res.msg
  240. } else {
  241. uni.showToast({ title: res.msg, icon: 'none' })
  242. }
  243. } else if (title.value == 9) {
  244. const res = await newsApi.handFinancialCalendar({})
  245. if (res.code == 200) {
  246. imgContent.value = res.msg
  247. } else {
  248. uni.showToast({ title: res.msg, icon: 'none' })
  249. }
  250. } else if (title.value == 10) {
  251. const res = await newsApi.newsEbookSingle({ id: Id.value })
  252. if (res.code == 200) {
  253. info.value = res.data
  254. } else {
  255. uni.showToast({ title: res.msg, icon: 'none' })
  256. }
  257. }
  258. } catch (error) {
  259. console.error('加载失败:', error)
  260. uni.showToast({ title: t('common.error'), icon: 'none' })
  261. } finally {
  262. uni.hideLoading()
  263. }
  264. }
  265. // 返回
  266. const backIndex = () => {
  267. uni.navigateTo({
  268. url: '/pages/mine/notice'
  269. })
  270. }
  271. // 监听路由参数
  272. onLoad((query) => {
  273. title.value = Number(query.title)
  274. Id.value = Number(query.id)
  275. getNewsSingle()
  276. })
  277. // 监听路由变化
  278. watch([() => title.value, () => Id.value], () => {
  279. getNewsSingle()
  280. })
  281. </script>
  282. <style scoped lang="scss">
  283. .content {
  284. flex: 1;
  285. width: 100%;
  286. background-color: #fff;
  287. overflow: hidden;
  288. overflow-y: auto;
  289. text-align: left;
  290. padding: 30rpx;
  291. box-sizing: border-box;
  292. line-height: 1.8;
  293. .img {
  294. margin-bottom: 30rpx;
  295. .content-image {
  296. width: 100%;
  297. max-height: 400rpx;
  298. object-fit: contain;
  299. }
  300. }
  301. .con-title {
  302. font-size: 36rpx;
  303. font-weight: bold;
  304. margin: 20rpx 0;
  305. color: #333;
  306. }
  307. .con-time {
  308. margin-bottom: 30rpx;
  309. font-size: 28rpx;
  310. color: #999;
  311. }
  312. .con-des {
  313. margin: 30rpx 0;
  314. font-size: 28rpx;
  315. color: #666;
  316. }
  317. }
  318. .ebookBox {
  319. display: flex;
  320. flex-direction: column;
  321. align-items: center;
  322. @media (min-width: 768px) {
  323. flex-direction: row;
  324. align-items: flex-start;
  325. }
  326. image {
  327. width: 360rpx;
  328. height: 525rpx;
  329. margin-right: 50rpx;
  330. border-radius: 16rpx;
  331. object-fit: cover;
  332. }
  333. .news-title {
  334. color: #EB3F57;
  335. font-size: 36rpx;
  336. font-weight: bold;
  337. margin-bottom: 20rpx;
  338. }
  339. .news-status {
  340. margin-top: 30rpx;
  341. a,
  342. .download-btn {
  343. display: inline-block;
  344. color: #ffffff;
  345. height: 60rpx;
  346. line-height: 60rpx;
  347. background-color: #EB3F57;
  348. padding: 0 30rpx;
  349. font-weight: bold;
  350. border-radius: 8rpx;
  351. font-size: 28rpx;
  352. }
  353. }
  354. }
  355. // 富文本样式
  356. :deep(.rich-text) {
  357. font-size: 28rpx;
  358. color: #666;
  359. table {
  360. border-collapse: collapse;
  361. width: 100%;
  362. margin: 20rpx 0;
  363. }
  364. th,
  365. td {
  366. border: 1rpx solid #dcdfe6;
  367. padding: 16rpx;
  368. text-align: left;
  369. }
  370. th {
  371. background-color: #f5f7fa;
  372. }
  373. img {
  374. max-width: 100%;
  375. height: auto;
  376. }
  377. }
  378. .content-title {
  379. display: flex;
  380. justify-content: space-between;
  381. align-items: center;
  382. font-size: px2rpx(20);
  383. font-weight: 500;
  384. .content-title-btns {
  385. margin: px2rpx(8) 0;
  386. display: flex;
  387. align-items: center;
  388. justify-content: center;
  389. gap: px2rpx(12);
  390. .btn-primary {
  391. min-width: px2rpx(120);
  392. background-color: var(--color-error);
  393. color: white;
  394. padding: 0 px2rpx(12);
  395. border: none;
  396. font-size: px2rpx(14);
  397. text-align: center;
  398. cursor: pointer;
  399. display: flex;
  400. align-items: center;
  401. justify-content: center;
  402. gap: px2rpx(8);
  403. }
  404. .btn-primary:active {
  405. background-color: var(--color-navy-700);
  406. }
  407. }
  408. }
  409. </style>