CakePHP凭证/折扣代码系统

CakePHP凭证/折扣代码系统,php,cakephp,logic,discount,shop,Php,Cakephp,Logic,Discount,Shop,例如,我在谷歌上查找了一些关于这方面的示例/解决方案,但我没有找到一个好的解决方案 我的情况是,我有一个平台,在这个平台上,用户应该有一个虚拟货币的余额,并且可以为它购买虚拟物品。现在有一个愿望是实施代金券和折扣。可能会有不同种类的代码,比如一个在购买物品时给予50%折扣的代码,一个额外物品的数量(有或没有最低物品数量),一个获得某种货币的代码,或者一个给推荐人一些东西的参考代码 我将其实现为Campaign和CampaignType,其中第一个保存Campaign信息,第二个保存action信

例如,我在谷歌上查找了一些关于这方面的示例/解决方案,但我没有找到一个好的解决方案

我的情况是,我有一个平台,在这个平台上,用户应该有一个虚拟货币的余额,并且可以为它购买虚拟物品。现在有一个愿望是实施代金券和折扣。可能会有不同种类的代码,比如一个在购买物品时给予50%折扣的代码,一个额外物品的数量(有或没有最低物品数量),一个获得某种货币的代码,或者一个给推荐人一些东西的参考代码

我将其实现为Campaign和CampaignType,其中第一个保存Campaign信息,第二个保存action信息

结构如下:

-- 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 ;
目前,我的逻辑是,当使用活动时,操作将根据活动类型的名称进行,例如在购买逻辑中:

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或将所有可能的代码类型转换为case感到有点不舒服。但是现在,因为有太多不同的东西(比如百分比折扣或固定金额折扣),所以这似乎是唯一的选择。
也许代码的结构/逻辑应该有所不同?

在我看来,这已经很简单了,将其与购买相结合将是了解更多问题的最佳选择。假设我们有
$this->request->data['price']
作为价格,那么我们有一个
type\u id
的示例
1
表示折扣

我们所要做的就是得到
,然后做百分比方程,这样

$discount=floatval('0'.$this->Campaign->value);
$finalPrice=$this->request->data['price']*$折扣;
如果我们在
开关
案例中实现它,以隔离它们的逻辑,效果会更好。这可能取决于您如何实现它,但这是概念的要点。

检查It是否适用于所有内容,并且没有任何内容是硬编码的,使用这种方法非常灵活

每当需要重新计算购物车时,就会触发一个。在内部,它调用其他方法来计算税收

通过事件实现此功能的优点是,很容易在以后通过附加折扣或税务计算进行扩展

请随意查看插件的全部代码,它不是一个简单的实现,它涵盖了购物车数据的cookie、会话和数据库存储,并且有很多事件