Browse Source

fix:分销订单

super-yimizi 1 day ago
parent
commit
3b334f2477

+ 1 - 1
addons/betterform/config.php

@@ -65,7 +65,7 @@ return [
         'title' => '弹窗宽高',
         'title' => '弹窗宽高',
         'type' => 'string',
         'type' => 'string',
         'content' => [],
         'content' => [],
-        'value' => '["90%", "90%"]',
+        'value' => '["100%", "100%"]',
         'rule' => 'required',
         'rule' => 'required',
         'msg' => '',
         'msg' => '',
         'tip' => '',
         'tip' => '',

+ 27 - 0
application/admin/controller/commission/Log.php

@@ -26,6 +26,32 @@ class Log extends Backend
     {
     {
         parent::_initialize();
         parent::_initialize();
         $this->model = new LogModel();
         $this->model = new LogModel();
+        
+        // 配置代理商和操作人信息展示
+        $this->assignconfig('commission_log_event_types', [
+            'agent' => __('分销商日志'),
+            'level' => __('等级变动日志'),
+            'order' => __('分销业绩'),
+            'team' => __('团队日志'),
+            'reward' => __('佣金日志'),
+            'share' => __('分享日志'),
+            'bind' => __('绑定日志')
+        ]);
+        
+        $this->assignconfig('commission_log_oper_types', [
+            'admin' => __('管理员'),
+            'system' => __('系统'),
+            'user' => __('用户')
+        ]);
+        
+        $this->assignconfig('commission_log_user_display_config', [
+            'showAvatar' => true,
+            'avatarSize' => 40,
+            'showMobile' => true,
+            'showId' => true,
+            'systemAvatarUrl' => '/assets/img/system-avatar.png',
+            'defaultAvatarUrl' => '/assets/img/avatar.png'
+        ]);
     }
     }
 
 
 
 
@@ -69,4 +95,5 @@ class Log extends Backend
         $result = ['total' => $logsArray['total'], 'rows' => $logsArray['data']];
         $result = ['total' => $logsArray['total'], 'rows' => $logsArray['data']];
         return json($result);
         return json($result);
     }
     }
+
 }
 }

+ 33 - 136
application/admin/controller/commission/Order.php

