perf: 优化人脸签到设置

This commit is contained in:
kuaifan 2024-10-24 10:55:58 +08:00
parent 287b6b396d
commit d6ddc5ff88
7 changed files with 119 additions and 69 deletions

View File

@ -65,7 +65,9 @@ class PublicController extends AbstractController
} }
/** /**
* {post} 签到 - 路由器openwrt上报 * {post} 签到 - 上报
* - 1、路由器openwrt签到上报
* - 2、考勤机签到上报
* *
* @apiParam {String} key * @apiParam {String} key
* @apiParam {String} mac 使用逗号分割多个 * @apiParam {String} mac 使用逗号分割多个
@ -84,6 +86,7 @@ class PublicController extends AbstractController
if ($setting['open'] !== 'open') { if ($setting['open'] !== 'open') {
return 'function off'; return 'function off';
} }
$alreadyTip = false;
if ($type === 'face') { if ($type === 'face') {
if (!in_array('face', $setting['modes'])) { if (!in_array('face', $setting['modes'])) {
return 'mode off'; return 'mode off';
@ -91,6 +94,7 @@ class PublicController extends AbstractController
if ($key != $setting['face_key']) { if ($key != $setting['face_key']) {
return 'key error'; return 'key error';
} }
$alreadyTip = $setting['face_retip'] === 'open';
} else { } else {
if (!in_array('auto', $setting['modes'])) { if (!in_array('auto', $setting['modes'])) {
return 'mode off'; return 'mode off';
@ -99,8 +103,7 @@ class PublicController extends AbstractController
return 'key error'; return 'key error';
} }
} }
if ($error = UserBot::checkinBotCheckin($mac, $time, $alreadyTip)) {
if ($error = UserBot::checkinBotCheckin($mac, $time)) {
return $error; return $error;
} }
return 'success'; return 'success';

View File

@ -399,7 +399,10 @@ class SystemController extends AbstractController
'remindin', 'remindin',
'remindexceed', 'remindexceed',
'edit', 'edit',
'faceupload', 'face_upload',
'face_remark',
'face_retip',
'manual_remark',
'modes', 'modes',
'key', 'key',
])) { ])) {
@ -433,7 +436,10 @@ class SystemController extends AbstractController
} }
// //
$setting['open'] = $setting['open'] ?: 'close'; $setting['open'] = $setting['open'] ?: 'close';
$setting['faceupload'] = $setting['faceupload'] ?: 'close'; $setting['face_upload'] = $setting['face_upload'] ?: 'close';
$setting['face_remark'] = $setting['face_remark'] ?: Doo::translate('考勤机');
$setting['face_retip'] = $setting['face_retip'] ?: 'open';
$setting['manual_remark'] = $setting['manual_remark'] ?: Doo::translate('手动签到');
$setting['time'] = $setting['time'] ? Base::json2array($setting['time']) : ['09:00', '18:00']; $setting['time'] = $setting['time'] ? Base::json2array($setting['time']) : ['09:00', '18:00'];
$setting['advance'] = intval($setting['advance']) ?: 120; $setting['advance'] = intval($setting['advance']) ?: 120;
$setting['delay'] = intval($setting['delay']) ?: 120; $setting['delay'] = intval($setting['delay']) ?: 120;

View File

@ -1680,7 +1680,11 @@ class UsersController extends AbstractController
* @apiGroup users * @apiGroup users
* @apiName checkin__save * @apiName checkin__save
* *
* @apiParam {Array} list 优先级数据,格式:[{mac,remark}] * @apiParam {String} type 类型
* - face: 人脸识别设置
* - mac: MAC设置
* @apiParam {String} faceimg 人脸图片地址
* @apiParam {Array} list 优先级数据,格式:[{mac,remark}]
* *
* @apiSuccess {Number} ret 返回状态码1正确、0错误 * @apiSuccess {Number} ret 返回状态码1正确、0错误
* @apiSuccess {String} msg 返回信息(错误描述) * @apiSuccess {String} msg 返回信息(错误描述)
@ -1694,52 +1698,52 @@ class UsersController extends AbstractController
if ($setting['open'] !== 'open') { if ($setting['open'] !== 'open') {
return Base::retError('此功能未开启,请联系管理员开启'); return Base::retError('此功能未开启,请联系管理员开启');
} }
if ($setting['edit'] !== 'open' && $setting['faceupload'] !== 'open') {
return Base::retError('未开放修改权限,请联系管理员');
}
// //
$type = Request::input('type');
$list = Request::input('list'); $list = Request::input('list');
$faceimg = Request::input('faceimg'); $faceimg = Request::input('faceimg');
// 默认返回值,使用用户传递数据 //
$data = [ $data = [
'list' => $list, 'list' => $list,
'faceimg' => $faceimg 'faceimg' => $faceimg
]; ];
// 当mac允许修改 switch ($type) {
if ($setting['edit' === 'open']) { case 'face':
$array = []; if ($setting['face_upload'] !== 'open') {
if (empty($list) || !is_array($list)) { return Base::retError('未开放修改权限,请联系管理员');
return Base::retError('参数错误');
}
foreach ($list AS $item) {
$item = Base::newTrim($item);
if (Base::isMac($item['mac'])) {
$mac = strtoupper($item['mac']);
$array[$mac] = [
'mac' => $mac,
'remark' => substr($item['remark'], 0, 50),
];
} }
} UserCheckinFace::saveFace($user->userid, $user->nickname(), $faceimg, "用户上传");
if (count($array) > 3) { break;
return Base::retError('最多只能添加3个MAC地址');
} case 'mac':
$saveMacRes = UserCheckinMac::saveMac($user->userid, $array); if ($setting['edit'] !== 'open') {
$data['list'] = $saveMacRes['data']; return Base::retError('未开放修改权限,请联系管理员');
} else { }
$list = UserCheckinMac::whereUserid($user->userid)->orderBy('id')->get(); $array = [];
$data['list'] = $list; if (empty($list) || !is_array($list)) {
return Base::retError('参数错误');
}
foreach ($list as $item) {
$item = Base::newTrim($item);
if (Base::isMac($item['mac'])) {
$mac = strtoupper($item['mac']);
$array[$mac] = [
'mac' => $mac,
'remark' => substr($item['remark'], 0, 50),
];
}
}
if (count($array) > 3) {
return Base::retError('最多只能添加3个MAC地址');
}
$saveMacRes = UserCheckinMac::saveMac($user->userid, $array);
$data['list'] = $saveMacRes['data'];
break;
default:
return Base::retError('参数错误');
} }
//
// 当图片允许修改
if ($setting['faceupload'] === 'open') {
UserCheckinFace::saveFace($user->userid, $user->nickname(), $faceimg, "用户上传");
} else {
$userface = UserCheckinFace::whereUserid($user->userid)->first();
$data['faceimg'] = $userface;
}
return Base::retSuccess('修改成功', $data); return Base::retSuccess('修改成功', $data);
} }

View File

@ -231,7 +231,7 @@ class UserBot extends AbstractModel
]; ];
$checkins[] = [ $checkins[] = [
'userid' => $UserInfo->userid, 'userid' => $UserInfo->userid,
'remark' => '手动签到', 'remark' => $setting['manual_remark'] ?: 'Manual',
]; ];
} }
} elseif (Base::leftExists($mac, "checkin-", true)) { } elseif (Base::leftExists($mac, "checkin-", true)) {
@ -244,7 +244,7 @@ class UserBot extends AbstractModel
]; ];
$checkins[] = [ $checkins[] = [
'userid' => $UserInfo->userid, 'userid' => $UserInfo->userid,
'remark' => '考勤机', 'remark' => $setting['face_remark'] ?: 'Machine',
]; ];
} }
} }
@ -278,6 +278,7 @@ class UserBot extends AbstractModel
if (Cache::get($cacheKey) === "yes") { if (Cache::get($cacheKey) === "yes") {
if ($alreadyTip && $dialog = WebSocketDialog::checkUserDialog($botUser, $checkin['userid'])) { if ($alreadyTip && $dialog = WebSocketDialog::checkUserDialog($botUser, $checkin['userid'])) {
$text = "今日已{$typeContent}打卡,无需重复打卡。"; $text = "今日已{$typeContent}打卡,无需重复打卡。";
$text .= $checkin['remark'] ? " ({$checkin['remark']})": "";
WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [ WebSocketDialogMsg::sendMsg(null, $dialog->id, 'template', [
'type' => 'content', 'type' => 'content',
'content' => $text, 'content' => $text,

View File

@ -1147,7 +1147,7 @@ export default {
type: data.type, type: data.type,
userid: data.userid, userid: data.userid,
nickname: data.nickname, nickname: data.nickname,
checkin_face: data.faceimg[0] ? data.faceimg[0].url : '' checkin_face: $A.arrayLength(data.faceimg) > 0 ? data.faceimg[0].url : ''
} }
} else if (data.type == 'department') { } else if (data.type == 'department') {
this.departmentEditLoading++; this.departmentEditLoading++;

View File

@ -20,7 +20,7 @@
<Divider orientation="left">{{ $L('签到设置') }}</Divider> <Divider orientation="left">{{ $L('签到设置') }}</Divider>
<div class="setting-checkin-row"> <div class="setting-checkin-row">
<Tabs v-model="checkinTabs" style="margin: 0;"> <Tabs v-model="checkinTabs" style="margin: 0;">
<TabPane :label="$L('人脸签到')" name="receive"> <TabPane :label="$L('人脸签到')" name="face">
<Row class="setting-template"> <Row class="setting-template">
<Col span="24">{{ $L('人脸图片') }}</Col> <Col span="24">{{ $L('人脸图片') }}</Col>
</Row> </Row>
@ -84,14 +84,13 @@ export default {
loadIng: 0, loadIng: 0,
formData: [], formData: [],
faceimgs: [], faceimgs: [],
nullDatum: { nullDatum: {
'mac': '', 'mac': '',
'remark': '', 'remark': '',
}, },
checkinTabs: "receive", checkinTabs: "face",
latelyLoad: 0, latelyLoad: 0,
latelyData: [], latelyData: [],
@ -144,12 +143,16 @@ export default {
remark: item.remark.trim() remark: item.remark.trim()
} }
}); });
const faceimg = this.faceimgs ? this.faceimgs[0].url : '' const faceimg = $A.arrayLength(this.faceimgs) > 0 ? this.faceimgs[0].url : ''
// //
this.loadIng++; this.loadIng++;
this.$store.dispatch("call", { this.$store.dispatch("call", {
url: 'users/checkin/save', url: 'users/checkin/save',
data: {list, faceimg}, data: {
type: this.checkinTabs,
list,
faceimg,
},
method: 'post', method: 'post',
}).then(({data}) => { }).then(({data}) => {
this.formData = data.list; this.formData = data.list;

View File

@ -56,7 +56,7 @@
</Form> </Form>
</FormItem> </FormItem>
<FormItem :label="$L('允许修改')" prop="edit"> <FormItem :label="$L('允许修改')" prop="edit">
<RadioGroup v-model="formData.faceupload"> <RadioGroup v-model="formData.face_upload">
<Radio label="open">{{ $L('允许') }}</Radio> <Radio label="open">{{ $L('允许') }}</Radio>
<Radio label="close">{{ $L('禁止') }}</Radio> <Radio label="close">{{ $L('禁止') }}</Radio>
</RadioGroup> </RadioGroup>
@ -69,13 +69,13 @@
</FormItem> </FormItem>
<FormItem :label="$L('签到方式')" prop="modes"> <FormItem :label="$L('签到方式')" prop="modes">
<CheckboxGroup v-model="formData.modes"> <CheckboxGroup v-model="formData.modes">
<Checkbox label="auto">{{$L('WiFi签到')}}</Checkbox>
<Checkbox label="face">{{$L('人脸签到')}}</Checkbox> <Checkbox label="face">{{$L('人脸签到')}}</Checkbox>
<Checkbox label="auto">{{$L('WiFi签到')}}</Checkbox>
<Checkbox label="manual">{{$L('手动签到')}}</Checkbox> <Checkbox label="manual">{{$L('手动签到')}}</Checkbox>
<Checkbox v-if="false" label="location">{{$L('定位签到')}}</Checkbox> <Checkbox v-if="false" label="location">{{$L('定位签到')}}</Checkbox>
</CheckboxGroup> </CheckboxGroup>
<div v-if="formData.modes.includes('auto')" class="form-tip">{{$L('WiFi签到')}}: {{$L('详情看下文安装说明')}}</div>
<div v-if="formData.modes.includes('face')" class="form-tip">{{$L('人脸签到')}}: {{$L('通过人脸识别机签到')}}</div> <div v-if="formData.modes.includes('face')" class="form-tip">{{$L('人脸签到')}}: {{$L('通过人脸识别机签到')}}</div>
<div v-if="formData.modes.includes('auto')" class="form-tip">{{$L('WiFi签到')}}: {{$L('详情看下文安装说明')}}</div>
<div v-if="formData.modes.includes('manual')" class="form-tip">{{$L('手动签到')}}: {{$L('通过在签到打卡机器人发送指令签到')}}</div> <div v-if="formData.modes.includes('manual')" class="form-tip">{{$L('手动签到')}}: {{$L('通过在签到打卡机器人发送指令签到')}}</div>
<div v-if="formData.modes.includes('location')" class="form-tip">{{$L('定位签到')}}: {{$L('通过在签到打卡机器人发送位置签到')}}</div> <div v-if="formData.modes.includes('location')" class="form-tip">{{$L('定位签到')}}: {{$L('通过在签到打卡机器人发送位置签到')}}</div>
</FormItem> </FormItem>
@ -83,21 +83,51 @@
</div> </div>
</div> </div>
<template v-if="formData.open === 'open' && formData.modes.includes('auto')"> <template v-if="formData.open === 'open'">
<div class="block-setting-space"></div> <template v-if="formData.modes.includes('face')">
<div class="block-setting-box"> <div class="block-setting-space"></div>
<h3>{{ $L('WiFi签到') }}</h3> <div class="block-setting-box">
<div class="form-box"> <h3>{{ $L('人脸签到') }}</h3>
<FormItem :label="$L('安装说明')" prop="explain"> <div class="form-box">
<p>1. {{ $L('WiFi签到延迟时长为±1分钟。') }}</p> <FormItem :label="$L('签到备注')" prop="face_remark">
<p>2. {{ $L('设备连接上指定路由器WiFi后自动签到。') }}</p> <Input :maxlength="30" v-model="formData.face_remark"/>
<p>3. {{ $L('仅支持Openwrt系统的路由器。') }}</p> </FormItem>
<p>4. {{ $L('关闭签到功能再开启需要重新安装。') }}</p> <FormItem :label="$L('重复打卡提醒')" prop="face_retip">
<p>5. {{ $L('进入路由器终端执行以下命令即可完成安装') }}:</p> <RadioGroup v-model="formData.face_retip">
<Input ref="cmd" @on-focus="clickCmd" style="margin-top:6px" type="textarea" readonly :value="formData.cmd"/> <Radio label="open">{{ $L('开启') }}</Radio>
</FormItem> <Radio label="close">{{ $L('关闭') }}</Radio>
</RadioGroup>
</FormItem>
</div>
</div> </div>
</div> </template>
<template v-if="formData.modes.includes('auto')">
<div class="block-setting-space"></div>
<div class="block-setting-box">
<h3>{{ $L('WiFi签到') }}</h3>
<div class="form-box">
<FormItem :label="$L('安装说明')" prop="explain">
<p>1. {{ $L('WiFi签到延迟时长为±1分钟。') }}</p>
<p>2. {{ $L('设备连接上指定路由器WiFi后自动签到。') }}</p>
<p>3. {{ $L('仅支持Openwrt系统的路由器。') }}</p>
<p>4. {{ $L('关闭签到功能再开启需要重新安装。') }}</p>
<p>5. {{ $L('进入路由器终端执行以下命令即可完成安装') }}:</p>
<Input ref="cmd" @on-focus="clickCmd" style="margin-top:6px" type="textarea" readonly :value="formData.cmd"/>
</FormItem>
</div>
</div>
</template>
<template v-if="formData.modes.includes('manual')">
<div class="block-setting-space"></div>
<div class="block-setting-box">
<h3>{{ $L('手动签到') }}</h3>
<div class="form-box">
<FormItem :label="$L('签到备注')" prop="manual_remark">
<Input :maxlength="30" v-model="formData.manual_remark"/>
</FormItem>
</div>
</div>
</template>
</template> </template>
</Form> </Form>
<div class="setting-footer"> <div class="setting-footer">
@ -132,10 +162,13 @@ export default {
formData: { formData: {
open: '', open: '',
faceupload: '',
edit: '', edit: '',
cmd: '', cmd: '',
modes: [], modes: [],
face_upload: '',
face_remark: '',
face_retip: '',
manual_remark: '',
}, },
ruleData: {}, ruleData: {},