Acme Harmony UI Design System
Components / Feedback & Infrastructure

反馈、消息与系统服务

规范了以 Ajax 网络封装、TaskCenter 异步任务中心、LoadingState 载入动画、TraceIdDisplay 错误追踪诊断以及 SystemNotificationBell 实时通知铃铛为核心的基础设施服务标准。

核心库封装: wwwroot/js/lib.js 最后更新: 2026-05-28
01 / Selection Rules

反馈机制选用矩阵 (Msg)

为避免系统内无节制弹出消息打断用户流,必须严格按照操作的“影响级别”和“严重程度”选择正确的反馈通道:


反馈类型 组件与入口 适用场景与边界 交互行为与红线规则
轻量消息通知
(Toast)
Msg.Success
Msg.Info
Msg.Warning
非阻断性操作反馈。如:保存成功、自动刷新完成。 浮动在页面右上角,自动延时 2.5 秒后渐隐消失。禁止弹窗阻断,绝对禁止要求用户手动点击关闭。
强警告弹窗
(Modal Message)
Msg.Error 明确的失败报错。如:表单校验未通过、API 异常、服务器 500 级崩溃。 在屏幕正中央阻断弹出,默认不自动关闭,必须用户手动点击“确定”关闭,必须显式展示 TraceId 方便复制。
阻断式确认
(Modal Confirm)
Msg.Confirm 涉及数据物理擦除、权限回收、作废等不可逆行为的前置确认。 弹出强制确认框,提供清晰的警示描述和“确定/取消”选项。点击“确定”时强制关联 Loading 态。
02 / Network Layer

基础数据服务 (Ajax)

1. 组件定位与核心机制

Ajax 是 Acme.IBP 对 jQuery $.ajax 的深度扩展与统一拦截封装。它自动为每次 HTTP 请求注入校验 token、绑定请求源组件的 loading 遮罩;在收到响应时拦截 401(跳转登录)、403(静默报警)、及 500(拉起包含 TraceId 的强阻断报错窗)。更重要的是,它具备异步长任务静默劫持机制。

2. 异步长任务 taskNo 自动侦测

当 API 返回的数据体中包含 taskNo 时,Ajax 全局拦截器会自动侦测到该任务标识并触发抛射物物理飞向任务中心的视觉引导,调用层无需在业务页面手动编写定位与动画计算逻辑。

3. 核心 API 签名说明

API 签名 核心参数 详细功能与拦截逻辑
Ajax.Get(url, params, success, error) url: 接口路径
params / data: 参数体
success: 成功回调
error: 失败回调
标准 HTTP GET 请求。自动处理 URL 缓存随机数,返回统一数据对象。
Ajax.Post(url, data, success, error) 标准 HTTP POST 请求。自动将 payload 序列化为 application/json 并注入跨站伪造防范 Token。

4. 标准开发使用示例

// 典型使用 Ajax 服务进行数据提报
Ajax.Post('/api/personnel/document-submit', { id: 'doc_1204', status: 2 }, function (res) {
    // 成功回调拦截器 (仅在 res.statusCode === 200 / res.succeeded === true 时进入)
    Msg.Success('提报完毕', '单据已成功流转至下一节点。');
    myGrid.refresh();
}, function (err) {
    // 失败回调拦截器 (若不配置,系统将默认弹出标准报错模态窗口,并展示 TraceId)
    console.error("提交异常详情: ", err);
    Msg.Warning('流转受限', err.message || '请检查当前单据是否满足审核条件');
});
03 / Async Queue

任务中心 (TaskCenter)

1. 组件定位与异步架构

TaskCenter(任务中心)解决系统执行耗时长的 IO、大文件生成动作时出现的长白屏和网关超时超时中断问题。在后台执行导出、复杂账单核对、大数据统计时,通过将物理渲染离线化,挂接至 TaskCenter 任务中心,实现“异步排队、进度轮询、后台交付”。

2. 飞入动画 (flyToTaskCenter) API

点击操作时,调用抛射动画将交互引导至导航栏:

// 在点击导出时手动捕获事件位置,触发小飞丸射向右上角
$('#btnExportOrder').click(function(e) {
    var clickPos = { x: e.clientX, y: e.clientY };
    
    Ajax.Post('/api/orders/export-async', {}, function(res) {
        if(res.data.taskNo) {
            // 抛射小动画飞向任务中心
            TaskCenter.flyToTaskCenter(clickPos);
        }
    });
});

3. 状态转移定义表

