YM
2025-03-10 f2a13e01e8843302dfb2e80fe18edec3a4ba137f
考勤组的增加已经表单逻辑
6个文件已修改
1个文件已添加
1918 ■■■■■ 已修改文件
app/user/controller/Api.php 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/user/controller/Attendance.php 113 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/user/validate/AttendanceCheck.php 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/user/view/attendance/add.html 479 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/user/view/work_plan/add.html 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/static/assets/gougu/css/gougu.css 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/static/assets/gougu/module/oaPicker.js 1226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/user/controller/Api.php
@@ -10,7 +10,7 @@
* @Author 勾股工作室 <hdm58@qq.com>
+-----------------------------------------------------------------------------------------------
*/
declare (strict_types = 1);
declare(strict_types=1);
namespace app\user\controller;
use app\api\BaseController;
@@ -22,22 +22,38 @@
    public function del_profiles()
    {
        $id = get_params("id");
        if (Db::name('AdminProfiles')->where('id', $id)->update(['delete_time'=>time()]) !== false) {
            return to_assign(0, "删除成功");
        } else {
            return to_assign(1, "删除失败");
        }
        if (Db::name('AdminProfiles')->where('id', $id)->update(['delete_time' => time()]) !== false) {
            return to_assign(0, "删除成功");
        } else {
            return to_assign(1, "删除失败");
        }
    }
    //删除班次考勤时间
    public function del_work_plan_time()
    {
        $id = get_params("id");
        if (Db::name('AttendanceWorkTime')->where('id', $id)->update(['is_del'=>1]) !== false) {
            return to_assign(0, "删除成功");
        } else {
            return to_assign(1, "删除失败");
        }
        if (Db::name('AttendanceWorkTime')->where('id', $id)->update(['is_del' => 1]) !== false) {
            return to_assign(0, "删除成功");
        } else {
            return to_assign(1, "删除失败");
        }
    }
    //获取班次列表
    public function get_work_plan()
    {
        $list = Db::name('AttendanceWorkPlan')->where('is_del', '=', 0)->order('create_time asc')->select()->each(function ($item, $key) {
            $item['create_time'] = date('Y-m-d H:i:s', $item['create_time']);
            $item['update_time'] = $item['update_time'] > 0 ? date('Y-m-d H:i:s', $item['update_time']) : "";
            return $item;
        })->toArray();
        foreach ($list as &$val) {
            $mappingTimes = Db::name('AttendanceWorkPlanWorkTimeLink')->where(['work_plan_id' => $val['id']])->column('work_time_id');
            $times = Db::name('AttendanceWorkTime')->where('id', 'in', $mappingTimes)->where('is_del', '=', 0)->select()->toArray();
            $val['times'] = $times;
        }
        $res['data'] = $list;
        return table_assign(0, '', $res);
    }
}
app/user/controller/Attendance.php
@@ -1,11 +1,11 @@
<?php
declare (strict_types = 1);
declare(strict_types=1);
namespace app\user\controller;
use app\base\BaseController;
// use app\user\validate\PositionCheck;
use app\user\validate\AttendanceCheck;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\View;
@@ -25,7 +25,7 @@
            $res['data'] = $list;
            return table_assign(0, '', $res);
        } else {
          return view();
            return view();
        }
    }
@@ -36,7 +36,7 @@
        if (request()->isAjax()) {
            if (!empty($param['id']) && $param['id'] > 0) {
                try {
                    validate(PositionCheck::class)->scene('edit')->check($param);
                    validate(AttendanceCheck::class)->scene('edit')->check($param);
                } catch (ValidateException $e) {
                    // 验证失败 输出错误信息
                    return to_assign(1, $e->getError());
@@ -67,7 +67,7 @@
                }
            } else {
                try {
                    validate(PositionCheck::class)->scene('add')->check($param);
                    validate(AttendanceCheck::class)->scene('add')->check($param);
                } catch (ValidateException $e) {
                    // 验证失败 输出错误信息
                    return to_assign(1, $e->getError());
@@ -75,7 +75,85 @@
                // 启动事务
                Db::startTrans();
                try {
                    $uid = Db::name('AttendanceGroup')->strict(false)->field(true)->insertGetId($param);
                    // 插入考勤组表
                    $setData = [
                        'name' => $param['name'],
                        'type' => $param['type'],
                        'is_del' => 0,
                        'create_time' => time(),
                        'mon_work_plan_id' => isset($param['work1']) && $param['work1'] == "on" && isset($param['work_plan_id1']) ? intval($param['work_plan_id1']) : 0,
                        'tue_work_plan_id' => isset($param['work2']) && $param['work2'] == "on" && isset($param['work_plan_id2']) ? intval($param['work_plan_id1']) : 0,
                        'wed_work_plan_id' => isset($param['work3']) && $param['work3'] == "on" && isset($param['work_plan_id3']) ? intval($param['work_plan_id1']) : 0,
                        'thur_work_plan_id' => isset($param['work4']) && $param['work4'] == "on" && isset($param['work_plan_id4']) ? intval($param['work_plan_id1']) : 0,
                        'fri_work_plan_id' => isset($param['work5']) && $param['work5'] == "on" && isset($param['work_plan_id5']) ? intval($param['work_plan_id1']) : 0,
                        'sat_work_plan_id' => isset($param['work6']) && $param['work6'] == "on" && isset($param['work_plan_id6']) ? intval($param['work_plan_id1']) : 0,
                        'sun_work_plan_id' => isset($param['work7']) && $param['work7'] == "on" && isset($param['work_plan_id7']) ? intval($param['work_plan_id1']) : 0,
                    ];
                    $uid = Db::name('AttendanceGroup')->strict(false)->field(true)->insertGetId($setData);
                    // 插入用户关联表
                    $attendance_participants_ids = explode(",", $param['attendance_participants_id']);
                    $attendance_not_participants_id = explode(",", $param['attendance_not_participants_id']);
                    foreach ($attendance_participants_ids as $key => $value) {
                        if ($value != '') {
                            $mappingData[$key] = [
                                'group_id' => $uid,
                                'user_id' => intval($value),
                                'type' => "1",
                            ];
                            Db::name('AttendanceUserLink')->strict(false)->field(true)->insertAll($mappingData);
                        }
                    }
                    foreach ($attendance_not_participants_id as $key => $value) {
                        if ($value != '') {
                            $mappingData[$key] = [
                                'group_id' => $uid,
                                'user_id' => intval($value),
                                'type' => "2",
                            ];
                            Db::name('AttendanceUserLink')->strict(false)->field(true)->insertAll($mappingData);
                        }
                    }
                    // 插入时间表
                    for ($i = 0; $i < count($param['necessaryTime']); $i++) {
                        // 获取时间数据
                        $timeData1 = [
                            'begin_data' => $param['necessaryTime'][$i] . " 00:00:00",
                            'end_data' => $param['necessaryTime'][$i] . " 23:59:59",
                            'type' => "1",
                        ];
                        // 插入时间数据
                        $timeIds1[$i] = Db::name('AttendanceSpecialDate')->strict(false)->field(true)->insertGetId($timeData1);
                    }
                    foreach ($timeIds1 as $key => $value) {
                        $mappingData1[$key] = [
                            'group_id' => $uid,
                            'special_date_id' => $value,
                        ];
                    }
                    Db::name('AttendanceGroupSpecialDateLink')->strict(false)->field(true)->insertAll($mappingData1);
                    for ($i = 0; $i < count($param['unNecessaryTime']); $i++) {
                        // 获取时间数据
                        $timeData2 = [
                            'begin_data' => $param['unNecessaryTime'][$i] . " 00:00:00",
                            'end_data' => $param['unNecessaryTime'][$i] . " 23:59:59",
                            'type' => "2",
                        ];
                        // 插入时间数据
                        $timeIds2[$i] = Db::name('AttendanceSpecialDate')->strict(false)->field(true)->insertGetId($timeData2);
                    }
                    foreach ($timeIds2 as $key => $value) {
                        $mappingData2[$key] = [
                            'group_id' => $uid,
                            'special_date_id' => $value,
                        ];
                    }
                    Db::name('AttendanceGroupSpecialDateLink')->strict(false)->field(true)->insertAll($mappingData2);
                    // foreach ($param['group_id'] as $k => $v) {
                    //     $data[$k] = [
                    //         'pid' => $uid,
@@ -94,22 +172,21 @@
                }
            }
            return to_assign();
        }
        else{
        } else {
            $id = isset($param['id']) ? $param['id'] : 0;
            // $group = Db::name('AdminGroup')->order('create_time asc')->select()->toArray();
            // if ($id > 0) {
            if ($id > 0) {
                $detail = Db::name('AttendanceGroup')->where(['id' => $id])->find();
            //     $detail['group_id'] = Db::name('PositionGroup')->where(['pid' => $id])->column('group_id');
            //     foreach ($group as &$val) {
            //         if (in_array($val['id'], $detail['group_id'])) {
            //             $val['checked'] = 1;
            //         } else {
            //             $val['checked'] = 0;
            //         }
            //     }
                //     $detail['group_id'] = Db::name('PositionGroup')->where(['pid' => $id])->column('group_id');
                //     foreach ($group as &$val) {
                //         if (in_array($val['id'], $detail['group_id'])) {
                //             $val['checked'] = 1;
                //         } else {
                //             $val['checked'] = 0;
                //         }
                // }
                View::assign('detail', $detail);
            // }
            }
            // View::assign('group', $group);
            View::assign('id', $id);
            return view();
app/user/validate/AttendanceCheck.php
New file
@@ -0,0 +1,49 @@
<?php
/**
+-----------------------------------------------------------------------------------------------
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
+-----------------------------------------------------------------------------------------------
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
+-----------------------------------------------------------------------------------------------
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
+-----------------------------------------------------------------------------------------------
* @Author 勾股工作室 <hdm58@qq.com>
+-----------------------------------------------------------------------------------------------
*/
namespace app\user\validate;
use think\facade\Db;
use think\Validate;
class AttendanceCheck extends Validate
{
    // 自定义验证规则
    protected function checkUnique($value, $rule, $data)
    {
        [$table, $field, $id] = explode(',', $rule);
        $idField = $id ?: 'id';
        $idValue = $data[$idField] ?? null;
        $map = [
            [$field, '=', $value],
        ];
        if (!is_null($idValue)) {
            $map[] = [$idField, '<>', $idValue];
        }
        return !Db::name(name: $table)->where($map)->count();
    }
    protected $rule = [
        'name' => 'require|checkUnique:AttendanceWorkPlan,name,id',
        'id' => 'require'
    ];
    protected $message = [
        'name.require' => '考勤组名称不能为空',
        'name.checkUnique' => '同样的考勤组名称已经存在',
        'id.require' => '缺少更新条件',
    ];
    protected $scene = [
        'add' => ['name'],
        'edit' => ['name', 'id'],
    ];
}
app/user/view/attendance/add.html
@@ -1,82 +1,272 @@
{extend name="../../base/view/common/base" /}
<!-- 主体 -->
{block name="body"}
<style>
  #showNecessaryTimeBox,
  #showUnNecessaryTimeBox {
    display: flex;
  }
  #showNecessaryTimeBox p,
  #showUnNecessaryTimeBox p {
    line-height: 26px;
    display: none;
  }
  #showNecessaryTimeList,
  #showUnNecessaryTimeList {
    display: flex;
    gap: 20px;
  }
  .timeItem {
    border: 1px solid #ccc;
    padding: 2px 8px;
    border-radius: 4px;
    position: relative;
  }
  .closeBtn {
    background: #ff5722;
    color: #fff;
    border-radius: 50%;
    font-size: 12px;
    display: inline-block;
    width: 16px;
    height: 16px;
    line-height: 18px;
    text-align: center;
    position: absolute;
    right: -6px;
    top: -6px;
    cursor: pointer;
  }
