feat(工人和负责人): 添加月度评分

master
yin5th 2023-01-10 11:02:24 +08:00
parent 7c7f822f59
commit 5b1f5280c9
8 changed files with 620 additions and 4 deletions

View File

@ -737,6 +737,7 @@ class Manager extends Base
'month' => date('m'), 'month' => date('m'),
'ym' => $ym, 'ym' => $ym,
'operated_by' => $accountId, 'operated_by' => $accountId,
'created_at' => date('Y-m-d H:i:s'),
]); ]);
return $this->json(); return $this->json();
} catch (Exception $e) { } catch (Exception $e) {

View File

@ -0,0 +1,222 @@
<?php
declare (strict_types=1);
namespace app\controller\manager;
use app\model\AccountStar;
use app\model\ClockLog;
use Exception;
use app\model\Log;
use think\Collection;
use think\response\View;
use think\response\Json;
use think\db\exception\DbException;
use think\exception\ValidateException;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
class Star extends Base
{
protected $noNeedLogin = ['index', 'add', 'edit', 'del', 'modify'];
/**
* 列表
*
* @throws Exception
*/
public function index()
{
$accountId = input('user_id/d', 0);
if ($this->request->isPost()) {
$params = input('searchParams/a');
$page = input('page/d', 1);
$size = input('size/d', 20);
$type = input('type', AccountStar::TYPE_MANAGER);
$where = [];
if (!empty($params)) {
foreach ($params as $key => $param) {
$param = trim($param);
if ($key == 'keyword') {
$where[] = ['a.nickname|a.mobile|a.real_name', 'like', '%'.$param.'%'];
continue;
}
if ($param == '0' || !empty($param)) {
$where[] = ['cl.'.$key, '=', $param];
}
}
}
$where[] = ['cl.type', '=', $type];
if ($accountId > 0) {
$where[] = ['cl.account_id', '=', $accountId];
}
$query = AccountStar::alias('cl')
->leftJoin('account a', 'a.id = cl.account_id')
->where($where);
$total = $query->count();
$res = [
'total' => $total,
'current' => $page ?: 1,
'size' => $size ?: 20,
'list' => [],
];
if ($total > 0) {
$res['list'] = $query->fieldRaw('cl.*,a.nickname,a.real_name')->page($page, $size)->order('cl.ym', 'desc')->select();
$res['list']->each(function ($item) {
$item->account_text = $item->nickname.' '.$item->real_name;//用户信息
$item->date = $item->year.'年'.$item->month.'月';
});
}
return $this->json(0, 'success', $res);
}
$this->data['userId'] = $accountId;
$this->data['worksiteList'] = \app\model\Worksite::list();
return $this->view();
}
/**
* 添加
*
* @return Json|View
*/
public function add()
{
if ($this->request->isPost()) {
try {
$input = input('post.');
if (!isset($input['name'])) {
return $this->json(4000, '参数错误');
}
ClockLog::create([
'name' => $input['name'] ?? '',
]);
return $this->json();
} catch (Exception $e) {
return $this->json(4001, '添加失败'.$e->getMessage());
}
}
return $this->view();
}
/**
* 编辑
*
* @return \think\response\Json|\think\response\View
*/
public function edit()
{
$id = input('id');
//通过ID查询
$item = ClockLog::where('id', (int) $id)->find();
if (empty($item)) {
return $this->json(4000, '没有相关记录!');
}
if ($this->request->isPost()) {
try {
$input = input('post.');
if (!isset($input['name'])) {
return $this->json(4000, '参数错误');
}
$item->save([
'name' => $input['name'] ?? '',
]);
return $this->json();
} catch (Exception $e) {
return $this->json(5000, $e->getMessage());
}
}
$this->data['item'] = $item;
$this->data['id'] = $id;
return $this->view();
}
/**
* 更新属性
*
* @throws ModelNotFoundException
* @throws DbException
* @throws DataNotFoundException
* @throws Exception
*/
public function modify()
{
if (!$this->request->isPost()) {
return $this->json(4000, '非法请求');
}
$item = input('post.');
$validate = $this->validateByApi($item, [
'field' => 'require',
'value' => 'require',
]);
if ($validate !== true) {
return $validate;
}
// 通过ID查询
if (!$info = ClockLog::where('id', (int) $item['id'])->find()) {
return $this->json(4001, '记录不存在');
}
$update = [$item['field'] => $item['value']];
try {
$info->save($update);
return $this->json();
} catch (ValidateException $e) {
return $this->json(4001, $e->getError());
} catch (Exception $e) {
return $this->json(5000, '修改失败');
}
}
/**
* 删除
*
* @return \think\response\Json
*/
public function del(): Json
{
if (!$this->request->isPost()) {
return $this->json(4000, '非法请求');
}
$ids = $this->request->param('ids/a', []);
if (empty($ids)) {
$ids[] = $this->request->param('id/d', 0);
$ids = array_filter($ids);
}
try {
if (count($ids)) {
//删除逻辑
if (\app\model\Account::whereIn('ClockLog', $ids)->count() > 0) {
return $this->json(4000, '所选岗位已分配给用户,请先移除后再删除');
}
ClockLog::whereIn('id', $ids)->delete();
Log::write(get_class(), 'del', '删除操作涉及到的ID为'.implode(',', $ids));
}
} catch (Exception $e) {
return $this->json(5000, $e->getMessage());
}
return $this->json();
}
}

View File

@ -6,6 +6,8 @@ use app\controller\manager\Base;
use app\exception\RepositoryException; use app\exception\RepositoryException;
use app\model\Account; use app\model\Account;
use app\model\Account as AccountModel; use app\model\Account as AccountModel;
use app\model\AccountStar;
use app\model\AccountWorksite;
use app\model\Position; use app\model\Position;
use app\model\Worksite; use app\model\Worksite;
use app\repository\AccountRepository; use app\repository\AccountRepository;
@ -29,7 +31,7 @@ use think\response\View;
*/ */
class Index extends Base class Index extends Base
{ {
protected $noNeedLogin = ['getAccountList']; protected $noNeedLogin = ['getAccountList', 'star'];
/** /**
* 详情 * 详情
@ -77,7 +79,7 @@ class Index extends Base
$item = input('post.'); $item = input('post.');
$validate = $this->validateByApi($item, [ $validate = $this->validateByApi($item, [
'real_name' => 'require', 'real_name' => 'require',
'mobile' => 'require', 'mobile' => 'require',
]); ]);
if ($validate !== true) { if ($validate !== true) {
@ -142,8 +144,8 @@ class Index extends Base
} }
} }
$this->data['item'] = $info; $this->data['item'] = $info;
$this->data['positionList'] = Position::list(); $this->data['positionList'] = Position::list();
$this->data['worksite_name'] = Worksite::where('id', $info['worksite_id'])->value('name'); $this->data['worksite_name'] = Worksite::where('id', $info['worksite_id'])->value('name');
return $this->view(); return $this->view();
@ -299,4 +301,70 @@ class Index extends Base
} }
return $this->json(4001, '非法请求'); return $this->json(4001, '非法请求');
} }
/**
* 负责人评定
*
* @return Redirect|Json|View
* @throws Exception
*/
public function star()
{
$id = input('id/d', 0);
if (!$info = Account::find($id)) {
if ($this->request->isPost()) {
return $this->json(4000, '用户不存在');
} else {
return $this->error('用户不存在');
}
}
if ($this->request->isPost()) {
$item = input('post.');
$validate = $this->validateByApi($item, [
'star_time|评定时间' => 'require',
'star|评级' => 'require|in:1,2,3,4,5',
]);
if ($validate !== true) {
return $validate;
}
if ($item['star_time'] > date('Y-m')) {
return $this->json(4002, '不能超过当前月份');
}
try {
$timeArr = explode('-', $item['star_time']);
$year = $timeArr[0];
$month = (string) $timeArr[1];
$ym = $year.$month;
if (AccountStar::where('type', AccountStar::TYPE_MANAGER)->where('account_id', $id)->where('ym', $ym)->count() > 0) {
return $this->json(4002, '该月已评');
}
AccountStar::create([
'type' => AccountStar::TYPE_MANAGER,
'star' => $item['star'],
'account_id' => $id,
'year' => $year,
'month' => $month,
'ym' => $ym,
'operated_by' => $this->auth['user_id'],
'created_at' => date('Y-m-d H:i:s'),
]);
return $this->json();
} catch (ValidateException $e) {
return $this->json(4001, $e->getError());
}
}
$this->data['item'] = $info;
$worksiteId = AccountWorksite::where('account_id', $id)->value('worksite_id');
$this->data['worksite_name'] = Worksite::where('id', $worksiteId)->value('name');
return $this->view();
}
} }

View File

@ -249,4 +249,8 @@ layui.use(['laytpl', 'table', 'jquery', 'form', 'miniTab', 'xmSelect', 'laydate'
}); });
} }
laydate.render({
elem: '#star-date',
type: 'month',
});
}); });

