├── php-api/ # 改造后的PHP接口层 ├── java-ad-service/ # 若依框架微服务(广告+VIP+分账) ├── uniapp-reader/ # UniApp前端项目 │ ├── pages/ # 各端页面 │ └──
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795
  1. <template>
  2. <view class="normal-login-container">
  3. <view class="logo-content align-center justify-center flex">
  4. <image style="width: 100rpx;height: 100rpx;" :src="globalConfig.appInfo.logo" mode="widthFix">
  5. </image>
  6. <text class="title">哎呀电子小说2</text>
  7. </view>
  8. <view class="login-form-content">
  9. <!-- 用户名密码登录 -->
  10. <view class="input-item flex align-center">
  11. <view class="iconfont icon-user icon"></view>
  12. <input v-model="loginForm.username" class="input" type="text" placeholder="请输入账号" maxlength="30" />
  13. </view>
  14. <view class="input-item flex align-center">
  15. <view class="iconfont icon-password icon"></view>
  16. <input v-model="loginForm.password" type="password" class="input" placeholder="请输入密码" maxlength="20" />
  17. </view>
  18. <view class="input-item flex align-center" style="width: 60%;margin: 0px;" v-if="captchaEnabled">
  19. <view class="iconfont icon-code icon"></view>
  20. <input v-model="loginForm.code" type="number" class="input" placeholder="请输入验证码" maxlength="4" />
  21. <view class="login-code">
  22. <image :src="codeUrl" @click="getCode" class="login-code-img"></image>
  23. </view>
  24. </view>
  25. <view class="action-btn">
  26. <button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">账号登录</button>
  27. </view>
  28. <!-- 微信一键登录 -->
  29. <view class="wechat-login-section">
  30. <button class="wechat-login-btn" @click="handleWechatLogin">
  31. <image src="/static/icons/wechat.png" class="wechat-icon"></image>
  32. <text>微信一键登录</text>
  33. </button>
  34. </view>
  35. <view class="reg text-center" v-if="register">
  36. <text class="text-grey1">没有账号?</text>
  37. <text @click="handleUserRegister" class="text-blue">立即注册</text>
  38. </view>
  39. <view class="xieyi text-center">
  40. <text class="text-grey1">登录即代表同意</text>
  41. <text @click="handleUserAgrement" class="text-blue">《用户协议》</text>
  42. <text @click="handlePrivacy" class="text-blue">《隐私协议》</text>
  43. </view>
  44. <!-- 备案信息 - 只在H5环境中显示 -->
  45. <!-- #ifdef H5 -->
  46. <view class="beian-info">
  47. <view class="beian-links">
  48. <a href="https://beian.miit.gov.cn" target="_blank" class="beian-link">陕ICP备2024057340号-2</a>
  49. <!-- <a href="http://www.beian.gov.cn" target="_blank" class="beian-link">
  50. <img src="/static/icons/police-beian.png" class="police-icon" />
  51. 京公网安备 11010502034567号
  52. </a> -->
  53. </view>
  54. <view class="copyright">
  55. © 2025 哎呀电子小说 * 哎呀电子 版权所有
  56. </view>
  57. </view>
  58. <!-- #endif -->
  59. </view>
  60. <!-- 广告组件保持不变 -->
  61. <!-- <ad-interstitial adpid="1433929280" :loadnext="true" v-slot:default="{loading, error}" @load="onadload" @close="onadclose" @error="onaderror">
  62. <button :disabled="loading" :loading="loading">点击广告获取奖励</button>
  63. <view v-if="error">{{error}}</view>
  64. </ad-interstitial>
  65. <view class="ad-view">
  66. <ad adpid="1325240772" @load="onload" @close="onclose" @error="onerror"></ad>
  67. </view>
  68. <view class="ad-view">
  69. <ad adpid="1695714925" @load="onload1" @close="onclose1" @error="onerror1"></ad>
  70. </view> -->
  71. </view>
  72. </template>
  73. <script>
  74. import { getCodeImg } from '@/api/login'
  75. import { getToken, setToken, removeToken } from '@/utils/auth'
  76. export default {
  77. data() {
  78. return {
  79. codeUrl: "",
  80. captchaEnabled: true,
  81. // 用户注册开关
  82. register: true,
  83. wxCode: "", // 添加这个变量来保存微信code
  84. globalConfig: {
  85. appInfo: {
  86. logo: '/static/logo.png',
  87. agreements: []
  88. }
  89. },
  90. loginForm: {
  91. username: "",
  92. password: "",
  93. code: "",
  94. uuid: ''
  95. }
  96. }
  97. },
  98. created() {
  99. this.safeInitConfig()
  100. this.getCode()
  101. },
  102. methods: {
  103. // 安全初始化配置
  104. safeInitConfig() {
  105. try {
  106. const app = getApp()
  107. if (app && app.globalData && app.globalData.config) {
  108. this.globalConfig = app.globalData.config
  109. } else {
  110. this.globalConfig = {
  111. appInfo: {
  112. logo: '/static/logo.png',
  113. name: '恋爱圈',
  114. agreements: [
  115. { title: '隐私协议', url: 'https://www.aiyadianzi.cn/privacy' },
  116. { title: '用户协议', url: 'https://www.aiyadianzi.cn/agreement' }
  117. ]
  118. }
  119. }
  120. }
  121. } catch (error) {
  122. console.warn('获取全局配置失败:', error)
  123. this.globalConfig = {
  124. appInfo: {
  125. logo: '/static/logo.png',
  126. name: '哎呀电子',
  127. agreements: []
  128. }
  129. }
  130. }
  131. },
  132. // 广告相关方法
  133. onadload(e) { console.log('广告数据加载成功') },
  134. onadclose(e) { console.log("onadclose",e) },
  135. onaderror(e) { console.log("onaderror: ", e.detail) },
  136. onload(e) { console.log("onload") },
  137. onclose(e) { console.log("onclose: " + e.detail) },
  138. onerror(e) { console.log("onerror: " + e.detail.errCode + " message:: " + e.detail.errMsg) },
  139. onload1(e) { console.log("onload") },
  140. onclose1(e) { console.log("onclose: " + e.detail) },
  141. onerror1(e) { console.log("onerror: " + e.detail.errCode + " message:: " + e.detail.errMsg) },
  142. // 微信登录 - 修复版
  143. async handleWechatLogin() {
  144. console.log('开始微信登录流程')
  145. try {
  146. // 1. 先检查网络状态
  147. const networkState = await this.checkNetworkState()
  148. if (!networkState) {
  149. uni.showToast({
  150. title: '网络连接不可用,请检查网络',
  151. icon: 'none'
  152. })
  153. return
  154. }
  155. // 2. 先获取微信code
  156. const loginRes = await this.getWxLoginCode()
  157. console.log('微信login结果:', loginRes)
  158. if (loginRes.errMsg !== 'login:ok' || !loginRes.code) {
  159. uni.showToast({
  160. title: '获取微信登录凭证失败',
  161. icon: 'none'
  162. })
  163. return
  164. }
  165. // 保存code,用于后续请求
  166. this.wxCode = loginRes.code
  167. // 3. 显示确认授权弹窗,然后获取用户信息
  168. uni.showModal({
  169. title: '授权确认',
  170. content: '需要获取您的用户信息以完成登录',
  171. confirmText: '允许',
  172. cancelText: '拒绝',
  173. success: async (res) => {
  174. if (res.confirm) {
  175. // 用户确认授权,获取用户信息
  176. await this.getUserInfoAndLogin()
  177. } else {
  178. uni.showToast({
  179. title: '授权已取消',
  180. icon: 'none'
  181. })
  182. }
  183. }
  184. })
  185. } catch (error) {
  186. console.error('微信登录流程失败:', error)
  187. let errorMsg = '登录失败,请重试'
  188. if (error.errMsg) {
  189. errorMsg = error.errMsg
  190. } else if (error.message) {
  191. errorMsg = error.message
  192. }
  193. uni.showToast({
  194. title: errorMsg,
  195. icon: 'none',
  196. duration: 3000
  197. })
  198. }
  199. },
  200. // 获取用户信息并登录
  201. async getUserInfoAndLogin() {
  202. try {
  203. uni.showLoading({
  204. title: '获取用户信息...',
  205. mask: true
  206. })
  207. // 直接调用getUserProfile,确保在用户交互中
  208. const userProfileRes = await new Promise((resolve, reject) => {
  209. uni.getUserProfile({
  210. desc: '用于完善会员资料',
  211. success: resolve,
  212. fail: reject
  213. })
  214. })
  215. console.log('用户信息获取结果:', userProfileRes)
  216. if (userProfileRes.errMsg !== 'getUserProfile:ok') {
  217. uni.hideLoading()
  218. uni.showToast({
  219. title: '获取用户信息失败',
  220. icon: 'none'
  221. })
  222. return
  223. }
  224. const userInfo = userProfileRes.userInfo
  225. uni.hideLoading()
  226. // 调用后端登录接口
  227. await this.sendLoginRequest(this.wxCode, userInfo)
  228. } catch (error) {
  229. uni.hideLoading()
  230. console.error('获取用户信息失败:', error)
  231. let errorMsg = '获取用户信息失败'
  232. if (error.errMsg) {
  233. if (error.errMsg.includes('getUserProfile:fail')) {
  234. errorMsg = '用户拒绝授权'
  235. } else {
  236. errorMsg = error.errMsg
  237. }
  238. }
  239. uni.showToast({
  240. title: errorMsg,
  241. icon: 'none',
  242. duration: 3000
  243. })
  244. }
  245. },
  246. // 发送登录请求到后端 - 修复版
  247. async sendLoginRequest(code, userInfo) {
  248. uni.showLoading({
  249. title: '登录中...',
  250. mask: true
  251. })
  252. try {
  253. const loginData = {
  254. code: code,
  255. userInfo: {
  256. nickName: userInfo.nickName,
  257. avatarUrl: userInfo.avatarUrl,
  258. gender: userInfo.gender,
  259. country: userInfo.country,
  260. province: userInfo.province,
  261. city: userInfo.city
  262. }
  263. }
  264. console.log('发送登录数据:', loginData)
  265. // 使用配置中的baseUrl
  266. const baseUrl = this.getBaseUrl()
  267. const requestUrl = `${baseUrl}/wxLogin`
  268. console.log('请求URL:', requestUrl)
  269. const res = await new Promise((resolve, reject) => {
  270. uni.request({
  271. url: requestUrl,
  272. method: 'POST',
  273. data: loginData,
  274. header: {
  275. 'content-type': 'application/json',
  276. },
  277. success: (res) => {
  278. console.log('请求成功,状态码:', res.statusCode)
  279. console.log('响应数据:', res.data)
  280. resolve(res.data)
  281. },
  282. fail: (err) => {
  283. console.error('请求失败:', err)
  284. reject(err)
  285. }
  286. })
  287. })
  288. uni.hideLoading()
  289. console.log('后端登录响应:', res)
  290. if (res.code === 200) {
  291. // 修复:使用正确的 token 存储方式
  292. const token = res.data.token
  293. const user = res.data.user
  294. console.log('解析出的token:', token)
  295. console.log('解析出的user:', user)
  296. if (!token) {
  297. throw new Error('后端返回的token为空')
  298. }
  299. // 修复:使用 auth.js 中的方法存储 token
  300. try {
  301. // 使用 setToken 方法存储 token(key 为 'App-Token')
  302. setToken(token)
  303. // 存储用户信息到本地存储
  304. uni.setStorageSync('userInfo', user)
  305. // 验证存储是否成功
  306. const storedToken = getToken() // 使用 getToken 方法获取
  307. const storedUserInfo = uni.getStorageSync('userInfo')
  308. console.log('存储验证 - token:', storedToken ? '成功' : '失败')
  309. console.log('存储验证 - userInfo:', storedUserInfo ? '成功' : '失败')
  310. if (!storedToken) {
  311. throw new Error('token存储失败')
  312. }
  313. // 尝试更新 Vuex 状态(如果存在)
  314. if (this.$store) {
  315. try {
  316. // 使用 user.js 中的 mutation 更新状态
  317. if (this.$store._mutations && this.$store._mutations['user/SET_TOKEN']) {
  318. this.$store.commit('user/SET_TOKEN', token)
  319. }
  320. if (user && this.$store._mutations && this.$store._mutations['user/SET_NAME']) {
  321. const userName = user.nickName || user.userName
  322. this.$store.commit('user/SET_NAME', userName)
  323. }
  324. if (user && user.avatar && this.$store._mutations && this.$store._mutations['user/SET_AVATAR']) {
  325. this.$store.commit('user/SET_AVATAR', user.avatar)
  326. }
  327. } catch (error) {
  328. console.warn('Vuex状态更新失败,但不影响登录:', error)
  329. }
  330. }
  331. } catch (storageError) {
  332. console.error('存储数据失败:', storageError)
  333. throw new Error('登录状态保存失败')
  334. }
  335. // 触发全局用户信息更新事件
  336. uni.$emit('userInfoUpdate', user)
  337. uni.$emit('loginStatusUpdate', {
  338. isLoggedIn: true,
  339. userInfo: user
  340. })
  341. uni.showToast({
  342. title: '登录成功',
  343. icon: 'success'
  344. })
  345. // 立即跳转页面
  346. setTimeout(() => {
  347. this.loginSuccess()
  348. }, 500)
  349. } else {
  350. uni.showToast({
  351. title: res.msg || '登录失败,请重试',
  352. icon: 'none',
  353. duration: 3000
  354. })
  355. }
  356. } catch (error) {
  357. uni.hideLoading()
  358. console.error('登录请求失败:', error)
  359. let errorMsg = '登录失败,请重试'
  360. if (error.message) {
  361. errorMsg = error.message
  362. }
  363. uni.showToast({
  364. title: errorMsg,
  365. icon: 'none',
  366. duration: 3000
  367. })
  368. }
  369. },
  370. // 获取微信登录code
  371. getWxLoginCode() {
  372. return new Promise((resolve, reject) => {
  373. uni.login({
  374. provider: 'weixin',
  375. success: resolve,
  376. fail: reject
  377. })
  378. })
  379. },
  380. // 检查网络状态
  381. checkNetworkState() {
  382. return new Promise((resolve) => {
  383. uni.getNetworkType({
  384. success: (res) => {
  385. if (res.networkType === 'none') {
  386. resolve(false)
  387. } else {
  388. resolve(true)
  389. }
  390. },
  391. fail: () => {
  392. resolve(true) // 如果获取网络状态失败,默认继续执行
  393. }
  394. })
  395. })
  396. },
  397. // 获取基础URL - 使用你的配置
  398. getBaseUrl() {
  399. // 直接从配置中获取baseUrl
  400. try {
  401. // 方式1: 从全局配置获取
  402. const app = getApp()
  403. if (app && app.globalData && app.globalData.config && app.globalData.config.baseUrl) {
  404. return app.globalData.config.baseUrl
  405. }
  406. // 方式2: 从Vue原型获取
  407. if (this.$config && this.$config.baseUrl) {
  408. return this.$config.baseUrl
  409. }
  410. // 方式3: 使用你的配置中的默认值
  411. return 'https://love.aiyadianzi.cn/prod-api' // 使用你配置的生产环境地址
  412. } catch (error) {
  413. console.warn('获取baseUrl失败,使用默认值:', error)
  414. return 'https://love.aiyadianzi.cn/prod-api'
  415. }
  416. },
  417. // 原有方法保持不变
  418. handleUserRegister() {
  419. this.$tab.redirectTo(`/pages/register/index`)
  420. },
  421. // 隐私协议
  422. handlePrivacy() {
  423. const site = this.globalConfig.appInfo.agreements[0] || { title: '隐私协议', url: '' }
  424. this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
  425. },
  426. // 用户协议
  427. handleUserAgrement() {
  428. const site = this.globalConfig.appInfo.agreements[1] || { title: '用户协议', url: '' }
  429. this.$tab.navigateTo(`/pages/common/webview/index?title=${site.title}&url=${site.url}`)
  430. },
  431. // 获取图形验证码
  432. getCode() {
  433. getCodeImg().then(res => {
  434. this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
  435. if (this.captchaEnabled) {
  436. this.codeUrl = 'data:image/gif;base64,' + res.img
  437. this.loginForm.uuid = res.uuid
  438. }
  439. }).catch(error => {
  440. console.error('获取验证码失败:', error)
  441. // 如果API调用失败,使用默认验证码
  442. this.captchaEnabled = false
  443. })
  444. },
  445. // 登录方法 - 使用原有的若依登录逻辑
  446. async handleLogin() {
  447. if (!this.loginForm.username) {
  448. this.$modal.msgError("请输入您的账号")
  449. return
  450. }
  451. if (!this.loginForm.password) {
  452. this.$modal.msgError("请输入您的密码")
  453. return
  454. }
  455. if (this.captchaEnabled && !this.loginForm.code) {
  456. this.$modal.msgError("请输入验证码")
  457. return
  458. }
  459. this.$modal.loading("登录中,请耐心等待...")
  460. try {
  461. // 使用原有的Login action
  462. await this.$store.dispatch('Login', this.loginForm)
  463. // 获取用户信息 - 添加详细的错误处理
  464. try {
  465. await this.$store.dispatch('GetInfo')
  466. // 确保用户信息正确存储
  467. const userInfo = this.$store.state.user
  468. console.log('Vuex用户信息:', userInfo)
  469. // 手动存储用户信息到本地存储,确保一致性
  470. if (userInfo && userInfo.name) {
  471. uni.setStorageSync('userInfo', {
  472. userName: userInfo.name,
  473. nickName: userInfo.name,
  474. avatar: userInfo.avatar
  475. })
  476. }
  477. this.$modal.msgSuccess("登录成功")
  478. // 立即触发全局状态更新
  479. uni.$emit('userInfoUpdate', userInfo)
  480. uni.$emit('loginStatusUpdate', {
  481. isLoggedIn: true,
  482. userInfo: userInfo
  483. })
  484. // 登录成功处理 - 使用延时确保状态更新完成
  485. setTimeout(() => {
  486. this.loginSuccess()
  487. }, 1000)
  488. } catch (infoError) {
  489. console.error('获取用户信息失败:', infoError)
  490. // 即使获取用户信息失败,只要登录成功就继续
  491. this.$modal.msgSuccess("登录成功")
  492. setTimeout(() => {
  493. this.loginSuccess()
  494. }, 1000)
  495. }
  496. } catch (error) {
  497. this.$modal.closeLoading()
  498. console.error('登录失败:', error)
  499. let errorMsg = '登录失败'
  500. if (error.message) {
  501. errorMsg = error.message
  502. } else if (error.msg) {
  503. errorMsg = error.msg
  504. }
  505. this.$modal.msgError(errorMsg)
  506. if (this.captchaEnabled) {
  507. this.getCode()
  508. }
  509. }
  510. },
  511. // 登录成功处理 - 增强版
  512. loginSuccess() {
  513. console.log('执行登录成功跳转')
  514. // 多重验证登录状态
  515. const token = getToken()
  516. const vuexUser = this.$store.state.user
  517. const storedUserInfo = uni.getStorageSync('userInfo')
  518. console.log('跳转前状态检查:')
  519. console.log('- token:', token ? '存在' : '不存在')
  520. console.log('- vuex用户:', vuexUser)
  521. console.log('- 存储用户:', storedUserInfo)
  522. if (token) {
  523. console.log('Token存在,允许跳转')
  524. // 即使没有完整的用户信息,只要token存在就允许访问
  525. uni.switchTab({
  526. url: '/pages/user/index',
  527. success: () => {
  528. console.log('跳转个人中心成功')
  529. // 强制刷新页面数据
  530. setTimeout(() => {
  531. uni.$emit('forceRefreshUserInfo')
  532. }, 500)
  533. },
  534. fail: (err) => {
  535. console.error('跳转失败:', err)
  536. // 备用跳转方案
  537. uni.switchTab({
  538. url: '/pages/index/index'
  539. })
  540. }
  541. })
  542. } else {
  543. console.error('跳转时Token不存在')
  544. uni.showToast({
  545. title: '登录状态异常,请重新登录',
  546. icon: 'none',
  547. duration: 3000
  548. })
  549. }
  550. }
  551. }
  552. }
  553. </script>
  554. <style lang="scss">
  555. page {
  556. background-color: #ffffff;
  557. }
  558. .normal-login-container {
  559. width: 100%;
  560. min-height: 100vh;
  561. padding: 40rpx;
  562. .logo-content {
  563. width: 100%;
  564. font-size: 21px;
  565. text-align: center;
  566. padding-top: 15%;
  567. flex-direction: column;
  568. image {
  569. border-radius: 4px;
  570. }
  571. .title {
  572. margin: 10px 0;
  573. font-size: 24px;
  574. color: #e94f87;
  575. }
  576. .subtitle {
  577. font-size: 14px;
  578. color: #999;
  579. }
  580. }
  581. .login-form-content {
  582. text-align: center;
  583. margin: 20px auto;
  584. margin-top: 10%;
  585. width: 100%;
  586. .input-item {
  587. margin: 20px auto;
  588. background-color: #f5f6f7;
  589. height: 45px;
  590. border-radius: 20px;
  591. .icon {
  592. font-size: 38rpx;
  593. margin-left: 10px;
  594. color: #999;
  595. }
  596. .input {
  597. width: 100%;
  598. font-size: 14px;
  599. line-height: 20px;
  600. text-align: left;
  601. padding-left: 15px;
  602. }
  603. }
  604. .login-btn {
  605. margin-top: 40px;
  606. height: 45px;
  607. background: #e94f87 !important;
  608. color: #fff;
  609. border-radius: 25px;
  610. font-size: 16px;
  611. }
  612. .wechat-login-section {
  613. margin: 20px 0;
  614. }
  615. .wechat-login-btn {
  616. display: flex;
  617. align-items: center;
  618. justify-content: center;
  619. background: #07c160;
  620. color: #fff;
  621. border: none;
  622. border-radius: 25px;
  623. padding: 12px;
  624. font-size: 16px;
  625. width: 100%;
  626. .wechat-icon {
  627. width: 20px;
  628. height: 20px;
  629. margin-right: 10px;
  630. }
  631. }
  632. .reg {
  633. margin-top: 15px;
  634. font-size: 14px;
  635. }
  636. .xieyi {
  637. color: #333;
  638. margin-top: 20px;
  639. font-size: 12px;
  640. }
  641. .login-code {
  642. height: 38px;
  643. position: absolute;
  644. right: 10px;
  645. .login-code-img {
  646. height: 38px;
  647. width: 100px;
  648. }
  649. }
  650. /* 备案信息样式 - 只在H5环境中生效 */
  651. /* #ifdef H5 */
  652. .beian-info {
  653. margin-top: 40px;
  654. padding-top: 20px;
  655. border-top: 1px solid #f0f0f0;
  656. text-align: center;
  657. color: #999;
  658. font-size: 12px;
  659. .beian-links {
  660. display: flex;
  661. justify-content: center;
  662. align-items: center;
  663. flex-wrap: wrap;
  664. gap: 15px;
  665. margin-bottom: 8px;
  666. .beian-link {
  667. color: #999;
  668. text-decoration: none;
  669. display: flex;
  670. align-items: center;
  671. transition: color 0.3s;
  672. &:hover {
  673. color: #e94f87;
  674. }
  675. .police-icon {
  676. width: 14px;
  677. height: 14px;
  678. margin-right: 4px;
  679. }
  680. }
  681. }
  682. .copyright {
  683. color: #999;
  684. }
  685. }
  686. /* #endif */
  687. }
  688. }
  689. .ad-view {
  690. background-color: #FFFFFF;
  691. margin-bottom: 20px;
  692. }
  693. </style>