</style>
<form class="layui-form p-4">
    <h3 class="pb-3">岗位职称</h3>
    {if condition="$id eq 0"}
    <table class="layui-table">
        <tr>
            <td class="layui-td-gray">岗位名称<font>*</font></td>
            <td>
                <input type="text" name="title" lay-verify="required" autocomplete="off" placeholder="请输入岗位名称" lay-reqText="请输入岗位名称" class="layui-input">
            </td>
            <td class="layui-td-gray-3">岗位工时单价(元)<font>*</font></td>
            <td>
                <input type="text" name="work_price" lay-verify="required|number" placeholder="请输入岗位工时单价" lay-reqText="请输入岗位工时单价" autocomplete="off" class="layui-input">
            </td>
        </tr>
        <tr>
            <td class="layui-td-gray">状态<font>*</font></td>
            <td colspan="3">
                <input type="radio" name="status" value="1" title="正常" checked>
                <input type="radio" name="status" value="0" title="禁用">
            </td>
        </tr>
        <tr>
            <td class="layui-td-gray">权限角色<font>*</font></td>
            <td colspan="3">
                {volist name="$group" id="v"}
                <input type="checkbox" name="group_id[]" title="{$v.title}" value="{$v.id}" lay-skin="primary">
                {/volist}
            </td>
        </tr>
        <tr>
            <td class="layui-td-gray">岗位备注</td>
            <td colspan="3">
                <textarea name="remark" placeholder="请输入岗位备注" class="layui-textarea"></textarea>
            </td>
        </tr>
    </table>
    {else/}
    <table class="layui-table layui-table-form">
        <tr>
            <td class="layui-td-gray">岗位名称<font>*</font></td>
            <td>
                <input type="text" name="title" value="{$detail.title}" lay-verify="required" autocomplete="off" placeholder="请输入岗位名称" lay-reqText="请输入岗位名称" class="layui-input">
            </td>
            <td class="layui-td-gray-3">岗位工时单价(元)<font>*</font></td>
            <td>
                <input type="text" name="work_price" value="{$detail.work_price}" lay-verify="required|number" placeholder="请输入岗位工时单价" lay-reqText="请输入岗位工时单价" autocomplete="off" class="layui-input">
            </td>
        </tr>
        <tr>
            <td class="layui-td-gray">状态<font>*</font></td>
            <td colspan="3">
                <input type="radio" name="status" value="1" title="正常" {eq name="$detail.status" value="1"}checked{/eq}>
                <input type="radio" name="status" value="0" title="禁止" {eq name="$detail.status" value="0"}checked{/eq}>
            </td>
        </tr>
        <tr>
            <td class="layui-td-gray">权限角色<font>*</font></td>
            <td colspan="3">
            {volist name="$group" id="v"}
                <input type="checkbox" name="group_id[]" title="{$v.title}" value="{$v.id}" {eq name="$v.checked" value="1" }checked{/eq} lay-skin="primary">
            {/volist}
            </td>
        </tr>
        <tr>
            <td class="layui-td-gray">岗位备注</td>
            <td colspan="3">
                <textarea name="remark" placeholder="请输入岗位备注" class="layui-textarea">{$detail.remark}</textarea>
            </td>
        </tr>
    </table>
    {/if}
    <div class="pt-4">
        <input type="hidden" name="id" value="{$id}">
        <button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="webform">立即提交</button>
        <button type="reset" class="layui-btn layui-btn-primary">重置</button>
    </div>
  <h3 class="pb-3">考勤组</h3>
  {if condition="$id eq 0"}
  <table class="layui-table">
    <tr>
      <td class="layui-td-gray-3">考勤组名称<font>*</font></td>
      <td>
        <input
          type="text"
          name="name"
          lay-verify="required"
          autocomplete="off"
          placeholder="请输入考勤组名称"
          lay-reqText="请输入岗位名称"
          class="layui-input"
        />
      </td>
      <td class="layui-td-gray-3">考勤类型<font>*</font></td>
      <td>
        <select name="type" lay-verify="required" lay-reqText="请选择">
          <option value="">请选择</option>
          <option value="1">固定班制</option>
          <option value="2">自由工时</option>
        </select>
      </td>
    </tr>
    <tr>
      <td class="layui-td-gray-3">参与考勤人员<font>*</font></td>
      <td>
        <input
          type="text"
          name="attendance_participants"
          autocomplete="off"
          readonly
          lay-verify="required"
          lay-reqText="请选择参与考勤人员"
          placeholder="请选择参与考勤人员"
          class="layui-input picker-diy"
        />
        <input type="hidden" name="attendance_participants_id" />
      </td>
      <td class="layui-td-gray-3">无需考勤人员</td>
      <td>
        <input
          type="text"
          name="attendance_not_participants"
          autocomplete="off"
          readonly
          lay-reqText="请选择无需考勤人员"
          placeholder="请选择无需考勤人员"
          class="layui-input picker-diy"
        />
        <input type="hidden" name="attendance_not_participants_id" />
      </td>
    </tr>
    <tr>
      <td class="layui-td-gray">工作日设置<font>*</font></td>
      <td colspan="5">
        <table
          id="timeBox"
          class="layui-table layui-table-min"
          style="margin: 0"
        >
          <tr>
            <th width="50"></th>
            <th width="100">工作日</th>
            <th>班次时间段</th>
            <th width="60">操作</th>
          </tr>
          <tr>
            <td>
              <input type="checkbox" name="work1" lay-skin="primary" title="" />
            </td>
            <td>周一</td>
            <td style="text-align: left"></td>
            <td>
              <a class="layui-btn layui-btn-xs picker-oa" data-types="workPlan"
                >设置班次</a
              >
              <input type="hidden" name="work_plan_id1" value="" />
            </td>
          </tr>
          <tr>
            <td>
              <input type="checkbox" name="work2" lay-skin="primary" title="" />
            </td>
            <td>周二</td>
            <td style="text-align: left"></td>
            <td>
              <a class="layui-btn layui-btn-xs picker-oa" data-types="workPlan"
                >设置班次</a
              >
              <input type="hidden" name="work_plan_id2" value="" />
            </td>
          </tr>
          <tr>
            <td>
              <input type="checkbox" name="work3" lay-skin="primary" title="" />
            </td>
            <td>周三</td>
            <td style="text-align: left"></td>
            <td>
              <a class="layui-btn layui-btn-xs picker-oa" data-types="workPlan"
                >设置班次</a
              >
              <input type="hidden" name="work_plan_id3" value="" />
            </td>
          </tr>
          <tr>
            <td>
              <input type="checkbox" name="work4" lay-skin="primary" title="" />
            </td>
            <td>周四</td>
            <td style="text-align: left"></td>
            <td>
              <a class="layui-btn layui-btn-xs picker-oa" data-types="workPlan"
                >设置班次</a
              >
              <input type="hidden" name="work_plan_id4" value="" />
            </td>
          </tr>
          <tr>
            <td>
              <input type="checkbox" name="work5" lay-skin="primary" title="" />
            </td>
            <td>周五</td>
            <td style="text-align: left"></td>
            <td>
              <a class="layui-btn layui-btn-xs picker-oa" data-types="workPlan"
                >设置班次</a
              >
              <input type="hidden" name="work_plan_id5" value="" />
            </td>
          </tr>
          <tr>
            <td>
              <input type="checkbox" name="work6" lay-skin="primary" title="" />
            </td>
            <td>周六</td>
            <td style="text-align: left"></td>
            <td>
              <a class="layui-btn layui-btn-xs picker-oa" data-types="workPlan"
                >设置班次</a
              >
              <input type="hidden" name="work_plan_id6" value="" />
            </td>
          </tr>
          <tr>
            <td>
              <input type="checkbox" name="work7" lay-skin="primary" title="" />
            </td>
            <td>周日</td>
            <td style="text-align: left"></td>
            <td>
              <a class="layui-btn layui-btn-xs picker-oa" data-types="workPlan"
                >设置班次</a
              >
              <input type="hidden" name="work_plan_id7" value="" />
            </td>
          </tr>
        </table>
      </td>
    </tr>
    <tr>
      <td class="layui-td-gray-3">特殊日期</td>
      <td colspan="5">
        <div style="margin-bottom: 10px">
          <div id="showNecessaryTimeBox">
            <p>必须打卡日期:</p>
            <div id="showNecessaryTimeList"></div>
          </div>
        </div>
        <div style="margin-bottom: 10px">
          <button
            class="layui-btn layui-btn-sm"
            type="button"
            id="addNecessaryTimeBtn"
          >
            + 新增必须打卡的日期
          </button>
        </div>
        <div style="margin-bottom: 10px">
          <div id="showUnNecessaryTimeBox">
            <p>无需打卡日期:</p>
            <div id="showUnNecessaryTimeList"></div>
          </div>
        </div>
        <div style="margin-bottom: 10px">
          <button
            class="layui-btn layui-btn-sm"
            type="button"
            id="addUnNecessaryTimeBtn"
          >
            + 新增无需打卡的日期
          </button>
        </div>
      </td>
    </tr>
  </table>
  {else/}
  <table class="layui-table layui-table-form">
    <tr>
      <td class="layui-td-gray">考勤组名称<font>*</font></td>
      <td>
        <input
          type="text"
          name="name"
          value="{$detail.name}"
          lay-verify="required"
          autocomplete="off"
          placeholder="请输入考勤组名称"
          lay-reqText="请输入岗位名称"
          class="layui-input"
        />
      </td>
    </tr>
  </table>
  {/if}
  <div class="pt-4">
    <input type="hidden" name="id" value="{$id}" />
    <button
      class="layui-btn layui-btn-normal"
      lay-submit=""
      lay-filter="webform"
    >
      立即提交
    </button>
    <button type="reset" class="layui-btn layui-btn-primary">重置</button>
  </div>
