商品二维码上传改为黏贴上传
This commit is contained in:
parent
68b59d2eab
commit
86a1a33693
@ -79,6 +79,7 @@ export default function CreateAskTasksPage({ api, librarySelection = [], onLibra
|
||||
const [addDialog, setAddDialog] = useState(null);
|
||||
const [publishOpen, setPublishOpen] = useState(false);
|
||||
const [linkCopied, setLinkCopied] = useState(false);
|
||||
const productQrPasteRef = useRef(null);
|
||||
const processingLibrarySelection = useRef(false);
|
||||
const consumedLibrarySelectionKey = useRef("");
|
||||
useEffect(() => {
|
||||
@ -160,6 +161,35 @@ export default function CreateAskTasksPage({ api, librarySelection = [], onLibra
|
||||
if (productQrInputRef.current) productQrInputRef.current.value = "";
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!publishOpen) return undefined;
|
||||
const pasteProductQr = (event) => {
|
||||
const imageItem = Array.from(event.clipboardData?.items || []).find((item) =>
|
||||
item.kind === "file" && item.type.startsWith("image/"),
|
||||
);
|
||||
if (!imageItem) return;
|
||||
const blob = imageItem.getAsFile?.();
|
||||
if (!blob) {
|
||||
setError("读取剪贴板图片失败,请重新复制后再试");
|
||||
return;
|
||||
}
|
||||
const extension = blob.type === "image/jpeg" ? "jpg" : blob.type.split("/")[1] || "png";
|
||||
const pastedFile = new File(
|
||||
[blob],
|
||||
`product-qr-${Date.now()}.${extension}`,
|
||||
{ type: blob.type, lastModified: Date.now() },
|
||||
);
|
||||
event.preventDefault();
|
||||
selectProductQr(pastedFile);
|
||||
};
|
||||
window.addEventListener("paste", pasteProductQr);
|
||||
const focusTimer = window.setTimeout(() => productQrPasteRef.current?.focus(), 0);
|
||||
return () => {
|
||||
window.clearTimeout(focusTimer);
|
||||
window.removeEventListener("paste", pasteProductQr);
|
||||
};
|
||||
}, [publishOpen]);
|
||||
|
||||
function clearAll() {
|
||||
if (busy) return;
|
||||
clearPageCache("create-ask-task");
|
||||
@ -814,12 +844,21 @@ export default function CreateAskTasksPage({ api, librarySelection = [], onLibra
|
||||
{form.product_qr_image ? (
|
||||
<div className="ask-product-qr-preview">
|
||||
<img src={form.product_qr_image} alt="商品二维码预览" />
|
||||
<div><strong>{form.product_qr_image_name || "商品二维码"}</strong><small>已上传商品二维码</small><button type="button" className="ghost-button" onClick={clearProductQr}>移除二维码</button></div>
|
||||
<div><strong>{form.product_qr_image_name || "商品二维码"}</strong><small>已上传商品二维码,可粘贴图片替换</small><button type="button" className="ghost-button" onClick={clearProductQr}>移除二维码</button></div>
|
||||
</div>
|
||||
) : (
|
||||
<button type="button" className="ask-product-qr-upload" onClick={() => productQrInputRef.current?.click()}><span>+ 上传商品二维码</span><small>支持 JPG、PNG、WEBP,单张不超过 5MB</small></button>
|
||||
<button
|
||||
ref={productQrPasteRef}
|
||||
type="button"
|
||||
className="ask-product-qr-upload"
|
||||
onClick={() => productQrInputRef.current?.click()}
|
||||
aria-label="粘贴或选择商品二维码"
|
||||
>
|
||||
<span>+ 粘贴或上传商品二维码</span>
|
||||
<small>复制图片后按 Ctrl+V 粘贴,也可选择 JPG、PNG、WEBP,单张不超过 5MB</small>
|
||||
</button>
|
||||
)}
|
||||
<small className="ask-product-token-hint">淘口令和二维码至少填写一种,也可以两者都填写</small>
|
||||
<small className="ask-product-token-hint">淘口令和二维码至少填写一种,也可以两者都填写;复制二维码图片后可直接按 Ctrl+V 粘贴</small>
|
||||
</div>
|
||||
<label>
|
||||
每个用户可领取问题数 *
|
||||
|
||||
@ -84,6 +84,10 @@ function TaskDetail({ task, close, onConfirmRefund, onCreateRefundUpload, onPoll
|
||||
setRefundFileError("");
|
||||
return true;
|
||||
}
|
||||
function clearRefundProofFile() {
|
||||
setRefundFile(null);
|
||||
setRefundFileError("");
|
||||
}
|
||||
useEffect(() => {
|
||||
if (!refundOpen || refundSession || !task.refund_endpoint) return undefined;
|
||||
let cancelled = false;
|
||||
@ -422,6 +426,15 @@ function TaskDetail({ task, close, onConfirmRefund, onCreateRefundUpload, onPoll
|
||||
<span>剪贴板粘贴上传(可选)</span>
|
||||
<strong>{refundFile ? "图片已粘贴,可直接确认" : "复制图片后,按 Ctrl+V 粘贴"}</strong>
|
||||
<small>{refundFile ? `${refundFile.name} · ${(refundFile.size / 1024).toFixed(0)}KB` : "支持 JPG、PNG、WEBP,最大 10MB"}</small>
|
||||
{refundFile && (
|
||||
<button
|
||||
type="button"
|
||||
className="refund-proof-remove"
|
||||
onClick={clearRefundProofFile}
|
||||
>
|
||||
移除图片
|
||||
</button>
|
||||
)}
|
||||
{refundFileError && <em>{refundFileError}</em>}
|
||||
</div>
|
||||
<label className="refund-proof-fallback">
|
||||
|
||||
@ -2929,6 +2929,20 @@
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
}
|
||||
.refund-proof-remove {
|
||||
justify-self: start;
|
||||
padding: 3px 7px;
|
||||
border: 1px solid #f0b7c0;
|
||||
border-radius: 6px;
|
||||
background: #fff5f6;
|
||||
color: #d23850;
|
||||
font-size: 11px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.refund-proof-remove:hover {
|
||||
border-color: #d23850;
|
||||
background: #ffecef;
|
||||
}
|
||||
.refund-proof-fallback {
|
||||
display: inline-flex;
|
||||
justify-content: flex-start;
|
||||
@ -5148,6 +5162,11 @@
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
}
|
||||
.ask-product-qr-upload:focus {
|
||||
border-color: #1764e8;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 3px rgba(23, 100, 232, .1);
|
||||
}
|
||||
.ask-product-qr-upload small {
|
||||
color: #8296ad;
|
||||
font-size: 10px;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user