Browse Source

fix:协议

super-yimizi 1 month ago
parent
commit
73ebf6b42a

+ 158 - 142
application/admin/controller/lottery/Activity.php

@@ -119,7 +119,7 @@ class Activity extends Backend
             if ($params) {
                 $params = $this->preExcludeFields($params);
                 
-                // 获取奖品和条件数据
+                // 获取奖品数据
                 $prizesJson = $this->request->post("prizes_json", "");
                 $prizesData = [];
                 if (!empty($prizesJson)) {
@@ -128,8 +128,16 @@ class Activity extends Backend
                         $this->error('奖品数据格式错误');
                     }
                 }
-                $conditionData = $this->request->post("condition/a", []);
-                $taskTypes = isset($params['task_type']) ? $params['task_type'] : [];
+                
+                // 获取规则数据
+                $rulesJson = $this->request->post("rules_json", "");
+                $rulesData = [];
+                if (!empty($rulesJson)) {
+                    $rulesData = json_decode($rulesJson, true);
+                    if (json_last_error() !== JSON_ERROR_NONE) {
+                        $this->error('规则数据格式错误');
+                    }
+                }
                 
                 // 处理活动基础数据
                 $activityData = $this->processActivityData($params);
@@ -137,8 +145,8 @@ class Activity extends Backend
                 // 验证奖品数据
                 $this->validatePrizesData($prizesData);
                 
-                // 验证条件数据
-                $this->validateConditionData($conditionData, $taskTypes);
+                // 验证规则数据
+                $this->validateRulesData($rulesData);
 
                 $result = false;
                 Db::startTrans();
@@ -159,7 +167,7 @@ class Activity extends Backend
                         $this->savePrizesData($activityId, $prizesData);
                         
                         // 保存参与条件数据
-                        $this->saveConditionData($activityId, $conditionData, $taskTypes);
+                        $this->saveRulesData($activityId, $rulesData);
                     }
                     
                     Db::commit();
