feat(后台工地): 添加工地时间 2.完善工人注册字段

master
yin5th 2023-01-12 14:57:41 +08:00
parent 6f1d50bffa
commit 8696374aff
8 changed files with 173 additions and 133 deletions

View File

@ -549,7 +549,7 @@ class User extends Base
$input = input('post.'); $input = input('post.');
// 人打卡 // 普通人打卡
if ($customer['role'] == Account::ROLE_NORMAL && $this->normalSign($accountId, $input['type'])) { if ($customer['role'] == Account::ROLE_NORMAL && $this->normalSign($accountId, $input['type'])) {
return $this->json(); return $this->json();
} }
@ -584,6 +584,12 @@ class User extends Base
return $this->json(4001, '今日已打过此卡'); return $this->json(4001, '今日已打过此卡');
} }
// 是否在打卡时间
$worktime = Worksite::worktime($input['worksite_id']);
switch ($input['type']) {
// case ClockLog::
}
$data = [ $data = [
'account_id' => $accountId, 'account_id' => $accountId,
'type' => $input['type'], 'type' => $input['type'],

View File

@ -96,7 +96,7 @@ class Worker extends Base
$fields = [ $fields = [
'real_name', 'mobile', 'pay', 'emergency_contact', 'emergency_phone', 'bank_card_name', 'bank_card_number', 'real_name', 'mobile', 'pay', 'emergency_contact', 'emergency_phone', 'bank_card_name', 'bank_card_number',
'bank_name', 'card_number', 'position', 'worksite_id', 'certificate', 'address_now', 'province', 'city', 'area', 'bank_name', 'card_number', 'position', 'worksite_id', 'certificate', 'address_now', 'province', 'city', 'area',
'id_front', 'id_back', 'bank_card_img' 'id_front', 'id_back', 'bank_card_img', 'work_experience'
]; ];
$post = array_filter($post, function ($item, $key) use ($fields) { $post = array_filter($post, function ($item, $key) use ($fields) {
return in_array($key, $fields); return in_array($key, $fields);
@ -182,119 +182,6 @@ class Worker extends Base
return $this->json(); return $this->json();
} }
/**
* 工人打卡
*/
public function sign(): Json
{
try {
$accountId = $this->request->user['user_id'] ?? 0;
if (!$customer = Account::findById($accountId)) {
return $this->json(6001, '请先登录');
}
if ($customer['role'] == Account::ROLE_NORMAL) {
return $this->normalSign();
}
$input = input('post.');
$rules = [
'type|打卡类型' => 'require|in:morning_on,morning_off,afternoon_on,afternoon_off',
'lat|维度' => 'require',
'lng|经度' => 'require',
'worksite_id|工地' => 'require|number',
];
$validate = $this->validateByApi($input, $rules, ['type.in' => '打卡类型错误']);
if ($validate !== true) {
return $validate;
}
if ($customer['role'] != Account::ROLE_WORKER) {
return $this->json(4003, '完成审核后方可打卡');
}
Config::load('extra/base', 'base');
$baseConfig = config('base');
$signArea = $baseConfig['sign_area'] ?? 200;
$worksite = Worksite::getNearest($input['lng'], $input['lat'], $signArea);
if (empty($worksite) || $worksite['id'] != $input['worksite_id']) {
return $this->json(4004, '不在打卡范围!');
}
$time = time();
// $time = $time - 86401 * 3;
$now = date('Y-m-d H:i:s', $time);
$day = date('Ymd', $time);
if (ClockLog::where('account_id', $accountId)->where('type', $input['type'])->where('create_time', '>', time() - 60)->count()) {
return $this->json(4001, '打卡频率过快!');
}
ClockLog::create([
'account_id' => $accountId,
'type' => $input['type'],
'worksite_id' => $input['worksite_id'],
'created_at' => $now,
'create_time' => $time,
'day' => $day,
'indexs' => $accountId.'-'.$input['worksite_id'].'-'.$day,
]);
// 创建当日工资初始记录
PayLog::createWhenNotExists($accountId, $input['worksite_id'], $day);
} catch (Exception $e) {
Log::error('工人打卡失败'.$e->getMessage());
return $this->json(5000, '打卡失败!');
}
return $this->json();
}
private function normalSign($customer)
{
try {
Config::load('extra/base', 'base');
$baseConfig = config('base');
$signArea = $baseConfig['sign_area'] ?? 200;
$worksite = Worksite::getNearest($input['lng'], $input['lat'], $signArea);
if (empty($worksite) || $worksite['id'] != $input['worksite_id']) {
return $this->json(4004, '不在打卡范围!');
}
$time = time();
// $time = $time - 86401 * 3;
$now = date('Y-m-d H:i:s', $time);
$day = date('Ymd', $time);
if (ClockLog::where('account_id', $accountId)->where('type', $input['type'])->where('create_time', '>', time() - 60)->count()) {
return $this->json(4001, '打卡频率过快!');
}
ClockLog::create([
'account_id' => $accountId,
'type' => $input['type'],
'worksite_id' => $input['worksite_id'],
'created_at' => $now,
'create_time' => $time,
'day' => $day,
'indexs' => $accountId.'-'.$input['worksite_id'].'-'.$day,
]);
// 创建当日工资初始记录
PayLog::createWhenNotExists($accountId, $input['worksite_id'], $day);
} catch (Exception $e) {
Log::error('工人打卡失败'.$e->getMessage());
return $this->json(5000, '打卡失败!');
}
return $this->json();
}
// 我的打卡 // 我的打卡
public function clockList(): Json public function clockList(): Json
{ {

View File

@ -62,7 +62,7 @@ class Worksite extends Base
$statusText = \app\model\Worksite::statusText(); $statusText = \app\model\Worksite::statusText();
$res['list']->each(function ($item) use ($statusText) { $res['list']->each(function ($item) use ($statusText) {
$item->status_text = $statusText[$item->status] ?? ''; $item->status_text = $statusText[$item->status] ?? '';
$item->manager = ($item->nickname ? '昵称:'.$item->nickname : '') .($item->real_name ? ' 姓名:'.$item->real_name : ''). ($item->mobile ? ' 手机:'.$item->mobile : ''); $item->manager = ($item->nickname ? '昵称:'.$item->nickname : '').($item->real_name ? ' 姓名:'.$item->real_name : '').($item->mobile ? ' 手机:'.$item->mobile : '');
}); });
} }
@ -94,6 +94,32 @@ class Worksite extends Base
'manager_id' => $input['manager_id'] ?? 0, 'manager_id' => $input['manager_id'] ?? 0,
]; ];
if (!isset($input['am']) || !isset($input['pm'])) {
return $this->json(4000, '工作时间必填');
}
$amArr = explode('-', $input['am']);
$pmArr = explode('-', $input['pm']);
$morningOn = trim($amArr[0]);
$morningOff = trim($amArr[1]);
$afternoonOn = trim($pmArr[0]);
$afternoonOff = trim($pmArr[1]);
if ($morningOn >= $morningOff || $afternoonOn >= $afternoonOff || $morningOff > $afternoonOn) {
return $this->json(4000, '工作时间设置错误');
}
$insert['morning_on'] = $morningOn;
$insert['morning_off'] = $morningOff;
$insert['afternoon_on'] = $afternoonOn;
$insert['afternoon_off'] = $afternoonOff;
$insert['start_at'] = time();//明天生效
$insert['old_morning_on'] = $morningOn;
$insert['old_morning_off'] = $morningOff;
$insert['old_afternoon_on'] = $afternoonOn;
$insert['old_afternoon_off'] = $afternoonOff;
if ($input['manager_id'] > 0) { if ($input['manager_id'] > 0) {
if (AccountWorksite::where('account_id', $input['manager_id'])->count() > 0) { if (AccountWorksite::where('account_id', $input['manager_id'])->count() > 0) {
return $this->json(4003, '该负责人已绑定其他工地'); return $this->json(4003, '该负责人已绑定其他工地');
@ -111,7 +137,6 @@ class Worksite extends Base
Account::where('id', $input['manager_id'])->save(['role' => Account::ROLE_MANAGER, 'worksite_id' => $item->id]); Account::where('id', $input['manager_id'])->save(['role' => Account::ROLE_MANAGER, 'worksite_id' => $item->id]);
} }
return $this->json(); return $this->json();
} catch (Exception $e) { } catch (Exception $e) {
return $this->json(4001, '添加失败'.$e->getMessage()); return $this->json(4001, '添加失败'.$e->getMessage());
@ -143,10 +168,50 @@ class Worksite extends Base
if ($this->request->isPost()) { if ($this->request->isPost()) {
try { try {
$input = input('post.'); $input = input('post.');
// 需要更新的字段
$update = [
'name' => $input['name'] ?? '',
'lng' => $input['lng'] ?? '',
'lat' => $input['lat'] ?? '',
'address' => $input['address'] ?? '',
'manager_id' => $input['manager_id'] ?? 0,
];
if (!isset($input['name']) || !isset($input['lng']) || !isset($input['lat'])) { if (!isset($input['name']) || !isset($input['lng']) || !isset($input['lat'])) {
return $this->json(4000, '参数错误'); return $this->json(4000, '参数错误');
} }
if (!isset($input['am']) || !isset($input['pm'])) {
return $this->json(4000, '工作时间必填');
}
$amArr = explode('-', $input['am']);
$pmArr = explode('-', $input['pm']);
$morningOn = trim($amArr[0]);
$morningOff = trim($amArr[1]);
$afternoonOn = trim($pmArr[0]);
$afternoonOff = trim($pmArr[1]);
if ($morningOn >= $morningOff || $afternoonOn >= $afternoonOff || $morningOff > $afternoonOn) {
return $this->json(4000, '工作时间设置错误');
}
// 工作时间是否有变更
// 若工作时间有变更 第二天生效时间在start_at前时使用old_系列时间
if ($item['morning_on'] != $morningOn || $item['morning_off'] != $morningOff
|| $item['afternoon_on'] != $afternoonOn || $item['afternoon_off'] != $afternoonOff) {
$update['morning_on'] = $morningOn;
$update['morning_off'] = $morningOff;
$update['afternoon_on'] = $afternoonOn;
$update['afternoon_off'] = $afternoonOff;
$update['start_at'] = strtotime('23:59:59') + 1;//明天生效
$update['old_morning_on'] = $item['morning_on'] ?: $morningOn;
$update['old_morning_off'] = $item['morning_off'] ?: $morningOff;
$update['old_afternoon_on'] = $item['afternoon_on'] ?: $afternoonOn;
$update['old_afternoon_off'] = $item['afternoon_off'] ?: $afternoonOff;
}
Account::where('id', $item['manager_id'])->save(['role' => Account::ROLE_NORMAL]); Account::where('id', $item['manager_id'])->save(['role' => Account::ROLE_NORMAL]);
AccountWorksite::where('worksite_id', $id)->delete(); AccountWorksite::where('worksite_id', $id)->delete();
if ($input['manager_id'] > 0) { if ($input['manager_id'] > 0) {
@ -161,13 +226,7 @@ class Worksite extends Base
Account::where('id', $input['manager_id'])->save(['role' => Account::ROLE_MANAGER, 'worksite_id' => $id]); Account::where('id', $input['manager_id'])->save(['role' => Account::ROLE_MANAGER, 'worksite_id' => $id]);
} }
$item->save([ $item->save($update);
'name' => $input['name'] ?? '',
'lng' => $input['lng'] ?? '',
'lat' => $input['lat'] ?? '',
'address' => $input['address'] ?? '',
'manager_id' => $input['manager_id'] ?? 0,
]);
return $this->json(); return $this->json();
} catch (Exception $e) { } catch (Exception $e) {
return $this->json(5000, $e->getMessage()); return $this->json(5000, $e->getMessage());
@ -180,12 +239,14 @@ class Worksite extends Base
foreach ($bindAccount as $ac) { foreach ($bindAccount as $ac) {
$accountList[] = [ $accountList[] = [
'name_text' => $ac['nickname'].'【姓名:'.$ac['real_name'].'】【手机:'.$ac['mobile'].'】', 'name_text' => $ac['nickname'].'【姓名:'.$ac['real_name'].'】【手机:'.$ac['mobile'].'】',
'id' => $ac['id'], 'selected' => true 'id' => $ac['id'], 'selected' => true
]; ];
} }
$this->data['jsonStr'] = $bindAccount ? json_encode($accountList, JSON_UNESCAPED_UNICODE) : json_encode([]); $item['am'] = $item['morning_on'].' - '.$item['morning_off'];
$this->data['item'] = $item; $item['pm'] = $item['afternoon_on'].' - '.$item['afternoon_off'];
$this->data['id'] = $id; $this->data['jsonStr'] = $bindAccount ? json_encode($accountList, JSON_UNESCAPED_UNICODE) : json_encode([]);
$this->data['item'] = $item;
$this->data['id'] = $id;
return $this->view(); return $this->view();
} }

View File

@ -86,7 +86,7 @@ class Account extends Base
{ {
return [ return [
'real_name', 'mobile', 'position', 'pay', 'emergency_contact', 'emergency_phone', 'bank_card_name', 'bank_card_number', 'real_name', 'mobile', 'position', 'pay', 'emergency_contact', 'emergency_phone', 'bank_card_name', 'bank_card_number',
'bank_name', 'card_number', 'bank_card_img', 'id_front', 'id_back', 'certificate' 'bank_name', 'card_number', 'bank_card_img', 'id_front', 'id_back', 'certificate', 'work_experience'
]; ];
} }
} }

View File

@ -30,7 +30,6 @@ class ClockLog extends Base
public static function typeText(): array public static function typeText(): array
{ {
return [ return [
self::TYPE_NORMAL => '普通打卡',
self::TYPE_MORNING_ON => '上午上班', self::TYPE_MORNING_ON => '上午上班',
self::TYPE_MORNING_OFF => '上午下班', self::TYPE_MORNING_OFF => '上午下班',
self::TYPE_AFTERNOON_ON => '下午上班', self::TYPE_AFTERNOON_ON => '下午上班',
@ -58,7 +57,7 @@ class ClockLog extends Base
* @return bool true=单位时间有打卡 false=单位时间未打卡 * @return bool true=单位时间有打卡 false=单位时间未打卡
* @throws \think\db\exception\DbException * @throws \think\db\exception\DbException
*/ */
public static function checkRate(int $accountId, string $type = self::TYPE_NORMAL, int $worksiteId = 0, int $seconds = 60): bool public static function checkRate(int $accountId, string $type = self::TYPE_MORNING_ON, int $worksiteId = 0, int $seconds = 60): bool
{ {
return self::where('account_id', $accountId) return self::where('account_id', $accountId)
->where('type', $type) ->where('type', $type)

View File

@ -149,4 +149,39 @@ class Worksite extends Base
return $result; return $result;
} }
/**
* 获取工地工作时间
*
* @param int $worksiteId 工地ID
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function worktime(int $worksiteId): array
{
if (!$worksite = self::where('id', $worksiteId)->find()) {
return [];
}
$res = [
'morning_on' => $worksite['morning_on'],
'morning_off' => $worksite['morning_off'],
'afternoon_on' => $worksite['afternoon_on'],
'afternoon_off' => $worksite['afternoon_off'],
];
// 当前时间小于start_at 使用old_系列时间
if ($worksite['start_at'] > time() && $worksite['start_at'] != 0) {
$res = [
'morning_on' => $worksite['old_morning_on'],
'morning_off' => $worksite['old_morning_off'],
'afternoon_on' => $worksite['old_afternoon_on'],
'afternoon_off' => $worksite['old_afternoon_off'],
];
}
return $res;
}
} }

View File

@ -37,6 +37,20 @@
</div> </div>
</div> </div>
<div class="layui-form-item">
<label class="layui-form-label required">上午工作时间</label>
<div class="layui-input-block">
<input type="text" id="am-time" name="am" class="layui-input" value="">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label required">下午工作时间</label>
<div class="layui-input-block">
<input type="text" id="pm-time" name="pm" class="layui-input" value="">
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-input-block"> <div class="layui-input-block">
<button class="layui-btn layui-btn-normal" data-url="/manager/worksite/add" lay-submit lay-filter="saveBtn">确认保存</button> <button class="layui-btn layui-btn-normal" data-url="/manager/worksite/add" lay-submit lay-filter="saveBtn">确认保存</button>
@ -51,7 +65,7 @@
<script src="__STATIC__/common/jquery-3.4.1.min.js"></script> <script src="__STATIC__/common/jquery-3.4.1.min.js"></script>
<script src="__MANAGER__/js/common/address.js?v={:mt_rand()}"></script> <script src="__MANAGER__/js/common/address.js?v={:mt_rand()}"></script>
<script> <script>
layui.use(['layer','form','jquery','location'],function(){ layui.use(['layer','form','jquery','location','laydate'],function(){
let $ = layui.jquery; let $ = layui.jquery;
let form = layui.form; let form = layui.form;
let location = layui.location; let location = layui.location;
@ -63,6 +77,18 @@
lat = lat.length > 0 ? lat : '30.68395'; lat = lat.length > 0 ? lat : '30.68395';
let locationData = {lng: lng,lat: lat}; let locationData = {lng: lng,lat: lat};
let laydate = layui.laydate;
laydate.render({
elem: '#am-time' //指定元素
,type: 'time'
,range: true
});
laydate.render({
elem: '#pm-time' //指定元素
,type: 'time'
,range: true
});
location.render("#locationBtn",{ location.render("#locationBtn",{
type: 1, type: 1,
apiType: "gaodeMap", apiType: "gaodeMap",

View File

@ -37,6 +37,20 @@
</div> </div>
</div> </div>
<div class="layui-form-item">
<label class="layui-form-label required">上午工作时间</label>
<div class="layui-input-block">
<input type="text" id="am-time" name="am" class="layui-input" value="{$item.am ?? ''}">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label required">下午工作时间</label>
<div class="layui-input-block">
<input type="text" id="pm-time" name="pm" class="layui-input" value="{$item.pm ?? ''}">
</div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<div class="layui-input-block"> <div class="layui-input-block">
<input type="hidden" name="id" value="{$item.id ?? 0}"> <input type="hidden" name="id" value="{$item.id ?? 0}">
@ -52,7 +66,7 @@
<script src="__STATIC__/common/jquery-3.4.1.min.js"></script> <script src="__STATIC__/common/jquery-3.4.1.min.js"></script>
<script src="__MANAGER__/js/common/address.js?v={:mt_rand()}"></script> <script src="__MANAGER__/js/common/address.js?v={:mt_rand()}"></script>
<script> <script>
layui.use(['layer','form','jquery','location'],function(){ layui.use(['layer','form','jquery','location', 'laydate'],function(){
let $ = layui.jquery; let $ = layui.jquery;
let form = layui.form; let form = layui.form;
let location = layui.location; let location = layui.location;
@ -64,6 +78,18 @@
lat = lat.length > 0 ? lat : '39.915'; lat = lat.length > 0 ? lat : '39.915';
let locationData = {lng: lng,lat: lat}; let locationData = {lng: lng,lat: lat};
let laydate = layui.laydate;
laydate.render({
elem: '#am-time' //指定元素
,type: 'time'
,range: true
});
laydate.render({
elem: '#pm-time' //指定元素
,type: 'time'
,range: true
});
location.render("#locationBtn",{ location.render("#locationBtn",{
type: 1, type: 1,
apiType: "gaodeMap", apiType: "gaodeMap",