| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- import { useEffect, useState } from "react";
- import { Button, Dropdown, Space } from "antd";
- import type { MenuProps } from "antd";
- import type { IArticleListResponse } from "../../api/Article";
- import { get } from "../../request";
- import { useAppSelector } from "../../hooks";
- import { currentUser } from "../../reducers/current-user";
- // 接口定义
- export interface IPromptNode {
- text: string;
- prompt?: string;
- children?: IPromptNode[];
- }
- // Markdown 解析函数
- export function parseMarkdownToPromptNodes(markdown: string): IPromptNode[] {
- const lines = markdown
- .split("\n")
- .map((l) => l.trim())
- .filter(Boolean);
- const result: IPromptNode[] = [];
- let currentButton: IPromptNode | null = null;
- let currentChild: { title: string; content: string[] } | null = null;
- for (const line of lines) {
- if (line.startsWith("# ")) {
- if (currentButton) {
- if (currentChild) {
- currentButton.children = currentButton.children || [];
- currentButton.children.push({
- text: currentChild.title,
- prompt: currentChild.content.join("\n"),
- });
- }
- result.push(currentButton);
- }
- currentButton = { text: line.replace("# ", ""), children: [] };
- currentChild = null;
- } else if (line.startsWith("## ")) {
- if (currentChild) {
- currentButton!.children!.push({
- text: currentChild.title,
- prompt: currentChild.content.join("\n"),
- });
- }
- currentChild = {
- title: line.replace("## ", ""),
- content: [],
- };
- } else {
- currentChild?.content.push(line);
- }
- }
- if (currentChild) {
- currentButton!.children!.push({
- text: currentChild.title,
- prompt: currentChild.content.join("\n"),
- });
- }
- if (currentButton) {
- // 若没有children但有currentChild.prompt,作为主按钮 prompt
- if (!currentButton.children?.length && currentChild?.content.length) {
- currentButton.prompt = currentChild.content.join("\n");
- delete currentButton.children;
- }
- result.push(currentButton);
- }
- return result;
- }
- interface IWidget {
- onText?: (prompt: string) => void;
- disabled?: boolean;
- }
- // 按钮组组件
- const PromptButtonGroup = ({ disabled = false, onText }: IWidget) => {
- const user = useAppSelector(currentUser);
- const [data, setData] = useState<IPromptNode[]>([]);
- useEffect(() => {
- if (!user) {
- return;
- }
- const getPromptOne = async (studio: string) => {
- const urlTpl = `/v2/article?view=template&studio_name=${studio}&subtitle=_template_prompt_&content=true`;
- const json = await get<IArticleListResponse>(urlTpl);
- if (json.ok) {
- if (json.data.rows.length > 0) {
- if (json.data.rows[0].content) {
- return json.data.rows[0].content;
- }
- }
- }
- return false;
- };
- const getPrompt = async () => {
- const my = await getPromptOne(user.realName);
- if (my) {
- setData(parseMarkdownToPromptNodes(my));
- return;
- }
- const system = await getPromptOne("admin");
- if (system) {
- setData(parseMarkdownToPromptNodes(system));
- }
- };
- getPrompt().catch((e) => console.error(e));
- }, [user, user?.realName]);
- return (
- <Space>
- {data.map((node) => {
- if (node.children && node.children.length > 0) {
- const items: MenuProps["items"] = node.children.map((child, idx) => ({
- key: `${node.text}-${idx}`,
- label: child.text,
- onClick: () => onText && onText(child.prompt || ""),
- }));
- return (
- <Dropdown key={node.text} menu={{ items }} trigger={["click"]}>
- <Button type="link" size="small" disabled={disabled}>
- {node.text}
- </Button>
- </Dropdown>
- );
- } else {
- return (
- <Button
- key={node.text}
- disabled={disabled}
- onClick={() => onText && onText(node.prompt || "")}
- >
- {node.text}
- </Button>
- );
- }
- })}
- </Space>
- );
- };
- export default PromptButtonGroup;
|