App.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template>
  2. <router-view />
  3. <Notify v-model:show="notify.show" :title="notify.title" :content="notify.content" />
  4. <Dialog class="g-dialog-message" v-model:show="message.show" theme="round-button" confirm-button-text="关闭"
  5. @closed="onClosed">
  6. <template #title>
  7. <div class="g-dialog-message__header">
  8. <h4>{{ currentMessage?.title }}</h4>
  9. <span>{{ formatDate(currentMessage?.createtime) }}</span>
  10. </div>
  11. </template>
  12. <div class="g-dialog-message__content" v-html="currentMessage?.content"></div>
  13. <div class="g-dialog-message__footer" v-if="messageList.length > 1">
  14. <span :class="{ disabled: message.index === 0 }" @click="changeMessage(-1)">上一条</span>
  15. <span :class="{ disabled: message.index === (messageList.length - 1) }" @click="changeMessage(1)">下一条</span>
  16. </div>
  17. </Dialog>
  18. </template>
  19. <script lang="ts" setup>
  20. import { reactive, computed, onMounted, PropType, watch } from 'vue'
  21. import { Locale, Dialog } from 'vant'
  22. import { dialog } from '@/utils/vant'
  23. import { formatDate } from '@/filters'
  24. import { useLogin } from '@/business/login'
  25. import { Language } from '@/constants/language'
  26. import { useNavigation } from './router/navigation'
  27. import { i18n, useNoticeStore, useLoginStore } from '@/stores'
  28. import eventBus from '@/services/bus'
  29. import plus from '@/utils/h5plus'
  30. import Notify from '@mobile/components/base/notify/index.vue'
  31. import enUS from 'vant/es/locale/lang/en-US'
  32. import zhCN from 'vant/es/locale/lang/zh-CN'
  33. import thTH from 'vant/es/locale/lang/th-TH'
  34. import zhTW from 'vant/es/locale/lang/zh-TW'
  35. import viVN from 'vant/es/locale/lang/vi-VN'
  36. const props = defineProps({
  37. statusBarStyle: {
  38. type: String as PropType<'dark' | 'light'>,
  39. default: 'light'
  40. },
  41. // 是否弹出未读消息
  42. showUnread: {
  43. type: Boolean,
  44. default: true
  45. }
  46. })
  47. const { userLogout } = useLogin()
  48. const { backHome } = useNavigation()
  49. const loginStore = useLoginStore()
  50. const noticeStore = useNoticeStore()
  51. // 消息弹窗
  52. const message = reactive({
  53. show: false,
  54. index: 0
  55. })
  56. // 获取用户阅读状态
  57. const getUserReadStatus = () => ({
  58. key: 'read_' + loginStore.loginId,
  59. value: formatDate(new Date().toISOString(), 'YYYY-MM-DD')
  60. })
  61. // 消息列表
  62. const messageList = computed(() => {
  63. const { key, value } = getUserReadStatus()
  64. const localValue = localStorage.getItem(key)
  65. const showUnread = props.showUnread && localValue !== value // 未读消息一天内只会弹框一次
  66. return noticeStore.noticeList.filter((e) => (showUnread && !e.readed) || e.isforcedisplay)
  67. })
  68. // 当前消息
  69. const currentMessage = computed(() => messageList.value[message.index])
  70. // 切换消息
  71. const changeMessage = (value: number) => {
  72. const i = message.index + value
  73. if (i > -1 && i < messageList.value.length) {
  74. message.index = i
  75. }
  76. }
  77. // 关闭消息弹窗
  78. const onClosed = () => {
  79. messageList.value.forEach((e) => noticeStore.updateNoticeReaded(e.autoid))
  80. }
  81. // 顶部通知
  82. const notify = reactive({
  83. show: false,
  84. title: '',
  85. content: ''
  86. })
  87. // 接收风控通知
  88. eventBus.$on('RiskToWebNtf', (msg, type) => {
  89. const res = msg as { title: string, content: string }
  90. if (type === 1) {
  91. notify.title = res.title
  92. notify.content = res.content
  93. notify.show = true
  94. } else {
  95. dialog({
  96. title: res.title,
  97. message: res.content,
  98. confirmButtonText: '确定'
  99. })
  100. }
  101. })
  102. // 接收用户登出通知
  103. eventBus.$on('LogoutNotify', (msg) => {
  104. userLogout(() => {
  105. if (msg) {
  106. dialog({
  107. message: msg as string,
  108. confirmButtonText: '确定'
  109. }).then(() => {
  110. backHome()
  111. })
  112. } else {
  113. backHome()
  114. }
  115. })
  116. })
  117. // 多语言列表
  118. const languageMap = {
  119. [Language.Simplified]: zhCN,
  120. [Language.English]: enUS,
  121. [Language.Traditional]: zhTW,
  122. [Language.Thai]: thTH,
  123. [Language.Vietnamese]: viVN
  124. }
  125. // 当前语言
  126. const language = i18n.global.locale
  127. if (language in languageMap) {
  128. Locale.use(language, languageMap[language])
  129. } else {
  130. Locale.use('en-US', enUS)
  131. }
  132. watch(() => noticeStore.isInitialized, () => {
  133. const [firstMessage] = messageList.value
  134. if (firstMessage) {
  135. const { key, value } = getUserReadStatus()
  136. localStorage.setItem(key, value) // 记录用户已读状态
  137. message.index = 0
  138. message.show = true
  139. }
  140. })
  141. onMounted(() => plus.setStatusBarStyle(props.statusBarStyle))
  142. </script>