chore: restructure project and add i18n support

- Reorganize project structure with new electron and shared directories
- Add comprehensive i18n support with Chinese, English, and Japanese locales
- Update build configurations and TypeScript paths for new structure
- Add various UI components including chat interface and task management
- Include Windows release binaries and localization files
- Update dependencies and fix import paths throughout the codebase
This commit is contained in:
duanshuwen
2026-04-06 14:39:06 +08:00
parent e76b034d50
commit 6615d11dd6
311 changed files with 823682 additions and 4460 deletions

Binary file not shown.

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="Content-Security-Policy" content="script-src 'self';">
<style>
:root {
--stop-color-start: #3b82f6;
--stop-color-end: #1d4ed8;
}
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background-color: transparent;
}
</style>
</head>
<body>
<svg width="30" height="30" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="gradient" x1="8.042%" y1="0%" x2="65.682%" y2="23.865%">
<stop stop-color="var(--stop-color-start)" offset="0%" />
<stop stop-color="var(--stop-color-end)" offset="100%" />
</linearGradient>
</defs>
<g fill="none" fill-rule="evenodd">
<g transform="translate(1 1)" stroke-width="2">
<circle stroke-opacity=".2" cx="18" cy="18" r="18" />
<path d="M36 18c0-9.94-8.06-18-18-18" stroke="url(#gradient)">
<animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="1s"
repeatCount="indefinite" />
</path>
</g>
</g>
</svg>
</body>
</html>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,138 @@
const normalizeUrl = (value) => {
const raw = String(value || '').trim();
if (!raw) return null;
try {
return new URL(raw);
} catch {
return null;
}
};
const isSameTarget = (currentUrl, targetUrl) => {
if (!currentUrl || !targetUrl) return false;
if (currentUrl.startsWith(targetUrl)) return true;
const current = normalizeUrl(currentUrl);
const target = normalizeUrl(targetUrl);
if (!current || !target) return false;
if (current.origin !== target.origin) return false;
if (!current.pathname.startsWith(target.pathname)) return false;
return true;
};
const isSameOrigin = (currentUrl, targetUrl) => {
const current = normalizeUrl(currentUrl);
const target = normalizeUrl(targetUrl);
if (!current || !target) return false;
return current.origin === target.origin;
};
const isBlankLikePage = (url) => {
const u = String(url || '').trim().toLowerCase();
if (!u) return true;
if (u === 'about:blank' || u.startsWith('about:blank#') || u.startsWith('about:blank?')) return true;
if (u === 'chrome://newtab/' || u.startsWith('chrome://newtab')) return true;
if (u.startsWith('chrome://new-tab-page')) return true;
return false;
};
const preparePage = async (
chromium,
{
tabIndex = Number(process.env.TAB_INDEX),
endpoint = process.env.CDP_ENDPOINT || 'http://127.0.0.1:9222',
targetUrl,
} = {},
) => {
const browser = await chromium.connectOverCDP(endpoint);
const context = browser.contexts()[0];
if (!context) {
throw new Error('No browser context available');
}
await context.addInitScript(() => {
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
});
let pages = await context.pages();
let page = null;
if (targetUrl) {
// 1. Try exact/path match
for (let i = 0; i < pages.length; i++) {
const p = pages[i];
if (isSameTarget(p.url(), targetUrl)) {
page = p;
break;
}
}
// 2. Try origin match
if (!page) {
for (let i = 0; i < pages.length; i++) {
const p = pages[i];
if (isSameOrigin(p.url(), targetUrl)) {
page = p;
break;
}
}
}
}
if (!page) {
const isTabIndexSet = Number.isFinite(tabIndex) && tabIndex >= 0;
// If targetUrl provided and NO specific tabIndex requested, avoid hijacking tab 0
if (targetUrl && !isTabIndexSet) {
// Try blank page
for (let i = 0; i < pages.length; i++) {
if (isBlankLikePage(pages[i].url())) {
page = pages[i];
break;
}
}
// Else new page
if (!page) {
page = await context.newPage();
}
} else {
// Legacy/Default behavior: use tabIndex (default 0)
const idx = isTabIndexSet ? Math.floor(tabIndex) : 0;
while (pages.length <= idx) {
await context.newPage();
pages = await context.pages();
}
page = pages[idx];
}
}
await page.bringToFront();
if (targetUrl) {
const currentUrl = page.url();
if (!currentUrl || !isSameTarget(currentUrl, targetUrl)) {
await page.goto(targetUrl, { waitUntil: 'domcontentloaded' });
}
}
return { browser, context, page };
};
const safeDisconnectBrowser = async (browser) => {
if (!browser) return;
try {
if (typeof browser.disconnect === 'function') {
await browser.disconnect();
} else {
await browser.close();
}
} catch {}
};
module.exports = {
preparePage,
safeDisconnectBrowser,
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,348 @@
```json
{
"code": 0,
"msg": null,
"data": [
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:19",
"id": "0d6898fb7105419f895e2153e48df115",
"pmsName": "亲子太空舱",
"xcName": "亲子太空舱",
"fzName": "亲子太空舱",
"mtName": "亲子太空舱",
"dyHotelName": "亲子太空舱-含私汤",
"dyHotSrpingName": "亲子太空舱-含私汤",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:20",
"id": "1c3616b31de946ee868f74b550e9a88f",
"pmsName": "豪华特色",
"xcName": "豪华特色房",
"fzName": "豪华特色房(麻将)",
"mtName": "豪华特色房",
"dyHotelName": "豪华特色房",
"dyHotSrpingName": "豪华特色房(含双人温泉,入住期间不限次)",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:21",
"id": "2cfdf51d2cff4384ba53a0fa5b8a6c77",
"pmsName": "行政套房A",
"xcName": "行政套房A",
"fzName": "行政套房A",
"mtName": "行政套房A",
"dyHotelName": "行政套房A",
"dyHotSrpingName": "行政套房A含双人温泉入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:22",
"id": "30ca794cc12743a19e6a2a8483838234",
"pmsName": "亲子房",
"xcName": "亲子房",
"fzName": "亲子房",
"mtName": "亲子房",
"dyHotelName": "亲子房",
"dyHotSrpingName": "亲子房(含三人温泉,入住期间不限次)",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:24",
"id": "4b307fd07e34483083f47d5ed32d9a26",
"pmsName": "太空舱",
"xcName": "太空舱(含私汤)",
"fzName": "太空舱",
"mtName": "太空舱(私汤)",
"dyHotelName": "太空舱",
"dyHotSrpingName": "太空舱(含双人温泉、入住期间不限次)",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:23",
"id": "4b77c93f42d34f7fa588a223dd1e1762",
"pmsName": "豪华行政套房",
"xcName": "",
"fzName": "",
"mtName": "",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:26",
"id": "53b3c2a68dd844cb8f8d4f339ce521ef",
"pmsName": "至大",
"xcName": "至尊大床房(含私汤)",
"fzName": "和雅小筑-至尊大床房(户外泡池)",
"mtName": "至尊大床房",
"dyHotelName": "",
"dyHotSrpingName": "至尊大床房-私汤",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:26",
"id": "5cd720a6ed124c11a2ef61f1eef5a98d",
"pmsName": "行政套房B",
"xcName": "行政套房B含私汤",
"fzName": "行政套房B",
"mtName": "",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:27",
"id": "76d9ff061da54e1f9ff1afd663dd22a5",
"pmsName": "汤墅会馆",
"xcName": "汤墅会馆(含私汤)",
"fzName": "汤墅会馆",
"mtName": "汤墅会馆(私汤)",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:28",
"id": "7a21366f0ed3421592a3ee6835e03433",
"pmsName": "高级家庭套房",
"xcName": "高级家庭套房",
"fzName": "",
"mtName": "",
"dyHotelName": "高级家庭套房",
"dyHotSrpingName": "高级家庭套房",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:30",
"id": "822bede1a81641e6853a6f6313185b85",
"pmsName": "高级标准间",
"xcName": "高级标准间",
"fzName": "高级标准间",
"mtName": "高级标准间",
"dyHotelName": "高级标准间",
"dyHotSrpingName": "高级标准间(含双人温泉,入住期间不限次)",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:29",
"id": "88bfd80b66454f14bb0fe2ea61cee7b3",
"pmsName": "至尊汤屋",
"xcName": "至尊养生汤屋(含私汤)",
"fzName": "至尊养生汤屋(含私汤)",
"mtName": "至尊养生汤屋(私汤)",
"dyHotelName": "至尊养生汤屋",
"dyHotSrpingName": "至尊养生汤屋-含双人温泉、入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:32",
"id": "9011e8d8d33945409344751132d21912",
"pmsName": "尊享豪大",
"xcName": "尊享豪华大床房(含私汤)",
"fzName": "豪华尊享大床房(双人温泉)",
"mtName": "尊享豪华大床房(私汤)",
"dyHotelName": "",
"dyHotSrpingName": "尊享豪华大床房-私汤",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:34",
"id": "94281bdcf8664a5bbcb3add6f62736fe",
"pmsName": "高级双人套房",
"xcName": "",
"fzName": "",
"mtName": "",
"dyHotelName": "高级双人套房",
"dyHotSrpingName": "高级双人套房-含双人温泉、入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:33",
"id": "a211b49ff3f94f5a8d8c30bf80f7289e",
"pmsName": "豪华至尊养生汤屋",
"xcName": "豪华至尊养生汤屋(含私汤)",
"fzName": "豪华至尊养生汤屋(私汤)",
"mtName": "豪华至尊养生汤屋(私汤)",
"dyHotelName": "豪华至尊养生汤屋",
"dyHotSrpingName": "豪华至尊养生汤屋",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:35",
"id": "b9042d303bbe4ee09a4ffb567692714a",
"pmsName": "豪华家庭套房",
"xcName": "",
"fzName": "",
"mtName": "",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:36",
"id": "bafb56cd74f44b44b836d727f5b604a7",
"pmsName": "豪华套房",
"xcName": "豪华套房(含私汤)",
"fzName": "天伦小筑-豪华套房(含私汤)",
"mtName": "豪华套房(私汤)",
"dyHotelName": "",
"dyHotSrpingName": "",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:37",
"id": "c03a339b407348438b056aca908b5580",
"pmsName": "雅致大床房",
"xcName": "雅致大床房",
"fzName": "",
"mtName": "",
"dyHotelName": "雅致大床",
"dyHotSrpingName": "雅致大床-房含双人温泉、入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:38",
"id": "c68fa888684641ff9be8e25b83e4e347",
"pmsName": "榻榻米双床房",
"xcName": "榻榻米双床房",
"fzName": "榻榻米双床房",
"mtName": "榻榻米双床房",
"dyHotelName": "榻榻米双床房",
"dyHotSrpingName": "榻榻米双床房-含双人温泉,入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
},
{
"createBy": "",
"createTime": "2026-03-07 04:48:15",
"updateBy": "",
"updateTime": "2026-03-07 14:22:39",
"id": "e6f8f7fb6f014a3a84f0a037df8544e6",
"pmsName": "雅致标准间",
"xcName": "雅致双床房",
"fzName": "雅致双床房",
"mtName": "",
"dyHotelName": "雅致标准间",
"dyHotSrpingName": "雅致标准间-含双人温泉、入住期间不限次",
"pcConfigId": "11",
"delFlag": 0,
"size": null,
"current": null
}
]
}
```