lobby.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <template>
  2. <view class="pp-lobby" :style="appSystemFontScaleStyle">
  3. <!-- 返回按钮 -->
  4. <view class="pp-lobby__back" @tap="goBack">
  5. <text class="wlIcon wlIcon-fanhui1"></text>
  6. </view>
  7. <!-- 背景图 -->
  8. <image class="pp-lobby__bg" :src="bgSrc" mode="aspectFill" />
  9. <!-- 内容层 -->
  10. <view class="pp-lobby__content">
  11. <!-- 顶部 Logo -->
  12. <view class="pp-lobby__header">
  13. <image class="pp-lobby__logo" :src="logoSrc" mode="aspectFit" />
  14. <text class="pp-lobby__app-name">{{ copy.appName }}</text>
  15. </view>
  16. <!-- 底部操作区 -->
  17. <view class="pp-lobby__actions">
  18. <!-- iOS 苹果登录主按钮 -->
  19. <!-- #ifdef APP-PLUS -->
  20. <view v-if="isIOS" class="pp-lobby__apple-btn" @tap="onAppleLogin">
  21. <image class="pp-lobby__icon" src="/static/imgs/Apple_logo.png" mode="aspectFit" />
  22. <text class="pp-lobby_text">{{ copy.appleLogin }}</text>
  23. </view>
  24. <!-- Android Google 登录主按钮 -->
  25. <view v-else class="pp-lobby__google-btn" @tap="onGoogleLogin">
  26. <image class="pp-lobby_google_icon" src="/static/imgs/Google_logo.png" mode="aspectFit" />
  27. <text class="pp-lobby_text">{{ copy.googleLogin }}</text>
  28. </view>
  29. <!-- #endif -->
  30. <!-- 其他登录方式 -->
  31. <view class="pp-lobby__others">
  32. <text class="pp-lobby__other-link" @tap="onLineLogin">{{ copy.lineLogin }}</text>
  33. <text class="pp-lobby__divider">|</text>
  34. <text class="pp-lobby__other-link" @tap="goSignin">{{ copy.accountLogin }}</text>
  35. </view>
  36. </view>
  37. </view>
  38. </view>
  39. </template>
  40. <script>
  41. import { appleLogin, googleLogin, lineLogin } from '@/features/passport/social-login'
  42. import { fetchAppBrand } from '@/features/shell/app-config-gateway'
  43. const FALLBACK_LOGO = '/static/logo.png'
  44. const DEFAULT_BG = '/static/imgs/login-bg.png'
  45. export default {
  46. components: {},
  47. data() {
  48. return {
  49. isIOS: false, // 是否为 iOS
  50. logoPath: '',
  51. appBrandName: '',
  52. bgPath: ''
  53. }
  54. },
  55. computed: {
  56. displayAppName() {
  57. const fromApi = (this.appBrandName || '').trim()
  58. if (fromApi) return fromApi
  59. return '88Live'
  60. },
  61. logoSrc() {
  62. const raw = (this.logoPath || '').trim()
  63. if (!raw) return FALLBACK_LOGO
  64. if (this.$appKit && typeof this.$appKit.oss === 'function') {
  65. return this.$appKit.oss(raw, 200, 200)
  66. }
  67. return raw
  68. },
  69. bgSrc() {
  70. const raw = (this.bgPath || '').trim()
  71. if (!raw) return DEFAULT_BG
  72. if (this.$appKit && typeof this.$appKit.oss === 'function') {
  73. return this.$appKit.oss(raw, 750, 1334)
  74. }
  75. return raw
  76. },
  77. copy() {
  78. const t = this.$t.bind(this)
  79. return {
  80. appName: this.displayAppName,
  81. appleLogin: t('passport.apple-login'),
  82. googleLogin: t('passport.google-login'),
  83. lineLogin: t('passport.line-login'),
  84. accountLogin: t('passport.account-login')
  85. }
  86. }
  87. },
  88. onLoad() {
  89. // #ifdef APP-PLUS
  90. this.isIOS = uni.getSystemInfoSync().platform === 'ios'
  91. // #endif
  92. this.loadBrand()
  93. },
  94. onBackPress() {
  95. uni.switchTab({
  96. url: '/pages/index/index',
  97. fail: () => uni.reLaunch({ url: '/pages/index/index' })
  98. })
  99. return true
  100. },
  101. methods: {
  102. async loadBrand() {
  103. try {
  104. const brand = await fetchAppBrand()
  105. this.logoPath = brand.logo || ''
  106. this.appBrandName = brand.name || ''
  107. this.bgPath = brand.login_bg || ''
  108. } catch (_) {
  109. this.logoPath = ''
  110. this.appBrandName = ''
  111. this.bgPath = ''
  112. }
  113. },
  114. async onAppleLogin() {
  115. try {
  116. // #ifdef APP-PLUS
  117. const result = await appleLogin()
  118. if (result) {
  119. this.$store.dispatch('user/login', result)
  120. this.$store.dispatch('cart/sync')
  121. const nickname = result.userinfo.nickname
  122. const toastTitle = nickname || this.$t('passport.tip-signin-ok')
  123. uni.showToast({ title: toastTitle, icon: 'success' ,duration: 2000})
  124. this.bounce()
  125. }
  126. // #endif
  127. // #ifndef APP-PLUS
  128. uni.showToast({ title: this.$t('passport.apple-not-supported'), icon: 'none' })
  129. // #endif
  130. } catch (err) {
  131. uni.showToast({ title: (err && err.message) || this.$t('passport.social-login-failed'), icon: 'none' })
  132. } finally {
  133. uni.hideLoading()
  134. }
  135. },
  136. // async onGoogleLogin() {
  137. // try {
  138. // // #ifdef APP-PLUS
  139. // const result = await googleLogin()
  140. // if (result) {
  141. // this.$store.dispatch('user/login', result)
  142. // this.$store.dispatch('cart/sync')
  143. // uni.showToast({ title: this.$t('passport.tip-signin-ok'), icon: 'success' })
  144. // this.bounce()
  145. // }
  146. // // #endif
  147. // // #ifndef APP-PLUS
  148. // uni.showToast({ title: this.$t('passport.google-not-supported'), icon: 'none' })
  149. // // #endif
  150. // } catch (err) {
  151. // uni.showToast({ title: (err && err.message) || this.$t('passport.social-login-failed'), icon: 'none' })
  152. // } finally {
  153. // }
  154. // },
  155. goBack() {
  156. uni.navigateBack({
  157. fail: () => {
  158. uni.switchTab({ url: '/pages/index/index' })
  159. }
  160. })
  161. },
  162. async onLineLogin() {
  163. try {
  164. // #ifdef APP-PLUS
  165. const result = await lineLogin()
  166. // WebView 打开后立即关闭 loading
  167. if (result) {
  168. this.$store.dispatch('user/login', result)
  169. this.$store.dispatch('cart/sync')
  170. uni.showToast({ title: this.$t('passport.tip-signin-ok'), icon: 'success' })
  171. this.bounce()
  172. }
  173. // #endif
  174. // #ifndef APP-PLUS
  175. uni.showToast({ title: this.$t('passport.line-not-supported'), icon: 'none' })
  176. // #endif
  177. } catch (err) {
  178. console.log('[LINE Login] ❌ 登录失败错误信息:', err)
  179. console.log('[LINE Login] ❌ 登录失败标题:', err.message)
  180. uni.showToast({ title: (err && err.message) || this.$t('passport.social-login-failed'), icon: 'none' })
  181. }
  182. },
  183. goSignin() {
  184. uni.navigateTo({ url: '/pages/passport/signin' })
  185. },
  186. bounce() {
  187. const fallback = '/pages/index/index'
  188. uni.switchTab({ url: fallback })
  189. }
  190. }
  191. }
  192. </script>
  193. <style lang="scss">
  194. .pp-lobby {
  195. position: relative;
  196. width: 100%;
  197. height: 100vh;
  198. overflow: hidden;
  199. }
  200. .pp-lobby__bg {
  201. position: absolute;
  202. top: 0;
  203. left: 0;
  204. width: 100%;
  205. height: 100%;
  206. z-index: 1;
  207. }
  208. .pp-lobby__content {
  209. position: relative;
  210. z-index: 2;
  211. width: 100%;
  212. height: 100%;
  213. display: flex;
  214. flex-direction: column;
  215. justify-content: space-between;
  216. padding: 120rpx 60rpx 160rpx;
  217. box-sizing: border-box;
  218. }
  219. /* 返回按钮 */
  220. .pp-lobby__back {
  221. position: absolute;
  222. top: 80rpx;
  223. left: 40rpx;
  224. z-index: 10;
  225. width: 72rpx;
  226. height: 72rpx;
  227. border-radius: 50%;
  228. background: rgba(0, 0, 0, 0.3);
  229. backdrop-filter: blur(10rpx);
  230. display: flex;
  231. align-items: center;
  232. justify-content: center;
  233. }
  234. /* 顶部 Logo 区域 */
  235. .pp-lobby__header {
  236. display: flex;
  237. flex-direction: column;
  238. align-items: center;
  239. padding-top: 80rpx;
  240. }
  241. .pp-lobby__logo {
  242. width: 160rpx;
  243. height: 160rpx;
  244. border-radius: 40rpx;
  245. }
  246. .pp-lobby__app-name {
  247. font-size: calc(48rpx * var(--app-font-scale, 1));
  248. font-weight: 800;
  249. color: #060606;
  250. margin-top: 24rpx;
  251. text-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.3);
  252. letter-spacing: 2rpx;
  253. }
  254. /* 底部操作区 */
  255. .pp-lobby__actions {
  256. display: flex;
  257. flex-direction: column;
  258. align-items: center;
  259. gap: 40rpx;
  260. }
  261. /* 苹果登录主按钮 */
  262. .pp-lobby__apple-btn {
  263. width: 100%;
  264. height: 88rpx;
  265. background: #FFFFFF;
  266. border-radius: 12rpx;
  267. display: flex;
  268. align-items: center;
  269. justify-content: center;
  270. gap: 16rpx;
  271. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  272. }
  273. .pp-lobby__icon {
  274. width: 40rpx;
  275. height: 40rpx;
  276. }
  277. .pp-lobby_google_icon {
  278. margin-right: 20rpx;
  279. width: 34rpx;
  280. height: 34rpx;
  281. }
  282. .pp-lobby_text {
  283. font-size: calc(32rpx * var(--app-font-scale, 1));
  284. font-weight: 500;
  285. color: #000000;
  286. letter-spacing: 0.5rpx;
  287. }
  288. // Google 登录按钮
  289. .pp-lobby__google-btn {
  290. width: 100%;
  291. height: 88rpx;
  292. background: #FFFFFF;
  293. border-radius: 12rpx;
  294. display: flex;
  295. align-items: center;
  296. justify-content: center;
  297. gap: 16rpx;
  298. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
  299. }
  300. /* 其他登录方式 */
  301. .pp-lobby__others {
  302. display: flex;
  303. align-items: center;
  304. justify-content: center;
  305. gap: 32rpx;
  306. }
  307. .pp-lobby__other-link {
  308. font-size: calc(28rpx * var(--app-font-scale, 1));
  309. color: rgba(255, 255, 255, 0.9);
  310. text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
  311. padding: 12rpx 24rpx;
  312. }
  313. .pp-lobby__divider {
  314. font-size: calc(30rpx * var(--app-font-scale, 1));
  315. color: rgba(255, 255, 255, 0.5);
  316. }
  317. </style>