從技術債務到架構升級,滴滴國際化外賣的變革

c6d5408f7cbc5e2f87eca3bf2b9d4ee2.gif

背 景

82117221e394557f5567ae81a522a8e9.gif

商家營銷簡述

c2fd876f5c6e1e6279da793078e707d6.png

在外賣平臺的運營中,我們致力于通過靈活的補貼策略激勵商家,與商家共同打造良好的合作關系,也會提供多樣化的營銷活動,幫助商家吸引更多用戶下單。通過這些活動,不僅能夠提高商家的銷量,還能讓用戶感受到實際的優惠,從而增強他們對平臺的粘性。

7b56ce3baed28ebc8c2fcc0d7996d229.gif

前端技術特點

業務特點:營銷場景玩法多、活動類型多、活動鏈路長、活動規則復雜。

中后臺技術特點:活動配置表單規則多、聯動復雜。

前臺技術特點:終端類型多(PC/EXE/PAD/PHONE)、代碼重復度高、用戶輸入校驗規則復雜。

業務技術架構

0d0fae11da1b917020a91c0c1d4f8a00.png

活動鏈路

1460a94546612b24e2b99ba65af57640.png

商家營銷相關項目迭代時間較長,積累的歷史技術債務越來越多,結合業務背景和以上的技術特點,之前對歷史項目進行過一波代碼治理,比如:多端代碼復用、后臺復雜度治理等。????

2023年的治理更多解的是代碼重復及腐化相關的問題,而外賣商家營銷活動的配置能力還處于非常基礎的階段,2024年,我們結合業務新訴求的契機,從系統架構治理維度,對商家營銷前端項目做了一個全面的升級。

34482a6fef815996e73680f0b336cc93.gif

現狀

外賣商家營銷活動,按活動來源區分主要有四大類:平臺招商、代運營、品牌代建、商戶自營銷,按類型區分主要有四大類:特價菜、買贈、免配、滿減。前后端底層區分這些活動渠道及類型都是case by case的形式,以招商活動創建為例:

不同活動類型,優惠信息都放在不同的字段里,特價菜是specialItemRule,免配是freeDeliveryRule,滿減是reductionRule,買贈是buyGiftsRule,且規則rules字段層級嵌套冗余,字段屬性沒有規律可循,以下列舉了兩類活動的部分字段。

特價菜活動規則字段示例

"specialItemRule": [{"rulePurposeType": 0,"rules": [{"type": 3,"content": {"discountValueRange": null,"discountValueList": [10, 11, 20],"discountType": 1}}],"selectItemNumRange": {"min": 1,"max": 10},"itemPromoRangeValue": {"min": 1,"max": 50},"picLimit": 1,"priceLimit": null,"itemType": 0,"checkItemPriceDay": 7}]

滿減規則字段示例

"reductionRule": [{"rulePurposeType": 0,"rules": [{"type": 1,"content": {"threshold": 10,"discount": 5}}, {"type": 1,"content": {"threshold": 20,"discount": 8}}]}]

9412be4aeb911e93a361df51e7d928a6.gif

面臨的挑戰

2024年隨著國際化外賣營銷業務需求明顯增長,比如:需要從0到1搭建連鎖品牌商家自運營能力、拓展新的營銷活動類型(商家券),按照現有的架構及配置能力來看,存在以下幾個問題:

  • 產品需求迭代支撐效率低:涉及通用字段,需要重復修改,特價菜+免配+滿減+買贈,4種活動類型改4次,如果再算上活動渠道修改,需要再翻倍,4種渠道??4類活動 = 16 次。

  • 開發遺漏:活動鏈路長,以當前最為復雜的招商活動為例,從運營后臺配置招商計劃=>商戶前臺報名招商活動,是一個較長的鏈路,由于系統數據模型不夠靈活,導致修改字段及UI展示時無規律可循,經常需要梳理遺漏點。

  • 可拓展性差:當前架構下,如果新增活動類型,則涉及全鏈路所有接口改動,可復用性低。

由于業務發展的契機,國際化外賣商家側需要新增一個連鎖品牌管理端,借助這個項目,我們進行了商家營銷架構的升級。

88f537892ee5352b86fb544f735b2124.gif

解決方案

fff062f372f34617752d692421443699.gif

問題分析

