App.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <script setup>
  2. import { ref, onMounted, nextTick, watch, onBeforeUnmount, getCurrentInstance } from 'vue';
  3. import { useI18n } from "vue-i18n";
  4. const { locale } = useI18n();
  5. import {
  6. onLoad,
  7. onShow,
  8. onLaunch
  9. } from '@dcloudio/uni-app'
  10. import {
  11. updateRoute
  12. } from "@/hooks/useRoute";
  13. import useGlobalStore from "@/stores/use-global-store";
  14. // import { useAppUpdate } from '@/hooks/useAppUpdate'
  15. // const { checkUpdate } = useAppUpdate()
  16. const globalStore = useGlobalStore()
  17. onLoad((options) => {
  18. updateRoute();
  19. // checkUpdate()
  20. })
  21. onShow((options) => {
  22. updateRoute();
  23. // checkUpdate()
  24. })
  25. // App.vue 或你的初始化文件中
  26. function initTheme() {
  27. // #ifdef H5
  28. // H5 端:使用 matchMedia 主动获取当前系统主题
  29. const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
  30. const theme = isDarkMode ? 'dark' : 'light'
  31. globalStore.setGlobalTheme(theme)
  32. // 监听变化(你的 onThemeChange 已经能工作,但可以再加一层保险)
  33. const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)')
  34. const handleChange = (e) => {
  35. const newTheme = e.matches ? 'dark' : 'light'
  36. globalStore.setGlobalTheme(newTheme)
  37. }
  38. // 兼容旧版浏览器
  39. if (darkModeQuery.addEventListener) {
  40. darkModeQuery.addEventListener('change', handleChange)
  41. } else {
  42. darkModeQuery.addListener(handleChange)
  43. }
  44. // 设置 data-bs-theme 属性到 html 标签
  45. document.documentElement.setAttribute('data-bs-theme', theme);
  46. document.documentElement.setAttribute('data-color-theme', 'blue');
  47. // 同时设置到 body 标签
  48. document.body.setAttribute('data-bs-theme', theme);
  49. document.body.setAttribute('data-color-theme', 'blue');
  50. // #endif
  51. // #ifdef APP-PLUS
  52. // App 端:使用原生 API
  53. uni.getSystemInfo({
  54. success: (res) => {
  55. let theme = res.osTheme || 'light'
  56. globalStore.setGlobalTheme(theme)
  57. }
  58. })
  59. uni.onThemeChange((res) => {
  60. globalStore.setGlobalTheme(res.theme)
  61. })
  62. // #endif
  63. }
  64. onLaunch((options) => {
  65. // updateRoute();
  66. // checkUpdate()
  67. // 调用初始化
  68. // initTheme()
  69. // 处理 signup 路径
  70. handleSignupRoute(options)
  71. })
  72. // 解析 URL 参数
  73. const parseUrlParams = () => {
  74. const params = {}
  75. // #ifdef H5
  76. // H5 端:直接从浏览器 URL 解析
  77. if (typeof window !== 'undefined' && window.location) {
  78. const href = window.location.href
  79. // 解析 hash 部分
  80. const hashIndex = href.indexOf('#')
  81. if (hashIndex !== -1) {
  82. const hash = href.substring(hashIndex + 1)
  83. // 解析路径
  84. const pathMatch = hash.match(/^\/([^/?]+)/)
  85. if (pathMatch) {
  86. params.path = pathMatch[1]
  87. }
  88. // 解析路径参数 signup/19628/RHOP4WVa/B0
  89. const pathParams = hash.match(/^\/signup\/([^/]+)\/?([^/]+)?\/?([^/]+)?/)
  90. if (pathParams) {
  91. params.path = 'signup'
  92. params.p1 = pathParams[1]
  93. params.p2 = pathParams[2]
  94. params.p3 = pathParams[3]
  95. }
  96. // 解析 query 参数
  97. const queryIndex = hash.indexOf('?')
  98. if (queryIndex !== -1) {
  99. const queryStr = hash.substring(queryIndex + 1)
  100. const pairs = queryStr.split('&')
  101. pairs.forEach(pair => {
  102. const [key, value] = pair.split('=')
  103. if (key && value) {
  104. params[key] = decodeURIComponent(value)
  105. }
  106. })
  107. }
  108. }
  109. }
  110. // #endif
  111. // #ifndef H5
  112. // App 端:从 options 参数获取
  113. if (typeof options === 'object' && options !== null) {
  114. Object.assign(params, options)
  115. }
  116. // #endif
  117. return params
  118. }
  119. // 处理 signup 和 signin 路径(仅 H5 端)
  120. const handleSignupRoute = (options) => {
  121. // #ifdef H5
  122. // 解析 URL 参数(从浏览器 URL 解析)
  123. const query = parseUrlParams()
  124. console.log('解析到的参数:', query);
  125. // 处理 signin 路径(自动登录)
  126. if (query.path === 'signin' && query.sysLoginToken) {
  127. // 跳转到登录页面并携带 token 参数
  128. const loginUrl = `/pages/login/index?sysLoginToken=${encodeURIComponent(query.sysLoginToken)}`
  129. console.log('跳转到登录页面:', loginUrl);
  130. uni.reLaunch({
  131. url: loginUrl,
  132. success: () => {
  133. console.log('跳转成功');
  134. },
  135. fail: (err) => {
  136. console.error('跳转失败:', err);
  137. }
  138. })
  139. return
  140. }
  141. // 判断是否是 signup 路径
  142. const isSignup = query.path === 'signup' || query.s || query.signup || query.activeTab === '2'
  143. if (!isSignup) return
  144. // 获取参数
  145. const id = query.id || query.agentId || query.p1 || ''
  146. const subId = query.subId || query.w || query.p2 || ''
  147. const code = query.code || query.oc || query.p3 || ''
  148. // 构建登录页面 URL
  149. let loginUrl = '/pages/login/index?activeTab=2'
  150. // 携带参数
  151. if (id) loginUrl += `&id=${id}`
  152. if (subId) loginUrl += `&subId=${subId}`
  153. if (code) loginUrl += `&code=${code}`
  154. console.log('跳转到:', loginUrl);
  155. // 跳转到注册页面
  156. uni.reLaunch({
  157. url: loginUrl,
  158. success: () => {
  159. console.log('跳转成功');
  160. },
  161. fail: (err) => {
  162. console.error('跳转失败:', err);
  163. }
  164. })
  165. // #endif
  166. }
  167. watch(locale, () => {
  168. // const currentPath = route.path;
  169. // menu.value.forEach((item, index) => {
  170. // if (item.children) {
  171. // const isActive = item.children.some(child => child.path.includes(currentPath));
  172. // menu.value[index].isOpenMenu = isActive;
  173. // if (isActive) {
  174. // nextTick(() => {
  175. // updateSubmenuHeight(index);
  176. // });
  177. // }
  178. // }
  179. // });
  180. }, { immediate: true })
  181. onMounted(() => {
  182. const sysInfo = uni.getSystemInfoSync();
  183. globalStore.setBarHeight(sysInfo.statusBarHeight || 60);
  184. // ---------- 新增 H5 端专属初始化 ----------
  185. // 仅在 H5 端执行(通过环境判断)
  186. // #ifdef H5
  187. if (typeof window !== 'undefined') {
  188. const instance = getCurrentInstance()
  189. if (instance) {
  190. window.vm = instance.proxy
  191. }
  192. }
  193. // #endif
  194. });
  195. </script>
  196. <style>
  197. /*每个页面公共css */
  198. </style>
  199. <style lang="scss">
  200. /* 注意要写在第一行,同时给style标签加入lang="scss"属性 */
  201. @import "uview-plus/index.scss";
  202. @import "@/static/scss/global/global.scss";
  203. @import "@/static/scss/global/vu.css";
  204. @import "/static/scss/style.scss";
  205. @font-face {
  206. font-family: 'Google Sans';
  207. src: url('/static/Google_Sans/GoogleSans-VariableFont_GRAD,opsz,wght.ttf') format('truetype-variations');
  208. font-weight: 100 900;
  209. font-style: normal;
  210. font-display: swap;
  211. }
  212. /* 全局字体,不破坏 uni-icons 图标 */
  213. view,
  214. text,
  215. button,
  216. input,
  217. textarea,
  218. label {
  219. font-family: 'Google Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  220. font-weight: 400;
  221. }
  222. /* 专门保护 uni-icons 不被覆盖 */
  223. .uni-icon,
  224. [class*="uni-icons-"],
  225. .uni-icons {
  226. font-family: uniicons !important;
  227. }
  228. /* 让整个项目文字都能选中 */
  229. * {
  230. -webkit-user-select: text !important;
  231. user-select: text !important;
  232. }
  233. /* 修复滚动层无法选中 */
  234. view,
  235. text,
  236. div,
  237. span {
  238. -webkit-user-select: text !important;
  239. user-select: text !important;
  240. }
  241. /* 强制修复 uni-datetime-picker 重复渲染双日历 */
  242. // .uni-calendar+.uni-calendar {
  243. // display: none !important;
  244. // }
  245. :deep(.u-toolbar__wrapper__confirm) {
  246. font-size: 20px !important;
  247. }
  248. :deep(.u-toolbar__wrapper__cancel) {
  249. font-size: 20px !important;
  250. }
  251. .page {
  252. /* padding: 31px 31px 110px 31px; */
  253. box-sizing: border-box;
  254. /* background: var(--main-bg); */
  255. }
  256. html {
  257. --bs-bg-opacity: 1;
  258. background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;
  259. font-size: 16px !important;
  260. }
  261. uni-page-body {
  262. height: 100%;
  263. }
  264. page {
  265. --bs-bg-opacity: 1;
  266. background-color: rgba(var(--bs-body-bg-rgb), var(--bs-bg-opacity)) !important;
  267. }
  268. </style>