feat: 2026-07-11 全量更新 - 代办集成+会议室预定+知识迭代修复+UI统一+Bug修复

== 已部署上线 (9项) ==
- 代办事项真实数据源集成 (企微审批API 8bug修复链)
- H5/坐席端 Logo样式统一+绿色背景
- 视频引导页修复 (localStorage key v2)
- 坐席端 v9 Vue版本修复 (ElMessage._context)
- 截图按钮 v10 修复 (getDisplayMedia user gesture)
- 扫码样式恢复+H5扫码登录跳转修复
- H5截图快捷键提示

== 代码完成待部署 (3项) ==
- 知识迭代3Bug修复 (#8 POST端点/#7 MERGE幂等/#6 过期检查)
- 会议室预定-小鱼易联终端 (40文件, 40/40测试通过)
- IT资产升级审批推送 (asset_service.py)

== 需求文档 (2项) ==
- 坐席端AI辅助消息框-PRD (4项新功能确认)
- 坐席端布局优化建议 v2.0 (7天计划)

== 新增文档 ==
- 日报-2026-07-11.md
- 知识迭代Bug修复报告-20260711.md
- 会议室预定-部署指南.md
- CHANGELOG.md 更新

== 测试 ==
- test_todo_integration.py: 40/40
- test_meetingroom.py: 40/40
- test_bugfix_ki_suggestions.py: 21/21
This commit is contained in:
Simon
2026-07-11 23:13:10 +08:00
parent 3d152fc8eb
commit bea288e414
928 changed files with 85169 additions and 54205 deletions
+137
View File
@@ -0,0 +1,137 @@
// =============================================================================
// 企微IT智能服务台 — 终端前端 Axios 实例与API封装
// =============================================================================
// 说明:创建 Axios 实例,封装会议室预定相关的 API 调用
// - 基础URL: ''Vite proxy 处理 /itportal 和 /api 前缀)
// - 请求拦截器:添加 Bearer Token(从 localStorage 读取)
// - 响应拦截器:统一处理 code !== 0 的业务错误
// =============================================================================
import axios from 'axios'
import type { AxiosInstance, InternalAxiosRequestConfig, AxiosResponse } from 'axios'
import type {
ApiResponse,
TerminalBinding,
RoomStatusResponse,
Booking,
BookingDetail,
BookRequest,
BookResponse,
Meetingroom,
QrcodeResponse,
ScanStatusResponse,
} from '@/types/meetingroom'
// 创建 Axios 实例
const apiClient: AxiosInstance = axios.create({
baseURL: '',
timeout: 15000,
headers: {
'Content-Type': 'application/json',
},
})
// 请求拦截器:添加 Bearer Token
apiClient.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const token = localStorage.getItem('terminal_token')
if (token) {
config.headers['Authorization'] = `Bearer ${token}`
}
return config
},
(error) => Promise.reject(error),
)
// 响应拦截器:统一处理业务错误
apiClient.interceptors.response.use(
(response: AxiosResponse<ApiResponse>) => {
const res = response.data
if (res.code !== 0) {
console.error('[API] 业务错误:', res.code, res.message)
return Promise.reject({ code: res.code, message: res.message || '请求失败' })
}
return res.data as any
},
(error) => {
console.error('[API] 网络错误:', error)
return Promise.reject({ code: -1, message: '网络异常,请稍后重试' })
},
)
// =============================================================================
// 会议室预定 API
// =============================================================================
/** 获取终端绑定关系 */
export async function getTerminalBinding(sn: string): Promise<TerminalBinding | null> {
return await apiClient.get(`/itportal/meetingroom/terminal/${sn}/binding`)
}
/** 获取会议室列表 */
export async function getMeetingroomList(
city?: string,
building?: string,
floor?: string,
): Promise<{ rooms: Meetingroom[] }> {
const params: Record<string, string> = {}
if (city) params.city = city
if (building) params.building = building
if (floor) params.floor = floor
return await apiClient.get('/itportal/meetingroom/list', { params })
}
/** 获取预定状态(指定日期) */
export async function getBookingInfo(
meetingroomId: number,
date?: string,
): Promise<{ bookings: Booking[] }> {
const params: Record<string, string> = {}
if (date) params.date = date
return await apiClient.get(`/itportal/meetingroom/${meetingroomId}/booking`, { params })
}
/** 获取当前实时状态 */
export async function getRoomStatus(meetingroomId: number): Promise<RoomStatusResponse> {
return await apiClient.get(`/itportal/meetingroom/${meetingroomId}/status`)
}
/** 预定会议室 */
export async function bookMeetingroom(data: BookRequest): Promise<BookResponse> {
return await apiClient.post('/itportal/meetingroom/book', data)
}
/** 取消预定 */
export async function cancelBooking(bookingId: string, meetingroomId: number): Promise<void> {
await apiClient.delete(`/itportal/meetingroom/booking/${bookingId}`, {
params: { meetingroom_id: meetingroomId },
})
}
/** 获取预定详情 */
export async function getBookingDetail(
bookingId: string,
meetingroomId: number,
): Promise<BookingDetail> {
return await apiClient.get(`/itportal/meetingroom/booking/${bookingId}/detail`, {
params: { meetingroom_id: meetingroomId },
})
}
// =============================================================================
// 扫码登录 API
// =============================================================================
/** 创建扫码登录二维码 */
export async function createQrcode(): Promise<QrcodeResponse> {
return await apiClient.get('/api/auth/qrcode')
}
/** 轮询扫码状态 */
export async function getScanStatus(ticket: string): Promise<ScanStatusResponse> {
return await apiClient.get('/api/auth/scan/status', {
params: { ticket },
})
}
export default apiClient