商品二维码上传改为黏贴上传
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 [addDialog, setAddDialog] = useState(null);
|
||||||
const [publishOpen, setPublishOpen] = useState(false);
|
const [publishOpen, setPublishOpen] = useState(false);
|
||||||
const [linkCopied, setLinkCopied] = useState(false);
|
const [linkCopied, setLinkCopied] = useState(false);
|
||||||
|
const productQrPasteRef = useRef(null);
|
||||||
const processingLibrarySelection = useRef(false);
|
const processingLibrarySelection = useRef(false);
|
||||||
const consumedLibrarySelectionKey = useRef("");
|
const consumedLibrarySelectionKey = useRef("");
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -160,6 +161,35 @@ export default function CreateAskTasksPage({ api, librarySelection = [], onLibra
|
|||||||
if (productQrInputRef.current) productQrInputRef.current.value = "";
|
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() {
|
function clearAll() {
|
||||||
if (busy) return;
|
if (busy) return;
|
||||||
clearPageCache("create-ask-task");
|
clearPageCache("create-ask-task");
|
||||||
@ -814,12 +844,21 @@ export default function CreateAskTasksPage({ api, librarySelection = [], onLibra
|
|||||||
{form.product_qr_image ? (
|
{form.product_qr_image ? (
|
||||||
<div className="ask-product-qr-preview">
|
<div className="ask-product-qr-preview">
|
||||||
<img src={form.product_qr_image} alt="商品二维码预览" />
|
<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>
|
</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>
|
</div>
|
||||||
<label>
|
<label>
|
||||||
每个用户可领取问题数 *
|
每个用户可领取问题数 *
|
||||||
|
|||||||
@ -84,6 +84,10 @@ function TaskDetail({ task, close, onConfirmRefund, onCreateRefundUpload, onPoll
|
|||||||
setRefundFileError("");
|
setRefundFileError("");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
function clearRefundProofFile() {
|
||||||
|
setRefundFile(null);
|
||||||
|
setRefundFileError("");
|
||||||
|
}
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!refundOpen || refundSession || !task.refund_endpoint) return undefined;
|
if (!refundOpen || refundSession || !task.refund_endpoint) return undefined;
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
@ -422,6 +426,15 @@ function TaskDetail({ task, close, onConfirmRefund, onCreateRefundUpload, onPoll
|
|||||||
<span>剪贴板粘贴上传(可选)</span>
|
<span>剪贴板粘贴上传(可选)</span>
|
||||||
<strong>{refundFile ? "图片已粘贴,可直接确认" : "复制图片后,按 Ctrl+V 粘贴"}</strong>
|
<strong>{refundFile ? "图片已粘贴,可直接确认" : "复制图片后,按 Ctrl+V 粘贴"}</strong>
|
||||||
<small>{refundFile ? `${refundFile.name} · ${(refundFile.size / 1024).toFixed(0)}KB` : "支持 JPG、PNG、WEBP,最大 10MB"}</small>
|
<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>}
|
{refundFileError && <em>{refundFileError}</em>}
|
||||||
</div>
|
</div>
|
||||||
<label className="refund-proof-fallback">
|
<label className="refund-proof-fallback">
|
||||||
|
|||||||
@ -2929,6 +2929,20 @@
|
|||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-style: normal;
|
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 {
|
.refund-proof-fallback {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
@ -5148,6 +5162,11 @@
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
cursor: pointer;
|
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 {
|
.ask-product-qr-upload small {
|
||||||
color: #8296ad;
|
color: #8296ad;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user