App.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <template>
  2. <div class="app-wrap">
  3. <Transition
  4. name="fade-out"
  5. >
  6. <StartUp
  7. v-show="!store.state.haveShownStartUp"
  8. @loading-over="store.commit('recordShowStartUp')"
  9. />
  10. </Transition>
  11. <div class="top-bar">
  12. <img
  13. class="logo"
  14. src="@/assets/images/logo.png"
  15. alt=""
  16. draggable="false"
  17. >
  18. <menu class="tab-bar">
  19. <button
  20. :class="{
  21. active: $route.meta.tabIdx === 1
  22. }"
  23. @click="$router.push({
  24. name: 'HomeView'
  25. })"
  26. >
  27. 要素地图
  28. </button>
  29. <button
  30. :class="{
  31. active: $route.meta.tabIdx === 2
  32. }"
  33. >
  34. 锡善之城
  35. </button>
  36. <button
  37. :class="{
  38. active: $route.meta.tabIdx === 3
  39. }"
  40. @click="$router.push({
  41. name: 'MuseumView'
  42. })"
  43. >
  44. 慈善博物馆
  45. </button>
  46. <button
  47. :class="{
  48. active: $route.meta.tabIdx === 4
  49. }"
  50. >
  51. 慈善云学校
  52. </button>
  53. <button
  54. :class="{
  55. active: $route.meta.tabIdx === 5
  56. }"
  57. >
  58. 慈善广场
  59. </button>
  60. <button
  61. :class="{
  62. active: $route.meta.tabIdx === 6
  63. }"
  64. >
  65. 爱心林场
  66. </button>
  67. <button
  68. :class="{
  69. active: $route.meta.tabIdx === 7
  70. }"
  71. >
  72. 慈善堂
  73. </button>
  74. <button
  75. :class="{
  76. active: $route.meta.tabIdx === 8
  77. }"
  78. @click="onClickFeedBack"
  79. >
  80. 留言反馈
  81. </button>
  82. </menu>
  83. <div class="right-button-wrap">
  84. <button
  85. class="shop"
  86. :class="{
  87. active: $route.meta.tabIdx === 9
  88. }"
  89. @click="onClickShop"
  90. />
  91. <button class="user" />
  92. </div>
  93. </div>
  94. <FeedBack
  95. v-if="isShowFeedBack"
  96. @close="isShowFeedBack = false"
  97. />
  98. <div class="content-area">
  99. <router-view />
  100. </div>
  101. </div>
  102. </template>
  103. <script setup>
  104. import { ref, computed, watch, onMounted } from "vue"
  105. import { useRoute, useRouter } from "vue-router"
  106. import { useStore } from "vuex"
  107. import StartUp from '@/components/StartUp.vue'
  108. import FeedBack from "@/components/FeedBack.vue"
  109. import { ElMessageBox } from 'element-plus'
  110. import { checkLoginStatusAndProcess, getUserFromStorageIfNeed } from '@/api.js'
  111. const route = useRoute()
  112. const router = useRouter()
  113. const store = useStore()
  114. // checkLoginStatusAndProcess()
  115. getUserFromStorageIfNeed()
  116. if (store.state.loginStatus === store.getters.loginStatusEnum.notLogin && route.name !== 'LoginView') {
  117. router.push({
  118. name: 'LoginView',
  119. query: {
  120. redirect: encodeURI(route.fullPath)
  121. }
  122. })
  123. }
  124. const isShowFeedBack = ref(false)
  125. function onClickFeedBack() {
  126. if (store.state.loginStatus === store.getters.loginStatusEnum.wxUser) {
  127. isShowFeedBack.value = true
  128. } else {
  129. ElMessageBox.confirm(
  130. '需登录后才能体验',
  131. '提示',
  132. {
  133. confirmButtonText: '去登录',
  134. cancelButtonText: '取消',
  135. type: 'message',
  136. }
  137. ).then(() => {
  138. isShowFeedBack.value = true
  139. }).catch(() => {
  140. })
  141. }
  142. }
  143. function onClickShop() {
  144. if (store.state.loginStatus === store.getters.loginStatusEnum.wxUser) {
  145. router.push({
  146. name: 'ShopView'
  147. })
  148. } else {
  149. ElMessageBox.confirm(
  150. '需登录后才能体验',
  151. '提示',
  152. {
  153. confirmButtonText: '去登录',
  154. cancelButtonText: '取消',
  155. type: 'message',
  156. }
  157. ).then(() => {
  158. router.push({
  159. name: 'ShopView'
  160. })
  161. }).catch(() => {
  162. })
  163. }
  164. }
  165. </script>
  166. <style lang="less">
  167. html, body {
  168. // overscroll-behavior: none;
  169. // overflow: hidden;
  170. height: 100%;
  171. }
  172. // * {
  173. // user-select: none;
  174. // -webkit-touch-callout: none;
  175. // }
  176. #app {
  177. height: 100%;
  178. }
  179. // // 360浏览器不支持not()
  180. // input, textarea {
  181. // user-select: initial;
  182. // }
  183. // 字体
  184. @font-face {
  185. font-family: 'Source Han Sans CN';
  186. src: url('@/assets/style/SourceHanSansCN-Regular.otf');
  187. }
  188. // @font-face {
  189. // font-family: 'Source Han Serif CN-Bold';
  190. // src: url('@/assets/style/SourceHanSerifCN-Bold.otf');
  191. // }
  192. // i {
  193. // font-style: italic;
  194. // }
  195. // 滚动条,只设置某一项可能导致不生效。
  196. &::-webkit-scrollbar { background: transparent; width: 6px; height: 0; }
  197. &::-webkit-scrollbar-thumb { background: #589498; opacity: 0.5; border-radius: 3px;}
  198. // vue组件过渡效果
  199. .fade-out-leave-active {
  200. transition: opacity 1s;
  201. pointer-events: none;
  202. }
  203. .fade-out-leave-to {
  204. opacity: 0;
  205. }
  206. // vue组件过渡效果
  207. .fade-in-enter-active {
  208. transition: opacity 1s;
  209. }
  210. .fade-in-enter-from {
  211. opacity: 0;
  212. }
  213. .fade-in-out-enter-active {
  214. transition: opacity 2s;
  215. }
  216. .fade-in-out-leave-active {
  217. transition: opacity 2s;
  218. pointer-events: none;
  219. }
  220. .fade-in-out-enter-from {
  221. opacity: 0;
  222. }
  223. .fade-in-out-leave-to {
  224. opacity: 0;
  225. }
  226. // 不断渐变显隐 animation
  227. .animation-show-hide {
  228. animation: show-hide 1.8s infinite;
  229. }
  230. @keyframes show-hide {
  231. 0% {
  232. opacity: 0;
  233. }
  234. 50% {
  235. opacity: 1;
  236. }
  237. 100% {
  238. opacity: 0;
  239. }
  240. }
  241. // // vue-viewer
  242. // .viewer-container {
  243. // background-color: rgba(0, 0, 0, 80%) !important;
  244. // }
  245. // 或者
  246. // .viewer-backdrop {
  247. // background-color: rgba(0, 0, 0, 90%) !important;
  248. // }
  249. </style>
  250. <style lang="less" scoped>
  251. .app-wrap{
  252. height: 100%;
  253. display: flex;
  254. flex-direction: column;
  255. background-image: url(@/assets/images/bg.jpg);
  256. background-size: cover;
  257. background-repeat: no-repeat;
  258. background-position: center center;
  259. >.top-bar{
  260. flex: 0 0 auto;
  261. height: 89px;
  262. background: linear-gradient( 180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.3) 100%);
  263. border-bottom: 1px solid rgba(255, 255, 255, 0.5);
  264. display: flex;
  265. align-items: center;
  266. justify-content: space-around;
  267. >img.logo{
  268. flex: 0 0 auto;
  269. }
  270. >menu.tab-bar{
  271. flex: 0 0 auto;
  272. display: flex;
  273. align-items: center;
  274. gap: 55px;
  275. @media only screen and (max-width: 1500px) {
  276. gap: 20px;
  277. }
  278. @media only screen and (max-width: 1250px) {
  279. gap: 10px;
  280. }
  281. >button{
  282. font-family: Source Han Sans CN, Source Han Sans CN;
  283. font-weight: 400;
  284. font-size: 22px;
  285. color: #FFFFFF;
  286. line-height: 26px;
  287. position: relative;
  288. z-index: 0;
  289. &:hover{
  290. font-weight: bold;
  291. color: #589498;
  292. }
  293. &.active{
  294. font-weight: bold;
  295. color: #589498;
  296. perspective: 1000px;
  297. &::before{
  298. content: '';
  299. display: block;
  300. position: absolute;
  301. width: 127px;
  302. height: 8px;
  303. background: #589498;
  304. clip-path: polygon(0 0, 100% 0, 97% 100%, 3% 100%);
  305. left: 50%;
  306. top: -31px;
  307. transform: translate(-50%, 0);
  308. }
  309. &::after{
  310. content: '';
  311. display: block;
  312. position: absolute;
  313. z-index: -1;
  314. width: 100%;
  315. top: 100%;
  316. height: 12px;
  317. background: #FFE794;
  318. filter: blur(15.945178985595703px);
  319. }
  320. }
  321. }
  322. }
  323. >.right-button-wrap{
  324. flex: 0 0 auto;
  325. display: flex;
  326. align-items: center;
  327. gap: 14px;
  328. >button.shop{
  329. width: 42px;
  330. height: 42px;
  331. background-image: url(@/assets/images/icon_shop.png);
  332. background-size: cover;
  333. background-repeat: no-repeat;
  334. background-position: center center;
  335. &:hover, &.active{
  336. background-image: url(@/assets/images/icon_shop-active.png);
  337. background-size: cover;
  338. background-repeat: no-repeat;
  339. background-position: center center;
  340. }
  341. }
  342. >button.user{
  343. width: 42px;
  344. height: 42px;
  345. background-image: url(@/assets/images/icon_user.png);
  346. background-size: cover;
  347. background-repeat: no-repeat;
  348. background-position: center center;
  349. &:hover{
  350. background-image: url(@/assets/images/icon_user-active.png);
  351. background-size: cover;
  352. background-repeat: no-repeat;
  353. background-position: center center;
  354. }
  355. }
  356. }
  357. }
  358. >.content-area{
  359. flex: 1 0 1px;
  360. position: relative;
  361. }
  362. }
  363. </style>