% !TEX program = xelatex
% UPS 自提 / 取件码 — 流程与系统设计示意（TikZ）
% Overleaf: 使用 fontset=fandol（TeX Live 自带，无需 SimSun）
% 本地 Windows 可改为: \usepackage[UTF8,scheme=plain]{ctex}\setCJKmainfont{SimSun}
\documentclass[11pt,a4paper]{article}
\usepackage[UTF8,scheme=plain,fontset=fandol]{ctex}
\usepackage{geometry}
\geometry{margin=2.2cm}
\usepackage{tikz}
\usetikzlibrary{
  arrows.meta,
  positioning,
  shapes.geometric,
  shapes.symbols,
  fit,
  backgrounds,
  calc,
  shadows.blur
}
\definecolor{UPSbrown}{HTML}{351C15}
\definecolor{UPSgold}{HTML}{FFB500}
\definecolor{UPSlight}{HTML}{F5F0E8}
\usepackage{hyperref}
\hypersetup{colorlinks=true,linkcolor=UPSbrown,urlcolor=UPSgold}

\tikzset{
  font=\small,
  actor/.style={
    draw=UPSbrown,
    line width=0.8pt,
    rounded corners=3pt,
    minimum width=2.6cm,
    minimum height=1cm,
    align=center,
    fill=white,
    drop shadow={shadow xshift=1pt,shadow yshift=-1pt}
  },
  sys/.style={
    draw=UPSbrown,
    line width=0.6pt,
    rounded corners=2pt,
    minimum width=3cm,
    minimum height=0.85cm,
    align=center,
    fill=UPSlight
  },
  % 勿用名「step」：与 TikZ 内置 key /tikz/step 冲突（Overleaf 会报 pgfkeys Error）
  flowstep/.style={
    draw=UPSbrown,
    rounded corners=2pt,
    fill=white,
    minimum width=3cm,
    minimum height=0.7cm,
    align=center,
    font=\footnotesize
  },
  flow/.style={-{Stealth[length=2.2mm]}, thick, UPSbrown},
  lab/.style={font=\footnotesize, align=center},
  secret/.style={fill=UPSgold!25, draw=UPSgold!80!black, dashed}
}

\title{\textcolor{UPSbrown}{UPS 风格自提点：取件码与系统设计}\\[0.3em]
\large TikZ 图示（教学/示意，非官方）}
\author{}
\date{}

\begin{document}
\maketitle

\begin{abstract}
\noindent
本文档用 TikZ 示意「快递员投件 — 平台发码 — 收件人取件」的信息边界：
投件方通常不掌握收件人取件码；取件码仅通过安全通道下发给收件人。
\end{abstract}

% --------------------------------------------------------------------------
\section{角色与信息可见性}

\begin{figure}[htbp]
\centering
\begin{tikzpicture}[node distance=1.4cm and 2cm]
  \node[actor] (c) {快递员\\（存件/投件）};
  \node[actor, right=3.2cm of c] (s) {发件人\\（电商/个人）};
  \coordinate (midcs) at ($ (c)!0.5!(s) $);
  \node[actor, below=1.8cm of midcs] (r) {收件人};

  \node[sys, right=3cm of r, minimum width=3.4cm] (plat) {物流平台\\\footnotesize 订单 / 轨迹 / 发码};
  \node[sys, below=of plat, minimum width=3.4cm] (lock) {自提柜控制器\\\footnotesize 格口 / 电子锁};

  \draw[flow] (c) -- node[lab, left] {投件扫码\\工号/任务单} (plat);
  \draw[flow] (s) -- node[lab, above, sloped] {运单信息\\（无取件码）} (plat);
  \draw[flow, UPSgold!70!black] (plat) -- node[lab, right] {短信/App\\\textbf{取件码}} (r);
  \draw[flow] (plat) -- node[lab, right] {开格指令} (lock);
  \draw[flow] (c) -- node[lab, below, sloped] {物理投件} (lock);

  \node[secret, rounded corners, fit=(r) (plat), inner sep=8pt, label={[font=\footnotesize]above:\textbf{取件码仅在收件人通道}}] {};
\end{tikzpicture}
\caption{示意：发件人与快递员一般不接收「收件取件码」；收件人通过平台下发获得取件码。}
\label{fig:visibility}
\end{figure}

% --------------------------------------------------------------------------
\section{业务流程（泳道图）}

