perf: 优化人脸签到功能

This commit is contained in:
kuaifan 2024-10-21 16:19:49 +08:00
parent 2284788366
commit 58b7853d63
19 changed files with 415 additions and 176 deletions

View File

@ -671,9 +671,13 @@ class UsersController extends AbstractController
* - all: 全部
* - 其他值: 非机器人(默认)
* - keys.department 部门ID0表示默认部门不赋值获取所有部门
* - keys.checkin_mac 签到mac地址get_checkin_mac=1时有效)
* - keys.checkin_face 人脸图片get_checkin_data=1时有效)
* - yes: 仅有人脸图片
* - no: 无人脸图片
* - all: 全部
* - keys.checkin_mac 签到mac地址get_checkin_data=1时有效)
*
* @apiParam {Number} [get_checkin_mac] 获取签到mac地址
* @apiParam {Number} [get_checkin_data] 获取签到mac地址
* - 0: 不获取(默认)
* - 1: 获取
* @apiParam {Number} [page] 当前页,默认:1
@ -690,7 +694,7 @@ class UsersController extends AbstractController
$builder = User::select(['*', 'nickname as nickname_original']);
//
$keys = Request::input('keys');
$getCheckinMac = intval(Request::input('get_checkin_mac')) === 1;
$getCheckinData = intval(Request::input('get_checkin_data')) === 1;
if (is_array($keys)) {
if ($keys['key']) {
if (str_contains($keys['key'], "@")) {
@ -758,10 +762,17 @@ class UsersController extends AbstractController
$builder->orderBy("is_principal","desc");
}
}
if ($getCheckinMac && isset($keys['checkin_mac'])) {
$builder->whereIn('userid', function ($query) use ($keys) {
$query->select('userid')->from('user_checkin_macs')->where("mac", "like", "%{$keys['checkin_mac']}%");
});
if ($getCheckinData) {
if (isset($keys['checkin_face'])) {
$builder->whereIn('userid', function ($query) use ($keys) {
$query->select('userid')->from('user_checkin_faces')->whereNotNull("faceimg");
});
}
if (isset($keys['checkin_mac'])) {
$builder->whereIn('userid', function ($query) use ($keys) {
$query->select('userid')->from('user_checkin_macs')->where("mac", "like", "%{$keys['checkin_mac']}%");
});
}
}
} else {
$builder->whereNull('disable_at');
@ -769,19 +780,11 @@ class UsersController extends AbstractController
}
$list = $builder->orderByDesc('userid')->paginate(Base::getPaginate(50, 20));
//
if ($getCheckinMac) {
$list->transform(function (User $user) use ($getCheckinMac) {
if ($getCheckinMac) {
$user->checkin_macs = UserCheckinMac::select(['id', 'mac', 'remark'])->whereUserid($user->userid)->orderBy('id')->get();
}
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) : '';
}
if ($getCheckinData) {
$list->transform(function (User $user) {
$checkinFace = UserCheckinFace::select(['faceimg'])->whereUserid($user->userid)->first();
$user->checkin_face = $checkinFace ? Base::fillUrl($checkinFace->faceimg) : '';
$user->checkin_macs = UserCheckinMac::select(['id', 'mac', 'remark'])->whereUserid($user->userid)->orderBy('id')->get();
return $user;
});
}
@ -1731,7 +1734,7 @@ class UsersController extends AbstractController
// 当图片允许修改
if ($setting['faceupload'] === 'open') {
UserCheckinFace::saveFace($user->userid, $user->nickname(), $faceimg, "用户上传");
UserCheckinFace::saveFace($user->userid, $user->nickname(), $faceimg, "用户上传");
} else {
$userface = UserCheckinFace::whereUserid($user->userid)->first();
$data['faceimg'] = $userface;

View File

@ -40,8 +40,8 @@ class UserCheckinFace extends AbstractModel
$faceFile = public_path($faceimg);
$record = base64_encode(file_get_contents($faceFile));
}
$url = 'http://' . env('APP_IPPR') . '.55' . ":7788/user";
$url = 'http://' . env('APP_IPPR') . '.14' . ":7788/user";
$data = [
'name' => $nickname,
'enrollid' => $userid,
@ -51,15 +51,15 @@ class UserCheckinFace extends AbstractModel
if ($record != '') {
$data['record'] = $record;
}
$res = Ihttp::ihttp_post($url, json_encode($data), 15);
if($res['data'] && $data = json_decode($res['data'])){
if($data->ret != 1 && $data->msg){
throw new ApiException($data->msg);
}
}
return AbstractModel::transaction(function() use ($userid, $faceimg, $remark) {
$checkinFace = self::query()->whereUserid($userid)->first();
if ($checkinFace) {
@ -86,12 +86,12 @@ class UserCheckinFace extends AbstractModel
}
public static function deleteDeviceUser($userid) {
$url = 'http://' . env('APP_IPPR') . '.55' . ":7788/user/delete";
$url = 'http://' . env('APP_IPPR') . '.14' . ":7788/user/delete";
$data = [
'enrollid' => $userid,
'backupnum' => 50, // 13 删除整个用户 50 删除图片
];
$res = Ihttp::ihttp_post($url, json_encode($data));
if($res['data'] && $data = json_decode($res['data'])){
if($data->ret != 1 && $data->msg){

View File

@ -212,7 +212,7 @@ services:
- mariadb
networks:
extnetwork:
ipv4_address: "${APP_IPPR}.55"
ipv4_address: "${APP_IPPR}.14"
restart: unless-stopped
networks:

View File

@ -187,8 +187,8 @@ server {
# OKR
location /apps/okr/ {
proxy_pass http://okr:5566/apps/okr/;
}
}
# AI
location /ai/ {
proxy_http_version 1.1;

View File

@ -1660,3 +1660,21 @@ Token
(*)退出群组
(*)已加入群组
请选择类型
人脸图片
允许成员自己上传人脸图片
人脸签到
人脸打卡
WiFi签到
设备情况
修改签到人脸图片
正在进行帐号【(*)】人脸图片修改。
修改人脸图片
会员签到设置
WiFi签到延迟时长为±1分钟。
通过人脸识别机签到
已上传
未上传
修改MAC地址
获取设备信息失败

View File

@ -24334,5 +24334,197 @@
"fr": "Veuillez sélectionner un type",
"id": "Silakan pilih jenis",
"ru": "Пожалуйста, выберите тип"
},
{
"key": "人脸图片",
"zh": "",
"zh-CHT": "人臉圖片",
"en": "Face Image",
"ko": "얼굴 이미지",
"ja": "顔写真",
"de": "Gesichtsbild",
"fr": "Image du visage",
"id": "Gambar Wajah",
"ru": "Изображение лица"
},
{
"key": "允许成员自己上传人脸图片",
"zh": "",
"zh-CHT": "允許成員自己上傳人臉圖片",
"en": "Allow members to upload their own face images",
"ko": "회원이 직접 얼굴 이미지를 업로드할 수 있도록 허용",
"ja": "メンバーが自身の顔写真をアップロードすることを許可",
"de": "Mitgliedern erlauben, ihre eigenen Gesichtsbilder hochzuladen",
"fr": "Autoriser les membres à télécharger leurs propres images faciales",
"id": "Izinkan anggota mengunggah gambar wajah mereka sendiri",
"ru": "Разрешить участникам загружать собственные изображения лица"
},
{
"key": "人脸签到",
"zh": "",
"zh-CHT": "人臉簽到",
"en": "Face Check-in",
"ko": "얼굴 인식 체크인",
"ja": "顔認証チェックイン",
"de": "Gesichtserkennung Check-in",
"fr": "Enregistrement par reconnaissance faciale",
"id": "Absensi Wajah",
"ru": "Регистрация по лицу"
},
{
"key": "人脸打卡",
"zh": "",
"zh-CHT": "人臉打卡",
"en": "Face Clock-in",
"ko": "얼굴 인식 출근",
"ja": "顔認証打刻",
"de": "Gesichtserkennung Stempeluhr",
"fr": "Pointage par reconnaissance faciale",
"id": "Absen dengan Wajah",
"ru": "Отметка времени по лицу"
},
{
"key": "WiFi签到",
"zh": "",
"zh-CHT": "WiFi簽到",
"en": "WiFi Check-in",
"ko": "WiFi 체크인",
"ja": "WiFiチェックイン",
"de": "WiFi Check-in",
"fr": "Enregistrement par WiFi",
"id": "Absensi WiFi",
"ru": "Регистрация по WiFi"
},
{
"key": "设备情况",
"zh": "",
"zh-CHT": "設備情況",
"en": "Device Status",
"ko": "기기 상태",
"ja": "デバイス状況",
"de": "Gerätestatus",
"fr": "État de l'appareil",
"id": "Status Perangkat",
"ru": "Состояние устройства"
},
{
"key": "修改签到人脸图片",
"zh": "",
"zh-CHT": "修改簽到人臉圖片",
"en": "Modify Check-in Face Image",
"ko": "체크인 얼굴 이미지 수정",
"ja": "チェックイン用顔写真の変更",
"de": "Check-in Gesichtsbild ändern",
"fr": "Modifier l'image faciale d'enregistrement",
"id": "Ubah Gambar Wajah Absensi",
"ru": "Изменить изображение лица для регистрации"
},
{
"key": "正在进行帐号【(*)】人脸图片修改。",
"zh": "",
"zh-CHT": "正在進行帳號【(*)】人臉圖片修改。",
"en": "Modifying face image for account [(*)】.",
"ko": "계정 [(*)】의 얼굴 이미지를 수정 중입니다.",
"ja": "アカウント【(*)】の顔写真を変更中です。",
"de": "Gesichtsbild für Konto [(*)】 wird geändert.",
"fr": "Modification de l'image faciale pour le compte [(*)】 en cours.",
"id": "Sedang mengubah gambar wajah untuk akun [(*)】.",
"ru": "Выполняется изменение изображения лица для учетной записи [(*)】."
},
{
"key": "修改人脸图片",
"zh": "",
"zh-CHT": "修改人臉圖片",
"en": "Modify Face Image",
"ko": "얼굴 이미지 수정",
"ja": "顔写真の変更",
"de": "Gesichtsbild ändern",
"fr": "Modifier l'image faciale",
"id": "Ubah Gambar Wajah",
"ru": "Изменить изображение лица"
},
{
"key": "会员签到设置",
"zh": "",
"zh-CHT": "會員簽到設置",
"en": "Member Check-in Settings",
"ko": "회원 체크인 설정",
"ja": "メンバーチェックイン設定",
"de": "Mitglieder Check-in Einstellungen",
"fr": "Paramètres d'enregistrement des membres",
"id": "Pengaturan Absensi Anggota",
"ru": "Настройки регистрации участников"
},
{
"key": "WiFi签到延迟时长为±1分钟。",
"zh": "",
"zh-CHT": "WiFi簽到延遲時長為±1分鐘。",
"en": "WiFi check-in delay is ±1 minute.",
"ko": "WiFi 체크인 지연 시간은 ±1분입니다.",
"ja": "WiFiチェックインの遅延時間は±1分です。",
"de": "WiFi Check-in Verzögerung beträgt ±1 Minute.",
"fr": "Le délai d'enregistrement WiFi est de ±1 minute.",
"id": "Penundaan absensi WiFi adalah ±1 menit.",
"ru": "Задержка регистрации по WiFi составляет ±1 минуту."
},
{
"key": "通过人脸识别机签到",
"zh": "",
"zh-CHT": "通過人臉識別機簽到",
"en": "Check-in via Facial Recognition Device",
"ko": "얼굴 인식기를 통한 체크인",
"ja": "顔認証機でチェックイン",
"de": "Check-in über Gesichtserkennungsgerät",
"fr": "Enregistrement par dispositif de reconnaissance faciale",
"id": "Absensi melalui Mesin Pengenalan Wajah",
"ru": "Регистрация через устройство распознавания лиц"
},
{
"key": "已上传",
"zh": "",
"zh-CHT": "已上傳",
"en": "Uploaded",
"ko": "업로드 완료",
"ja": "アップロード済み",
"de": "Hochgeladen",
"fr": "Téléchargé",
"id": "Telah Diunggah",
"ru": "Загружено"
},
{
"key": "未上传",
"zh": "",
"zh-CHT": "未上傳",
"en": "Not Uploaded",
"ko": "미업로드",
"ja": "未アップロード",
"de": "Nicht hochgeladen",
"fr": "Non téléchargé",
"id": "Belum Diunggah",
"ru": "Не загружено"
},
{
"key": "修改MAC地址",
"zh": "",
"zh-CHT": "修改MAC地址",
"en": "Modify MAC Address",
"ko": "MAC 주소 수정",
"ja": "MACアドレスの変更",
"de": "MAC-Adresse ändern",
"fr": "Modifier l'adresse MAC",
"id": "Ubah Alamat MAC",
"ru": "Изменить MAC-адрес"
},
{
"key": "获取设备信息失败",
"zh": "",
"zh-CHT": "獲取設備信息失敗",
"en": "Failed to Retrieve Device Information",
"ko": "기기 정보 가져오기 실패",
"ja": "デバイス情報の取得に失敗しました",
"de": "Abrufen der Geräteinformationen fehlgeschlagen",
"fr": "Échec de la récupération des informations de l'appareil",
"id": "Gagal Mengambil Informasi Perangkat",
"ru": "Не удалось получить информацию об устройстве"
}
]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -97,14 +97,28 @@
</Select>
</div>
</li>
<li v-if="checkinMac">
<div class="search-label">
{{$L("MAC地址")}}
</div>
<div class="search-content">
<Input v-model="keys.checkin_mac" :placeholder="$L('MAC地址')" clearable/>
</div>
</li>
<template v-if="checkinMode">
<li>
<div class="search-label">
{{$L("人脸图片")}}
</div>
<div class="search-content">
<Select v-model="keys.checkin_face" :placeholder="$L('全部')">
<Option value="">{{$L('全部')}}</Option>
<Option value="yes">{{$L('已上传')}}</Option>
<Option value="no">{{$L('未上传')}}</Option>
</Select>
</div>
</li>
<li>
<div class="search-label">
{{$L("MAC地址")}}
</div>
<div class="search-content">
<Input v-model="keys.checkin_mac" :placeholder="$L('MAC地址')" clearable/>
</div>
</li>
</template>
<li v-else>
<div class="search-label">
{{$L("邮箱认证")}}
@ -251,13 +265,10 @@
<Row class="team-department-checkin-item">
<Col span="12">
<ImgUpload v-model="checkinFaceEditData.faceimg" :num="1" :width="512" :height="512" :whcut="1"></ImgUpload>
<span class="form-tip">{{$L('建议尺寸200x200')}}</span>
</Col>
<Col span="12">
<!-- <Input v-model="item.remark" :maxlength="100" :placeholder="$L('备注')"/> -->
<span class="form-tip">{{$L('建议尺寸500x500')}}</span>
</Col>
</Row>
</Form>
<div slot="footer" class="adaption">
<Button type="default" @click="checkinFaceEditShow=false">{{$L('取消')}}</Button>
@ -334,7 +345,7 @@ export default {
name: "TeamManagement",
components: {UserAvatarTip, UserSelect, ImgUpload},
props: {
checkinMac: {
checkinMode: {
type: Boolean,
default: false
},
@ -550,7 +561,7 @@ export default {
arr.push(h('span', '/'))
}
arr.push(h('span', this.$L('最后在线')))
return h('div', arr)
return h('AutoTip', arr)
},
render: (h, params) => {
const {line_at, disable_at} = params.row;
@ -573,21 +584,43 @@ export default {
render: (h, params) => {
const identity = params.row.identity;
const dropdownItems = [];
if (this.checkinMode) {
dropdownItems.push(...[
h('EDropdownItem', {
props: {
command: 'checkin_face',
},
style: {
color: '#f90',
fontWeight: 'bold'
}
}, [h('div', this.$L('修改人脸图片'))]),
h('EDropdownItem', {
props: {
command: 'checkin_mac',
},
style: {
color: '#f90',
fontWeight: 'bold'
}
}, [h('div', this.$L('修改MAC地址'))])
])
}
if (identity.includes('admin')) {
dropdownItems.push(h('EDropdownItem', {
props: {
command: 'clearadmin',
divided: this.checkinMode
},
}, [h('div', this.$L('取消管理员'))]));
} else {
dropdownItems.push(h('EDropdownItem', {
props: {
command: 'setadmin',
divided: this.checkinMode
},
}, [h('div', this.$L('设为管理员'))]));
}
if (identity.includes('temp')) {
dropdownItems.push(h('EDropdownItem', {
props: {
@ -601,46 +634,30 @@ export default {
},
}, [h('div', this.$L('设为临时帐号'))]));
}
dropdownItems.push(h('EDropdownItem', {
props: {
command: 'email',
},
}, [h('div', this.$L('修改邮箱'))]))
dropdownItems.push(h('EDropdownItem', {
props: {
command: 'password',
},
}, [h('div', this.$L('修改密码'))]))
if (this.checkinMac) {
dropdownItems.push(h('EDropdownItem', {
dropdownItems.push(...[
h('EDropdownItem', {
props: {
command: 'checkin_mac',
command: 'email',
},
}, [h('div', this.$L('修改MAC'))]))
dropdownItems.push(h('EDropdownItem', {
}, [h('div', this.$L('修改邮箱'))]),
h('EDropdownItem', {
props: {
command: 'checkin_face',
command: 'password',
},
}, [h('div', this.$L('修改人脸图片'))]))
}
dropdownItems.push(h('EDropdownItem', {
props: {
command: 'department',
},
}, [h('div', this.$L('修改部门'))]))
}, [h('div', this.$L('修改密码'))]),
h('EDropdownItem', {
props: {
command: 'department',
},
}, [h('div', this.$L('修改部门'))])
])
if (identity.includes('disable')) {
dropdownItems.push(h('EDropdownItem', {
props: {
command: 'cleardisable',
},
style: {
color: '#f90'
color: 'red'
}
}, [h('div', this.$L('恢复帐号(已离职)'))]));
} else {
@ -649,7 +666,7 @@ export default {
command: 'setdisable',
},
style: {
color: '#f90'
color: 'red'
}
}, [h('div', this.$L('操作离职'))]));
}
@ -790,59 +807,68 @@ export default {
}
},
created() {
if (this.checkinMac) {
this.columns.splice(5, 0, {
title: this.$L('设备情况'),
key: 'checkin_mac',
minWidth: 80,
render: (h, {row}) => {
let checkin_macs = $A.cloneJSON(row.checkin_macs || [])
let checkin_face = $A.cloneJSON(row.checkin_face || '')
const tmp = []
const checkin_face_desc = checkin_face ? "已上传(人脸)" : "未上传(人脸)"
if (checkin_macs.length === 0) {
if (checkin_face){
tmp.push(h('AutoTip', checkin_face_desc))
if (this.checkinMode) {
this.columns.splice(5, 0, ...[
{
key: 'checkin_face',
minWidth: 80,
renderHeader: (h) => {
return h('AutoTip', {
style: {
color: '#f90'
}
}, this.$L('人脸图片'))
},
render: (h, {row}) => {
const checkin_face = $A.cloneJSON(row.checkin_face || '')
return h('div', checkin_face ? this.$L('已上传') : '-');
},
}, {
key: 'checkin_mac',
minWidth: 80,
renderHeader: (h) => {
return h('AutoTip', {
style: {
color: '#f90'
}
}, this.$L('MAC地址'))
},
render: (h, {row}) => {
let checkin_macs = $A.cloneJSON(row.checkin_macs || [])
if (checkin_macs.length === 0) {
return h('div', '-');
} else {
const desc = (item) => {
if (item.remark) {
return `${item.mac} (${item.remark})`
}
return item.mac
}
const tmp = []
tmp.push(h('AutoTip', desc(checkin_macs[0])))
if (checkin_macs.length > 1) {
checkin_macs = checkin_macs.splice(1)
tmp.push(h('ETooltip', [
h('div', {
slot: 'content',
domProps: {
innerHTML: checkin_macs.map(item => {
return desc(item)
}).join("<br/>")
}
}),
h('div', {
class: 'department-tag-num'
}, ` +${checkin_macs.length}`)
]))
}
return h('div', {
class: 'team-table-department-warp'
}, tmp);
}
return h('div', '-');
} else {
const desc = (item) => {
if (item.remark) {
return `${item.mac} (${item.remark})`
}
return item.mac
}
const checkin_devices_desc = []
tmp.push(h('AutoTip', desc(checkin_macs[0])))
if (checkin_macs.length > 1) {
checkin_macs = checkin_macs.splice(1)
checkin_devices_desc.push(...checkin_macs.map(item => {
return desc(item)
}))
if (checkin_face) {
checkin_devices_desc.push(checkin_face_desc)
}
tmp.push(h('ETooltip', [
h('div', {
slot: 'content',
domProps: {
innerHTML: checkin_devices_desc.join("<br/>")
}
}),
h('div', {
class: 'department-tag-num'
}, ` +${checkin_devices_desc.length}`)
]))
}
return h('div', {
class: 'team-table-department-warp'
}, tmp);
}
},
})
},
}
])
}
},
mounted() {
@ -908,7 +934,7 @@ export default {
url: 'users/lists',
data: {
keys,
get_checkin_mac: this.checkinMac ? 1 : 0,
get_checkin_data: this.checkinMode ? 1 : 0,
page: Math.max(this.page, 1),
pagesize: Math.max($A.runNum(this.pageSize), 10),
},
@ -1014,7 +1040,7 @@ export default {
nickname: row.nickname,
faceimg: row.checkin_face
};
this.checkinFaceEditShow = true;
break;

View File

@ -18,12 +18,27 @@
<div class="setting-checkin-button" @click="calendarShow=true">{{$L('查看更多签到数据')}}</div>
<Divider orientation="left">{{$L('签到设置')}}</Divider>
<Alert>
{{$L('设备连接上指定路由器WiFi后自动签到。')}}
</Alert>
<div class="setting-checkin-row">
<Tabs v-model="checkinTabs" style="margin: 0;">
<TabPane :label="$L('设备MAC地址')" name="mac">
<TabPane :label="$L('人脸签到')" name="receive">
<div class="setting-checkin-row">
<Row class="setting-template">
<Col span="12">{{$L('人脸图片')}}</Col>
<Col span="12"></Col>
</Row>
<Row class="setting-template">
<Col span="12">
<ImgUpload v-model="faceimgs" :num="1" :width="512" :height="512" :whcut="1"></ImgUpload>
<span class="form-tip">{{$L('建议尺寸500x500')}}</span>
</Col>
</Row>
</div>
</TabPane>
<TabPane :label="$L('WiFi签到')" name="mac">
<Alert type="success">
{{$L('设备连接上指定路由器WiFi后自动签到。')}}
</Alert>
<Row class="setting-template">
<Col span="12">{{$L('设备MAC地址')}}</Col>
<Col span="12">{{$L('备注')}}</Col>
@ -43,26 +58,11 @@
</Row>
<Button type="default" icon="md-add" @click="addDatum">{{$L('添加设备')}}</Button>
</TabPane>
<TabPane :label="$L('人脸图片')" name="receive">
<div class="setting-checkin-row">
<Row class="setting-template">
<Col span="12">{{$L('人脸图片')}}</Col>
<Col span="12"></Col>
</Row>
<Row class="setting-template">
<Col span="12">
<ImgUpload v-model="faceimgs" :num="1" :width="512" :height="512" :whcut="1"></ImgUpload>
<span class="form-tip">{{$L('建议尺寸200x200')}}</span>
</Col>
</Row>
</div>
</TabPane>
</Tabs>
</div>
</Form>
<div class="setting-footer">
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
@ -98,7 +98,7 @@ export default {
'mac': '',
'remark': '',
},
checkinTabs: "mac",
checkinTabs: "receive",
latelyLoad: 0,
latelyData: [],

View File

@ -10,7 +10,7 @@
<Radio label="close">{{ $L('关闭') }}</Radio>
</RadioGroup>
<div class="export-data">
<p @click="allUserShow=true">{{$L('管理成员MAC地址')}}</p>
<p @click="allUserShow=true">{{$L('会员签到设置')}}</p>
<p @click="exportShow=true">{{$L('导出签到数据')}}</p>
</div>
</FormItem>
@ -51,27 +51,27 @@
</Form>
</FormItem>
<FormItem :label="$L('允许修改')" prop="edit">
<RadioGroup v-model="formData.edit">
<Radio label="open">{{ $L('允许') }}</Radio>
<Radio label="close">{{ $L('禁止') }}</Radio>
</RadioGroup>
<div class="form-tip">{{$L('允许成员自己修改MAC地址')}}</div>
<RadioGroup v-model="formData.faceupload">
<Radio label="open">{{ $L('允许') }}</Radio>
<Radio label="close">{{ $L('禁止') }}</Radio>
</RadioGroup>
<div class="form-tip">{{$L('允许成员自己上传人脸图片')}}</div>
<RadioGroup v-model="formData.edit">
<Radio label="open">{{ $L('允许') }}</Radio>
<Radio label="close">{{ $L('禁止') }}</Radio>
</RadioGroup>
<div class="form-tip">{{$L('允许成员自己修改MAC地址')}} ({{$L('WiFi签到')}})</div>
</FormItem>
<FormItem :label="$L('签到方式')" prop="modes">
<CheckboxGroup v-model="formData.modes">
<Checkbox label="auto">{{$L('自动签到')}}</Checkbox>
<Checkbox label="manual">{{$L('手动签到')}}</Checkbox>
<Checkbox label="auto">{{$L('WiFi签到')}}</Checkbox>
<Checkbox label="face">{{$L('人脸签到')}}</Checkbox>
<Checkbox label="manual">{{$L('手动签到')}}</Checkbox>
<Checkbox v-if="false" label="location">{{$L('定位签到')}}</Checkbox>
</CheckboxGroup>
<div v-if="formData.modes.includes('auto')" 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('face')" 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('face')" class="form-tip">{{$L('人脸签到')}}: {{$L('')}}</div>
<div v-if="formData.modes.includes('location')" class="form-tip">{{$L('定位签到')}}: {{$L('通过在签到打卡机器人发送位置签到')}}</div>
</FormItem>
</template>
@ -81,10 +81,10 @@
<template v-if="formData.open === 'open' && formData.modes.includes('auto')">
<div class="block-setting-space"></div>
<div class="block-setting-box">
<h3>{{ $L('自动签到') }}</h3>
<h3>{{ $L('WiFi签到') }}</h3>
<div class="form-box">
<FormItem :label="$L('安装说明')" prop="explain">
<p>1. {{ $L('自动签到延迟时长为±1分钟。') }}</p>
<p>1. {{ $L('WiFi签到延迟时长为±1分钟。') }}</p>
<p>2. {{ $L('设备连接上指定路由器WiFi后自动签到。') }}</p>
<p>3. {{ $L('仅支持Openwrt系统的路由器。') }}</p>
<p>4. {{ $L('关闭签到功能再开启需要重新安装。') }}</p>
@ -108,7 +108,7 @@
v-model="allUserShow"
placement="right"
:size="1380">
<TeamManagement v-if="allUserShow" checkin-mac/>
<TeamManagement v-if="allUserShow" checkin-mode/>
</DrawerOverlay>
</div>
</template>