feat(mini): v4.0.8 客服卡片主包落地、定位误报修复,合伙人微信内预览保存海报
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import PageHeader from '@dukang/shared-ui/PageHeader';
|
||||
import type { PartnerAssocSummary } from '@dukang/shared-types';
|
||||
import { request } from '../lib/api';
|
||||
import { toastError, toastSuccess } from '../lib/toast';
|
||||
import { isHttpImageUrl, previewSaveableImage } from '../lib/wechat-save-image';
|
||||
import { isWechatEnv } from '../lib/weixin';
|
||||
import { usePartnerPageView } from '../lib/usePageView';
|
||||
|
||||
@@ -11,7 +12,6 @@ export default function AssocQrcodePage() {
|
||||
usePartnerPageView('partner_assoc_qrcode_view');
|
||||
const navigate = useNavigate();
|
||||
const [summary, setSummary] = useState<PartnerAssocSummary | null>(null);
|
||||
const [previewUrl, setPreviewUrl] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -21,11 +21,12 @@ export default function AssocQrcodePage() {
|
||||
.finally(() => setLoading(false));
|
||||
}, []);
|
||||
|
||||
useEffect(() => () => {
|
||||
if (previewUrl) URL.revokeObjectURL(previewUrl);
|
||||
}, [previewUrl]);
|
||||
|
||||
async function downloadQr() {
|
||||
const publicUrl = summary?.qrcodeUrl;
|
||||
if (isWechatEnv() && isHttpImageUrl(publicUrl)) {
|
||||
await previewSaveableImage(publicUrl);
|
||||
return;
|
||||
}
|
||||
const token = localStorage.getItem('accessToken');
|
||||
try {
|
||||
const res = await fetch('/api/v1/partner/assoc/qrcode', {
|
||||
@@ -37,11 +38,6 @@ export default function AssocQrcodePage() {
|
||||
if (!res.ok) throw new Error('下载失败');
|
||||
const blob = await res.blob();
|
||||
const url = URL.createObjectURL(blob);
|
||||
if (isWechatEnv()) {
|
||||
setPreviewUrl(url);
|
||||
toastSuccess('请长按图片保存到相册');
|
||||
return;
|
||||
}
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `partner-assoc-${summary?.partnerId || 'qr'}.png`;
|
||||
@@ -49,9 +45,8 @@ export default function AssocQrcodePage() {
|
||||
URL.revokeObjectURL(url);
|
||||
toastSuccess('已开始下载');
|
||||
} catch (e) {
|
||||
if (summary?.qrcodeUrl) {
|
||||
setPreviewUrl(summary.qrcodeUrl);
|
||||
toastSuccess('请长按图片保存到相册');
|
||||
if (isWechatEnv() && isHttpImageUrl(publicUrl)) {
|
||||
await previewSaveableImage(publicUrl);
|
||||
return;
|
||||
}
|
||||
toastError(e instanceof Error ? e.message : '下载失败');
|
||||
@@ -70,7 +65,8 @@ export default function AssocQrcodePage() {
|
||||
</p>
|
||||
{summary?.qrcodeUrl ? (
|
||||
<img
|
||||
src={previewUrl || summary.qrcodeUrl}
|
||||
className="partner-longpress-img"
|
||||
src={summary.qrcodeUrl}
|
||||
alt="关联码"
|
||||
style={{ width: 220, height: 220, background: '#fff' }}
|
||||
/>
|
||||
@@ -83,11 +79,11 @@ export default function AssocQrcodePage() {
|
||||
<button type="button" className="partner-btn-primary" style={{ marginTop: 20 }} onClick={() => void downloadQr()}>
|
||||
下载二维码
|
||||
</button>
|
||||
{previewUrl && isWechatEnv() && (
|
||||
{isWechatEnv() && summary?.qrcodeUrl ? (
|
||||
<p className="label-md text-muted" style={{ marginTop: 12 }}>
|
||||
微信内请长按上方图片保存
|
||||
微信内请点「下载二维码」后长按保存
|
||||
</p>
|
||||
)}
|
||||
) : null}
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
fetchAssocQrcodeImage,
|
||||
} from '../lib/activity-posters';
|
||||
import { toastError, toastSuccess } from '../lib/toast';
|
||||
import { blobToDataUrl, isHttpImageUrl, previewSaveableImage } from '../lib/wechat-save-image';
|
||||
import { isWechatEnv } from '../lib/weixin';
|
||||
import { usePartnerPageView } from '../lib/usePageView';
|
||||
|
||||
@@ -58,7 +59,7 @@ export default function UsersManagePage() {
|
||||
}, []);
|
||||
|
||||
useEffect(() => () => {
|
||||
if (previewUrl) URL.revokeObjectURL(previewUrl);
|
||||
if (previewUrl?.startsWith('blob:')) URL.revokeObjectURL(previewUrl);
|
||||
}, [previewUrl]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -131,12 +132,17 @@ export default function UsersManagePage() {
|
||||
async function downloadMainImage() {
|
||||
const posterId = summary?.activityPosterId;
|
||||
try {
|
||||
if (isWechatEnv() && !posterId && isHttpImageUrl(summary?.qrcodeUrl)) {
|
||||
await previewSaveableImage(summary.qrcodeUrl);
|
||||
return;
|
||||
}
|
||||
const blob = posterId
|
||||
? await fetchActivityPosterImage(posterId)
|
||||
: await fetchAssocQrcodeImage();
|
||||
if (isWechatEnv()) {
|
||||
setPreviewUrl(URL.createObjectURL(blob));
|
||||
toastSuccess('请长按图片保存到相册');
|
||||
if (previewUrl?.startsWith('blob:')) URL.revokeObjectURL(previewUrl);
|
||||
setPreviewUrl(await blobToDataUrl(blob));
|
||||
toastSuccess('请长按上方图片保存到相册');
|
||||
return;
|
||||
}
|
||||
downloadBlob(blob, posterId
|
||||
@@ -144,7 +150,11 @@ export default function UsersManagePage() {
|
||||
: `partner-assoc-${summary?.partnerId || 'qr'}.png`);
|
||||
toastSuccess('已开始下载');
|
||||
} catch (e) {
|
||||
if (!posterId && summary?.qrcodeUrl) {
|
||||
if (!posterId && isHttpImageUrl(summary?.qrcodeUrl)) {
|
||||
if (isWechatEnv()) {
|
||||
await previewSaveableImage(summary.qrcodeUrl);
|
||||
return;
|
||||
}
|
||||
setPreviewUrl(summary.qrcodeUrl);
|
||||
toastSuccess('请长按图片保存到相册');
|
||||
return;
|
||||
@@ -182,6 +192,7 @@ export default function UsersManagePage() {
|
||||
</p>
|
||||
{summary?.activityPosterId && (previewUrl || heroUrl) ? (
|
||||
<img
|
||||
className="partner-longpress-img"
|
||||
src={previewUrl || heroUrl || ''}
|
||||
alt="活动图"
|
||||
style={{ width: '100%', maxWidth: 360, background: '#f5f5f5' }}
|
||||
@@ -190,6 +201,7 @@ export default function UsersManagePage() {
|
||||
<p className="body-md text-muted">正在生成活动图…</p>
|
||||
) : previewUrl || summary?.qrcodeUrl ? (
|
||||
<img
|
||||
className="partner-longpress-img"
|
||||
src={previewUrl || summary?.qrcodeUrl || ''}
|
||||
alt="关联码"
|
||||
style={{ width: 200, height: 200, background: '#fff' }}
|
||||
@@ -203,9 +215,11 @@ export default function UsersManagePage() {
|
||||
<button type="button" className="partner-btn-primary" style={{ marginTop: 16 }} onClick={() => void downloadMainImage()}>
|
||||
{summary?.activityPosterId ? '下载活动图' : '下载二维码'}
|
||||
</button>
|
||||
{previewUrl && isWechatEnv() && (
|
||||
<p className="label-md text-muted" style={{ marginTop: 8 }}>微信内请长按上方图片保存</p>
|
||||
)}
|
||||
{isWechatEnv() && (previewUrl || summary?.qrcodeUrl) ? (
|
||||
<p className="label-md text-muted" style={{ marginTop: 8 }}>
|
||||
微信内请点「{summary?.activityPosterId ? '下载活动图' : '下载二维码'}」后长按保存
|
||||
</p>
|
||||
) : null}
|
||||
</section>
|
||||
|
||||
<Link to="/center/activity-posters" className="partner-menu-card" style={{ display: 'block', marginBottom: 20, textDecoration: 'none', color: 'inherit' }}>
|
||||
|
||||
Reference in New Issue
Block a user