This commit is contained in:
WenC 2024-04-22 18:20:26 +08:00
parent 99b65965c6
commit 5099637414
2 changed files with 203 additions and 47 deletions

View File

@ -2,13 +2,15 @@ import {useContext, useEffect, useRef, useState} from "react";
import {GlobalContext} from "../../context/GlobalContext.ts"; import {GlobalContext} from "../../context/GlobalContext.ts";
import {put, WebSocketBaseUrl} from "../../util/AjaxUtils.ts"; import {put, WebSocketBaseUrl} from "../../util/AjaxUtils.ts";
import {Button, Col, Divider, Empty, Row, Space, Spin, Table, TableProps} from "antd"; import {Button, Col, Divider, Empty, Row, Space, Spin, Table, TableProps} from "antd";
import {CheckOutlined, ReloadOutlined} from "@ant-design/icons"; import {CheckOutlined, EditOutlined, ReloadOutlined} from "@ant-design/icons";
import useMessage from "antd/es/message/useMessage"; import useMessage from "antd/es/message/useMessage";
import TextArea from "antd/es/input/TextArea";
type PropsType = { type PropsType = {
projId: string; projId: string;
projIntroduction?: string; projIntroduction?: string;
projDesc?: string; projDesc?: string;
projMods?: ProjModType[];
} }
type ProjModType = { type ProjModType = {
@ -23,11 +25,17 @@ export default function AiHelper(props: PropsType) {
const [messageApi, messageApiHolder] = useMessage(); const [messageApi, messageApiHolder] = useMessage();
const [projIntroduction, setProjIntroduction] = useState<string>(props.projIntroduction ? props.projIntroduction : ''); const [projIntroduction, setProjIntroduction] = useState<string>(props.projIntroduction ? props.projIntroduction : '');
const [newProjIntroduction, setNewProjIntroduction] = useState<string>(''); const [newProjIntroduction, setNewProjIntroduction] = useState<string>('');
const [isProjIntroductionEdit, setIsProjIntroductionEdit] = useState<boolean>(false);
const [isNewProjIntroductionEdit, setIsNewProjIntroductionEdit] = useState<boolean>(false);
const [isProjIntroductionLoading, setIsProjIntroductionLoading] = useState(false); const [isProjIntroductionLoading, setIsProjIntroductionLoading] = useState(false);
const [projDesc, setProjDesc] = useState<string>(props.projDesc ? props.projDesc : ''); const [projDesc, setProjDesc] = useState<string>(props.projDesc ? props.projDesc : '');
const [newProjDesc, setNewProjDesc] = useState<string>(''); const [newProjDesc, setNewProjDesc] = useState<string>('');
const [isProjDescEdit, setIsProjDescEdit] = useState<boolean>(false);
const [isNewProjDescEdit, setIsNewProjDescEdit] = useState<boolean>(false);
const [isProjDescLoading, setIsProjDescLoading] = useState(false); const [isProjDescLoading, setIsProjDescLoading] = useState(false);
const [projModArray, setProjModArray] = useState<ProjModType[]>([]);
const [projModArray, setProjModArray] = useState<ProjModType[]>(props.projMods ? props.projMods : []);
const [newProjModArray, setNewProjModArray] = useState<ProjModType[]>([]); const [newProjModArray, setNewProjModArray] = useState<ProjModType[]>([]);
const [isProjModArrayLoading, setIsProjModArrayLoading] = useState(false); const [isProjModArrayLoading, setIsProjModArrayLoading] = useState(false);
@ -78,7 +86,16 @@ export default function AiHelper(props: PropsType) {
} }
const projModColumnArray: TableProps<ProjModType>['columns'] = [ const projModColumnArray: TableProps<ProjModType>['columns'] = [
{title: '序号', dataIndex: 'index', key: 'index', width: 60, align: 'center', render: (value, record, index) => {return index + 1}}, {
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: 'name', key: 'name', width: 200, align: 'center'},
{title: '模块描述', dataIndex: 'desc', key: 'desc', align: 'center'}, {title: '模块描述', dataIndex: 'desc', key: 'desc', align: 'center'},
]; ];
@ -113,19 +130,19 @@ export default function AiHelper(props: PropsType) {
/** /**
* *
*/ */
const updateProjIntroduction = () => { const updateProjIntroduction = (content: string) => {
put<any>({ put<any>({
messageApi, messageApi,
url: `/api/proj/update-introduction/${props.projId}`, url: `/api/proj/update-introduction/${props.projId}`,
body: { body: {
content: newProjIntroduction content: content
}, },
onBefore() { onBefore() {
setIsProjIntroductionLoading(true); setIsProjIntroductionLoading(true);
}, },
onSuccess() { onSuccess() {
messageApi.success('保存成功'); messageApi.success('保存成功');
setProjIntroduction(newProjIntroduction); setProjIntroduction(content);
setNewProjIntroduction(''); setNewProjIntroduction('');
}, },
onFinally() { onFinally() {
@ -137,19 +154,19 @@ export default function AiHelper(props: PropsType) {
/** /**
* *
*/ */
const updateProjDesc = () => { const updateProjDesc = (content: string) => {
put<any>({ put<any>({
messageApi, messageApi,
url: `/api/proj/update-desc/${props.projId}`, url: `/api/proj/update-desc/${props.projId}`,
body: { body: {
content: newProjDesc content: content
}, },
onBefore() { onBefore() {
setIsProjDescLoading(true); setIsProjDescLoading(true);
}, },
onSuccess() { onSuccess() {
messageApi.success('保存成功').then(); messageApi.success('保存成功').then();
setProjDesc(newProjDesc); setProjDesc(content);
setNewProjDesc(''); setNewProjDesc('');
}, },
onFinally() { onFinally() {
@ -157,6 +174,29 @@ 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(() => { useEffect(() => {
if (!props.projId) { if (!props.projId) {
@ -165,6 +205,105 @@ export default function AiHelper(props: PropsType) {
websocket(); websocket();
}, [globalContext.user.userId, props.projId]); }, [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 ( return (
<> <>
{messageApiHolder} {messageApiHolder}
@ -174,28 +313,29 @@ export default function AiHelper(props: PropsType) {
<Spin tip="正在处理,请稍后..." size="small" spinning={isProjIntroductionLoading}> <Spin tip="正在处理,请稍后..." size="small" spinning={isProjIntroductionLoading}>
<div style={{padding: '5px 0 0 0'}}> <div style={{padding: '5px 0 0 0'}}>
{newProjIntroduction ? <Divider orientation="right" plain></Divider> : <></>} {newProjIntroduction ? <Divider orientation="right" plain></Divider> : <></>}
{projIntroduction ? <div>{projIntroduction}</div> : <Empty description="暂无内容"/>} {projIntroduction ? (
isProjIntroductionEdit ? <TextArea rows={10} value={projIntroduction} placeholder="请编辑简介" maxLength={1500} onChange={(e) => {
setProjIntroduction(e.currentTarget.value);
}}/>
: <div>{projIntroduction}</div>
) : <Empty description="暂无内容"/>}
{ {
newProjIntroduction ? ( newProjIntroduction ? (
<> <>
<Divider orientation="right" plain></Divider> <Divider orientation="right" plain></Divider>
<div>{newProjIntroduction}</div> {
isNewProjIntroductionEdit ? (
<TextArea rows={10} value={newProjIntroduction} placeholder="请编辑简介" maxLength={1500} onChange={(e) => {
setNewProjIntroduction(e.currentTarget.value);
}}/>
) : <div>{newProjIntroduction}</div>
}
</> </>
) : <></> ) : <></>
} }
</div> </div>
<div style={{padding: '5px 0 0 0', textAlign: 'center'}}> <div style={{padding: '5px 0 0 0', textAlign: 'center'}}>
{ {renderNewProjIntroductionBtn()}
newProjIntroduction ? (
<Space>
<Button type="link" style={{cursor: 'pointer'}}
onClick={updateProjIntroduction}><CheckOutlined/> </Button>
<Button type="link" style={{cursor: 'pointer'}}
onClick={generateProjIntroduction}><ReloadOutlined/> </Button>
</Space>
) : <Button type="link" style={{cursor: 'pointer'}}
onClick={generateProjIntroduction}>AI生成</Button>
}
</div> </div>
</Spin> </Spin>
</Col> </Col>
@ -205,28 +345,32 @@ export default function AiHelper(props: PropsType) {
<Spin tip="正在处理,请稍后..." size="small" spinning={isProjDescLoading}> <Spin tip="正在处理,请稍后..." size="small" spinning={isProjDescLoading}>
<div style={{padding: '5px 0 0 0'}}> <div style={{padding: '5px 0 0 0'}}>
{newProjDesc ? <Divider orientation="right" plain></Divider> : <></>} {newProjDesc ? <Divider orientation="right" plain></Divider> : <></>}
{projDesc ? <div>{projDesc}</div> : <Empty description="暂无内容"/>} {projDesc ? (
isProjDescEdit ?
<TextArea rows={10} value={projDesc} placeholder="请编辑详情"
maxLength={1500} onChange={(e) => {
setProjDesc(e.currentTarget.value);
}}/>
: <div>{projDesc}</div>
) : <Empty description="暂无内容"/>}
{ {
newProjDesc ? ( newProjDesc ? (
<> <>
<Divider orientation="right" plain></Divider> <Divider orientation="right" plain></Divider>
<div>{newProjDesc}</div> {
isNewProjDescEdit ? (
<TextArea rows={10} value={newProjDesc} placeholder="请编辑简介"
maxLength={1500} onChange={(e) => {
setNewProjDesc(e.currentTarget.value);
}}/>
) : <div>{newProjDesc}</div>
}
</> </>
) : <></> ) : <></>
} }
</div> </div>
<div style={{padding: '5px 0 0 0', textAlign: 'center'}}> <div style={{padding: '5px 0 0 0', textAlign: 'center'}}>
{ {renderNewProjDescBtn()}
newProjDesc ? (
<Space>
<Button type="link" style={{cursor: 'pointer'}}
onClick={updateProjDesc}><CheckOutlined/> </Button>
<Button type="link" style={{cursor: 'pointer'}}
onClick={generateProjDesc}><ReloadOutlined/> </Button>
</Space>
) : <Button type="link" style={{cursor: 'pointer'}}
onClick={generateProjDesc}>AI生成</Button>
}
</div> </div>
</Spin> </Spin>
</Col> </Col>
@ -236,12 +380,14 @@ export default function AiHelper(props: PropsType) {
<Spin tip="正在处理,请稍后..." size="small" spinning={isProjModArrayLoading}> <Spin tip="正在处理,请稍后..." size="small" spinning={isProjModArrayLoading}>
<div style={{padding: '5px 0 0 0'}}> <div style={{padding: '5px 0 0 0'}}>
{newProjModArray.length > 0 ? <Divider orientation="right" plain></Divider> : <></>} {newProjModArray.length > 0 ? <Divider orientation="right" plain></Divider> : <></>}
<Table columns={projModColumnArray} dataSource={projModArray} size="small" bordered={true} scroll={{y: 240}} pagination={{pageSize: 20}}/> <Table columns={projModColumnArray} dataSource={projModArray} size="small" bordered={true}
scroll={{y: 240}} pagination={{pageSize: 20}}/>
{ {
newProjModArray.length > 0 ? ( newProjModArray.length > 0 ? (
<> <>
<Divider orientation="right" plain></Divider> <Divider orientation="right" plain></Divider>
<Table columns={projModColumnArray} dataSource={newProjModArray} size="small" bordered={true} scroll={{y: 240}} pagination={{pageSize: 20}}/> <Table columns={projModColumnArray} dataSource={newProjModArray} size="small"
bordered={true} scroll={{y: 240}} pagination={{pageSize: 20}}/>
</> </>
) : <></> ) : <></>
} }
@ -251,7 +397,7 @@ export default function AiHelper(props: PropsType) {
newProjModArray.length > 0 ? ( newProjModArray.length > 0 ? (
<Space> <Space>
<Button type="link" style={{cursor: 'pointer'}} <Button type="link" style={{cursor: 'pointer'}}
onClick={generateProjModArray}><CheckOutlined/> </Button> onClick={updateProjModArray}><CheckOutlined/> </Button>
<Button type="link" style={{cursor: 'pointer'}} <Button type="link" style={{cursor: 'pointer'}}
onClick={generateProjModArray}><ReloadOutlined/> </Button> onClick={generateProjModArray}><ReloadOutlined/> </Button>
</Space> </Space>

View File

@ -19,6 +19,12 @@ type AiHelperType = {
projId: string; projId: string;
projIntroduction: string; projIntroduction: string;
projDesc: string; projDesc: string;
projMods: ProjModType[];
}
type ProjModType = {
name: string,
desc: string
} }
export default function ProjEdit() { export default function ProjEdit() {
@ -41,7 +47,8 @@ export default function ProjEdit() {
const [aiHelper, setAiHelper] = useState<AiHelperType>({ const [aiHelper, setAiHelper] = useState<AiHelperType>({
projId: '', projId: '',
projIntroduction: '', projIntroduction: '',
projDesc: '' projDesc: '',
projMods: [],
}); });
@ -213,7 +220,8 @@ export default function ProjEdit() {
setAiHelper({ setAiHelper({
projId: data.projId, projId: data.projId,
projIntroduction: data.projIntroduction, projIntroduction: data.projIntroduction,
projDesc: data.projDesc projDesc: data.projDesc,
projMods: data.projMods
}) })
setAiHelperModalOpen(!data.projIntroduction || !data.projDesc) setAiHelperModalOpen(!data.projIntroduction || !data.projDesc)
@ -253,6 +261,7 @@ export default function ProjEdit() {
} }
</StepProjEdit> </StepProjEdit>
{/*trueisEditStepEdited*/}
<StepProjEdit step={2} <StepProjEdit step={2}
process={!isEditStepEdited ? Process.PENDING : (isConfigEdited ? Process.COMPLETE : Process.PROCESSING)} process={!isEditStepEdited ? Process.PENDING : (isConfigEdited ? Process.COMPLETE : Process.PROCESSING)}
descTitle="功能设置" descTitle="功能设置"
@ -263,7 +272,7 @@ export default function ProjEdit() {
title={item.title} title={item.title}
desc={item.desc} desc={item.desc}
btnName={item.btnName} btnName={item.btnName}
canBtnClick={isEditStepEdited} canBtnClick={true}
status={item.status} status={item.status}
handleEdit={item.handleEdit} handleEdit={item.handleEdit}
/> />
@ -370,12 +379,12 @@ export default function ProjEdit() {
window.open(`${Axios.defaults?.baseURL}/route/proj/download/code/${pathParams.projId}`) window.open(`${Axios.defaults?.baseURL}/route/proj/download/code/${pathParams.projId}`)
}} }}
/> />
<CardProjJump title="找代理" {/*<CardProjJump title="找代理"*/}
desc="到软著代理完成软著申请" {/* desc="到软著代理完成软著申请"*/}
handleJump={() => { {/* handleJump={() => {*/}
nav(`/agent-select/${pathParams.projId}`); {/* nav(`/agent-select/${pathParams.projId}`);*/}
}} {/* }}*/}
/> {/*/>*/}
</StepProjEdit> </StepProjEdit>
</div> </div>
<div className="btn-container"> <div className="btn-container">
@ -444,6 +453,7 @@ export default function ProjEdit() {
projId={aiHelper.projId} projId={aiHelper.projId}
projIntroduction={aiHelper.projIntroduction} projIntroduction={aiHelper.projIntroduction}
projDesc={aiHelper.projDesc} projDesc={aiHelper.projDesc}
projMods={aiHelper.projMods}
/> />
</Modal> </Modal>
</> </>