refactor: rename page routers

This commit is contained in:
Junyan Qin
2025-04-26 11:19:05 +08:00
parent 2d64447c08
commit e03e12539a
23 changed files with 26 additions and 26 deletions
@@ -0,0 +1,3 @@
export interface ICreateBotField {
}
@@ -0,0 +1,23 @@
.configPageContainer {
width: 100%;
height: 100%;
}
.cardContainer {
width: 420px;
height: 220px;
border: 1px solid black;
}
.botListContainer {
align-self: flex-start;
justify-self: flex-start;
width: calc(100% - 60px);
margin: auto;
display: grid;
grid-template-rows: repeat(auto-fill, minmax(220px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
gap: 15px;
justify-items: center;
align-items: center;
}
@@ -0,0 +1,39 @@
import {BotCardVO} from "@/app/home/bots/components/bot-card/BotCardVO";
import styles from "./botCard.module.css";
export default function BotCard({
botCardVO
}: {
botCardVO: BotCardVO;
}) {
return (
<div className={`${styles.cardContainer}`}>
{/* icon和基本信息 */}
<div className={`${styles.iconBasicInfoContainer}`}>
{/* icon */}
<div className={`${styles.icon}`}>
ICO
</div>
{/* bot基本信息 */}
<div className={`${styles.basicInfoContainer}`}>
<div className={`${styles.basicInfoText} ${styles.bigText}`}>
{botCardVO.name}
</div>
<div className={`${styles.basicInfoText}`}>
{botCardVO.adapter}
</div>
<div className={`${styles.basicInfoText}`}>
线{botCardVO.pipelineName}
</div>
</div>
</div>
{/* 描述和创建时间 */}
<div className={`${styles.urlAndUpdateText}`}>
{botCardVO.description}
</div>
<div className={`${styles.urlAndUpdateText}`}>
{botCardVO.updateTime}
</div>
</div>
)
}
@@ -0,0 +1,28 @@
export interface IBotCardVO {
id: string;
name: string;
adapter: string;
description: string;
updateTime: string;
pipelineName: string;
}
export class BotCardVO implements IBotCardVO {
id: string;
adapter: string;
description: string;
name: string;
updateTime: string;
pipelineName: string;
constructor(props: IBotCardVO) {
this.id = props.id;
this.name = props.name;
this.adapter = props.adapter;
this.description = props.description;
this.updateTime = props.updateTime;
this.pipelineName = props.pipelineName;
}
}
@@ -0,0 +1,67 @@
.iconBasicInfoContainer {
width: 300px;
height: 100px;
margin-left: 20px;
display: flex;
flex-direction: row;
}
.cardContainer {
width: 360px;
height: 200px;
background-color: #FFF;
border-radius: 9px;
box-shadow: rgba(0, 0, 0, 0.4) 0 1px 1px -1px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-evenly;
}
.iconBasicInfoContainer {
width: 300px;
height: 100px;
margin-left: 20px;
display: flex;
flex-direction: row;
}
.icon {
width: 90px;
height: 90px;
border-radius: 5px;
font-size: 40px;
line-height: 90px;
text-align: center;
color: #ffffff;
background: rgba(96, 149, 209, 0.31);
border: 1px solid rgba(96, 149, 209, 0.31);
}
.basicInfoContainer {
width: 200px;
height: 90px;
padding-left: 20px;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-between;
}
.basicInfoText {
}
.bigText {
font-size: 20px;
}
.urlAndUpdateText {
margin-left: 20px;
}
.createCardContainer {
font-size: 90px;
background: #6062E7;
color: white;
}
@@ -0,0 +1,222 @@
import {BotFormEntity, IBotFormEntity} from "@/app/home/bots/components/bot-form/BotFormEntity";
import {fetchAdapterList} from "@/app/home/mock-api/index"
import {Button, Form, Input, Select, Space} from "antd";
import {useEffect, useState} from "react";
import {IChooseAdapterEntity} from "@/app/home/bots/components/bot-form/ChooseAdapterEntity";
import {
DynamicFormItemConfig,
IDynamicFormItemConfig,
parseDynamicFormItemType
} from "@/app/home/components/dynamic-form/DynamicFormItemConfig";
import {UUID} from 'uuidjs'
import DynamicFormComponent from "@/app/home/components/dynamic-form/DynamicFormComponent";
import {ICreateLLMField} from "@/app/home/models/ICreateLLMField";
export default function BotForm({
initBotId,
onFormSubmit,
onFormCancel,
}: {
initBotId?: string;
onFormSubmit: (value: IBotFormEntity) => void;
onFormCancel: (value: IBotFormEntity) => void;
}) {
const [adapterNameToDynamicConfigMap, setAdapterNameToDynamicConfigMap] = useState(new Map<string, IDynamicFormItemConfig[]>())
const [form] = Form.useForm<IBotFormEntity>();
const [showDynamicForm, setShowDynamicForm] = useState<boolean>(false)
const [dynamicForm] = Form.useForm();
const [adapterNameList, setAdapterNameList] = useState<IChooseAdapterEntity[]>([])
const [dynamicFormConfigList, setDynamicFormConfigList] = useState<IDynamicFormItemConfig[]>([])
useEffect(() => {
initBotFormComponent()
if (initBotId) {
onEditMode()
} else {
onCreateMode()
}
}, [])
async function initBotFormComponent() {
// 拉取adapter
const rawAdapterList = await fetchAdapterList()
// 初始化适配器选择列表
setAdapterNameList(
rawAdapterList.map(item => {
return {
label: item.label.zh_CN,
value: item.name
}
})
)
// 初始化适配器表单map
rawAdapterList.forEach(rawAdapter => {
adapterNameToDynamicConfigMap.set(
rawAdapter.name,
rawAdapter.spec.config.map(item =>
new DynamicFormItemConfig({
default: item.default,
id: UUID.generate(),
label: item.label,
name: item.name,
required: item.required,
type: parseDynamicFormItemType(item.type)
})
)
)
})
// 拉取初始化表单信息
if (initBotId) {
getBotFieldById(initBotId).then(val => {
form.setFieldsValue(val)
handleAdapterSelect(val.adapter)
})
} else {
form.resetFields()
}
setAdapterNameToDynamicConfigMap(adapterNameToDynamicConfigMap)
}
async function onCreateMode() {
}
function onEditMode() {
}
async function getBotFieldById(botId: string): Promise<IBotFormEntity> {
return new BotFormEntity({
adapter: "telegram",
description: "模拟拉取bot",
name: "模拟电报bot",
adapter_config: {
token: "aaabbbccc"
},
})
}
function handleAdapterSelect(adapterName: string) {
if (adapterName) {
console.log(adapterNameToDynamicConfigMap)
const dynamicFormConfigList = adapterNameToDynamicConfigMap.get(adapterName)
if (dynamicFormConfigList) {
console.log(dynamicFormConfigList)
setDynamicFormConfigList(dynamicFormConfigList)
}
setShowDynamicForm(true)
} else {
setShowDynamicForm(false)
}
}
function handleSubmitButton() {
form.submit()
}
function handleFormFinish(value: IBotFormEntity) {
dynamicForm.submit()
}
// 只有通过外层固定表单验证才会走到这里,真正的提交逻辑在这里
function onDynamicFormSubmit(value: object) {
if (initBotId) {
// 编辑提交
console.log('submit edit', form.getFieldsValue() ,value)
} else {
// 创建提交
console.log('submit create', form.getFieldsValue() ,value)
}
onFormSubmit(form.getFieldsValue())
setShowDynamicForm(false)
form.resetFields()
dynamicForm.resetFields()
}
function handleSaveButton() {
}
return (
<div>
<Form
form={form}
labelCol={{span: 5}}
wrapperCol={{span: 18}}
layout='vertical'
onFinish={handleFormFinish}
>
<Form.Item<IBotFormEntity>
label={"机器人名称"}
name={"name"}
rules={[{required: true, message: "该项为必填项哦~"}]}
>
<Input
placeholder="为机器人取个好听的名字吧~"
style={{width: 260}}
></Input>
</Form.Item>
<Form.Item<IBotFormEntity>
label={"描述"}
name={"description"}
rules={[{required: true, message: "该项为必填项哦~"}]}
>
<Input
placeholder="简单描述一下这个机器人"
></Input>
</Form.Item>
<Form.Item<IBotFormEntity>
label={"平台/适配器选择"}
name={"adapter"}
rules={[{required: true, message: "该项为必填项哦~"}]}
>
<Select
style={{width: 220}}
onChange={(value) => {
handleAdapterSelect(value)
}}
options={adapterNameList}
/>
</Form.Item>
</Form>
{
showDynamicForm &&
<DynamicFormComponent
form={dynamicForm}
itemConfigList={dynamicFormConfigList}
onSubmit={onDynamicFormSubmit}
/>
}
<Space>
{
!initBotId &&
<Button
type="primary"
htmlType="button"
onClick={handleSubmitButton}
>
</Button>
}
{
initBotId &&
<Button
type="primary"
htmlType="submit"
onClick={handleSaveButton}
>
</Button>
}
<Button htmlType="button" onClick={() => {
onFormCancel(form.getFieldsValue())
}}>
</Button>
</Space>
</div>
)
}
@@ -0,0 +1,20 @@
export interface IBotFormEntity {
name: string,
description: string,
adapter: string,
adapter_config: object;
}
export class BotFormEntity implements IBotFormEntity {
adapter: string;
description: string;
name: string;
adapter_config: object;
constructor(props: IBotFormEntity) {
this.adapter = props.adapter;
this.description = props.description;
this.name = props.name;
this.adapter_config = props.adapter_config;
}
}
@@ -0,0 +1,4 @@
export interface IChooseAdapterEntity {
label: string
value: string
}
+150
View File
@@ -0,0 +1,150 @@
"use client"
import {useEffect, useState} from "react";
import styles from "./botConfig.module.css";
import EmptyAndCreateComponent from "@/app/home/components/empty-and-create-component/EmptyAndCreateComponent";
import {useRouter} from "next/navigation";
import {BotCardVO} from "@/app/home/bots/components/bot-card/BotCardVO";
import {Modal} from "antd";
import BotForm from "@/app/home/bots/components/bot-form/BotForm";
import BotCard from "@/app/home/bots/components/bot-card/BotCard";
import CreateCardComponent from "@/app/infra/basic-component/create-card-component/CreateCardComponent"
export default function BotConfigPage() {
const router = useRouter();
const [pageShowRule, setPageShowRule] = useState<BotConfigPageShowRule>(BotConfigPageShowRule.NO_BOT)
const [modalOpen, setModalOpen] = useState<boolean>(false);
const [botList, setBotList] = useState<BotCardVO[]>([])
const [isEditForm, setIsEditForm] = useState(false)
const [nowSelectedBotCard, setNowSelectedBotCard] = useState<BotCardVO>()
useEffect(() => {
// TODO:补齐加载转圈逻辑
checkHasLLM().then((hasLLM) => {
if (hasLLM) {
const botList = getBotList()
if (botList.length === 0) {
setPageShowRule(BotConfigPageShowRule.NO_BOT)
} else {
setPageShowRule(BotConfigPageShowRule.HAVE_BOT)
}
setBotList(botList)
} else {
setPageShowRule(BotConfigPageShowRule.NO_LLM)
}
})
}, [])
async function checkHasLLM(): Promise<boolean> {
// NOT IMPL
return true
}
function getBotList(): BotCardVO[] {
let botList: BotCardVO[] = [
new BotCardVO({
adapter: "QQ bot",
description: "1111",
id: "1111",
name: "第一个bot",
updateTime: "202300001111",
pipelineName: "默认流水线",
}),
new BotCardVO({
adapter: "WX bot",
description: "22211",
id: "2222",
name: "第2个bot",
updateTime: "2025011011",
pipelineName: "默认流水线",
}),
]
// botList = []
return botList
}
function handleCreateBotClick() {
setIsEditForm(false)
setNowSelectedCard(undefined)
setModalOpen(true);
}
function setNowSelectedCard(cardVO: BotCardVO | undefined) {
setNowSelectedBotCard(cardVO)
}
function selectBot(cardVO: BotCardVO) {
setIsEditForm(true)
setNowSelectedCard(cardVO)
console.log("set now vo", cardVO)
setModalOpen(true)
}
return (
<div className={styles.configPageContainer}>
<Modal
title={isEditForm ? "编辑机器人" : "创建机器人"}
centered
open={modalOpen}
onOk={() => setModalOpen(false)}
onCancel={() => setModalOpen(false)}
width={700}
footer={null}
destroyOnClose={true}
>
<BotForm
initBotId={nowSelectedBotCard?.id}
onFormSubmit={() => setIsEditForm(false)}
onFormCancel={() => setModalOpen(false)}
/>
</Modal>
{pageShowRule === BotConfigPageShowRule.NO_LLM &&
<EmptyAndCreateComponent
title={"需要先创建大模型才能配置机器人哦~"}
subTitle={"快去创建一个吧!"}
buttonText={"创建大模型 GO"}
onButtonClick={() => {
router.push("/home/models");
}}
/>
}
{pageShowRule === BotConfigPageShowRule.NO_BOT &&
<EmptyAndCreateComponent
title={"您还未配置机器人哦~"}
subTitle={"快去创建一个吧!"}
buttonText={"创建机器人 +"}
onButtonClick={handleCreateBotClick}
/>
}
{pageShowRule === BotConfigPageShowRule.HAVE_BOT &&
<div className={`${styles.botListContainer}`}
>
{botList.map(cardVO => {
return (
<div
key={cardVO.id}
onClick={() => {selectBot(cardVO)}}
>
<BotCard botCardVO={cardVO} />
</div>)
})}
<CreateCardComponent
width={360}
height={200}
plusSize={90}
onClick={handleCreateBotClick}
/>
</div>
}
</div>
)
}
enum BotConfigPageShowRule {
NO_LLM,
NO_BOT,
HAVE_BOT,
}