商家營銷配置能力薄弱主要體現在底層數據結構缺乏通用性和擴展性。

從全局配置維度來看:

4e3e82c6c7a5e919b9d61c70a2779e3b.png

從數據結構現狀來看:

28277721b6e689a0dbe8b84da36a584e.png

  • 同一類活動,在不同平臺(端、后臺)數據結構不一致。

  • 同一類活動,在不同活動來源場景下(自營銷、招商、代運營、品牌),數據結構不一致。

  • 四類活動,活動規則數據結構不一致,創建需要case by case拼裝,詳情需要case by case渲染。

  • 差異化分支共有:自營銷創建4 + 招商報名4 + 招商計劃4 + 代運營1 + 品牌4 =?17

bba6deab74a8bae8e4593c08c58fdbfc.gif

整體思路

架構治理最重要的一環就是設計出一個統一的活動數據模型,涵蓋所有平臺和活動來源場景。

67cff1624fb4aa1263b95a07036d17cd.png

  • 抽象活動實體信息

  • 統一差異化配置

  1. 按活動信息維度拆分組織字段,而不是按業務維度拆分(收斂類型、來源)。

  2. 按通用字段概括優惠類型,而不是按業務概念枚舉(收斂規則)。

  • 支持靈活拓展

fe6ab9894837482b39043764d8548b87.gif

項目成果

在抽象出活動配置模型后,為保證后續需求或者人員變更能夠按照規范持續迭代,通過對應的配置模型的API文檔,配套前端JSON Schema校驗工具,約束后續拓展。

底層數據結構完成治理后,在新項目中,我們也對配置表單方案進行了優化,使得項目的數據流轉更加清晰,確保數據的一致性和可靠性。

而在前后端交互層面,對接口字段進行了運行時校驗,做到了接口安全約束,避免因數據缺陷而導致的前端錯誤。

934da6bab9adc7d3e22c023f72e37ef7.gif

數據結構對比

新版活動數據結構是一個面向對象的設計架構,采用組合式領域模型設計,通過策略模式實現業務規則的動態裝配。

基礎活動模型(ActInfoModel)可以被視為一個父類或者超類,定義了通用的屬性和行為,而其子類(如自營銷活動模型selfOpsModel)繼承了基礎特性,并可以實現或者重寫一些特定的功能,以滿足不同渠道的具體需求。

當出現新的渠道或者活動類型時,只需要創建新的子類,遵循現有的父類結構。而基礎模型的修改也不會影響所有子類,只需要確保子類能夠適應父類的接口變化即可。

bb9b8e6f23b81d998fe7ced944345bcf.png

07bb9ae91e5f0bcc9241d8b4dfc1cc55.gif

配置表單方案優化

在之前的項目里,表單間的組件通信,是傳統多層組件的數據傳遞形式,通過父子組件層層傳遞。

d50236d151224f79dfacc516320a80cb.png

數據流:自上而下,每個組件都需要通過props接受和傳遞數據。

缺點:增加了代碼復雜性,每個組件都需要顯式傳遞數據,容易出現冗余代碼和數據同步問題。

這種形式對于簡單的表單場景來說,比較直觀,但是對于商家營銷活動配置場景來說,在過往需求迭代中出現了維護困難和數據同步異常的問題,在新項目里,我們使用了配置模型+依賴注入的表單方案。

3e6e565e1e840f2950321a888ed37218.png

數據流: 數據通過依賴注入在組件樹的各層之間傳遞,子組件直接獲取所需數據

優點: 降低了組件之間的耦合性,減少了多層傳遞的冗余性,數據更加集中且易于管理

數據流轉對比

ca949fb9baec1ef25f85c238970be44b.png

使用配置模型 + 依賴注入的方式不僅可以簡化數據流轉,還能實現集中管理,減少代碼冗余,提高數據一致性,更容易進行維護和調試,特別是在需要動態配置或復雜業務邏輯的場景下表現尤為突出。

84ab7ce00545421977ab6e4067b8e0ea.gif

接口安全保障

當前數據安全問題

為了避免接口數據異常,導致前端頁面白屏,我們通常會在代碼中加一些字段兜底邏輯,這樣帶來的問題:

  • 冗余的兜底邏輯:在組件中,使用“||“操作符、可選鏈和解構默認值等方式進行兜底處理,導致同樣的邏輯在多個地方反復出現。

  • 復雜的數據結構處理:對于復雜的數據結構,通常為了某個字段兜底會出現一大坨繁瑣的代碼,影響代碼可讀性與代碼效率。

  • 數據類型安全問題:常規兜底形式無法保證數據類型安全,可能造成不符合預期的類型錯誤,進而引發應用程序中的邏輯錯誤或頁面崩潰。

在抽象出活動配置模型后,活動配置的定義是由標準的JSON Schema描述組成的,在這個基礎上,我們定義一些校驗及默認填充規則,并引入集中式的兜底機制,在接口數據返回時,調用一個校驗工具函數,實現統一的兜底策略。校驗工具函數是借助zod這個工具庫去實現的。

招商活動配置描述示例

// 招商活動規則
export const SignUpActRuleSchema = ActRuleSchema.extend({selectNumRange: z.object({min: z.number().default(0),max: z.number().default(0),}).default({ min: 0, max: 0 }),actType: z.union([z.number(), z.string()]).default(0),rule: z.array(SignUpRuleSchema).default([]),
})
export type SignUpActRule = z.infer<typeof SignUpActRuleSchema>// 招商活動詳情頁接口信息
export const SignUpDetailSchema = z.object({actRule: SignUpActRuleSchema.default({}),actInfo: SignUpInfoSchema.default({}),shopJoinInfo: z.array(ShopJoinInfoSchema).default([]),
})

?接口返回處理示例

// 招商活動詳情接口
// useApiSchema是統一的返回數據校驗工具函數
export async function getSignUpDetail(params: object = {}): Promise<SignUpDetail> {const response = await post(GET_SIGN_UP_DETAIL, params, { returnData: false })return useApiSchema<SignUpDetail>(SignUpDetailSchema, response.data, response.traceId)
}

useApiSchema函數功能包含:數據校驗、兜底數據填充、埋點上報。

接口返回字段中若出現返回數據類型錯誤或者未返回的情況,將返回自定義的默認值從而保障頁面正常展示,對于錯誤數據也做了埋點上報,當到達一定閾值時會進行報警。

adb9b15fda60921b770d3c3278956f60.gif

效率提升

日常迭代

活動配置模型通過字段的抽象和整合,大幅提升了字段擴展的效率。原本因各活動類型和場景的數據結構差異,需要在多處修改數據結構和組件邏輯的場景,現在只需在一處進行修改即可,大大提高了開發效率。

以前臺項目活動規則相關迭代為例:

4858dd86d23322be33302e9329c463a3.png


開發實例

以近期需求為例,我們需要新增一種券活動類型,通過采用活動配置模型和集中式狀態管理的開發形式,使得開發過程中對于數據相關的處理邏輯與狀態管理要比之前簡易很多,開發效率提升約40%

04d7fafaf3282e0b3783108acf8f7ee7.gif

后續規劃

以上架構治理都是針對新的項目去做的實踐,而對于國際化外賣商家營銷前端的其他項目同樣需要做架構升級改造,后續我們計劃收斂運營后臺的活動配置,將最為復雜的招商活動鏈路進行標準化,后臺配置=>前臺應用,引用同一套數據模型。

國際化外賣商家營銷前端架構預期

a6c24bc92116ebd99be0d3fb39609f96.png

b10055791bb59e1e007aeb8aaf1e116b.gif

往期文章回顧

fe660ffc84f9eb75fefe6f055703fa93.png

ace4c42c6569082cb8cc5190b6141698.gif

致謝

核心開發:杜雨軒、閆莉

關鍵合作方:宋亞閣、陳玨、吳召學

項目指導:董亞杰

整體方案的產出到落地實踐離不開以上同學的辛苦付出,借此機會表示由衷感謝!同時,也非常感謝能夠耐心閱讀到這里的讀者,業務技術架構治理是一個持續的過程,需要持續的關注、投入與調整,也需要與業務深度融合,以實現業務與技術目標的雙贏。

歡迎感興趣的同學拍磚指導,一起交流討論!小編將選取5位同學,送上20W無線充電器!

934d351de39d12cf0b6e8c4c40b448cd.jpeg

//??E N D?//

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/70077.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/70077.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/70077.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

