From 4f663dd7613cf4a638db4c3c0b3fea9e3db62953 Mon Sep 17 00:00:00 2001 From: weifashi <605403358@qq.com> Date: Mon, 8 Jan 2024 01:20:10 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feat:=20=20=E6=B7=BB=E5=8A=A0=E5=B9=B4?= =?UTF-8?q?=E5=BA=A6=E6=8A=A5=E5=91=8A=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/UsersController.php | 150 +++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index ec4a03a87..ea39acbeb 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -18,6 +18,7 @@ use App\Models\UserBot; use App\Models\WebSocket; use App\Models\UmengAlias; use App\Models\UserDelete; +use App\Models\ProjectTask; use App\Models\UserTransfer; use App\Models\AbstractModel; use App\Models\UserCheckinMac; @@ -25,6 +26,7 @@ use App\Models\UserDepartment; use App\Models\WebSocketDialog; use App\Models\UserCheckinRecord; use App\Models\WebSocketDialogMsg; +use Illuminate\Support\Facades\DB; use App\Models\UserEmailVerification; use App\Module\AgoraIO\AgoraTokenGenerator; @@ -2002,4 +2004,152 @@ class UsersController extends AbstractController // 返回 return Base::retSuccess('success', $lists); } + + /** + * @api {get} api/users/annual/report 34. 年度报告 + * + * @apiVersion 1.0.0 + * @apiGroup users + * @apiName annual__report + * + * @apiSuccess {Number} ret 返回状态码(1正确、0错误) + * @apiSuccess {String} msg 返回信息(错误描述) + * @apiSuccess {Object} data 返回数据 + */ + public function annual__report() + { + $user = User::auth(); + // + global $_A; + if (!isset($_A["__annual__report_".$user->userid])) { + $year = '2023'; + $time = '2300-01-01 00:00:01'; + $prefix = \DB::getTablePrefix(); + $hireTimestamp = strtotime($user->created_at); + DB::statement("SET SQL_MODE=''"); + + // 我的任务 + $taskDb = DB::table('project_tasks as t') + ->join('project_task_users as tu', 't.id', '=', 'tu.task_id') + ->where('tu.owner', 1) + ->whereYear('t.created_at', $year) + ->where('tu.userid', $user->userid); + + // 我的任务 - 时长(分钟) + $durationTaskDb = $taskDb->clone() + ->selectRaw(" + {$prefix}t.id, + {$prefix}t.flow_item_name, + {$prefix}t.name as task_name, + {$prefix}p.name as project_name, + {$prefix}c.name as project_column_name, + {$prefix}t.start_at, + {$prefix}t.end_at, + {$prefix}t.complete_at, + {$prefix}t.created_at, + ifnull(TIMESTAMPDIFF(MINUTE, {$prefix}t.start_at, {$prefix}t.complete_at), 0) as duration + ") + ->leftJoin('projects as p', 'p.id', '=', 't.project_id') + ->leftJoin('project_columns as c', 'c.id', '=', 't.column_id') + ->whereNotNull('t.start_at') + ->whereNotNull('t.complete_at'); + + // + $_A["__annual__report_".$user->userid] = [ + // 入职时间(年月日) + 'hire_date' => date("Y-m-d", $hireTimestamp), + // 在职时间(天为单位) + 'tenure_days' => floor((strtotime(date('Y-m-d')) - $hireTimestamp) / (24 * 60 * 60)), + // 最晚在线时间 + 'latest_online_time' => date( + 'Y-m-d H:i:s', + UserCheckinRecord::whereUserid($user->userid) + ->whereYear('created_at', $year) + ->where(function ($query) { + $query->where(function ($query) { + $query->whereRaw('HOUR(FROM_UNIXTIME(report_time)) < 6'); + $query->whereRaw('DATE(FROM_UNIXTIME(report_time)) = CURDATE() - INTERVAL 1 DAY'); + })->orWhere(function ($query) { + $query->whereRaw('DATE(FROM_UNIXTIME(report_time)) = CURDATE()'); + }); + })->max('report_time') + ), + // 跟谁聊天最多(发消息的次数。可以是群、私聊、机器人除外) + 'longest_chat_user' => DB::table('web_socket_dialogs as d') + ->selectRaw(" + {$prefix}d.id, + {$prefix}d.name as dialog_name, + {$prefix}d.type as dialog_type, + {$prefix}d.group_type as dialog_group_type, + {$prefix}m.chat_num + ") + ->leftJoinSub(function ($query) use ($user, $year) { + $query->select('web_socket_dialog_msgs.dialog_id', DB::raw('count(*) as chat_num')) + ->from('web_socket_dialog_msgs') + ->where('web_socket_dialog_msgs.userid', $user->userid) + ->whereYear('web_socket_dialog_msgs.created_at', 2024) + ->groupBy('web_socket_dialog_msgs.dialog_id'); + }, 'm', 'm.dialog_id', '=', 'd.id') + ->leftJoin('web_socket_dialog_users as du', function ($query) use ($user) { + $query->on('d.id', '=', 'du.dialog_id'); + $query->where('d.type', 'user'); + }) + ->leftJoin('users as u', 'du.userid', '=', 'u.userid') + ->where('d.type', '!=', 'user') + ->orWhere('u.bot', 0) + ->orderByDesc('m.chat_num') + ->first(), + // 跟所有ai机器人聊天的次数 + 'chat_al_num' => DB::table('web_socket_dialog_msgs as m') + ->join('web_socket_dialogs as d', 'd.id', '=', 'm.dialog_id') + ->join('web_socket_dialog_users as du', 'd.id', '=', 'du.dialog_id') + ->join('users as u', 'du.userid', '=', 'u.userid') + ->where('u.email', 'like', "%ai-%") + ->where('u.bot', 1) + ->where('m.userid', $user->userid) + ->whereYear('m.created_at', $year) + ->count(), + // 文件创建数量 + 'file_created_num' => File::whereCreatedId($user->userid)->whereYear('created_at', $year)->count(), + // 参与过的项目 + 'projects' => DB::table('projects as p') + ->select('p.id', 'p.name') + ->join('project_users as pu', 'p.id', '=', 'pu.project_id') + ->join('project_task_users as ptu', 'p.id', '=', 'ptu.project_id') + ->where(function($query) use ($user,$year) { + $query->where('pu.userid', $user->userid); + $query->whereYear('pu.created_at', $year); + }) + ->orWhere(function($query) use ($user,$year) { + $query->where('ptu.userid', $user->userid); + $query->whereYear('ptu.created_at', $year); + }) + ->groupBy('p.id') + ->take(100) + ->get(), + // 任务统计 + 'tasks' => [ + // 总数量 + 'total' => $taskDb->count(), + // 完成数量 + 'completed' => $taskDb->clone()->whereNotNUll('t.complete_at')->count(), + // 超时数量 + 'overtime' => $taskDb->clone()->whereRaw("ifnull({$prefix}t.complete_at,'$time') > ifnull({$prefix}t.end_at,'$time')")->count(), + // 做得最久的任务 + 'longest_task' => $durationTaskDb->clone()->orderByDesc('duration')->first(), + // 做得最快的任务 + 'fastest_task' => $durationTaskDb->clone()->orderBy('duration')->first(), + // 每个月完成多少个任务 + 'month_completed_task' => $taskDb->clone() + ->selectRaw("MONTH({$prefix}t.complete_at) AS month, COUNT({$prefix}t.id) AS num") + ->whereNotNUll('t.complete_at') + ->whereYear('t.complete_at', $year) + ->groupBy('month') + ->get() + ] + ]; + } + // + return Base::retSuccess('success', $_A["__annual__report_".$user->userid]); + } } From b78e4240cb0353f8bc0a288396b7bb1b61c381ae Mon Sep 17 00:00:00 2001 From: weifashi <605403358@qq.com> Date: Mon, 8 Jan 2024 01:22:58 +0800 Subject: [PATCH 2/7] =?UTF-8?q?feat:=20=20=E6=B7=BB=E5=8A=A0=E5=B9=B4?= =?UTF-8?q?=E5=BA=A6=E6=8A=A5=E5=91=8A=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/UsersController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index ea39acbeb..a46a4fd6b 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -2087,7 +2087,7 @@ class UsersController extends AbstractController $query->select('web_socket_dialog_msgs.dialog_id', DB::raw('count(*) as chat_num')) ->from('web_socket_dialog_msgs') ->where('web_socket_dialog_msgs.userid', $user->userid) - ->whereYear('web_socket_dialog_msgs.created_at', 2024) + ->whereYear('web_socket_dialog_msgs.created_at', $year) ->groupBy('web_socket_dialog_msgs.dialog_id'); }, 'm', 'm.dialog_id', '=', 'd.id') ->leftJoin('web_socket_dialog_users as du', function ($query) use ($user) { From 7c4d537d6732fbc0ecfbf328a216048c9e3f51dd Mon Sep 17 00:00:00 2001 From: weifashi <605403358@qq.com> Date: Mon, 8 Jan 2024 01:25:44 +0800 Subject: [PATCH 3/7] =?UTF-8?q?perf:=20=20=E5=8E=BB=E6=8E=89=E6=9C=AA?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/PublicController.php | 7 ------- app/Http/Controllers/Api/UsersController.php | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/app/Http/Controllers/Api/PublicController.php b/app/Http/Controllers/Api/PublicController.php index 05980b8db..13a053536 100755 --- a/app/Http/Controllers/Api/PublicController.php +++ b/app/Http/Controllers/Api/PublicController.php @@ -2,15 +2,8 @@ namespace App\Http\Controllers\Api; -use App\Models\User; use App\Models\UserBot; -use App\Models\UserCheckinMac; -use App\Models\UserCheckinRecord; -use App\Models\WebSocketDialog; -use App\Models\WebSocketDialogMsg; use App\Module\Base; -use Cache; -use Carbon\Carbon; use Request; /** diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index a46a4fd6b..d620b06ab 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -2090,7 +2090,7 @@ class UsersController extends AbstractController ->whereYear('web_socket_dialog_msgs.created_at', $year) ->groupBy('web_socket_dialog_msgs.dialog_id'); }, 'm', 'm.dialog_id', '=', 'd.id') - ->leftJoin('web_socket_dialog_users as du', function ($query) use ($user) { + ->leftJoin('web_socket_dialog_users as du', function ($query) { $query->on('d.id', '=', 'du.dialog_id'); $query->where('d.type', 'user'); }) From 322a855ba2cd971534b487d9b7a0cbe527827a57 Mon Sep 17 00:00:00 2001 From: weifashi <605403358@qq.com> Date: Mon, 8 Jan 2024 01:26:37 +0800 Subject: [PATCH 4/7] =?UTF-8?q?perf:=20=20=E5=8E=BB=E6=8E=89=E6=9C=AA?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/UsersController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index d620b06ab..887256ac5 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -18,7 +18,6 @@ use App\Models\UserBot; use App\Models\WebSocket; use App\Models\UmengAlias; use App\Models\UserDelete; -use App\Models\ProjectTask; use App\Models\UserTransfer; use App\Models\AbstractModel; use App\Models\UserCheckinMac; From 937bc4ead3bf20d2385b6366e2641d5d87581650 Mon Sep 17 00:00:00 2001 From: weifashi <605403358@qq.com> Date: Mon, 8 Jan 2024 09:32:28 +0800 Subject: [PATCH 5/7] =?UTF-8?q?perf:=20=20=E5=B9=B4=E5=BA=A6=E6=8A=A5?= =?UTF-8?q?=E5=91=8A=E6=8E=A5=E5=8F=A3=09=20-=20=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF=E5=AD=97=E6=AE=B5=E8=BF=94?= =?UTF-8?q?=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/UsersController.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 887256ac5..034d0c02d 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -2076,12 +2076,15 @@ class UsersController extends AbstractController // 跟谁聊天最多(发消息的次数。可以是群、私聊、机器人除外) 'longest_chat_user' => DB::table('web_socket_dialogs as d') ->selectRaw(" - {$prefix}d.id, - {$prefix}d.name as dialog_name, - {$prefix}d.type as dialog_type, - {$prefix}d.group_type as dialog_group_type, - {$prefix}m.chat_num - ") + {$prefix}d.id, + {$prefix}d.name as dialog_name, + {$prefix}d.type as dialog_type, + {$prefix}d.group_type as dialog_group_type, + {$prefix}m.chat_num, + {$prefix}u.userid, + {$prefix}u.email as user_email, + {$prefix}u.nickname as user_nickname + ") ->leftJoinSub(function ($query) use ($user, $year) { $query->select('web_socket_dialog_msgs.dialog_id', DB::raw('count(*) as chat_num')) ->from('web_socket_dialog_msgs') From ebce9fa59699f608ec06b7b75293996fa2e0ac6d Mon Sep 17 00:00:00 2001 From: weifashi <605403358@qq.com> Date: Mon, 8 Jan 2024 22:58:36 +0800 Subject: [PATCH 6/7] =?UTF-8?q?feat:=20=20=E6=9B=B4=E6=96=B0okr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index ea2205aa6..24c478d41 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -177,7 +177,7 @@ services: okr: container_name: "dootask-okr-${APP_ID}" - image: "kuaifan/doookr:0.0.26" + image: "kuaifan/doookr:0.0.27" environment: TZ: "${TIMEZONE:-PRC}" DOO_TASK_URL: "http://${APP_IPPR}.3" @@ -186,6 +186,7 @@ services: MYSQL_DBNAME: "${DB_DATABASE}" MYSQL_USERNAME: "${DB_USERNAME}" MYSQL_PASSWORD: "${DB_PASSWORD}" + MYSQL_PREFIX: "${DB_PREFIX}" DEMO_DATA: true networks: extnetwork: From 5a44076859d807d61aa44a06364c619a6b877f07 Mon Sep 17 00:00:00 2001 From: weifashi <605403358@qq.com> Date: Tue, 9 Jan 2024 17:26:03 +0800 Subject: [PATCH 7/7] =?UTF-8?q?perf:=20=20=E5=B9=B4=E5=BA=A6=E6=B1=87?= =?UTF-8?q?=E6=8A=A5=E6=8E=A5=E5=8F=A3=E8=BF=94=E5=9B=9E=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=A4=B4=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/UsersController.php | 80 +++++++++++++------- 1 file changed, 53 insertions(+), 27 deletions(-) diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 034d0c02d..f8a226bf6 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -2053,8 +2053,60 @@ class UsersController extends AbstractController ->whereNotNull('t.start_at') ->whereNotNull('t.complete_at'); + // 最多聊天用户 + $longestChat = DB::table('web_socket_dialogs as d') + ->selectRaw(" + {$prefix}d.id, + {$prefix}d.name as dialog_name, + {$prefix}d.type as dialog_type, + {$prefix}d.group_type as dialog_group_type, + {$prefix}m.chat_num, + {$prefix}u.userid, + {$prefix}u.email as user_email, + {$prefix}u.nickname as user_nickname, + ifnull({$prefix}d.avatar, {$prefix}u.userimg) as avatar + ") + ->leftJoinSub(function ($query) use ($user, $year) { + $query->select('web_socket_dialog_msgs.dialog_id', DB::raw('count(*) as chat_num')) + ->from('web_socket_dialog_msgs') + ->where('web_socket_dialog_msgs.userid', $user->userid) + ->whereYear('web_socket_dialog_msgs.created_at', $year) + ->groupBy('web_socket_dialog_msgs.dialog_id'); + }, 'm', 'm.dialog_id', '=', 'd.id') + ->leftJoin('web_socket_dialog_users as du', function ($query) use ($user) { + $query->on('d.id', '=', 'du.dialog_id'); + $query->where('du.userid', '!=', $user->userid); + $query->where('d.type', 'user'); + }) + ->leftJoin('users as u', 'du.userid', '=', 'u.userid') + ->where('d.type', '!=', 'user') + ->orWhere('u.bot', 0) + ->orderByDesc('m.chat_num') + ->first(); + if (!empty($longestChat)) { + if ($longestChat->avatar) { + $longestChat->avatar = url($longestChat->avatar); + } else if ($longestChat->dialog_type == 'user') { + $longestChat->avatar = User::getAvatar($longestChat->userid, $longestChat->avatar, $longestChat->user_email, $longestChat->user_nickname); + } else { + $longestChat->avatar = match ($longestChat->dialog_group_type) { + 'department' => url("images/avatar/default_group_department.png"), + 'project' => url("images/avatar/default_group_project.png"), + 'task' => url("images/avatar/default_group_task.png"), + default => url("images/avatar/default_group_people.png"), + }; + } + } + // $_A["__annual__report_".$user->userid] = [ + // 本人信息 + 'user' => [ + 'userid' => $user->userid, + 'email' => $user->email, + 'nickname' => $user->nickname, + 'avatar' => User::getAvatar($user->userid, $user->userimg, $user->email, $user->nickname) + ], // 入职时间(年月日) 'hire_date' => date("Y-m-d", $hireTimestamp), // 在职时间(天为单位) @@ -2074,33 +2126,7 @@ class UsersController extends AbstractController })->max('report_time') ), // 跟谁聊天最多(发消息的次数。可以是群、私聊、机器人除外) - 'longest_chat_user' => DB::table('web_socket_dialogs as d') - ->selectRaw(" - {$prefix}d.id, - {$prefix}d.name as dialog_name, - {$prefix}d.type as dialog_type, - {$prefix}d.group_type as dialog_group_type, - {$prefix}m.chat_num, - {$prefix}u.userid, - {$prefix}u.email as user_email, - {$prefix}u.nickname as user_nickname - ") - ->leftJoinSub(function ($query) use ($user, $year) { - $query->select('web_socket_dialog_msgs.dialog_id', DB::raw('count(*) as chat_num')) - ->from('web_socket_dialog_msgs') - ->where('web_socket_dialog_msgs.userid', $user->userid) - ->whereYear('web_socket_dialog_msgs.created_at', $year) - ->groupBy('web_socket_dialog_msgs.dialog_id'); - }, 'm', 'm.dialog_id', '=', 'd.id') - ->leftJoin('web_socket_dialog_users as du', function ($query) { - $query->on('d.id', '=', 'du.dialog_id'); - $query->where('d.type', 'user'); - }) - ->leftJoin('users as u', 'du.userid', '=', 'u.userid') - ->where('d.type', '!=', 'user') - ->orWhere('u.bot', 0) - ->orderByDesc('m.chat_num') - ->first(), + 'longest_chat_user' => $longestChat, // 跟所有ai机器人聊天的次数 'chat_al_num' => DB::table('web_socket_dialog_msgs as m') ->join('web_socket_dialogs as d', 'd.id', '=', 'm.dialog_id')