Browse Source

fix:用户

super-yimizi 2 months ago
parent
commit
eeb415b904

+ 160 - 15
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,29 @@ 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->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,20 +72,39 @@ 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->winRecord = $winRecordMap[$row->id] ?? null;
+            });
+           
 
             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'
+                ]);
+                $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']);
                 }
             }
             
@@ -77,13 +120,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 +210,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 +227,44 @@ 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} 条记录");
     }
 } 

+ 12 - 1
application/admin/controller/user/User.php

@@ -4,7 +4,8 @@ namespace app\admin\controller\user;
 
 use app\common\controller\Backend;
 use app\common\library\Auth;
-
+use app\common\Enum\StatusEnum;
+use app\common\Enum\UserEnum;
 /**
  * 会员管理
  *
@@ -25,6 +26,10 @@ class User extends Backend
     {
         parent::_initialize();
         $this->model = new \app\admin\model\User;
+        $this->view->assign('statusList', StatusEnum::getMap());
+        $this->assignconfig('statusList', json_encode(StatusEnum::getMap()));
+        $this->view->assign('genderList', UserEnum::getGenderMap());
+        $this->assignconfig('genderList',json_encode(UserEnum::getGenderMap()));
     }
 
     /**
@@ -80,7 +85,13 @@ class User extends Backend
         if (!$row) {
             $this->error(__('No Results were found'));
         }
+        
+        // 获取第三方登录信息
+        $thirdList = $this->model->third()->where('user_id', $ids)->select();
+        
         $this->view->assign('groupList', build_select('row[group_id]', \app\admin\model\UserGroup::column('id,name'), $row['group_id'], ['class' => 'form-control selectpicker']));
+        $this->view->assign('thirdList', $thirdList);
+        
         return parent::edit($ids);
     }
 

+ 5 - 0
application/admin/model/User.php

@@ -111,4 +111,9 @@ class User extends Model
         return $this->belongsTo('UserGroup', 'group_id', 'id', [], 'LEFT')->setEagerlyType(0);
     }
 
+    public function third()
+    {
+        return $this->hasMany('Third', 'user_id', 'id');
+    }
+
 }

+ 28 - 8
application/admin/model/lottery/DrawRecord.php

@@ -3,7 +3,8 @@
 namespace app\admin\model\lottery;
 
 use think\Model;
-
+use app\common\Enum\LotteryEnum;
+use app\common\Enum\StatusEnum;
 class DrawRecord extends Model
 {
     // 表名
@@ -19,20 +20,39 @@ class DrawRecord extends Model
     // 追加属性
     protected $append = [
         'trigger_type_text',
-        'draw_time_text'
+        'draw_time_text',
+        'is_win_text',
+        'status_text',
     ];
 
+    public function getIsWinList()
+    {
+        return LotteryEnum::getIsWinMap();
+    }
+
+    public function getStatusList(){
+        return StatusEnum::getMap();
+    }
+
+    public function getStatusTextAttr($value, $data)
+    {
+        $value = $value ? $value : (isset($data['status']) ? $data['status'] : '');
+        $list = $this->getStatusList();
+        return isset($list[$value]) ? $list[$value] : '';
+    }
+
+    public function getIsWinTextAttr($value, $data)
+    {
+        $value = $value ? $value : (isset($data['is_win']) ? $data['is_win'] : '');
+        $list = $this->getIsWinList();
+        return isset($list[$value]) ? $list[$value] : '';
+    }
     /**
      * 触发类型列表
      */
     public function getTriggerTypeList()
     {
-        return [
-            '1' => __('购买商品'),
-            '2' => __('订单消费'),
-            '3' => __('充值'),
-            '4' => __('累计消费')
-        ];
+        return  LotteryEnum::getTriggerTypeMap();
     }
 
     // 获取器

+ 332 - 116
application/admin/view/lottery/draw_record/detail.html

@@ -3,137 +3,353 @@
         <h3 class="panel-title">抽奖记录详情</h3>
     </div>
     <div class="panel-body">
+        <!-- 基本信息 -->
         <div class="row">
             <div class="col-md-6">
-                <table class="table table-bordered">
-                    <tbody>
-                        <tr>
-                            <td class="col-sm-3 text-right">记录ID:</td>
-                            <td class="col-sm-9">{$row.id}</td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">活动名称:</td>
-                            <td>{$row.activity.name|default='-'}</td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">用户昵称:</td>
-                            <td>{$row.user.nickname|default='-'}</td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">奖品名称:</td>
-                            <td>{$row.prize.name|default='-'}</td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">奖品类型:</td>
-                            <td>
-                                {switch name="$row.prize.type"}
-                                    {case value="1"}未中奖{/case}
-                                    {case value="2"}实物奖品{/case}
-                                    {case value="3"}积分{/case}
-                                    {case value="4"}余额{/case}
-                                    {case value="5"}优惠券{/case}
-                                    {case value="6"}红包{/case}
-                                    {case value="7"}兑换码{/case}
-                                    {case value="8"}商城奖品{/case}
-                                    {default /}未知
-                                {/switch}
-                            </td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">是否中奖:</td>
-                            <td>
-                                {if condition="$row.is_win"}
-                                    <span class="label label-success">是</span>
-                                {else /}
-                                    <span class="label label-default">否</span>
-                                {/if}
-                            </td>
-                        </tr>
-                    </tbody>
-                </table>
+                <div class="box box-primary">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">基本信息</h3>
+                    </div>
+                    <div class="box-body">
+                        <table class="table table-bordered">
+                            <tbody>
+                                <tr>
+                                    <td class="col-sm-4 text-right"><strong>记录ID:</strong></td>
+                                    <td class="col-sm-8">{$row.id}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>活动名称:</strong></td>
+                                    <td>
+                                        {$row.activity.name|default='-'}
+                                        {if condition="$row.activity.id"}
+                                            <!-- <a href="{:url('lottery/activity/edit', ['ids' => $row.activity.id])}" class="btn btn-xs btn-info" target="_blank">
+                                                <i class="fa fa-edit"></i> 查看活动
+                                            </a> -->
+                                        {/if}
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>用户信息:</strong></td>
+                                    <td>
+                                        {$row.user.nickname|default='-'}
+                                        {if condition="$row.user.mobile"}
+                                            <br><small class="text-muted">手机:{$row.user.mobile}</small>
+                                        {/if}
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>奖品信息:</strong></td>
+                                    <td>
+                                        <div class="media">
+                                            {if condition="$row.prize.image"}
+                                            <div class="media-left">
+                                                <img src="{$row.prize.image|cdnurl}" class="media-object" style="width: 50px; height: 50px;" alt="奖品图片">
+                                            </div>
+                                            {/if}
+                                            <div class="media-body">
+                                                <strong>{$row.prize.name|default='-'}</strong>
+                                                <br>
+                                                <span class="label label-{switch name='$row.prize.type'}{case value='1'}default{/case}{case value='2'}primary{/case}{case value='3'}warning{/case}{case value='4'}info{/case}{case value='5'}success{/case}{case value='6'}danger{/case}{default}default{/switch}">
+                                                    {switch name="$row.prize.type"}
+                                                        {case value="1"}未中奖{/case}
+                                                        {case value="2"}实物奖品{/case}
+                                                        {case value="3"}积分{/case}
+                                                        {case value="4"}余额{/case}
+                                                        {case value="5"}优惠券{/case}
+                                                        {case value="6"}红包{/case}
+                                                        {case value="7"}兑换码{/case}
+                                                        {case value="8"}商城奖品{/case}
+                                                        {default /}未知
+                                                    {/switch}
+                                                </span>
+                                            </div>
+                                        </div>
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>是否中奖:</strong></td>
+                                    <td>
+                                        {if condition="$row.is_win"}
+                                            <span class="label label-success"><i class="fa fa-check"></i> 中奖</span>
+                                        {else /}
+                                            <span class="label label-default"><i class="fa fa-times"></i> 未中奖</span>
+                                        {/if}
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>抽奖状态:</strong></td>
+                                    <td>
+                                        {switch name="$row.status"}
+                                            {case value="1"}<span class="label label-info">参与</span>{/case}
+                                            {case value="2"}<span class="label label-success">中奖</span>{/case}
+                                            {case value="3"}<span class="label label-default">未中奖</span>{/case}
+                                            {default /}<span class="label label-warning">未知</span>
+                                        {/switch}
+                                    </td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
             </div>
+            
             <div class="col-md-6">
