feat: 调整脚本功能

This commit is contained in:
duanshuwen
2026-04-12 17:01:04 +08:00
parent c16fc93685
commit 6432634d17
11 changed files with 58 additions and 158 deletions

View File

@@ -220,8 +220,8 @@
#### 3.5 添加脚本模板和默认脚本
- **内容**
- 提供常用模板(点击元素、输入文本、等待页面加载)
- 预置参考图中的示例脚本change model、pause、pause resume 等)作为 `.mjs` 文件放置到 `electron/scripts/seed/` 目录
- 应用首次启动或检测到 `electron/scripts/` 为空时,将 seed 目录下的示例脚本复制/同步到主目录,并注册到元数据索引
- 预置参考图中的示例脚本change model、pause、pause resume 等)作为 `.mjs` 文件放置到 `electron/scripts/` 目录
- 应用首次启动或检测到 `electron/scripts/` 为空时,直接将 `electron/scripts/` 目录下的 `.mjs` 示例脚本注册到元数据索引
- 用户通过面板删除默认脚本时,直接删除对应的 `.mjs` 文件及索引条目
- **依赖**script-store-service
- **预估工时**3 小时
@@ -235,7 +235,7 @@
- 录制功能至少能生成可运行的 Playwright 代码并正确落盘
- 面板中的"测试"或"运行"按钮能直接执行 `electron/scripts/` 目录下的真实脚本文件
- 脚本执行输出完整呈现在日志面板
- 默认脚本从 `electron/scripts/seed/` 同步后可正常加载和运行
- 默认脚本从 `electron/scripts/` 同步后可正常加载和运行
---
@@ -414,11 +414,7 @@
electron/
└── scripts/
├── scripts.meta.json # 脚本元数据索引(名称、启用状态、渠道等)
├── change-model.mjs # 默认示例脚本(由 seed/ 自动同步)
├── pause.mjs
├── pause-resume.mjs
└── seed/ # 预置种子脚本目录(应用自带,只读模板源)
├── change-model.mjs
├── change-model.mjs # 默认示例脚本(自动同步)
├── pause.mjs
└── pause-resume.mjs

View File

