新增页面: - ai-analyses.html: AI分析列表(Tab筛选:全部/人员安全/设备异常/环境风险) - ai-analysis.html: AI分析详情(设备信息+AI分析描述+建议措施) - reports.html: 隐患随手拍列表(Tab筛选:全部/待处理/处理中/已处理,FAB悬浮新建按钮) - report-detail.html: 隐患详情(状态时间线+认领/处理完成操作) Mock层补全: - MOCK_AI_ANALYSES (4条AI分析记录,3种类型) - getAnalysisTypeInfo() / getAIAnalysisById() 辅助函数 - apiGetAIAnalyses() / apiGetAIAnalysisDetail() / apiGetReportDetail() UI规范统一(frontend-dev skill门控): - 统一TabBar为tab-bar class,替换所有weui-tabbar - 随手拍入口统一为reports.html,report.html为新建表单 - 新页面全部实现skeleton骨架屏+空状态+loading状态 - severity/status使用RemixIcon,无emoji - pulse-dot动画用于待处理状态指示
188 lines
4.9 KiB
JavaScript
188 lines
4.9 KiB
JavaScript
// ============================
|
||
// API 基础封装 — Mock 模式
|
||
// ============================
|
||
|
||
const API_BASE = '/v1';
|
||
|
||
// 登录
|
||
function apiLogin(username, password) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
resolve({
|
||
code: 0,
|
||
data: {
|
||
token: 'mock-token-' + Date.now(),
|
||
expiresAt: new Date(Date.now() + 7 * 24 * 3600 * 1000).toISOString(),
|
||
user: MOCK_USER,
|
||
}
|
||
});
|
||
}, 500);
|
||
});
|
||
}
|
||
|
||
// 获取设备列表
|
||
function apiGetDevices(params = {}) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
let items = [...MOCK_DEVICES];
|
||
if (params.type === 'tower_crane') {
|
||
items = items.filter(d => d.type === 'tower_crane');
|
||
} else if (params.type === 'elevator') {
|
||
items = items.filter(d => d.type === 'elevator');
|
||
}
|
||
resolve({ code: 0, data: { total: items.length, items } });
|
||
}, 300);
|
||
});
|
||
}
|
||
|
||
// 获取设备实时数据
|
||
function apiGetDeviceRealtime(deviceId) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
const data = getRealtimeById(deviceId);
|
||
resolve({ code: 0, data });
|
||
}, 200);
|
||
});
|
||
}
|
||
|
||
// 获取预警列表
|
||
function apiGetAlerts(params = {}) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
let items = [...MOCK_ALERTS];
|
||
if (params.level === 'danger') {
|
||
items = items.filter(a => a.level === 'danger');
|
||
} else if (params.level === 'warning') {
|
||
items = items.filter(a => a.level === 'warning');
|
||
} else if (params.status === 'handled') {
|
||
items = items.filter(a => a.status === 'handled' || a.status === 'ignored');
|
||
} else if (params.status === 'unread') {
|
||
items = items.filter(a => a.status === 'unread');
|
||
}
|
||
const unreadCount = MOCK_ALERTS.filter(a => a.status === 'unread').length;
|
||
resolve({ code: 0, data: { total: items.length, unreadCount, items } });
|
||
}, 300);
|
||
});
|
||
}
|
||
|
||
// 获取预警详情
|
||
function apiGetAlertDetail(alertId) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
const alert = getAlertById(alertId);
|
||
resolve({ code: 0, data: alert });
|
||
}, 200);
|
||
});
|
||
}
|
||
|
||
// 处理预警
|
||
function apiHandleAlert(alertId, action, note) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
const alert = MOCK_ALERTS.find(a => a.id === alertId);
|
||
if (alert) {
|
||
alert.status = action === 'handled' ? 'handled' : 'ignored';
|
||
if (note) alert.handleNote = note;
|
||
}
|
||
resolve({ code: 0, message: '操作成功' });
|
||
}, 500);
|
||
});
|
||
}
|
||
|
||
// 提交隐患随手拍
|
||
function apiSubmitReport(formData) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
const newReport = {
|
||
id: 'rep' + Date.now(),
|
||
...formData,
|
||
createdAt: new Date().toLocaleString('zh-CN'),
|
||
};
|
||
MOCK_REPORTS.unshift(newReport);
|
||
resolve({ code: 0, data: newReport });
|
||
}, 800);
|
||
});
|
||
}
|
||
|
||
// 获取随手拍记录
|
||
function apiGetReports() {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
resolve({ code: 0, data: { total: MOCK_REPORTS.length, items: MOCK_REPORTS } });
|
||
}, 300);
|
||
});
|
||
}
|
||
|
||
// 获取随手拍详情
|
||
function apiGetReportDetail(id) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
const item = MOCK_REPORTS.find(r => r.id === id);
|
||
resolve({ code: 0, data: item });
|
||
}, 200);
|
||
});
|
||
}
|
||
|
||
// 获取施工日志列表
|
||
function apiGetLogs() {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
resolve({ code: 0, data: { total: MOCK_LOGS.length, items: MOCK_LOGS } });
|
||
}, 300);
|
||
});
|
||
}
|
||
|
||
// 提交施工日志
|
||
function apiSubmitLog(formData) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
const newLog = {
|
||
id: 'log' + Date.now(),
|
||
...formData,
|
||
createdAt: new Date().toLocaleString('zh-CN'),
|
||
};
|
||
MOCK_LOGS.unshift(newLog);
|
||
resolve({ code: 0, data: newLog });
|
||
}, 800);
|
||
});
|
||
}
|
||
|
||
// OSS 预签名 URL(Mock)
|
||
function apiGetUploadToken(filename, contentType) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
resolve({
|
||
code: 0,
|
||
data: {
|
||
uploadUrl: 'https://jesxion-ai-studio.oss-cn-beijing.aliyuncs.com/mock/' + filename,
|
||
objectKey: 'mock/' + filename,
|
||
expiresAt: new Date(Date.now() + 3600 * 1000).toISOString(),
|
||
}
|
||
});
|
||
}, 300);
|
||
});
|
||
}
|
||
|
||
// 获取 AI 分析列表
|
||
function apiGetAIAnalyses(params = {}) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
let items = [...MOCK_AI_ANALYSES];
|
||
if (params.type && params.type !== 'all') {
|
||
items = items.filter(a => a.analysisType === params.type);
|
||
}
|
||
resolve({ code: 0, data: { total: items.length, items } });
|
||
}, 300);
|
||
});
|
||
}
|
||
|
||
// 获取 AI 分析详情
|
||
function apiGetAIAnalysisDetail(id) {
|
||
return new Promise((resolve) => {
|
||
setTimeout(() => {
|
||
const item = MOCK_AI_ANALYSES.find(a => a.id === id);
|
||
resolve({ code: 0, data: item });
|
||
}, 200);
|
||
});
|
||
}
|