-                <table class="table table-bordered">
-                    <tbody>
-                        <tr>
-                            <td class="col-sm-3 text-right">触发类型:</td>
-                            <td class="col-sm-9">{$row.trigger_type_text|default='-'}</td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">触发金额:</td>
-                            <td>
-                                {if condition="$row.trigger_amount"}
-                                    ¥{$row.trigger_amount}
-                                {else /}
-                                    -
-                                {/if}
-                            </td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">抽奖时间:</td>
-                            <td>{$row.draw_time|date="Y-m-d H:i:s",###}</td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">创建时间:</td>
-                            <td>{$row.createtime|date="Y-m-d H:i:s",###}</td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">更新时间:</td>
-                            <td>
-                                {if condition="$row.updatetime"}
-                                    {$row.updatetime|date="Y-m-d H:i:s",###}
-                                {else /}
-                                    -
-                                {/if}
-                            </td>
-                        </tr>
-                    </tbody>
-                </table>
+                <div class="box box-info">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">触发信息</h3>
+                    </div>
+                    <div class="box-body">
+                        <table class="table table-bordered">
+                            <tbody>
+                                <tr>
+                                    <td class="col-sm-4 text-right"><strong>触发类型:</strong></td>
+                                    <td class="col-sm-8">
+                                        {switch name="$row.trigger_type"}
+                                            {case value="1"}<span class="label label-primary">购买商品</span>{/case}
+                                            {case value="2"}<span class="label label-success">订单消费</span>{/case}
+                                            {case value="3"}<span class="label label-warning">充值</span>{/case}
+                                            {case value="4"}<span class="label label-info">累计消费</span>{/case}
+                                            {default /}<span class="label label-default">未知</span>
+                                        {/switch}
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>触发订单ID:</strong></td>
+                                    <td>
+                                        {if condition="$row.trigger_order_id"}
+                                            {$row.trigger_order_id}
+                                            <a href="{:url('shop/order/detail', ['ids' => $row.trigger_order_id])}" class="btn btn-xs btn-info" target="_blank">
+                                                <i class="fa fa-external-link"></i> 查看订单
+                                            </a>
+                                        {else /}
+                                            -
+                                        {/if}
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>触发金额:</strong></td>
+                                    <td>
+                                        {if condition="$row.trigger_amount"}
+                                            <span class="text-success"><strong>¥{$row.trigger_amount}</strong></span>
+                                        {else /}
+                                            -
+                                        {/if}
+                                    </td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>抽奖IP:</strong></td>
+                                    <td>{$row.draw_ip|default='-'}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>抽奖时间:</strong></td>
+                                    <td>{$row.draw_time|date="Y-m-d H:i:s",###}</td>
+                                </tr>
+                                <tr>
+                                    <td class="text-right"><strong>创建时间:</strong></td>
+                                    <td>{$row.createtime|date="Y-m-d H:i:s",###}</td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
             </div>
         </div>
         
+        <!-- 设备信息 -->
+        {if condition="$row.device_info_data"}
+        <div class="row">
+            <div class="col-md-12">
+                <div class="box box-warning">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">设备信息</h3>
+                    </div>
+                    <div class="box-body">
+                        <div class="row">
+                            <div class="col-md-6">
+                                <table class="table table-bordered">
+                                    <tbody>
+                                        <tr>
+                                            <td class="text-right"><strong>用户代理:</strong></td>
+                                            <td>{$row.device_info_data.user_agent|default='-'}</td>
+                                        </tr>
+                                        <tr>
+                                            <td class="text-right"><strong>设备类型:</strong></td>
+                                            <td>{$row.device_info_data.device_type|default='-'}</td>
+                                        </tr>
+                                        <tr>
+                                            <td class="text-right"><strong>操作系统:</strong></td>
+                                            <td>{$row.device_info_data.os|default='-'}</td>
+                                        </tr>
+                                    </tbody>
+                                </table>
+                            </div>
+                            <div class="col-md-6">
+                                <table class="table table-bordered">
+                                    <tbody>
+                                        <tr>
+                                            <td class="text-right"><strong>浏览器:</strong></td>
+                                            <td>{$row.device_info_data.browser|default='-'}</td>
+                                        </tr>
+                                        <tr>
+                                            <td class="text-right"><strong>屏幕分辨率:</strong></td>
+                                            <td>{$row.device_info_data.screen_resolution|default='-'}</td>
+                                        </tr>
+                                        <tr>
+                                            <td class="text-right"><strong>来源页面:</strong></td>
+                                            <td>{$row.device_info_data.referrer|default='-'}</td>
+                                        </tr>
+                                    </tbody>
+                                </table>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        {/if}
+        
+        <!-- 中奖详情 -->
         {if condition="$row.winRecord"}
         <div class="row">
             <div class="col-md-12">
-                <h4>中奖详情</h4>
-                <table class="table table-bordered">
-                    <tbody>
-                        <tr>
-                            <td class="col-sm-2 text-right">中奖记录ID:</td>
-                            <td class="col-sm-10">{$row.winRecord.id}</td>
-                        </tr>
-                        <tr>
-                            <td class="text-right">兑奖状态:</td>
-                            <td>
-                                {switch name="$row.winRecord.status"}
-                                    {case value="0"}<span class="label label-warning">待兑奖</span>{/case}
-                                    {case value="1"}<span class="label label-success">已兑奖</span>{/case}
-                                    {case value="2"}<span class="label label-danger">已过期</span>{/case}
-                                    {case value="3"}<span class="label label-info">已取消</span>{/case}
-                                    {default /}<span class="label label-default">未知</span>
-                                {/switch}
-                            </td>
-                        </tr>
-                        {if condition="$row.winRecord.redeem_time"}
-                        <tr>
-                            <td class="text-right">兑奖时间:</td>
-                            <td>{$row.winRecord.redeem_time|date="Y-m-d H:i:s",###}</td>
-                        </tr>
+                <div class="box box-success">
+                    <div class="box-header with-border">
+                        <h3 class="box-title">中奖发放详情</h3>
+                        <div class="box-tools pull-right">
+                            <!-- {if condition="$row.winRecord.deliver_status == 0"}
+                                <button type="button" class="btn btn-sm btn-warning" onclick="deliverPrize({$row.winRecord.id})">
+                                    <i class="fa fa-send"></i> 立即发放
+                                </button>
+                            {/if} -->
+                        </div>
+                    </div>
+                    <div class="box-body">
+                        <div class="row">
+                            <div class="col-md-6">
+                                <table class="table table-bordered">
+                                    <tbody>
+                                        <tr>
+                                            <td class="col-sm-4 text-right"><strong>中奖记录ID:</strong></td>
+                                            <td class="col-sm-8">{$row.winRecord.id}</td>
+                                        </tr>
+                                        <tr>
+                                            <td class="text-right"><strong>发放状态:</strong></td>
+                                            <td>
+                                                {switch name="$row.winRecord.deliver_status"}
+                                                    {case value="0"}<span class="label label-warning"><i class="fa fa-clock-o"></i> 待发放</span>{/case}
+                                                    {case value="1"}<span class="label label-success"><i class="fa fa-check"></i> 已发放</span>{/case}
+                                                    {case value="2"}<span class="label label-danger"><i class="fa fa-times"></i> 发放失败</span>{/case}
+                                                    {case value="3"}<span class="label label-info"><i class="fa fa-ban"></i> 已取消</span>{/case}
+                                                    {default /}<span class="label label-default">未知</span>
+                                                {/switch}
+                                            </td>
+                                        </tr>
+                                        {if condition="$row.winRecord.deliver_time"}
+                                        <tr>
+                                            <td class="text-right"><strong>发放时间:</strong></td>
+                                            <td>{$row.winRecord.deliver_time|date="Y-m-d H:i:s",###}</td>
+                                        </tr>
+                                        {/if}
+                                        {if condition="$row.winRecord.exchange_code"}
+                                        <tr>
+                                            <td class="text-right"><strong>兑换码:</strong></td>
+                                            <td>
+                                                <code>{$row.winRecord.exchange_code}</code>
+                                                {if condition="$row.winRecord.code_used_time"}
+                                                    <br><small class="text-success">已使用于 {$row.winRecord.code_used_time|date="Y-m-d H:i:s",###}</small>
+                                                {else /}
+                                                    <br><small class="text-warning">未使用</small>
+                                                {/if}
+                                            </td>
+                                        </tr>
+                                        {/if}
+                                    </tbody>
+                                </table>
+                            </div>
+                            <div class="col-md-6">
+                                <table class="table table-bordered">
+                                    <tbody>
+                                        {if condition="$row.winRecord.receiver_name"}
+                                        <tr>
+                                            <td class="col-sm-4 text-right"><strong>收货人:</strong></td>
+                                            <td class="col-sm-8">{$row.winRecord.receiver_name}</td>
+                                        </tr>
+                                        {/if}
+                                        {if condition="$row.winRecord.receiver_mobile"}
+                                        <tr>
+                                            <td class="text-right"><strong>收货手机:</strong></td>
+                                            <td>{$row.winRecord.receiver_mobile}</td>
+                                        </tr>
+                                        {/if}
+                                        {if condition="$row.winRecord.receiver_address"}
+                                        <tr>
+                                            <td class="text-right"><strong>收货地址:</strong></td>
+                                            <td>{$row.winRecord.receiver_address}</td>
+                                        </tr>
+                                        {/if}
+                                        {if condition="$row.winRecord.express_company"}
+                                        <tr>
+                                            <td class="text-right"><strong>快递公司:</strong></td>
+                                            <td>{$row.winRecord.express_company}</td>
+                                        </tr>
+                                        {/if}
+                                        {if condition="$row.winRecord.express_number"}
+                                        <tr>
+                                            <td class="text-right"><strong>快递单号:</strong></td>
+                                            <td>
+                                                <code>{$row.winRecord.express_number}</code>
+                                                <a href="javascript:;" onclick="trackExpress('{$row.winRecord.express_company}', '{$row.winRecord.express_number}')" class="btn btn-xs btn-info">
+                                                    <i class="fa fa-search"></i> 查询物流
+                                                </a>
+                                            </td>
+                                        </tr>
+                                        {/if}
+                                    </tbody>
+                                </table>
+                            </div>
+                        </div>
+                        
+                        {if condition="$row.winRecord.fail_reason"}
+                        <div class="alert alert-danger">
+                            <h4><i class="icon fa fa-ban"></i> 发放失败原因</h4>
+                            {$row.winRecord.fail_reason}
+                        </div>
                         {/if}
-                        {if condition="$row.winRecord.expire_time"}
-                        <tr>
-                            <td class="text-right">过期时间:</td>
-                            <td>{$row.winRecord.expire_time|date="Y-m-d H:i:s",###}</td>
-                        </tr>
+                        
+                        {if condition="$row.winRecord.admin_remark"}
+                        <div class="alert alert-info">
+                            <h4><i class="icon fa fa-info"></i> 管理员备注</h4>
+                            {$row.winRecord.admin_remark}
+                        </div>
                         {/if}
-                    </tbody>
-                </table>
+                    </div>
+                </div>
             </div>
         </div>
         {/if}
         
-        <div class="form-group text-center">
-            <button type="button" class="btn btn-default" onclick="Layer.closeAll();">关闭</button>
+       
+        
+        <!-- 备注信息 -->
+        {if condition="$row.remark"}
+        <div class="row">
+            <div class="col-md-12">
+                <div class="alert alert-warning">
+                    <h4><i class="icon fa fa-warning"></i> 备注信息</h4>
+                    {$row.remark}
+                </div>
+            </div>
         </div>
+        {/if}
+        
+        <!-- <div class="form-group text-center">
+            <button type="button" class="btn btn-default" onclick="Layer.closeAll();">关闭</button>
+            {if condition="$row.is_win && $row.winRecord && $row.winRecord.deliver_status == 0"}
+                <button type="button" class="btn btn-warning" onclick="deliverPrize({$row.winRecord.id})">
+                    <i class="fa fa-send"></i> 发放奖品
+                </button>
+            {/if}
+        </div> -->
     </div>
-</div> 
+</div>
+

+ 210 - 131
application/admin/view/user/user/edit.html

@@ -1,146 +1,225 @@
 <form id="edit-form" class="form-horizontal" role="form" data-toggle="validator" method="POST" action="">
     {:token()}
     <input type="hidden" name="row[id]" value="{$row.id|htmlentities}">
-    <div class="form-group">
-        <label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            {$groupList}
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-username" class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-username" data-rule="required" class="form-control" name="row[username]" type="text" value="{$row.username|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-nickname" data-rule="required" class="form-control" name="row[nickname]" type="text" value="{$row.nickname|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-password" class="control-label col-xs-12 col-sm-2">{:__('Password')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-password" data-rule="password" class="form-control" name="row[password]" type="password" value="" placeholder="{:__('Leave password blank if dont want to change')}" autocomplete="new-password" />
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-email" class="control-label col-xs-12 col-sm-2">{:__('Email')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-email" data-rule="email" class="form-control" name="row[email]" type="text" value="{$row.email|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-mobile" class="control-label col-xs-12 col-sm-2">{:__('Mobile')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-mobile" data-rule="mobile" class="form-control" name="row[mobile]" type="text" value="{$row.mobile|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-avatar" class="control-label col-xs-12 col-sm-2">{:__('Avatar')}:</label>
-        <div class="col-xs-12 col-sm-8">
-            <div class="input-group">
-                <input id="c-avatar" data-rule="" class="form-control" size="50" name="row[avatar]" type="text" value="{$row.avatar|htmlentities}">
-                <div class="input-group-addon no-border no-padding">
-                    <span><button type="button" id="faupload-avatar" class="btn btn-danger faupload" data-input-id="c-avatar" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp" data-multiple="false" data-preview-id="p-avatar"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
-                    <span><button type="button" id="fachoose-avatar" class="btn btn-primary fachoose" data-input-id="c-avatar" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
+    
+    <!-- 用户基本信息 -->
+    <div class="panel panel-default">
+        <div class="panel-heading">
+            <h3 class="panel-title">基本信息</h3>
+        </div>
+        <div class="panel-body">
+            <div class="form-group">
+                <label class="control-label col-xs-12 col-sm-2">{:__('Group')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    {$groupList}
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-username" class="control-label col-xs-12 col-sm-2">{:__('Username')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-username" data-rule="required" class="form-control" name="row[username]" type="text" value="{$row.username|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-nickname" class="control-label col-xs-12 col-sm-2">{:__('Nickname')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-nickname" data-rule="required" class="form-control" name="row[nickname]" type="text" value="{$row.nickname|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-password" class="control-label col-xs-12 col-sm-2">{:__('Password')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-password" data-rule="password" class="form-control" name="row[password]" type="password" value="" placeholder="{:__('Leave password blank if dont want to change')}" autocomplete="new-password" />
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-email" class="control-label col-xs-12 col-sm-2">{:__('Email')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-email" data-rule="email" class="form-control" name="row[email]" type="text" value="{$row.email|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-mobile" class="control-label col-xs-12 col-sm-2">{:__('Mobile')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-mobile" data-rule="mobile" class="form-control" name="row[mobile]" type="text" value="{$row.mobile|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-avatar" class="control-label col-xs-12 col-sm-2">{:__('Avatar')}:</label>
+                <div class="col-xs-12 col-sm-8">
+                    <div class="input-group">
+                        <input id="c-avatar" data-rule="" class="form-control" size="50" name="row[avatar]" type="text" value="{$row.avatar|htmlentities}">
+                        <div class="input-group-addon no-border no-padding">
+                            <span><button type="button" id="faupload-avatar" class="btn btn-danger faupload" data-input-id="c-avatar" data-mimetype="image/gif,image/jpeg,image/png,image/jpg,image/bmp" data-multiple="false" data-preview-id="p-avatar"><i class="fa fa-upload"></i> {:__('Upload')}</button></span>
+                            <span><button type="button" id="fachoose-avatar" class="btn btn-primary fachoose" data-input-id="c-avatar" data-mimetype="image/*" data-multiple="false"><i class="fa fa-list"></i> {:__('Choose')}</button></span>
+                        </div>
+                        <span class="msg-box n-right" for="c-avatar"></span>
+                    </div>
+                    <ul class="row list-inline faupload-preview" id="p-avatar"></ul>
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-level" class="control-label col-xs-12 col-sm-2">{:__('Level')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-level" data-rule="required" class="form-control" name="row[level]" type="number" value="{$row.level|htmlentities}">
+                </div>
+            </div>
+                         <div class="form-group">
+                 <label class="control-label col-xs-12 col-sm-2">{:__('Gender')}:</label>
+                 <div class="col-xs-12 col-sm-8">
+                     {:build_radios('row[gender]', ['1'=>'男', '2'=>'女', '0'=>'未知'], $row['gender'])}
+                 </div>
+             </div>
+            <div class="form-group">
+                <label for="c-birthday" class="control-label col-xs-12 col-sm-2">{:__('Birthday')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-birthday" data-rule="" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-use-current="true" name="row[birthday]" type="text" value="{$row.birthday|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-bio" class="control-label col-xs-12 col-sm-2">{:__('Bio')}:</label>
+                <div class="col-xs-12 col-sm-8">
+                    <input id="c-bio" data-rule="" class="form-control" name="row[bio]" type="text" value="{$row.bio|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-money" class="control-label col-xs-12 col-sm-2">{:__('Money')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-money" data-rule="required" class="form-control" name="row[money]" type="number" value="{$row.money|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-score" class="control-label col-xs-12 col-sm-2">{:__('Score')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-score" data-rule="required" class="form-control" name="row[score]" type="number" value="{$row.score|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-successions" class="control-label col-xs-12 col-sm-2">{:__('Successions')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-successions" data-rule="required" class="form-control" name="row[successions]" type="number" value="{$row.successions|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label for="c-maxsuccessions" class="control-label col-xs-12 col-sm-2">{:__('Maxsuccessions')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <input id="c-maxsuccessions" data-rule="required" class="form-control" name="row[maxsuccessions]" type="number" value="{$row.maxsuccessions|htmlentities}">
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
+                <div class="col-xs-12 col-sm-8">
+                    {:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])}
                 </div>
-                <span class="msg-box n-right" for="c-avatar"></span>
             </div>
-            <ul class="row list-inline faupload-preview" id="p-avatar"></ul>
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-level" class="control-label col-xs-12 col-sm-2">{:__('Level')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-level" data-rule="required" class="form-control" name="row[level]" type="number" value="{$row.level|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label class="control-label col-xs-12 col-sm-2">{:__('Gender')}:</label>
-        <div class="col-xs-12 col-sm-8">
-            {:build_radios('row[gender]', ['1'=>__('Male'), '0'=>__('Female')], $row['gender'])}
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-birthday" class="control-label col-xs-12 col-sm-2">{:__('Birthday')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-birthday" data-rule="" class="form-control datetimepicker" data-date-format="YYYY-MM-DD" data-use-current="true" name="row[birthday]" type="text" value="{$row.birthday|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-bio" class="control-label col-xs-12 col-sm-2">{:__('Bio')}:</label>
-        <div class="col-xs-12 col-sm-8">
-            <input id="c-bio" data-rule="" class="form-control" name="row[bio]" type="text" value="{$row.bio|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-money" class="control-label col-xs-12 col-sm-2">{:__('Money')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-money" data-rule="required" class="form-control" name="row[money]" type="number" value="{$row.money|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-score" class="control-label col-xs-12 col-sm-2">{:__('Score')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-score" data-rule="required" class="form-control" name="row[score]" type="number" value="{$row.score|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-successions" class="control-label col-xs-12 col-sm-2">{:__('Successions')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-successions" data-rule="required" class="form-control" name="row[successions]" type="number" value="{$row.successions|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-maxsuccessions" class="control-label col-xs-12 col-sm-2">{:__('Maxsuccessions')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-maxsuccessions" data-rule="required" class="form-control" name="row[maxsuccessions]" type="number" value="{$row.maxsuccessions|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-prevtime" class="control-label col-xs-12 col-sm-2">{:__('Prevtime')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-prevtime" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[prevtime]" type="text" value="{$row.prevtime|datetime}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-logintime" class="control-label col-xs-12 col-sm-2">{:__('Logintime')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-logintime" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[logintime]" type="text" value="{$row.logintime|datetime}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-loginip" class="control-label col-xs-12 col-sm-2">{:__('Loginip')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-loginip" data-rule="required" class="form-control" name="row[loginip]" type="text" value="{$row.loginip|htmlentities}">
-        </div>
-    </div>
-    <div class="form-group">
-        <label for="c-loginfailure" class="control-label col-xs-12 col-sm-2">{:__('Loginfailure')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-loginfailure" data-rule="required" class="form-control" name="row[loginfailure]" type="number" value="{$row.loginfailure|htmlentities}">
         </div>
     </div>
-    <div class="form-group">
-        <label for="c-joinip" class="control-label col-xs-12 col-sm-2">{:__('Joinip')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-joinip" data-rule="required" class="form-control" name="row[joinip]" type="text" value="{$row.joinip|htmlentities}">
+    
+    <!-- 登录信息 (只读) -->
+    <div class="panel panel-info login-info">
+        <div class="panel-heading">
+            <h3 class="panel-title">
+                <i class="fa fa-info-circle"></i> 登录信息 (只读)
+            </h3>
         </div>
-    </div>
-    <div class="form-group">
-        <label for="c-jointime" class="control-label col-xs-12 col-sm-2">{:__('Jointime')}:</label>
-        <div class="col-xs-12 col-sm-4">
-            <input id="c-jointime" data-rule="required" class="form-control datetimepicker" data-date-format="YYYY-MM-DD HH:mm:ss" data-use-current="true" name="row[jointime]" type="text" value="{$row.jointime|datetime}">
+        <div class="panel-body">
+            <div class="form-group">
+                <label class="control-label col-xs-12 col-sm-2">{:__('Prevtime')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <p class="form-control-static text-muted">{$row.prevtime|datetime}</p>
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="control-label col-xs-12 col-sm-2">{:__('Logintime')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <p class="form-control-static text-muted">{$row.logintime|datetime}</p>
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="control-label col-xs-12 col-sm-2">{:__('Loginip')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <p class="form-control-static text-muted">{$row.loginip|htmlentities}</p>
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="control-label col-xs-12 col-sm-2">{:__('Loginfailure')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <p class="form-control-static text-muted">{$row.loginfailure|htmlentities}</p>
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="control-label col-xs-12 col-sm-2">{:__('Joinip')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <p class="form-control-static text-muted">{$row.joinip|htmlentities}</p>
+                </div>
+            </div>
+            <div class="form-group">
+                <label class="control-label col-xs-12 col-sm-2">{:__('Jointime')}:</label>
+                <div class="col-xs-12 col-sm-4">
+                    <p class="form-control-static text-muted">{$row.jointime|datetime}</p>
+                </div>
+            </div>
         </div>
     </div>
-    <div class="form-group">
-        <label class="control-label col-xs-12 col-sm-2">{:__('Status')}:</label>
-        <div class="col-xs-12 col-sm-8">
-            {:build_radios('row[status]', ['normal'=>__('Normal'), 'hidden'=>__('Hidden')], $row['status'])}
+    
+    <!-- 第三方登录信息 -->
+    <div class="panel panel-success">
+        <div class="panel-heading">
+            <h3 class="panel-title">
+                <i class="fa fa-users"></i> 第三方登录信息
+            </h3>
+        </div>
+        <div class="panel-body">
+            {if condition="$thirdList"}
+                <div class="table-responsive">
+                    <table class="table table-striped table-bordered third-info-table">
+                        <thead>
+                            <tr>
+                                <!-- <th>平台</th> -->
+                                <th>OpenID</th>
+                                <th>UnionID</th>
+                                <!-- <th>昵称</th> -->
+                                <th>登录时间</th>
+                            </tr>
+                        </thead>
+                        <tbody>
+                            {volist name="thirdList" id="third"}
+                            <tr>
+                                <!-- <td>
+                                    <span class="label label-{switch name="third.platform"}
+                                        {case value="wechat"}success{/case}
+                                        {case value="qq"}info{/case}
+                                        {case value="weibo"}warning{/case}
+                                        {default}default{/default}
+                                    {/switch} third-platform-label">
+                                        {$third.platform|ucfirst}
+                                    </span>
+                                </td> -->
+                                <td>
+                                    <small class="text-muted">{$third.openid}</small>
+                                </td>
+                                <td>
+                                    <small class="text-muted">{$third.unionid}</small>
+                                </td>
+                                <!-- <td>{$third.openname|htmlentities}</td> -->
+                                <td>
+                                    <small class="text-muted">{$third.logintime|datetime}</small>
+                                </td>
+                                
+                               
+                            </tr>
+                            {/volist}
+                        </tbody>
+                    </table>
+                </div>
+            {else/}
+                <div class="alert alert-info">
+                    <i class="fa fa-info-circle"></i> 该用户暂未绑定任何第三方账号
+                </div>
+            {/if}
         </div>
     </div>
+    
     <div class="form-group layer-footer">
         <label class="control-label col-xs-12 col-sm-2"></label>
         <div class="col-xs-12 col-sm-8">

+ 256 - 263
application/common/Enum/LotteryEnum.php

@@ -45,18 +45,8 @@ class LotteryEnum
   
       // ============ 奖品发放方式 ============
       const DELIVER_TYPE_AUTO = 1;            // 自动发放
-      const DELIVER_TYPE_MANUAL = 2;          // 手动发放
-  
-          // ============ 奖品发放状态 ============
-    const DELIVER_STATUS_PENDING = 0;       // 待发放
-    const DELIVER_STATUS_SUCCESS = 1;       // 已发放
-    const DELIVER_STATUS_FAILED = 2;        // 发放失败
-    const DELIVER_STATUS_CANCELLED = 3;     // 已取消
-
-    // ============ 抽奖状态 ============
-    const DRAW_STATUS_PARTICIPATED = 1;     // 已参与(等待开奖)
-    const DRAW_STATUS_WIN = 2;              // 已中奖
-    const DRAW_STATUS_NO_WIN = 3;           // 未中奖
+      const DELIVER_TYPE_MANUAL = 2;          // 手动发放 
+   
   
       // ============ 参与条件类型 ============
       const CONDITION_TYPE_BUY_GOODS = 1;     // 购买指定商品
@@ -85,131 +75,47 @@ class LotteryEnum
     const REDEEM_EXPIRE_FOREVER = 1;        // 永久有效
     const REDEEM_EXPIRE_FIXED = 2;          // 固定时长
   
-      /**
-       * 获取活动状态映射(页面显示用)
-       */
-      public static function getActivityStatusMap()
-      {
-          return [
-              self::STATUS_NOT_STARTED => '未开始',
-              self::STATUS_ONGOING => '进行中',
-              self::STATUS_ENDED => '已结束',
-              self::STATUS_CANCELLED => '已取消',
-              self::STATUS_SUSPENDED => '已暂停',
-          ];
-      }
-      
-      /**
-       * 获取全部活动状态映射(包含逻辑状态)
-       */
-      public static function getAllActivityStatusMap()
-      {
-          return [
-              self::STATUS_NOT_STARTED => '未开始',
-              self::STATUS_ONGOING => '进行中',
-              self::STATUS_ENDED => '已结束',
-              self::STATUS_CANCELLED => '已取消',
-              self::STATUS_SUSPENDED => '已暂停',
-              self::STATUS_CLOSED => '已关闭',
-              self::STATUS_DELETED => '已删除',
-              self::STATUS_EXPIRED => '已过期',
-          ];
-      }
-  
-      /**
-       * 获取活动类型映射
-       */
-      public static function getActivityTypeMap()
-      {
-          return [
-              self::LOTTERY_TYPE_CONSUMPTION_LOTTERY => '消费抽奖',
-          ];
-      }
-  
-      /**
-       * 获取开奖方式映射
-       */
-      public static function getLotteryTypeMap()
-      {
-          return [
-              self::LOTTERY_TYPE_INSTANT => '即抽即中',
-              self::LOTTERY_TYPE_TIME => '按时间开奖',
-              //self::LOTTERY_TYPE_PEOPLE => '按人数开奖',
-          ];
-      }
-  
-      /**
-       * 获取用户群体类型映射
-       */
-      public static function getUserLimitTypeMap()
-      {
-          return [
-              self::USER_LIMIT_ALL => '全部会员',
-            //   self::USER_LIMIT_LEVEL => '会员等级',
-            //   self::USER_LIMIT_TAG => '会员标签',
-          ];
-      }
-  
-      /**
-       * 获取引导样式映射
-       */
-      public static function getGuideStyleMap()
-      {
-          return [
-              self::GUIDE_STYLE_DEFAULT => '默认样式',
-              self::GUIDE_STYLE_CUSTOM => '自定义',
-          ];
-      }
-  
-      /**
-       * 获取奖品类型映射
-       */
-      public static function getPrizeTypeMap()
-      {
-          return [
-              self::PRIZE_TYPE_NO_PRIZE => '未中奖',
-              self::PRIZE_TYPE_GOODS => '实物奖品',
-            //   self::PRIZE_TYPE_POINTS => '积分',
-            //   self::PRIZE_TYPE_BALANCE => '余额',
-            //   self::PRIZE_TYPE_COUPON => '优惠券',
-            //   self::PRIZE_TYPE_REDPACK => '红包',
-            //   self::PRIZE_TYPE_CODE => '兑换码',
-            //   self::PRIZE_TYPE_SHOP_GOODS => '商城奖品',
-          ];
-      }
-  
-      /**
-       * 获取奖品默认图片映射
-       */
-      public static function getPrizeDefaultImageMap()
-      {
-          // 从配置文件获取图片路径
-          $config = config('site');
-          
-          return [
-              self::PRIZE_TYPE_NO_PRIZE => $config['prize_losing_lottery'] ?? '/assets/img/avatar.png',
-              self::PRIZE_TYPE_GOODS => $config['prize_goods'] ?? '/assets/img/package.png',
-              self::PRIZE_TYPE_POINTS => $config['prize_credit'] ?? '/assets/img/circle.png',
-              self::PRIZE_TYPE_BALANCE => $config['prize_balance'] ?? '/assets/img/circle.png',
-              self::PRIZE_TYPE_COUPON => $config['prize_coupon'] ?? '/assets/img/circle.png',
-              self::PRIZE_TYPE_REDPACK => $config['prize_redbag'] ?? '/assets/img/circle.png',
-              self::PRIZE_TYPE_CODE => $config['prize_code'] ?? '/assets/img/circle.png',
-              self::PRIZE_TYPE_SHOP_GOODS => $config['prize_shop_goods'] ?? '/assets/img/package.png',
-          ];
-      }
-  
-      /**
-       * 获取奖品发放方式映射
-       */
-      public static function getDeliverTypeMap()
-      {
-          return [
-              self::DELIVER_TYPE_AUTO => '自动发放',
-              self::DELIVER_TYPE_MANUAL => '手动发放',
-          ];
-      }
-  
-          /**
+
+     // ============ 参与记录相关的 ============
+     const IS_WIN_YES = 1;   //是否中奖
+     const IS_WIN_NO = 0;   //没有中奖
+
+     // ============ 奖品发放状态 ============
+    const DELIVER_STATUS_PENDING = 0;       // 待发放
+    const DELIVER_STATUS_SUCCESS = 1;       // 已发放
+    const DELIVER_STATUS_FAILED = 2;        // 发放失败
+    const DELIVER_STATUS_CANCELLED = 3;     // 已取消
+
+    // ============ 抽奖状态 ============
+    const DRAW_STATUS_PARTICIPATED = 1;     // 已参与(等待开奖)
+    const DRAW_STATUS_WIN = 2;              // 已中奖
+    const DRAW_STATUS_NO_WIN = 3;           // 未中奖
+     public static function getIsWinText($value)
+     {
+        $map = self::getIsWinMap();
+          return $map[$value] ?? '未知';
+     }
+     public static function getIsWinMap()
+     {
+        return [
+            self::IS_WIN_YES => '是',
+            self::IS_WIN_NO => '否',
+        ];
+     }
+     public static function getDrawStatusText($value)
+     {
+        $map = self::getDrawStatusMap();
+          return $map[$value] ?? '未知';
+     }
+     public static function getDrawStatusMap()
+     {
+        return [
+            self::DRAW_STATUS_PARTICIPATED => '已参与',
+            self::DRAW_STATUS_WIN => '已中奖',
+            self::DRAW_STATUS_NO_WIN => '未中奖',
+        ];
+     }
+             /**
      * 获取奖品发放状态映射
      */
     public static function getDeliverStatusMap()
@@ -221,18 +127,12 @@ class LotteryEnum
             self::DELIVER_STATUS_CANCELLED => '已取消',
         ];
     }
-
-    /**
-     * 获取抽奖状态映射
-     */
-    public static function getDrawStatusMap()
+    public static function getDeliverStatusText($value)
     {
-        return [
-            self::DRAW_STATUS_PARTICIPATED => '已参与',
-            self::DRAW_STATUS_WIN => '已中奖',
-            self::DRAW_STATUS_NO_WIN => '未中奖',
-        ];
+        $map = self::getDeliverStatusMap();
+          return $map[$value] ?? '未知';
     }
+      
     public static function getDrawStatusList()
     {
         return [
@@ -241,32 +141,8 @@ class LotteryEnum
             self::DRAW_STATUS_NO_WIN,
         ];
     }
-  
-      /**
-       * 获取参与条件类型映射
-       */
-      public static function getConditionTypeMap()
-      {
-          return [
-              self::CONDITION_TYPE_BUY_GOODS => '购买指定商品',
-              self::CONDITION_TYPE_ORDER_AMOUNT => '单笔订单消费满N元',
-              //self::CONDITION_TYPE_RECHARGE_AMOUNT => '单次充值金额满N元',
-              self::CONDITION_TYPE_TOTAL_AMOUNT => '活动期间累计消费N元',
-          ];
-      }
-  
-      /**
-       * 获取商品规则映射
-       */
-      public static function getGoodsRuleMap()
-      {
-          return [
-              self::GOODS_RULE_INCLUDE => '指定商品参与',
-              self::GOODS_RULE_EXCLUDE => '指定商品不可参与',
-          ];
-      }
-  
-          /**
+
+    /**
      * 获取触发类型映射  后台
      */
     public static function getTriggerTypeMap()
@@ -291,128 +167,245 @@ class LotteryEnum
             self::CHANCE_GET_TYPE_ADMIN_GRANT => '管理员赠送',
         ];
     }
+     /**
+     * 获取机会获取类型文本
+     */
+    public static function getChanceGetTypeText($type)
+    {
+        $map = self::getChanceGetTypeMap();
+        return $map[$type] ?? '未知';
+    }
+
   
+
+    // ============ 抽奖活动配置的· ============
+
       /**
-       * 获取兑奖期限类型映射
-       */
-      public static function getRedeemExpireTypeMap()
-      {
-          return [
-              self::REDEEM_EXPIRE_FOREVER => '永久有效',
-              self::REDEEM_EXPIRE_FIXED => '固定时长',
-          ];
-      }
-  
-      /**
-       * 获取活动状态文本
-       */
-      public static function getActivityStatusText($status)
-      {
-          $map = self::getAllActivityStatusMap();
-          return $map[$status] ?? '未知';
+     * 获取活动状态映射(页面显示用)
+     */
+    public static function getActivityStatusMap()
+    {
+        return [
+            self::STATUS_NOT_STARTED => '未开始',
+            self::STATUS_ONGOING => '进行中',
+            self::STATUS_ENDED => '已结束',
+            self::STATUS_CANCELLED => '已取消',
+            self::STATUS_SUSPENDED => '已暂停',
+        ];
+    }
+      
+    /**
+     * 获取全部活动状态映射(包含逻辑状态)
+     */
+    public static function getAllActivityStatusMap()
+    {
+        return [
+            self::STATUS_NOT_STARTED => '未开始',
+            self::STATUS_ONGOING => '进行中',
+            self::STATUS_ENDED => '已结束',
+            self::STATUS_CANCELLED => '已取消',
+            self::STATUS_SUSPENDED => '已暂停',
+            self::STATUS_CLOSED => '已关闭',
+            self::STATUS_DELETED => '已删除',
+            self::STATUS_EXPIRED => '已过期',
+        ];
       }
   
-      /**
-       * 获取奖品类型文本
-       */
-      public static function getPrizeTypeText($type)
-      {
-          $map = self::getPrizeTypeMap();
-          return $map[$type] ?? '未知';
-      }
+    /**
+     * 获取活动类型映射
+     */
+    public static function getActivityTypeMap()
+    {
+        return [
+            self::LOTTERY_TYPE_CONSUMPTION_LOTTERY => '消费抽奖',
+        ];
+    }
+
+    /**
+     * 获取开奖方式映射
+     */
+    public static function getLotteryTypeMap()
+    {
+        return [
+            self::LOTTERY_TYPE_INSTANT => '即抽即中',
+            self::LOTTERY_TYPE_TIME => '按时间开奖',
+            //self::LOTTERY_TYPE_PEOPLE => '按人数开奖',
+        ];
+    }
   
-      /**
-       * 获取开奖方式文本
-       */
-      public static function getLotteryTypeText($type)
-      {
-          $map = self::getLotteryTypeMap();
-          return $map[$type] ?? '未知';
-      }
+    /**
+     * 获取用户群体类型映射
+     */
+    public static function getUserLimitTypeMap()
+    {
+        return [
+            self::USER_LIMIT_ALL => '全部会员',
+        //   self::USER_LIMIT_LEVEL => '会员等级',
+        //   self::USER_LIMIT_TAG => '会员标签',
+        ];
+    }
   
-          /**
-     * 获取条件类型文本
+    /**
+     * 获取引导样式映射
      */
-    public static function getConditionTypeText($type)
+    public static function getGuideStyleMap()
     {
-        $map = self::getConditionTypeMap();
-        return $map[$type] ?? '未知';
+        return [
+            self::GUIDE_STYLE_DEFAULT => '默认样式',
+            self::GUIDE_STYLE_CUSTOM => '自定义',
+        ];
     }
 
-
+    /**
+     * 获取奖品类型映射
+     */
+    public static function getPrizeTypeMap()
+    {
+        return [
+            self::PRIZE_TYPE_NO_PRIZE => '未中奖',
+            self::PRIZE_TYPE_GOODS => '实物奖品',
+        //   self::PRIZE_TYPE_POINTS => '积分',
+        //   self::PRIZE_TYPE_BALANCE => '余额',
+        //   self::PRIZE_TYPE_COUPON => '优惠券',
+        //   self::PRIZE_TYPE_REDPACK => '红包',
+        //   self::PRIZE_TYPE_CODE => '兑换码',
+        //   self::PRIZE_TYPE_SHOP_GOODS => '商城奖品',
+        ];
+    }
 
     /**
-     * 获取机会获取类型文本
+     * 获取奖品默认图片映射
      */
-    public static function getChanceGetTypeText($type)
+    public static function getPrizeDefaultImageMap()
     {
-        $map = self::getChanceGetTypeMap();
-        return $map[$type] ?? '未知';
+        // 从配置文件获取图片路径
+        $config = config('site');
+        
+        return [
+            self::PRIZE_TYPE_NO_PRIZE => $config['prize_losing_lottery'] ?? '/assets/img/avatar.png',
+            self::PRIZE_TYPE_GOODS => $config['prize_goods'] ?? '/assets/img/package.png',
+            self::PRIZE_TYPE_POINTS => $config['prize_credit'] ?? '/assets/img/circle.png',
+            self::PRIZE_TYPE_BALANCE => $config['prize_balance'] ?? '/assets/img/circle.png',
+            self::PRIZE_TYPE_COUPON => $config['prize_coupon'] ?? '/assets/img/circle.png',
+            self::PRIZE_TYPE_REDPACK => $config['prize_redbag'] ?? '/assets/img/circle.png',
+            self::PRIZE_TYPE_CODE => $config['prize_code'] ?? '/assets/img/circle.png',
+            self::PRIZE_TYPE_SHOP_GOODS => $config['prize_shop_goods'] ?? '/assets/img/package.png',
+        ];
     }
 
     /**
-     * 获取抽奖状态文本
+     * 获取奖品发放方式映射
      */
-    public static function getDrawStatusText($status)
+    public static function getDeliverTypeMap()
     {
-        $map = self::getDrawStatusMap();
-        return $map[$status] ?? '未知';
+        return [
+            self::DELIVER_TYPE_AUTO => '自动发放',
+            self::DELIVER_TYPE_MANUAL => '手动发放',
+        ];
+    }  
+    /**
+     * 获取参与条件类型映射
+     */
+    public static function getConditionTypeMap()
+    {
+        return [
+            self::CONDITION_TYPE_BUY_GOODS => '购买指定商品',
+            self::CONDITION_TYPE_ORDER_AMOUNT => '单笔订单消费满N元',
+            //self::CONDITION_TYPE_RECHARGE_AMOUNT => '单次充值金额满N元',
+            self::CONDITION_TYPE_TOTAL_AMOUNT => '活动期间累计消费N元',
+        ];
     }
   
-      /**
-       * 验证活动状态是否有效(包含所有状态)
-       */
-      public static function isValidActivityStatus($status)
-      {
-          return array_key_exists($status, self::getAllActivityStatusMap());
-      }
+    /**
+     * 获取商品规则映射
+     */
+    public static function getGoodsRuleMap()
+    {
+        return [
+            self::GOODS_RULE_INCLUDE => '指定商品参与',
+            self::GOODS_RULE_EXCLUDE => '指定商品不可参与',
+        ];
+    }
   
-      /**
-       * 判断是否为可在页面显示的状态
-       */
-      public static function isDisplayableStatus($status)
-      {
-          return array_key_exists($status, self::getActivityStatusMap());
-      }
+    /**
+     * 获取兑奖期限类型映射
+     */
+    public static function getRedeemExpireTypeMap()
+    {
+        return [
+            self::REDEEM_EXPIRE_FOREVER => '永久有效',
+            self::REDEEM_EXPIRE_FIXED => '固定时长',
+        ];
+    }
   
-      /**
-       * 判断是否为逻辑状态(不在页面显示)
-       */
-      public static function isLogicalStatus($status)
-      {
-          return in_array($status, [
-              self::STATUS_CLOSED,
-              self::STATUS_DELETED,
-              self::STATUS_EXPIRED
-          ]);
-      }
+    /**
+     * 获取活动状态文本
+     */
+    public static function getActivityStatusText($status)
+    {
+        $map = self::getAllActivityStatusMap();
+        return $map[$status] ?? '未知';
+    }
   
-      /**
-       * 验证奖品类型是否有效
-       */
-      public static function isValidPrizeType($type)
-      {
-          return array_key_exists($type, self::getPrizeTypeMap());
-      }
+    /**
+     * 获取奖品类型文本
+     */
+    public static function getPrizeTypeText($type)
+    {
+        $map = self::getPrizeTypeMap();
+        return $map[$type] ?? '未知';
+    }
+
+    /**
+     * 获取开奖方式文本
+     */
+    public static function getLotteryTypeText($type)
+    {
+        $map = self::getLotteryTypeMap();
+        return $map[$type] ?? '未知';
+    }
   
-      /**
-       * 验证开奖方式是否有效
-       */
-      public static function isValidLotteryType($type)
-      {
-          return array_key_exists($type, self::getLotteryTypeMap());
-      }
+    /**
+     * 获取条件类型文本
+     */
+    public static function getConditionTypeText($type)
+    {
+        $map = self::getConditionTypeMap();
+        return $map[$type] ?? '未知';
+    }   
+
+    /**
+     * 验证活动状态是否有效(包含所有状态)
+     */
+    public static function isValidActivityStatus($status)
+    {
+        return array_key_exists($status, self::getAllActivityStatusMap());
+    }
+
+  
+    /**
+     * 验证奖品类型是否有效
+     */
+    public static function isValidPrizeType($type)
+    {
+        return array_key_exists($type, self::getPrizeTypeMap());
+    }
   
-          /**
+    /**
+     * 验证开奖方式是否有效
+     */
+    public static function isValidLotteryType($type)
+    {
+        return array_key_exists($type, self::getLotteryTypeMap());
+    }
+  
+    /**
      * 验证条件类型是否有效
      */
     public static function isValidConditionType($type)
     {
         return array_key_exists($type, self::getConditionTypeMap());
     }
-
-
-
     /**
      * 验证机会获取类型是否有效
      */

+ 22 - 0
application/common/Enum/ThirdOauthEnum.php

@@ -0,0 +1,22 @@
+<?php
+namespace app\common\Enum;
+
+
+/**
+ * 全局状态枚举  provider 提供商 、 platform
+ */
+class ThirdOauthEnum
+{
+    const PROVIDER_WECHAT = 'wechat';
+    const PROVIDER_QQ = 'qq';
+    const PROVIDER_WEIBO = 'weibo';
+
+    public static function getMap()
+    {
+        return [
+            self::PROVIDER_WECHAT => '微信',
+            self::PROVIDER_QQ => 'QQ',
+            self::PROVIDER_WEIBO => '微博',
+        ];
+    }
+}

+ 309 - 103
public/assets/js/backend/lottery/draw_record.js

@@ -5,175 +5,381 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             // 初始化表格参数
             Table.api.init({
                 extend: {
-                    index_url: 'lottery/drawrecord/index' + location.search,
-                    detail_url: 'lottery/drawrecord/detail',
-                    del_url: 'lottery/drawrecord/del',
-                    multi_url: 'lottery/drawrecord/multi',
-                    export_url: 'lottery/drawrecord/export',
+                    index_url: 'lottery/draw_record/index' + location.search,
+                    detail_url: 'lottery/draw_record/detail',
+                    del_url: 'lottery/draw_record/del',
+                    multi_url: 'lottery/draw_record/multi',
+                    export_url: 'lottery/draw_record/export',
+                    statistics_url: 'lottery/draw_record/statistics',
+                    batch_deliver_url: 'lottery/draw_record/batchDeliver',
                     table: 'shop_lottery_draw_record',
                 }
             });
 
             var table = $("#table");
 
-            // 初始化表格
+            // 初始化全部记录表格
             table.bootstrapTable({
                 url: $.fn.bootstrapTable.defaults.extend.index_url,
                 pk: 'id',
-                sortName: 'id',
+                sortName: 'createtime',
                 sortOrder: 'desc',
                 fixedColumns: true,
                 fixedRightNumber: 1,
                 columns: [
                     [
                         {checkbox: true},
-                        {field: 'id', title: __('ID'), operate: false, sortable: true},
+                        {field: 'id', title: 'ID', operate: false, sortable: true},
                         {
                             field: 'activity.name', 
-                            title: __('活动名称'), 
+                            title: '活动名称', 
                             operate: 'LIKE',
-                            formatter: function(value, row, index) {
-                                return row.activity ? row.activity.name : '-';
+                            formatter: function(value, row) {
+                                if (row.activity && row.activity.name) {
+                                    return '<a href="javascript:;" onclick="Fast.api.open(\'lottery/activity/detail?ids=' + row.activity.id + '\', \'活动详情\')">' + row.activity.name + '</a>';
+                                }
+                                return '-';
                             }
                         },
                         {
-                            field: 'user.nickname', 
-                            title: __('用户昵称'), 
+                            field: 'user.username', 
+                            title: '用户信息', 
                             operate: 'LIKE',
-                            formatter: function(value, row, index) {
-                                return row.user ? row.user.nickname : '-';
+                            formatter: function (value, row, index) {
+                                // 显示用户头像和用户名
+                                var avatar = row.user && row.user.avatar ? row.user.avatar : '/assets/img/avatar.png';
+                                var username = row.user && row.user.username ? row.user.username : '游客';
+                                var userId = row.user_id || '';
+                                
+                                // 处理头像URL
+                                var avatarUrl = avatar;
+                                if (avatar && !avatar.startsWith('http') && !avatar.startsWith('//')) {
+                                    avatarUrl = Fast.api.cdnurl ? Fast.api.cdnurl(avatar) : avatar;
+                                }
+                                
+                                return '<div style="display:flex;align-items:center;">' + 
+                                       '<img src="' + avatarUrl + '" style="width:40px;height:40px;border-radius:50%;margin-right:10px;" />' +
+                                       '<div>' +
+                                       '<div style="color:#337ab7;font-weight:bold;">' + username + '</div>' +
+                                       '<div style="color:#999;font-size:12px;">ID: ' + userId + '</div>' +
+                                       '</div>' +
+                                       '</div>';
                             }
                         },
                         {
                             field: 'prize.name', 
-                            title: __('奖品名称'), 
+                            title: '奖品名称', 
                             operate: 'LIKE',
-                            formatter: function(value, row, index) {
-                                return row.prize ? row.prize.name : '-';
-                            }
-                        },
-                        {
-                            field: 'prize.type', 
-                            title: __('奖品类型'), 
-                            searchList: {
-                                "1": "未中奖",
-                                "2": "实物奖品", 
-                                "3": "积分",
-                                "4": "余额",
-                                "5": "优惠券",
-                                "6": "红包",
-                                "7": "兑换码",
-                                "8": "商城奖品"
-                            },
-                            formatter: function(value, row, index) {
-                                if (!row.prize) return '-';
-                                var typeMap = {
-                                    1: '未中奖',
-                                    2: '实物奖品',
-                                    3: '积分',
-                                    4: '余额',
-                                    5: '优惠券',
-                                    6: '红包',
-                                    7: '兑换码',
-                                    8: '商城奖品'
-                                };
-                                return typeMap[row.prize.type] || '未知';
+                            formatter: function(value, row) {
+                                if (row.prize && row.prize.name) {
+                                    var typeClass = Controller.api.getPrizeTypeClass(row.prize.type);
+                                    var typeName = Controller.api.getPrizeTypeName(row.prize.type);
+                                    return row.prize.name + '<br><span class="label label-' + typeClass + '">' + typeName + '</span>';
+                                }
+                                return '-';
                             }
                         },
                         {
                             field: 'is_win', 
-                            title: __('是否中奖'), 
-                            searchList: {"0": "否", "1": "是"}, 
-                            formatter: Table.api.formatter.toggle,
-                            operate: false
+                            title: '是否中奖', 
+                            searchList: Controller.api.parseConfigJson('isWinList'), 
+                            formatter: function(value, row) {
+                                return value == 1 ? 
+                                    '<span class="label label-success"><i class="fa fa-check"></i> 中奖</span>' : 
+                                    '<span class="label label-default"><i class="fa fa-times"></i> 未中奖</span>';
+                            }
                         },
                         {
                             field: 'trigger_type', 
-                            title: __('触发类型'), 
-                            searchList: {
-                                "1": "购买指定商品",
-                                "2": "单笔订单消费满额",
-                                "3": "单次充值满额",
-                                "4": "活动期间累计消费满额"
-                            },
-                            formatter: function(value, row, index) {
-                                var typeMap = {
-                                    1: '购买指定商品',
-                                    2: '单笔订单消费满额', 
-                                    3: '单次充值满额',
-                                    4: '活动期间累计消费满额'
-                                };
-                                return typeMap[value] || '-';
+                            title: '触发类型', 
+                            searchList: Controller.api.parseConfigJson('triggerTypeList'),
+                            formatter: function(value, row) {
+                                var typeMap = Controller.api.parseConfigJson('triggerTypeList');
+                                var type = typeMap[value] || {text: '未知', class: 'default'};
+                                return '<span class="label label-' + type.class + '">' + type.text + '</span>';
                             }
                         },
                         {
                             field: 'trigger_amount', 
-                            title: __('触发金额'), 
+                            title: '触发金额', 
                             operate: 'BETWEEN',
-                            formatter: function(value, row, index) {
-                                return value ? '¥' + parseFloat(value).toFixed(2) : '-';
+                            formatter: function(value, row) {
+                                return value ? '<span class="text-success">¥' + parseFloat(value).toFixed(2) + '</span>' : '-';
                             }
                         },
                         {
-                            field: 'draw_time', 
-                            title: __('抽奖时间'), 
-                            operate: 'RANGE', 
-                            addclass: 'datetimerange', 
-                            autocomplete: false, 
-                            formatter: Table.api.formatter.datetime
+                            field: 'status', 
+                            title: '状态', 
+                            searchList: Controller.api.parseConfigJson('statusList'), 
+                            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>';
+                            }
                         },
                         {
-                            field: 'createtime', 
-                            title: __('创建时间'), 
-                            operate: 'RANGE', 
-                            addclass: 'datetimerange', 
-                            autocomplete: false, 
-                            formatter: Table.api.formatter.datetime
+                            field: 'winRecord.deliver_status', 
+                            title: '发放状态', 
+                            searchList: Controller.api.parseConfigJson('deliverStatusList'), 
+                            formatter: function(value, row) {
+                                if (!row.is_win || !row.winRecord) return '-';
+                                var statusMap = Controller.api.parseConfigJson('deliverStatusList');
+                                var status = statusMap[value] || {text: '未知', class: 'default'};
+                                return '<span class="label label-' + status.class + '">' + status.text + '</span>';
+                            },
+                            operate: false
                         },
+                        {field: 'draw_time', title: '抽奖时间', operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
+                        {field: 'createtime', title: '创建时间', operate:'RANGE', addclass:'datetimerange', autocomplete:false, formatter: Table.api.formatter.datetime},
                         {
                             field: 'operate', 
                             title: __('Operate'), 
                             table: table, 
-                            events: Table.api.events.operate, 
-                            formatter: Table.api.formatter.operate,
+                            events: Table.api.events.operate,
                             buttons: [
                                 {
                                     name: 'detail',
-                                    title: __('详情'),
-                                    classname: 'btn btn-xs btn-primary btn-dialog',
-                                    icon: 'fa fa-eye',
+                                    title: '查看详情',
+                                    classname: 'btn btn-xs btn-info btn-dialog',
+                                    icon: 'fa fa-list',
                                     url: 'lottery/drawrecord/detail'
                                 }
-                            ]
+                            ],
+                            formatter: Table.api.formatter.operate
                         }
                     ]
                 ]
             });
 
+  
+
             // 为表格绑定事件
             Table.api.bindevent(table);
+
             
-            // 导出功能
-            $(document).on('click', '.btn-export', function() {
-                var options = table.bootstrapTable('getOptions');
-                var url = options.extend.export_url;
-                var filter = options.queryParams ? options.queryParams({}) : {};
-                
-                // 构建导出URL
-                var exportUrl = url + '?filter=' + encodeURIComponent(JSON.stringify(filter));
-                
-                // 打开导出链接
-                window.open(exportUrl);
-            });
-        },
-        
-        detail: function () {
-            // 详情页面不需要特殊处理
+            // 绑定自定义事件
+            Controller.api.bindevent();
+            
+            // // 初始化统计数据
+            // Controller.api.loadStatistics();
         },
         
         api: {
+
+             // 解析Config中的JSON字符串的辅助函数
+             parseConfigJson: function(configKey, defaultValue) {
+                var configValue = Config[configKey] || defaultValue || {};
+                
+                // 如果是字符串,尝试解析JSON
+                if (typeof configValue === 'string') {
+                    try {
+                        return JSON.parse(configValue);
+                    } catch (e) {
+                        return defaultValue || {};
+                    }
+                }
+                
+                return configValue;
+            },
             bindevent: function () {
-                Form.api.bindevent($("form[role=form]"));
+                // 统计按钮
+                // $(document).on('click', '.btn-statistics', function() {
+                //     $('a[href="#t-statistics"]').tab('show');
+                //     Controller.api.loadStatistics();
+                // });
+                
+                // // 刷新统计
+                // $(document).on('click', '#refresh-stats', function() {
+                //     Controller.api.loadStatistics();
+                // });
+                
+                // // 批量发放
+                // $(document).on('click', '.btn-batch-deliver, .btn-batch-deliver-win', function() {
+                //     var table = $(this).hasClass('btn-batch-deliver-win') ? $("#table-win") : $("#table");
+                //     var ids = Table.api.selectedids(table);
+                //     if (ids.length === 0) {
+                //         Toastr.error('请选择要处理的记录');
+                //         return;
+                //     }
+                    
+                //     Layer.confirm('确定要批量发放选中的奖品吗?', function(index) {
+                //         Fast.api.ajax({
+                //             url: 'lottery/drawrecord/batchDeliver',
+                //             data: {ids: ids}
+                //         }, function(data, ret) {
+                //             Layer.msg(ret.msg);
+                //             table.bootstrapTable('refresh');
+                //             Layer.close(index);
+                //         });
+                //     });
+                // });
+                
+                // 导出中奖记录
+                $(document).on('click', '.btn-export-win', function() {
+                    var filter = JSON.stringify({is_win: 1});
+                    window.open(Fast.api.fixurl('lottery/drawrecord/export') + '?filter=' + encodeURIComponent(filter));
+                });
+                
+                // 刷新中奖记录表格
+                $(document).on('click', '.btn-refresh-win', function() {
+                    $("#table-win").bootstrapTable('refresh');
+                });
+                
+                // Tab切换事件
+                $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
+                    var target = $(e.target).attr("href");
+                    if (target === '#t-statistics') {
+                        Controller.api.loadStatistics();
+                    }
+                });
+            },
+            
+            // 加载统计数据
+            // loadStatistics: function() {
+            //     Fast.api.ajax({
+            //         url: 'lottery/drawrecord/statistics'
+            //     }, function(data, ret) {
+            //         if (ret.code === 1) {
+            //             Controller.api.renderStatistics(data);
+            //         }
+            //     });
+            // },
+            
+            // 渲染统计数据
+            // renderStatistics: function(data) {
+            //     // 更新概览数据
+            //     $('#total-draws').text(data.total_draws || 0);
+            //     $('#total-wins').text(data.total_wins || 0);
+            //     $('#win-rate').text((data.win_rate || 0) + '%');
+                
+            //     // 计算今日抽奖
+            //     var today = new Date().toISOString().substr(0, 10);
+            //     var todayData = data.recent_trend.find(function(item) {
+            //         return item.date === today;
+            //     });
+            //     $('#today-draws').text(todayData ? todayData.draws : 0);
+                
+            //     // 渲染图表
+            //     Controller.api.renderCharts(data);
+            // },
+            
+            // 渲染图表
+            // renderCharts: function(data) {
+            //     // 触发类型统计图表
+            //     if (data.by_trigger_type && data.by_trigger_type.length > 0) {
+            //         Controller.api.renderTriggerTypeChart(data.by_trigger_type);
+            //     }
+                
+            //     // 趋势图表
+            //     if (data.recent_trend && data.recent_trend.length > 0) {
+            //         Controller.api.renderTrendChart(data.recent_trend);
+            //     }
+            // },
+            
+            // // 渲染触发类型图表
+            // renderTriggerTypeChart: function(data) {
+            //     var ctx = document.getElementById('trigger-type-chart');
+            //     if (!ctx) return;
+                
+            //     var typeMap = {
+            //         1: '购买商品',
+            //         2: '订单消费',
+            //         3: '充值',
+            //         4: '累计消费'
+            //     };
+                
+            //     var labels = data.map(function(item) {
+            //         return typeMap[item.trigger_type] || '未知';
+            //     });
+            //     var counts = data.map(function(item) {
+            //         return item.count;
+            //     });
+                
+            //     new Chart(ctx, {
+            //         type: 'doughnut',
+            //         data: {
+            //             labels: labels,
+            //             datasets: [{
+            //                 data: counts,
+            //                 backgroundColor: [
+            //                     '#3c8dbc',
+            //                     '#00a65a',
+            //                     '#f39c12',
+            //                     '#d2d6de'
+            //                 ]
+            //             }]
+            //         },
+            //         options: {
+            //             responsive: true,
+            //             maintainAspectRatio: false
+            //         }
+            //     });
+            // },
+            
+            // // 渲染趋势图表
+            // renderTrendChart: function(data) {
+            //     var ctx = document.getElementById('trend-chart');
+            //     if (!ctx) return;
+                
+            //     var labels = data.map(function(item) {
+            //         return item.date.substr(5); // 只显示月-日
+            //     });
+            //     var draws = data.map(function(item) {
+            //         return item.draws;
+            //     });
+            //     var wins = data.map(function(item) {
+            //         return item.wins;
+            //     });
+                
+            //     new Chart(ctx, {
+            //         type: 'line',
+            //         data: {
+            //             labels: labels,
+            //             datasets: [{
+            //                 label: '抽奖次数',
+            //                 data: draws,
+            //                 borderColor: '#3c8dbc',
+            //                 backgroundColor: 'rgba(60, 141, 188, 0.1)',
+            //                 tension: 0.4
+            //             }, {
+            //                 label: '中奖次数',
+            //                 data: wins,
+            //                 borderColor: '#00a65a',
+            //                 backgroundColor: 'rgba(0, 166, 90, 0.1)',
+            //                 tension: 0.4
+            //             }]
+            //         },
+            //         options: {
+            //             responsive: true,
+            //             maintainAspectRatio: false,
+            //             scales: {
+            //                 y: {
+            //                     beginAtZero: true
+            //                 }
+            //             }
+            //         }
+            //     });
+            // },
+            
+           // 获取奖品类型名称
+            getPrizeTypeName: function(type) {
+                var typeMap =   Controller.api.parseConfigJson('prizeTypeList');
+                return typeMap[type] || '未知';
+            },
+            
+            // 获取奖品类型样式类
+            getPrizeTypeClass: function(type) {
+                var classMap = {
+                    1: 'default',
+                    2: 'primary',
+                    3: 'warning',
+                    4: 'info',
+                    5: 'success',
+                    6: 'danger',
+                    7: 'default',
+                    8: 'primary'
+                };
+                return classMap[type] || 'default';
             }
         }
     };

+ 125 - 13
public/assets/js/backend/user/user.js

@@ -28,21 +28,46 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                         {checkbox: true},
                         {field: 'id', title: __('Id'), sortable: true},
                         {field: 'group.name', title: __('Group')},
-                        {field: 'username', title: __('Username'), operate: 'LIKE'},
-                        {field: 'nickname', title: __('Nickname'), operate: 'LIKE'},
+                        // {field: 'username', title: __('Username'), operate: 'LIKE'},
+                        {
+                            field: 'user.username', 
+                            title: '用户信息', 
+                            operate: 'LIKE',
+                            formatter: function (value, row, index) {
+                                // 显示用户头像和用户名
+                                var avatar = row && row.avatar ? row.avatar : '/assets/img/avatar.png';
+                                var username = row && row.username ? row.username : '游客';
+                                var userId = row.id || '';
+                                
+                                // 处理头像URL
+                                var avatarUrl = avatar;
+                                if (avatar && !avatar.startsWith('http') && !avatar.startsWith('//')) {
+                                    avatarUrl = Fast.api.cdnurl ? Fast.api.cdnurl(avatar) : avatar;
+                                }
+                                
+                                return '<div style="display:flex;align-items:center;">' + 
+                                       '<img src="' + avatarUrl + '" style="width:40px;height:40px;border-radius:50%;margin-right:10px;" />' +
+                                       '<div>' +
+                                       '<div style="color:#337ab7;font-weight:bold;">' + username + '</div>' +
+                                       '<div style="color:#999;font-size:12px;">ID: ' + userId + '</div>' +
+                                       '</div>' +
+                                       '</div>';
+                            }
+                        },
+                        // {field: 'nickname', title: __('Nickname'), operate: 'LIKE'},
                         {field: 'email', title: __('Email'), operate: 'LIKE'},
                         {field: 'mobile', title: __('Mobile'), operate: 'LIKE'},
-                        {field: 'avatar', title: __('Avatar'), events: Table.api.events.image, formatter: Table.api.formatter.image, operate: false},
-                        {field: 'level', title: __('Level'), operate: 'BETWEEN', sortable: true},
-                        {field: 'gender', title: __('Gender'), visible: false, searchList: {1: __('Male'), 0: __('Female')}},
-                        {field: 'score', title: __('Score'), operate: 'BETWEEN', sortable: true},
-                        {field: 'successions', title: __('Successions'), visible: false, operate: 'BETWEEN', sortable: true},
-                        {field: 'maxsuccessions', title: __('Maxsuccessions'), visible: false, operate: 'BETWEEN', sortable: true},
-                        {field: 'logintime', title: __('Logintime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
-                        {field: 'loginip', title: __('Loginip'), formatter: Table.api.formatter.search},
-                        {field: 'jointime', title: __('Jointime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
-                        {field: 'joinip', title: __('Joinip'), formatter: Table.api.formatter.search},
-                        {field: 'status', title: __('Status'), formatter: Table.api.formatter.status, searchList: {normal: __('Normal'), hidden: __('Hidden')}},
+                        // {field: 'avatar', title: __('Avatar'), events: Table.api.events.image, formatter: Table.api.formatter.image, operate: false},
+                       //{field: 'level', title: __('Level'), operate: 'BETWEEN', sortable: true},
+                        {field: 'gender', title: __('Gender'), visible: false, searchList: Controller.api.parseConfigJson('genderList')},
+                        // {field: 'score', title: __('Score'), operate: 'BETWEEN', sortable: true},
+                        // {field: 'successions', title: __('Successions'), visible: false, operate: 'BETWEEN', sortable: true},
+                        // {field: 'maxsuccessions', title: __('Maxsuccessions'), visible: false, operate: 'BETWEEN', sortable: true},
+                        // {field: 'logintime', title: __('Logintime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
+                        // {field: 'loginip', title: __('Loginip'), formatter: Table.api.formatter.search},
+                        // {field: 'jointime', title: __('Jointime'), formatter: Table.api.formatter.datetime, operate: 'RANGE', addclass: 'datetimerange', sortable: true},
+                        // {field: 'joinip', title: __('Joinip'), formatter: Table.api.formatter.search},
+                        {field: 'status', title: __('Status'), formatter: Table.api.formatter.status, searchList: Controller.api.parseConfigJson('statusList')},
                         {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, formatter: Table.api.formatter.operate}
                     ]
                 ]
@@ -55,9 +80,96 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             Controller.api.bindevent();
         },
         edit: function () {
+            // 为第三方信息卡片添加样式
+            $(document).ready(function(){
+                // 添加第三方信息卡片样式
+                $('.third-info-card').each(function(){
+                    $(this).hover(
+                        function(){
+                            $(this).css({
+                                'box-shadow': '0 4px 8px rgba(0,0,0,0.1)',
+                                'transform': 'translateY(-2px)',
+                                'transition': 'all 0.3s ease'
+                            });
+                        },
+                        function(){
+                            $(this).css({
+                                'box-shadow': '0 1px 3px rgba(0,0,0,0.1)',
+                                'transform': 'translateY(0)',
+                                'transition': 'all 0.3s ease'
+                            });
+                        }
+                    );
+                });
+                
+                // 为登录信息面板添加样式
+                $('.login-info .form-control-static').each(function(){
+                    $(this).css({
+                        'background-color': '#f8f9fa',
+                        'padding': '8px 12px',
+                        'border-radius': '4px',
+                        'border': '1px solid #e9ecef',
+                        'margin': '0'
+                    });
+                });
+                
+                // 为第三方平台标签添加图标
+                $('.third-platform-label').each(function(){
+                    var platform = $(this).text().toLowerCase().trim();
+                    var icon = '';
+                    switch(platform) {
+                        case 'wechat':
+                            icon = '<i class="fa fa-wechat"></i> ';
+                            break;
+                        case 'qq':
+                            icon = '<i class="fa fa-qq"></i> ';
+                            break;
+                        case 'weibo':
+                            icon = '<i class="fa fa-weibo"></i> ';
+                            break;
+                        default:
+                            icon = '<i class="fa fa-link"></i> ';
+                    }
+                    $(this).html(icon + $(this).text());
+                });
+                
+                // 为第三方信息卡片添加响应式处理
+                function adjustThirdInfoCards() {
+                    if ($(window).width() < 768) {
+                        $('.third-info-card').parent().removeClass('col-md-6').addClass('col-md-12');
+                    } else {
+                        $('.third-info-card').parent().removeClass('col-md-12').addClass('col-md-6');
+                    }
+                }
+                
+                // 初始调整
+                adjustThirdInfoCards();
+                
+                // 窗口大小改变时调整
+                $(window).resize(function() {
+                    adjustThirdInfoCards();
+                });
+            });
+            
             Controller.api.bindevent();
         },
         api: {
+             // 解析Config中的JSON字符串的辅助函数
+             parseConfigJson: function(configKey, defaultValue) {
+                var configValue = Config[configKey] || defaultValue || {};
+                
+                // 如果是字符串,尝试解析JSON
+                if (typeof configValue === 'string') {
+                    try {
+                        return JSON.parse(configValue);
+                    } catch (e) {
+                        return defaultValue || {};
+                    }
+                }
+                
+                return configValue;
+            },
+            
             bindevent: function () {
                 Form.api.bindevent($("form[role=form]"));
             }