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

20
release/builder-debug.yml Normal file
View File

@@ -0,0 +1,20 @@
x64:
firstOrDefaultFilePatterns:
- '!**/node_modules/**'
- '!public{,/**/*}'
- '!release{,/**/*}'
- dist
- dist-electron
- package.json
- '!**/*.{iml,hprof,orig,pyc,pyo,rbc,swp,csproj,sln,suo,xproj,cc,d.ts,mk,a,o,obj,forge-meta,pdb}'
- '!**/._*'
- '!**/electron-builder.{yaml,yml,json,json5,toml,ts}'
- '!**/{.git,.hg,.svn,CVS,RCS,SCCS,__pycache__,.DS_Store,thumbs.db,.gitignore,.gitkeep,.gitattributes,.npmignore,.idea,.vs,.flowconfig,.jshintrc,.eslintrc,.circleci,.yarn-integrity,.yarn-metadata.json,yarn-error.log,yarn.lock,package-lock.json,npm-debug.log,pnpm-lock.yaml,bun.lock,bun.lockb,appveyor.yml,.travis.yml,circle.yml,.nyc_output,.husky,.github,electron-builder.env}'
- '!.yarn{,/**/*}'
- '!.editorconfig'
- '!.yarnrc.yml'
nodeModuleFilePatterns:
- '**/*'
- dist
- dist-electron
- package.json

View File

@@ -0,0 +1,99 @@
directories:
output: release
buildResources: public
appId: com.znkj.znai
productName: NIANXX
copyright: Copyright © 2026 智念科技
compression: maximum
artifactName: ${productName}-${version}-${os}-${arch}.${ext}
files:
- filter:
- dist
- dist-electron
- package.json
extraResources:
- from: public/
to: public/
filter:
- '**/*'
- from: src/main/scripts/
to: scripts/
filter:
- '**/*'
asar: true
asarUnpack:
- '**/*.node'
npmRebuild: false
afterPack: ./scripts/after-pack.cjs
mac:
category: public.app-category.productivity
icon: public/logo.icns
target:
- target: dmg
arch:
- x64
- arm64
- target: zip
arch:
- x64
- arm64
darkModeSupport: true
hardenedRuntime: true
gatekeeperAssess: false
entitlements: entitlements.mac.plist
entitlementsInherit: entitlements.mac.plist
notarize: false
dmg:
size: 1g
icon: public/logo.icns
iconSize: 100
window:
width: 540
height: 380
contents:
- type: file
x: 130
'y': 220
- type: link
path: /Applications
x: 410
'y': 220
win:
verifyUpdateCodeSignature: false
target:
- target: nsis
arch: x64
nsis:
oneClick: false
perMachine: false
warningsAsErrors: false
allowToChangeInstallationDirectory: true
deleteAppDataOnUninstall: false
differentialPackage: true
createDesktopShortcut: true
createStartMenuShortcut: true
shortcutName: NIANXX
uninstallDisplayName: NIANXX
license: LICENSE
linux:
icon: public/
target:
- target: AppImage
arch:
- x64
- target: deb
arch:
- x64
category: Utility
maintainer: 智念科技 <duanshuwen@gogpay.cn>
vendor: 智念科技
synopsis: 智念AI - 一款应用智能的多功能桌面应用
description: 智念AI是一款基于Electron的智能桌面应用提供AI助手、任务管理、数据分析等多种功能。
desktop:
entry:
Name: NIANXX
Comment: 智念AI - 智能桌面应用
Categories: Utility;Network;
Keywords: ai;assistant;automation;chat;
StartupWMClass: zn-ai
electronVersion: 40.8.5

View File

@@ -0,0 +1,21 @@
Copyright (c) Electron contributors
Copyright (c) 2013-2020 GitHub Inc.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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
}
]
}
```

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1 @@
{"file_format_version": "1.0.0", "ICD": {"library_path": ".\\vk_swiftshader.dll", "api_version": "1.0.5"}}

Binary file not shown.