mirror of
https://github.com/hansjone/dsh-im-ops.git
synced 2026-10-10 06:30:46 +08:00
Add DingTalk to unified IM plugin
This commit is contained in:
parent
c7b573a7aa
commit
af7e6a2296
14 changed files with 1809 additions and 578 deletions
|
|
@ -1,5 +1,7 @@
|
|||
import * as React from 'react';
|
||||
|
||||
import { DINGTALK_RPC_CHANNEL } from '@xmanrui/dsh-dingtalk/client-api';
|
||||
import { DingtalkSettingsTab } from '@xmanrui/dsh-dingtalk/client-source';
|
||||
import { FeishuSettingsTab } from './channels/feishu/index.js';
|
||||
import { FEISHU_RPC_CHANNEL } from './channels/feishu/api.js';
|
||||
import { installFeishuStyles } from './channels/feishu/styles.js';
|
||||
|
|
@ -16,6 +18,7 @@ export const inject = ['slots', 'connection'];
|
|||
const CHANNELS = Object.freeze([
|
||||
{ id: 'weixin', label: '微信' },
|
||||
{ id: 'feishu', label: '飞书' },
|
||||
{ id: 'dingtalk', label: '钉钉' },
|
||||
]);
|
||||
|
||||
function WeixinLogo() {
|
||||
|
|
@ -37,17 +40,29 @@ function FeishuLogo() {
|
|||
));
|
||||
}
|
||||
|
||||
function ChannelLogo({ channel }) {
|
||||
return channel === 'weixin' ? h(WeixinLogo) : h(FeishuLogo);
|
||||
function DingtalkLogo() {
|
||||
return h('span', { className: 'dim-logo dim-logoDingtalk', 'aria-hidden': 'true' },
|
||||
h('svg', { viewBox: '0 0 48 48', focusable: 'false' },
|
||||
h('path', {
|
||||
fill: 'currentColor',
|
||||
d: 'M37.05 22.783c-6.758-5.216-14.378-12.128-22.73-19.538-.655-.585-1.242-.354-1.536.42-1.88 4.973-.058 9.386 2.889 11.932s7.368 4.912 10.058 6.155c.105.049.013.203-.093.163-4.953-2.182-8.397-3.765-13.07-7.368-.497-.388-1.01-.242-1.07.521-.384 4.748 2.657 8.483 6.058 9.745 2.1.781 4.398 1.212 6.53 1.474.109.015.084.178-.027.178-2.747.01-6.058-.654-8.935-1.751-.606-.233-.818.25-.722.633.491 2.008 2.974 5.076 6.926 5.73a12 12 0 0 0 2.228.115c.164 0 .208.089.154.217q-2.685 4.6-2.803 4.797c-.091.152-.036.275.156.275h3.543c.164 0 .264.106.18.246l-4.958 8.196c-.191.328.035.565.395.301s15.212-11.133 15.636-11.448c.195-.142.148-.327-.124-.327h-3.18c-.206 0-.252-.14-.111-.28.14-.141 3.602-3.594 4.837-4.888 1.283-1.35 1.938-3.825-.231-5.498',
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
export function IMSettingsTab({ feishuRpcCall, weixinRpcCall }) {
|
||||
function ChannelLogo({ channel }) {
|
||||
if (channel === 'weixin') return h(WeixinLogo);
|
||||
if (channel === 'feishu') return h(FeishuLogo);
|
||||
return h(DingtalkLogo);
|
||||
}
|
||||
|
||||
export function IMSettingsTab({ dingtalkRpcCall, feishuRpcCall, weixinRpcCall }) {
|
||||
const [selected, setSelected] = React.useState('weixin');
|
||||
const active = CHANNELS.find((channel) => channel.id === selected) ?? CHANNELS[0];
|
||||
return h('section', { className: 'dim-page', 'aria-label': 'IM机器人设置' },
|
||||
h('header', { className: 'dim-title' },
|
||||
h('p', null, '通过扫码把机器人接入 DeepSeek Harness'),
|
||||
h('div', { className: 'dim-channelCount' }, '2 个渠道'),
|
||||
h('div', { className: 'dim-channelCount' }, `${CHANNELS.length} 个渠道`),
|
||||
),
|
||||
h('div', { className: 'dim-layout' },
|
||||
h('nav', { className: 'dim-rail', role: 'tablist', 'aria-label': 'IM 渠道' },
|
||||
|
|
@ -73,7 +88,9 @@ export function IMSettingsTab({ feishuRpcCall, weixinRpcCall }) {
|
|||
'aria-labelledby': `dim-tab-${active.id}`,
|
||||
}, active.id === 'weixin'
|
||||
? h(WeixinSettingsTab, { rpcCall: weixinRpcCall })
|
||||
: h(FeishuSettingsTab, { rpcCall: feishuRpcCall })),
|
||||
: active.id === 'feishu'
|
||||
? h(FeishuSettingsTab, { rpcCall: feishuRpcCall })
|
||||
: h(DingtalkSettingsTab, { rpcCall: dingtalkRpcCall })),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -90,12 +107,14 @@ export function apply(ctx) {
|
|||
ctx.connection.rpc.call(FEISHU_RPC_CHANNEL, endpoint, payload, signal);
|
||||
const weixinRpcCall = (endpoint, payload, signal) =>
|
||||
ctx.connection.rpc.call(WEIXIN_RPC_CHANNEL, endpoint, payload, signal);
|
||||
const dingtalkRpcCall = (endpoint, payload, signal) =>
|
||||
ctx.connection.rpc.call(DINGTALK_RPC_CHANNEL, endpoint, payload, signal);
|
||||
|
||||
ctx.slots.inject('settings.plugins.tab', () => ctx.slots.register({
|
||||
name: 'settings.plugins.tab',
|
||||
id: 'im',
|
||||
order: 20,
|
||||
label: 'IM机器人',
|
||||
inject: () => ({ feishuRpcCall, weixinRpcCall }),
|
||||
inject: () => ({ dingtalkRpcCall, feishuRpcCall, weixinRpcCall }),
|
||||
}, IMSettingsTab));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,13 +28,16 @@ const CSS = String.raw`
|
|||
.dim-logoWeixin svg { width: 19px; height: 19px; }
|
||||
.dim-logoFeishu { background: white; border: 1px solid var(--dsw-alias-line-border, #e5e6eb); }
|
||||
.dim-logoFeishu svg { width: 22px; height: 22px; }
|
||||
.dim-logoDingtalk { color: white; background: #1677ff; }
|
||||
.dim-logoDingtalk svg { width: 24px; height: 24px; }
|
||||
.dim-channelCopy { min-width: 0; display: block; }
|
||||
.dim-channelCopy strong { overflow: hidden; color: inherit; font-size: 14px; line-height: 20px; font-weight: 680; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.dim-divider { width: 1px; min-height: 520px; background: var(--dsw-alias-line-divider, #eef0f3); }
|
||||
.dim-panel { min-width: 0; }
|
||||
.dim-panel .bxf-page, .dim-panel .dxw-page { width: 100%; max-width: none; padding: 0 0 24px; }
|
||||
.dim-panel .bxf-heading, .dim-panel .dxw-heading { justify-content: flex-end; }
|
||||
.dim-panel .bxf-headingTools, .dim-panel .dxw-tools { width: 100%; justify-content: flex-end; }
|
||||
.dim-panel .bxf-page, .dim-panel .dxw-page, .dim-panel .ddt-page { width: 100%; max-width: none; padding: 0 0 24px; }
|
||||
.dim-panel .bxf-heading, .dim-panel .dxw-heading, .dim-panel .ddt-heading { justify-content: flex-end; }
|
||||
.dim-panel .bxf-headingTools, .dim-panel .dxw-tools, .dim-panel .ddt-tools { width: 100%; justify-content: flex-end; }
|
||||
.dim-panel .ddt-headingCopy { display: none; }
|
||||
@media (max-width: 840px) {
|
||||
.dim-title { align-items: flex-start; }
|
||||
.dim-layout { grid-template-columns: minmax(0, 1fr); gap: 18px; }
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { apply as applyDingtalk } from '@xmanrui/dsh-dingtalk';
|
||||
import { apply as applyFeishu } from '@xmanrui/dsh-feishu';
|
||||
import { apply as applyWeixin } from '@xmanrui/dsh-weixin';
|
||||
|
||||
|
|
@ -7,12 +8,14 @@ export const inject = ['connection', 'credentials', 'webServer'];
|
|||
export function createImHostPlugin(internals = {}) {
|
||||
const startFeishu = internals.applyFeishu ?? applyFeishu;
|
||||
const startWeixin = internals.applyWeixin ?? applyWeixin;
|
||||
const startDingtalk = internals.applyDingtalk ?? applyDingtalk;
|
||||
return Object.freeze({
|
||||
name,
|
||||
inject,
|
||||
async apply(ctx, config = {}) {
|
||||
await startFeishu(ctx, config.feishu ?? {});
|
||||
await startWeixin(ctx, config.weixin ?? {});
|
||||
await startDingtalk(ctx, config.dingtalk ?? {});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue