mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-12 03:01:12 +00:00
Merge commit '814a488801b328daf67f86c33ac422704303dceb' into pro
# Conflicts: # app/Http/Controllers/Api/SystemController.php # public/site/en/about.html # public/site/en/download.html # public/site/en/help.html # public/site/en/index.html # public/site/en/log.html # public/site/en/price.html # public/site/en/product.html # public/site/en/solutions.html # public/site/zh/about.html # public/site/zh/download.html # public/site/zh/help.html # public/site/zh/index.html # public/site/zh/log.html # public/site/zh/price.html # public/site/zh/product.html # public/site/zh/solutions.html # resources/mobile
This commit is contained in:
commit
2284788366
@ -78,17 +78,28 @@ class PublicController extends AbstractController
|
|||||||
$key = trim(Request::input('key'));
|
$key = trim(Request::input('key'));
|
||||||
$mac = trim(Request::input('mac'));
|
$mac = trim(Request::input('mac'));
|
||||||
$time = intval(Request::input('time'));
|
$time = intval(Request::input('time'));
|
||||||
|
$type = trim(Request::input('type'));
|
||||||
//
|
//
|
||||||
$setting = Base::setting('checkinSetting');
|
$setting = Base::setting('checkinSetting');
|
||||||
if ($setting['open'] !== 'open') {
|
if ($setting['open'] !== 'open') {
|
||||||
return 'function off';
|
return 'function off';
|
||||||
}
|
}
|
||||||
if (!in_array('auto', $setting['modes'])) {
|
if ($type === 'face') {
|
||||||
return 'mode off';
|
if (!in_array('face', $setting['modes'])) {
|
||||||
}
|
return 'mode off';
|
||||||
if ($key != $setting['key']) {
|
}
|
||||||
return 'key error';
|
if ($key != $setting['face_key']) {
|
||||||
|
return 'key error';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!in_array('auto', $setting['modes'])) {
|
||||||
|
return 'mode off';
|
||||||
|
}
|
||||||
|
if ($key != $setting['key']) {
|
||||||
|
return 'key error';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($error = UserBot::checkinBotCheckin($mac, $time)) {
|
if ($error = UserBot::checkinBotCheckin($mac, $time)) {
|
||||||
return $error;
|
return $error;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -399,6 +399,7 @@ class SystemController extends AbstractController
|
|||||||
'remindin',
|
'remindin',
|
||||||
'remindexceed',
|
'remindexceed',
|
||||||
'edit',
|
'edit',
|
||||||
|
'faceupload',
|
||||||
'modes',
|
'modes',
|
||||||
'key',
|
'key',
|
||||||
])) {
|
])) {
|
||||||
@ -407,6 +408,7 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
if ($all['open'] === 'close') {
|
if ($all['open'] === 'close') {
|
||||||
$all['key'] = md5(Base::generatePassword(32));
|
$all['key'] = md5(Base::generatePassword(32));
|
||||||
|
$all['face_key'] = md5(Base::generatePassword(32));
|
||||||
} else {
|
} else {
|
||||||
$botUser = User::botGetOrCreate('check-in');
|
$botUser = User::botGetOrCreate('check-in');
|
||||||
if (!$botUser) {
|
if (!$botUser) {
|
||||||
@ -414,7 +416,7 @@ class SystemController extends AbstractController
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($all['modes']) {
|
if ($all['modes']) {
|
||||||
$all['modes'] = array_intersect($all['modes'], ['auto', 'manual', 'location']);
|
$all['modes'] = array_intersect($all['modes'], ['auto', 'manual', 'location', 'face']);
|
||||||
}
|
}
|
||||||
$setting = Base::setting('checkinSetting', Base::newTrim($all));
|
$setting = Base::setting('checkinSetting', Base::newTrim($all));
|
||||||
} else {
|
} else {
|
||||||
@ -425,8 +427,13 @@ class SystemController extends AbstractController
|
|||||||
$setting['key'] = md5(Base::generatePassword(32));
|
$setting['key'] = md5(Base::generatePassword(32));
|
||||||
Base::setting('checkinSetting', $setting);
|
Base::setting('checkinSetting', $setting);
|
||||||
}
|
}
|
||||||
|
if (empty($setting['face_key'])) {
|
||||||
|
$setting['face_key'] = md5(Base::generatePassword(32));
|
||||||
|
Base::setting('checkinSetting', $setting);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
$setting['open'] = $setting['open'] ?: 'close';
|
$setting['open'] = $setting['open'] ?: 'close';
|
||||||
|
$setting['faceupload'] = $setting['faceupload'] ?: 'close';
|
||||||
$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;
|
||||||
|
|||||||
@ -20,6 +20,7 @@ use App\Models\UmengAlias;
|
|||||||
use App\Models\UserDelete;
|
use App\Models\UserDelete;
|
||||||
use App\Models\UserTransfer;
|
use App\Models\UserTransfer;
|
||||||
use App\Models\AbstractModel;
|
use App\Models\AbstractModel;
|
||||||
|
use App\Models\UserCheckinFace;
|
||||||
use App\Models\UserCheckinMac;
|
use App\Models\UserCheckinMac;
|
||||||
use App\Models\UserDepartment;
|
use App\Models\UserDepartment;
|
||||||
use App\Models\WebSocketDialog;
|
use App\Models\WebSocketDialog;
|
||||||
@ -775,6 +776,14 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
return $user;
|
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);
|
return Base::retSuccess('success', $list);
|
||||||
@ -795,6 +804,7 @@ class UsersController extends AbstractController
|
|||||||
* - settemp 设为临时帐号
|
* - settemp 设为临时帐号
|
||||||
* - cleartemp 取消临时身份(取消临时帐号)
|
* - cleartemp 取消临时身份(取消临时帐号)
|
||||||
* - checkin_macs 修改自动签到mac地址(需要参数 checkin_macs)
|
* - checkin_macs 修改自动签到mac地址(需要参数 checkin_macs)
|
||||||
|
* - checkin_face 修改签到人脸图片(需要参数 checkin_face)
|
||||||
* - department 修改部门(需要参数 department)
|
* - department 修改部门(需要参数 department)
|
||||||
* - setdisable 设为离职(需要参数 disable_time、transfer_userid)
|
* - setdisable 设为离职(需要参数 disable_time、transfer_userid)
|
||||||
* - cleardisable 取消离职
|
* - cleardisable 取消离职
|
||||||
@ -805,6 +815,7 @@ class UsersController extends AbstractController
|
|||||||
* @apiParam {String} [nickname] 昵称
|
* @apiParam {String} [nickname] 昵称
|
||||||
* @apiParam {String} [profession] 职位
|
* @apiParam {String} [profession] 职位
|
||||||
* @apiParam {String} [checkin_macs] 自动签到mac地址
|
* @apiParam {String} [checkin_macs] 自动签到mac地址
|
||||||
|
* @apiParam {String} [checkin_face] 人脸图片地址
|
||||||
* @apiParam {String} [department] 部门
|
* @apiParam {String} [department] 部门
|
||||||
* @apiParam {String} [disable_time] 离职时间
|
* @apiParam {String} [disable_time] 离职时间
|
||||||
* @apiParam {String} [transfer_userid] 离职交接人
|
* @apiParam {String} [transfer_userid] 离职交接人
|
||||||
@ -869,6 +880,11 @@ class UsersController extends AbstractController
|
|||||||
}
|
}
|
||||||
return UserCheckinMac::saveMac($userInfo->userid, $array);
|
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':
|
case 'department':
|
||||||
if (!is_array($data['department'])) {
|
if (!is_array($data['department'])) {
|
||||||
$data['department'] = [];
|
$data['department'] = [];
|
||||||
@ -1643,8 +1659,14 @@ class UsersController extends AbstractController
|
|||||||
$user = User::auth();
|
$user = User::auth();
|
||||||
//
|
//
|
||||||
$list = UserCheckinMac::whereUserid($user->userid)->orderBy('id')->get();
|
$list = UserCheckinMac::whereUserid($user->userid)->orderBy('id')->get();
|
||||||
|
$userface = UserCheckinFace::whereUserid($user->userid)->first();
|
||||||
|
|
||||||
|
$data = [
|
||||||
|
'list' => $list,
|
||||||
|
'faceimg' => $userface ? Base::fillUrl($userface->faceimg) : ''
|
||||||
|
];
|
||||||
//
|
//
|
||||||
return Base::retSuccess('success', $list);
|
return Base::retSuccess('success', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1669,30 +1691,53 @@ class UsersController extends AbstractController
|
|||||||
if ($setting['open'] !== 'open') {
|
if ($setting['open'] !== 'open') {
|
||||||
return Base::retError('此功能未开启,请联系管理员开启');
|
return Base::retError('此功能未开启,请联系管理员开启');
|
||||||
}
|
}
|
||||||
if ($setting['edit'] !== 'open') {
|
if ($setting['edit'] !== 'open' && $setting['faceupload'] !== 'open') {
|
||||||
return Base::retError('未开放修改权限,请联系管理员');
|
return Base::retError('未开放修改权限,请联系管理员');
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
$list = Request::input('list');
|
$list = Request::input('list');
|
||||||
$array = [];
|
$faceimg = Request::input('faceimg');
|
||||||
if (empty($list) || !is_array($list)) {
|
// 默认返回值,使用用户传递数据
|
||||||
return Base::retError('参数错误');
|
$data = [
|
||||||
}
|
'list' => $list,
|
||||||
foreach ($list AS $item) {
|
'faceimg' => $faceimg
|
||||||
$item = Base::newTrim($item);
|
];
|
||||||
if (Base::isMac($item['mac'])) {
|
// 当mac允许修改
|
||||||
$mac = strtoupper($item['mac']);
|
if ($setting['edit' === 'open']) {
|
||||||
$array[$mac] = [
|
$array = [];
|
||||||
'mac' => $mac,
|
if (empty($list) || !is_array($list)) {
|
||||||
'remark' => substr($item['remark'], 0, 50),
|
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'];
|
||||||
|
} else {
|
||||||
|
$list = UserCheckinMac::whereUserid($user->userid)->orderBy('id')->get();
|
||||||
|
$data['list'] = $list;
|
||||||
}
|
}
|
||||||
if (count($array) > 3) {
|
|
||||||
return Base::retError('最多只能添加3个MAC地址');
|
|
||||||
|
// 当图片允许修改
|
||||||
|
if ($setting['faceupload'] === 'open') {
|
||||||
|
UserCheckinFace::saveFace($user->userid, $user->nickname(), $faceimg, "用户上传");
|
||||||
|
} else {
|
||||||
|
$userface = UserCheckinFace::whereUserid($user->userid)->first();
|
||||||
|
$data['faceimg'] = $userface;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
return UserCheckinMac::saveMac($user->userid, $array);
|
return Base::retSuccess('修改成功', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -234,6 +234,19 @@ class UserBot extends AbstractModel
|
|||||||
'remark' => '手动签到',
|
'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) {
|
if ($array) {
|
||||||
$record = UserCheckinRecord::where($array)->first();
|
$record = UserCheckinRecord::where($array)->first();
|
||||||
|
|||||||
103
app/Models/UserCheckinFace.php
Normal file
103
app/Models/UserCheckinFace.php
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Exceptions\ApiException;
|
||||||
|
use App\Module\Base;
|
||||||
|
use App\Module\Ihttp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App\Models\UserCheckinFace
|
||||||
|
*
|
||||||
|
* @property int $id
|
||||||
|
* @property int|null $userid 会员id
|
||||||
|
* @property string|null $faceimg 人脸图片
|
||||||
|
* @property int|null $status 状态
|
||||||
|
* @property string|null $remark 备注
|
||||||
|
* @property \Illuminate\Support\Carbon|null $created_at
|
||||||
|
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace newModelQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace newQuery()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace query()
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace whereCreatedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace whereFaceimg($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace whereId($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace whereRemark($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace whereStatus($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace whereUpdatedAt($value)
|
||||||
|
* @method static \Illuminate\Database\Eloquent\Builder|UserCheckinFace whereUserid($value)
|
||||||
|
* @mixin \Eloquent
|
||||||
|
*/
|
||||||
|
class UserCheckinFace extends AbstractModel
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function saveFace($userid, $nickname, $faceimg, $remark='')
|
||||||
|
{
|
||||||
|
// 取上传图片的URL
|
||||||
|
$faceimg = Base::unFillUrl($faceimg);
|
||||||
|
$record = "";
|
||||||
|
if ($faceimg != '') {
|
||||||
|
$faceFile = public_path($faceimg);
|
||||||
|
$record = base64_encode(file_get_contents($faceFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = 'http://' . env('APP_IPPR') . '.55' . ":7788/user";
|
||||||
|
$data = [
|
||||||
|
'name' => $nickname,
|
||||||
|
'enrollid' => $userid,
|
||||||
|
'admin' => 0,
|
||||||
|
'backupnum' => 50,
|
||||||
|
];
|
||||||
|
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) {
|
||||||
|
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, // 13 删除整个用户 50 删除图片
|
||||||
|
];
|
||||||
|
|
||||||
|
$res = Ihttp::ihttp_post($url, json_encode($data));
|
||||||
|
if($res['data'] && $data = json_decode($res['data'])){
|
||||||
|
if($data->ret != 1 && $data->msg){
|
||||||
|
throw new ApiException($data->msg);
|
||||||
|
// return Base::retError($data->msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateUserCheckinFacesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
if (Schema::hasTable('user_checkin_faces'))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Schema::create('user_checkin_faces', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('id');
|
||||||
|
$table->bigInteger('userid')->nullable()->default(0)->comment('会员id');
|
||||||
|
$table->string('faceimg')->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');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -193,6 +193,27 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- mariadb
|
- mariadb
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
face:
|
||||||
|
container_name: "dootask-face-${APP_ID}"
|
||||||
|
image: "hitosea2020/dooface:0.0.1"
|
||||||
|
ports:
|
||||||
|
- "7788:7788"
|
||||||
|
environment:
|
||||||
|
TZ: "${TIMEZONE:-PRC}"
|
||||||
|
STORAGE: mysql
|
||||||
|
MYSQL_HOST: "${DB_HOST}"
|
||||||
|
MYSQL_PORT: "${DB_PORT}"
|
||||||
|
MYSQL_USERNAME: "${DB_USERNAME}"
|
||||||
|
MYSQL_PASSWORD: "${DB_PASSWORD}"
|
||||||
|
MYSQL_DB_NAME: "${DB_DATABASE}"
|
||||||
|
DB_PREFIX: "${DB_PREFIX}"
|
||||||
|
REPORT_API: "http://${APP_IPPR}.3:80/api/public/checkin/report"
|
||||||
|
depends_on:
|
||||||
|
- mariadb
|
||||||
|
networks:
|
||||||
|
extnetwork:
|
||||||
|
ipv4_address: "${APP_IPPR}.55"
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
extnetwork:
|
extnetwork:
|
||||||
|
|||||||
@ -237,6 +237,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
|
|
||||||
|
<!--修改Face-->
|
||||||
|
<Modal
|
||||||
|
v-model="checkinFaceEditShow"
|
||||||
|
:title="$L('修改签到人脸图片')">
|
||||||
|
<Form :model="checkinMacEditData" label-width="auto" @submit.native.prevent>
|
||||||
|
<Alert type="error" style="margin-bottom:18px">{{$L(`正在进行帐号【ID:${checkinFaceEditData.userid},${checkinFaceEditData.nickname}】人脸图片修改。`)}}</Alert>
|
||||||
|
<Row class="team-department-checkin-item">
|
||||||
|
<Col span="12">{{$L('人脸图片')}}</Col>
|
||||||
|
<Col span="12"></Col>
|
||||||
|
</Row>
|
||||||
|
<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('备注')"/> -->
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
</Form>
|
||||||
|
<div slot="footer" class="adaption">
|
||||||
|
<Button type="default" @click="checkinFaceEditShow=false">{{$L('取消')}}</Button>
|
||||||
|
<Button type="primary" :loading="checkinFaceEditLoading > 0" @click="operationUser(checkinFaceEditData, true)">{{$L('确定修改')}}</Button>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
|
||||||
<!--修改部门-->
|
<!--修改部门-->
|
||||||
<Modal
|
<Modal
|
||||||
v-model="departmentEditShow"
|
v-model="departmentEditShow"
|
||||||
@ -300,10 +328,11 @@
|
|||||||
<script>
|
<script>
|
||||||
import UserSelect from "../../../components/UserSelect.vue";
|
import UserSelect from "../../../components/UserSelect.vue";
|
||||||
import UserAvatarTip from "../../../components/UserAvatar/tip.vue";
|
import UserAvatarTip from "../../../components/UserAvatar/tip.vue";
|
||||||
|
import ImgUpload from "../../../components/ImgUpload";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "TeamManagement",
|
name: "TeamManagement",
|
||||||
components: {UserAvatarTip, UserSelect},
|
components: {UserAvatarTip, UserSelect, ImgUpload},
|
||||||
props: {
|
props: {
|
||||||
checkinMac: {
|
checkinMac: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -591,6 +620,12 @@ export default {
|
|||||||
command: 'checkin_mac',
|
command: 'checkin_mac',
|
||||||
},
|
},
|
||||||
}, [h('div', this.$L('修改MAC'))]))
|
}, [h('div', this.$L('修改MAC'))]))
|
||||||
|
|
||||||
|
dropdownItems.push(h('EDropdownItem', {
|
||||||
|
props: {
|
||||||
|
command: 'checkin_face',
|
||||||
|
},
|
||||||
|
}, [h('div', this.$L('修改人脸图片'))]))
|
||||||
}
|
}
|
||||||
|
|
||||||
dropdownItems.push(h('EDropdownItem', {
|
dropdownItems.push(h('EDropdownItem', {
|
||||||
@ -671,6 +706,10 @@ export default {
|
|||||||
checkinMacEditLoading: 0,
|
checkinMacEditLoading: 0,
|
||||||
checkinMacEditData: {},
|
checkinMacEditData: {},
|
||||||
|
|
||||||
|
checkinFaceEditShow: false,
|
||||||
|
checkinFaceEditLoading: 0,
|
||||||
|
checkinFaceEditData: {},
|
||||||
|
|
||||||
departmentEditShow: false,
|
departmentEditShow: false,
|
||||||
departmentEditLoading: 0,
|
departmentEditLoading: 0,
|
||||||
departmentEditData: {},
|
departmentEditData: {},
|
||||||
@ -753,12 +792,21 @@ export default {
|
|||||||
created() {
|
created() {
|
||||||
if (this.checkinMac) {
|
if (this.checkinMac) {
|
||||||
this.columns.splice(5, 0, {
|
this.columns.splice(5, 0, {
|
||||||
title: this.$L('MAC地址'),
|
title: this.$L('设备情况'),
|
||||||
key: 'checkin_mac',
|
key: 'checkin_mac',
|
||||||
minWidth: 80,
|
minWidth: 80,
|
||||||
render: (h, {row}) => {
|
render: (h, {row}) => {
|
||||||
let checkin_macs = $A.cloneJSON(row.checkin_macs || [])
|
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_macs.length === 0) {
|
||||||
|
if (checkin_face){
|
||||||
|
tmp.push(h('AutoTip', checkin_face_desc))
|
||||||
|
return h('div', {
|
||||||
|
class: 'team-table-department-warp'
|
||||||
|
}, tmp);
|
||||||
|
}
|
||||||
return h('div', '-');
|
return h('div', '-');
|
||||||
} else {
|
} else {
|
||||||
const desc = (item) => {
|
const desc = (item) => {
|
||||||
@ -767,22 +815,26 @@ export default {
|
|||||||
}
|
}
|
||||||
return item.mac
|
return item.mac
|
||||||
}
|
}
|
||||||
const tmp = []
|
const checkin_devices_desc = []
|
||||||
tmp.push(h('AutoTip', desc(checkin_macs[0])))
|
tmp.push(h('AutoTip', desc(checkin_macs[0])))
|
||||||
if (checkin_macs.length > 1) {
|
if (checkin_macs.length > 1) {
|
||||||
checkin_macs = checkin_macs.splice(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', [
|
tmp.push(h('ETooltip', [
|
||||||
h('div', {
|
h('div', {
|
||||||
slot: 'content',
|
slot: 'content',
|
||||||
domProps: {
|
domProps: {
|
||||||
innerHTML: checkin_macs.map(item => {
|
innerHTML: checkin_devices_desc.join("<br/>")
|
||||||
return desc(item)
|
|
||||||
}).join("<br/>")
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
h('div', {
|
h('div', {
|
||||||
class: 'department-tag-num'
|
class: 'department-tag-num'
|
||||||
}, ` +${checkin_macs.length}`)
|
}, ` +${checkin_devices_desc.length}`)
|
||||||
]))
|
]))
|
||||||
}
|
}
|
||||||
return h('div', {
|
return h('div', {
|
||||||
@ -955,6 +1007,16 @@ export default {
|
|||||||
}
|
}
|
||||||
this.checkinMacEditShow = true;
|
this.checkinMacEditShow = true;
|
||||||
break;
|
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':
|
case 'department':
|
||||||
let departments = []
|
let departments = []
|
||||||
@ -1026,6 +1088,14 @@ export default {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (data.type == 'checkin_macs') {
|
if (data.type == 'checkin_macs') {
|
||||||
this.checkinMacEditLoading++;
|
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') {
|
} else if (data.type == 'department') {
|
||||||
this.departmentEditLoading++;
|
this.departmentEditLoading++;
|
||||||
} else if (data.type == 'setdisable') {
|
} else if (data.type == 'setdisable') {
|
||||||
@ -1042,6 +1112,8 @@ export default {
|
|||||||
resolve()
|
resolve()
|
||||||
if (data.type == 'checkin_macs') {
|
if (data.type == 'checkin_macs') {
|
||||||
this.checkinMacEditShow = false;
|
this.checkinMacEditShow = false;
|
||||||
|
} else if (data.type == 'checkin_face') {
|
||||||
|
this.checkinFaceEditShow = false;
|
||||||
} else if (data.type == 'department') {
|
} else if (data.type == 'department') {
|
||||||
this.departmentEditShow = false;
|
this.departmentEditShow = false;
|
||||||
} else if (data.type == 'setdisable') {
|
} else if (data.type == 'setdisable') {
|
||||||
@ -1056,6 +1128,8 @@ export default {
|
|||||||
}).finally(_ => {
|
}).finally(_ => {
|
||||||
if (data.type == 'checkin_macs') {
|
if (data.type == 'checkin_macs') {
|
||||||
this.checkinMacEditLoading--;
|
this.checkinMacEditLoading--;
|
||||||
|
} else if (data.type == 'checkin_face') {
|
||||||
|
this.checkinFaceEditLoading--;
|
||||||
} else if (data.type == 'department') {
|
} else if (data.type == 'department') {
|
||||||
this.departmentEditLoading--;
|
this.departmentEditLoading--;
|
||||||
} else if (data.type == 'setdisable') {
|
} else if (data.type == 'setdisable') {
|
||||||
|
|||||||
@ -22,25 +22,47 @@
|
|||||||
{{$L('设备连接上指定路由器(WiFi)后自动签到。')}}
|
{{$L('设备连接上指定路由器(WiFi)后自动签到。')}}
|
||||||
</Alert>
|
</Alert>
|
||||||
<div class="setting-checkin-row">
|
<div class="setting-checkin-row">
|
||||||
<Row class="setting-template">
|
<Tabs v-model="checkinTabs" style="margin: 0;">
|
||||||
<Col span="12">{{$L('设备MAC地址')}}</Col>
|
<TabPane :label="$L('设备MAC地址')" name="mac">
|
||||||
<Col span="12">{{$L('备注')}}</Col>
|
<Row class="setting-template">
|
||||||
</Row>
|
<Col span="12">{{$L('设备MAC地址')}}</Col>
|
||||||
<Row v-for="(item, key) in formData" :key="key" class="setting-template">
|
<Col span="12">{{$L('备注')}}</Col>
|
||||||
<Col span="12">
|
</Row>
|
||||||
<Input
|
<Row v-for="(item, key) in formData" :key="key" class="setting-template">
|
||||||
v-model="item.mac"
|
<Col span="12">
|
||||||
:maxlength="20"
|
<Input
|
||||||
:placeholder="$L('请输入设备MAC地址')"
|
v-model="item.mac"
|
||||||
clearable
|
:maxlength="20"
|
||||||
@on-clear="delDatum(key)"/>
|
:placeholder="$L('请输入设备MAC地址')"
|
||||||
</Col>
|
clearable
|
||||||
<Col span="12">
|
@on-clear="delDatum(key)"/>
|
||||||
<Input v-model="item.remark" :maxlength="100" :placeholder="$L('备注')"/>
|
</Col>
|
||||||
</Col>
|
<Col span="12">
|
||||||
</Row>
|
<Input v-model="item.remark" :maxlength="100" :placeholder="$L('备注')"/>
|
||||||
</div>
|
</Col>
|
||||||
<Button type="default" icon="md-add" @click="addDatum">{{$L('添加设备')}}</Button>
|
</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>
|
</Form>
|
||||||
<div class="setting-footer">
|
<div class="setting-footer">
|
||||||
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
|
<Button :loading="loadIng > 0" type="primary" @click="submitForm">{{$L('提交')}}</Button>
|
||||||
@ -59,9 +81,10 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import CheckinCalendar from "../components/CheckinCalendar";
|
import CheckinCalendar from "../components/CheckinCalendar";
|
||||||
|
import ImgUpload from "../../../components/ImgUpload";
|
||||||
export default {
|
export default {
|
||||||
name: "ManageCheckin",
|
name: "ManageCheckin",
|
||||||
components: {CheckinCalendar},
|
components: {CheckinCalendar, ImgUpload},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -69,10 +92,13 @@ export default {
|
|||||||
|
|
||||||
formData: [],
|
formData: [],
|
||||||
|
|
||||||
|
faceimgs: [],
|
||||||
|
|
||||||
nullDatum: {
|
nullDatum: {
|
||||||
'mac': '',
|
'mac': '',
|
||||||
'remark': '',
|
'remark': '',
|
||||||
},
|
},
|
||||||
|
checkinTabs: "mac",
|
||||||
|
|
||||||
latelyLoad: 0,
|
latelyLoad: 0,
|
||||||
latelyData: [],
|
latelyData: [],
|
||||||
@ -104,7 +130,8 @@ export default {
|
|||||||
this.$store.dispatch("call", {
|
this.$store.dispatch("call", {
|
||||||
url: 'users/checkin/get',
|
url: 'users/checkin/get',
|
||||||
}).then(({data}) => {
|
}).then(({data}) => {
|
||||||
this.formData = data.length > 0 ? data : [$A.cloneJSON(this.nullDatum)];
|
this.formData = data.list.length > 0 ? data.list : [$A.cloneJSON(this.nullDatum)];
|
||||||
|
this.faceimgs = data.faceimg
|
||||||
this.formData_bak = $A.cloneJSON(this.formData);
|
this.formData_bak = $A.cloneJSON(this.formData);
|
||||||
}).catch(({msg}) => {
|
}).catch(({msg}) => {
|
||||||
$A.modalError(msg);
|
$A.modalError(msg);
|
||||||
@ -124,14 +151,16 @@ export default {
|
|||||||
remark: item.remark.trim()
|
remark: item.remark.trim()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
const faceimg = this.faceimgs ? 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},
|
data: {list, faceimg},
|
||||||
method: 'post',
|
method: 'post',
|
||||||
}).then(({data}) => {
|
}).then(({data}) => {
|
||||||
this.formData = data;
|
this.formData = data.list;
|
||||||
|
this.faceimgs = data.faceimg
|
||||||
this.formData_bak = $A.cloneJSON(this.formData);
|
this.formData_bak = $A.cloneJSON(this.formData);
|
||||||
$A.messageSuccess('修改成功');
|
$A.messageSuccess('修改成功');
|
||||||
}).catch(({msg}) => {
|
}).catch(({msg}) => {
|
||||||
|
|||||||
@ -56,15 +56,22 @@
|
|||||||
<Radio label="close">{{ $L('禁止') }}</Radio>
|
<Radio label="close">{{ $L('禁止') }}</Radio>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
<div class="form-tip">{{$L('允许成员自己修改MAC地址')}}</div>
|
<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>
|
||||||
</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('自动签到')}}</Checkbox>
|
<Checkbox label="auto">{{$L('自动签到')}}</Checkbox>
|
||||||
<Checkbox label="manual">{{$L('手动签到')}}</Checkbox>
|
<Checkbox label="manual">{{$L('手动签到')}}</Checkbox>
|
||||||
|
<Checkbox label="face">{{$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('自动签到')}}: {{$L('详情看下文安装说明')}}</div>
|
<div v-if="formData.modes.includes('auto')" 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('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>
|
<div v-if="formData.modes.includes('location')" class="form-tip">{{$L('定位签到')}}: {{$L('通过在签到打卡机器人发送位置签到')}}</div>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</template>
|
</template>
|
||||||
@ -119,6 +126,7 @@ export default {
|
|||||||
|
|
||||||
formData: {
|
formData: {
|
||||||
open: '',
|
open: '',
|
||||||
|
faceupload: '',
|
||||||
edit: '',
|
edit: '',
|
||||||
cmd: '',
|
cmd: '',
|
||||||
modes: [],
|
modes: [],
|
||||||
|
|||||||
2
resources/assets/js/store/actions.js
vendored
2
resources/assets/js/store/actions.js
vendored
@ -24,7 +24,7 @@ export default {
|
|||||||
await $A.IDBRemove("cacheVersion")
|
await $A.IDBRemove("cacheVersion")
|
||||||
}
|
}
|
||||||
const cacheVersion = await $A.IDBString("cacheVersion")
|
const cacheVersion = await $A.IDBString("cacheVersion")
|
||||||
if (cacheVersion !== state.cacheVersion) {
|
if (cacheVersion && cacheVersion !== state.cacheVersion) {
|
||||||
await dispatch("handleClearCache")
|
await dispatch("handleClearCache")
|
||||||
} else {
|
} else {
|
||||||
await dispatch("handleReadCache")
|
await dispatch("handleReadCache")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user