fix:完善门店和总部管理端
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { View, Text, Input, Button } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import type { PromoCodeItem } from '@dukang/shared-types';
|
||||
import HqHeader from '../../components/HqHeader';
|
||||
import { request, toast } from '../../lib/api';
|
||||
import { useHqSession } from '../../lib/session';
|
||||
import { navTo } from '../../lib/session';
|
||||
import { buildPromoQrDataUrl } from '../../lib/promo-qr';
|
||||
import './index.css';
|
||||
import './index.css';
|
||||
|
||||
export default function PromoGeneratePage() {
|
||||
useHqSession();
|
||||
const [name, setName] = useState('');
|
||||
const [code, setCode] = useState('');
|
||||
const [creating, setCreating] = useState(false);
|
||||
const [created, setCreated] = useState<PromoCodeItem | null>(null);
|
||||
const [qrUrl, setQrUrl] = useState('');
|
||||
|
||||
useEffect(() => {
|
||||
if (!created?.landingUrl) {
|
||||
setQrUrl('');
|
||||
return;
|
||||
}
|
||||
void buildPromoQrDataUrl(created.landingUrl).then(setQrUrl).catch(() => setQrUrl(''));
|
||||
}, [created]);
|
||||
|
||||
async function handleGenerate() {
|
||||
const trimmed = name.trim();
|
||||
if (!trimmed) {
|
||||
toast('请填写渠道名称');
|
||||
return;
|
||||
}
|
||||
setCreating(true);
|
||||
try {
|
||||
const payload: { name: string; code?: string } = { name: trimmed };
|
||||
if (code.trim()) payload.code = code.trim().toUpperCase();
|
||||
const row = await request<PromoCodeItem>('/admin/promo-codes', {
|
||||
method: 'POST',
|
||||
data: payload,
|
||||
});
|
||||
setCreated(row);
|
||||
toast('推广码已生成', 'success');
|
||||
} catch (e) {
|
||||
toast(e instanceof Error ? e.message : '生成失败');
|
||||
} finally {
|
||||
setCreating(false);
|
||||
}
|
||||
}
|
||||
|
||||
function copyLink() {
|
||||
if (!created?.landingUrl) return;
|
||||
Taro.setClipboardData({ data: created.landingUrl }).then(() => toast('推广链接已复制', 'success'));
|
||||
}
|
||||
|
||||
return (
|
||||
<View className="hq-page promo-page">
|
||||
<HqHeader title="生成推广码" back />
|
||||
|
||||
<View className="hq-card" style="margin:16px">
|
||||
<Text style="display:block;font-size:14px;color:var(--hq-muted);margin-bottom:16px">
|
||||
填写渠道信息,生成专属溯源推广码与落地链接。
|
||||
</Text>
|
||||
|
||||
<Text className="hq-label">渠道名称 *</Text>
|
||||
<Input
|
||||
className="hq-input"
|
||||
placeholder="如:郑州品鉴会、门店地推"
|
||||
value={name}
|
||||
onInput={(e) => setName(e.detail.value)}
|
||||
/>
|
||||
|
||||
<Text className="hq-label" style="margin-top:16px">自定义码值(选填)</Text>
|
||||
<Input
|
||||
className="hq-input"
|
||||
placeholder="留空则系统自动生成,如 DKDEMO1"
|
||||
value={code}
|
||||
onInput={(e) => setCode(e.detail.value.toUpperCase())}
|
||||
/>
|
||||
|
||||
<Button
|
||||
className="hq-btn hq-btn--primary hq-btn--block"
|
||||
style="margin-top:20px"
|
||||
loading={creating}
|
||||
disabled={creating}
|
||||
onClick={handleGenerate}
|
||||
>
|
||||
生成推广码
|
||||
</Button>
|
||||
</View>
|
||||
|
||||
{created && (
|
||||
<View className="promo-result">
|
||||
<View className="promo-result__qr-wrap">
|
||||
{qrUrl ? (
|
||||
<View
|
||||
className="promo-result__qr"
|
||||
style={{ backgroundImage: `url(${qrUrl})` }}
|
||||
/>
|
||||
) : (
|
||||
<View className="promo-result__qr promo-result__qr--loading">
|
||||
<Text className="material-symbols-outlined">hourglass_top</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
<Text className="promo-result__title">{created.name}</Text>
|
||||
<Text className="promo-result__code">码值:{created.code}</Text>
|
||||
|
||||
<View className="promo-result__actions">
|
||||
<View className="promo-card__btn promo-card__btn--outline" onClick={copyLink}>
|
||||
<Text className="material-symbols-outlined" style="font-size:18px">link</Text>
|
||||
<Text>复制链接</Text>
|
||||
</View>
|
||||
<View
|
||||
className="promo-card__btn promo-card__btn--ghost"
|
||||
onClick={() => navTo(`/pages/promo/detail?id=${created.id}`)}
|
||||
>
|
||||
<Text>查看详情</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user