供应链 PC 实操落地实践
目录 一、背景 二、实操模式 三、快捷码设计和使用 快捷码布局 快捷码的准确识别 快捷码的高亮反馈 快捷码打印和黏贴建议 四、问题复盘 基准体验的梳理 五、实操环境检测 实操环境的安装和配置 实操环境检测能力的使用流程 实操检测能力的技术架构 实操环境的检查时机 输入法的检测和自动修复 统一打印组件 软件更新 六、信息反馈及异常SOP 七、效率指标的定义、监控和分析 八、后续规划 一、背景 在供应链履约流程中,PC实操发货主要负责 "完成复查入库商品的数量、规格和质量,并核对证书和防伪扣的正确性,确保商品无问题后,对订单内的商品进行打包、打印黏贴物流面单,并交接给3PL配送"。 作为配送前的最后一道屏障,需要确保供应链从生产入库到出库的环节的质量符合预期,最终将包裹交付到物流供应商,配送给消费者。 随着得物业务规模变大,供应链对成本、效率、质量的要求在不断提升,云仓业务模式开始逐步测试并铺开,仓内的设备环境与得物自有仓出现差异,因此PC实操系统需要在设备采购成本和实操的效率之间寻找平衡点。 云仓内的设备环境不一致,实操系统会面临如下问题: 大部分云仓BPO没有平板电脑,无法直接使用得物既有的实操系统(Pink Flutter App); 打印机型号众多,打印指令无法统一,容易造成打印配置和打印效果不一致; 设备类型和配置的不一致,带来了更多的适配问题,很容易形成业务流程的卡点,影响开仓和实操的效率。 为了解决这些问题,PC实操系统需要是跨平台的,从而保障系统使用的灵活性 ,并降低对设备种类的依赖度 ;其次通过接入得物统一打印组件,来抹平打印机型号的差异带来的成本。 本文主要介绍实操发货交互模式的实现、实操环境的检测及自动修复 ,文章最后也介绍了实操效率指标的定义。 二、实操模式 实操系统的信息输入有多种选择,可以是触屏电脑、扫码枪、键盘鼠标等。实操过程需要向系统内的录入多种条形码、二维码等信息,以及复检、打包的结果信息。按照不同的输入设备类型,可以将实操分为如下几种: PC实操系统同时支持了以上三种模式,但考虑到实际的设备环境和使用效率 ,推荐仓内使用扫码实操模式,即采用扫码枪 + 屏显二维码 + 粘贴实体码的混合扫码实操方案。 三、快捷码设计和使用 在扫码模式中,可以将这些快捷指令二维码简称为"快捷码"。设计快捷码的初衷,是为了简化实操的输入设备种类,在不切换到键盘鼠标的情况下,仅通过扫码枪就可以完成信息的录入、操作指令的执行。快捷码除了可以进行数据接口通信、交互操作,也可以执行多个指令的组合指令。 快捷码布局 如何将快捷码融合到PC实操系统,考虑过多个方案: 1. 环绕布局 2. 左右布局 3. 二级指令菜单 指令折叠:有些指令使用频次很少,且具有一定的"误操作风险",因此考虑二级指令菜单的交互,将不常用的折叠起来。借助扫码枪即可扫码打开二级菜单,此时操作区收窄,或者以Popup形式呈现,二级菜单发生有效扫码即可关闭,或者主动扫交互码关闭。 快捷指令交互系统:所有流程支持快捷指令,可以扫码展开、折叠,也可以扫码查看订单明细等,扫码关闭弹窗,代替鼠标,大部分操作需要做到扫完即关,确保操作区的可用性。 大部分快捷码在正向流程里的使用频率并不高,并且屏显快捷码过多,会增加扫错二维码的风险 。因此在方案3的基础上,将二维码进行归类,并收纳到功能导航中,同时会建议将常用快捷码打印黏贴至工位使用。 为了提升扫码的效率,屏幕上的快捷码会保持简洁,只会存在1-3个快捷码,并且在布局的设计上有较大的分布间距,避免扫码失误的情况出现。 快捷码的准确识别 我们定义以**"@"字符开头标识一个快捷指令的开始**,数字则代表快捷码类型,如 @01 代表打印面单。这样的设计可以降低生成的快捷码的复杂度,提升识别的准确率。 扫码枪扫码后会以连续字符串输入给活跃的焦点设备 ,并以Enter结尾;基于这个特点, 要准确识别一个快捷码指令有三个必要条件:@开头、 Enter结尾、连续输入。完成指令识别后,就可以准确执行指令注册的函数了。然而,在识别过程也会遇到一些问题。 字符录入冲突。在一个连续的指令输入过程中,会禁用默认键入的内容,这样可以避免焦点处于输入框的同时扫描了快捷码,意外将快捷码字符录入到输入框中。 焦点冲突。由于实操系统同时支持键盘模式操作,可以通过Enter键模拟鼠标对按钮的点击;当焦点处于按钮上时扫描了快捷码,扫码枪输入的Enter会造成按钮意外触发点击。因此在识别到扫码内容为快捷指令类型时,会在短时间将按钮移除焦点,指令结束后再重新设置焦点。 (e: KeyboardEvent) => { const enterKey = e.key === "Enter"; // @ 开头,开启一个新的快捷指令 if (e.key === "@") { e.preventDefault(); scaning.current = true; } // ... // 处理按钮输入锁定等兼容逻辑 if (scaning.current && !enterKey) { activeCode.current += String(e.key); e.preventDefault(); } else if (activeCode.current && enterKey) { scaning.current = false; // next // 快捷指令执行函数和标记高亮等 } //... // 输入解锁等能力 }; 快捷码的高亮反馈类似 支付宝商家二维码收款的到账提示音,实操过程的操作和信息录入,需要对结果进行反馈。 目前,除提示"成功"、"失败"的声音反馈外,还会对命中的二维码添加高亮块进行视觉反馈,这也解决了部分仓库没有音响设备,可以通过视觉反馈的形式感知操作行为。 快捷码打印和黏贴建议 为了更方便的让仓内打印黏贴快捷指令二维码,将常用的快捷指令码分为两大类:正向流程和逆向流程;并支持在实操系统直接打印。 实操流程简单的仓库,只需要把必要的 1 - 4 个快捷码黏贴于工位即可。 快捷码的打印通过动态渲染html片段并执行打印来实现,如下: /** * 打印html片段 */ export function printHTMLOutWithCSS(config: { content?: string; cssText?: string; }) { if (!config?.content) return; const cssText = config?.cssText; const iframeEle = document.createElement("iframe"); iframeEle.style.display = "none"; document.body.append(iframeEle); const iframeDoc = iframeEle?.contentDocument || iframeEle?.contentWindow?.document; if (iframeDoc?.body) { iframeDoc.body.innerHTML = `<style>${cssText || ""}</style>${ config?.content }`; iframeEle?.contentWindow?.print(); } document.body.removeChild(iframeEle); } printHTMLOutWithCSS({ content: `${dom.outerHTML}<div class="qrcode-button-name">${ config?.name || "-" }</div>`, cssText: STYLE_PRINT_STR, }); 四、问题复盘 8月中旬开始PC实操已在部分云仓生产环境使用起来,我们梳理了仓内遇到的问题及操作效率,可以归类如下: 异常流程、逆向流程,无SOP。依赖经验和培训。如:订单被取消,后续的操作建议。 实操环境检测及自动化配置。如输入法检测、扫码枪配置检测、打印机环境检测和配置等。 正向流程存在冗余。除了必要的信息输入,其余部分可以自动化完成。如:防伪完成。 基准体验的梳理 解决这些问题前,需要先了解好的体验和正确的流程是什么样的,再去优化才有据可依。一个好用的实操流程的特征可以枚举如下: 开仓或实操开始前"实操助手" 可以保障实操环境、设备配置的可用性,并可以自助修复卡点问题; 保障大部分订单仅需扫码必要的订单、商品、防伪信息,即可自动化完成发货,操作链路无冗余; 提升高频操作的无键盘化的覆盖率,全程仅需用到扫码枪,降低用户设备上的使用负担; 针对异常流程,可以系统化低成本的录入异常SOP预案,自动呈现提示语、解决问题的快捷指令等。 接下来介绍下PC实操如何通过"实操环境检测"和"异常SOP链路"来解决这些问题的。 五、实操环境检测 实操环境的安装和配置 进入实操系统后,会引导安装得物打印软件,并对打印机进行配置。 实操环境检测能力的使用流程 仓内实操人员开工后,通过如下流程来保障实操环境的可用性。 实操检测能力的技术架构 实操环境检测能力内置于得物打印Electron应用中,通过Socket长链接通信,借助Electron系统级API的优势能力来拓展Web端实操系统的能力边界。实操Web系统和得物打印Electron系统的调用交互过程如下: 实操环境的检查时机 PC实操系统会在心跳检查的循环里自动检查实操环境(输入法、打印机、软件版本);实操系统焦点到前台后,也会立即触发一次检查。扫码枪属于手动输入设备,因此需要手动点击进行检测(大小写转换、输入速度)。 输入法的检测和自动修复 实操过程需要一个英文的输入法语言环境,这是由于在中文环境下,扫码枪录入信息时,键入的英文字符很容易意外命中中文字符,导致输入内容错误。因此实操开始前,需要对输入法自动进行检查和设置。 Electron Nodejs主进程拥有强大的动态脚本的执行能力,我们可以即此对Windows系统语言进行检测和设置。Windows官方提供的国际化语言相关系统API文档,出于安全和体验考量,没有提供活跃窗口语言修改后立即生效的能力,需要切换焦点后才可以生效,如果强行切换到英语输入法,会导致系统其他输入法被卸载,这可能会对实操用户带来困扰。 为了解决这个问题,目前会对已安装输入法的进行缓存(Shell变量$restoreLanguageList),卸载全部输入法后,再异步进行已安装输入法的复原,同时也会安装英语输入法 en-US,并设置为首选输入法。 // # constant const PLAT_WIN = os.platform() === 'win32' const LANG_CONFIG = { 'en-US': { name: 'en-US', code: '0409:00000409', delay: 1.5, }, 'zh-CN': { name: 'zh-CN', code: '0804:{81D4E9C9-1D3B-41BC-9E6C-4B40BF79E35E}{FA550B04-5AD7-411F-A5AC-CA038EC515D7}', delay: 1.5, }, } /** * 获取shell指令集 */ function getShellLangScripts({ delay, name, code, }: { delay: number name: string code: string }) { const tplName = name || 'en-US' const tplCode = code || '0409:00000409' const tplDelay = delay || 1.5 // powershell 指令集 return { // ## 脚本: 重置系统输入法为 name 如en-US,删除其他输入法,立即生效,无需切换窗口焦点 // ## 优点,避免用户意外打开中文输入法,缺点,用户已有输入法被卸载 RESET: [ `Set-WinSystemLocale ${tplName};`, `Set-WinUserLanguageList ${tplName} -Force;`, `Set-WinDefaultInputMethodOverride -InputTip "${tplCode}";`, ], // ## 脚本: 添加系统输入法 name 如en-US,合并其他输入法,立即生效,无需切换窗口焦点 // ## 优点,用户已有输入法依然存在,缺点,中文输入法可能还存在于用户的输入法列表中 COMPATIBLE: [ `$restoreLanguageList = Get-WinUserLanguageList;`, `$restoreLanguageList.Remove("${tplName}");`, `$restoreLanguageList.Insert(0, "${tplName}");`, `Set-WinUserLanguageList ${tplName} -Force;`, // windows未开放当前窗口立即生效,这里通过hack实现 `Start-Sleep -Seconds ${tplDelay};`, `Set-WinUserLanguageList -LanguageList $restoreLanguageList -Force;`, // 设置默认输入法和系统语言 `Set-WinDefaultInputMethodOverride -InputTip "${tplCode}";`, `Set-WinSystemLocale zh-CN;`, // 调整语言顺序后,Win11下会将首个语言设置为展示语言,这里重置为中文 `Set-WinUILanguageOverride -Language zh-CN;`, ], } } /** * 添加系统输入法 en-US,合并其他输入法,立即生效,无需切换窗口焦点 */ */ export type ActionTypeLangAdapt = 'COMPATIBLE' | 'RESET' | 'CAT' export type NameTypeLangAdapt = 'zh-CN' | 'en-US' let lockExecLang = false export function adaptOrCatLang( actionType?: ActionTypeLangAdapt, nameType?: NameTypeLangAdapt, delay?: string, fn?: (status: 'success' | 'failed', msg: string) => void ) { if (lockExecLang) return lockExecLang = true const fnAffair = (status: 'success' | 'failed', msg: string) => { fn?.(status, msg) lockExecLang = false } if (!PLAT_WIN) { fnAffair('failed', '仅支持windows系统') return } const langTplConfig = LANG_CONFIG[nameType] langTplConfig.delay = Number(delay) || langTplConfig.delay if (!langTplConfig) { fnAffair('failed', '语言类型错误') return } const shellLangScripts = getShellLangScripts(langTplConfig) switch (actionType) { case 'CAT': const out = childProcess.execSync( 'powershell.exe (Get-WinUserLanguageList)[0].LanguageTag;' ) fnAffair('success', out?.toString('utf8')?.trim() || '') break default: const langScript = shellLangScripts?.[actionType]?.join('') if (langScript) { const out = childProcess.spawn(langScript, { shell: 'powershell.exe', }) out.on('exit', function () { fnAffair('success', `语言切换成功(${nameType})`) }) } else { fnAffair('failed', '指令类型错误') } break } } 语言环境自动修复效果如下: 具体视频见得物技术公众号 统一打印组件 新版实操接入了"得物打印"提供的统一打印组件能力(基于 Chromium 统一内核实现),主要考虑到两点原因: 新版打印机组件,可以实现和打印机机型解耦,不再要求 BPO 购买指定机型打印机,节省 BPO 成本; 保证打印效果的一致性,为后边统一面单打印做基础。 借助统一打印组件能力,可以屏蔽不同打印机型号给实操环境带来的复杂性和不可控性,大大降低了开仓的成本,提升实操效率和一致性。统一打印组件的连接状态检查和实操环境的检测是同步进行的,因此只需要按照指引安装即可。 软件更新 实操系统需要保证得物打印的是最新版本,因此在检测到软件版本需要更新后,通过URL Schemes唤起Electron应用,进行软件的更新和配置更新。 六、信息反馈及异常SOP 实操人员的工作就是识别信息并做出判断和操作的过程。在实操界面的头部增加操作状态反馈,增强状态呈现和信息反馈,可以帮助提升实操用户的专注度。用于明确告诉用户当前处于什么流程,结果成功/失败。 一般有两种信息反馈形式: 声音,仓内无音响设备则无法触达; 通知,有常驻通知和非常驻两种。 当系统出现预期之外的情况,比如订单被取消了,那么供应链流程也需要执行返架和挂起重置。此时如果没有Case by Case的SOP指引,实操流程就会被卡住,此时过于依赖培训和经验来解决。因此目前会将已知的异常链路和用户反馈,不断迭代到异常SOP中,提升系统的易用性。 七、效率指标的定义、监控和分析 业务产品迭代到后期,问题的定位和流程的优化,往往不是可以通过经验上的判断来完成的,需要借助数据来驱动体验优化。Q4云仓会逐步铺开,随着使用量的提升,基础实操数据的指标定义、监控和数据分析的能力就愈发重要。 目前定义了衡量实操效率和易用性的基础指标,核心关注用户能否顺滑的完成发货流程,避免逆向反复。 对应的实操效率看板如下: 八、后续规划 实操开仓效率 完成实操检测能力的验证,确定后续开仓流程细节,确认检测能力短板; 提升实操效率指标的可用性、逆向流程分析和发现问题的效率。 实操开仓保障 保障后续开仓顺利进行,补齐商品图无键盘切换、关键词信息和AI复检等能力; 保障PC实操在云仓DB和得物仓的兼容性和可用性,通过微前端兼容云仓登录,从而提升迭代的一致性和效率。 系统体验提升 信息透出屏效和自动录入能力; 设备环境问题可以通过"实操助手"检测能力自行解决; 业务异常不中断操作流程,并可以自行解决问题。 *文 / Tony 本文属得物技术原创,更多精彩文章请看:得物技术 未经得物技术许可严禁转载,否则依法追究法律责任!