mirror of
https://gitee.com/bootx/dax-pay-h5
synced 2026-08-07 21:55:48 +08:00
feat(h5): 新增微信认证落地页(跨端,支持 PC 微信访问)
This commit is contained in:
@@ -84,6 +84,15 @@ const routeModuleList: Array<RouteRecordRaw> = [
|
||||
title: '支付宝认证',
|
||||
},
|
||||
},
|
||||
// 微信认证落地页(跨端:与 PC 端同 path 各指各 view,微信公众号 OAuth 重定向回调取 code)
|
||||
{
|
||||
path: RoutePath.AUTH_WECHAT,
|
||||
name: 'WechatAuth',
|
||||
component: () => import('@/mobile/views/auth/wechat/index.vue'),
|
||||
meta: {
|
||||
title: '微信认证',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export default routeModuleList
|
||||
|
||||
293
src/mobile/views/auth/wechat/index.vue
Normal file
293
src/mobile/views/auth/wechat/index.vue
Normal file
@@ -0,0 +1,293 @@
|
||||
<script lang="ts" setup>
|
||||
import type { AuthResult } from '@/shared/api/channel-auth'
|
||||
import { showFailToast, showSuccessToast } from 'vant'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { authAndGet } from '@/shared/api/channel-auth'
|
||||
|
||||
defineOptions({ name: 'WechatAuthPage' })
|
||||
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
|
||||
// 微信 OAuth 重定向回调: path 携带 authToken, query 携带 code
|
||||
const authToken = route.params.authToken as string
|
||||
const code = route.query.code as string | undefined
|
||||
|
||||
const loading = ref(true)
|
||||
const authResult = ref<AuthResult>({})
|
||||
const failed = ref(false)
|
||||
const failMsg = ref('')
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
/**
|
||||
* 标记失败状态
|
||||
*/
|
||||
function markFailed(msg: string) {
|
||||
failed.value = true
|
||||
failMsg.value = msg
|
||||
loading.value = false
|
||||
showFailToast(msg)
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面初始化: 取回调 code + authToken 换取 openId 后回写后端
|
||||
*/
|
||||
function init() {
|
||||
if (!authToken || !code) {
|
||||
markFailed(t('auth.wechat.codeMissing'))
|
||||
return
|
||||
}
|
||||
authAndGet({
|
||||
authType: 'wechat',
|
||||
authCode: code,
|
||||
authToken,
|
||||
})
|
||||
.then((data) => {
|
||||
authResult.value = data ?? {}
|
||||
loading.value = false
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
markFailed(err?.message || t('auth.wechat.authFail'))
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制用户标识
|
||||
*/
|
||||
async function handleCopy() {
|
||||
const value = authResult.value.openId
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await navigator.clipboard.writeText(value)
|
||||
showSuccessToast(t('auth.wechat.copySuccess'))
|
||||
}
|
||||
catch {
|
||||
showFailToast(t('auth.wechat.copyFail'))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回上一页(微信内嵌浏览器无直接关闭 API, 用历史回退兜底)
|
||||
*/
|
||||
function handleBack() {
|
||||
if (window.history.length > 1) {
|
||||
window.history.back()
|
||||
}
|
||||
else {
|
||||
window.close()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="auth-container">
|
||||
<!-- 加载中 -->
|
||||
<div v-if="loading" class="loading-box">
|
||||
<div class="logo-wrapper">
|
||||
<div class="channel-logo">
|
||||
微
|
||||
</div>
|
||||
</div>
|
||||
<van-loading vertical color="#07c160" size="32px">
|
||||
<span class="loading-text">{{ t('auth.wechat.loading') }}</span>
|
||||
</van-loading>
|
||||
<div class="footer-tip">
|
||||
<van-icon name="shield-o" />
|
||||
<span>{{ t('auth.wechat.secureTip') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 失败 -->
|
||||
<div v-else-if="failed" class="result-box">
|
||||
<div class="status-icon">
|
||||
<van-icon name="close" color="#ee0a24" size="64px" />
|
||||
</div>
|
||||
<h3 class="result-title">
|
||||
{{ t('auth.wechat.failTitle') }}
|
||||
</h3>
|
||||
<p class="fail-msg">
|
||||
{{ failMsg }}
|
||||
</p>
|
||||
<div class="action-buttons">
|
||||
<van-button plain round block class="close-btn" @click="handleBack">
|
||||
{{ t('auth.wechat.close') }}
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 成功结果 -->
|
||||
<div v-else class="result-box">
|
||||
<div class="status-icon">
|
||||
<van-icon name="checked" color="#07c160" size="64px" />
|
||||
</div>
|
||||
<h3 class="result-title">
|
||||
{{ t('auth.wechat.successTitle') }}
|
||||
</h3>
|
||||
<div class="info-card">
|
||||
<div class="info-item">
|
||||
<span class="label">{{ t('auth.wechat.openId') }}</span>
|
||||
<div class="value-box" @click="handleCopy">
|
||||
<span class="value">{{ authResult.openId }}</span>
|
||||
<van-icon name="records" class="copy-icon" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-buttons">
|
||||
<van-button type="primary" color="#07c160" round block @click="handleCopy">
|
||||
{{ t('auth.wechat.copy') }}
|
||||
</van-button>
|
||||
<van-button plain round block class="close-btn" @click="handleBack">
|
||||
{{ t('auth.wechat.close') }}
|
||||
</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
.auth-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
padding: 20px;
|
||||
background-color: #f5f5f5;
|
||||
|
||||
.loading-box,
|
||||
.result-box {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
max-width: 340px;
|
||||
padding: 40px 24px;
|
||||
background: #fff;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 4px 12px rgb(0 0 0 / 5%);
|
||||
}
|
||||
|
||||
.loading-box {
|
||||
.logo-wrapper {
|
||||
margin-bottom: 24px;
|
||||
|
||||
.channel-logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #07c160, #5fd39a);
|
||||
border-radius: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
margin-top: 12px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.footer-tip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 32px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
|
||||
.van-icon {
|
||||
margin-right: 4px;
|
||||
font-size: 14px;
|
||||
color: #07c160;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.result-box {
|
||||
.status-icon {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.result-title {
|
||||
margin: 0 0 24px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.fail-msg {
|
||||
margin: 0 0 24px;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
margin-bottom: 32px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 12px;
|
||||
|
||||
.info-item {
|
||||
.label {
|
||||
display: block;
|
||||
margin-bottom: 8px;
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.value-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 12px;
|
||||
cursor: pointer;
|
||||
background: #fff;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8px;
|
||||
|
||||
&:active {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.value {
|
||||
margin-right: 8px;
|
||||
font-family: monospace;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.copy-icon {
|
||||
flex-shrink: 0;
|
||||
font-size: 16px;
|
||||
color: #07c160;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
width: 100%;
|
||||
|
||||
.close-btn {
|
||||
margin-top: 12px;
|
||||
color: #666;
|
||||
border-color: #eee;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -40,6 +40,13 @@ const routes: RouteRecordRaw[] = [
|
||||
component: () => import('@/pc/views/protocol/Index.vue'),
|
||||
meta: { title: '协议' },
|
||||
},
|
||||
// 微信认证落地页(跨端:与移动端同 path 各指各 view,PC 微信内置浏览器可访问)
|
||||
{
|
||||
path: RoutePath.AUTH_WECHAT,
|
||||
name: 'PcWechatAuth',
|
||||
component: () => import('@/pc/views/auth/wechat/Index.vue'),
|
||||
meta: { title: '微信认证' },
|
||||
},
|
||||
...mobileOnlyStubs,
|
||||
// 兜底:移动端专属路径(如 /home/index)或任何未匹配路径,渲染 PC 404 页
|
||||
// 用 component 而非 redirect——vue-router 5 下 catch-all + redirect 在初始导航不触发
|
||||
|
||||
384
src/pc/views/auth/wechat/Index.vue
Normal file
384
src/pc/views/auth/wechat/Index.vue
Normal file
@@ -0,0 +1,384 @@
|
||||
<script lang="ts" setup>
|
||||
import type { AuthResult } from '@/shared/api/channel-auth'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useRoute } from 'vue-router'
|
||||
import { authAndGet } from '@/shared/api/channel-auth'
|
||||
|
||||
defineOptions({ name: 'PcWechatAuth' })
|
||||
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
|
||||
// 微信 OAuth 重定向回调: path 携带 authToken, query 携带 code
|
||||
const authToken = route.params.authToken as string
|
||||
const code = route.query.code as string | undefined
|
||||
|
||||
const loading = ref(true)
|
||||
const authResult = ref<AuthResult>({})
|
||||
const failed = ref(false)
|
||||
const failMsg = ref('')
|
||||
|
||||
// 复制提示浮层(PC 端无 vant,用 auto-hide 轻量 toast 代替)
|
||||
const toastVisible = ref(false)
|
||||
const toastMsg = ref('')
|
||||
let toastTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (toastTimer) {
|
||||
clearTimeout(toastTimer)
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* 显示轻量提示(2 秒后自动隐藏)
|
||||
*/
|
||||
function showToast(msg: string) {
|
||||
toastMsg.value = msg
|
||||
toastVisible.value = true
|
||||
if (toastTimer) {
|
||||
clearTimeout(toastTimer)
|
||||
}
|
||||
toastTimer = setTimeout(() => {
|
||||
toastVisible.value = false
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记失败状态
|
||||
*/
|
||||
function markFailed(msg: string) {
|
||||
failed.value = true
|
||||
failMsg.value = msg
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面初始化: 取回调 code + authToken 换取 openId 后回写后端
|
||||
*/
|
||||
function init() {
|
||||
if (!authToken || !code) {
|
||||
markFailed(t('auth.wechat.codeMissing'))
|
||||
return
|
||||
}
|
||||
authAndGet({
|
||||
authType: 'wechat',
|
||||
authCode: code,
|
||||
authToken,
|
||||
})
|
||||
.then((data) => {
|
||||
authResult.value = data ?? {}
|
||||
loading.value = false
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
markFailed(err?.message || t('auth.wechat.authFail'))
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制用户标识
|
||||
*/
|
||||
async function handleCopy() {
|
||||
const value = authResult.value.openId
|
||||
if (!value) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await navigator.clipboard.writeText(value)
|
||||
showToast(t('auth.wechat.copySuccess'))
|
||||
}
|
||||
catch {
|
||||
showToast(t('auth.wechat.copyFail'))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回上一页(PC 微信内置浏览器无直接关闭 API,用历史回退兜底)
|
||||
*/
|
||||
function handleBack() {
|
||||
if (window.history.length > 1) {
|
||||
window.history.back()
|
||||
}
|
||||
else {
|
||||
window.close()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="pc-wechat-auth">
|
||||
<div class="pc-wechat-auth__box">
|
||||
<!-- 加载中 -->
|
||||
<div v-if="loading" class="pc-wechat-auth__panel">
|
||||
<div class="pc-wechat-auth__logo">
|
||||
<span>微</span>
|
||||
</div>
|
||||
<div class="pc-wechat-auth__spinner" />
|
||||
<p class="pc-wechat-auth__loading-text">
|
||||
{{ t('auth.wechat.loading') }}
|
||||
</p>
|
||||
<div class="pc-wechat-auth__secure-tip">
|
||||
<svg viewBox="0 0 1024 1024" width="14" height="14" aria-hidden="true">
|
||||
<path fill="#07c160" d="M512 64 128 224v320c0 198 154 366 384 416 230-50 384-218 384-416V224L512 64z m0 380c-70 0-128-58-128-128s58-128 128-128 128 58 128 128-58 128-128 128z" />
|
||||
</svg>
|
||||
<span>{{ t('auth.wechat.secureTip') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 失败 -->
|
||||
<div v-else-if="failed" class="pc-wechat-auth__panel">
|
||||
<svg class="pc-wechat-auth__status-icon pc-wechat-auth__status-icon--fail" viewBox="0 0 1024 1024" width="64" height="64" aria-hidden="true">
|
||||
<path fill="#ee0a24" d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64z m193.5 561.7-41.8 41.8L512 515.8 360.3 667.5l-41.8-41.8L470.2 474 318.5 322.3l41.8-41.8L512 432.2l151.7-151.7 41.8 41.8L553.8 474l151.7 151.7z" />
|
||||
</svg>
|
||||
<h3 class="pc-wechat-auth__result-title">
|
||||
{{ t('auth.wechat.failTitle') }}
|
||||
</h3>
|
||||
<p class="pc-wechat-auth__fail-msg">
|
||||
{{ failMsg }}
|
||||
</p>
|
||||
<button class="pc-wechat-auth__btn pc-wechat-auth__btn--ghost" type="button" @click="handleBack">
|
||||
{{ t('auth.wechat.close') }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 成功结果 -->
|
||||
<div v-else class="pc-wechat-auth__panel">
|
||||
<svg class="pc-wechat-auth__status-icon" viewBox="0 0 1024 1024" width="64" height="64" aria-hidden="true">
|
||||
<path fill="#07c160" d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64z m193.5 225.7L416 615.5 318.5 518l-45.3 45.3L416 706l351.8-351.8-45.3-45.3z" />
|
||||
</svg>
|
||||
<h3 class="pc-wechat-auth__result-title">
|
||||
{{ t('auth.wechat.successTitle') }}
|
||||
</h3>
|
||||
<div class="pc-wechat-auth__info-card">
|
||||
<span class="pc-wechat-auth__info-label">{{ t('auth.wechat.openId') }}</span>
|
||||
<div class="pc-wechat-auth__value-box" @click="handleCopy">
|
||||
<span class="pc-wechat-auth__value">{{ authResult.openId }}</span>
|
||||
<svg class="pc-wechat-auth__copy-icon" viewBox="0 0 1024 1024" width="16" height="16" aria-hidden="true">
|
||||
<path fill="#07c160" d="M768 128H192a64 64 0 0 0-64 64v512h64V192h576V128z m192 192v512a64 64 0 0 1-64 64H384a64 64 0 0 1-64-64V320a64 64 0 0 1 64-64h512a64 64 0 0 1 64 64z m-64 0H384v512h512V320z" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<button class="pc-wechat-auth__btn pc-wechat-auth__btn--primary" type="button" @click="handleCopy">
|
||||
{{ t('auth.wechat.copy') }}
|
||||
</button>
|
||||
<button class="pc-wechat-auth__btn pc-wechat-auth__btn--ghost" type="button" @click="handleBack">
|
||||
{{ t('auth.wechat.close') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 轻量提示浮层 -->
|
||||
<Transition name="pc-wechat-auth-toast">
|
||||
<div v-if="toastVisible" class="pc-wechat-auth__toast">
|
||||
{{ toastMsg }}
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
/* PC 端微信认证落地页:scoped 原生 px + 媒体查询,不使用 UnoCSS 的 px 原子类 */
|
||||
.pc-wechat-auth {
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 32px 16px;
|
||||
background: linear-gradient(180deg, #f5f7fa 0%, #eef1f5 100%);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__box {
|
||||
width: 100%;
|
||||
max-width: 440px;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__panel {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 48px 40px;
|
||||
background: #fff;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
/* 加载态 */
|
||||
.pc-wechat-auth__logo {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 32px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
background: linear-gradient(135deg, #07c160, #5fd39a);
|
||||
border-radius: 18px;
|
||||
margin-bottom: 28px;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__spinner {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border: 3px solid #e4f3eb;
|
||||
border-top-color: #07c160;
|
||||
border-radius: 50%;
|
||||
animation: pc-wechat-auth-spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes pc-wechat-auth-spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.pc-wechat-auth__loading-text {
|
||||
margin: 18px 0 0;
|
||||
font-size: 15px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__secure-tip {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
margin-top: 36px;
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
/* 状态图标 */
|
||||
.pc-wechat-auth__status-icon {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__result-title {
|
||||
margin: 0 0 28px;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
color: #1d2129;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__fail-msg {
|
||||
margin: 0 0 32px;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
color: #606266;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
/* 信息卡片 */
|
||||
.pc-wechat-auth__info-card {
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
margin-bottom: 36px;
|
||||
background: #f8f9fa;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__info-label {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__value-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
padding: 12px 14px;
|
||||
background: #fff;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: background 0.2s ease;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__value-box:hover {
|
||||
background: #f5f7fa;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__value {
|
||||
flex: 1;
|
||||
font-family: 'Monaco', 'Menlo', 'Consolas', monospace;
|
||||
font-size: 14px;
|
||||
color: #1d2129;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__copy-icon {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 按钮 */
|
||||
.pc-wechat-auth__btn {
|
||||
width: 100%;
|
||||
height: 46px;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
border: none;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__btn--primary {
|
||||
color: #fff;
|
||||
background: #07c160;
|
||||
box-shadow: 0 6px 16px rgba(7, 193, 96, 0.28);
|
||||
}
|
||||
|
||||
.pc-wechat-auth__btn--primary:hover {
|
||||
background: #06ad55;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 8px 20px rgba(7, 193, 96, 0.36);
|
||||
}
|
||||
|
||||
.pc-wechat-auth__btn--ghost {
|
||||
margin-top: 12px;
|
||||
color: #606266;
|
||||
background: #fff;
|
||||
border: 1px solid #ebeef5;
|
||||
}
|
||||
|
||||
.pc-wechat-auth__btn--ghost:hover {
|
||||
color: #07c160;
|
||||
border-color: #07c160;
|
||||
background: #f5fcf8;
|
||||
}
|
||||
|
||||
/* 轻量提示浮层 */
|
||||
.pc-wechat-auth__toast {
|
||||
position: fixed;
|
||||
top: 40px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
padding: 12px 24px;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
background: rgba(29, 33, 41, 0.9);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.pc-wechat-auth-toast-enter-active,
|
||||
.pc-wechat-auth-toast-leave-active {
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
|
||||
.pc-wechat-auth-toast-enter-from,
|
||||
.pc-wechat-auth-toast-leave-to {
|
||||
opacity: 0;
|
||||
transform: translate(-50%, -12px);
|
||||
}
|
||||
</style>
|
||||
@@ -13,5 +13,18 @@
|
||||
"paramMissing": "Missing auth parameters",
|
||||
"authCodeFail": "Failed to get auth code",
|
||||
"authFail": "Failed to get user id"
|
||||
},
|
||||
"wechat": {
|
||||
"loading": "Fetching authorization...",
|
||||
"secureTip": "WeChat secure auth",
|
||||
"successTitle": "Success",
|
||||
"failTitle": "Failed",
|
||||
"openId": "WeChat OpenId",
|
||||
"copy": "Copy",
|
||||
"close": "Close",
|
||||
"copySuccess": "Copied",
|
||||
"copyFail": "Copy failed",
|
||||
"codeMissing": "No auth code received, please retry",
|
||||
"authFail": "Failed to get user id"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,5 +13,18 @@
|
||||
"paramMissing": "授权参数缺失",
|
||||
"authCodeFail": "获取授权码失败",
|
||||
"authFail": "获取用户标识失败"
|
||||
},
|
||||
"wechat": {
|
||||
"loading": "正在获取授权信息...",
|
||||
"secureTip": "微信安全认证",
|
||||
"successTitle": "获取成功",
|
||||
"failTitle": "获取失败",
|
||||
"openId": "微信OpenId",
|
||||
"copy": "复制信息",
|
||||
"close": "关闭页面",
|
||||
"copySuccess": "复制成功",
|
||||
"copyFail": "复制失败",
|
||||
"codeMissing": "未获取到授权码,请重新发起认证",
|
||||
"authFail": "获取用户标识失败"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,4 +25,6 @@ export const RoutePath = {
|
||||
PROTOCOL: '/protocol/:protocolType',
|
||||
/** 支付宝认证落地页(移动独占:JSAPI 取码) */
|
||||
AUTH_ALIPAY: '/auth/alipay/:aliAppId/:queryCode',
|
||||
/** 微信认证落地页(跨端:公众号 OAuth 重定向回调,PC 微信内置浏览器也可访问) */
|
||||
AUTH_WECHAT: '/auth/wechat/:authToken',
|
||||
} as const
|
||||
|
||||
Reference in New Issue
Block a user