最近公司要求完善我們商城的運費模板功能,使運費計算更加精確。我接到任務之后就着手分析,到目前為止已實現了一部分。現在把相關的東西記錄在這里,為了方便日后自己查看,也希望能夠幫助部分初學者,給他們一個個參照;在功能上有不同想法的人希望不要吝惜自己的智慧,能夠在評論中提點一二。
剛接到任務,我是想當然的根據公司的業務來分析的,感覺到很復雜,邏輯不清不楚,各種關系也理不順。之后我就從淘寶的運費模板去分析,還有淘寶開放平台上的運費模板API,里面有數據結構,再結合ECShop等有名的開源電子商城系統的運費模板的設計方法去分析,然后把分析到的各種邏輯、關系在紙上記錄下來;比如有幾個對象,有哪些屬性,各個對象之間的關系,有哪些約束條件等等一一記錄下來,你用甘特圖也好,用草圖也行,但是一定要自己看得懂,最好別人也看得懂,我是用草圖畫的,因為這個功能是我一個人單獨來實現,所以我自己能看懂就行了。之后我根據自己畫的草圖就整理出來了概要設計說明書,因為這只是一個功能,所以我並沒有按照軟件工程的那種格式去寫這個概要說明書,而是把一些必須要記錄的重點的東西記錄下來,整理的一篇文檔而已。我這個設計基本是按淘寶的來的,但是跟它的數據結構不一樣,下面我把它貼出來。
一:需求說明
1.1 用戶需求說明
客戶在商城下單的時候能夠能夠根據客戶選擇的運送方式和用戶所在地區自動計算運費
1.2 設計需求和約束說明
1:模板有包郵和不包郵兩種,不包郵需要自己定義;
2:計價方式分為按件數、按重量兩種;(業務的特殊性,不需要按體積計價)
3:運送方式有EMS、天天快遞、順豐快遞、贛農速配四種;(贛農速配是自有物流,其他三種是合作物流)
4:一個運費模板可以有多個運送方式,每種運送方式必須要有一種運送到全國的默認運費,非默認的運費需要設置地區
5:每個運費模板可以設置是否指定條件包郵,並且多種條件可以同時存在
6:每個產品必須綁定一個運費模板
二:頁面設計(參照淘寶的運費模板頁面設計)
2.1 列表頁
2.2 新增頁和編輯頁
三:數據結構
3.1 模板表設計(FareTemplate)
列名 |
數據類型 |
空值 |
默認值 |
備注 |
ID |
int |
Not null |
|
主鍵 |
模板名稱 |
string |
Not null |
|
|
寶貝地址 |
string |
Not null |
|
|
發貨時間 |
Datetime |
null |
|
幾小時內發貨 |
是否包郵 |
bit |
|
否 |
不包郵約束運送方式不能為空 |
計價方式 |
int |
Not null |
|
按件數、按重量、按體積 |
是否指定條件包郵 |
bit |
Not null |
否 |
|
3.2 包郵條件表(InclPostageProviso)
列名 |
數據類型 |
空值 |
默認值 |
備注 |
ID |
Int |
Not null |
|
主鍵 |
關聯模板 |
Int |
Not null |
|
模板表外鍵 |
包郵地區 |
string |
null |
|
省-市-區 |
包郵件數 |
Int |
Null |
|
|
包郵重量 |
Decimal |
Null |
|
單位KG |
包郵體積 |
Decimal |
Null |
|
單位m³ |
包郵金額 |
Decimal |
Null |
|
|
3.3 運送方式表(CarryMode)
列名 |
數據類型 |
空值 |
默認值 |
備注 |
ID |
Int |
Not null |
|
主鍵 |
關聯模板 |
Int |
Not null |
|
模板表外鍵 |
運送地區 |
string |
Not null |
|
與地區表一對多關系 |
首件 |
int |
null |
|
依據計價方式來選擇 |
首重 |
decimal |
null |
|
|
首體積 |
decimal |
null |
|
|
首費 |
decimal |
Not null |
|
|
續重 |
decimal |
null |
|
依據計價方式來選擇 |
續體積 |
decimal |
null |
|
|
續件 |
int |
Null |
|
|
續費 |
Decimal |
Not null |
|
|
運送方式 |
Int |
Not null |
|
EMS、順豐、天天等 |
是否默認 |
int |
Not null |
是 |
3.4 數據庫實現代碼

