Files
i-tools/app/move-car/display/page.tsx
yfan 3d175d75af
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Sync to CNB / sync (push) Has been cancelled
Delete old workflow runs / del_runs (push) Has been cancelled
Upstream Sync / Sync latest commits from upstream repo (push) Has been cancelled
first commit
2026-01-30 16:57:44 +08:00

173 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { toast } from "sonner";
import { Car, Phone, Bell, Info } from "lucide-react";
export default function MoveCarDisplay() {
const [plateNumber, setPlateNumber] = useState("");
const [phoneNumber, setPhoneNumber] = useState("");
const [token, setToken] = useState("");
const [uid, setUid] = useState("");
const [newEnergy, setNewEnergy] = useState(false);
useEffect(() => {
const urlParams = new URLSearchParams(window.location.search);
setPlateNumber(urlParams.get("plateNumber") || "");
setPhoneNumber(urlParams.get("phoneNumber") || "");
setToken(urlParams.get("token") || "");
setUid(urlParams.get("uid") || "");
setNewEnergy(urlParams.get("new") === "true");
}, []);
const notifyOwner = () => {
const currentTime = new Date().getTime();
const lastNotifyTimeKey = "lastNotifyTime" + plateNumber;
const lastNotifyTime = localStorage.getItem(lastNotifyTimeKey);
const timeDifference = lastNotifyTime
? (currentTime - parseInt(lastNotifyTime)) / 1000
: 0;
if (lastNotifyTime && timeDifference < 60) {
toast.warning("您已发送过通知请1分钟后再次尝试。");
return;
}
const promise = fetch("https://wxpusher.zjiecode.com/api/send/message", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
appToken: token,
content: "您好,有人需要您挪车,请及时处理。",
contentType: 1,
uids: [uid],
}),
})
.then((response) => response.json())
.then((data) => {
if (data.code === 1000) {
localStorage.setItem(lastNotifyTimeKey, currentTime.toString());
return "通知已发送!";
} else {
throw new Error("通知发送失败");
}
});
toast.promise(promise, {
loading: '正在发送通知...',
success: (data) => data,
error: '通知发送失败,请稍后重试',
});
};
const callNumber = () => {
window.location.href = "tel:" + phoneNumber;
};
return (
<div className="space-y-4 max-w-md mx-auto pt-4 px-2">
{/* 车牌展示区域 */}
<div className="flex justify-center py-2">
<div
className={`relative flex h-32 w-full items-center justify-center overflow-hidden rounded-lg border-[3px] shadow-xl ${
newEnergy
? "border-black/80 bg-linear-to-b from-[#F0F3F5] to-[#42C063] text-black"
: "border-white bg-[#003399] text-white"
}`}
>
{/* 装饰性反光效果 */}
<div className="pointer-events-none absolute inset-0 bg-linear-to-br from-white/20 to-transparent opacity-50" />
{/* 车牌边框内饰线 (仅蓝牌显示) */}
{!newEnergy && (
<div className="absolute inset-1 rounded-md border border-white/50" />
)}
<div className="relative z-10 flex items-center gap-1 font-mono text-5xl font-bold tracking-widest">
<span>{plateNumber.slice(0, 2)}</span>
{newEnergy ? (
<span className="mx-1 h-2 w-2 rounded-full bg-current opacity-20" />
) : (
<span className="mx-2 h-2 w-2 rounded-full bg-current opacity-80" />
)}
<span>{plateNumber.slice(2)}</span>
</div>
{/* 新能源标志水印 (仅绿牌显示) */}
{newEnergy && (
<div className="absolute -bottom-6 -right-6 rotate-12 opacity-10">
<Car className="h-24 w-24" />
</div>
)}
</div>
</div>
{/* 车辆信息 */}
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium flex items-center gap-2 text-muted-foreground">
<Info className="h-4 w-4" />
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="grid grid-cols-3 gap-2 text-sm">
<div className="text-muted-foreground"></div>
<div className="col-span-2 font-medium"></div>
<div className="text-muted-foreground"></div>
<div className="col-span-2 font-medium font-mono">{plateNumber}</div>
<div className="text-muted-foreground"></div>
<div className="col-span-2 font-medium font-mono">{phoneNumber}</div>
</div>
</CardContent>
</Card>
{/* 操作按钮 */}
<Card className="border-t-4 border-t-primary/20">
<CardHeader>
<CardTitle className="text-center"></CardTitle>
</CardHeader>
<CardContent className="space-y-3">
{uid && token && (
<Button
size="lg"
className={`w-full gap-2 text-lg h-14 ${
newEnergy
? "bg-emerald-600 hover:bg-emerald-700 shadow-emerald-200 dark:shadow-none"
: "bg-blue-600 hover:bg-blue-700 shadow-blue-200 dark:shadow-none"
} shadow-xl transition-all hover:scale-[1.02] active:scale-[0.98]`}
onClick={notifyOwner}
>
<Bell className="h-5 w-5" />
</Button>
)}
<Button
size="lg"
variant={uid && token ? "outline" : "default"}
className={`w-full gap-2 text-lg h-14 ${!(uid && token) ? (newEnergy
? "bg-emerald-600 hover:bg-emerald-700 shadow-emerald-200 dark:shadow-none shadow-xl transition-all hover:scale-[1.02] active:scale-[0.98]"
: "bg-blue-600 hover:bg-blue-700 shadow-blue-200 dark:shadow-none shadow-xl transition-all hover:scale-[1.02] active:scale-[0.98]") : ""}`}
onClick={callNumber}
>
<Phone className="h-5 w-5" />
</Button>
</CardContent>
</Card>
{/* 温馨提示 */}
<div className="px-4 py-2 bg-muted/50 rounded-lg text-xs text-center text-muted-foreground">
💡
</div>
</div>
);
}