状态名称 对应状态码 视觉标示 (UI Color) 前端对应交互约定
排队中 (Queue) 10 中灰 (#6c757d) 任务项置于任务中心头部,展示“等待分配线程”旋转文字。
执行中 (Running) 20 主题绿 (#41b584) 渲染带有百分比的动态进度条。任务项提供“强制取消”图标按钮。
已完成 (Success) 30 成功绿 (#10b981) 进度归 100%。渲染出绿色“下载物理附件”动作键,绑定专属 OSS 下载 URL
发生错误 (Error) 40 高危红 (#ef4444) 进度条爆红,展示“查看错误详情”,点击直接展示后台的异常堆栈信息。
04 / Layout Feedback

载入状态与骨架屏 (LoadingState)

1. 组件定位与防抖机制

为消灭网速卡顿、局部区域白屏造成的体验中断,Acme.IBP 规定当任何区域请求延迟预计超过 300ms 时,必须调用 LoadingState。组件内置了 200ms 的防抖机制:若请求在 200ms 内瞬间完成,则不显示骨架以防闪烁。

2. 两种核心加载规格

1. 局部旋转 Spinner Loading
适用于小卡片、按钮提交或小型区块。
正在处理...
2. 动态骨架占位 Skeleton
适用于复杂详情页加载、AG Grid 数据首屏加载。

3. API 调用与 DOM 类名约定

方法 / 类名 使用方法 交互与样式表现
LoadingState.init(container, options) var loader = LoadingState.init('#MyCard', options) 核心初始化方法。在指定 DOM 容器内构建一个 LoadingState 状态管理实例。
loader.showLoading() / loader.setState('loading') loader.showLoading() 切换实例为正在加载状态,展示 Spinner 旋转或骨架屏动画。
loader.showEmpty() / loader.setState('empty') loader.showEmpty() 切换实例为无数据状态,自动展示标准 Empty 缺省图标与说明。
loader.showError() / loader.setState('error') loader.showError() 切换实例为异常报错状态,展示带有一键重试按钮的错误面板。
loader.setState('success') loader.setState('success') 切换实例为成功,自动隐藏所有状态遮罩并还原展示容器的物理子 DOM。
.acme-skeleton HTML class 标记 骨架屏特效类。利用 CSS 动画实现闪烁的灰色条纹占位条(如上图右侧)。
05 / Diagnostics

错误诊断追踪 (TraceIdDisplay)

1. 组件定位与红线指标

在微服务与高并发架构下,后台的报错通常隐藏在数以万计的集群日志中。为了能秒级定位线上问题,Acme.IBP 规定:前端抛出的任何 500 级崩溃、物理异常提示,必须在最显眼处渲染 TraceId 模块。严禁只弹“系统开小差了/出错了”这种对排查完全无助的垃圾提示。

2. 标准 UI 渲染约定

报错时,系统会自动在对话框底部渲染一栏专属的 .ds-trace-id-container

物理保存失败 (500 Internal Error)
数据插入冲突: 字段 'DepartmentCode' 存在唯一的唯一索引约束冲突。
TraceId: 01F8269AA42BD38FBA9E

3. 错误捕获集成模式

错误诊断完全整合在 Ajax 网络包中,如果后端抛出异常,拦截器会自动抓取 Response 标头的 X-Trace-Id

// Ajax 自动生成的错误框底层逻辑概要 (wwwroot/js/lib.js)
Ajax.onError = function(xhr) {
    var traceId = xhr.getResponseHeader('X-Trace-Id') || 'N/A';
    var errorMsg = xhr.responseJSON ? xhr.responseJSON.errors : '服务器内部系统崩溃';
    
    var html = '<div class="error-msg-box">' + errorMsg + '</div>' +
               '<div class="ds-trace-id-container">' +
                 '<span>诊断追踪码: <code>' + traceId + '</code></span>' +
                 '<button class="btn-copy-trace" onclick="copyText(\'' + traceId + '\')">复制</button>' +
               '</div>';
               
    Msg.Error('物理处理崩溃', html);
};
06 / Real-time Notify

通知铃铛 (SystemNotificationBell)

1. 组件定位与接口轮询机制

SystemNotificationBell 是挂载于主框架顶栏右侧的实时警示与推送铃铛。底层并未采用长连接 WebSocket,而是基于 /api/system/system-notification 接口在主框架内进行心跳定时轮询,自动拉取未读消息数、待办弹窗队列并更新红点通知徽标。

2. JS 驱动 API 规范

通知铃铛实例会在主框架全局初始化,并挂载于 window.AcmeSystemNotificationBell。在子业务页面执行审批、流转等动作后,可通过该全局对象实现即时联动:

公开 API 方法 参数/返回值 详细功能描述与工程调用约定
window.AcmeSystemNotificationBell.reload() void 最常用方法。立即强制重新加载当前登录人的未读通知列表并重绘下拉框。
window.AcmeSystemNotificationBell.refreshBadge() void 立即强制拉取未读计数并刷新顶栏铃铛的红色数字徽标。
window.AcmeSystemNotificationBell.loadPending() void 仅拉取当前账号处于“待处理 (Pending)”状态的任务队列。
window.AcmeSystemNotificationBell.loadProcessed() void 拉取当前账号处于“已处理 (Processed)”状态的归档历史。
window.AcmeSystemNotificationBell.loadPopupQueue() void 轮询加载后台推送的强阻断弹窗消息队列并按顺序在页面中央弹出。

3. 业务页面主动通知重载联动示例

// 在子页面执行“审批通过”操作后,手动触发顶栏铃铛的重载刷新,以同步更新红点数字
$('#btnPassApproval').click(function() {
    Ajax.Post('/api/workflow/pass', { docId: '10042' }, function() {
        Msg.Success('审批通过', '单据已流转,正在同步通知红点...');
        
        // 核心安全调用:穿透子页面 iframe 刷新主框架的铃铛徽标与内容
        if (window.parent && window.parent.AcmeSystemNotificationBell) {
            window.parent.AcmeSystemNotificationBell.refreshBadge();
            window.parent.AcmeSystemNotificationBell.reload();
        }
        
        myGrid.refresh();
    });
});
代码复制成功!已写入剪贴板