@@ -213,7 +221,7 @@ class Activity extends Backend
         // 处理兑奖期限设置
         if (isset($params['redeem_expire_type'])) {
             $params['redeem_expire_type'] = intval($params['redeem_expire_type']);
-            if ($params['redeem_expire_type'] == ActivityEnum::REDEEM_EXPIRE_FIXED) {
+            if ($params['redeem_expire_type'] == 2) { // 固定时长
                 $params['redeem_expire_days'] = isset($params['redeem_expire_days']) ? intval($params['redeem_expire_days']) : 7;
             } else {
                 $params['redeem_expire_days'] = null;
@@ -240,7 +248,7 @@ class Activity extends Backend
         unset($params['task_type']);
         
         // 设置默认值
-        $params['type'] = ActivityEnum::ACTIVITY_TYPE_CONSUMPTION_LOTTERY; // 消费抽奖
+        $params['type'] = 1; // 消费抽奖
         
         // 初始化统计字段
         if (!isset($params['total_draw_count'])) {
@@ -261,8 +269,12 @@ class Activity extends Backend
      */
     private function validatePrizesData($prizesData)
     {
-        if (empty($prizesData) || count($prizesData) < 8) {
-            throw new Exception('奖品数量不足,必须配置8个奖品(包含未中奖项)');
+        if (empty($prizesData)) {
+            throw new Exception('请至少添加一个奖品');
+        }
+        
+        if (count($prizesData) > 10) {
+            throw new Exception('奖品数量不能超过10个');
         }
         
         $totalRate = 0;
@@ -294,31 +306,37 @@ class Activity extends Backend
     }
     
     /**
-     * 验证条件数据
+     * 验证规则数据
      */
-    private function validateConditionData($conditionData, $taskTypes)
+    private function validateRulesData($rulesData)
     {
-        if (empty($taskTypes)) {
-            throw new Exception('请至少选择一种任务类型');
+        if (empty($rulesData)) {
+            throw new Exception('请至少设置一种参与条件');
         }
         
-        foreach ($taskTypes as $taskType) {
-            $type = intval($taskType);
+        foreach ($rulesData as $type => $rule) {
+            if (!isset($rule['type'])) {
+                throw new Exception('规则配置不完整');
+            }
             
-            switch ($type) {
+            switch (intval($rule['type'])) {
                 case 1: // 购买指定商品
-                    if (!isset($conditionData[$type]) || empty($conditionData[$type]['goods_ids'])) {
-                        throw new Exception('购买指定商品任务必须選擇商品');
+                    if (empty($rule['goods_ids'])) {
+                        throw new Exception('购买指定商品规则必须选择商品');
+                    }
+                    $goodsIds = json_decode($rule['goods_ids'], true);
+                    if (!is_array($goodsIds) || empty($goodsIds)) {
+                        throw new Exception('购买指定商品规则的商品数据格式错误');
                     }
                     break;
                 case 2: // 单笔订单消费满额
                 case 3: // 单次充值满额
                 case 4: // 活动期间累计消费满额
-                    if (!isset($conditionData[$type]) || empty($conditionData[$type]['condition_value'])) {
-                        throw new Exception('消费/充值任务必须设置金额');
+                    if (empty($rule['condition_value'])) {
+                        throw new Exception('消费/充值规则必须设置金额');
                     }
-                    if (floatval($conditionData[$type]['condition_value']) <= 0) {
-                        throw new Exception('消费/充值任务金额必须大于0');
+                    if (floatval($rule['condition_value']) <= 0) {
+                        throw new Exception('消费/充值规则金额必须大于0');
                     }
                     break;
             }
@@ -348,23 +366,23 @@ class Activity extends Backend
             
                          // 根据奖品类型设置特定字段
             switch (intval($prize['type'])) {
-                case ActivityEnum::PRIZE_TYPE_POINTS: // 积分 - 使用amount字段存储积分数量
+                case LotteryEnum::PRIZE_TYPE_POINTS: // 积分 - 使用amount字段存储积分数量
                     $prizeData['amount'] = isset($prize['points']) ? intval($prize['points']) : 0;
                     $prizeData['description'] = '积分奖品';
                     break;
-                case ActivityEnum::PRIZE_TYPE_BALANCE: // 余额 - 使用amount字段存储余额金额
+                case LotteryEnum::PRIZE_TYPE_BALANCE: // 余额 - 使用amount字段存储余额金额
                     $prizeData['amount'] = isset($prize['balance']) ? floatval($prize['balance']) : 0;
                     $prizeData['description'] = '余额奖品';
                     break;
-                case ActivityEnum::PRIZE_TYPE_COUPON: // 优惠券
+                case LotteryEnum::PRIZE_TYPE_COUPON: // 优惠券
                     $prizeData['coupon_id'] = isset($prize['coupon_id']) ? intval($prize['coupon_id']) : 0;
                     $prizeData['description'] = '优惠券奖品';
                     break;
-                case ActivityEnum::PRIZE_TYPE_REDPACK: // 红包 - 使用amount字段存储红包金额
+                case LotteryEnum::PRIZE_TYPE_REDPACK: // 红包 - 使用amount字段存储红包金额
                     $prizeData['amount'] = isset($prize['redpack_amount']) ? floatval($prize['redpack_amount']) : 0;
                     $prizeData['description'] = '红包奖品';
                     break;
-                case ActivityEnum::PRIZE_TYPE_CODE: // 兑换码
+                case LotteryEnum::PRIZE_TYPE_CODE: // 兑换码
                     if (isset($prize['manual_codes']) && !empty($prize['manual_codes'])) {
                         $codes = array_filter(array_map('trim', explode("\n", $prize['manual_codes'])));
                         $prizeData['exchange_codes'] = json_encode($codes);
@@ -374,15 +392,15 @@ class Activity extends Backend
                     }
                     $prizeData['description'] = '兑换码奖品';
                     break;
-                case ActivityEnum::PRIZE_TYPE_SHOP_GOODS: // 商城奖品
+                case LotteryEnum::PRIZE_TYPE_SHOP_GOODS: // 商城奖品
                     $prizeData['goods_id'] = isset($prize['goods_id']) ? intval($prize['goods_id']) : 0;
                     $prizeData['goods_sku_id'] = isset($prize['goods_sku_id']) ? intval($prize['goods_sku_id']) : null;
                     $prizeData['description'] = '商城奖品';
                     break;
-                case ActivityEnum::PRIZE_TYPE_GOODS: // 实物奖品
+                case LotteryEnum::PRIZE_TYPE_GOODS: // 实物奖品
                     $prizeData['description'] = isset($prize['description']) ? $prize['description'] : '实物奖品';
                     break;
-                case ActivityEnum::PRIZE_TYPE_NO_PRIZE: // 未中奖
+                case LotteryEnum::PRIZE_TYPE_NO_PRIZE: // 未中奖
                 default:
                     $prizeData['description'] = '未中奖';
                     break;
@@ -393,39 +411,37 @@ class Activity extends Backend
     }
     
     /**
-     * 保存参与条件数据
+     * 保存规则数据
      */
-    private function saveConditionData($activityId, $conditionData, $taskTypes)
+    private function saveRulesData($activityId, $rulesData)
     {
         $conditionModel = new \app\admin\model\lottery\Condition;
         
-        foreach ($taskTypes as $taskType) {
-            $type = intval($taskType);
-            $condition = isset($conditionData[$type]) ? $conditionData[$type] : [];
+        foreach ($rulesData as $type => $rule) {
+            $typeInt = intval($type);
             
             $conditionRecord = [
                 'activity_id' => $activityId,
-                'type' => $type,
+                'type' => $typeInt,
                 'reward_times' => 1,
                 'is_repeatable' => 0,
                 'status' => $conditionModel::STATUS_ENABLED,
                 'createtime' => time()
             ];
             
-            switch ($type) {
-                case ActivityEnum::CONDITION_TYPE_BUY_GOODS: // 购买指定商品
-                    $goodsIds = isset($condition['goods_ids']) ? $condition['goods_ids'] : '[]';
+            switch ($typeInt) {
+                case LotteryEnum::CONDITION_TYPE_BUY_GOODS: // 购买指定商品
+                    $goodsIds = isset($rule['goods_ids']) ? $rule['goods_ids'] : '[]';
                     if (is_string($goodsIds)) {
                         $goodsIds = json_decode($goodsIds, true) ?: [];
                     }
                     $conditionRecord['goods_ids'] = json_encode($goodsIds);
-                    $conditionRecord['goods_rule'] = isset($condition['goods_rule']) ? intval($condition['goods_rule']) : $conditionModel::GOODS_RULE_INCLUDE;
+                    $conditionRecord['goods_rule'] = isset($rule['goods_rule']) ? intval($rule['goods_rule']) : $conditionModel::GOODS_RULE_INCLUDE;
                     break;
-                case ActivityEnum::CONDITION_TYPE_ORDER_AMOUNT: // 单笔订单消费满额
-                case ActivityEnum::CONDITION_TYPE_RECHARGE_AMOUNT: // 单次充值满额
-                case ActivityEnum::CONDITION_TYPE_TOTAL_AMOUNT: // 活动期间累计消费满额
-                    $conditionRecord['condition_value'] = isset($condition['condition_value']) ? floatval($condition['condition_value']) : 0;
-                    if ($type == ActivityEnum::CONDITION_TYPE_TOTAL_AMOUNT) {
+                case LotteryEnum::CONDITION_TYPE_ORDER_AMOUNT: // 单笔订单消费满额
+                case LotteryEnum::CONDITION_TYPE_TOTAL_AMOUNT: // 活动期间累计消费满额
+                    $conditionRecord['condition_value'] = isset($rule['condition_value']) ? floatval($rule['condition_value']) : 0;
+                    if ($typeInt == LotteryEnum::CONDITION_TYPE_TOTAL_AMOUNT) {
                         $conditionRecord['is_repeatable'] = 0; // 累计消费不可重复
                     } else {
                         $conditionRecord['is_repeatable'] = 1; // 其他类型可重复
@@ -457,7 +473,7 @@ class Activity extends Backend
             if ($params) {
                 $params = $this->preExcludeFields($params);
                 
-                // 获取奖品和条件数据
+                // 获取奖品数据
                 $prizesJson = $this->request->post("prizes_json", "");
                 $prizesData = [];
                 if (!empty($prizesJson)) {
@@ -466,8 +482,16 @@ class Activity extends Backend
                         $this->error('奖品数据格式错误');
                     }
                 }
-                $conditionData = $this->request->post("condition/a", []);
-                $taskTypes = isset($params['task_type']) ? $params['task_type'] : [];
+                
+                // 获取规则数据
+                $rulesJson = $this->request->post("rules_json", "");
+                $rulesData = [];
+                if (!empty($rulesJson)) {
+                    $rulesData = json_decode($rulesJson, true);
+                    if (json_last_error() !== JSON_ERROR_NONE) {
+                        $this->error('规则数据格式错误');
+                    }
+                }
                 
                 // 处理活动基础数据
                 $activityData = $this->processActivityData($params);
@@ -475,8 +499,8 @@ class Activity extends Backend
                 // 验证奖品数据
                 $this->validatePrizesData($prizesData);
                 
-                // 验证条件数据
-                $this->validateConditionData($conditionData, $taskTypes);
+                // 验证规则数据
+                $this->validateRulesData($rulesData);
 
                 $result = false;
                 Db::startTrans();
@@ -494,16 +518,16 @@ class Activity extends Backend
                         $activityId = $ids;
                         
                         // 删除原有奖品数据
-                        Db::name('shop_lottery_prize')->where('activity_id', $activityId)->delete();
+                        Db::table('shop_lottery_prize')->where('activity_id', $activityId)->delete();
                         
                         // 删除原有条件数据
-                        Db::name('shop_lottery_condition')->where('activity_id', $activityId)->delete();
+                        Db::table('shop_lottery_condition')->where('activity_id', $activityId)->delete();
                         
                         // 保存新的奖品数据
                         $this->savePrizesData($activityId, $prizesData);
                         
-                        // 保存新的参与条件数据
-                        $this->saveConditionData($activityId, $conditionData, $taskTypes);
+                        // 保存新的规则数据
+                        $this->saveRulesData($activityId, $rulesData);
                     }
                     
                     Db::commit();
@@ -559,122 +583,114 @@ class Activity extends Backend
         }
         
         // 获取奖品数据
-        $prizes = Db::name('shop_lottery_prize')
+        $prizes = Db::table('shop_lottery_prize')
             ->where('activity_id', $ids)
             ->order('sort_order', 'asc')
             ->select();
         
-        // 处理奖品数据的字段映射
-        foreach ($prizes as &$prize) {
-            // 将数据表字段映射回前端字段
-            $prize['quantity'] = $prize['total_stock']; // 前端使用quantity字段
-            $prize['rate'] = $prize['probability']; // 前端使用rate字段
+        // 处理奖品数据的字段映射,转换为前端需要的格式
+        $processedPrizes = [];
+        foreach ($prizes as $prize) {
+            $prizeData = [
+                'id' => $prize['id'],
+                'name' => $prize['name'],
+                'type' => intval($prize['type']),
+                'image' => $prize['image'] ?? '',
+                'description' => $prize['description'] ?? '',
+                'quantity' => intval($prize['total_stock']), // 前端使用quantity字段
+                'rate' => floatval($prize['probability']), // 前端使用rate字段
+                'sort_order' => intval($prize['sort_order']),
+            ];
             
-            // 根据奖品类型设置特定字段
+            // 根据奖品类型设置特定字段(保留所有类型的处理逻辑,但只显示启用的类型)
             switch (intval($prize['type'])) {
-                case ActivityEnum::PRIZE_TYPE_POINTS:
-                    $prize['points'] = $prize['amount'] ?? 0;
+                case LotteryEnum::PRIZE_TYPE_NO_PRIZE:
+                    // 未中奖项的特殊处理
+                    $prizeData['quantity'] = 0; // 未中奖项数量固定为0
                     break;
-                case ActivityEnum::PRIZE_TYPE_BALANCE:
-                    $prize['balance'] = $prize['amount'] ?? 0;
+                case LotteryEnum::PRIZE_TYPE_GOODS:
+                    // 实物奖品的特殊处理
                     break;
-                case ActivityEnum::PRIZE_TYPE_REDPACK:
-                    $prize['redpack_amount'] = $prize['amount'] ?? 0;
+                case LotteryEnum::PRIZE_TYPE_POINTS:
+                    $prizeData['points'] = intval($prize['amount'] ?? 0);
                     break;
-                case ActivityEnum::PRIZE_TYPE_CODE:
+                case LotteryEnum::PRIZE_TYPE_BALANCE:
+                    $prizeData['balance'] = floatval($prize['amount'] ?? 0);
+                    break;
+                case LotteryEnum::PRIZE_TYPE_COUPON:
+                    $prizeData['coupon_id'] = $prize['coupon_id'] ?? '';
+                    $prizeData['coupon_name'] = $prize['coupon_name'] ?? '';
+                    break;
+                case LotteryEnum::PRIZE_TYPE_REDPACK:
+                    $prizeData['redpack_amount'] = floatval($prize['amount'] ?? 0);
+                    break;
+                case LotteryEnum::PRIZE_TYPE_CODE:
+                    $prizeData['code_type'] = $prize['code_type'] ?? 'auto';
                     if (!empty($prize['exchange_codes'])) {
                         $codes = json_decode($prize['exchange_codes'], true) ?: [];
-                        $prize['manual_codes'] = implode("\n", $codes);
+                        $prizeData['manual_codes'] = implode("\n", $codes);
                     }
                     break;
+                case LotteryEnum::PRIZE_TYPE_SHOP_GOODS:
+                    $prizeData['goods_id'] = $prize['goods_id'] ?? '';
+                    $prizeData['goods_name'] = $prize['goods_name'] ?? '';
+                    break;
             }
+            
+            $processedPrizes[] = $prizeData;
         }
         
+        // 使用处理后的奖品数据
+        $prizes = $processedPrizes;
+        
         // 获取条件数据
-        $conditions = Db::name('shop_lottery_condition')
+        $conditions = Db::table('shop_lottery_condition')
             ->where('activity_id', $ids)
             ->select();
         
-        // 处理条件数据的字段映射
-        $taskTypes = [];
-        $conditionsData = [];
+        // 处理条件数据的字段映射并构建规则数据
+        $rulesData = [];
         foreach ($conditions as $condition) {
-            $taskTypes[] = $condition['type'];
-            $conditionsData[$condition['type']] = $condition;
+            $rule = [
+                'type' => $condition['type']
+            ];
             
-            // 处理商品IDs JSON
-            if (!empty($condition['goods_ids'])) {
-                $conditionsData[$condition['type']]['goods_ids_array'] = json_decode($condition['goods_ids'], true) ?: [];
+            // 根据条件类型设置特定字段
+            switch (intval($condition['type'])) {
+                case LotteryEnum::CONDITION_TYPE_BUY_GOODS:
+                    $rule['goods_rule'] = $condition['goods_rule'] ?? 1;
+                    $rule['goods_ids'] = $condition['goods_ids'] ?? '[]';
+                    // 解析商品ID数组用于前端显示
+                    $rule['goods_ids_array'] = json_decode($condition['goods_ids'], true) ?: [];
+                    break;
+                case LotteryEnum::CONDITION_TYPE_ORDER_AMOUNT:
+                case LotteryEnum::CONDITION_TYPE_TOTAL_AMOUNT:
+                    $rule['condition_value'] = $condition['condition_value'] ?? 0;
+                    break;
             }
+            
+            $rulesData[$condition['type']] = $rule;
         }
-        
+        // echo "<pre>";
+        // print_r($prizes);
+        // echo "</pre>";
+        // exit;
         $this->view->assign("row", $row);
-        $this->view->assign("prizes", $prizes);
-        $this->view->assign("prizesJson", json_encode($prizes)); // 为前端JavaScript提供JSON格式的奖品数据
-        $this->view->assign("conditions", $conditions);
-        $this->view->assign("conditionsData", $conditionsData);
-        $this->view->assign("taskTypes", $taskTypes);
-        return $this->view->fetch();
-    }
-
-    /**
-     * 奖品管理
-     */
-    public function prize($ids = null)
-    {
-        $activity = $this->model->get($ids);
-        if (!$activity) {
-            $this->error(__('No Results were found'));
-        }
-        
-        $this->view->assign("activity", $activity);
-        return $this->view->fetch();
-    }
 
-    /**
-     * 参与条件管理
-     */
-    public function condition($ids = null)
-    {
-        $activity = $this->model->get($ids);
-        if (!$activity) {
-            $this->error(__('No Results were found'));
-        }
+        // 使用assignconfig传递数据给JavaScript
+        $this->assignconfig("existingPrizes", $prizes); // 奖品数据
+        $this->assignconfig("existingRulesData", $rulesData); // 规则数据
+        $this->assignconfig("existingConditions", $conditions); // 条件数据
+        $this->assignconfig("existingTaskTypes", array_keys($rulesData)); // 任务类型
         
-        $this->view->assign("activity", $activity);
-        return $this->view->fetch();
-    }
-
-    /**
-     * 抽奖记录
-     */
-    public function records($ids = null)
-    {
-        $activity = $this->model->get($ids);
-        if (!$activity) {
-            $this->error(__('No Results were found'));
-        }
+        // 保持向后兼容,仍然传递给模板
+        $this->view->assign("prizes", $prizes);
+        $this->view->assign("rulesData", $rulesData);
+        $this->view->assign("conditions", $conditions);
+        $this->view->assign("taskTypes", array_keys($rulesData));
         
-        $this->view->assign("activity", $activity);
         return $this->view->fetch();
     }
 
-    /**
-     * 统计数据
-     */
-    public function statistics($ids = null)
-    {
-        $activity = $this->model->get($ids);
-        if (!$activity) {
-            $this->error(__('No Results were found'));
-        }
-        
-        // 获取统计数据
-        $statisticsModel = new \app\admin\model\lottery\Statistics;
-        $statistics = $statisticsModel->where('activity_id', $ids)->order('stat_date', 'desc')->paginate(15);
-        
-        $this->view->assign("activity", $activity);
-        $this->view->assign("statistics", $statistics);
-        return $this->view->fetch();
-    }
+  
 } 

+ 203 - 18
application/admin/controller/lottery/DrawRecord.php

@@ -3,7 +3,8 @@
 namespace app\admin\controller\lottery;
 
 use app\common\controller\Backend;
-
+use app\common\Enum\StatusEnum;
+use app\common\Enum\LotteryEnum;
 /**
  * 抽奖记录管理
  *
@@ -17,6 +18,7 @@ class DrawRecord extends Backend
      * @var \app\admin\model\lottery\DrawRecord
      */
     protected $model = null;
+    protected $relationSearch = true;
 
     public function _initialize()
     {
@@ -24,7 +26,31 @@ class DrawRecord extends Backend
         $this->model = new \app\admin\model\lottery\DrawRecord;
         
         // 获取枚举值列表
-        $this->view->assign("triggerTypeList", $this->model->getTriggerTypeList());
+        $this->view->assign([
+            "triggerTypeList" => $this->model->getTriggerTypeList(),
+            "statusList" => StatusEnum::getMap(),
+            "isWinList" =>  LotteryEnum::getIsWinMap(),
+            "deliverStatusList" => LotteryEnum::getDeliverStatusMap(),
+        ]);
+        $this->assignconfig("triggerTypeList", json_encode($this->model->getTriggerTypeList()));
+        $this->assignconfig("statusList", json_encode(StatusEnum::getMap()));
+        $this->assignconfig("isWinList", json_encode(LotteryEnum::getIsWinMap()));
+        $this->assignconfig("deliverStatusList", json_encode(LotteryEnum::getDeliverStatusMap()));
+        // 参与状态
+        $this->assignconfig("drawStatusList", json_encode(LotteryEnum::getDrawStatusMap()));
+        // 奖品类型配置
+        $this->view->assign("prizeTypeList", LotteryEnum::getPrizeTypeMap());
+        $this->assignconfig("prizeTypeList", json_encode(LotteryEnum::getPrizeTypeMap()));
+        $this->assignconfig("prizeTypeList", json_encode(LotteryEnum::getPrizeTypeMap()));
+        // 发放状态
+        $this->view->assign("deliverStatusList", LotteryEnum::getDeliverStatusMap());
+        $this->assignconfig("deliverStatusList", json_encode(LotteryEnum::getDeliverStatusMap()));
+        // 抽奖类型
+        $this->view->assign("lotteryTypeList", LotteryEnum::getLotteryTypeMap());
+        $this->assignconfig("lotteryTypeList", json_encode(LotteryEnum::getLotteryTypeMap()));
+        // 抽奖方式
+        $this->view->assign("lotteryTypeList", LotteryEnum::getLotteryTypeMap());
+        $this->assignconfig("lotteryTypeList", json_encode(LotteryEnum::getLotteryTypeMap()));
     }
 
     /**
@@ -48,23 +74,54 @@ class DrawRecord extends Backend
                     ->where($where)
                     ->order($sort, $order)
                     ->paginate($limit);
-
+                       //  where  in  查询 中奖记录 
+            $drawRecordIds = $list->column('id');
+            $winRecord = new \app\admin\model\lottery\WinRecord;
+            $objWinRecord = $winRecord->where('draw_record_id', 'in', $drawRecordIds)
+                                      ->select();
+            $winRecordList = collection($objWinRecord)->toArray();
+            $winRecordMap = [];
+            foreach ($winRecordList as $item) {
+                $winRecordMap[$item['draw_record_id']] = $item;
+            }         
+            $list->each(function($row) use ($winRecordMap) {
+                $row->win_record_id = 0;
+                $row->deliver_status = 0;
+                $row->deliver_time = 0;
+                if (isset($winRecordMap[$row->id])) {
+                    $row->win_record_id =  $winRecordMap[$row->id]['id'] ?? 0;
+                    $row->deliver_status =  $winRecordMap[$row->id]['deliver_status'] ?? 0;
+                    $row->deliver_time =  $winRecordMap[$row->id]['deliver_time'] ?? 0;       
+                }                
+            });   
             foreach ($list as $row) {
-                $row->visible(['id','activity_id','user_id','prize_id','is_win','trigger_type','trigger_amount','draw_time','createtime']);
-                $row->visible(['activity', 'user', 'prize']);
+                $row->visible([
+                    'id', 'activity_id', 'user_id', 'prize_id', 'is_win', 
+                    'trigger_type', 'trigger_order_id', 'trigger_amount', 
+                    'draw_ip', 'draw_time', 'device_info', 'status', 'createtime','win_record_id','deliver_status','deliver_time'
+                ]);
+                $row->visible(['activity', 'user', 'prize', 'winRecord']);
                 
-                // 处理关联数据(belongsTo关系)
+                // 处理关联数据
                 if ($row->getRelation('activity')) {
-                    $row->getRelation('activity')->visible(['name']);
+                    $row->getRelation('activity')->visible(['id', 'name', 'type','lottery_type','lottery_time']);
                 }
                 if ($row->getRelation('user')) {
-                    $row->getRelation('user')->visible(['nickname']);
+                    $row->getRelation('user')->visible(['id', 'username', 'mobile','avatar']);
                 }
                 if ($row->getRelation('prize')) {
-                    $row->getRelation('prize')->visible(['name', 'type']);
+                    $row->getRelation('prize')->visible(['id', 'name', 'type', 'image']);
                 }
-            }
-            
+                $row->win_record_id = 0;
+                $row->deliver_status = 0;
+                $row->deliver_time = 0;
+                if (isset($winRecordMap[$row->id])) {
+                    $row->win_record_id =  $winRecordMap[$row->id]['id'] ?? 0;
+                    $row->deliver_status =  $winRecordMap[$row->id]['deliver_status'] ?? 0;
+                    $row->deliver_time =  $winRecordMap[$row->id]['deliver_time'] ?? 0;       
+                }
+                
+            }      
             $result = array("total" => $list->total(), "rows" => $list->items());
 
             return json($result);
@@ -77,13 +134,82 @@ class DrawRecord extends Backend
      */
     public function detail($ids = null)
     {
-        $row = $this->model->with(['activity', 'user', 'prize', 'winRecord'])->get($ids);
+        $row = $this->model->with(['activity', 'user', 'prize', 'winRecord'])->find($ids);
         if (!$row) {
             $this->error(__('No Results were found'));
         }
         
+        // 解析win_info JSON数据
+        if ($row->win_info) {
+            $row->win_info_data = json_decode($row->win_info, true);
+        }
+        
+        // 解析设备信息
+        if ($row->device_info) {
+            $row->device_info_data = json_decode($row->device_info, true);
+        }
+        
         $this->view->assign("row", $row);
-        return $this->view->fetch();
+        return $this->view->fetch('lottery/draw_record/detail');
+    }
+
+    /**
+     * 统计数据
+     */
+    public function statistics()
+    {
+        $stats = [];
+        
+        // 总抽奖次数
+        $stats['total_draws'] = $this->model->count();
+        
+        // 中奖次数
+        $stats['total_wins'] = $this->model->where('is_win', 1)->count();
+        
+        // 中奖率
+        $stats['win_rate'] = $stats['total_draws'] > 0 ? 
+            round($stats['total_wins'] / $stats['total_draws'] * 100, 2) : 0;
+        
+        // 按触发类型统计
+        $stats['by_trigger_type'] = $this->model
+            ->field('trigger_type, COUNT(*) as count')
+            ->group('trigger_type')
+            ->select()
+            ->toArray();
+        
+        // 按奖品类型统计中奖情况
+        $stats['by_prize_type'] = $this->model
+            ->alias('dr')
+            ->join('shop_lottery_prize p', 'dr.prize_id = p.id')
+            ->field('p.type, COUNT(*) as total_count, SUM(dr.is_win) as win_count')
+            ->group('p.type')
+            ->select()
+            ->toArray();
+        
+        // 最近7天抽奖趋势
+        $stats['recent_trend'] = [];
+        for ($i = 6; $i >= 0; $i--) {
+            $date = date('Y-m-d', strtotime("-{$i} days"));
+            $start_time = strtotime($date);
+            $end_time = strtotime($date . ' 23:59:59');
+            
+            $daily_draws = $this->model
+                ->where('draw_time', 'between', [$start_time, $end_time])
+                ->count();
+            $daily_wins = $this->model
+                ->where('draw_time', 'between', [$start_time, $end_time])
+                ->where('is_win', 1)
+                ->count();
+                
+            $stats['recent_trend'][] = [
+                'date' => $date,
+                'draws' => $daily_draws,
+                'wins' => $daily_wins,
+                'rate' => $daily_draws > 0 ? round($daily_wins / $daily_draws * 100, 2) : 0
+            ];
+        }
+        
+        return json(['code' => 1, 'data' => $stats]);
     }
 
     /**
@@ -98,12 +224,16 @@ class DrawRecord extends Backend
             $where = json_decode($filter, true);
         }
         
-        $list = $this->model->with(['activity', 'user', 'prize'])
+        $list = $this->model->with(['activity', 'user', 'prize', 'winRecord'])
                           ->where($where)
                           ->order('createtime', 'desc')
                           ->select();
         
-        $header = ['ID', '活动名称', '用户昵称', '奖品名称', '是否中奖', '触发类型', '触发金额', '抽奖时间'];
+        $header = [
+            'ID', '活动名称', '用户昵称', '用户手机', '奖品名称', '奖品类型',
+            '是否中奖', '触发类型', '触发金额', '抽奖IP', '抽奖时间', 
+            '发放状态', '收货人', '快递单号', '创建时间'
+        ];
         $data = [];
         
         foreach ($list as $item) {
@@ -111,15 +241,70 @@ class DrawRecord extends Backend
                 $item->id,
                 $item->activity->name ?? '',
                 $item->user->nickname ?? '',
+                $item->user->mobile ?? '',
                 $item->prize->name ?? '',
+                $item->prize->type_text ?? '',
                 $item->is_win ? '是' : '否',
                 $item->trigger_type_text,
-                $item->trigger_amount,
-                date('Y-m-d H:i:s', $item->draw_time)
+                $item->trigger_amount ?? '',
+                $item->draw_ip ?? '',
+                date('Y-m-d H:i:s', $item->draw_time),
+                $item->winRecord->deliver_status_text ?? '',
+                $item->winRecord->receiver_name ?? '',
+                $item->winRecord->express_number ?? '',
+                date('Y-m-d H:i:s', $item->createtime)
             ];
         }
         
         // 这里可以集成Excel导出功能
-        $this->success('导出成功', '', $data);
+        $this->success('导出成功', '', ['header' => $header, 'data' => $data]);
+    }
+
+    /**
+     * 批量处理中奖发放
+     */
+    public function batchDeliver()
+    {
+        $ids = $this->request->post('ids');
+        if (!$ids) {
+            $this->error('请选择要处理的记录');
+        }
+        
+        $count = 0;
+        foreach ($ids as $id) {
+            $record = $this->model->with('winRecord')->get($id);
+            if ($record && $record->is_win && $record->winRecord) {
+                // 这里可以调用具体的发放逻辑
+                $count++;
+            }
+        }
+        
+        $this->success("成功处理 {$count} 条记录");
+    }
+
+    /**
+     * 发货
+     */
+    public function deliver($ids = null)
+    {
+        $winRecordId = $this->request->param('id');
+        $winRecord = \app\admin\model\lottery\WinRecord::get($winRecordId);
+        if (!$winRecord) {
+            $this->error('未找到中奖记录');
+        }
+        if ($this->request->isPost()) {
+            $params = $this->request->post('row/a');
+            if (!$params['express_company'] || !$params['express_number']) {
+                $this->error('快递公司和快递单号不能为空');
+            }
+            $winRecord->express_company = $params['express_company'];
+            $winRecord->express_number = $params['express_number'];
+            $winRecord->deliver_status = 1; // 假设1为已发货
+            $winRecord->deliver_time = time();
+            $winRecord->save();
+            $this->success('发货成功');
+        }
+        $this->view->assign('winRecord', $winRecord);
+        return $this->view->fetch('lottery/draw_record/deliver');
     }
 } 

+ 4 - 1
application/admin/view/lottery/activity/index.html

@@ -1,6 +1,9 @@
 <div class="panel panel-default panel-intro">
-    {:build_heading()}
+    <div class="panel-heading">
+        <div class="panel-lead"><em>抽奖活动列表</em>用于管理、审核抽奖活动内容</div>
+    </div>
 
+    
     <div class="panel-body">
         <div id="myTabContent" class="tab-content">
             <div class="tab-pane fade active in" id="one">

+ 4 - 5
application/admin/view/lottery/draw_record/index.html

@@ -1,18 +1,17 @@
 <div class="panel panel-default panel-intro">
     <div class="panel-heading">
-        <ul class="nav nav-tabs">
-            <li class="active"><a href="#t-all" data-toggle="tab">{:__('All')}</a></li>
-        </ul>
+        <div class="panel-lead"><em>抽奖记录列表</em>用于管理、活动记录内容</div>
     </div>
 
+
     <div class="panel-body">
         <div id="myTabContent" class="tab-content">
             <div class="tab-pane fade active in" id="t-all">
                 <div class="widget-body no-padding">
                     <div id="toolbar" class="toolbar">
                         <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
-                        <a href="javascript:;" class="btn btn-success btn-export btn-disabled disabled" title="{:__('Export')}" ><i class="fa fa-download"></i> {:__('Export')}</a>
-                        <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
+                        <!-- <a href="javascript:;" class="btn btn-success btn-export btn-disabled disabled" title="{:__('Export')}" ><i class="fa fa-download"></i> {:__('Export')}</a>
+                        <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a> -->
                     </div>
                     <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
                            data-operate-detail="{:$auth->check('lottery/drawrecord/detail')}"

+ 1 - 0
application/admin/view/shop/comment/index.html

@@ -2,6 +2,7 @@
     
     <div class="panel-heading">
         <div class="panel-lead"><em>评论列表</em>用于管理、审核商品评论内容</div>
+        {:build_heading(null,FALSE)}
         <ul class="nav nav-tabs" data-field="evaluate_status">
             <li class="{:$Think.get.evaluate_status === null ? 'active' : ''}"><a href="#t-all" data-value="" data-toggle="tab">{:__('All')}</a></li>
             {foreach name="evaluateStatusList" item="vo" key="key"}

+ 10 - 7
application/api/controller/Page.php

@@ -3,7 +3,7 @@
 namespace app\api\controller;
 
 use app\common\model\Page as PageModel;
-
+use app\common\library\Service;
 /**
  * 单页
  */
@@ -25,12 +25,15 @@ class Page extends Base
         // if (!$page || $page['status'] != 'normal') {
         //     $this->error('未找到指定的单页');
         // }
-        $page->setInc('views');
-        $image = $page->getData('image');
-        $fields = explode(',', 'id,title,content,image,description,status,createtime');
-        $page = array_intersect_key($page->toArray(), array_flip($fields));
-        $page['content'] = \addons\shop\library\Service::formatTplToUniapp($page['content']);
-        $page['image'] = $image ? cdnurl($image, true) : $image;
+        if (!empty($page)) {
+            $page->setInc('views');
+            $image = $page->getData('image');
+            $fields = explode(',', 'id,title,content,image,description,status,createtime');
+            $page = array_intersect_key($page->toArray(), array_flip($fields));
+            $page['content'] = Service::formatTplToUniapp($page['content']);
+            $page['image'] = $image ? cdnurl($image, true) : $image;
+        }
+       
         $this->success('获取成功', $page);
     }
 

+ 39 - 9
public/assets/js/backend/lottery/draw_record.js

@@ -110,22 +110,35 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                         {
                             field: 'status', 
                             title: '状态', 
-                            searchList: Controller.api.parseConfigJson('statusList'), 
+                            searchList: Controller.api.parseConfigJson('drawStatusList'), 
                             formatter: function(value, row) {
-                                var statusMap = Controller.api.parseConfigJson('statusList');
-                                var status = statusMap[value] || {text: '未知', class: 'warning'};
-                                return '<span class="label label-' + status.class + '">' + status.text + '</span>';
+                                var statusMap = Controller.api.parseConfigJson('drawStatusList');
+                                var text = statusMap[value] || '未知';
+                                var classMap = {
+                                    1: 'info',
+                                    2: 'success',
+                                    3: 'default'
+                                };
+                                var statusClass = classMap[value] || 'warning';
+                                return '<span class="label label-' + statusClass + '">' + text + '</span>';
                             }
                         },
                         {
-                            field: 'winRecord.deliver_status', 
+                            field: 'deliver_status', 
                             title: '发放状态', 
                             searchList: Controller.api.parseConfigJson('deliverStatusList'), 
                             formatter: function(value, row) {
-                                if (!row.is_win || !row.winRecord) return '-';
+                                if (!row.is_win || !row.win_record_id) return '-';
                                 var statusMap = Controller.api.parseConfigJson('deliverStatusList');
-                                var status = statusMap[value] || {text: '未知', class: 'default'};
-                                return '<span class="label label-' + status.class + '">' + status.text + '</span>';
+                                var text = statusMap[value] || '未知';
+                                var classMap = {
+                                    0: 'info',      // 待发放
+                                    1: 'success',   // 已发放
+                                    2: 'danger',    // 发放失败
+                                    3: 'default'    // 已取消
+                                };
+                                var statusClass = classMap[value] || 'warning';
+                                return '<span class="label label-' + statusClass + '">' + text + '</span>';
                             },
                             operate: false
                         },
@@ -142,7 +155,24 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                                     title: '查看详情',
                                     classname: 'btn btn-xs btn-info btn-dialog',
                                     icon: 'fa fa-list',
-                                    url: 'lottery/drawrecord/detail'
+                                    url: 'lottery/draw_record/detail'
+                                },
+                                {
+                                    name: 'deliver',
+                                    title: '发货',
+                                    classname: 'btn btn-xs btn-success btn-dialog',
+                                    icon: 'fa fa-truck',
+                                    url: 'lottery/draw_record/deliver',
+                                    visible: function(row) {
+                                        return row.win_record_id > 0 && row.deliver_status == 0;
+                                    },
+                                    extend: 'data-area="[\'600px\', \'400px\']"',
+                                    callback: function (data) {
+                                        // 可自定义回调
+                                    },
+                                    params: function(row) {
+                                        return {id: row.win_record_id};
+                                    }
                                 }
                             ],
                             formatter: Table.api.formatter.operate