Files
wecom_it_smart_desk/frontend-portal/src/api/qrcode.ts
T
Simon c3899594d0 feat(portal): 扫码登录 + 角色自动分发 (Phase 1.3 task #16)
- 新建 frontend-portal/src/api/qrcode.ts — /api/auth_qrcode/* API 适配
- 新建 frontend-portal/src/composables/useQrcodeLogin.ts — 扫码核心逻辑
- 新建 frontend-portal/src/views/QrcodeLogin.vue — Portal 扫码登录 UI
  - 扫码成功后按角色自动跳:
    - 只有 admin    → /itadmin/
    - 只有 agent    → /itagent/
    - admin+agent   → /itportal/select(多角色)
    - 默认 user     → /itdesk/
- 改 frontend-portal/src/router/index.ts — 默认 / → /qrcode-login
  (原 PortalSelect.vue 保留作多角色 fallback)
- 新建 docs/NGINX-DOMAIN-ROUTING.md — 运维域名分发配置模板

build:  frontend-portal vue-tsc + vite build 通过
       QrcodeLogin chunk 4.82 kB
2026-06-21 01:06:47 +08:00

47 lines
1.5 KiB
TypeScript

// =============================================================================
// IT智能服务台 — Portal 扫码登录 API 适配层 (Phase 1.3, task #16)
// =============================================================================
// 说明:复用 backend/app/api/auth_qrcode.py 接口(Phase 1.1)
// Portal 是统一入口,扫码成功后根据用户角色自动跳到对应端:
// - 只有 user 角色 → /itdesk/(H5)
// - 只有 agent 角色 → /itagent/(坐席工作台)
// - 只有 admin 角色 → /itadmin/(管理后台)
// - 多角色 → /itportal/select(角色选择页)
// =============================================================================
import apiClient from './index'
import type { AxiosResponse } from 'axios'
export interface QrcodeCreateData {
ticket: string
qrcode_url: string
expires_in: number
expires_at: string
qrcode_png_base64?: string
}
export type QrcodePollStatus = 'waiting' | 'scanned' | 'confirmed' | 'expired'
export interface QrcodePollData {
status: QrcodePollStatus
employee_id?: string
name?: string
token?: string
roles?: string[]
}
/**
* 生成登录二维码
*/
export async function createQrcode(): Promise<QrcodeCreateData> {
const response: AxiosResponse = await apiClient.post('/auth_qrcode/create')
return response.data.data
}
/**
* 轮询扫码状态
*/
export async function pollQrcode(ticket: string): Promise<QrcodePollData> {
const response: AxiosResponse = await apiClient.get(`/auth_qrcode/poll/${ticket}`)
return response.data.data
}