调整AI
This commit is contained in:
parent
5099637414
commit
4058877acd
@ -1,10 +1,12 @@
|
||||
import {useContext, useEffect, useRef, useState} from "react";
|
||||
import {GlobalContext} from "../../context/GlobalContext.ts";
|
||||
import {put, WebSocketBaseUrl} from "../../util/AjaxUtils.ts";
|
||||
import {Button, Col, Divider, Empty, Row, Space, Spin, Table, TableProps} from "antd";
|
||||
import {CheckOutlined, EditOutlined, ReloadOutlined} from "@ant-design/icons";
|
||||
import {get, post, put, WebSocketBaseUrl} from "../../util/AjaxUtils.ts";
|
||||
import {Col, Divider, Row, Spin} from "antd";
|
||||
import useMessage from "antd/es/message/useMessage";
|
||||
import TextArea from "antd/es/input/TextArea";
|
||||
import AiHelperText from "./text/AiHelperText.tsx";
|
||||
import AiHelperMod from "./mod/AiHelperMod.tsx";
|
||||
import {IProjMod} from "../../interfaces/proj/IProj.ts";
|
||||
import {MAX_MOD_SIZE} from "../../route/proj/edit/ProjConfigModList.tsx";
|
||||
|
||||
type PropsType = {
|
||||
projId: string;
|
||||
@ -14,6 +16,7 @@ type PropsType = {
|
||||
}
|
||||
|
||||
type ProjModType = {
|
||||
id: string,
|
||||
name: string,
|
||||
desc: string
|
||||
}
|
||||
@ -25,20 +28,17 @@ export default function AiHelper(props: PropsType) {
|
||||
const [messageApi, messageApiHolder] = useMessage();
|
||||
const [projIntroduction, setProjIntroduction] = useState<string>(props.projIntroduction ? props.projIntroduction : '');
|
||||
const [newProjIntroduction, setNewProjIntroduction] = useState<string>('');
|
||||
const [isProjIntroductionEdit, setIsProjIntroductionEdit] = useState<boolean>(false);
|
||||
const [isNewProjIntroductionEdit, setIsNewProjIntroductionEdit] = useState<boolean>(false);
|
||||
const [isProjIntroductionLoading, setIsProjIntroductionLoading] = useState(false);
|
||||
|
||||
const [projDesc, setProjDesc] = useState<string>(props.projDesc ? props.projDesc : '');
|
||||
const [newProjDesc, setNewProjDesc] = useState<string>('');
|
||||
const [isProjDescEdit, setIsProjDescEdit] = useState<boolean>(false);
|
||||
const [isNewProjDescEdit, setIsNewProjDescEdit] = useState<boolean>(false);
|
||||
const [isProjDescLoading, setIsProjDescLoading] = useState(false);
|
||||
|
||||
const [projModArray, setProjModArray] = useState<ProjModType[]>(props.projMods ? props.projMods : []);
|
||||
const [projModArray, setProjModArray] = useState<IProjMod[]>([]);
|
||||
const [newProjModArray, setNewProjModArray] = useState<ProjModType[]>([]);
|
||||
const [isProjModArrayLoading, setIsProjModArrayLoading] = useState(false);
|
||||
|
||||
|
||||
const ping = () => {
|
||||
clearTimeout(pingTimeout.current);
|
||||
pingTimeout.current = setTimeout(() => {
|
||||
@ -74,6 +74,8 @@ export default function AiHelper(props: PropsType) {
|
||||
setIsProjModArrayLoading(false);
|
||||
const projMods = JSON.parse(data.content) as ProjModType[];
|
||||
setNewProjModArray(projMods);
|
||||
} else if (data.type == 'REFRESH_PROJ_MOD_FIELDS') {
|
||||
listMods();
|
||||
}
|
||||
}
|
||||
ws.current.onerror = (event) => {
|
||||
@ -85,20 +87,21 @@ export default function AiHelper(props: PropsType) {
|
||||
}
|
||||
}
|
||||
|
||||
const projModColumnArray: TableProps<ProjModType>['columns'] = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
key: 'index',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
render: (_value, _record, index) => {
|
||||
return index + 1
|
||||
const listMods = () => {
|
||||
get<IProjMod[]>({
|
||||
messageApi,
|
||||
url: `/api/proj-mod/list/proj-id/${props.projId}`,
|
||||
onBefore() {
|
||||
setIsProjModArrayLoading(true);
|
||||
},
|
||||
onSuccess({data}) {
|
||||
setProjModArray(data);
|
||||
},
|
||||
onFinally() {
|
||||
setIsProjModArrayLoading(false);
|
||||
}
|
||||
},
|
||||
{title: '模块名称', dataIndex: 'name', key: 'name', width: 200, align: 'center'},
|
||||
{title: '模块描述', dataIndex: 'desc', key: 'desc', align: 'center'},
|
||||
];
|
||||
})
|
||||
}
|
||||
|
||||
const generateProjIntroduction = () => {
|
||||
ws.current?.send(JSON.stringify({
|
||||
@ -174,239 +177,106 @@ export default function AiHelper(props: PropsType) {
|
||||
}
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 保存模块
|
||||
*/
|
||||
const updateProjModArray = () => {
|
||||
put<any>({
|
||||
messageApi,
|
||||
url: `/api/proj-mod/update-mods/${props.projId}`,
|
||||
body: {
|
||||
list: newProjModArray
|
||||
},
|
||||
onBefore() {
|
||||
setIsProjModArrayLoading(true);
|
||||
},
|
||||
onSuccess() {
|
||||
messageApi.success('保存成功').then();
|
||||
setProjModArray(newProjModArray);
|
||||
setNewProjModArray([]);
|
||||
},
|
||||
onFinally() {
|
||||
setIsProjModArrayLoading(false)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.projId) {
|
||||
return;
|
||||
}
|
||||
listMods();
|
||||
websocket();
|
||||
}, [globalContext.user.userId, props.projId]);
|
||||
|
||||
/**
|
||||
* 项目简介按钮
|
||||
*/
|
||||
const renderNewProjIntroductionBtn = () => {
|
||||
if(!newProjIntroduction) {
|
||||
if(!isProjIntroductionEdit) {
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={generateProjIntroduction}>AI生成</Button>
|
||||
{
|
||||
projIntroduction ? (
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsProjIntroductionEdit(true);
|
||||
}}><EditOutlined /> 编辑</Button>
|
||||
) : <></>
|
||||
}
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsProjIntroductionEdit(false);
|
||||
updateProjIntroduction(projIntroduction);
|
||||
}}><CheckOutlined/> 保存结果</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
if(!isNewProjIntroductionEdit) {
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
updateProjIntroduction(newProjIntroduction);
|
||||
}}><CheckOutlined/> 保存结果</Button>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={generateProjIntroduction}><ReloadOutlined/> 重新生成</Button>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsNewProjIntroductionEdit(true);
|
||||
}}><EditOutlined /> 编辑</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsNewProjIntroductionEdit(false);
|
||||
}}><CheckOutlined/> 确定</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
/**
|
||||
* 项目简介按钮
|
||||
*/
|
||||
const renderNewProjDescBtn = () => {
|
||||
if(!newProjDesc) {
|
||||
if(!isProjDescEdit) {
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={generateProjDesc}>AI生成</Button>
|
||||
{
|
||||
projIntroduction ? (
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsProjDescEdit(true);
|
||||
}}><EditOutlined /> 编辑</Button>
|
||||
) : <></>
|
||||
}
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsProjDescEdit(false);
|
||||
updateProjDesc(projDesc);
|
||||
}}><CheckOutlined/> 保存结果</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
if(!isNewProjDescEdit) {
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
updateProjDesc(newProjDesc);
|
||||
}}><CheckOutlined/> 保存结果</Button>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={generateProjDesc}><ReloadOutlined/> 重新生成</Button>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsNewProjDescEdit(true);
|
||||
}}><EditOutlined /> 编辑</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsNewProjDescEdit(false);
|
||||
}}><CheckOutlined/> 确定</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{messageApiHolder}
|
||||
<Row>
|
||||
<Col span={24}>
|
||||
<div style={{padding: '5px 0 0 0', fontWeight: 'bold'}}>项目简介</div>
|
||||
<Spin tip="正在处理,请稍后..." size="small" spinning={isProjIntroductionLoading}>
|
||||
<div style={{padding: '5px 0 0 0'}}>
|
||||
{newProjIntroduction ? <Divider orientation="right" plain>原简介</Divider> : <></>}
|
||||
{projIntroduction ? (
|
||||
isProjIntroductionEdit ? <TextArea rows={10} value={projIntroduction} placeholder="请编辑简介" maxLength={1500} onChange={(e) => {
|
||||
setProjIntroduction(e.currentTarget.value);
|
||||
}}/>
|
||||
: <div>{projIntroduction}</div>
|
||||
) : <Empty description="暂无内容"/>}
|
||||
{
|
||||
newProjIntroduction ? (
|
||||
<>
|
||||
<Divider orientation="right" plain>新简介</Divider>
|
||||
{
|
||||
isNewProjIntroductionEdit ? (
|
||||
<TextArea rows={10} value={newProjIntroduction} placeholder="请编辑简介" maxLength={1500} onChange={(e) => {
|
||||
setNewProjIntroduction(e.currentTarget.value);
|
||||
}}/>
|
||||
) : <div>{newProjIntroduction}</div>
|
||||
}
|
||||
</>
|
||||
) : <></>
|
||||
}
|
||||
</div>
|
||||
<div style={{padding: '5px 0 0 0', textAlign: 'center'}}>
|
||||
{renderNewProjIntroductionBtn()}
|
||||
</div>
|
||||
<AiHelperText title="项目简介"
|
||||
text={projIntroduction}
|
||||
newText={newProjIntroduction}
|
||||
maxLength={1500}
|
||||
handleGenerate={() => {
|
||||
generateProjIntroduction();
|
||||
}}
|
||||
handleSave={(text) => {
|
||||
updateProjIntroduction(text);
|
||||
}}
|
||||
/>
|
||||
</Spin>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Divider dashed/>
|
||||
<div style={{padding: '5px 0 0 0', fontWeight: 'bold'}}>项目详情</div>
|
||||
<Spin tip="正在处理,请稍后..." size="small" spinning={isProjDescLoading}>
|
||||
<div style={{padding: '5px 0 0 0'}}>
|
||||
{newProjDesc ? <Divider orientation="right" plain>原详情</Divider> : <></>}
|
||||
{projDesc ? (
|
||||
isProjDescEdit ?
|
||||
<TextArea rows={10} value={projDesc} placeholder="请编辑详情"
|
||||
maxLength={1500} onChange={(e) => {
|
||||
setProjDesc(e.currentTarget.value);
|
||||
}}/>
|
||||
: <div>{projDesc}</div>
|
||||
) : <Empty description="暂无内容"/>}
|
||||
{
|
||||
newProjDesc ? (
|
||||
<>
|
||||
<Divider orientation="right" plain>新详情</Divider>
|
||||
{
|
||||
isNewProjDescEdit ? (
|
||||
<TextArea rows={10} value={newProjDesc} placeholder="请编辑简介"
|
||||
maxLength={1500} onChange={(e) => {
|
||||
setNewProjDesc(e.currentTarget.value);
|
||||
}}/>
|
||||
) : <div>{newProjDesc}</div>
|
||||
}
|
||||
</>
|
||||
) : <></>
|
||||
}
|
||||
</div>
|
||||
<div style={{padding: '5px 0 0 0', textAlign: 'center'}}>
|
||||
{renderNewProjDescBtn()}
|
||||
</div>
|
||||
<AiHelperText title="项目详情"
|
||||
text={projDesc}
|
||||
newText={newProjDesc}
|
||||
maxLength={1500}
|
||||
handleGenerate={() => {
|
||||
generateProjDesc();
|
||||
}}
|
||||
handleSave={(text) => {
|
||||
updateProjDesc(text);
|
||||
}}
|
||||
/>
|
||||
</Spin>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Divider dashed/>
|
||||
<div style={{padding: '5px 0 0 0', fontWeight: 'bold'}}>项目模块</div>
|
||||
<Spin tip="正在处理,请稍后..." size="small" spinning={isProjModArrayLoading}>
|
||||
<div style={{padding: '5px 0 0 0'}}>
|
||||
{newProjModArray.length > 0 ? <Divider orientation="right" plain>原模块</Divider> : <></>}
|
||||
<Table columns={projModColumnArray} dataSource={projModArray} size="small" bordered={true}
|
||||
scroll={{y: 240}} pagination={{pageSize: 20}}/>
|
||||
{
|
||||
newProjModArray.length > 0 ? (
|
||||
<>
|
||||
<Divider orientation="right" plain>新模块</Divider>
|
||||
<Table columns={projModColumnArray} dataSource={newProjModArray} size="small"
|
||||
bordered={true} scroll={{y: 240}} pagination={{pageSize: 20}}/>
|
||||
</>
|
||||
) : <></>
|
||||
}
|
||||
</div>
|
||||
<div style={{padding: '5px 0 0 0', textAlign: 'center'}}>
|
||||
{
|
||||
newProjModArray.length > 0 ? (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}}
|
||||
onClick={updateProjModArray}><CheckOutlined/> 保存结果</Button>
|
||||
<Button type="link" style={{cursor: 'pointer'}}
|
||||
onClick={generateProjModArray}><ReloadOutlined/> 重新生成</Button>
|
||||
</Space>
|
||||
) : <Button type="link" style={{cursor: 'pointer'}}
|
||||
onClick={generateProjModArray}>AI生成</Button>
|
||||
}
|
||||
</div>
|
||||
<AiHelperMod mods={projModArray}
|
||||
newMods={newProjModArray}
|
||||
handleGenerate={() => {
|
||||
generateProjModArray();
|
||||
}}
|
||||
handleSave={(index, mod) => {
|
||||
if(projModArray.length > MAX_MOD_SIZE) {
|
||||
messageApi.error(`模块最大数量为${MAX_MOD_SIZE}`);
|
||||
return;
|
||||
}
|
||||
post<any>({
|
||||
messageApi,
|
||||
url: `/api/proj-mod/save-ai/${props.projId}`,
|
||||
body: {
|
||||
name: mod.name,
|
||||
desc: mod.desc,
|
||||
},
|
||||
onBefore() {
|
||||
setIsProjModArrayLoading(true);
|
||||
},
|
||||
onSuccess() {
|
||||
messageApi.success('提交成功')
|
||||
listMods();
|
||||
newProjModArray.splice(index, 1);
|
||||
setNewProjModArray([
|
||||
...newProjModArray
|
||||
]);
|
||||
},
|
||||
onFinally() {
|
||||
setIsProjModArrayLoading(false);
|
||||
}
|
||||
})
|
||||
}}
|
||||
handleResaveField={(_index, projModId) => {
|
||||
post<any>({
|
||||
messageApi,
|
||||
url: `/api/proj-mod/resave-ai-field/${props.projId}/${projModId}`,
|
||||
onBefore() {
|
||||
setIsProjModArrayLoading(true);
|
||||
},
|
||||
onSuccess() {
|
||||
messageApi.success('提交成功')
|
||||
listMods();
|
||||
},
|
||||
onFinally() {
|
||||
setIsProjModArrayLoading(false);
|
||||
}
|
||||
})
|
||||
}}
|
||||
/>
|
||||
</Spin>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
</>
|
||||
)
|
||||
|
155
src/components/ai/mod/AiHelperMod.tsx
Normal file
155
src/components/ai/mod/AiHelperMod.tsx
Normal file
@ -0,0 +1,155 @@
|
||||
import {Button, Divider, Dropdown, Space, Table, TableProps} from "antd";
|
||||
import {CheckOutlined, LoadingOutlined, ReloadOutlined, RedoOutlined} from "@ant-design/icons";
|
||||
import {useEffect, useState} from "react";
|
||||
import {IProjMod} from "../../../interfaces/proj/IProj.ts";
|
||||
|
||||
type PropsType = {
|
||||
mods: IProjMod[];
|
||||
newMods: ProjModType[],
|
||||
handleGenerate: () => void;
|
||||
handleSave: (index: number, mod: ProjModType) => void;
|
||||
handleResaveField: (index: number, projModId: string) => void;
|
||||
}
|
||||
|
||||
type ProjModType = {
|
||||
name: string,
|
||||
desc: string,
|
||||
}
|
||||
|
||||
const savedItems = [
|
||||
{
|
||||
key: 'edit',
|
||||
label: '编辑',
|
||||
},{
|
||||
key: 'remove',
|
||||
label: '删除',
|
||||
},
|
||||
]
|
||||
|
||||
export default function AiHelperMod(props: PropsType) {
|
||||
const [modArray, setModArray] = useState<IProjMod[]>([]);
|
||||
const [newModArray, setNewModArray] = useState<ProjModType[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
setModArray(props.mods);
|
||||
setNewModArray(props.newMods);
|
||||
}, [props.mods, props.newMods]);
|
||||
|
||||
const modColumnArray: TableProps<IProjMod>['columns'] = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
key: 'index',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
render: (_value, _record, index) => {
|
||||
return index + 1
|
||||
}
|
||||
},
|
||||
{title: '模块名称', dataIndex: 'modName', key: 'name', width: 200, align: 'center'},
|
||||
{title: '模块描述', dataIndex: 'modDesc', key: 'desc', align: 'center'},
|
||||
{
|
||||
title: 'AI状态',
|
||||
dataIndex: 'aiFieldStatus',
|
||||
key: 'desc',
|
||||
width: 100,
|
||||
align: 'center',
|
||||
render: (value) => {
|
||||
if(value == 'GENERATING') {
|
||||
return '处理中'
|
||||
}
|
||||
if(value == 'FIELD') {
|
||||
return '失败'
|
||||
}
|
||||
if(value == 'SUCCESS') {
|
||||
return '成功'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'option',
|
||||
key: 'option',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
render: (_value, record, index) => {
|
||||
if(record.aiFieldStatus == 'GENERATING') {
|
||||
return <LoadingOutlined />
|
||||
}
|
||||
if(record.aiFieldStatus == 'FAILED') {
|
||||
return <Button onClick={() => {
|
||||
props.handleResaveField(index, record.projModId);
|
||||
}}><RedoOutlined /></Button>
|
||||
}
|
||||
return (
|
||||
<Dropdown menu={{ items: savedItems }} placement="bottomCenter" arrow>
|
||||
<Button>…</Button>
|
||||
</Dropdown>
|
||||
)
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
const newModColumnArray: TableProps<ProjModType>['columns'] = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
key: 'index',
|
||||
width: 60,
|
||||
align: 'center',
|
||||
render: (_value, _record, index) => {
|
||||
return index + 1
|
||||
}
|
||||
},
|
||||
{title: '模块名称', dataIndex: 'name', key: 'name', width: 200, align: 'center'},
|
||||
{title: '模块描述', dataIndex: 'desc', key: 'desc', align: 'center'},
|
||||
{
|
||||
title: '确认',
|
||||
dataIndex: 'option',
|
||||
key: 'option',
|
||||
width: 80,
|
||||
align: 'center',
|
||||
render: (_value, record, index) => {
|
||||
return (
|
||||
<Button onClick={() => {
|
||||
props.handleSave(index, record);
|
||||
}}>
|
||||
<CheckOutlined />
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{padding: '5px 0 0 0'}}>
|
||||
{newModArray.length > 0 ? <Divider orientation="right" plain>原模块</Divider> : <></>}
|
||||
<Table columns={modColumnArray} dataSource={modArray} size="small" bordered={true} scroll={{y: 240}} pagination={false}/>
|
||||
{
|
||||
newModArray.length > 0 ? (
|
||||
<>
|
||||
<Divider orientation="right" plain>新模块</Divider>
|
||||
<Table columns={newModColumnArray} dataSource={newModArray} size="small" bordered={true} scroll={{y: 240}} pagination={false}/>
|
||||
</>
|
||||
) : <></>
|
||||
}
|
||||
</div>
|
||||
<div style={{padding: '5px 0 0 0', textAlign: 'center'}}>
|
||||
{
|
||||
newModArray.length > 0 ? (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}}
|
||||
onClick={() => {
|
||||
props.handleGenerate();
|
||||
}}><ReloadOutlined/> 重新生成</Button>
|
||||
</Space>
|
||||
) : <Button type="link" style={{cursor: 'pointer'}}
|
||||
onClick={() => {
|
||||
props.handleGenerate();
|
||||
}}>AI生成</Button>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
129
src/components/ai/text/AiHelperText.tsx
Normal file
129
src/components/ai/text/AiHelperText.tsx
Normal file
@ -0,0 +1,129 @@
|
||||
import {Button, Divider, Empty, Space} from "antd";
|
||||
import TextArea from "antd/es/input/TextArea";
|
||||
import {useEffect, useState} from "react";
|
||||
import {CheckOutlined, EditOutlined, ReloadOutlined} from "@ant-design/icons";
|
||||
|
||||
type PropsType = {
|
||||
title: string;
|
||||
maxLength: number;
|
||||
text: string;
|
||||
newText: string;
|
||||
handleGenerate: () => void;
|
||||
handleSave: (newText: string) => void;
|
||||
}
|
||||
|
||||
export default function AiHelperText(props: PropsType) {
|
||||
|
||||
const [text, setText] = useState('');
|
||||
const [newText, setNewText] = useState('');
|
||||
const [isTextEdit, setIsTextEdit] = useState(false);
|
||||
const [isNewTextEdit, setIsNewTextEdit] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setText(props.text);
|
||||
setNewText(props.newText);
|
||||
}, [props.text, props.newText])
|
||||
|
||||
const renderTextBtn = () => {
|
||||
if (!newText) {
|
||||
if (!isTextEdit) {
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
props.handleGenerate();
|
||||
}}>AI生成</Button>
|
||||
{
|
||||
text ? (
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsTextEdit(true);
|
||||
}}><EditOutlined/> 编辑</Button>
|
||||
) : <></>
|
||||
}
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
props.handleSave(text);
|
||||
setIsTextEdit(false);
|
||||
}}><CheckOutlined/> 保存结果</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
if (!isNewTextEdit) {
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
props.handleSave(newText);
|
||||
setIsNewTextEdit(false);
|
||||
}}><CheckOutlined/> 保存结果</Button>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
props.handleGenerate();
|
||||
}}><ReloadOutlined/> 重新生成</Button>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsNewTextEdit(true);
|
||||
}}><EditOutlined/> 编辑</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Space>
|
||||
<Button type="link" style={{cursor: 'pointer'}} onClick={() => {
|
||||
setIsNewTextEdit(false);
|
||||
}}><CheckOutlined/> 确定</Button>
|
||||
</Space>
|
||||
)
|
||||
}
|
||||
|
||||
const renderTextDom = () => {
|
||||
if(!text) {
|
||||
return <Empty description="暂无内容"/>
|
||||
}
|
||||
if(!isTextEdit) {
|
||||
return <div>{text}</div>
|
||||
}
|
||||
return (
|
||||
<TextArea autoSize={true} value={text} placeholder={`请编辑${props.title}`} maxLength={props.maxLength} onChange={(e) => {
|
||||
setText(e.currentTarget.value);
|
||||
}}/>
|
||||
)
|
||||
}
|
||||
|
||||
const renderNewTextDom = () => {
|
||||
if(!newText) {
|
||||
return <></>
|
||||
}
|
||||
if(!isNewTextEdit) {
|
||||
return (
|
||||
<>
|
||||
<Divider orientation="right" plain>新{props.title}</Divider>
|
||||
<div>{newText}</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Divider orientation="right" plain>新{props.title}</Divider>
|
||||
<TextArea autoSize={true} value={newText} placeholder={`请编辑${props.title}`} maxLength={props.maxLength} onChange={(e) => {
|
||||
setNewText(e.currentTarget.value);
|
||||
}}/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{padding: '5px 0 0 0', fontWeight: 'bold'}}>{props.title}</div>
|
||||
<div style={{padding: '5px 0 0 0'}}>
|
||||
{newText ? <Divider orientation="right" plain>原{props.title}</Divider> : <></>}
|
||||
{renderTextDom()}
|
||||
{renderNewTextDom()}
|
||||
</div>
|
||||
<div style={{padding: '5px 0 0 0', textAlign: 'center'}}>
|
||||
{renderTextBtn()}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
@ -59,6 +59,19 @@ export interface IProjPay {
|
||||
chargeAdditionals: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 项目模块
|
||||
*/
|
||||
export interface IProjMod {
|
||||
projModId: string;
|
||||
projId: string;
|
||||
projContext: string;
|
||||
modName: string;
|
||||
modDesc: string;
|
||||
modIcon: string;
|
||||
modContext: string;
|
||||
aiFieldStatus: string;
|
||||
}
|
||||
|
||||
export interface IProj {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user