電商系統設計之商品 (下)

GraceDevelopment發表於2018-07-31

電商大夥每天都在用,類似某貓,某狗等。 電商系統設計看似複雜又很簡單,看似簡單又很複雜 本章適合初級工程師及中級工程師細看,大佬請隨意

前言

商品系統與訂單系統(交易系統)是相鋪相成的,當買家購買商品後將經歷一個過程

商品系統->交易系統->訂單系統->物流系統->售後系統

clipboard.png

完成上述流程則是完成了一筆交易,經常網上購物的童鞋都懂這個。今天我們講下從商品系統到交易系統和訂單系統的儲存過程及其設計上的應該注意的“坑”。

儲存

前倆篇文章講解的商品系統的SKU與SPU的設計過程

  • SPU(Standard Product Unit)標準化產品單元
  • SKU(Stock Keeping Unit)庫存量單元

現在我們已經清楚商品系統資料表的設計並且清楚為什麼要這樣設計。

現在丟擲了一個問題

使用者購買的商品如何儲存到訂單/交易系統中?

關聯問題

現在有這麼一個場景

小明在某寶買了一部愛瘋手機,顏色是紅色,儲存是32G,他選擇使用某寶支付.

SKU 產品 顏色 儲存
001 愛瘋手機 紅色 32G
002 愛瘋手機 紅色 256G
003 愛瘋手機 黑色 32G
004 愛瘋手機 黑色 256G

小明選擇購買SKU=001的產品,正常情況下訂單表應該與此SKU編碼相關聯來維持資料一致性。像這樣

訂單號 使用者 SKU
SN110 小明 001

這種設計有個弊端,商品的名稱及價格都不是固定,如果商戶修改了商品的標題或者其他的屬性,那小明當時買的愛瘋手機是8000元,結果過了幾年降價了商戶修改了價格,結果小明的購買清單裡也變成了修改後的價格,所以說這種僅僅關聯的設計是不可取的(至少在電商系統中不可取)。

訂單號 使用者 SKU 商品標題 商品價格 商品封面圖 商品其他屬性
SN110 小明 001 愛瘋手機 8000 aifeng.png 其他屬性

像上表中設計,有人會問了 “那關聯的意義何在呢?”

我的回答是 “保持資料關聯” ,雖然商戶有可能改變商品屬性,但作為一名程式設計師,應該儘可能的記錄使用者所有的動作。

文末有訂單表的資料結構

多商戶電商

實際在電商系統設計上,個人感覺不應區分多商戶的電商與單使用者的電商(至少開發者不應區分他們),但前期設計上就應把多商戶概念帶入到系統內。哪怕只有一個官方專賣店呢?!

clipboard.png

涉及到多商戶就需要考慮使用者統一下單問題了。

  • 訂單是由購物車下單,多個商品來自多個商戶
  • 如果進行拆單、分單
  • 如何進行下單通知等等多商戶的問題

關於多商戶的問題不是本章的重點,本次我先提出這幾個疑問,感興趣的同學可以提前思考下,後續文章會詳細講解

訂單是由購物車下單,多個商品來自多個商戶

如果下單是來自多個商戶的商品,那麼訂單的資料庫介面應該這樣設計

訂單表

訂單號 使用者
SN110 小明

訂單詳情表

訂單號 SKU 使用者 商戶
SN110 001 小明 官方
SN110 002 小明 第三方

無論購買多少商品並且商品歸屬於多少個商戶,我們都應把使用者一次性購買的商品歸屬與一個訂單,訂單下再關聯多個商品的詳情。在售後操作上,也方便買家退換單個商品。

文末有詳細資料結構設計

後臺功能列表

這裡提供下功能名稱與URL為參考

選單名稱 URL
商品管理 /product
釋出商品 /product/create
商品類目 /product/category
品牌管理 /product/brand
規格管理 /product/attribute
回收站 /product/recycle
訂單列表 /order

後臺的設計和操作套路我會單獨拿一篇文章來介紹。這裡只做一個大概的table。

資料表

order 訂單表

