114 lines
4.4 KiB
TypeScript
114 lines
4.4 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog';
|
|
import type { Body_create_model_api_models_create_post } from '@/api/models/Body_create_model_api_models_create_post';
|
|
import type { Body_update_model_api_models__model_id__put } from '@/api/models/Body_update_model_api_models__model_id__put';
|
|
import ModelForm from './components/ModelForm';
|
|
import { api } from '@/lib/api';
|
|
import { ConfirmDialog } from '@/components/block/confirm-dialog';
|
|
|
|
interface ModelItem {
|
|
id: number;
|
|
tag: Record<string, string>;
|
|
cover_url: string;
|
|
status: number;
|
|
create_time: string;
|
|
}
|
|
|
|
const ModelPage: React.FC = () => {
|
|
const [models, setModels] = useState<ModelItem[]>([]);
|
|
const [_, setLoading] = useState(false);
|
|
const [selected, setSelected] = useState<ModelItem | null>(null);
|
|
const [open, setOpen] = useState(false);
|
|
const [editMode, setEditMode] = useState(false);
|
|
|
|
const fetchModels = async () => {
|
|
setLoading(true);
|
|
try {
|
|
const res = await api.Service.getModelsListApiModelsListGet({});
|
|
setModels(res.data || []);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchModels();
|
|
}, []);
|
|
|
|
const handleAdd = () => {
|
|
setEditMode(false);
|
|
setSelected(null);
|
|
setOpen(true);
|
|
};
|
|
|
|
const handleEdit = (item: ModelItem) => {
|
|
setEditMode(true);
|
|
setSelected(item);
|
|
setOpen(true);
|
|
};
|
|
|
|
const handleDelete = async (id: number) => {
|
|
ConfirmDialog.confirm({
|
|
content: '确定要删除该模特吗?',
|
|
onConfirm: async () => {
|
|
await api.Service.deleteModelApiModelsModelIdDelete({ modelId: id });
|
|
fetchModels();
|
|
},
|
|
});
|
|
};
|
|
|
|
const handleFormSubmit = async (data: Body_create_model_api_models_create_post | Body_update_model_api_models__model_id__put, id?: number) => {
|
|
console.log(data);
|
|
if (editMode && id) {
|
|
await api.Service.updateModelApiModelsModelIdPut({ modelId: id, formData: data as Body_update_model_api_models__model_id__put });
|
|
} else {
|
|
await api.Service.createModelApiModelsCreatePost({ formData: data as Body_create_model_api_models_create_post });
|
|
}
|
|
setOpen(false);
|
|
fetchModels();
|
|
};
|
|
|
|
return (
|
|
<div className='p-6'>
|
|
<div className='flex justify-between items-center mb-4'>
|
|
<h1 className='text-2xl font-bold'>模特维护</h1>
|
|
<Button onClick={handleAdd}>新建模特</Button>
|
|
</div>
|
|
<div className='grid gap-6 grid-cols-[repeat(auto-fit,minmax(500px,500px))]'>
|
|
{models.map(item => (
|
|
<div key={item.id} className='w-[500px] bg-white dark:bg-zinc-900 rounded-lg shadow p-4 flex gap-3'>
|
|
<img src={item.cover_url} alt='cover' className='w-[200px] object-cover rounded aspect-[9/16]' />
|
|
<div className='flex-1 flex flex-col gap-2'>
|
|
<div className='flex-1 flex flex-col gap-1'>
|
|
<div className='text-sm text-muted-foreground'>ID: {item.id}</div>
|
|
<div className='text-sm truncate'>标签: {Object.values(item.tag).join('_')}</div>
|
|
<div className='text-sm'>
|
|
状态: <span className={item.status === 1 ? 'text-green-600' : 'text-red-500'}>{item.status === 1 ? '启用' : '禁用'}</span>
|
|
</div>
|
|
<div className='text-xs text-muted-foreground'>创建时间: {item.create_time}</div>
|
|
</div>
|
|
<div className='mt-4 flex flex-col gap-2'>
|
|
<Button variant='outline' onClick={() => handleEdit(item)} className='flex-1'>
|
|
编辑
|
|
</Button>
|
|
<Button variant='destructive' onClick={() => handleDelete(item.id)} className='flex-1' disabled={item.status === 1}>
|
|
删除
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<Dialog open={open} onOpenChange={setOpen}>
|
|
<DialogContent style={{ width: '650px', maxWidth: '650px' }}>
|
|
<DialogTitle>{editMode ? '编辑模特' : '新建模特'}</DialogTitle>
|
|
<ModelForm initialData={selected} onSubmit={handleFormSubmit} onCancel={() => setOpen(false)} editMode={editMode} />
|
|
</DialogContent>
|
|
</Dialog>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ModelPage;
|