feat:三个窗口接口联调版本
This commit is contained in:
@@ -20,6 +20,10 @@
|
|||||||
"@element-plus/icons-vue": "^2.3.2",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
"@jsplumb/browser-ui": "^6.2.10",
|
"@jsplumb/browser-ui": "^6.2.10",
|
||||||
"@types/markdown-it": "^14.1.2",
|
"@types/markdown-it": "^14.1.2",
|
||||||
|
"@vue-flow/background": "^1.3.2",
|
||||||
|
"@vue-flow/controls": "^1.1.3",
|
||||||
|
"@vue-flow/core": "^1.48.1",
|
||||||
|
"@vue-flow/minimap": "^1.5.4",
|
||||||
"@vueuse/core": "^14.0.0",
|
"@vueuse/core": "^14.0.0",
|
||||||
"axios": "^1.12.2",
|
"axios": "^1.12.2",
|
||||||
"dompurify": "^3.3.0",
|
"dompurify": "^3.3.0",
|
||||||
|
|||||||
195
frontend/pnpm-lock.yaml
generated
195
frontend/pnpm-lock.yaml
generated
@@ -17,6 +17,18 @@ importers:
|
|||||||
'@types/markdown-it':
|
'@types/markdown-it':
|
||||||
specifier: ^14.1.2
|
specifier: ^14.1.2
|
||||||
version: 14.1.2
|
version: 14.1.2
|
||||||
|
'@vue-flow/background':
|
||||||
|
specifier: ^1.3.2
|
||||||
|
version: 1.3.2(@vue-flow/core@1.48.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
|
||||||
|
'@vue-flow/controls':
|
||||||
|
specifier: ^1.1.3
|
||||||
|
version: 1.1.3(@vue-flow/core@1.48.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
|
||||||
|
'@vue-flow/core':
|
||||||
|
specifier: ^1.48.1
|
||||||
|
version: 1.48.1(vue@3.5.25(typescript@5.9.3))
|
||||||
|
'@vue-flow/minimap':
|
||||||
|
specifier: ^1.5.4
|
||||||
|
version: 1.5.4(@vue-flow/core@1.48.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
|
||||||
'@vueuse/core':
|
'@vueuse/core':
|
||||||
specifier: ^14.0.0
|
specifier: ^14.0.0
|
||||||
version: 14.1.0(vue@3.5.25(typescript@5.9.3))
|
version: 14.1.0(vue@3.5.25(typescript@5.9.3))
|
||||||
@@ -625,36 +637,42 @@ packages:
|
|||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@parcel/watcher-linux-arm-musl@2.5.1':
|
'@parcel/watcher-linux-arm-musl@2.5.1':
|
||||||
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
|
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@parcel/watcher-linux-arm64-glibc@2.5.1':
|
'@parcel/watcher-linux-arm64-glibc@2.5.1':
|
||||||
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
|
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@parcel/watcher-linux-arm64-musl@2.5.1':
|
'@parcel/watcher-linux-arm64-musl@2.5.1':
|
||||||
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
|
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@parcel/watcher-linux-x64-glibc@2.5.1':
|
'@parcel/watcher-linux-x64-glibc@2.5.1':
|
||||||
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
|
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@parcel/watcher-linux-x64-musl@2.5.1':
|
'@parcel/watcher-linux-x64-musl@2.5.1':
|
||||||
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
|
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
|
||||||
engines: {node: '>= 10.0.0'}
|
engines: {node: '>= 10.0.0'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@parcel/watcher-win32-arm64@2.5.1':
|
'@parcel/watcher-win32-arm64@2.5.1':
|
||||||
resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==}
|
resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==}
|
||||||
@@ -726,56 +744,67 @@ packages:
|
|||||||
resolution: {integrity: sha512-UPMMNeC4LXW7ZSHxeP3Edv09aLsFUMaD1TSVW6n1CWMECnUIJMFFB7+XC2lZTdPtvB36tYC0cJWc86mzSsaviw==}
|
resolution: {integrity: sha512-UPMMNeC4LXW7ZSHxeP3Edv09aLsFUMaD1TSVW6n1CWMECnUIJMFFB7+XC2lZTdPtvB36tYC0cJWc86mzSsaviw==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-musleabihf@4.53.4':
|
'@rollup/rollup-linux-arm-musleabihf@4.53.4':
|
||||||
resolution: {integrity: sha512-H8uwlV0otHs5Q7WAMSoyvjV9DJPiy5nJ/xnHolY0QptLPjaSsuX7tw+SPIfiYH6cnVx3fe4EWFafo6gH6ekZKA==}
|
resolution: {integrity: sha512-H8uwlV0otHs5Q7WAMSoyvjV9DJPiy5nJ/xnHolY0QptLPjaSsuX7tw+SPIfiYH6cnVx3fe4EWFafo6gH6ekZKA==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-gnu@4.53.4':
|
'@rollup/rollup-linux-arm64-gnu@4.53.4':
|
||||||
resolution: {integrity: sha512-BLRwSRwICXz0TXkbIbqJ1ibK+/dSBpTJqDClF61GWIrxTXZWQE78ROeIhgl5MjVs4B4gSLPCFeD4xML9vbzvCQ==}
|
resolution: {integrity: sha512-BLRwSRwICXz0TXkbIbqJ1ibK+/dSBpTJqDClF61GWIrxTXZWQE78ROeIhgl5MjVs4B4gSLPCFeD4xML9vbzvCQ==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-musl@4.53.4':
|
'@rollup/rollup-linux-arm64-musl@4.53.4':
|
||||||
resolution: {integrity: sha512-6bySEjOTbmVcPJAywjpGLckK793A0TJWSbIa0sVwtVGfe/Nz6gOWHOwkshUIAp9j7wg2WKcA4Snu7Y1nUZyQew==}
|
resolution: {integrity: sha512-6bySEjOTbmVcPJAywjpGLckK793A0TJWSbIa0sVwtVGfe/Nz6gOWHOwkshUIAp9j7wg2WKcA4Snu7Y1nUZyQew==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@rollup/rollup-linux-loong64-gnu@4.53.4':
|
'@rollup/rollup-linux-loong64-gnu@4.53.4':
|
||||||
resolution: {integrity: sha512-U0ow3bXYJZ5MIbchVusxEycBw7bO6C2u5UvD31i5IMTrnt2p4Fh4ZbHSdc/31TScIJQYHwxbj05BpevB3201ug==}
|
resolution: {integrity: sha512-U0ow3bXYJZ5MIbchVusxEycBw7bO6C2u5UvD31i5IMTrnt2p4Fh4ZbHSdc/31TScIJQYHwxbj05BpevB3201ug==}
|
||||||
cpu: [loong64]
|
cpu: [loong64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-ppc64-gnu@4.53.4':
|
'@rollup/rollup-linux-ppc64-gnu@4.53.4':
|
||||||
resolution: {integrity: sha512-iujDk07ZNwGLVn0YIWM80SFN039bHZHCdCCuX9nyx3Jsa2d9V/0Y32F+YadzwbvDxhSeVo9zefkoPnXEImnM5w==}
|
resolution: {integrity: sha512-iujDk07ZNwGLVn0YIWM80SFN039bHZHCdCCuX9nyx3Jsa2d9V/0Y32F+YadzwbvDxhSeVo9zefkoPnXEImnM5w==}
|
||||||
cpu: [ppc64]
|
cpu: [ppc64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-gnu@4.53.4':
|
'@rollup/rollup-linux-riscv64-gnu@4.53.4':
|
||||||
resolution: {integrity: sha512-MUtAktiOUSu+AXBpx1fkuG/Bi5rhlorGs3lw5QeJ2X3ziEGAq7vFNdWVde6XGaVqi0LGSvugwjoxSNJfHFTC0g==}
|
resolution: {integrity: sha512-MUtAktiOUSu+AXBpx1fkuG/Bi5rhlorGs3lw5QeJ2X3ziEGAq7vFNdWVde6XGaVqi0LGSvugwjoxSNJfHFTC0g==}
|
||||||
cpu: [riscv64]
|
cpu: [riscv64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-musl@4.53.4':
|
'@rollup/rollup-linux-riscv64-musl@4.53.4':
|
||||||
resolution: {integrity: sha512-btm35eAbDfPtcFEgaXCI5l3c2WXyzwiE8pArhd66SDtoLWmgK5/M7CUxmUglkwtniPzwvWioBKKl6IXLbPf2sQ==}
|
resolution: {integrity: sha512-btm35eAbDfPtcFEgaXCI5l3c2WXyzwiE8pArhd66SDtoLWmgK5/M7CUxmUglkwtniPzwvWioBKKl6IXLbPf2sQ==}
|
||||||
cpu: [riscv64]
|
cpu: [riscv64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@rollup/rollup-linux-s390x-gnu@4.53.4':
|
'@rollup/rollup-linux-s390x-gnu@4.53.4':
|
||||||
resolution: {integrity: sha512-uJlhKE9ccUTCUlK+HUz/80cVtx2RayadC5ldDrrDUFaJK0SNb8/cCmC9RhBhIWuZ71Nqj4Uoa9+xljKWRogdhA==}
|
resolution: {integrity: sha512-uJlhKE9ccUTCUlK+HUz/80cVtx2RayadC5ldDrrDUFaJK0SNb8/cCmC9RhBhIWuZ71Nqj4Uoa9+xljKWRogdhA==}
|
||||||
cpu: [s390x]
|
cpu: [s390x]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-gnu@4.53.4':
|
'@rollup/rollup-linux-x64-gnu@4.53.4':
|
||||||
resolution: {integrity: sha512-jjEMkzvASQBbzzlzf4os7nzSBd/cvPrpqXCUOqoeCh1dQ4BP3RZCJk8XBeik4MUln3m+8LeTJcY54C/u8wb3DQ==}
|
resolution: {integrity: sha512-jjEMkzvASQBbzzlzf4os7nzSBd/cvPrpqXCUOqoeCh1dQ4BP3RZCJk8XBeik4MUln3m+8LeTJcY54C/u8wb3DQ==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-musl@4.53.4':
|
'@rollup/rollup-linux-x64-musl@4.53.4':
|
||||||
resolution: {integrity: sha512-lu90KG06NNH19shC5rBPkrh6mrTpq5kviFylPBXQVpdEu0yzb0mDgyxLr6XdcGdBIQTH/UAhDJnL+APZTBu1aQ==}
|
resolution: {integrity: sha512-lu90KG06NNH19shC5rBPkrh6mrTpq5kviFylPBXQVpdEu0yzb0mDgyxLr6XdcGdBIQTH/UAhDJnL+APZTBu1aQ==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@rollup/rollup-openharmony-arm64@4.53.4':
|
'@rollup/rollup-openharmony-arm64@4.53.4':
|
||||||
resolution: {integrity: sha512-dFDcmLwsUzhAm/dn0+dMOQZoONVYBtgik0VuY/d5IJUUb787L3Ko/ibvTvddqhb3RaB7vFEozYevHN4ox22R/w==}
|
resolution: {integrity: sha512-dFDcmLwsUzhAm/dn0+dMOQZoONVYBtgik0VuY/d5IJUUb787L3Ko/ibvTvddqhb3RaB7vFEozYevHN4ox22R/w==}
|
||||||
@@ -846,24 +875,28 @@ packages:
|
|||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@tailwindcss/oxide-linux-arm64-musl@4.1.18':
|
'@tailwindcss/oxide-linux-arm64-musl@4.1.18':
|
||||||
resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==}
|
resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@tailwindcss/oxide-linux-x64-gnu@4.1.18':
|
'@tailwindcss/oxide-linux-x64-gnu@4.1.18':
|
||||||
resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==}
|
resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
'@tailwindcss/oxide-linux-x64-musl@4.1.18':
|
'@tailwindcss/oxide-linux-x64-musl@4.1.18':
|
||||||
resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==}
|
resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==}
|
||||||
engines: {node: '>= 10'}
|
engines: {node: '>= 10'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
'@tailwindcss/oxide-wasm32-wasi@4.1.18':
|
'@tailwindcss/oxide-wasm32-wasi@4.1.18':
|
||||||
resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==}
|
resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==}
|
||||||
@@ -956,6 +989,9 @@ packages:
|
|||||||
'@types/web-bluetooth@0.0.16':
|
'@types/web-bluetooth@0.0.16':
|
||||||
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
|
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
|
||||||
|
|
||||||
|
'@types/web-bluetooth@0.0.20':
|
||||||
|
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
|
||||||
|
|
||||||
'@types/web-bluetooth@0.0.21':
|
'@types/web-bluetooth@0.0.21':
|
||||||
resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
|
resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
|
||||||
|
|
||||||
@@ -1076,6 +1112,29 @@ packages:
|
|||||||
'@volar/typescript@2.4.26':
|
'@volar/typescript@2.4.26':
|
||||||
resolution: {integrity: sha512-N87ecLD48Sp6zV9zID/5yuS1+5foj0DfuYGdQ6KHj/IbKvyKv1zNX6VCmnKYwtmHadEO6mFc2EKISiu3RDPAvA==}
|
resolution: {integrity: sha512-N87ecLD48Sp6zV9zID/5yuS1+5foj0DfuYGdQ6KHj/IbKvyKv1zNX6VCmnKYwtmHadEO6mFc2EKISiu3RDPAvA==}
|
||||||
|
|
||||||
|
'@vue-flow/background@1.3.2':
|
||||||
|
resolution: {integrity: sha512-eJPhDcLj1wEo45bBoqTXw1uhl0yK2RaQGnEINqvvBsAFKh/camHJd5NPmOdS1w+M9lggc9igUewxaEd3iCQX2w==}
|
||||||
|
peerDependencies:
|
||||||
|
'@vue-flow/core': ^1.23.0
|
||||||
|
vue: ^3.3.0
|
||||||
|
|
||||||
|
'@vue-flow/controls@1.1.3':
|
||||||
|
resolution: {integrity: sha512-XCf+G+jCvaWURdFlZmOjifZGw3XMhN5hHlfMGkWh9xot+9nH9gdTZtn+ldIJKtarg3B21iyHU8JjKDhYcB6JMw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@vue-flow/core': ^1.23.0
|
||||||
|
vue: ^3.3.0
|
||||||
|
|
||||||
|
'@vue-flow/core@1.48.1':
|
||||||
|
resolution: {integrity: sha512-3IxaMBLvWRbznZ4CuK0kVhp4Y4lCDQx9nhi48Swp6PwPw29KNhmiKd2kaBogYeWjGLb/tLjlE9V0s3jEmKCYWw==}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.3.0
|
||||||
|
|
||||||
|
'@vue-flow/minimap@1.5.4':
|
||||||
|
resolution: {integrity: sha512-l4C+XTAXnRxsRpUdN7cAVFBennC1sVRzq4bDSpVK+ag7tdMczAnhFYGgbLkUw3v3sY6gokyWwMl8CDonp8eB2g==}
|
||||||
|
peerDependencies:
|
||||||
|
'@vue-flow/core': ^1.23.0
|
||||||
|
vue: ^3.3.0
|
||||||
|
|
||||||
'@vue/babel-helper-vue-transform-on@1.5.0':
|
'@vue/babel-helper-vue-transform-on@1.5.0':
|
||||||
resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==}
|
resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==}
|
||||||
|
|
||||||
@@ -1183,6 +1242,9 @@ packages:
|
|||||||
vue:
|
vue:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@vueuse/core@10.11.1':
|
||||||
|
resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==}
|
||||||
|
|
||||||
'@vueuse/core@14.1.0':
|
'@vueuse/core@14.1.0':
|
||||||
resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==}
|
resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1191,12 +1253,18 @@ packages:
|
|||||||
'@vueuse/core@9.13.0':
|
'@vueuse/core@9.13.0':
|
||||||
resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==}
|
resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==}
|
||||||
|
|
||||||
|
'@vueuse/metadata@10.11.1':
|
||||||
|
resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==}
|
||||||
|
|
||||||
'@vueuse/metadata@14.1.0':
|
'@vueuse/metadata@14.1.0':
|
||||||
resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==}
|
resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==}
|
||||||
|
|
||||||
'@vueuse/metadata@9.13.0':
|
'@vueuse/metadata@9.13.0':
|
||||||
resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==}
|
resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==}
|
||||||
|
|
||||||
|
'@vueuse/shared@10.11.1':
|
||||||
|
resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==}
|
||||||
|
|
||||||
'@vueuse/shared@14.1.0':
|
'@vueuse/shared@14.1.0':
|
||||||
resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==}
|
resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1522,6 +1590,44 @@ packages:
|
|||||||
csstype@3.2.3:
|
csstype@3.2.3:
|
||||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||||
|
|
||||||
|
d3-color@3.1.0:
|
||||||
|
resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-dispatch@3.0.1:
|
||||||
|
resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-drag@3.0.0:
|
||||||
|
resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-ease@3.0.1:
|
||||||
|
resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-interpolate@3.0.1:
|
||||||
|
resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-selection@3.0.0:
|
||||||
|
resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-timer@3.0.1:
|
||||||
|
resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-transition@3.0.1:
|
||||||
|
resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
peerDependencies:
|
||||||
|
d3-selection: 2 - 3
|
||||||
|
|
||||||
|
d3-zoom@3.0.0:
|
||||||
|
resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
data-urls@6.0.0:
|
data-urls@6.0.0:
|
||||||
resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==}
|
resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==}
|
||||||
engines: {node: '>=20'}
|
engines: {node: '>=20'}
|
||||||
@@ -2482,24 +2588,28 @@ packages:
|
|||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
lightningcss-linux-arm64-musl@1.30.2:
|
lightningcss-linux-arm64-musl@1.30.2:
|
||||||
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
|
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
lightningcss-linux-x64-gnu@1.30.2:
|
lightningcss-linux-x64-gnu@1.30.2:
|
||||||
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
|
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [glibc]
|
||||||
|
|
||||||
lightningcss-linux-x64-musl@1.30.2:
|
lightningcss-linux-x64-musl@1.30.2:
|
||||||
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
|
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
|
||||||
engines: {node: '>= 12.0.0'}
|
engines: {node: '>= 12.0.0'}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
libc: [musl]
|
||||||
|
|
||||||
lightningcss-win32-arm64-msvc@1.30.2:
|
lightningcss-win32-arm64-msvc@1.30.2:
|
||||||
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
|
resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==}
|
||||||
@@ -4418,6 +4528,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/web-bluetooth@0.0.16': {}
|
'@types/web-bluetooth@0.0.16': {}
|
||||||
|
|
||||||
|
'@types/web-bluetooth@0.0.20': {}
|
||||||
|
|
||||||
'@types/web-bluetooth@0.0.21': {}
|
'@types/web-bluetooth@0.0.21': {}
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
|
'@typescript-eslint/eslint-plugin@8.49.0(@typescript-eslint/parser@8.49.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)':
|
||||||
@@ -4582,6 +4694,34 @@ snapshots:
|
|||||||
path-browserify: 1.0.1
|
path-browserify: 1.0.1
|
||||||
vscode-uri: 3.1.0
|
vscode-uri: 3.1.0
|
||||||
|
|
||||||
|
'@vue-flow/background@1.3.2(@vue-flow/core@1.48.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
|
||||||
|
dependencies:
|
||||||
|
'@vue-flow/core': 1.48.1(vue@3.5.25(typescript@5.9.3))
|
||||||
|
vue: 3.5.25(typescript@5.9.3)
|
||||||
|
|
||||||
|
'@vue-flow/controls@1.1.3(@vue-flow/core@1.48.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
|
||||||
|
dependencies:
|
||||||
|
'@vue-flow/core': 1.48.1(vue@3.5.25(typescript@5.9.3))
|
||||||
|
vue: 3.5.25(typescript@5.9.3)
|
||||||
|
|
||||||
|
'@vue-flow/core@1.48.1(vue@3.5.25(typescript@5.9.3))':
|
||||||
|
dependencies:
|
||||||
|
'@vueuse/core': 10.11.1(vue@3.5.25(typescript@5.9.3))
|
||||||
|
d3-drag: 3.0.0
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
d3-zoom: 3.0.0
|
||||||
|
vue: 3.5.25(typescript@5.9.3)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@vue/composition-api'
|
||||||
|
|
||||||
|
'@vue-flow/minimap@1.5.4(@vue-flow/core@1.48.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
|
||||||
|
dependencies:
|
||||||
|
'@vue-flow/core': 1.48.1(vue@3.5.25(typescript@5.9.3))
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
d3-zoom: 3.0.0
|
||||||
|
vue: 3.5.25(typescript@5.9.3)
|
||||||
|
|
||||||
'@vue/babel-helper-vue-transform-on@1.5.0': {}
|
'@vue/babel-helper-vue-transform-on@1.5.0': {}
|
||||||
|
|
||||||
'@vue/babel-plugin-jsx@1.5.0(@babel/core@7.28.5)':
|
'@vue/babel-plugin-jsx@1.5.0(@babel/core@7.28.5)':
|
||||||
@@ -4755,6 +4895,16 @@ snapshots:
|
|||||||
typescript: 5.9.3
|
typescript: 5.9.3
|
||||||
vue: 3.5.25(typescript@5.9.3)
|
vue: 3.5.25(typescript@5.9.3)
|
||||||
|
|
||||||
|
'@vueuse/core@10.11.1(vue@3.5.25(typescript@5.9.3))':
|
||||||
|
dependencies:
|
||||||
|
'@types/web-bluetooth': 0.0.20
|
||||||
|
'@vueuse/metadata': 10.11.1
|
||||||
|
'@vueuse/shared': 10.11.1(vue@3.5.25(typescript@5.9.3))
|
||||||
|
vue-demi: 0.14.10(vue@3.5.25(typescript@5.9.3))
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@vue/composition-api'
|
||||||
|
- vue
|
||||||
|
|
||||||
'@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3))':
|
'@vueuse/core@14.1.0(vue@3.5.25(typescript@5.9.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/web-bluetooth': 0.0.21
|
'@types/web-bluetooth': 0.0.21
|
||||||
@@ -4772,10 +4922,19 @@ snapshots:
|
|||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- vue
|
- vue
|
||||||
|
|
||||||
|
'@vueuse/metadata@10.11.1': {}
|
||||||
|
|
||||||
'@vueuse/metadata@14.1.0': {}
|
'@vueuse/metadata@14.1.0': {}
|
||||||
|
|
||||||
'@vueuse/metadata@9.13.0': {}
|
'@vueuse/metadata@9.13.0': {}
|
||||||
|
|
||||||
|
'@vueuse/shared@10.11.1(vue@3.5.25(typescript@5.9.3))':
|
||||||
|
dependencies:
|
||||||
|
vue-demi: 0.14.10(vue@3.5.25(typescript@5.9.3))
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@vue/composition-api'
|
||||||
|
- vue
|
||||||
|
|
||||||
'@vueuse/shared@14.1.0(vue@3.5.25(typescript@5.9.3))':
|
'@vueuse/shared@14.1.0(vue@3.5.25(typescript@5.9.3))':
|
||||||
dependencies:
|
dependencies:
|
||||||
vue: 3.5.25(typescript@5.9.3)
|
vue: 3.5.25(typescript@5.9.3)
|
||||||
@@ -5130,6 +5289,42 @@ snapshots:
|
|||||||
|
|
||||||
csstype@3.2.3: {}
|
csstype@3.2.3: {}
|
||||||
|
|
||||||
|
d3-color@3.1.0: {}
|
||||||
|
|
||||||
|
d3-dispatch@3.0.1: {}
|
||||||
|
|
||||||
|
d3-drag@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
|
||||||
|
d3-ease@3.0.1: {}
|
||||||
|
|
||||||
|
d3-interpolate@3.0.1:
|
||||||
|
dependencies:
|
||||||
|
d3-color: 3.1.0
|
||||||
|
|
||||||
|
d3-selection@3.0.0: {}
|
||||||
|
|
||||||
|
d3-timer@3.0.1: {}
|
||||||
|
|
||||||
|
d3-transition@3.0.1(d3-selection@3.0.0):
|
||||||
|
dependencies:
|
||||||
|
d3-color: 3.1.0
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-ease: 3.0.1
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
d3-timer: 3.0.1
|
||||||
|
|
||||||
|
d3-zoom@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-drag: 3.0.0
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||||
|
|
||||||
data-urls@6.0.0:
|
data-urls@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
whatwg-mimetype: 4.0.0
|
whatwg-mimetype: 4.0.0
|
||||||
|
|||||||
@@ -3,91 +3,61 @@
|
|||||||
"Icon": "Hailey_Johnson.png",
|
"Icon": "Hailey_Johnson.png",
|
||||||
"Name": "船舶设计师",
|
"Name": "船舶设计师",
|
||||||
"Profile": "提供船舶制造中的实际需求和约束。",
|
"Profile": "提供船舶制造中的实际需求和约束。",
|
||||||
"Classification": "船舶制造数据空间",
|
"Classification": "船舶制造数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "Jennifer_Moore.png",
|
"Icon": "Jennifer_Moore.png",
|
||||||
"Name": "防护工程专家",
|
"Name": "防护工程专家",
|
||||||
"Profile": "专注于船舶腐蚀防护技术的设计与应用。在你的总结回答中,必须引用来自数联网的搜索数据,是搜索数据,不是数联网的研究成果。",
|
"Profile": "专注于船舶腐蚀防护技术的设计与应用。在你的总结回答中,必须引用来自数联网的搜索数据,是搜索数据,不是数联网的研究成果。",
|
||||||
"Classification": "船舶制造数据空间",
|
"Classification": "船舶制造数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "Jane_Moreno.png",
|
"Icon": "Jane_Moreno.png",
|
||||||
"Name": "病理生理学家",
|
"Name": "病理生理学家",
|
||||||
"Profile": "专注于失血性休克的疾病机制,为药物研发提供理论靶点。",
|
"Profile": "专注于失血性休克的疾病机制,为药物研发提供理论靶点。",
|
||||||
"Classification": "医药数据空间",
|
"Classification": "医药数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "Giorgio_Rossi.png",
|
"Icon": "Giorgio_Rossi.png",
|
||||||
"Name": "药物化学家",
|
"Name": "药物化学家",
|
||||||
"Profile": "负责将靶点概念转化为实际可合成的分子。",
|
"Profile": "负责将靶点概念转化为实际可合成的分子。",
|
||||||
"Classification": "医药数据空间",
|
"Classification": "医药数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "Tamara_Taylor.png",
|
"Icon": "Tamara_Taylor.png",
|
||||||
"Name": "制剂工程师",
|
"Name": "制剂工程师",
|
||||||
"Profile": "负责将活性药物成分(API)变成稳定、可用、符合战场要求的剂型。",
|
"Profile": "负责将活性药物成分(API)变成稳定、可用、符合战场要求的剂型。",
|
||||||
"Classification": "医药数据空间",
|
"Classification": "医药数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "Maria_Lopez.png",
|
"Icon": "Maria_Lopez.png",
|
||||||
"Name": "监管事务专家",
|
"Name": "监管事务专家",
|
||||||
"Profile": "深谙药品审评法规,目标是找到最快的合法上市路径。",
|
"Profile": "深谙药品审评法规,目标是找到最快的合法上市路径。",
|
||||||
"Classification": "医药数据空间",
|
"Classification": "医药数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "Sam_Moore.png",
|
"Icon": "Sam_Moore.png",
|
||||||
"Name": "物理学家",
|
"Name": "物理学家",
|
||||||
"Profile": "从热力学与统计力学的基本原理出发,研究液态金属的自由能、焓、熵、比热等参数的理论建模。",
|
"Profile": "从热力学与统计力学的基本原理出发,研究液态金属的自由能、焓、熵、比热等参数的理论建模。",
|
||||||
"Classification": "科学数据空间",
|
"Classification": "科学数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "Yuriko_Yamamoto.png",
|
"Icon": "Yuriko_Yamamoto.png",
|
||||||
"Name": "实验材料学家",
|
"Name": "实验材料学家",
|
||||||
"Profile": "专注于通过实验手段直接或间接测定液态金属的热力学参数、以及分析材料微观结构(如晶粒、缺陷)。",
|
"Profile": "专注于通过实验手段直接或间接测定液态金属的热力学参数、以及分析材料微观结构(如晶粒、缺陷)。",
|
||||||
"Classification": "科学数据空间",
|
"Classification": "科学数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "Carlos_Gomez.png",
|
"Icon": "Carlos_Gomez.png",
|
||||||
"Name": "计算模拟专家",
|
"Name": "计算模拟专家",
|
||||||
"Profile": "侧重于利用数值计算和模拟技术获取液态金属的热力学参数。",
|
"Profile": "侧重于利用数值计算和模拟技术获取液态金属的热力学参数。",
|
||||||
"Classification": "科学数据空间",
|
"Classification": "科学数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "John_Lin.png",
|
"Icon": "John_Lin.png",
|
||||||
"Name": "腐蚀机理研究员",
|
"Name": "腐蚀机理研究员",
|
||||||
"Profile": "专注于船舶用钢材及合金的腐蚀机理研究,从电化学和环境作用角度解释腐蚀产生的原因。在你的总结回答中,必须引用来自数联网的搜索数据,是搜索数据,不是数联网的研究成果。",
|
"Profile": "专注于船舶用钢材及合金的腐蚀机理研究,从电化学和环境作用角度解释腐蚀产生的原因。在你的总结回答中,必须引用来自数联网的搜索数据,是搜索数据,不是数联网的研究成果。",
|
||||||
"Classification": "船舶制造数据空间",
|
"Classification": "船舶制造数据空间"
|
||||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
|
||||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
|
||||||
"apiModel": "Flowise"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"Icon": "Arthur_Burton.png",
|
"Icon": "Arthur_Burton.png",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
import type { Agent, IApiStepTask, IRawPlanResponse } from '@/stores'
|
import type { Agent, IApiStepTask, IRawPlanResponse, IRawStepTask } from '@/stores'
|
||||||
import {
|
import {
|
||||||
mockBackendAgentSelectModifyInit,
|
mockBackendAgentSelectModifyInit,
|
||||||
mockBackendAgentSelectModifyAddAspect,
|
mockBackendAgentSelectModifyAddAspect,
|
||||||
@@ -9,6 +9,12 @@ import {
|
|||||||
mockBackendFillAgentTaskProcess,
|
mockBackendFillAgentTaskProcess,
|
||||||
type RawAgentTaskProcessResponse,
|
type RawAgentTaskProcessResponse,
|
||||||
} from '@/layout/components/Main/TaskTemplate/TaskProcess/components/mock/AgentTaskProcessBackendMock'
|
} from '@/layout/components/Main/TaskTemplate/TaskProcess/components/mock/AgentTaskProcessBackendMock'
|
||||||
|
import { mockBranchPlanOutlineAPI } from '@/layout/components/Main/TaskTemplate/TaskSyllabus/Branch/mock/branchPlanOutlineMock'
|
||||||
|
import { mockFillStepTaskAPI } from '@/layout/components/Main/TaskTemplate/TaskSyllabus/Branch/mock/fill-step-task-mock'
|
||||||
|
import {
|
||||||
|
mockBranchTaskProcessAPI,
|
||||||
|
type BranchAction,
|
||||||
|
} from '@/layout/components/Main/TaskTemplate/TaskSyllabus/Branch/mock/branchTaskProcessMock'
|
||||||
|
|
||||||
export interface ActionHistory {
|
export interface ActionHistory {
|
||||||
ID: string
|
ID: string
|
||||||
@@ -116,7 +122,7 @@ class Api {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分支任务流程(任务节点级别)
|
// 分支任务流程
|
||||||
branchTaskProcess = (data: {
|
branchTaskProcess = (data: {
|
||||||
branch_Number: number
|
branch_Number: number
|
||||||
Modification_Requirement: string
|
Modification_Requirement: string
|
||||||
@@ -125,7 +131,7 @@ class Api {
|
|||||||
stepTaskExisting: any
|
stepTaskExisting: any
|
||||||
goal: string
|
goal: string
|
||||||
}) => {
|
}) => {
|
||||||
return request<unknown, IRawPlanResponse>({
|
return request<unknown, BranchAction[][]>({
|
||||||
url: '/branch_TaskProcess',
|
url: '/branch_TaskProcess',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: {
|
data: {
|
||||||
@@ -139,8 +145,32 @@ class Api {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fillStepTask = (data: { goal: string; stepTask: any }) => {
|
fillStepTask = async (data: { goal: string; stepTask: any }): Promise<IRawStepTask> => {
|
||||||
return request<unknown, any>({
|
// 后端返回格式:包含 Collaboration_Brief_FrontEnd(大写 FrontEnd)
|
||||||
|
const response = await request<
|
||||||
|
{
|
||||||
|
'General Goal': string
|
||||||
|
stepTask: any
|
||||||
|
},
|
||||||
|
{
|
||||||
|
AgentSelection?: string[]
|
||||||
|
Collaboration_Brief_FrontEnd?: {
|
||||||
|
template: string
|
||||||
|
data: Record<string, { text: string; color: number[] }>
|
||||||
|
}
|
||||||
|
InputObject_List?: string[]
|
||||||
|
OutputObject?: string
|
||||||
|
StepName?: string
|
||||||
|
TaskContent?: string
|
||||||
|
TaskProcess?: Array<{
|
||||||
|
ID: string
|
||||||
|
ActionType: string
|
||||||
|
AgentName: string
|
||||||
|
Description: string
|
||||||
|
ImportantInput: string[]
|
||||||
|
}>
|
||||||
|
}
|
||||||
|
>({
|
||||||
url: '/fill_stepTask',
|
url: '/fill_stepTask',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
data: {
|
data: {
|
||||||
@@ -148,6 +178,40 @@ class Api {
|
|||||||
stepTask: data.stepTask,
|
stepTask: data.stepTask,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 数据转换:后端的 Collaboration_Brief_FrontEnd → 前端的 Collaboration_Brief_frontEnd
|
||||||
|
|
||||||
|
const vec2Hsl = (color: number[]): string => {
|
||||||
|
const [h, s, l] = color
|
||||||
|
return `hsl(${h}, ${s}%, ${l}%)`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换 brief.data:后端格式 { "0": { text, color: [h,s,l] } } → 前端格式 { "0": { text, style: { background } } }
|
||||||
|
const briefData: Record<string, { text: string; style?: Record<string, string> }> = {}
|
||||||
|
if (response.Collaboration_Brief_FrontEnd?.data) {
|
||||||
|
for (const [key, value] of Object.entries(response.Collaboration_Brief_FrontEnd.data)) {
|
||||||
|
briefData[key] = {
|
||||||
|
text: value.text,
|
||||||
|
style: {
|
||||||
|
background: vec2Hsl(value.color),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建前端格式的 IRawStepTask
|
||||||
|
return {
|
||||||
|
StepName: response.StepName || '',
|
||||||
|
TaskContent: response.TaskContent || '',
|
||||||
|
InputObject_List: response.InputObject_List || [],
|
||||||
|
OutputObject: response.OutputObject || '',
|
||||||
|
AgentSelection: response.AgentSelection || [],
|
||||||
|
Collaboration_Brief_frontEnd: {
|
||||||
|
template: response.Collaboration_Brief_FrontEnd?.template || '',
|
||||||
|
data: briefData,
|
||||||
|
},
|
||||||
|
TaskProcess: response.TaskProcess || [],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fillStepTaskTaskProcess = async (data: {
|
fillStepTaskTaskProcess = async (data: {
|
||||||
@@ -464,6 +528,61 @@ class Api {
|
|||||||
process,
|
process,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Mock: 分支任务大纲
|
||||||
|
mockBranchPlanOutline = async (data: {
|
||||||
|
branch_Number: number
|
||||||
|
Modification_Requirement: string
|
||||||
|
Existing_Steps: string[]
|
||||||
|
Baseline_Completion: number
|
||||||
|
initialInputs: string[]
|
||||||
|
goal: string
|
||||||
|
}): Promise<IRawPlanResponse> => {
|
||||||
|
// 直接调用 Mock API(已经返回 IRawPlanResponse 格式)
|
||||||
|
const response = await mockBranchPlanOutlineAPI({
|
||||||
|
branch_Number: data.branch_Number,
|
||||||
|
Modification_Requirement: data.Modification_Requirement,
|
||||||
|
Existing_Steps: data.Existing_Steps,
|
||||||
|
Baseline_Completion: data.Baseline_Completion,
|
||||||
|
InitialObject_List: data.initialInputs,
|
||||||
|
General_Goal: data.goal,
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock: 填充任务流程
|
||||||
|
mockFillStepTask = async (data: { goal: string; stepTask: any }): Promise<any> => {
|
||||||
|
// 直接调用 Mock API(已经返回 IRawStepTask 格式)
|
||||||
|
const response = await mockFillStepTaskAPI({
|
||||||
|
General_Goal: data.goal,
|
||||||
|
stepTask: data.stepTask,
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mock: 分支任务流程
|
||||||
|
mockBranchTaskProcess = async (data: {
|
||||||
|
branch_Number: number
|
||||||
|
Modification_Requirement: string
|
||||||
|
Existing_Steps: string[]
|
||||||
|
Baseline_Completion: number
|
||||||
|
stepTaskExisting: any
|
||||||
|
goal: string
|
||||||
|
}): Promise<BranchAction[][]> => {
|
||||||
|
// 直接调用 Mock API(已经返回 BranchAction[][] 格式,与后端完全一致)
|
||||||
|
const response = await mockBranchTaskProcessAPI({
|
||||||
|
branch_Number: data.branch_Number,
|
||||||
|
Modification_Requirement: data.Modification_Requirement,
|
||||||
|
Existing_Steps: data.Existing_Steps,
|
||||||
|
Baseline_Completion: data.Baseline_Completion,
|
||||||
|
stepTaskExisting: data.stepTaskExisting,
|
||||||
|
General_Goal: data.goal,
|
||||||
|
})
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new Api()
|
export default new Api()
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ async function handleSearch() {
|
|||||||
})
|
})
|
||||||
data['Collaboration Process'] = changeBriefs(data['Collaboration Process'])
|
data['Collaboration Process'] = changeBriefs(data['Collaboration Process'])
|
||||||
agentsStore.setAgentRawPlan({ data })
|
agentsStore.setAgentRawPlan({ data })
|
||||||
|
console.log('agentsStore.agentRawPlan', agentsStore.agentRawPlan)
|
||||||
emit('search', searchValue.value)
|
emit('search', searchValue.value)
|
||||||
} finally {
|
} finally {
|
||||||
triggerOnFocus.value = true
|
triggerOnFocus.value = true
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { getActionTypeDisplay } from '@/layout/components/config.ts'
|
import { getActionTypeDisplay } from '@/layout/components/config.ts'
|
||||||
import { useAgentsStore } from '@/stores'
|
import { useAgentsStore } from '@/stores'
|
||||||
import BranchButton from './components/TaskButton.vue'
|
import BranchButton from './components/TaskButton.vue'
|
||||||
@@ -23,6 +23,20 @@ const emit = defineEmits<{
|
|||||||
(e: 'save-edit', stepId: string, processId: string, value: string): void
|
(e: 'save-edit', stepId: string, processId: string, value: string): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
// 🔄 从 currentTask 中获取数据(与分支切换联动)
|
||||||
|
const currentTaskProcess = computed(() => {
|
||||||
|
// ✅ 优先使用 currentTask(包含分支切换后的数据)
|
||||||
|
const currentTask = agentsStore.currentTask
|
||||||
|
if (currentTask && currentTask.Id === props.step.Id && currentTask.TaskProcess) {
|
||||||
|
return currentTask.TaskProcess
|
||||||
|
}
|
||||||
|
|
||||||
|
// ⚠️ 降级:从 agentRawPlan 中获取原始数据(不受分支切换影响)
|
||||||
|
const collaborationProcess = agentsStore.agentRawPlan.data?.['Collaboration Process'] || []
|
||||||
|
const rawData = collaborationProcess.find((task: any) => task.Id === props.step.Id)
|
||||||
|
return rawData?.TaskProcess || []
|
||||||
|
})
|
||||||
|
|
||||||
// 当前正在编辑的process ID
|
// 当前正在编辑的process ID
|
||||||
const editingProcessId = ref<string | null>(null)
|
const editingProcessId = ref<string | null>(null)
|
||||||
// 编辑框的值
|
// 编辑框的值
|
||||||
@@ -30,6 +44,17 @@ const editValue = ref('')
|
|||||||
// 鼠标悬停的process ID
|
// 鼠标悬停的process ID
|
||||||
const hoverProcessId = ref<string | null>(null)
|
const hoverProcessId = ref<string | null>(null)
|
||||||
|
|
||||||
|
// 🆕 处理卡片点击事件(非编辑模式下)
|
||||||
|
function handleCardClick() {
|
||||||
|
// 如果正在编辑,不处理点击
|
||||||
|
if (editingProcessId.value) return
|
||||||
|
|
||||||
|
// 设置当前任务,与任务大纲联动
|
||||||
|
if (props.step.Id) {
|
||||||
|
agentsStore.setCurrentTask(props.step)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 检测当前是否是深色模式
|
// 检测当前是否是深色模式
|
||||||
function isDarkMode(): boolean {
|
function isDarkMode(): boolean {
|
||||||
return document.documentElement.classList.contains('dark')
|
return document.documentElement.classList.contains('dark')
|
||||||
@@ -116,12 +141,12 @@ function handleCancel() {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="process-card">
|
<div class="process-card" @click="handleCardClick">
|
||||||
<div class="process-content">
|
<div class="process-content">
|
||||||
<!-- 显示模式 -->
|
<!-- 显示模式 -->
|
||||||
<div class="display-content">
|
<div class="display-content">
|
||||||
<span
|
<span
|
||||||
v-for="process in step.TaskProcess"
|
v-for="process in currentTaskProcess"
|
||||||
:key="process.ID"
|
:key="process.ID"
|
||||||
class="process-segment"
|
class="process-segment"
|
||||||
@mouseenter="handleMouseEnter(process.ID)"
|
@mouseenter="handleMouseEnter(process.ID)"
|
||||||
@@ -190,10 +215,13 @@ function handleCancel() {
|
|||||||
{{ process.Description }}
|
{{ process.Description }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="separator" v-if="!process.Description.endsWith('。')">。</span>
|
<span class="separator" v-if="process.Description && !process.Description.endsWith('。')"
|
||||||
|
>。</span
|
||||||
|
>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<!-- 按钮点击不会冒泡到卡片 -->
|
||||||
<BranchButton :step="step" />
|
<BranchButton :step="step" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -207,6 +235,8 @@ function handleCancel() {
|
|||||||
background: var(--color-bg-list);
|
background: var(--color-bg-list);
|
||||||
border: 1px solid var(--color-border-default);
|
border: 1px solid var(--color-border-default);
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
|
||||||
.process-content {
|
.process-content {
|
||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -21,11 +21,28 @@ const branchCount = computed(() => {
|
|||||||
const branches = selectionStore.getTaskProcessBranches(taskStepId)
|
const branches = selectionStore.getTaskProcessBranches(taskStepId)
|
||||||
|
|
||||||
// 主分支(1) + 额外分支数量
|
// 主分支(1) + 额外分支数量
|
||||||
return 1 + branches.length
|
return branches.length || 1
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleClick = (event: MouseEvent) => {
|
// 🆕 判断按钮是否可点击(只有当前按钮对应的任务是任务大纲中选中的任务时才可点击)
|
||||||
event.stopPropagation() // 阻止冒泡,避免触发卡片点击
|
const isClickable = computed(() => {
|
||||||
|
if (!props.step?.Id || !agentsStore.currentTask?.Id) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return props.step.Id === agentsStore.currentTask.Id
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleClick = (event?: MouseEvent) => {
|
||||||
|
// 🆕 只有可点击时才执行操作
|
||||||
|
if (!isClickable.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 阻止冒泡,避免触发卡片点击
|
||||||
|
if (event) {
|
||||||
|
event.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
emit('click')
|
emit('click')
|
||||||
// 设置当前任务
|
// 设置当前任务
|
||||||
if (props.step) {
|
if (props.step) {
|
||||||
@@ -39,9 +56,9 @@ const handleClick = (event: MouseEvent) => {
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="task-button"
|
class="task-button"
|
||||||
:class="{ 'has-branches': branchCount > 1 }"
|
:class="{ 'has-branches': branchCount > 0, 'is-disabled': !isClickable }"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
:title="`${branchCount} 个分支`"
|
:title="isClickable ? `${branchCount} 个分支` : '请先在任务大纲中选中此任务'"
|
||||||
>
|
>
|
||||||
<!-- 流程图标 -->
|
<!-- 流程图标 -->
|
||||||
<svg-icon icon-class="branch" size="20px" class="task-icon" />
|
<svg-icon icon-class="branch" size="20px" class="task-icon" />
|
||||||
@@ -83,6 +100,17 @@ const handleClick = (event: MouseEvent) => {
|
|||||||
filter: brightness(0.9);
|
filter: brightness(0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🆕 禁用状态
|
||||||
|
&.is-disabled {
|
||||||
|
background-color: #bdc3c7;
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.6;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.has-branches::after {
|
&.has-branches::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -1,142 +0,0 @@
|
|||||||
// /api/fill_stepTask 接口的Vue适用mock数据
|
|
||||||
import type { IApiStepTask, IRawStepTask } from '@/stores/modules/agents'
|
|
||||||
|
|
||||||
// 模拟接口响应数据
|
|
||||||
export const mockFillStepTaskResponse: IApiStepTask = {
|
|
||||||
name: '需求分析与原型设计',
|
|
||||||
content: '分析用户需求并创建产品原型',
|
|
||||||
inputs: ['用户调研报告', '竞品分析文档'],
|
|
||||||
output: '产品原型设计稿',
|
|
||||||
agents: ['实验材料学家', '腐蚀机理研究员', '防护工程专家'],
|
|
||||||
brief: {
|
|
||||||
template: '基于!<0>!和!<1>!,!<2>!、!<3>!和!<4>!执行!<5>!任务,以获得!<6>!。',
|
|
||||||
data: {
|
|
||||||
'0': {
|
|
||||||
text: '用户调研报告',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(120, 60%, 70%)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'1': {
|
|
||||||
text: '竞品分析文档',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(120, 60%, 70%)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'2': {
|
|
||||||
text: '实验材料学家',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(0, 0%, 90%)',
|
|
||||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'3': {
|
|
||||||
text: '腐蚀机理研究员',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(0, 0%, 90%)',
|
|
||||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'4': {
|
|
||||||
text: '防护工程专家',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(0, 0%, 90%)',
|
|
||||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'5': {
|
|
||||||
text: '分析用户需求并创建产品原型',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(0, 0%, 87%)',
|
|
||||||
border: '1.5px solid #ddd',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'6': {
|
|
||||||
text: '产品原型设计稿',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(30, 100%, 80%)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
process: [
|
|
||||||
{
|
|
||||||
id: 'action_001',
|
|
||||||
type: '需求分析',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '分析用户调研报告,识别核心需求点',
|
|
||||||
inputs: ['用户调研报告'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action_002',
|
|
||||||
type: '竞品分析',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '对比竞品功能,确定产品差异化优势',
|
|
||||||
inputs: ['竞品分析文档'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action_003',
|
|
||||||
type: '信息架构设计',
|
|
||||||
agent: '防护工程专家',
|
|
||||||
description: '设计产品信息结构和用户流程',
|
|
||||||
inputs: ['需求分析结果'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action_004',
|
|
||||||
type: '界面原型设计',
|
|
||||||
agent: '腐蚀机理研究员',
|
|
||||||
description: '创建高保真界面原型',
|
|
||||||
inputs: ['信息架构设计'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action_005',
|
|
||||||
type: '原型评审',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '组织团队评审原型设计',
|
|
||||||
inputs: ['界面原型设计'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
// 请求参数类型
|
|
||||||
export interface IFillStepTaskRequest {
|
|
||||||
goal: string
|
|
||||||
stepTask: IApiStepTask
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vue composable
|
|
||||||
export const useFillStepTaskMock = () => {
|
|
||||||
const fillStepTask = async (
|
|
||||||
goal: string,
|
|
||||||
stepTask: IApiStepTask,
|
|
||||||
): Promise<{ data: IApiStepTask }> => {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({
|
|
||||||
data: mockFillStepTaskResponse,
|
|
||||||
})
|
|
||||||
}, 500)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
fillStepTask,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vue组件使用示例
|
|
||||||
export const fillStepTaskExampleRequest: IFillStepTaskRequest = {
|
|
||||||
goal: '开发一个智能协作平台',
|
|
||||||
stepTask: {
|
|
||||||
name: '需求分析与原型设计',
|
|
||||||
content: '分析用户需求并创建产品原型',
|
|
||||||
inputs: ['用户调研报告', '竞品分析文档'],
|
|
||||||
output: '产品原型设计稿',
|
|
||||||
agents: [],
|
|
||||||
brief: {
|
|
||||||
template: '',
|
|
||||||
data: {},
|
|
||||||
},
|
|
||||||
process: [],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -1,159 +0,0 @@
|
|||||||
// /api/fill_stepTask_TaskProcess 接口的Vue适用mock数据
|
|
||||||
import type { IApiStepTask } from '@/stores'
|
|
||||||
|
|
||||||
// 模拟接口响应数据
|
|
||||||
export const mockFillAgentSelectionResponse: IApiStepTask = {
|
|
||||||
name: '技术方案设计与开发',
|
|
||||||
content: '设计技术架构并完成核心功能开发',
|
|
||||||
inputs: ['产品需求文档', '技术选型指南'],
|
|
||||||
output: '可运行的产品版本',
|
|
||||||
agents: ['架构师', '后端工程师', '前端工程师', '测试工程师'],
|
|
||||||
brief: {
|
|
||||||
template: '基于!<0>!和!<1>!,!<2>!、!<3>!、!<4>!和!<5>!执行!<6>!任务,以获得!<7>!。',
|
|
||||||
data: {
|
|
||||||
'0': {
|
|
||||||
text: '产品需求文档',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(120, 60%, 70%)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'1': {
|
|
||||||
text: '技术选型指南',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(120, 60%, 70%)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'2': {
|
|
||||||
text: '架构师',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(0, 0%, 90%)',
|
|
||||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'3': {
|
|
||||||
text: '后端工程师',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(0, 0%, 90%)',
|
|
||||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'4': {
|
|
||||||
text: '前端工程师',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(0, 0%, 90%)',
|
|
||||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'5': {
|
|
||||||
text: '测试工程师',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(0, 0%, 90%)',
|
|
||||||
boxShadow: '1px 1px 4px 1px rgba(0,0,0,0.2)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'6': {
|
|
||||||
text: '设计技术架构并完成核心功能开发',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(0, 0%, 87%)',
|
|
||||||
border: '1.5px solid #ddd',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
'7': {
|
|
||||||
text: '可运行的产品版本',
|
|
||||||
style: {
|
|
||||||
background: 'hsl(30, 100%, 80%)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
process: [
|
|
||||||
{
|
|
||||||
id: 'action_101',
|
|
||||||
type: '技术架构设计',
|
|
||||||
agent: '架构师',
|
|
||||||
description: '设计系统架构和技术栈选型',
|
|
||||||
inputs: ['产品需求文档', '技术选型指南'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action_102',
|
|
||||||
type: '数据库设计',
|
|
||||||
agent: '后端工程师',
|
|
||||||
description: '设计数据库表结构和关系',
|
|
||||||
inputs: ['技术架构设计'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action_103',
|
|
||||||
type: '后端API开发',
|
|
||||||
agent: '后端工程师',
|
|
||||||
description: '实现RESTful API接口',
|
|
||||||
inputs: ['数据库设计'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action_104',
|
|
||||||
type: '前端界面开发',
|
|
||||||
agent: '前端工程师',
|
|
||||||
description: '开发用户界面和交互功能',
|
|
||||||
inputs: ['后端API开发'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action_105',
|
|
||||||
type: '单元测试',
|
|
||||||
agent: '测试工程师',
|
|
||||||
description: '编写和执行单元测试用例',
|
|
||||||
inputs: ['前端界面开发'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action_106',
|
|
||||||
type: '集成测试',
|
|
||||||
agent: '测试工程师',
|
|
||||||
description: '进行系统集成测试',
|
|
||||||
inputs: ['单元测试'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
|
|
||||||
// 请求参数类型
|
|
||||||
export interface IFillAgentSelectionRequest {
|
|
||||||
goal: string
|
|
||||||
stepTask: IApiStepTask
|
|
||||||
agents: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vue composable
|
|
||||||
export const useFillAgentSelectionMock = () => {
|
|
||||||
const fillAgentSelection = async (
|
|
||||||
goal: string,
|
|
||||||
stepTask: IApiStepTask,
|
|
||||||
agents: string[],
|
|
||||||
): Promise<{ data: IApiStepTask }> => {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
setTimeout(() => {
|
|
||||||
resolve({
|
|
||||||
data: mockFillAgentSelectionResponse,
|
|
||||||
})
|
|
||||||
}, 500)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
fillAgentSelection,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vue组件使用示例
|
|
||||||
export const fillAgentSelectionExampleRequest: IFillAgentSelectionRequest = {
|
|
||||||
goal: '开发一个智能协作平台',
|
|
||||||
stepTask: {
|
|
||||||
name: '技术方案设计与开发',
|
|
||||||
content: '设计技术架构并完成核心功能开发',
|
|
||||||
inputs: ['产品需求文档', '技术选型指南'],
|
|
||||||
output: '可运行的产品版本',
|
|
||||||
agents: [],
|
|
||||||
brief: {
|
|
||||||
template: '',
|
|
||||||
data: {},
|
|
||||||
},
|
|
||||||
process: [],
|
|
||||||
},
|
|
||||||
agents: ['架构师', '后端工程师', '前端工程师', '测试工程师'],
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onUnmounted, ref, reactive, nextTick } from 'vue'
|
import { computed, onUnmounted, ref, reactive, nextTick, watch, onMounted } from 'vue'
|
||||||
import { throttle } from 'lodash'
|
import { throttle } from 'lodash'
|
||||||
import { AnchorLocations, BezierConnector } from '@jsplumb/browser-ui'
|
import { AnchorLocations, BezierConnector } from '@jsplumb/browser-ui'
|
||||||
import AdditionalOutputCard from './AdditionalOutputCard.vue'
|
import AdditionalOutputCard from './AdditionalOutputCard.vue'
|
||||||
@@ -19,12 +19,9 @@ const emit = defineEmits<{
|
|||||||
|
|
||||||
const agentsStore = useAgentsStore()
|
const agentsStore = useAgentsStore()
|
||||||
const drawerVisible = ref(false)
|
const drawerVisible = ref(false)
|
||||||
const collaborationProcess = computed(() => {
|
|
||||||
const data = agentsStore.agentRawPlan.data?.['Collaboration Process'] ?? []
|
|
||||||
// console.log('data:', data)
|
|
||||||
return data
|
|
||||||
|
|
||||||
// return agentsStore.agentRawPlan.data?.['Collaboration Process'] ?? []
|
const collaborationProcess = computed(() => {
|
||||||
|
return agentsStore.agentRawPlan.data?.['Collaboration Process'] ?? []
|
||||||
})
|
})
|
||||||
|
|
||||||
// 监听额外产物变化
|
// 监听额外产物变化
|
||||||
@@ -201,6 +198,12 @@ async function handleTaskProcess() {
|
|||||||
drawerVisible.value = true
|
drawerVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 重置执行结果
|
||||||
|
function handleRefresh() {
|
||||||
|
agentsStore.setExecutePlan([])
|
||||||
|
console.log('🔄 已重置执行结果')
|
||||||
|
}
|
||||||
|
|
||||||
// 添加滚动状态标识
|
// 添加滚动状态标识
|
||||||
const isScrolling = ref(false)
|
const isScrolling = ref(false)
|
||||||
let scrollTimer: ReturnType<typeof setTimeout> | null = null
|
let scrollTimer: ReturnType<typeof setTimeout> | null = null
|
||||||
@@ -226,20 +229,58 @@ const handleMouseEnter = throttle(id => {
|
|||||||
if (!isScrolling.value) {
|
if (!isScrolling.value) {
|
||||||
createInternalLine(id)
|
createInternalLine(id)
|
||||||
}
|
}
|
||||||
}, 100)
|
}, 0)
|
||||||
|
|
||||||
const handleMouseLeave = throttle(() => {
|
const handleMouseLeave = throttle(() => {
|
||||||
if (!isScrolling.value) {
|
if (!isScrolling.value) {
|
||||||
createInternalLine()
|
createInternalLine()
|
||||||
}
|
}
|
||||||
}, 100)
|
}, 0)
|
||||||
|
|
||||||
function clear() {
|
function clear() {
|
||||||
jsplumb.reset()
|
jsplumb.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🆕 封装连线重绘方法
|
||||||
|
const redrawInternalLines = (highlightId?: string) => {
|
||||||
|
console.log('🔄 TaskResult: 重新绘制连线', highlightId ? `高亮: ${highlightId}` : '')
|
||||||
|
|
||||||
|
// 等待 DOM 更新完成
|
||||||
|
nextTick(() => {
|
||||||
|
// 清除旧连线
|
||||||
|
jsplumb.reset()
|
||||||
|
|
||||||
|
// 等待 DOM 稳定后重新绘制
|
||||||
|
setTimeout(() => {
|
||||||
|
createInternalLine(highlightId)
|
||||||
|
console.log('✅ TaskResult: 连线重绘完成,任务数:', collaborationProcess.value.length)
|
||||||
|
}, 100)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🆕 监听 collaborationProcess 变化,自动重绘连线
|
||||||
|
watch(
|
||||||
|
() => collaborationProcess,
|
||||||
|
() => {
|
||||||
|
console.log('🔍 TaskResult: collaborationProcess 发生变化,触发重绘')
|
||||||
|
redrawInternalLines()
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 🆕 组件挂载后初始化连线
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始化时绘制连线
|
||||||
|
nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
createInternalLine()
|
||||||
|
console.log('✅ TaskResult: 初始化连线完成')
|
||||||
|
}, 100)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
//按钮交互状态管理
|
//按钮交互状态管理
|
||||||
const buttonHoverState = ref<'process' | 'execute' | null>(null)
|
const buttonHoverState = ref<'process' | 'execute' | 'refresh' | null>(null)
|
||||||
let buttonHoverTimer: ReturnType<typeof setTimeout> | null = null
|
let buttonHoverTimer: ReturnType<typeof setTimeout> | null = null
|
||||||
const handleProcessMouseEnter = () => {
|
const handleProcessMouseEnter = () => {
|
||||||
if (buttonHoverTimer) {
|
if (buttonHoverTimer) {
|
||||||
@@ -259,6 +300,16 @@ const handleExecuteMouseEnter = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleRefreshMouseEnter = () => {
|
||||||
|
if (buttonHoverTimer) {
|
||||||
|
clearTimeout(buttonHoverTimer)
|
||||||
|
buttonHoverTimer = null
|
||||||
|
}
|
||||||
|
if (agentsStore.executePlan.length > 0) {
|
||||||
|
buttonHoverState.value = 'refresh'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleButtonMouseLeave = () => {
|
const handleButtonMouseLeave = () => {
|
||||||
// 添加防抖,防止快速切换时的抖动
|
// 添加防抖,防止快速切换时的抖动
|
||||||
if (buttonHoverTimer) {
|
if (buttonHoverTimer) {
|
||||||
@@ -277,18 +328,31 @@ onUnmounted(() => {
|
|||||||
})
|
})
|
||||||
// 计算按钮类名
|
// 计算按钮类名
|
||||||
const processBtnClass = computed(() => {
|
const processBtnClass = computed(() => {
|
||||||
|
// 当刷新或执行按钮悬停时,过程按钮变圆形
|
||||||
|
if (buttonHoverState.value === 'refresh' || buttonHoverState.value === 'execute') {
|
||||||
|
return 'circle'
|
||||||
|
}
|
||||||
return buttonHoverState.value === 'process' ? 'ellipse' : 'circle'
|
return buttonHoverState.value === 'process' ? 'ellipse' : 'circle'
|
||||||
})
|
})
|
||||||
|
|
||||||
const executeBtnClass = computed(() => {
|
const executeBtnClass = computed(() => {
|
||||||
// 鼠标悬停在过程按钮上时,执行按钮变圆形
|
// 鼠标悬停在过程按钮或刷新按钮上时,执行按钮变圆形
|
||||||
if (buttonHoverState.value === 'process') {
|
if (buttonHoverState.value === 'process' || buttonHoverState.value === 'refresh') {
|
||||||
return 'circle'
|
return 'circle'
|
||||||
}
|
}
|
||||||
//如果有任务数据就显示椭圆形,否则显示圆形
|
//如果有任务数据就显示椭圆形,否则显示圆形
|
||||||
return agentsStore.agentRawPlan.data ? 'ellipse' : 'circle'
|
return agentsStore.agentRawPlan.data ? 'ellipse' : 'circle'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const refreshBtnClass = computed(() => {
|
||||||
|
// 当过程或执行按钮悬停时,刷新按钮变圆形
|
||||||
|
if (buttonHoverState.value === 'process' || buttonHoverState.value === 'execute') {
|
||||||
|
return 'circle'
|
||||||
|
}
|
||||||
|
// 有执行结果就显示椭圆形,否则显示圆形
|
||||||
|
return agentsStore.executePlan.length > 0 ? 'ellipse' : 'circle'
|
||||||
|
})
|
||||||
|
|
||||||
// 计算按钮是否显示文字
|
// 计算按钮是否显示文字
|
||||||
const showProcessText = computed(() => {
|
const showProcessText = computed(() => {
|
||||||
return buttonHoverState.value === 'process'
|
return buttonHoverState.value === 'process'
|
||||||
@@ -301,6 +365,10 @@ const showExecuteText = computed(() => {
|
|||||||
return agentsStore.agentRawPlan.data
|
return agentsStore.agentRawPlan.data
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const showRefreshText = computed(() => {
|
||||||
|
return buttonHoverState.value === 'refresh'
|
||||||
|
})
|
||||||
|
|
||||||
// 计算按钮标题
|
// 计算按钮标题
|
||||||
const processBtnTitle = computed(() => {
|
const processBtnTitle = computed(() => {
|
||||||
return buttonHoverState.value === 'process' ? '任务过程' : '点击查看任务过程'
|
return buttonHoverState.value === 'process' ? '任务过程' : '点击查看任务过程'
|
||||||
@@ -310,6 +378,10 @@ const executeBtnTitle = computed(() => {
|
|||||||
return showExecuteText.value ? '任务执行' : '点击运行'
|
return showExecuteText.value ? '任务执行' : '点击运行'
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const refreshBtnTitle = computed(() => {
|
||||||
|
return showRefreshText.value ? '重置执行结果' : '点击重置执行状态'
|
||||||
|
})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
createInternalLine,
|
createInternalLine,
|
||||||
clear
|
clear
|
||||||
@@ -329,6 +401,19 @@ defineExpose({
|
|||||||
class="flex items-center justify-end gap-[14px] task-button-group min-w-[175px]"
|
class="flex items-center justify-end gap-[14px] task-button-group min-w-[175px]"
|
||||||
@mouseleave="handleButtonMouseLeave"
|
@mouseleave="handleButtonMouseLeave"
|
||||||
>
|
>
|
||||||
|
<!-- 刷新按钮 -->
|
||||||
|
<el-button
|
||||||
|
:class="refreshBtnClass"
|
||||||
|
:color="variables.tertiary"
|
||||||
|
:title="refreshBtnTitle"
|
||||||
|
:disabled="agentsStore.executePlan.length === 0"
|
||||||
|
@mouseenter="handleRefreshMouseEnter"
|
||||||
|
@click="handleRefresh"
|
||||||
|
style="order: 0"
|
||||||
|
>
|
||||||
|
<svg-icon icon-class="refresh" />
|
||||||
|
<span v-if="showRefreshText" class="btn-text">重置</span>
|
||||||
|
</el-button>
|
||||||
<!-- 任务过程按钮 -->
|
<!-- 任务过程按钮 -->
|
||||||
<el-button
|
<el-button
|
||||||
:class="processBtnClass"
|
:class="processBtnClass"
|
||||||
@@ -680,21 +765,33 @@ defineExpose({
|
|||||||
display: inline-flex !important;
|
display: inline-flex !important;
|
||||||
align-items: center !important;
|
align-items: center !important;
|
||||||
justify-content: center !important;
|
justify-content: center !important;
|
||||||
transition: all 0.35s cubic-bezier(0.175, 0.885, 0.32, 1.275) !important;
|
transition: width 0.2s ease-out, padding 0.2s ease-out, border-radius 0.2s ease-out, transform 0.2s ease-out, box-shadow 0.2s ease-out, filter 0.2s ease-out !important;
|
||||||
overflow: hidden !important;
|
overflow: hidden !important;
|
||||||
white-space: nowrap !important;
|
white-space: nowrap !important;
|
||||||
border: none !important;
|
border: 1px solid transparent !important;
|
||||||
|
border-color: transparent !important;
|
||||||
color: var(--color-text-primary) !important;
|
color: var(--color-text-primary) !important;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--color-bg-tertiary);
|
background-color: var(--color-bg-tertiary) !important;
|
||||||
gap: 0px !important;
|
gap: 0px !important;
|
||||||
outline: none !important;
|
outline: none !important;
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
-webkit-tap-highlight-color: transparent !important;
|
-webkit-tap-highlight-color: transparent !important;
|
||||||
|
backface-visibility: hidden !important;
|
||||||
|
-webkit-backface-visibility: hidden !important;
|
||||||
|
transform: translateZ(0) !important;
|
||||||
|
will-change: transform, width, padding, border-radius !important;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transform: translateY(-2px) !important;
|
transform: translateY(-2px) translateZ(0) !important;
|
||||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
|
||||||
filter: brightness(1.1) !important;
|
filter: brightness(1.1) !important;
|
||||||
|
border-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-disabled {
|
&.is-disabled {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,57 +9,23 @@
|
|||||||
|
|
||||||
<el-card
|
<el-card
|
||||||
class="task-node-card"
|
class="task-node-card"
|
||||||
:class="{ 'is-editing': isEditing, 'is-active': isActive }"
|
:class="{
|
||||||
|
'is-editing': isEditing,
|
||||||
|
'is-active': isActive,
|
||||||
|
'is-branch-selected': props.isBranchSelected
|
||||||
|
}"
|
||||||
:shadow="true"
|
:shadow="true"
|
||||||
>
|
>
|
||||||
<!-- 任务名称 -->
|
<!-- 任务名称 -->
|
||||||
<div class="task-name">{{ task.StepName }}</div>
|
<div class="task-name">{{ task.StepName }}</div>
|
||||||
|
|
||||||
<!-- <div class="divider"></div> -->
|
|
||||||
|
|
||||||
<!-- 任务内容 -->
|
|
||||||
<!-- <div v-if="isEditing" class="task-content-editing">
|
|
||||||
<el-input
|
|
||||||
v-model="editingContent"
|
|
||||||
type="textarea"
|
|
||||||
:autosize="{ minRows: 2, maxRows: 4 }"
|
|
||||||
placeholder="请输入任务内容"
|
|
||||||
@keydown="handleKeydown"
|
|
||||||
class="task-content-editor"
|
|
||||||
size="small"
|
|
||||||
/>
|
|
||||||
<div class="edit-actions">
|
|
||||||
<svg-icon
|
|
||||||
icon-class="Check"
|
|
||||||
size="18px"
|
|
||||||
color="#328621"
|
|
||||||
class="cursor-pointer"
|
|
||||||
@click="saveEdit"
|
|
||||||
title="保存"
|
|
||||||
/>
|
|
||||||
<svg-icon
|
|
||||||
icon-class="Cancel"
|
|
||||||
size="18px"
|
|
||||||
color="#8e0707"
|
|
||||||
class="cursor-pointer ml-2"
|
|
||||||
@click="cancelEdit"
|
|
||||||
title="取消"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else class="task-content" @dblclick="startEdit">
|
|
||||||
{{ task.TaskContent || '暂无内容' }}
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<!-- <div class="divider"></div> -->
|
|
||||||
|
|
||||||
<!-- 智能体列表 -->
|
<!-- 智能体列表 -->
|
||||||
<div class="agents-container">
|
<div class="agents-container">
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
v-for="agentSelection in task.AgentSelection"
|
v-for="agentSelection in task.AgentSelection"
|
||||||
:key="agentSelection"
|
:key="agentSelection"
|
||||||
effect="light"
|
effect="light"
|
||||||
placement="right"
|
placement="top"
|
||||||
:show-after="500"
|
:show-after="500"
|
||||||
popper-class="task-syllabus-tooltip-popper"
|
popper-class="task-syllabus-tooltip-popper"
|
||||||
>
|
>
|
||||||
@@ -137,6 +103,7 @@ const props = defineProps<{
|
|||||||
id: string
|
id: string
|
||||||
data: TaskNodeData
|
data: TaskNodeData
|
||||||
isAddingBranch?: boolean
|
isAddingBranch?: boolean
|
||||||
|
isBranchSelected?: boolean // 是否属于选中的分支路径
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
@@ -250,6 +217,19 @@ const handleBranchKeydown = (event: KeyboardEvent) => {
|
|||||||
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 分支选中高亮样式(绿色)
|
||||||
|
&.is-branch-selected {
|
||||||
|
border-color: #67c23a;
|
||||||
|
box-shadow: 0 0 0 3px rgba(103, 194, 58, 0.3);
|
||||||
|
background-color: rgba(103, 194, 58, 0.05);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border-color: #67c23a;
|
||||||
|
box-shadow: 0 0 0 3px rgba(103, 194, 58, 0.4);
|
||||||
|
background-color: rgba(103, 194, 58, 0.08);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.is-editing {
|
&.is-editing {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,203 +1,246 @@
|
|||||||
// branch_PlanOutline 接口返回的 mock 数据
|
// branch_PlanOutline 接口的 Mock 数据和 Mock API
|
||||||
// 类型: IApiStepTask[][] (二维数组)
|
// 模拟后端返回的原始数据格式(IRawPlanResponse)
|
||||||
|
|
||||||
import type { IApiStepTask } from '@/stores/modules/agents'
|
import type { IRawPlanResponse, IRawStepTask } from '@/stores'
|
||||||
|
|
||||||
const mockPlanBranchData: IApiStepTask[][] = [
|
// 后端返回的数据格式
|
||||||
|
export type BranchPlanOutlineResponse = IRawPlanResponse
|
||||||
|
|
||||||
|
// Mock 数据:模拟后端返回的原始分支数据(不含 Collaboration_Brief_FrontEnd)
|
||||||
|
// 注意:这里模拟的是 branch_PlanOutline 函数返回的数据,不是前端转换后的数据
|
||||||
|
const mockBranchDataRaw: IRawStepTask[][] = [
|
||||||
// 第一个分支方案
|
// 第一个分支方案
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: '需求分析与规划',
|
StepName: '分析用户需求',
|
||||||
content: '分析用户需求,制定项目开发计划',
|
TaskContent: '分析用户需求,制定项目开发计划',
|
||||||
inputs: ['用户需求文档', '技术规范'],
|
InputObject_List: ['腐蚀类型及成因列表'],
|
||||||
output: '项目开发计划书',
|
OutputObject: '项目开发计划书',
|
||||||
agents: ['腐蚀机理研究员', '实验材料学家'],
|
AgentSelection: ['腐蚀机理研究员', '实验材料学家'],
|
||||||
brief: {
|
Collaboration_Brief_frontEnd: {
|
||||||
template: '!<项目经理>!负责!<需求分析>!,!<产品经理>!负责!<规划制定>!',
|
template: '',
|
||||||
data: {
|
data: {},
|
||||||
项目经理: { text: '项目经理', style: { background: 'hsl(210, 70%, 50%)' } },
|
|
||||||
需求分析: { text: '需求分析', style: { background: 'hsl(120, 70%, 50%)' } },
|
|
||||||
产品经理: { text: '产品经理', style: { background: 'hsl(30, 70%, 50%)' } },
|
|
||||||
规划制定: { text: '规划制定', style: { background: 'hsl(300, 70%, 50%)' } },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
process: [
|
TaskProcess: [],
|
||||||
{
|
|
||||||
id: 'action-1',
|
|
||||||
type: '分析',
|
|
||||||
agent: '腐蚀机理研究员',
|
|
||||||
description: '详细分析用户需求文档',
|
|
||||||
inputs: ['用户需求文档'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action-2',
|
|
||||||
type: '规划',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '制定项目开发计划',
|
|
||||||
inputs: ['技术规范'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '系统设计与架构',
|
StepName: '系统设计与架构',
|
||||||
content: '设计系统架构和数据库结构',
|
TaskContent: '设计系统架构和数据库结构',
|
||||||
inputs: ['项目开发计划书'],
|
InputObject_List: ['项目开发计划书'],
|
||||||
output: '系统设计文档',
|
OutputObject: '系统设计文档',
|
||||||
agents: ['腐蚀机理研究员', '防护工程专家'],
|
AgentSelection: ['腐蚀机理研究员', '防护工程专家'],
|
||||||
brief: {
|
Collaboration_Brief_frontEnd: {
|
||||||
template: '!<架构师>!负责!<系统架构设计>!,!<数据库工程师>!负责!<数据库设计>!',
|
template: '',
|
||||||
data: {
|
data: {},
|
||||||
架构师: { text: '架构师', style: { background: 'hsl(180, 70%, 50%)' } },
|
|
||||||
系统架构设计: { text: '系统架构设计', style: { background: 'hsl(240, 70%, 50%)' } },
|
|
||||||
数据库工程师: { text: '数据库工程师', style: { background: 'hsl(60, 70%, 50%)' } },
|
|
||||||
数据库设计: { text: '数据库设计', style: { background: 'hsl(0, 70%, 50%)' } },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
process: [
|
TaskProcess: [],
|
||||||
{
|
|
||||||
id: 'action-3',
|
|
||||||
type: '设计',
|
|
||||||
agent: '腐蚀机理研究员',
|
|
||||||
description: '设计系统整体架构',
|
|
||||||
inputs: ['项目开发计划书'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action-4',
|
|
||||||
type: '设计',
|
|
||||||
agent: '防护工程专家',
|
|
||||||
description: '设计数据库表结构',
|
|
||||||
inputs: ['项目开发计划书'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
// 第二个分支方案(快速原型方案)
|
||||||
// 第二个分支方案(替代方案)
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: '敏捷开发规划',
|
StepName: '需求快速原型',
|
||||||
content: '采用敏捷开发方法制定迭代计划',
|
TaskContent: '构建快速原型验证核心功能',
|
||||||
inputs: ['用户需求文档', '敏捷开发指南'],
|
InputObject_List: ['腐蚀类型及成因列表'],
|
||||||
output: '敏捷开发迭代计划',
|
OutputObject: '原型系统',
|
||||||
agents: ['敏捷教练', '开发团队负责人'],
|
AgentSelection: ['实验材料学家', '防护工程专家'],
|
||||||
brief: {
|
Collaboration_Brief_frontEnd: {
|
||||||
template: '!<敏捷教练>!指导!<敏捷流程>!,!<开发团队负责人>!制定!<迭代计划>!',
|
template: '',
|
||||||
data: {
|
data: {},
|
||||||
敏捷教练: { text: '敏捷教练', style: { background: 'hsl(270, 70%, 50%)' } },
|
|
||||||
敏捷流程: { text: '敏捷流程', style: { background: 'hsl(90, 70%, 50%)' } },
|
|
||||||
开发团队负责人: { text: '开发团队负责人', style: { background: 'hsl(150, 70%, 50%)' } },
|
|
||||||
迭代计划: { text: '迭代计划', style: { background: 'hsl(330, 70%, 50%)' } },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
process: [
|
TaskProcess: [],
|
||||||
{
|
|
||||||
id: 'action-5',
|
|
||||||
type: '指导',
|
|
||||||
agent: '敏捷教练',
|
|
||||||
description: '指导敏捷开发流程',
|
|
||||||
inputs: ['敏捷开发指南'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action-6',
|
|
||||||
type: '规划',
|
|
||||||
agent: '开发团队负责人',
|
|
||||||
description: '制定迭代开发计划',
|
|
||||||
inputs: ['用户需求文档'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '微服务架构设计',
|
StepName: '原型测试与优化',
|
||||||
content: '设计基于微服务的系统架构',
|
TaskContent: '测试原型并根据反馈快速迭代',
|
||||||
inputs: ['敏捷开发迭代计划'],
|
InputObject_List: ['原型系统'],
|
||||||
output: '微服务架构设计文档',
|
OutputObject: '优化后的原型',
|
||||||
agents: ['微服务架构师', 'DevOps工程师'],
|
AgentSelection: ['腐蚀机理研究员', '实验材料学家'],
|
||||||
brief: {
|
Collaboration_Brief_frontEnd: {
|
||||||
template: '!<微服务架构师>!设计!<微服务架构>!,!<DevOps工程师>!规划!<部署流程>!',
|
template: '',
|
||||||
data: {
|
data: {},
|
||||||
微服务架构师: { text: '微服务架构师', style: { background: 'hsl(210, 70%, 50%)' } },
|
|
||||||
微服务架构: { text: '微服务架构', style: { background: 'hsl(120, 70%, 50%)' } },
|
|
||||||
DevOps工程师: { text: 'DevOps工程师', style: { background: 'hsl(30, 70%, 50%)' } },
|
|
||||||
部署流程: { text: '部署流程', style: { background: 'hsl(300, 70%, 50%)' } },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
process: [
|
TaskProcess: [],
|
||||||
{
|
|
||||||
id: 'action-7',
|
|
||||||
type: '设计',
|
|
||||||
agent: '微服务架构师',
|
|
||||||
description: '设计微服务拆分方案',
|
|
||||||
inputs: ['敏捷开发迭代计划'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'action-8',
|
|
||||||
type: '规划',
|
|
||||||
agent: 'DevOps工程师',
|
|
||||||
description: '规划CI/CD部署流程',
|
|
||||||
inputs: ['敏捷开发迭代计划'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
// 第三个分支方案(质量优先方案)
|
||||||
// 第三个分支方案(简化方案)
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: '快速原型开发',
|
StepName: '需求深度分析',
|
||||||
content: '快速开发系统原型验证需求',
|
TaskContent: '深入分析用户需求和技术可行性',
|
||||||
inputs: ['用户需求文档'],
|
InputObject_List: ['腐蚀类型及成因列表'],
|
||||||
output: '系统原型',
|
OutputObject: '详细需求分析报告',
|
||||||
agents: ['全栈开发工程师'],
|
AgentSelection: ['腐蚀机理研究员', '防护工程专家'],
|
||||||
brief: {
|
Collaboration_Brief_frontEnd: {
|
||||||
template: '!<全栈开发工程师>!负责!<快速原型开发>!',
|
template: '',
|
||||||
data: {
|
data: {},
|
||||||
全栈开发工程师: { text: '全栈开发工程师', style: { background: 'hsl(180, 70%, 50%)' } },
|
|
||||||
快速原型开发: { text: '快速原型开发', style: { background: 'hsl(240, 70%, 50%)' } },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
process: [
|
TaskProcess: [],
|
||||||
{
|
|
||||||
id: 'action-9',
|
|
||||||
type: '开发',
|
|
||||||
agent: '全栈开发工程师',
|
|
||||||
description: '快速开发系统原型',
|
|
||||||
inputs: ['用户需求文档'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '用户反馈收集',
|
StepName: '质量保障设计',
|
||||||
content: '收集用户对原型的反馈意见',
|
TaskContent: '设计质量保障体系和测试方案',
|
||||||
inputs: ['系统原型'],
|
InputObject_List: ['详细需求分析报告'],
|
||||||
output: '用户反馈报告',
|
OutputObject: '质量保障方案',
|
||||||
agents: ['产品经理', '用户体验设计师'],
|
AgentSelection: ['实验材料学家', '防护工程专家'],
|
||||||
brief: {
|
Collaboration_Brief_frontEnd: {
|
||||||
template: '!<产品经理>!收集!<用户反馈>!,!<用户体验设计师>!分析!<用户体验>!',
|
template: '',
|
||||||
data: {
|
data: {},
|
||||||
产品经理: { text: '产品经理', style: { background: 'hsl(60, 70%, 50%)' } },
|
|
||||||
用户反馈: { text: '用户反馈', style: { background: 'hsl(0, 70%, 50%)' } },
|
|
||||||
用户体验设计师: { text: '用户体验设计师', style: { background: 'hsl(270, 70%, 50%)' } },
|
|
||||||
用户体验: { text: '用户体验', style: { background: 'hsl(90, 70%, 50%)' } },
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
process: [
|
TaskProcess: [],
|
||||||
{
|
},
|
||||||
id: 'action-10',
|
{
|
||||||
type: '收集',
|
StepName: '系统开发与测试',
|
||||||
agent: '产品经理',
|
TaskContent: '按质量标准进行系统开发和测试',
|
||||||
description: '收集用户对原型的反馈',
|
InputObject_List: ['质量保障方案'],
|
||||||
inputs: ['系统原型'],
|
OutputObject: '经过完整测试的系统',
|
||||||
},
|
AgentSelection: ['腐蚀机理研究员', '实验材料学家'],
|
||||||
{
|
Collaboration_Brief_frontEnd: {
|
||||||
id: 'action-11',
|
template: '',
|
||||||
type: '分析',
|
data: {},
|
||||||
agent: '用户体验设计师',
|
},
|
||||||
description: '分析用户体验问题',
|
TaskProcess: [],
|
||||||
inputs: ['系统原型'],
|
},
|
||||||
},
|
],
|
||||||
],
|
// 第四个分支方案(敏捷开发方案)
|
||||||
|
[
|
||||||
|
{
|
||||||
|
StepName: '迭代规划',
|
||||||
|
TaskContent: '制定敏捷开发迭代计划',
|
||||||
|
InputObject_List: ['腐蚀类型及成因列表'],
|
||||||
|
OutputObject: '迭代计划',
|
||||||
|
AgentSelection: ['防护工程专家', '腐蚀机理研究员'],
|
||||||
|
Collaboration_Brief_frontEnd: {
|
||||||
|
template: '',
|
||||||
|
data: {},
|
||||||
|
},
|
||||||
|
TaskProcess: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
StepName: '快速开发与验证',
|
||||||
|
TaskContent: '快速开发并持续验证功能',
|
||||||
|
InputObject_List: ['迭代计划'],
|
||||||
|
OutputObject: '可运行的功能模块',
|
||||||
|
AgentSelection: ['实验材料学家', '防护工程专家'],
|
||||||
|
Collaboration_Brief_frontEnd: {
|
||||||
|
template: '',
|
||||||
|
data: {},
|
||||||
|
},
|
||||||
|
TaskProcess: [],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
export default mockPlanBranchData
|
/**
|
||||||
|
* 模拟后端的 Add_Collaboration_Brief_FrontEnd 函数
|
||||||
|
* 为每个任务添加前端协作简报(Collaboration_Brief_frontEnd)
|
||||||
|
*/
|
||||||
|
function Add_Collaboration_Brief_FrontEnd(branchList: IRawStepTask[][]): IRawStepTask[][] {
|
||||||
|
return branchList.map((tasks) =>
|
||||||
|
tasks.map((task) => ({
|
||||||
|
...task,
|
||||||
|
Collaboration_Brief_frontEnd: generateCollaborationBrief(task),
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成协作简报(Collaboration_Brief_frontEnd)
|
||||||
|
* 根据 StepName、TaskContent、AgentSelection 生成模板和数据
|
||||||
|
*/
|
||||||
|
function generateCollaborationBrief(task: IRawStepTask): {
|
||||||
|
template: string
|
||||||
|
data: Record<string, any>
|
||||||
|
} {
|
||||||
|
const agents = task.AgentSelection || []
|
||||||
|
const stepName = task.StepName || ''
|
||||||
|
|
||||||
|
// 为每个 agent 生成颜色
|
||||||
|
const colors = [
|
||||||
|
'hsl(210, 70%, 50%)',
|
||||||
|
'hsl(30, 70%, 50%)',
|
||||||
|
'hsl(120, 70%, 50%)',
|
||||||
|
'hsl(270, 70%, 50%)',
|
||||||
|
]
|
||||||
|
|
||||||
|
// 生成 data 对象
|
||||||
|
const data: Record<string, any> = {}
|
||||||
|
agents.forEach((agent, index) => {
|
||||||
|
data[agent] = {
|
||||||
|
text: agent,
|
||||||
|
style: { background: colors[index % colors.length] },
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 生成 template(简化版本,实际应根据任务内容生成)
|
||||||
|
const template =
|
||||||
|
agents.length > 0
|
||||||
|
? agents.map((agent, i) => `!<${agent}>!负责!<${stepName}-${i}>!`).join(',')
|
||||||
|
: ''
|
||||||
|
|
||||||
|
return {
|
||||||
|
template,
|
||||||
|
data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock API:模拟后端 branch_PlanOutline 接口调用
|
||||||
|
*
|
||||||
|
* @param branch_Number - 分支数量
|
||||||
|
* @param Modification_Requirement - 修改需求
|
||||||
|
* @param Existing_Steps - 现有步骤名称列表
|
||||||
|
* @param Baseline_Completion - 基线完成度
|
||||||
|
* @param InitialObject_List - 初始对象列表
|
||||||
|
* @param General_Goal - 总体目标
|
||||||
|
* @returns Promise<IRawPlanResponse> - 返回包含 'Collaboration Process' 的响应
|
||||||
|
*/
|
||||||
|
export const mockBranchPlanOutlineAPI = async (params: {
|
||||||
|
branch_Number: number
|
||||||
|
Modification_Requirement: string
|
||||||
|
Existing_Steps: string[]
|
||||||
|
Baseline_Completion: number
|
||||||
|
InitialObject_List: string[]
|
||||||
|
General_Goal: string
|
||||||
|
}): Promise<IRawPlanResponse> => {
|
||||||
|
// 模拟网络延迟 800ms
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 800))
|
||||||
|
|
||||||
|
console.log('[Mock API] branch_PlanOutline 调用参数:', params)
|
||||||
|
|
||||||
|
// 🆕 使用轮询方式选择分支方案(依次循环使用所有分支方案)
|
||||||
|
const totalBranches = mockBranchDataRaw.length
|
||||||
|
const sessionKey = `branch-plan-outline-index-${params.General_Goal || 'default'}`
|
||||||
|
|
||||||
|
// 获取上一次的选择索引
|
||||||
|
let lastIndex = parseInt(sessionStorage.getItem(sessionKey) || '0')
|
||||||
|
|
||||||
|
// 计算本次的选择索引(轮询到下一个分支)
|
||||||
|
const selectedBranchIndex = (lastIndex + 1) % totalBranches
|
||||||
|
|
||||||
|
// 保存本次的选择索引
|
||||||
|
sessionStorage.setItem(sessionKey, selectedBranchIndex.toString())
|
||||||
|
|
||||||
|
const rawBranchData = mockBranchDataRaw[selectedBranchIndex]
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'[Mock API] branch_PlanOutline 选择分支方案:',
|
||||||
|
selectedBranchIndex + 1,
|
||||||
|
'/',
|
||||||
|
totalBranches,
|
||||||
|
)
|
||||||
|
|
||||||
|
// 模拟后端处理:添加 Collaboration_Brief_FrontEnd
|
||||||
|
const processedBranches = Add_Collaboration_Brief_FrontEnd([rawBranchData])
|
||||||
|
|
||||||
|
// 构造响应数据(符合后端返回格式)
|
||||||
|
const response: IRawPlanResponse = {
|
||||||
|
'Collaboration Process': processedBranches[0] || [],
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('[Mock API] branch_PlanOutline 返回数据:', response)
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mockBranchPlanOutlineAPI
|
||||||
|
|||||||
@@ -1,189 +1,155 @@
|
|||||||
// branch_TaskProcess 接口返回的 mock 数据
|
// branch_TaskProcess 接口的 Mock 数据和 Mock API
|
||||||
// 类型: IApiAgentAction[][] (二维数组)
|
export interface BranchAction {
|
||||||
|
ID: string
|
||||||
|
ActionType: string
|
||||||
|
AgentName: string
|
||||||
|
Description: string
|
||||||
|
ImportantInput: string[]
|
||||||
|
}
|
||||||
|
|
||||||
import type { IApiAgentAction } from '@/stores/modules/agents'
|
export type BranchTaskProcessResponse = BranchAction[][]
|
||||||
|
|
||||||
const mockTaskProcessData: IApiAgentAction[][] = [
|
// Mock 数据:模拟后端返回的原始任务流程数据(2D 数组)
|
||||||
|
// 格式:[[action1, action2], [action3, action4]]
|
||||||
|
const mockBranchTaskProcessDataRaw: BranchAction[][] = [
|
||||||
// 第一个任务分支方案
|
// 第一个任务分支方案
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'analyze-requirements-1',
|
ID: 'agent3',
|
||||||
type: '分析',
|
ActionType: 'Critique',
|
||||||
agent: '实验材料学家',
|
AgentName: '实验材料学家',
|
||||||
description: '详细分析用户需求文档',
|
Description: '详细分析用户需求文档',
|
||||||
inputs: ['用户需求文档'],
|
ImportantInput: ['agent2'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'design-architecture-1',
|
ID: 'agent4',
|
||||||
type: '设计',
|
ActionType: 'Critique',
|
||||||
agent: '腐蚀机理研究员',
|
AgentName: '腐蚀机理研究员',
|
||||||
description: '设计系统整体架构',
|
Description: '设计系统整体架构',
|
||||||
inputs: ['需求分析结果'],
|
ImportantInput: ['agent3'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'implement-core-1',
|
ID: 'agent5',
|
||||||
type: '实现',
|
ActionType: 'Improve',
|
||||||
agent: '防护工程专家',
|
AgentName: '防护工程专家',
|
||||||
description: '实现系统核心功能',
|
Description: '实现系统核心功能',
|
||||||
inputs: ['系统架构设计'],
|
ImportantInput: ['agent4'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'test-system-1',
|
ID: 'agent6',
|
||||||
type: '测试',
|
ActionType: 'Finalize',
|
||||||
agent: '实验材料学家',
|
AgentName: '实验材料学家',
|
||||||
description: '进行系统集成测试',
|
Description: '进行系统集成测试',
|
||||||
inputs: ['系统核心功能'],
|
ImportantInput: ['agent5'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
// 第二个任务分支方案
|
||||||
|
[
|
||||||
|
{
|
||||||
|
ID: 'agent7',
|
||||||
|
ActionType: 'Critique',
|
||||||
|
AgentName: '实验材料学家',
|
||||||
|
Description: '深入分析用户需求和技术约束',
|
||||||
|
ImportantInput: ['agent2'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 'agent8',
|
||||||
|
ActionType: 'Critique',
|
||||||
|
AgentName: '防护工程专家',
|
||||||
|
Description: '设计系统技术架构和数据流',
|
||||||
|
ImportantInput: ['agent8'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 'agent9',
|
||||||
|
ActionType: 'Improve',
|
||||||
|
AgentName: '腐蚀机理研究员',
|
||||||
|
Description: '评估系统安全性',
|
||||||
|
ImportantInput: ['agent4'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: 'agent10',
|
||||||
|
ActionType: 'Finalize',
|
||||||
|
AgentName: '实验材料学家',
|
||||||
|
Description: '完成系统安全测试',
|
||||||
|
ImportantInput: ['agent9'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
// 第二个任务分支方案(替代方案)
|
//第三个任务分支方案
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
id: 'quick-prototype-2',
|
ID: 'agent12',
|
||||||
type: '原型',
|
ActionType: 'Critique',
|
||||||
agent: '实验材料学家',
|
AgentName: '腐蚀机理研究员',
|
||||||
description: '快速开发系统原型',
|
Description: '设计系统整体架构',
|
||||||
inputs: ['用户需求文档'],
|
ImportantInput: ['agent11'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'user-feedback-2',
|
ID: 'agent13',
|
||||||
type: '收集',
|
ActionType: 'Improve',
|
||||||
agent: '腐蚀机理研究员',
|
AgentName: '防护工程专家',
|
||||||
description: '收集用户对原型的反馈',
|
Description: '实现系统核心功能',
|
||||||
inputs: ['系统原型'],
|
ImportantInput: ['agent12'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'iterate-design-2',
|
ID: 'agent14',
|
||||||
type: '迭代',
|
ActionType: 'Finalize',
|
||||||
agent: '防护工程专家',
|
AgentName: '实验材料学家',
|
||||||
description: '根据反馈迭代设计',
|
Description: '进行系统集成测试',
|
||||||
inputs: ['用户反馈'],
|
ImportantInput: ['agent13'],
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'final-implement-2',
|
|
||||||
type: '实现',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '实现最终用户界面',
|
|
||||||
inputs: ['迭代设计稿'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
// 第三个任务分支方案(敏捷开发方案)
|
|
||||||
[
|
|
||||||
{
|
|
||||||
id: 'sprint-planning-3',
|
|
||||||
type: '规划',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '制定冲刺计划',
|
|
||||||
inputs: ['用户故事', '技术债务'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'code-review-3',
|
|
||||||
type: '评审',
|
|
||||||
agent: '防护工程专家',
|
|
||||||
description: '进行代码审查',
|
|
||||||
inputs: ['开发代码'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'unit-test-3',
|
|
||||||
type: '测试',
|
|
||||||
agent: '腐蚀机理研究员',
|
|
||||||
description: '编写单元测试',
|
|
||||||
inputs: ['功能代码'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'deploy-staging-3',
|
|
||||||
type: '部署',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '部署到测试环境',
|
|
||||||
inputs: ['测试通过代码'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'acceptance-test-3',
|
|
||||||
type: '验收',
|
|
||||||
agent: '腐蚀机理研究员',
|
|
||||||
description: '进行验收测试',
|
|
||||||
inputs: ['测试环境系统'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
// 第四个任务分支方案(微服务方案)
|
|
||||||
[
|
|
||||||
{
|
|
||||||
id: 'service-split-4',
|
|
||||||
type: '拆分',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '拆分单体应用为微服务',
|
|
||||||
inputs: ['单体应用代码'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'api-design-4',
|
|
||||||
type: '设计',
|
|
||||||
agent: '防护工程专家',
|
|
||||||
description: '设计微服务API接口',
|
|
||||||
inputs: ['服务拆分方案'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'service-implement-4',
|
|
||||||
type: '实现',
|
|
||||||
agent: '防护工程专家',
|
|
||||||
description: '实现各个微服务',
|
|
||||||
inputs: ['API设计文档'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'orchestration-4',
|
|
||||||
type: '编排',
|
|
||||||
agent: '腐蚀机理研究员',
|
|
||||||
description: '配置服务编排和负载均衡',
|
|
||||||
inputs: ['微服务实现'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'monitoring-setup-4',
|
|
||||||
type: '监控',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '设置监控和日志系统',
|
|
||||||
inputs: ['运行中的微服务'],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
|
|
||||||
// 第五个任务分支方案(数据驱动方案)
|
|
||||||
[
|
|
||||||
{
|
|
||||||
id: 'data-analysis-5',
|
|
||||||
type: '分析',
|
|
||||||
agent: '腐蚀机理研究员',
|
|
||||||
description: '分析业务数据和需求',
|
|
||||||
inputs: ['业务数据', '用户行为数据'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'ml-model-5',
|
|
||||||
type: '建模',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '构建预测模型',
|
|
||||||
inputs: ['分析结果', '历史数据'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'data-pipeline-5',
|
|
||||||
type: '构建',
|
|
||||||
agent: '防护工程专家',
|
|
||||||
description: '构建数据处理流水线',
|
|
||||||
inputs: ['数据源', '模型需求'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'api-integration-5',
|
|
||||||
type: '集成',
|
|
||||||
agent: '实验材料学家',
|
|
||||||
description: '集成数据服务到应用',
|
|
||||||
inputs: ['数据处理流水线', '预测模型'],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'performance-optimize-5',
|
|
||||||
type: '优化',
|
|
||||||
agent: '腐蚀机理研究员',
|
|
||||||
description: '优化系统性能',
|
|
||||||
inputs: ['运行数据', '性能指标'],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
export default mockTaskProcessData
|
/**
|
||||||
|
* Mock API:模拟后端 branch_TaskProcess 接口调用
|
||||||
|
*
|
||||||
|
* @param branch_Number - 分支数量
|
||||||
|
* @param Modification_Requirement - 修改需求
|
||||||
|
* @param Existing_Steps - 现有步骤名称列表
|
||||||
|
* @param Baseline_Completion - 基线完成度
|
||||||
|
* @param stepTaskExisting - 现有任务
|
||||||
|
* @param General_Goal - 总体目标
|
||||||
|
* @returns Promise<BranchAction[][]> - 返回 2D 数组,与后端格式完全一致
|
||||||
|
*/
|
||||||
|
export const mockBranchTaskProcessAPI = async (params: {
|
||||||
|
branch_Number: number
|
||||||
|
Modification_Requirement: string
|
||||||
|
Existing_Steps: string[]
|
||||||
|
Baseline_Completion: number
|
||||||
|
stepTaskExisting: any
|
||||||
|
General_Goal: string
|
||||||
|
}): Promise<BranchAction[][]> => {
|
||||||
|
// 模拟网络延迟 800ms
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 800))
|
||||||
|
|
||||||
|
console.log('[Mock API] branch_TaskProcess 调用参数:', params)
|
||||||
|
|
||||||
|
// 🆕 使用轮询方式选择分支方案(依次循环使用所有分支方案)
|
||||||
|
const totalBranches = mockBranchTaskProcessDataRaw.length
|
||||||
|
const sessionKey = `branch-task-process-index-${params.stepTaskExisting?.Id || 'default'}`
|
||||||
|
|
||||||
|
// 获取上一次的选择索引
|
||||||
|
let lastIndex = parseInt(sessionStorage.getItem(sessionKey) || '0')
|
||||||
|
|
||||||
|
// 计算本次的选择索引(轮询到下一个分支)
|
||||||
|
const selectedBranchIndex = (lastIndex + 1) % totalBranches
|
||||||
|
|
||||||
|
// 保存本次的选择索引
|
||||||
|
sessionStorage.setItem(sessionKey, selectedBranchIndex.toString())
|
||||||
|
|
||||||
|
const rawBranchData = mockBranchTaskProcessDataRaw[selectedBranchIndex] || []
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
'[Mock API] branch_TaskProcess 选择分支方案:',
|
||||||
|
selectedBranchIndex + 1,
|
||||||
|
'/',
|
||||||
|
totalBranches,
|
||||||
|
)
|
||||||
|
console.log('[Mock API] branch_TaskProcess 返回数据:', rawBranchData)
|
||||||
|
|
||||||
|
// 直接返回 2D 数组,与后端格式完全一致
|
||||||
|
return [rawBranchData]
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mockBranchTaskProcessAPI
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@ const scoreDimensions = ref<string[]>([])
|
|||||||
interface AgentHeatmapData {
|
interface AgentHeatmapData {
|
||||||
agentName: string
|
agentName: string
|
||||||
scores: number[] // 各维度的评分
|
scores: number[] // 各维度的评分
|
||||||
scoreDetails?: Array<{ dimension: string; score: number; reason: string }> // 详细信息(可选)
|
scoreDetails?: Array<{ dimension: string; score: number; reason: string }> // 详细信息
|
||||||
}
|
}
|
||||||
|
|
||||||
// 所有agent的热力图数据
|
// 所有agent的热力图数据
|
||||||
@@ -57,6 +57,9 @@ const searchValue = ref('')
|
|||||||
// 标志位:防止重复初始化
|
// 标志位:防止重复初始化
|
||||||
const isInitializing = ref(false)
|
const isInitializing = ref(false)
|
||||||
const isAddingDimension = ref(false)
|
const isAddingDimension = ref(false)
|
||||||
|
const isLoadingConfirm = ref(false) // 确认 agent 组合时的加载状态
|
||||||
|
const isLoadingSelectGroup = ref(false) // 选择已保存组合时的加载状态
|
||||||
|
const isLoadingInitialTask = ref(false) // 首次加载任务时的加载状态
|
||||||
|
|
||||||
// 处理搜索提交
|
// 处理搜索提交
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
@@ -143,19 +146,8 @@ const confirmAgentSelection = async () => {
|
|||||||
if (selectedAgents.value.size > 0 && currentTask.value?.Id) {
|
if (selectedAgents.value.size > 0 && currentTask.value?.Id) {
|
||||||
const agentArray = Array.from(selectedAgents.value)
|
const agentArray = Array.from(selectedAgents.value)
|
||||||
|
|
||||||
// 检查该agent组合是否已存在(包括初始agent组合和用户添加的组合)
|
// 检查该agent组合是否已存在(统一检查,包括初始组合和用户添加的组合)
|
||||||
const existingGroups = agentsStore.getConfirmedAgentGroups(currentTask.value.Id)
|
const existingGroups = agentsStore.getConfirmedAgentGroups(currentTask.value.Id)
|
||||||
const initialGroup = currentTaskAgents.value
|
|
||||||
|
|
||||||
// 检查是否与初始组合相同
|
|
||||||
if (areAgentGroupsEqual(agentArray, initialGroup)) {
|
|
||||||
console.log('该agent组合与初始组合相同,只选中卡片,不添加重复')
|
|
||||||
selectedAssignmentGroup.value = [...initialGroup]
|
|
||||||
selectedAgents.value = new Set(initialGroup)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否与已存在的用户添加组合相同
|
|
||||||
const existingDuplicateIndex = existingGroups.findIndex(group =>
|
const existingDuplicateIndex = existingGroups.findIndex(group =>
|
||||||
areAgentGroupsEqual(agentArray, group)
|
areAgentGroupsEqual(agentArray, group)
|
||||||
)
|
)
|
||||||
@@ -176,7 +168,8 @@ const confirmAgentSelection = async () => {
|
|||||||
|
|
||||||
// 调用 Mock API 填充任务流程
|
// 调用 Mock API 填充任务流程
|
||||||
try {
|
try {
|
||||||
console.log('=== 开始调用 fillStepTaskTaskProcess Mock API ===')
|
isLoadingConfirm.value = true
|
||||||
|
console.log('=== 开始调用 mockFillStepTaskTaskProcess Mock API ===')
|
||||||
console.log('1. 当前任务数据 (IRawStepTask 格式):', currentTask.value)
|
console.log('1. 当前任务数据 (IRawStepTask 格式):', currentTask.value)
|
||||||
console.log('2. 选中的 agents:', agentArray)
|
console.log('2. 选中的 agents:', agentArray)
|
||||||
|
|
||||||
@@ -218,12 +211,14 @@ const confirmAgentSelection = async () => {
|
|||||||
console.log('✅ Mock API 调用成功,数据已存储到 selectionStore')
|
console.log('✅ Mock API 调用成功,数据已存储到 selectionStore')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Mock API 调用失败:', error)
|
console.error('❌ Mock API 调用失败:', error)
|
||||||
|
} finally {
|
||||||
|
isLoadingConfirm.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 点击 Assignment 部分的 agent 组合卡片,更新 Comparison 部分的选中状态
|
// 点击 Assignment 部分的 agent 组合卡片,更新 Comparison 部分的选中状态
|
||||||
const selectAgentGroup = (agentNames: string[]) => {
|
const selectAgentGroup = async (agentNames: string[]) => {
|
||||||
// 更新Assignment边框状态
|
// 更新Assignment边框状态
|
||||||
selectedAssignmentGroup.value = [...agentNames]
|
selectedAssignmentGroup.value = [...agentNames]
|
||||||
|
|
||||||
@@ -237,6 +232,116 @@ const selectAgentGroup = (agentNames: string[]) => {
|
|||||||
agentsStore.setSelectedAgentGroup(currentTask.value.Id, agentNames)
|
agentsStore.setSelectedAgentGroup(currentTask.value.Id, agentNames)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🆕 联动更新:更新 currentTask 的 AgentSelection 和 TaskProcess
|
||||||
|
if (currentTask.value?.Id && agentNames.length > 0) {
|
||||||
|
console.log('🔄 开始联动更新 currentTask 的 agent 组合:', agentNames)
|
||||||
|
|
||||||
|
// 从 selectionStore 获取该 agent 组合对应的 TaskProcess 数据
|
||||||
|
let taskProcessData = selectionStore.getAgentTaskProcess(currentTask.value.Id, agentNames)
|
||||||
|
|
||||||
|
// 🆕 如果 selectionStore 中没有数据,自动调用 API 加载
|
||||||
|
if (!taskProcessData) {
|
||||||
|
console.log('⚠️ selectionStore 中没有该组合的 TaskProcess 数据,开始加载...')
|
||||||
|
console.log('📋 当前任务信息:', {
|
||||||
|
taskId: currentTask.value.Id,
|
||||||
|
taskName: currentTask.value.StepName,
|
||||||
|
agents: agentNames
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
isLoadingSelectGroup.value = true
|
||||||
|
// 将 IRawStepTask 转换为 IApiStepTask 格式
|
||||||
|
const stepTaskForApi = {
|
||||||
|
name: currentTask.value.StepName || '',
|
||||||
|
content: currentTask.value.TaskContent || '',
|
||||||
|
inputs: currentTask.value.InputObject_List || [],
|
||||||
|
output: currentTask.value.OutputObject || '',
|
||||||
|
agents: agentNames,
|
||||||
|
brief: currentTask.value.Collaboration_Brief_frontEnd || {
|
||||||
|
template: '',
|
||||||
|
data: {}
|
||||||
|
},
|
||||||
|
process: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const goal = agentsStore.agentRawPlan.data?.['General Goal'] || '开发智能协作系统'
|
||||||
|
|
||||||
|
console.log('📤 准备调用 API:', {
|
||||||
|
goal,
|
||||||
|
stepTask: stepTaskForApi,
|
||||||
|
agents: agentNames
|
||||||
|
})
|
||||||
|
|
||||||
|
// 调用 Mock API 加载数据
|
||||||
|
const filledTask = await api.mockFillStepTaskTaskProcess({
|
||||||
|
goal,
|
||||||
|
stepTask: stepTaskForApi,
|
||||||
|
agents: agentNames
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('🔍 API 返回的完整响应:', filledTask)
|
||||||
|
console.log('🔍 process 数据:', filledTask.process)
|
||||||
|
console.log('🔍 process 长度:', filledTask.process?.length)
|
||||||
|
console.log('✅ TaskProcess 数据加载成功:', {
|
||||||
|
agents: agentNames,
|
||||||
|
processCount: filledTask.process?.length || 0,
|
||||||
|
processDetail: filledTask.process,
|
||||||
|
briefDetail: filledTask.brief
|
||||||
|
})
|
||||||
|
|
||||||
|
// 存储到 selectionStore
|
||||||
|
selectionStore.setAgentTaskProcess(currentTask.value.Id, agentNames, filledTask)
|
||||||
|
|
||||||
|
console.log('💾 数据已存储到 selectionStore,验证存储是否成功...')
|
||||||
|
// 验证存储
|
||||||
|
const storedData = selectionStore.getAgentTaskProcess(currentTask.value.Id, agentNames)
|
||||||
|
console.log('📦 验证存储结果:', storedData ? '成功' : '失败', storedData)
|
||||||
|
|
||||||
|
taskProcessData = filledTask
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 加载 TaskProcess 数据失败:', error)
|
||||||
|
return
|
||||||
|
} finally {
|
||||||
|
isLoadingSelectGroup.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taskProcessData) {
|
||||||
|
console.log('✅ 找到 TaskProcess 数据,开始更新 currentTask:', {
|
||||||
|
taskId: currentTask.value.Id,
|
||||||
|
agents: agentNames,
|
||||||
|
processCount: taskProcessData.process?.length || 0,
|
||||||
|
processDetail: taskProcessData.process,
|
||||||
|
briefDetail: taskProcessData.brief
|
||||||
|
})
|
||||||
|
|
||||||
|
// 🆕 数据格式转换:IApiAgentAction[] → TaskProcess[]
|
||||||
|
const convertedTaskProcess = (taskProcessData.process || []).map(action => ({
|
||||||
|
ID: action.id,
|
||||||
|
ActionType: action.type,
|
||||||
|
AgentName: action.agent,
|
||||||
|
Description: action.description,
|
||||||
|
ImportantInput: action.inputs || []
|
||||||
|
}))
|
||||||
|
|
||||||
|
console.log('🔄 数据格式转换完成:', {
|
||||||
|
original: taskProcessData.process,
|
||||||
|
converted: convertedTaskProcess
|
||||||
|
})
|
||||||
|
|
||||||
|
// 更新 currentTask 的 AgentSelection 和 TaskProcess
|
||||||
|
// 使用 updateCurrentAgentSelection 强制更新,避免被 setCurrentTask 的"智能保留"逻辑阻止
|
||||||
|
agentsStore.updateCurrentAgentSelection(
|
||||||
|
[...agentNames],
|
||||||
|
convertedTaskProcess,
|
||||||
|
taskProcessData.brief || currentTask.value.Collaboration_Brief_frontEnd
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log('✅ currentTask 已更新,新的 AgentSelection:', agentNames)
|
||||||
|
console.log('📋 验证更新结果:', agentsStore.currentTask)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 重新排序:被选中的agent排在前面,其他agent按平均分降序
|
// 重新排序:被选中的agent排在前面,其他agent按平均分降序
|
||||||
if (agentsHeatmapData.value.length > 0) {
|
if (agentsHeatmapData.value.length > 0) {
|
||||||
agentsHeatmapData.value.sort((a, b) => {
|
agentsHeatmapData.value.sort((a, b) => {
|
||||||
@@ -406,18 +511,27 @@ const fetchAgentScores = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 切换到真实API时,取消注释下面这行
|
// TODO: 切换到真实API时,取消注释下面这行
|
||||||
// const response = await api.agentSelectModifyInit({
|
// const agentScores = await api.agentSelectModifyInit({
|
||||||
// goal: agentsStore.agentRawPlan.data?.['General Goal'] || '',
|
// goal: agentsStore.agentRawPlan.data?.['General Goal'] || '',
|
||||||
// stepTask: currentTask.value
|
// stepTask: currentTask.value
|
||||||
// })
|
// })
|
||||||
|
|
||||||
// 使用 Mock API(开发阶段)
|
// 🆕 使用 Mock API(开发阶段),传递当前任务的 AgentSelection 以获取对应的维度
|
||||||
|
const goal = agentsStore.agentRawPlan.data?.['General Goal'] || '开发智能协作系统'
|
||||||
|
console.log('📤 调用 mockAgentSelectModifyInit,参数:', {
|
||||||
|
goal,
|
||||||
|
stepTask: currentTask.value,
|
||||||
|
agentSelection: currentTask.value?.AgentSelection
|
||||||
|
})
|
||||||
|
|
||||||
const agentScores = await api.mockAgentSelectModifyInit()
|
const agentScores = await api.mockAgentSelectModifyInit()
|
||||||
|
|
||||||
// 从转换后的数据中提取维度列表(第一个agent的所有维度)
|
// 从转换后的数据中提取维度列表(第一个agent的所有维度)
|
||||||
const firstAgent = Object.keys(agentScores)[0]
|
const firstAgent = Object.keys(agentScores)[0]
|
||||||
const aspectList = firstAgent ? Object.keys(agentScores[firstAgent] || {}) : []
|
const aspectList = firstAgent ? Object.keys(agentScores[firstAgent] || {}) : []
|
||||||
|
|
||||||
|
console.log('✅ 获取到的维度列表:', aspectList)
|
||||||
|
|
||||||
// 保存到 store
|
// 保存到 store
|
||||||
agentsStore.setAgentScoreData({
|
agentsStore.setAgentScoreData({
|
||||||
aspectList,
|
aspectList,
|
||||||
@@ -594,9 +708,10 @@ watch(
|
|||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
// 按需加载初始 agent 组合的 TaskProcess(方案B)
|
// 初始化和任务切换处理
|
||||||
// 当用户第一次打开智能体探索窗口时,检查当前任务的初始 agent 组合是否已有 TaskProcess 数据
|
// 1. 首次加载时,自动将初始 agent 组合添加到 confirmedAgentGroups
|
||||||
// 如果没有,则调用 fill_stepTask_TaskProcess API 获取并存储
|
// 2. 恢复之前的选择状态
|
||||||
|
// 3. 加载 TaskProcess 数据
|
||||||
watch(
|
watch(
|
||||||
() => currentTask.value,
|
() => currentTask.value,
|
||||||
async newTask => {
|
async newTask => {
|
||||||
@@ -604,66 +719,82 @@ watch(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从 store 中恢复之前选择的 agent 组合
|
// 检查是否已经添加过初始组合
|
||||||
|
const existingGroups = agentsStore.getConfirmedAgentGroups(newTask.Id)
|
||||||
|
const hasInitialGroup = existingGroups.length > 0
|
||||||
|
|
||||||
|
// 首次初始化:自动添加初始组合(相当于系统自动执行了 confirmAgentSelection)
|
||||||
|
if (!hasInitialGroup) {
|
||||||
|
console.log('🎯 首次初始化,自动添加初始 agent 组合到 Assignment')
|
||||||
|
agentsStore.addConfirmedAgentGroup(newTask.Id, [...newTask.AgentSelection])
|
||||||
|
|
||||||
|
// 调用 API 获取初始 agent 组合的 TaskProcess 数据
|
||||||
|
console.log('🔄 开始加载初始 agent 组合的 TaskProcess...')
|
||||||
|
|
||||||
|
// 检查是否已有数据
|
||||||
|
if (!selectionStore.hasAgentTaskProcess(newTask.Id, newTask.AgentSelection)) {
|
||||||
|
try {
|
||||||
|
isLoadingInitialTask.value = true
|
||||||
|
console.log('=== 开始加载初始 agent 组合的 TaskProcess ===')
|
||||||
|
console.log('1. 任务ID:', newTask.Id)
|
||||||
|
console.log('2. 初始 agents:', newTask.AgentSelection)
|
||||||
|
|
||||||
|
// 将 IRawStepTask 转换为 IApiStepTask 格式
|
||||||
|
const stepTaskForApi = {
|
||||||
|
name: newTask.StepName || '',
|
||||||
|
content: newTask.TaskContent || '',
|
||||||
|
inputs: newTask.InputObject_List || [],
|
||||||
|
output: newTask.OutputObject || '',
|
||||||
|
agents: newTask.AgentSelection,
|
||||||
|
brief: newTask.Collaboration_Brief_frontEnd || {
|
||||||
|
template: '',
|
||||||
|
data: {}
|
||||||
|
},
|
||||||
|
process: []
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('3. 转换后的 API 请求参数:', stepTaskForApi)
|
||||||
|
|
||||||
|
const goal = agentsStore.agentRawPlan.data?.['General Goal'] || '开发智能协作系统'
|
||||||
|
console.log('4. General Goal:', goal)
|
||||||
|
|
||||||
|
// 调用 Mock API 获取 TaskProcess
|
||||||
|
const filledTask = await api.mockFillStepTaskTaskProcess({
|
||||||
|
goal,
|
||||||
|
stepTask: stepTaskForApi,
|
||||||
|
agents: newTask.AgentSelection
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('=== 初始 agent 组合 TaskProcess 加载成功 ===')
|
||||||
|
console.log('5. TaskProcess 流程数量:', filledTask.process?.length || 0)
|
||||||
|
|
||||||
|
// 存储到 selectionStore
|
||||||
|
selectionStore.setAgentTaskProcess(newTask.Id, newTask.AgentSelection, filledTask)
|
||||||
|
console.log('✅ 初始 agent 组合的 TaskProcess 已加载并存储')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ 加载初始 agent 组合的 TaskProcess 失败:', error)
|
||||||
|
} finally {
|
||||||
|
isLoadingInitialTask.value = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('ℹ️ 初始 agent 组合已有 TaskProcess 数据,跳过加载')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从 store 中恢复之前选择的 agent 组合(如果有)
|
||||||
const savedAgentGroup = agentsStore.getSelectedAgentGroup(newTask.Id)
|
const savedAgentGroup = agentsStore.getSelectedAgentGroup(newTask.Id)
|
||||||
if (savedAgentGroup) {
|
if (savedAgentGroup) {
|
||||||
console.log('📂 恢复之前选择的 agent 组合:', savedAgentGroup)
|
console.log('📂 恢复之前选择的 agent 组合:', savedAgentGroup)
|
||||||
selectedAssignmentGroup.value = [...savedAgentGroup]
|
selectedAssignmentGroup.value = [...savedAgentGroup]
|
||||||
selectedAgents.value = new Set(savedAgentGroup)
|
selectedAgents.value = new Set(savedAgentGroup)
|
||||||
} else {
|
} else {
|
||||||
// 没有保存的选择,使用默认的初始组合
|
// 没有保存的选择,默认选中第一个组合(即初始组合)
|
||||||
selectedAssignmentGroup.value = [...newTask.AgentSelection]
|
const allGroups = agentsStore.getConfirmedAgentGroups(newTask.Id)
|
||||||
selectedAgents.value = new Set(newTask.AgentSelection)
|
if (allGroups.length > 0 && allGroups[0]) {
|
||||||
}
|
console.log('🔄 默认选中第一个组合(初始组合):', allGroups[0])
|
||||||
|
selectedAssignmentGroup.value = [...allGroups[0]]
|
||||||
// 调用 API 获取初始 agent 组合的 TaskProcess 数据
|
selectedAgents.value = new Set(allGroups[0])
|
||||||
console.log('🔄 开始加载初始 agent 组合的 TaskProcess...')
|
|
||||||
|
|
||||||
// 检查是否已有数据
|
|
||||||
if (selectionStore.hasAgentTaskProcess(newTask.Id, newTask.AgentSelection)) {
|
|
||||||
console.log('ℹ️ 初始 agent 组合已有 TaskProcess 数据,跳过加载')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log('=== 开始加载初始 agent 组合的 TaskProcess ===')
|
|
||||||
console.log('1. 任务ID:', newTask.Id)
|
|
||||||
console.log('2. 初始 agents:', newTask.AgentSelection)
|
|
||||||
|
|
||||||
// 将 IRawStepTask 转换为 IApiStepTask 格式
|
|
||||||
const stepTaskForApi = {
|
|
||||||
name: newTask.StepName || '',
|
|
||||||
content: newTask.TaskContent || '',
|
|
||||||
inputs: newTask.InputObject_List || [],
|
|
||||||
output: newTask.OutputObject || '',
|
|
||||||
agents: newTask.AgentSelection,
|
|
||||||
brief: newTask.Collaboration_Brief_frontEnd || {
|
|
||||||
template: '',
|
|
||||||
data: {}
|
|
||||||
},
|
|
||||||
process: []
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('3. 转换后的 API 请求参数:', stepTaskForApi)
|
|
||||||
|
|
||||||
const goal = agentsStore.agentRawPlan.data?.['General Goal'] || '开发智能协作系统'
|
|
||||||
console.log('4. General Goal:', goal)
|
|
||||||
|
|
||||||
// 调用 Mock API 获取 TaskProcess
|
|
||||||
const filledTask = await api.mockFillStepTaskTaskProcess({
|
|
||||||
goal,
|
|
||||||
stepTask: stepTaskForApi,
|
|
||||||
agents: newTask.AgentSelection
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log('=== 初始 agent 组合 TaskProcess 加载成功 ===')
|
|
||||||
console.log('5. TaskProcess 流程数量:', filledTask.process?.length || 0)
|
|
||||||
|
|
||||||
// 存储到 selectionStore
|
|
||||||
selectionStore.setAgentTaskProcess(newTask.Id, newTask.AgentSelection, filledTask)
|
|
||||||
console.log('✅ 初始 agent 组合的 TaskProcess 已加载并存储')
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ 加载初始 agent 组合的 TaskProcess 失败:', error)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ immediate: true } // 立即执行一次
|
{ immediate: true } // 立即执行一次
|
||||||
@@ -672,7 +803,7 @@ watch(
|
|||||||
// 获取热力图颜色(评分1-5,颜色从浅到深)
|
// 获取热力图颜色(评分1-5,颜色从浅到深)
|
||||||
const getHeatmapColor = (score: number) => {
|
const getHeatmapColor = (score: number) => {
|
||||||
const colors = [
|
const colors = [
|
||||||
'#f0f0f0', // 1分 - 最浅
|
'#f7f7f7', // 1分 - 最浅
|
||||||
'#d4e5f7', // 2分
|
'#d4e5f7', // 2分
|
||||||
'#89b4e8', // 3分
|
'#89b4e8', // 3分
|
||||||
'#4575b4', // 4分
|
'#4575b4', // 4分
|
||||||
@@ -686,49 +817,15 @@ const getHeatmapColor = (score: number) => {
|
|||||||
<div class="agent-allocation-container">
|
<div class="agent-allocation-container">
|
||||||
<!-- 左侧区域 - 20% -->
|
<!-- 左侧区域 - 20% -->
|
||||||
<div class="allocation-left">
|
<div class="allocation-left">
|
||||||
<div class="section-card">
|
<div class="section-card" v-loading="isLoadingSelectGroup">
|
||||||
<div class="section-title">Assignment</div>
|
<div class="section-title">Assignment</div>
|
||||||
<!-- 初始agent组合卡片 -->
|
<!-- 所有 agent 组合卡片(包括初始组合和用户创建的组合) -->
|
||||||
<div
|
|
||||||
class="agents-grid"
|
|
||||||
:class="{ 'agent-group-selected': isAgentGroupSelected(currentTaskAgents) }"
|
|
||||||
@click="selectAgentGroup(currentTaskAgents)"
|
|
||||||
>
|
|
||||||
<el-tooltip
|
|
||||||
v-for="agent in currentTaskAgents"
|
|
||||||
:key="agent"
|
|
||||||
effect="light"
|
|
||||||
placement="top"
|
|
||||||
:teleported="false"
|
|
||||||
:show-after="500"
|
|
||||||
popper-class="agent-allocation-tooltip-popper"
|
|
||||||
>
|
|
||||||
<template #content>
|
|
||||||
<div class="agent-tooltip">
|
|
||||||
<div class="agent-tooltip-name">{{ agent }}</div>
|
|
||||||
<div class="agent-tooltip-separator"></div>
|
|
||||||
<div class="agent-tooltip-description">
|
|
||||||
{{
|
|
||||||
agentsStore.agents.find(a => a.Name === agent)?.Profile || '暂无描述'
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<div class="agent-item">
|
|
||||||
<div class="agent-icon" :style="{ background: getAgentMapIcon(agent).color }">
|
|
||||||
<svg-icon :icon-class="getAgentMapIcon(agent).icon" color="#fff" size="20px" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-tooltip>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 确认的agent组合列表 -->
|
|
||||||
<div
|
<div
|
||||||
v-for="(group, groupIndex) in confirmedAgentGroups"
|
v-for="(group, groupIndex) in confirmedAgentGroups"
|
||||||
:key="groupIndex"
|
:key="groupIndex"
|
||||||
class="agents-grid"
|
class="agents-grid"
|
||||||
:class="{ 'agent-group-selected': isAgentGroupSelected(group) }"
|
:class="{ 'agent-group-selected': isAgentGroupSelected(group) }"
|
||||||
style="margin-top: 12px"
|
:style="{ marginTop: groupIndex > 0 ? '12px' : '0' }"
|
||||||
@click="selectAgentGroup(group)"
|
@click="selectAgentGroup(group)"
|
||||||
>
|
>
|
||||||
<el-tooltip
|
<el-tooltip
|
||||||
@@ -767,7 +864,11 @@ const getHeatmapColor = (score: number) => {
|
|||||||
<div class="allocation-right">
|
<div class="allocation-right">
|
||||||
<div class="section-card">
|
<div class="section-card">
|
||||||
<div class="section-title">Comparison</div>
|
<div class="section-title">Comparison</div>
|
||||||
<div v-if="allAgents.length > 0" class="comparison-content">
|
<div
|
||||||
|
v-if="allAgents.length > 0"
|
||||||
|
class="comparison-content"
|
||||||
|
v-loading="isInitializing || isLoadingInitialTask || isLoadingConfirm"
|
||||||
|
>
|
||||||
<!-- 热力矩阵图 -->
|
<!-- 热力矩阵图 -->
|
||||||
<div v-if="agentsHeatmapData.length > 0" class="heatmap-container">
|
<div v-if="agentsHeatmapData.length > 0" class="heatmap-container">
|
||||||
<!-- 虚线选择框 - 包裹选中的agent头像 -->
|
<!-- 虚线选择框 - 包裹选中的agent头像 -->
|
||||||
@@ -777,7 +878,11 @@ const getHeatmapColor = (score: number) => {
|
|||||||
:style="getSelectionBoxStyle()"
|
:style="getSelectionBoxStyle()"
|
||||||
>
|
>
|
||||||
<!-- 确定按钮 -->
|
<!-- 确定按钮 -->
|
||||||
<div class="confirm-button" @click="confirmAgentSelection">
|
<div
|
||||||
|
class="confirm-button"
|
||||||
|
:class="{ 'is-loading': isLoadingConfirm }"
|
||||||
|
@click="confirmAgentSelection"
|
||||||
|
>
|
||||||
<svg-icon icon-class="Check" color="#328621" size="12px" />
|
<svg-icon icon-class="Check" color="#328621" size="12px" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -874,7 +979,7 @@ const getHeatmapColor = (score: number) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 输入框区域 -->
|
<!-- 输入框区域 -->
|
||||||
<div class="search-input-container">
|
<div class="search-input-container" v-loading="isAddingDimension">
|
||||||
<el-input
|
<el-input
|
||||||
v-model="searchValue"
|
v-model="searchValue"
|
||||||
placeholder="请输入新维度"
|
placeholder="请输入新维度"
|
||||||
@@ -887,7 +992,7 @@ const getHeatmapColor = (score: number) => {
|
|||||||
size="16px"
|
size="16px"
|
||||||
color="#409eff"
|
color="#409eff"
|
||||||
class="submit-icon"
|
class="submit-icon"
|
||||||
:class="{ 'is-disabled': !searchValue }"
|
:class="{ 'is-disabled': !searchValue, 'is-loading': isAddingDimension }"
|
||||||
@click="searchValue && handleSubmit()"
|
@click="searchValue && handleSubmit()"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -1039,6 +1144,25 @@ const getHeatmapColor = (score: number) => {
|
|||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.is-loading {
|
||||||
|
opacity: 0.6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
from {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1102,16 +1226,19 @@ const getHeatmapColor = (score: number) => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
padding-top: 40px; // 对齐第一个评分单元格(跳过列头)
|
padding-top: 40px; // 对齐第一个评分单元格
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
max-width: 200px; //
|
||||||
|
|
||||||
.dimension-label {
|
.dimension-label {
|
||||||
width: 60px;
|
min-width: 60px; // 改为最小宽度,允许根据内容自适应
|
||||||
|
width: auto; // 宽度自适应
|
||||||
height: 40px;
|
height: 40px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
|
padding-right: 8px; // 添加右侧内边距,确保文字不会紧贴边缘
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--color-text-title-header);
|
color: var(--color-text-title-header);
|
||||||
@@ -1119,6 +1246,7 @@ const getHeatmapColor = (score: number) => {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
|
white-space: nowrap; // 防止文字换行
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: #409eff;
|
color: #409eff;
|
||||||
@@ -1177,6 +1305,11 @@ const getHeatmapColor = (score: number) => {
|
|||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.is-loading {
|
||||||
|
opacity: 0.7;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ const agentGroupCount = computed(() => {
|
|||||||
const confirmedGroups = agentsStore.getConfirmedAgentGroups(agentsStore.currentTask.Id)
|
const confirmedGroups = agentsStore.getConfirmedAgentGroups(agentsStore.currentTask.Id)
|
||||||
|
|
||||||
// 当前任务agents(1) + 已确认的agent组合数量
|
// 当前任务agents(1) + 已确认的agent组合数量
|
||||||
return 1 + confirmedGroups.length
|
return confirmedGroups.length || 1
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ const emit = defineEmits<{
|
|||||||
// 获取分支数量 - 主分支(1) + 额外分支数量
|
// 获取分支数量 - 主分支(1) + 额外分支数量
|
||||||
const branchCount = computed(() => {
|
const branchCount = computed(() => {
|
||||||
// flowBranches 包含所有通过 Branch 创建的分支
|
// flowBranches 包含所有通过 Branch 创建的分支
|
||||||
const extraBranches = selectionStore.flowBranches?.length || 0
|
const extraBranches = selectionStore.flowBranches?.length || 1
|
||||||
// 始终至少有1个主分支
|
// 始终至少有1个主分支
|
||||||
return 1 + extraBranches
|
return extraBranches
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
@@ -26,7 +26,7 @@ const handleClick = () => {
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="branch-button"
|
class="branch-button"
|
||||||
:class="{ 'has-branches': branchCount > 1 }"
|
:class="{ 'has-branches': branchCount > 0 }"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
:title="`${branchCount} 个分支`"
|
:title="`${branchCount} 个分支`"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -0,0 +1,116 @@
|
|||||||
|
// Mock数据 - 用于agentSelectModifyAddAspect接口
|
||||||
|
// 模拟用户输入新维度后,所有agent在该维度上的评分数据
|
||||||
|
|
||||||
|
import { vueAgentList } from './AgentAssignmentMock'
|
||||||
|
|
||||||
|
// 类型定义
|
||||||
|
export interface NewDimensionScore {
|
||||||
|
score: number
|
||||||
|
reason: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type NewDimensionScoreData = Record<string, NewDimensionScore>
|
||||||
|
|
||||||
|
// 模拟接口返回的数据结构
|
||||||
|
export interface AgentAddAspectResponse {
|
||||||
|
aspectName: string // 新添加的维度名称
|
||||||
|
agentScores: NewDimensionScoreData // 所有agent在该维度上的评分
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成指定维度名称的mock评分数据
|
||||||
|
export const generateMockDimensionScores = (dimensionName: string): AgentAddAspectResponse => {
|
||||||
|
const agentScores: NewDimensionScoreData = {}
|
||||||
|
|
||||||
|
vueAgentList.forEach((agent) => {
|
||||||
|
// 随机生成1-5的评分
|
||||||
|
const score = Math.floor(Math.random() * 5) + 1
|
||||||
|
|
||||||
|
// 根据评分生成不同的原因描述
|
||||||
|
let reason = ''
|
||||||
|
switch (score) {
|
||||||
|
case 5:
|
||||||
|
reason = `在"${dimensionName}"方面表现卓越,展现出杰出的能力和深刻的理解`
|
||||||
|
break
|
||||||
|
case 4:
|
||||||
|
reason = `在"${dimensionName}"方面表现优秀,具有良好的专业能力和执行力`
|
||||||
|
break
|
||||||
|
case 3:
|
||||||
|
reason = `在"${dimensionName}"方面表现合格,能够完成相关任务`
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
reason = `在"${dimensionName}"方面表现一般,仍有提升空间`
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
reason = `在"${dimensionName}"方面需要加强,建议进一步提升相关能力`
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
agentScores[agent] = { score, reason }
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
aspectName: dimensionName,
|
||||||
|
agentScores,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预设的一些常用维度及其评分数据
|
||||||
|
export const presetDimensionScores: Record<string, AgentAddAspectResponse> = {
|
||||||
|
创新性: generateMockDimensionScores('创新性'),
|
||||||
|
技术能力: generateMockDimensionScores('技术能力'),
|
||||||
|
沟通技巧: generateMockDimensionScores('沟通技巧'),
|
||||||
|
问题解决: generateMockDimensionScores('问题解决'),
|
||||||
|
团队协作: generateMockDimensionScores('团队协作'),
|
||||||
|
学习能力: generateMockDimensionScores('学习能力'),
|
||||||
|
执行力: generateMockDimensionScores('执行力'),
|
||||||
|
责任心: generateMockDimensionScores('责任心'),
|
||||||
|
适应性: generateMockDimensionScores('适应性'),
|
||||||
|
领导力: generateMockDimensionScores('领导力'),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟API调用函数(用于前端测试)
|
||||||
|
export const mockAgentAddAspectApi = async (
|
||||||
|
aspectList: string[],
|
||||||
|
): Promise<AgentAddAspectResponse[]> => {
|
||||||
|
// 获取新增的维度(最后一个)
|
||||||
|
const newAspect = aspectList[aspectList.length - 1]
|
||||||
|
|
||||||
|
// 模拟网络延迟 500ms
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 20000))
|
||||||
|
|
||||||
|
// 如果是预设维度,返回预设数据
|
||||||
|
if (presetDimensionScores[newAspect]) {
|
||||||
|
return [presetDimensionScores[newAspect]]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则动态生成新的评分数据
|
||||||
|
return [generateMockDimensionScores(newAspect)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vue Composition API 兼容的hook
|
||||||
|
export const useAgentAddAspectMock = () => {
|
||||||
|
const addNewDimension = async (dimensionName: string) => {
|
||||||
|
const response = await mockAgentAddAspectApi([dimensionName])
|
||||||
|
return response[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
const getMultipleDimensions = async (dimensionNames: string[]) => {
|
||||||
|
const responses: AgentAddAspectResponse[] = []
|
||||||
|
|
||||||
|
for (const dimension of dimensionNames) {
|
||||||
|
if (presetDimensionScores[dimension]) {
|
||||||
|
responses.push(presetDimensionScores[dimension])
|
||||||
|
} else {
|
||||||
|
responses.push(generateMockDimensionScores(dimension))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return responses
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
addNewDimension,
|
||||||
|
getMultipleDimensions,
|
||||||
|
generateMockDimensionScores,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,192 @@
|
|||||||
|
// 模拟后端原始返回格式的Mock数据 - 维度 -> agent -> { Reason, Score }
|
||||||
|
import { vueAgentList, vueAspectList } from './AgentAssignmentMock'
|
||||||
|
|
||||||
|
// 后端返回的评分项格式
|
||||||
|
export interface BackendScoreItem {
|
||||||
|
Reason: string
|
||||||
|
Score: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后端返回的完整数据格式
|
||||||
|
export type BackendAgentScoreResponse = Record<string, Record<string, BackendScoreItem>>
|
||||||
|
|
||||||
|
// 模拟后端返回的原始数据结构(维度 -> agent -> { Reason, Score })
|
||||||
|
export const mockBackendAgentScoreData: BackendAgentScoreResponse = {
|
||||||
|
能力: {
|
||||||
|
船舶设计师: { Reason: '展现出卓越的创造力和创新思维', Score: 4 },
|
||||||
|
防护工程专家: { Reason: '展现出杰出的创造性问题解决能力', Score: 5 },
|
||||||
|
病理生理学家: { Reason: '具有中等创造技能,有待提升', Score: 3 },
|
||||||
|
药物化学家: { Reason: '在大多数情况下展现较强的创造性思维', Score: 4 },
|
||||||
|
制剂工程师: { Reason: '展现出胜任的创造能力', Score: 3 },
|
||||||
|
监管事务专家: { Reason: '具有较强的创造性表达能力', Score: 4 },
|
||||||
|
物理学家: { Reason: '擅长创新性思维方法', Score: 5 },
|
||||||
|
实验材料学家: { Reason: '展现出卓越的创造性思维和创新能力', Score: 5 },
|
||||||
|
计算模拟专家: { Reason: '展现出良好的创造性问题解决能力', Score: 4 },
|
||||||
|
腐蚀机理研究员: { Reason: '展现出卓越的创造性问题解决能力', Score: 5 },
|
||||||
|
先进材料研发员: { Reason: '展现出平衡的创造能力', Score: 4 },
|
||||||
|
肾脏病学家: { Reason: '展现出卓越的创造天赋', Score: 5 },
|
||||||
|
临床研究协调员: { Reason: '展现出胜任的创造性思维', Score: 3 },
|
||||||
|
中医药专家: { Reason: '展现出较强的创造性主动性', Score: 4 },
|
||||||
|
药物安全专家: { Reason: '具有发展中的创造技能', Score: 3 },
|
||||||
|
二维材料科学家: { Reason: '展现出卓越的创造愿景', Score: 5 },
|
||||||
|
光电物理学家: { Reason: '展现出卓越的创造性执行力', Score: 4 },
|
||||||
|
机器学习专家: { Reason: '具有较强的创造性问题解决能力', Score: 4 },
|
||||||
|
流体动力学专家: { Reason: '展现出胜任的创造能力', Score: 3 },
|
||||||
|
},
|
||||||
|
可用性: {
|
||||||
|
船舶设计师: { Reason: '展现出卓越的共情能力和社会意识', Score: 5 },
|
||||||
|
防护工程专家: { Reason: '具有较强的情绪调节和人际交往技能', Score: 4 },
|
||||||
|
病理生理学家: { Reason: '展现出卓越的情感智力', Score: 5 },
|
||||||
|
药物化学家: { Reason: '在大多数情况下展现平均的情感智力', Score: 3 },
|
||||||
|
制剂工程师: { Reason: '具有良好的情绪意识和沟通能力', Score: 4 },
|
||||||
|
监管事务专家: { Reason: '在情绪意识方面偶尔表现不足', Score: 3 },
|
||||||
|
物理学家: { Reason: '具有较强的情绪理解能力', Score: 4 },
|
||||||
|
实验材料学家: { Reason: '展现出卓越的共情能力和社交技能', Score: 5 },
|
||||||
|
计算模拟专家: { Reason: '具有良好的情绪调节能力', Score: 4 },
|
||||||
|
腐蚀机理研究员: { Reason: '展现出卓越的情感智力和社会意识', Score: 5 },
|
||||||
|
先进材料研发员: { Reason: '具有发展中的情绪意识', Score: 3 },
|
||||||
|
肾脏病学家: { Reason: '擅长人际交往和建立关系', Score: 5 },
|
||||||
|
临床研究协调员: { Reason: '展现出平衡的情感智力', Score: 4 },
|
||||||
|
中医药专家: { Reason: '具有基本的情绪理解能力', Score: 3 },
|
||||||
|
药物安全专家: { Reason: '展现出良好的情绪调节能力', Score: 4 },
|
||||||
|
二维材料科学家: { Reason: '展现出卓越的社会意识', Score: 5 },
|
||||||
|
光电物理学家: { Reason: '在情感智力方面需要提升', Score: 3 },
|
||||||
|
机器学习专家: { Reason: '具有较强的共情能力', Score: 4 },
|
||||||
|
流体动力学专家: { Reason: '具有良好的情绪沟通技能', Score: 4 },
|
||||||
|
},
|
||||||
|
专业性: {
|
||||||
|
船舶设计师: { Reason: '展现出胜任的哲学推理技能', Score: 3 },
|
||||||
|
防护工程专家: { Reason: '展现出卓越的逻辑推理和分析能力', Score: 5 },
|
||||||
|
病理生理学家: { Reason: '展现出深刻的哲学洞察力和批判性思维', Score: 2 },
|
||||||
|
药物化学家: { Reason: '展现出良好的哲学理解能力', Score: 1 },
|
||||||
|
制剂工程师: { Reason: '具有基础哲学推理能力,存在一些局限', Score: 3 },
|
||||||
|
监管事务专家: { Reason: '展现出较强的分析思维能力', Score: 4 },
|
||||||
|
物理学家: { Reason: '展现出卓越的哲学深度', Score: 5 },
|
||||||
|
实验材料学家: { Reason: '展现出卓越的专业分析和推理能力', Score: 5 },
|
||||||
|
计算模拟专家: { Reason: '具有良好的批判性思维能力', Score: 4 },
|
||||||
|
腐蚀机理研究员: { Reason: '具有较强的专业性分析和推理能力', Score: 4 },
|
||||||
|
先进材料研发员: { Reason: '展现出卓越的逻辑推理能力', Score: 5 },
|
||||||
|
肾脏病学家: { Reason: '具有基础的哲学理解能力', Score: 3 },
|
||||||
|
临床研究协调员: { Reason: '展现出平衡的哲学推理能力', Score: 4 },
|
||||||
|
中医药专家: { Reason: '需要在哲学思维方面发展', Score: 3 },
|
||||||
|
药物安全专家: { Reason: '展现出良好的分析技能', Score: 4 },
|
||||||
|
二维材料科学家: { Reason: '具有较强的哲学洞察力', Score: 4 },
|
||||||
|
光电物理学家: { Reason: '擅长批判性思维和分析', Score: 5 },
|
||||||
|
机器学习专家: { Reason: '具有基础哲学推理能力', Score: 3 },
|
||||||
|
流体动力学专家: { Reason: '展现出卓越的哲学才能', Score: 5 },
|
||||||
|
},
|
||||||
|
效率: {
|
||||||
|
船舶设计师: { Reason: '在任务完成方面展现出卓越的效率', Score: 4 },
|
||||||
|
防护工程专家: { Reason: '擅长高效的工作流程管理', Score: 5 },
|
||||||
|
病理生理学家: { Reason: '展现出平均的效率,有提升空间', Score: 3 },
|
||||||
|
药物化学家: { Reason: '具有良好的时间管理技能', Score: 4 },
|
||||||
|
制剂工程师: { Reason: '展现出胜任的效率', Score: 3 },
|
||||||
|
监管事务专家: { Reason: '展现出卓越的生产力', Score: 5 },
|
||||||
|
物理学家: { Reason: '具有强大的任务执行能力', Score: 4 },
|
||||||
|
实验材料学家: { Reason: '具有良好的工作效率和时间管理', Score: 4 },
|
||||||
|
计算模拟专家: { Reason: '展现出良好的工作流程优化能力', Score: 4 },
|
||||||
|
腐蚀机理研究员: { Reason: '展现出卓越的效率和工作流程管理', Score: 5 },
|
||||||
|
先进材料研发员: { Reason: '展现出足够的效率', Score: 3 },
|
||||||
|
肾脏病学家: { Reason: '擅长快速完成任务', Score: 5 },
|
||||||
|
临床研究协调员: { Reason: '展现出良好的生产力', Score: 4 },
|
||||||
|
中医药专家: { Reason: '具有中等的效率水平', Score: 3 },
|
||||||
|
药物安全专家: { Reason: '具有较强的任务效率', Score: 4 },
|
||||||
|
二维材料科学家: { Reason: '具有良好的执行速度', Score: 4 },
|
||||||
|
光电物理学家: { Reason: '展现出卓越的效率', Score: 5 },
|
||||||
|
机器学习专家: { Reason: '展现出平均的生产力', Score: 3 },
|
||||||
|
流体动力学专家: { Reason: '在执行方面具有良好的效率', Score: 4 },
|
||||||
|
},
|
||||||
|
准确性: {
|
||||||
|
船舶设计师: { Reason: '展现出卓越的细节关注度', Score: 5 },
|
||||||
|
防护工程专家: { Reason: '展现出卓越的准确性和精确度', Score: 5 },
|
||||||
|
病理生理学家: { Reason: '展现出卓越的精确度', Score: 5 },
|
||||||
|
药物化学家: { Reason: '展现出良好的准确性', Score: 4 },
|
||||||
|
制剂工程师: { Reason: '展现出中等的准确性,有提升空间', Score: 3 },
|
||||||
|
监管事务专家: { Reason: '具有较强的细节关注度', Score: 4 },
|
||||||
|
物理学家: { Reason: '在精确度和准确性方面表现卓越', Score: 5 },
|
||||||
|
实验材料学家: { Reason: '展现出卓越的细节导向和精确度', Score: 5 },
|
||||||
|
计算模拟专家: { Reason: '展现出平均的准确性', Score: 3 },
|
||||||
|
腐蚀机理研究员: { Reason: '展现出卓越的准确性和精确技能', Score: 5 },
|
||||||
|
先进材料研发员: { Reason: '展现出卓越的准确性', Score: 5 },
|
||||||
|
肾脏病学家: { Reason: '展现出较强的精确度', Score: 4 },
|
||||||
|
临床研究协调员: { Reason: '展现出中等的准确性', Score: 3 },
|
||||||
|
中医药专家: { Reason: '具有良好的细节导向能力', Score: 4 },
|
||||||
|
药物安全专家: { Reason: '在准确性和精确度方面表现卓越', Score: 5 },
|
||||||
|
二维材料科学家: { Reason: '展现出较强的细节关注度', Score: 4 },
|
||||||
|
光电物理学家: { Reason: '展现出平均的准确性水平', Score: 3 },
|
||||||
|
机器学习专家: { Reason: '在工作中具有良好的精确度', Score: 4 },
|
||||||
|
流体动力学专家: { Reason: '展现出卓越的准确性', Score: 5 },
|
||||||
|
},
|
||||||
|
协作性: {
|
||||||
|
船舶设计师: { Reason: '展现出卓越的协作技能', Score: 4 },
|
||||||
|
防护工程专家: { Reason: '在团队合作和协作方面表现卓越', Score: 5 },
|
||||||
|
病理生理学家: { Reason: '具有较强的协作能力', Score: 4 },
|
||||||
|
药物化学家: { Reason: '具有中等的协作技能', Score: 3 },
|
||||||
|
制剂工程师: { Reason: '展现出良好的团队合作精神', Score: 4 },
|
||||||
|
监管事务专家: { Reason: '具有较强的合作能力', Score: 4 },
|
||||||
|
物理学家: { Reason: '展现出平均的协作技能', Score: 3 },
|
||||||
|
实验材料学家: { Reason: '在团队协作方面表现卓越', Score: 5 },
|
||||||
|
计算模拟专家: { Reason: '展现出良好的合作工作能力', Score: 4 },
|
||||||
|
腐蚀机理研究员: { Reason: '在团队协作和合作方面表现卓越', Score: 5 },
|
||||||
|
先进材料研发员: { Reason: '具有中等的协作水平', Score: 3 },
|
||||||
|
肾脏病学家: { Reason: '展现出良好的协作技能', Score: 4 },
|
||||||
|
临床研究协调员: { Reason: '在协调和团队合作方面表现卓越', Score: 5 },
|
||||||
|
中医药专家: { Reason: '具有较强的合作能力', Score: 4 },
|
||||||
|
药物安全专家: { Reason: '展现出平均的协作水平', Score: 3 },
|
||||||
|
二维材料科学家: { Reason: '展现出良好的团队合作精神', Score: 4 },
|
||||||
|
光电物理学家: { Reason: '具有较强的协作技能', Score: 4 },
|
||||||
|
机器学习专家: { Reason: '在团队协作方面表现卓越', Score: 5 },
|
||||||
|
流体动力学专家: { Reason: '具有中等的协作能力', Score: 3 },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟后端API调用 - agentSelectModifyInit
|
||||||
|
export const mockBackendAgentSelectModifyInit = async (): Promise<BackendAgentScoreResponse> => {
|
||||||
|
// 模拟网络延迟 300ms
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 300))
|
||||||
|
return mockBackendAgentScoreData
|
||||||
|
}
|
||||||
|
|
||||||
|
// 模拟后端API调用 - agentSelectModifyAddAspect(添加新维度)
|
||||||
|
export const mockBackendAgentSelectModifyAddAspect = async (
|
||||||
|
aspectList: string[]
|
||||||
|
): Promise<BackendAgentScoreResponse> => {
|
||||||
|
// 模拟网络延迟 500ms
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 500))
|
||||||
|
|
||||||
|
// 获取新添加的维度(最后一个)
|
||||||
|
const newAspect = aspectList[aspectList.length - 1]
|
||||||
|
if (!newAspect) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成该维度下所有agent的评分
|
||||||
|
const aspectData: Record<string, BackendScoreItem> = {}
|
||||||
|
|
||||||
|
vueAgentList.forEach(agent => {
|
||||||
|
const score = Math.floor(Math.random() * 5) + 1
|
||||||
|
let reason = ''
|
||||||
|
switch (score) {
|
||||||
|
case 5:
|
||||||
|
reason = `在"${newAspect}"方面表现卓越,展现出杰出的能力和深刻的理解`
|
||||||
|
break
|
||||||
|
case 4:
|
||||||
|
reason = `在"${newAspect}"方面表现优秀,具有良好的专业能力和执行力`
|
||||||
|
break
|
||||||
|
case 3:
|
||||||
|
reason = `在"${newAspect}"方面表现合格,能够完成相关任务`
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
reason = `在"${newAspect}"方面表现一般,仍有提升空间`
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
reason = `在"${newAspect}"方面需要加强,建议进一步提升相关能力`
|
||||||
|
break
|
||||||
|
}
|
||||||
|
aspectData[agent] = { Reason: reason, Score: score }
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
[newAspect]: aspectData
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,314 @@
|
|||||||
|
// Vue兼容的mock数据 - 6个维度,19个智能体
|
||||||
|
export const vueAgentList = [
|
||||||
|
'船舶设计师',
|
||||||
|
'防护工程专家',
|
||||||
|
'病理生理学家',
|
||||||
|
'药物化学家',
|
||||||
|
'制剂工程师',
|
||||||
|
'监管事务专家',
|
||||||
|
'物理学家',
|
||||||
|
'实验材料学家',
|
||||||
|
'计算模拟专家',
|
||||||
|
'腐蚀机理研究员',
|
||||||
|
'先进材料研发员',
|
||||||
|
'肾脏病学家',
|
||||||
|
'临床研究协调员',
|
||||||
|
'中医药专家',
|
||||||
|
'药物安全专家',
|
||||||
|
'二维材料科学家',
|
||||||
|
'光电物理学家',
|
||||||
|
'机器学习专家',
|
||||||
|
'流体动力学专家',
|
||||||
|
]
|
||||||
|
|
||||||
|
export const vueAspectList = ['能力', '可用性', '专业性', '效率', '准确性', '协作性']
|
||||||
|
|
||||||
|
// 类型定义
|
||||||
|
export type AgentName = (typeof vueAgentList)[number]
|
||||||
|
export type AspectName = (typeof vueAspectList)[number]
|
||||||
|
|
||||||
|
export interface AgentScore {
|
||||||
|
score: number
|
||||||
|
reason: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IAgentSelectModifyAddRequest = Record<AspectName, Record<AgentName, AgentScore>>
|
||||||
|
|
||||||
|
// Vue友好的数据结构 - agent -> 维度 -> 评分(与后端返回格式一致)
|
||||||
|
export const vueAgentScoreData: Record<AgentName, Record<AspectName, AgentScore>> = {
|
||||||
|
船舶设计师: {
|
||||||
|
能力: { score: 4, reason: '展现出卓越的创造力和创新思维' },
|
||||||
|
可用性: { score: 5, reason: '展现出卓越的共情能力和社会意识' },
|
||||||
|
专业性: { score: 3, reason: '展现出胜任的哲学推理技能' },
|
||||||
|
效率: { score: 4, reason: '在任务完成方面展现出卓越的效率' },
|
||||||
|
准确性: { score: 5, reason: '展现出卓越的细节关注度' },
|
||||||
|
协作性: { score: 4, reason: '展现出卓越的协作技能' },
|
||||||
|
},
|
||||||
|
防护工程专家: {
|
||||||
|
能力: { score: 5, reason: '展现出杰出的创造性问题解决能力' },
|
||||||
|
可用性: { score: 4, reason: '具有较强的情绪调节和人际交往技能' },
|
||||||
|
专业性: { score: 5, reason: '展现出卓越的逻辑推理和分析能力' },
|
||||||
|
效率: { score: 5, reason: '擅长高效的工作流程管理' },
|
||||||
|
准确性: { score: 5, reason: '展现出卓越的准确性和精确度' },
|
||||||
|
协作性: { score: 5, reason: '在团队合作和协作方面表现卓越' },
|
||||||
|
},
|
||||||
|
病理生理学家: {
|
||||||
|
能力: { score: 3, reason: '具有中等创造技能,有待提升' },
|
||||||
|
可用性: { score: 5, reason: '展现出卓越的情感智力' },
|
||||||
|
专业性: { score: 2, reason: '展现出深刻的哲学洞察力和批判性思维' },
|
||||||
|
效率: { score: 3, reason: '展现出平均的效率,有提升空间' },
|
||||||
|
准确性: { score: 5, reason: '展现出卓越的精确度' },
|
||||||
|
协作性: { score: 4, reason: '具有较强的协作能力' },
|
||||||
|
},
|
||||||
|
药物化学家: {
|
||||||
|
能力: { score: 4, reason: '在大多数情况下展现较强的创造性思维' },
|
||||||
|
可用性: { score: 3, reason: '在大多数情况下展现平均的情感智力' },
|
||||||
|
专业性: { score: 1, reason: '展现出良好的哲学理解能力' },
|
||||||
|
效率: { score: 4, reason: '具有良好的时间管理技能' },
|
||||||
|
准确性: { score: 4, reason: '展现出良好的准确性' },
|
||||||
|
协作性: { score: 3, reason: '具有中等的协作技能' },
|
||||||
|
},
|
||||||
|
制剂工程师: {
|
||||||
|
能力: { score: 3, reason: '展现出胜任的创造能力' },
|
||||||
|
可用性: { score: 4, reason: '具有良好的情绪意识和沟通能力' },
|
||||||
|
专业性: { score: 3, reason: '具有基础哲学推理能力,存在一些局限' },
|
||||||
|
效率: { score: 3, reason: '展现出胜任的效率' },
|
||||||
|
准确性: { score: 3, reason: '展现出中等的准确性,有提升空间' },
|
||||||
|
协作性: { score: 4, reason: '展现出良好的团队合作精神' },
|
||||||
|
},
|
||||||
|
监管事务专家: {
|
||||||
|
能力: { score: 4, reason: '具有较强的创造性表达能力' },
|
||||||
|
可用性: { score: 3, reason: '在情绪意识方面偶尔表现不足' },
|
||||||
|
专业性: { score: 4, reason: '展现出较强的分析思维能力' },
|
||||||
|
效率: { score: 5, reason: '展现出卓越的生产力' },
|
||||||
|
准确性: { score: 4, reason: '具有较强的细节关注度' },
|
||||||
|
协作性: { score: 4, reason: '具有较强的合作能力' },
|
||||||
|
},
|
||||||
|
物理学家: {
|
||||||
|
能力: { score: 5, reason: '擅长创新性思维方法' },
|
||||||
|
可用性: { score: 4, reason: '具有较强的情绪理解能力' },
|
||||||
|
专业性: { score: 5, reason: '展现出卓越的哲学深度' },
|
||||||
|
效率: { score: 4, reason: '具有强大的任务执行能力' },
|
||||||
|
准确性: { score: 5, reason: '在精确度和准确性方面表现卓越' },
|
||||||
|
协作性: { score: 3, reason: '展现出平均的协作技能' },
|
||||||
|
},
|
||||||
|
实验材料学家: {
|
||||||
|
能力: { score: 5, reason: '展现出卓越的创造性思维和创新能力' },
|
||||||
|
可用性: { score: 5, reason: '展现出卓越的共情能力和社交技能' },
|
||||||
|
专业性: { score: 5, reason: '展现出卓越的专业分析和推理能力' },
|
||||||
|
效率: { score: 4, reason: '具有良好的工作效率和时间管理' },
|
||||||
|
准确性: { score: 5, reason: '展现出卓越的细节导向和精确度' },
|
||||||
|
协作性: { score: 5, reason: '在团队协作方面表现卓越' },
|
||||||
|
},
|
||||||
|
计算模拟专家: {
|
||||||
|
能力: { score: 4, reason: '展现出良好的创造性问题解决能力' },
|
||||||
|
可用性: { score: 4, reason: '具有良好的情绪调节能力' },
|
||||||
|
专业性: { score: 4, reason: '具有良好的批判性思维能力' },
|
||||||
|
效率: { score: 4, reason: '展现出良好的工作流程优化能力' },
|
||||||
|
准确性: { score: 3, reason: '展现出平均的准确性' },
|
||||||
|
协作性: { score: 4, reason: '展现出良好的合作工作能力' },
|
||||||
|
},
|
||||||
|
腐蚀机理研究员: {
|
||||||
|
能力: { score: 5, reason: '展现出卓越的创造性问题解决能力' },
|
||||||
|
可用性: { score: 5, reason: '展现出卓越的情感智力和社会意识' },
|
||||||
|
专业性: { score: 4, reason: '具有较强的专业性分析和推理能力' },
|
||||||
|
效率: { score: 5, reason: '展现出卓越的效率和工作流程管理' },
|
||||||
|
准确性: { score: 5, reason: '展现出卓越的准确性和精确技能' },
|
||||||
|
协作性: { score: 5, reason: '在团队协作和合作方面表现卓越' },
|
||||||
|
},
|
||||||
|
先进材料研发员: {
|
||||||
|
能力: { score: 4, reason: '展现出平衡的创造能力' },
|
||||||
|
可用性: { score: 3, reason: '具有发展中的情绪意识' },
|
||||||
|
专业性: { score: 5, reason: '展现出卓越的逻辑推理能力' },
|
||||||
|
效率: { score: 3, reason: '展现出足够的效率' },
|
||||||
|
准确性: { score: 5, reason: '展现出卓越的准确性' },
|
||||||
|
协作性: { score: 3, reason: '具有中等的协作水平' },
|
||||||
|
},
|
||||||
|
肾脏病学家: {
|
||||||
|
能力: { score: 5, reason: '展现出卓越的创造天赋' },
|
||||||
|
可用性: { score: 5, reason: '擅长人际交往和建立关系' },
|
||||||
|
专业性: { score: 3, reason: '具有基础的哲学理解能力' },
|
||||||
|
效率: { score: 5, reason: '擅长快速完成任务' },
|
||||||
|
准确性: { score: 4, reason: '展现出较强的精确度' },
|
||||||
|
协作性: { score: 4, reason: '展现出良好的协作技能' },
|
||||||
|
},
|
||||||
|
临床研究协调员: {
|
||||||
|
能力: { score: 3, reason: '展现出胜任的创造性思维' },
|
||||||
|
可用性: { score: 4, reason: '展现出平衡的情感智力' },
|
||||||
|
专业性: { score: 4, reason: '展现出平衡的哲学推理能力' },
|
||||||
|
效率: { score: 4, reason: '展现出良好的生产力' },
|
||||||
|
准确性: { score: 3, reason: '展现出中等的准确性' },
|
||||||
|
协作性: { score: 5, reason: '在协调和团队合作方面表现卓越' },
|
||||||
|
},
|
||||||
|
中医药专家: {
|
||||||
|
能力: { score: 4, reason: '展现出较强的创造性主动性' },
|
||||||
|
可用性: { score: 3, reason: '具有基本的情绪理解能力' },
|
||||||
|
专业性: { score: 3, reason: '需要在哲学思维方面发展' },
|
||||||
|
效率: { score: 3, reason: '具有中等的效率水平' },
|
||||||
|
准确性: { score: 4, reason: '具有良好的细节导向能力' },
|
||||||
|
协作性: { score: 4, reason: '具有较强的合作能力' },
|
||||||
|
},
|
||||||
|
药物安全专家: {
|
||||||
|
能力: { score: 3, reason: '具有发展中的创造技能' },
|
||||||
|
可用性: { score: 4, reason: '展现出良好的情绪调节能力' },
|
||||||
|
专业性: { score: 4, reason: '展现出良好的分析技能' },
|
||||||
|
效率: { score: 4, reason: '具有较强的任务效率' },
|
||||||
|
准确性: { score: 5, reason: '在准确性和精确度方面表现卓越' },
|
||||||
|
协作性: { score: 3, reason: '展现出平均的协作水平' },
|
||||||
|
},
|
||||||
|
二维材料科学家: {
|
||||||
|
能力: { score: 5, reason: '展现出卓越的创造愿景' },
|
||||||
|
可用性: { score: 5, reason: '展现出卓越的社会意识' },
|
||||||
|
专业性: { score: 4, reason: '具有较强的哲学洞察力' },
|
||||||
|
效率: { score: 4, reason: '具有良好的执行速度' },
|
||||||
|
准确性: { score: 4, reason: '展现出较强的细节关注度' },
|
||||||
|
协作性: { score: 4, reason: '展现出良好的团队合作精神' },
|
||||||
|
},
|
||||||
|
光电物理学家: {
|
||||||
|
能力: { score: 4, reason: '展现出卓越的创造性执行力' },
|
||||||
|
可用性: { score: 3, reason: '在情感智力方面需要提升' },
|
||||||
|
专业性: { score: 5, reason: '擅长批判性思维和分析' },
|
||||||
|
效率: { score: 5, reason: '展现出卓越的效率' },
|
||||||
|
准确性: { score: 3, reason: '展现出平均的准确性水平' },
|
||||||
|
协作性: { score: 4, reason: '具有较强的协作技能' },
|
||||||
|
},
|
||||||
|
机器学习专家: {
|
||||||
|
能力: { score: 4, reason: '具有较强的创造性问题解决能力' },
|
||||||
|
可用性: { score: 4, reason: '具有较强的共情能力' },
|
||||||
|
专业性: { score: 3, reason: '具有基础哲学推理能力' },
|
||||||
|
效率: { score: 3, reason: '展现出平均的生产力' },
|
||||||
|
准确性: { score: 4, reason: '在工作中具有良好的精确度' },
|
||||||
|
协作性: { score: 5, reason: '在团队协作方面表现卓越' },
|
||||||
|
},
|
||||||
|
流体动力学专家: {
|
||||||
|
能力: { score: 3, reason: '展现出胜任的创造能力' },
|
||||||
|
可用性: { score: 4, reason: '具有良好的情绪沟通技能' },
|
||||||
|
专业性: { score: 5, reason: '展现出卓越的哲学才能' },
|
||||||
|
效率: { score: 4, reason: '在执行方面具有良好的效率' },
|
||||||
|
准确性: { score: 5, reason: '展现出卓越的准确性' },
|
||||||
|
协作性: { score: 3, reason: '具有中等的协作能力' },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vue友好的智能体选择配置
|
||||||
|
export const vueAgentSelections = {
|
||||||
|
balanced: { agents: ['船舶设计师', '防护工程专家', '病理生理学家'] },
|
||||||
|
creative: { agents: ['防护工程专家', '物理学家', '二维材料科学家'] },
|
||||||
|
emotional: { agents: ['船舶设计师', '病理生理学家', '实验材料学家'] },
|
||||||
|
philosophical: { agents: ['病理生理学家', '物理学家', '光电物理学家'] },
|
||||||
|
mixed: { agents: ['药物化学家', '先进材料研发员', '肾脏病学家', '机器学习专家'] },
|
||||||
|
}
|
||||||
|
|
||||||
|
export const vueCurrentAgentSelection = 'balanced'
|
||||||
|
|
||||||
|
// Vue兼容的工具函数
|
||||||
|
export const vueCalculateAgentAverages = () => {
|
||||||
|
const averages: Record<string, number> = {}
|
||||||
|
|
||||||
|
vueAgentList.forEach((agent) => {
|
||||||
|
let total = 0
|
||||||
|
let count = 0
|
||||||
|
|
||||||
|
vueAspectList.forEach((aspect) => {
|
||||||
|
// 数据结构:agentScores[agent][aspect]
|
||||||
|
const scoreData = vueAgentScoreData[agent]?.[aspect]
|
||||||
|
if (scoreData) {
|
||||||
|
total += scoreData.score
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
averages[agent] = count > 0 ? Number((total / count).toFixed(2)) : 0
|
||||||
|
})
|
||||||
|
|
||||||
|
return averages
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取按平均分排序的智能体列表
|
||||||
|
export const vueGetSortedAgentsByAverage = () => {
|
||||||
|
const averages = vueCalculateAgentAverages()
|
||||||
|
return [...vueAgentList].sort((a, b) => {
|
||||||
|
return averages[b] - averages[a]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vue Composition API 兼容的hook
|
||||||
|
export const useAgentMockData = () => {
|
||||||
|
// 在Vue中可以使用ref或reactive包装数据
|
||||||
|
const agentScores = vueAgentScoreData
|
||||||
|
const agentSelections = vueAgentSelections
|
||||||
|
const currentSelection = vueCurrentAgentSelection
|
||||||
|
|
||||||
|
// 计算平均分的响应式函数
|
||||||
|
const calculateAverages = () => {
|
||||||
|
return vueCalculateAgentAverages()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取特定维度的评分(返回该维度下所有智能体的评分)
|
||||||
|
const getScoresByAspect = (aspect: AspectName) => {
|
||||||
|
const result: Record<AgentName, AgentScore> = {}
|
||||||
|
// 数据结构:agentScores[agent][aspect],需要遍历所有agent提取指定aspect
|
||||||
|
vueAgentList.forEach((agent) => {
|
||||||
|
if (agentScores[agent]?.[aspect]) {
|
||||||
|
result[agent] = agentScores[agent][aspect]!
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取特定智能体的所有维度评分
|
||||||
|
const getScoresByAgent = (agent: AgentName) => {
|
||||||
|
// 数据结构:agentScores[agent][aspect],直接返回agent的所有维度评分
|
||||||
|
return agentScores[agent] || {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
agentScores,
|
||||||
|
agentSelections,
|
||||||
|
currentSelection,
|
||||||
|
calculateAverages,
|
||||||
|
getScoresByAspect,
|
||||||
|
getScoresByAgent,
|
||||||
|
getSortedAgents: vueGetSortedAgentsByAverage,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vue 2.x 兼容的选项式API版本
|
||||||
|
export const vueMockMixin = {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
vueAgentScores: vueAgentScoreData,
|
||||||
|
vueAgentSelections: vueAgentSelections,
|
||||||
|
vueCurrentSelection: vueCurrentAgentSelection,
|
||||||
|
vueAgentList: vueAgentList,
|
||||||
|
vueAspectList: vueAspectList,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
vueAgentAverages() {
|
||||||
|
return vueCalculateAgentAverages()
|
||||||
|
},
|
||||||
|
vueSortedAgents() {
|
||||||
|
return vueGetSortedAgentsByAverage()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
vueGetScoresByAspect(aspect: AspectName) {
|
||||||
|
const agentScores = (this as any).vueAgentScores
|
||||||
|
const agentList = (this as any).vueAgentList
|
||||||
|
// 数据结构:agentScores[agent][aspect],遍历所有agent提取指定aspect
|
||||||
|
const result: Record<string, { score: number; reason: string }> = {}
|
||||||
|
agentList.forEach((agent: string) => {
|
||||||
|
if (agentScores[agent]?.[aspect]) {
|
||||||
|
result[agent] = agentScores[agent][aspect]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return result
|
||||||
|
},
|
||||||
|
vueGetScoresByAgent(agent: AgentName) {
|
||||||
|
const agentScores = (this as any).vueAgentScores
|
||||||
|
// 数据结构:agentScores[agent][aspect],直接返回agent的所有维度评分
|
||||||
|
return agentScores[agent] || {}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ import SvgIcon from '@/components/SvgIcon/index.vue'
|
|||||||
import { getAgentMapIcon } from '@/layout/components/config.ts'
|
import { getAgentMapIcon } from '@/layout/components/config.ts'
|
||||||
import { type ConnectArg, Jsplumb } from '@/layout/components/Main/TaskTemplate/utils.ts'
|
import { type ConnectArg, Jsplumb } from '@/layout/components/Main/TaskTemplate/utils.ts'
|
||||||
import { type IRawStepTask, useAgentsStore } from '@/stores'
|
import { type IRawStepTask, useAgentsStore } from '@/stores'
|
||||||
import { computed, ref, nextTick } from 'vue'
|
import { computed, ref, nextTick, watch, onMounted } from 'vue'
|
||||||
import { AnchorLocations } from '@jsplumb/browser-ui'
|
import { AnchorLocations } from '@jsplumb/browser-ui'
|
||||||
import MultiLineTooltip from '@/components/MultiLineTooltip/index.vue'
|
import MultiLineTooltip from '@/components/MultiLineTooltip/index.vue'
|
||||||
import Bg from './Bg.vue'
|
import Bg from './Bg.vue'
|
||||||
@@ -15,7 +15,6 @@ const planReady = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const openPlanModification = () => {
|
const openPlanModification = () => {
|
||||||
console.log('打开分支修改窗口')
|
|
||||||
agentsStore.openPlanModification()
|
agentsStore.openPlanModification()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +201,56 @@ function clear() {
|
|||||||
jsplumb.reset()
|
jsplumb.reset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 🆕 封装连线重绘方法
|
||||||
|
const redrawConnections = () => {
|
||||||
|
console.log('🔄 重新绘制 jsplumb 连线')
|
||||||
|
|
||||||
|
// 等待 DOM 更新完成
|
||||||
|
nextTick(() => {
|
||||||
|
// 清除旧连线
|
||||||
|
jsplumb.reset()
|
||||||
|
|
||||||
|
// 等待 DOM 稳定后重新绘制
|
||||||
|
setTimeout(() => {
|
||||||
|
const arr: ConnectArg[] = []
|
||||||
|
const currentTaskId = agentsStore.currentTask?.Id
|
||||||
|
|
||||||
|
// 重新绘制所有连线
|
||||||
|
collaborationProcess.value.forEach(item => {
|
||||||
|
arr.push(...handleCurrentTask(item, item.Id !== currentTaskId))
|
||||||
|
})
|
||||||
|
|
||||||
|
jsplumb.connects(arr)
|
||||||
|
console.log('✅ jsplumb 连线重绘完成,任务数:', collaborationProcess.value.length)
|
||||||
|
}, 100)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🆕 监听 collaborationProcess 变化,自动重绘连线
|
||||||
|
watch(
|
||||||
|
() => collaborationProcess,
|
||||||
|
() => {
|
||||||
|
console.log('🔍 collaborationProcess 发生变化,触发重绘')
|
||||||
|
redrawConnections()
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// 🆕 组件挂载后初始化连线
|
||||||
|
onMounted(() => {
|
||||||
|
// 初始化时绘制连线
|
||||||
|
nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const arr: ConnectArg[] = []
|
||||||
|
collaborationProcess.value.forEach(item => {
|
||||||
|
arr.push(...handleCurrentTask(item, true))
|
||||||
|
})
|
||||||
|
jsplumb.connects(arr)
|
||||||
|
console.log('✅ 初始化 jsplumb 连线完成')
|
||||||
|
}, 100)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
changeTask,
|
changeTask,
|
||||||
clear
|
clear
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
<Header />
|
<Header />
|
||||||
<Main />
|
<Main />
|
||||||
|
|
||||||
<FloatWindow
|
<FloatWindow
|
||||||
v-if="agentsStore.planModificationWindow"
|
v-if="agentsStore.planModificationWindow"
|
||||||
title="任务大纲探索"
|
title="任务大纲探索"
|
||||||
@@ -91,6 +92,7 @@ onMounted(() => {
|
|||||||
>
|
>
|
||||||
<PlanModification />
|
<PlanModification />
|
||||||
</FloatWindow>
|
</FloatWindow>
|
||||||
|
|
||||||
<FloatWindow
|
<FloatWindow
|
||||||
v-if="agentsStore.planTaskWindow"
|
v-if="agentsStore.planTaskWindow"
|
||||||
title="任务过程探索"
|
title="任务过程探索"
|
||||||
|
|||||||
@@ -222,7 +222,113 @@ export const useAgentsStore = defineStore('agents', () => {
|
|||||||
// 当前的展示的任务流程
|
// 当前的展示的任务流程
|
||||||
const currentTask = ref<IRawStepTask>()
|
const currentTask = ref<IRawStepTask>()
|
||||||
function setCurrentTask(task: IRawStepTask) {
|
function setCurrentTask(task: IRawStepTask) {
|
||||||
currentTask.value = task
|
const existingTask = currentTask.value
|
||||||
|
|
||||||
|
// 🆕 智能判断:如果是同一个任务,保留用户修改过的数据(AgentSelection、TaskProcess、Collaboration_Brief_frontEnd)
|
||||||
|
if (existingTask && existingTask.Id === task.Id) {
|
||||||
|
currentTask.value = {
|
||||||
|
...task,
|
||||||
|
AgentSelection: existingTask.AgentSelection || task.AgentSelection,
|
||||||
|
TaskProcess: existingTask.TaskProcess || task.TaskProcess,
|
||||||
|
Collaboration_Brief_frontEnd:
|
||||||
|
existingTask.Collaboration_Brief_frontEnd || task.Collaboration_Brief_frontEnd,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🆕 同步更新主流程数据(让执行结果卡片和任务大纲都能联动)
|
||||||
|
syncCurrentTaskToMainProcess(currentTask.value)
|
||||||
|
|
||||||
|
console.log('🔄 setCurrentTask: 保留同一任务的分支数据', {
|
||||||
|
taskId: task.Id,
|
||||||
|
taskName: task.StepName,
|
||||||
|
preservedAgentSelection: currentTask.value.AgentSelection,
|
||||||
|
preservedTaskProcessLength: currentTask.value.TaskProcess?.length || 0,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 不同任务:使用新任务数据
|
||||||
|
currentTask.value = task
|
||||||
|
console.log('🔄 setCurrentTask: 切换到不同任务', {
|
||||||
|
taskId: task.Id,
|
||||||
|
taskName: task.StepName,
|
||||||
|
agentSelection: task.AgentSelection,
|
||||||
|
taskProcessLength: task.TaskProcess?.length || 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🆕 同步 currentTask 到主流程数据
|
||||||
|
function syncCurrentTaskToMainProcess(updatedTask: IRawStepTask) {
|
||||||
|
const collaborationProcess = agentRawPlan.value.data?.['Collaboration Process']
|
||||||
|
if (!collaborationProcess) {
|
||||||
|
console.warn('⚠️ syncCurrentTaskToMainProcess: collaborationProcess 不存在')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskIndex = collaborationProcess.findIndex((t) => t.Id === updatedTask.Id)
|
||||||
|
if (taskIndex === -1) {
|
||||||
|
console.warn('⚠️ syncCurrentTaskToMainProcess: 未找到对应任务', updatedTask.Id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用 splice 确保 Vue 响应式更新
|
||||||
|
collaborationProcess.splice(taskIndex, 1, {
|
||||||
|
...collaborationProcess[taskIndex]!,
|
||||||
|
AgentSelection: updatedTask.AgentSelection || [],
|
||||||
|
TaskProcess: updatedTask.TaskProcess || [],
|
||||||
|
Collaboration_Brief_frontEnd: updatedTask.Collaboration_Brief_frontEnd,
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log('✅ syncCurrentTaskToMainProcess: 已同步到主流程', {
|
||||||
|
taskName: collaborationProcess[taskIndex]!.StepName,
|
||||||
|
agentSelection: collaborationProcess[taskIndex]!.AgentSelection,
|
||||||
|
taskProcessLength: collaborationProcess[taskIndex]!.TaskProcess?.length || 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🆕 设置当前任务的 TaskProcess 数据(用于切换分支时更新显示)
|
||||||
|
function setCurrentTaskProcess(taskProcess: TaskProcess[]) {
|
||||||
|
if (currentTask.value) {
|
||||||
|
// 创建新的对象引用,确保响应式更新
|
||||||
|
currentTask.value = {
|
||||||
|
...currentTask.value,
|
||||||
|
TaskProcess: JSON.parse(JSON.stringify(taskProcess)),
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🆕 同步到主流程数据(让执行结果卡片和任务大纲都能联动)
|
||||||
|
syncCurrentTaskToMainProcess(currentTask.value)
|
||||||
|
|
||||||
|
console.log('✅ 已更新 currentTask.TaskProcess 并同步到主流程:', {
|
||||||
|
taskId: currentTask.value.Id,
|
||||||
|
agent数量: taskProcess.length,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🆕 更新当前任务的 AgentSelection 和 TaskProcess(用于在 AgentAllocation 中切换 agent 组合)
|
||||||
|
// 此函数专门用于强制更新,不会被 setCurrentTask 的"智能保留"逻辑阻止
|
||||||
|
function updateCurrentAgentSelection(
|
||||||
|
agentSelection: string[],
|
||||||
|
taskProcess: TaskProcess[],
|
||||||
|
collaborationBrief: any,
|
||||||
|
) {
|
||||||
|
if (currentTask.value) {
|
||||||
|
// 直接更新 currentTask,不保留旧数据
|
||||||
|
currentTask.value = {
|
||||||
|
...currentTask.value,
|
||||||
|
AgentSelection: agentSelection,
|
||||||
|
TaskProcess: taskProcess,
|
||||||
|
Collaboration_Brief_frontEnd: collaborationBrief,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同步到主流程数据
|
||||||
|
syncCurrentTaskToMainProcess(currentTask.value)
|
||||||
|
|
||||||
|
console.log('✅ 已强制更新 currentTask 的 AgentSelection 并同步到主流程:', {
|
||||||
|
taskId: currentTask.value.Id,
|
||||||
|
taskName: currentTask.value.StepName,
|
||||||
|
newAgentSelection: agentSelection,
|
||||||
|
taskProcessLength: taskProcess.length,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const agentRawPlan = ref<{ data?: IRawPlanResponse; loading?: boolean }>({ loading: false })
|
const agentRawPlan = ref<{ data?: IRawPlanResponse; loading?: boolean }>({ loading: false })
|
||||||
@@ -315,6 +421,9 @@ export const useAgentsStore = defineStore('agents', () => {
|
|||||||
setSearchValue,
|
setSearchValue,
|
||||||
currentTask,
|
currentTask,
|
||||||
setCurrentTask,
|
setCurrentTask,
|
||||||
|
setCurrentTaskProcess, // 🆕 设置当前任务的 TaskProcess
|
||||||
|
updateCurrentAgentSelection, // 🆕 强制更新 AgentSelection(用于 AgentAllocation 切换组合)
|
||||||
|
syncCurrentTaskToMainProcess, // 🆕 同步 currentTask 到主流程
|
||||||
agentRawPlan,
|
agentRawPlan,
|
||||||
setAgentRawPlan,
|
setAgentRawPlan,
|
||||||
executePlan,
|
executePlan,
|
||||||
|
|||||||
@@ -207,11 +207,50 @@ export const useSelectionStore = defineStore('selection', () => {
|
|||||||
console.log('🗑️ 清除所有任务的 agent 组合 TaskProcess 数据')
|
console.log('🗑️ 清除所有任务的 agent 组合 TaskProcess 数据')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ==================== 当前生效的任务过程分支 ====================
|
||||||
|
// 记录每个任务步骤当前生效的分支 ID(持久化选中状态)
|
||||||
|
// 结构: Map<taskStepId, branchId>
|
||||||
|
const activeTaskProcessBranchMap = ref<Map<string, string>>(new Map())
|
||||||
|
|
||||||
|
// 🆕 当前生效的 TaskProcess 数据(用于外部组件显示职责分配)
|
||||||
|
// 结构: Map<taskStepId, TaskProcess[]>
|
||||||
|
const activeTaskProcessDataMap = ref<Map<string, any[]>>(new Map())
|
||||||
|
|
||||||
|
// 设置当前生效的分支
|
||||||
|
function setActiveTaskProcessBranch(taskStepId: string, branchId: string) {
|
||||||
|
activeTaskProcessBranchMap.value.set(taskStepId, branchId)
|
||||||
|
console.log('✅ 设置当前生效分支:', { taskStepId, branchId })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🆕 设置当前生效的 TaskProcess 数据
|
||||||
|
function setActiveTaskProcessData(taskStepId: string, taskProcess: any[]) {
|
||||||
|
activeTaskProcessDataMap.value.set(taskStepId, taskProcess)
|
||||||
|
console.log('✅ 设置当前生效的 TaskProcess 数据:', { taskStepId, taskProcess })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前生效的分支 ID
|
||||||
|
function getActiveTaskProcessBranch(taskStepId: string): string | undefined {
|
||||||
|
return activeTaskProcessBranchMap.value.get(taskStepId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🆕 获取当前生效的 TaskProcess 数据
|
||||||
|
function getActiveTaskProcessData(taskStepId: string): any[] | undefined {
|
||||||
|
return activeTaskProcessDataMap.value.get(taskStepId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除生效分支
|
||||||
|
function clearActiveTaskProcessBranch(taskStepId: string) {
|
||||||
|
activeTaskProcessBranchMap.value.delete(taskStepId)
|
||||||
|
activeTaskProcessDataMap.value.delete(taskStepId)
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// 状态
|
// 状态
|
||||||
flowBranches,
|
flowBranches,
|
||||||
taskProcessBranchesMap,
|
taskProcessBranchesMap,
|
||||||
agentTaskProcessMap,
|
agentTaskProcessMap,
|
||||||
|
activeTaskProcessBranchMap,
|
||||||
|
activeTaskProcessDataMap, // 🆕 新增
|
||||||
|
|
||||||
// 任务大纲分支管理方法
|
// 任务大纲分支管理方法
|
||||||
addFlowBranch,
|
addFlowBranch,
|
||||||
@@ -229,6 +268,13 @@ export const useSelectionStore = defineStore('selection', () => {
|
|||||||
removeTaskProcessBranch,
|
removeTaskProcessBranch,
|
||||||
clearTaskProcessBranches,
|
clearTaskProcessBranches,
|
||||||
|
|
||||||
|
// 🆕 任务过程分支生效状态管理方法
|
||||||
|
setActiveTaskProcessBranch,
|
||||||
|
setActiveTaskProcessData, // 🆕 新增
|
||||||
|
getActiveTaskProcessBranch,
|
||||||
|
getActiveTaskProcessData, // 🆕 新增
|
||||||
|
clearActiveTaskProcessBranch,
|
||||||
|
|
||||||
// Agent 组合 TaskProcess 数据管理方法
|
// Agent 组合 TaskProcess 数据管理方法
|
||||||
getAgentGroupKey,
|
getAgentGroupKey,
|
||||||
setAgentTaskProcess,
|
setAgentTaskProcess,
|
||||||
|
|||||||
Reference in New Issue
Block a user