feat: 优化会展策划网站UI和添加Duoduo Agent设计流程展示
主要更新: - 统一所有页面导航栏样式为glass-morphism风格 - 添加Duoduo Agent智能设计系统完整可视化流程 - 展示从CAD到展位概念的5个设计阶段 - 优化页面交互效果和用户体验 详细修改: - web_frontend/web_result/pages/: 统一6个页面导航栏样式 - operation.html: 新增Duoduo Agent设计流程展示模块 - 添加5张设计阶段图片展示 (CAD/概念/白模/渲染/最终方案) - 增强视觉效果和动画交互 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
BIN
web_frontend/exhibition-demo/image/Agent_BG.jpg
Normal file
BIN
web_frontend/exhibition-demo/image/Agent_BG.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 514 KiB |
15
web_frontend/exhibition-demo/node_modules/.package-lock.json
generated
vendored
15
web_frontend/exhibition-demo/node_modules/.package-lock.json
generated
vendored
@@ -2121,6 +2121,21 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
||||
|
||||
22
web_frontend/exhibition-demo/node_modules/fsevents/LICENSE
generated
vendored
Normal file
22
web_frontend/exhibition-demo/node_modules/fsevents/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
-----------
|
||||
|
||||
Copyright (C) 2010-2020 by Philipp Dunkel, Ben Noordhuis, Elan Shankar, Paul Miller
|
||||
|
||||
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.
|
||||
89
web_frontend/exhibition-demo/node_modules/fsevents/README.md
generated
vendored
Normal file
89
web_frontend/exhibition-demo/node_modules/fsevents/README.md
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
# fsevents
|
||||
|
||||
Native access to MacOS FSEvents in [Node.js](https://nodejs.org/)
|
||||
|
||||
The FSEvents API in MacOS allows applications to register for notifications of
|
||||
changes to a given directory tree. It is a very fast and lightweight alternative
|
||||
to kqueue.
|
||||
|
||||
This is a low-level library. For a cross-platform file watching module that
|
||||
uses fsevents, check out [Chokidar](https://github.com/paulmillr/chokidar).
|
||||
|
||||
## Usage
|
||||
|
||||
```sh
|
||||
npm install fsevents
|
||||
```
|
||||
|
||||
Supports only **Node.js v8.16 and higher**.
|
||||
|
||||
```js
|
||||
const fsevents = require('fsevents');
|
||||
|
||||
// To start observation
|
||||
const stop = fsevents.watch(__dirname, (path, flags, id) => {
|
||||
const info = fsevents.getInfo(path, flags);
|
||||
});
|
||||
|
||||
// To end observation
|
||||
stop();
|
||||
```
|
||||
|
||||
> **Important note:** The API behaviour is slightly different from typical JS APIs. The `stop` function **must** be
|
||||
> retrieved and stored somewhere, even if you don't plan to stop the watcher. If you forget it, the garbage collector
|
||||
> will eventually kick in, the watcher will be unregistered, and your callbacks won't be called anymore.
|
||||
|
||||
The callback passed as the second parameter to `.watch` get's called whenever the operating system detects a
|
||||
a change in the file system. It takes three arguments:
|
||||
|
||||
###### `fsevents.watch(dirname: string, (path: string, flags: number, id: string) => void): () => Promise<undefined>`
|
||||
|
||||
* `path: string` - the item in the filesystem that have been changed
|
||||
* `flags: number` - a numeric value describing what the change was
|
||||
* `id: string` - an unique-id identifying this specific event
|
||||
|
||||
Returns closer callback which when called returns a Promise resolving when the watcher process has been shut down.
|
||||
|
||||
###### `fsevents.getInfo(path: string, flags: number, id: string): FsEventInfo`
|
||||
|
||||
The `getInfo` function takes the `path`, `flags` and `id` arguments and converts those parameters into a structure
|
||||
that is easier to digest to determine what the change was.
|
||||
|
||||
The `FsEventsInfo` has the following shape:
|
||||
|
||||
```js
|
||||
/**
|
||||
* @typedef {'created'|'modified'|'deleted'|'moved'|'root-changed'|'cloned'|'unknown'} FsEventsEvent
|
||||
* @typedef {'file'|'directory'|'symlink'} FsEventsType
|
||||
*/
|
||||
{
|
||||
"event": "created", // {FsEventsEvent}
|
||||
"path": "file.txt",
|
||||
"type": "file", // {FsEventsType}
|
||||
"changes": {
|
||||
"inode": true, // Had iNode Meta-Information changed
|
||||
"finder": false, // Had Finder Meta-Data changed
|
||||
"access": false, // Had access permissions changed
|
||||
"xattrs": false // Had xAttributes changed
|
||||
},
|
||||
"flags": 0x100000000
|
||||
}
|
||||
```
|
||||
|
||||
## Changelog
|
||||
|
||||
- v2.3 supports Apple Silicon ARM CPUs
|
||||
- v2 supports node 8.16+ and reduces package size massively
|
||||
- v1.2.8 supports node 6+
|
||||
- v1.2.7 supports node 4+
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- I'm getting `EBADPLATFORM` `Unsupported platform for fsevents` error.
|
||||
- It's fine, nothing is broken. fsevents is macos-only. Other platforms are skipped. If you want to hide this warning, report a bug to NPM bugtracker asking them to hide ebadplatform warnings by default.
|
||||
|
||||
## License
|
||||
|
||||
The MIT License Copyright (C) 2010-2020 by Philipp Dunkel, Ben Noordhuis, Elan Shankar, Paul Miller — see LICENSE file.
|
||||
|
||||
Visit our [GitHub page](https://github.com/fsevents/fsevents) and [NPM Page](https://npmjs.org/package/fsevents)
|
||||
46
web_frontend/exhibition-demo/node_modules/fsevents/fsevents.d.ts
generated
vendored
Normal file
46
web_frontend/exhibition-demo/node_modules/fsevents/fsevents.d.ts
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
declare type Event = "created" | "cloned" | "modified" | "deleted" | "moved" | "root-changed" | "unknown";
|
||||
declare type Type = "file" | "directory" | "symlink";
|
||||
declare type FileChanges = {
|
||||
inode: boolean;
|
||||
finder: boolean;
|
||||
access: boolean;
|
||||
xattrs: boolean;
|
||||
};
|
||||
declare type Info = {
|
||||
event: Event;
|
||||
path: string;
|
||||
type: Type;
|
||||
changes: FileChanges;
|
||||
flags: number;
|
||||
};
|
||||
declare type WatchHandler = (path: string, flags: number, id: string) => void;
|
||||
export declare function watch(path: string, handler: WatchHandler): () => Promise<void>;
|
||||
export declare function watch(path: string, since: number, handler: WatchHandler): () => Promise<void>;
|
||||
export declare function getInfo(path: string, flags: number): Info;
|
||||
export declare const constants: {
|
||||
None: 0x00000000;
|
||||
MustScanSubDirs: 0x00000001;
|
||||
UserDropped: 0x00000002;
|
||||
KernelDropped: 0x00000004;
|
||||
EventIdsWrapped: 0x00000008;
|
||||
HistoryDone: 0x00000010;
|
||||
RootChanged: 0x00000020;
|
||||
Mount: 0x00000040;
|
||||
Unmount: 0x00000080;
|
||||
ItemCreated: 0x00000100;
|
||||
ItemRemoved: 0x00000200;
|
||||
ItemInodeMetaMod: 0x00000400;
|
||||
ItemRenamed: 0x00000800;
|
||||
ItemModified: 0x00001000;
|
||||
ItemFinderInfoMod: 0x00002000;
|
||||
ItemChangeOwner: 0x00004000;
|
||||
ItemXattrMod: 0x00008000;
|
||||
ItemIsFile: 0x00010000;
|
||||
ItemIsDir: 0x00020000;
|
||||
ItemIsSymlink: 0x00040000;
|
||||
ItemIsHardlink: 0x00100000;
|
||||
ItemIsLastHardlink: 0x00200000;
|
||||
OwnEvent: 0x00080000;
|
||||
ItemCloned: 0x00400000;
|
||||
};
|
||||
export {};
|
||||
83
web_frontend/exhibition-demo/node_modules/fsevents/fsevents.js
generated
vendored
Normal file
83
web_frontend/exhibition-demo/node_modules/fsevents/fsevents.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** © 2020 by Philipp Dunkel, Ben Noordhuis, Elan Shankar, Paul Miller
|
||||
** Licensed under MIT License.
|
||||
*/
|
||||
|
||||
/* jshint node:true */
|
||||
"use strict";
|
||||
|
||||
if (process.platform !== "darwin") {
|
||||
throw new Error(`Module 'fsevents' is not compatible with platform '${process.platform}'`);
|
||||
}
|
||||
|
||||
const Native = require("./fsevents.node");
|
||||
const events = Native.constants;
|
||||
|
||||
function watch(path, since, handler) {
|
||||
if (typeof path !== "string") {
|
||||
throw new TypeError(`fsevents argument 1 must be a string and not a ${typeof path}`);
|
||||
}
|
||||
if ("function" === typeof since && "undefined" === typeof handler) {
|
||||
handler = since;
|
||||
since = Native.flags.SinceNow;
|
||||
}
|
||||
if (typeof since !== "number") {
|
||||
throw new TypeError(`fsevents argument 2 must be a number and not a ${typeof since}`);
|
||||
}
|
||||
if (typeof handler !== "function") {
|
||||
throw new TypeError(`fsevents argument 3 must be a function and not a ${typeof handler}`);
|
||||
}
|
||||
|
||||
let instance = Native.start(Native.global, path, since, handler);
|
||||
if (!instance) throw new Error(`could not watch: ${path}`);
|
||||
return () => {
|
||||
const result = instance ? Promise.resolve(instance).then(Native.stop) : Promise.resolve(undefined);
|
||||
instance = undefined;
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
function getInfo(path, flags) {
|
||||
return {
|
||||
path,
|
||||
flags,
|
||||
event: getEventType(flags),
|
||||
type: getFileType(flags),
|
||||
changes: getFileChanges(flags),
|
||||
};
|
||||
}
|
||||
|
||||
function getFileType(flags) {
|
||||
if (events.ItemIsFile & flags) return "file";
|
||||
if (events.ItemIsDir & flags) return "directory";
|
||||
if (events.MustScanSubDirs & flags) return "directory";
|
||||
if (events.ItemIsSymlink & flags) return "symlink";
|
||||
}
|
||||
function anyIsTrue(obj) {
|
||||
for (let key in obj) {
|
||||
if (obj[key]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function getEventType(flags) {
|
||||
if (events.ItemRemoved & flags) return "deleted";
|
||||
if (events.ItemRenamed & flags) return "moved";
|
||||
if (events.ItemCreated & flags) return "created";
|
||||
if (events.ItemModified & flags) return "modified";
|
||||
if (events.RootChanged & flags) return "root-changed";
|
||||
if (events.ItemCloned & flags) return "cloned";
|
||||
if (anyIsTrue(flags)) return "modified";
|
||||
return "unknown";
|
||||
}
|
||||
function getFileChanges(flags) {
|
||||
return {
|
||||
inode: !!(events.ItemInodeMetaMod & flags),
|
||||
finder: !!(events.ItemFinderInfoMod & flags),
|
||||
access: !!(events.ItemChangeOwner & flags),
|
||||
xattrs: !!(events.ItemXattrMod & flags),
|
||||
};
|
||||
}
|
||||
|
||||
exports.watch = watch;
|
||||
exports.getInfo = getInfo;
|
||||
exports.constants = events;
|
||||
BIN
web_frontend/exhibition-demo/node_modules/fsevents/fsevents.node
generated
vendored
Executable file
BIN
web_frontend/exhibition-demo/node_modules/fsevents/fsevents.node
generated
vendored
Executable file
Binary file not shown.
62
web_frontend/exhibition-demo/node_modules/fsevents/package.json
generated
vendored
Normal file
62
web_frontend/exhibition-demo/node_modules/fsevents/package.json
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"name": "fsevents",
|
||||
"version": "2.3.3",
|
||||
"description": "Native Access to MacOS FSEvents",
|
||||
"main": "fsevents.js",
|
||||
"types": "fsevents.d.ts",
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"files": [
|
||||
"fsevents.d.ts",
|
||||
"fsevents.js",
|
||||
"fsevents.node"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "node-gyp clean && rm -f fsevents.node",
|
||||
"build": "node-gyp clean && rm -f fsevents.node && node-gyp rebuild && node-gyp clean",
|
||||
"test": "/bin/bash ./test.sh 2>/dev/null",
|
||||
"prepublishOnly": "npm run build"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fsevents/fsevents.git"
|
||||
},
|
||||
"keywords": [
|
||||
"fsevents",
|
||||
"mac"
|
||||
],
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Philipp Dunkel",
|
||||
"email": "pip@pipobscure.com"
|
||||
},
|
||||
{
|
||||
"name": "Ben Noordhuis",
|
||||
"email": "info@bnoordhuis.nl"
|
||||
},
|
||||
{
|
||||
"name": "Elan Shankar",
|
||||
"email": "elan.shanker@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Miroslav Bajtoš",
|
||||
"email": "mbajtoss@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Paul Miller",
|
||||
"url": "https://paulmillr.com"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/fsevents/fsevents/issues"
|
||||
},
|
||||
"homepage": "https://github.com/fsevents/fsevents",
|
||||
"devDependencies": {
|
||||
"node-gyp": "^9.4.0"
|
||||
}
|
||||
}
|
||||
@@ -142,7 +142,7 @@ const ResultModal: React.FC<ResultModalProps> = ({ isOpen, onClose, onViewDetail
|
||||
{/* 操作按钮 */}
|
||||
<div className="flex gap-3">
|
||||
<a
|
||||
href="../../web_result/index.html"
|
||||
href="../web_result/index.html"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex-1 px-6 py-3 bg-gradient-to-r from-blue-600 to-purple-600 text-white rounded-xl font-medium hover:shadow-lg transform hover:scale-105 transition-all flex items-center justify-center gap-2"
|
||||
|
||||
@@ -8,8 +8,25 @@ interface LandingPageProps {
|
||||
|
||||
const LandingPage: React.FC<LandingPageProps> = ({ onStart }) => {
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center p-8">
|
||||
<div className="max-w-4xl w-full">
|
||||
<div className="min-h-screen flex items-center justify-center p-8 relative">
|
||||
{/* 背景图片和蒙版 */}
|
||||
<div className="absolute inset-0 z-0">
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
backgroundImage: 'url(/images/博览会.jpg)',
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
opacity: 0.08
|
||||
}}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-gray-900/50 via-purple-900/30 to-blue-900/40" />
|
||||
<div className="absolute inset-0 backdrop-blur-sm" />
|
||||
</div>
|
||||
|
||||
{/* 主内容 */}
|
||||
<div className="max-w-4xl w-full relative z-10">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
@@ -33,7 +50,7 @@ const LandingPage: React.FC<LandingPageProps> = ({ onStart }) => {
|
||||
transition={{ delay: 0.4 }}
|
||||
>
|
||||
<h1 className="text-6xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent">
|
||||
AI 会展策划系统
|
||||
DuoDuo Agent
|
||||
</h1>
|
||||
<p className="mt-4 text-xl text-neutral-600 dark:text-neutral-400">
|
||||
多Agent协同 · 智能生成 · 专业方案
|
||||
|
||||
@@ -767,11 +767,28 @@ const WorkflowPageV4 = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="h-screen bg-gray-50 flex flex-col">
|
||||
<div className="h-screen bg-gray-50 flex flex-col relative">
|
||||
{/* 背景图片和蒙版 */}
|
||||
<div className="absolute inset-0 z-0">
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
backgroundImage: 'url(/images/Whisk_e8f83d1a37.jpg)',
|
||||
backgroundSize: 'cover',
|
||||
backgroundPosition: 'center',
|
||||
backgroundRepeat: 'no-repeat',
|
||||
opacity: 0.15
|
||||
}}
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-gray-900/30 via-purple-900/20 to-blue-900/30" />
|
||||
</div>
|
||||
|
||||
{/* 主内容容器 */}
|
||||
<div className="relative z-10 h-full flex flex-col">
|
||||
{/* 顶部控制栏 */}
|
||||
<div className="bg-white border-b border-gray-200 px-6 py-3 flex items-center justify-between">
|
||||
<div className="flex items-center gap-4">
|
||||
<h1 className="text-lg font-semibold text-gray-900">AI会展策划系统 - 多Agent协同演示</h1>
|
||||
<h1 className="text-lg font-semibold text-gray-900">DuoDuo Agent - 多智能体协同生成·专业方案</h1>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={status === 'idle' ? () => setShowRequirementModal(true) : pauseDemo}
|
||||
@@ -809,9 +826,9 @@ const WorkflowPageV4 = () => {
|
||||
</div>
|
||||
|
||||
{/* 主内容区 */}
|
||||
<div className="flex-1 flex overflow-hidden">
|
||||
<div className="flex-1 flex overflow-hidden backdrop-blur-sm">
|
||||
{/* 左侧:n8n工作流 */}
|
||||
<div className="w-1/2 border-r border-gray-200 bg-white flex flex-col">
|
||||
<div className="w-1/2 border-r border-gray-200 bg-white/95 backdrop-blur-md flex flex-col">
|
||||
<div className="px-4 py-2 border-b border-gray-200 flex items-center justify-between bg-gray-50">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-3 h-3 rounded-full bg-green-500"></div>
|
||||
@@ -1026,6 +1043,7 @@ const WorkflowPageV4 = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 弹窗组件 */}
|
||||
<RequirementModal
|
||||
|
||||
Reference in New Issue
Block a user