前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >供应链PC实操落地实践|得物技术

供应链PC实操落地实践|得物技术

原创
作者头像
得物技术
修改2024-10-15 18:19:21
修改2024-10-15 18:19:21
14300
代码可运行
举报
文章被收录于专栏:得物技术
运行总次数:0
代码可运行

一、背景

在供应链履约流程中,PC实操发货主要负责 “完成复查入库商品的数量、规格和质量,并核对证书和防伪扣的正确性,确保商品无问题后,对订单内的商品进行打包、打印黏贴物流面单,并交接给3PL配送”。

作为配送前的最后一道屏障,需要确保供应链从生产入库到出库的环节的质量符合预期,最终将包裹交付到物流供应商,配送给消费者。

随着得物业务规模变大,供应链对成本、效率、质量的要求在不断提升,云仓业务模式开始逐步测试并铺开,仓内的设备环境与得物自有仓出现差异,因此PC实操系统需要在设备采购成本和实操的效率之间寻找平衡点。

云仓内的设备环境不一致,实操系统会面临如下问题:

  1. 大部分云仓BPO没有平板电脑,无法直接使用得物既有的实操系统(Pink Flutter App);
  2. 打印机型号众多,打印指令无法统一,容易造成打印配置和打印效果不一致;
  3. 设备类型和配置的不一致,带来了更多的适配问题,很容易形成业务流程的卡点,影响开仓和实操的效率。

为了解决这些问题,PC实操系统需要是跨平台的,从而保障系统使用的灵活性,并降低对设备种类的依赖度;其次通过接入得物统一打印组件,来抹平打印机型号的差异带来的成本

本文主要介绍实操发货交互模式的实现实操环境的检测及自动修复,文章最后也介绍了实操效率指标的定义

二、实操模式

实操系统的信息输入有多种选择,可以是触屏电脑、扫码枪、键盘鼠标等。实操过程需要向系统内的录入多种条形码、二维码等信息,以及复检、打包的结果信息。按照不同的输入设备类型,可以将实操分为如下几种:

PC实操系统同时支持了以上三种模式,但考虑到实际的设备环境和使用效率,推荐仓内使用扫码实操模式,即采用扫码枪 + 屏显二维码 + 粘贴实体码的混合扫码实操方案

三、快捷码设计和使用

在扫码模式中,可以将这些快捷指令二维码简称为“快捷码”。设计快捷码的初衷,是为了简化实操的输入设备种类,在不切换到键盘鼠标的情况下,仅通过扫码枪就可以完成信息的录入、操作指令的执行。快捷码除了可以进行数据接口通信、交互操作,也可以执行多个指令的组合指令。

快捷码布局

如何将快捷码融合到PC实操系统,考虑过多个方案:

1. 环绕布局

2. 左右布局

3. 二级指令菜单

指令折叠:有些指令使用频次很少,且具有一定的“误操作风险”,因此考虑二级指令菜单的交互,将不常用的折叠起来。借助扫码枪即可扫码打开二级菜单,此时操作区收窄,或者以Popup形式呈现,二级菜单发生有效扫码即可关闭,或者主动扫交互码关闭。

快捷指令交互系统:所有流程支持快捷指令,可以扫码展开、折叠,也可以扫码查看订单明细等,扫码关闭弹窗,代替鼠标,大部分操作需要做到扫完即关,确保操作区的可用性。

大部分快捷码在正向流程里的使用频率并不高,并且屏显快捷码过多,会增加扫错二维码的风险。因此在方案3的基础上,将二维码进行归类,并收纳到功能导航中,同时会建议将常用快捷码打印黏贴至工位使用

为了提升扫码的效率,屏幕上的快捷码会保持简洁,只会存在1-3个快捷码,并且在布局的设计上有较大的分布间距,避免扫码失误的情况出现。

快捷码的准确识别

我们定义以“@”字符开头标识一个快捷指令的开始,数字则代表快捷码类型,如 @01 代表打印面单。这样的设计可以降低生成的快捷码的复杂度,提升识别的准确率。

扫码枪扫码后会以连续字符串输入给活跃的焦点设备,并以Enter结尾;基于这个特点, 要准确识别一个快捷码指令有三个必要条件:@开头、 Enter结尾、连续输入。完成指令识别后,就可以准确执行指令注册的函数了。然而,在识别过程也会遇到一些问题。

  • 字符录入冲突。在一个连续的指令输入过程中,会禁用默认键入的内容,这样可以避免焦点处于输入框的同时扫描了快捷码,意外将快捷码字符录入到输入框中。
  • 焦点冲突。由于实操系统同时支持键盘模式操作,可以通过Enter键模拟鼠标对按钮的点击;当焦点处于按钮上时扫描了快捷码,扫码枪输入的Enter会造成按钮意外触发点击。因此在识别到扫码内容为快捷指令类型时,会在短时间将按钮移除焦点,指令结束后再重新设置焦点。
代码语言:javascript
代码运行次数:0
复制
(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片段并执行打印来实现,如下:

代码语言:javascript
代码运行次数:0
复制
/**
 * 打印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,并设置为首选输入法。

代码语言:javascript
代码运行次数:0
复制
// # 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云仓会逐步铺开,随着使用量的提升,基础实操数据的指标定义、监控和数据分析的能力就愈发重要。

目前定义了衡量实操效率和易用性的基础指标,核心关注用户能否顺滑的完成发货流程,避免逆向反复

对应的实操效率看板如下:

八、后续规划

1. 实操开仓效率

  • 完成实操检测能力的验证,确定后续开仓流程细节,确认检测能力短板;
  • 提升实操效率指标的可用性、逆向流程分析和发现问题的效率。

2. 实操开仓保障

  • 保障后续开仓顺利进行,补齐商品图无键盘切换、关键词信息和AI复检等能力;
  • 保障PC实操在云仓DB和得物仓的兼容性和可用性,通过微前端兼容云仓登录,从而提升迭代的一致性和效率。

3. 系统体验提升

  • 信息透出屏效和自动录入能力;
  • 设备环境问题可以通过“实操助手”检测能力自行解决;
  • 业务异常不中断操作流程,并可以自行解决问题。

* 文 / Tony

本文属得物技术原创,未经得物技术许可严禁转载,否则依法追究法律责任!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档