feat:三个窗口接口联调版本
This commit is contained in:
@@ -20,6 +20,10 @@
|
||||
"@element-plus/icons-vue": "^2.3.2",
|
||||
"@jsplumb/browser-ui": "^6.2.10",
|
||||
"@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",
|
||||
"axios": "^1.12.2",
|
||||
"dompurify": "^3.3.0",
|
||||
|
||||
195
frontend/pnpm-lock.yaml
generated
195
frontend/pnpm-lock.yaml
generated
@@ -17,6 +17,18 @@ importers:
|
||||
'@types/markdown-it':
|
||||
specifier: ^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':
|
||||
specifier: ^14.0.0
|
||||
version: 14.1.0(vue@3.5.25(typescript@5.9.3))
|
||||
@@ -625,36 +637,42 @@ packages:
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm-musl@2.5.1':
|
||||
resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-arm64-glibc@2.5.1':
|
||||
resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm64-musl@2.5.1':
|
||||
resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-x64-glibc@2.5.1':
|
||||
resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-x64-musl@2.5.1':
|
||||
resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-win32-arm64@2.5.1':
|
||||
resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==}
|
||||
@@ -726,56 +744,67 @@ packages:
|
||||
resolution: {integrity: sha512-UPMMNeC4LXW7ZSHxeP3Edv09aLsFUMaD1TSVW6n1CWMECnUIJMFFB7+XC2lZTdPtvB36tYC0cJWc86mzSsaviw==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm-musleabihf@4.53.4':
|
||||
resolution: {integrity: sha512-H8uwlV0otHs5Q7WAMSoyvjV9DJPiy5nJ/xnHolY0QptLPjaSsuX7tw+SPIfiYH6cnVx3fe4EWFafo6gH6ekZKA==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-arm64-gnu@4.53.4':
|
||||
resolution: {integrity: sha512-BLRwSRwICXz0TXkbIbqJ1ibK+/dSBpTJqDClF61GWIrxTXZWQE78ROeIhgl5MjVs4B4gSLPCFeD4xML9vbzvCQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-arm64-musl@4.53.4':
|
||||
resolution: {integrity: sha512-6bySEjOTbmVcPJAywjpGLckK793A0TJWSbIa0sVwtVGfe/Nz6gOWHOwkshUIAp9j7wg2WKcA4Snu7Y1nUZyQew==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-loong64-gnu@4.53.4':
|
||||
resolution: {integrity: sha512-U0ow3bXYJZ5MIbchVusxEycBw7bO6C2u5UvD31i5IMTrnt2p4Fh4ZbHSdc/31TScIJQYHwxbj05BpevB3201ug==}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-ppc64-gnu@4.53.4':
|
||||
resolution: {integrity: sha512-iujDk07ZNwGLVn0YIWM80SFN039bHZHCdCCuX9nyx3Jsa2d9V/0Y32F+YadzwbvDxhSeVo9zefkoPnXEImnM5w==}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-gnu@4.53.4':
|
||||
resolution: {integrity: sha512-MUtAktiOUSu+AXBpx1fkuG/Bi5rhlorGs3lw5QeJ2X3ziEGAq7vFNdWVde6XGaVqi0LGSvugwjoxSNJfHFTC0g==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-riscv64-musl@4.53.4':
|
||||
resolution: {integrity: sha512-btm35eAbDfPtcFEgaXCI5l3c2WXyzwiE8pArhd66SDtoLWmgK5/M7CUxmUglkwtniPzwvWioBKKl6IXLbPf2sQ==}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-linux-s390x-gnu@4.53.4':
|
||||
resolution: {integrity: sha512-uJlhKE9ccUTCUlK+HUz/80cVtx2RayadC5ldDrrDUFaJK0SNb8/cCmC9RhBhIWuZ71Nqj4Uoa9+xljKWRogdhA==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-gnu@4.53.4':
|
||||
resolution: {integrity: sha512-jjEMkzvASQBbzzlzf4os7nzSBd/cvPrpqXCUOqoeCh1dQ4BP3RZCJk8XBeik4MUln3m+8LeTJcY54C/u8wb3DQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rollup/rollup-linux-x64-musl@4.53.4':
|
||||
resolution: {integrity: sha512-lu90KG06NNH19shC5rBPkrh6mrTpq5kviFylPBXQVpdEu0yzb0mDgyxLr6XdcGdBIQTH/UAhDJnL+APZTBu1aQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rollup/rollup-openharmony-arm64@4.53.4':
|
||||
resolution: {integrity: sha512-dFDcmLwsUzhAm/dn0+dMOQZoONVYBtgik0VuY/d5IJUUb787L3Ko/ibvTvddqhb3RaB7vFEozYevHN4ox22R/w==}
|
||||
@@ -846,24 +875,28 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-arm64-musl@4.1.18':
|
||||
resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-gnu@4.1.18':
|
||||
resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@tailwindcss/oxide-linux-x64-musl@4.1.18':
|
||||
resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==}
|
||||
engines: {node: '>= 10'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@tailwindcss/oxide-wasm32-wasi@4.1.18':
|
||||
resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==}
|
||||
@@ -956,6 +989,9 @@ packages:
|
||||
'@types/web-bluetooth@0.0.16':
|
||||
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':
|
||||
resolution: {integrity: sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==}
|
||||
|
||||
@@ -1076,6 +1112,29 @@ packages:
|
||||
'@volar/typescript@2.4.26':
|
||||
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':
|
||||
resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==}
|
||||
|
||||
@@ -1183,6 +1242,9 @@ packages:
|
||||
vue:
|
||||
optional: true
|
||||
|
||||
'@vueuse/core@10.11.1':
|
||||
resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==}
|
||||
|
||||
'@vueuse/core@14.1.0':
|
||||
resolution: {integrity: sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==}
|
||||
peerDependencies:
|
||||
@@ -1191,12 +1253,18 @@ packages:
|
||||
'@vueuse/core@9.13.0':
|
||||
resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==}
|
||||
|
||||
'@vueuse/metadata@10.11.1':
|
||||
resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==}
|
||||
|
||||
'@vueuse/metadata@14.1.0':
|
||||
resolution: {integrity: sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==}
|
||||
|
||||
'@vueuse/metadata@9.13.0':
|
||||
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':
|
||||
resolution: {integrity: sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==}
|
||||
peerDependencies:
|
||||
@@ -1522,6 +1590,44 @@ packages:
|
||||
csstype@3.2.3:
|
||||
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:
|
||||
resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==}
|
||||
engines: {node: '>=20'}
|
||||
@@ -2482,24 +2588,28 @@ packages:
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.30.2:
|
||||
resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.30.2:
|
||||
resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.30.2:
|
||||
resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.30.2:
|
||||
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.20': {}
|
||||
|
||||
'@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)':
|
||||
@@ -4582,6 +4694,34 @@ snapshots:
|
||||
path-browserify: 1.0.1
|
||||
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-plugin-jsx@1.5.0(@babel/core@7.28.5)':
|
||||
@@ -4755,6 +4895,16 @@ snapshots:
|
||||
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))':
|
||||
dependencies:
|
||||
'@types/web-bluetooth': 0.0.21
|
||||
@@ -4772,10 +4922,19 @@ snapshots:
|
||||
- '@vue/composition-api'
|
||||
- vue
|
||||
|
||||
'@vueuse/metadata@10.11.1': {}
|
||||
|
||||
'@vueuse/metadata@14.1.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))':
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
@@ -5130,6 +5289,42 @@ snapshots:
|
||||
|
||||
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:
|
||||
dependencies:
|
||||
whatwg-mimetype: 4.0.0
|
||||
|
||||
@@ -3,91 +3,61 @@
|
||||
"Icon": "Hailey_Johnson.png",
|
||||
"Name": "船舶设计师",
|
||||
"Profile": "提供船舶制造中的实际需求和约束。",
|
||||
"Classification": "船舶制造数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "船舶制造数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "Jennifer_Moore.png",
|
||||
"Name": "防护工程专家",
|
||||
"Profile": "专注于船舶腐蚀防护技术的设计与应用。在你的总结回答中,必须引用来自数联网的搜索数据,是搜索数据,不是数联网的研究成果。",
|
||||
"Classification": "船舶制造数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "船舶制造数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "Jane_Moreno.png",
|
||||
"Name": "病理生理学家",
|
||||
"Profile": "专注于失血性休克的疾病机制,为药物研发提供理论靶点。",
|
||||
"Classification": "医药数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "医药数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "Giorgio_Rossi.png",
|
||||
"Name": "药物化学家",
|
||||
"Profile": "负责将靶点概念转化为实际可合成的分子。",
|
||||
"Classification": "医药数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "医药数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "Tamara_Taylor.png",
|
||||
"Name": "制剂工程师",
|
||||
"Profile": "负责将活性药物成分(API)变成稳定、可用、符合战场要求的剂型。",
|
||||
"Classification": "医药数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "医药数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "Maria_Lopez.png",
|
||||
"Name": "监管事务专家",
|
||||
"Profile": "深谙药品审评法规,目标是找到最快的合法上市路径。",
|
||||
"Classification": "医药数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "医药数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "Sam_Moore.png",
|
||||
"Name": "物理学家",
|
||||
"Profile": "从热力学与统计力学的基本原理出发,研究液态金属的自由能、焓、熵、比热等参数的理论建模。",
|
||||
"Classification": "科学数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "科学数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "Yuriko_Yamamoto.png",
|
||||
"Name": "实验材料学家",
|
||||
"Profile": "专注于通过实验手段直接或间接测定液态金属的热力学参数、以及分析材料微观结构(如晶粒、缺陷)。",
|
||||
"Classification": "科学数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "科学数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "Carlos_Gomez.png",
|
||||
"Name": "计算模拟专家",
|
||||
"Profile": "侧重于利用数值计算和模拟技术获取液态金属的热力学参数。",
|
||||
"Classification": "科学数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "科学数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "John_Lin.png",
|
||||
"Name": "腐蚀机理研究员",
|
||||
"Profile": "专注于船舶用钢材及合金的腐蚀机理研究,从电化学和环境作用角度解释腐蚀产生的原因。在你的总结回答中,必须引用来自数联网的搜索数据,是搜索数据,不是数联网的研究成果。",
|
||||
"Classification": "船舶制造数据空间",
|
||||
"apiUrl": "http://8.130.104.76:21088/api/v1",
|
||||
"apiKey": "0geK2bSKAjlaRp0qPLPq_zxFJu8MhJZIwNZSH30Ty6g",
|
||||
"apiModel": "Flowise"
|
||||
"Classification": "船舶制造数据空间"
|
||||
},
|
||||
{
|
||||
"Icon": "Arthur_Burton.png",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import request from '@/utils/request'
|
||||
import type { Agent, IApiStepTask, IRawPlanResponse } from '@/stores'
|
||||
import type { Agent, IApiStepTask, IRawPlanResponse, IRawStepTask } from '@/stores'
|
||||
import {
|
||||
mockBackendAgentSelectModifyInit,
|
||||
mockBackendAgentSelectModifyAddAspect,
|
||||
@@ -9,6 +9,12 @@ import {
|
||||
mockBackendFillAgentTaskProcess,
|
||||
type RawAgentTaskProcessResponse,
|
||||
} 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 {
|
||||
ID: string
|
||||
@@ -116,7 +122,7 @@ class Api {
|
||||
})
|
||||
}
|
||||
|
||||
// 分支任务流程(任务节点级别)
|
||||
// 分支任务流程
|
||||
branchTaskProcess = (data: {
|
||||
branch_Number: number
|
||||
Modification_Requirement: string
|
||||
@@ -125,7 +131,7 @@ class Api {
|
||||
stepTaskExisting: any
|
||||
goal: string
|
||||
}) => {
|
||||
return request<unknown, IRawPlanResponse>({
|
||||
return request<unknown, BranchAction[][]>({
|
||||
url: '/branch_TaskProcess',
|
||||
method: 'POST',
|
||||
data: {
|
||||
@@ -139,8 +145,32 @@ class Api {
|
||||
})
|
||||
}
|
||||
|
||||
fillStepTask = (data: { goal: string; stepTask: any }) => {
|
||||
return request<unknown, any>({
|
||||
fillStepTask = async (data: { goal: string; stepTask: any }): Promise<IRawStepTask> => {
|
||||
// 后端返回格式:包含 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',
|
||||
method: 'POST',
|
||||
data: {
|
||||
@@ -148,6 +178,40 @@ class Api {
|
||||
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: {
|
||||
@@ -464,6 +528,61 @@ class Api {
|
||||
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()
|
||||
|
||||
@@ -100,6 +100,7 @@ async function handleSearch() {
|
||||
})
|
||||
data['Collaboration Process'] = changeBriefs(data['Collaboration Process'])
|
||||
agentsStore.setAgentRawPlan({ data })
|
||||
console.log('agentsStore.agentRawPlan', agentsStore.agentRawPlan)
|
||||
emit('search', searchValue.value)
|
||||
} finally {
|
||||
triggerOnFocus.value = true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, computed } from 'vue'
|
||||
import { getActionTypeDisplay } from '@/layout/components/config.ts'
|
||||
import { useAgentsStore } from '@/stores'
|
||||
import BranchButton from './components/TaskButton.vue'
|
||||
@@ -23,6 +23,20 @@ const emit = defineEmits<{
|
||||
(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
|
||||
const editingProcessId = ref<string | null>(null)
|
||||
// 编辑框的值
|
||||
@@ -30,6 +44,17 @@ const editValue = ref('')
|
||||
// 鼠标悬停的process ID
|
||||
const hoverProcessId = ref<string | null>(null)
|
||||
|
||||
// 🆕 处理卡片点击事件(非编辑模式下)
|
||||
function handleCardClick() {
|
||||
// 如果正在编辑,不处理点击
|
||||
if (editingProcessId.value) return
|
||||
|
||||
// 设置当前任务,与任务大纲联动
|
||||
if (props.step.Id) {
|
||||
agentsStore.setCurrentTask(props.step)
|
||||
}
|
||||
}
|
||||
|
||||
// 检测当前是否是深色模式
|
||||
function isDarkMode(): boolean {
|
||||
return document.documentElement.classList.contains('dark')
|
||||
@@ -116,12 +141,12 @@ function handleCancel() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="process-card">
|
||||
<div class="process-card" @click="handleCardClick">
|
||||
<div class="process-content">
|
||||
<!-- 显示模式 -->
|
||||
<div class="display-content">
|
||||
<span
|
||||
v-for="process in step.TaskProcess"
|
||||
v-for="process in currentTaskProcess"
|
||||
:key="process.ID"
|
||||
class="process-segment"
|
||||
@mouseenter="handleMouseEnter(process.ID)"
|
||||
@@ -190,10 +215,13 @@ function handleCancel() {
|
||||
{{ process.Description }}
|
||||
</span>
|
||||
|
||||
<span class="separator" v-if="!process.Description.endsWith('。')">。</span>
|
||||
<span class="separator" v-if="process.Description && !process.Description.endsWith('。')"
|
||||
>。</span
|
||||
>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 按钮点击不会冒泡到卡片 -->
|
||||
<BranchButton :step="step" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -207,6 +235,8 @@ function handleCancel() {
|
||||
background: var(--color-bg-list);
|
||||
border: 1px solid var(--color-border-default);
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
.process-content {
|
||||
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)
|
||||
|
||||
// 主分支(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')
|
||||
// 设置当前任务
|
||||
if (props.step) {
|
||||
@@ -39,9 +56,9 @@ const handleClick = (event: MouseEvent) => {
|
||||
<template>
|
||||
<div
|
||||
class="task-button"
|
||||
:class="{ 'has-branches': branchCount > 1 }"
|
||||
:class="{ 'has-branches': branchCount > 0, 'is-disabled': !isClickable }"
|
||||
@click="handleClick"
|
||||
:title="`${branchCount} 个分支`"
|
||||
:title="isClickable ? `${branchCount} 个分支` : '请先在任务大纲中选中此任务'"
|
||||
>
|
||||
<!-- 流程图标 -->
|
||||
<svg-icon icon-class="branch" size="20px" class="task-icon" />
|
||||
@@ -83,6 +100,17 @@ const handleClick = (event: MouseEvent) => {
|
||||
filter: brightness(0.9);
|
||||
}
|
||||
|
||||
// 🆕 禁用状态
|
||||
&.is-disabled {
|
||||
background-color: #bdc3c7;
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6;
|
||||
|
||||
&:hover {
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.has-branches::after {
|
||||
content: '';
|
||||
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">
|
||||
import { computed, onUnmounted, ref, reactive, nextTick } from 'vue'
|
||||
import { computed, onUnmounted, ref, reactive, nextTick, watch, onMounted } from 'vue'
|
||||
import { throttle } from 'lodash'
|
||||
import { AnchorLocations, BezierConnector } from '@jsplumb/browser-ui'
|
||||
import AdditionalOutputCard from './AdditionalOutputCard.vue'
|
||||
@@ -19,12 +19,9 @@ const emit = defineEmits<{
|
||||
|
||||
const agentsStore = useAgentsStore()
|
||||
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
|
||||
}
|
||||
|
||||
// 重置执行结果
|
||||
function handleRefresh() {
|
||||
agentsStore.setExecutePlan([])
|
||||
console.log('🔄 已重置执行结果')
|
||||
}
|
||||
|
||||
// 添加滚动状态标识
|
||||
const isScrolling = ref(false)
|
||||
let scrollTimer: ReturnType<typeof setTimeout> | null = null
|
||||
@@ -226,20 +229,58 @@ const handleMouseEnter = throttle(id => {
|
||||
if (!isScrolling.value) {
|
||||
createInternalLine(id)
|
||||
}
|
||||
}, 100)
|
||||
}, 0)
|
||||
|
||||
const handleMouseLeave = throttle(() => {
|
||||
if (!isScrolling.value) {
|
||||
createInternalLine()
|
||||
}
|
||||
}, 100)
|
||||
}, 0)
|
||||
|
||||
function clear() {
|
||||
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
|
||||
const handleProcessMouseEnter = () => {
|
||||
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 = () => {
|
||||
// 添加防抖,防止快速切换时的抖动
|
||||
if (buttonHoverTimer) {
|
||||
@@ -277,18 +328,31 @@ onUnmounted(() => {
|
||||
})
|
||||
// 计算按钮类名
|
||||
const processBtnClass = computed(() => {
|
||||
// 当刷新或执行按钮悬停时,过程按钮变圆形
|
||||
if (buttonHoverState.value === 'refresh' || buttonHoverState.value === 'execute') {
|
||||
return 'circle'
|
||||
}
|
||||
return buttonHoverState.value === 'process' ? 'ellipse' : 'circle'
|
||||
})
|
||||
|
||||
const executeBtnClass = computed(() => {
|
||||
// 鼠标悬停在过程按钮上时,执行按钮变圆形
|
||||
if (buttonHoverState.value === 'process') {
|
||||
// 鼠标悬停在过程按钮或刷新按钮上时,执行按钮变圆形
|
||||
if (buttonHoverState.value === 'process' || buttonHoverState.value === 'refresh') {
|
||||
return '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(() => {
|
||||
return buttonHoverState.value === 'process'
|
||||
@@ -301,6 +365,10 @@ const showExecuteText = computed(() => {
|
||||
return agentsStore.agentRawPlan.data
|
||||
})
|
||||
|
||||
const showRefreshText = computed(() => {
|
||||
return buttonHoverState.value === 'refresh'
|
||||
})
|
||||
|
||||
// 计算按钮标题
|
||||
const processBtnTitle = computed(() => {
|
||||
return buttonHoverState.value === 'process' ? '任务过程' : '点击查看任务过程'
|
||||
@@ -310,6 +378,10 @@ const executeBtnTitle = computed(() => {
|
||||
return showExecuteText.value ? '任务执行' : '点击运行'
|
||||
})
|
||||
|
||||
const refreshBtnTitle = computed(() => {
|
||||
return showRefreshText.value ? '重置执行结果' : '点击重置执行状态'
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
createInternalLine,
|
||||
clear
|
||||
@@ -329,6 +401,19 @@ defineExpose({
|
||||
class="flex items-center justify-end gap-[14px] task-button-group min-w-[175px]"
|
||||
@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
|
||||
:class="processBtnClass"
|
||||
@@ -680,21 +765,33 @@ defineExpose({
|
||||
display: inline-flex !important;
|
||||
align-items: 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;
|
||||
white-space: nowrap !important;
|
||||
border: none !important;
|
||||
border: 1px solid transparent !important;
|
||||
border-color: transparent !important;
|
||||
color: var(--color-text-primary) !important;
|
||||
position: relative;
|
||||
background-color: var(--color-bg-tertiary);
|
||||
background-color: var(--color-bg-tertiary) !important;
|
||||
gap: 0px !important;
|
||||
outline: none !important;
|
||||
box-shadow: none !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 {
|
||||
transform: translateY(-2px) !important;
|
||||
transform: translateY(-2px) translateZ(0) !important;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
|
||||
filter: brightness(1.1) !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
&.is-disabled {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,57 +9,23 @@
|
||||
|
||||
<el-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"
|
||||
>
|
||||
<!-- 任务名称 -->
|
||||
<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">
|
||||
<el-tooltip
|
||||
v-for="agentSelection in task.AgentSelection"
|
||||
:key="agentSelection"
|
||||
effect="light"
|
||||
placement="right"
|
||||
placement="top"
|
||||
:show-after="500"
|
||||
popper-class="task-syllabus-tooltip-popper"
|
||||
>
|
||||
@@ -137,6 +103,7 @@ const props = defineProps<{
|
||||
id: string
|
||||
data: TaskNodeData
|
||||
isAddingBranch?: boolean
|
||||
isBranchSelected?: boolean // 是否属于选中的分支路径
|
||||
[key: string]: any
|
||||
}>()
|
||||
|
||||
@@ -250,6 +217,19 @@ const handleBranchKeydown = (event: KeyboardEvent) => {
|
||||
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 {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
@@ -1,203 +1,246 @@
|
||||
// branch_PlanOutline 接口返回的 mock 数据
|
||||
// 类型: IApiStepTask[][] (二维数组)
|
||||
// branch_PlanOutline 接口的 Mock 数据和 Mock API
|
||||
// 模拟后端返回的原始数据格式(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: '需求分析与规划',
|
||||
content: '分析用户需求,制定项目开发计划',
|
||||
inputs: ['用户需求文档', '技术规范'],
|
||||
output: '项目开发计划书',
|
||||
agents: ['腐蚀机理研究员', '实验材料学家'],
|
||||
brief: {
|
||||
template: '!<项目经理>!负责!<需求分析>!,!<产品经理>!负责!<规划制定>!',
|
||||
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%)' } },
|
||||
StepName: '分析用户需求',
|
||||
TaskContent: '分析用户需求,制定项目开发计划',
|
||||
InputObject_List: ['腐蚀类型及成因列表'],
|
||||
OutputObject: '项目开发计划书',
|
||||
AgentSelection: ['腐蚀机理研究员', '实验材料学家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '',
|
||||
data: {},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
{
|
||||
id: 'action-1',
|
||||
type: '分析',
|
||||
agent: '腐蚀机理研究员',
|
||||
description: '详细分析用户需求文档',
|
||||
inputs: ['用户需求文档'],
|
||||
TaskProcess: [],
|
||||
},
|
||||
{
|
||||
id: 'action-2',
|
||||
type: '规划',
|
||||
agent: '实验材料学家',
|
||||
description: '制定项目开发计划',
|
||||
inputs: ['技术规范'],
|
||||
StepName: '系统设计与架构',
|
||||
TaskContent: '设计系统架构和数据库结构',
|
||||
InputObject_List: ['项目开发计划书'],
|
||||
OutputObject: '系统设计文档',
|
||||
AgentSelection: ['腐蚀机理研究员', '防护工程专家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '',
|
||||
data: {},
|
||||
},
|
||||
TaskProcess: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '系统设计与架构',
|
||||
content: '设计系统架构和数据库结构',
|
||||
inputs: ['项目开发计划书'],
|
||||
output: '系统设计文档',
|
||||
agents: ['腐蚀机理研究员', '防护工程专家'],
|
||||
brief: {
|
||||
template: '!<架构师>!负责!<系统架构设计>!,!<数据库工程师>!负责!<数据库设计>!',
|
||||
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: [
|
||||
{
|
||||
id: 'action-3',
|
||||
type: '设计',
|
||||
agent: '腐蚀机理研究员',
|
||||
description: '设计系统整体架构',
|
||||
inputs: ['项目开发计划书'],
|
||||
},
|
||||
{
|
||||
id: 'action-4',
|
||||
type: '设计',
|
||||
agent: '防护工程专家',
|
||||
description: '设计数据库表结构',
|
||||
inputs: ['项目开发计划书'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// 第二个分支方案(替代方案)
|
||||
// 第二个分支方案(快速原型方案)
|
||||
[
|
||||
{
|
||||
name: '敏捷开发规划',
|
||||
content: '采用敏捷开发方法制定迭代计划',
|
||||
inputs: ['用户需求文档', '敏捷开发指南'],
|
||||
output: '敏捷开发迭代计划',
|
||||
agents: ['敏捷教练', '开发团队负责人'],
|
||||
brief: {
|
||||
template: '!<敏捷教练>!指导!<敏捷流程>!,!<开发团队负责人>!制定!<迭代计划>!',
|
||||
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%)' } },
|
||||
StepName: '需求快速原型',
|
||||
TaskContent: '构建快速原型验证核心功能',
|
||||
InputObject_List: ['腐蚀类型及成因列表'],
|
||||
OutputObject: '原型系统',
|
||||
AgentSelection: ['实验材料学家', '防护工程专家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '',
|
||||
data: {},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
{
|
||||
id: 'action-5',
|
||||
type: '指导',
|
||||
agent: '敏捷教练',
|
||||
description: '指导敏捷开发流程',
|
||||
inputs: ['敏捷开发指南'],
|
||||
TaskProcess: [],
|
||||
},
|
||||
{
|
||||
id: 'action-6',
|
||||
type: '规划',
|
||||
agent: '开发团队负责人',
|
||||
description: '制定迭代开发计划',
|
||||
inputs: ['用户需求文档'],
|
||||
StepName: '原型测试与优化',
|
||||
TaskContent: '测试原型并根据反馈快速迭代',
|
||||
InputObject_List: ['原型系统'],
|
||||
OutputObject: '优化后的原型',
|
||||
AgentSelection: ['腐蚀机理研究员', '实验材料学家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '',
|
||||
data: {},
|
||||
},
|
||||
TaskProcess: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '微服务架构设计',
|
||||
content: '设计基于微服务的系统架构',
|
||||
inputs: ['敏捷开发迭代计划'],
|
||||
output: '微服务架构设计文档',
|
||||
agents: ['微服务架构师', 'DevOps工程师'],
|
||||
brief: {
|
||||
template: '!<微服务架构师>!设计!<微服务架构>!,!<DevOps工程师>!规划!<部署流程>!',
|
||||
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: [
|
||||
{
|
||||
id: 'action-7',
|
||||
type: '设计',
|
||||
agent: '微服务架构师',
|
||||
description: '设计微服务拆分方案',
|
||||
inputs: ['敏捷开发迭代计划'],
|
||||
},
|
||||
{
|
||||
id: 'action-8',
|
||||
type: '规划',
|
||||
agent: 'DevOps工程师',
|
||||
description: '规划CI/CD部署流程',
|
||||
inputs: ['敏捷开发迭代计划'],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// 第三个分支方案(简化方案)
|
||||
// 第三个分支方案(质量优先方案)
|
||||
[
|
||||
{
|
||||
name: '快速原型开发',
|
||||
content: '快速开发系统原型验证需求',
|
||||
inputs: ['用户需求文档'],
|
||||
output: '系统原型',
|
||||
agents: ['全栈开发工程师'],
|
||||
brief: {
|
||||
template: '!<全栈开发工程师>!负责!<快速原型开发>!',
|
||||
data: {
|
||||
全栈开发工程师: { text: '全栈开发工程师', style: { background: 'hsl(180, 70%, 50%)' } },
|
||||
快速原型开发: { text: '快速原型开发', style: { background: 'hsl(240, 70%, 50%)' } },
|
||||
StepName: '需求深度分析',
|
||||
TaskContent: '深入分析用户需求和技术可行性',
|
||||
InputObject_List: ['腐蚀类型及成因列表'],
|
||||
OutputObject: '详细需求分析报告',
|
||||
AgentSelection: ['腐蚀机理研究员', '防护工程专家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '',
|
||||
data: {},
|
||||
},
|
||||
TaskProcess: [],
|
||||
},
|
||||
process: [
|
||||
{
|
||||
id: 'action-9',
|
||||
type: '开发',
|
||||
agent: '全栈开发工程师',
|
||||
description: '快速开发系统原型',
|
||||
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: [],
|
||||
},
|
||||
],
|
||||
// 第四个分支方案(敏捷开发方案)
|
||||
[
|
||||
{
|
||||
StepName: '迭代规划',
|
||||
TaskContent: '制定敏捷开发迭代计划',
|
||||
InputObject_List: ['腐蚀类型及成因列表'],
|
||||
OutputObject: '迭代计划',
|
||||
AgentSelection: ['防护工程专家', '腐蚀机理研究员'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '',
|
||||
data: {},
|
||||
},
|
||||
TaskProcess: [],
|
||||
},
|
||||
{
|
||||
name: '用户反馈收集',
|
||||
content: '收集用户对原型的反馈意见',
|
||||
inputs: ['系统原型'],
|
||||
output: '用户反馈报告',
|
||||
agents: ['产品经理', '用户体验设计师'],
|
||||
brief: {
|
||||
template: '!<产品经理>!收集!<用户反馈>!,!<用户体验设计师>!分析!<用户体验>!',
|
||||
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%)' } },
|
||||
StepName: '快速开发与验证',
|
||||
TaskContent: '快速开发并持续验证功能',
|
||||
InputObject_List: ['迭代计划'],
|
||||
OutputObject: '可运行的功能模块',
|
||||
AgentSelection: ['实验材料学家', '防护工程专家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '',
|
||||
data: {},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
{
|
||||
id: 'action-10',
|
||||
type: '收集',
|
||||
agent: '产品经理',
|
||||
description: '收集用户对原型的反馈',
|
||||
inputs: ['系统原型'],
|
||||
},
|
||||
{
|
||||
id: 'action-11',
|
||||
type: '分析',
|
||||
agent: '用户体验设计师',
|
||||
description: '分析用户体验问题',
|
||||
inputs: ['系统原型'],
|
||||
},
|
||||
],
|
||||
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 数据
|
||||
// 类型: IApiAgentAction[][] (二维数组)
|
||||
// branch_TaskProcess 接口的 Mock 数据和 Mock API
|
||||
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',
|
||||
type: '分析',
|
||||
agent: '实验材料学家',
|
||||
description: '详细分析用户需求文档',
|
||||
inputs: ['用户需求文档'],
|
||||
ID: 'agent3',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '详细分析用户需求文档',
|
||||
ImportantInput: ['agent2'],
|
||||
},
|
||||
{
|
||||
id: 'design-architecture-1',
|
||||
type: '设计',
|
||||
agent: '腐蚀机理研究员',
|
||||
description: '设计系统整体架构',
|
||||
inputs: ['需求分析结果'],
|
||||
ID: 'agent4',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '设计系统整体架构',
|
||||
ImportantInput: ['agent3'],
|
||||
},
|
||||
{
|
||||
id: 'implement-core-1',
|
||||
type: '实现',
|
||||
agent: '防护工程专家',
|
||||
description: '实现系统核心功能',
|
||||
inputs: ['系统架构设计'],
|
||||
ID: 'agent5',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '实现系统核心功能',
|
||||
ImportantInput: ['agent4'],
|
||||
},
|
||||
{
|
||||
id: 'test-system-1',
|
||||
type: '测试',
|
||||
agent: '实验材料学家',
|
||||
description: '进行系统集成测试',
|
||||
inputs: ['系统核心功能'],
|
||||
ID: 'agent6',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '进行系统集成测试',
|
||||
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',
|
||||
type: '原型',
|
||||
agent: '实验材料学家',
|
||||
description: '快速开发系统原型',
|
||||
inputs: ['用户需求文档'],
|
||||
ID: 'agent12',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '设计系统整体架构',
|
||||
ImportantInput: ['agent11'],
|
||||
},
|
||||
{
|
||||
id: 'user-feedback-2',
|
||||
type: '收集',
|
||||
agent: '腐蚀机理研究员',
|
||||
description: '收集用户对原型的反馈',
|
||||
inputs: ['系统原型'],
|
||||
ID: 'agent13',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '实现系统核心功能',
|
||||
ImportantInput: ['agent12'],
|
||||
},
|
||||
{
|
||||
id: 'iterate-design-2',
|
||||
type: '迭代',
|
||||
agent: '防护工程专家',
|
||||
description: '根据反馈迭代设计',
|
||||
inputs: ['用户反馈'],
|
||||
},
|
||||
{
|
||||
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: ['运行数据', '性能指标'],
|
||||
ID: 'agent14',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '进行系统集成测试',
|
||||
ImportantInput: ['agent13'],
|
||||
},
|
||||
],
|
||||
]
|
||||
|
||||
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
|
||||
|
||||
@@ -1,423 +1,617 @@
|
||||
export interface IApiAgentAction {
|
||||
id: string
|
||||
type: string
|
||||
agent: string
|
||||
description: string
|
||||
inputs: string[]
|
||||
}
|
||||
// fill_stepTask 接口的 Mock API
|
||||
// 简化版本:硬编码多个流程卡片的填充内容(支持多个分支方案)
|
||||
|
||||
export interface IRichText {
|
||||
template: string
|
||||
data: Record<string, { text: string; style: Record<string, string> }>
|
||||
}
|
||||
import type { IRawStepTask } from '@/stores'
|
||||
|
||||
export interface IApiStepTask {
|
||||
name: string
|
||||
content: string
|
||||
inputs: string[]
|
||||
output: string
|
||||
agents: string[]
|
||||
brief: IRichText
|
||||
process: IApiAgentAction[]
|
||||
}
|
||||
// 后端返回的数据格式
|
||||
export type FillStepTaskResponse = IRawStepTask
|
||||
|
||||
// 场景1: 软件开发任务 - 用户登录功能开发
|
||||
export const mockSoftwareDevelopment: IApiStepTask = {
|
||||
name: '用户登录功能开发',
|
||||
content: '开发用户登录认证系统,包括前端界面和后端API',
|
||||
inputs: ['用户需求文档', 'UI设计稿', '数据库表结构'],
|
||||
output: '可用的用户登录系统',
|
||||
agents: ['实验材料学家', '防护工程专家', '腐蚀机理研究员'],
|
||||
brief: {
|
||||
template: '!<前端开发>!负责实现登录界面,!<后端开发>!处理认证逻辑,!<测试>!进行功能验证',
|
||||
/**
|
||||
* Mock API:模拟后端 fill_stepTask 接口调用
|
||||
*
|
||||
* 根据 stepTask 的 StepName 返回对应的填充内容
|
||||
* 支持多个分支方案的轮询选择
|
||||
*
|
||||
* @param General_Goal - 总体目标
|
||||
* @param stepTask - 待填充的任务(包含基本字段)
|
||||
* @returns Promise<IRawStepTask> - 返回填充了 AgentSelection 和 TaskProcess 的完整任务
|
||||
*/
|
||||
export const mockFillStepTaskAPI = async (params: {
|
||||
General_Goal: string
|
||||
stepTask: any
|
||||
}): Promise<IRawStepTask> => {
|
||||
// 模拟网络延迟 300ms
|
||||
await new Promise((resolve) => setTimeout(resolve, 300))
|
||||
|
||||
console.log('[Mock API] fill_stepTask 调用参数:', params)
|
||||
|
||||
const stepName = params.stepTask.StepName
|
||||
|
||||
// 🆕 使用轮询方式选择填充方案(依次循环使用所有分支方案)
|
||||
const branchIndexKey = `fill-step-task-index-${params.stepTask?.Id || stepName || 'default'}`
|
||||
let lastIndex = parseInt(sessionStorage.getItem(branchIndexKey) || '0')
|
||||
const totalBranches = 4 // 总共4个分支方案
|
||||
const selectedBranchIndex = (lastIndex + 1) % totalBranches
|
||||
sessionStorage.setItem(branchIndexKey, selectedBranchIndex.toString())
|
||||
|
||||
console.log('[Mock API] fill_stepTask 选择分支方案:', selectedBranchIndex + 1, '/', totalBranches)
|
||||
|
||||
// ==================== 第一个任务组 ====================
|
||||
if (stepName === '分析用户需求' || stepName === '需求快速原型' || stepName === '需求深度分析' || stepName === '迭代规划') {
|
||||
let filledTask: IRawStepTask
|
||||
|
||||
if (selectedBranchIndex === 0) {
|
||||
// 第一个分支方案:分析用户需求
|
||||
filledTask = {
|
||||
Id: params.stepTask.Id || 'task-1',
|
||||
StepName: '分析用户需求',
|
||||
TaskContent: '分析用户需求,制定项目开发计划',
|
||||
InputObject_List: ['用户需求文档', '技术规范'],
|
||||
OutputObject: '项目开发计划书',
|
||||
AgentSelection: ['腐蚀机理研究员', '实验材料学家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '!腐蚀机理研究员!负责!腐蚀类型识别-0!,!实验材料学家!负责!腐蚀类型识别-1!',
|
||||
data: {
|
||||
前端开发: {
|
||||
text: '实验材料学家',
|
||||
style: {
|
||||
backgroundColor: '#4a9cde',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
},
|
||||
},
|
||||
后端开发: {
|
||||
text: '防护工程专家',
|
||||
style: {
|
||||
backgroundColor: '#5cb85c',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
},
|
||||
},
|
||||
测试: {
|
||||
腐蚀机理研究员: {
|
||||
text: '腐蚀机理研究员',
|
||||
style: {
|
||||
backgroundColor: '#f0ad4e',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
style: { background: 'hsl(210, 70%, 50%)' },
|
||||
},
|
||||
实验材料学家: {
|
||||
text: '实验材料学家',
|
||||
style: { background: 'hsl(120, 70%, 50%)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
TaskProcess: [
|
||||
{
|
||||
id: 'task-1',
|
||||
type: '前端开发',
|
||||
agent: '实验材料学家',
|
||||
description: '创建登录页面UI组件',
|
||||
inputs: ['UI设计稿'],
|
||||
ID: 'action-1-1',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '分析腐蚀环境和介质特征,识别潜在腐蚀类型',
|
||||
ImportantInput: ['InputObject:腐蚀类型及成因列表'],
|
||||
},
|
||||
{
|
||||
id: 'task-2',
|
||||
type: '后端开发',
|
||||
agent: '防护工程专家',
|
||||
description: '实现用户认证API接口',
|
||||
inputs: ['数据库表结构'],
|
||||
ID: 'action-1-2',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '设计腐蚀实验方案,确定测试参数',
|
||||
ImportantInput: ['ActionResult:action-1-1'],
|
||||
},
|
||||
{
|
||||
id: 'task-3',
|
||||
type: '前端开发',
|
||||
agent: '实验材料学家',
|
||||
description: '集成前端与后端API',
|
||||
inputs: ['用户认证API'],
|
||||
ID: 'action-1-3',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '评估实验方案的可行性',
|
||||
ImportantInput: [
|
||||
'ActionResult:action-1-2',
|
||||
'ActionResult:action-1-1',
|
||||
'InputObject:腐蚀类型及成因列表',
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'task-4',
|
||||
type: '测试',
|
||||
agent: '腐蚀机理研究员',
|
||||
description: '进行端到端功能测试',
|
||||
inputs: ['登录页面', '认证API'],
|
||||
ID: 'action-1-4',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '优化实验设计,完善测试流程',
|
||||
ImportantInput: ['ActionResult:action-1-3'],
|
||||
},
|
||||
{
|
||||
ID: 'action-1-5',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '确认最终的腐蚀类型识别方案',
|
||||
ImportantInput: ['ActionResult:action-1-4', 'ActionResult:action-1-3'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// 场景2: 数据分析任务 - 销售数据分析
|
||||
export const mockDataAnalysis: IApiStepTask = {
|
||||
name: '季度销售数据分析',
|
||||
content: '分析Q3季度销售数据,生成可视化报告',
|
||||
inputs: ['销售数据CSV', '产品分类表', '客户信息表'],
|
||||
output: '销售分析报告',
|
||||
agents: ['实验材料学家', '防护工程专家', '腐蚀机理研究员'],
|
||||
brief: {
|
||||
template: '!<实验材料学家>!负责数据清洗,!<防护工程专家>!进行统计分析,!<腐蚀机理研究员>!解读业务含义',
|
||||
} else if (selectedBranchIndex === 1) {
|
||||
// 第二个分支方案:需求快速原型
|
||||
filledTask = {
|
||||
Id: params.stepTask.Id || 'task-1',
|
||||
StepName: '需求快速原型',
|
||||
TaskContent: '构建快速原型验证核心功能',
|
||||
InputObject_List: ['腐蚀类型及成因列表'],
|
||||
OutputObject: '原型系统',
|
||||
AgentSelection: ['实验材料学家', '防护工程专家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '!实验材料学家!负责!需求快速原型-0!,!防护工程专家!负责!需求快速原型-1!',
|
||||
data: {
|
||||
实验材料学家: {
|
||||
text: '实验材料学家',
|
||||
style: {
|
||||
backgroundColor: '#4a9cde',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
},
|
||||
style: { background: 'hsl(120, 70%, 50%)' },
|
||||
},
|
||||
防护工程专家: {
|
||||
text: '防护工程专家',
|
||||
style: {
|
||||
backgroundColor: '#5cb85c',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
},
|
||||
},
|
||||
腐蚀机理研究员: {
|
||||
text: '腐蚀机理研究员',
|
||||
style: {
|
||||
backgroundColor: '#f0ad4e',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
style: { background: 'hsl(30, 70%, 50%)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
TaskProcess: [
|
||||
{
|
||||
id: 'task-1',
|
||||
type: '数据清洗',
|
||||
agent: '实验材料学家',
|
||||
description: '清洗和预处理销售数据',
|
||||
inputs: ['销售数据CSV'],
|
||||
ID: 'action-1-1-branch2',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '基于腐蚀类型列表,设计快速原型验证方案',
|
||||
ImportantInput: ['InputObject:腐蚀类型及成因列表'],
|
||||
},
|
||||
{
|
||||
id: 'task-2',
|
||||
type: '统计分析',
|
||||
agent: '防护工程专家',
|
||||
description: '计算销售指标和趋势',
|
||||
inputs: ['清洗后的数据'],
|
||||
ID: 'action-1-2-branch2',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '实现原型核心功能和用户界面',
|
||||
ImportantInput: ['ActionResult:action-1-1-branch2'],
|
||||
},
|
||||
{
|
||||
id: 'task-3',
|
||||
type: '可视化',
|
||||
agent: '防护工程专家',
|
||||
description: '创建数据可视化图表',
|
||||
inputs: ['分析结果'],
|
||||
ID: 'action-1-3-branch2',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '评估原型功能完整性和用户体验',
|
||||
ImportantInput: ['ActionResult:action-1-2-branch2'],
|
||||
},
|
||||
{
|
||||
id: 'task-4',
|
||||
type: '报告编写',
|
||||
agent: '腐蚀机理研究员',
|
||||
description: '撰写业务分析报告',
|
||||
inputs: ['可视化图表', '分析结果'],
|
||||
ID: 'action-1-4-branch2',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '根据反馈优化原型功能和界面',
|
||||
ImportantInput: ['ActionResult:action-1-3-branch2'],
|
||||
},
|
||||
{
|
||||
ID: 'action-1-5-branch2',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '确认最终版本的原型系统',
|
||||
ImportantInput: ['ActionResult:action-1-4-branch2'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// 场景3: 文档编写任务 - 产品需求文档
|
||||
export const mockDocumentation: IApiStepTask = {
|
||||
name: '产品需求文档编写',
|
||||
content: '为新功能编写详细的产品需求文档',
|
||||
inputs: ['产品原型', '用户故事', '技术约束'],
|
||||
output: 'PRD文档',
|
||||
agents: ['实验材料学家', '防护工程专家', '腐蚀机理研究员'],
|
||||
brief: {
|
||||
template: '!<实验材料学家>!主导文档编写,!<防护工程专家>!提供技术输入,!<腐蚀机理研究员>!补充用户体验细节',
|
||||
} else if (selectedBranchIndex === 2) {
|
||||
// 第三个分支方案:需求深度分析
|
||||
filledTask = {
|
||||
Id: params.stepTask.Id || 'task-1',
|
||||
StepName: '需求深度分析',
|
||||
TaskContent: '深入分析用户需求和技术可行性',
|
||||
InputObject_List: ['腐蚀类型及成因列表'],
|
||||
OutputObject: '详细需求分析报告',
|
||||
AgentSelection: ['腐蚀机理研究员', '防护工程专家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '!腐蚀机理研究员!负责!需求深度分析-0!,!防护工程专家!负责!需求深度分析-1!',
|
||||
data: {
|
||||
实验材料学家: {
|
||||
text: '实验材料学家',
|
||||
style: {
|
||||
backgroundColor: '#4a9cde',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
},
|
||||
腐蚀机理研究员: {
|
||||
text: '腐蚀机理研究员',
|
||||
style: { background: 'hsl(210, 70%, 50%)' },
|
||||
},
|
||||
防护工程专家: {
|
||||
text: '防护工程专家',
|
||||
style: {
|
||||
backgroundColor: '#5cb85c',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
},
|
||||
},
|
||||
腐蚀机理研究员: {
|
||||
text: '腐蚀机理研究员',
|
||||
style: {
|
||||
backgroundColor: '#f0ad4e',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
style: { background: 'hsl(30, 70%, 50%)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
TaskProcess: [
|
||||
{
|
||||
id: 'task-1',
|
||||
type: '需求分析',
|
||||
agent: '实验材料学家',
|
||||
description: '分析用户需求和业务目标',
|
||||
inputs: ['用户故事'],
|
||||
ID: 'action-1-1-branch3',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '全面分析腐蚀环境和技术约束条件',
|
||||
ImportantInput: ['InputObject:腐蚀类型及成因列表'],
|
||||
},
|
||||
{
|
||||
id: 'task-2',
|
||||
type: '技术评估',
|
||||
agent: '防护工程专家',
|
||||
description: '评估技术可行性和约束',
|
||||
inputs: ['产品原型'],
|
||||
ID: 'action-1-2-branch3',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '评估技术可行性和防护方案',
|
||||
ImportantInput: ['ActionResult:action-1-1-branch3'],
|
||||
},
|
||||
{
|
||||
id: 'task-3',
|
||||
type: 'UX设计',
|
||||
agent: '腐蚀机理研究员',
|
||||
description: '完善用户体验设计',
|
||||
inputs: ['需求分析结果'],
|
||||
ID: 'action-1-3-branch3',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '评审需求分析的完整性和准确性',
|
||||
ImportantInput: ['ActionResult:action-1-2-branch3', 'ActionResult:action-1-1-branch3'],
|
||||
},
|
||||
{
|
||||
id: 'task-4',
|
||||
type: '文档编写',
|
||||
agent: '实验材料学家',
|
||||
description: '编写完整的PRD文档',
|
||||
inputs: ['技术评估', 'UX设计'],
|
||||
ID: 'action-1-4-branch3',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '补充技术风险评估和应对策略',
|
||||
ImportantInput: ['ActionResult:action-1-3-branch3'],
|
||||
},
|
||||
{
|
||||
ID: 'action-1-5-branch3',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '确认详细需求分析报告',
|
||||
ImportantInput: ['ActionResult:action-1-4-branch3', 'ActionResult:action-1-3-branch3'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// 场景4: 复杂协作任务 - 系统迁移项目
|
||||
export const mockSystemMigration: IApiStepTask = {
|
||||
name: '旧系统到新系统迁移',
|
||||
content: '将现有系统迁移到新的技术架构',
|
||||
inputs: ['旧系统代码', '新系统架构图', '迁移计划'],
|
||||
output: '成功迁移的系统',
|
||||
agents: ['实验材料学家', '防护工程专家', '腐蚀机理研究员'],
|
||||
brief: {
|
||||
template:
|
||||
'!<防护工程专家>!制定迁移策略,!<实验材料学家>!执行代码迁移,!<腐蚀机理研究员>!负责部署,!<防护工程专家>!确保质量',
|
||||
} else {
|
||||
// 第四个分支方案:迭代规划
|
||||
filledTask = {
|
||||
Id: params.stepTask.Id || 'task-1',
|
||||
StepName: '迭代规划',
|
||||
TaskContent: '制定敏捷开发迭代计划',
|
||||
InputObject_List: ['腐蚀类型及成因列表'],
|
||||
OutputObject: '迭代计划',
|
||||
AgentSelection: ['防护工程专家', '腐蚀机理研究员'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '!防护工程专家!负责!迭代规划-0!,!腐蚀机理研究员!负责!迭代规划-1!',
|
||||
data: {
|
||||
防护工程专家: {
|
||||
text: '防护工程专家',
|
||||
style: {
|
||||
backgroundColor: '#5cb85c',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
},
|
||||
},
|
||||
实验材料学家: {
|
||||
text: '实验材料学家',
|
||||
style: {
|
||||
backgroundColor: '#4a9cde',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
},
|
||||
style: { background: 'hsl(30, 70%, 50%)' },
|
||||
},
|
||||
腐蚀机理研究员: {
|
||||
text: '腐蚀机理研究员',
|
||||
style: {
|
||||
backgroundColor: '#f0ad4e',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
style: { background: 'hsl(210, 70%, 50%)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
TaskProcess: [
|
||||
{
|
||||
id: 'task-1',
|
||||
type: '架构设计',
|
||||
agent: '防护工程专家',
|
||||
description: '设计系统迁移架构',
|
||||
inputs: ['新系统架构图'],
|
||||
ID: 'action-1-1-branch4',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '制定敏捷开发总体框架和迭代周期',
|
||||
ImportantInput: ['InputObject:腐蚀类型及成因列表'],
|
||||
},
|
||||
{
|
||||
id: 'task-2',
|
||||
type: '代码迁移',
|
||||
agent: '实验材料学家',
|
||||
description: '迁移业务逻辑代码',
|
||||
inputs: ['旧系统代码', '迁移架构'],
|
||||
ID: 'action-1-2-branch4',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '规划各迭代阶段的技术验证重点',
|
||||
ImportantInput: ['ActionResult:action-1-1-branch4'],
|
||||
},
|
||||
{
|
||||
id: 'task-3',
|
||||
type: '数据迁移',
|
||||
agent: '实验材料学家',
|
||||
description: '迁移数据库和数据',
|
||||
inputs: ['旧系统数据'],
|
||||
ID: 'action-1-3-branch4',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '评审迭代计划的合理性和可执行性',
|
||||
ImportantInput: ['ActionResult:action-1-2-branch4'],
|
||||
},
|
||||
{
|
||||
id: 'task-4',
|
||||
type: '部署',
|
||||
agent: '腐蚀机理研究员',
|
||||
description: '部署新系统到生产环境',
|
||||
inputs: ['迁移后的代码'],
|
||||
ID: 'action-1-4-branch4',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '优化迭代节奏和里程碑设置',
|
||||
ImportantInput: ['ActionResult:action-1-3-branch4'],
|
||||
},
|
||||
{
|
||||
id: 'task-5',
|
||||
type: '测试',
|
||||
agent: '防护工程专家',
|
||||
description: '进行系统集成测试',
|
||||
inputs: ['部署的系统'],
|
||||
ID: 'action-1-5-branch4',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '确认最终迭代计划',
|
||||
ImportantInput: ['ActionResult:action-1-4-branch4', 'ActionResult:action-1-3-branch4'],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
// 场景5: 简单任务 - 日常报告生成
|
||||
export const mockSimpleTask: IApiStepTask = {
|
||||
name: '每日运营报告生成',
|
||||
content: '自动生成每日业务运营报告',
|
||||
inputs: ['业务数据', '报告模板'],
|
||||
output: '每日运营报告',
|
||||
agents: ['实验材料学家', '防护工程专家', '腐蚀机理研究员'],
|
||||
brief: {
|
||||
template: '!<实验材料学家>!自动处理数据并生成报告',
|
||||
console.log('[Mock API] fill_stepTask 返回数据:', filledTask)
|
||||
return filledTask
|
||||
}
|
||||
// ==================== 第二个任务组 ====================
|
||||
else if (stepName === '系统设计与架构' || stepName === '原型测试与优化' || stepName === '质量保障设计' || stepName === '快速开发与验证') {
|
||||
let filledTask: IRawStepTask
|
||||
|
||||
if (selectedBranchIndex === 0) {
|
||||
// 第一个分支方案:系统设计与架构
|
||||
filledTask = {
|
||||
Id: params.stepTask.Id || 'task-2',
|
||||
StepName: '系统设计与架构',
|
||||
TaskContent: '设计系统架构和数据库结构',
|
||||
InputObject_List: ['项目开发计划书'],
|
||||
OutputObject: '系统设计文档',
|
||||
AgentSelection: ['腐蚀机理研究员', '防护工程专家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '!腐蚀机理研究员!负责!系统设计与架构-0!,!防护工程专家!负责!系统设计与架构-1!',
|
||||
data: {
|
||||
腐蚀机理研究员: {
|
||||
text: '腐蚀机理研究员',
|
||||
style: { background: 'hsl(210, 70%, 50%)' },
|
||||
},
|
||||
防护工程专家: {
|
||||
text: '防护工程专家',
|
||||
style: { background: 'hsl(30, 70%, 50%)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
TaskProcess: [
|
||||
{
|
||||
ID: 'action-2-1',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '分析系统功能需求,提出整体架构方案',
|
||||
ImportantInput: ['InputObject:项目开发计划书'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-2',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '设计防护系统架构和数据库模型',
|
||||
ImportantInput: ['ActionResult:action-2-1'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-3',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '评审架构设计的合理性和可扩展性',
|
||||
ImportantInput: ['ActionResult:action-2-2', 'InputObject:项目开发计划书'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-4',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '优化架构设计,补充性能和安全方案',
|
||||
ImportantInput: ['ActionResult:action-2-3', 'ActionResult:action-2-2'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-5',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '确认最终系统架构设计文档',
|
||||
ImportantInput: ['ActionResult:action-2-4', 'ActionResult:action-2-3'],
|
||||
},
|
||||
],
|
||||
}
|
||||
} else if (selectedBranchIndex === 1) {
|
||||
// 第二个分支方案:原型测试与优化
|
||||
filledTask = {
|
||||
Id: params.stepTask.Id || 'task-2',
|
||||
StepName: '原型测试与优化',
|
||||
TaskContent: '测试原型并根据反馈快速迭代',
|
||||
InputObject_List: ['原型系统'],
|
||||
OutputObject: '优化后的原型',
|
||||
AgentSelection: ['腐蚀机理研究员', '实验材料学家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '!腐蚀机理研究员!负责!原型测试与优化-0!,!实验材料学家!负责!原型测试与优化-1!',
|
||||
data: {
|
||||
腐蚀机理研究员: {
|
||||
text: '腐蚀机理研究员',
|
||||
style: { background: 'hsl(210, 70%, 50%)' },
|
||||
},
|
||||
实验材料学家: {
|
||||
text: '实验材料学家',
|
||||
style: { background: 'hsl(120, 70%, 50%)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
TaskProcess: [
|
||||
{
|
||||
ID: 'action-2-1-branch2',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '制定原型测试计划和验证标准',
|
||||
ImportantInput: ['InputObject:原型系统'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-2-branch2',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '执行原型测试并收集性能数据',
|
||||
ImportantInput: ['ActionResult:action-2-1-branch2'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-3-branch2',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '分析测试结果和用户反馈',
|
||||
ImportantInput: ['ActionResult:action-2-2-branch2'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-4-branch2',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '根据测试结果优化原型功能和性能',
|
||||
ImportantInput: ['ActionResult:action-2-3-branch2'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-5-branch2',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '确认优化后的原型版本',
|
||||
ImportantInput: ['ActionResult:action-2-4-branch2', 'ActionResult:action-2-3-branch2'],
|
||||
},
|
||||
],
|
||||
}
|
||||
} else if (selectedBranchIndex === 2) {
|
||||
// 第三个分支方案:质量保障设计
|
||||
filledTask = {
|
||||
Id: params.stepTask.Id || 'task-2',
|
||||
StepName: '质量保障设计',
|
||||
TaskContent: '设计质量保障体系和测试方案',
|
||||
InputObject_List: ['详细需求分析报告'],
|
||||
OutputObject: '质量保障方案',
|
||||
AgentSelection: ['实验材料学家', '防护工程专家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '!实验材料学家!负责!质量保障设计-0!,!防护工程专家!负责!质量保障设计-1!',
|
||||
data: {
|
||||
实验材料学家: {
|
||||
text: '实验材料学家',
|
||||
style: {
|
||||
backgroundColor: '#4a9cde',
|
||||
color: 'white',
|
||||
padding: '2px 6px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
display: 'inline-block',
|
||||
style: { background: 'hsl(120, 70%, 50%)' },
|
||||
},
|
||||
防护工程专家: {
|
||||
text: '防护工程专家',
|
||||
style: { background: 'hsl(30, 70%, 50%)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
process: [
|
||||
TaskProcess: [
|
||||
{
|
||||
id: 'task-1',
|
||||
type: '数据处理',
|
||||
agent: '实验材料学家',
|
||||
description: '提取和处理业务数据',
|
||||
inputs: ['业务数据'],
|
||||
ID: 'action-2-1-branch3',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '制定质量标准和测试指标体系',
|
||||
ImportantInput: ['InputObject:详细需求分析报告'],
|
||||
},
|
||||
{
|
||||
id: 'task-2',
|
||||
type: '报告生成',
|
||||
agent: '防护工程专家',
|
||||
description: '根据模板生成报告',
|
||||
inputs: ['处理后的数据', '报告模板'],
|
||||
ID: 'action-2-2-branch3',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '设计质量保障流程和验证方案',
|
||||
ImportantInput: ['ActionResult:action-2-1-branch3'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-3-branch3',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '评审质量保障方案的完整性',
|
||||
ImportantInput: ['ActionResult:action-2-2-branch3'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-4-branch3',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '完善质量保障方案,补充风险控制',
|
||||
ImportantInput: ['ActionResult:action-2-3-branch3'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-5-branch3',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '确认最终质量保障方案',
|
||||
ImportantInput: ['ActionResult:action-2-4-branch3', 'ActionResult:action-2-3-branch3'],
|
||||
},
|
||||
],
|
||||
}
|
||||
} else {
|
||||
// 第四个分支方案:快速开发与验证
|
||||
filledTask = {
|
||||
Id: params.stepTask.Id || 'task-2',
|
||||
StepName: '快速开发与验证',
|
||||
TaskContent: '快速开发并持续验证功能',
|
||||
InputObject_List: ['迭代计划'],
|
||||
OutputObject: '可运行的功能模块',
|
||||
AgentSelection: ['实验材料学家', '防护工程专家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '!实验材料学家!负责!快速开发与验证-0!,!防护工程专家!负责!快速开发与验证-1!',
|
||||
data: {
|
||||
实验材料学家: {
|
||||
text: '实验材料学家',
|
||||
style: { background: 'hsl(120, 70%, 50%)' },
|
||||
},
|
||||
防护工程专家: {
|
||||
text: '防护工程专家',
|
||||
style: { background: 'hsl(30, 70%, 50%)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
TaskProcess: [
|
||||
{
|
||||
ID: 'action-2-1-branch4',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '根据迭代计划快速开发功能模块',
|
||||
ImportantInput: ['InputObject:迭代计划'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-2-branch4',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '实现功能防护机制和验证逻辑',
|
||||
ImportantInput: ['ActionResult:action-2-1-branch4'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-3-branch4',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '验证功能模块的正确性和性能',
|
||||
ImportantInput: ['ActionResult:action-2-2-branch4'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-4-branch4',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '防护工程专家',
|
||||
Description: '根据验证结果优化功能实现',
|
||||
ImportantInput: ['ActionResult:action-2-3-branch4'],
|
||||
},
|
||||
{
|
||||
ID: 'action-2-5-branch4',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '确认可运行的功能模块',
|
||||
ImportantInput: ['ActionResult:action-2-4-branch4', 'ActionResult:action-2-3-branch4'],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[Mock API] fill_stepTask 返回数据:', filledTask)
|
||||
return filledTask
|
||||
}
|
||||
// ==================== 第三个任务组(仅第三个分支方案) ====================
|
||||
else if (stepName === '系统开发与测试') {
|
||||
const filledTask: IRawStepTask = {
|
||||
Id: params.stepTask.Id || 'task-3',
|
||||
StepName: '系统开发与测试',
|
||||
TaskContent: '按质量标准进行系统开发和测试',
|
||||
InputObject_List: ['质量保障方案'],
|
||||
OutputObject: '经过完整测试的系统',
|
||||
AgentSelection: ['腐蚀机理研究员', '实验材料学家'],
|
||||
Collaboration_Brief_frontEnd: {
|
||||
template: '!腐蚀机理研究员!负责!系统开发与测试-0!,!实验材料学家!负责!系统开发与测试-1!',
|
||||
data: {
|
||||
腐蚀机理研究员: {
|
||||
text: '腐蚀机理研究员',
|
||||
style: { background: 'hsl(210, 70%, 50%)' },
|
||||
},
|
||||
实验材料学家: {
|
||||
text: '实验材料学家',
|
||||
style: { background: 'hsl(120, 70%, 50%)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
TaskProcess: [
|
||||
{
|
||||
ID: 'action-3-1',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '根据质量标准制定系统开发计划',
|
||||
ImportantInput: ['InputObject:质量保障方案'],
|
||||
},
|
||||
{
|
||||
ID: 'action-3-2',
|
||||
ActionType: 'Propose',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '按标准实施系统开发和单元测试',
|
||||
ImportantInput: ['ActionResult:action-3-1'],
|
||||
},
|
||||
{
|
||||
ID: 'action-3-3',
|
||||
ActionType: 'Critique',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '评审系统开发质量和测试覆盖率',
|
||||
ImportantInput: ['ActionResult:action-3-2'],
|
||||
},
|
||||
{
|
||||
ID: 'action-3-4',
|
||||
ActionType: 'Improve',
|
||||
AgentName: '实验材料学家',
|
||||
Description: '根据评审结果完善系统功能和测试',
|
||||
ImportantInput: ['ActionResult:action-3-3'],
|
||||
},
|
||||
{
|
||||
ID: 'action-3-5',
|
||||
ActionType: 'Finalize',
|
||||
AgentName: '腐蚀机理研究员',
|
||||
Description: '确认经过完整测试的系统版本',
|
||||
ImportantInput: ['ActionResult:action-3-4', 'ActionResult:action-3-3'],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
// 完整的 mock 数据集合
|
||||
export const mockFillStepTaskData = {
|
||||
softwareDevelopment: mockSoftwareDevelopment,
|
||||
dataAnalysis: mockDataAnalysis,
|
||||
documentation: mockDocumentation,
|
||||
systemMigration: mockSystemMigration,
|
||||
simpleTask: mockSimpleTask,
|
||||
console.log('[Mock API] fill_stepTask 返回数据:', filledTask)
|
||||
return filledTask
|
||||
}
|
||||
// ==================== 其他任务 ====================
|
||||
else {
|
||||
// 其他任务,返回空 TaskProcess
|
||||
console.warn('[Mock API] 未知的 StepName:', stepName)
|
||||
return {
|
||||
...params.stepTask,
|
||||
AgentSelection: [],
|
||||
TaskProcess: [],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Vue 组件使用示例
|
||||
export const mockFillStepTaskForVue = {
|
||||
// 返回所有 mock 数据的数组形式
|
||||
getAllMockTasks(): IApiStepTask[] {
|
||||
return [
|
||||
mockSoftwareDevelopment,
|
||||
mockDataAnalysis,
|
||||
mockDocumentation,
|
||||
mockSystemMigration,
|
||||
mockSimpleTask,
|
||||
]
|
||||
},
|
||||
|
||||
// 根据任务类型获取 mock 数据
|
||||
getMockTaskByType(type: string): IApiStepTask | null {
|
||||
const tasks = {
|
||||
软件开发: mockSoftwareDevelopment,
|
||||
数据分析: mockDataAnalysis,
|
||||
文档编写: mockDocumentation,
|
||||
系统迁移: mockSystemMigration,
|
||||
简单任务: mockSimpleTask,
|
||||
}
|
||||
return tasks[type as keyof typeof tasks] || null
|
||||
},
|
||||
|
||||
// 模拟 API 响应
|
||||
mockApiResponse(): Promise<IApiStepTask[]> {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(this.getAllMockTasks())
|
||||
}, 500)
|
||||
})
|
||||
},
|
||||
}
|
||||
export default mockFillStepTaskAPI
|
||||
|
||||
@@ -29,7 +29,7 @@ const scoreDimensions = ref<string[]>([])
|
||||
interface AgentHeatmapData {
|
||||
agentName: string
|
||||
scores: number[] // 各维度的评分
|
||||
scoreDetails?: Array<{ dimension: string; score: number; reason: string }> // 详细信息(可选)
|
||||
scoreDetails?: Array<{ dimension: string; score: number; reason: string }> // 详细信息
|
||||
}
|
||||
|
||||
// 所有agent的热力图数据
|
||||
@@ -57,6 +57,9 @@ const searchValue = ref('')
|
||||
// 标志位:防止重复初始化
|
||||
const isInitializing = ref(false)
|
||||
const isAddingDimension = ref(false)
|
||||
const isLoadingConfirm = ref(false) // 确认 agent 组合时的加载状态
|
||||
const isLoadingSelectGroup = ref(false) // 选择已保存组合时的加载状态
|
||||
const isLoadingInitialTask = ref(false) // 首次加载任务时的加载状态
|
||||
|
||||
// 处理搜索提交
|
||||
const handleSubmit = async () => {
|
||||
@@ -143,19 +146,8 @@ const confirmAgentSelection = async () => {
|
||||
if (selectedAgents.value.size > 0 && currentTask.value?.Id) {
|
||||
const agentArray = Array.from(selectedAgents.value)
|
||||
|
||||
// 检查该agent组合是否已存在(包括初始agent组合和用户添加的组合)
|
||||
// 检查该agent组合是否已存在(统一检查,包括初始组合和用户添加的组合)
|
||||
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 =>
|
||||
areAgentGroupsEqual(agentArray, group)
|
||||
)
|
||||
@@ -176,7 +168,8 @@ const confirmAgentSelection = async () => {
|
||||
|
||||
// 调用 Mock API 填充任务流程
|
||||
try {
|
||||
console.log('=== 开始调用 fillStepTaskTaskProcess Mock API ===')
|
||||
isLoadingConfirm.value = true
|
||||
console.log('=== 开始调用 mockFillStepTaskTaskProcess Mock API ===')
|
||||
console.log('1. 当前任务数据 (IRawStepTask 格式):', currentTask.value)
|
||||
console.log('2. 选中的 agents:', agentArray)
|
||||
|
||||
@@ -218,12 +211,14 @@ const confirmAgentSelection = async () => {
|
||||
console.log('✅ Mock API 调用成功,数据已存储到 selectionStore')
|
||||
} catch (error) {
|
||||
console.error('❌ Mock API 调用失败:', error)
|
||||
} finally {
|
||||
isLoadingConfirm.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 点击 Assignment 部分的 agent 组合卡片,更新 Comparison 部分的选中状态
|
||||
const selectAgentGroup = (agentNames: string[]) => {
|
||||
const selectAgentGroup = async (agentNames: string[]) => {
|
||||
// 更新Assignment边框状态
|
||||
selectedAssignmentGroup.value = [...agentNames]
|
||||
|
||||
@@ -237,6 +232,116 @@ const selectAgentGroup = (agentNames: string[]) => {
|
||||
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按平均分降序
|
||||
if (agentsHeatmapData.value.length > 0) {
|
||||
agentsHeatmapData.value.sort((a, b) => {
|
||||
@@ -406,18 +511,27 @@ const fetchAgentScores = async () => {
|
||||
}
|
||||
|
||||
// TODO: 切换到真实API时,取消注释下面这行
|
||||
// const response = await api.agentSelectModifyInit({
|
||||
// const agentScores = await api.agentSelectModifyInit({
|
||||
// goal: agentsStore.agentRawPlan.data?.['General Goal'] || '',
|
||||
// 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()
|
||||
|
||||
// 从转换后的数据中提取维度列表(第一个agent的所有维度)
|
||||
const firstAgent = Object.keys(agentScores)[0]
|
||||
const aspectList = firstAgent ? Object.keys(agentScores[firstAgent] || {}) : []
|
||||
|
||||
console.log('✅ 获取到的维度列表:', aspectList)
|
||||
|
||||
// 保存到 store
|
||||
agentsStore.setAgentScoreData({
|
||||
aspectList,
|
||||
@@ -594,9 +708,10 @@ watch(
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
// 按需加载初始 agent 组合的 TaskProcess(方案B)
|
||||
// 当用户第一次打开智能体探索窗口时,检查当前任务的初始 agent 组合是否已有 TaskProcess 数据
|
||||
// 如果没有,则调用 fill_stepTask_TaskProcess API 获取并存储
|
||||
// 初始化和任务切换处理
|
||||
// 1. 首次加载时,自动将初始 agent 组合添加到 confirmedAgentGroups
|
||||
// 2. 恢复之前的选择状态
|
||||
// 3. 加载 TaskProcess 数据
|
||||
watch(
|
||||
() => currentTask.value,
|
||||
async newTask => {
|
||||
@@ -604,28 +719,22 @@ watch(
|
||||
return
|
||||
}
|
||||
|
||||
// 从 store 中恢复之前选择的 agent 组合
|
||||
const savedAgentGroup = agentsStore.getSelectedAgentGroup(newTask.Id)
|
||||
if (savedAgentGroup) {
|
||||
console.log('📂 恢复之前选择的 agent 组合:', savedAgentGroup)
|
||||
selectedAssignmentGroup.value = [...savedAgentGroup]
|
||||
selectedAgents.value = new Set(savedAgentGroup)
|
||||
} else {
|
||||
// 没有保存的选择,使用默认的初始组合
|
||||
selectedAssignmentGroup.value = [...newTask.AgentSelection]
|
||||
selectedAgents.value = new Set(newTask.AgentSelection)
|
||||
}
|
||||
// 检查是否已经添加过初始组合
|
||||
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)) {
|
||||
console.log('ℹ️ 初始 agent 组合已有 TaskProcess 数据,跳过加载')
|
||||
return
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -664,6 +773,28 @@ watch(
|
||||
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)
|
||||
if (savedAgentGroup) {
|
||||
console.log('📂 恢复之前选择的 agent 组合:', savedAgentGroup)
|
||||
selectedAssignmentGroup.value = [...savedAgentGroup]
|
||||
selectedAgents.value = new Set(savedAgentGroup)
|
||||
} else {
|
||||
// 没有保存的选择,默认选中第一个组合(即初始组合)
|
||||
const allGroups = agentsStore.getConfirmedAgentGroups(newTask.Id)
|
||||
if (allGroups.length > 0 && allGroups[0]) {
|
||||
console.log('🔄 默认选中第一个组合(初始组合):', allGroups[0])
|
||||
selectedAssignmentGroup.value = [...allGroups[0]]
|
||||
selectedAgents.value = new Set(allGroups[0])
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true } // 立即执行一次
|
||||
@@ -672,7 +803,7 @@ watch(
|
||||
// 获取热力图颜色(评分1-5,颜色从浅到深)
|
||||
const getHeatmapColor = (score: number) => {
|
||||
const colors = [
|
||||
'#f0f0f0', // 1分 - 最浅
|
||||
'#f7f7f7', // 1分 - 最浅
|
||||
'#d4e5f7', // 2分
|
||||
'#89b4e8', // 3分
|
||||
'#4575b4', // 4分
|
||||
@@ -686,49 +817,15 @@ const getHeatmapColor = (score: number) => {
|
||||
<div class="agent-allocation-container">
|
||||
<!-- 左侧区域 - 20% -->
|
||||
<div class="allocation-left">
|
||||
<div class="section-card">
|
||||
<div class="section-card" v-loading="isLoadingSelectGroup">
|
||||
<div class="section-title">Assignment</div>
|
||||
<!-- 初始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组合列表 -->
|
||||
<!-- 所有 agent 组合卡片(包括初始组合和用户创建的组合) -->
|
||||
<div
|
||||
v-for="(group, groupIndex) in confirmedAgentGroups"
|
||||
:key="groupIndex"
|
||||
class="agents-grid"
|
||||
:class="{ 'agent-group-selected': isAgentGroupSelected(group) }"
|
||||
style="margin-top: 12px"
|
||||
:style="{ marginTop: groupIndex > 0 ? '12px' : '0' }"
|
||||
@click="selectAgentGroup(group)"
|
||||
>
|
||||
<el-tooltip
|
||||
@@ -767,7 +864,11 @@ const getHeatmapColor = (score: number) => {
|
||||
<div class="allocation-right">
|
||||
<div class="section-card">
|
||||
<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">
|
||||
<!-- 虚线选择框 - 包裹选中的agent头像 -->
|
||||
@@ -777,7 +878,11 @@ const getHeatmapColor = (score: number) => {
|
||||
: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" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -874,7 +979,7 @@ const getHeatmapColor = (score: number) => {
|
||||
</div>
|
||||
|
||||
<!-- 输入框区域 -->
|
||||
<div class="search-input-container">
|
||||
<div class="search-input-container" v-loading="isAddingDimension">
|
||||
<el-input
|
||||
v-model="searchValue"
|
||||
placeholder="请输入新维度"
|
||||
@@ -887,7 +992,7 @@ const getHeatmapColor = (score: number) => {
|
||||
size="16px"
|
||||
color="#409eff"
|
||||
class="submit-icon"
|
||||
:class="{ 'is-disabled': !searchValue }"
|
||||
:class="{ 'is-disabled': !searchValue, 'is-loading': isAddingDimension }"
|
||||
@click="searchValue && handleSubmit()"
|
||||
/>
|
||||
</template>
|
||||
@@ -1039,6 +1144,25 @@ const getHeatmapColor = (score: number) => {
|
||||
transform: scale(1.1);
|
||||
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;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
padding-top: 40px; // 对齐第一个评分单元格(跳过列头)
|
||||
padding-top: 40px; // 对齐第一个评分单元格
|
||||
flex-shrink: 0;
|
||||
max-width: 200px; //
|
||||
|
||||
.dimension-label {
|
||||
width: 60px;
|
||||
min-width: 60px; // 改为最小宽度,允许根据内容自适应
|
||||
width: auto; // 宽度自适应
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px; // 添加右侧内边距,确保文字不会紧贴边缘
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: var(--color-text-title-header);
|
||||
@@ -1119,6 +1246,7 @@ const getHeatmapColor = (score: number) => {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: all 0.2s ease;
|
||||
white-space: nowrap; // 防止文字换行
|
||||
|
||||
&:hover {
|
||||
color: #409eff;
|
||||
@@ -1177,6 +1305,11 @@ const getHeatmapColor = (score: number) => {
|
||||
opacity: 0.4;
|
||||
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)
|
||||
|
||||
// 当前任务agents(1) + 已确认的agent组合数量
|
||||
return 1 + confirmedGroups.length
|
||||
return confirmedGroups.length || 1
|
||||
})
|
||||
|
||||
const handleClick = () => {
|
||||
|
||||
@@ -11,9 +11,9 @@ const emit = defineEmits<{
|
||||
// 获取分支数量 - 主分支(1) + 额外分支数量
|
||||
const branchCount = computed(() => {
|
||||
// flowBranches 包含所有通过 Branch 创建的分支
|
||||
const extraBranches = selectionStore.flowBranches?.length || 0
|
||||
const extraBranches = selectionStore.flowBranches?.length || 1
|
||||
// 始终至少有1个主分支
|
||||
return 1 + extraBranches
|
||||
return extraBranches
|
||||
})
|
||||
|
||||
const handleClick = () => {
|
||||
@@ -26,7 +26,7 @@ const handleClick = () => {
|
||||
<template>
|
||||
<div
|
||||
class="branch-button"
|
||||
:class="{ 'has-branches': branchCount > 1 }"
|
||||
:class="{ 'has-branches': branchCount > 0 }"
|
||||
@click="handleClick"
|
||||
: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 { type ConnectArg, Jsplumb } from '@/layout/components/Main/TaskTemplate/utils.ts'
|
||||
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 MultiLineTooltip from '@/components/MultiLineTooltip/index.vue'
|
||||
import Bg from './Bg.vue'
|
||||
@@ -15,7 +15,6 @@ const planReady = computed(() => {
|
||||
})
|
||||
|
||||
const openPlanModification = () => {
|
||||
console.log('打开分支修改窗口')
|
||||
agentsStore.openPlanModification()
|
||||
}
|
||||
|
||||
@@ -202,6 +201,56 @@ function clear() {
|
||||
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({
|
||||
changeTask,
|
||||
clear
|
||||
|
||||
@@ -84,6 +84,7 @@ onMounted(() => {
|
||||
|
||||
<Header />
|
||||
<Main />
|
||||
|
||||
<FloatWindow
|
||||
v-if="agentsStore.planModificationWindow"
|
||||
title="任务大纲探索"
|
||||
@@ -91,6 +92,7 @@ onMounted(() => {
|
||||
>
|
||||
<PlanModification />
|
||||
</FloatWindow>
|
||||
|
||||
<FloatWindow
|
||||
v-if="agentsStore.planTaskWindow"
|
||||
title="任务过程探索"
|
||||
|
||||
@@ -222,7 +222,113 @@ export const useAgentsStore = defineStore('agents', () => {
|
||||
// 当前的展示的任务流程
|
||||
const currentTask = ref<IRawStepTask>()
|
||||
function setCurrentTask(task: IRawStepTask) {
|
||||
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 })
|
||||
@@ -315,6 +421,9 @@ export const useAgentsStore = defineStore('agents', () => {
|
||||
setSearchValue,
|
||||
currentTask,
|
||||
setCurrentTask,
|
||||
setCurrentTaskProcess, // 🆕 设置当前任务的 TaskProcess
|
||||
updateCurrentAgentSelection, // 🆕 强制更新 AgentSelection(用于 AgentAllocation 切换组合)
|
||||
syncCurrentTaskToMainProcess, // 🆕 同步 currentTask 到主流程
|
||||
agentRawPlan,
|
||||
setAgentRawPlan,
|
||||
executePlan,
|
||||
|
||||
@@ -207,11 +207,50 @@ export const useSelectionStore = defineStore('selection', () => {
|
||||
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 {
|
||||
// 状态
|
||||
flowBranches,
|
||||
taskProcessBranchesMap,
|
||||
agentTaskProcessMap,
|
||||
activeTaskProcessBranchMap,
|
||||
activeTaskProcessDataMap, // 🆕 新增
|
||||
|
||||
// 任务大纲分支管理方法
|
||||
addFlowBranch,
|
||||
@@ -229,6 +268,13 @@ export const useSelectionStore = defineStore('selection', () => {
|
||||
removeTaskProcessBranch,
|
||||
clearTaskProcessBranches,
|
||||
|
||||
// 🆕 任务过程分支生效状态管理方法
|
||||
setActiveTaskProcessBranch,
|
||||
setActiveTaskProcessData, // 🆕 新增
|
||||
getActiveTaskProcessBranch,
|
||||
getActiveTaskProcessData, // 🆕 新增
|
||||
clearActiveTaskProcessBranch,
|
||||
|
||||
// Agent 组合 TaskProcess 数据管理方法
|
||||
getAgentGroupKey,
|
||||
setAgentTaskProcess,
|
||||
|
||||
Reference in New Issue
Block a user