| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- import { validateCredentials } from './validate-credentials.js'
- import { buildEncryptedLoginBody } from './login-rsa.js'
- import { get, post } from './request.js'
- import {
- getToken,
- getRefreshToken,
- isLoggedIn,
- getUser,
- clearSession,
- saveSession,
- updateStoredUser,
- forceRelogin,
- setReturnUrl,
- takeReturnUrl
- } from './auth-session.js'
- export { validateCredentials }
- export {
- getToken,
- getRefreshToken,
- isLoggedIn,
- getUser,
- clearSession,
- updateStoredUser,
- forceRelogin,
- setReturnUrl,
- takeReturnUrl
- }
- /**
- * 拉取当前用户资料并写回本地(含职位、部门)。
- * @returns {Promise<object|null>}
- */
- export async function fetchCurrentUser() {
- const token = getToken()
- if (!token) return null
- const data = await get('/web/auth/current-user', {
- Authorization: 'Bearer ' + token
- })
- if (data) {
- const prev = getUser() || {}
- const merged = Object.assign({}, prev, data)
- updateStoredUser(merged)
- return merged
- }
- return null
- }
- /**
- * 可选:清除历史 mock_ 前缀假会话,避免误判已登录。
- */
- export function clearLegacyMockSessionIfNeeded() {
- const token = getToken()
- if (typeof token === 'string' && token.indexOf('mock_') === 0) {
- clearSession()
- }
- }
- /**
- * 真实账号密码登录。
- * @param {{ username: string, password: string }} params
- */
- export async function passwordLogin({ username, password }) {
- const v = validateCredentials(username, password)
- if (!v.ok) {
- const err = new Error(v.message)
- err.code = v.code
- throw err
- }
- const body = await buildEncryptedLoginBody(
- (username || '').trim(),
- password || ''
- )
- const data = await post('/web/auth/login', body)
- if (!data || !data.token) {
- throw new Error('登录失败')
- }
- saveSession({
- token: data.token,
- refreshToken: data.refreshToken,
- userInfo: data.userInfo
- })
- // 密码登录成功后静默绑定微信(失败不影响登录)
- bindWechatQuietly()
- return data
- }
- /**
- * 微信授权登录(openid 优先;未绑定需 phoneCode)。
- */
- export async function wechatLogin({ loginCode, phoneCode }) {
- const payload = { loginCode }
- if (phoneCode) {
- payload.phoneCode = phoneCode
- }
- const data = await post('/mini/auth/wechat-login', payload)
- if (!data || !data.token) {
- throw new Error('登录失败')
- }
- saveSession({
- token: data.token,
- refreshToken: data.refreshToken,
- userInfo: data.userInfo
- })
- return data
- }
- /**
- * 网页扫码登录:标记会话已扫码(供 PC 端轮询展示「已扫码」)。
- * @param {string} sessionId 完整 sessionId 或小程序码 scene(短码)
- */
- export async function webQrScanned(sessionId) {
- return post('/mini/auth/web-qr-scanned', { sessionId })
- }
- /**
- * 网页扫码登录:授权手机号并确认(不写本地会话,仅完成 PC 端登录)。
- * @param {{ sessionId: string, loginCode: string, phoneCode: string }} params
- */
- export async function webQrConfirm({ sessionId, loginCode, phoneCode }) {
- return post('/mini/auth/web-qr-confirm', {
- sessionId,
- loginCode,
- phoneCode
- })
- }
- /**
- * 深链无 JWT 时静默换票(仅 loginCode,后端按已绑 openid 签发)。
- */
- export async function silentWechatLogin() {
- const loginRes = await new Promise((resolve, reject) => {
- uni.login({ provider: 'weixin', success: resolve, fail: reject })
- })
- const loginCode = loginRes && loginRes.code
- if (!loginCode) throw new Error('静默登录失败')
- const data = await post('/mini/auth/wechat-login', { loginCode })
- if (!data || !data.token) throw new Error('静默登录失败')
- saveSession({
- token: data.token,
- refreshToken: data.refreshToken,
- userInfo: data.userInfo
- })
- return data
- }
- /**
- * 已登录态下用 wx.login code 绑定 openid;失败静默。
- */
- export async function bindWechatQuietly() {
- try {
- const loginRes = await new Promise((resolve, reject) => {
- uni.login({ provider: 'weixin', success: resolve, fail: reject })
- })
- const loginCode = loginRes && loginRes.code
- if (!loginCode) return
- const token = getToken()
- if (!token) return
- await post(
- '/mini/auth/wechat-bind',
- { loginCode },
- { Authorization: 'Bearer ' + token }
- )
- } catch (e) {
- console.warn('wechat bind skipped', e && e.message)
- }
- }
- /**
- * 查询当前用户是否已绑定服务号(用于微信审批通知)。
- * @returns {Promise<{ bound: boolean }>}
- */
- export async function fetchMpBindStatus() {
- const token = getToken()
- if (!token) return { bound: false }
- const data = await get('/mini/auth/mp-bind-status', {
- Authorization: 'Bearer ' + token
- })
- return { bound: !!(data && data.bound) }
- }
|