物流路由线路配载前端算法逻辑实现方案

asdnglove 2023-04-27 19:27:30

    1. 前置知识

    1.1 基本概念

    1.1.1 配载

    配载代表着某条线路是否具有发往某个方向(区域、省市县、分拣等)的能力,也可以说是网点(分拣中心)是否具有承载配载所指方向货物的能力。一般网络规划者,在均衡线路间货量时,会通过调整配载来完成。

    线路上可允许配载货物的 “产品类型、最终妥投目的地”,通过线路的配载,计算 当前网点 到 目的网点 的 下一个网点 ,线路 绑定的配载代表通过当前线路最终可以到达的目的地 。以下图为例

    表示:如果放置在整个路由网络资源中,一个标记 T1 的货物要从北京发往福建,可选的路由有①北京站 - 北京 - 武汉 - 福建 - 福建站;②北京站 - 北京 - 广州 - 福建 - 福建站;之所以剔除了北京站 - 北京 - 上海 - 福建 - 福建站以及北京站 - 北京 - 武汉 - 上海 - 福建 - 福建站,正是因为后两条线路中未包含 T1 的配载代码,只标记了 T2 , 说明这条线路只有配载航空的货物,而没有普通陆运的带货能力。

    下图就是用于描述配载的树形结构

    1.1.2 班期与生失效日期

    班期:指的是发运频率,1234567 代表着每周七天中,这个班次的 “上线时间”,一般来讲,维护时缺失某个值,会造成路由中断的现象。

    生失效日期:指的是该配载有效时间范围

    1.1.3 配载合并逻辑

    网点四级地址的关系以配载树的形式展现,勾选节点添加的配载在右侧的配载列表中展示

    当某个节点的子节点没有全部勾选时,展示当前勾选的节点到配载列表中

    当某个节点的子节点全部勾选时(在符合相关条件时,这里涉及到的算法逻辑后面详述),展示相应的父节点到配载列表中,这个逻辑是递归的

    1.2 现有实现技术

    目前的线路配载前端基于 zTree+FixedHeaderTable+JQuery 实现,通过 zTree 监听节点被选中和取消选中,计算该操作后是否触发节点的合并或展开,进而重新渲染配载列表中的数据

    2. 现状问题

    2.1 节点合并算法逻辑有误

    如果一个父节点下的所有子节点都被维护,即使子节点下的班期不同、生失效日期不重叠,系统都会自动合并到父节点。合并的展示效果为:

    班期:对于纯新增配载显示 1234567;对于父节点下有一个子节点,班期显示为已存在配载的班期

    生失效时间:统一为该切段线路的生失效日期

    例如:X 线路被切割成两段,2022-11-02~2023-01-25 以及 2022-01-26~ 长久有效两段,在线路视图点击 2022-11-02~2023-01-25 这段的配载维护,X 下有 A1(配载时间为 2022-11-02~ 长久有效、班期 12),其父节点为 A,A 下还有子节点 A2、A3。今天是 11.17 日,将 A2、A3 都勾选上(时间任意,班期为 12345),配载会立刻合并为 A(生效时间 2022-11-02~2023-01-25,配载 1234567)

    线路X

    生效时间        失效时间

    2022-11-02   2023-01-25

    A(父节点):包含A1、A2、A3三个子节点,当前只存在A1的配载如下:

    生效时间        失效时间        班期

    A1  2022-11-02   2099-12-31      12

    参考日期为11.17日,此时勾选A2+A3后触发A的合并,此时配载列表展示A节点

    生效时间        失效时间        班期

    A  2022-11-02   2023-01-25      1234567

    2.2 配载保存和显示的值不一致

    上面操作触发合并,提交后库中保存的配载记录为:

    生效时间        失效时间        班期

    A1  2022-11-02    2022-11-16     12

    A   2022-11-17    2023-01-25     1234567

    2.3 本质原因

    原有根据 zTree 节点触发合并的算法有问题,不考虑当前节点下其他子节点的配载的班期和生失效日期,而是根据是否同一个父节点直接合并。导致合并逻辑错误,保存与展示的数据不一致。

    3. 预期效果

    3.1 配载合并班期逻辑

    条件:同一个父节点 + 各个子节点班期一致

    A(父节点):包含A1、A2、A3三个子节点,其中任意节点的班期不一致都无法合并

    3.2 配载生失效日期切断逻辑

    新添加节点,生效日期 为 参考日期,失效日期 为 线路失效日期

    参考日期选择 大于 当前 同级子节点的某天,当触发合并时

    合并后的父节点:生效日期取参考日期,失效时间取 同级子节点列表中失效时间最小的

    合并后的子节点:

    1)如果 原始生效日期 小于 合并后 父节点的生效日期,则切断 原始生效日期~父节点的生效日期 - 1 天(相当于保留切断前的生效日期那一段)

    2)如果 原始失效日期 大于 合并后 父节点的失效日期,则切断 父节点的失效日期 + 1 ~ 原始失效日期 (相当于保留切断前的失效日期那一段)

    针对同一个节点的配载生失效日期切断的逻辑,举例

    1. 配载A的原始生失效时间为 20221103 - 20221110

    2. 配载A在经过同级子节点合并后,生失效时间为 20221105-20221108

    3. 那么对于配载A来说,在合并后仍然需要保留两段配载记录

    3.1 生失效时间为 20221103-20221104

    3.2 生失效时间为 20221109-20221110

    3.3 配载合并后保存逻辑

    采用所见即所的方式保存数据,用户在前端完成切断操作后,保存到数据库的记录与前端展示一致

    4. 实现逻辑

    4.1 整体逻辑

    4.2 定义数据结构及初始化

    zTree:配载树

    treeNode:配载树中的节点

    nodeId:节点id

    childrenNodes:包含当前节点的所有子节点集合

    stowageList:配载列表的Dom结构

    originStowageMapTI:原始配载:{key:节点;value:配载数据的dom结构}

    newStowageMapTI:新增节点配载:{key:节点id;value:节点}

    stowageFrequencyMap:配载节点和班期关系:{key:节点id;value:班期}

    stowageTimeMap:配载节点和生失效日期关系:{key:节点id;value:[生效时间,失效时间]}

    frequencyTreeMap:班期和节点的关系:{key:班期;value:节点数组}

    node.pid:节点的父id

    node.id:节点的id

    在配载树上监听事件,当触发选中 / 取消选中时,递归的获取 childrenNodes

    维护配载与班期、配载与生失效日期的关系

    将已有配载列表中的数据维护到 stowageFrequencyMap、stowageTimeMap、originStowageMapTI 中

    4.3 配载合并班期逻辑

    1)如果当前节点非禁用 && 勾选 执行 合并逻辑;否则递归遍历节点;最终返回结果集

    2)如果当前节点非半选 && 非父节点,向父节点中查找班期,维护节点属性,加入结果集并返回

    3)根据节点的 pid 查找 stowageFrequencyMap 中是否存在班期

    配载树中的网点关系主要是四级,举例说明 C(快递全国) 下面某些节点的level 与 pid 的关系

    level=1

    pid:C  表示全国

    level=2

    pid:C-10 表示华南

    level=3

    pid:C-10-16 表示福建

    level=4

    pid:C-10-16-1303 表示泉州

    算法逻辑:根据pid截取相应的字符串为key,查找是否存在父节点的班期

    1. 如果是父节点则遍历,按照每个子节点去 stowageFrequencyMap 中获取班期,分为两种情况如下;找到班期后维护 frequencyTreeMap,将同班期的节点维护到 list 中保存,即形成 班期 - 节点 list 的数据结构

    2. 向父节点中获取班期,同上

    3. 向子节点中递归获取班期,并将结果保存到新的数据结构 frequencyChildMap 中,然后合并到 frequencyTreeMap 中

    对 frequencyTreeMap 集合进行判断,如果数量为 1 表示 与该节点同级的节点班期相同,触发了合并,将节点加入结果集返回;否则说明当前节点的同级节点存在不同班期,不能进行节点向上合并,直接遍历 frequencyTreeMap 中的 value 集合,加入结果集返回

    对于触发了合并的结果集 frequencyTreeMap 中的每个节点遍历 同 当前线路的生失效日期比较,取出同级节点中的 最大生效时间,最小失效时间,作为该同级节点中的最大公共时间范围设置到每个节点属性中

    4.4 配载生失效日期切断逻辑

    定义变量

    1. queryTime:参考日期

    2. maxDisableTime:最大失效时间

    3. enableTime:线路生效时间

    4. disableTime:线路失效时间

    5. originEnableTime:记录原始生效时间

    6. originDisableTime:记录原始失效时间

    7. newDisableTime :enableTime - 24 * 60 * 60 * 1000

    8. newEnableTime:disableTime + 24 * 60 * 60 * 1000

    循环遍历每个结果集中的节点,判断是否渲染到配载列表中

    根据当前节点 id 判断是否存在于 stowageList 中,如果存在直接显示;根据节点 id 删除 originStowageMapTI 集合

    更新生失效日期,分别判断 原始配载中是否存在需要切断的日期,新添加配载中是否存在需要切断的日期;然后将当前节点添加到配载列表中

    遍历 originStowageMapTI ,判断历史的配载节点是否需要进行日期切断,分为以下两种情况;然后根据节点 id 删除 originStowageMapTI

    如果 originEnableTime < enableTime:添加新的配载记录,生效时间取 originEnableTime, 失效时间取 newDisableTime

    如果 originDisableTime > disableTime:添加新的配载记录,生效时间取 newEnableTime, 失效时间取 originDisableTime

    遍历 newStowageMapTI ,判断新添加的节点是否需要进行日期切断;然后根据节点 id 删除 newStowageMapTI

    如果 originDisableTime > disableTime:添加新的配载记录,生效时间取 newEnableTime, 失效时间取 originDisableTime

    5. 总结

    路由线路配载维护业务核心且频繁使用功能,为了实现业务述求,将完全没有关联的树形结构 和 Dom 列表 结合在一起。采用了多种数据模型 + 数据结构的组合形式,构造两者之间的关系,结合遍历、深度优先搜索、字符串查找等算法进行实现,在春节串点优化专项上线后取得了预期的收益。

---------------------------------------------------------------------------------------------------------------------------

每日小知识分享:每一个 HTML 文档中,都有一个不可或缺的标签:<head>,在几乎所有的HTML里, 我们都可以看到类似下面这段代码:

<head><meta charset=utf-8><meta http-equiv=content-type content=text/html; charset=utf-8><meta name=renderer content=webkit/><meta name=force-rendering content=webkit/><meta http-equiv=X-UA-Compatible content=IE=edge,chrome=1/><meta http-equiv=Content-Type content=www.llyz.net imtoken;charset=gb2312><meta name=viewport content=width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no></head>

head标签作为一个容器,主要包含了用于描述 HTML 文档自身信息(元数据)的标签,这些标签一般不会在页面中被显示出来,主要告知搜索引擎本页面的关键字以及对应网址,在SEO中传递相关权重起到非常重要的作用。

...全文
19 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

20

社区成员

发帖
与我相关
我的任务
社区描述
欢迎各位区块链技术应用的学者来交流
社区管理员
  • 小林同学i
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