@@ -27,6 +27,29 @@ class Order extends Backend
     {
     {
         parent::_initialize();
         parent::_initialize();
         $this->model = new OrderModel();
         $this->model = new OrderModel();
+        
+        // 配置订单和用户信息展示
+        $this->assignconfig('commission_order_status_types', [
+            '-2' => __('已扣除'),
+            '-1' => __('已取消'),
+            '0' => __('不计入'),
+            '1' => __('已计入')
+        ]);
+        
+        $this->assignconfig('commission_reward_status_types', [
+            '-2' => __('已退回'),
+            '-1' => __('已取消'),
+            '0' => __('未结算'),
+            '1' => __('已结算')
+        ]);
+        
+        $this->assignconfig('commission_order_user_display_config', [
+            'showAvatar' => true,
+            'avatarSize' => 40,
+            'showMobile' => true,
+            'showId' => true,
+            'defaultAvatarUrl' => '/assets/img/avatar.png'
+        ]);
     }
     }
 
 
     /**
     /**
@@ -35,8 +58,6 @@ class Order extends Backend
     public function index()
     public function index()
     {
     {
         if (!$this->request->isAjax()) {
         if (!$this->request->isAjax()) {
-            $exportConfig = (new \addons\shopro\library\Export())->getConfig();
-            $this->assignconfig("save_type", $exportConfig['save_type'] ?? 'download');
             return $this->view->fetch();
             return $this->view->fetch();
         }
         }
 
 
@@ -203,146 +224,22 @@ class Order extends Backend
 
 
 
 
 
 
+    /**
+     * 导出(需要根据实际Export类来实现)
+     */
     public function export()
     public function export()
     {
     {
-        $cellTitles = [
-            // 主要字段
-            'commission_order_id' => 'Id',
-            'order_sn' => '订单号',
-            'goods_title' => '商品名称',
-            'goods_sku_text' => '商品规格',
-            'goods_price' => '商品价格',
-            'goods_num' => '购买数量',
-            'refund_status_text' => '退款状态',
-            'buyer_nickname' => '下单用户',
-            'buyer_mobile' => '手机号',
-            'share_nickname' => '推广分销商',
-            'share_mobile' => '手机号',
-            'commission_reward_status_text' => '佣金状态',
-            'reward_event_text' => '结算方式',
-            'commission_time' => '结算时间',
-            'reward_type_text' => '商品结算方式',
-            'amount' => '商品结算金额',
-            'commission_order_status_text' => '分销商业绩',
-            'total_commission' => '分销总金额',
-            'total_commissioned' => '到账金额',
-            // 佣金明细
-            'reward_agent_nickname' => '分佣用户',
-            'reward_agent_mobile' => '分佣手机号',
-            'reward_commission' => '分佣金额',
-            'reward_status_text' => '分佣状态',
-            'reward_type_text' => '入账方式',
-            'reward_commission_time' => '结算时间',
-        ];
-
+        // 获取查询条件
+        [$where] = $this->buildparams();
+        
         // 数据总条数
         // 数据总条数
-        $total = $this->model->sheepFilter()->count();
+        $total = $this->model->where($where)->count();
         if ($total <= 0) {
         if ($total <= 0) {
             $this->error('导出数据为空');
             $this->error('导出数据为空');
         }
         }
 
 
-        $export = new \addons\shopro\library\Export();
-        $params = [
-            'file_name' => '分销订单列表',
-            'cell_titles' => $cellTitles,
-            'total' => $total,
-            'is_sub_cell' => true,
-            'sub_start_cell' => 'reward_agent_nickname',
-            'sub_field' => 'rewards'
-        ];
-
-        $total_amount = 0;
-        $total_commission = 0;
-        $total_commission_cancel = 0;
-        $total_commission_accounted = 0;
-        $total_commission_back = 0;
-        $total_commission_pending = 0;
-        $result = $export->export($params, function ($pages) use (&$total_amount, &$total_commission, &$total_commission_cancel, &$total_commission_accounted, &$total_commission_back, &$total_commission_pending, $total) {
-            $datas = $this->model->sheepFilter()->with(['buyer', 'agent', 'order', 'rewards.agent', 'order_item'])
-                ->limit((($pages['page'] - 1) * $pages['list_rows']), $pages['list_rows'])
-                ->select();
-
-            $datas = collection($datas);
-            $datas->each(function ($commissionOrder) use (&$total_amount, &$total_commission, &$total_commission_cancel, &$total_commission_accounted, &$total_commission_back, &$total_commission_pending, $total) {
-                $total_amount += $commissionOrder['amount'];
-                foreach ($commissionOrder['rewards'] as $reward) {
-                    $total_commission += $reward['commission'];
-                    switch ($reward['status']) {
-                        case RewardModel::COMMISSION_REWARD_STATUS_ACCOUNTED:
-                            $total_commission_accounted += $reward['commission'];
-                            break;
-                        case RewardModel::COMMISSION_REWARD_STATUS_BACK:
-                            $total_commission_back += $reward['commission'];
-                            break;
-                        case RewardModel::COMMISSION_REWARD_STATUS_PENDING:
-                            $total_commission_pending += $reward['commission'];
-                            break;
-                        case RewardModel::COMMISSION_REWARD_STATUS_CANCEL:
-                            $total_commission_cancel += $reward['commission'];
-                            break;
-                    }
-                }
-            })->toArray();
-
-            $newDatas = [];
-            foreach ($datas as $commissionOrder) {
-                $commission = 0;
-                $commissioned = 0;
-                foreach ($commissionOrder['rewards'] as $reward) {
-                    if ($reward['status'] == 1) {
-                        $commissioned += $reward['commission'];
-                    }
-                    $commission += $reward['commission'];
-                }
-
-                $data = [
-                    'commission_order_id' => $commissionOrder['id'],
-                    'order_sn' => $commissionOrder['order'] ? $commissionOrder['order']['order_sn'] : '',
-                    'goods_title' => $commissionOrder['order_item'] ? '#' . $commissionOrder['order_item']['goods_id'] . ' ' . $commissionOrder['order_item']['goods_title'] : '',
-                    'goods_sku_text' => $commissionOrder['order_item'] ? $commissionOrder['order_item']['goods_sku_text'] : '',
-                    'goods_price' => $commissionOrder['order_item'] ? $commissionOrder['order_item']['goods_price'] : '',
-                    'goods_num' => $commissionOrder['order_item'] ? $commissionOrder['order_item']['goods_num'] : '',
-                    'refund_status_text' => $commissionOrder['order_item'] ? $commissionOrder['order_item']['refund_status_text'] : '',
-                    'buyer_nickname' => $commissionOrder['buyer'] ? $commissionOrder['buyer']['nickname'] : '-',
-                    'buyer_mobile' => $commissionOrder['buyer'] ? $commissionOrder['buyer']['mobile'] . ' ' : '-',
-                    'share_nickname' => $commissionOrder['agent'] ? $commissionOrder['agent']['nickname'] : '-',
-                    'share_mobile' => $commissionOrder['agent'] ? $commissionOrder['agent']['mobile'] . ' ' : '-',
-
-                    // 这里循环 rewards 佣金详情
-
-                    'commission_reward_status_text' => $commissionOrder['commission_reward_status_text'],
-                    'reward_event_text' => $commissionOrder['reward_event_text'],
-                    'commission_time' => $commissionOrder['commission_time'],
-                    'reward_type_text' => $commissionOrder['reward_type_text'],
-                    'amount' => $commissionOrder['amount'],
-                    'commission_order_status_text' => $commissionOrder['commission_order_status_text'],
-                    'total_commission' => $commission,
-                    'total_commissioned' => $commissioned,
-                ];
-
-                $rewardsItems = [];
-                foreach ($commissionOrder['rewards'] as $reward) {
-                    $rewardsItems[] = [
-                        'reward_agent_nickname' => $reward['agent'] ? $reward['agent']['nickname'] : '',
-                        'reward_agent_mobile' => $reward['agent'] ? $reward['agent']['mobile'] : '',
-                        'reward_commission' => $reward['commission'],
-                        'reward_status_text' => $reward['status_text'],
-                        'reward_type_text' => $reward['type_text'],
-                        'reward_commission_time' => $reward['commission_time']
-                    ];
-                }
-
-                $data['rewards'] = $rewardsItems;
-
-                $newDatas[] = $data;
-            }
-
-            if ($pages['is_last_page']) {
-                $newDatas[] = ['order_id' => "商品总订单数:" . $total . ";商品结算总金额:¥" . $total_amount .  ";分佣总金额:¥" . $total_commission . ";已取消佣金:¥" . $total_commission_cancel . ";已退回佣金:¥" . $total_commission_back . ";未结算佣金:" . $total_commission_pending . ";已结算佣金:" . $total_commission_accounted];
-            }
-            return $newDatas;
-        });
-
-        $this->success('导出成功' . (isset($result['file_path']) && $result['file_path'] ? ',请在服务器: “' . $result['file_path'] . '” 查看' : ''), null, $result);
+        // TODO: 实现具体的导出逻辑
+        // 这里需要根据实际的Export类来实现
+        $this->error('导出功能待实现');
     }
     }
 }
 }

