feat: 企业微信OAuth静默登录

- 新增 GET /api/wecom/oauth-url 和 /api/wecom/oauth-callback
- OAuth回调返回HTML页面直接写localStorage(避坑企微webview 307重定向不可靠)
- 菜单URL改为OAuth静默授权链接(snsapi_base + agentid)
- redirect目标编码到state参数中(避坑redirect_uri不允许自定义query)
- wecom_userid大小写不敏感匹配
- 前端路由守卫处理 ?token= 自动登录(fallback)
- Login.vue企微环境检测自动跳OAuth
- setup-menu同步更新为OAuth链接

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-30 12:33:43 +08:00
parent 4139b54a57
commit 804812dd7e
3 changed files with 128 additions and 3 deletions
+15
View File
@@ -9,6 +9,11 @@ const route = useRoute()
const auth = useAuthStore()
const loading = ref(false)
function isWecom(): boolean {
const ua = navigator.userAgent || ''
return /wxwork/i.test(ua)
}
function isMobileDevice(): boolean {
const ua = navigator.userAgent || ''
return /Android|iPhone|iPad|iPod|webOS/i.test(ua) || window.innerWidth < 768
@@ -80,6 +85,16 @@ onMounted(async () => {
return
}
// ── WeChat Work silent login: redirect to OAuth (no user interaction needed) ──
if (isWecom()) {
const targetPath = (route.query.redirect as string) || '/m'
const endpoint = import.meta.env.VITE_CASDOOR_ENDPOINT || ''
// In production, the backend builds the OAuth URL; use the API
const apiBase = window.location.origin
window.location.href = `${apiBase}/api/wecom/oauth-url?redirect=${encodeURIComponent(targetPath)}`
return
}
// ── Auto-redirect to Casdoor (no button needed) ──
loading.value = true
goCasdoorLogin()