View File

@ -0,0 +1,212 @@
layui.use(['laytpl', 'table', 'jquery', 'form', 'miniTab', 'xmSelect', 'laydate'], function () {
let $ = layui.jquery,
table = layui.table,
xmSelect = layui.xmSelect,
miniTab = layui.miniTab,
laydate = layui.laydate,
form = layui.form;
/**** index begin ***/
if ($('.location-index-page').length > 0) {
miniTab.listen();
// 渲染表格
let listUrl = $('#table-container').data('url');
let insTb = table.render({
elem: '#table-container',
title: '列表',
defaultToolbar: ['filter', 'exports', {
title: '搜索' //自定义头部工具栏右侧图标。如无需自定义,去除该参数即可
, layEvent: 'search'
, icon: 'layui-icon-search'
}],
toolbar: '#toolbar-tpl',
method: 'POST',
url: listUrl,
page: true,
limit: 20,
limits: [20, 50, 100, 200, 500, 1000],
request: {
pageName: 'page',
limitName: 'size',
},
parseData: function (res) {
return {
"code": res.code, //解析接口状态
"msg": res.msg, //解析提示文本
"count": res.data.total, //解析数据长度
"data": res.data.list //解析数据列表
};
},
cols: [[
{type: 'checkbox'},
{field: 'id', title: '评定ID', minWidth: 100},
{field: 'account_text', title: '用户', minWidth: 250},
{field: 'star', title: '评定分数'},
{field: 'date', title: '月份'},
{field: 'created_at', title: '评定时间'},
{templet: '#row-operate', width: 280, align: 'center', title: '操作', hide: true}
]],
done: function () {
Tools.setInsTb(insTb);
}
});
//监听工具条 注意区别toolbar和tool toolbar是表头上的工具条 tool是行中的工具条
table.on('toolbar(table-container-filter)', function (obj) {
let layEvent = obj.event;
let insTb = Tools.getInsTb();
let url = $($(this).context).data('href')
let title = $($(this).context).data('title')
let width = $($(this).context).data('width') ? $($(this).context).data('width') : '100%';
let height = $($(this).context).data('height') ? $($(this).context).data('height') : '100%';
let checkStatus = table.checkStatus('table-container');
let selected = checkStatus.data;
let ids = [];
switch (layEvent) {
// toolbar 删除
case 'del':
if (checkStatus.data.length <= 0) {
layer.msg('请先选择数据');
return false;
}
// let selected = checkStatus.data;
// let ids = [];
$.each(selected, function (index, val) {
ids.push(val.id);
})
delRow(url, ids, insTb);
return false;
// toolbar 刷新
case 'refresh':
refreshTab(insTb);
return false;
// toolbar 搜索
case 'search':
let search = $('.table-search-fieldset');
if (search.hasClass('div-show')) {
search.css('display', 'none').removeClass('div-show');
} else {
search.css('display', 'block').addClass('div-show');
}
return false;
// 其他 默认为打开弹出层
default:
if (layEvent !== 'LAYTABLE_COLS' && layEvent !== 'LAYTABLE_EXPORT') {
openLayer(url, title, width, height);
return false;
}
}
});
//监听行工具条
table.on('tool(table-container-filter)', function (obj) {
let data = obj.data;
let layEvent = obj.event;
let url = $($(this).context).data('href');
let title = $($(this).context).data('title');
let width = $($(this).context).data('width') ? $($(this).context).data('width') : '100%';
let height = $($(this).context).data('height') ? $($(this).context).data('height') : '100%';
let insTb = Tools.getInsTb();
switch (layEvent) {
// 行 删除
case 'del':
let ids = [data.id];
delRow(url, ids, insTb);
return false;
//其他 默认为打开弹出层
default:
openLayer(url, title, width, height);
return false;
}
});
changeSwitch('changeSaleable');//监听上下架
let modifyUrl = $('#row-modify').data('url');
table.on('edit(table-container)', function (obj) {
let id = obj.data.id;
$.ajax(modifyUrl, {
data: {"id": id, "field": obj.field, "value": obj.value}
, dataType: 'json'
, type: 'POST'
})
.done(function (res) {
if (res.code === 0) {
insTb.reload();
}
})
});
// switch变更
function changeSwitch(filter) {
form.on('switch(' + filter + ')', function (obj) {
let val = obj.elem.checked ? 1 : 0;
$.post(modifyUrl, {id: this.value, field: this.name, value: val}, function (res) {
layer.msg(res.msg)
if (res.code !== 0) {
//操作不成功则刷新页面
insTb.reload();
}
})
});
}
// 监听搜索操作
form.on('submit(data-search-btn)', function (data) {
//执行搜索重载
table.reload('table-container', {
page: {curr: 1}
, where: data.field
}, 'data');
return false;
});
}
/*** index end ***/
if ($('.location-operate-page').length > 0) {
let parentCategory = $('#parent-category');
let categoryList = parentCategory.data('list') ? parentCategory.data('list') : [];
xmSelect.render({
el: '#parent-category',
paging: false,
autoRow: true,
clickClose: true,
name: 'category_id',
tips: '请选择分类',
direction: 'auto',
height: 'auto',
model: {
icon: 'hidden',
},
prop: {
name: 'title',
value: 'id',
},
tree: {
show: true,
strict: false,
clickCheck: true,
expandedKeys: true,
clickExpand: false
},
theme: {
color: '#1e84ff',
},
data: categoryList
});
laydate.render({
elem: '#published-at',
type: 'datetime',
});
}
});