英語—四級CET4考試—技巧篇—選詞填空—實操教學—2014 年 6 月大學英語四級考試真題(第 2 套)

&#x1f3e0;個人主頁&#xff1a;fo安方的博客? &#x1f482;個人簡歷&#xff1a;大家好&#xff0c;我是fo安方&#xff0c;目前中南大學MBA在讀&#xff0c;也考取過HCIE Cloud Computing、CCIE Security、PMP、CISP、RHCE、CCNP RS、PEST 3等證書。&#x1f433; &…

線性代數中的正交和標準正交向量

在線性代數中&#xff0c;理解正交向量和正交向量至關重要&#xff0c;尤其是對于機器學習中的應用。這篇博文將簡化這些概念&#xff0c;而不會太深入地深入研究復雜的數學。 正交向量 如果兩個向量的點積等于零&#xff0c;則認為這兩個向量是正交的。但點積到底是什么呢&am…

企業文件共享中的權限管理與安全風險防范

在企業的日常運營中&#xff0c;文件共享是必不可少的一項工作。然而&#xff0c;文件共享過程中如果權限管理不當&#xff0c;極易引發安全風險&#xff0c;導致企業敏感信息泄露。因此&#xff0c;加強文件共享中的權限管理與安全風險防范&#xff0c;對于保障企業信息安全至…

急停信號的含義

前言&#xff1a; 大家好&#xff0c;我是上位機馬工&#xff0c;碩士畢業4年年入40萬&#xff0c;目前在一家自動化公司擔任軟件經理&#xff0c;從事C#上位機軟件開發8年以上&#xff01;我們在開發C#的運動控制程序的時候&#xff0c;一個必要的步驟就是確認設備按鈕的急停…

數據結構:圖;鄰接矩陣和鄰接表

鄰接矩陣&#xff1a; 1.概念&#xff1a; 鄰接矩陣是圖的存儲結構之一&#xff0c;通過二維數組表示頂點間的連接關系。 2.具體例子 &#xff1a; 一.無向圖鄰接矩陣示例&#xff1a; 示例圖&#xff08;頂點&#xff1a;A、B、C&#xff0c;邊&#xff1a;A-B、B-C&…

Kubernetes-master 組件

以下是Kubernetes Master Machine的組件。 etcd 它存儲集群中每個節點可以使用的配置信息。它是一個高可用性鍵值存儲&#xff0c;可以在多個節點之間分布。只有Kubernetes API服務器可以訪問它&#xff0c;因為它可能具有一些敏感信息。這是一個分布式鍵值存儲&#xff0c;所…

【第2章:神經網絡基礎與實現——2.1 前饋神經網絡的結構與工作原理】

老鐵們好!今天我們要來一場長達兩萬字的超詳細技術探險,我會像拆解樂高積木一樣把前饋神經網絡(Feedforward Neural Network)的每個零件擺在臺面上,用最接地氣的方式讓你徹底搞懂這個深度學習基石的工作原理。準備好了嗎?我們開始吧! 第一章:神經網絡的 “樂高積木” 1…

【云安全】云原生- K8S kubeconfig 文件泄露

什么是 kubeconfig 文件&#xff1f; kubeconfig 文件是 Kubernetes 的配置文件&#xff0c;用于存儲集群的訪問憑證、API Server 的地址和認證信息&#xff0c;允許用戶和 kubectl 等工具與 Kubernetes 集群進行交互。它通常包含多個集群的配置&#xff0c;支持通過上下文&am…

【環境安裝】重裝Docker-26.0.2版本

【機器背景說明】Linux-Centos7&#xff1b;已有低版本的Docker 【目標環境說明】 卸載已有Docker&#xff0c;用docker-26.0.2.tgz安裝包安裝 1.Docker包下載 下載地址&#xff1a;Index of linux/static/stable/x86_64/ 2.卸載已有的Docker 卸載之前首先停掉服務 sudo…

字節跳動后端二面

&#x1f4cd;1. 數據庫的事務性質&#xff0c;InnoDB是如何實現的&#xff1f; 數據庫事務具有ACID特性&#xff0c;即原子性、一致性、隔離性和持久性。InnoDB通過以下機制實現這些特性&#xff1a; &#x1f680; 實現細節&#xff1a; 原子性&#xff1a;通過undo log實…