</form>
{/block}
<!-- /主体 -->
@@ -84,34 +274,117 @@
<!-- 脚本 -->
{block name="script"}
<script>
    const moduleInit = ['tool'];
    function gouguInit() {
        var form = layui.form,tool=layui.tool;
        form.on('submit(webform)', function(data){
            let callback = function (e) {
                layer.msg(e.msg);
                if (e.code == 0) {
                    setTimeout(function () {
                        parent.location.reload();
                    }, 1000);
                }
            }
            tool.post("/user/position/add", data.field, callback);
            return false;
        });
        //监听提交
        form.on('submit(webform)', function(data){
            let callback = function (e) {
                layer.msg(e.msg);
                if (e.code == 0) {
                    tool.sideClose(1000);
                }
            }
            tool.post("/user/position/add", data.field, callback);
            return false;
        });
    }
  const moduleInit = ["tool", "oaPicker"];
  function gouguInit() {
    var oaPicker = layui.oaPicker,
      laydate = layui.laydate,
      form = layui.form,
      tool = layui.tool;
    //选择员工弹窗
    $("body").on("click", ".picker-diy", function () {
      let that = $(this);
      let ids = that.next().val() + "",
        names = that.val() + "";
      oaPicker.employeeInit({
        ids: ids,
        names: names,
        type: 2, //1是单选,2是多选
        callback: function (data) {
          //这里是选择后的回调方法,可以根据具体需求自定义写哦
          let select_id = [],
            select_name = [];
          for (var a = 0; a < data.length; a++) {
            select_id.push(data[a].id);
            select_name.push(data[a].name);
          }
          that.val(select_name.join(","));
          that.next().val(select_id.join(","));
        }
      });
    });
    laydate.render({
      elem: "#addNecessaryTimeBtn",
      done: function (value, date) {
        $("#addNecessaryTimeBtn").html("+ 新增必须打卡的日期");
        var oldValues = $(".timeValue");
        var isE = false;
        for (let i = 0; i < oldValues.length; i++) {
          const oldValue = oldValues[i];
          if (oldValue.innerHTML == value) {
            isE = true;
          }
        }
        if (!isE) {
          $("#showNecessaryTimeBox p").show();
          $("#showNecessaryTimeList").append(
            "<div class='timeItem'><span class='timeValue'>" +
              value +
              "</span><input type='hidden' name='necessaryTime[]' value=" +
              value +
              " /><span class='closeBtn layui-icon'>&#x1006;</span></div>"
          );
          bindCloseBtn();
        } else {
          layer.msg("已有相同日期");
        }
      }
    });
    laydate.render({
      elem: "#addUnNecessaryTimeBtn",
      done: function (value, date) {
        $("#addUnNecessaryTimeBtn").html("+ 新增无需打卡的日期");
        var oldValues = $(".timeValue");
        var isE = false;
        for (let i = 0; i < oldValues.length; i++) {
          const oldValue = oldValues[i];
          if (oldValue.innerHTML == value) {
            isE = true;
          }
        }
        if (!isE) {
          $("#showUnNecessaryTimeBox p").show();
          $("#showUnNecessaryTimeList").append(
            "<div class='timeItem'><span class='timeValue'>" +
              value +
              "</span><input type='hidden' name='unNecessaryTime[]' value=" +
              value +
              " /><span class='closeBtn layui-icon'>&#x1006;</span></div>"
          );
          bindCloseBtn();
        } else {
          layer.msg("已有相同日期");
        }
      }
    });
        //监听提交
    form.on("submit(webform)", function (data) {
      let callback = function (e) {
        layer.msg(e.msg);
        if (e.code == 0) {
          tool.sideClose(1000);
        }
      };
      tool.post("/user/attendance/add", data.field, callback);
      return false;
    });
  }
  function bindCloseBtn() {
    $(".closeBtn").off("click");
    $(".closeBtn").on("click", function () {
      let that = $(this);
      that.parent().remove();
      if ($("#showNecessaryTimeList .timeItem").length == 0) {
        $("#showNecessaryTimeBox p").hide();
      }
      if ($("#showUnNecessaryTimeList .timeItem").length == 0) {
        $("#showUnNecessaryTimeBox p").hide();
      }
    });
  }
