fix: 5项交互修复 - 删除图片恢复虚线框、prompt文案统一、移除overflow、多选输入解耦、label加可多选

This commit is contained in:
2026-04-17 21:19:20 +08:00
parent 28b913692c
commit 8f746c25f3
3 changed files with 88 additions and 26 deletions

View File

@@ -60,6 +60,7 @@ export default function ReportEditor() {
});
const [anesthesiaOptions, setAnesthesiaOptions] = useState<string[]>(['全麻', '局麻', '腰麻', '硬膜外麻醉', '静脉麻醉', '吸入麻醉']);
const [openDropdown, setOpenDropdown] = useState<string | null>(null);
const [multiInputText, setMultiInputText] = useState<Record<string, string>>({});
const [touched, setTouched] = useState<Record<string, boolean>>({});
const [formFields, setFormFields] = useState<FormField[]>([]);
const [imagePickerOpen, setImagePickerOpen] = useState(false);
@@ -307,6 +308,8 @@ export default function ReportEditor() {
<span class="delete-btn" contenteditable="false">×</span>
<span class="placeholder-text" style="color:#94a3b8;font-size:11px;pointer-events:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;">插入/点击放置图片</span>
`;
placeholder.style.border = '1px dashed #cbd5e1';
placeholder.style.background = '#f8fafc';
if (editorRef.current) contentRef.current = editorRef.current.innerHTML;
saveDraftToStorage();
} else {
@@ -423,24 +426,23 @@ export default function ReportEditor() {
const insertImage = () => {
editorRef.current?.focus();
const input = prompt('请输入占位符的最大宽度和高度(px),用英文逗号分隔(如: 100,50。留空则默认宽高为 200*200。(提示: 正文一行文字高度约为 20 像素左右)', '');
if (input === null) return;
const parts = input.split(',').map(s => s.trim());
const widthStr = parts[0] || '';
const heightStr = parts[1] || '';
let width = parseInt(widthStr) || 0;
let height = parseInt(heightStr) || 0;
if (!widthStr && !heightStr) {
width = 200;
height = 200;
} else if (widthStr && !heightStr) {
height = 200;
} else if (!widthStr && heightStr) {
width = 200;
let width = 200;
let height = 200;
while (true) {
const input = prompt('请输入占位符的最大宽度和高度(px),用*号分隔(如: 100*50。留空则默认宽高为 200*200。(提示: 正文一行文字高度约为 20 像素左右)', '');
if (input === null) return;
const trimmed = input.trim();
if (trimmed === '') break;
const parts = trimmed.split('*').map(s => s.trim());
if (parts.length === 2 && /^\d+$/.test(parts[0]) && /^\d+$/.test(parts[1])) {
width = parseInt(parts[0]) || 0;
height = parseInt(parts[1]) || 0;
break;
}
alert('格式错误,请确保使用 * 分隔两个数字,例如 100*50');
}
let styleStr = 'display:inline-flex;align-items:center;justify-content:center;border:1px dashed #cbd5e1;background:#f8fafc;vertical-align:middle;margin:0 4px;cursor:pointer;overflow:hidden;';
let styleStr = 'display:inline-flex;align-items:center;justify-content:center;border:1px dashed #cbd5e1;background:#f8fafc;vertical-align:middle;margin:0 4px;cursor:pointer;';
if (width > 0) styleStr += `width:${width}px;`;
if (height > 0) styleStr += `height:${height}px;`;
@@ -1301,16 +1303,13 @@ export default function ReportEditor() {
return Array.from(new Set(text.split(/[,;;、]/).map(s => s.trim()).filter(Boolean)));
};
const handleMultiChange = (text: string) => {
const handleMultiCommit = (text: string) => {
const values = parseMultiInput(text);
const next = { ...reportData, [field.key]: values };
setReportData(next);
stateRef.current = { ...stateRef.current, reportData: next };
saveDraftToStorage();
};
const handleMultiCommit = (text: string) => {
const values = parseMultiInput(text);
const currentOpts = field.options || multiSelectOptions[field.key] || [];
const newOpts = values.filter(v => !currentOpts.includes(v));
if (newOpts.length > 0) {
@@ -1327,9 +1326,11 @@ export default function ReportEditor() {
}
};
const currentInputText = multiInputText[field.key] !== undefined ? multiInputText[field.key] : displayText;
return (
<div key={field.key} className="space-y-1 select-dropdown-root relative">
<label className="block text-xs font-bold text-text-main">{field.label}</label>
<label className="block text-xs font-bold text-text-main">{field.label}</label>
<div
className="w-full px-3 py-2 border border-border rounded-lg bg-white flex flex-wrap gap-1 items-center min-h-[42px] cursor-text"
onClick={() => setOpenDropdown(field.key)}
@@ -1338,14 +1339,28 @@ export default function ReportEditor() {
type="text"
className="outline-none text-sm w-full bg-transparent"
placeholder="输入或选择,多个用逗号分隔"
value={displayText}
onChange={(e) => handleMultiChange(e.target.value)}
value={currentInputText}
onChange={(e) => {
setMultiInputText(prev => ({ ...prev, [field.key]: e.target.value }));
}}
onFocus={() => setOpenDropdown(field.key)}
onBlur={(e) => handleMultiCommit(e.target.value)}
onBlur={(e) => {
handleMultiCommit(e.target.value);
setMultiInputText(prev => {
const next = { ...prev };
delete next[field.key];
return next;
});
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
handleMultiCommit((e.target as HTMLInputElement).value);
setMultiInputText(prev => {
const next = { ...prev };
delete next[field.key];
return next;
});
}
}}
/>
@@ -1357,9 +1372,15 @@ export default function ReportEditor() {
key={opt}
className="px-3 py-2 text-sm hover:bg-slate-50 cursor-pointer flex justify-between items-center"
onClick={() => {
const newText = currentValues.length > 0 ? `${displayText}, ${opt}` : opt;
handleMultiChange(newText);
const base = multiInputText[field.key] !== undefined ? multiInputText[field.key] : displayText;
const newText = base.length > 0 ? `${base}, ${opt}` : opt;
setMultiInputText(prev => ({ ...prev, [field.key]: newText }));
handleMultiCommit(newText);
setMultiInputText(prev => {
const next = { ...prev };
delete next[field.key];
return next;
});
}}
>
<span>{opt}</span>

View File

@@ -183,6 +183,8 @@ export default function TemplateManage() {
<span class="delete-btn" contenteditable="false">×</span>
<span class="placeholder-text" style="color:#94a3b8;font-size:11px;pointer-events:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;">插入/点击放置图片</span>
`;
placeholder.style.border = '1px dashed #cbd5e1';
placeholder.style.background = '#f8fafc';
} else {
const range = document.createRange();
range.selectNode(placeholder);