CREATE TABLE `order` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_no` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '訂單編號',
  `order_sn` varchar(100) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '交易號',
  `member_id` int(11) NOT NULL COMMENT '客戶編號',
  `supplier_id` int(11) DEFAULT '0' COMMENT '商戶編碼',
  `supplier_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '商戶名稱',
  `order_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '訂單狀態 0未付款,1已付款,2已發貨,3已簽收,-1退貨申請,-2退貨中,-3已退貨,-4取消交易 -5撤銷申請',
  `after_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '使用者售後狀態 0 未發起售後 1 申請售後 -1 售後已取消 2 處理中 200 處理完畢',
  `product_count` int(11) NOT NULL DEFAULT '0' COMMENT '商品數量',
  `product_amount_total` decimal(12,4) NOT NULL COMMENT '商品總價',
  `order_amount_total` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT '實際付款金額',
  `logistics_fee` decimal(12,4) NOT NULL COMMENT '運費金額',
  `address_id` int(11) NOT NULL COMMENT '收貨地址編碼',
  `pay_channel` tinyint(4) NOT NULL DEFAULT '0' COMMENT '支付渠道 0餘額 1微信 2支付寶',
  `out_trade_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '訂單支付單號',
  `escrow_trade_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '第三方支付流水號',
  `pay_time` int(11) NOT NULL DEFAULT '0' COMMENT '付款時間',
  `delivery_time` int(11) NOT NULL DEFAULT '0' COMMENT '發貨時間',
  `order_settlement_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '訂單結算狀態 0未結算 1已結算',
  `order_settlement_time` int(11) NOT NULL DEFAULT '0' COMMENT '訂單結算時間',
  `is_package` enum('0','1') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '是否是套餐',
  `is_integral` enum('0','1') COLLATE utf8mb4_unicode_ci DEFAULT '0' COMMENT '是否是積分產品',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `order_order_sn_member_id_order_status_out_trade_no_index` (`order_sn`,`member_id`,`order_status`,`out_trade_no`(191))
) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
複製程式碼

order_detail 訂單詳情

CREATE TABLE `order_detail` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL COMMENT '訂單編碼',
  `product_id` int(11) NOT NULL COMMENT '商品編碼',
  `product_name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品名稱',
  `product_price` decimal(12,4) NOT NULL COMMENT '商品價格',
  `product_sku` int(11) NOT NULL COMMENT '商品SKU',
  `product_picture_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
  `product_mode_desc` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '商品型號資訊',
  `product_mode_params` int(11) DEFAULT NULL COMMENT '商品型號引數',
  `discount_rate` tinyint(4) NOT NULL DEFAULT '0' COMMENT '折扣比例',
  `discount_amount` decimal(12,4) NOT NULL DEFAULT '0.0000' COMMENT '折扣比例',
  `number` int(11) NOT NULL DEFAULT '1' COMMENT '購買數量',
  `subtotal` decimal(12,4) NOT NULL COMMENT '小計金額',
  `is_product_exists` enum('0','1') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0' COMMENT '商品是否有效 1失效',
  `remark` text COLLATE utf8mb4_unicode_ci COMMENT '客戶商品備註',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `order_detail_order_id_index` (`order_id`)
) ENGINE=InnoDB AUTO_INCREMENT=118 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
複製程式碼

order_logistics 訂單物流

CREATE TABLE `order_logistics` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_id` int(11) NOT NULL COMMENT '訂單編碼',
  `express_no` varchar(125) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '發貨快遞單號',
  `consignee_realname` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收貨人姓名',
  `consignee_telphone` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '聯絡電話',
  `consignee_telphone2` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '備用聯絡電話',
  `consignee_address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收貨地址',
  `consignee_zip` int(11) NOT NULL COMMENT '郵政編碼',
  `logistics_type` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流方式',
  `logistics_fee` decimal(12,2) NOT NULL DEFAULT '0.00' COMMENT '物流發貨運費',
  `order_logistics_status` int(11) NOT NULL DEFAULT '0' COMMENT '物流狀態',
  `logistics_settlement_status` int(11) NOT NULL DEFAULT '0' COMMENT '物流結算狀態',
  `logistics_result_last` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流最後狀態描述',
  `logistics_result` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流描述',
  `logistics_create_time` int(11) NOT NULL DEFAULT '0' COMMENT '發貨時間',
  `logistics_update_time` int(11) NOT NULL DEFAULT '0' COMMENT '物流更新時間',
  `logistics_settlement_time` int(11) NOT NULL DEFAULT '0' COMMENT '物流結算時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
複製程式碼

order_returns 訂單退換貨

CREATE TABLE `order_returns` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `returns_no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '退貨編號 供客戶查詢',
  `order_id` int(11) NOT NULL COMMENT '訂單編號',
  `express_no` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流單號',
  `consignee_realname` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收貨人姓名',
  `consignee_telphone` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '聯絡電話',
  `consignee_telphone2` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '備用聯絡電話',
  `consignee_address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '收貨地址',
  `consignee_zip` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '郵政編碼',
  `logistics_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '物流方式',
  `logistics_fee` decimal(12,2) NOT NULL COMMENT '物流發貨運費',
  `order_logistics_status` int(11) DEFAULT NULL COMMENT '物流狀態',
  `logistics_settlement_status` int(11) DEFAULT NULL COMMENT '物流結算狀態',
  `logistics_result_last` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流最後狀態描述',
  `logistics_result` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '物流描述',
  `logistics_create_time` int(11) DEFAULT NULL COMMENT '發貨時間',
  `logistics_update_time` int(11) DEFAULT NULL COMMENT '物流更新時間',
  `logistics_settlement_time` int(11) DEFAULT NULL COMMENT '物流結算時間',
  `returns_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '0全部退單 1部分退單',
  `handling_way` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'PUPAWAY:退貨入庫;REDELIVERY:重新發貨;RECLAIM-REDELIVERY:不要求歸還並重新發貨; REFUND:退款; COMPENSATION:不退貨並賠償',
  `returns_amount` decimal(8,2) NOT NULL COMMENT '退款金額',
  `return_submit_time` int(11) NOT NULL COMMENT '退貨申請時間',
  `handling_time` int(11) NOT NULL COMMENT '退貨處理時間',
  `remark` text COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '退貨原因',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
複製程式碼

order_returns_apply 售後申請

退換貨申請

CREATE TABLE `order_returns_apply` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `order_no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '訂單單號',
  `order_detail_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '子訂單編碼',
  `return_no` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '售後單號',
  `member_id` int(11) NOT NULL COMMENT '使用者編碼',
  `state` tinyint(4) NOT NULL COMMENT '型別 0 僅退款 1退貨退款',
  `product_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '貨物狀態 0:已收到貨 1:未收到貨',
  `why` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '退換貨原因',
  `status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '稽核狀態 -1 拒絕 0 未稽核 1稽核通過',
  `audit_time` int(11) NOT NULL DEFAULT '0' COMMENT '稽核時間',
  `audit_why` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '稽核原因',
  `note` text COLLATE utf8mb4_unicode_ci COMMENT '備註',
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
複製程式碼

致謝

感謝你看完這篇文章,接下來會繼續出一些電商相關的文章,例如交易系統的設計、訂單系統的設計等等。感謝近期來關注我的童鞋們。作為一個程式設計師,我很榮幸能把我知道的分享給大家。

程式碼多變,初心不變

相關文章