use nopCommerce go ------------ /*運費模板*/ ------------ --模板表-- create table FareTemplate ( Id int not null identity(1,1) primary key,--主鍵 Name varchar(20) not null ,--模板名稱 ShopAddr varchar(100) null,--寶貝地址 DispatchTime varchar(20) null,--發貨時間 IsInclPostage bit default(1),--是否包郵 ValuationModel int not null,--計價方式(1:按件 2:按重量 3:按體積) IsInclPostageByif bit default(0) --是否指定條件包郵 ) --包郵條件表-- create table InclPostageProviso ( Id int not null identity(1,1) primary key,--主鍵 FareId int not null foreign key(FareId) references FareTemplate,--模板表外鍵 Region varchar(50) null,--包郵地區(存id,格式為'省-市-區',以'|'分隔) PieceNo int null,--包郵件數 WeightNo decimal(18,2) null,--包郵重量 BulkNo decimal(18,2) null,--包郵體積 Amount decimal(18,2) null,--包郵金額 ) --運送方式表-- create table CarryMode ( Id int not null identity(1,1) primary key,--主鍵 FareId int not null foreign key(FareId) references FareTemplate,--模板表外鍵 Region varchar(50) null,--運送地區(存id,格式為'省-市-區',以'|'分隔) FirstPiece int null,--首件數量 FirstWeight decimal(18,2) null,--首重重量 FirstBulk decimal(18,2) null,--首體積大小 FirstAmount decimal(18,2) not null,--首費 SecondPiece int null,--續件 SecondWeight decimal(18,2) null,--續重 SecondBulk decimal(18,2) null,--續體積 SecondAmount decimal(18,2) not null,--續費 CarryWay int default(0),--運送方式(贛農速運,ems,順豐,天天) IsDefault bit default(1) --是否默認的運送方式 ) --插入默認模板-- insert into FareTemplate(Name,ShopAddr,DispatchTime,IsInclPostage,ValuationModel,IsInclPostageByif) values('默認模板','江西省南昌市高新區','24小時','0','1','1') insert into InclPostageProviso(FareId,Amount) values('1','199') insert into CarryMode(FareId,FirstPiece,FirstAmount,SecondPiece,SecondAmount,CarryWay,IsDefault) values('1','1','8','1','2','0','1') insert into CarryMode(FareId,FirstPiece,FirstAmount,SecondPiece,SecondAmount,CarryWay,IsDefault) values('1','1','20','1','5','1','1') insert into CarryMode(FareId,FirstPiece,FirstAmount,SecondPiece,SecondAmount,CarryWay,IsDefault) values('1','1','22','1','10','2','1') insert into CarryMode(FareId,FirstPiece,FirstAmount,SecondPiece,SecondAmount,CarryWay,IsDefault) values('1','1','8','1','5','3','1') --插入權限-- insert into PermissionRecord(Name,SystemName,Category) values('運費模板管理','ManageFareTemplate','Configuration') --更新產品表並向產品表插入默認模板-- alter table Product add FareId int null foreign key(FareId) references FareTemplate --模板表外鍵 update Product set FareId=1 --查詢模板-- select * from FareTemplate select * from CarryMode select * from InclPostageProviso
四:運費計算算法設計
4.1 單商品算法:判斷是否包郵->判斷是否滿足條件包郵->根據客戶選擇的運送方式判斷地區->沒有所在地區則使用默認運費->求最大首費和最小續費
4.2 購物車算法:先計算單品的運送方式->求最大首費和最小續費
解釋:一種商品可能存在多種合適的運送方式,最大首費就是這幾種運送方式里的首費最大的值,最小續費類似。
基本的設計思想就是這些,希望大家能看懂,不清楚的可以評論留言,大家一起交流。我的實現是在.net平台使用MVC+EF技術來實現的,后續等我全部實現了之后,我會貼出部分實現的代碼來一起交流。