fix: add actionable DingTalk connection diagnostics

This commit is contained in:
xmanrui 2026-09-04 02:18:18 +08:00
parent 3010535409
commit 1b05fa8d32
18 changed files with 1038 additions and 299 deletions

View file

@ -169,19 +169,36 @@ function ProgressPanel({ status, busy, onCancel }) {
h(Button, { onClick: onCancel, disabled: busy }, '取消接入')));
}
function ConnectionErrorDiagnostic({ error }) {
if (!error) return null;
return h('div', { className: 'ddt-errorDiagnostic' },
error.hint ? h('p', { className: 'ddt-errorHint' }, error.hint) : null,
h('span', { className: 'ddt-errorCode' },
h('span', null, '错误码'), `: ${error.code}`,
error.referenceId
? h(React.Fragment, null, ' · ', h('span', null, '参考号'), `: ${error.referenceId}`)
: null));
}
function ProvisionError({ provision, busy, onRetry, onClose }) {
const error = provision.error ?? {
code: 'DINGTALK_PROVISION_FAILED',
message: '钉钉机器人没有接入完成',
};
const connectionFailed = Boolean(error.referenceId);
return h('div', { className: 'ddt-card dim-surfaceCard' },
h('div', { className: 'ddt-inlineError dim-inlineError', role: 'alert' },
h('h3', null, provision.status === 'expired' ? '二维码已过期' : '钉钉机器人没有接入完成'),
h('h3', null, provision.status === 'expired'
? '二维码已过期'
: connectionFailed ? '机器人已保存,但连接未就绪' : '钉钉机器人没有接入完成'),
h('p', null, error.message),
h('span', { className: 'ddt-errorCode' }, error.code),
h(ConnectionErrorDiagnostic, { error }),
h('div', { className: 'ddt-actions dim-viewActions' },
h(Button, { kind: 'primary', onClick: onRetry, disabled: busy }, '重新生成二维码'),
h(Button, { onClick: onClose, disabled: busy }, '关闭'))));
connectionFailed
? h(Button, { kind: 'primary', onClick: onClose, disabled: busy }, '查看已保存的机器人')
: h(React.Fragment, null,
h(Button, { kind: 'primary', onClick: onRetry, disabled: busy }, '重新生成二维码'),
h(Button, { onClick: onClose, disabled: busy }, '关闭')))));
}
function checkedTime(value) {
@ -278,6 +295,7 @@ export function AccountCard({
h(Button, { className: 'dim-cardAction', kind: 'danger', onClick: onRequestRemove, disabled: Boolean(busy) },
'移除接入')),
summary ? h('div', { className: 'ddt-summary dim-cardSummary' }, summary) : null,
account.error ? h(ConnectionErrorDiagnostic, { error: account.error }) : null,
account.lastMessageError ? h(LastMessageErrorSummary, {
className: 'ddt-summary',
error: account.lastMessageError,
@ -614,6 +632,12 @@ export function DingtalkSettingsTab({ rpcCall }) {
? snapshot?.bots.find((bot) => bot.botId === result.botId)
: snapshot?.bots.find((bot) => bot.connected);
if (!account?.connected) {
if (account?.error) {
setProvision((current) => current?.attemptId === attemptId
? { ...current, ...result, status: 'failed', error: account.error }
: current);
return;
}
setProvision((current) => current?.attemptId === attemptId
? { ...current, ...result, status: 'connecting' }
: current);
@ -698,9 +722,12 @@ export function DingtalkSettingsTab({ rpcCall }) {
return snapshot;
} catch (error) {
if (!mountedRef.current) return undefined;
const visibleError = presentError(error);
const failureMessage = operation === 'reconnect'
? '连接检查失败,请稍后重试。'
: `操作失败:${presentError(error).message}`;
? visibleError.referenceId
? `连接检查失败:${visibleError.message}(参考号:${visibleError.referenceId})`
: '连接检查失败,请稍后重试。'
: `操作失败:${visibleError.message}`;
if (operation === 'reconnect') {
setFeedbackByBot((current) => ({
...current,