diff --git a/.DS_Store b/.DS_Store index 8fa1f89..abdbdb3 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/application/.DS_Store b/application/.DS_Store index 14bbb88..a4549a0 100644 Binary files a/application/.DS_Store and b/application/.DS_Store differ diff --git a/application/admin/.DS_Store b/application/admin/.DS_Store index 502d309..bf2d426 100644 Binary files a/application/admin/.DS_Store and b/application/admin/.DS_Store differ diff --git a/application/admin/controller/ChatQuickReply.php b/application/admin/controller/ChatQuickReply.php new file mode 100644 index 0000000..109a67f --- /dev/null +++ b/application/admin/controller/ChatQuickReply.php @@ -0,0 +1,229 @@ +get(); + $this->assign('get', $get); + + $category = Request::instance()->get('category'); + $status = Request::instance()->get('status'); + + $where = []; + if ($category) { + $where['category'] = $category; + } + if ($status !== null && $status !== '') { + $where['status'] = (int)$status; + } + + $list = Db::name('chat_quick_reply') + ->where($where) + ->order('sort asc, id desc') + ->paginate(15, false, ['query' => $get]); + + // 获取分类列表 + $categories = Db::name('chat_quick_reply') + ->whereNotNull('category') + ->where('category', '<>', '') + ->group('category') + ->column('category'); + + $this->assign('list', $list); + $this->assign('categories', $categories); + + return $this->fetch(); + } + + /** + * 添加快捷回复 + */ + public function add() + { + if (Request::instance()->isPost()) { + $data = Request::instance()->post(); + + // 验证 + if (empty($data['title'])) { + $this->error('标题不能为空'); + } + if (empty($data['content'])) { + $this->error('内容不能为空'); + } + + $insertData = [ + 'category' => $data['category'] ?? null, + 'title' => $data['title'], + 'content' => $data['content'], + 'sort' => (int)($data['sort'] ?? 0), + 'status' => (int)($data['status'] ?? 1), + 'create_time' => time(), + 'update_time' => time(), + ]; + + $result = Db::name('chat_quick_reply')->insert($insertData); + + if ($result) { + insertAdminLog('添加快捷回复', '标题: ' . $data['title']); + $this->success('添加成功', '/chat_quick_reply/index'); + } else { + $this->error('添加失败'); + } + } + + // 获取分类列表 + $categories = Db::name('chat_quick_reply') + ->whereNotNull('category') + ->where('category', '<>', '') + ->group('category') + ->column('category'); + + $this->assign('categories', $categories); + $this->assign('info', []); + + return $this->fetch(); + } + + /** + * 编辑快捷回复 + */ + public function edit() + { + $id = Request::instance()->param('id'); + + if (Request::instance()->isPost()) { + $data = Request::instance()->post(); + + // 验证 + if (empty($data['title'])) { + $this->error('标题不能为空'); + } + if (empty($data['content'])) { + $this->error('内容不能为空'); + } + + $updateData = [ + 'category' => $data['category'] ?? null, + 'title' => $data['title'], + 'content' => $data['content'], + 'sort' => (int)($data['sort'] ?? 0), + 'status' => (int)($data['status'] ?? 1), + 'update_time' => time(), + ]; + + $result = Db::name('chat_quick_reply')->where('id', $id)->update($updateData); + + if ($result !== false) { + insertAdminLog('编辑快捷回复', 'ID: ' . $id); + $this->success('修改成功', '/chat_quick_reply/index'); + } else { + $this->error('修改失败'); + } + } + + $info = Db::name('chat_quick_reply')->where('id', $id)->find(); + if (!$info) { + $this->error('记录不存在'); + } + + // 获取分类列表 + $categories = Db::name('chat_quick_reply') + ->whereNotNull('category') + ->where('category', '<>', '') + ->group('category') + ->column('category'); + + $this->assign('info', $info); + $this->assign('categories', $categories); + + return $this->fetch('add'); + } + + /** + * 删除快捷回复 + */ + public function del() + { + $id = Request::instance()->param('id'); + + if (!$id) { + $this->error('参数错误'); + } + + $info = Db::name('chat_quick_reply')->where('id', $id)->find(); + if (!$info) { + $this->error('记录不存在'); + } + + $result = Db::name('chat_quick_reply')->where('id', $id)->delete(); + + if ($result) { + insertAdminLog('删除快捷回复', 'ID: ' . $id . ', 标题: ' . $info['title']); + $this->success('删除成功'); + } else { + $this->error('删除失败'); + } + } + + /** + * 修改状态 + */ + public function status() + { + $id = Request::instance()->post('id'); + $status = Request::instance()->post('status'); + + if (!$id) { + return json(['code' => 1, 'msg' => '参数错误']); + } + + $result = Db::name('chat_quick_reply')->where('id', $id)->update([ + 'status' => (int)$status, + 'update_time' => time(), + ]); + + if ($result !== false) { + return json(['code' => 0, 'msg' => '操作成功']); + } else { + return json(['code' => 1, 'msg' => '操作失败']); + } + } + + /** + * 修改排序 + */ + public function sort() + { + $id = Request::instance()->post('id'); + $sort = Request::instance()->post('sort'); + + if (!$id) { + return json(['code' => 1, 'msg' => '参数错误']); + } + + $result = Db::name('chat_quick_reply')->where('id', $id)->update([ + 'sort' => (int)$sort, + 'update_time' => time(), + ]); + + if ($result !== false) { + return json(['code' => 0, 'msg' => '操作成功']); + } else { + return json(['code' => 1, 'msg' => '操作失败']); + } + } +} diff --git a/application/admin/controller/Common.php b/application/admin/controller/Common.php index 17796c9..0967ff8 100644 --- a/application/admin/controller/Common.php +++ b/application/admin/controller/Common.php @@ -29,6 +29,8 @@ class Common extends Controller{ 'Info', 'Log', 'Login', + 'Chat', + 'ChatQuickReply', ); if($user_info['role'] == 1){ if(!in_array($curContrller, $jiankongController)){ @@ -40,6 +42,8 @@ class Common extends Controller{ 'Index', 'Agent', 'Login', + 'Chat', + 'ChatQuickReply', ); if($user_info['role'] == 2){ if(!in_array($curContrller, $dlController)){ diff --git a/application/admin/controller/Login.php b/application/admin/controller/Login.php index f3a30b4..79171fb 100644 --- a/application/admin/controller/Login.php +++ b/application/admin/controller/Login.php @@ -59,7 +59,15 @@ class Login extends Controller{ } $last_login_info = Db::name('admin')->where(array('id' => $admin_info['id']))->field(['last_login_time','last_login_ip'])->find(); Session::set('last_login_info',$last_login_info); - Db::name('admin')->where(array('id' => $admin_info['id']))->update(array('last_login_time' => time(), 'last_login_ip' => getIP())); + + // 生成login_token用于WebSocket连接验证 + $login_token = md5($admin_info['id'] . time() . uniqid()); + Db::name('admin')->where(array('id' => $admin_info['id']))->update(array( + 'last_login_time' => time(), + 'last_login_ip' => getIP(), + 'login_token' => $login_token + )); + $user_info = Db::name('admin')->where('id',$admin_info['id'])->find(); Session::set('user_info',$user_info); insertAdminLog('登录'); diff --git a/application/admin/controller/Report.php b/application/admin/controller/Report.php index 254e55a..4496f92 100644 --- a/application/admin/controller/Report.php +++ b/application/admin/controller/Report.php @@ -36,17 +36,17 @@ class Report extends Common{ } $agent_list = Db::name('user')->where($where)->select(); - // 时间条件 + // 时间条件(默认:今天07:00:00 ~ 明天06:59:59) if($startDate){ $startTime = strtotime($startDate); }else{ - $startTime = strtotime(date('Y-m-d')); + $startTime = strtotime(date('Y-m-d') . ' 07:00:00'); $get['startDate'] = date('Y-m-d H:i:s',$startTime); } if($endDate){ $endTime = strtotime($endDate); }else{ - $endTime = time(); + $endTime = strtotime(date('Y-m-d', strtotime('+1 day')) . ' 06:59:59'); $get['endDate'] = date('Y-m-d H:i:s',$endTime); } $this->assign('get',$get); diff --git a/application/admin/view/.DS_Store b/application/admin/view/.DS_Store index e0b13bd..0a3a7b6 100644 Binary files a/application/admin/view/.DS_Store and b/application/admin/view/.DS_Store differ diff --git a/application/admin/view/agent/profit.html b/application/admin/view/agent/profit.html index 0613b3e..38deb11 100644 --- a/application/admin/view/agent/profit.html +++ b/application/admin/view/agent/profit.html @@ -95,16 +95,30 @@ layui.use('laydate', function () { var laydate = layui.laydate; + // 计算默认时间:今天07:00:00 ~ 明天06:59:59 + var now = new Date(); + var y = now.getFullYear(); + var m = ('0' + (now.getMonth() + 1)).slice(-2); + var d = ('0' + now.getDate()).slice(-2); + var tomorrow = new Date(now.getTime() + 86400000); + var ty = tomorrow.getFullYear(); + var tm = ('0' + (tomorrow.getMonth() + 1)).slice(-2); + var td = ('0' + tomorrow.getDate()).slice(-2); + var defaultStart = y + '-' + m + '-' + d + ' 07:00:00'; + var defaultEnd = ty + '-' + tm + '-' + td + ' 06:59:59'; + // 开始时间 laydate.render({ elem: '#start', - type: 'datetime' + type: 'datetime', + value: defaultStart }); // 结束时间 laydate.render({ elem: '#end', - type: 'datetime' + type: 'datetime', + value: defaultEnd }); }); function get_profit(){ diff --git a/application/admin/view/chat/detail.html b/application/admin/view/chat/detail.html new file mode 100644 index 0000000..c05c966 --- /dev/null +++ b/application/admin/view/chat/detail.html @@ -0,0 +1,89 @@ +{include file="public/header" /} + +
+
+
会话信息
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + {if condition="$session.rating"} + + + + + {/if} +
会话ID:{$session.id}用户名:{$session.username}
用户余额:{$session.money}客服:{$session.admin_username|default='未分配'}
来源: + {switch name="session.source"} + {case value="1"}PC{/case} + {case value="2"}Game{/case} + {case value="3"}Portal{/case} + {/switch} + 状态: + {switch name="session.status"} + {case value="0"}待分配{/case} + {case value="1"}进行中{/case} + {case value="2"}已结束{/case} + {/switch} +
开始时间:{$session.create_time|date='Y-m-d H:i:s',###}结束时间:{if condition="$session.end_time"}{$session.end_time|date='Y-m-d H:i:s',###}{else/}-{/if}
评分: + {$session.rating}星 + {if condition="$session.rating_content"} +
{$session.rating_content} + {/if} +
+
+
+ +
+
聊天记录
+
+ {volist name="messages" id="msg"} +
+
+
+ {eq name="msg.sender_type" value="1"} + 用户 + {else/} + 客服 + {/eq} + · {$msg.create_time|date='Y-m-d H:i:s',###} +
+
+ {eq name="msg.msg_type" value="2"} + + {else/} + {$msg.content} + {/eq} +
+
+
+ {/volist} +
+
+
+ + diff --git a/application/admin/view/chat/record.html b/application/admin/view/chat/record.html new file mode 100644 index 0000000..b0ea1af --- /dev/null +++ b/application/admin/view/chat/record.html @@ -0,0 +1,117 @@ +{include file="public/header" /} + +
+ + 首页 + 聊天记录查询 + + + +
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+ + +
+
+ + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + + {/volist} + +
会话ID用户名客服来源状态评分开始时间结束时间操作
{$vo.id}{$vo.username}{$vo.admin_username|default='未分配'} + {switch name="vo.source"} + {case value="1"}PC{/case} + {case value="2"}Game{/case} + {case value="3"}Portal{/case} + {/switch} + + {switch name="vo.status"} + {case value="0"}待分配{/case} + {case value="1"}进行中{/case} + {case value="2"}已结束{/case} + {/switch} + + {if condition="$vo.rating"} + {$vo.rating}星 + {else/} + - + {/if} + {$vo.create_time|date='Y-m-d H:i:s',###}{if condition="$vo.end_time"}{$vo.end_time|date='Y-m-d H:i:s',###}{else/}-{/if} + + + +
+
+ {$list->render()} +
+
+ + + diff --git a/application/admin/view/chat_quick_reply/add.html b/application/admin/view/chat_quick_reply/add.html new file mode 100644 index 0000000..0bcb06c --- /dev/null +++ b/application/admin/view/chat_quick_reply/add.html @@ -0,0 +1,70 @@ +{include file="public/header" /} + +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ + +
+
+
+ + +
+
+
+ + + diff --git a/application/admin/view/chat_quick_reply/index.html b/application/admin/view/chat_quick_reply/index.html new file mode 100644 index 0000000..62f1359 --- /dev/null +++ b/application/admin/view/chat_quick_reply/index.html @@ -0,0 +1,134 @@ +{include file="public/header" /} + +
+ + 首页 + 快捷回复管理 + + + +
+
+
+
+
+ +
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + + + {volist name="list" id="vo"} + + + + + + + + + + + {/volist} + +
ID分类标题内容排序状态创建时间操作
{$vo.id}{$vo.category|default='无'}{$vo.title}{$vo.content} + + + + {$vo.create_time|date='Y-m-d H:i:s',###} + + + + + + +
+
+ {$list->render()} +
+
+ + + diff --git a/application/admin/view/index/index.html b/application/admin/view/index/index.html index ce8eecc..a5b5367 100644 --- a/application/admin/view/index/index.html +++ b/application/admin/view/index/index.html @@ -122,6 +122,17 @@
  • 今日最佳记录
  • +
  • + + 客服管理 + + + +
  • +
    + +
    + +
    + +
    + +
    +
    @@ -242,6 +252,8 @@ query.limit_high_tie = $('#limit_high_tie').val(); query.limit_low_pair = $('#limit_low_pair').val(); query.limit_high_pair = $('#limit_high_pair').val(); + query.limit_low_nn = $('#limit_low_nn').val(); + query.limit_high_nn = $('#limit_high_nn').val(); query.type_xima = $('#xima_type').val(); query.agent_ximalv = $('#agent_ximalv').val() || 0; query.agent_ximalv_dt = $('#agent_ximalv_dt').val() || 0; @@ -320,6 +332,18 @@ }); return false; } + if(query.limit_low_nn.length == 0 || query.limit_low_nn == undefined){ + layer.alert(lang.empty_min_nn_limit,{ + title:lang.message, + }); + return false; + } + if(query.limit_high_nn.length == 0 || query.limit_high_nn == undefined){ + layer.alert(lang.empty_max_nn_limit,{ + title:lang.message, + }); + return false; + } if(query.type_xima == ''){ layer.alert(lang.empty_wash_type,{ title:lang.message, diff --git a/application/agent/view/agent/edit.html b/application/agent/view/agent/edit.html index adbd403..07b279d 100644 --- a/application/agent/view/agent/edit.html +++ b/application/agent/view/agent/edit.html @@ -81,6 +81,16 @@ +
    + +
    + +
    + +
    + +
    +
    @@ -152,6 +162,8 @@ query.limit_high_tie = $('#limit_high_tie').val(); query.limit_low_pair = $('#limit_low_pair').val(); query.limit_high_pair = $('#limit_high_pair').val(); + query.limit_low_nn = $('#limit_low_nn').val(); + query.limit_high_nn = $('#limit_high_nn').val(); query.agent_ximalv = $('#agent_ximalv').val() || 0; query.agent_ximalv_dt = $('#agent_ximalv_dt').val() || 0; query.agent_ximalv_nn = $('#agent_ximalv_nn').val() || 0; @@ -209,6 +221,20 @@ }); return false; } + if(query.limit_low_nn.length == 0 || query.limit_low_nn == undefined){ + layer.alert(lang.empty_min_nn_limit,{ + title:lang.message, + }); + return false; + } + if(query.limit_high_nn.length == 0 || query.limit_high_nn == undefined){ + layer.alert(lang.empty_max_nn_limit,{ + title:lang.message, + }); + return false; + } + return false; + } if(query.agent_ximalv.length == 0 || query.agent_ximalv == undefined){ ayer.alert(lang.empty_baccacat_rate,{ title:lang.message, diff --git a/application/agent/view/player/add.html b/application/agent/view/player/add.html index 8db047a..034f84c 100644 --- a/application/agent/view/player/add.html +++ b/application/agent/view/player/add.html @@ -547,6 +547,16 @@
    +
    + +
    + +
    + +
    + +
    +
    @@ -695,6 +705,8 @@ query.limit_high_tie = $('#limit_high_tie').val(); query.limit_low_pair = $('#limit_low_pair').val(); query.limit_high_pair = $('#limit_high_pair').val(); + query.limit_low_nn = $('#limit_low_nn').val(); + query.limit_high_nn = $('#limit_high_nn').val(); query.win_limit = $('#win_limit').val(); query.agent_commission = $('#agent_commission').val(); query.agent_commission_dt = $('#agent_commission_dt').val(); @@ -787,6 +799,18 @@ }); return false; } + if(query.limit_low_nn.length == 0 || query.limit_low_nn == undefined){ + layer.alert(lang.empty_min_nn_limit,{ + title:lang.message, + }); + return false; + } + if(query.limit_high_nn.length == 0 || query.limit_high_nn == undefined){ + layer.alert(lang.empty_max_nn_limit,{ + title:lang.message, + }); + return false; + } if(query.win_limit.length == 0 || query.win_limit == undefined){ layer.alert(lang.empty_day_win_limit,{ title:lang.message, diff --git a/application/agent/view/player/edit.html b/application/agent/view/player/edit.html index 831fe2a..64c06a6 100644 --- a/application/agent/view/player/edit.html +++ b/application/agent/view/player/edit.html @@ -134,6 +134,18 @@
    +
    + +
    + +
    +
    + +
    + +
    +
    +
    @@ -616,6 +628,8 @@ + +