</script>
{/block}
<!-- /脚本 -->
<!-- /脚本 -->
app/user/view/work_plan/add.html
@@ -555,17 +555,6 @@
      tool.post("/user/workPlan/add", data.field, callback);
      return false;
    });
    //监听提交
    form.on("submit(webform)", function (data) {
      let callback = function (e) {
        layer.msg(e.msg);
        if (e.code == 0) {
          tool.sideClose(1000);
        }
      };
      tool.post("/user/workPlan/add", data.field, callback);
      return false;
    });
  }
</script>
{/block}
public/static/assets/gougu/css/gougu.css
@@ -9,7 +9,7 @@
.gougu-picker .layui-layer-btn1{background-color:#f5f5f5}
.gougu-picker .layui-layer-btn2{background-color:#EAFAFF}
.picker-table{padding:8px 8px 0;}
.picker-table .layui-table-cell {padding:4px; height: 32px;line-height: 24px;}
.picker-table .layui-table-cell {padding:4px; line-height: 24px;}
.layui-table-cell{padding:6px;}
.layui-table-box{background-color:#fff;}
.layui-table-page{background-color:#fff;border-bottom:1px solid #eeeeee;}
public/static/assets/gougu/module/oaPicker.js
@@ -1,514 +1,724 @@
layui.define(['tool'], function (exports) {
    const layer = layui.layer, tool = layui.tool,form=layui.form, table=layui.table,tree = layui.tree;
    const dataPicker ={
        'department':{
            title:'选择部门',
            url:'/api/index/get_department',
            area: ['400px', '524px'],
            searchbar:'',
            page:false,
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'部门名称'}]
        },
        'position':{
            title:'选择岗位',
            url:'/api/index/get_position',
            area: ['400px', '524px'],
            searchbar:'',
            page:false,
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'岗位名称'}]
        },
        'services':{
            title:'选择服务类型',
            url:'/api/index/get_services',
            area: ['400px', '524px'],
            searchbar:'',
            page:false,
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'服务名称'},{field:'price',title:'服务单价'}]
        },
        'template':{
            title:'选择消息模板',
            url:'/api/index/get_template',
            area: ['600px', '568px'],
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'消息模板名称'}]
        },
        'workcate':{
            title:'选择工作类型',
            url:'/api/index/get_work_cate',
            area: ['400px', '524px'],
            searchbar:'',
            page:false,
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'工作类型名称'}]
        },
        'property':{
            title:'选择固定资产',
            url:'/adm/api/get_property',
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'资产名称'}]
        },
        'car':{
            title:'选择车辆信息',
            url:'/adm/api/get_car',
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'车辆名称'},{field:'name',width:100,title:'车牌号码',align:'center'}]
        },
        'room':{
            title:'选择会议室',
            url:'/adm/api/get_meeting_room',
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'会议室名称'},{field:'num',width:100,title:'可容纳人数',align:'center'}]
        },
        'customer':{
            title:'选择客户',
            url:'/customer/api/get_customer',
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'name',title:'客户名称'}]
        },
        'supplier':{
            title:'选择供应商',
            url:'/contract/api/get_supplier',
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'供应商名称'}]
        },
        'contract':{
            title:'选择销售合同',
            url:'/contract/api/get_contract',
            area: ['800px', '568px'],
            cols:[{ field: 'code',width:160,title:'合同编号',align:'center'},{field:'name',title:'合同名称'},{ field:'customer',title:'关联客户',width: 240}]
        },
        'product':{
            title:'选择产品',
            url:'/contract/api/get_product',
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'产品名称'},{field:'sale_price',title:'销售单价',width: 120,align:'center'}]
        },
        'purchase':{
            title:'选择采购合同',
            url:'/contract/api/get_purchase',
            area: ['800px', '568px'],
            cols:[{ field: 'code',width:160,title:'合同编号',align:'center'},{field:'name',title:'合同名称'},{ field:'supplier',title:'关联供应商',width: 240}]
        },
        'purchased':{
            title:'选择采购物品',
            url:'/contract/api/get_purchased',
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'采购物品名称'},{field:'purchase_price',title:'采购单价',width: 120,align:'center'}]
        },
        'project':{
            title:'选择项目',
            url:'/project/api/get_project',
            cols:[{field:'id',width:90,title:'序号',align:'center'},{field:'title',title:'项目名称'}]
        },
        'task':{
            title:'选择任务',
            url:'/project/api/get_task',
            area: ['800px', '568px'],
            cols:[{field:'id',width:90,title:'序号',align:'center'},{ field:'title',title:'任务主题'},{field:'project',width:240,title:'关联项目'}]
        }
    }
