From 5413457b6b8503798572e96b12f1a8d7957a70a8 Mon Sep 17 00:00:00 2001 From: yijixx Date: Sun, 29 Sep 2024 17:31:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E4=BA=BA=E8=84=B8?= =?UTF-8?q?=E6=89=93=E5=8D=A1=E8=AE=BE=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Http/Controllers/Api/SystemController.php | 2 + app/Http/Controllers/Api/UsersController.php | 54 ++++++++- app/Models/UserBot.php | 15 ++- app/Models/UserCheckinFace.php | 108 ++++++++++++++++++ ...135805_create_user_checkin_faces_table.php | 38 ++++++ .../manage/components/TeamManagement.vue | 63 +++++++++- .../js/pages/manage/setting/checkin.vue | 27 ++++- .../setting/components/SystemCheckin.vue | 6 + resources/mobile | 2 +- 9 files changed, 305 insertions(+), 10 deletions(-) create mode 100644 app/Models/UserCheckinFace.php create mode 100644 database/migrations/2024_09_27_135805_create_user_checkin_faces_table.php diff --git a/app/Http/Controllers/Api/SystemController.php b/app/Http/Controllers/Api/SystemController.php index d07f292e6..583b86213 100755 --- a/app/Http/Controllers/Api/SystemController.php +++ b/app/Http/Controllers/Api/SystemController.php @@ -393,6 +393,7 @@ class SystemController extends AbstractController 'remindin', 'remindexceed', 'edit', + 'faceupload', 'modes', 'key', ])) { @@ -414,6 +415,7 @@ class SystemController extends AbstractController } // $setting['open'] = $setting['open'] ?: 'close'; + $setting['faceupload'] = $setting['faceupload'] ?: 'close'; $setting['time'] = $setting['time'] ? Base::json2array($setting['time']) : ['09:00', '18:00']; $setting['advance'] = intval($setting['advance']) ?: 120; $setting['delay'] = intval($setting['delay']) ?: 120; diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 567d08647..b77f6b3ab 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -20,6 +20,7 @@ use App\Models\UmengAlias; use App\Models\UserDelete; use App\Models\UserTransfer; use App\Models\AbstractModel; +use App\Models\UserCheckinFace; use App\Models\UserCheckinMac; use App\Models\UserDepartment; use App\Models\WebSocketDialog; @@ -775,6 +776,14 @@ class UsersController extends AbstractController } return $user; }); + // user_face + $list->transform(function (User $user) use ($getCheckinMac) { + if ($getCheckinMac) { + $checkinFace = UserCheckinFace::query()->whereUserid($user->userid)->first(); + $user->checkin_face = $checkinFace ? Base::fillUrl($checkinFace->faceimg) : ''; + } + return $user; + }); } // return Base::retSuccess('success', $list); @@ -795,6 +804,7 @@ class UsersController extends AbstractController * - settemp 设为临时帐号 * - cleartemp 取消临时身份(取消临时帐号) * - checkin_macs 修改自动签到mac地址(需要参数 checkin_macs) + * - checkin_face 修改签到人脸图片(需要参数 checkin_face) * - department 修改部门(需要参数 department) * - setdisable 设为离职(需要参数 disable_time、transfer_userid) * - cleardisable 取消离职 @@ -805,6 +815,7 @@ class UsersController extends AbstractController * @apiParam {String} [nickname] 昵称 * @apiParam {String} [profession] 职位 * @apiParam {String} [checkin_macs] 自动签到mac地址 + * @apiParam {String} [checkin_face] 人脸图片地址 * @apiParam {String} [department] 部门 * @apiParam {String} [disable_time] 离职时间 * @apiParam {String} [transfer_userid] 离职交接人 @@ -869,6 +880,11 @@ class UsersController extends AbstractController } return UserCheckinMac::saveMac($userInfo->userid, $array); + case 'checkin_face': + $faceimg = $data['checkin_face'] ? $data['checkin_face'] : ''; + + return UserCheckinFace::saveFace($userInfo->userid, $userInfo->nickname, $faceimg, "管理员上传"); + case 'department': if (!is_array($data['department'])) { $data['department'] = []; @@ -1643,8 +1659,16 @@ class UsersController extends AbstractController $user = User::auth(); // $list = UserCheckinMac::whereUserid($user->userid)->orderBy('id')->get(); + $userface = UserCheckinFace::whereUserid($user->userid)->first(); + + // 组装数据 + // TODO 如何获取http连接 + $data = [ + 'list' => $list, + 'faceimg'=> $userface ? Base::fillUrl($userface->faceimg) : '' + ]; // - return Base::retSuccess('success', $list); + return Base::retSuccess('success', $data); } /** @@ -1674,6 +1698,7 @@ class UsersController extends AbstractController } // $list = Request::input('list'); + $faceimg = Request::input('faceimg'); $array = []; if (empty($list) || !is_array($list)) { return Base::retError('参数错误'); @@ -1691,8 +1716,31 @@ class UsersController extends AbstractController if (count($array) > 3) { return Base::retError('最多只能添加3个MAC地址'); } - // - return UserCheckinMac::saveMac($user->userid, $array); + // TODO 后续考虑是否单独写一个接口 + if ($setting['faceupload'] !== 'open' && $faceimg != '') { + return Base::retError('未开放修改权限,请联系管理员'); + } + if ($setting['faceupload'] === 'open') { + try{ + $saveFaceRes = UserCheckinFace::saveFace($user->userid, $user->nickname(), $faceimg, "用户上传"); + if ($saveFaceRes['ret'] == 0) { + return $saveFaceRes; + } + } catch(\Throwable) { + + } + + } + $saveMacRes = UserCheckinMac::saveMac($user->userid, $array); + + + $data = [ + 'list' => $saveMacRes['data'], + 'faceimg' => $faceimg + ]; + $saveMacRes['data'] = $data; + return $saveMacRes; + } /** diff --git a/app/Models/UserBot.php b/app/Models/UserBot.php index b311acd5e..016c6d6f6 100644 --- a/app/Models/UserBot.php +++ b/app/Models/UserBot.php @@ -223,7 +223,20 @@ class UserBot extends AbstractModel 'remark' => '手动签到', ]; } - } + } elseif (Base::leftExists($mac, "checkin-", true)) { + $mac = Base::leftDelete($mac, "checkin-", true); + if ($UserInfo = User::whereUserid($mac)->whereBot(0)->first()) { + $array = [ + 'userid' => $UserInfo->userid, + 'mac' => '00:00:00:00:00:00', + 'date' => $nowDate, + ]; + $checkins[] = [ + 'userid' => $UserInfo->userid, + 'remark' => '考勤机', + ]; + } + } if ($array) { $record = UserCheckinRecord::where($array)->first(); if (empty($record)) { diff --git a/app/Models/UserCheckinFace.php b/app/Models/UserCheckinFace.php new file mode 100644 index 000000000..377531472 --- /dev/null +++ b/app/Models/UserCheckinFace.php @@ -0,0 +1,108 @@ + $nickname, + 'enrollid' => $userid, + 'admin' => 0, + 'backupnum' => 50, + ]; + if ($record != '') { + $data['record'] = $record; + } + + $res = Ihttp::ihttp_post($url, json_encode($data)); + if($res['data'] && $data = json_decode($res['data'])){ + if($data->ret != 1 && $data->msg){ + return Base::retError($data->msg); + } + } + + + return AbstractModel::transaction(function() use ($userid, $faceimg, $remark) { + // self::updateInsert([ + // 'userid' => $userid, + // 'faceimg' => $faceimg, + // 'status' => 1, + // 'remark' => $remark + // ]); + $checkinFace = self::query()->whereUserid($userid)->first(); + if ($checkinFace) { + self::updateData(['id' => $checkinFace->id], [ + 'faceimg' => $faceimg, + 'status' => 1, + 'remark' => $remark + ]); + } else { + $checkinFace = new UserCheckinFace(); + $checkinFace->faceimg = $faceimg; + $checkinFace->userid = $userid; + $checkinFace->remark = $remark; + $checkinFace->save(); + } + if ($faceimg == '') { + $res = UserCheckinFace::deleteDeviceUser($userid); + if ($res) { + return $res; + } + } + return Base::retSuccess('上传成功'); + }); + } + + public static function deleteDeviceUser($userid) { + $url = 'http://' . env('APP_IPPR') . '.55' . ":7788/user/delete"; + $data = [ + 'enrollid' => $userid, + 'backupnum' => 50, + ]; + + $res = Ihttp::ihttp_post($url, json_encode($data)); + if($res['data'] && $data = json_decode($res['data'])){ + if($data->ret != 1 && $data->msg){ + return Base::retError($data->msg); + } + } + } +} diff --git a/database/migrations/2024_09_27_135805_create_user_checkin_faces_table.php b/database/migrations/2024_09_27_135805_create_user_checkin_faces_table.php new file mode 100644 index 000000000..c1e1bd376 --- /dev/null +++ b/database/migrations/2024_09_27_135805_create_user_checkin_faces_table.php @@ -0,0 +1,38 @@ +bigIncrements('id'); + $table->bigInteger('userid')->nullable()->default(0)->comment('会员id'); + $table->string('faceimg', 100)->nullable()->default('')->comment('人脸图片'); + $table->integer('status')->nullable()->default(0)->comment('状态'); + $table->string('remark',100)->nullable()->default('')->comment('备注'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('user_checkin_faces'); + } +} diff --git a/resources/assets/js/pages/manage/components/TeamManagement.vue b/resources/assets/js/pages/manage/components/TeamManagement.vue index b9917f379..260ea5b0f 100644 --- a/resources/assets/js/pages/manage/components/TeamManagement.vue +++ b/resources/assets/js/pages/manage/components/TeamManagement.vue @@ -237,6 +237,34 @@ + + + +
+ {{$L(`正在进行帐号【ID:${checkinFaceEditData.userid},${checkinFaceEditData.nickname}】人脸图片修改。`)}} + + {{$L('人脸图片')}} + + + + + + {{$L('建议尺寸:200x200')}} + + + + + + +
+
+ + +
+
+ import UserSelect from "../../../components/UserSelect.vue"; import UserAvatarTip from "../../../components/UserAvatar/tip.vue"; +import ImgUpload from "../../../components/ImgUpload"; export default { name: "TeamManagement", - components: {UserAvatarTip, UserSelect}, + components: {UserAvatarTip, UserSelect, ImgUpload}, props: { checkinMac: { type: Boolean, @@ -587,6 +616,12 @@ export default { command: 'checkin_mac', }, }, [h('div', this.$L('修改MAC'))])) + + dropdownItems.push(h('EDropdownItem', { + props: { + command: 'checkin_face', + }, + }, [h('div', this.$L('修改人脸图片'))])) } dropdownItems.push(h('EDropdownItem', { @@ -667,6 +702,10 @@ export default { checkinMacEditLoading: 0, checkinMacEditData: {}, + checkinFaceEditShow: false, + checkinFaceEditLoading: 0, + checkinFaceEditData: {}, + departmentEditShow: false, departmentEditLoading: 0, departmentEditData: {}, @@ -951,6 +990,16 @@ export default { } this.checkinMacEditShow = true; break; + case 'checkin_face': + this.checkinFaceEditData = { + type: 'checkin_face', + userid: row.userid, + nickname: row.nickname, + faceimg: row.checkin_face + }; + + this.checkinFaceEditShow = true; + break; case 'department': let departments = [] @@ -1022,6 +1071,14 @@ export default { return new Promise((resolve, reject) => { if (data.type == 'checkin_macs') { this.checkinMacEditLoading++; + } else if (data.type == 'checkin_face') { + this.checkinFaceEditLoading++; + data = { + type: data.type, + userid: data.userid, + nickname: data.nickname, + checkin_face: data.faceimg[0] ? data.faceimg[0].url : '' + } } else if (data.type == 'department') { this.departmentEditLoading++; } else if (data.type == 'setdisable') { @@ -1038,6 +1095,8 @@ export default { resolve() if (data.type == 'checkin_macs') { this.checkinMacEditShow = false; + } else if (data.type == 'checkin_face') { + this.checkinFaceEditShow = false; } else if (data.type == 'department') { this.departmentEditShow = false; } else if (data.type == 'setdisable') { @@ -1052,6 +1111,8 @@ export default { }).finally(_ => { if (data.type == 'checkin_macs') { this.checkinMacEditLoading--; + } else if (data.type == 'checkin_face') { + this.checkinFaceEditLoading--; } else if (data.type == 'department') { this.departmentEditLoading--; } else if (data.type == 'setdisable') { diff --git a/resources/assets/js/pages/manage/setting/checkin.vue b/resources/assets/js/pages/manage/setting/checkin.vue index 1e7706fcc..3a5173c2c 100644 --- a/resources/assets/js/pages/manage/setting/checkin.vue +++ b/resources/assets/js/pages/manage/setting/checkin.vue @@ -41,6 +41,19 @@ +
+ + {{$L('人脸图片')}} + + + + + + + {{$L('建议尺寸:200x200')}} + + +