素材云批量提交
This commit is contained in:
@@ -431,7 +431,10 @@ export async function getOpenTypeList(params?: {
|
||||
page_size?: number;
|
||||
type_name?: string;
|
||||
open_type?: number;
|
||||
}): Promise<{ total: number; items: any[] }> {
|
||||
}): Promise<{
|
||||
pagination: any;
|
||||
data: never[];
|
||||
}> {
|
||||
const q = new URLSearchParams();
|
||||
if (params?.page) q.set('page', String(params.page));
|
||||
if (params?.page_size) q.set('page_size', String(params.page_size));
|
||||
|
||||
@@ -10,8 +10,8 @@ import { formatDate } from '../utils/formatDate';
|
||||
|
||||
interface OpenType {
|
||||
id: string;
|
||||
open_type: number;
|
||||
type_name: string;
|
||||
openType: number;
|
||||
typeName: string;
|
||||
description: string;
|
||||
thumb?: string;
|
||||
createdAt: string;
|
||||
@@ -49,6 +49,8 @@ const AdminPlatform: React.FC = () => {
|
||||
const [detailModalVisible, setDetailModalVisible] = useState(false);
|
||||
const [updateModalVisible, setUpdateModalVisible] = useState(false);
|
||||
const [currentOpenType, setCurrentOpenType] = useState<OpenType | null>(null);
|
||||
const [createThumbUrl, setCreateThumbUrl] = useState('');
|
||||
const [updateThumbUrl, setUpdateThumbUrl] = useState('');
|
||||
|
||||
const [createForm] = Form.useForm();
|
||||
const [updateForm] = Form.useForm();
|
||||
@@ -60,8 +62,8 @@ const AdminPlatform: React.FC = () => {
|
||||
page: p || page,
|
||||
page_size: ps || pageSize,
|
||||
});
|
||||
setOpenTypes(res.items || []);
|
||||
setTotal(res.total || 0);
|
||||
setOpenTypes(res.data || []);
|
||||
setTotal(res.pagination.total || 0);
|
||||
} catch {
|
||||
message.error('加载开户方式列表失败');
|
||||
} finally {
|
||||
@@ -76,16 +78,16 @@ const AdminPlatform: React.FC = () => {
|
||||
const handleCreate = async () => {
|
||||
try {
|
||||
const values = await createForm.validateFields();
|
||||
console.log(values);
|
||||
await createOpenType({
|
||||
open_type: values.open_type,
|
||||
type_name: values.type_name,
|
||||
description: values.description,
|
||||
thumb: values.thumb,
|
||||
thumb: createThumbUrl,
|
||||
});
|
||||
message.success('创建成功');
|
||||
setCreateModalVisible(false);
|
||||
createForm.resetFields();
|
||||
setCreateThumbUrl('');
|
||||
load();
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || '创建失败');
|
||||
@@ -95,7 +97,7 @@ const AdminPlatform: React.FC = () => {
|
||||
const handleDetail = async (id: string) => {
|
||||
try {
|
||||
const openType = await getOpenType(id);
|
||||
setCurrentOpenType(openType);
|
||||
setCurrentOpenType(openType.data || {});
|
||||
setDetailModalVisible(true);
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || '获取详情失败');
|
||||
@@ -105,19 +107,14 @@ const AdminPlatform: React.FC = () => {
|
||||
const handleUpdate = async (id: string) => {
|
||||
try {
|
||||
const openType = await getOpenType(id);
|
||||
setCurrentOpenType(openType);
|
||||
updateForm.setFieldsValue({
|
||||
open_type: openType.open_type,
|
||||
type_name: openType.type_name,
|
||||
description: openType.description,
|
||||
thumb: openType.thumb,
|
||||
});
|
||||
setCurrentOpenType(openType.data || {});
|
||||
setUpdateThumbUrl(openType.thumb || '');
|
||||
setUpdateModalVisible(true);
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || '获取详情失败');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const handleSaveUpdate = async () => {
|
||||
if (!currentOpenType) return;
|
||||
try {
|
||||
@@ -126,12 +123,13 @@ const AdminPlatform: React.FC = () => {
|
||||
open_type: values.open_type,
|
||||
type_name: values.type_name,
|
||||
description: values.description,
|
||||
thumb: values.thumb,
|
||||
thumb: updateThumbUrl,
|
||||
});
|
||||
message.success('更新成功');
|
||||
setUpdateModalVisible(false);
|
||||
updateForm.resetFields();
|
||||
setCurrentOpenType(null);
|
||||
setUpdateThumbUrl('');
|
||||
load();
|
||||
} catch (e: any) {
|
||||
message.error(e?.message || '更新失败');
|
||||
@@ -166,13 +164,13 @@ const AdminPlatform: React.FC = () => {
|
||||
},
|
||||
{
|
||||
title: '开户类型',
|
||||
dataIndex: 'open_type',
|
||||
dataIndex: 'openType',
|
||||
width: 100,
|
||||
render: (v: number) => <Typography.Text>{v}</Typography.Text>,
|
||||
},
|
||||
{
|
||||
title: '类型名称',
|
||||
dataIndex: 'type_name',
|
||||
dataIndex: 'typeName',
|
||||
width: 150,
|
||||
render: (v: string) => <Typography.Text strong>{v}</Typography.Text>,
|
||||
},
|
||||
@@ -191,9 +189,12 @@ const AdminPlatform: React.FC = () => {
|
||||
title: '缩略图',
|
||||
dataIndex: 'thumb',
|
||||
width: 120,
|
||||
render: (v: string) => (
|
||||
v ? <img src={v} alt="thumb" style={{ width: 80, height: 60, objectFit: 'cover' }} /> : '-'
|
||||
),
|
||||
render: (v: string) => {
|
||||
if (!v) return '-';
|
||||
const baseUrl = import.meta.env.VITE_API_BASE || 'http://localhost:8000';
|
||||
const fullUrl = v.startsWith('http') ? v : `${baseUrl}${v}`;
|
||||
return <img src={fullUrl} alt="thumb" style={{ width: 80, height: 60, objectFit: 'cover' }} />;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
@@ -291,7 +292,9 @@ const AdminPlatform: React.FC = () => {
|
||||
onCancel={() => {
|
||||
setCreateModalVisible(false);
|
||||
createForm.resetFields();
|
||||
setCreateThumbUrl('');
|
||||
}}
|
||||
mask={{ closable: false }}
|
||||
okText="创建"
|
||||
cancelText="取消"
|
||||
width={600}
|
||||
@@ -326,28 +329,28 @@ const AdminPlatform: React.FC = () => {
|
||||
>
|
||||
<Input.TextArea placeholder="请输入描述" rows={4} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="thumb"
|
||||
label="缩略图"
|
||||
>
|
||||
<Form.Item label="缩略图">
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
fileList={createThumbUrl ? [{ uid: '1', name: 'thumb', status: 'done', url: createThumbUrl }] : []}
|
||||
customRequest={async ({ file, onSuccess, onError }) => {
|
||||
try {
|
||||
const uploadFile = assertUploadFile(file);
|
||||
const res = await uploadImage(uploadFile);
|
||||
console.log(res);
|
||||
createForm.setFieldsValue({ thumb: res.url });
|
||||
setCreateThumbUrl(res.url);
|
||||
onSuccess?.({ url: res.url });
|
||||
} catch (e) {
|
||||
onError?.(normalizeUploadError(e));
|
||||
}
|
||||
}}
|
||||
onRemove={() => setCreateThumbUrl('')}
|
||||
>
|
||||
<div>
|
||||
<UploadOutlined style={{ fontSize: 24, color: '#999' }} />
|
||||
<div style={{ marginTop: 8 }}>上传图片</div>
|
||||
</div>
|
||||
{!createThumbUrl && (
|
||||
<div>
|
||||
<UploadOutlined style={{ fontSize: 24, color: '#999' }} />
|
||||
<div style={{ marginTop: 8 }}>上传图片</div>
|
||||
</div>
|
||||
)}
|
||||
</Upload>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
@@ -356,32 +359,68 @@ const AdminPlatform: React.FC = () => {
|
||||
<Modal
|
||||
title="开户方式详情"
|
||||
open={detailModalVisible}
|
||||
onOk={() => setDetailModalVisible(false)}
|
||||
onCancel={() => {
|
||||
setDetailModalVisible(false);
|
||||
setCurrentOpenType(null);
|
||||
}}
|
||||
mask={{ closable: false }}
|
||||
okText="关闭"
|
||||
cancelText="取消"
|
||||
width={600}
|
||||
width={520}
|
||||
>
|
||||
{currentOpenType && (
|
||||
<div style={{ lineHeight: '2' }}>
|
||||
<p><strong>ID:</strong> {currentOpenType.id}</p>
|
||||
<p><strong>开户类型:</strong> {currentOpenType.open_type}</p>
|
||||
<p><strong>类型名称:</strong> {currentOpenType.type_name}</p>
|
||||
<p><strong>描述:</strong> {currentOpenType.description}</p>
|
||||
<p>
|
||||
<strong>缩略图:</strong>{' '}
|
||||
{currentOpenType.thumb ? (
|
||||
<img
|
||||
src={currentOpenType.thumb}
|
||||
alt="thumb"
|
||||
style={{ width: 120, height: 80, objectFit: 'cover' }}
|
||||
/>
|
||||
) : '-'}
|
||||
</p>
|
||||
<p><strong>创建时间:</strong> {formatDate(currentOpenType.createdAt)}</p>
|
||||
<p><strong>更新时间:</strong> {formatDate(currentOpenType.updatedAt)}</p>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 16, background: '#f8fafc', borderRadius: 8 }}>
|
||||
<div style={{
|
||||
width: 80, height: 60, borderRadius: 6, overflow: 'hidden',
|
||||
background: currentOpenType.thumb ? 'transparent' : '#e2e8f0',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
}}>
|
||||
{currentOpenType.thumb ? (
|
||||
<img
|
||||
src={currentOpenType.thumb.startsWith('http') ? currentOpenType.thumb : `${import.meta.env.VITE_API_BASE || 'http://localhost:8000'}${currentOpenType.thumb}`}
|
||||
alt="thumb"
|
||||
style={{ width: '100%', height: '100%', objectFit: 'cover' }}
|
||||
/>
|
||||
) : (
|
||||
<Typography.Text type="secondary" style={{ fontSize: 12 }}>暂无图片</Typography.Text>
|
||||
)}
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontSize: 16, fontWeight: 600 }}>{currentOpenType.typeName}</div>
|
||||
<div style={{ fontSize: 12, color: '#64748b', marginTop: 4 }}>开户类型: {currentOpenType.openType}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
|
||||
<div style={{ display: 'flex', gap: 12 }}>
|
||||
<Typography.Text type="secondary" style={{ width: 80, flexShrink: 0 }}>ID</Typography.Text>
|
||||
<Typography.Text>{currentOpenType.id}</Typography.Text>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 12 }}>
|
||||
<Typography.Text type="secondary" style={{ width: 80, flexShrink: 0 }}>开户类型</Typography.Text>
|
||||
<Typography.Text>{currentOpenType.openType}</Typography.Text>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 12 }}>
|
||||
<Typography.Text type="secondary" style={{ width: 80, flexShrink: 0 }}>类型名称</Typography.Text>
|
||||
<Typography.Text>{currentOpenType.typeName}</Typography.Text>
|
||||
</div>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<Typography.Text type="secondary" style={{ width: 80 }}>描述</Typography.Text>
|
||||
<div style={{ padding: 12, background: '#f8fafc', borderRadius: 6, fontSize: 13, lineHeight: 1.6 }}>
|
||||
{currentOpenType.description || '-'}
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 12 }}>
|
||||
<Typography.Text type="secondary" style={{ width: 80, flexShrink: 0 }}>创建时间</Typography.Text>
|
||||
<Typography.Text>{formatDate(currentOpenType.createdAt)}</Typography.Text>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 12 }}>
|
||||
<Typography.Text type="secondary" style={{ width: 80, flexShrink: 0 }}>更新时间</Typography.Text>
|
||||
<Typography.Text>{formatDate(currentOpenType.updatedAt)}</Typography.Text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Modal>
|
||||
@@ -395,6 +434,16 @@ const AdminPlatform: React.FC = () => {
|
||||
updateForm.resetFields();
|
||||
setCurrentOpenType(null);
|
||||
}}
|
||||
afterOpenChange={(open) => {
|
||||
if (open && currentOpenType) {
|
||||
updateForm.setFieldsValue({
|
||||
open_type: currentOpenType.openType,
|
||||
type_name: currentOpenType.typeName,
|
||||
description: currentOpenType.description,
|
||||
});
|
||||
}
|
||||
}}
|
||||
mask={{ closable: false }}
|
||||
okText="更新"
|
||||
cancelText="取消"
|
||||
width={600}
|
||||
@@ -424,29 +473,23 @@ const AdminPlatform: React.FC = () => {
|
||||
>
|
||||
<Input.TextArea placeholder="请输入描述" rows={4} />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="thumb"
|
||||
label="缩略图"
|
||||
>
|
||||
<Form.Item label="缩略图">
|
||||
<Upload
|
||||
listType="picture-card"
|
||||
defaultFileList={
|
||||
currentOpenType?.thumb
|
||||
? [{ uid: '1', name: 'thumb', status: 'done', url: currentOpenType.thumb }]
|
||||
: []
|
||||
}
|
||||
fileList={updateThumbUrl ? [{ uid: '1', name: 'thumb', status: 'done', url: updateThumbUrl }] : []}
|
||||
customRequest={async ({ file, onSuccess, onError }) => {
|
||||
try {
|
||||
const uploadFile = assertUploadFile(file);
|
||||
const res = await uploadImage(uploadFile);
|
||||
updateForm.setFieldsValue({ thumb: res.url });
|
||||
setUpdateThumbUrl(res.url);
|
||||
onSuccess?.({ url: res.url });
|
||||
} catch (e) {
|
||||
onError?.(normalizeUploadError(e));
|
||||
}
|
||||
}}
|
||||
onRemove={() => setUpdateThumbUrl('')}
|
||||
>
|
||||
{!updateForm.getFieldValue('thumb') && (
|
||||
{!updateThumbUrl && (
|
||||
<div>
|
||||
<UploadOutlined style={{ fontSize: 24, color: '#999' }} />
|
||||
<div style={{ marginTop: 8 }}>上传图片</div>
|
||||
|
||||
Reference in New Issue
Block a user