layui.define(["tool"], function (exports) {
  const layer = layui.layer,
    tool = layui.tool,
    form = layui.form,
    table = layui.table,
    tree = layui.tree;
    let select_ids=[];select_names=[];select_array=[];
    const obj = {
        employeeRender:function(){
            var me=this,letterTem='';
            for(var i=0;i<26;i++){
                letterTem+='<span class="layui-letter-span" data-code="'+String.fromCharCode(97+i)+'">'+String.fromCharCode(65+i)+'</span>';
            }
            var tpl='<div style="width:210px; height:388px; border-right:1px solid #eee; overflow-x: hidden; overflow-y: auto; float:left;">\
  const dataPicker = {
    department: {
      title: "选择部门",
      url: "/api/index/get_department",
      area: ["400px", "524px"],
      searchbar: "",
      page: false,
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "部门名称" }
      ]
    },
    position: {
      title: "选择岗位",
      url: "/api/index/get_position",
      area: ["400px", "524px"],
      searchbar: "",
      page: false,
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "岗位名称" }
      ]
    },
    services: {
      title: "选择服务类型",
      url: "/api/index/get_services",
      area: ["400px", "524px"],
      searchbar: "",
      page: false,
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "服务名称" },
        { field: "price", title: "服务单价" }
      ]
    },
    template: {
      title: "选择消息模板",
      url: "/api/index/get_template",
      area: ["600px", "568px"],
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "消息模板名称" }
      ]
    },
    workcate: {
      title: "选择工作类型",
      url: "/api/index/get_work_cate",
      area: ["400px", "524px"],
      searchbar: "",
      page: false,
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "工作类型名称" }
      ]
    },
    property: {
      title: "选择固定资产",
      url: "/adm/api/get_property",
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "资产名称" }
      ]
    },
    car: {
      title: "选择车辆信息",
      url: "/adm/api/get_car",
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "车辆名称" },
        { field: "name", width: 100, title: "车牌号码", align: "center" }
      ]
    },
    room: {
      title: "选择会议室",
      url: "/adm/api/get_meeting_room",
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "会议室名称" },
        { field: "num", width: 100, title: "可容纳人数", align: "center" }
      ]
    },
    customer: {
      title: "选择客户",
      url: "/customer/api/get_customer",
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "name", title: "客户名称" }
      ]
    },
    supplier: {
      title: "选择供应商",
      url: "/contract/api/get_supplier",
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "供应商名称" }
      ]
    },
    contract: {
      title: "选择销售合同",
      url: "/contract/api/get_contract",
      area: ["800px", "568px"],
      cols: [
        { field: "code", width: 160, title: "合同编号", align: "center" },
        { field: "name", title: "合同名称" },
        { field: "customer", title: "关联客户", width: 240 }
      ]
    },
    product: {
      title: "选择产品",
      url: "/contract/api/get_product",
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "产品名称" },
        { field: "sale_price", title: "销售单价", width: 120, align: "center" }
      ]
    },
    purchase: {
      title: "选择采购合同",
      url: "/contract/api/get_purchase",
      area: ["800px", "568px"],
      cols: [
        { field: "code", width: 160, title: "合同编号", align: "center" },
        { field: "name", title: "合同名称" },
        { field: "supplier", title: "关联供应商", width: 240 }
      ]
    },
    purchased: {
      title: "选择采购物品",
      url: "/contract/api/get_purchased",
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "采购物品名称" },
        {
          field: "purchase_price",
          title: "采购单价",
          width: 120,
          align: "center"
        }
      ]
    },
    project: {
      title: "选择项目",
      url: "/project/api/get_project",
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "项目名称" }
      ]
    },
    task: {
      title: "选择任务",
      url: "/project/api/get_task",
      area: ["800px", "568px"],
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "title", title: "任务主题" },
        { field: "project", width: 240, title: "关联项目" }
      ]
    },
    workPlan: {
      title: "选择班次",
      url: "/user/api/get_work_plan",
      cols: [
        { field: "id", width: 90, title: "序号", align: "center" },
        { field: "name", title: "班次名称" },
        {
          field: "time",
          width: 240,
          title: "考勤时间"
        }
      ]
    }
  };
  let select_ids = [];
  select_names = [];
  select_array = [];
  const obj = {
    employeeRender: function () {
      var me = this,
        letterTem = "";
      for (var i = 0; i < 26; i++) {
        letterTem +=
          '<span class="layui-letter-span" data-code="' +
          String.fromCharCode(97 + i) +
          '">' +
          String.fromCharCode(65 + i) +
          "</span>";
      }
      var tpl =
        '<div style="width:210px; height:388px; border-right:1px solid #eee; overflow-x: hidden; overflow-y: auto; float:left;">\
                            <div id="employeeDepament" style="padding:6px 0;"></div>\
                        </div>\
                        <div style="width:588px; height:388px; user-select:none; overflow-x: hidden; overflow-y: auto; float:left;">\
                            <div style="padding:12px 10px 0;"><div style="color:#999; text-align:center;">⇐ 点击左边部门筛选员工,或者点击下面字母筛选</div><div id="letterBar" style="color:#999; text-align:center;">'+letterTem+'</div></div>\
                            <div style="padding:12px 10px 0;"><div style="color:#999; text-align:center;">⇐ 点击左边部门筛选员工,或者点击下面字母筛选</div><div id="letterBar" style="color:#999; text-align:center;">' +
        letterTem +
        '</div></div>\
                            <div id="employee" style="padding:6px 12px"></div>\
                            <div style="padding:10px 15px; border-top:1px solid #eee;;"><strong>已选择</strong><span class="layui-tags-all">全选</span></div>\
                            <div id="selectTags" style="padding:10px 15px;">'+me.employeeSelect(0)+'</div>\
                        </div>';
            return tpl;
        },
        employeeSelect:function(t){
            var me=this,select_tags='';
            if(me.settings.type == 0){
                select_tags+='<span style="color:#1E9FFF">'+me.settings.names+'</span>';
            }
            else{
                select_ids=[];
                select_names=[];
                for(var a=0;a<select_array.length;a++){
                    if(me.settings.fixedid==select_array[a].id && me.settings.fixedid!=0){
                        select_tags+='<span class="layui-tags-span">'+select_array[a].name+'</span>';
                    }
                    else{
                        select_tags+='<span class="layui-tags-span">'+select_array[a].name+'<i data-id="'+select_array[a].id+'" class="layui-icon layui-tags-close">ဆ</i></span>';
                    }
                    if(t==1){
                        $('#employee').find('[data-id="'+select_array[a].id+'"]').addClass('on');
                    }
                    select_ids.push(parseInt(select_array[a].id));
                    select_names.push(select_array[a].name);
                }
            }
            //console.log(select_array);
            return select_tags;
        },
        employeeInit: function (options) {
            const opts={
                "title":"选择员工",
                "department_url": "/api/index/get_department_tree",
                "employee_url": "/api/index/get_employee",
                "type":1,//1单人,2多人
                "fixedid":0,
                "ids":"",
                "names":"",
                "ajax_data":[],
                "callback": function(){}
            };
            this.settings = $.extend({}, opts, options);
            var me=this;
            select_ids=[];
            select_names=[];
            select_array=[];
            if(me.settings.ids!='' && me.settings.names!=''){
                select_ids=me.settings.ids.split(',');
                select_names=me.settings.names.split(',');
                select_ids.sort((a, b) => a - b);
                for(var m=0;m<select_ids.length;m++){
                    select_array.push({id:select_ids[m],name:select_names[m]});
                }
            }
            $(parent.$('.express-close')).addClass('parent-colse');
            layer.open({
                type:1,
                title:me.settings.title,
                area:['800px','500px'],
                resize:false,
                content:me.employeeRender(),
                end: function(){
                    $(parent.$('.express-close')).removeClass('parent-colse');
                },
                success:function(obj,idx){
                        var dataList=[],letterBar=$('#letterBar'),employee = $('#employee'),selectTags = $('#selectTags');
                        $.ajax({
                            url:me.settings.department_url,
                            type:'get',
                            success:function(res){
                                //仅节点左侧图标控制收缩
                                tree.render({
                                    elem: '#employeeDepament',
                                    data: res.trees,
                                    onlyIconControl: true,  //是否仅允许节点左侧图标控制展开收缩
                                    click: function(obj){
                                        var tagsItem='<div style="color:#999; text-align:center;">暂无员工</div>';
                                        $("#employeeDepament").find('.layui-tree-main').removeClass('on');
                                        $(obj.elem).find('.layui-tree-main').eq(0).addClass('on');
                                        letterBar.find('span').removeClass('on');
                                        $.ajax({
                                            url:me.settings.employee_url,
                                            type:'get',
                                            data:{did:obj.data.id},
                                            success:function(res){
                                                me.ajax_data = res.data;
                                                dataList=me.ajax_data;
                                                if(dataList.length>1 && me.settings.type == 2){
                                                    $('.layui-tags-all').show();
                                                }
                                                else{
                                                    $('.layui-tags-all').hide();
                                                }
                                                if(dataList.length>0){
                                                    tagsItem='';
                                                    for(var i=0; i<dataList.length; i++){
                                                        if(select_ids.indexOf(dataList[i].id) == -1){
                                                            tagsItem+='<span class="layui-tags-span" data-idx="'+i+'" data-id="'+dataList[i].id+'">'+dataList[i].name+'</span>';
                                                        }
                                                        else{
                                                            tagsItem+='<span class="layui-tags-span on" data-idx="'+i+'" data-id="'+dataList[i].id+'">'+dataList[i].name+'</span>';
                                                        }
                                                    }
                                                }
                                                employee.html(tagsItem);
                                            }
                                        })
                                    }
                                });
                                letterBar.on("click" ,'span',function(){
                                    var code=$(this).data('code');
                                    $(this).addClass('on').siblings().removeClass('on');
                                    $.ajax({
                                        url:me.settings.employee_url,
                                        type:'get',
                                        data:{id:1},
                                        success:function(res){
                                            me.ajax_data = res.data;
                                            var letterData=[],tagsItem='<div style="color:#999; text-align:center;">暂无员工</div>';;
                                            if(me.ajax_data.length>0){
                                                var tagsItemCode='';
                                                for(var i=0; i<me.ajax_data.length; i++){
                                                    if(me.ajax_data[i].username.slice(0,1)==code){
                                                        if(select_ids.indexOf(me.ajax_data[i].id) == -1){
                                                            tagsItemCode+='<span class="layui-tags-span" data-idx="'+i+'" data-id="'+me.ajax_data[i].id+'">'+me.ajax_data[i].name+'</span>';
                                                        }
                                                        else{
                                                            tagsItemCode+='<span class="layui-tags-span on" data-idx="'+i+'" data-id="'+me.ajax_data[i].id+'">'+me.ajax_data[i].name+'</span>';
                                                        }
                                                        letterData.push(me.ajax_data[i]);
                                                    }
                                                }
                                                dataList=letterData;
                                                if(dataList.length>2 && me.settings.type == 2){
                                                    $('.layui-tags-all').show();
                                                }
                                                else{
                                                    $('.layui-tags-all').hide();
                                                }
                                                if(tagsItemCode!=''){
                                                    tagsItem = tagsItemCode;
                                                }
                                            }
                                            employee.html(tagsItem);
                                        }
                                    })
                                });
                            }
                        })
                        if(me.settings.type == 2){
                            $('.layui-tags-all').on('click',function(){
                                for(var a=0; a<dataList.length;a++){
                                    if(select_ids.indexOf(dataList[a]['id']) == -1){
                                        select_array.push(dataList[a]);;
                                    }
                                }
                                selectTags.html(me.employeeSelect(1));
                            });
                        }
                        employee.on('click','.layui-tags-span',function(){
                            let item_idx=$(this).data('idx');
                            let select_item = me.ajax_data[item_idx];
                            if(me.settings.type == 1){
                                me.settings.callback([select_item]);
                                layer.close(idx);
                            }
                            else{
                                if(select_ids.indexOf(select_item['id']) == -1){
                                    select_array.push(select_item);
                                    selectTags.html(me.employeeSelect(1));
                                }
                            }
                        });
                        selectTags.on('click','.layui-tags-close',function(){
                            let id=$(this).data('id');
                            let new_slected=[];
                            $('#employee').find('[data-id="'+id+'"]').removeClass('on');
                            for(var i=0;i<select_array.length;i++){
                                if(select_array[i].id!=id){
                                    new_slected.push(select_array[i]);
                                }
                            }
                            select_array=new_slected;
                            selectTags.html(me.employeeSelect(1));
                        });
                        if(me.settings.type == 1){
                            $('#layui-layer'+idx).find('.layui-layer-btn0').hide();
                        }
                    },
                    btn: ['确定添加', '清空已选'],
                    btnAlign:'c',
                    btn1: function(idx){
                        me.settings.callback(select_array);
                        layer.close(idx);
                    },
                    btn2: function(idx){
                        let canceldata= {department:"",did:0,id:0,mobile:0,name:"",nickname:"",position_id:0,sex:0,status:0,thumb:"",username:""};
                        me.settings.callback([canceldata]);
                        layer.close(idx);
                    }
            })
        },
        picker:function(types,type,callback,map){
            let pickerIndex = new Date().getTime();
            let pickerTable,options;
            const opts={
                "title":"选择",
                "url": "",
                "ids":"",
                "titles":"",
                "where":map,
                "area": ['600px', '568px'],
                "cols":[{field: 'id',width: 80,title:'序号',align:'center'},{field:'title',title:'名称'}],
                "searchbar":'<form class="layui-form pb-2"><div class="layui-input-inline" style="width:420px; margin-right:5px;"><input type="text" name="keywords" placeholder="请输入关键字" class="layui-input" autocomplete="off" /></div><button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="picker">提交搜索</button><button type="reset" class="layui-btn layui-btn-reset" lay-filter="picker-reset">清空</button></form>',
                "page":true,
                "type":type,//1单选择,2多选
                "btnno":true,
                "add": "",//新增url
                "callback": callback
            };
            if(Object.prototype.toString.call(types) === '[object Object]'){
                options = types;
            }
            else{
                options = dataPicker[types];
            }
            let settings = $.extend({},opts,options);
            //console.log(settings);
            let btn = ['确定选择'];
            if(settings.btnno==true){
                btn = ['确定选择','清空已选'];
            }
            if(settings.add!=''){
                btn = ['确定选择','清空已选','新增'];
            }
            $(parent.$('.express-close')).addClass('parent-colse');
            layer.open({
                title: settings.title,
                area: settings.area,
                type: 1,
                skin: 'gougu-picker',
                content: '<div class="picker-table" id="pickerBox'+pickerIndex+'">'+settings.searchbar+'<div id="pickerTable'+pickerIndex+'"></div></div>',
                end: function(){
                    $(parent.$('.express-close')).removeClass('parent-colse');
                },
                success: function () {
                    let cols=JSON.parse(JSON.stringify(settings.cols));
                    if(settings.type==1){
                        cols.splice(0, 0, {type: 'radio', title: '选择'});
                    }
                    if(settings.type==2){
                        cols.splice(0, 0, {type: 'checkbox', title: '选择'});
                    }
                    pickerTable = table.render({
                        elem: '#pickerTable'+pickerIndex,
                        url: settings.url,
                        where:settings.where,
                        page: settings.page, //开启分页
                        limit: 10,
                        height: '407',
                        cols: [cols]
                    });
                    //搜索提交
                    form.on('submit(picker)', function (data) {
                        let maps = $.extend({}, settings.where, data.field);
                        pickerTable.reload({where:maps,page:{curr: 1}});
                        return false;
                    });
                    //重置搜索提交
                    $('#pickerBox'+pickerIndex).on('click', '[lay-filter="picker-reset"]', function () {
                        let prev = $(this).prev();
                        if (typeof(prev) != "undefined" ) {
                            setTimeout(function () {
                                prev.click();
                            }, 10)
                        }
                    });
                },
                btn: btn,
                btnAlign: 'c',
                btn1: function (idx) {
                    var checkStatus = table.checkStatus(pickerTable.config.id);
                    var data = checkStatus.data;
                    if (data.length > 0) {
                        callback(data);
                        layer.close(idx);
                    }
                    else {
                        layer.msg('请先选择内容');
                        return false;
                    }
                },
                btn2: function (idx) {
                    callback([{'id':0,'title':'','name':''}]);
                    layer.close(idx);
                },
                btn3: function (idx) {
                    tool.side(settings.add);
                    layer.close(idx);
                }
            })
        }
    }
    //选择员工弹窗
    $('body').on('click','.picker-admin',function () {
        let that = $(this);
        let type = that.data('type');
        if (typeof(type) == "undefined" || type == '') {
            type = 1;
        }
        let ids=that.next().val()+'',names = that.val()+'';
        obj.employeeInit({
            ids:ids,
            names:names,
            type:type,
            callback:function(data){
                let select_id=[],select_name=[];
                for(var a=0; a<data.length;a++){
                    select_id.push(data[a].id);
                    select_name.push(data[a].name);
                }
                console.log(select_name);
                that.val(select_name.join(','));
                that.next().val(select_id.join(','));
            }
        });
    });
    //选择下属员工弹窗
    $('body').on('click','.picker-sub',function () {
        let that = $(this);
        let type = that.data('type');
        if (typeof(type) == "undefined" || type == '') {
            type = 1;
        }
        let ids=that.next().val()+'',names = that.val()+'';
        obj.employeeInit({
            title:"选择下属",
            department_url: "/api/index/get_department_tree_sub",
            employee_url: "/api/index/get_employee_sub",
            ids:ids,
            names:names,
            type:type,
            callback:function(data){
                let select_id=[],select_name=[];
                for(var a=0; a<data.length;a++){
                    select_id.push(data[a].id);
                    select_name.push(data[a].name);
                }
                console.log(select_name);
                that.val(select_name.join(','));
                that.next().val(select_id.join(','));
            }
        });
    });
    //选择OA数据弹层
    $('body').on('click','.picker-oa',function () {
        let that = $(this),ids = [],titles=[],map = {};
        let types = that.data('types');
        let type = that.data('type');
        let where = that.data('where');
        if (typeof(types) == "undefined" || types == '') {
            layer.msg('请设置【picker】的类型');
            return false;
        }
        if (typeof(type) == "undefined" || type == '') {
            type = 1;
        }
        if (typeof(where) == "undefined" || where == '') {
            map = {};
        }
        else{
            map = JSON.parse(where);
        }
        let callback = function(data){
            for ( var i = 0; i <data.length; i++){
                ids.push(data[i].id);
                if(!data[i].title){
                    titles.push(data[i].name);
                }else{
                    titles.push(data[i].title);
                }
            }
            that.val(titles.join(','));
            that.next().val(ids.join(','));
        }
        obj.picker(types,type,callback,map);
    });
    //输出接口
    exports('oaPicker', obj);
});
                            <div id="selectTags" style="padding:10px 15px;">' +
        me.employeeSelect(0) +
        "</div>\
                        </div>";
      return tpl;
    },
    employeeSelect: function (t) {
      var me = this,
        select_tags = "";
      if (me.settings.type == 0) {
        select_tags +=
          '<span style="color:#1E9FFF">' + me.settings.names + "</span>";
      } else {
        select_ids = [];
        select_names = [];
        for (var a = 0; a < select_array.length; a++) {
          if (
            me.settings.fixedid == select_array[a].id &&
            me.settings.fixedid != 0
          ) {
            select_tags +=
              '<span class="layui-tags-span">' +
              select_array[a].name +
              "</span>";
          } else {
            select_tags +=
              '<span class="layui-tags-span">' +
              select_array[a].name +
              '<i data-id="' +
              select_array[a].id +
              '" class="layui-icon layui-tags-close">ဆ</i></span>';
          }
          if (t == 1) {
            $("#employee")
              .find('[data-id="' + select_array[a].id + '"]')
              .addClass("on");
          }
          select_ids.push(parseInt(select_array[a].id));
          select_names.push(select_array[a].name);
        }
      }
      //console.log(select_array);
      return select_tags;
    },
    employeeInit: function (options) {
      const opts = {
        title: "选择员工",
        department_url: "/api/index/get_department_tree",
        employee_url: "/api/index/get_employee",
        type: 1, //1单人,2多人
        fixedid: 0,
        ids: "",
        names: "",
        ajax_data: [],
        callback: function () {}
      };
      this.settings = $.extend({}, opts, options);
      var me = this;
      select_ids = [];
      select_names = [];
      select_array = [];
      if (me.settings.ids != "" && me.settings.names != "") {
        select_ids = me.settings.ids.split(",");
        select_names = me.settings.names.split(",");
        select_ids.sort((a, b) => a - b);
        for (var m = 0; m < select_ids.length; m++) {
          select_array.push({ id: select_ids[m], name: select_names[m] });
        }
      }
      $(parent.$(".express-close")).addClass("parent-colse");
      layer.open({
        type: 1,
        title: me.settings.title,
        area: ["800px", "500px"],
        resize: false,
        content: me.employeeRender(),
        end: function () {
          $(parent.$(".express-close")).removeClass("parent-colse");
        },
        success: function (obj, idx) {
          var dataList = [],
            letterBar = $("#letterBar"),
            employee = $("#employee"),
            selectTags = $("#selectTags");
          $.ajax({
            url: me.settings.department_url,
            type: "get",
            success: function (res) {
              //仅节点左侧图标控制收缩
              tree.render({
                elem: "#employeeDepament",
                data: res.trees,
                onlyIconControl: true, //是否仅允许节点左侧图标控制展开收缩
                click: function (obj) {
                  var tagsItem =
                    '<div style="color:#999; text-align:center;">暂无员工</div>';
                  $("#employeeDepament")
                    .find(".layui-tree-main")
                    .removeClass("on");
                  $(obj.elem).find(".layui-tree-main").eq(0).addClass("on");
                  letterBar.find("span").removeClass("on");
                  $.ajax({
                    url: me.settings.employee_url,
                    type: "get",
                    data: { did: obj.data.id },
                    success: function (res) {
                      me.ajax_data = res.data;
                      dataList = me.ajax_data;
                      if (dataList.length > 1 && me.settings.type == 2) {
                        $(".layui-tags-all").show();
                      } else {
                        $(".layui-tags-all").hide();
                      }
                      if (dataList.length > 0) {
                        tagsItem = "";
                        for (var i = 0; i < dataList.length; i++) {
                          if (select_ids.indexOf(dataList[i].id) == -1) {
                            tagsItem +=
                              '<span class="layui-tags-span" data-idx="' +
                              i +
                              '" data-id="' +
                              dataList[i].id +
                              '">' +
                              dataList[i].name +
                              "</span>";
                          } else {
                            tagsItem +=
                              '<span class="layui-tags-span on" data-idx="' +
                              i +
                              '" data-id="' +
                              dataList[i].id +
                              '">' +
                              dataList[i].name +
                              "</span>";
                          }
                        }
                      }
                      employee.html(tagsItem);
                    }
                  });
                }
              });
              letterBar.on("click", "span", function () {
                var code = $(this).data("code");
                $(this).addClass("on").siblings().removeClass("on");
                $.ajax({
                  url: me.settings.employee_url,
                  type: "get",
                  data: { id: 1 },
                  success: function (res) {
                    me.ajax_data = res.data;
                    var letterData = [],
                      tagsItem =
                        '<div style="color:#999; text-align:center;">暂无员工</div>';
                    if (me.ajax_data.length > 0) {
                      var tagsItemCode = "";
                      for (var i = 0; i < me.ajax_data.length; i++) {
                        if (me.ajax_data[i].username.slice(0, 1) == code) {
                          if (select_ids.indexOf(me.ajax_data[i].id) == -1) {
                            tagsItemCode +=
                              '<span class="layui-tags-span" data-idx="' +
                              i +
                              '" data-id="' +
                              me.ajax_data[i].id +
                              '">' +
                              me.ajax_data[i].name +
                              "</span>";
                          } else {
                            tagsItemCode +=
                              '<span class="layui-tags-span on" data-idx="' +
                              i +
                              '" data-id="' +
                              me.ajax_data[i].id +
                              '">' +
                              me.ajax_data[i].name +
                              "</span>";
                          }
                          letterData.push(me.ajax_data[i]);
                        }
                      }
                      dataList = letterData;
                      if (dataList.length > 2 && me.settings.type == 2) {
                        $(".layui-tags-all").show();
                      } else {
                        $(".layui-tags-all").hide();
                      }
                      if (tagsItemCode != "") {
                        tagsItem = tagsItemCode;
                      }
                    }
                    employee.html(tagsItem);
                  }
                });
              });
            }
          });
          if (me.settings.type == 2) {
            $(".layui-tags-all").on("click", function () {
              for (var a = 0; a < dataList.length; a++) {
                if (select_ids.indexOf(dataList[a]["id"]) == -1) {
                  select_array.push(dataList[a]);
                }
              }
              selectTags.html(me.employeeSelect(1));
            });
          }
          employee.on("click", ".layui-tags-span", function () {
            let item_idx = $(this).data("idx");
            let select_item = me.ajax_data[item_idx];
            if (me.settings.type == 1) {
              me.settings.callback([select_item]);
              layer.close(idx);
            } else {
              if (select_ids.indexOf(select_item["id"]) == -1) {
                select_array.push(select_item);
                selectTags.html(me.employeeSelect(1));
              }
            }
          });
          selectTags.on("click", ".layui-tags-close", function () {
            let id = $(this).data("id");
            let new_slected = [];
            $("#employee")
              .find('[data-id="' + id + '"]')
              .removeClass("on");
            for (var i = 0; i < select_array.length; i++) {
              if (select_array[i].id != id) {
                new_slected.push(select_array[i]);
              }
            }
            select_array = new_slected;
            selectTags.html(me.employeeSelect(1));
          });
          if (me.settings.type == 1) {
            $("#layui-layer" + idx)
              .find(".layui-layer-btn0")
              .hide();
          }
        },
        btn: ["确定添加", "清空已选"],
        btnAlign: "c",
        btn1: function (idx) {
          me.settings.callback(select_array);
          layer.close(idx);
        },
        btn2: function (idx) {
          let canceldata = {
            department: "",
            did: 0,
            id: 0,
            mobile: 0,
            name: "",
            nickname: "",
            position_id: 0,
            sex: 0,
            status: 0,
            thumb: "",
            username: ""
          };
          me.settings.callback([canceldata]);
          layer.close(idx);
        }
      });
    },
    picker: function (types, type, callback, map) {
      let pickerIndex = new Date().getTime();
      let pickerTable, options;
      const opts = {
        title: "选择",
        url: "",
        ids: "",
        titles: "",
        where: map,
        area: ["600px", "568px"],
        cols: [
          { field: "id", width: 80, title: "序号", align: "center" },
          { field: "title", title: "名称" }
        ],
        searchbar:
          '<form class="layui-form pb-2"><div class="layui-input-inline" style="width:420px; margin-right:5px;"><input type="text" name="keywords" placeholder="请输入关键字" class="layui-input" autocomplete="off" /></div><button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="picker">提交搜索</button><button type="reset" class="layui-btn layui-btn-reset" lay-filter="picker-reset">清空</button></form>',
        page: true,
        type: type, //1单选择,2多选
        btnno: true,
        add: "", //新增url
        callback: callback
      };
      if (Object.prototype.toString.call(types) === "[object Object]") {
        options = types;
      } else {
        options = dataPicker[types];
      }
      let settings = $.extend({}, opts, options);
      //console.log(settings);
      let btn = ["确定选择"];
      if (settings.btnno == true) {
        btn = ["确定选择", "清空已选"];
      }
      if (settings.add != "") {
        btn = ["确定选择", "清空已选", "新增"];
      }
      $(parent.$(".express-close")).addClass("parent-colse");
      layer.open({
        title: settings.title,
        area: settings.area,
        type: 1,
        skin: "gougu-picker",
        content:
          '<div class="picker-table" id="pickerBox' +
          pickerIndex +
          '">' +
          settings.searchbar +
          '<div id="pickerTable' +
          pickerIndex +
          '"></div></div>',
        end: function () {
          $(parent.$(".express-close")).removeClass("parent-colse");
        },
        success: function () {
          let cols = JSON.parse(JSON.stringify(settings.cols));
          if (settings.type == 1) {
            cols.splice(0, 0, { type: "radio", title: "选择" });
          }
          if (settings.type == 2) {
            cols.splice(0, 0, { type: "checkbox", title: "选择" });
          }
          // 单独处理
          // 班次的列格式化显示
          if (types == "workPlan") {
            cols[cols.length - 1].templet = function (d) {
              var html = "";
              if (d.times && d.times.length) {
                for (var i = 0; i < d.times.length; i++) {
                  html +=
                    "<span style='margin-right: 30px'>" +
                    d.times[i].begin_time +
                    " - " +
                    d.times[i].end_time +
                    "</span>";
                }
              } else {
                html = "-";
              }
              return html;
            };
          }
          pickerTable = table.render({
            elem: "#pickerTable" + pickerIndex,
            url: settings.url,
            where: settings.where,
            page: settings.page, //开启分页
            limit: 10,
            height: "407",
            cols: [cols]
          });
          //搜索提交
          form.on("submit(picker)", function (data) {
            let maps = $.extend({}, settings.where, data.field);
            pickerTable.reload({ where: maps, page: { curr: 1 } });
            return false;
          });
          //重置搜索提交
          $("#pickerBox" + pickerIndex).on(
            "click",
            '[lay-filter="picker-reset"]',
            function () {
              let prev = $(this).prev();
              if (typeof prev != "undefined") {
                setTimeout(function () {
                  prev.click();
                }, 10);
              }
            }
          );
        },
        btn: btn,
        btnAlign: "c",
        btn1: function (idx) {
          var checkStatus = table.checkStatus(pickerTable.config.id);
          var data = checkStatus.data;
          if (data.length > 0) {
            callback(data);
            layer.close(idx);
          } else {
            layer.msg("请先选择内容");
            return false;
          }
        },
        btn2: function (idx) {
          callback([{ id: 0, title: "", name: "" }]);
          layer.close(idx);
        },
        btn3: function (idx) {
          tool.side(settings.add);
          layer.close(idx);
        }
      });
    }
  };
  //选择员工弹窗
  $("body").on("click", ".picker-admin", function () {
    let that = $(this);
    let type = that.data("type");
    if (typeof type == "undefined" || type == "") {
      type = 1;
    }
    let ids = that.next().val() + "",
      names = that.val() + "";
    obj.employeeInit({
      ids: ids,
      names: names,
      type: type,
      callback: function (data) {
        let select_id = [],
          select_name = [];
        for (var a = 0; a < data.length; a++) {
          select_id.push(data[a].id);
          select_name.push(data[a].name);
        }
        console.log(select_name);
        that.val(select_name.join(","));
        that.next().val(select_id.join(","));
      }
    });
  });
  //选择下属员工弹窗
  $("body").on("click", ".picker-sub", function () {
    let that = $(this);
    let type = that.data("type");
    if (typeof type == "undefined" || type == "") {
      type = 1;
    }
    let ids = that.next().val() + "",
      names = that.val() + "";
    obj.employeeInit({
      title: "选择下属",
      department_url: "/api/index/get_department_tree_sub",
      employee_url: "/api/index/get_employee_sub",
      ids: ids,
      names: names,
      type: type,
      callback: function (data) {
        let select_id = [],
          select_name = [];
        for (var a = 0; a < data.length; a++) {
          select_id.push(data[a].id);
          select_name.push(data[a].name);
        }
        console.log(select_name);
        that.val(select_name.join(","));
        that.next().val(select_id.join(","));
      }
    });
  });
  //选择OA数据弹层
  $("body").on("click", ".picker-oa", function () {
    let that = $(this),
      ids = [],
      titles = [],
      map = {};
    let types = that.data("types");
    let type = that.data("type");
    let where = that.data("where");
    if (typeof types == "undefined" || types == "") {
      layer.msg("请设置【picker】的类型");
      return false;
    }
    if (typeof type == "undefined" || type == "") {
      type = 1;
    }
    if (typeof where == "undefined" || where == "") {
      map = {};
    } else {
      map = JSON.parse(where);
    }
    let callback = function (data) {
      for (var i = 0; i < data.length; i++) {
        ids.push(data[i].id);
        if (!data[i].title) {
          titles.push(data[i].name);
        } else {
          titles.push(data[i].title);
        }
      }
      that.val(titles.join(","));
      that.next().val(ids.join(","));
      // 单独处理班次按钮的处理结果
      if (types == "workPlan") {
        var selectName = data[0].name;
        var html = "";
        if (selectName) {
          html += selectName + ":";
        }
        if (data[0].times && data[0].times.length) {
          for (var i = 0; i < data[0].times.length; i++) {
            var timeItem = data[0].times[i];
            html +=
              "<span style='margin-right: 30px'>" +
              timeItem.begin_time +
              " - " +
              timeItem.end_time +
              "</span>";
          }
        }
        that.parent().prev().html(html);
      }
    };
    obj.picker(types, type, callback, map);
  });
  //输出接口
  exports("oaPicker", obj);
});