我向Google查看了一些关于此问题的示例/解决方案,例如Creating Discount Code System (MySQL/php),但我找不到一个好的解决方案。
我的情况是,我有一个平台,用户应该在虚拟货币中有余额,并且可以为它购买虚拟物品。现在希望实施优惠券和折扣。会有不同类型的代码,例如一个可以在购买商品时获得50%折扣,一个额外商品数量(有或没有最低商品数量),只需一个代码来获取某种货币,或者一个参考代码可以为推荐人提供一些代码
我已将其实施为广告系列和CampaignType,其中第一个包含广告系列信息,第二个包含操作信息。
这是结构:
-- Table structure for table `cake_campaigns`
CREATE TABLE IF NOT EXISTS `cake_campaigns` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 NOT NULL,
`code` varchar(100) COLLATE utf8_bin NOT NULL,
`type_id` varchar(50) CHARACTER SET utf16 COLLATE utf16_bin NOT NULL DEFAULT '1',
`value` int(10) unsigned NOT NULL DEFAULT '5' COMMENT 'Percentage or amount',
`min_amount` bigint(20) unsigned NOT NULL DEFAULT '0',
`owner_id` bigint(20) unsigned NOT NULL,
`created` datetime NOT NULL,
`active` tinyint(1) unsigned NOT NULL DEFAULT '1',
`single_use` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `code` (`code`),
KEY `owner_id` (`owner_id`),
FULLTEXT KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=4 ;
-- Table structure for table `cake_campaign_types`
CREATE TABLE IF NOT EXISTS `cake_campaign_types` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 NOT NULL,
`unit` varchar(10) CHARACTER SET utf16 NOT NULL DEFAULT '%',
`multiplier` double(10,8) NOT NULL DEFAULT '0.01000000',
`type` varchar(50) COLLATE utf8_bin DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=7 ;
目前我的逻辑是,当使用广告系列时,该操作将根据CampaignType的名称进行操作,例如在购买逻辑中:
if (isset($this->request->data['Purchase']['code'])) {
$code = $this->request->data['Purchase']['code'];
$campaign = $this->Campaign->findByCode($code);
$this->Campaign->id = $campaign['Campaign']['id'];
// campaign no longer active
if ($this->Campaign->field('active') == 0) $code = false;
if ($this->CampaignLog->find('first', array('conditions' => array(
'user_id' => $this->User->field('id'),
'campaign_id' => $this->Campaign->field('id'),
'activated' => 1,
)))) $code = false; // code has already been used
unset($this->request->data['Purchase']['code']);
} else $code = false;
// Some purchasing logic here
if ($code) {
$this->CampaignLog->create();
$this->CampaignLog->save(array(
'campaign_id' => $this->Campaign->field('id'),
'user_id' => $this->User->field('id'),
'activated' => 1,
'source' => $this->Session->read('referrer'),
'earnings' => $earned,
'created' => strftime('%Y-%m-%d %H:%M:%S'),
));
if ($this->Campaign->field('single_use') == 1) {
$this->Campaign->saveField("active", 0);
}
// Apply code here
}
现在,我的问题是: 关于应用这些代码的最佳做法是什么,因为我对使用if-then-else或switch-case通过所有可能的代码类型感到有些不安。但是现在,因为有很多东西可以不同(例如折扣 - 百分比或设定金额),那么这似乎是唯一的选择。 也许代码的结构/逻辑应该不同?
答案 0 :(得分:0)
在我看来,这已经很简单,将其与购买结合起来是了解更多问题的最佳选择。假设我们的价格为$this->request->data['price']
,那么我们的type_id
示例1
代表折扣。
我们所要做的就是获得value
并做百分比等式,就像
$discount = floatval('0.' . $this->Campaign->value);
$finalPrice = $this->request->data['price'] * $discount;
如果我们在switch
案例中实施它以隔离其逻辑,那就更好了。这可能取决于你如何实现它,但这是概念的要点。
答案 1 :(得分:0)
检查cart plugin它是using events的所有内容并且没有任何硬编码,使用此方法非常灵活。
只要需要重新计算购物车,就会触发one method。在里面调用其他方法来计算税额and discounts。
通过事件实现此功能的优势在于,以后可以通过额外的折扣或税收计算进行扩展。
随意查看插件的整个代码,它不是一个简单的实现,涵盖购物车数据的cookie,会话和数据库存储,并且有许多事情的事件。