+ 2 - 2
application/admin/view/commission/identity/index.html

@@ -10,10 +10,10 @@
                 <div class="widget-body no-padding">
                 <div class="widget-body no-padding">
                     <div id="toolbar" class="toolbar">
                     <div id="toolbar" class="toolbar">
                         <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
                         <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
-                        <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('commission/identity/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
+                        <!-- <a href="javascript:;" class="btn btn-success btn-add {:$auth->check('commission/identity/add')?'':'hide'}" title="{:__('Add')}" ><i class="fa fa-plus"></i> {:__('Add')}</a>
                         <a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('commission/identity/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
                         <a href="javascript:;" class="btn btn-success btn-edit btn-disabled disabled {:$auth->check('commission/identity/edit')?'':'hide'}" title="{:__('Edit')}" ><i class="fa fa-pencil"></i> {:__('Edit')}</a>
                         <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('commission/identity/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
                         <a href="javascript:;" class="btn btn-danger btn-del btn-disabled disabled {:$auth->check('commission/identity/del')?'':'hide'}" title="{:__('Delete')}" ><i class="fa fa-trash"></i> {:__('Delete')}</a>
-                        <a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('commission/identity/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a>
+                        <a href="javascript:;" class="btn btn-danger btn-import {:$auth->check('commission/identity/import')?'':'hide'}" title="{:__('Import')}" id="btn-import-file" data-url="ajax/upload" data-mimetype="csv,xls,xlsx" data-multiple="false"><i class="fa fa-upload"></i> {:__('Import')}</a> -->
                     </div>
                     </div>
                     <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
                     <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
                            data-operate-add="{:$auth->check('commission/identity/add')}"
                            data-operate-add="{:$auth->check('commission/identity/add')}"

+ 133 - 0
application/admin/view/commission/order/index.html

@@ -1,9 +1,140 @@
+<style>
+    .dashboard-content {
+        padding: 20px;
+        background: #f8f9fa;
+        border-radius: 8px;
+        margin-bottom: 20px;
+        border: 1px solid #e9ecef;
+    }
+
+    .dashboard-item {
+        text-align: center;
+        margin-bottom: 15px;
+        padding: 10px;
+        background: #fff;
+        border-radius: 6px;
+        border: 1px solid #e9ecef;
+        transition: all 0.3s ease;
+    }
+
+    .dashboard-item:hover {
+        box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+        border-color: #007bff;
+    }
+
+    .dashboard-top {
+        line-height: 28px;
+        font-size: 24px;
+        font-weight: 500;
+        color: #495057;
+        margin-bottom: 5px;
+    }
+
+    .dashboard-unit {
+        font-size: 14px;
+        margin-left: 4px;
+        color: #6c757d;
+        font-weight: 400;
+    }
+
+    .dashboard-bottom {
+        line-height: 16px;
+        font-size: 12px;
+        font-weight: 400;
+        color: #868e96;
+    }
+
+    /* 响应式优化 */
+    @media (max-width: 767px) {
+        .dashboard-content {
+            padding: 15px;
+        }
+        
+        .dashboard-item {
+            margin-bottom: 10px;
+        }
+        
+        .dashboard-top {
+            font-size: 20px;
+        }
+    }
+</style>
+
 <div class="panel panel-default panel-intro">
 <div class="panel panel-default panel-intro">
     {:build_heading()}
     {:build_heading()}
 
 
     <div class="panel-body">
     <div class="panel-body">
         <div id="myTabContent" class="tab-content">
         <div id="myTabContent" class="tab-content">
             <div class="tab-pane fade active in" id="one">
             <div class="tab-pane fade active in" id="one">
+                <!-- 统计信息 -->
+                <div class="dashboard-content" id="commission-stats" style="margin-bottom: 20px;">
+                    <div class="row">
+                        <div class="col-xs-6 col-sm-6 col-md-2 col-lg">
+                            <div class="dashboard-item">
+                                <div class="dashboard-top">
+                                    <span id="total-count">0</span>
+                                    <span class="dashboard-unit">单</span>
+                                </div>
+                                <div class="dashboard-bottom">商品总订单数</div>
+                            </div>
+                        </div>
+                        <div class="col-xs-6 col-sm-6 col-md-2 col-lg">
+                            <div class="dashboard-item">
+                                <div class="dashboard-top">
+                                    <span id="total-amount">0.00</span>
+                                    <span class="dashboard-unit">元</span>
+                                </div>
+                                <div class="dashboard-bottom">商品结算总金额</div>
+                            </div>
+                        </div>
+                        <div class="col-xs-6 col-sm-6 col-md-2 col-lg">
+                            <div class="dashboard-item">
+                                <div class="dashboard-top">
+                                    <span id="total-commission">0.00</span>
+                                    <span class="dashboard-unit">元</span>
+                                </div>
+                                <div class="dashboard-bottom">分佣总金额</div>
+                            </div>
+                        </div>
+                        <div class="col-xs-6 col-sm-6 col-md-2 col-lg">
+                            <div class="dashboard-item">
+                                <div class="dashboard-top">
+                                    <span id="total-pending">0.00</span>
+                                    <span class="dashboard-unit">元</span>
+                                </div>
+                                <div class="dashboard-bottom">未结算佣金</div>
+                            </div>
+                        </div>
+                        <div class="col-xs-6 col-sm-6 col-md-2 col-lg">
+                            <div class="dashboard-item">
+                                <div class="dashboard-top">
+                                    <span id="total-accounted">0.00</span>
+                                    <span class="dashboard-unit">元</span>
+                                </div>
+                                <div class="dashboard-bottom">已结算佣金</div>
+                            </div>
+                        </div>
+                        <div class="col-xs-6 col-sm-6 col-md-2 col-lg">
+                            <div class="dashboard-item">
+                                <div class="dashboard-top">
+                                    <span id="total-back">0.00</span>
+                                    <span class="dashboard-unit">元</span>
+                                </div>
+                                <div class="dashboard-bottom">已退回佣金</div>
+                            </div>
+                        </div>
+                        <div class="col-xs-6 col-sm-6 col-md-2 col-lg">
+                            <div class="dashboard-item">
+                                <div class="dashboard-top">
+                                    <span id="total-cancel">0.00</span>
+                                    <span class="dashboard-unit">元</span>
+                                </div>
+                                <div class="dashboard-bottom">已取消佣金</div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                
                 <div class="widget-body no-padding">
                 <div class="widget-body no-padding">
                     <div id="toolbar" class="toolbar">
                     <div id="toolbar" class="toolbar">
                         <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
                         <a href="javascript:;" class="btn btn-primary btn-refresh" title="{:__('Refresh')}" ><i class="fa fa-refresh"></i> </a>
@@ -11,6 +142,8 @@
                     <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
                     <table id="table" class="table table-striped table-bordered table-hover table-nowrap"
                            data-operate-edit="{:$auth->check('commission/order/edit')}"
                            data-operate-edit="{:$auth->check('commission/order/edit')}"
                            data-operate-del="{:$auth->check('commission/order/del')}"
                            data-operate-del="{:$auth->check('commission/order/del')}"
+                           data-operate-detail="{:$auth->check('commission/order/detail')}"
+                           data-operate-detail="{:$auth->check('commission/order/detail')}"
                            width="100%">
                            width="100%">
                     </table>
                     </table>
                 </div>
                 </div>

+ 48 - 0
application/common.php

@@ -73,6 +73,54 @@ if (!function_exists('string_hide')) {
 }
 }
 
 
 
 
+if (!function_exists('morph_to')) {
+    /**
+     * 多态关联
+     *
+     * @param array|object $items
+     * @param array $morphs
+     * @param array $fields
+     * @return array|object
+     */
+    function morph_to($items, $morphs, $fields)
+    {
+        if ($items instanceof \think\Paginator) {
+            $data = $items->items();
+        } else if ($items instanceof \think\Collection) {
+            $data = $items;
+        } else {
+            $data = collection($items);
+        }
+
+        $allIds = [];
+        foreach ($data as $item) {
+            $allIds[$item[$fields[0]]][] = $item[$fields[1]];
+        }
+
+        $morphsData = [];
+        foreach ($allIds as $key => $ids) {
+            $morphData = (new $morphs[$key])::where('id', 'in', $ids)->select();
+            $morphsData[$key] = array_column($morphData, null, 'id');
+        }
+
+        $morph_key = strstr($fields[0], '_', true);
+        foreach ($data as &$item) {
+            $item->{$morph_key} = $morphsData[$item[$fields[0]]][$item[$fields[1]]] ?? null;
+        }
+
+        if ($items instanceof \think\Paginator) {
+            $items->data = $items;
+        } else {
+            $items = $data;
+        }
+
+        return $items;
+    }
+}
+
+
+
+
 if (!function_exists('account_hide')) {
 if (!function_exists('account_hide')) {
     /**
     /**
      * 隐藏账号部分字符串
      * 隐藏账号部分字符串

+ 150 - 18
public/assets/js/backend/commission/log.js

@@ -16,7 +16,47 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             });
             });
 
 
             var table = $("#table");
             var table = $("#table");
+            
+            // 获取后台配置
+            var eventTypes = Controller.api.parseConfigJson('commission_log_event_types', {
+                "agent": __('分销商日志'),
+                "level": __('等级变动日志'),
+                "order": __('分销业绩'),
+                "team": __('团队日志'),
+                "reward": __('佣金日志'),
+                "share": __('分享日志'),
+                "bind": __('绑定日志')
+            });
+            
+            var operTypes = Controller.api.parseConfigJson('commission_log_oper_types', {
+                "admin": __('管理员'),
+                "system": __('系统'),
+                "user": __('用户')
+            });
+            
+            var displayConfig = Controller.api.parseConfigJson('commission_log_user_display_config', {
+                showAvatar: true,
+                avatarSize: 40,
+                showMobile: true,
+                showId: true,
+                systemAvatarUrl: '/assets/img/system-avatar.png',
+                defaultAvatarUrl: '/assets/img/avatar.png'
+            });
+
 
 
+            // 创建统一的代理商信息展示方法
+            function formatAgentInfo(row) {
+                if (!row.agent || !row.agent.user) {
+                    return '-';
+                }
+                return Controller.api.formatUserInfo(row.agent.user, row.agent_id, '分销商', displayConfig);
+            }
+
+            // 创建统一的操作人信息展示方法
+            function formatOperatorInfo(row) {
+                return Controller.api.formatOperatorInfo(row.oper, row.oper_type, displayConfig);
+            }
+           
             // 初始化表格
             // 初始化表格
             table.bootstrapTable({
             table.bootstrapTable({
                 url: $.fn.bootstrapTable.defaults.extend.index_url,
                 url: $.fn.bootstrapTable.defaults.extend.index_url,
@@ -25,25 +65,26 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                 columns: [
                 columns: [
                     [
                     [
                         {checkbox: true},
                         {checkbox: true},
-                        {field: 'id', title: __('ID'), width: 60},
-                        {field: 'agent.user.nickname', title: __('分销商'), operate: 'LIKE'},
-                        {field: 'agent.user.mobile', title: __('手机号'), operate: 'LIKE'},
-                        {field: 'event', title: __('事件类型'), searchList: {
-                            "agent": __('分销商日志'),
-                            "level": __('等级变动日志'),
-                            "order": __('分销业绩'),
-                            "team": __('团队日志'),
-                            "reward": __('佣金日志'),
-                            "share": __('分享日志'),
-                            "bind": __('绑定日志')
-                        }},
+                        {field: 'id', title: __('ID'), width: 60},                     
+                        {field: 'event_text', title: __('事件类型'), searchList: eventTypes},
+                        {
+                            field: 'agent.username', 
+                            title: __('分销商'), 
+                            operate: 'LIKE',
+                            formatter: function (value, row, index) {
+                                return formatAgentInfo(row);
+                            }
+                        },
                         {field: 'remark', title: __('备注'), operate: 'LIKE'},
                         {field: 'remark', title: __('备注'), operate: 'LIKE'},
-                        {field: 'oper_type', title: __('操作人类型'), searchList: {
-                            "admin": __('管理员'),
-                            "system": __('系统'),
-                            "user": __('用户')
-                        }},
-                        {field: 'oper.nickname', title: __('操作人'), operate: 'LIKE'},
+                        {field: 'oper_type', title: __('操作人类型'), searchList: operTypes},
+                        {
+                            field: 'oper.oper_type_text', 
+                            title: __('操作人'), 
+                            operate: 'LIKE',
+                            formatter: function (value, row, index) {
+                                return formatOperatorInfo(row);
+                            }
+                        },
                         {field: 'createtime', 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, 
                         {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, 
                          buttons: [
                          buttons: [
@@ -68,6 +109,97 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             Table.api.bindevent(table);
             Table.api.bindevent(table);
         },
         },
         api: {
         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;
+            },
+            
+            // 统一的用户信息展示方法
+            formatUserInfo: function(user, userId, userType, config) {
+                if (!user) return '-';
+                
+                config = config || {
+                    showAvatar: true,
+                    avatarSize: 40,
+                    showMobile: true,
+                    showId: true,
+                    defaultAvatarUrl: '/assets/img/avatar.png'
+                };
+                
+                var avatar = user.avatar ? user.avatar : config.defaultAvatarUrl;
+                var nickname = user.nickname || user.username || (userType || '用户');
+                var mobile = user.mobile || '';
+                
+                // 处理头像URL
+                var avatarUrl = avatar;
+                if (avatar && !avatar.startsWith('http') && !avatar.startsWith('//')) {
+                    avatarUrl = Fast.api.cdnurl ? Fast.api.cdnurl(avatar) : avatar;
+                }
+                
+                var typeColor = userType === '管理员' ? '#dc3545' : (userType === '用户' ? '#17a2b8' : '#337ab7');
+                
+                var html = '<div style="display:flex;align-items:center;">';
+                
+                if (config.showAvatar) {
+                    html += '<img src="' + avatarUrl + '" style="width:' + config.avatarSize + 'px;height:' + config.avatarSize + 'px;border-radius:50%;margin-right:10px;" />';
+                }
+                
+                html += '<div>' +
+                        '<div style="color:#337ab7;font-weight:bold;">' + nickname + '</div>' +
+                        '<div style="color:' + typeColor + ';font-size:12px;">';
+                
+                var info = [];
+                if (config.showMobile && mobile) {
+                    info.push(mobile);
+                }
+                if (config.showId && userId) {
+                    info.push('ID: ' + userId);
+                }
+                
+                html += info.join(' ') + '</div></div></div>';
+                return html;
+            },
+            
+            // 格式化代理商信息展示
+            formatAgentInfo: function(agentData, config) {
+                if (!agentData || !agentData.user) {
+                    return '-';
+                }
+                return this.formatUserInfo(agentData.user, agentData.user_id || agentData.id, '分销商', config);
+            },
+            
+            // 格式化操作人信息展示
+            formatOperatorInfo: function(operData, operType, config) {
+                if (operType === 'system') {
+                    var sysConfig = config || { avatarSize: 40, systemAvatarUrl: '/assets/img/system-avatar.png' };
+                    var html = '<div style="display:flex;align-items:center;">';
+                    html += '<img src="' + sysConfig.systemAvatarUrl + '" style="width:' + sysConfig.avatarSize + 'px;height:' + sysConfig.avatarSize + 'px;border-radius:50%;margin-right:10px;" />';
+                    html += '<div>' +
+                            '<div style="color:#28a745;font-weight:bold;">系统</div>' +
+                            '<div style="color:#999;font-size:12px;">自动操作</div>' +
+                            '</div></div>';
+                    return html;
+                }
+                
+                if (!operData) {
+                    return '-';
+                }
+                
+                var userType = operType === 'admin' ? '管理员' : '用户';
+                return this.formatUserInfo(operData, operData.id, userType, config);
+            },
+            
             bindevent: function () {
             bindevent: function () {
                 Form.api.bindevent($("form[role=form]"));
                 Form.api.bindevent($("form[role=form]"));
             }
             }

+ 213 - 75
public/assets/js/backend/commission/order.js

@@ -16,12 +16,74 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             });
             });
 
 
             var table = $("#table");
             var table = $("#table");
+            
+            // 获取后台配置
+            var orderStatusTypes = Controller.api.parseConfigJson('commission_order_status_types', {
+                '-2': __('已扣除'),
+                '-1': __('已取消'),
+                '0': __('不计入'),
+                '1': __('已计入')
+            });
+            
+            var rewardStatusTypes = Controller.api.parseConfigJson('commission_reward_status_types', {
+                '-2': __('已退回'),
+                '-1': __('已取消'),
+                '0': __('未结算'),
+                '1': __('已结算')
+            });
+            
+            var displayConfig = Controller.api.parseConfigJson('commission_order_user_display_config', {
+                showAvatar: true,
+                avatarSize: 40,
+                showMobile: true,
+                showId: true,
+                defaultAvatarUrl: '/assets/img/avatar.png'
+            });
+
+            // 格式化订单状态
+            function formatOrderStatus(value, colorMap) {
+                var statusConfig = colorMap[value];
+                if (!statusConfig) return value;
+                return '<span class="label label-' + statusConfig.color + '">' + statusConfig.text + '</span>';
+            }
+
+            // 格式化用户信息(买家或代理商)
+            function formatUserInfo(user, userId, userType) {
+                if (!user) return '-';
+                return Controller.api.formatUserInfo(user, userId || user.id, userType, displayConfig);
+            }
+
+            // 统计信息处理
+            function updateStats(data) {
+                if (data.extend && data.extend.count) {
+                    var count = data.extend.count;
+                    
+                    // 格式化数字显示
+                    function formatNumber(number) {
+                        return (number || 0).toFixed(2);
+                    }
+                    
+                    $('#total-count').text(count.total || 0);
+                    $('#total-amount').text(formatNumber(count.total_amount));
+                    $('#total-commission').text(formatNumber(count.total_commission));
+                    $('#total-pending').text(formatNumber(count.total_commission_pending));
+                    $('#total-accounted').text(formatNumber(count.total_commission_accounted));
+                    $('#total-back').text(formatNumber(count.total_commission_back));
+                    $('#total-cancel').text(formatNumber(count.total_commission_cancel));
+                }
+            }
 
 
             // 初始化表格
             // 初始化表格
             table.bootstrapTable({
             table.bootstrapTable({
                 url: $.fn.bootstrapTable.defaults.extend.index_url,
                 url: $.fn.bootstrapTable.defaults.extend.index_url,
                 pk: 'id',
                 pk: 'id',
                 sortName: 'id',
                 sortName: 'id',
+                fixedColumns: true, // 启用固定列功能
+                fixedRightNumber: 1, // 固定右侧最后1列(操作列)
+                responseHandler: function(res) {
+                    updateStats(res);
+                    return res;
+                },
                 columns: [
                 columns: [
                     [
                     [
                         {checkbox: true},
                         {checkbox: true},
@@ -32,85 +94,101 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                             }
                             }
                             return '-';
                             return '-';
                         }},
                         }},
-                        {field: 'order_item.goods_title', title: __('商品名称'), operate: 'LIKE', formatter: function(value, row, index) {
-                            if (row.order_item && row.order_item.goods_title) {
-                                return '<a href="javascript:;" data-goods-id="' + row.order_item.goods_id + '" class="searchit goods-detail">' + row.order_item.goods_title + '</a>';
+                        {field: 'order_item.goods_title', title: __('商品信息'), operate: 'LIKE', width: 300, formatter: function(value, row, index) {
+                            if (row.order_item) {
+                                var item = row.order_item;
+                                var html = '<div style="display: flex; align-items: center; padding: 5px 0;">';
+                                
+                                // 商品图片
+                                var imageUrl = item.goods_image || item.image || '/assets/img/goods-default.png';
+                                if (imageUrl && !imageUrl.startsWith('http') && !imageUrl.startsWith('//')) {
+                                    imageUrl = Fast.api.cdnurl ? Fast.api.cdnurl(imageUrl) : imageUrl;
+                                }
+                                html += '<div style="margin-right: 12px; flex-shrink: 0;">';
+                                html += '<img src="' + imageUrl + '" style="width: 60px; height: 60px; object-fit: cover; border-radius: 4px; border: 1px solid #e9ecef;" />';
+                                html += '</div>';
+                                
+                                // 商品信息
+                                html += '<div style="flex: 1; min-width: 0;">';
+                                
+                                // 商品标题
+                                var goodsTitle = item.goods_title || item.title || '-';
+                                html += '<div style="color: #337ab7; font-weight: bold; margin-bottom: 4px; line-height: 1.4;">';
+                                html += '<a href="javascript:;" data-goods-id="' + item.goods_id + '" class="searchit goods-detail" style="color: #337ab7; text-decoration: none;">';
+                                html += goodsTitle;
+                                html += '</a></div>';
+                                
+                                // 商品规格
+                                if (item.goods_sku || item.sku_name || item.specs) {
+                                    var specs = item.goods_sku || item.sku_name || item.specs;
+                                    html += '<div style="color: #6c757d; font-size: 12px; margin-bottom: 4px;">' + specs + '</div>';
+                                }
+                                
+                                // 商品价格和数量
+                                var price = item.price || item.goods_price || 0;
+                                var nums = item.nums || item.quantity || 1;
+                                html += '<div style="color: #28a745; font-weight: bold; font-size: 14px;">';
+                                html += '¥' + parseFloat(price).toFixed(2) + ' × ' + nums;
+                                html += '</div>';
+                                
+                                html += '</div></div>';
+                                return html;
                             }
                             }
                             return '-';
                             return '-';
                         }},
                         }},
-                        {field: 'buyer.nickname', title: __('下单用户'), operate: 'LIKE'},
-                        {field: 'buyer.mobile', title: __('手机号'), operate: 'LIKE'},
-                        {field: 'agent.nickname', title: __('推广分销商'), operate: 'LIKE'},
-                        {field: 'agent.mobile', title: __('推广手机号'), operate: 'LIKE'},
+                        {
+                            field: 'buyer.nickname', 
+                            title: __('下单用户'), 
+                            operate: 'LIKE',
+                            formatter: function (value, row, index) {
+                                return formatUserInfo(row.buyer, row.user_id, '用户');
+                            }
+                        },
+                        {
+                            field: 'agent.nickname', 
+                            title: __('推广分销商'), 
+                            operate: 'LIKE',
+                            formatter: function (value, row, index) {
+                                return formatUserInfo(row.agent, row.agent_id, '分销商');
+                            }
+                        },
                         {field: 'amount', title: __('结算金额'), operate: 'BETWEEN'},
                         {field: 'amount', title: __('结算金额'), operate: 'BETWEEN'},
-                        {field: 'commission_order_status', title: __('业绩状态'), searchList: {
-                            "-2": __('已扣除'),
-                            "-1": __('已取消'),
-                            "0": __('不计入'),
-                            "1": __('已计入')
-                        }, formatter: function(value, row, index) {
+                        {field: 'commission_order_status', title: __('业绩状态'), searchList: orderStatusTypes, formatter: function(value, row, index) {
                             var statusMap = {
                             var statusMap = {
-                                '-2': {text: '已扣除', color: 'danger'},
-                                '-1': {text: '已取消', color: 'warning'},
-                                '0': {text: '不计入', color: 'info'},
-                                '1': {text: '已计入', color: 'success'}
+                                '-2': {text: orderStatusTypes['-2'] || '已扣除', color: 'danger'},
+                                '-1': {text: orderStatusTypes['-1'] || '已取消', color: 'warning'},
+                                '0': {text: orderStatusTypes['0'] || '不计入', color: 'info'},
+                                '1': {text: orderStatusTypes['1'] || '已计入', color: 'success'}
                             };
                             };
-                            var status = statusMap[value] || {text: value, color: 'default'};
-                            return '<span class="label label-' + status.color + '">' + status.text + '</span>';
+                            return formatOrderStatus(value, statusMap);
                         }},
                         }},
-                        {field: 'commission_reward_status', title: __('佣金状态'), searchList: {
-                            "-2": __('已退回'),
-                            "-1": __('已取消'),
-                            "0": __('未结算'),
-                            "1": __('已结算')
-                        }, formatter: function(value, row, index) {
+                        {field: 'commission_reward_status', title: __('佣金状态'), searchList: rewardStatusTypes, formatter: function(value, row, index) {
                             var statusMap = {
                             var statusMap = {
-                                '-2': {text: '已退回', color: 'danger'},
-                                '-1': {text: '已取消', color: 'warning'},
-                                '0': {text: '未结算', color: 'info'},
-                                '1': {text: '已结算', color: 'success'}
+                                '-2': {text: rewardStatusTypes['-2'] || '已退回', color: 'danger'},
+                                '-1': {text: rewardStatusTypes['-1'] || '已取消', color: 'warning'},
+                                '0': {text: rewardStatusTypes['0'] || '未结算', color: 'info'},
+                                '1': {text: rewardStatusTypes['1'] || '已结算', color: 'success'}
                             };
                             };
-                            var status = statusMap[value] || {text: value, color: 'default'};
-                            return '<span class="label label-' + status.color + '">' + status.text + '</span>';
+                            return formatOrderStatus(value, statusMap);
                         }},
                         }},
                         {field: 'commission_time', title: __('结算时间'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false, formatter: Table.api.formatter.datetime},
                         {field: 'commission_time', title: __('结算时间'), operate: 'RANGE', addclass: 'datetimerange', autocomplete: false, formatter: Table.api.formatter.datetime},
                         {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, 
                         {field: 'operate', title: __('Operate'), table: table, events: Table.api.events.operate, 
+                         width: 150,
                          buttons: [
                          buttons: [
                              {
                              {
-                                 name: 'confirm',
-                                 text: __('结算'),
-                                 title: __('结算佣金'),
-                                 classname: 'btn btn-xs btn-success',
-                                 icon: 'fa fa-check',
-                                 visible: function (row) {
-                                     return row.commission_reward_status == 0;
-                                 },
-                                 click: function (data) {
-                                     Layer.confirm('确认结算此订单的佣金?', function(index) {
-                                         Fast.api.ajax({
-                                             url: 'commission/order/confirm',
-                                             data: {commission_order_id: data.id}
-                                         }, function(data, ret) {
-                                             table.bootstrapTable('refresh');
-                                             Layer.close(index);
-                                         });
-                                     });
-                                 }
-                             },
-                             {
-                                 name: 'cancel',
-                                 text: __('取消'),
-                                 title: __('取消佣金'),
-                                 classname: 'btn btn-xs btn-warning',
-                                 icon: 'fa fa-times',
+                                 name: 'back',
+                                 text: __('手动退回'),
+                                 title: __('手动退回佣金'),
+                                 classname: 'btn btn-xs btn-danger',
+                                 icon: 'fa fa-undo',
                                  visible: function (row) {
                                  visible: function (row) {
-                                     return row.commission_reward_status == 0;
+                                     return row.commission_reward_status == 1;
                                  },
                                  },
                                  click: function (data) {
                                  click: function (data) {
-                                     Layer.confirm('确认取消此订单的佣金?', function(index) {
+                                     Layer.confirm('确认手动退回此订单的佣金?', function(index) {
                                          Fast.api.ajax({
                                          Fast.api.ajax({
-                                             url: 'commission/order/cancel',
-                                             data: {commission_order_id: data.id}
+                                             url: 'commission/order/back',
+                                             data: {commission_order_id: data.id, deduct_order_money: 1}
                                          }, function(data, ret) {
                                          }, function(data, ret) {
                                              table.bootstrapTable('refresh');
                                              table.bootstrapTable('refresh');
                                              Layer.close(index);
                                              Layer.close(index);
@@ -119,24 +197,22 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
                                  }
                                  }
                              },
                              },
                              {
                              {
-                                 name: 'back',
-                                 text: __('退回'),
-                                 title: __('退回佣金'),
-                                 classname: 'btn btn-xs btn-danger',
-                                 icon: 'fa fa-undo',
+                                 name: 'detail',
+                                 text: __('订单详情'),
+                                 title: __('查看订单详情'),
+                                 classname: 'btn btn-xs btn-info',
+                                 icon: 'fa fa-eye',
                                  visible: function (row) {
                                  visible: function (row) {
-                                     return row.commission_reward_status == 1;
+                                     return true; // 始终显示
                                  },
                                  },
                                  click: function (data) {
                                  click: function (data) {
-                                     Layer.confirm('确认退回此订单的佣金?', function(index) {
-                                         Fast.api.ajax({
-                                             url: 'commission/order/back',
-                                             data: {commission_order_id: data.id, deduct_order_money: 1}
-                                         }, function(data, ret) {
-                                             table.bootstrapTable('refresh');
-                                             Layer.close(index);
+                                     if (data.order_id) {
+                                         Fast.api.open('order/order/detail?id=' + data.order_id, '订单详情', {
+                                             area: ['90%', '90%']
                                          });
                                          });
-                                     });
+                                     } else {
+                                         Layer.msg('订单ID不存在');
+                                     }
                                  }
                                  }
                              }
                              }
                          ], 
                          ], 
@@ -161,6 +237,68 @@ define(['jquery', 'bootstrap', 'backend', 'table', 'form'], function ($, undefin
             });
             });
         },
         },
         api: {
         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;
+            },
+            
+            // 统一的用户信息展示方法
+            formatUserInfo: function(user, userId, userType, config) {
+                if (!user) return '-';
+                
+                config = config || {
+                    showAvatar: true,
+                    avatarSize: 40,
+                    showMobile: true,
+                    showId: true,
+                    defaultAvatarUrl: '/assets/img/avatar.png'
+                };
+                
+                var avatar = user.avatar ? user.avatar : config.defaultAvatarUrl;
+                var nickname = user.nickname || user.username || (userType || '用户');
+                var mobile = user.mobile || '';
+                
+                // 处理头像URL
+                var avatarUrl = avatar;
+                if (avatar && !avatar.startsWith('http') && !avatar.startsWith('//')) {
+                    avatarUrl = Fast.api.cdnurl ? Fast.api.cdnurl(avatar) : avatar;
+                }
+                
+                var typeColor = userType === '分销商' ? '#28a745' : (userType === '用户' ? '#17a2b8' : '#337ab7');
+                
+                var html = '<div style="display:flex;align-items:center;">';
+                
+                if (config.showAvatar) {
+                    html += '<img src="' + avatarUrl + '" style="width:' + config.avatarSize + 'px;height:' + config.avatarSize + 'px;border-radius:50%;margin-right:10px;" />';
+                }
+                
+                html += '<div>' +
+                        '<div style="color:#337ab7;font-weight:bold;">' + nickname + '</div>' +
+                        '<div style="color:' + typeColor + ';font-size:12px;">';
+                
+                var info = [];
+                if (config.showMobile && mobile) {
+                    info.push(mobile);
+                }
+                if (config.showId && userId) {
+                    info.push('ID: ' + userId);
+                }
+                
+                html += info.join(' ') + '</div></div></div>';
+                return html;
+            },
+            
             bindevent: function () {
             bindevent: function () {
                 Form.api.bindevent($("form[role=form]"));
                 Form.api.bindevent($("form[role=form]"));
             }
             }