SpringBoot中使用MyBatis-Plus詳細介紹

目錄 一、MyBatis-Plus的使用步驟 1.引入MybatisPlus的起步依賴 2.定義Mapper&#xff08;也叫dao&#xff09;層的接口 3.MyBatis-Plus中常用注解 4. 使用MyBatis-Plus時要做如下配置 5.條件構造器 Wrapper 一、MyBatis-Plus的使用步驟 1.引入MybatisPlus的起步依賴 M…

vue3讀取webrtc-stream 視頻流

一.首先下載webrtc-stream&#xff0c;方便自己本地搭建視頻流服務 https://download.csdn.net/download/cyw8998/90373521 解壓后&#xff0c;啟動命令 webrtc-streamer.exe -H 127.0.0.1:8020 二.vue3代碼如下 <template><h1>video</h1><video id&…

vue3搭建實戰項目筆記二

vue3搭建實戰項目筆記二 2.1.git管理項目2.2.隱藏tabBar欄2.2.1 方案一&#xff1a;在路由元信息中設置一個參數是否顯示tabBar2.2.2 方案二&#xff1a;通過全局設置相對定位樣式 2.3.項目里封裝axios2.3.1 發送網絡請求的兩種做法2.3.2 封裝axios并發送網絡請求2.3.2.1 對axi…

USC 安防平臺之移動偵測

隨著第四次科技革命的開啟&#xff0c;AI技術獲取了突飛猛進的發展&#xff0c;視頻監控對應的視頻分析技術也獲取了巨大的發展。 還記得15年前采用人工提取特征做前景背景分離和提取&#xff0c;大部分依賴CPU&#xff0c;最多使用一下TI的DM642 DSP加速&#xff0c;開發難度…

Unity CommandBuffer繪制粒子系統網格顯示

CommandBuffer是 Unity 提供的一種在渲染流程中插入自定義渲染命令的機制。在渲染粒子系統時&#xff0c;常規的渲染流程可能無法滿足特定的渲染需求&#xff0c;而CommandBuffer允許開發者靈活地設置渲染參數、控制渲染順序以及執行自定義的繪制操作。通過它&#xff0c;可以精…

【天地圖】繪制、刪除點線面

使用天地圖繪制、刪除點線面 實現效果圖地圖組件完整代碼使用地圖組件完整代碼 實現效果圖 地圖組件完整代碼 // 天地圖組件 <template><div class"map-container"><div id"mapCon"></div></div> </template><scri…

Java八股文詳細文檔.2(基于黑馬、ChatGPT、DeepSeek)

通過B站黑馬程序員的八股文教學&#xff0c;自己也二刷了&#xff0c;結合ChatGpt、deepSeek總結了一下,Java八股文詳細文檔.2&#xff08;Redis篇和消息中間件篇&#xff0c;還沒有寫完&#xff0c;這只是一部分&#xff09; Java八股文詳細文檔.1&#xff08;包含JVM篇、數據…

簡述 tsconfig.json 中 rootDir 和 include 之間的關系

tsconfig.json 中的 rootDir 和 include 之間有一定的關系&#xff0c;但它們的作用是不同的。理解它們的關系可以幫助你更好地配置 TypeScript 項目。 1. rootDir 的作用 rootDir 用于指定 TypeScript 編譯器&#xff08;tsc&#xff09;的“根目錄”。它的主要作用是&#x…

如何在Spring Boot中使用Profiles實現環境隔離

文章目錄 如何在Spring Boot中使用Profiles實現環境隔離什么是Spring Profiles1.基本概念2.配置管理3.使用場景4.條件化配置5.優點Spring Profiles的基礎知識1.Profile的定義2.配置文件3.激活Profiles4.條件化配置5.Profile的優先級與合并6.Profiles的最佳實踐配置文件的組織1.…

SpringBoot使用TraceId日志鏈路追蹤

項目場景&#xff1a; ??有時候一個業務調用鏈場景&#xff0c;很長&#xff0c;調了各種各樣的方法&#xff0c;看日志的時候&#xff0c;各個接口的日志穿插&#xff0c;確實讓人頭大。為了解決這個痛點&#xff0c;就使用了TraceId&#xff0c;根據TraceId關鍵字進入服務…