|
|
@@ -0,0 +1,741 @@
|
|
|
+import { useMemo, useState } from "react";
|
|
|
+import {
|
|
|
+ BadgeCheck,
|
|
|
+ BarChart3,
|
|
|
+ Building2,
|
|
|
+ CheckCircle2,
|
|
|
+ ChevronRight,
|
|
|
+ ClipboardList,
|
|
|
+ Clock3,
|
|
|
+ FileSpreadsheet,
|
|
|
+ Laptop,
|
|
|
+ Layers3,
|
|
|
+ LineChart,
|
|
|
+ LockKeyhole,
|
|
|
+ Mail,
|
|
|
+ MapPin,
|
|
|
+ MonitorDown,
|
|
|
+ PackageSearch,
|
|
|
+ Search,
|
|
|
+ ShieldCheck,
|
|
|
+ Smartphone,
|
|
|
+ TabletSmartphone,
|
|
|
+ WalletCards,
|
|
|
+ type LucideIcon,
|
|
|
+} from "lucide-react";
|
|
|
+import { motion } from "motion/react";
|
|
|
+import logoImage from "./assets/images/zjy/logo.webp";
|
|
|
+
|
|
|
+type PlatformPrice = {
|
|
|
+ platform: string;
|
|
|
+ price: string;
|
|
|
+ best?: boolean;
|
|
|
+};
|
|
|
+
|
|
|
+type DrugQuote = {
|
|
|
+ name: string;
|
|
|
+ spec: string;
|
|
|
+ advice: string;
|
|
|
+ prices: PlatformPrice[];
|
|
|
+};
|
|
|
+
|
|
|
+type Capability = {
|
|
|
+ title: string;
|
|
|
+ desc: string;
|
|
|
+ icon: typeof PackageSearch;
|
|
|
+};
|
|
|
+
|
|
|
+type Scenario = {
|
|
|
+ title: string;
|
|
|
+ desc: string;
|
|
|
+ metrics: string[];
|
|
|
+};
|
|
|
+
|
|
|
+type DownloadOption = {
|
|
|
+ icon: LucideIcon;
|
|
|
+ title: string;
|
|
|
+ desc: string;
|
|
|
+ isAvailable: boolean;
|
|
|
+ url?: string;
|
|
|
+};
|
|
|
+
|
|
|
+const sectionReveal = {
|
|
|
+ initial: { opacity: 0, y: 34 },
|
|
|
+ whileInView: { opacity: 1, y: 0 },
|
|
|
+ viewport: { once: true, amount: 0.18 },
|
|
|
+ transition: { duration: 0.65, ease: "easeOut" as const },
|
|
|
+};
|
|
|
+
|
|
|
+const itemReveal = {
|
|
|
+ initial: { opacity: 0, y: 22 },
|
|
|
+ whileInView: { opacity: 1, y: 0 },
|
|
|
+ viewport: { once: true, amount: 0.25 },
|
|
|
+ transition: { duration: 0.55, ease: "easeOut" as const },
|
|
|
+};
|
|
|
+
|
|
|
+export default function App() {
|
|
|
+ const [activeQuoteIndex, setActiveQuoteIndex] = useState(0);
|
|
|
+ const [activeScenario, setActiveScenario] = useState(0);
|
|
|
+
|
|
|
+ // 平台连接状态用于渲染首屏左侧账号列表,后续若接入真实平台可替换为接口数据。
|
|
|
+ const connectedPlatforms = useMemo(() => ["药**", "一**", "*易*", "*帮*", "药**"], []);
|
|
|
+
|
|
|
+ // 首屏比价示例用于模拟采购人员切换不同药品后的横向价格结果。
|
|
|
+ const quotes: DrugQuote[] = useMemo(
|
|
|
+ () => [
|
|
|
+ {
|
|
|
+ name: "阿莫西林胶囊",
|
|
|
+ spec: "0.25g*24粒 / 300盒起订",
|
|
|
+ advice: "低价优先",
|
|
|
+ prices: [
|
|
|
+ { platform: "药**", price: "¥5.86", best: true },
|
|
|
+ { platform: "一**", price: "¥6.12" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "布洛芬缓释胶囊",
|
|
|
+ spec: "0.3g*20粒 / 区域仓发货",
|
|
|
+ advice: "可凑单",
|
|
|
+ prices: [
|
|
|
+ { platform: "药**", price: "¥9.48" },
|
|
|
+ { platform: "一**", price: "¥9.06", best: true },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "连花清瘟胶囊",
|
|
|
+ spec: "36粒 / 支持同城配送",
|
|
|
+ advice: "优先采购",
|
|
|
+ prices: [
|
|
|
+ { platform: "药**", price: "¥11.20" },
|
|
|
+ { platform: "一**", price: "¥10.98" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ [],
|
|
|
+ );
|
|
|
+
|
|
|
+ // 能力模块承接上传 HTML 的功能信息,并统一成可复用的卡片结构。
|
|
|
+ const capabilities: Capability[] = useMemo(
|
|
|
+ () => [
|
|
|
+ {
|
|
|
+ title: "同品规归并",
|
|
|
+ desc: "按商品名、规格、厂家、批准文号聚合同类结果,减少名称差异造成的误判。",
|
|
|
+ icon: Layers3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "采购成本看板",
|
|
|
+ desc: "按单次采购、门店、月份统计节省金额,帮助老板看清每一笔差价。",
|
|
|
+ icon: BarChart3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "起订量与凑单",
|
|
|
+ desc: "同步平台起订量、满减与配送门槛,优先给出适合当前采购量的选择。",
|
|
|
+ icon: WalletCards,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "采购清单导入",
|
|
|
+ desc: "批量导入常采目录或补货清单,一次生成跨平台价格排序结果。",
|
|
|
+ icon: FileSpreadsheet,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "缺货替代提醒",
|
|
|
+ desc: "当前平台缺货时,自动提示其他平台现货与相近替代规格。",
|
|
|
+ icon: Clock3,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "账号安全管控",
|
|
|
+ desc: "按员工角色分配查看与采购权限,离职人员可快速停用访问。",
|
|
|
+ icon: LockKeyhole,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ [],
|
|
|
+ );
|
|
|
+
|
|
|
+ // 客户场景用于移动端和桌面端共用同一份内容,避免两套文案维护不一致。
|
|
|
+ const scenarios: Scenario[] = useMemo(
|
|
|
+ () => [
|
|
|
+ {
|
|
|
+ title: "单体药店老板",
|
|
|
+ desc: "每天补货品种不多,但价格波动敏感。智价云 药店版把常采品种的各平台价格摆在同一页,老板能快速确认在哪里买更划算。",
|
|
|
+ metrics: ["少登录", "少抄价", "少漏采"],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: "连锁采购人员",
|
|
|
+ desc: "采购清单更长、门店更多,需要兼顾价格、起订量和配送时效。智价云 药店版支持批量比价与门店账号管理,适合标准化采购流程。",
|
|
|
+ metrics: ["批量搜", "按门店", "可复盘"],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ [],
|
|
|
+ );
|
|
|
+
|
|
|
+ // 下载入口保持为配置化数据,便于拿到真实安装包链接后替换跳转行为。
|
|
|
+ const downloadOptions: DownloadOption[] = useMemo(
|
|
|
+ () => [
|
|
|
+ {
|
|
|
+ icon: MonitorDown,
|
|
|
+ title: "Windows",
|
|
|
+ desc: "门店采购主力端",
|
|
|
+ isAvailable: true,
|
|
|
+ url: "https://priceapi.kailin.com.cn/desktop-updates/%E8%8D%AF%E6%98%93%E9%87%87-x64.exe",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ icon: Laptop,
|
|
|
+ title: "MacOS",
|
|
|
+ desc: "总部与采购办公",
|
|
|
+ isAvailable: true,
|
|
|
+ url: "https://priceapi.kailin.com.cn/desktop-updates/%E8%8D%AF%E6%98%93%E9%87%87-arm64.dmg",
|
|
|
+ },
|
|
|
+ { icon: Smartphone, title: "iOS", desc: "敬请期待", isAvailable: false },
|
|
|
+ { icon: TabletSmartphone, title: "Android", desc: "敬请期待", isAvailable: false },
|
|
|
+ ],
|
|
|
+ [],
|
|
|
+ );
|
|
|
+
|
|
|
+ // 产品中心与页脚复用同一份链接,匹配其他官网顶部下拉和底部栏目结构。
|
|
|
+ const products = useMemo(
|
|
|
+ () => [
|
|
|
+ { name: "智价云 药店版", url: "#top" },
|
|
|
+ { name: "智价云", url: "https://price.kailin.com.cn" },
|
|
|
+ { name: "开邻智数", url: "https://saas.kailin.com.cn" },
|
|
|
+ ],
|
|
|
+ [],
|
|
|
+ );
|
|
|
+
|
|
|
+ // 锚点滚动统一经过这个函数,保证导航、按钮在单页内的跳转行为一致。
|
|
|
+ const scrollTo = (id: string) => {
|
|
|
+ const target = document.getElementById(id);
|
|
|
+ target?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
|
+ };
|
|
|
+
|
|
|
+ const activeQuote = quotes[activeQuoteIndex];
|
|
|
+
|
|
|
+ const openProduct = (url: string) => {
|
|
|
+ if (url.startsWith("#")) {
|
|
|
+ scrollTo(url.slice(1));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ window.open(url, "_blank", "noreferrer");
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className="min-h-screen bg-deep-ink text-on-surface">
|
|
|
+ <header className="fixed top-0 z-50 w-full border-b border-slate-800 bg-slate-950/70 backdrop-blur-md">
|
|
|
+ <nav className="mx-auto flex h-20 max-w-7xl items-center justify-between px-6">
|
|
|
+ <div className="flex cursor-pointer items-center gap-3 font-headline" onClick={() => scrollTo("top")} aria-label="返回智价云药店版首页">
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ width: "7.75rem",
|
|
|
+ height: "2.35rem",
|
|
|
+ borderRadius: "9999px",
|
|
|
+ overflow: "hidden",
|
|
|
+ }}
|
|
|
+ className="flex items-center justify-center gap-2 bg-white px-3 text-primary shadow-lg shadow-black/10">
|
|
|
+ <img style={{ width: "6.75rem", height: "3rem" }} src={logoImage} alt="智价云 Logo" className="w-7 h-7 object-contain" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="hidden items-center space-x-10 md:flex">
|
|
|
+ <button className="relative inline-flex items-center font-headline text-sm font-bold leading-none text-secondary" onClick={() => scrollTo("top")}>
|
|
|
+ 首页
|
|
|
+ <span className="absolute left-0 -bottom-2 h-0.5 w-full rounded-full bg-secondary" />
|
|
|
+ </button>
|
|
|
+
|
|
|
+ <div className="group relative">
|
|
|
+ <span className="inline-flex cursor-default items-center font-headline text-sm font-medium leading-none text-slate-300 transition-colors hover:text-white">
|
|
|
+ 产品中心
|
|
|
+ </span>
|
|
|
+ <div className="invisible absolute left-1/2 top-full mt-3 min-w-36 -translate-x-1/2 rounded-lg border border-slate-800 bg-slate-900/95 p-1.5 opacity-0 shadow-xl transition-all duration-200 group-hover:visible group-hover:opacity-100">
|
|
|
+ {products.map((product) =>
|
|
|
+ product.url.startsWith("#") ? (
|
|
|
+ <button
|
|
|
+ key={product.name}
|
|
|
+ onClick={() => openProduct(product.url)}
|
|
|
+ className="block w-full rounded-md px-3 py-2 text-left text-sm text-slate-200 transition-colors hover:bg-slate-800 hover:text-white">
|
|
|
+ {product.name}
|
|
|
+ </button>
|
|
|
+ ) : (
|
|
|
+ <a
|
|
|
+ key={product.name}
|
|
|
+ href={product.url}
|
|
|
+ target="_blank"
|
|
|
+ rel="noreferrer"
|
|
|
+ className="block rounded-md px-3 py-2 text-sm text-slate-200 transition-colors hover:bg-slate-800 hover:text-white">
|
|
|
+ {product.name}
|
|
|
+ </a>
|
|
|
+ ),
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <a
|
|
|
+ href="https://home.kailin.com.cn"
|
|
|
+ target="_blank"
|
|
|
+ rel="noreferrer"
|
|
|
+ className="relative inline-flex items-center font-headline text-sm font-medium leading-none text-slate-300 transition-colors hover:text-white">
|
|
|
+ 关于我们
|
|
|
+ </a>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <button
|
|
|
+ onClick={() => scrollTo("download")}
|
|
|
+ className="rounded-lg bg-blue-600 px-6 py-2.5 font-headline text-sm font-bold text-white transition-all hover:bg-blue-500 active:scale-95">
|
|
|
+ 下载客户端
|
|
|
+ </button>
|
|
|
+ </nav>
|
|
|
+ </header>
|
|
|
+
|
|
|
+ <main id="top" className="overflow-hidden pt-20">
|
|
|
+ <section className="hero-grid relative border-b border-slate-800 bg-[#070d1a] px-5 py-14 md:px-8 lg:min-h-[720px] lg:py-16">
|
|
|
+ <div className="absolute inset-0 bg-[radial-gradient(circle_at_20%_20%,rgba(37,99,235,0.26),transparent_32%),radial-gradient(circle_at_78%_18%,rgba(56,189,248,0.14),transparent_28%),linear-gradient(135deg,rgba(2,6,23,0.84)_0%,rgba(15,23,42,0.94)_52%,rgba(2,6,23,0.98)_100%)]" />
|
|
|
+ <div className="absolute inset-0 hero-grid-lines" />
|
|
|
+
|
|
|
+ <div className="relative z-10 mx-auto grid max-w-7xl items-center gap-10 lg:grid-cols-[0.86fr_1.14fr]">
|
|
|
+ <motion.div initial={{ opacity: 0, y: 28 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.75, ease: "easeOut" }} className="max-w-2xl">
|
|
|
+ <div className="inline-flex items-center gap-3 font-headline text-sm font-extrabold text-blue-200">
|
|
|
+ <span className="h-1 w-8 rounded-full bg-danger" />
|
|
|
+ 药店、诊所等终端多电商平台采购比价追踪软件
|
|
|
+ </div>
|
|
|
+ <h1 className="mt-5 font-headline text-5xl font-extrabold leading-[1.04] tracking-normal text-white sm:text-6xl lg:text-7xl">智价云 药店版</h1>
|
|
|
+ <p className="mt-6 max-w-xl text-lg leading-8 text-slate-300 md:text-xl">
|
|
|
+ 绑定 B 端电商账号后,跨平台搜索同一商品,价格、库存、起订量和配送条件一次横向对比与下单。抢购快人一步!关注重点品规价格提醒及时扫货购进!
|
|
|
+ </p>
|
|
|
+
|
|
|
+ <div className="mt-9 flex flex-col gap-3 sm:flex-row">
|
|
|
+ <button
|
|
|
+ onClick={() => window.open("http://8.135.32.236:8001/desktop-updates/%E8%8D%AF%E6%98%93%E9%87%87-x64.exe")}
|
|
|
+ className="inline-flex h-13 items-center justify-center gap-2 rounded-md bg-primary px-6 font-bold text-white shadow-[0_16px_36px_rgba(37,99,235,0.35)] transition hover:-translate-y-0.5 hover:bg-blue-500">
|
|
|
+ <MonitorDown className="h-5 w-5" />
|
|
|
+ 下载客户端(Windows)
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ onClick={() => window.open("https://priceapi.kailin.com.cn/desktop-updates/%E8%8D%AF%E6%98%93%E9%87%87-arm64.dmg")}
|
|
|
+ className="inline-flex h-13 items-center justify-center gap-2 rounded-md bg-primary px-6 font-bold text-white shadow-[0_16px_36px_rgba(37,99,235,0.35)] transition hover:-translate-y-0.5 hover:bg-blue-500">
|
|
|
+ <Laptop className="h-5 w-5" />
|
|
|
+ 下载客户端(Mac)
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ onClick={() => scrollTo("compare")}
|
|
|
+ className="inline-flex h-13 items-center justify-center gap-2 rounded-md border border-slate-700 bg-slate-900 px-6 font-bold text-slate-100 transition hover:-translate-y-0.5 hover:border-blue-400 hover:text-blue-200">
|
|
|
+ <PackageSearch className="h-5 w-5" />
|
|
|
+ 查看比价流程
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* <div className="mt-7 flex flex-wrap gap-2 text-sm text-slate-300">
|
|
|
+ {["Windows", "macOS", "iOS 敬请期待", "Android 敬请期待", "单体药店与连锁采购团队"].map((item) => (
|
|
|
+ <span key={item} className="rounded-md border border-slate-700 bg-slate-900/80 px-3 py-2 shadow-sm shadow-black/10">
|
|
|
+ {item}
|
|
|
+ </span>
|
|
|
+ ))}
|
|
|
+ </div> */}
|
|
|
+ </motion.div>
|
|
|
+
|
|
|
+ <motion.div
|
|
|
+ initial={{ opacity: 0, x: 42, scale: 0.98 }}
|
|
|
+ animate={{ opacity: 1, x: 0, scale: 1 }}
|
|
|
+ transition={{ delay: 0.12, duration: 0.75, ease: "easeOut" }}
|
|
|
+ className="relative">
|
|
|
+ <WorkbenchPreview
|
|
|
+ activeQuote={activeQuote}
|
|
|
+ activeQuoteIndex={activeQuoteIndex}
|
|
|
+ connectedPlatforms={connectedPlatforms}
|
|
|
+ quotes={quotes}
|
|
|
+ setActiveQuoteIndex={setActiveQuoteIndex}
|
|
|
+ />
|
|
|
+ </motion.div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <motion.section id="compare" className="scroll-mt-20 bg-deep-ink px-5 py-20 md:px-8 lg:py-24" {...sectionReveal}>
|
|
|
+ <div className="mx-auto max-w-7xl">
|
|
|
+ <SectionIntro
|
|
|
+ kicker="横向比价"
|
|
|
+ title="把分散在不同平台里的药品价格,放到同一个采购视图里。"
|
|
|
+ desc="智价云 药店版面向药店老板和采购人员,将搜索、比价、库存判断、起订量检查与采购建议聚合在同一套工作台中,减少反复登录和人工抄价。"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div className="mt-9 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
|
|
+ {[
|
|
|
+ ["一站式", "输入商品名、条码或批准文号后多平台并行查询"],
|
|
|
+ ["多平台", "多垂直电商平台"],
|
|
|
+ ["多账号", "同一门店或连锁门店可绑定不同采购账号"],
|
|
|
+ ["实时查", "价格、库存、配送、起订量同步展示"],
|
|
|
+ ].map(([value, label]) => (
|
|
|
+ <motion.div
|
|
|
+ key={value}
|
|
|
+ {...itemReveal}
|
|
|
+ className="rounded-lg border border-slate-800 bg-slate-900/85 p-6 shadow-sm shadow-black/20 transition hover:-translate-y-1 hover:border-blue-500/50 hover:bg-slate-900">
|
|
|
+ <strong className="block font-headline text-4xl font-extrabold text-primary">{value}</strong>
|
|
|
+ <span className="mt-4 block text-sm leading-6 text-slate-400">{label}</span>
|
|
|
+ </motion.div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </motion.section>
|
|
|
+
|
|
|
+ <motion.section id="bind" className="scroll-mt-20 bg-slate-950 px-5 py-20 md:px-8 lg:py-24" {...sectionReveal}>
|
|
|
+ <div className="mx-auto max-w-7xl">
|
|
|
+ <SectionIntro
|
|
|
+ kicker="账号绑定"
|
|
|
+ title="采购账号归集管理,平台权益继续保留。"
|
|
|
+ desc="门店仍使用自己的 B 端电商平台账号,智价云 药店版负责统一检索与结果呈现,方便采购人员在同一界面做判断。"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div className="mt-10 grid gap-8 lg:grid-cols-[0.9fr_1.1fr]">
|
|
|
+ <div className="grid gap-3">
|
|
|
+ {[
|
|
|
+ ["01", "绑定平台账号", "支持主流医药 B2B 电商账号接入。"],
|
|
|
+ ["02", "选择门店与采购权限", "老板、采购员、财务按岗位查看对应门店和采购范围。"],
|
|
|
+ ["03", "搜索后横向决策", "同品规商品按价格、库存、配送时效和起订量排序。"],
|
|
|
+ ].map(([index, title, desc]) => (
|
|
|
+ <motion.article
|
|
|
+ key={index}
|
|
|
+ {...itemReveal}
|
|
|
+ className="grid grid-cols-[42px_1fr] gap-4 rounded-lg border border-slate-800 bg-slate-900/85 p-4">
|
|
|
+ <div className="grid h-11 w-11 place-items-center rounded-lg bg-blue-500/15 font-headline font-extrabold text-blue-200">{index}</div>
|
|
|
+ <div>
|
|
|
+ <h3 className="font-headline text-lg font-extrabold text-white">{title}</h3>
|
|
|
+ <p className="mt-1 text-sm leading-6 text-slate-400">{desc}</p>
|
|
|
+ </div>
|
|
|
+ </motion.article>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <motion.div {...itemReveal} className="rounded-lg border border-slate-800 bg-slate-900/85 p-5 shadow-panel">
|
|
|
+ <div className="flex flex-wrap items-center justify-between gap-4">
|
|
|
+ <div>
|
|
|
+ <p className="text-xs font-bold uppercase tracking-[0.16em] text-slate-500">Account Hub</p>
|
|
|
+ <h3 className="mt-1 font-headline text-xl font-extrabold text-white">门店账号连接状态</h3>
|
|
|
+ </div>
|
|
|
+ <span className="inline-flex items-center gap-2 rounded-full border border-emerald-400/25 bg-emerald-400/10 px-3 py-1.5 text-sm font-bold text-emerald-300">
|
|
|
+ <ShieldCheck className="h-4 w-4" />
|
|
|
+ 已加密托管
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="mt-5 grid gap-3">
|
|
|
+ {[
|
|
|
+ ["郑州康宁大药房", "药** / 店长账号", "刚刚同步"],
|
|
|
+ ["金水区二店", "一** / 采购账号", "2分钟前"],
|
|
|
+ ].map(([store, account, sync]) => (
|
|
|
+ <div key={store} className="grid gap-3 rounded-md border border-slate-800 bg-slate-950/80 p-4 sm:grid-cols-[1fr_82px_96px] sm:items-center">
|
|
|
+ <div>
|
|
|
+ <strong className="block text-sm text-slate-100">{store}</strong>
|
|
|
+ <span className="text-xs text-slate-500">{account}</span>
|
|
|
+ </div>
|
|
|
+ <span className="inline-flex items-center gap-1 text-sm font-extrabold text-emerald-300">
|
|
|
+ <CheckCircle2 className="h-4 w-4" />
|
|
|
+ 在线
|
|
|
+ </span>
|
|
|
+ <span className="text-sm font-bold text-primary sm:text-right">{sync}</span>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </motion.div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </motion.section>
|
|
|
+
|
|
|
+ <motion.section id="features" className="scroll-mt-20 bg-[#08111f] px-5 py-20 text-white md:px-8 lg:py-24" {...sectionReveal}>
|
|
|
+ <div className="mx-auto max-w-7xl">
|
|
|
+ <SectionIntro
|
|
|
+ dark
|
|
|
+ kicker="核心能力"
|
|
|
+ title="为药店采购设计的高频功能。"
|
|
|
+ desc="围绕采购前、采购中、采购后的高频动作设计,让价格判断、账号安全和成本复盘形成闭环。"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div className="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
|
|
+ {capabilities.map((item) => (
|
|
|
+ <motion.article
|
|
|
+ key={item.title}
|
|
|
+ {...itemReveal}
|
|
|
+ className="rounded-lg border border-white/10 bg-white/[0.04] p-6 transition hover:-translate-y-1 hover:border-primary/60 hover:bg-white/[0.07]">
|
|
|
+ <div className="grid h-12 w-12 place-items-center rounded-lg bg-primary/20 text-blue-200">
|
|
|
+ <item.icon className="h-6 w-6" />
|
|
|
+ </div>
|
|
|
+ <h3 className="mt-5 font-headline text-xl font-extrabold">{item.title}</h3>
|
|
|
+ <p className="mt-3 text-sm leading-6 text-slate-300">{item.desc}</p>
|
|
|
+ </motion.article>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </motion.section>
|
|
|
+
|
|
|
+ <motion.section id="download" className="scroll-mt-20 bg-slate-950 px-5 py-20 md:px-8 lg:py-24" {...sectionReveal}>
|
|
|
+ <div className="mx-auto max-w-7xl">
|
|
|
+ <div className="grid gap-8 rounded-lg border border-slate-800 bg-slate-900/85 p-6 shadow-panel lg:grid-cols-[0.75fr_1.25fr] lg:items-center lg:p-8">
|
|
|
+ <div>
|
|
|
+ <p className="font-headline text-sm font-extrabold text-secondary">全端覆盖</p>
|
|
|
+ <h2 className="mt-3 font-headline text-3xl font-extrabold leading-tight text-white md:text-4xl">
|
|
|
+ 电脑端做批量对比与采购,手机端远程管理与查阅。
|
|
|
+ </h2>
|
|
|
+ <p className="mt-4 leading-7 text-slate-400">采购办公室、收银台、仓库盘点、外出谈单都能接上同一套账号与比价结果。</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
|
|
+ {downloadOptions.map(({ icon: Icon, title, desc, isAvailable, url }) => (
|
|
|
+ <button
|
|
|
+ key={title}
|
|
|
+ className={`min-h-32 rounded-lg border p-4 text-left transition ${
|
|
|
+ isAvailable
|
|
|
+ ? "border-slate-800 bg-slate-950/80 hover:-translate-y-1 hover:border-blue-500/60 hover:bg-slate-900"
|
|
|
+ : "cursor-not-allowed border-slate-800 bg-slate-950/45 opacity-70"
|
|
|
+ }`}
|
|
|
+ onClick={() => {
|
|
|
+ // 未上线的平台只展示状态,不触发咨询跳转,避免给用户造成可下载的误解。
|
|
|
+ if (!isAvailable) return;
|
|
|
+ if (url) {
|
|
|
+ window.open(url);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ scrollTo("contact");
|
|
|
+ }}>
|
|
|
+ <strong className="flex items-center gap-2 font-headline text-base font-extrabold text-white">
|
|
|
+ <Icon className="h-5 w-5 text-secondary" />
|
|
|
+ {title}
|
|
|
+ </strong>
|
|
|
+ <span className="mt-8 block text-sm text-slate-400">{desc}</span>
|
|
|
+ </button>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </motion.section>
|
|
|
+
|
|
|
+ <motion.section className="bg-deep-ink px-5 py-20 md:px-8 lg:py-24" {...sectionReveal}>
|
|
|
+ <div className="mx-auto max-w-7xl">
|
|
|
+ <SectionIntro
|
|
|
+ kicker="客户场景"
|
|
|
+ title="让采购从“人工跑平台 手动查”,变成“按低价秒对比 做选择”。"
|
|
|
+ desc="从单体药店到中小连锁,智价云 药店版帮采购人员把分散平台、账号和价格条件收束成一个稳定流程。"
|
|
|
+ />
|
|
|
+
|
|
|
+ <div className="mt-9 grid gap-4 lg:grid-cols-2">
|
|
|
+ {scenarios.map((scenario, index) => (
|
|
|
+ <button
|
|
|
+ key={scenario.title}
|
|
|
+ onClick={() => setActiveScenario(index)}
|
|
|
+ className={`rounded-lg border p-6 text-left transition ${
|
|
|
+ activeScenario === index
|
|
|
+ ? "border-blue-500/60 bg-blue-500/10 shadow-md shadow-black/20"
|
|
|
+ : "border-slate-800 bg-slate-900/85 hover:border-slate-700"
|
|
|
+ }`}>
|
|
|
+ <div className="flex items-center justify-between gap-4">
|
|
|
+ <h3 className="font-headline text-2xl font-extrabold text-white">{scenario.title}</h3>
|
|
|
+ <ChevronRight className={`h-5 w-5 transition ${activeScenario === index ? "text-secondary" : "text-slate-600"}`} />
|
|
|
+ </div>
|
|
|
+ <p className="mt-4 leading-7 text-slate-400">{scenario.desc}</p>
|
|
|
+ <div className="mt-6 grid grid-cols-3 gap-3">
|
|
|
+ {scenario.metrics.map((metric) => (
|
|
|
+ <span key={metric} className="border-l-4 border-danger bg-slate-950/80 px-3 py-2 text-sm font-bold text-slate-100">
|
|
|
+ {metric}
|
|
|
+ </span>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </button>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </motion.section>
|
|
|
+
|
|
|
+ <footer id="contact" className="scroll-mt-20 border-t border-slate-800 bg-slate-950 px-6 py-16">
|
|
|
+ <div className="mx-auto grid max-w-7xl grid-cols-1 gap-12 md:grid-cols-4">
|
|
|
+ <div className="space-y-6">
|
|
|
+ <div className="font-headline text-xl font-bold text-white">智价云 药店版</div>
|
|
|
+ <p className="text-sm leading-relaxed text-slate-400">
|
|
|
+ 药店、诊所等终端多电商平台采购比价追踪软件,帮助单体药店与连锁采购团队统一检索、横向比价和管理平台账号。省时省力又省钱!
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <h5 className="mb-6 text-xs font-bold uppercase tracking-widest text-slate-200">联系我们</h5>
|
|
|
+ <ul className="space-y-4 text-sm text-slate-400">
|
|
|
+ <li className="flex items-center gap-2">
|
|
|
+ <Mail className="h-4 w-4 text-secondary" />
|
|
|
+ <a
|
|
|
+ href="mailto:bd@dotouch.tech?subject=%E6%99%BA%E4%BB%B7%E4%BA%91%E8%8D%AF%E5%BA%97%E7%89%88%E4%BA%A7%E5%93%81%E5%92%A8%E8%AF%A2"
|
|
|
+ className="transition-colors hover:text-secondary">
|
|
|
+ bd@dotouch.tech
|
|
|
+ </a>
|
|
|
+ </li>
|
|
|
+ <li className="flex items-start gap-2">
|
|
|
+ <MapPin className="mt-0.5 h-4 w-4 text-secondary" />
|
|
|
+ <span>深圳大方无隅科技有限公司</span>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <h5 className="mb-6 text-xs font-bold uppercase tracking-widest text-slate-200">产品中心</h5>
|
|
|
+ <ul className="space-y-4 text-sm text-slate-400">
|
|
|
+ {products.map((product) => (
|
|
|
+ <li key={product.name}>
|
|
|
+ {product.url.startsWith("#") ? (
|
|
|
+ <button onClick={() => openProduct(product.url)} className="transition-colors hover:text-secondary">
|
|
|
+ {product.name}
|
|
|
+ </button>
|
|
|
+ ) : (
|
|
|
+ <a href={product.url} target="_blank" rel="noreferrer" className="transition-colors hover:text-secondary">
|
|
|
+ {product.name}
|
|
|
+ </a>
|
|
|
+ )}
|
|
|
+ </li>
|
|
|
+ ))}
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <h5 className="mb-6 text-xs font-bold uppercase tracking-widest text-slate-200">法律条款</h5>
|
|
|
+ <ul className="space-y-4 text-sm text-slate-400">
|
|
|
+ <li>
|
|
|
+ <a href="/privacy" target="_blank" rel="noreferrer" className="transition-colors hover:text-secondary">
|
|
|
+ 隐私政策
|
|
|
+ </a>
|
|
|
+ </li>
|
|
|
+ <li>
|
|
|
+ <a href="/agreement" target="_blank" rel="noreferrer" className="transition-colors hover:text-secondary">
|
|
|
+ 用户协议
|
|
|
+ </a>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="mx-auto mt-16 max-w-7xl border-t border-slate-800 pt-8 text-center">
|
|
|
+ <p className="text-sm text-slate-500">© 粤ICP备2024220172号-9</p>
|
|
|
+ </div>
|
|
|
+ </footer>
|
|
|
+ </main>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function SectionIntro({ kicker, title, desc, dark = true }: { kicker: string; title: string; desc: string; dark?: boolean }) {
|
|
|
+ return (
|
|
|
+ <div className="max-w-3xl">
|
|
|
+ <p className="font-headline text-sm font-extrabold text-secondary">{kicker}</p>
|
|
|
+ <h2 className={`mt-3 font-headline text-3xl font-extrabold leading-tight md:text-4xl ${dark ? "text-white" : "text-white"}`}>{title}</h2>
|
|
|
+ <p className={`mt-4 leading-7 ${dark ? "text-slate-400" : "text-slate-400"}`}>{desc}</p>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function WorkbenchPreview({
|
|
|
+ activeQuote,
|
|
|
+ activeQuoteIndex,
|
|
|
+ connectedPlatforms,
|
|
|
+ quotes,
|
|
|
+ setActiveQuoteIndex,
|
|
|
+}: {
|
|
|
+ activeQuote: DrugQuote;
|
|
|
+ activeQuoteIndex: number;
|
|
|
+ connectedPlatforms: string[];
|
|
|
+ quotes: DrugQuote[];
|
|
|
+ setActiveQuoteIndex: (index: number) => void;
|
|
|
+}) {
|
|
|
+ return (
|
|
|
+ <div className="rounded-lg border border-slate-700/80 bg-slate-900/95 shadow-panel">
|
|
|
+ <div className="flex h-12 items-center justify-between border-b border-slate-800 bg-slate-950/90 px-4">
|
|
|
+ <div className="flex gap-2">
|
|
|
+ <span className="h-2.5 w-2.5 rounded-full bg-danger" />
|
|
|
+ <span className="h-2.5 w-2.5 rounded-full bg-slate-600" />
|
|
|
+ <span className="h-2.5 w-2.5 rounded-full bg-emerald-600" />
|
|
|
+ </div>
|
|
|
+ <div className="inline-flex items-center gap-2 text-sm font-bold text-emerald-300">
|
|
|
+ <BadgeCheck className="h-4 w-4" />4 个采购平台已连接
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="grid min-h-[520px] lg:grid-cols-[210px_1fr]">
|
|
|
+ <aside className="border-b border-slate-800 bg-slate-950/70 p-5 lg:border-b-0 lg:border-r">
|
|
|
+ <p className="text-xs font-semibold text-slate-500">B端电商账号</p>
|
|
|
+ <div className="mt-4 grid gap-3">
|
|
|
+ {connectedPlatforms.map((platform) => (
|
|
|
+ <div
|
|
|
+ key={platform}
|
|
|
+ className="flex min-h-11 items-center justify-between rounded-md border border-slate-800 bg-slate-900 px-3 text-sm font-bold text-slate-100">
|
|
|
+ {platform}
|
|
|
+ <span className="h-2 w-2 rounded-full bg-emerald-600" />
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ <div className="mt-7 rounded-md border border-emerald-400/20 bg-emerald-400/10 p-4">
|
|
|
+ <div className="flex items-center gap-2 text-sm font-extrabold text-emerald-300">
|
|
|
+ <ShieldCheck className="h-4 w-4" />
|
|
|
+ 账号安全
|
|
|
+ </div>
|
|
|
+ <p className="mt-2 text-xs leading-5 text-emerald-100/70">角色权限、加密托管、离职停用统一管理。</p>
|
|
|
+ </div>
|
|
|
+ </aside>
|
|
|
+
|
|
|
+ <div className="p-5 md:p-6">
|
|
|
+ <div className="grid gap-3 sm:grid-cols-[1fr_118px]">
|
|
|
+ <div className="flex min-h-12 items-center gap-3 rounded-md border border-slate-700 bg-slate-950 px-4 font-bold text-slate-100">
|
|
|
+ <Search className="h-5 w-5 text-secondary" />
|
|
|
+ {activeQuote.name}
|
|
|
+ <span className="hidden font-normal text-slate-500 sm:inline">{activeQuote.spec}</span>
|
|
|
+ </div>
|
|
|
+ <button className="rounded-md bg-danger px-4 font-bold text-white">横向搜索</button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="mt-5 grid grid-cols-3 gap-2">
|
|
|
+ {quotes.map((quote, index) => (
|
|
|
+ <button
|
|
|
+ key={quote.name}
|
|
|
+ onClick={() => setActiveQuoteIndex(index)}
|
|
|
+ className={`rounded-md border px-3 py-2 text-left text-xs font-bold transition ${
|
|
|
+ activeQuoteIndex === index
|
|
|
+ ? "border-blue-500 bg-blue-500/15 text-blue-200"
|
|
|
+ : "border-slate-800 text-slate-500 hover:border-blue-500/40 hover:text-slate-300"
|
|
|
+ }`}>
|
|
|
+ {quote.name}
|
|
|
+ </button>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="mt-5 overflow-hidden rounded-md border border-slate-800">
|
|
|
+ <div className="grid grid-cols-[1.1fr_0.8fr_0.8fr_88px] border-b border-slate-800 bg-slate-950 px-4 py-3 text-xs font-bold text-slate-500">
|
|
|
+ <span>商品</span>
|
|
|
+ <span>平台</span>
|
|
|
+ <span>价格</span>
|
|
|
+ <span>建议</span>
|
|
|
+ </div>
|
|
|
+ {activeQuote.prices.map((item) => (
|
|
|
+ <div
|
|
|
+ key={item.platform}
|
|
|
+ className="grid min-h-16 grid-cols-[1.1fr_0.8fr_0.8fr_88px] items-center border-b border-slate-800 px-4 py-3 text-sm last:border-b-0">
|
|
|
+ <div>
|
|
|
+ <strong className="block text-slate-100">{activeQuote.name}</strong>
|
|
|
+ <span className="text-xs text-slate-500">{item.note}</span>
|
|
|
+ </div>
|
|
|
+ <span className="font-bold text-slate-300">{item.platform}</span>
|
|
|
+ <span className={`font-headline text-lg font-extrabold ${item.best ? "text-danger" : "text-blue-300"}`}>{item.price}</span>
|
|
|
+ <span
|
|
|
+ className={`w-max rounded-full px-2.5 py-1 text-xs font-bold ${
|
|
|
+ item.best ? "bg-rose-400/10 text-rose-300" : "bg-emerald-400/10 text-emerald-300"
|
|
|
+ }`}>
|
|
|
+ {item.best ? activeQuote.advice : "备选"}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div className="mt-5 grid gap-3 sm:grid-cols-3">
|
|
|
+ {[
|
|
|
+ [ClipboardList, "本次预计节省", "¥1,286"],
|
|
|
+ [PackageSearch, "可比价商品", "186"],
|
|
|
+ [Building2, "缺货替代", "24"],
|
|
|
+ ].map(([Icon, label, value]) => (
|
|
|
+ <div key={label as string} className="rounded-lg border border-slate-800 bg-slate-950/80 p-4">
|
|
|
+ <Icon className="h-5 w-5 text-secondary" />
|
|
|
+ <span className="mt-3 block text-xs text-slate-500">{label as string}</span>
|
|
|
+ <strong className="mt-1 block font-headline text-2xl font-extrabold text-white">{value as string}</strong>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|