兌換碼的設計

2023-08-22 18:03:48

先上表結構圖, 我這裡用的MySQL資料庫, 表結構如下

對應建表SQL:

create table cdk(
    id int(11) unsigned not null primary key auto_increment,
    cdk varchar(16) not null comment '兌換碼',
    cdk_kind tinyint not null comment '兌換型別 1-會員卡, 2-優惠券, 3-優惠券包',
    cdk_kind_no varchar(32) not null comment '兌換型別編號',
    cdk_status tinyint not null default 1 comment '兌換碼使用狀態 1-未使用, 2-已使用',
    cdk_export_status tinyint not null default 1 comment '兌換碼匯出狀態 1-未匯出, 2-已匯出',
    act_account_id int(11) comment '使用人',
    act_time datetime comment '使用時間',
    gen_account_id int(11) comment '生成人',
    gen_time datetime comment '生成時間',
    export_account_id int(11) comment '匯出人',
    export_time datetime comment '匯出時間',
    valid_time datetime comment '有效期開始時間',
    expire_time datetime comment '有效期失效時間',
    remark text comment '備註',
    create_time datetime not null default current_timestamp comment '建立時間',
    update_time datetime not null default current_timestamp on update CURRENT_TIMESTAMP comment '更新時間',
    unique key(cdk)
)engine=innodb comment '兌換碼';

設計說明
1.兌換碼與兌換商品型別:
一個表中可以維護所有可以通過兌換碼兌換的商品的兌換碼, 使用cdk_kind區分不同的商品型別, 使用cdk_kind_no區分某個商品下更具體的商品. 比如你平臺共有兩種會員卡, 編號分別為"VIP"和"SVIP", 則cdk_kind=1, cdk_kind_no分別為"VIP"和"SVIP".

cdk欄位為兌換碼, 這裡是此欄位單獨作為唯一索引. 另有方案可以用cdk欄位與cdk_kind一起做聯合唯一索引.
cdk欄位單獨做唯一索引, 則只需要設計一個兌換頁面, 換到什麼就是什麼, 當然也可以多個兌換入口頁面, 調同一個介面就行;
cdk欄位與cdk_kind做聯合唯一索引時, 意味著同一個兌換碼在不同的地方可以兌換不同的商品, 需要多個入口或者一個入口時需要選擇兌換的商品型別.

如果有新的商品需要參與使用兌換碼兌換, 只需要新增cdk_kind欄位的列舉.

兌換碼服務與被兌換商品的服務之間, 可以兌換碼服務直接呼叫被兌換商品的服務, 也可以兌換碼服務將兌換資訊放入訊息佇列, 被兌換商品的服務消費訊息處理兌換入賬.

2.兌換碼兌換之後, 對應記錄由1-未使用狀態變為2-已使用狀態.

3.匯出狀態, 即為兌換碼是否出庫的狀態. 剛生成出來時為1-未匯出狀態, 可以通過從管理後臺下載到excel等方式出庫, 出庫後及改為2-已匯出狀態, 標識這個兌換碼已經有人預定了, 不能重複給另一個人.
同時, 管理後臺最好設計兌換碼不可見, 即不在頁面展示兌換碼的號碼, 避免能見到的人把未匯出狀態的碼直接給出去使用, 也可以避免有人將別人已匯出但未使用的碼提前使用.

4.兌換碼可以設計有效期開始和結束時間, 時間範圍內才可以兌換. 可以用在某些特定的場景下. 比如某個會員卡需要一週之後才上線, 但可以提前將其兌換碼上線. 指定一週之後才生效.

5.為避免多個人同時匯出兌換碼的衝突, 建議遵循誰生成誰匯出的原則, 即設計中的gen_account_id-生成人欄位與export_account_id-匯出人欄位, 與當前登入的的賬號id一致.
假如有使用者a和使用者b兩個人在幾乎同時操作匯出, 使用者a需要100個, 使用者b需要10個, 在使用者a生成了100個的時候, 使用者b發現庫中有足夠的未匯出狀態的碼, 則可能自己不會生成, 而是把使用者a生成的100箇中的10個搶先匯出了. 而如果遵循"誰生成誰匯出"則可以避免此類問題.