253 lines
20 KiB
JavaScript
253 lines
20 KiB
JavaScript
window.__ModuleLoader__.load({
|
||||
|
|
id: "dsh-plugin-mcn-schedule",
|
|||
|
|
factory: (require) => {
|
|||
|
|
var module = { exports: {} };
|
|||
|
|
var exports = module.exports;
|
|||
|
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|||
|
|
let react = require("react");
|
|||
|
|
let react_dom = require("react-dom");
|
|||
|
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|||
|
|
//#region plugin css
|
|||
|
|
const css = ".mcnSched_page{position:relative;background:var(--dsw-alias-bg-base);width:100%;min-width:0;height:100%;min-height:0;color:var(--dsw-alias-label-primary);font-family:var(--dsw-font-family);flex:1;grid-template-rows:minmax(0,1fr);display:grid;overflow:hidden}.mcnSched_body{display:flex;flex-direction:column;height:100%;min-height:0;padding:16px;box-sizing:border-box;gap:12px}.mcnSched_toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.mcnSched_title{font-size:16px;font-weight:600;margin:0}.mcnSched_spacer{flex:1}.mcnSched_input{border:1px solid var(--dsw-alias-border-l2,var(--dsw-alias-border));border-radius:8px;padding:6px 10px;font:var(--dsw-font-s-14);background:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-elevated));color:var(--dsw-alias-label-primary);min-width:200px;box-sizing:border-box}.mcnSched_select{border:1px solid var(--dsw-alias-border-l2,var(--dsw-alias-border));border-radius:8px;padding:6px 8px;font:var(--dsw-font-s-14);background:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-elevated));color:var(--dsw-alias-label-primary)}.mcnSched_textarea{border:1px solid var(--dsw-alias-border-l2,var(--dsw-alias-border));border-radius:8px;padding:6px 10px;font:var(--dsw-font-s-14);background:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-elevated));color:var(--dsw-alias-label-primary);resize:vertical;box-sizing:border-box;width:100%;min-height:64px}.mcnSched_btn{border:1px solid var(--dsw-alias-border-l2,var(--dsw-alias-border));border-radius:8px;padding:6px 14px;font:var(--dsw-font-s-14);cursor:pointer;background:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-elevated));color:var(--dsw-alias-label-primary);transition:background var(--ds-transition-duration-fast) var(--ds-ease-in-out);white-space:nowrap}.mcnSched_btn:hover{background:var(--dsw-alias-interactive-bg-hover)}.mcnSched_btnPrimary{background:var(--mcn-brand,#4176e6);color:#fff;border-color:transparent}.mcnSched_btnPrimary:hover{background:var(--mcn-brand-hover,#3359c9)}.mcnSched_btnSm{padding:2px 10px;font-size:12px;line-height:1.8}.mcnSched_tableWrap{flex:1;min-height:0;overflow:auto;border:1px solid var(--dsw-alias-border-l2,var(--dsw-alias-border));border-radius:8px}.mcnSched_table{width:100%;border-collapse:collapse;font:var(--dsw-font-s-14);min-width:860px}.mcnSched_table th{position:sticky;top:0;background:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-elevated));text-align:left;padding:8px 10px;border-bottom:1px solid var(--dsw-alias-border-l2,var(--dsw-alias-border));font-weight:600;white-space:nowrap;user-select:none}.mcnSched_table td{padding:8px 10px;border-bottom:1px solid var(--dsw-alias-border-l2,var(--dsw-alias-border));vertical-align:middle}.mcnSched_table tr:hover{background:var(--dsw-alias-interactive-bg-hover)}.mcnSched_cellTrack{white-space:nowrap}.mcnSched_cellContent{color:var(--dsw-alias-label-secondary);max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mcnSched_badge{display:inline-block;padding:1px 8px;border-radius:10px;font-size:12px;line-height:18px;white-space:nowrap}.mcnSched_badgeOn{background:rgba(46,190,140,.18);color:var(--dsw-alias-label-primary)}.mcnSched_badgeOff{background:rgba(236,19,19,.14);color:var(--dsw-alias-label-primary)}.mcnSched_badgeAt{background:rgba(65,118,230,.15);color:var(--dsw-alias-label-primary)}.mcnSched_badgeEvery{background:rgba(255,122,69,.15);color:var(--dsw-alias-label-primary)}.mcnSched_badgeAgent{background:rgba(139,92,246,.16);color:var(--dsw-alias-label-primary)}.mcnSched_loading{display:flex;align-items:center;justify-content:center;height:100%;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-s-14)}.mcnSched_empty{padding:40px 20px;text-align:center;color:var(--dsw-alias-label-secondary);font:var(--dsw-font-s-14);line-height:1.8}.mcnSched_mask{position:fixed;inset:0;background:rgba(0,0,0,.4);display:flex;align-items:flex-start;justify-content:center;padding-top:24vh;z-index:100}.mcnSched_modal{background:var(--dsw-alias-bg-layer-1,var(--dsw-alias-bg-elevated));border-radius:12px;padding:20px;min-width:380px;max-width:460px;box-sha
|
|||
|
|
const key = "dsh-plugin-mcn-schedule/Schedule.module.css";
|
|||
|
|
if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(key) + "]")) {
|
|||
|
|
const el = document.createElement("style");
|
|||
|
|
el.dataset.plugin = "dsh-plugin-mcn-schedule";
|
|||
|
|
el.dataset.pluginCss = key;
|
|||
|
|
el.textContent = css;
|
|||
|
|
document.head.appendChild(el);
|
|||
|
|
}
|
|||
|
|
const cssMap = {
|
|||
|
|
"page": "mcnSched_page",
|
|||
|
|
"body": "mcnSched_body",
|
|||
|
|
"toolbar": "mcnSched_toolbar",
|
|||
|
|
"title": "mcnSched_title",
|
|||
|
|
"spacer": "mcnSched_spacer",
|
|||
|
|
"input": "mcnSched_input",
|
|||
|
|
"select": "mcnSched_select",
|
|||
|
|
"textarea": "mcnSched_textarea",
|
|||
|
|
"btn": "mcnSched_btn",
|
|||
|
|
"btnPrimary": "mcnSched_btnPrimary",
|
|||
|
|
"btnSm": "mcnSched_btnSm",
|
|||
|
|
"tableWrap": "mcnSched_tableWrap",
|
|||
|
|
"table": "mcnSched_table",
|
|||
|
|
"cellTrack": "mcnSched_cellTrack",
|
|||
|
|
"cellContent": "mcnSched_cellContent",
|
|||
|
|
"badge": "mcnSched_badge",
|
|||
|
|
"badgeOn": "mcnSched_badgeOn",
|
|||
|
|
"badgeOff": "mcnSched_badgeOff",
|
|||
|
|
"badgeAt": "mcnSched_badgeAt",
|
|||
|
|
"badgeEvery": "mcnSched_badgeEvery",
|
|||
|
|
"badgeAgent": "mcnSched_badgeAgent",
|
|||
|
|
"loading": "mcnSched_loading",
|
|||
|
|
"empty": "mcnSched_empty",
|
|||
|
|
"mask": "mcnSched_mask",
|
|||
|
|
"modal": "mcnSched_modal",
|
|||
|
|
"modalTitle": "mcnSched_modalTitle",
|
|||
|
|
"modalText": "mcnSched_modalText",
|
|||
|
|
"modalBtns": "mcnSched_modalBtns",
|
|||
|
|
"formGrid": "mcnSched_formGrid",
|
|||
|
|
"formItem": "mcnSched_formItem",
|
|||
|
|
"formItemWide": "mcnSched_formItemWide",
|
|||
|
|
"toast": "mcnSched_toast"
|
|||
|
|
};
|
|||
|
|
//#endregion
|
|||
|
|
//#region 图标
|
|||
|
|
function IconClock({ size = 22 }) {
|
|||
|
|
return (0, react_jsx_runtime.jsx)("svg", {
|
|||
|
|
viewBox: "0 0 24 24",
|
|||
|
|
width: size,
|
|||
|
|
height: size,
|
|||
|
|
fill: "none",
|
|||
|
|
stroke: "currentColor",
|
|||
|
|
strokeWidth: "2",
|
|||
|
|
strokeLinecap: "round",
|
|||
|
|
strokeLinejoin: "round",
|
|||
|
|
"aria-hidden": "true",
|
|||
|
|
style: { color: "var(--mcn-brand,#4176e6)" },
|
|||
|
|
children: [(0, react_jsx_runtime.jsx)("circle", { cx: "12", cy: "12", r: "10" }), (0, react_jsx_runtime.jsx)("polyline", { points: "12 6 12 12 16 14" })]
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region 计划任务页面
|
|||
|
|
function SchedulePage() {
|
|||
|
|
const [tasks, setTasks] = (0, react.useState)([]);
|
|||
|
|
const [events, setEvents] = (0, react.useState)([]);
|
|||
|
|
const [loading, setLoading] = (0, react.useState)(true);
|
|||
|
|
const [modalOpen, setModalOpen] = (0, react.useState)(false);
|
|||
|
|
const [editing, setEditing] = (0, react.useState)(null);
|
|||
|
|
const [toast, setToast] = (0, react.useState)(null);
|
|||
|
|
const lastSeenRef = (0, react.useRef)(Date.now());
|
|||
|
|
const toastTimer = (0, react.useRef)(null);
|
|||
|
|
|
|||
|
|
const fmtTime = (ts) => {
|
|||
|
|
if (ts == null) return "-";
|
|||
|
|
const d = new Date(ts);
|
|||
|
|
const p = (n) => String(n).padStart(2, "0");
|
|||
|
|
return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())} ${p(d.getHours())}:${p(d.getMinutes())}`;
|
|||
|
|
};
|
|||
|
|
const showToast = (msg) => {
|
|||
|
|
setToast(msg);
|
|||
|
|
if (toastTimer.current) clearTimeout(toastTimer.current);
|
|||
|
|
toastTimer.current = setTimeout(() => setToast(null), 6000);
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const load = () => {
|
|||
|
|
fetch("/mcn/schedule/list")
|
|||
|
|
.then((r) => r.json())
|
|||
|
|
.then((d) => { if (d.ok) { setTasks(d.tasks || []); } })
|
|||
|
|
.catch(() => {})
|
|||
|
|
.finally(() => setLoading(false));
|
|||
|
|
};
|
|||
|
|
const pollEvents = () => {
|
|||
|
|
const since = lastSeenRef.current;
|
|||
|
|
fetch("/mcn/schedule/events?since=" + since)
|
|||
|
|
.then((r) => r.json())
|
|||
|
|
.then((d) => {
|
|||
|
|
if (!d.ok || !d.events || d.events.length === 0) return;
|
|||
|
|
const last = Math.max(...d.events.map((e) => new Date(e.at).getTime()));
|
|||
|
|
lastSeenRef.current = Math.max(lastSeenRef.current, last);
|
|||
|
|
setEvents((prev) => [...d.events, ...prev].slice(0, 20));
|
|||
|
|
for (const ev of d.events) {
|
|||
|
|
showToast(`⏰ 计划任务「${ev.name}」${ev.prompt ? ":" + ev.prompt : "已触发"}`);
|
|||
|
|
}
|
|||
|
|
load();
|
|||
|
|
})
|
|||
|
|
.catch(() => {});
|
|||
|
|
};
|
|||
|
|
(0, react.useEffect)(() => {
|
|||
|
|
load();
|
|||
|
|
const t1 = setInterval(pollEvents, 12000);
|
|||
|
|
const t2 = setInterval(load, 30000);
|
|||
|
|
return () => { clearInterval(t1); clearInterval(t2); if (toastTimer.current) clearTimeout(toastTimer.current); };
|
|||
|
|
}, []);
|
|||
|
|
|
|||
|
|
const openCreate = () => { setEditing(null); setModalOpen(true); };
|
|||
|
|
const openEdit = (t) => { setEditing(t); setModalOpen(true); };
|
|||
|
|
const toggleEnabled = (t) => {
|
|||
|
|
fetch("/mcn/schedule/update", {
|
|||
|
|
method: "POST",
|
|||
|
|
headers: { "Content-Type": "application/json" },
|
|||
|
|
body: JSON.stringify({ id: t.id, enabled: !t.enabled }),
|
|||
|
|
}).then((r) => r.json()).then((d) => { if (d.ok) { load(); showToast(!t.enabled ? "已启用" : "已停用"); } }).catch(() => {});
|
|||
|
|
};
|
|||
|
|
const fireNow = (t) => {
|
|||
|
|
fetch("/mcn/schedule/fire-now", {
|
|||
|
|
method: "POST",
|
|||
|
|
headers: { "Content-Type": "application/json" },
|
|||
|
|
body: JSON.stringify({ id: t.id }),
|
|||
|
|
}).then((r) => r.json()).then((d) => { if (d.ok) { showToast("已触发测试"); setTimeout(load, 500); } }).catch(() => {});
|
|||
|
|
};
|
|||
|
|
const remove = (t) => {
|
|||
|
|
if (!window.confirm(`确认删除任务「${t.name}」?`)) return;
|
|||
|
|
fetch("/mcn/schedule/delete", {
|
|||
|
|
method: "POST",
|
|||
|
|
headers: { "Content-Type": "application/json" },
|
|||
|
|
body: JSON.stringify({ id: t.id }),
|
|||
|
|
}).then((r) => r.json()).then((d) => { if (d.ok) { load(); showToast("已删除"); } }).catch(() => {});
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const submit = (form) => {
|
|||
|
|
const url = editing ? "/mcn/schedule/update" : "/mcn/schedule/create";
|
|||
|
|
const body = { name: form.name, prompt: form.prompt, enabled: form.enabled, type: form.type, action: form.action || "remind" };
|
|||
|
|
if (form.type === "at") body.at = form.at;
|
|||
|
|
else body.intervalMinutes = Number(form.intervalMinutes);
|
|||
|
|
if (editing) body.id = editing.id;
|
|||
|
|
fetch(url, {
|
|||
|
|
method: "POST",
|
|||
|
|
headers: { "Content-Type": "application/json" },
|
|||
|
|
body: JSON.stringify(body),
|
|||
|
|
}).then((r) => r.json()).then((d) => {
|
|||
|
|
if (d.ok) { setModalOpen(false); load(); showToast(editing ? "已保存" : "已创建"); }
|
|||
|
|
else { showToast(d.error || "操作失败"); }
|
|||
|
|
}).catch(() => showToast("请求失败"));
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|||
|
|
className: cssMap.page,
|
|||
|
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|||
|
|
className: cssMap.body,
|
|||
|
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|||
|
|
className: cssMap.toolbar,
|
|||
|
|
children: [(0, react_jsx_runtime.jsx)("span", { className: cssMap.title, children: "计划任务" }), (0, react_jsx_runtime.jsx)("span", { className: cssMap.spacer }), (0, react_jsx_runtime.jsx)("button", { type: "button", className: cssMap.btn + " " + cssMap.btnPrimary, onClick: openCreate, children: "+ 新建任务" })]
|
|||
|
|
}), events.length > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|||
|
|
className: cssMap.cellTrack,
|
|||
|
|
style: { font: "var(--dsw-font-s-13)", color: "var(--dsw-alias-label-secondary)" },
|
|||
|
|
children: "最近触发:" + events.slice(0, 3).map((e) => `${e.name}(${fmtTime(new Date(e.at).getTime())})`).join("、")
|
|||
|
|
}), loading ? (0, react_jsx_runtime.jsx)("div", { className: cssMap.loading, children: "加载中…" }) : tasks.length === 0 ? (0, react_jsx_runtime.jsx)("div", { className: cssMap.empty, children: "暂无计划任务,点击右上角「+ 新建任务」创建" }) : (0, react_jsx_runtime.jsx)("div", {
|
|||
|
|
className: cssMap.tableWrap,
|
|||
|
|
children: (0, react_jsx_runtime.jsx)("table", {
|
|||
|
|
className: cssMap.table,
|
|||
|
|
children: [(0, react_jsx_runtime.jsx)("thead", {
|
|||
|
|
children: (0, react_jsx_runtime.jsx)("tr", {
|
|||
|
|
children: ["任务名称", "类型", "状态", "下次执行", "上次执行", "提醒内容", "操作"].map((h) => (0, react_jsx_runtime.jsx)("th", { children: h }))
|
|||
|
|
})
|
|||
|
|
}), (0, react_jsx_runtime.jsx)("tbody", {
|
|||
|
|
children: tasks.map((t) => (0, react_jsx_runtime.jsx)("tr", {
|
|||
|
|
children: [(0, react_jsx_runtime.jsx)("td", { className: cssMap.cellTrack, children: t.name }), (0, react_jsx_runtime.jsx)("td", { children: [(0, react_jsx_runtime.jsx)("span", { className: cssMap.badge + " " + (t.type === "at" ? cssMap.badgeAt : cssMap.badgeEvery), children: t.type === "at" ? "一次性" : "循环" }), t.action === "agent" && (0, react_jsx_runtime.jsx)("span", { className: cssMap.badge + " " + cssMap.badgeAgent, children: "AI执行" })] }), (0, react_jsx_runtime.jsx)("td", { children: (0, react_jsx_runtime.jsx)("span", { className: cssMap.badge + " " + (t.enabled ? cssMap.badgeOn : cssMap.badgeOff), children: t.enabled ? "启用" : "停用" }) }), (0, react_jsx_runtime.jsx)("td", { className: cssMap.cellTrack, children: t.type === "at" ? fmtTime(t.nextRunAt) + (t.firedAt ? "(已触发)" : "") : fmtTime(t.nextRunAt) }), (0, react_jsx_runtime.jsx)("td", { className: cssMap.cellTrack, children: fmtTime(t.lastFiredAt) }), (0, react_jsx_runtime.jsx)("td", { className: cssMap.cellContent, children: t.prompt || "-" }), (0, react_jsx_runtime.jsx)("td", {
|
|||
|
|
children: [(0, react_jsx_runtime.jsx)("button", { type: "button", className: cssMap.btn + " " + cssMap.btnSm, onClick: () => openEdit(t), children: "编辑" }), " ", (0, react_jsx_runtime.jsx)("button", { type: "button", className: cssMap.btn + " " + cssMap.btnSm, onClick: () => toggleEnabled(t), children: t.enabled ? "停用" : "启用" }), " ", (0, react_jsx_runtime.jsx)("button", { type: "button", className: cssMap.btn + " " + cssMap.btnSm, onClick: () => fireNow(t), children: "触发" }), " ", (0, react_jsx_runtime.jsx)("button", { type: "button", className: cssMap.btn + " " + cssMap.btnSm, onClick: () => remove(t), children: "删除" })]
|
|||
|
|
})]
|
|||
|
|
}, t.id))
|
|||
|
|
})]
|
|||
|
|
})
|
|||
|
|
})]
|
|||
|
|
}), modalOpen && (0, react_jsx_runtime.jsxs)("div", {
|
|||
|
|
className: cssMap.mask,
|
|||
|
|
onClick: () => setModalOpen(false),
|
|||
|
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|||
|
|
className: cssMap.modal,
|
|||
|
|
onClick: (e) => e.stopPropagation(),
|
|||
|
|
children: [(0, react_jsx_runtime.jsx)("div", { className: cssMap.modalTitle, children: editing ? `编辑任务「${editing.name}」` : "新建计划任务" }), (0, react_jsx_runtime.jsx)(ScheduleForm, { initial: editing, onSubmit: submit, onCancel: () => setModalOpen(false) })]
|
|||
|
|
})]
|
|||
|
|
}), toast && (0, react_jsx_runtime.jsx)("div", { className: cssMap.toast, children: toast })]
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function ScheduleForm({ initial, onSubmit, onCancel }) {
|
|||
|
|
const [name, setName] = (0, react.useState)(initial?.name || "");
|
|||
|
|
const [type, setType] = (0, react.useState)(initial?.type || "at");
|
|||
|
|
const [at, setAt] = (0, react.useState)(initial?.at || "");
|
|||
|
|
const [intervalMinutes, setIntervalMinutes] = (0, react.useState)(String(initial?.intervalMinutes || 10));
|
|||
|
|
const [prompt, setPrompt] = (0, react.useState)(initial?.prompt || "");
|
|||
|
|
const [action, setAction] = (0, react.useState)(initial?.action || "remind");
|
|||
|
|
const [enabled, setEnabled] = (0, react.useState)(initial?.enabled !== false);
|
|||
|
|
const [err, setErr] = (0, react.useState)("");
|
|||
|
|
const submit = () => {
|
|||
|
|
if (!name.trim()) { setErr("请填写任务名称"); return; }
|
|||
|
|
if (type === "at" && !at) { setErr("请选择执行时间"); return; }
|
|||
|
|
if (type === "every" && (!Number(intervalMinutes) || Number(intervalMinutes) < 1)) { setErr("周期间隔不能小于 1 分钟"); return; }
|
|||
|
|
onSubmit({ name, type, at, intervalMinutes, prompt, action, enabled });
|
|||
|
|
};
|
|||
|
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|||
|
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|||
|
|
className: cssMap.formGrid,
|
|||
|
|
children: [(0, react_jsx_runtime.jsx)("label", { className: cssMap.formItemWide, children: [(0, react_jsx_runtime.jsx)("span", { children: "任务名称" }), (0, react_jsx_runtime.jsx)("input", { className: cssMap.input, style: { width: "100%" }, value: name, onChange: (e) => setName(e.target.value), placeholder: "如:每日检查日榜" })] }), (0, react_jsx_runtime.jsx)("label", { className: cssMap.formItem, children: [(0, react_jsx_runtime.jsx)("span", { children: "任务类型" }), (0, react_jsx_runtime.jsx)("select", { className: cssMap.select, value: type, onChange: (e) => setType(e.target.value), children: [(0, react_jsx_runtime.jsx)("option", { value: "at", children: "一次性(指定时间)" }), (0, react_jsx_runtime.jsx)("option", { value: "every", children: "循环(固定间隔)" })] })] }), (0, react_jsx_runtime.jsx)("label", { className: cssMap.formItem, children: [(0, react_jsx_runtime.jsx)("span", { children: "动作" }), (0, react_jsx_runtime.jsx)("select", { className: cssMap.select, value: action, onChange: (e) => setAction(e.target.value), children: [(0, react_jsx_runtime.jsx)("option", { value: "remind", children: "仅页面提醒" }), (0, react_jsx_runtime.jsx)("option", { value: "agent", children: "触发 AI 执行" })] })] }), type === "every" ? (0, react_jsx_runtime.jsx)("label", { className: cssMap.formItem, children: [(0, react_jsx_runtime.jsx)("span", { children: "间隔(分钟)" }), (0, react_jsx_runtime.jsx)("input", { className: cssMap.input, type: "number", min: 1, value: intervalMinutes, onChange: (e) => setIntervalMinutes(e.target.value) })] }) : (0, react_jsx_runtime.jsx)("label", { className: cssMap.formItem, children: [(0, react_jsx_runtime.jsx)("span", { children: "执行时间" }), (0, react_jsx_runtime.jsx)("input", { className: cssMap.input, type: "datetime-local", value: at, onChange: (e) => setAt(e.target.value) })] }), (0, react_jsx_runtime.jsx)("label", { className: cssMap.formItemWide, children: [(0, react_jsx_runtime.jsx)("span", { children: action === "agent" ? "任务指令(AI 将执行的内容)" : "提醒内容(可选)" }), (0, react_jsx_runtime.jsx)("textarea", { className: cssMap.textarea, value: prompt, onChange: (e) => setPrompt(e.target.value), placeholder: action === "agent" ? "如:分析今日抖音日榜数据,生成简报保存到工作区" : "到点后提醒的内容,如:检查今日日榜数据" })] }), (0, react_jsx_runtime.jsx)("label", { className: cssMap.formItemWide, children: [(0, react_jsx_runtime.jsx)("span", { children: "状态" }), (0, react_jsx_runtime.jsx)("select", { className: cssMap.select, value: enabled ? "1" : "0", onChange: (e) => setEnabled(e.target.value === "1"), children: [(0, react_jsx_runtime.jsx)("option", { value: "1", children: "启用" }), (0, react_jsx_runtime.jsx)("option", { value: "0", children: "停用" })] })] }), err && (0, react_jsx_runtime.jsx)("div", { className: cssMap.formItemWide, style: { color: "#ff6b6b" }, children: err })]
|
|||
|
|
}), (0, react_jsx_runtime.jsxs)("div", {
|
|||
|
|
className: cssMap.modalBtns,
|
|||
|
|
children: [(0, react_jsx_runtime.jsx)("button", { type: "button", className: cssMap.btn, onClick: onCancel, children: "取消" }), (0, react_jsx_runtime.jsx)("button", { type: "button", className: cssMap.btn + " " + cssMap.btnPrimary, onClick: submit, children: initial ? "保存" : "创建" })]
|
|||
|
|
})]
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
//#region plugin entry
|
|||
|
|
const inject = [];
|
|||
|
|
function apply() {
|
|||
|
|
window.__mcnEntries = window.__mcnEntries || [];
|
|||
|
|
// 幂等:避免插件热重载重复注册
|
|||
|
|
if (!window.__mcnEntries.some((e) => e.id === "mcn-schedule")) {
|
|||
|
|
// unshift 置顶:入口放到 MCN 工作台上方
|
|||
|
|
window.__mcnEntries.unshift({
|
|||
|
|
id: "mcn-schedule",
|
|||
|
|
icon: IconClock,
|
|||
|
|
title: "计划任务",
|
|||
|
|
desc: "定时提醒 / 周期任务",
|
|||
|
|
component: SchedulePage,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
//#endregion
|
|||
|
|
exports.apply = apply;
|
|||
|
|
exports.inject = inject;
|
|||
|
|
return module.exports;
|
|||
|
|
}
|
|||
|
|
});
|