feat: 暂存添加ai chat and prompt generate
This commit is contained in:
parent
3da62fd254
commit
553e4d62f0
@ -26,8 +26,10 @@
|
||||
"classnames": "^2.5.1",
|
||||
"clsx": "^2.1.1",
|
||||
"copy-to-clipboard": "^3.3.3",
|
||||
"d3": "^7.9.0",
|
||||
"immer": "^10.1.1",
|
||||
"lodash-es": "^4.17.21",
|
||||
"marked": "^14.1.2",
|
||||
"nanoid": "^5.0.7",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
@ -41,6 +43,7 @@
|
||||
"@eslint/js": "^9.11.0",
|
||||
"@tailwindcss/aspect-ratio": "^0.4.2",
|
||||
"@tailwindcss/typography": "^0.5.15",
|
||||
"@types/d3": "^7.4.3",
|
||||
"@types/node": "^22.5.5",
|
||||
"@types/react": "^18.3.8",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
|
439
pnpm-lock.yaml
generated
439
pnpm-lock.yaml
generated
@ -50,12 +50,18 @@ importers:
|
||||
copy-to-clipboard:
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3
|
||||
d3:
|
||||
specifier: ^7.9.0
|
||||
version: 7.9.0
|
||||
immer:
|
||||
specifier: ^10.1.1
|
||||
version: 10.1.1
|
||||
lodash-es:
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.21
|
||||
marked:
|
||||
specifier: ^14.1.2
|
||||
version: 14.1.2
|
||||
nanoid:
|
||||
specifier: ^5.0.7
|
||||
version: 5.0.7
|
||||
@ -90,6 +96,9 @@ importers:
|
||||
'@tailwindcss/typography':
|
||||
specifier: ^0.5.15
|
||||
version: 0.5.15(tailwindcss@3.4.13)
|
||||
'@types/d3':
|
||||
specifier: ^7.4.3
|
||||
version: 7.4.3
|
||||
'@types/node':
|
||||
specifier: ^22.5.5
|
||||
version: 22.5.5
|
||||
@ -741,27 +750,105 @@ packages:
|
||||
'@types/babel__traverse@7.20.6':
|
||||
resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==}
|
||||
|
||||
'@types/d3-array@3.2.1':
|
||||
resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==}
|
||||
|
||||
'@types/d3-axis@3.0.6':
|
||||
resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==}
|
||||
|
||||
'@types/d3-brush@3.0.6':
|
||||
resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==}
|
||||
|
||||
'@types/d3-chord@3.0.6':
|
||||
resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==}
|
||||
|
||||
'@types/d3-color@3.1.3':
|
||||
resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
|
||||
|
||||
'@types/d3-contour@3.0.6':
|
||||
resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==}
|
||||
|
||||
'@types/d3-delaunay@6.0.4':
|
||||
resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==}
|
||||
|
||||
'@types/d3-dispatch@3.0.6':
|
||||
resolution: {integrity: sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==}
|
||||
|
||||
'@types/d3-drag@3.0.7':
|
||||
resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==}
|
||||
|
||||
'@types/d3-dsv@3.0.7':
|
||||
resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==}
|
||||
|
||||
'@types/d3-ease@3.0.2':
|
||||
resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
|
||||
|
||||
'@types/d3-fetch@3.0.7':
|
||||
resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==}
|
||||
|
||||
'@types/d3-force@3.0.10':
|
||||
resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==}
|
||||
|
||||
'@types/d3-format@3.0.4':
|
||||
resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==}
|
||||
|
||||
'@types/d3-geo@3.1.0':
|
||||
resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==}
|
||||
|
||||
'@types/d3-hierarchy@3.1.7':
|
||||
resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==}
|
||||
|
||||
'@types/d3-interpolate@3.0.4':
|
||||
resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
|
||||
|
||||
'@types/d3-path@3.1.0':
|
||||
resolution: {integrity: sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==}
|
||||
|
||||
'@types/d3-polygon@3.0.2':
|
||||
resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==}
|
||||
|
||||
'@types/d3-quadtree@3.0.6':
|
||||
resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==}
|
||||
|
||||
'@types/d3-random@3.0.3':
|
||||
resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==}
|
||||
|
||||
'@types/d3-scale-chromatic@3.0.3':
|
||||
resolution: {integrity: sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==}
|
||||
|
||||
'@types/d3-scale@4.0.8':
|
||||
resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==}
|
||||
|
||||
'@types/d3-selection@3.0.10':
|
||||
resolution: {integrity: sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==}
|
||||
|
||||
'@types/d3-shape@3.1.6':
|
||||
resolution: {integrity: sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==}
|
||||
|
||||
'@types/d3-time-format@4.0.3':
|
||||
resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==}
|
||||
|
||||
'@types/d3-time@3.0.3':
|
||||
resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==}
|
||||
|
||||
'@types/d3-timer@3.0.2':
|
||||
resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
|
||||
|
||||
'@types/d3-transition@3.0.8':
|
||||
resolution: {integrity: sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==}
|
||||
|
||||
'@types/d3-zoom@3.0.8':
|
||||
resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==}
|
||||
|
||||
'@types/d3@7.4.3':
|
||||
resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==}
|
||||
|
||||
'@types/estree@1.0.5':
|
||||
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
|
||||
|
||||
'@types/geojson@7946.0.14':
|
||||
resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==}
|
||||
|
||||
'@types/hast@2.3.10':
|
||||
resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==}
|
||||
|
||||
@ -1033,6 +1120,10 @@ packages:
|
||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
commander@7.2.0:
|
||||
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
compute-scroll-into-view@3.1.0:
|
||||
resolution: {integrity: sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==}
|
||||
|
||||
@ -1067,10 +1158,34 @@ packages:
|
||||
csstype@3.1.3:
|
||||
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
|
||||
|
||||
d3-array@3.2.4:
|
||||
resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-axis@3.0.0:
|
||||
resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-brush@3.0.0:
|
||||
resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-chord@3.0.1:
|
||||
resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-color@3.1.0:
|
||||
resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-contour@4.0.2:
|
||||
resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-delaunay@6.0.4:
|
||||
resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-dispatch@3.0.1:
|
||||
resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==}
|
||||
engines: {node: '>=12'}
|
||||
@ -1079,18 +1194,79 @@ packages:
|
||||
resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-dsv@3.0.1:
|
||||
resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
|
||||
d3-ease@3.0.1:
|
||||
resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-fetch@3.0.1:
|
||||
resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-force@3.0.0:
|
||||
resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-format@3.1.0:
|
||||
resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-geo@3.1.1:
|
||||
resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-hierarchy@3.1.2:
|
||||
resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-interpolate@3.0.1:
|
||||
resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-path@3.1.0:
|
||||
resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-polygon@3.0.1:
|
||||
resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-quadtree@3.0.1:
|
||||
resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-random@3.0.1:
|
||||
resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-scale-chromatic@3.1.0:
|
||||
resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-scale@4.0.2:
|
||||
resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-selection@3.0.0:
|
||||
resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-shape@3.2.0:
|
||||
resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-time-format@4.1.0:
|
||||
resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-time@3.1.0:
|
||||
resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3-timer@3.0.1:
|
||||
resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
|
||||
engines: {node: '>=12'}
|
||||
@ -1105,6 +1281,10 @@ packages:
|
||||
resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
d3@7.9.0:
|
||||
resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
dayjs@1.11.13:
|
||||
resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==}
|
||||
|
||||
@ -1123,6 +1303,9 @@ packages:
|
||||
deep-is@0.1.4:
|
||||
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
||||
|
||||
delaunator@5.0.1:
|
||||
resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==}
|
||||
|
||||
dequal@2.0.3:
|
||||
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
|
||||
engines: {node: '>=6'}
|
||||
@ -1360,6 +1543,10 @@ packages:
|
||||
html-void-elements@3.0.0:
|
||||
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
|
||||
|
||||
iconv-lite@0.6.3:
|
||||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
ignore@5.3.2:
|
||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||
engines: {node: '>= 4'}
|
||||
@ -1378,6 +1565,10 @@ packages:
|
||||
inline-style-parser@0.2.4:
|
||||
resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==}
|
||||
|
||||
internmap@2.0.3:
|
||||
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
is-alphabetical@2.0.1:
|
||||
resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
|
||||
|
||||
@ -1515,6 +1706,11 @@ packages:
|
||||
lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
|
||||
marked@14.1.2:
|
||||
resolution: {integrity: sha512-f3r0yqpz31VXiDB/wj9GaOB0a2PRLQl6vJmXiFrniNwjkKdvakqJRULhjFKJpxOchlCRiG5fcacoUZY5Xa6PEQ==}
|
||||
engines: {node: '>= 18'}
|
||||
hasBin: true
|
||||
|
||||
mdast-util-to-hast@13.2.0:
|
||||
resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
|
||||
|
||||
@ -2030,6 +2226,9 @@ packages:
|
||||
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
|
||||
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
|
||||
|
||||
robust-predicates@3.0.2:
|
||||
resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==}
|
||||
|
||||
rollup@4.22.0:
|
||||
resolution: {integrity: sha512-W21MUIFPZ4+O2Je/EU+GP3iz7PH4pVPUXSbEZdatQnxo29+3rsUjgrJmzuAZU24z7yRAnFN6ukxeAhZh/c7hzg==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
@ -2038,6 +2237,12 @@ packages:
|
||||
run-parallel@1.2.0:
|
||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||
|
||||
rw@1.3.3:
|
||||
resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
|
||||
|
||||
safer-buffer@2.1.2:
|
||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||
|
||||
scheduler@0.23.2:
|
||||
resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==}
|
||||
|
||||
@ -2966,18 +3171,81 @@ snapshots:
|
||||
dependencies:
|
||||
'@babel/types': 7.25.6
|
||||
|
||||
'@types/d3-array@3.2.1': {}
|
||||
|
||||
'@types/d3-axis@3.0.6':
|
||||
dependencies:
|
||||
'@types/d3-selection': 3.0.10
|
||||
|
||||
'@types/d3-brush@3.0.6':
|
||||
dependencies:
|
||||
'@types/d3-selection': 3.0.10
|
||||
|
||||
'@types/d3-chord@3.0.6': {}
|
||||
|
||||
'@types/d3-color@3.1.3': {}
|
||||
|
||||
'@types/d3-contour@3.0.6':
|
||||
dependencies:
|
||||
'@types/d3-array': 3.2.1
|
||||
'@types/geojson': 7946.0.14
|
||||
|
||||
'@types/d3-delaunay@6.0.4': {}
|
||||
|
||||
'@types/d3-dispatch@3.0.6': {}
|
||||
|
||||
'@types/d3-drag@3.0.7':
|
||||
dependencies:
|
||||
'@types/d3-selection': 3.0.10
|
||||
|
||||
'@types/d3-dsv@3.0.7': {}
|
||||
|
||||
'@types/d3-ease@3.0.2': {}
|
||||
|
||||
'@types/d3-fetch@3.0.7':
|
||||
dependencies:
|
||||
'@types/d3-dsv': 3.0.7
|
||||
|
||||
'@types/d3-force@3.0.10': {}
|
||||
|
||||
'@types/d3-format@3.0.4': {}
|
||||
|
||||
'@types/d3-geo@3.1.0':
|
||||
dependencies:
|
||||
'@types/geojson': 7946.0.14
|
||||
|
||||
'@types/d3-hierarchy@3.1.7': {}
|
||||
|
||||
'@types/d3-interpolate@3.0.4':
|
||||
dependencies:
|
||||
'@types/d3-color': 3.1.3
|
||||
|
||||
'@types/d3-path@3.1.0': {}
|
||||
|
||||
'@types/d3-polygon@3.0.2': {}
|
||||
|
||||
'@types/d3-quadtree@3.0.6': {}
|
||||
|
||||
'@types/d3-random@3.0.3': {}
|
||||
|
||||
'@types/d3-scale-chromatic@3.0.3': {}
|
||||
|
||||
'@types/d3-scale@4.0.8':
|
||||
dependencies:
|
||||
'@types/d3-time': 3.0.3
|
||||
|
||||
'@types/d3-selection@3.0.10': {}
|
||||
|
||||
'@types/d3-shape@3.1.6':
|
||||
dependencies:
|
||||
'@types/d3-path': 3.1.0
|
||||
|
||||
'@types/d3-time-format@4.0.3': {}
|
||||
|
||||
'@types/d3-time@3.0.3': {}
|
||||
|
||||
'@types/d3-timer@3.0.2': {}
|
||||
|
||||
'@types/d3-transition@3.0.8':
|
||||
dependencies:
|
||||
'@types/d3-selection': 3.0.10
|
||||
@ -2987,8 +3255,43 @@ snapshots:
|
||||
'@types/d3-interpolate': 3.0.4
|
||||
'@types/d3-selection': 3.0.10
|
||||
|
||||
'@types/d3@7.4.3':
|
||||
dependencies:
|
||||
'@types/d3-array': 3.2.1
|
||||
'@types/d3-axis': 3.0.6
|
||||
'@types/d3-brush': 3.0.6
|
||||
'@types/d3-chord': 3.0.6
|
||||
'@types/d3-color': 3.1.3
|
||||
'@types/d3-contour': 3.0.6
|
||||
'@types/d3-delaunay': 6.0.4
|
||||
'@types/d3-dispatch': 3.0.6
|
||||
'@types/d3-drag': 3.0.7
|
||||
'@types/d3-dsv': 3.0.7
|
||||
'@types/d3-ease': 3.0.2
|
||||
'@types/d3-fetch': 3.0.7
|
||||
'@types/d3-force': 3.0.10
|
||||
'@types/d3-format': 3.0.4
|
||||
'@types/d3-geo': 3.1.0
|
||||
'@types/d3-hierarchy': 3.1.7
|
||||
'@types/d3-interpolate': 3.0.4
|
||||
'@types/d3-path': 3.1.0
|
||||
'@types/d3-polygon': 3.0.2
|
||||
'@types/d3-quadtree': 3.0.6
|
||||
'@types/d3-random': 3.0.3
|
||||
'@types/d3-scale': 4.0.8
|
||||
'@types/d3-scale-chromatic': 3.0.3
|
||||
'@types/d3-selection': 3.0.10
|
||||
'@types/d3-shape': 3.1.6
|
||||
'@types/d3-time': 3.0.3
|
||||
'@types/d3-time-format': 4.0.3
|
||||
'@types/d3-timer': 3.0.2
|
||||
'@types/d3-transition': 3.0.8
|
||||
'@types/d3-zoom': 3.0.8
|
||||
|
||||
'@types/estree@1.0.5': {}
|
||||
|
||||
'@types/geojson@7946.0.14': {}
|
||||
|
||||
'@types/hast@2.3.10':
|
||||
dependencies:
|
||||
'@types/unist': 2.0.11
|
||||
@ -3348,6 +3651,8 @@ snapshots:
|
||||
|
||||
commander@4.1.1: {}
|
||||
|
||||
commander@7.2.0: {}
|
||||
|
||||
compute-scroll-into-view@3.1.0: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
@ -3380,8 +3685,34 @@ snapshots:
|
||||
|
||||
csstype@3.1.3: {}
|
||||
|
||||
d3-array@3.2.4:
|
||||
dependencies:
|
||||
internmap: 2.0.3
|
||||
|
||||
d3-axis@3.0.0: {}
|
||||
|
||||
d3-brush@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)
|
||||
|
||||
d3-chord@3.0.1:
|
||||
dependencies:
|
||||
d3-path: 3.1.0
|
||||
|
||||
d3-color@3.1.0: {}
|
||||
|
||||
d3-contour@4.0.2:
|
||||
dependencies:
|
||||
d3-array: 3.2.4
|
||||
|
||||
d3-delaunay@6.0.4:
|
||||
dependencies:
|
||||
delaunator: 5.0.1
|
||||
|
||||
d3-dispatch@3.0.1: {}
|
||||
|
||||
d3-drag@3.0.0:
|
||||
@ -3389,14 +3720,71 @@ snapshots:
|
||||
d3-dispatch: 3.0.1
|
||||
d3-selection: 3.0.0
|
||||
|
||||
d3-dsv@3.0.1:
|
||||
dependencies:
|
||||
commander: 7.2.0
|
||||
iconv-lite: 0.6.3
|
||||
rw: 1.3.3
|
||||
|
||||
d3-ease@3.0.1: {}
|
||||
|
||||
d3-fetch@3.0.1:
|
||||
dependencies:
|
||||
d3-dsv: 3.0.1
|
||||
|
||||
d3-force@3.0.0:
|
||||
dependencies:
|
||||
d3-dispatch: 3.0.1
|
||||
d3-quadtree: 3.0.1
|
||||
d3-timer: 3.0.1
|
||||
|
||||
d3-format@3.1.0: {}
|
||||
|
||||
d3-geo@3.1.1:
|
||||
dependencies:
|
||||
d3-array: 3.2.4
|
||||
|
||||
d3-hierarchy@3.1.2: {}
|
||||
|
||||
d3-interpolate@3.0.1:
|
||||
dependencies:
|
||||
d3-color: 3.1.0
|
||||
|
||||
d3-path@3.1.0: {}
|
||||
|
||||
d3-polygon@3.0.1: {}
|
||||
|
||||
d3-quadtree@3.0.1: {}
|
||||
|
||||
d3-random@3.0.1: {}
|
||||
|
||||
d3-scale-chromatic@3.1.0:
|
||||
dependencies:
|
||||
d3-color: 3.1.0
|
||||
d3-interpolate: 3.0.1
|
||||
|
||||
d3-scale@4.0.2:
|
||||
dependencies:
|
||||
d3-array: 3.2.4
|
||||
d3-format: 3.1.0
|
||||
d3-interpolate: 3.0.1
|
||||
d3-time: 3.1.0
|
||||
d3-time-format: 4.1.0
|
||||
|
||||
d3-selection@3.0.0: {}
|
||||
|
||||
d3-shape@3.2.0:
|
||||
dependencies:
|
||||
d3-path: 3.1.0
|
||||
|
||||
d3-time-format@4.1.0:
|
||||
dependencies:
|
||||
d3-time: 3.1.0
|
||||
|
||||
d3-time@3.1.0:
|
||||
dependencies:
|
||||
d3-array: 3.2.4
|
||||
|
||||
d3-timer@3.0.1: {}
|
||||
|
||||
d3-transition@3.0.1(d3-selection@3.0.0):
|
||||
@ -3416,6 +3804,39 @@ snapshots:
|
||||
d3-selection: 3.0.0
|
||||
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||
|
||||
d3@7.9.0:
|
||||
dependencies:
|
||||
d3-array: 3.2.4
|
||||
d3-axis: 3.0.0
|
||||
d3-brush: 3.0.0
|
||||
d3-chord: 3.0.1
|
||||
d3-color: 3.1.0
|
||||
d3-contour: 4.0.2
|
||||
d3-delaunay: 6.0.4
|
||||
d3-dispatch: 3.0.1
|
||||
d3-drag: 3.0.0
|
||||
d3-dsv: 3.0.1
|
||||
d3-ease: 3.0.1
|
||||
d3-fetch: 3.0.1
|
||||
d3-force: 3.0.0
|
||||
d3-format: 3.1.0
|
||||
d3-geo: 3.1.1
|
||||
d3-hierarchy: 3.1.2
|
||||
d3-interpolate: 3.0.1
|
||||
d3-path: 3.1.0
|
||||
d3-polygon: 3.0.1
|
||||
d3-quadtree: 3.0.1
|
||||
d3-random: 3.0.1
|
||||
d3-scale: 4.0.2
|
||||
d3-scale-chromatic: 3.1.0
|
||||
d3-selection: 3.0.0
|
||||
d3-shape: 3.2.0
|
||||
d3-time: 3.1.0
|
||||
d3-time-format: 4.1.0
|
||||
d3-timer: 3.0.1
|
||||
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||
d3-zoom: 3.0.0
|
||||
|
||||
dayjs@1.11.13: {}
|
||||
|
||||
debug@4.3.7:
|
||||
@ -3428,6 +3849,10 @@ snapshots:
|
||||
|
||||
deep-is@0.1.4: {}
|
||||
|
||||
delaunator@5.0.1:
|
||||
dependencies:
|
||||
robust-predicates: 3.0.2
|
||||
|
||||
dequal@2.0.3: {}
|
||||
|
||||
devlop@1.1.0:
|
||||
@ -3729,6 +4154,10 @@ snapshots:
|
||||
|
||||
html-void-elements@3.0.0: {}
|
||||
|
||||
iconv-lite@0.6.3:
|
||||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
|
||||
ignore@5.3.2: {}
|
||||
|
||||
immer@10.1.1: {}
|
||||
@ -3742,6 +4171,8 @@ snapshots:
|
||||
|
||||
inline-style-parser@0.2.4: {}
|
||||
|
||||
internmap@2.0.3: {}
|
||||
|
||||
is-alphabetical@2.0.1: {}
|
||||
|
||||
is-alphanumerical@2.0.1:
|
||||
@ -3848,6 +4279,8 @@ snapshots:
|
||||
dependencies:
|
||||
yallist: 3.1.1
|
||||
|
||||
marked@14.1.2: {}
|
||||
|
||||
mdast-util-to-hast@13.2.0:
|
||||
dependencies:
|
||||
'@types/hast': 3.0.4
|
||||
@ -4460,6 +4893,8 @@ snapshots:
|
||||
|
||||
reusify@1.0.4: {}
|
||||
|
||||
robust-predicates@3.0.2: {}
|
||||
|
||||
rollup@4.22.0:
|
||||
dependencies:
|
||||
'@types/estree': 1.0.5
|
||||
@ -4486,6 +4921,10 @@ snapshots:
|
||||
dependencies:
|
||||
queue-microtask: 1.2.3
|
||||
|
||||
rw@1.3.3: {}
|
||||
|
||||
safer-buffer@2.1.2: {}
|
||||
|
||||
scheduler@0.23.2:
|
||||
dependencies:
|
||||
loose-envify: 1.4.0
|
||||
|
38
src/pages/ai-chat/AiModule.tsx
Normal file
38
src/pages/ai-chat/AiModule.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { useAiStore } from './store/ai-store';
|
||||
import { CloseOutlined } from '@ant-design/icons';
|
||||
import { Button } from 'antd';
|
||||
|
||||
export const AiMoudle = () => {
|
||||
const aiStore = useAiStore(
|
||||
useShallow((state) => {
|
||||
return {
|
||||
open: state.open,
|
||||
setOpen: state.setOpen,
|
||||
runAi: state.runAi,
|
||||
};
|
||||
}),
|
||||
);
|
||||
if (!aiStore.open) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<div className='w-96 flex-shrink-0 bg-gray-100 border-l-2 shadow-lg flex flex-col'>
|
||||
<div className='flex gap-4 bg-slate-400 p-2'>
|
||||
<Button className='position ml-4 !bg-slate-400 !border-black' onClick={() => aiStore.setOpen(false)} icon={<CloseOutlined />}></Button>
|
||||
<h1 className='ml-10'>Ai Moudle</h1>
|
||||
</div>
|
||||
<div className='flex-grow p-2'>
|
||||
<div> chat message</div>
|
||||
<div>
|
||||
<Button
|
||||
onClick={() => {
|
||||
aiStore.runAi();
|
||||
}}>
|
||||
Send
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
7
src/pages/ai-chat/index.tsx
Normal file
7
src/pages/ai-chat/index.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import { AiMoudle } from './AiModule';
|
||||
import { useAiStore } from './store/ai-store';
|
||||
export { AiMoudle, useAiStore };
|
||||
|
||||
export const App = () => {
|
||||
return <div>AI Chat</div>;
|
||||
};
|
58
src/pages/ai-chat/store/ai-store.ts
Normal file
58
src/pages/ai-chat/store/ai-store.ts
Normal file
@ -0,0 +1,58 @@
|
||||
import { query } from '@/modules';
|
||||
import { message } from 'antd';
|
||||
import { create } from 'zustand';
|
||||
|
||||
export type AiStore = {
|
||||
open: boolean;
|
||||
setOpen: (open: boolean) => void;
|
||||
type?: string;
|
||||
key: string;
|
||||
setKey: (key: string) => void;
|
||||
setType?: (type: string) => void;
|
||||
sendMsg: (msg: string) => void;
|
||||
formData: any;
|
||||
setFormData: (data: any) => void;
|
||||
runAi: () => any;
|
||||
title: string;
|
||||
setTitle: (title: string) => void;
|
||||
};
|
||||
|
||||
export const useAiStore = create<AiStore>((set, get) => {
|
||||
return {
|
||||
open: false,
|
||||
setOpen: (open) => set({ open }),
|
||||
key: '',
|
||||
setKey: (key) => set({ key }),
|
||||
sendMsg: (msg) => {
|
||||
console.log(msg);
|
||||
},
|
||||
formData: {},
|
||||
setFormData: (data) => set({ formData: data }),
|
||||
runAi: async () => {
|
||||
const { formData } = get();
|
||||
const res = await query.post({
|
||||
path: 'ai',
|
||||
key: 'run',
|
||||
data: {
|
||||
key: formData.key,
|
||||
inputs: [
|
||||
{
|
||||
key: 'title',
|
||||
value: '根据描述生成代码',
|
||||
},
|
||||
{
|
||||
key: 'description',
|
||||
value: '我想获取一个card, 包含标题和内容,标题是evision,内容是这是一个测试',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
if (res.code === 200) {
|
||||
console.log(res.data);
|
||||
message.success('Success');
|
||||
}
|
||||
},
|
||||
title: '',
|
||||
setTitle: (title) => set({ title }),
|
||||
};
|
||||
});
|
@ -11,6 +11,8 @@ type Props = {
|
||||
style?: React.CSSProperties;
|
||||
language?: string;
|
||||
listen?: boolean;
|
||||
placeholder?: string;
|
||||
onBlur?: () => void;
|
||||
};
|
||||
export const TextArea = (props: Props) => {
|
||||
const [code, setCode] = useState<string>('');
|
||||
@ -27,12 +29,13 @@ export const TextArea = (props: Props) => {
|
||||
<div className={clsx('min-h-16 max-h-52 overflow-scroll scrollbar p-1 ', props.className)}>
|
||||
<CodeEditor
|
||||
value={code}
|
||||
language='js'
|
||||
language={props.language || 'js'}
|
||||
className='border rounded-sm '
|
||||
readOnly={props.readonly}
|
||||
placeholder='Please enter JS code.'
|
||||
placeholder={props.placeholder || 'Please enter JS code.'}
|
||||
onChange={(evn) => _onChange(evn.target.value)}
|
||||
padding={10}
|
||||
onBlur={props.onBlur}
|
||||
style={{
|
||||
// backgroundColor: '#f5f5f5',
|
||||
fontFamily: 'ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace',
|
||||
|
@ -59,12 +59,7 @@ const FormModal = () => {
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='code' label='code'>
|
||||
<TextArea
|
||||
value={containerStore.formData.code}
|
||||
style={{
|
||||
height: '200px',
|
||||
}}
|
||||
/>
|
||||
<TextArea />
|
||||
</Form.Item>
|
||||
<Form.Item label=' ' colon={false}>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
|
41
src/pages/prompt/D3.tsx
Normal file
41
src/pages/prompt/D3.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { query } from '@/modules';
|
||||
import { useEffect } from 'react';
|
||||
import { drawGraph } from './graph/d3';
|
||||
export const D3Grahp = () => {
|
||||
const get = async () => {
|
||||
const res = await query.post({
|
||||
path: 'prompt',
|
||||
key: 'list',
|
||||
});
|
||||
console.log(res);
|
||||
const grahpData = {
|
||||
nodes: res.data.map((item) => {
|
||||
return {
|
||||
id: item.id,
|
||||
label: item.title,
|
||||
type: 'prompt',
|
||||
};
|
||||
}),
|
||||
links: [],
|
||||
};
|
||||
drawGraph(grahpData);
|
||||
};
|
||||
const getD3 = async () => {
|
||||
const res = await query.post({
|
||||
path: 'prompt',
|
||||
key: 'getD3',
|
||||
});
|
||||
drawGraph(res.data);
|
||||
};
|
||||
useEffect(() => {
|
||||
getD3();
|
||||
return () => {
|
||||
document.querySelector('.ai-graph')!.innerHTML = '';
|
||||
};
|
||||
}, []);
|
||||
return (
|
||||
<div className='w-full h-full'>
|
||||
<svg className='ai-graph border shadow-sm p-2 mx-auto mt-10 ' width='960' height='600' ></svg>
|
||||
</div>
|
||||
);
|
||||
};
|
57
src/pages/prompt/edit/Edit.tsx
Normal file
57
src/pages/prompt/edit/Edit.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import { Button, Form, Input } from 'antd';
|
||||
import { TextArea } from '../../container/components/TextArea';
|
||||
import clsx from 'clsx';
|
||||
|
||||
export const Edit = () => {
|
||||
const [form] = Form.useForm();
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
const onSave = () => {
|
||||
//
|
||||
};
|
||||
const isEdit = form.getFieldValue('id');
|
||||
return (
|
||||
<div className='w-full h-full felx flex-col bg-gray-200'>
|
||||
<h1 className='text-center py-4'>Prompt JS Code Generate</h1>
|
||||
<div className='py-2 px-4 w-3/4 min-w-[600px] mx-auto border shadow rounded bg-white'>
|
||||
<Form form={form} onFinish={onFinish} className='mt-4' labelCol={{ span: 4 }}>
|
||||
<Form.Item name='id' hidden>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='title' label='Title'>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='description' label='Description'>
|
||||
<Input.TextArea rows={4} />
|
||||
</Form.Item>
|
||||
<Form.Item name='code' label='Code'>
|
||||
<TextArea className='max-h-full' style={{ minHeight: 300 }} />
|
||||
</Form.Item>
|
||||
<Form.Item label=' ' colon={false}>
|
||||
<div className='flex gap-2'>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
Generate
|
||||
</Button>
|
||||
<Button htmlType='reset'>Reset</Button>
|
||||
<Button
|
||||
type='primary'
|
||||
onClick={() => {
|
||||
//
|
||||
}}>
|
||||
Save
|
||||
</Button>
|
||||
<Button
|
||||
className={clsx(isEdit ? 'block' : 'hidden')}
|
||||
onClick={() => {
|
||||
//
|
||||
}}>
|
||||
Preview
|
||||
</Button>
|
||||
</div>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
342
src/pages/prompt/edit/List.tsx
Normal file
342
src/pages/prompt/edit/List.tsx
Normal file
@ -0,0 +1,342 @@
|
||||
import { Button, Input, message, Modal, Table } from 'antd';
|
||||
import { Fragment, useEffect, useMemo, useState } from 'react';
|
||||
import { usePromptStore } from '../store/prompt';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
import { Form } from 'antd';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import { useNavigate } from 'react-router';
|
||||
import { EditOutlined, SettingOutlined, LinkOutlined, SaveOutlined, DeleteOutlined, LeftOutlined, CaretRightOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import clsx from 'clsx';
|
||||
import { TextArea } from '@/pages/container/components/TextArea';
|
||||
|
||||
import { marked } from 'marked';
|
||||
import { extractKeysFromBraces } from '@/utils/extra';
|
||||
import { useAiStore } from '@/pages/ai-chat';
|
||||
|
||||
const FormModal = () => {
|
||||
const [form] = Form.useForm();
|
||||
const promptStore = usePromptStore(
|
||||
useShallow((state) => {
|
||||
return {
|
||||
showEdit: state.showEdit,
|
||||
setShowEdit: state.setShowEdit,
|
||||
formData: state.formData,
|
||||
updateData: state.updateData,
|
||||
runAi: state.runAi,
|
||||
};
|
||||
}),
|
||||
);
|
||||
useEffect(() => {
|
||||
const open = promptStore.showEdit;
|
||||
if (open) {
|
||||
const isNull = JSON.stringify(promptStore.formData) === '{}';
|
||||
if (isNull) {
|
||||
form.resetFields();
|
||||
} else {
|
||||
form.setFieldsValue(promptStore.formData || {});
|
||||
}
|
||||
}
|
||||
}, [promptStore.showEdit]);
|
||||
const onFinish = async (values: any) => {
|
||||
let other = {};
|
||||
if (!values.id) {
|
||||
other = {
|
||||
presetData: {
|
||||
validator: {},
|
||||
data: {
|
||||
prompt: '',
|
||||
inputs: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
promptStore.updateData({
|
||||
...values,
|
||||
...other,
|
||||
});
|
||||
};
|
||||
const onClose = () => {
|
||||
promptStore.setShowEdit(false);
|
||||
form.resetFields();
|
||||
};
|
||||
const isEdit = promptStore.formData.id;
|
||||
return (
|
||||
<Modal
|
||||
title={isEdit ? 'Edit' : 'Add'}
|
||||
open={promptStore.showEdit}
|
||||
onClose={() => promptStore.setShowEdit(false)}
|
||||
destroyOnClose
|
||||
footer={false}
|
||||
width={800}
|
||||
onCancel={onClose}>
|
||||
<Form
|
||||
form={form}
|
||||
onFinish={onFinish}
|
||||
labelCol={{
|
||||
span: 4,
|
||||
}}
|
||||
wrapperCol={{
|
||||
span: 20,
|
||||
}}>
|
||||
<Form.Item name='id' hidden>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='title' label='title'>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='description' label='description'>
|
||||
<Input.TextArea rows={4} />
|
||||
</Form.Item>
|
||||
<Form.Item name='key' label='key'>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label=' ' colon={false}>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
Submit
|
||||
</Button>
|
||||
<Button className='ml-2' htmlType='reset' onClick={onClose}>
|
||||
Cancel
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
export const List = () => {
|
||||
const navicate = useNavigate();
|
||||
const aiStore = useAiStore(
|
||||
useShallow((state) => {
|
||||
return {
|
||||
open: state.open,
|
||||
setOpen: state.setOpen,
|
||||
key: state.key,
|
||||
setKey: state.setKey,
|
||||
sendMsg: state.sendMsg,
|
||||
};
|
||||
}),
|
||||
);
|
||||
const promptStore = usePromptStore(
|
||||
useShallow((state) => {
|
||||
return {
|
||||
setFormData: state.setFormData,
|
||||
setShowEdit: state.setShowEdit,
|
||||
list: state.list,
|
||||
deleteData: state.deleteData,
|
||||
getList: state.getList,
|
||||
loading: state.loading,
|
||||
updateData: state.updateData,
|
||||
formData: state.formData,
|
||||
runAi: state.runAi,
|
||||
};
|
||||
}),
|
||||
);
|
||||
const [codeEdit, setCodeEdit] = useState(false);
|
||||
const [code, setCode] = useState('');
|
||||
const [form] = Form.useForm<{ inputs: any[] }>();
|
||||
useEffect(() => {
|
||||
promptStore.getList();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (!codeEdit) {
|
||||
form.setFieldsValue({ inputs: [] });
|
||||
}
|
||||
}, [codeEdit]);
|
||||
const onAdd = () => {
|
||||
promptStore.setFormData({});
|
||||
promptStore.setShowEdit(true);
|
||||
setCodeEdit(false);
|
||||
};
|
||||
const getFormInputs = () => {
|
||||
if (!codeEdit) return;
|
||||
console.log('blur getFormInputs');
|
||||
|
||||
const keys = extractKeysFromBraces(code);
|
||||
const inputs = form.getFieldValue('inputs') || [];
|
||||
const newInputs = keys
|
||||
.map((key) => {
|
||||
const has = inputs.some((item: any) => item.key === key);
|
||||
if (!has) {
|
||||
return {
|
||||
key,
|
||||
value: '',
|
||||
};
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(Boolean);
|
||||
if (newInputs.length > 0) {
|
||||
form.setFieldsValue({ inputs: [...inputs, ...newInputs] });
|
||||
}
|
||||
};
|
||||
const len = form.getFieldValue('inputs')?.length || 0;
|
||||
return (
|
||||
<div className='w-full h-full flex flex-col'>
|
||||
<div className='flex flex-grow overflow-hidden h-full'>
|
||||
<Button onClick={onAdd} type='primary' className='m-4 w-64 flex-shrink-0' icon={<PlusOutlined />}></Button>
|
||||
<div className='flex-grow overflow-auto scrollbar bg-gray-100'>
|
||||
<div className='flex flex-wrap gap-x-10 gap-y-4 rounded pt-10 justify-center'>
|
||||
{promptStore.list.length > 0 &&
|
||||
promptStore.list.map((item) => {
|
||||
const { presetData } = item;
|
||||
const md = presetData?.data?.prompt || '';
|
||||
const inputs = presetData?.data?.inputs || [];
|
||||
const html = marked.parse(md);
|
||||
return (
|
||||
<Fragment key={item.id}>
|
||||
<div className='flex text-sm gap flex-col w-[600px] max-h-[400px] bg-white p-4 rounded-lg' key={item.id} onClick={() => {}}>
|
||||
<div
|
||||
className='px-4 cursor-pointer'
|
||||
onClick={() => {
|
||||
setCode(md);
|
||||
promptStore.setFormData(item);
|
||||
form.setFieldsValue({
|
||||
inputs: inputs.map((item) => {
|
||||
return { key: item.key, value: item.value };
|
||||
}),
|
||||
});
|
||||
setCodeEdit(true);
|
||||
}}>
|
||||
<div
|
||||
className='font-bold flex'
|
||||
onClick={(e) => {
|
||||
// copy(item.code);
|
||||
// e.stopPropagation();
|
||||
// message.success('copy code success');
|
||||
}}>
|
||||
{item.title || '-'}
|
||||
<div
|
||||
className=' ml-3 text-xs text-gray-400'
|
||||
style={{
|
||||
fontFamily: 'D-DIN',
|
||||
}}>
|
||||
{item?.key ? item.key : '-'}
|
||||
</div>
|
||||
</div>
|
||||
<div className='font-light mt-2'>{item.description ? item.description : '-'}</div>
|
||||
</div>
|
||||
{/* <div className='w-full text-xs'>
|
||||
<TextArea className='max-h-[240px] scrollbar' value={item.code} readonly />
|
||||
</div> */}
|
||||
<div className='px-4 mt-2'>{md ? 'Prompt' : ''}</div>
|
||||
<div className='px-4'>
|
||||
<div className='max-h-52 overflow-scroll scrollbar p-4 border shadow-sm mt-1'>
|
||||
<div dangerouslySetInnerHTML={{ __html: html }}></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex mt-4 ml-4'>
|
||||
<Button.Group>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
promptStore.setFormData(item);
|
||||
promptStore.setShowEdit(true);
|
||||
setCodeEdit(false);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
icon={<EditOutlined />}></Button>
|
||||
<Button
|
||||
onClick={(e) => {
|
||||
promptStore.deleteData(item.id);
|
||||
e.stopPropagation();
|
||||
}}
|
||||
icon={<DeleteOutlined />}></Button>
|
||||
<Button
|
||||
icon={<CaretRightOutlined />}
|
||||
onClick={() => {
|
||||
// navicate(`/prompt/${item.id}`);
|
||||
promptStore.setFormData(item);
|
||||
// promptStore.runAi();
|
||||
aiStore.setOpen(true);
|
||||
}}
|
||||
/>
|
||||
</Button.Group>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
})}
|
||||
{new Array(4).fill(0).map((_, index) => {
|
||||
return <div key={index} className='w-[600px]'></div>;
|
||||
})}
|
||||
{promptStore.list.length == 0 && (
|
||||
<div className='text-center' key={'no-data'}>
|
||||
No Data
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={clsx('bg-gray-100 border-l flex flex-col border-bg-slate-300 w-[600px] flex-shrink-0', !codeEdit && 'hidden')}>
|
||||
<div className='bg-white p-2'>
|
||||
<div className='mt-2 ml-2 flex gap-2'>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setCodeEdit(false);
|
||||
promptStore.setFormData({});
|
||||
}}
|
||||
icon={<LeftOutlined />}></Button>
|
||||
<Button
|
||||
onClick={() => {
|
||||
// console.log('save', promptStore.formData);
|
||||
const { presetData } = promptStore.formData;
|
||||
const inputs = form.getFieldValue('inputs') || [];
|
||||
promptStore.updateData({ ...promptStore.formData, presetData: { ...presetData, data: { ...presetData.data, prompt: code, inputs } } });
|
||||
}}
|
||||
icon={<SaveOutlined />}></Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex-grow p-2 rounded-2 shadow-sm overflow-hidden'>
|
||||
<TextArea
|
||||
value={code}
|
||||
language='markdown'
|
||||
placeholder='Please enter markdown code.'
|
||||
onChange={(value) => {
|
||||
setCode(value);
|
||||
}}
|
||||
onBlur={() => {
|
||||
console.log('blur');
|
||||
setTimeout(() => {
|
||||
getFormInputs();
|
||||
}, 400);
|
||||
}}
|
||||
className='h-full max-h-full scrollbar'
|
||||
style={{
|
||||
overflow: 'auto',
|
||||
minHeight: '200px',
|
||||
// height: '100%', // height: '100%' 有bug
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='flex-shrink-0 px-4 mt-4'>
|
||||
<h1 className={clsx('mb-2', len === 0 && 'hidden')}>Match Keys</h1>
|
||||
<Form form={form}>
|
||||
<Form.List name='inputs'>
|
||||
{(fields, { add, remove }) => {
|
||||
return (
|
||||
<>
|
||||
{fields.map((field, index) => {
|
||||
return (
|
||||
<div key={field.name + '-' + index} className='flex gap-2'>
|
||||
<Form.Item name={[field.name, 'key']} rules={[{ required: true, message: 'Missing name' }]}>
|
||||
<Input placeholder='name' />
|
||||
</Form.Item>
|
||||
<Form.Item name={[field.name, 'value']} rules={[{ required: true, message: 'Missing value' }]}>
|
||||
<Input placeholder='value' />
|
||||
</Form.Item>
|
||||
{/* <Button onClick={() => add()} className='flex items-center'>
|
||||
+
|
||||
</Button> */}
|
||||
<Button onClick={() => remove(field.name)}>-</Button>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}}
|
||||
</Form.List>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<FormModal />
|
||||
</div>
|
||||
);
|
||||
};
|
18
src/pages/prompt/graph/d3.css
Normal file
18
src/pages/prompt/graph/d3.css
Normal file
@ -0,0 +1,18 @@
|
||||
.node circle {
|
||||
fill: #69b3a2;
|
||||
stroke: #333;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
.link {
|
||||
fill: none;
|
||||
stroke: #999;
|
||||
stroke-opacity: 0.6;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
text {
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 12px;
|
||||
pointer-events: none;
|
||||
}
|
122
src/pages/prompt/graph/d3.ts
Normal file
122
src/pages/prompt/graph/d3.ts
Normal file
@ -0,0 +1,122 @@
|
||||
// @ts-nocheck
|
||||
import * as d3 from 'd3';
|
||||
import './d3.css';
|
||||
|
||||
export const drawGraph = (graphData) => {
|
||||
// 初始配置:宽度和高度通过容器自适应
|
||||
const svg = d3.select('.ai-graph');
|
||||
|
||||
const margin = { top: 20, right: 20, bottom: 20, left: 20 };
|
||||
|
||||
const updateChartSize = () => {
|
||||
const width = svg.node().clientWidth - margin.left - margin.right;
|
||||
const height = svg.node().clientHeight - margin.top - margin.bottom;
|
||||
|
||||
svg.attr('viewBox', `0 0 ${width} ${height}`);
|
||||
|
||||
return { width, height };
|
||||
};
|
||||
|
||||
let { width, height } = updateChartSize();
|
||||
|
||||
// 使用力导向布局
|
||||
const simulation = d3
|
||||
.forceSimulation(graphData.nodes)
|
||||
.force(
|
||||
'link',
|
||||
d3
|
||||
.forceLink(graphData.links)
|
||||
.id((d) => d.id)
|
||||
.distance(100)
|
||||
)
|
||||
.force('charge', d3.forceManyBody().strength(-300))
|
||||
.force('center', d3.forceCenter(width / 2, height / 2))
|
||||
.force('collide', d3.forceCollide(20)); // 防止节点重叠,半径设置为20
|
||||
|
||||
// 绘制连线
|
||||
const link = svg.append('g')
|
||||
.selectAll('line')
|
||||
.data(graphData.links)
|
||||
.enter()
|
||||
.append('line')
|
||||
.attr('class', 'link');
|
||||
|
||||
// 绘制节点
|
||||
const node = svg.append('g')
|
||||
.selectAll('g')
|
||||
.data(graphData.nodes)
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', 'node');
|
||||
|
||||
node.append('circle').attr('r', 10);
|
||||
|
||||
// 添加节点标签
|
||||
node
|
||||
.append('text')
|
||||
.attr('dx', 12)
|
||||
.attr('dy', '.35em')
|
||||
.text((d) => d.label);
|
||||
|
||||
// 限制节点在SVG范围内
|
||||
const clampPosition = (d, width, height) => {
|
||||
d.x = Math.max(10, Math.min(width - 10, d.x)); // 10为节点半径
|
||||
d.y = Math.max(10, Math.min(height - 10, d.y));
|
||||
};
|
||||
|
||||
// 更新节点和连线位置
|
||||
simulation.on('tick', () => {
|
||||
link
|
||||
.attr('x1', (d) => d.source.x)
|
||||
.attr('y1', (d) => d.source.y)
|
||||
.attr('x2', (d) => d.target.x)
|
||||
.attr('y2', (d) => d.target.y);
|
||||
|
||||
node.attr('transform', (d) => {
|
||||
// 限制节点在SVG内部
|
||||
clampPosition(d, width, height);
|
||||
return `translate(${d.x},${d.y})`;
|
||||
});
|
||||
});
|
||||
|
||||
// 添加拖拽事件
|
||||
node.call(
|
||||
d3
|
||||
.drag()
|
||||
.on('start', (event, d) => {
|
||||
if (!event.active) simulation.alphaTarget(0.3).restart();
|
||||
d.fx = d.x;
|
||||
d.fy = d.y;
|
||||
})
|
||||
.on('drag', (event, d) => {
|
||||
d.fx = event.x;
|
||||
d.fy = event.y;
|
||||
})
|
||||
.on('end', (event, d) => {
|
||||
if (!event.active) simulation.alphaTarget(0);
|
||||
d.fx = null;
|
||||
d.fy = null;
|
||||
})
|
||||
);
|
||||
|
||||
// 添加双击事件
|
||||
node.on('dblclick', (event, d) => {
|
||||
d.fx = null;
|
||||
d.fy = null;
|
||||
console.log('dblclick', d);
|
||||
});
|
||||
|
||||
// 监听窗口大小变化时更新图表
|
||||
const resize = () => {
|
||||
const { width, height } = updateChartSize();
|
||||
simulation.force('center', d3.forceCenter(width / 2, height / 2));
|
||||
simulation.alpha(1).restart(); // 重启仿真以更新布局
|
||||
};
|
||||
|
||||
window.addEventListener('resize', resize);
|
||||
|
||||
// 在需要的时候手动调用,销毁图表时可以移除监听
|
||||
return () => {
|
||||
window.removeEventListener('resize', resize);
|
||||
};
|
||||
};
|
@ -1,57 +1,18 @@
|
||||
import { Button, Form, Input } from 'antd';
|
||||
import { TextArea } from '../container/components/TextArea';
|
||||
import clsx from 'clsx';
|
||||
import { Routes, Route, Navigate } from 'react-router-dom';
|
||||
import { Edit } from './edit/Edit';
|
||||
import { List } from './edit/List';
|
||||
import { D3Grahp } from './D3';
|
||||
import { Main } from './layout/Main';
|
||||
|
||||
export const App = () => {
|
||||
const [form] = Form.useForm();
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
const onSave = () => {
|
||||
//
|
||||
};
|
||||
const isEdit = form.getFieldValue('id');
|
||||
return (
|
||||
<div className='w-full h-full felx flex-col bg-gray-200'>
|
||||
<h1 className='text-center py-4'>Prompt JS Code Generate</h1>
|
||||
<div className='py-2 px-4 w-3/4 min-w-[600px] mx-auto border shadow rounded bg-white'>
|
||||
<Form form={form} onFinish={onFinish} className='mt-4' labelCol={{ span: 4 }}>
|
||||
<Form.Item name='id' hidden>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='title' label='Title'>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name='description' label='Description'>
|
||||
<Input.TextArea rows={4} />
|
||||
</Form.Item>
|
||||
<Form.Item name='code' label='Code'>
|
||||
<TextArea className='max-h-full' style={{ minHeight: 300 }} />
|
||||
</Form.Item>
|
||||
<Form.Item label=' ' colon={false}>
|
||||
<div className='flex gap-2'>
|
||||
<Button type='primary' htmlType='submit'>
|
||||
Generate
|
||||
</Button>
|
||||
<Button htmlType='reset'>Reset</Button>
|
||||
<Button
|
||||
type='primary'
|
||||
onClick={() => {
|
||||
//
|
||||
}}>
|
||||
Save
|
||||
</Button>
|
||||
<Button
|
||||
className={clsx(isEdit ? 'block' : 'hidden')}
|
||||
onClick={() => {
|
||||
//
|
||||
}}>
|
||||
Preview
|
||||
</Button>
|
||||
</div>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>
|
||||
</div>
|
||||
<Routes>
|
||||
<Route element={<Main />}>
|
||||
<Route path='/' element={<Navigate to='/prompt/list' />} />
|
||||
<Route path='/graph' element={<D3Grahp />} />
|
||||
<Route path='/edit' element={<Edit />} />
|
||||
<Route path='/list' element={<List />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
);
|
||||
};
|
||||
|
13
src/pages/prompt/layout/Main.tsx
Normal file
13
src/pages/prompt/layout/Main.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { AiMoudle } from '@/pages/ai-chat';
|
||||
import { Outlet } from 'react-router';
|
||||
|
||||
export const Main = () => {
|
||||
return (
|
||||
<div className='w-full h-full flex'>
|
||||
<div className='flex-grow h-full'>
|
||||
<Outlet />
|
||||
</div>
|
||||
<AiMoudle />
|
||||
</div>
|
||||
);
|
||||
};
|
97
src/pages/prompt/store/prompt.ts
Normal file
97
src/pages/prompt/store/prompt.ts
Normal file
@ -0,0 +1,97 @@
|
||||
import { create } from 'zustand';
|
||||
import { query } from '@/modules';
|
||||
import { message } from 'antd';
|
||||
type PromptStore = {
|
||||
showEdit: boolean;
|
||||
setShowEdit: (showEdit: boolean) => void;
|
||||
formData: any;
|
||||
setFormData: (formData: any) => void;
|
||||
loading: boolean;
|
||||
setLoading: (loading: boolean) => void;
|
||||
list: any[];
|
||||
getList: () => Promise<void>;
|
||||
updateData: (data: any) => Promise<void>;
|
||||
deleteData: (id: string) => Promise<void>;
|
||||
runAi: () => any;
|
||||
};
|
||||
export const usePromptStore = create<PromptStore>((set, get) => {
|
||||
return {
|
||||
showEdit: false,
|
||||
setShowEdit: (showEdit) => set({ showEdit }),
|
||||
formData: {},
|
||||
setFormData: (formData) => set({ formData }),
|
||||
loading: false,
|
||||
setLoading: (loading) => set({ loading }),
|
||||
list: [],
|
||||
getList: async () => {
|
||||
set({ loading: true });
|
||||
const res = await query.post({
|
||||
path: 'prompt',
|
||||
key: 'list',
|
||||
});
|
||||
set({ loading: false });
|
||||
if (res.code === 200) {
|
||||
set({ list: res.data });
|
||||
} else {
|
||||
message.error(res.msg || 'Request failed');
|
||||
}
|
||||
},
|
||||
updateData: async (data) => {
|
||||
const { getList } = get();
|
||||
const res = await query.post({
|
||||
path: 'prompt',
|
||||
key: 'update',
|
||||
data,
|
||||
});
|
||||
if (res.code === 200) {
|
||||
message.success('Success');
|
||||
set({ showEdit: false, formData: [] });
|
||||
getList();
|
||||
} else {
|
||||
message.error(res.msg || 'Request failed');
|
||||
}
|
||||
},
|
||||
deleteData: async (id) => {
|
||||
const { getList } = get();
|
||||
const res = await query.post({
|
||||
path: 'prompt',
|
||||
key: 'delete',
|
||||
id,
|
||||
});
|
||||
if (res.code === 200) {
|
||||
getList();
|
||||
message.success('Success');
|
||||
} else {
|
||||
message.error(res.msg || 'Request failed');
|
||||
}
|
||||
},
|
||||
runAi: async () => {
|
||||
const { formData } = get();
|
||||
const res = await query.post({
|
||||
path: 'ai',
|
||||
key: 'run',
|
||||
data: {
|
||||
key: formData.key,
|
||||
inputs: [
|
||||
{
|
||||
key: 'title',
|
||||
value: '根据描述生成代码',
|
||||
},
|
||||
{
|
||||
key: 'description',
|
||||
value: '我想获取一个card, 包含标题和内容,标题是evision,内容是这是一个测试',
|
||||
},
|
||||
],
|
||||
data: {
|
||||
title: formData.title,
|
||||
description: formData.description,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (res.code === 200) {
|
||||
console.log(res.data);
|
||||
message.success('Success');
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
11
src/utils/extra.ts
Normal file
11
src/utils/extra.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export function extractKeysFromBraces(text: string) {
|
||||
const regex = /\{\{\s*(.*?)\s*\}\}/g;
|
||||
const keys: string[] = [];
|
||||
let matches: RegExpExecArray | null;
|
||||
|
||||
while ((matches = regex.exec(text)) !== null) {
|
||||
keys.push(matches[1]); // 获取{{}}中间的key
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user