@@ -1488,7 +1488,6 @@ class executeScriptService extends events.EventEmitter {
}
}
const META_FILENAME = "scripts.meta.json";
const SEED_DIR = "seed";
function getScriptsDir$1() {
return electron.app.isPackaged ? path.join(__dirname, "scripts") : path.join(process.cwd(), "electron/scripts");
}
@@ -1541,18 +1540,14 @@ function seedScripts() {
if (fs.existsSync(metaPath)) {
return;
}
const seedDir = path.join(scriptsDir, SEED_DIR);
if (!fs.existsSync(seedDir)) {
log.info("[script-store-service] Seed directory does not exist, skipping seed.");
if (!fs.existsSync(scriptsDir)) {
log.info("[script-store-service] Scripts directory does not exist, skipping seed.");
return;
}
const meta = { scripts: [] };
const seedFiles = fs.readdirSync(seedDir).filter((f) => f.endsWith(".mjs"));
for (const file of seedFiles) {
const seedPath = path.join(seedDir, file);
const destPath = path.join(scriptsDir, file);
const scriptFiles = fs.readdirSync(scriptsDir).filter((f) => f.endsWith(".mjs"));
for (const file of scriptFiles) {
try {
fs.copyFileSync(seedPath, destPath);
const name = file.replace(/\.mjs$/, "");
const now = (/* @__PURE__ */ new Date()).toISOString();
meta.scripts.push({
@@ -1566,7 +1561,7 @@ function seedScripts() {
updatedAt: now
});
} catch (err) {
log.warn("[script-store-service] Failed to copy seed file", file, err);
log.warn("[script-store-service] Failed to seed script", file, err);
}
}
writeMeta(meta);

View File

@@ -1,18 +0,0 @@
import { chromium } from 'playwright';
import { preparePage, safeDisconnectBrowser } from './common/tabs.js';
(async () => {
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const { page } = await preparePage(browser, {
targetUrl: 'about:blank',
});
// Example: navigate and click an element
// await page.goto('https://example.com');
// await page.click('text=Change Model');
console.log('Change model script executed');
await safeDisconnectBrowser(browser);
process.exit(0);
})();

View File

@@ -1,18 +0,0 @@
import { chromium } from 'playwright';
import { preparePage, safeDisconnectBrowser } from './common/tabs.js';
(async () => {
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const { page } = await preparePage(browser, {
targetUrl: 'about:blank',
});
// Example: fill a form and submit
// await page.fill('input[name="username"]', 'test');
// await page.click('button[type="submit"]');
console.log('Pause resume script executed');
await safeDisconnectBrowser(browser);
process.exit(0);
})();

View File

@@ -1,18 +0,0 @@
import { chromium } from 'playwright';
import { preparePage, safeDisconnectBrowser } from './common/tabs.js';
(async () => {
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const { page } = await preparePage(browser, {
targetUrl: 'about:blank',
});
// Example: wait for a specific element or timeout
// await page.waitForSelector('[data-testid="status-paused"]');
// await page.waitForTimeout(2000);
console.log('Pause script executed');
await safeDisconnectBrowser(browser);
process.exit(0);
})();

View File

@@ -1,34 +1,54 @@
{
"scripts": [
{
"id": "seed-change-model",
"name": "change-model",
"description": "",
"filename": "change-model.mjs",
"id": "script-dy-hot-spring-trace",
"name": "抖音温泉房态追踪",
"description": "抖音生活服务平台温泉房型房态自动化追踪脚本",
"filename": "dy_hot_spring_trace.js",
"enabled": true,
"channel": "common",
"createdAt": "2026-04-12T05:27:08.543Z",
"updatedAt": "2026-04-12T05:27:08.543Z"
"channel": "douyin",
"createdAt": "2026-04-09T19:29:52.000Z",
"updatedAt": "2026-04-09T19:29:52.000Z"
},
{
"id": "seed-pause-resume",
"name": "pause-resume",
"description": "",
"filename": "pause-resume.mjs",
"id": "script-dy-hotel-trace",
"name": "抖音酒店房态追踪",
"description": "抖音生活服务平台酒店房型房态自动化追踪脚本",
"filename": "dy_hotel_trace.js",
"enabled": true,
"channel": "common",
"createdAt": "2026-04-12T05:27:08.544Z",
"updatedAt": "2026-04-12T05:27:08.544Z"
"channel": "douyin",
"createdAt": "2026-04-09T19:29:52.000Z",
"updatedAt": "2026-04-09T19:29:52.000Z"
},
{
"id": "seed-pause",
"name": "pause",
"description": "",
"filename": "pause.mjs",
"id": "script-fg-trace",
"name": "飞猪房态追踪",
"description": "飞猪平台房型房态自动化追踪脚本",
"filename": "fg_trace.js",
"enabled": true,
"channel": "common",
"createdAt": "2026-04-12T05:27:08.544Z",
"updatedAt": "2026-04-12T05:27:08.544Z"
"channel": "fliggy",
"createdAt": "2026-04-09T19:35:34.000Z",
"updatedAt": "2026-04-09T19:35:34.000Z"
},
{
"id": "script-mt-trace",
"name": "美团房态追踪",
"description": "美团平台房型房态自动化追踪脚本",
"filename": "mt_trace.js",
"enabled": true,
"channel": "meituan",
"createdAt": "2026-04-09T19:29:52.000Z",
"updatedAt": "2026-04-09T19:29:52.000Z"
},
{
"id": "script-open-all-channel",
"name": "打开所有渠道",
"description": "一键打开所有配置渠道页面的通用脚本",
"filename": "open_all_channel.js",
"enabled": true,
"channel": "",
"createdAt": "2026-04-09T19:29:52.000Z",
"updatedAt": "2026-04-09T19:29:52.000Z"
}
]
}

View File

@@ -1,18 +0,0 @@
import { chromium } from 'playwright';
import { preparePage, safeDisconnectBrowser } from './common/tabs.js';
(async () => {
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const { page } = await preparePage(browser, {
targetUrl: 'about:blank',
});
// Example: navigate and click an element
// await page.goto('https://example.com');
// await page.click('text=Change Model');
console.log('Change model script executed');
await safeDisconnectBrowser(browser);
process.exit(0);
})();

View File

@@ -1,18 +0,0 @@
import { chromium } from 'playwright';
import { preparePage, safeDisconnectBrowser } from './common/tabs.js';
(async () => {
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const { page } = await preparePage(browser, {
targetUrl: 'about:blank',
});
// Example: fill a form and submit
// await page.fill('input[name="username"]', 'test');
// await page.click('button[type="submit"]');
console.log('Pause resume script executed');
await safeDisconnectBrowser(browser);
process.exit(0);
})();

View File

@@ -1,18 +0,0 @@
import { chromium } from 'playwright';
import { preparePage, safeDisconnectBrowser } from './common/tabs.js';
(async () => {
const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
const { page } = await preparePage(browser, {
targetUrl: 'about:blank',
});
// Example: wait for a specific element or timeout
// await page.waitForSelector('[data-testid="status-paused"]');
// await page.waitForTimeout(2000);
console.log('Pause script executed');
await safeDisconnectBrowser(browser);
process.exit(0);
})();

View File

@@ -10,7 +10,6 @@ import type {
} from '@lib/script-types';
const META_FILENAME = 'scripts.meta.json';
const SEED_DIR = 'seed';
function getScriptsDir(): string {
return app.isPackaged
@@ -79,20 +78,16 @@ function seedScripts(): void {
return;
}
const seedDir = path.join(scriptsDir, SEED_DIR);
if (!fs.existsSync(seedDir)) {
log.info('[script-store-service] Seed directory does not exist, skipping seed.');
if (!fs.existsSync(scriptsDir)) {
log.info('[script-store-service] Scripts directory does not exist, skipping seed.');
return;
}
const meta: ScriptsMeta = { scripts: [] };
const seedFiles = fs.readdirSync(seedDir).filter((f) => f.endsWith('.mjs'));
const scriptFiles = fs.readdirSync(scriptsDir).filter((f) => f.endsWith('.mjs'));
for (const file of seedFiles) {
const seedPath = path.join(seedDir, file);
const destPath = path.join(scriptsDir, file);
for (const file of scriptFiles) {
try {
fs.copyFileSync(seedPath, destPath);
const name = file.replace(/\.mjs$/, '');
const now = new Date().toISOString();
meta.scripts.push({
@@ -106,7 +101,7 @@ function seedScripts(): void {
updatedAt: now,
});
} catch (err) {
log.warn('[script-store-service] Failed to copy seed file', file, err);
log.warn('[script-store-service] Failed to seed script', file, err);
}
}

View File

@@ -249,6 +249,8 @@ async function confirmDelete(id: string) {
confirmButtonText: t('common.delete', 'Delete'),
cancelButtonText: t('common.cancel', 'Cancel'),
type: 'warning',
lockScroll: false,
closeOnClickModal: false,
},
);
await store.deleteScript(id);