App.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  1. <template>
  2. <div
  3. v-loading="pageLoading"
  4. :class="{
  5. 'app-wrap': showWrap
  6. }"
  7. >
  8. <template v-if="showWrap && route.query.hideTopBar !== '1'">
  9. <div
  10. v-show="isShowTopBar"
  11. class="top-bar"
  12. >
  13. <img
  14. class="logo"
  15. src="@/assets/images/logo.png"
  16. alt=""
  17. draggable="false"
  18. @click="router.push({name: 'Banner'})"
  19. >
  20. <menu
  21. class="tab-bar"
  22. >
  23. <button
  24. :class="{
  25. active: $route.meta.tabIdx === 0
  26. }"
  27. @click="$router.push({
  28. name: 'AboutView'
  29. })"
  30. >
  31. 关于博物馆
  32. </button>
  33. <button
  34. :class="{
  35. active: $route.meta.tabIdx === 1
  36. }"
  37. @click="$router.push({
  38. name: 'HomeView'
  39. })"
  40. >
  41. 慈善地图
  42. </button>
  43. <button
  44. :class="{
  45. active: $route.meta.tabIdx === 2
  46. }"
  47. @click="$router.push({
  48. name: 'CityOfXishan'
  49. })"
  50. >
  51. 锡善云城
  52. </button>
  53. <button
  54. :class="{
  55. active: $route.meta.tabIdx === 3
  56. }"
  57. @click="$router.push({
  58. name: 'MuseumView'
  59. })"
  60. >
  61. 慈善博物馆
  62. </button>
  63. <!-- <button
  64. :class="{
  65. active: $route.meta.tabIdx === 4
  66. }"
  67. @click="$router.push({
  68. name: 'CloudSchool'
  69. })"
  70. >
  71. 慈善云学校
  72. </button>
  73. <button
  74. :class="{
  75. active: $route.meta.tabIdx === 5
  76. }"
  77. @click="$router.push({
  78. name: 'SquareView'
  79. })"
  80. >
  81. 慈善广场
  82. </button>
  83. <button
  84. :class="{
  85. active: $route.meta.tabIdx === 6
  86. }"
  87. @click="onClickLoveForest"
  88. >
  89. 爱心林场
  90. </button>
  91. <button
  92. :class="{
  93. active: $route.meta.tabIdx === 7
  94. }"
  95. @click=" router.push({
  96. name: 'CharityHall'
  97. })"
  98. >
  99. 慈善堂
  100. </button> -->
  101. <button
  102. :class="{
  103. active: $route.meta.tabIdx === 8
  104. }"
  105. @click="onClickFeedBack"
  106. >
  107. 留言反馈
  108. </button>
  109. </menu>
  110. <div class="right-button-wrap">
  111. <button
  112. class="shop"
  113. :class="{
  114. active: $route.meta.tabIdx === 9
  115. }"
  116. @click="onClickShop"
  117. />
  118. <button
  119. class="hide-top-bar"
  120. @click="isShowTopBar = false"
  121. />
  122. </div>
  123. </div>
  124. <button
  125. v-show="!isShowTopBar"
  126. class="show-top-bar"
  127. @click="isShowTopBar = true"
  128. />
  129. </template>
  130. <FeedBack
  131. v-if="isShowFeedBack"
  132. @close="isShowFeedBack = false"
  133. />
  134. <div class="content-area">
  135. <router-view />
  136. </div>
  137. </div>
  138. </template>
  139. <script setup>
  140. import { computed, ref, watch } from "vue"
  141. import { useRoute, useRouter } from "vue-router"
  142. import { useStore } from "vuex"
  143. import { ElMessage } from 'element-plus'
  144. import FeedBack from "@/components/FeedBack.vue"
  145. import {
  146. // checkLoginStatusAndProcess,
  147. getUserFromStorageIfNeed,
  148. getShopContact
  149. } from '@/api.js'
  150. import { app } from './main'
  151. let init = false
  152. const route = useRoute()
  153. const router = useRouter()
  154. const store = useStore()
  155. const isDev = process.env.VUE_APP_CLI_MODE === 'dev'
  156. const showWrap = computed(() => route.name && route.name !== 'Banner')
  157. watch(route, () => {
  158. if (!init) {
  159. const cache = Number(localStorage.getItem('$isTablet'))
  160. const isTablet = cache === 1 || route.query.device === 'tablet'
  161. app.provide('$isTablet', isTablet)
  162. if (isTablet) {
  163. localStorage.setItem('$isTablet', 1)
  164. }
  165. init = true
  166. }
  167. })
  168. store.commit('getPageVisitRecordFromStorage')
  169. // checkLoginStatusAndProcess()
  170. getUserFromStorageIfNeed()
  171. const isShowTopBar = ref(true)
  172. const isShowFeedBack = ref(false)
  173. function onClickFeedBack() {
  174. if (process.env.VUE_APP_CLI_MODE === 'dev' || store.state.loginStatus === store.getters.loginStatusEnum.wxUser) {
  175. isShowFeedBack.value = true
  176. } else {
  177. location.href = `https://open.weixin.qq.com/connect/qrconnect?appid=wx3d4f2e0cfc3b8e54&redirect_uri=https%3A%2F%2Fsit-wuxicishan.4dage.com%2F%23%2Flogin-temp&response_type=code&scope=snsapi_login&state=${encodeURIComponent(route.name)}#wechat_redirect`
  178. }
  179. }
  180. const pageLoading = ref(false)
  181. async function onClickShop() {
  182. try {
  183. pageLoading.value = true
  184. const data = await getShopContact()
  185. if (data.display === 0) {
  186. ElMessage({
  187. message: '商城暂未开启,敬请期待',
  188. type: 'warning',
  189. })
  190. return
  191. }
  192. if (isDev || store.state.loginStatus === store.getters.loginStatusEnum.wxUser) {
  193. router.push({
  194. name: 'ShopView'
  195. })
  196. } else {
  197. location.href = `https://open.weixin.qq.com/connect/qrconnect?appid=wx3d4f2e0cfc3b8e54&redirect_uri=https%3A%2F%2Fsit-wuxicishan.4dage.com%2F%23%2Flogin-temp&response_type=code&scope=snsapi_login&state=${encodeURIComponent('ShopView')}#wechat_redirect`
  198. }
  199. } finally {
  200. pageLoading.value = false
  201. }
  202. }
  203. </script>
  204. <style lang="less">
  205. html, body {
  206. // overscroll-behavior: none;
  207. // overflow: hidden;
  208. height: 100%;
  209. }
  210. // * {
  211. // user-select: none;
  212. // -webkit-touch-callout: none;
  213. // }
  214. #app {
  215. height: 100%;
  216. }
  217. // // 360浏览器不支持not()
  218. // input, textarea {
  219. // user-select: initial;
  220. // }
  221. // 字体
  222. @font-face {
  223. font-family: 'Source Han Sans CN';
  224. src: url('@/assets/style/SOURCEHANSANSCN-LIGHT.OTF');
  225. // src: url('@/assets/style/SourceHanSansCN-Regular.otf');
  226. }
  227. @font-face {
  228. font-family: 'Source Han Sans CN-Bold';
  229. src: url('@/assets/style/SourceHanSansSCBold.otf');
  230. }
  231. @font-face{
  232. font-family: 'Source Han Serif CN';
  233. src: url('@/assets/style/SourceHanSerifCN-Regular.otf');
  234. }
  235. // i {
  236. // font-style: italic;
  237. // }
  238. @font-face{
  239. font-family: 'Alibaba PuHuiTi-Bold';
  240. src: url('@/assets/style/ALIBABA-PUHUITI-MEDIUM.OTF');
  241. }
  242. // 滚动条,只设置某一项可能导致不生效。
  243. &::-webkit-scrollbar { background: transparent; width: 6px; height: 0; }
  244. &::-webkit-scrollbar-thumb { background: #589498; opacity: 0.5; border-radius: 3px;}
  245. // vue组件过渡效果
  246. .fade-out-leave-active {
  247. transition: opacity 1s;
  248. pointer-events: none;
  249. }
  250. .fade-out-leave-to {
  251. opacity: 0;
  252. }
  253. // vue组件过渡效果
  254. .fade-in-enter-active {
  255. transition: opacity 1s;
  256. }
  257. .fade-in-enter-from {
  258. opacity: 0;
  259. }
  260. .fade-in-out-enter-active {
  261. transition: opacity 2s;
  262. }
  263. .fade-in-out-leave-active {
  264. transition: opacity 2s;
  265. pointer-events: none;
  266. }
  267. .fade-in-out-enter-from {
  268. opacity: 0;
  269. }
  270. .fade-in-out-leave-to {
  271. opacity: 0;
  272. }
  273. // 不断渐变显隐 animation
  274. .animation-show-hide {
  275. animation: show-hide 1.8s infinite;
  276. }
  277. @keyframes show-hide {
  278. 0% {
  279. opacity: 0;
  280. }
  281. 50% {
  282. opacity: 1;
  283. }
  284. 100% {
  285. opacity: 0;
  286. }
  287. }
  288. // // vue-viewer
  289. // .viewer-container {
  290. // background-color: rgba(0, 0, 0, 80%) !important;
  291. // }
  292. // 或者
  293. // .viewer-backdrop {
  294. // background-color: rgba(0, 0, 0, 90%) !important;
  295. // }
  296. </style>
  297. <style lang="less" scoped>
  298. .app-wrap{
  299. height: 100%;
  300. display: flex;
  301. flex-direction: column;
  302. background-image: url(@/assets/images/bg.jpg);
  303. background-size: cover;
  304. background-repeat: no-repeat;
  305. background-position: center center;
  306. font-size: 14px;
  307. >.top-bar{
  308. flex: 0 0 auto;
  309. height: 89px;
  310. background: linear-gradient( 180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0) 50%, rgba(255,255,255,0.3) 100%);
  311. border-bottom: 1px solid rgba(255, 255, 255, 0.5);
  312. display: flex;
  313. align-items: center;
  314. justify-content: space-around;
  315. >img.logo{
  316. flex: 0 0 auto;
  317. width: 131px;
  318. cursor: pointer;
  319. }
  320. >menu.tab-bar{
  321. flex: 0 0 auto;
  322. display: flex;
  323. align-items: center;
  324. gap: 55px;
  325. @media only screen and (max-width: 1500px) {
  326. gap: 20px;
  327. }
  328. @media only screen and (max-width: 1250px) {
  329. gap: 10px;
  330. }
  331. >button{
  332. font-family: Source Han Sans CN, Source Han Sans CN;
  333. font-weight: 400;
  334. font-size: 22px;
  335. color: #FFFFFF;
  336. line-height: 26px;
  337. position: relative;
  338. z-index: 0;
  339. &:hover{
  340. font-weight: bold;
  341. color: #589498;
  342. }
  343. &.active{
  344. font-weight: bold;
  345. color: #589498;
  346. perspective: 1000px;
  347. &::before{
  348. content: '';
  349. display: block;
  350. position: absolute;
  351. width: 127px;
  352. height: 8px;
  353. background: #589498;
  354. clip-path: polygon(0 0, 100% 0, 97% 100%, 3% 100%);
  355. left: 50%;
  356. top: -31px;
  357. transform: translate(-50%, 0);
  358. }
  359. &::after{
  360. content: '';
  361. display: block;
  362. position: absolute;
  363. z-index: -1;
  364. width: 100%;
  365. top: 100%;
  366. height: 12px;
  367. background: #FFE794;
  368. filter: blur(15.945178985595703px);
  369. }
  370. }
  371. }
  372. }
  373. >.right-button-wrap{
  374. flex: 0 0 auto;
  375. display: flex;
  376. align-items: center;
  377. gap: 14px;
  378. >button.shop{
  379. width: 42px;
  380. height: 42px;
  381. background-image: url(@/assets/images/icon_shop.png);
  382. background-size: cover;
  383. background-repeat: no-repeat;
  384. background-position: center center;
  385. &.active{
  386. background-image: url(@/assets/images/icon_shop-active.png);
  387. background-size: cover;
  388. background-repeat: no-repeat;
  389. background-position: center center;
  390. }
  391. }
  392. >button.hide-top-bar{
  393. width: 42px;
  394. height: 42px;
  395. background-image: url(@/assets/images/button-hide-top-bar.png);
  396. background-size: cover;
  397. background-repeat: no-repeat;
  398. background-position: center center;
  399. }
  400. }
  401. }
  402. >button.show-top-bar{
  403. position: fixed;
  404. top: 0px;
  405. right: 10px;
  406. width: 60px;
  407. height: 60px;
  408. background-image: url(@/assets/images/button-show-top-bar.png);
  409. background-size: cover;
  410. background-repeat: no-repeat;
  411. background-position: center center;
  412. z-index: 2;
  413. }
  414. >.content-area{
  415. flex: 1 0 1px;
  416. position: relative;
  417. z-index: 1;
  418. }
  419. }
  420. </style>