| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | import React from 'react'; |
| | import { Input, Typography, Button, Switch } from '@douyinfe/semi-ui'; |
| | import { IconFile } from '@douyinfe/semi-icons'; |
| | import { FileText, Plus, X, Image } from 'lucide-react'; |
| |
|
| | const ImageUrlInput = ({ |
| | imageUrls, |
| | imageEnabled, |
| | onImageUrlsChange, |
| | onImageEnabledChange, |
| | disabled = false, |
| | }) => { |
| | const handleAddImageUrl = () => { |
| | const newUrls = [...imageUrls, '']; |
| | onImageUrlsChange(newUrls); |
| | }; |
| |
|
| | const handleUpdateImageUrl = (index, value) => { |
| | const newUrls = [...imageUrls]; |
| | newUrls[index] = value; |
| | onImageUrlsChange(newUrls); |
| | }; |
| |
|
| | const handleRemoveImageUrl = (index) => { |
| | const newUrls = imageUrls.filter((_, i) => i !== index); |
| | onImageUrlsChange(newUrls); |
| | }; |
| |
|
| | return ( |
| | <div className={disabled ? 'opacity-50' : ''}> |
| | <div className='flex items-center justify-between mb-2'> |
| | <div className='flex items-center gap-2'> |
| | <Image |
| | size={16} |
| | className={ |
| | imageEnabled && !disabled ? 'text-blue-500' : 'text-gray-400' |
| | } |
| | /> |
| | <Typography.Text strong className='text-sm'> |
| | 图片地址 |
| | </Typography.Text> |
| | {disabled && ( |
| | <Typography.Text className='text-xs text-orange-600'> |
| | (已在自定义模式中忽略) |
| | </Typography.Text> |
| | )} |
| | </div> |
| | <div className='flex items-center gap-2'> |
| | <Switch |
| | checked={imageEnabled} |
| | onChange={onImageEnabledChange} |
| | checkedText='启用' |
| | uncheckedText='停用' |
| | size='small' |
| | className='flex-shrink-0' |
| | disabled={disabled} |
| | /> |
| | <Button |
| | icon={<Plus size={14} />} |
| | size='small' |
| | theme='solid' |
| | type='primary' |
| | onClick={handleAddImageUrl} |
| | className='!rounded-full !w-4 !h-4 !p-0 !min-w-0' |
| | disabled={!imageEnabled || disabled} |
| | /> |
| | </div> |
| | </div> |
| | |
| | {!imageEnabled ? ( |
| | <Typography.Text className='text-xs text-gray-500 mb-2 block'> |
| | {disabled |
| | ? '图片功能在自定义请求体模式下不可用' |
| | : '启用后可添加图片URL进行多模态对话'} |
| | </Typography.Text> |
| | ) : imageUrls.length === 0 ? ( |
| | <Typography.Text className='text-xs text-gray-500 mb-2 block'> |
| | {disabled |
| | ? '图片功能在自定义请求体模式下不可用' |
| | : '点击 + 按钮添加图片URL进行多模态对话'} |
| | </Typography.Text> |
| | ) : ( |
| | <Typography.Text className='text-xs text-gray-500 mb-2 block'> |
| | 已添加 {imageUrls.length} 张图片 |
| | {disabled ? ' (自定义模式下不可用)' : ''} |
| | </Typography.Text> |
| | )} |
| | |
| | <div |
| | className={`space-y-2 max-h-32 overflow-y-auto image-list-scroll ${!imageEnabled || disabled ? 'opacity-50' : ''}`} |
| | > |
| | {imageUrls.map((url, index) => ( |
| | <div key={index} className='flex items-center gap-2'> |
| | <div className='flex-1'> |
| | <Input |
| | placeholder={`https://example.com/image${index + 1}.jpg`} |
| | value={url} |
| | onChange={(value) => handleUpdateImageUrl(index, value)} |
| | className='!rounded-lg' |
| | size='small' |
| | prefix={<IconFile size='small' />} |
| | disabled={!imageEnabled || disabled} |
| | /> |
| | </div> |
| | <Button |
| | icon={<X size={12} />} |
| | size='small' |
| | theme='borderless' |
| | type='danger' |
| | onClick={() => handleRemoveImageUrl(index)} |
| | className='!rounded-full !w-6 !h-6 !p-0 !min-w-0 !text-red-500 hover:!bg-red-50 flex-shrink-0' |
| | disabled={!imageEnabled || disabled} |
| | /> |
| | </div> |
| | ))} |
| | </div> |
| | </div> |
| | ); |
| | }; |
| |
|
| | export default ImageUrlInput; |
| |
|