\begin{figure}[htbp]
\centering
\begin{tikzpicture}[
  x=1cm, y=1cm,
  lane/.style={draw=UPSbrown!40, fill=UPSlight, minimum height=5.2cm, minimum width=3.6cm, anchor=north west}
]

  % lanes
  \node[lane] (L1) at (0,0) {};
  \node[anchor=north west, font=\bfseries\footnotesize, text=UPSbrown] at (0.15,-0.15) {快递员};
  \node[lane] (L2) at (4,0) {};
  \node[anchor=north west, font=\bfseries\footnotesize, text=UPSbrown] at (4.15,-0.15) {平台};
  \node[lane] (L3) at (8,0) {};
  \node[anchor=north west, font=\bfseries\footnotesize, text=UPSbrown] at (8.15,-0.15) {收件人};

  % courier steps
  \node[flowstep] at (1.8,-1.1) (a1) {到站扫描};
  \node[flowstep, below=0.55 of a1] (a2) {分配格口};
  \node[flowstep, below=0.55 of a2] (a3) {投件关门};

  % platform steps
  \node[flowstep] at (5.8,-1.1) (b1) {校验运单};
  \node[flowstep, below=0.55 of b1] (b2) {生成取件码};
  \node[flowstep, below=0.55 of b2] (b3) {短信/App 推送};
  \node[flowstep, below=0.55 of b3] (b4) {更新状态\\「待取件」};

  % recipient
  \node[flowstep] at (9.8,-1.1) (c1) {收到通知};
  \node[flowstep, below=0.55 of c1] (c2) {到柜输入码};
  \node[flowstep, below=0.55 of c2] (c3) {取件完成};

  \draw[flow] (a1) -- (b1);
  \draw[flow] (b2) -- (c1);
  \path (a3.south) ++(0,-0.2) coordinate (tmpa);
  \draw[flow] (tmpa) -- (tmpa -| b1.west) |- (b1);
  \path (c2.west) ++(-0.6,0) coordinate (tmpr);
  \draw[flow] (c2.west) -- (tmpr) |- (b4.east);

\end{tikzpicture}
\caption{泳道示意：平台在投件确认后生成取件码并下发收件人；快递员侧流程与取件码解耦。}
\label{fig:swimlane}
\end{figure}

% --------------------------------------------------------------------------
\section{系统分层架构}

\begin{figure}[htbp]
\centering
\begin{tikzpicture}[node distance=0.75cm]
  \node[sys, minimum width=10cm, text width=9.6cm] (cli) {客户端层：快递员 App / 收件人 App / 柜机触摸屏};
  \node[sys, minimum width=10cm, text width=9.6cm, below=of cli] (gw) {网关层：API 网关、鉴权、限流、审计日志};
  \node[sys, minimum width=4.5cm, below left=1 and -0.2 of gw] (ord) {订单与运单服务};
  \node[sys, minimum width=4.5cm, below right=1 and -0.2 of gw] (code) {取件码服务\\\footnotesize 生成·绑定·失效};
  \node[sys, minimum width=4.5cm, below=of ord] (dev) {设备接入服务\\\footnotesize 开柜指令·状态回传};
  \node[sys, minimum width=4.5cm, below=of code] (msg) {消息服务\\\footnotesize 短信·推送·邮件};
  \node[sys, minimum width=10cm, text width=9.6cm, below=1.2 of dev.south west, anchor=west, xshift=0] (data) {数据层：运单库、取件码表（哈希）、设备影子、不可变审计};

  \draw[flow] (cli) -- (gw);
  \draw[flow] (gw.south west) ++(1.2,0) -- ++(0,-0.35) -| (ord);
  \draw[flow] (gw.south east) ++(-1.2,0) -- ++(0,-0.35) -| (code);
  \draw[flow] (ord) -- (dev);
  \draw[flow] (code) -- (msg);
  \draw[flow] (dev) -- (data.north -| dev);
  \draw[flow] (msg) -- (data.north -| msg);
\end{tikzpicture}
\caption{逻辑分层：取件码由独立服务生成与校验，与投件流水解耦，便于最小权限与审计。}
\label{fig:architecture}
\end{figure}

% --------------------------------------------------------------------------
\section{取件码生命周期（状态机）}

\begin{figure}[htbp]
\centering
\begin{tikzpicture}[
  stnode/.style={circle, draw=UPSbrown, minimum size=1.15cm, align=center, font=\footnotesize, fill=white},
  acc/.style={-{Stealth}, thick, UPSbrown}
]
  \node[stnode] (A) {未生成};
  \node[stnode, right=2.8cm of A] (B) {已生成\\未通知};
  \node[stnode, right=2.8cm of B] (C) {已下发};
  \coordinate (midBC) at ($ (B)!0.5!(C) $);
  \node[stnode, below=2cm of midBC] (D) {已核销};
  \node[stnode, left=2.8cm of D, fill=UPSlight] (E) {过期/作废};

  \draw[acc] (A) -- node[above, font=\scriptsize] {投件确认} (B);
  \draw[acc] (B) -- node[above, font=\scriptsize] {推送} (C);
  \draw[acc] (C) -- node[right, font=\scriptsize] {正确输入} (D);
  \draw[acc] (C) -- node[below left, font=\scriptsize] {超时策略} (E);
  \draw[acc] (B) -- node[left, font=\scriptsize] {撤件} (E);
\end{tikzpicture}
\caption{取件码状态机示意：实际生产需加入重试、风控冻结、客服人工核销等分支。}
\label{fig:statemachine}
\end{figure}

\vfill
\noindent\rule{\linewidth}{0.4pt}\\[0.3em]
{\footnotesize\textcolor{UPSbrown}{Disclaimer:} 图示为通用物流自提逻辑的教学草稿，与 UPS 任何地区正式产品文档无关。配色仅作风格参考。}

\end{document}
