From 96d2ffee4b4c1351ef229f0a7bd46ca6ed9972e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E6=99=AF=E7=AB=8B?= Date: Wed, 27 Jan 2021 16:47:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=8A=98=E6=89=A3=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/data/controller/UserDiscount.php | 115 +++++++++++ app/data/controller/UserLevel.php | 8 +- app/data/service/PrizeService.php | 253 +++++++++++++++++++++++++ app/data/service/UserService.php | 2 +- app/data/view/user_discount/form.html | 66 +++++++ app/data/view/user_discount/index.html | 73 +++++++ app/data/view/user_level/form.html | 39 ++-- app/data/view/user_level/index.html | 18 +- 8 files changed, 544 insertions(+), 30 deletions(-) create mode 100644 app/data/controller/UserDiscount.php create mode 100644 app/data/service/PrizeService.php create mode 100644 app/data/view/user_discount/form.html create mode 100644 app/data/view/user_discount/index.html diff --git a/app/data/controller/UserDiscount.php b/app/data/controller/UserDiscount.php new file mode 100644 index 000000000..9ffdc3472 --- /dev/null +++ b/app/data/controller/UserDiscount.php @@ -0,0 +1,115 @@ +title = '折扣方案管理'; + $query = $this->_query($this->table); + $query->where(['deleted' => 0])->order('sort desc,id desc')->page(); + } + + /** + * 数据列表处理 + * @param array $data + */ + protected function _page_filter(array &$data) + { + foreach ($data as &$vo) { + $vo['items'] = json_decode($vo['items'], true); + } + } + + /** + * 添加折扣方案 + * @auth true + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function add() + { + $this->_form($this->table, 'form'); + } + + /** + * 编辑折扣方案 + * @auth true + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function edit() + { + $this->_form($this->table, 'form'); + } + + /** + * 表单数据处理 + * @param array $vo + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + protected function _form_filter(array &$vo) + { + if ($this->request->isPost()) { + $rule = []; + foreach ($vo as $k => $v) if (stripos($k, '_level_') !== false) { + [, $level] = explode('_level_', $k); + $rule[] = ['level' => $level, 'discount' => $v]; + } + $vo['items'] = json_encode($rule, JSON_UNESCAPED_UNICODE); + } else { + $map = ['status' => 1]; + $this->levels = $this->app->db->name('DataUserLevel')->where($map)->order('number asc')->select()->toArray(); + if (!empty($vo['items'])) foreach (json_decode($vo['items'], true) as $item) { + $vo["_level_{$item['level']}"] = $item['discount']; + } + } + } + + /** + * 修改折扣方案状态 + * @auth true + * @throws \think\db\exception\DbException + */ + public function state() + { + $this->_save($this->table); + } + + /** + * 删除折扣方案配置 + * @auth true + * @throws \think\db\exception\DbException + */ + public function remove() + { + $this->_delete($this->table); + } + +} \ No newline at end of file diff --git a/app/data/controller/UserLevel.php b/app/data/controller/UserLevel.php index 361031a2b..eda3976e6 100644 --- a/app/data/controller/UserLevel.php +++ b/app/data/controller/UserLevel.php @@ -2,6 +2,7 @@ namespace app\data\controller; +use app\data\service\PrizeService; use think\admin\Controller; /** @@ -39,6 +40,9 @@ class UserLevel extends Controller { foreach ($data as &$vo) { $vo['rebate_rule'] = str2arr($vo['rebate_rule']); + foreach ($vo['rebate_rule'] as &$v) { + $v = PrizeService::instance()->getName($v); + } } } @@ -73,7 +77,7 @@ class UserLevel extends Controller protected function _form_filter(array &$vo) { if ($this->request->isGet()) { - $this->rules = ['首推奖利', '复购奖利', '直属团队', '间接团队', '差额奖励']; + $this->prizes = PrizeService::PRIZES; $vo['rebate_rule'] = str2arr($vo['rebate_rule'] ?? ''); } else { $vo['utime'] = time(); @@ -103,7 +107,7 @@ class UserLevel extends Controller { if ($state) { $order = 'number asc,utime desc'; - if (input('old_level', 100) < input('level', '0')) $order = 'number asc,utime asc'; + if (input('old_number', 100) < input('number', '0')) $order = 'number asc,utime asc'; foreach ($this->app->db->name($this->table)->order($order)->cursor() as $k => $vo) { $this->app->db->name($this->table)->where(['id' => $vo['id']])->update(['number' => $k + 1]); } diff --git a/app/data/service/PrizeService.php b/app/data/service/PrizeService.php new file mode 100644 index 000000000..37ff0111b --- /dev/null +++ b/app/data/service/PrizeService.php @@ -0,0 +1,253 @@ + ['code' => self::PRIZE_01, 'name' => '首推奖励', 'func' => '_prize01'], + self::PRIZE_02 => ['code' => self::PRIZE_02, 'name' => '复购奖励', 'func' => '_prize02'], + self::PRIZE_03 => ['code' => self::PRIZE_03, 'name' => '直属团队', 'func' => '_prize03'], + self::PRIZE_04 => ['code' => self::PRIZE_04, 'name' => '间接团队', 'func' => '_prize04'], + self::PRIZE_05 => ['code' => self::PRIZE_05, 'name' => '差额奖励', 'func' => '_prize05'], + ]; + + protected $user; + protected $order; + protected $fromer; + + /** + * 获取奖励名称 + * @param string $prize + * @return string + */ + public function getName(string $prize): string + { + return self::PRIZES[$prize]['name'] ?? $prize; + } + + /** + * 执行订单返利 + * @param string $orderNo + * @throws Exception + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + public function execute(string $orderNo) + { + // 获取订单数据 + $map = ['order_no' => $orderNo, 'payment_status' => 1]; + $this->order = $this->app->db->name('ShopOrder')->where($map)->find(); + if (empty($this->order)) throw new Exception('订单不存在'); + // 获取用户数据 + $map = ['id' => $this->order['uid']]; + $this->user = $this->app->db->name('DataUser')->where($map)->find(); + if (empty($this->user)) throw new Exception('用户不存在'); + // 获取推荐用户 + if ($this->order['from'] > 0) { + $map = ['id' => $this->order['from']]; + $this->fromer = $this->app->db->name('DataUser')->where($map)->find(); + if (empty($this->fromer)) throw new Exception('推荐不存在'); + } + // 批量发放奖励 + foreach (self::PRIZES as $vo) { + if (method_exists($this, $vo['func'])) { + $this->{$vo['func']}(); + } + } + } + + /** + * 首推奖励 + * @return boolean + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + protected function _prize01(): bool + { + if (empty($this->fromer)) return false; + $map = ['order_uid' => $this->user['id']]; + if ($this->app->db->name('DataUserRebate')->where($map)->count() > 0) return false; + if (!$this->checkLevelPrize(PrizeService::PRIZE_01, $this->fromer['vip_number'])) return false; + // 创建返利奖励记录 + $map = ['type' => PrizeService::PRIZE_01, 'order_no' => $this->order['order_no'], 'order_uid' => $this->order['uid']]; + if ($this->app->db->name('DataUserRebate')->where($map)->count() < 1) { + if (sysconf('shop.fristType') == 1) { + $amount = sysconf('shop.fristValue') ?: '0.00'; + $name = PrizeService::instance()->getName(PrizeService::PRIZE_01) . ",每人 {$amount} 元"; + } else { + $amount = sysconf('shop.fristValue') * $this->order['amount_total'] / 100; + $name = PrizeService::instance()->getName(PrizeService::PRIZE_01) . ",订单 " . sysconf('shop.fristValue') . '%'; + } + $this->app->db->name('DataUserRebate')->insert(array_merge($map, [ + 'uid' => $this->fromer['id'], 'name' => $name, 'amount' => $amount, 'order_amount' => $this->order['amount_total'], + ])); + // 更新会员奖利金额 + UserService::instance()->syncLevel($this->fromer['id']); + } + return true; + } + + /** + * 复购奖励 + * @return boolean + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + protected function _prize02(): bool + { + if (empty($this->fromer)) return false; + $map = ['order_uid' => $this->user['id']]; + if ($this->app->db->name('DataUserRebate')->where($map)->count() < 1) return false; + if (!$this->checkLevelPrize(PrizeService::PRIZE_02, $this->fromer['vip_number'])) return false; + // 创建返利奖励记录 + $map = ['type' => PrizeService::PRIZE_02, 'order_no' => $this->order['order_no'], 'order_uid' => $this->order['uid']]; + if ($this->app->db->name('DataUserRebate')->where($map)->count() < 1) { + if (sysconf('shop.repeatType') == 1) { + $amount = sysconf('shop.repeatValue') ?: '0.00'; + $name = PrizeService::instance()->getName(PrizeService::PRIZE_02) . ",每人 {$amount} 元"; + } else { + $amount = sysconf('shop.repeatValue') * $this->order['amount_total'] / 100; + $name = PrizeService::instance()->getName(PrizeService::PRIZE_02) . ",订单 " . sysconf('shop.repeatValue') . '%'; + } + $this->app->db->name('DataUserRebate')->insert(array_merge($map, [ + 'uid' => $this->fromer['id'], 'name' => $name, 'amount' => $amount, 'order_amount' => $this->order['amount_total'], + ])); + // 更新会员奖利金额 + UserService::instance()->syncLevel($this->fromer['id']); + } + return true; + } + + /** + * 直属团队 + * @return boolean + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + private function _prize03(): bool + { + if (empty($this->fromer)) return false; + if (!$this->checkLevelPrize(PrizeService::PRIZE_03, $this->fromer['vip_number'])) return false; + // 创建返利奖励记录 + $map = ['type' => PrizeService::PRIZE_03, 'order_no' => $this->order['order_no'], 'order_uid' => $this->order['uid']]; + if ($this->app->db->name('DataUserRebate')->where($map)->count() < 1) { + $amount = sysconf('shop.repeatValue') * $this->order['amount_total'] / 100; + $name = PrizeService::instance()->getName(PrizeService::PRIZE_03) . ",订单 " . sysconf('shop.repeatValue') . '%'; + $this->app->db->name('DataUserRebate')->insert(array_merge($map, [ + 'uid' => $this->fromer['id'], 'name' => $name, 'amount' => $amount, 'order_amount' => $this->order['amount_total'], + ])); + // 更新会员奖利金额 + UserService::instance()->syncLevel($this->fromer['id']); + } + return true; + } + + /** + * 间接团队 + * @return boolean + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + private function _prize04(): bool + { + if (empty($this->fromer)) return false; + $pm2 = $this->app->db->name('DataUser')->where(['id' => $this->fromer['from']])->find(); + if (empty($pm2)) return false; + if (!$this->checkLevelPrize(PrizeService::PRIZE_04, $pm2['vip_number'])) return false; + $map = ['type' => PrizeService::PRIZE_04, 'order_no' => $this->order['order_no'], 'order_uid' => $this->order['uid']]; + if ($this->app->db->name('DataUserRebate')->where($map)->count() < 1) { + $amount = sysconf('shop.indirectValue') * $this->order['amount_total'] / 100; + $name = PrizeService::instance()->getName(PrizeService::PRIZE_04) . ",订单 " . sysconf('shop.indirectValue') . '%'; + $this->app->db->name('DataUserRebate')->insert(array_merge($map, [ + 'uid' => $pm2['id'], 'name' => $name, 'amount' => $amount, 'order_amount' => $this->order['amount_total'], + ])); + // 更新代理奖利金额 + UserService::instance()->syncLevel($pm2['id']); + } + return true; + } + + /** + * 差额奖励 + * @return false + * @throws \think\db\exception\DataNotFoundException + * @throws \think\db\exception\DbException + * @throws \think\db\exception\ModelNotFoundException + */ + private function _prize05(): bool + { + $pids = array_reverse(explode('-', trim($this->user['path'], '-'))); + if (empty($pids)) return false; + // 获取拥有差额奖励的等级 + $query = $this->app->db->name('DataUserLevel'); + $numbs = $query->whereLike('rule', '%,' . PrizeService::PRIZE_05 . ',%')->column('number'); + // 获取可以参与奖励的代理 + $query = $this->app->db->name('DataUser')->whereIn('vip_number', $numbs); + $users = $query->whereIn('id', $pids)->orderField('id', $pids)->select()->toArray(); + // 查询需要计算奖励的商品 + $map = [['order_no', '=', $this->order['order_no']], ['discount_rate', '<', 100]]; + $this->app->db->name('StoreOrderItem')->where($map)->select()->each(function ($item) use ($users) { + foreach ($users as $user) { + $map = [ + 'order_no' => $this->order['order_no'], + '', + ]; + + $discountRule = $this->app->db->name('DataUserDiscount')->where(['status' => '1', 'is_deleted' => '0'])->value('rule'); + if (!empty($discountRule) && is_array($rules = json_decode($discountRule, true))) { + [$tempLevel, $tempRate] = [$item['vip_number'], $item['discount_rate']]; + foreach ($rules as $rule) if ($rule['level'] > $tempLevel) foreach ($uids as $mem) if ($mem['vip_number'] > $tempLevel) { + if ($tempRate > $rule['discount'] && $tempRate < 100) { + $diffRate = $tempRate - $rule['discount']; + $this->orderno = "{$this->order['order_no']}#{$tempLevel}-{$mem['vip_number']}"; + if ($this->app->db->name('DataUserRebate')->where(['order_no' => $this->orderno])->count() < 1) { + $this->app->db->name('DataUserRebate')->insert([ + 'order_no' => $this->orderno, 'order_uid' => $this->order['mid'], + 'order_price' => $this->order['amount_total'], 'type' => '5', 'mid' => $mem['id'], + 'profit_price' => $diffRate * $item['goods_amount_total'] / 100, + 'profit_state' => intval(empty($this->settlement)), + 'description' => "等级差额奖励{$tempLevel}#{$mem['vip_number']}商品金额{$diffRate}%", + ]); + $this->app->db->name('StoreOrderItem')->where(['id' => $item['id']])->update(['discount_state' => '1']); + } + [$tempLevel, $tempRate] = [$mem['vip_number'], $rule['discount']]; + } + } + } + } + }); + return true; + } + + /** + * 检查等级是否有奖励 + * @param string $prize + * @param integer $level + * @return boolean + */ + protected function checkLevelPrize(string $prize, int $level): bool + { + $map = [['number', '=', $level], ['rebate_rule', 'like', "%,{$prize},%"]]; + return $this->app->db->name('DataUserLevel')->where($map)->count() > 0; + } +} \ No newline at end of file diff --git a/app/data/service/UserService.php b/app/data/service/UserService.php index 074c06c25..4a2eecc30 100644 --- a/app/data/service/UserService.php +++ b/app/data/service/UserService.php @@ -230,7 +230,7 @@ class UserService extends Service // 计算会员级别 foreach ($this->app->db->name('DataUserLevel')->where(['status' => 1])->order('number desc')->select()->toArray() as $item) { $l1 = empty($item['goods_vip_status']) || $user['vip_auth'] > 0; - $l2 = empty($item['teams_user_status']) || $item['teams_user_number'] <= $teamsDirect + $teamsIndirect; + $l2 = empty($item['teams_users_status']) || $item['teams_users_number'] <= $teamsDirect + $teamsIndirect; $l3 = empty($item['teams_direct_status']) || $item['teams_direct_number'] <= $teamsDirect; $l4 = empty($item['teams_indirect_status']) || $item['teams_indirect_number'] <= $teamsIndirect; $l5 = empty($item['order_amount_status']) || $item['order_amount_number'] <= $amountTotal; diff --git a/app/data/view/user_discount/form.html b/app/data/view/user_discount/form.html new file mode 100644 index 000000000..a214190a0 --- /dev/null +++ b/app/data/view/user_discount/form.html @@ -0,0 +1,66 @@ +
+
+ + + +
+ 用户级别折扣 + Discount Scheme + + + + + + + + + {foreach $levels as $level} + + + + + {/foreach} + +
会员级别原价比例
+ [ VIP{$level.number} ] {$level.name|default=''} + + +
+
+ + + +
+ {notempty name='vo.id'}{/notempty} + +
+ + +
+
+ + +
+ + + + diff --git a/app/data/view/user_discount/index.html b/app/data/view/user_discount/index.html new file mode 100644 index 000000000..c429ba6ec --- /dev/null +++ b/app/data/view/user_discount/index.html @@ -0,0 +1,73 @@ +{extend name="../../admin/view/main"} + +{block name="button"} + +{if auth("add")} + +{/if} + +{/block} + +{block name='content'} +
+ + {notempty name='list'} + + + + + + + + + + + {/notempty} + + {foreach $list as $key=>$vo} + + + + + + + + + {/foreach} + +
+ + + + 折扣方案等级折扣使用状态
+ + + + {$vo.name|default=''} + {foreach $vo.items as $v} + + VIP{$v.level} : {$v.discount+0}% + + {/foreach} + + {if $vo.status eq 0}已禁用{elseif $vo.status eq 1}使用中{/if} + + + {if auth("edit")} + 编 辑 + {/if} + + {if auth("state") and $vo.status eq 1} + 禁 用 + {elseif auth("state")} + 启 用 + {/if} + + {if auth("remove")} + 删 除 + {/if} + +
+ {empty name='list'}没有记录哦{else}{$pagehtml|raw|default=''}{/empty} +
+{/block} \ No newline at end of file diff --git a/app/data/view/user_level/form.html b/app/data/view/user_level/form.html index 20548d7a7..92f476890 100644 --- a/app/data/view/user_level/form.html +++ b/app/data/view/user_level/form.html @@ -2,13 +2,12 @@
- 用户等级 -
+ 用户等级 +
- 等级序号 - + {for start="1" end="10" name="i"}{if isset($vo.number) and $vo.number eq $i} {else} @@ -16,14 +15,14 @@
- 升级规则 + 升级规则
{php}$vo['upgrade_type'] = isset($vo['upgrade_type'])?$vo['upgrade_type']:1;{/php} {foreach [1=>'达成所有条件',0=>'达成任何条件'] as $k => $v} @@ -36,7 +35,7 @@
- 升级条件 + 升级条件
@@ -94,18 +93,18 @@
- 发放奖利 -
- {foreach $rules as $key}{if isset($vo.rebate_rule) && is_array($vo.rebate_rule) && in_array($key,$vo.rebate_rule)} - + 发放奖利 +
+ {foreach $prizes as $prize}{if isset($vo.rebate_rule) && is_array($vo.rebate_rule) && in_array($prize.code, $vo.rebate_rule)} + {else} - + {/if}{/foreach}
- 等级描述 + 等级描述 @@ -113,7 +112,7 @@
{notempty name='vo.id'}{/notempty} - {notempty name='vo.level'}{/notempty} + {notempty name='vo.number'}{/notempty}
diff --git a/app/data/view/user_level/index.html b/app/data/view/user_level/index.html index 47c0f636e..4e9bc8b09 100644 --- a/app/data/view/user_level/index.html +++ b/app/data/view/user_level/index.html @@ -2,20 +2,20 @@ {block name="button"} - + - + {/block} {block name='content'} -
+
注意,用户级别配置不能随意修改或删除,会影响系统结算与用户升级!
-
- +
+
{notempty name='list'} @@ -44,11 +44,15 @@ - + - +
[ {$vo.number} ] {$vo.name|default=''} {if $vo.upgrade_type eq 1}全部完成{else}任何条件{/if} {if $vo.goods_vip_status>0} {else} - {/if}{if $vo.teams_user_status>0} {$vo.teams_user_number} 人 {else} - {/if}{if $vo.teams_users_status>0} {$vo.teams_users_number} 人 {else} - {/if} {if $vo.teams_direct_status>0} {$vo.teams_direct_number} 人 {else} - {/if} {if $vo.teams_indirect_status>0} {$vo.teams_indirect_number} 人 {else} - {/if} {if $vo.order_amount_status>0} {$vo.order_amount_number+0} 元 {else} - {/if}{:join(', ',$vo.rebate_rule)} + {foreach $vo.rebate_rule as $v} + {$v} + {/foreach} + {if $vo.status eq 0}已禁用{elseif $vo.status eq 1}使用中{/if}