View File

@ -74,6 +74,10 @@
<a class="layui-btn layui-btn-primary layui-btn-xs" data-href="/manager/account/index/worker.html?id={{d.id}}" data-title="工人信息" lay-event="detail">工人信息</a> <a class="layui-btn layui-btn-primary layui-btn-xs" data-href="/manager/account/index/worker.html?id={{d.id}}" data-title="工人信息" lay-event="detail">工人信息</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" data-href="/manager/clock/index.html?user_id={{d.id}}" data-title="【{{d.real_name}}】打卡记录" lay-event="detail">打卡列表</a> <a class="layui-btn layui-btn-primary layui-btn-xs" data-href="/manager/clock/index.html?user_id={{d.id}}" data-title="【{{d.real_name}}】打卡记录" lay-event="detail">打卡列表</a>
{{# } }} {{# } }}
{{# if (d.role === 2) { }}
<a class="layui-btn layui-btn-primary layui-btn-xs" data-href="/manager/account/index/star.html?id={{d.id}}" data-title="负责人评定" lay-event="detail">负责人评定</a>
<a class="layui-btn layui-btn-primary layui-btn-xs" data-href="/manager/star/index.html?user_id={{d.id}}" data-title="【{{d.nickname}}】评定记录" lay-event="detail">评定列表</a>
{{# } }}
<!-- <a class="layui-btn layui-btn-warm layui-btn-xs" data-href="/manager/account/index/agent.html?id={{d.id}}" data-title="代理设置" lay-event="detail">代理设置</a>--> <!-- <a class="layui-btn layui-btn-warm layui-btn-xs" data-href="/manager/account/index/agent.html?id={{d.id}}" data-title="代理设置" lay-event="detail">代理设置</a>-->
</script> </script>

View File

@ -0,0 +1,50 @@
{layout name="manager/layout" /}
<div class="layuimini-container location-operate-page">
<div class="layuimini-main">
<div class="layui-form layuimini-form">
<div class="layui-form-item">
<label class="layui-form-label">微信昵称</label>
<div class="layui-input-block">
<input type="text" value="{$item['nickname']}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">所属工地</label>
<div class="layui-input-block">
<input type="text" value="{$worksite_name}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">姓名</label>
<div class="layui-input-block">
<input type="text" value="{$item['real_name']}" class="layui-input" disabled>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">选择评定时间(月)</label>
<div class="layui-input-block">
<input type="text" name="star_time" value="{:date('Y-m')}" autocomplete="off" class="layui-input" id="star-date">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">评级</label>
<div class="layui-input-block">
<input type="number" name="star" value="5" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<input type="hidden" name="id" value="{$item.id ?? 0}">
<button class="layui-btn layui-btn-normal" data-url="/manager/account/index/star" lay-submit lay-filter="saveBtn">确认保存</button>
</div>
</div>
</div>
</div>
</div>
<script src="__MANAGER__/js/account/account.js?v={:mt_rand()}"></script>

View File

@ -0,0 +1,55 @@
{layout name="manager/layout" /}
<div class="layui-row layui-col-space12">
<div class="layui-col-xs12 layui-col-md12">
<div class="layuimini-container location-index-page">
<div class="layuimini-main">
<fieldset class="table-search-fieldset" style="display: block">
<legend>搜索信息</legend>
<div style="margin: 10px 10px 10px 10px">
<form class="layui-form layui-form-pane" action="">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">关键词</label>
<div class="layui-input-block">
<input class="layui-input" name="keyword" placeholder="支持模糊查询">
</div>
</div>
<div class="layui-inline">
<button type="submit" class="layui-btn layui-btn-primary" lay-submit
lay-filter="data-search-btn"><i class="layui-icon"></i> 搜 索
</button>
</div>
</div>
</form>
</div>
</fieldset>
<div class="image-table">
<table id="table-container" class="layui-table" data-url="/manager/star/index?user_id={$userId ?? 0}"
lay-filter="table-container-filter"></table>
</div>
</div>
</div>
</div>
</div>
<!-- 隐藏列 -->
<!-- 编辑单元格提交url -->
<input type="hidden" id="row-modify" data-url="/manager/clock/modify">
<!-- 操作列 -->
<script type="text/html" id="row-operate">
<a class="layui-btn layui-btn-danger layui-btn-xs" data-href="/manager/star/del.html" lay-event="del">删除</a>
</script>
<!-- toolbar -->
<script type="text/html" id="toolbar-tpl">
<a class="layui-btn layui-btn-primary layui-btn-sm" data-table-refresh lay-event="refresh"><i
class="fa fa-refresh"></i></a>
<!-- <a class="layui-btn layui-btn-normal layui-btn-sm" data-href="/manager/star/add.html" data-title="添加" lay-event="add">添加</a>-->
<!-- <a class="layui-btn layui-btn-danger layui-btn-sm" data-href="/manager/star/del.html" lay-event="del">删除</a>-->
</script>
<script src="__MANAGER__/js/star/star.js?v={:mt_rand()}"></script>