first commit
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
use think\facade\Db;
|
||||
|
||||
//获取项目状态
|
||||
function get_status($id=0)
|
||||
{
|
||||
$status_array = ['未设置','未开始','进行中','已完成','已关闭'];
|
||||
if($id==0){
|
||||
return $status_array;
|
||||
}
|
||||
else{
|
||||
$news_array=[];
|
||||
foreach($status_array as $key => $value){
|
||||
if($key>0){
|
||||
$news_array[]=array(
|
||||
'id'=>$key,
|
||||
'title'=>$value,
|
||||
);
|
||||
}
|
||||
}
|
||||
return $news_array;
|
||||
}
|
||||
}
|
||||
|
||||
//根据状态读取审批状态名称
|
||||
function status_name($status=0)
|
||||
{
|
||||
$status_array = get_status();
|
||||
return $status_array[$status];
|
||||
}
|
||||
|
||||
|
||||
//获取任务全部状态
|
||||
function get_task_status($id=0)
|
||||
{
|
||||
$status_task_array = ['未设置','未开始','进行中','已完成','已拒绝','已关闭'];
|
||||
if($id==0){
|
||||
return $status_task_array;
|
||||
}
|
||||
else{
|
||||
$news_array=[];
|
||||
foreach($status_task_array as $key => $value){
|
||||
if($key>0){
|
||||
$news_array[]=array(
|
||||
'id'=>$key,
|
||||
'title'=>$value,
|
||||
);
|
||||
}
|
||||
}
|
||||
return $news_array;
|
||||
}
|
||||
}
|
||||
|
||||
//根据任务状态读取审批状态名称
|
||||
function status_task_name($status=0)
|
||||
{
|
||||
$status_task_array = get_task_status();
|
||||
return $status_task_array[$status];
|
||||
}
|
||||
|
||||
//获取任务紧急程度
|
||||
function get_priority($id=0)
|
||||
{
|
||||
$priority_array = ['未设置','低','中','高','紧急'];
|
||||
if($id==0){
|
||||
return $priority_array;
|
||||
}
|
||||
else{
|
||||
$news_array=[];
|
||||
foreach($priority_array as $key => $value){
|
||||
if($key>0){
|
||||
$news_array[]=array(
|
||||
'id'=>$key,
|
||||
'title'=>$value,
|
||||
);
|
||||
}
|
||||
}
|
||||
return $news_array;
|
||||
}
|
||||
}
|
||||
|
||||
//根据任务紧急程度名称
|
||||
function priority_name($priority=0)
|
||||
{
|
||||
$priority_array = get_priority();
|
||||
return $priority_array[$priority];
|
||||
}
|
||||
|
||||
//是否是项目管理员,count>1即有权限
|
||||
function isAuthProject($uid)
|
||||
{
|
||||
if($uid == 1){
|
||||
return 1;
|
||||
}
|
||||
$map = [];
|
||||
$map[] = ['name', '=', 'project_admin'];
|
||||
$map[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',conf_1)")];
|
||||
$count = Db::name('DataAuth')->where($map)->count();
|
||||
return $count;
|
||||
}
|
||||
//读取项目
|
||||
function get_project($uid = 0)
|
||||
{
|
||||
$map = [];
|
||||
$map[] = ['delete_time', '=', 0];
|
||||
if ($uid > 0) {
|
||||
$project_ids = Db::name('ProjectUser')->where(['uid' => $uid, 'delete_time' => 0])->column('project_id');
|
||||
$map[] = ['id', 'in', $project_ids];
|
||||
}
|
||||
$project = Db::name('Project')->where($map)->select()->toArray();
|
||||
return $project;
|
||||
}
|
||||
|
||||
//任务分配情况统计
|
||||
function plan_count($arrData)
|
||||
{
|
||||
$documents = array();
|
||||
foreach ($arrData as $index => $value) {
|
||||
$planTime = date("Y-m-d", $value['end_time']);
|
||||
if (empty($documents[$planTime])) {
|
||||
$documents[$planTime] = 1;
|
||||
} else {
|
||||
$documents[$planTime] += 1;
|
||||
}
|
||||
}
|
||||
return $documents;
|
||||
}
|
||||
|
||||
//工时登记情况统计
|
||||
function hour_count($arrData)
|
||||
{
|
||||
$documents = array();
|
||||
foreach ($arrData as $index => $value) {
|
||||
$hourTime = date("Y-m-d", $value['start_time']);
|
||||
if (empty($documents[$hourTime])) {
|
||||
$documents[$hourTime] = $value['labor_time'] + 0;
|
||||
} else {
|
||||
$documents[$hourTime] += $value['labor_time'];
|
||||
}
|
||||
$documents[$hourTime] = round($documents[$hourTime], 2);
|
||||
}
|
||||
return $documents;
|
||||
}
|
||||
|
||||
//燃尽图统计
|
||||
function cross_count($arrData)
|
||||
{
|
||||
$documents = array();
|
||||
foreach ($arrData as $index => $value) {
|
||||
$planTime = date("Y-m-d", $value['end_time']);
|
||||
if (empty($documents[$planTime])) {
|
||||
$documents[$planTime] = 1;
|
||||
} else {
|
||||
$documents[$planTime] += 1;
|
||||
}
|
||||
}
|
||||
return $documents;
|
||||
}
|
||||
@@ -0,0 +1,623 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
declare (strict_types = 1);
|
||||
namespace app\project\controller;
|
||||
|
||||
use app\api\BaseController;
|
||||
use app\project\model\Project as ProjectModel;
|
||||
use app\project\model\ProjectTask;
|
||||
use app\oa\model\Schedule;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
|
||||
class Api extends BaseController
|
||||
{
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
protected $model;
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(); // 调用父类构造函数
|
||||
$this->model = new ProjectModel();
|
||||
}
|
||||
//获取项目列表
|
||||
public function get_project()
|
||||
{
|
||||
$param = get_params();
|
||||
$uid = $this->uid;
|
||||
$auth = isAuth($uid,'project_admin','conf_1');
|
||||
$where = array();
|
||||
$whereOr = array();
|
||||
$where[] = ['delete_time', '=', 0];
|
||||
if($auth == 0){
|
||||
$whereOr[] = ['director_uid', '=', $uid];
|
||||
$project_ids = Db::name('ProjectUser')->where(['uid' => $uid, 'delete_time' => 0])->column('project_id');
|
||||
$whereOr[] = ['id', 'in', $project_ids];
|
||||
$dids_a = get_leader_departments($uid);
|
||||
$dids_b = get_role_departments($uid);
|
||||
$dids = array_merge($dids_a, $dids_b);
|
||||
if(!empty($dids)){
|
||||
$whereOr[] = ['did','in',$dids];
|
||||
}
|
||||
}
|
||||
if (!empty($param['keywords'])) {
|
||||
$where[] = ['name|content', 'like', '%' . $param['keywords'] . '%'];
|
||||
}
|
||||
$list = $this->model->datalist($param,$where,$whereOr);
|
||||
return table_assign(0, '', $list);
|
||||
}
|
||||
|
||||
//获取任务列表
|
||||
public function get_task()
|
||||
{
|
||||
$param = get_params();
|
||||
$uid = $this->uid;
|
||||
$where = [];
|
||||
$whereOr = [];
|
||||
$where[] = ['delete_time', '=', 0];
|
||||
if (!empty($param['status'])) {
|
||||
$where[] = ['status', '=', $param['status']];
|
||||
}
|
||||
if (!empty($param['priority'])) {
|
||||
$where[] = ['priority', '=', $param['priority']];
|
||||
}
|
||||
if (!empty($param['work_id'])) {
|
||||
$where[] = ['work_id', '=', $param['work_id']];
|
||||
}
|
||||
if (!empty($param['director_uid'])) {
|
||||
$where[] = ['director_uid', 'in', $param['director_uid']];
|
||||
}
|
||||
if (!empty($param['keywords'])) {
|
||||
$where[] = ['title|content', 'like', '%' . $param['keywords'] . '%'];
|
||||
}
|
||||
if(!empty($param['project_id'])){
|
||||
$where[] = ['project_id', '=', $param['project_id']];
|
||||
}
|
||||
else{
|
||||
$auth = isAuth($uid,'project_admin','conf_1');
|
||||
if($auth == 0){
|
||||
$whereOr[] = ['admin_id', '=', $uid];
|
||||
$whereOr[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',assist_admin_ids)")];
|
||||
$dids_a = get_leader_departments($uid);
|
||||
$dids_b = get_role_departments($uid);
|
||||
$dids = array_merge($dids_a, $dids_b);
|
||||
if(!empty($dids)){
|
||||
$whereOr[] = ['did','in',$dids];
|
||||
}
|
||||
if (empty($param['director_uid'])) {
|
||||
$whereOr[] = ['director_uid', '=', $uid];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$model = new ProjectTask();
|
||||
$list = $model->datalist($param,$where,$whereOr);
|
||||
return table_assign(0, '', $list);
|
||||
}
|
||||
|
||||
//获取项目概况数据
|
||||
public function get_chart_data()
|
||||
{
|
||||
$param = get_params();
|
||||
$tasks = Db::name('ProjectTask')->field('id,plan_hours,end_time,status,over_time')->order('end_time asc')->where([['project_id', '=', $param['project_id']],['end_time','>',0],['delete_time', '=', 0]])->select()->toArray();
|
||||
|
||||
$task_count = count($tasks);
|
||||
$task_count_ok = Db::name('ProjectTask')->where([['project_id', '=', $param['project_id']], ['delete_time', '=', 0],['status', '>', 2]])->count();
|
||||
$task_delay = 0;
|
||||
if ($task_count > 0) {
|
||||
foreach ($tasks as $k => $v) {
|
||||
if (($v['status'] < 3) && ($v['end_time'] < time() - 86400)) {
|
||||
$task_delay++;
|
||||
}
|
||||
if (($v['status'] == 3) && ($v['end_time'] < $v['over_time'] - 86400)) {
|
||||
$task_delay++;
|
||||
}
|
||||
}
|
||||
}
|
||||
$task_pie = [
|
||||
'count' => $task_count,
|
||||
'count_ok' => $task_count_ok,
|
||||
'delay' => $task_delay,
|
||||
'ok_lv' => $task_count == 0 ? 100 : round($task_count_ok * 100 / $task_count, 2),
|
||||
'delay_lv' => $task_count == 0 ? 100 : round($task_delay * 100 / $task_count, 2),
|
||||
];
|
||||
|
||||
$date_tasks = [];
|
||||
if ($tasks) {
|
||||
$date_tasks = plan_count($tasks);
|
||||
}
|
||||
|
||||
$tasks_ok = Db::name('ProjectTask')->field('id,over_time as end_time')->order('over_time asc')->where([['over_time', '>', 0], ['delete_time', '=', 0], ['project_id', '=', $param['project_id']]])->select()->toArray();
|
||||
$date_tasks_ok = [];
|
||||
if ($tasks_ok) {
|
||||
$date_tasks_ok = plan_count($tasks_ok);
|
||||
}
|
||||
$tids = Db::name('ProjectTask')->where(['delete_time' => 0, 'project_id' => $param['project_id']])->column('id');
|
||||
$schedules = Db::name('Schedule')->where([['tid', 'in', $tids], ['delete_time', '=', 0]])->select()->toArray();
|
||||
$date_schedules = [];
|
||||
if ($schedules) {
|
||||
$date_schedules = hour_count($schedules);
|
||||
}
|
||||
$res['task_pie'] = $task_pie;
|
||||
$res['date_tasks'] = $date_tasks;
|
||||
$res['date_tasks_ok'] = $date_tasks_ok;
|
||||
$res['date_schedules'] = $date_schedules;
|
||||
to_assign(0, '', $res);
|
||||
}
|
||||
|
||||
//添加附件
|
||||
public function add_file()
|
||||
{
|
||||
$param = get_params();
|
||||
$param['create_time'] = time();
|
||||
$param['admin_id'] = $this->uid;
|
||||
$fid = Db::name('ProjectFile')->strict(false)->field(true)->insertGetId($param);
|
||||
if ($fid) {
|
||||
return to_assign(0, '上传成功', $fid);
|
||||
}
|
||||
}
|
||||
|
||||
//删除
|
||||
public function delete_file()
|
||||
{
|
||||
if (request()->isDelete()) {
|
||||
$id = get_params("id");
|
||||
$detail = Db::name('ProjectFile')->where('id', $id)->find();
|
||||
if (Db::name('ProjectFile')->where('id', $id)->delete() !== false) {
|
||||
$file_name = Db::name('File')->where('id', $detail['file_id'])->value('name');
|
||||
return to_assign(0, "删除成功");
|
||||
} else {
|
||||
return to_assign(0, "删除失败");
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
//工作记录列表
|
||||
public function schedule()
|
||||
{
|
||||
$param = get_params();
|
||||
$task_ids = Db::name('ProjectTask')->where(['delete_time' => 0, 'project_id' => $param['tid']])->column('id');
|
||||
$where = array();
|
||||
if (!empty($param['keywords'])) {
|
||||
$where[] = ['a.title', 'like', '%' . $param['keywords'] . '%'];
|
||||
}
|
||||
if (!empty($param['uid'])) {
|
||||
$where[] = ['a.admin_id', '=', $param['uid']];
|
||||
}
|
||||
if (!empty($task_ids)) {
|
||||
$where[] = ['a.tid', 'in', $task_ids];
|
||||
}
|
||||
$where[] = ['a.delete_time', '=', 0];
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$list = Schedule::where($where)
|
||||
->field('a.*,u.name,d.title as department,t.title as task,p.name as project,w.title as work_cate')
|
||||
->alias('a')
|
||||
->join('Admin u', 'a.admin_id = u.id', 'LEFT')
|
||||
->join('Department d', 'u.did = d.id', 'LEFT')
|
||||
->join('ProjectTask t', 'a.tid = t.id', 'LEFT')
|
||||
->join('WorkCate w', 'w.id = t.cate', 'LEFT')
|
||||
->join('Project p', 't.project_id = p.id', 'LEFT')
|
||||
->order('a.end_time desc')
|
||||
->paginate(['list_rows'=> $rows])
|
||||
->each(function ($item, $key) {
|
||||
$item->start_time_a = empty($item->start_time) ? '' : date('Y-m-d', $item->start_time);
|
||||
$item->start_time_b = empty($item->start_time) ? '' : date('H:i', $item->start_time);
|
||||
$item->end_time_a = empty($item->end_time) ? '' : date('Y-m-d', $item->end_time);
|
||||
$item->end_time_b = empty($item->end_time) ? '' : date('H:i', $item->end_time);
|
||||
|
||||
$item->start_time = empty($item->start_time) ? '' : date('Y-m-d H:i', $item->start_time);
|
||||
$item->end_time = empty($item->end_time) ? '' : date('H:i', $item->end_time);
|
||||
});
|
||||
return table_assign(0, '', $list);
|
||||
}
|
||||
|
||||
//查看工作记录详情
|
||||
public function schedule_detail($id)
|
||||
{
|
||||
$id = get_params('id');
|
||||
$schedule = Schedule::where(['id' => $id])->find();
|
||||
if (!empty($schedule)) {
|
||||
$schedule['start_time_1'] = date('H:i', $schedule['start_time']);
|
||||
$schedule['end_time_1'] = date('H:i', $schedule['end_time']);
|
||||
$schedule['start_time'] = date('Y-m-d', $schedule['start_time']);
|
||||
$schedule['end_time'] = date('Y-m-d', $schedule['end_time']);
|
||||
$schedule['user'] = Db::name('Admin')->where(['id' => $schedule['admin_id']])->value('name');
|
||||
$schedule['department'] = Db::name('Department')->where(['id' => $schedule['did']])->value('title');
|
||||
}
|
||||
if (request()->isAjax()) {
|
||||
return to_assign(0, "", $schedule);
|
||||
} else {
|
||||
return $schedule;
|
||||
}
|
||||
}
|
||||
|
||||
//任务的工作记录列表
|
||||
public function task_schedule()
|
||||
{
|
||||
$param = get_params();
|
||||
$where = array();
|
||||
$where['a.tid'] = $param['tid'];
|
||||
$where['a.delete_time'] = 0;
|
||||
$list = Db::name('Schedule')
|
||||
->field('a.*,u.name')
|
||||
->alias('a')
|
||||
->join('Admin u', 'u.id = a.admin_id')
|
||||
->order('a.create_time desc')
|
||||
->where($where)
|
||||
->select()->toArray();
|
||||
foreach ($list as $k => $v) {
|
||||
$list[$k]['start_time'] = empty($v['start_time']) ? '' : date('Y-m-d H:i', $v['start_time']);
|
||||
$list[$k]['end_time'] = empty($v['end_time']) ? '' : date('H:i', $v['end_time']);
|
||||
}
|
||||
return to_assign(0, '', $list);
|
||||
}
|
||||
|
||||
|
||||
public function project_user()
|
||||
{
|
||||
$param = get_params();
|
||||
$project = Db::name('Project')->where(['id' => $param['tid']])->find();
|
||||
$users = Db::name('ProjectUser')
|
||||
->field('pu.*,a.name,a.mobile,p.title as position,d.title as department')
|
||||
->alias('pu')
|
||||
->join('Admin a', 'pu.uid = a.id', 'LEFT')
|
||||
->join('Department d', 'a.did = d.id', 'LEFT')
|
||||
->join('Position p', 'a.position_id = p.id', 'LEFT')
|
||||
->order('pu.id asc')
|
||||
->where(['pu.project_id' => $param['tid']])
|
||||
->select()->toArray();
|
||||
if(!empty($users)){
|
||||
foreach ($users as $k => &$v) {
|
||||
$v['role'] = 0; //普通项目成员
|
||||
if ($v['uid'] == $project['admin_id']) {
|
||||
$v['role'] = 1; //项目创建人
|
||||
}
|
||||
if ($v['uid'] == $project['director_uid']) {
|
||||
$v['role'] = 2; //项目负责人
|
||||
}
|
||||
|
||||
$v['create_time'] = date('Y-m-d', (int) $v['create_time']);
|
||||
if($v['delete_time'] > 0){
|
||||
$v['delete_time'] = date('Y-m-d', (int) $v['delete_time']);
|
||||
}
|
||||
else{
|
||||
$v['delete_time'] = '-';
|
||||
}
|
||||
|
||||
$tids = Db::name('ProjectTask')->where([['project_id','=',$param['tid']],['delete_time','=',0]])->column('id');
|
||||
$schedule_map = [];
|
||||
$schedule_map[] = ['tid','in',$tids];
|
||||
$schedule_map[] = ['delete_time','=',0];
|
||||
$schedule_map[] = ['admin_id','=',$v['uid']];
|
||||
$v['schedules'] = Db::name('Schedule')->where($schedule_map)->count();
|
||||
$v['labor_times'] = Db::name('Schedule')->where($schedule_map)->sum('labor_time');
|
||||
|
||||
$task_map = [];
|
||||
$task_map[] = ['project_id','=',$param['tid']];
|
||||
$task_map[] = ['delete_time', '=', 0];
|
||||
|
||||
$task_map1 = [
|
||||
['admin_id', '=', $v['uid']],
|
||||
];
|
||||
$task_map2 = [
|
||||
['director_uid', '=', $v['uid']],
|
||||
];
|
||||
$task_map3 = [
|
||||
['', 'exp', Db::raw("FIND_IN_SET('{$v['uid']}',assist_admin_ids)")],
|
||||
];
|
||||
|
||||
//任务总数
|
||||
$v['tasks_total'] = Db::name('ProjectTask')
|
||||
->where(function ($query) use ($task_map1, $task_map2, $task_map3) {
|
||||
$query->where($task_map1)->whereor($task_map2)->whereor($task_map3);
|
||||
})
|
||||
->where($task_map)->count();
|
||||
//已完成任务
|
||||
$task_map[] = ['status', '>', 2]; //已完成
|
||||
$v['tasks_finish'] = Db::name('ProjectTask')->where(function ($query) use ($task_map1, $task_map2, $task_map3) {
|
||||
$query->where($task_map1)->whereor($task_map2)->whereor($task_map3);
|
||||
})
|
||||
->where($task_map)->count();
|
||||
//未完成任务
|
||||
$v['tasks_unfinish'] = $v['tasks_total'] - $v['tasks_finish'];
|
||||
$v['tasks_pensent'] = "100%";
|
||||
if ($v['tasks_total'] > 0) {
|
||||
$v['tasks_pensent'] = round($v['tasks_finish'] / $v['tasks_total'] * 100, 2) . "%";
|
||||
}
|
||||
}
|
||||
}
|
||||
to_assign(0, '', $users);
|
||||
}
|
||||
|
||||
//新增项目成员
|
||||
public function add_user()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isPost()) {
|
||||
if($param['uid'] == 0){
|
||||
to_assign(1, '已取消');
|
||||
}
|
||||
$has = Db::name('ProjectUser')->where(['uid' => $param['uid'],'project_id'=>$param['project_id']])->find();
|
||||
if(!empty($has)){
|
||||
to_assign(1, '该员工已经是项目成员');
|
||||
}
|
||||
$project = Db::name('Project')->where(['id' => $param['project_id']])->find();
|
||||
if($this->uid == 1 || $this->uid == $project['admin_id'] || $this->uid == $project['director_uid']){
|
||||
$param['admin_id'] = $this->uid;
|
||||
$param['create_time'] = time();
|
||||
$res = Db::name('ProjectUser')->strict(false)->field(true)->insert($param);
|
||||
if ($res) {
|
||||
to_assign();
|
||||
}
|
||||
}else{
|
||||
to_assign(1, '只有项目创建者和负责人才有权限新增项目成员');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//移除项目成员
|
||||
public function remove_user()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isDelete()) {
|
||||
$detail = Db::name('ProjectUser')->where(['id' => $param['id']])->find();
|
||||
$project = Db::name('Project')->where(['id' => $detail['project_id']])->find();
|
||||
if($this->uid == $project['admin_id'] || $this->uid == $project['director_uid']){
|
||||
if($detail['uid'] == $project['admin_id']){
|
||||
to_assign(1, '该项目成员是项目的创建者,不能移除');
|
||||
}
|
||||
if($detail['uid'] == $project['director_uid']){
|
||||
to_assign(1, '该项目成员是项目的负责人,需要去除负责人权限才能移除');
|
||||
}
|
||||
$param['delete_time'] = time();
|
||||
if (Db::name('ProjectUser')->update($param) !== false) {
|
||||
return to_assign(0, "移除成功");
|
||||
} else {
|
||||
return to_assign(1, "移除失败");
|
||||
}
|
||||
}else{
|
||||
to_assign(1, '只有项目创建者和负责人才有权限移除项目成员');
|
||||
}
|
||||
}else{
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
//恢复项目成员
|
||||
public function recover_user()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isPost()) {
|
||||
$detail = Db::name('ProjectUser')->where(['id' => $param['id']])->find();
|
||||
$project = Db::name('Project')->where(['id' => $detail['project_id']])->find();
|
||||
if($this->uid == $project['admin_id'] || $this->uid == $project['director_uid']){
|
||||
$param['delete_time'] = 0;
|
||||
if (Db::name('ProjectUser')->update($param) !== false) {
|
||||
return to_assign(0, "恢复成功");
|
||||
} else {
|
||||
return to_assign(1, "恢复失败");
|
||||
}
|
||||
}else{
|
||||
to_assign(1, '只有项目创建者和负责人才有权限恢复项目成员');
|
||||
}
|
||||
}else{
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
//关闭项目
|
||||
public function close()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$id = get_params("id");
|
||||
$project = Db::name('Project')->where('id', $id)->find();
|
||||
if($project['status'] == 3){
|
||||
return to_assign(1, "已完成的项目当不能关闭");
|
||||
}
|
||||
$auth = isAuth($this->uid,'project_admin','conf_1');
|
||||
if($project['admin_id'] == $this->uid || $project['director_uid'] == $this->uid || $auth==1){
|
||||
if (Db::name('Project')->where('id', $id)->update(['status'=>4]) !== false) {
|
||||
add_log('close', $id, [],'项目');
|
||||
return to_assign(0, "操作成功");
|
||||
} else {
|
||||
return to_assign(1, "操作失败");
|
||||
}
|
||||
}
|
||||
else{
|
||||
return to_assign(1, "只有项目管理员、项目创建人、项目负责人才有权限关闭");
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
//开启项目
|
||||
public function open()
|
||||
{
|
||||
if (request()->isPost()) {
|
||||
$id = get_params("id");
|
||||
$project = Db::name('Project')->where('id', $id)->find();
|
||||
if($project['status'] == 3){
|
||||
return to_assign(1, "已完成的项目当不能开启");
|
||||
}
|
||||
$auth = isAuth($this->uid,'project_admin','conf_1');
|
||||
if($project['admin_id'] == $this->uid || $project['director_uid'] == $this->uid || $auth==1){
|
||||
if (Db::name('Project')->where('id', $id)->update(['status'=>2]) !== false) {
|
||||
add_log('open', $id, [],'项目');
|
||||
return to_assign(0, "操作成功");
|
||||
} else {
|
||||
return to_assign(1, "操作失败");
|
||||
}
|
||||
}
|
||||
else{
|
||||
return to_assign(1, "只有项目管理员、项目创建人、项目负责人才有权限开启");
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
//删除已有的项目步骤
|
||||
public function step_del()
|
||||
{
|
||||
if (request()->isDelete()) {
|
||||
$id = get_params("id");
|
||||
$step = Db::name('ProjectStep')->where('id', $id)->find();
|
||||
if($step['is_current'] == 1){
|
||||
return to_assign(1, "项目当前所在步骤不能删除");
|
||||
}
|
||||
$project = Db::name('Project')->where('id', $step['project_id'])->find();
|
||||
$auth = isAuth($this->uid,'project_admin','conf_1');
|
||||
if($project['admin_id'] == $this->uid || $project['director_uid'] == $this->uid || $auth==1){
|
||||
if (Db::name('ProjectStep')->where('id', $id)->update(['delete_time'=>time()]) !== false) {
|
||||
return to_assign(0, "删除成功");
|
||||
} else {
|
||||
return to_assign(1, "删除失败");
|
||||
}
|
||||
}
|
||||
else{
|
||||
return to_assign(1, "只有项目管理员、项目创建人、项目负责人才有权限删除");
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
//审核
|
||||
public function step_check()
|
||||
{
|
||||
$param = get_params();
|
||||
$detail = Db::name('Project')->where(['id' => $param['id']])->find();
|
||||
if($detail['status'] > 3){
|
||||
return to_assign(1, "不支持该操作:项目已关闭");
|
||||
}
|
||||
//当前审核节点详情
|
||||
$step = Db::name('ProjectStep')->where(['project_id'=>$detail['id'],'is_current' => 1,'delete_time'=>0])->find();
|
||||
if (!empty($step) && $this->uid != $step['director_uid']){
|
||||
return to_assign(1,'您没权限操作');
|
||||
}
|
||||
//审核通过
|
||||
if($param['check'] == 1){
|
||||
$next_step = Db::name('ProjectStep')->where([['project_id','=',$detail['id']],['sort','>',$step['sort']],['delete_time','=',0]])->order('sort', 'asc')->find();
|
||||
if(!empty($next_step)){
|
||||
Db::name('ProjectStep')->where('id', $step['id'])->strict(false)->field(true)->update(['is_current'=>0]);
|
||||
Db::name('ProjectStep')->where('id', $next_step['id'])->strict(false)->field(true)->update(['is_current'=>1]);
|
||||
$param['status'] = 2;
|
||||
}
|
||||
else{
|
||||
//不存在下一步审核,审核结束
|
||||
$param['status'] = 3;
|
||||
Db::name('ProjectStep')->where('id', $step['id'])->strict(false)->field(true)->update(['is_current'=>0]);
|
||||
}
|
||||
//审核通过数据操作
|
||||
Db::name('Project')->strict(false)->field('status')->update($param);
|
||||
$checkData=array(
|
||||
'project_id' => $detail['id'],
|
||||
'step_id' => $step['id'],
|
||||
'check_uid' => $this->uid,
|
||||
'check_time' => time(),
|
||||
'status' => $param['check'],
|
||||
'content' => $param['content'],
|
||||
'create_time' => time()
|
||||
);
|
||||
Db::name('ProjectStepRecord')->strict(false)->field(true)->insertGetId($checkData);
|
||||
add_log('check', $param['id'], $param,'项目阶段');
|
||||
return to_assign();
|
||||
}
|
||||
//回退审核
|
||||
else if($param['check'] == 2){
|
||||
//获取上一步的审核信息
|
||||
$prev_step = Db::name('ProjectStep')->where([['project_id','=',$detail['id']],['sort','<',$step['sort']],['delete_time','=',0]])->order('sort', 'desc')->find();
|
||||
if(!empty($prev_step)){
|
||||
//存在上一步审核
|
||||
Db::name('ProjectStep')->where('id', $step['id'])->strict(false)->field(true)->update(['is_current'=>0]);
|
||||
Db::name('ProjectStep')->where('id', $prev_step['id'])->strict(false)->field(true)->update(['is_current'=>1]);
|
||||
$checkData=array(
|
||||
'project_id' => $detail['id'],
|
||||
'step_id' => $step['id'],
|
||||
'check_uid' => $this->uid,
|
||||
'check_time' => time(),
|
||||
'status' => $param['check'],
|
||||
'content' => $param['content'],
|
||||
'create_time' => time()
|
||||
);
|
||||
Db::name('ProjectStepRecord')->strict(false)->field(true)->insertGetId($checkData);
|
||||
add_log('refue', $param['id'], $param,'项目阶段');
|
||||
return to_assign();
|
||||
}
|
||||
else{
|
||||
return to_assign(1,'已经是第一个阶段了');
|
||||
}
|
||||
}
|
||||
//回退审核
|
||||
else if($param['check'] == 3){
|
||||
$auth = isAuth($this->uid,'project_admin','conf_1');
|
||||
if($detail['admin_id'] == $this->uid || $detail['director_uid'] == $this->uid || $auth==1){
|
||||
//获取最后一步的审核信息
|
||||
$prev_step = Db::name('ProjectStep')->where([['project_id','=',$detail['id']],['delete_time','=',0]])->order('sort', 'desc')->find();
|
||||
if(!empty($prev_step)){
|
||||
//最后一步审核
|
||||
Db::name('ProjectStep')->where('id', $prev_step['id'])->strict(false)->field(true)->update(['is_current'=>1]);
|
||||
Db::name('Project')->where('id', $detail['id'])->strict(false)->field(true)->update(['status'=>2]);
|
||||
$checkData=array(
|
||||
'project_id' => $detail['id'],
|
||||
'step_id' => $prev_step['id'],
|
||||
'check_uid' => $this->uid,
|
||||
'check_time' => time(),
|
||||
'status' => $param['check'],
|
||||
'content' => $param['content'],
|
||||
'create_time' => time()
|
||||
);
|
||||
Db::name('ProjectStepRecord')->strict(false)->field(true)->insertGetId($checkData);
|
||||
add_log('refue', $param['id'], $param,'项目阶段');
|
||||
return to_assign();
|
||||
}
|
||||
else{
|
||||
return to_assign(1,'项目阶段不存在');
|
||||
}
|
||||
}
|
||||
else{
|
||||
return to_assign(1, "只有项目管理员、项目创建人、项目负责人才有权限操作");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//获取项目类别
|
||||
public function get_project_cate()
|
||||
{
|
||||
$list = get_base_data('project_cate');
|
||||
return to_assign(0, '', $list);
|
||||
}
|
||||
|
||||
public function get_project_step()
|
||||
{
|
||||
$param = get_params();
|
||||
$where = array();
|
||||
if (!empty($param['keywords'])) {
|
||||
$where[] = ['title', 'like', '%' . $param['keywords'] . '%'];
|
||||
}
|
||||
$where[] = ['status', '=', 1];
|
||||
$where[] = ['delete_time', '=', 0];
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$list = Db::name('Step')->where($where)->order('id desc')->paginate(['list_rows'=> $rows]);
|
||||
return table_assign(0, '', $list);
|
||||
}
|
||||
|
||||
public function project_edit()
|
||||
{
|
||||
$param = get_params();
|
||||
$this->model->apiedit($param);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\project\controller;
|
||||
|
||||
use app\base\BaseController;
|
||||
use app\project\model\ProjectCate as ProjectCateModel;
|
||||
use app\project\validate\CateValidate;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
|
||||
class Cate extends BaseController
|
||||
{
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
protected $model;
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(); // 调用父类构造函数
|
||||
$this->model = new ProjectCateModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
public function datalist()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$list = $this->model->where('delete_time',0)->order('sort asc')->select();
|
||||
return to_assign(0, '', $list);
|
||||
}
|
||||
else{
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isAjax()) {
|
||||
if (!empty($param['id']) && $param['id'] > 0) {
|
||||
try {
|
||||
validate(CateValidate::class)->scene('edit')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$this->model->edit($param);
|
||||
} else {
|
||||
try {
|
||||
validate(CateValidate::class)->scene('add')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$this->model->add($param);
|
||||
}
|
||||
}else{
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
if ($id>0) {
|
||||
$detail = $this->model->getById($id);
|
||||
View::assign('detail', $detail);
|
||||
}
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
public function view($id)
|
||||
{
|
||||
$detail = $this->model->getById($id);
|
||||
if (!empty($detail)) {
|
||||
View::assign('detail', $detail);
|
||||
return view();
|
||||
}
|
||||
else{
|
||||
return view(EEEOR_REPORTING,['code'=>404,'warning'=>'找不到页面']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
if (request()->isDelete()) {
|
||||
$param = get_params();
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
$type = isset($param['type']) ? $param['type'] : 0;
|
||||
$this->model->delById($id,$type);
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
*/
|
||||
public function set()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$param = get_params();
|
||||
$res = $this->model->strict(false)->field('id,status')->update($param);
|
||||
if ($res) {
|
||||
if($param['status'] == 0){
|
||||
add_log('disable', $param['id'], $param);
|
||||
}
|
||||
else if($param['status'] == 1){
|
||||
add_log('recovery', $param['id'], $param);
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
else{
|
||||
return to_assign(0, '操作失败');
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\project\controller;
|
||||
|
||||
use app\base\BaseController;
|
||||
use app\project\model\ProjectDocument;
|
||||
use app\project\validate\DocumentCheck;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
|
||||
class Document extends BaseController
|
||||
{
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
protected $model;
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(); // 调用父类构造函数
|
||||
$this->model = new ProjectDocument();
|
||||
}
|
||||
|
||||
public function datalist()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$param = get_params();
|
||||
$where = array();
|
||||
$whereOr = array();
|
||||
if (!empty($param['keywords'])) {
|
||||
$where[] = ['title|content', 'like', '%' . $param['keywords'] . '%'];
|
||||
}
|
||||
if (!empty($param['project_id'])) {
|
||||
$where[] = ['project_id', '=', $param['project_id']];
|
||||
} else {
|
||||
$project_ids = Db::name('ProjectUser')->where(['uid' => $this->uid, 'delete_time' => 0])->column('project_id');
|
||||
$whereOr[] = ['admin_id', '=', $this->uid];
|
||||
$whereOr[] = ['project_id', 'in', $project_ids];
|
||||
}
|
||||
$where[] = ['delete_time', '=', 0];
|
||||
$list = $this->model->datalist($param,$where,$whereOr);
|
||||
return table_assign(0, '', $list);
|
||||
} else {
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
//添加
|
||||
public function add()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isPost()) {
|
||||
if (!empty($param['id']) && $param['id'] > 0) {
|
||||
$detail = $this->model->detail($param['id']);
|
||||
try {
|
||||
validate(DocumentCheck::class)->scene('edit')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$param['update_time'] = time();
|
||||
$res = ProjectDocument::where('id', $param['id'])->strict(false)->field(true)->update($param);
|
||||
if ($res) {
|
||||
add_log('edit', $param['id'], $param);
|
||||
}
|
||||
return to_assign();
|
||||
} else {
|
||||
try {
|
||||
validate(DocumentCheck::class)->scene('add')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$param['create_time'] = time();
|
||||
$param['admin_id'] = $this->uid;
|
||||
$sid = ProjectDocument::strict(false)->field(true)->insertGetId($param);
|
||||
if ($sid) {
|
||||
add_log('add', $sid, $param);
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
} else {
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
$project_id = isset($param['project_id']) ? $param['project_id'] : 0;
|
||||
if($id>0){
|
||||
$detail = $this->model->detail($id);
|
||||
if($detail['file_ids'] !=''){
|
||||
$file_array = Db::name('File')->where('id','in',$detail['file_ids'])->select();
|
||||
$detail['file_array'] = $file_array;
|
||||
}
|
||||
View::assign('detail', $detail);
|
||||
}
|
||||
if($project_id>0){
|
||||
$project_name = Db::name('Project')->where(['id' => $project_id])->value('name');
|
||||
View::assign('project_name', $project_name);
|
||||
}
|
||||
View::assign('project_id', $project_id);
|
||||
View::assign('id', $id);
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
//查看
|
||||
public function view()
|
||||
{
|
||||
$param = get_params();
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
$detail = $this->model->detail($id);
|
||||
if (empty($detail)) {
|
||||
if (empty($detail)) {
|
||||
echo '<div style="text-align:center;color:red;margin-top:20%;">该文档不存在</div>';exit;
|
||||
}
|
||||
} else {
|
||||
$project_ids = Db::name('ProjectUser')->where(['uid' => $this->uid, 'delete_time' => 0])->column('project_id');
|
||||
if (in_array($detail['project_id'], $project_ids) || ($this->uid = $detail['admin_id'])) {
|
||||
if($detail['file_ids'] !=''){
|
||||
$file_array = Db::name('File')->where('id','in',$detail['file_ids'])->select();
|
||||
$detail['file_array'] = $file_array;
|
||||
}
|
||||
View::assign('detail', $detail);
|
||||
if(is_mobile()){
|
||||
return view('qiye@/project/document_view');
|
||||
}
|
||||
return view();
|
||||
}
|
||||
else{
|
||||
echo '<div style="text-align:center;color:red;margin-top:20%;">您没权限查看该文档</div>';exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//删除
|
||||
public function delete()
|
||||
{
|
||||
if (request()->isDelete()) {
|
||||
$id = get_params("id");
|
||||
$detail = Db::name('ProjectDocument')->where('id', $id)->find();
|
||||
if ($detail['admin_id'] != $this->uid) {
|
||||
return to_assign(1, "你不是该文档的创建人,无权限删除");
|
||||
}
|
||||
if (Db::name('ProjectDocument')->where('id', $id)->update(['delete_time' => time()]) !== false) {
|
||||
return to_assign(0, "删除成功");
|
||||
} else {
|
||||
return to_assign(0, "删除失败");
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\project\controller;
|
||||
|
||||
use app\base\BaseController;
|
||||
use app\project\model\Project as ProjectModel;
|
||||
use app\project\validate\IndexValidate;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
|
||||
class Index extends BaseController
|
||||
{
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
protected $model;
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(); // 调用父类构造函数
|
||||
$this->model = new ProjectModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
public function datalist()
|
||||
{
|
||||
$param = get_params();
|
||||
$uid = $this->uid;
|
||||
$auth = isAuth($uid,'project_admin','conf_1');
|
||||
$tab = isset($param['tab']) ? $param['tab'] : 0;
|
||||
if (request()->isAjax()) {
|
||||
$where = array();
|
||||
$whereOr = array();
|
||||
$where[] = ['delete_time', '=', 0];
|
||||
if (!empty($param['status'])) {
|
||||
$where[] = ['status', '=', $param['status']];
|
||||
}
|
||||
if (!empty($param['cate_id'])) {
|
||||
$where[] = ['cate_id', '=', $param['cate_id']];
|
||||
}
|
||||
if (!empty($param['keywords'])) {
|
||||
$where[] = ['name|content', 'like', '%' . $param['keywords'] . '%'];
|
||||
}
|
||||
if (!empty($param['director_uid'])) {
|
||||
$where[] = ['director_uid', 'in', $param['director_uid']];
|
||||
}
|
||||
else{
|
||||
if($auth == 0){
|
||||
$whereOr[] = ['director_uid', '=', $uid];
|
||||
$project_ids = Db::name('ProjectUser')->where(['uid' => $uid, 'delete_time' => 0])->column('project_id');
|
||||
$whereOr[] = ['id', 'in', $project_ids];
|
||||
$dids_a = get_leader_departments($uid);
|
||||
$dids_b = get_role_departments($uid);
|
||||
$dids = array_merge($dids_a, $dids_b);
|
||||
if(!empty($dids)){
|
||||
$whereOr[] = ['did','in',$dids];
|
||||
}
|
||||
}
|
||||
}
|
||||
if($tab == 0){
|
||||
|
||||
}
|
||||
if($tab == 1){
|
||||
$where[] = ['status', '=', 2];
|
||||
}
|
||||
if($tab == 2){
|
||||
$time = time();
|
||||
$dalay_time = time()+7*86400;
|
||||
$where[] = ['status', '<', 3];
|
||||
$where[] = ['end_time', 'between', [$time,$dalay_time]];
|
||||
}
|
||||
if($tab == 3){
|
||||
$where[] = ['status', '<', 3];
|
||||
$where[] = ['end_time', '<', time()];
|
||||
}
|
||||
$list = $this->model->datalist($param,$where,$whereOr);
|
||||
return table_assign(0, '', $list);
|
||||
}
|
||||
else{
|
||||
View::assign('auth', $auth);
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isAjax()) {
|
||||
if (isset($param['range_time'])) {
|
||||
$range_time = explode('到',$param['range_time']);
|
||||
$param['start_time'] = strtotime(urldecode(trim($range_time[0])));
|
||||
$param['end_time'] = strtotime(urldecode(trim($range_time[1])));
|
||||
}
|
||||
else{
|
||||
$param['start_time'] = strtotime(urldecode(trim($param['start_time'])));
|
||||
$param['end_time'] = strtotime(urldecode(trim($param['end_time'])));
|
||||
}
|
||||
$step_title_data = isset($param['step_title']) ? $param['step_title'] : '';
|
||||
$step_director_uid_data = isset($param['step_director_uid']) ? $param['step_director_uid'] : '';
|
||||
$step_uids_data = isset($param['step_uids']) ? $param['step_uids'] : '';
|
||||
$step_start_time_data = isset($param['step_start_time']) ? $param['step_start_time'] : '';
|
||||
$step_end_time_data = isset($param['step_end_time']) ? $param['step_end_time'] : '';
|
||||
$step_cycle_time_data = isset($param['step_cycle_time']) ? $param['step_cycle_time'] : '';
|
||||
$step_remark_data = isset($param['step_remark']) ? $param['step_remark'] : '';
|
||||
$step_id_data = isset($param['step_id']) ? $param['step_id'] : 0;
|
||||
|
||||
$step = [];
|
||||
$time_1 = $param['start_time'];
|
||||
$time_2 = $param['end_time'];
|
||||
if(!empty($step_title_data)){
|
||||
foreach ($step_title_data as $key => $value) {
|
||||
if (!$value) {
|
||||
continue;
|
||||
}
|
||||
if(!empty($step_cycle_time_data)){
|
||||
$step_cycle_time = explode('到',$step_cycle_time_data[$key]);
|
||||
$start_time = strtotime(urldecode(trim($step_cycle_time[0])));
|
||||
$end_time = strtotime(urldecode(trim($step_cycle_time[1])));
|
||||
}
|
||||
else{
|
||||
$start_time = strtotime(urldecode(trim($step_start_time_data[$key])));
|
||||
$end_time = strtotime(urldecode(trim($step_end_time_data[$key])));
|
||||
}
|
||||
if($start_time<$time_1){
|
||||
return to_assign(1, '第'.($key+1).'阶段的开始时间不能小于项目计划周期的开始时间');
|
||||
break;
|
||||
}
|
||||
if($end_time>$time_2){
|
||||
return to_assign(1, '第'.($key+1).'阶段的结束时间不能大于项目计划周期的结束时间');
|
||||
break;
|
||||
}
|
||||
$item = [];
|
||||
$item['title'] = $value;
|
||||
$item['director_uid'] = $step_director_uid_data[$key];
|
||||
$item['uids'] = $step_uids_data[$key];
|
||||
$item['sort'] = $key;
|
||||
$item['start_time'] = $start_time;
|
||||
$item['end_time'] = $end_time;
|
||||
$item['remark'] = $step_remark_data[$key];
|
||||
$item['id'] = $step_id_data[$key];
|
||||
$item['create_time'] = time();
|
||||
$step[]=$item;
|
||||
}
|
||||
}
|
||||
if (!empty($param['id']) && $param['id'] > 0) {
|
||||
try {
|
||||
validate(IndexValidate::class)->scene('edit')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$this->model->edit($param,$step);
|
||||
} else {
|
||||
try {
|
||||
validate(IndexValidate::class)->scene('add')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$param['status'] = 2;
|
||||
$param['step_sort'] = 0;
|
||||
$param['admin_id'] = $this->uid;
|
||||
$this->model->add($param,$step);
|
||||
}
|
||||
}else{
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
if ($id>0) {
|
||||
$detail = $this->model->getById($id);
|
||||
$detail['current_step'] = Db::name('ProjectStep')->where(['project_id' => $id, 'is_current' => 1,'delete_time'=>0])->value('sort');
|
||||
View::assign('detail', $detail);
|
||||
if(is_mobile()){
|
||||
return view('qiye@/project/project_edit');
|
||||
}
|
||||
return view('edit');
|
||||
}
|
||||
if(is_mobile()){
|
||||
return view('qiye@/project/project_add');
|
||||
}
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
public function view($id)
|
||||
{
|
||||
$detail = $this->model->getById($id);
|
||||
if (!empty($detail)) {
|
||||
$detail['status_name'] = status_name($detail['status']);
|
||||
$detail['cate'] = Db::name('ProjectCate')->where([['id', '=', $detail['cate_id']]])->value('title');
|
||||
$team_admin_ids = Db::name('ProjectUser')->where(['delete_time' => 0,'project_id'=>$id])->column('uid');
|
||||
$team_admin_names = Db::name('Admin')->where('id', 'in', $team_admin_ids)->column('name');
|
||||
$detail['team_admin_names'] = implode(',', $team_admin_names);
|
||||
|
||||
$tids = Db::name('ProjectTask')->where([['project_id', '=', $detail['id']], ['delete_time', '=', 0]])->column('id');
|
||||
$detail['schedules'] = Db::name('Schedule')->where([['tid', 'in', $tids], ['delete_time', '=', 0]])->count();
|
||||
$detail['hours'] = Db::name('Schedule')->where([['tid', 'in', $tids], ['delete_time', '=', 0]])->sum('labor_time');
|
||||
$detail['plan_hours'] = Db::name('ProjectTask')->where([['project_id', '=', $detail['id']], ['delete_time', '=', 0]])->sum('plan_hours');
|
||||
|
||||
$detail['tasks'] = Db::name('ProjectTask')->where([['project_id', '=', $detail['id']],['delete_time', '=', 0]])->count();
|
||||
$detail['tasks_finish'] = Db::name('ProjectTask')->where([['project_id', '=', $detail['id']],['status', '>', 2], ['delete_time', '=', 0]])->count();
|
||||
$detail['tasks_unfinish'] = $detail['tasks'] - $detail['tasks_finish'];
|
||||
|
||||
$task_map = [];
|
||||
$task_map[] = ['project_id', '=', $detail['id']];
|
||||
$task_map[] = ['delete_time', '=', 0];
|
||||
//判断是否是创建者或者负责人
|
||||
$role = 0;
|
||||
if ($detail['admin_id'] == $this->uid) {
|
||||
$role = 1; //创建人
|
||||
}
|
||||
if ($detail['director_uid'] == $this->uid) {
|
||||
$role = 2; //负责人
|
||||
}
|
||||
$auth = isAuth($this->uid,'project_admin','conf_1');
|
||||
if ($auth == 1) {
|
||||
$role = 3; //项目管理员
|
||||
}
|
||||
|
||||
//相关附件
|
||||
$file_array = Db::name('ProjectFile')
|
||||
->field('mf.id,mf.topic_id,mf.admin_id,f.id as file_id,f.name,f.filesize,f.filepath,f.fileext,f.create_time,f.admin_id,a.name as admin_name')
|
||||
->alias('mf')
|
||||
->join('File f', 'mf.file_id = f.id', 'LEFT')
|
||||
->join('Admin a', 'mf.admin_id = a.id', 'LEFT')
|
||||
->order('mf.create_time desc')
|
||||
->where(array('mf.topic_id' => $id, 'mf.module' => 'project'))
|
||||
->select()->toArray();
|
||||
|
||||
//阶段操作记录
|
||||
$step_record = Db::name('ProjectStepRecord')
|
||||
->field('s.*,a.name as check_name,p.title')
|
||||
->alias('s')
|
||||
->join('Admin a', 'a.id = s.check_uid', 'LEFT')
|
||||
->join('ProjectStep p', 'p.id = s.step_id', 'LEFT')
|
||||
->order('s.check_time asc')
|
||||
->where(array('s.project_id' => $id))
|
||||
->select()->toArray();
|
||||
foreach ($step_record as $kk => &$vv) {
|
||||
$vv['check_time_str'] = date('Y-m-d H:i', $vv['check_time']);
|
||||
$vv['status_str'] = '提交';
|
||||
if($vv['status'] == 1){
|
||||
$vv['status_str'] = '确认完成';
|
||||
}
|
||||
else if($vv['status'] == 2){
|
||||
$vv['status_str'] = '回退';
|
||||
}
|
||||
if($vv['status'] == 3){
|
||||
$vv['status_str'] = '撤销';
|
||||
}
|
||||
if($vv['content'] == ''){
|
||||
$vv['content'] = '无';
|
||||
}
|
||||
}
|
||||
|
||||
//当前项目阶段
|
||||
$step = Db::name('ProjectStep')->where(array('project_id' => $id, 'is_current' => 1,'delete_time'=>0))->find();
|
||||
if(!empty($step)){
|
||||
$step['director_name'] = Db::name('Admin')->where(['id' => $step['director_uid']])->value('name');
|
||||
$unames = Db::name('Admin')->where([['id','in',$step['uids']]])->column('name');
|
||||
$step['unames'] = implode(',',$unames);
|
||||
}
|
||||
View::assign('role', $role);
|
||||
View::assign('file_array', $file_array);
|
||||
View::assign('step', $step);
|
||||
View::assign('step_record', $step_record);
|
||||
View::assign('detail', $detail);
|
||||
if(is_mobile()){
|
||||
return view('qiye@/project/view');
|
||||
}
|
||||
return view();
|
||||
}
|
||||
else{
|
||||
return view(EEEOR_REPORTING,['code'=>404,'warning'=>'找不到页面']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
$param = get_params();
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
if (request()->isDelete()) {
|
||||
$this->model->delById($id);
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\project\controller;
|
||||
|
||||
use app\base\BaseController;
|
||||
use app\project\model\Step as StepModel;
|
||||
use app\project\validate\StepValidate;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
|
||||
class Step extends BaseController
|
||||
{
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
protected $model;
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(); // 调用父类构造函数
|
||||
$this->model = new StepModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
public function datalist()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$list = $this->model->where('delete_time',0)->order('sort asc')->select();
|
||||
return to_assign(0, '', $list);
|
||||
}
|
||||
else{
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isAjax()) {
|
||||
if (!empty($param['id']) && $param['id'] > 0) {
|
||||
try {
|
||||
validate(StepValidate::class)->scene('edit')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$this->model->edit($param);
|
||||
} else {
|
||||
try {
|
||||
validate(StepValidate::class)->scene('add')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$this->model->add($param);
|
||||
}
|
||||
}else{
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
if ($id>0) {
|
||||
$detail = $this->model->getById($id);
|
||||
View::assign('detail', $detail);
|
||||
}
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
public function view($id)
|
||||
{
|
||||
$detail = $this->model->getById($id);
|
||||
if (!empty($detail)) {
|
||||
View::assign('detail', $detail);
|
||||
return view();
|
||||
}
|
||||
else{
|
||||
return view(EEEOR_REPORTING,['code'=>404,'warning'=>'找不到页面']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
if (request()->isDelete()) {
|
||||
$param = get_params();
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
$type = isset($param['type']) ? $param['type'] : 0;
|
||||
$this->model->delById($id,$type);
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
*/
|
||||
public function set()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$param = get_params();
|
||||
$res = $this->model->strict(false)->field('id,status')->update($param);
|
||||
if ($res) {
|
||||
if($param['status'] == 0){
|
||||
add_log('disable', $param['id'], $param);
|
||||
}
|
||||
else if($param['status'] == 1){
|
||||
add_log('recovery', $param['id'], $param);
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
else{
|
||||
return to_assign(0, '操作失败');
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\project\controller;
|
||||
|
||||
use app\base\BaseController;
|
||||
use app\project\model\ProjectTask;
|
||||
use app\api\model\Comment;
|
||||
use app\oa\model\Schedule;
|
||||
use app\api\model\EditLog;
|
||||
use app\project\validate\TaskCheck;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
|
||||
class Task extends BaseController
|
||||
{
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
protected $model;
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(); // 调用父类构造函数
|
||||
$this->model = new ProjectTask();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
public function datalist()
|
||||
{
|
||||
$param = get_params();
|
||||
$uid = $this->uid;
|
||||
$auth = isAuth($uid,'project_admin','conf_1');
|
||||
if (request()->isAjax()) {
|
||||
$tab = isset($param['tab']) ? $param['tab'] : 0;
|
||||
$time = time();
|
||||
$time = time();
|
||||
$dalay_time = time()+7*86400;
|
||||
$where = [];
|
||||
$whereOr = [];
|
||||
$where[] = ['delete_time', '=', 0];
|
||||
if (!empty($param['status'])) {
|
||||
$where[] = ['status', '=', $param['status']];
|
||||
}
|
||||
if (!empty($param['priority'])) {
|
||||
$where[] = ['priority', '=', $param['priority']];
|
||||
}
|
||||
if (!empty($param['work_id'])) {
|
||||
$where[] = ['work_id', '=', $param['work_id']];
|
||||
}
|
||||
if (!empty($param['keywords'])) {
|
||||
$where[] = ['title|content', 'like', '%' . $param['keywords'] . '%'];
|
||||
}
|
||||
if(!empty($param['project_id'])){
|
||||
$where[] = ['project_id', '=', $param['project_id']];
|
||||
}
|
||||
if (!empty($param['director_uid'])) {
|
||||
$where[] = ['director_uid', 'in', $param['director_uid']];
|
||||
}
|
||||
else{
|
||||
if($auth == 0){
|
||||
$whereOr[] = ['admin_id', '=', $uid];
|
||||
$whereOr[] = ['', 'exp', Db::raw("FIND_IN_SET('{$uid}',assist_admin_ids)")];
|
||||
$dids_a = get_leader_departments($uid);
|
||||
$dids_b = get_role_departments($uid);
|
||||
$dids = array_merge($dids_a, $dids_b);
|
||||
if(!empty($dids)){
|
||||
$whereOr[] = ['did','in',$dids];
|
||||
}
|
||||
if (empty($param['director_uid'])) {
|
||||
$whereOr[] = ['director_uid', '=', $uid];
|
||||
}
|
||||
}
|
||||
}
|
||||
if($tab==1){
|
||||
//进行中
|
||||
$where[] = ['status', '<', 3];
|
||||
}
|
||||
if($tab==2){
|
||||
//即将逾期
|
||||
$where[] = ['status', '<', 3];
|
||||
$where[] = ['end_time','between',[$time,$dalay_time]];
|
||||
}
|
||||
if($tab==3){
|
||||
//已逾期
|
||||
$where[] = ['status', '<', 3];
|
||||
$where[] = ['end_time','<',$time];
|
||||
}
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$order = empty($param['order']) ? 'status asc,id desc' : $param['order'];
|
||||
$list = $this->model->datalist($param,$where,$whereOr);
|
||||
return table_assign(0, '', $list);
|
||||
}
|
||||
else{
|
||||
View::assign('auth', $auth);
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
//添加
|
||||
public function add()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isPost()) {
|
||||
if (isset($param['end_time'])) {
|
||||
$param['end_time'] = strtotime(urldecode($param['end_time']));
|
||||
}
|
||||
if (isset($param['status'])) {
|
||||
if ($param['status'] == 3) {
|
||||
$param['over_time'] = time();
|
||||
$param['done_ratio'] = 100;
|
||||
} else {
|
||||
$param['over_time'] = 0;
|
||||
$param['done_ratio'] = 10;
|
||||
}
|
||||
}
|
||||
if (!empty($param['id']) && $param['id'] > 0) {
|
||||
$old = $this->model->detail($param['id']);
|
||||
try {
|
||||
validate(TaskCheck::class)->scene('edit')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$param['update_time'] = time();
|
||||
if(!empty($param['director_uid'])){
|
||||
$param['did'] = Db::name('Admin')->where(['id' => $param['director_uid']])->value('did');
|
||||
}
|
||||
$res = ProjectTask::where('id', $param['id'])->strict(false)->field(true)->update($param);
|
||||
if ($res) {
|
||||
add_log('edit', $param['id'], $param);
|
||||
$log=new EditLog();
|
||||
$log->edit('Task',$param['id'],$param,$old);
|
||||
}
|
||||
return to_assign();
|
||||
} else {
|
||||
try {
|
||||
validate(TaskCheck::class)->scene('add')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$param['create_time'] = time();
|
||||
$param['admin_id'] = $this->uid;
|
||||
if(empty($param['director_uid'])){
|
||||
$param['did'] = $this->did;
|
||||
}
|
||||
else{
|
||||
$param['did'] = Db::name('Admin')->where(['id' => $param['director_uid']])->value('did');
|
||||
}
|
||||
$insertId = ProjectTask::strict(false)->field(true)->insertGetId($param);
|
||||
if ($insertId) {
|
||||
add_log('add', $insertId, $param);
|
||||
$log=new EditLog();
|
||||
$log->add('Task',$insertId);
|
||||
//发消息
|
||||
//event('SendMessage',$msg);
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
} else {
|
||||
if (isset($param['project_id'])) {
|
||||
View::assign('project_id', $param['project_id']);
|
||||
}
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
//查看
|
||||
public function view()
|
||||
{
|
||||
$param = get_params();
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
$detail = (new ProjectTask())->detail($id);
|
||||
$role_uid = [$detail['admin_id'], $detail['director_uid']];
|
||||
$role_edit = 'view';
|
||||
if (in_array($this->uid, $role_uid)) {
|
||||
$role_edit = 'edit';
|
||||
}
|
||||
$project_ids = Db::name('ProjectUser')->where(['uid' => $this->uid, 'delete_time' => 0])->column('project_id');
|
||||
$auth = isAuth($this->uid,'project_admin','conf_1');
|
||||
if (in_array($detail['project_id'], $project_ids) || in_array($this->uid, $role_uid) || in_array($this->uid, explode(",",$detail['assist_admin_ids'])) || $auth==1) {
|
||||
$file_array = Db::name('ProjectFile')
|
||||
->field('mf.id,mf.topic_id,mf.admin_id,mf.file_id,f.name,f.filesize,f.filepath,f.fileext,f.create_time,f.admin_id,a.name as admin_name')
|
||||
->alias('mf')
|
||||
->join('File f', 'mf.file_id = f.id', 'LEFT')
|
||||
->join('Admin a', 'mf.admin_id = a.id', 'LEFT')
|
||||
->order('mf.create_time desc')
|
||||
->where(array('mf.topic_id' => $id, 'mf.module' => 'task'))
|
||||
->select()->toArray();
|
||||
|
||||
View::assign('detail', $detail);
|
||||
View::assign('file_array', $file_array);
|
||||
View::assign('role_edit', $role_edit);
|
||||
View::assign('id', $id);
|
||||
if(is_mobile()){
|
||||
return view('qiye@/project/task_view');
|
||||
}
|
||||
return view();
|
||||
}
|
||||
else{
|
||||
return view(EEEOR_REPORTING,['code'=>405,'warning'=>'无权限访问']);
|
||||
}
|
||||
}
|
||||
|
||||
//删除
|
||||
public function del()
|
||||
{
|
||||
if (request()->isDelete()) {
|
||||
$id = get_params("id");
|
||||
$auth = isAuth($this->uid,'project_admin','conf_1');
|
||||
$detail = Db::name('ProjectTask')->where('id', $id)->find();
|
||||
if ($detail['admin_id'] != $this->uid && $auth==0) {
|
||||
return to_assign(1, "你不是该任务的创建人,无权限删除");
|
||||
}
|
||||
$hour = Db::name('Schedule')->where(['tid' => $id,'delete_time' => 0])->count();
|
||||
if($hour>0){
|
||||
return to_assign(1, "已有工作日志的任务不支持删除");
|
||||
}
|
||||
if (Db::name('ProjectTask')->where('id', $id)->update(['delete_time' => time()]) !== false) {
|
||||
return to_assign(0, "删除成功");
|
||||
} else {
|
||||
return to_assign(0, "删除失败");
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
public function hour() {
|
||||
if (request()->isAjax()) {
|
||||
$param = get_params();
|
||||
$uid = $this->uid;
|
||||
$auth = isAuth($uid,'project_admin','conf_1');
|
||||
$tid = isset($param['tid']) ? $param['tid'] : 0;
|
||||
$where = [];
|
||||
$whereOr = [];
|
||||
|
||||
//按时间检索
|
||||
if (!empty($param['range_time'])) {
|
||||
$range_time =explode('至', $param['range_time']);
|
||||
$where[] = ['a.start_time', 'between',[strtotime($range_time[0]),strtotime($range_time[1])]];
|
||||
}
|
||||
|
||||
if ($tid>0) {
|
||||
$task_ids = Db::name('ProjectTask')->where(['delete_time' => 0, 'project_id' => $param['tid']])->column('id');
|
||||
$where[] = ['a.tid', 'in', $task_ids];
|
||||
}
|
||||
else{
|
||||
$where[] = ['a.tid', '>', 0];
|
||||
if (!empty($param['keywords'])) {
|
||||
$where[] = ['a.title', 'like', '%' . trim($param['keywords']) . '%'];
|
||||
}
|
||||
if($auth == 0){
|
||||
if (!empty($param['uid'])) {
|
||||
$where[] = ['a.admin_id', '=', $param['uid']];
|
||||
} else {
|
||||
$whereOr[] = ['a.admin_id', '=', $uid];
|
||||
$dids_a = get_leader_departments($uid);
|
||||
$dids_b = get_role_departments($uid);
|
||||
$dids = array_merge($dids_a, $dids_b);
|
||||
if(!empty($dids)){
|
||||
$whereOr[] = ['a.did','in',$dids];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$where[] = ['a.delete_time', '=', 0];
|
||||
|
||||
$model = new Schedule();
|
||||
$list = $model->datalist($param,$where,$whereOr);
|
||||
return table_assign(0, '', $list);
|
||||
} else {
|
||||
View::assign('is_leader', isLeader($this->uid));
|
||||
View::assign('role_auth', isAuth($this->uid,'office_admin','conf_1'));
|
||||
View::assign('hour_auth', valueAuth('office_admin','conf_2'));
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
public function comment() {
|
||||
if (request()->isAjax()) {
|
||||
$param = get_params();
|
||||
$param['admin_id'] = $this->uid;
|
||||
if (!empty($param['uid'])) {
|
||||
$where[] = ['admin_id', '=', $param['uid']];
|
||||
}
|
||||
if (!empty($param['keywords'])) {
|
||||
$where[] = ['content', 'like', '%' . trim($param['keywords']) . '%'];
|
||||
}
|
||||
if (!empty($param['module'])) {
|
||||
$where[] = ['module', '=', $param['module']];
|
||||
}
|
||||
if (!empty($param['topic_id'])) {
|
||||
$where['topic_id'] = $param['topic_id'];
|
||||
}
|
||||
$where[] = ['delete_time', '=', 0];
|
||||
$model = new Comment();
|
||||
$list = $model->datalist($param,$where);
|
||||
return table_assign(0, '', $list);
|
||||
} else {
|
||||
return view();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\project\controller;
|
||||
|
||||
use app\base\BaseController;
|
||||
use app\project\model\WorkCate as WorkCateModel;
|
||||
use app\project\validate\WorkValidate;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Db;
|
||||
use think\facade\View;
|
||||
|
||||
class Work extends BaseController
|
||||
{
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
protected $model;
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(); // 调用父类构造函数
|
||||
$this->model = new WorkCateModel();
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
public function datalist()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$list = $this->model->order('sort asc')->select();
|
||||
return to_assign(0, '', $list);
|
||||
}
|
||||
else{
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
$param = get_params();
|
||||
if (request()->isAjax()) {
|
||||
if (!empty($param['id']) && $param['id'] > 0) {
|
||||
try {
|
||||
validate(WorkValidate::class)->scene('edit')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$this->model->edit($param);
|
||||
} else {
|
||||
try {
|
||||
validate(WorkValidate::class)->scene('add')->check($param);
|
||||
} catch (ValidateException $e) {
|
||||
// 验证失败 输出错误信息
|
||||
return to_assign(1, $e->getError());
|
||||
}
|
||||
$this->model->add($param);
|
||||
}
|
||||
}else{
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
if ($id>0) {
|
||||
$detail = $this->model->getById($id);
|
||||
View::assign('detail', $detail);
|
||||
}
|
||||
return view();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
public function view($id)
|
||||
{
|
||||
$detail = $this->model->getById($id);
|
||||
if (!empty($detail)) {
|
||||
View::assign('detail', $detail);
|
||||
return view();
|
||||
}
|
||||
else{
|
||||
return view(EEEOR_REPORTING,['code'=>404,'warning'=>'找不到页面']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
public function del()
|
||||
{
|
||||
if (request()->isDelete()) {
|
||||
$param = get_params();
|
||||
$id = isset($param['id']) ? $param['id'] : 0;
|
||||
$type = isset($param['type']) ? $param['type'] : 0;
|
||||
$this->model->delById($id,$type);
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置
|
||||
*/
|
||||
public function set()
|
||||
{
|
||||
if (request()->isAjax()) {
|
||||
$param = get_params();
|
||||
$res = $this->model->strict(false)->field('id,status')->update($param);
|
||||
if ($res) {
|
||||
if($param['status'] == 0){
|
||||
add_log('disable', $param['id'], $param);
|
||||
}
|
||||
else if($param['status'] == 1){
|
||||
add_log('recovery', $param['id'], $param);
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
else{
|
||||
return to_assign(0, '操作失败');
|
||||
}
|
||||
} else {
|
||||
return to_assign(1, "错误的请求");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
return [
|
||||
'listen' => [
|
||||
//注册监听类
|
||||
'SendMessage' => ['app\listener\SendMessage'],
|
||||
],
|
||||
//'subscribe' => ['app\subscribe\Message'],
|
||||
];
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// 这是系统自动生成的middleware定义文件
|
||||
return [
|
||||
//开启session中间件
|
||||
//'think\middleware\SessionInit',
|
||||
//验证勾股OA是否完成安装
|
||||
\app\home\middleware\Install::class,
|
||||
];
|
||||
@@ -0,0 +1,275 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
namespace app\project\model;
|
||||
use think\model;
|
||||
use think\facade\Db;
|
||||
use app\api\model\EditLog;
|
||||
class Project extends Model
|
||||
{
|
||||
/**
|
||||
* 获取分页列表
|
||||
* @param $where
|
||||
* @param $param
|
||||
*/
|
||||
public function datalist($param=[],$where=[],$whereOr=[])
|
||||
{
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$order = empty($param['order']) ? 'id desc' : $param['order'];
|
||||
try {
|
||||
$list = self::where($where)
|
||||
->where(function ($query) use ($whereOr) {
|
||||
if (!empty($whereOr))
|
||||
$query->whereOr($whereOr);
|
||||
})
|
||||
->order($order)
|
||||
->paginate(['list_rows'=> $rows])
|
||||
->each(function ($item, $key){
|
||||
$item['title'] = $item['name'];
|
||||
$item->director_name = Db::name('Admin')->where(['id' => $item->director_uid])->value('name');
|
||||
$item->department = Db::name('Department')->where(['id' => $item->did])->value('title');
|
||||
$item->admin_name = Db::name('Admin')->where(['id' => $item->admin_id])->value('name');
|
||||
$item->status_name = status_name($item->status);
|
||||
$item->range_time = date('Y-m-d',$item->start_time). ' 至 ' .date('Y-m-d',$item->end_time);
|
||||
$item->delay = count_days(date("Y-m-d"),date('Y-m-d', $item->end_time));
|
||||
$item->cate = Db::name('ProjectCate')->where('id', $item->cate_id)->value('title');
|
||||
$task_map = [];
|
||||
$task_map[] = ['project_id', '=', $item->id];
|
||||
$task_map[] = ['delete_time', '=', 0];
|
||||
//任务总数
|
||||
$item->tasks_total = Db::name('ProjectTask')->where($task_map)->count();
|
||||
//已完成任务
|
||||
$task_map[] = ['status', '>', 2];
|
||||
$item->tasks_finish = Db::name('ProjectTask')->where($task_map)->count();
|
||||
//未完成任务
|
||||
$item->tasks_unfinish = $item->tasks_total - $item->tasks_finish;
|
||||
$item->tasks_pensent = "0.00%";
|
||||
if ($item->tasks_total > 0) {
|
||||
$item->tasks_pensent = round($item->tasks_finish / $item->tasks_total * 100, 2) . "%";
|
||||
}
|
||||
$step = Db::name('ProjectStep')->where(['project_id' => $item->id,'is_current' => 1,'delete_time'=>0])->find();
|
||||
if(!empty($step)){
|
||||
$item->step_director = Db::name('Admin')->where(['id'=>$step['director_uid']])->value('name');
|
||||
$item->step = $step['title'] . '『' . $item->step_director. '』';
|
||||
}
|
||||
else{
|
||||
$item->step = '-';
|
||||
}
|
||||
$item['create_time'] = to_date($item['create_time'],'Y-m-d H:i:s');
|
||||
});
|
||||
return $list;
|
||||
} catch(\Exception $e) {
|
||||
return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
public function apilist($where, $param)
|
||||
{
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$order = empty($param['order']) ? 'id desc' : $param['order'];
|
||||
try {
|
||||
$list = self::where($where)->field('id,status,name as title')->order($order)->paginate(['list_rows'=> $rows]);
|
||||
return $list;
|
||||
} catch(\Exception $e) {
|
||||
return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据
|
||||
* @param $param
|
||||
*/
|
||||
public function add($param,$step)
|
||||
{
|
||||
$insertId = 0;
|
||||
// 启动事务
|
||||
Db::startTrans();
|
||||
try {
|
||||
$param['create_time'] = time();
|
||||
$insertId = self::strict(false)->field(true)->insertGetId($param);
|
||||
$step_users=[];
|
||||
//项目阶段
|
||||
foreach ($step as $key => &$value) {
|
||||
if($key==0){
|
||||
$value['is_current'] = 1;
|
||||
}
|
||||
else{
|
||||
$value['is_current'] = 0;
|
||||
}
|
||||
$value['project_id'] = $insertId;
|
||||
if(!empty($value['director_uid'])){
|
||||
$step_users[] = $value['director_uid'];
|
||||
}
|
||||
if(!empty($value['uids'])){
|
||||
$step_users[] = $value['uids'];
|
||||
}
|
||||
}
|
||||
Db::name('ProjectStep')->strict(false)->field(true)->insertAll($step);
|
||||
$step_users_str = implode(',',$step_users);
|
||||
//项目成员
|
||||
$project_users = $param['admin_id'];
|
||||
if (!empty($param['director_uid'])){
|
||||
$project_users.=",".$param['director_uid'];
|
||||
}
|
||||
if (!empty($param['team_admin_ids'])){
|
||||
$project_users.=",".$param['team_admin_ids'];
|
||||
}
|
||||
if (!empty($step_users_str)){
|
||||
$project_users.=",".$step_users_str;
|
||||
}
|
||||
$project_array = explode(",",(string)$project_users);
|
||||
$project_array = array_unique($project_array);
|
||||
$project_user_array=[];
|
||||
foreach ($project_array as $k => $v) {
|
||||
if (is_numeric($v)) {
|
||||
$project_user_array[]=array(
|
||||
'uid'=>$v,
|
||||
'admin_id'=>$param['admin_id'],
|
||||
'project_id'=>$insertId,
|
||||
'create_time'=>time(),
|
||||
);
|
||||
}
|
||||
}
|
||||
Db::name('ProjectUser')->strict(false)->field(true)->insertAll($project_user_array);
|
||||
|
||||
|
||||
add_log('add', $insertId, $param);
|
||||
$log=new EditLog();
|
||||
$log->add('Project',$insertId);
|
||||
// 提交事务
|
||||
Db::commit();
|
||||
} catch(\Exception $e) {
|
||||
// 回滚事务
|
||||
Db::rollback();
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
return to_assign(0,'操作成功',['return_id'=>$insertId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑信息
|
||||
* @param $param
|
||||
*/
|
||||
public function edit($param,$step)
|
||||
{
|
||||
// 启动事务
|
||||
Db::startTrans();
|
||||
try {
|
||||
$param['update_time'] = time();
|
||||
$old = self::find($param['id']);
|
||||
self::where('id', $param['id'])->strict(false)->field(true)->update($param);
|
||||
$current_step = Db::name('ProjectStep')->where(['project_id' => $param['id'], 'is_current' => 1,'delete_time'=>0])->value('sort');
|
||||
//项目阶段
|
||||
foreach ($step as $key => $value) {
|
||||
$value['project_id'] = $param['id'];
|
||||
if($value['id'] == 0){
|
||||
Db::name('ProjectStep')->strict(false)->field(true)->insert($value);
|
||||
}
|
||||
else{
|
||||
$value['update_time'] = time();
|
||||
if($value['sort'] == $current_step){
|
||||
$value['is_current'] = 1;
|
||||
}
|
||||
else{
|
||||
$value['is_current'] = 0;
|
||||
}
|
||||
Db::name('ProjectStep')->strict(false)->field(true)->update($value);
|
||||
}
|
||||
}
|
||||
add_log('edit', $param['id'], $param);
|
||||
$log=new EditLog();
|
||||
$log->edit('Project',$param['id'],$param,$old);
|
||||
// 提交事务
|
||||
Db::commit();
|
||||
} catch(\Exception $e) {
|
||||
// 回滚事务
|
||||
Db::rollback();
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
return to_assign(0,'操作成功',['return_id'=>$param['id']]);
|
||||
}
|
||||
|
||||
public function apiedit($param)
|
||||
{
|
||||
try {
|
||||
$param['update_time'] = time();
|
||||
$old = self::find($param['id']);
|
||||
self::where('id', $param['id'])->strict(false)->field(true)->update($param);
|
||||
add_log('edit', $param['id'], $param,'项目');
|
||||
$log=new EditLog();
|
||||
$log->edit('Project',$param['id'],$param,$old);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
return to_assign(0,'操作成功',['return_id'=>$param['id']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id获取信息
|
||||
* @param $id
|
||||
*/
|
||||
public function getById($id)
|
||||
{
|
||||
$info = self::find($id);
|
||||
$info['admin_name'] = Db::name('Admin')->where(['id' => $info['admin_id']])->value('name');
|
||||
$info['director_name'] = Db::name('Admin')->where(['id' => $info['director_uid']])->value('name');
|
||||
$info['department'] = Db::name('Department')->where(['id' => $info['did']])->value('title');
|
||||
$info['contract_name'] = Db::name('Contract')->where(['id' => $info['contract_id']])->value('name');
|
||||
$info['create_time'] = to_date($info['create_time'],'Y-m-d H:i:s');
|
||||
$info['update_time'] = to_date($info['update_time'],'Y-m-d H:i:s');
|
||||
//项目阶段
|
||||
$step_array = Db::name('ProjectStep')
|
||||
->field('s.*,a.name as director_name')
|
||||
->alias('s')
|
||||
->join('Admin a', 'a.id = s.director_uid', 'LEFT')
|
||||
->order('s.sort asc')
|
||||
->where(array('s.project_id' => $id, 's.delete_time' => 0))
|
||||
->select()->toArray();
|
||||
foreach ($step_array as $kk => &$vv) {
|
||||
$unames = Db::name('Admin')->where([['id','in',$vv['uids']]])->column('name');
|
||||
$vv['unames'] = implode(',',$unames);
|
||||
}
|
||||
$info['step_array'] = $step_array;
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除信息
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @return array
|
||||
*/
|
||||
public function delById($id,$type=0)
|
||||
{
|
||||
if($type==0){
|
||||
//逻辑删除
|
||||
try {
|
||||
$param['delete_time'] = time();
|
||||
self::where('id', $id)->update(['delete_time'=>time()]);
|
||||
add_log('delete', $id);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
}
|
||||
else{
|
||||
//物理删除
|
||||
try {
|
||||
self::destroy($id);
|
||||
add_log('delete', $id);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
namespace app\project\model;
|
||||
use think\model;
|
||||
use think\facade\Db;
|
||||
class ProjectCate extends Model
|
||||
{
|
||||
/**
|
||||
* 获取分页列表
|
||||
* @param $where
|
||||
* @param $param
|
||||
*/
|
||||
public function datalist($where, $param)
|
||||
{
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$order = empty($param['order']) ? 'id desc' : $param['order'];
|
||||
try {
|
||||
$list = self::where($where)->order($order)->paginate(['list_rows'=> $rows]);
|
||||
return $list;
|
||||
} catch(\Exception $e) {
|
||||
return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据
|
||||
* @param $param
|
||||
*/
|
||||
public function add($param)
|
||||
{
|
||||
$insertId = 0;
|
||||
try {
|
||||
$param['create_time'] = time();
|
||||
$insertId = self::strict(false)->field(true)->insertGetId($param);
|
||||
add_log('add', $insertId, $param);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
return to_assign(0,'操作成功',['return_id'=>$insertId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑信息
|
||||
* @param $param
|
||||
*/
|
||||
public function edit($param)
|
||||
{
|
||||
try {
|
||||
$param['update_time'] = time();
|
||||
self::where('id', $param['id'])->strict(false)->field(true)->update($param);
|
||||
add_log('edit', $param['id'], $param);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
return to_assign(0,'操作成功',['return_id'=>$param['id']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id获取信息
|
||||
* @param $id
|
||||
*/
|
||||
public function getById($id)
|
||||
{
|
||||
$info = self::find($id);
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除信息
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @return array
|
||||
*/
|
||||
public function delById($id,$type=0)
|
||||
{
|
||||
if($type==0){
|
||||
//逻辑删除
|
||||
try {
|
||||
$param['delete_time'] = time();
|
||||
self::where('id', $id)->update(['delete_time'=>time()]);
|
||||
add_log('delete', $id);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
}
|
||||
else{
|
||||
//物理删除
|
||||
try {
|
||||
self::destroy($id);
|
||||
add_log('delete', $id);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
declare (strict_types = 1);
|
||||
namespace app\Project\model;
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
|
||||
class ProjectDocument extends Model
|
||||
{
|
||||
public function datalist($param,$where,$whereOr)
|
||||
{
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$order = empty($param['order']) ? 'id desc' : $param['order'];
|
||||
try {
|
||||
$list = self::where($where)
|
||||
->where(function ($query) use($whereOr) {
|
||||
if (!empty($whereOr)){
|
||||
$query->whereOr($whereOr);
|
||||
}
|
||||
})
|
||||
->order($order)
|
||||
->paginate(['list_rows'=> $rows])
|
||||
->each(function ($item, $key){
|
||||
$item->admin_name = Db::name('Admin')->where(['id' => $item->admin_id])->value('name');
|
||||
if ($item->project_id > 0) {
|
||||
$item->project = Db::name('Project')->where(['id' => $item->project_id])->value('name');
|
||||
}
|
||||
else{
|
||||
$item->project = '-';
|
||||
}
|
||||
$item['create_time'] = to_date($item['create_time']);
|
||||
});
|
||||
return $list;
|
||||
} catch(\Exception $e) {
|
||||
return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
//详情
|
||||
public function detail($id)
|
||||
{
|
||||
$detail = Db::name('ProjectDocument')->where(['id' => $id])->find();
|
||||
if (!empty($detail)) {
|
||||
$detail['project_name'] = '-';
|
||||
if ($detail['project_id'] > 0) {
|
||||
$detail['project_name'] = Db::name('Project')->where(['id' => $detail['project_id']])->value('name');
|
||||
}
|
||||
$detail['admin_name'] = Db::name('Admin')->where(['id' => $detail['admin_id']])->value('name');
|
||||
$detail['times'] = time_trans($detail['create_time']);
|
||||
$detail['create_time'] = to_date($detail['create_time']);
|
||||
}
|
||||
return $detail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\project\model;
|
||||
|
||||
use think\facade\Db;
|
||||
use think\Model;
|
||||
|
||||
class ProjectTask extends Model
|
||||
{
|
||||
//列表
|
||||
function datalist($param=[],$where=[],$whereOr=[]) {
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$order = empty($param['order']) ? 'status asc,id desc' : $param['order'];
|
||||
try {
|
||||
$list = self::where($where)
|
||||
->where(function ($query) use ($whereOr) {
|
||||
if (!empty($whereOr))
|
||||
$query->whereOr($whereOr);
|
||||
})
|
||||
->withoutField('content')
|
||||
->order($order)
|
||||
->paginate(['list_rows'=> $rows])
|
||||
->each(function ($item, $key){
|
||||
$item['director_name'] = '-';
|
||||
if ($item['director_uid'] > 0) {
|
||||
$item['director_name'] = Db::name('Admin')->where(['id' => $item['director_uid']])->value('name');
|
||||
}
|
||||
$assist_admin_names = Db::name('Admin')->where([['id', 'in', $item['assist_admin_ids']]])->column('name');
|
||||
if (empty($assist_admin_names)) {
|
||||
$item['assist_admin_names'] = '-';
|
||||
} else {
|
||||
$item['assist_admin_names'] = implode(',', $assist_admin_names);
|
||||
}
|
||||
$item['cate_name'] = Db::name('WorkCate')->where(['id' => $item['work_id']])->value('title');
|
||||
if ($item['project_id'] == 0) {
|
||||
$item['project_name'] = '-';
|
||||
} else {
|
||||
$item['project_name'] = Db::name('Project')->where(['id' => $item['project_id']])->value('name');
|
||||
}
|
||||
$item['delay'] = 0;
|
||||
if ($item['end_time'] > 0) {
|
||||
$item['end_time'] = date('Y-m-d', $item['end_time']);
|
||||
if ($item['over_time'] > 0 && $item['status'] < 4) {
|
||||
$item['delay'] = count_days($item['end_time'], date('Y-m-d', $item['over_time']));
|
||||
}
|
||||
if ($item['over_time'] == 0 && $item['status'] < 4) {
|
||||
$item['delay'] = count_days($item['end_time']);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$item['delay'] = 9999;
|
||||
$item['end_time'] = '-';
|
||||
}
|
||||
$item['priority_name'] = priority_name($item['priority']);
|
||||
$item['status_name'] = status_task_name($item['status']);
|
||||
return $item;
|
||||
});
|
||||
return $list;
|
||||
} catch(\Exception $e) {
|
||||
return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
//详情
|
||||
public function detail($id)
|
||||
{
|
||||
$detail = Db::name('ProjectTask')->where(['id' => $id])->find();
|
||||
if (!empty($detail)) {
|
||||
$detail['project_name'] = '';
|
||||
if ($detail['project_id'] > 0) {
|
||||
$detail['project_name'] = Db::name('Project')->where(['id' => $detail['project_id']])->value('name');
|
||||
}
|
||||
$detail['admin_name'] = Db::name('Admin')->where(['id' => $detail['admin_id']])->value('name');
|
||||
$detail['work_hours'] = Db::name('Schedule')->where(['delete_time' => 0, 'tid' => $detail['id']])->sum('labor_time');
|
||||
$detail['cate_name'] = Db::name('WorkCate')->where(['id' => $detail['work_id']])->value('title');
|
||||
|
||||
$detail['director_name']= '';
|
||||
if($detail['director_uid'] > 0){
|
||||
$detail['director_name'] = Db::name('Admin')->where(['id' => $detail['director_uid']])->value('name');
|
||||
}
|
||||
$detail['schedules'] = Db::name('Schedule')->where(['tid' => $detail['id'], 'delete_time' => 0])->count();
|
||||
$detail['logs'] = Db::name('EditLog')->where(['name' => 'Task', 'action_id' => $detail['id']])->count();
|
||||
$detail['comments'] = Db::name('Comment')->where(['module' => 'task', 'delete_time' => 0, 'topic_id' => $detail['id']])->count();
|
||||
$detail['assist_admin_names'] = '';
|
||||
if (!empty($detail['assist_admin_ids'])) {
|
||||
$assist_admin_names = Db::name('Admin')->where('id', 'in', $detail['assist_admin_ids'])->column('name');
|
||||
$detail['assist_admin_names'] = implode(',', $assist_admin_names);
|
||||
}
|
||||
$detail['priority_name'] = priority_name($detail['priority']);
|
||||
$detail['status_name'] = status_task_name($detail['status']);
|
||||
$detail['times'] = time_trans($detail['create_time']);
|
||||
$detail['delay'] = 0;
|
||||
if($detail['end_time']>0){
|
||||
$detail['end_time'] = date('Y-m-d', $detail['end_time']);
|
||||
if ($detail['over_time'] > 0 && $detail['status'] < 4) {
|
||||
$detail['delay'] = count_days($detail['end_time'], date('Y-m-d', $detail['over_time']));
|
||||
}
|
||||
if ($detail['over_time'] == 0 && $detail['status'] < 4) {
|
||||
$detail['delay'] = count_days($detail['end_time']);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$detail['end_time'] = '';
|
||||
}
|
||||
}
|
||||
return $detail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
namespace app\project\model;
|
||||
use think\model;
|
||||
use think\facade\Db;
|
||||
class Step extends Model
|
||||
{
|
||||
/**
|
||||
* 获取分页列表
|
||||
* @param $where
|
||||
* @param $param
|
||||
*/
|
||||
public function datalist($where, $param)
|
||||
{
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$order = empty($param['order']) ? 'id desc' : $param['order'];
|
||||
try {
|
||||
$list = self::where($where)->order($order)->paginate(['list_rows'=> $rows]);
|
||||
return $list;
|
||||
} catch(\Exception $e) {
|
||||
return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据
|
||||
* @param $param
|
||||
*/
|
||||
public function add($param)
|
||||
{
|
||||
$insertId = 0;
|
||||
try {
|
||||
$param['create_time'] = time();
|
||||
$insertId = self::strict(false)->field(true)->insertGetId($param);
|
||||
add_log('add', $insertId, $param);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
return to_assign(0,'操作成功',['return_id'=>$insertId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑信息
|
||||
* @param $param
|
||||
*/
|
||||
public function edit($param)
|
||||
{
|
||||
try {
|
||||
$param['update_time'] = time();
|
||||
self::where('id', $param['id'])->strict(false)->field(true)->update($param);
|
||||
add_log('edit', $param['id'], $param);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
return to_assign(0,'操作成功',['return_id'=>$param['id']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id获取信息
|
||||
* @param $id
|
||||
*/
|
||||
public function getById($id)
|
||||
{
|
||||
$info = self::find($id);
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除信息
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @return array
|
||||
*/
|
||||
public function delById($id,$type=0)
|
||||
{
|
||||
if($type==0){
|
||||
//逻辑删除
|
||||
try {
|
||||
$param['delete_time'] = time();
|
||||
self::where('id', $id)->update(['delete_time'=>time()]);
|
||||
add_log('delete', $id);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
}
|
||||
else{
|
||||
//物理删除
|
||||
try {
|
||||
self::destroy($id);
|
||||
add_log('delete', $id);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\project\model;
|
||||
use think\model;
|
||||
use think\facade\Db;
|
||||
class WorkCate extends Model
|
||||
{
|
||||
/**
|
||||
* 获取分页列表
|
||||
* @param $where
|
||||
* @param $param
|
||||
*/
|
||||
public function datalist($where, $param)
|
||||
{
|
||||
$rows = empty($param['limit']) ? get_config('app.page_size') : $param['limit'];
|
||||
$order = empty($param['order']) ? 'id desc' : $param['order'];
|
||||
try {
|
||||
$list = self::where($where)->order($order)->paginate(['list_rows'=> $rows]);
|
||||
return $list;
|
||||
} catch(\Exception $e) {
|
||||
return ['code' => 1, 'data' => [], 'msg' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加数据
|
||||
* @param $param
|
||||
*/
|
||||
public function add($param)
|
||||
{
|
||||
$insertId = 0;
|
||||
try {
|
||||
$param['create_time'] = time();
|
||||
$insertId = self::strict(false)->field(true)->insertGetId($param);
|
||||
add_log('add', $insertId, $param);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
return to_assign(0,'操作成功',['return_id'=>$insertId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑信息
|
||||
* @param $param
|
||||
*/
|
||||
public function edit($param)
|
||||
{
|
||||
try {
|
||||
$param['update_time'] = time();
|
||||
self::where('id', $param['id'])->strict(false)->field(true)->update($param);
|
||||
add_log('edit', $param['id'], $param);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
return to_assign(0,'操作成功',['return_id'=>$param['id']]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据id获取信息
|
||||
* @param $id
|
||||
*/
|
||||
public function getById($id)
|
||||
{
|
||||
$info = self::find($id);
|
||||
return $info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除信息
|
||||
* @param $id
|
||||
* @param $type
|
||||
* @return array
|
||||
*/
|
||||
public function delById($id,$type=0)
|
||||
{
|
||||
if($type==0){
|
||||
//逻辑删除
|
||||
try {
|
||||
$param['delete_time'] = time();
|
||||
self::where('id', $id)->update(['delete_time'=>time()]);
|
||||
add_log('delete', $id);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
}
|
||||
else{
|
||||
//物理删除
|
||||
try {
|
||||
self::destroy($id);
|
||||
add_log('delete', $id);
|
||||
} catch(\Exception $e) {
|
||||
return to_assign(1, '操作失败,原因:'.$e->getMessage());
|
||||
}
|
||||
}
|
||||
return to_assign();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\project\validate;
|
||||
use think\Validate;
|
||||
use think\facade\Db;
|
||||
|
||||
class CateValidate extends Validate
|
||||
{
|
||||
// 自定义验证规则
|
||||
protected function checkOne($value,$rule,$data=[])
|
||||
{
|
||||
$id = isset($data['id'])?$data['id']:0;
|
||||
$count = Db::name('ProjectCate')->where([['title','=',$data['title']],['id','<>',$id],['delete_time','=',0]])->count();
|
||||
return $count == 0 ? true : false;
|
||||
}
|
||||
|
||||
protected $rule = [
|
||||
'title' => 'require|checkOne',
|
||||
'id' => 'require',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'title.require' => '名称不能为空',
|
||||
'title.checkOne' => '同样的名称已经存在',
|
||||
'id.require' => '缺少更新条件',
|
||||
];
|
||||
|
||||
protected $scene = [
|
||||
'add' => ['title'],
|
||||
'edit' => ['title', 'id'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\project\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class DocumentCheck extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require',
|
||||
'id' => 'require',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'title.require' => '文档标题不能为空',
|
||||
'id.require' => '缺少更新条件',
|
||||
];
|
||||
|
||||
protected $scene = [
|
||||
'add' => ['title'],
|
||||
'edit' => ['id'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\project\validate;
|
||||
use think\Validate;
|
||||
use think\facade\Db;
|
||||
|
||||
class IndexValidate extends Validate
|
||||
{
|
||||
// 自定义验证规则
|
||||
protected function checkOne($value,$rule,$data=[])
|
||||
{
|
||||
$id = isset($data['id'])?$data['id']:0;
|
||||
$count = Db::name('Project')->where([['name','=',$data['name']],['id','<>',$id],['delete_time','=',0]])->count();
|
||||
return $count == 0 ? true : false;
|
||||
}
|
||||
|
||||
protected $rule = [
|
||||
'name' => 'require|checkOne',
|
||||
'id' => 'require',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'name.require' => '项目名称不能为空',
|
||||
'name.checkOne' => '同样的项目名称已经存在',
|
||||
'id.require' => '缺少更新条件',
|
||||
];
|
||||
|
||||
protected $scene = [
|
||||
'add' => ['title'],
|
||||
'edit' => ['title', 'id'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\project\validate;
|
||||
use think\Validate;
|
||||
use think\facade\Db;
|
||||
|
||||
class StepValidate extends Validate
|
||||
{
|
||||
// 自定义验证规则
|
||||
protected function checkOne($value,$rule,$data=[])
|
||||
{
|
||||
$id = isset($data['id'])?$data['id']:0;
|
||||
$count = Db::name('Step')->where([['title','=',$data['title']],['id','<>',$id],['delete_time','=',0]])->count();
|
||||
return $count == 0 ? true : false;
|
||||
}
|
||||
|
||||
protected $rule = [
|
||||
'title' => 'require|checkOne',
|
||||
'id' => 'require',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'title.require' => '名称不能为空',
|
||||
'title.checkOne' => '同样的名称已经存在',
|
||||
'id.require' => '缺少更新条件',
|
||||
];
|
||||
|
||||
protected $scene = [
|
||||
'add' => ['title'],
|
||||
'edit' => ['title', 'id'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\project\validate;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class TaskCheck extends Validate
|
||||
{
|
||||
protected $rule = [
|
||||
'title' => 'require',
|
||||
'plan_hours' => 'require|regex:/^[0-9]+(.[0-9]{1,1})?$/',
|
||||
'id' => 'require',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'title.require' => '任务主题不能为空',
|
||||
'plan_hours.require' => '预估工时不能为空',
|
||||
'plan_hours.regex' => '预估工时只能是整数或者1位小数的数字',
|
||||
'id.require' => '缺少更新条件',
|
||||
];
|
||||
|
||||
protected $scene = [
|
||||
'add' => ['title'],
|
||||
'hours' => ['plan_hours'],
|
||||
'edit' => ['id'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/**
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* GouGuOPEN [ 左手研发,右手开源,未来可期!]
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Copyright (c) 2021~2024 http://www.gouguoa.com All rights reserved.
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Licensed 勾股OA,开源且可免费使用,但并不是自由软件,未经授权许可不能去除勾股OA的相关版权信息
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
* @Author 勾股工作室 <hdm58@qq.com>
|
||||
+-----------------------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
namespace app\project\validate;
|
||||
use think\Validate;
|
||||
use think\facade\Db;
|
||||
|
||||
class WorkValidate extends Validate
|
||||
{
|
||||
// 自定义验证规则
|
||||
protected function checkOne($value,$rule,$data=[])
|
||||
{
|
||||
$id = isset($data['id'])?$data['id']:0;
|
||||
$count = Db::name('WorkCate')->where([['title','=',$data['title']],['id','<>',$id]])->count();
|
||||
return $count == 0 ? true : false;
|
||||
}
|
||||
|
||||
protected $rule = [
|
||||
'title' => 'require|checkOne',
|
||||
'id' => 'require',
|
||||
];
|
||||
|
||||
protected $message = [
|
||||
'title.require' => '名称不能为空',
|
||||
'title.checkOne' => '同样的名称已经存在',
|
||||
'id.require' => '缺少更新条件',
|
||||
];
|
||||
|
||||
protected $scene = [
|
||||
'add' => ['title'],
|
||||
'edit' => ['title', 'id'],
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<form class="layui-form p-page">
|
||||
<h3 class="pb-3">项目分类</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<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" value="{$detail.title|default=''}"></td>
|
||||
<td class="layui-td-gray">排序</td>
|
||||
<td><input type="text" name="sort" placeholder="请输入排序,数字" autocomplete="off" class="layui-input" value="{$detail.sort|default=''}"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="pt-4">
|
||||
<input type="hidden" name="id" value="{$detail.id|default=0}"/>
|
||||
<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}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
var 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) {
|
||||
tool.sideClose(1000);
|
||||
}
|
||||
}
|
||||
let clickbtn = $(this);
|
||||
tool.post("/project/cate/add", data.field, callback,clickbtn);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,124 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
|
||||
<div class="p-page">
|
||||
<table class="layui-hide" id="table_project_cate" lay-filter="table_project_cate"></table>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm add-new" type="button">+ 添加项目分类</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const moduleInit = ['tool'];
|
||||
function gouguInit() {
|
||||
var table = layui.table, tool = layui.tool;
|
||||
|
||||
layui.pageTable = table.render({
|
||||
elem: "#table_project_cate"
|
||||
,toolbar: '#toolbarDemo'
|
||||
,url: "/project/cate/datalist"
|
||||
,page: false
|
||||
,limit: 999
|
||||
,cellMinWidth: 80
|
||||
,cols: [[
|
||||
{field:'id',width:80, title: 'ID号', align:'center'}
|
||||
,{field:'title',title: '类型名称'}
|
||||
,{field:'status', title: '状态',width:80,align:'center',templet: function(d){
|
||||
var html1='<span class="green">正常</span>';
|
||||
var html2='<span class="yellow">禁用</span>';
|
||||
if(d.status==1){
|
||||
return html1;
|
||||
}
|
||||
else{
|
||||
return html2;
|
||||
}
|
||||
}}
|
||||
,{width:100,title: '操作', align:'center',ignoreExport:true,templet: function(d){
|
||||
var html='';
|
||||
var btn='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>';
|
||||
var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
|
||||
var btn2='<a class="layui-btn layui-btn-xs" lay-event="open">启用</a>';
|
||||
if(d.status==1){
|
||||
html = '<div class="layui-btn-group">'+btn+btn1+'</div>';
|
||||
}
|
||||
else{
|
||||
html = '<div class="layui-btn-group">'+btn+btn2+'</div>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
table.on('tool(table_project_cate)',function (obj) {
|
||||
if(obj.event === 'edit'){
|
||||
add_cate(obj.data.id,obj.data.title);
|
||||
}
|
||||
if(obj.event === 'disable'){
|
||||
layer.confirm('确定要禁用该记录吗?', {icon: 3, title:'提示'}, function(index){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/cate/set", {id:obj.data.id,status: 0}, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
if(obj.event === 'open'){
|
||||
layer.confirm('确定要启用该记录吗?', {icon: 3, title:'提示'}, function(index){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/cate/set", {id:obj.data.id,status:1}, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('body').on('click','.add-new',function(){
|
||||
add_cate(0,'');
|
||||
});
|
||||
|
||||
function add_cate(id,val){
|
||||
var title = '新增类型';
|
||||
if(id>0){
|
||||
title = '编辑类型';
|
||||
}
|
||||
layer.prompt({
|
||||
title: title,
|
||||
value: val,
|
||||
yes: function(index, layero) {
|
||||
// 获取文本框输入的值
|
||||
var value = layero.find(".layui-layer-input").val();
|
||||
if (value) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/cate/add", {id: id,title: value}, callback);
|
||||
layer.close(index);
|
||||
} else {
|
||||
layer.msg('请填写类型名称');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,16 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<h3 class="pb-3">项目分类详情</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目分类名称</td>
|
||||
<td>{$detail.title|default=''}"></td>
|
||||
<td class="layui-td-gray">排序</td>
|
||||
<td>{$detail.sort|default=0}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
@@ -0,0 +1,136 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
{block name="body"}
|
||||
<form class="layui-form p-4">
|
||||
{eq name="id" value ="0"}
|
||||
<h3 class="pb-3">新建文档</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">文档名称<font>*</font></td>
|
||||
<td>
|
||||
<input type="text" name="title" lay-verify="required" lay-reqText="请输入文档名称" placeholder="请输入文档名称" class="layui-input" value="">
|
||||
</td>
|
||||
<td class="layui-td-gray">关联项目<font>*</font></td>
|
||||
<td>
|
||||
<input type="text" name="project_name" placeholder="所属项目" value="{$project_name|default=''}" readonly class="layui-input picker-oa" data-types="project" autocomplete="off" />
|
||||
<input type="hidden" name="project_id" value="{$project_id}" />
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray-2">
|
||||
<div class="layui-input-inline">相关附件</div>
|
||||
<div class="layui-input-inline">
|
||||
<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="5">
|
||||
<div class="layui-row" id="uploadBox">
|
||||
<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids|default=''}">
|
||||
{notempty name="$detail.file_ids"}
|
||||
{volist name="$detail.file_array" id="vo"}
|
||||
<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo)}</div>
|
||||
{/volist}
|
||||
{/notempty}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray" style="vertical-align:top;">文档内容<font>*</font></td>
|
||||
<td colspan="5">
|
||||
<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container" style="border:0;padding:0"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{else/}
|
||||
<h3 class="pb-3">编辑文档</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">文档名称<font>*</font>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="title" lay-verify="required" lay-reqText="请输入文档名称" placeholder="请输入文档名称"
|
||||
class="layui-input" value="{$detail.title}">
|
||||
</td>
|
||||
<td class="layui-td-gray">关联项目<font>*</font></td>
|
||||
<td>
|
||||
<select id="projectId" name="project_id" lay-filter="project_id">
|
||||
<option value="">请选择关联项目</option>
|
||||
{volist name=":get_project()" id="v"}
|
||||
<option value="{$v.id}" {eq name = "$v.id" value="$detail.project_id"} selected{/eq}>{$v.name}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray-2">
|
||||
<div class="layui-input-inline">相关附件</div>
|
||||
<div class="layui-input-inline">
|
||||
<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn"><i class="layui-icon"></i></button>
|
||||
</div>
|
||||
</td>
|
||||
<td colspan="5">
|
||||
<div class="layui-row" id="uploadBox">
|
||||
<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids|default=''}">
|
||||
{notempty name="$detail.file_ids"}
|
||||
{volist name="$detail.file_array" id="vo"}
|
||||
<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo)}</div>
|
||||
{/volist}
|
||||
{/notempty}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray" style="vertical-align:top;">文档内容<font>*</font></td>
|
||||
<td colspan="5">
|
||||
<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container" style="border:0;padding:0">{$detail.content}</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{/eq}
|
||||
<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}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const moduleInit = ['tool','uploadPlus','tinymce','oaPicker'];
|
||||
function gouguInit() {
|
||||
var form = layui.form,tool=layui.tool,uploadPlus = layui.uploadPlus;
|
||||
//相关附件上传
|
||||
var attachment = new uploadPlus();
|
||||
|
||||
//编辑器初始化
|
||||
var editor = layui.tinymce;
|
||||
var edit = editor.render({
|
||||
selector: "#container",
|
||||
images_upload_url: '/api/index/upload/sourse/tinymce',//图片上传接口
|
||||
height:600
|
||||
});
|
||||
|
||||
//监听提交
|
||||
form.on('submit(webform)', function (data) {
|
||||
data.field.content = tinyMCE.editors['container'].getContent();
|
||||
if (data.field.content == '') {
|
||||
layer.msg('请先完善文档内容');
|
||||
return false;
|
||||
}
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
tool.sideClose(1000,'documentTable');
|
||||
}
|
||||
}
|
||||
let clickbtn = $(this);
|
||||
tool.post("/project/document/add", data.field, callback,clickbtn);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
{/block}
|
||||
@@ -0,0 +1,116 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<div class="gg-form-bar border-t border-x">
|
||||
<form class="layui-form" lay-filter="barsearchform">
|
||||
<div class="layui-input-inline" style="width:240px;">
|
||||
<input type="text" name="project_name" placeholder="所属项目" readonly class="layui-input picker-oa" data-types="project" autocomplete="off" />
|
||||
<input name="project_id" style="display: none;" value="" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:300px;">
|
||||
<input type="text" name="keywords" placeholder="关键字" class="layui-input" autocomplete="off" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:150px;">
|
||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
|
||||
<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<table class="layui-hide" id="document" lay-filter="document"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" lay-event="add">+ 新建文档</button>
|
||||
</div>
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const moduleInit = ['tool','tablePlus','oaPicker'];
|
||||
function gouguInit() {
|
||||
var table = layui.tablePlus, form = layui.form, tool = layui.tool;
|
||||
|
||||
layui.documentTable = table.render({
|
||||
elem: '#document',
|
||||
title: '文档列表',
|
||||
toolbar: '#toolbarDemo',
|
||||
is_excel: true,
|
||||
cellMinWidth: 80,
|
||||
height: 'full-114',
|
||||
url: "/project/document/datalist",
|
||||
cols: [[
|
||||
{
|
||||
field: 'id', title: '文档编号', width: 90, align: 'center', templet: function (d) {
|
||||
return 'D' + d.id;
|
||||
}
|
||||
}
|
||||
, {
|
||||
field: 'title', title: '文档主题',minWidth:240, templet: function (d) {
|
||||
var html = '<a class="side-a" data-href="/project/document/view/id/' + d.id + '">' + d.title + '</a>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
, { field: 'project', title: '关联项目', width: 240,}
|
||||
, { field: 'admin_name', title: '创建人', align: 'center', width: 80 }
|
||||
, { field: 'create_time', title: '创建时间', align: 'center', width: 150 }
|
||||
,{
|
||||
field: 'right',
|
||||
fixed:'right',
|
||||
title: '操作',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
templet: function (d) {
|
||||
var html = '<div class="layui-btn-group">';
|
||||
var btn1='<span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</span>';
|
||||
var btn2='<span class="layui-btn layui-btn-xs" lay-event="edit">编辑</span>';
|
||||
var btn3='<span class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</span>';
|
||||
return html+btn1+btn2+btn3+'</div>';
|
||||
}
|
||||
}
|
||||
]]
|
||||
});
|
||||
|
||||
|
||||
//触发事件
|
||||
table.on('toolbar(document)', function(obj){
|
||||
if (obj.event === 'add') {
|
||||
tool.side("/project/document/add");
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
//监听行工具事件
|
||||
table.on('tool(document)', function(obj) {
|
||||
var data = obj.data;
|
||||
if (obj.event === 'view') {
|
||||
tool.side("/project/document/view?id="+data.id);
|
||||
return;
|
||||
}
|
||||
if(obj.event === 'edit'){
|
||||
tool.side('/project/document/add?id='+data.id);
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'del') {
|
||||
layer.confirm('确定要删除吗?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function(index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
obj.del();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/document/delete", {id: data.id}, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,58 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
{block name="style"}
|
||||
<link rel="stylesheet" href="{__GOUGU__}/third_party/prism/prism.css"/>
|
||||
<style>
|
||||
.text-detial-ops{line-height: 30px; color:#999; font-size: 12px; padding: 12px 0;}
|
||||
.text-detial-ops span{margin-right: 20px;}
|
||||
.text-detial-ops a{margin-right:10px;}
|
||||
.text-detial-content{padding: 8px 0; color:#333; word-break: break-all; border-top:1px solid #e8e8e8;font-size: 16px!important; line-height: 1.72!important;}
|
||||
.text-detial-content p{padding: 8px 0;}
|
||||
.text-detial-content img{max-width:98%!important; margin:0 auto; display:block; border: 1px solid #e6e6e6; -webkit-box-shadow: 0 2px 6px rgba(26,26,26,.08); box-shadow: 0 2px 6px rgba(26,26,26,.08); border-radius: 4px;}
|
||||
.text-detial-content h1,.text-detial-content h2,.text-detial-content h3,.text-detial-content h4,.text-detial-content h5{margin-top:10px;}
|
||||
.text-detial-content a{color:#186AF2; font-style:italic;}
|
||||
.text-detial-content a:hover{text-decoration:underline;}
|
||||
|
||||
.text-detial-content p code,.blog-detial-content pre{margin:0 3px;font-size: 14px; font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; background: #f6f6f6; padding: 10px; border-radius: 2px;}
|
||||
.text-detial-content p code{border: 1px solid #eee;padding: 2px 4px;}
|
||||
.text-detial-content table {border-collapse: collapse; border-spacing: 0; display: block; width: 100%; overflow: auto; word-break: normal;word-break: keep-all; margin-top: 0;margin-bottom: 16px;}
|
||||
.text-detial-content table tr {background-color: #fff;border-top: 1px solid #ccc;}
|
||||
.text-detial-content table tr:nth-child(2n) {background-color: #f8f8f8;}
|
||||
.text-detial-content table td, .blog-detial-content table th { padding: 6px 12px;border: 1px solid #ddd; font-size:14px; }
|
||||
.text-detial-content table th {font-weight: 800;}
|
||||
.text-detial-content li {list-style: initial;margin-left: 20px;}
|
||||
:not(pre)>code[class*=language-], pre[class*=language-]{background:#fff!important;border:1px solid #e8e8e8!important; border-radius:3px;}
|
||||
.upload-file{padding:12px; background-color:#fff; border:1px solid #eee; margin-bottom:12px;}
|
||||
.upload-file h3{margin-bottom:12px;}
|
||||
</style>
|
||||
{/block}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<form class="layui-form p-4">
|
||||
<h1>{$detail.title}</h1>
|
||||
<div class="text-detial-ops">
|
||||
<span>{$detail.admin_name}发表于:{$detail.create_time}</span><span>关联项目:{$detail.project_name}</span>
|
||||
</div>
|
||||
<div class="text-detial-content">
|
||||
{$detail.content|raw}
|
||||
</div>
|
||||
{notempty name="$detail.file_ids"}
|
||||
<div class="upload-file layui-row">
|
||||
<h3>相关附件</h3>
|
||||
{volist name="$detail.file_array" id="vo"}
|
||||
<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo,'view')}</div>
|
||||
{/volist}
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{/block}
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script src="{__GOUGU__}/third_party/prism/prism.js"></script>
|
||||
<script>
|
||||
const moduleInit = ['tool'];
|
||||
function gouguInit() {
|
||||
var form = layui.form,tool=layui.tool;
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,266 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<form class="layui-form p-page">
|
||||
<h3 class="pb-3">新建项目</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目名称<font>*</font></td>
|
||||
<td colspan="3"><input type="text" name="name" lay-verify="required" lay-reqText="请输入项目名称" placeholder="请输入项目名称" class="layui-input" value=""></td>
|
||||
<td class="layui-td-gray">项目类别<font>*</font></td>
|
||||
<td>
|
||||
<select name="cate_id" lay-filter="cate" lay-verify="required" lay-reqText="请选择项目类别">
|
||||
<option value="">请选择</option>
|
||||
{volist name = ":get_base_data('ProjectCate')" id="vo"}
|
||||
<option value="{$vo.id}">{$vo.title}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目经理<font>*</font></td>
|
||||
<td>
|
||||
<input type="text" name="director_name" placeholder="请选择项目经理(负责人)" readonly class="layui-input" value="" lay-verify="required" readonly lay-reqText="请选择项目经理(负责人)">
|
||||
<input type="hidden" name="director_uid" value="0">
|
||||
<input type="hidden" name="did" value="0">
|
||||
</td>
|
||||
<td class="layui-td-gray">归属部门<font>*</font></td>
|
||||
<td><input type="text" name="department" value="" autocomplete="off" readonly class="layui-input"></td>
|
||||
<td class="layui-td-gray">始止日期<span style="color: red">*</span></td>
|
||||
<td><input type="text" name="range_time" class="layui-input tool-time" data-range="到" readonly placeholder="开始 到 结束" lay-verify="required" lay-reqText="请选择计划完成周期"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目成员<span style="color: red">*</span></td>
|
||||
<td colspan="5">
|
||||
<input type="text" name="team_admin_names" placeholder="请选择项目成员" readonly class="layui-input picker-admin" data-type="2" value="" lay-verify="required" lay-reqText="请完善项目成员">
|
||||
<input type="hidden" name="team_admin_ids" class="layui-input" value="">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">关联合同</td>
|
||||
<td colspan="5">
|
||||
<input type="text" class="layui-input picker-oa" data-types="contract" name="contract_name" placeholder="请选择需要关联的合同" readonly value="">
|
||||
<input type="hidden" class="layui-input" name="contract_id" value="0">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目简介</td>
|
||||
<td colspan="5">
|
||||
<textarea name="content" class="layui-textarea"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" style="background-color:#FAFAFA;">
|
||||
<strong>项目阶段</strong><span style="color: red">*</span>
|
||||
<span class="layui-btn layui-btn-sm" id="stepAdd">+ 添加阶段</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<table id="stepTable" class="layui-table layui-table-min" style="margin:0">
|
||||
<tr>
|
||||
<th width="60">序号</th>
|
||||
<th width="200">阶段名称</th>
|
||||
<th width="80">阶段负责人</th>
|
||||
<th width="180">阶段成员</th>
|
||||
<th width="162">阶段周期</th>
|
||||
<th>阶段说明</th>
|
||||
<th width="120">操作</th>
|
||||
</tr>
|
||||
{volist name = ":get_base_data('step')" id="vo" key="k"}
|
||||
<tr class="step-tr">
|
||||
<td class="step-key">第 <strong>{$k}</strong> 阶段</td>
|
||||
<td>
|
||||
<div class="layui-input-group">
|
||||
<input type="text" name="step_title[]" value="{$vo.title}" class="layui-input" lay-verify="required" lay-reqText="请输入阶段名称">
|
||||
<div class="layui-input-split layui-input-suffix picker-diy" style="cursor: pointer;"><i class="layui-icon layui-icon-search"></i></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>
|
||||
<input type="hidden" name="step_director_uid[]" value="0" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" data-type="2">
|
||||
<input type="hidden" name="step_uids[]" value="">
|
||||
</td>
|
||||
<td><input type="text" name="step_cycle_time[]" value="" class="layui-input layui-input-readonly tool-time" data-range="到" lay-verify="required" lay-reqText="请选择阶段周期" readonly></td>
|
||||
<td><input type="text" name="step_remark[]" value="" class="layui-input"></td>
|
||||
<td>
|
||||
<input type="hidden" name="step_id[]" value="0" class="layui-input">
|
||||
<div class="layui-btn-group">
|
||||
<span class="layui-btn layui-btn-xs step-up">上移</span>
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs step-down">下移</span>
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs step-del" data-id="0">删除</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{/volist}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="pt-3">
|
||||
<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}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
var moduleInit = ['tool','oaPicker'];
|
||||
|
||||
function gouguInit() {
|
||||
var form = layui.form, tool = layui.tool,oaPicker = layui.oaPicker;
|
||||
//选择项目经理
|
||||
$('body').on('click','[name="director_name"]',function () {
|
||||
var ids=$('[name="director_uid"]').val(),names=$('[name="director_name"]').val();
|
||||
oaPicker.employeeInit({
|
||||
ids:ids,
|
||||
names:names,
|
||||
type:1,
|
||||
callback:function(data){
|
||||
let select_id=[],select_name=[],select_did=[],select_dname=[];
|
||||
for(var a=0; a<data.length;a++){
|
||||
select_id.push(data[a].id);
|
||||
select_name.push(data[a].name);
|
||||
select_did.push(data[a].did);
|
||||
select_dname.push(data[a].department);
|
||||
}
|
||||
$('[name="director_uid"]').val(select_id.join(','));
|
||||
$('[name="director_name"]').val(select_name.join(','));
|
||||
$('[name="did"]').val(select_did.join(','));
|
||||
$('[name="department"]').val(select_dname.join(','));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//添加阶段信息表格
|
||||
$('#stepAdd').on('click',function(){
|
||||
var html = '';
|
||||
html += '<tr class="step-tr">\
|
||||
<td class="step-key">第 <strong>0</strong> 阶段</td>\
|
||||
<td>\
|
||||
<div class="layui-input-group">\
|
||||
<input type="text" name="step_title[]" value="" class="layui-input" lay-verify="required" lay-reqText="请输入阶段名称">\
|
||||
<div class="layui-input-split layui-input-suffix picker-diy" style="cursor: pointer;"><i class="layui-icon layui-icon-search"></i></div>\
|
||||
</div>\
|
||||
</td>\
|
||||
<td>\
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>\
|
||||
<input type="hidden" name="step_director_uid[]" value="0" readonly>\
|
||||
</td>\
|
||||
<td>\
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" data-type="2">\
|
||||
<input type="hidden" name="step_uids[]" value="">\
|
||||
</td>\
|
||||
<td><input type="text" name="step_cycle_time[]" value="" class="layui-input layui-input-readonly tool-time" data-range="到" lay-verify="required" lay-reqText="请选择服务周期" readonly></td>\
|
||||
<td><input type="text" name="step_remark[]" value="" class="layui-input"></td>\
|
||||
<td>\
|
||||
<input type="hidden" name="step_id[]" value="0" class="layui-input">\
|
||||
<div class="layui-btn-group">\
|
||||
<span class="layui-btn layui-btn-xs step-up">上移</span>\
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs step-down">下移</span>\
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs step-del" data-id="0">删除</span>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>';
|
||||
$('#stepTable').append(html).find('.tr-none').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
form.render();
|
||||
});
|
||||
$('#stepTable').on('click','.step-del',function(){
|
||||
if($('.step-tr').length<2){
|
||||
layer.msg('至少保留一个项目阶段');
|
||||
return false;
|
||||
}
|
||||
$(this).parents('.step-tr').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
});
|
||||
|
||||
$('#stepTable').on('click','.step-up',function(e){
|
||||
let obj = $(e.target).closest('tr');
|
||||
tr_pre($(obj[0]));
|
||||
})
|
||||
|
||||
$('#stepTable').on('click','.step-down',function(e){
|
||||
var obj = $(e.target).closest('tr');
|
||||
tr_next($(obj[0]));
|
||||
})
|
||||
|
||||
|
||||
function tr_pre(o) {
|
||||
var pres = o.prevAll('tr.step-tr');
|
||||
if (pres.length > 0) {
|
||||
var tmp = o.clone(true);
|
||||
var oo = pres[0];
|
||||
o.remove();
|
||||
$(oo).before(tmp);
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}
|
||||
else{
|
||||
layer.msg('已经第一个了');
|
||||
}
|
||||
}
|
||||
|
||||
function tr_next(o) {
|
||||
var nexts = o.nextAll('tr.step-tr');
|
||||
if (nexts.length > 0) {
|
||||
var tmp = o.clone(true);
|
||||
var oo = nexts[0];
|
||||
o.remove();
|
||||
$(oo).after(tmp);
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}else{
|
||||
layer.msg('已经最后一个了');
|
||||
}
|
||||
}
|
||||
|
||||
$('body').on('click','.picker-diy',function () {
|
||||
let that = $(this),ids = [],titles=[],map = {};
|
||||
let callback = function(data){
|
||||
for ( var i = 0; i <data.length; i++){
|
||||
ids.push(data[i].id);
|
||||
titles.push(data[i].title);
|
||||
}
|
||||
that.prev().val(titles.join(','));
|
||||
}
|
||||
let opts={
|
||||
"title":"选择项目阶段",
|
||||
"url": "/project/api/get_project_step",
|
||||
"ids":"",
|
||||
"titles":"",
|
||||
"area": ['600px', '580px'],
|
||||
"cols":[{field: 'id',width: 80,title:'序号',align:'center'},{field:'title',title:'项目阶段'}]
|
||||
}
|
||||
oaPicker.picker(opts,1,callback,map);//单选
|
||||
});
|
||||
|
||||
|
||||
//监听提交
|
||||
form.on('submit(webform)', function (data) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
tool.sideClose(1000);
|
||||
}
|
||||
}
|
||||
let clickbtn = $(this);
|
||||
tool.post("/project/index/add", data.field, callback,clickbtn);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,154 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
|
||||
<div class="p-page">
|
||||
<form class="layui-form gg-form-bar border-t border-x" lay-filter="barsearchform">
|
||||
<div class="layui-input-inline" style="width:100px;">
|
||||
<select name="status">
|
||||
<option value="">项目状态</option>
|
||||
<option value="1">未开始</option>
|
||||
<option value="2">进行中</option>
|
||||
<option value="3">已完成</option>
|
||||
<option value="4">已关闭</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:136px;">
|
||||
<select name="cate_id">
|
||||
<option value="">项目类别</option>
|
||||
{volist name = ":get_base_data('ProjectCate')" id="vo"}
|
||||
<option value="{$vo.id}">{$vo.title}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:160px;">
|
||||
<input type="text" name="director" placeholder="项目负责人,可多选" readonly class="layui-input picker-admin" data-type="2" autocomplete="off" />
|
||||
<input name="director_uid" style="display: none;" value="" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:300px">
|
||||
<input type="text" name="keywords" placeholder="关键字,项目名称/项目描述" class="layui-input" autocomplete="off" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:150px">
|
||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
|
||||
<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
|
||||
</div>
|
||||
</form>
|
||||
<table class="layui-hide" id="table_project" lay-filter="table_project"></table>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm tool-add" type="button" data-href="/project/index/add">+ 添加项目</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const auth = {$auth};
|
||||
const moduleInit = ['tool','tablePlus','oaPicker'];
|
||||
function gouguInit() {
|
||||
var table = layui.tablePlus, tool = layui.tool;
|
||||
|
||||
layui.pageTable = table.render({
|
||||
elem: "#table_project"
|
||||
, toolbar: "#toolbarDemo"
|
||||
,url: "/project/index/datalist"
|
||||
,page: true
|
||||
,limit: 20
|
||||
,cellMinWidth: 80
|
||||
,height: 'full-114'
|
||||
,cols: [[
|
||||
{field:'id',width:80, title: 'ID号', align:'center'}
|
||||
,{ field: 'status', title: '项目状态', align: 'center', width: 90, templet: function (d) {
|
||||
var html = '<span class="check-status-color-' + d.status + '">『' + d.status_name + '』</span>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
,{field:'cate',title: '项目类别',width:100,align:'center'}
|
||||
,{field:'name',title: '项目名称',minWidth:240}
|
||||
,{field:'director_name',title: '负责人',width:80,align:'center'}
|
||||
,{ field:'range_time', title: '项目计划周期', align: 'center', width: 200}
|
||||
,{field:'step',title: '当前阶段及负责人',align: 'center',width: 180}
|
||||
,{field:'tasks_unfinish', align: 'center', style: 'color: #91CC75;', width: 90, 'title': '进行中任务' }
|
||||
,{field:'tasks_finish', align: 'center', style: 'color: #FAC858;', width: 90, 'title': '已完成任务' }
|
||||
,{field:'tasks_pensent', align: 'center', style: 'color: #EE6666;', width: 90, 'title': '任务完成率' }
|
||||
,{field:'admin_name',title: '创建人',width:80,align:'center'}
|
||||
,{field:'create_time', title: '创建时间',width:150,align:'center'}
|
||||
,{width:120,fixed:'right',title: '操作', align:'center',ignoreExport:true,templet: function(d){
|
||||
var html='';
|
||||
var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>';
|
||||
var btn2='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>';
|
||||
var btn3='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a>';
|
||||
if(d.status==3){
|
||||
btn2='';
|
||||
btn3='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="affirm">反确认完成</a>';
|
||||
}
|
||||
if(auth == 1 || d.admin_id == login_admin || d.director_uid == login_admin){
|
||||
return '<div class="layui-btn-group">'+btn1+btn2+btn3+'</div>';
|
||||
}
|
||||
else{
|
||||
return btn1
|
||||
}
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
table.on('tool(table_project)',function (obj) {
|
||||
var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
|
||||
var data = obj.data;
|
||||
if (obj.event === 'view') {
|
||||
tool.side("/project/index/view?id="+data.id);
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'edit') {
|
||||
tool.side("/project/index/add?id="+data.id);
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'affirm') {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '请输入反确认的原因或理由',
|
||||
area: ['500px', '252px'],
|
||||
content: '<div style="padding:5px;"><textarea class="layui-textarea" id="remarkTextarea" style="width: 100%; height:132px;"></textarea></div>',
|
||||
btnAlign: 'c',
|
||||
btn: ['确认操作'],
|
||||
yes: function (index) {
|
||||
let remark = $("#remarkTextarea").val();
|
||||
if (remark != '') {
|
||||
tool.post("/project/api/step_check", {id: data.id,check:3,content:remark}, callback);
|
||||
layer.close(index);
|
||||
} else {
|
||||
layer.msg('请输入原因或理由');
|
||||
}
|
||||
}
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'del') {
|
||||
layer.confirm('确定要删除该项目吗?', { icon: 3, title: '提示' }, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
obj.del();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/index/del", { id: data.id }, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,297 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<form class="layui-form p-page">
|
||||
<h3 class="pb-3">编辑项目</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目名称<font>*</font></td>
|
||||
<td colspan="3"><input type="text" name="name" lay-verify="required" lay-reqText="请输入项目名称" placeholder="请输入项目名称" class="layui-input" value="{$detail.name}"></td>
|
||||
<td class="layui-td-gray">项目类别<font>*</font></td>
|
||||
<td>
|
||||
<select name="cate_id" lay-verify="required" lay-reqText="请选择项目类别">
|
||||
<option value="">请选择</option>
|
||||
{volist name = ":get_base_data('ProjectCate')" id="vo"}
|
||||
<option value="{$vo.id}" {eq name="$vo.id" value="$detail.cate_id"} selected{/eq}>{$vo.title}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目经理<font>*</font></td>
|
||||
<td>
|
||||
<input type="text" name="director_name" placeholder="请选择项目经理(负责人)" readonly class="layui-input" value="{$detail.director_name}" lay-verify="required" readonly lay-reqText="请选择项目经理(负责人)">
|
||||
<input type="hidden" name="director_uid" value="{$detail.director_uid}">
|
||||
<input type="hidden" name="did" value="{$detail.did}">
|
||||
</td>
|
||||
<td class="layui-td-gray">归属部门<font>*</font></td>
|
||||
<td><input type="text" name="department" value="{$detail.department}" autocomplete="off" readonly class="layui-input"></td>
|
||||
<td class="layui-td-gray">始止日期<span style="color: red">*</span></td>
|
||||
<td><input type="text" name="range_time" value="{$detail.start_time|date='Y-m-d'} 到 {$detail.end_time|date='Y-m-d'}" class="layui-input tool-time" data-range="到" readonly placeholder="开始 到 结束" lay-verify="required" lay-reqText="请选择计划完成周期"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">关联合同</td>
|
||||
<td colspan="5">
|
||||
<input type="text" class="layui-input picker-oa" data-types="contract" name="contract_name" placeholder="请选择需要关联的合同" readonly value="{$detail.contract_name|default=''}">
|
||||
<input type="hidden" class="layui-input" name="contract_id" value="{$detail.contract_id}">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目简介</td>
|
||||
<td colspan="5">
|
||||
<textarea name="content" class="layui-textarea">{$detail.content|default=''}</textarea>
|
||||
</td>
|
||||
</tr>
|
||||
{lt name="$detail.status" value="3"}
|
||||
<tr>
|
||||
<td colspan="6" style="background-color:#FAFAFA;"><strong>项目阶段</strong><span style="color: red">*</span> <span class="layui-btn layui-btn-xs" id="stepAdd">+ 添加阶段</span></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6">
|
||||
<table id="stepTable" class="layui-table layui-table-min" style="margin:0">
|
||||
<tr>
|
||||
<th width="60">序号</th>
|
||||
<th width="180">阶段名称</th>
|
||||
<th width="80">阶段负责人</th>
|
||||
<th width="180">阶段成员</th>
|
||||
<th width="162">阶段周期</th>
|
||||
<th>阶段说明</th>
|
||||
<th width="120">操作</th>
|
||||
</tr>
|
||||
{volist name="$detail.step_array" id="vo" key="k"}
|
||||
{egt name="$vo.sort" value="$detail.current_step"}
|
||||
<tr class="step-tr">
|
||||
<td class="step-key">第 <strong>{$k}</strong> 阶段</td>
|
||||
<td>
|
||||
<div class="layui-input-group">
|
||||
<input type="text" name="step_title[]" value="{$vo.title}" class="layui-input" lay-verify="required" lay-reqText="请输入阶段名称">
|
||||
<div class="layui-input-split layui-input-suffix picker-diy" style="cursor: pointer;"><i class="layui-icon layui-icon-search"></i></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="{$vo.director_name}" class="layui-input layui-input-readonly picker-admin" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>
|
||||
<input type="hidden" name="step_director_uid[]" value="{$vo.director_uid}" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="{$vo.unames}" class="layui-input layui-input-readonly picker-admin" data-type="2">
|
||||
<input type="hidden" name="step_uids[]" value="{$vo.uids}">
|
||||
</td>
|
||||
<td><input type="text" name="step_cycle_time[]" value="{$vo.start_time|date='Y-m-d'} 到 {$vo.end_time|date='Y-m-d'}" class="layui-input layui-input-readonly tool-time" data-range="到" lay-verify="required" lay-reqText="请选择阶段周期" readonly></td>
|
||||
<td><input type="text" name="step_remark[]" value="{$vo.remark|default=''}" class="layui-input"></td>
|
||||
<td>
|
||||
<input type="hidden" name="step_id[]" value="{$vo.id}" class="layui-input">
|
||||
<div class="layui-btn-group">
|
||||
<span class="layui-btn layui-btn-xs step-up">上移</span>
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs step-down">下移</span>
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs step-del" data-id="{$vo.id}">删除</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{else/}
|
||||
<tr>
|
||||
<td class="step-key">第 <strong>{$k}</strong> 阶段</td>
|
||||
<td><input type="text" name="step_title[]" value="{$vo.title}" class="layui-input layui-input-readonly" readonly lay-verify="required" lay-reqText="请输入阶段名称"></td>
|
||||
<td>
|
||||
<input type="text" value="{$vo.director_name}" class="layui-input layui-input-readonly" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>
|
||||
<input type="hidden" name="step_director_uid[]" value="{$vo.director_uid}" readonly>
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" value="{$vo.unames}" class="layui-input layui-input-readonly" data-type="2">
|
||||
<input type="hidden" name="step_uids[]" value="{$vo.uids}">
|
||||
</td>
|
||||
<td><input type="text" name="step_cycle_time[]" value="{$vo.start_time|date='Y-m-d'} 到 {$vo.end_time|date='Y-m-d'}" class="layui-input layui-input-readonly" data-range="到" lay-verify="required" lay-reqText="请选择阶段周期" readonly></td>
|
||||
<td><input type="text" name="step_remark[]" value="{$vo.remark|default=''}" readonly class="layui-input layui-input-readonly"></td>
|
||||
<td>
|
||||
<input type="hidden" name="step_id[]" value="{$vo.id}" class="layui-input">
|
||||
-
|
||||
</td>
|
||||
</tr>
|
||||
{/egt}
|
||||
{/volist}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
{/lt}
|
||||
</table>
|
||||
<div class="pt-3">
|
||||
<input type="hidden" name="id" value="{$detail.id|default=0}"/>
|
||||
<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}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
var moduleInit = ['tool','oaPicker'];
|
||||
|
||||
function gouguInit() {
|
||||
var form = layui.form, tool = layui.tool,oaPicker = layui.oaPicker;
|
||||
//选择项目经理
|
||||
$('body').on('click','[name="director_name"]',function () {
|
||||
var ids=$('[name="director_uid"]').val(),names=$('[name="director_name"]').val();
|
||||
oaPicker.employeeInit({
|
||||
ids:ids,
|
||||
names:names,
|
||||
type:1,
|
||||
callback:function(data){
|
||||
let select_id=[],select_name=[],select_did=[],select_dname=[];
|
||||
for(var a=0; a<data.length;a++){
|
||||
select_id.push(data[a].id);
|
||||
select_name.push(data[a].name);
|
||||
select_did.push(data[a].did);
|
||||
select_dname.push(data[a].department);
|
||||
}
|
||||
$('[name="director_uid"]').val(select_id.join(','));
|
||||
$('[name="director_name"]').val(select_name.join(','));
|
||||
$('[name="did"]').val(select_did.join(','));
|
||||
$('[name="department"]').val(select_dname.join(','));
|
||||
}
|
||||
});
|
||||
});
|
||||
//添加阶段信息表格
|
||||
$('#stepAdd').on('click',function(){
|
||||
var html = '';
|
||||
html += '<tr class="step-tr">\
|
||||
<td class="step-key">第 <strong>0</strong> 阶段</td>\
|
||||
<td>\
|
||||
<div class="layui-input-group">\
|
||||
<input type="text" name="step_title[]" value="" class="layui-input" lay-verify="required" lay-reqText="请输入阶段名称">\
|
||||
<div class="layui-input-split layui-input-suffix picker-diy" style="cursor: pointer;"><i class="layui-icon layui-icon-search"></i></div>\
|
||||
</div>\
|
||||
</td>\
|
||||
<td>\
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" lay-verify="required" lay-reqText="请选择阶段负责人" readonly>\
|
||||
<input type="hidden" name="step_director_uid[]" value="0" readonly>\
|
||||
</td>\
|
||||
<td>\
|
||||
<input type="text" value="" class="layui-input layui-input-readonly picker-admin" data-type="2">\
|
||||
<input type="hidden" name="step_uids[]" value="">\
|
||||
</td>\
|
||||
<td><input type="text" name="step_cycle_time[]" value="" class="layui-input layui-input-readonly tool-time" data-range="到" lay-verify="required" lay-reqText="请选择服务周期" readonly></td>\
|
||||
<td><input type="text" name="step_remark[]" value="" class="layui-input"></td>\
|
||||
<td>\
|
||||
<input type="hidden" name="step_id[]" value="0" class="layui-input">\
|
||||
<div class="layui-btn-group">\
|
||||
<span class="layui-btn layui-btn-xs step-up">上移</span>\
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs step-down">下移</span>\
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs step-del" data-id="0">删除</span>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>';
|
||||
$('#stepTable').append(html).find('.tr-none').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
form.render();
|
||||
});
|
||||
$('#stepTable').on('click','.layui-btn-danger',function(){
|
||||
if($('.step-tr').length<2){
|
||||
layer.msg('至少保留一个项目阶段');
|
||||
return false;
|
||||
}
|
||||
let that=$(this);
|
||||
let id = that.data('id');
|
||||
if(id==0){
|
||||
that.parents('.step-tr').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}
|
||||
else{
|
||||
layer.confirm('确定要删除该项目阶段吗?', { icon: 3, title: '提示' }, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
that.parents('.step-tr').remove();
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}
|
||||
}
|
||||
tool.delete("/project/api/step_del", { id: id }, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('#stepTable').on('click','.step-up',function(e){
|
||||
let obj = $(e.target).closest('tr');
|
||||
tr_pre($(obj[0]));
|
||||
})
|
||||
|
||||
$('#stepTable').on('click','.step-down',function(e){
|
||||
var obj = $(e.target).closest('tr');
|
||||
tr_next($(obj[0]));
|
||||
})
|
||||
|
||||
|
||||
function tr_pre(o) {
|
||||
var pres = o.prevAll('tr.step-tr');
|
||||
if (pres.length > 0) {
|
||||
var tmp = o.clone(true);
|
||||
var oo = pres[0];
|
||||
o.remove();
|
||||
$(oo).before(tmp);
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}
|
||||
else{
|
||||
layer.msg('已经第一个了');
|
||||
}
|
||||
}
|
||||
|
||||
function tr_next(o) {
|
||||
var nexts = o.nextAll('tr.step-tr');
|
||||
if (nexts.length > 0) {
|
||||
var tmp = o.clone(true);
|
||||
var oo = nexts[0];
|
||||
o.remove();
|
||||
$(oo).after(tmp);
|
||||
$('#stepTable').find('.step-key').each(function(index,item){
|
||||
$(this).html('第 <strong>'+(index+1)+'</strong> 阶段');
|
||||
})
|
||||
}else{
|
||||
layer.msg('已经最后一个了');
|
||||
}
|
||||
}
|
||||
|
||||
$('body').on('click','.picker-diy',function () {
|
||||
let that = $(this),ids = [],titles=[],map = {};
|
||||
let callback = function(data){
|
||||
for ( var i = 0; i <data.length; i++){
|
||||
ids.push(data[i].id);
|
||||
titles.push(data[i].title);
|
||||
}
|
||||
that.prev().val(titles.join(','));
|
||||
}
|
||||
let opts={
|
||||
"title":"选择项目阶段",
|
||||
"url": "/project/api/get_project_step",
|
||||
"ids":"",
|
||||
"titles":"",
|
||||
"area": ['600px', '580px'],
|
||||
"cols":[{field: 'id',width: 80,title:'序号',align:'center'},{field:'title',title:'项目阶段'}]
|
||||
}
|
||||
oaPicker.picker(opts,1,callback,map);//单选
|
||||
});
|
||||
|
||||
//监听提交
|
||||
form.on('submit(webform)', function (data) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
tool.sideClose(1000);
|
||||
}
|
||||
}
|
||||
let clickbtn = $(this);
|
||||
tool.post("/project/index/add", data.field, callback,clickbtn);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,552 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
{block name="style"}
|
||||
<style>
|
||||
.layui-tab-title .layui-this{background-color:#fff;}
|
||||
.layui-tab-card,.layui-card{box-shadow:0 0 0 0 rgb(0 0 0 / 10%); border-radius:0;}
|
||||
.layui-card-tips {color: #969696;}
|
||||
.layui-card-value {padding: 4px 0 5px;font-size: 18px;color: #1E9FFF;}
|
||||
|
||||
.check-items{overflow-x: auto; padding: 2px 0;}
|
||||
|
||||
.check-item .check-item-icon strong{margin-right:3px; font-size:36px;}
|
||||
.check-item strong.blue,.check-item strong.gray{display:none;}
|
||||
.check-item.blue strong.black,.check-item.gray strong.black{display:none;}
|
||||
.check-item.blue strong.blue{display:block;}
|
||||
.check-item.gray strong.gray{display:block;}
|
||||
|
||||
.flow-flex-row {box-direction: row;
|
||||
box-orient: horizontal;
|
||||
-webkit-box-orient: horizontal;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
}
|
||||
.flow-flexbox { width: 100%;text-align: left;
|
||||
display: -webkit-box;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
display: -webkit-flex;
|
||||
box-align: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.check-item{width: auto; -ms-flex-negative: 0; flex-shrink: 0; padding:8px 0;}
|
||||
.check-item i{font-size:20px; margin-right:3px;}
|
||||
.layui-icon[data-ok]{color:#34a853}
|
||||
.layui-icon[data-no]{color:#FF5722;}
|
||||
.layui-icon[data-on]{color:#4285f4;}
|
||||
.check-item-time{color:#969696; font-size:12px; margin-left:3px;}
|
||||
.check-item .layui-icon.layui-icon-right{font-size:20px;}
|
||||
.check-item:last-child .layui-icon-right{display:none;}
|
||||
.file-card{line-height:normal;}
|
||||
</style>
|
||||
{/block}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<h2 class="pb-3">
|
||||
<span class="font20">{$detail.name}</span>
|
||||
{gt name="$role" value="0"}
|
||||
{eq name="$detail.status" value="4"}
|
||||
<span class="layui-btn layui-btn-xs" data-event="open">开启</span>
|
||||
{else/}
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs" data-event="close">关闭</span>
|
||||
{/eq}
|
||||
{/gt}
|
||||
</h2>
|
||||
<div class="pb-2">
|
||||
<span class="layui-badge layui-bg-gray">#T{$detail.id}</span>
|
||||
<span class="mx-2">{$detail.admin_name}</span>
|
||||
<span class="gray">创建于{$detail.create_time}<span>{gt name="$detail.update_time" value="0"},最近更新于 {$detail.update_time}{/gt}</span></span>
|
||||
</div>
|
||||
<div class="layui-tabs layui-tab-brief" id="projectTab">
|
||||
<ul class="layui-tabs-header border-t border-x bg-white">
|
||||
<li class="layui-this" data-load="true">项目概览</li>
|
||||
<li data-load="">项目任务</li>
|
||||
<li data-load="">工作记录</li>
|
||||
<li data-load="">项目文档</li>
|
||||
<li data-load="">项目人员</li>
|
||||
<li data-load="">项目动态</li>
|
||||
<li data-load="">项目评论</li>
|
||||
</ul>
|
||||
<div class="layui-tabs-body" style="padding:0">
|
||||
<div class="layui-tabs-item layui-show">
|
||||
{include file="/index/view_overview" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_task" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_schedule" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_document" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_user" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_log" /}
|
||||
</div>
|
||||
|
||||
<div class="layui-tabs-item">
|
||||
{include file="/index/view_comment" /}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script src="{__GOUGU__}/third_party/echart/echarts.min.js"></script>
|
||||
<script>
|
||||
const project_id = '{$detail.id}';
|
||||
const project_start_time = "{$detail.start_time|date='Y-m-d'}";
|
||||
var chartProgress = document.getElementById('progress');
|
||||
var progressChart = echarts.init(chartProgress);
|
||||
var optionA;
|
||||
optionA = {
|
||||
backgroundColor: "#ffffff",
|
||||
title: {
|
||||
text: '67.45%',//主标题文本
|
||||
subtext: '任务完成率',//副标题文本
|
||||
x: 'center',
|
||||
y: '39%',
|
||||
textStyle: {
|
||||
fontWeight: 'normal',
|
||||
fontSize: 18,
|
||||
color: '#FF974C',
|
||||
align: 'center'
|
||||
},
|
||||
subtextStyle: {
|
||||
fontSize: 12,
|
||||
color: '#6c7a89',
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "item",
|
||||
formatter: '{b}:<br/><strong>{c}</strong>',
|
||||
show: true,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '80%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 1048, name: '待处理' },
|
||||
{ value: 735, name: '已完成' }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var chartDelay = document.getElementById('delay');
|
||||
var delayChart = echarts.init(chartDelay);
|
||||
var optionB;
|
||||
optionB = {
|
||||
backgroundColor: "#ffffff",
|
||||
title: {
|
||||
text: '40.25%',//主标题文本
|
||||
subtext: '任务延迟率',//副标题文本
|
||||
x: 'center',
|
||||
y: '39%',
|
||||
textStyle: {
|
||||
fontWeight: 'normal',
|
||||
fontSize: 18,
|
||||
color: '#FF974C',
|
||||
align: 'center',
|
||||
marginLeft: '-10px'
|
||||
},
|
||||
subtextStyle: {
|
||||
fontSize: 12,
|
||||
color: '#6c7a89',
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
trigger: "item",
|
||||
formatter: '{b}:<br/><strong>{c}</strong>',
|
||||
show: true,
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '80%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: [{
|
||||
value: 1048,
|
||||
name: '延迟',
|
||||
itemStyle: {
|
||||
color: "#ED6666",
|
||||
}
|
||||
},
|
||||
{
|
||||
value: 735,
|
||||
name: '未延迟',
|
||||
itemStyle: {
|
||||
color: "#91CC75",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
var chartCross = document.getElementById('cross');
|
||||
var crossChart = echarts.init(chartCross);
|
||||
var optionD;
|
||||
optionD = {
|
||||
backgroundColor: "#ffffff",
|
||||
color: ['#8C92A4', '#2C7EF8'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#6a7985'
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['任务计划剩余', '任务实际剩余']
|
||||
},
|
||||
grid: {
|
||||
top: 36,
|
||||
left: 8,
|
||||
right: 36,
|
||||
bottom: 0,
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'dashed'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
yAxis: [{
|
||||
axisLine: {
|
||||
show: true
|
||||
},
|
||||
boundaryGap: false,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'dashed'
|
||||
}
|
||||
},
|
||||
type: 'value'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
var chartPlan = document.getElementById('plan');
|
||||
var planChart = echarts.init(chartPlan);
|
||||
var optionE;
|
||||
|
||||
optionE = {
|
||||
backgroundColor: "#ffffff",
|
||||
title: {
|
||||
top: 0,
|
||||
left: 0,
|
||||
text: ''
|
||||
},
|
||||
tooltip: {
|
||||
padding: 6,
|
||||
formatter: function (obj) {
|
||||
var value = obj.value;
|
||||
var tips = '<div style="font-size: 12px;">' + value[0] + '<br>';
|
||||
tips += '共 ' + value[1] + ' 个工作任务';
|
||||
tips += '</div>';
|
||||
return tips;
|
||||
}
|
||||
},
|
||||
visualMap: {
|
||||
min: 0,
|
||||
max: 10,
|
||||
show: false,
|
||||
inRange: {
|
||||
color: ['#fafafa', '#20BF3F']
|
||||
}
|
||||
},
|
||||
calendar: {
|
||||
top: 24,
|
||||
left: 36,
|
||||
right: 4,
|
||||
cellSize: ['auto', 16],
|
||||
range: ['2022-03-01', '2022-08-01'],
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#333',
|
||||
type: 'dashed',
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
borderWidth: 0.5
|
||||
},
|
||||
yearLabel: { show: false },
|
||||
monthLabel: {
|
||||
nameMap: 'cn',
|
||||
fontSize: 12
|
||||
},
|
||||
dayLabel: {
|
||||
show: true,
|
||||
formatter: '{start} 1st',
|
||||
fontWeight: 'lighter',
|
||||
nameMap: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
fontSize: 12
|
||||
}
|
||||
},
|
||||
series: {
|
||||
type: 'heatmap',
|
||||
coordinateSystem: 'calendar',
|
||||
data: []
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var chartWork = document.getElementById('work');
|
||||
var workChart = echarts.init(chartWork);
|
||||
var optionF;
|
||||
|
||||
optionF = {
|
||||
backgroundColor: "#ffffff",
|
||||
title: {
|
||||
top: 0,
|
||||
left: 0,
|
||||
text: ''
|
||||
},
|
||||
tooltip: {
|
||||
padding: 6,
|
||||
formatter: function (obj) {
|
||||
var value = obj.value;
|
||||
var tips = '<div style="font-size: 12px;">' + value[0] + '<br>';
|
||||
tips += '共 ' + value[1] + ' 个工时';
|
||||
tips += '</div>';
|
||||
return tips;
|
||||
}
|
||||
},
|
||||
visualMap: {
|
||||
min: 0,
|
||||
max: 10,
|
||||
show: false,
|
||||
inRange: {
|
||||
color: ['#fafafa', '#359AEF']
|
||||
}
|
||||
},
|
||||
calendar: {
|
||||
top: 24,
|
||||
left: 36,
|
||||
right: 4,
|
||||
cellSize: ['auto', 16],
|
||||
range: ['2022-03-01', '2022-08-01'],
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#333',
|
||||
type: 'dashed',
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
borderWidth: 0.5
|
||||
},
|
||||
yearLabel: { show: false },
|
||||
monthLabel: {
|
||||
nameMap: 'cn',
|
||||
fontSize: 12
|
||||
},
|
||||
dayLabel: {
|
||||
show: true,
|
||||
formatter: '{start} 1st',
|
||||
fontWeight: 'lighter',
|
||||
nameMap: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
|
||||
fontSize: 12
|
||||
}
|
||||
},
|
||||
series: {
|
||||
type: 'heatmap',
|
||||
coordinateSystem: 'calendar',
|
||||
data: []
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function getCalendarData(arr) {
|
||||
var rangeArray = [];
|
||||
for (var property in arr) {
|
||||
rangeArray.push(property);
|
||||
}
|
||||
var rangeArray = [rangeArray[0], rangeArray[rangeArray.length - 1]];
|
||||
var start = +echarts.number.parseDate(rangeArray[0]);
|
||||
var end = +echarts.number.parseDate(rangeArray[1]);
|
||||
if (start + 7776000000 > end) {
|
||||
end = start + 8640000000;
|
||||
rangeArray[1] = echarts.format.formatTime('yyyy-MM-dd', end);
|
||||
}
|
||||
var dayTime = 3600 * 24 * 1000;
|
||||
var data = [];
|
||||
for (var time = start; time < end; time += dayTime) {
|
||||
var this_date = echarts.format.formatTime('yyyy-MM-dd', time);
|
||||
if (arr[this_date]) {
|
||||
data.push([this_date, arr[this_date]]);
|
||||
} else {
|
||||
data.push([this_date, 0]);
|
||||
}
|
||||
}
|
||||
var res = { 'range': rangeArray, 'data': data };
|
||||
return res;
|
||||
}
|
||||
|
||||
//燃尽图统计
|
||||
function cross_count(arr, arr2) {
|
||||
var planArray = [], doArray = [];
|
||||
var today = new Date();
|
||||
var todayStr = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
|
||||
for (var a in arr) {
|
||||
planArray.push(a);
|
||||
}
|
||||
var rangeArray = [planArray[0], planArray[planArray.length - 1]];
|
||||
if (arr2 instanceof Array == false) {
|
||||
for (var b in arr2) {
|
||||
doArray.push(b);
|
||||
}
|
||||
if ((+echarts.number.parseDate(doArray[doArray.length - 1])) < (+echarts.number.parseDate(todayStr))) {
|
||||
doArray.push(todayStr);
|
||||
}
|
||||
if ((+echarts.number.parseDate(planArray[planArray.length - 1])) < (+echarts.number.parseDate(doArray[doArray.length - 1]))) {
|
||||
rangeArray[1] = doArray[doArray.length - 1];
|
||||
}
|
||||
}
|
||||
var start = +echarts.number.parseDate(rangeArray[0]);
|
||||
var end = +echarts.number.parseDate(rangeArray[1]);
|
||||
var todayInt = +echarts.number.parseDate(todayStr);
|
||||
var dayTime = 3600 * 24 * 1000;
|
||||
var xArray = [], yArray = [], yArray2 = [], done = 0, doneArray = [];
|
||||
for (var time = start; time <= end; time += dayTime) {
|
||||
var this_date = echarts.format.formatTime('yyyy-MM-dd', time);
|
||||
xArray.push(this_date);
|
||||
var plan = cross_recursion(time, end, arr);
|
||||
yArray.push(plan);
|
||||
|
||||
if (arr2[this_date]) {
|
||||
done += arr2[this_date];
|
||||
}
|
||||
if (time <= todayInt) {
|
||||
doneArray.push(done);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < doneArray.length; i++) {
|
||||
yArray2.push(yArray[0] - doneArray[i]);
|
||||
}
|
||||
var start_time = +echarts.number.parseDate(project_start_time), tem_x_array = [], tem_y_array = [];
|
||||
if (start_time < start) {
|
||||
for (var tem_time = start_time; tem_time < start; tem_time += dayTime) {
|
||||
var this_date = echarts.format.formatTime('yyyy-MM-dd', tem_time);
|
||||
tem_x_array.push(this_date);
|
||||
tem_y_array.push(yArray[0]);
|
||||
}
|
||||
xArray = tem_x_array.concat(xArray);
|
||||
yArray = tem_y_array.concat(yArray);
|
||||
yArray2 = tem_y_array.concat(yArray2);
|
||||
}
|
||||
return { 'x': xArray, 'y': yArray, 'y2': yArray2 };
|
||||
}
|
||||
|
||||
function cross_recursion(start, end, arr) {
|
||||
var count = 0;
|
||||
var dayTime = 3600 * 24 * 1000;
|
||||
for (var time = start; time <= end; time += dayTime) {
|
||||
var this_date = echarts.format.formatTime('yyyy-MM-dd', time);
|
||||
if (arr[this_date]) {
|
||||
count += arr[this_date];
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
//
|
||||
const moduleInit = ['tool','oaPicker','uploadPlus','tablePlus','oaComment','oaSchedule','oaEdit'];
|
||||
|
||||
function gouguInit() {
|
||||
var tool = layui.tool,tabs = layui.tabs,comment = layui.oaComment;
|
||||
|
||||
comment.init({
|
||||
"box":'commentBox',//容器id
|
||||
"input": 'commentInput',
|
||||
"topic_id":project_id,
|
||||
"module": 'project',
|
||||
});
|
||||
|
||||
$('body').on('click','[data-event="close"]',function(){
|
||||
tool.ask('确定要关闭该项目?',function(){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
parent.layui.pageTable.reload();
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
},2000)
|
||||
}
|
||||
}
|
||||
tool.post("/project/api/close", { 'id': project_id}, callback);
|
||||
})
|
||||
})
|
||||
$('body').on('click','[data-event="open"]',function(){
|
||||
tool.ask('确定要开启该项目?',function(){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
parent.layui.pageTable.reload();
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
},2000)
|
||||
}
|
||||
}
|
||||
tool.post("/project/api/open", { 'id': project_id}, callback);
|
||||
})
|
||||
})
|
||||
|
||||
overview();
|
||||
tabs.on('afterChange(projectTab)', function(data){
|
||||
let index = data.index;
|
||||
if(index == 1){
|
||||
project_task();
|
||||
}
|
||||
else if(index == 2){
|
||||
project_schedule();
|
||||
}
|
||||
else if(index == 3){
|
||||
project_document();
|
||||
}
|
||||
else if(index == 4){
|
||||
project_user();
|
||||
}
|
||||
else if(index == 5){
|
||||
project_log();
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,6 @@
|
||||
<div class="px-3 pt-3 border bg-white">
|
||||
<div class="comment-input">
|
||||
<input type="text" id="commentInput" readonly placeholder="发表一下你的看法" class="layui-input" value="">
|
||||
</div>
|
||||
<div id="commentBox" class="pt-3"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,86 @@
|
||||
<div class="bg-white">
|
||||
<table class="layui-hide" id="document" lay-filter="document"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbardocument">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" lay-event="add">+ 新建文档</button>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
function project_document(){
|
||||
if($('#projectTab').find('li').eq(3).data('load') =='true'){
|
||||
return false;
|
||||
}
|
||||
$('#projectTab').find('li').eq(3).data('load','true');
|
||||
let tool = layui.tool, table = layui.tablePlus;
|
||||
//项目任务
|
||||
parent.layui.documentTable = table.render({
|
||||
elem: '#document',
|
||||
title: '文档列表',
|
||||
toolbar: '#toolbardocument',
|
||||
cellMinWidth:80,
|
||||
url: "/project/document/datalist",
|
||||
where:{'project_id':project_id},
|
||||
page: true, //开启分页
|
||||
limit: 20,
|
||||
cols: [[
|
||||
{field: 'id', title: '文档编号', width: 80, align: 'center', templet: function (d) {
|
||||
return 'D' + d.id;
|
||||
}
|
||||
}
|
||||
,{field: 'title', title: '文档主题'}
|
||||
,{field:'admin_name',title: '创建人', align:'center',width: 80}
|
||||
,{field:'create_time',title: '创建时间', align:'center', width: 150}
|
||||
,{
|
||||
field: 'right',
|
||||
fixed:'right',
|
||||
title: '操作',
|
||||
width: 120,
|
||||
align: 'center',
|
||||
templet: function (d) {
|
||||
var html = '<div class="layui-btn-group">';
|
||||
var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>'
|
||||
var btn2='<span class="layui-btn layui-btn-xs" lay-event="edit">编辑</span>';
|
||||
var btn3='<span class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</span>';
|
||||
return html+btn1+btn2+btn3+'</div>';
|
||||
}
|
||||
}
|
||||
]]
|
||||
});
|
||||
|
||||
//触发事件
|
||||
table.on('toolbar(document)', function(obj){
|
||||
if (obj.event === 'add') {
|
||||
tool.side('/project/document/add?project_id='+project_id);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
table.on('tool(document)', function(obj){
|
||||
var data = obj.data; //获得当前行数据
|
||||
if(obj.event === 'view'){ //查看
|
||||
let url = '/project/document/view/id/'+data.id;
|
||||
tool.side(url);
|
||||
}
|
||||
if(obj.event === 'edit'){
|
||||
tool.side('/project/document/add?id='+data.id);
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'del') {
|
||||
layer.confirm('确定要删除吗?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function(index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
obj.del();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/document/delete", {id: data.id}, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,9 @@
|
||||
<div class="border">
|
||||
<div id="logList" class="log-timeline p-3"></div>
|
||||
</div>
|
||||
<script>
|
||||
function project_log(){
|
||||
let oaEdit = layui.oaEdit;
|
||||
oaEdit.log('logList','Project',project_id);
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,415 @@
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目状态</td>
|
||||
<td><span class="check-status-color-{$detail.status}">『{$detail.status_name}』</span></td>
|
||||
<td class="layui-td-gray">项目类别</td>
|
||||
<td>{$detail.cate}</td>
|
||||
<td class="layui-td-gray">始止日期</td>
|
||||
<td>{$detail.start_time|date='Y-m-d'} 到 {$detail.end_time|date='Y-m-d'}</td>
|
||||
<td class="layui-td-gray">所属部门</td>
|
||||
<td>{$detail.department|default='-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目经理</td>
|
||||
<td>{$detail.director_name}</td>
|
||||
<td class="layui-td-gray">项目成员</td>
|
||||
<td colspan="5">{$detail.team_admin_names|default='-'}</td>
|
||||
</tr>
|
||||
{gt name="$detail.contract_id" value="0"}
|
||||
<tr>
|
||||
<td class="layui-td-gray">关联合同</td>
|
||||
<td colspan="7">{$detail.contract_name}</td>
|
||||
</tr>
|
||||
{/gt}
|
||||
{notempty name="$detail.content"}
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目简介</td>
|
||||
<td colspan="7">{$detail.content}</td>
|
||||
</tr>
|
||||
{/notempty}
|
||||
</table>
|
||||
|
||||
<div class="layui-card border" style="margin-top:16px;">
|
||||
<div class="layui-card-header" style="height:43px; line-height:43px;">
|
||||
<strong>项目阶段</strong>
|
||||
</div>
|
||||
<div class="px-3 py-1 border-b">
|
||||
<div class="flow-flexbox check-items flow-flex-row">
|
||||
{volist name="$detail.step_array" id="vo"}
|
||||
<div class='flow-flexbox flow-flex-row check-item {eq name="$vo.is_current" value="1"} blue{/eq} {notempty name="$step"}{lt name="$vo.sort" value="$step.sort"} gray{/lt}{else/} gray{/notempty}'>
|
||||
<div class="check-item-icon">
|
||||
<strong class="iconfont icon-bianji blue"></strong>
|
||||
<strong class="iconfont icon-kaoheguanli gray"></strong>
|
||||
<strong class="iconfont icon-genjinjilu black"></strong>
|
||||
</div>
|
||||
<div>
|
||||
<div class="check-item-name"><strong class="f16">{$vo.title}</strong> {$vo.director_name|default=''}</div>
|
||||
<div class="check-item-time">{$vo.start_time|date='Y-m-d'} 到 {$vo.end_time|date='Y-m-d'}</div>
|
||||
</div>
|
||||
<div class="layui-icon layui-icon-right"></div>
|
||||
</div>
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
{notempty name="$step"}
|
||||
<div class="p-3 border-b">
|
||||
<div>
|
||||
<span class="gray">当前阶段:</span>{$step.title}
|
||||
<span class="gray" style="margin-left:20px">阶段周期:</span>{$step.start_time|date='Y-m-d'} 到 {$step.end_time|date='Y-m-d'}
|
||||
<span class="gray" style="margin-left:20px">负责人:</span>{$step.director_name}
|
||||
{eq name="$step.director_uid" value="$login_admin.id"}
|
||||
<span class="layui-btn layui-btn-normal layui-btn-xs" data-event="step" data-check="1">确认完成</span>
|
||||
<span class="layui-btn layui-btn-danger layui-btn-xs" data-event="step" data-check="2">退回上一阶段</span>
|
||||
{/eq}
|
||||
</div>
|
||||
{notempty name="$step.unames"}
|
||||
<div class="pt-2">
|
||||
<span class="gray">阶段成员:</span>{$step.unames|default=''}
|
||||
</div>
|
||||
{/notempty}
|
||||
{notempty name="$step.remark"}
|
||||
<div class="pt-2">
|
||||
<span class="gray">阶段说明:</span>{$step.remark|default=''}
|
||||
</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
{/notempty}
|
||||
<div class="p-3">
|
||||
<p><strong>阶段流转记录</strong></p>
|
||||
{notempty name="$step_record"}
|
||||
<ul class="layui-timeline pt-2">
|
||||
{volist name="$step_record" id="vo"}
|
||||
<li class="layui-timeline-item delete_{$vo.delete_time}">
|
||||
<i class="layui-icon layui-timeline-axis"></i>
|
||||
{if ($vo.status == 1)}
|
||||
<p style="padding-left:24px">{$vo.check_time_str}<span class="black mx-1">{$vo.check_name}</span><span class="mr-1 green">{$vo.status_str}</span>了『{$vo.title}』的工作。操作意见:<span class="green">{$vo.content|default='-'}</span></p>
|
||||
{else /}
|
||||
<p style="padding-left:24px">{$vo.check_time_str}<span class="black mx-1">{$vo.check_name}</span>在阶段『{$vo.title}』执行了<span class="mx-1 red">{$vo.status_str}</span>操作。操作意见:<span class="red">{$vo.content|default='-'}</span></p>
|
||||
{/if}
|
||||
</li>
|
||||
{/volist}
|
||||
</ul>
|
||||
{else/}
|
||||
<div class="layui-data-none">暂无阶段流转记录</div>
|
||||
{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-card border">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>项目附件</strong>
|
||||
<button type="button" class="layui-btn layui-btn-xs" id="uploadBtn">上传附件</button>
|
||||
</div>
|
||||
<div class="layui-row p-2" id="uploadBox">
|
||||
{volist name="file_array" id="vo"}
|
||||
<div class="layui-col-md4" id="fileItem{$vo.id}">{:file_card($vo)}</div>
|
||||
{/volist}
|
||||
{empty name="$file_array" }
|
||||
<div class="layui-data-none">暂无项目附件</div>
|
||||
{/empty}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-row mb-4 border">
|
||||
<div class="layui-col-xs6 layui-col-md3">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>项目概况</strong>
|
||||
</div>
|
||||
<div class="p-3">
|
||||
<dl>
|
||||
<dt>任务 <span class="gray">(已完成/全部)</span></dt>
|
||||
<dd class="layui-card-value" title="已完成/总任务">{$detail.tasks_finish} / {$detail.tasks}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="pt-2 px-3">
|
||||
<dl>
|
||||
<dt>项目工时 <span class="gray">(实际/计划)</span></dt>
|
||||
<dd class="layui-card-value" title="实际工时/计划工时">{$detail.hours} / {$detail.plan_hours}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="pt-2 px-3">
|
||||
<dl>
|
||||
<dt>工作记录</dt>
|
||||
<dd class="layui-card-value" title="工作记录数">{$detail.schedules}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xs6 layui-col-md9">
|
||||
<div class="layui-card border-l">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>项目进度</strong>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div class="layui-row">
|
||||
<div class="layui-col-md6">
|
||||
<div id="progress" class="gougu-data-none" style="width:100%; height:200px;"></div>
|
||||
</div>
|
||||
<div class="layui-col-md6">
|
||||
<div id="delay" class="gougu-data-none" style="width:100%; height:200px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="layui-card border">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>项目燃尽图</strong>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="cross" class="gougu-data-none" style="width:100%; height:360px;"
|
||||
data-tips="任务数:{$detail.tasks},已完成:{$detail.tasks_finish},未完成:{$detail.tasks_unfinish}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="layui-row border">
|
||||
<div class="layui-col-xs6 layui-col-md6">
|
||||
<div class="layui-card border-r">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>任务分配情况</strong>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="plan" class="gougu-data-none" style="width:100%; height:150px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-col-xs6 layui-col-md6">
|
||||
<div class="layui-card">
|
||||
<div class="layui-card-header" style="height:45px; line-height:45px;">
|
||||
<strong>工时登记情况</strong>
|
||||
</div>
|
||||
<div class="layui-card-body">
|
||||
<div id="work" class="gougu-data-none" style="width:100%; height:150px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
function overview(){
|
||||
let form = layui.form,tool = layui.tool,uploadPlus = layui.uploadPlus;
|
||||
|
||||
$('body').on('click','[data-event="step"]',function(){
|
||||
let check = $(this).data('check');
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
},2000)
|
||||
parent.layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
if(check == 2){
|
||||
$(parent.$('.express-close')).addClass('parent-colse');
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '请输入退回的原因或理由',
|
||||
area: ['500px', '252px'],
|
||||
content: '<div style="padding:5px;"><textarea class="layui-textarea" id="remarkTextarea" style="width: 100%; height:132px;"></textarea></div>',
|
||||
btnAlign: 'c',
|
||||
btn: ['确认回退'],
|
||||
end: function(){
|
||||
$(parent.$('.express-close')).removeClass('parent-colse');
|
||||
},
|
||||
yes: function () {
|
||||
let remark = $("#remarkTextarea").val();
|
||||
if (remark != '') {
|
||||
tool.post("/project/api/step_check", {id: project_id,check:check,content:remark}, callback);
|
||||
} else {
|
||||
layer.msg('请输入原因或理由');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
else{
|
||||
$(parent.$('.express-close')).addClass('parent-colse');
|
||||
layer.open({
|
||||
type: 1,
|
||||
title: '请输入操作意见',
|
||||
area: ['500px', '252px'],
|
||||
content: '<div style="padding:5px;"><textarea class="layui-textarea" id="remarkTextarea" style="width: 100%; height:132px;"></textarea></div>',
|
||||
btnAlign: 'c',
|
||||
btn: ['确认完成'],
|
||||
end: function(){
|
||||
$(parent.$('.express-close')).removeClass('parent-colse');
|
||||
},
|
||||
yes: function () {
|
||||
let remark = $("#remarkTextarea").val();
|
||||
if (remark != '') {
|
||||
tool.post("/project/api/step_check", {id: project_id,check:check,content:remark}, callback);
|
||||
} else {
|
||||
layer.msg('请输入操作意见');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
var attachment = new uploadPlus({
|
||||
"target":'uploadBtn',
|
||||
"targetBox":'uploadBox',
|
||||
"attachment":{
|
||||
"type":1,//0ajax多文件模式,1ajax单文件单记录模式
|
||||
"uidDelete":true,//是否开启只有上传人自己才能删除自己的附件
|
||||
"ajaxSave":function(res){
|
||||
let callback = function (e) {
|
||||
layer.msg('上传成功');
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
},2000)
|
||||
}
|
||||
tool.post("/project/api/add_file", { 'topic_id': project_id, 'file_id': res.data.id, 'file_name': res.data.name, 'module': 'project' }, callback);
|
||||
},
|
||||
"ajaxDelete":function(file_id){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
$('#fileItem' + file_id).remove();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/api/delete_file", {id: file_id}, callback);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let callback = function (res) {
|
||||
if (res.data.date_tasks instanceof Array == false) {
|
||||
optionA.title.text = res.data.task_pie.ok_lv + '%';
|
||||
optionA.series = [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '80%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: res.data.task_pie.count - res.data.task_pie.count_ok, name: '待处理' },
|
||||
{ value: res.data.task_pie.count_ok, name: '已完成' }
|
||||
]
|
||||
}
|
||||
];
|
||||
optionA && progressChart.setOption(optionA);
|
||||
|
||||
optionB.title.text = res.data.task_pie.delay_lv + '%';
|
||||
optionB.series = [
|
||||
{
|
||||
type: 'pie',
|
||||
radius: ['60%', '80%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false
|
||||
},
|
||||
data: [{
|
||||
value: res.data.task_pie.delay,
|
||||
name: '延迟',
|
||||
itemStyle: {
|
||||
color: "#ED6666",
|
||||
}
|
||||
},
|
||||
{
|
||||
value: (res.data.task_pie.count - res.data.task_pie.delay),
|
||||
name: '未延迟',
|
||||
itemStyle: {
|
||||
color: "#91CC75",
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
||||
optionB && delayChart.setOption(optionB);
|
||||
|
||||
var dataD = cross_count(res.data.date_tasks, res.data.date_tasks_ok);
|
||||
var tips = $('#cross').data('tips');
|
||||
optionD.title = {
|
||||
text: '',
|
||||
subtext: tips,
|
||||
top: -10,
|
||||
},
|
||||
optionD.xAxis = {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'dashed'
|
||||
}
|
||||
},
|
||||
data: dataD.x,
|
||||
axisLabel: {
|
||||
rotate: 30,
|
||||
formatter: function (value, index) {
|
||||
return value.slice(5);
|
||||
}
|
||||
}
|
||||
};
|
||||
optionD.series = [
|
||||
{
|
||||
name: '任务计划剩余',
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
markLine: {
|
||||
data: [{ type: 'average', name: 'Avg' }],
|
||||
},
|
||||
lineStyle: {
|
||||
width: 2
|
||||
},
|
||||
data: dataD.y
|
||||
},
|
||||
{
|
||||
name: '任务实际剩余',
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
areaStyle: {
|
||||
opacity: 0.1
|
||||
},
|
||||
markLine: {
|
||||
data: [{ type: 'average', name: 'Avg' }],
|
||||
},
|
||||
lineStyle: {
|
||||
width: 2
|
||||
},
|
||||
data: dataD.y2
|
||||
}
|
||||
]
|
||||
optionD && crossChart.setOption(optionD)
|
||||
|
||||
var dataE = getCalendarData(res.data.date_tasks);
|
||||
optionE.calendar.range = dataE.range,
|
||||
optionE.series = {
|
||||
type: 'heatmap',
|
||||
coordinateSystem: 'calendar',
|
||||
data: dataE.data
|
||||
}
|
||||
optionE && planChart.setOption(optionE);
|
||||
|
||||
if (res.data.date_schedules instanceof Array == false) {
|
||||
var dataF = getCalendarData(res.data.date_schedules);
|
||||
optionF.calendar.range = dataF.range,
|
||||
optionF.series = {
|
||||
type: 'heatmap',
|
||||
coordinateSystem: 'calendar',
|
||||
data: dataF.data
|
||||
}
|
||||
optionF && workChart.setOption(optionF);
|
||||
}
|
||||
}
|
||||
}
|
||||
tool.get('/project/api/get_chart_data', { 'project_id': project_id }, callback);
|
||||
|
||||
window.onresize = function () {
|
||||
progressChart.resize();
|
||||
delayChart.resize();
|
||||
crossChart.resize();
|
||||
planChart.resize();
|
||||
workChart.resize();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,64 @@
|
||||
<div class="bg-white">
|
||||
<table class="layui-hide" id="scheduleApi" lay-filter="schedule"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbarschedule">
|
||||
<div class="layui-btn-container">
|
||||
<span class="yellow">如需创建工作日志,请到项目任务的详情页创建</span>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
function project_schedule(){
|
||||
if($('#projectTab').find('li').eq(2).data('load') =='true'){
|
||||
return false;
|
||||
}
|
||||
$('#projectTab').find('li').eq(2).data('load','true');
|
||||
let form = layui.form,tool = layui.tool,table = layui.tablePlus,work = layui.oaSchedule,oaPicker = layui.oaPicker;
|
||||
//项目工作记录
|
||||
layui.scheduleTable = table.render({
|
||||
elem: '#scheduleApi',
|
||||
title: '工作记录列表',
|
||||
toolbar: '#toolbarschedule',
|
||||
cellMinWidth: 80,
|
||||
url: "/oa/api/get_schedule", //数据接口
|
||||
where: { 'project_id': project_id },
|
||||
cols: [[ //表头
|
||||
{ field: 'id', title: '序号', width: 60, align: 'center' }
|
||||
, {
|
||||
field: 'start_time', title: '工作时间范围', align: 'center', width: 180, templet: function (d) {
|
||||
var html = d.start_time + '至' + d.end_time;
|
||||
return html;
|
||||
}
|
||||
}
|
||||
, { field: 'labor_time', title: '工时', style: 'color: #91CC75;', align: 'center', width: 60 }
|
||||
, { field: 'labor_type_string', title: '工作类型', align: 'center', width: 90,templet:function(d){
|
||||
var html = '<span class="layui-color-'+d.labor_type+'">'+d.labor_type_string+'</span>';
|
||||
return html;
|
||||
}}
|
||||
, { field: 'work_cate', title: '工作类别', align: 'center', width: 100 }
|
||||
, { field: 'title', title: '工作内容' }
|
||||
, { field: 'name', title: '执行员工', align: 'center', width: 80 }
|
||||
, { field: 'department', title: '所在部门', align: 'center', width: 100 }
|
||||
, { field: 'create_time', title: '记录时间', align: 'center', width: 150 }
|
||||
, {title: '操作',fixed:'right', align: 'center', width: 100, templet: function (d) {
|
||||
if(d.admin_id == login_admin){
|
||||
return '<div class="layui-btn-group"><span class="layui-btn layui-btn-xs" lay-event="edit">修改</span><span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</span></div>';
|
||||
}
|
||||
else{
|
||||
return '<span class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
]]
|
||||
});
|
||||
//监听行工具事件
|
||||
table.on('tool(schedule)', function (obj) {
|
||||
if (obj.event === 'edit') {
|
||||
work.add(0, obj.data);
|
||||
}
|
||||
if (obj.event === 'view') {
|
||||
work.view(obj.data);
|
||||
}
|
||||
return false;
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,64 @@
|
||||
<div class="bg-white">
|
||||
<table class="layui-hide" id="task" lay-filter="task"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbartask">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" lay-event="add">+ 新建任务</button>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
function project_task(){
|
||||
if($('#projectTab').find('li').eq(1).data('load') =='true'){
|
||||
return false;
|
||||
}
|
||||
$('#projectTab').find('li').eq(1).data('load','true');
|
||||
let tool = layui.tool, table = layui.tablePlus;
|
||||
//项目任务
|
||||
parent.layui.taskTable = table.render({
|
||||
elem: '#task',
|
||||
title: '任务列表',
|
||||
toolbar: '#toolbartask',
|
||||
cellMinWidth:80,
|
||||
url: "/project/api/get_task",
|
||||
where:{'project_id':project_id},
|
||||
page: true, //开启分页
|
||||
limit: 20,
|
||||
cols: [[
|
||||
{field: 'id', title: '任务编号', width: 80, align: 'center', fixed: 'left', templet: function (d) {
|
||||
return 'T' + d.id;
|
||||
}
|
||||
}
|
||||
,{ field: 'status', title: '任务状态', align: 'center', width: 90, templet: function (d) {
|
||||
var html = '<span class="check-status-color-' + d.status + '">『' + d.status_name + '』</span>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
, { field: 'cate_name', title: '工作类型', width: 90, align: 'center'}
|
||||
,{field:'title',title: '任务主题', minWidth: 300,templet:function(d){
|
||||
var html = '<span class="layui-badge layui-bg-'+d.priority+'">'+d.priority_name+'</span> <a data-href="/project/task/view/id/'+d.id+'.html" class="side-a">'+d.title+'</a>';
|
||||
return html;
|
||||
}}
|
||||
,{field:'director_name',title: '负责人', align:'center',width: 80}
|
||||
,{field:'assist_admin_names',title: '协作人',width: 160}
|
||||
,{field:'plan_hours',title: '预估工时', align:'center',width: 80}
|
||||
,{field:'end_time',title: '预计结束日期', width: 150,templet:function(d){
|
||||
var html = d.end_time;
|
||||
if(d.delay>0){
|
||||
html+= '<span class="red ml-1" style="font-size:12px;">逾期'+d.delay+'天</span>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
//触发事件
|
||||
table.on('toolbar(task)', function(obj){
|
||||
var checkStatus = table.checkStatus(obj.config.id);
|
||||
switch(obj.event){
|
||||
case 'add':
|
||||
tool.side('/project/task/add?project_id='+project_id);
|
||||
break;
|
||||
};
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,116 @@
|
||||
<div class="bg-white">
|
||||
<table class="layui-hide" id="user" lay-filter="user"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbaruser">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" lay-event="add">+ 新增项目成员</button>
|
||||
</div>
|
||||
</script>
|
||||
<script>
|
||||
function project_user(){
|
||||
if($('#projectTab').find('li').eq(4).data('load') =='true'){
|
||||
return false;
|
||||
}
|
||||
$('#projectTab').find('li').eq(4).data('load','true');
|
||||
let tool = layui.tool, table = layui.tablePlus,oaPicker = layui.oaPicker;
|
||||
//项目成员
|
||||
layui.userTable = table.render({
|
||||
elem: '#user',
|
||||
title: '项目成员列表',
|
||||
cellMinWidth: 60,
|
||||
toolbar: '#toolbaruser',
|
||||
url: "/project/api/project_user", //数据接口
|
||||
where: { 'tid': project_id },
|
||||
page: false, //开启分页
|
||||
limit: 20,
|
||||
cols: [[ //表头
|
||||
{ field: 'name', fixed: 'left', title: '成员姓名', width: 90, align: 'center', rowspan: 2 }
|
||||
, { field: 'create_time', title: '进入项目日期', width: 110, align: 'center', rowspan: 2 }
|
||||
, { field: 'role', title: '角色', align: 'center', width: 90, rowspan: 2, templet: function (d) {
|
||||
var html='<span style="color: #4285F4;">普通成员</span>';
|
||||
if(d.role==1){
|
||||
html='<span style="color: #EE6666;">项目创建人</span>';
|
||||
}
|
||||
if(d.role==2){
|
||||
html='<span style="color: #91CC75;">项目负责人</span>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
, { field: 'position', title: '职位', align: 'center', width: 100, rowspan: 2 }
|
||||
, { field: 'department', title: '所在部门', align: 'center', width: 120, rowspan: 2 }
|
||||
, { field: 'mobile', title: '手机号码', align: 'center', width: 110, rowspan: 2 }
|
||||
, { align: 'center', title: '工作记录', colspan: 2 }
|
||||
, { align: 'center', title: '项目任务', colspan: 3 }
|
||||
, { field: 'delete_time', title: '移除日期', align: 'center', minWidth: 120, rowspan: 2 }
|
||||
, { field: 'status',fixed: 'right', title: '状态', align: 'center', width: 60, rowspan: 2, templet: function (d) {
|
||||
var html = '<span style="color:#EE6666">✘</span>';
|
||||
if(d.delete_time == '-')
|
||||
html = '<span style="color:#91CC75">✔</span>';
|
||||
return html;
|
||||
}}
|
||||
, {title: '操作',fixed: 'right', align: 'center', width: 60, rowspan: 2, templet: function (d) {
|
||||
var html = '<span class="layui-btn layui-btn-xs" lay-event="recover">恢复</span>';
|
||||
if(d.delete_time == '-')
|
||||
html = '<span class="layui-btn layui-btn-danger layui-btn-xs" lay-event="remove">移除</span>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
], [
|
||||
{ field: 'schedules', align: 'center', style: 'color: #91CC75;', width: 72, 'title': '记录' }
|
||||
, { field: 'labor_times', align: 'center', style: 'color: #4285F4;', width: 70, 'title': '工时' }
|
||||
, { field: 'tasks_unfinish', align: 'center', style: 'color: #91CC75;', width: 72, 'title': '进行中' }
|
||||
, { field: 'tasks_finish', align: 'center', style: 'color: #FAC858;', width: 70, 'title': '已完成' }
|
||||
, { field: 'tasks_pensent', align: 'center', style: 'color: #EE6666;', width: 72, 'title': '完成率' }
|
||||
]]
|
||||
});
|
||||
|
||||
//触发事件
|
||||
table.on('toolbar(user)', function(obj){
|
||||
var checkStatus = table.checkStatus(obj.config.id);
|
||||
switch(obj.event){
|
||||
case 'add':
|
||||
oaPicker.employeeInit({
|
||||
type: 1,
|
||||
callback: function (data) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if(e.code == 0){
|
||||
layui.userTable.reload();
|
||||
}
|
||||
}
|
||||
let select_id=[];
|
||||
for(var a=0; a<data.length;a++){
|
||||
select_id.push(data[a].id);
|
||||
}
|
||||
let ids = select_id.join(',');
|
||||
tool.post("/project/api/add_user", {uid: ids,project_id: project_id}, callback);
|
||||
}
|
||||
})
|
||||
break;
|
||||
};
|
||||
});
|
||||
|
||||
//监听行工具事件
|
||||
table.on('tool(user)', function (obj) {
|
||||
let postData = { "id": obj.data.id };
|
||||
let callback = function (e) {
|
||||
layer.closeAll();
|
||||
layer.msg(e.msg);
|
||||
if(e.code == 0){
|
||||
layui.userTable.reload();
|
||||
}
|
||||
}
|
||||
if (obj.event === 'remove') {
|
||||
tool.ask('确定要移除该项目成员吗?', function (index) {
|
||||
tool.delete("/project/api/remove_user", postData, callback);
|
||||
});
|
||||
}
|
||||
if (obj.event === 'recover') {
|
||||
tool.ask('确定要恢复该项目成员吗?', function (index) {
|
||||
tool.post("/project/api/recover_user", postData, callback);
|
||||
});
|
||||
}
|
||||
return;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,45 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<form class="layui-form p-page">
|
||||
<h3 class="pb-3">项目步骤</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<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" value="{$detail.title|default=''}"></td>
|
||||
<td class="layui-td-gray">排序</td>
|
||||
<td><input type="text" name="sort" placeholder="请输入排序,数字" autocomplete="off" class="layui-input" value="{$detail.sort|default=''}"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="pt-4">
|
||||
<input type="hidden" name="id" value="{$detail.id|default=0}"/>
|
||||
<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}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
var 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) {
|
||||
tool.sideClose(1000);
|
||||
}
|
||||
}
|
||||
let clickbtn = $(this);
|
||||
tool.post("/project/step/add", data.field, callback,clickbtn);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,124 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
|
||||
<div class="p-page">
|
||||
<table class="layui-hide" id="table_step" lay-filter="table_step"></table>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm add-new" type="button">+ 添加项目步骤</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const moduleInit = ['tool'];
|
||||
function gouguInit() {
|
||||
var table = layui.table, tool = layui.tool;
|
||||
|
||||
layui.pageTable = table.render({
|
||||
elem: "#table_step"
|
||||
,toolbar: '#toolbarDemo'
|
||||
,url: "/project/step/datalist"
|
||||
,page: false
|
||||
,limit: 999
|
||||
,cellMinWidth: 80
|
||||
,cols: [[
|
||||
{field:'id',width:80, title: 'ID号', align:'center'}
|
||||
,{field:'title',title: '类型名称'}
|
||||
,{field:'status', title: '状态',width:80,align:'center',templet: function(d){
|
||||
var html1='<span class="green">正常</span>';
|
||||
var html2='<span class="yellow">禁用</span>';
|
||||
if(d.status==1){
|
||||
return html1;
|
||||
}
|
||||
else{
|
||||
return html2;
|
||||
}
|
||||
}}
|
||||
,{width:100,title: '操作', align:'center',ignoreExport:true,templet: function(d){
|
||||
var html='';
|
||||
var btn='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>';
|
||||
var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
|
||||
var btn2='<a class="layui-btn layui-btn-xs" lay-event="open">启用</a>';
|
||||
if(d.status==1){
|
||||
html = '<div class="layui-btn-group">'+btn+btn1+'</div>';
|
||||
}
|
||||
else{
|
||||
html = '<div class="layui-btn-group">'+btn+btn2+'</div>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
table.on('tool(table_step)',function (obj) {
|
||||
if(obj.event === 'edit'){
|
||||
add_cate(obj.data.id,obj.data.title);
|
||||
}
|
||||
if(obj.event === 'disable'){
|
||||
layer.confirm('确定要禁用该记录吗?', {icon: 3, title:'提示'}, function(index){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/step/set", {id:obj.data.id,status: 0}, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
if(obj.event === 'open'){
|
||||
layer.confirm('确定要启用该记录吗?', {icon: 3, title:'提示'}, function(index){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/step/set", {id:obj.data.id,status:1}, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('body').on('click','.add-new',function(){
|
||||
add_cate(0,'');
|
||||
});
|
||||
|
||||
function add_cate(id,val){
|
||||
var title = '新增类型';
|
||||
if(id>0){
|
||||
title = '编辑类型';
|
||||
}
|
||||
layer.prompt({
|
||||
title: title,
|
||||
value: val,
|
||||
yes: function(index, layero) {
|
||||
// 获取文本框输入的值
|
||||
var value = layero.find(".layui-layer-input").val();
|
||||
if (value) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/step/add", {id: id,title: value}, callback);
|
||||
layer.close(index);
|
||||
} else {
|
||||
layer.msg('请填写类型名称');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,16 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<h3 class="pb-3">项目步骤详情</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">项目步骤名称</td>
|
||||
<td>{$detail.title|default=''}"></td>
|
||||
<td class="layui-td-gray">排序</td>
|
||||
<td>{$detail.sort|default=0}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
@@ -0,0 +1,111 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
{block name="body"}
|
||||
<form class="layui-form p-page">
|
||||
<h3 class="pb-3">新建任务</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">任务主题<font>*</font></td>
|
||||
<td colspan="3"><input type="text" name="title" lay-verify="required" lay-reqText="请输入任务主题" placeholder="请输入任务主题" class="layui-input" value=""></td>
|
||||
<td class="layui-td-gray-2">任务优先级<span style="color: red">*</span></td>
|
||||
<td>
|
||||
<select name="priority" lay-verify="required" lay-reqText="请选择优先级">
|
||||
{volist name=":get_priority()" id="vo"}
|
||||
{gt name="$key" value="0"}
|
||||
<option value="{$key}">{$vo}</option>
|
||||
{/gt}
|
||||
{/volist}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">工作类型<span style="color: red">*</span></td>
|
||||
<td>
|
||||
<select name="work_id" lay-verify="required" lay-reqText="请选择工作类型">
|
||||
<option value="">请选择</option>
|
||||
{volist name=":get_base_data('WorkCate')" id="vo"}
|
||||
<option value="{$vo.id}">{$vo.title}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</td>
|
||||
<td class="layui-td-gray">预估工时<span style="color: red">*</span></td>
|
||||
<td><input type="text" name="plan_hours" lay-verify="required|number" lay-reqText="请填写预估工时" placeholder="请填写预估工时" class="layui-input" value=""></td>
|
||||
<td class="layui-td-gray-2">预计结束日期<span style="color: red">*</span></td>
|
||||
<td><input type="text" name="end_time" readonly lay-verify="required" lay-reqText="请选择预计结束日期" placeholder="请选择时间" class="layui-input tool-time" value=""></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">负责人</td>
|
||||
<td>
|
||||
<input type="text" name="director_name" placeholder="请选择" readonly class="layui-input picker-admin" value="">
|
||||
<input type="hidden" name="director_uid" readonly value="0">
|
||||
</td>
|
||||
{empty name="$project_id"}
|
||||
<td class="layui-td-gray">协作人</td>
|
||||
<td>
|
||||
<input type="text" name="assist_admin_names" placeholder="请选择" readonly class="layui-input picker-admin" data-type="2" value="">
|
||||
<input type="hidden" name="assist_admin_ids" readonly value="">
|
||||
</td>
|
||||
<td class="layui-td-gray">关联项目</td>
|
||||
<td>
|
||||
<input type="text" name="project_name" placeholder="所属项目" readonly class="layui-input picker-oa" data-types="project" autocomplete="off" />
|
||||
<input type="hidden" name="project_id" value="0" />
|
||||
</td>
|
||||
{else/}
|
||||
<td class="layui-td-gray">协作人</td>
|
||||
<td colspan="3">
|
||||
<input type="hidden" name="project_id" readonly value="{$project_id}">
|
||||
<input type="text" name="assist_admin_names" placeholder="请选择" readonly class="layui-input picker-admin" data-type="2" value="">
|
||||
<input type="hidden" name="assist_admin_ids" readonly value="">
|
||||
</td>
|
||||
{/empty}
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray" style="vertical-align:top;">详细描述<font>*</font></td>
|
||||
<td colspan="5">
|
||||
<textarea name="content" placeholder="请输入内容" class="layui-textarea" id="container" style="border:0;padding:0"></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="pt-4">
|
||||
<input type="hidden" name="id" value="0" />
|
||||
<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}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const moduleInit = ['tool','tinymce','oaPicker'];
|
||||
function gouguInit() {
|
||||
var form = layui.form,tool=layui.tool, oaPicker = layui.oaPicker;
|
||||
|
||||
//编辑器初始化
|
||||
var editor = layui.tinymce;
|
||||
var edit = editor.render({
|
||||
selector: "#container",
|
||||
images_upload_url: '/api/index/upload/sourse/tinymce',//图片上传接口
|
||||
height: 500
|
||||
});
|
||||
|
||||
//监听提交
|
||||
form.on('submit(webform)', function (data) {
|
||||
data.field.content = tinyMCE.editors['container'].getContent();
|
||||
if (data.field.content == '') {
|
||||
layer.msg('请先完善任务描述内容');
|
||||
return false;
|
||||
}
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
tool.sideClose(1000);
|
||||
}
|
||||
}
|
||||
let clickbtn = $(this);
|
||||
tool.post("/project/task/add", data.field, callback,clickbtn);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
@@ -0,0 +1,111 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
{block name="style"}
|
||||
<style>
|
||||
.layui-unselect dl {max-height:188px;}
|
||||
</style>
|
||||
{/block}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<form class="layui-form gg-form-bar border-x border-t" lay-filter="barsearchform">
|
||||
<div class="layui-input-inline" style="width:100px;">
|
||||
<input type="text" name="username" placeholder="请选择评论人" class="layui-input picker-admin" readonly />
|
||||
<input type="text" name="uid" value="" style="display:none" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:300px;">
|
||||
<input type="text" name="keywords" placeholder="关键字,输入评论内容" class="layui-input"/>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:150px;">
|
||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
|
||||
<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<table class="layui-hide" id="test" lay-filter="test"></table>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<h3>任务评论</h3>
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const moduleInit = ['tool','tablePlus','oaPicker'];
|
||||
function gouguInit() {
|
||||
var form = layui.form,table = layui.tablePlus,tool=layui.tool, work = layui.oaSchedule;
|
||||
layui.commentTable = table.render({
|
||||
elem: '#test'
|
||||
,toolbar: '#toolbarDemo'
|
||||
,title:'评论列表'
|
||||
,url: "/project/task/comment"
|
||||
,cellMinWidth: 80
|
||||
,is_excel:true
|
||||
,height: 'full-110'
|
||||
,cols: [[ //表头
|
||||
{field: 'id', title: '序号',fixed: 'left', width:80, align:'center'}
|
||||
,{field: 'content', title: '评论内容'}
|
||||
,{field: 'project', title: '关联项目&任务', width:300,templet:function(d){
|
||||
var html='';
|
||||
if(d.labor_type==0){
|
||||
html='<span class="layui-color-'+d.labor_type+'">-</span>';
|
||||
}
|
||||
else if(d.module =='project'){
|
||||
html='<span class="green">『项目』</span><a data-href="/project/index/view/id/'+d.topic_id+'.html" class="side-a">'+d.topic_name+'</a>';
|
||||
}
|
||||
else{
|
||||
html='<span class="blue">『任务』</span><a data-href="/project/task/view/id/'+d.topic_id+'.html" class="side-a">'+d.topic_name+'</a>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
,{field: 'to_names', title: '@关联人', width:160}
|
||||
,{field: 'admin_name', title: '评论人', align:'center',width:80}
|
||||
,{field: 'create_time', title: '评论时间', align:'center',width:150}
|
||||
,{field: 'right', title: '操作',fixed:'right', width:90, align:'center',templet:function(d){
|
||||
if(d.read==0){
|
||||
return '<button class="layui-btn layui-btn-xs layui-btn-normal" lay-event="read">设为已读</button>';
|
||||
}
|
||||
else if(d.read==2){
|
||||
return '<button class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</button>';
|
||||
}
|
||||
else{
|
||||
return '-';
|
||||
}
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
table.on('tool(test)', function(obj){
|
||||
var data = obj.data;
|
||||
if (obj.event === 'read') {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.commentTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/api/read_comment", { id: data.id }, callback);
|
||||
}
|
||||
if (obj.event === 'del') {
|
||||
layer.confirm('确定要删除该评论吗?', { icon: 3, title: '提示' }, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
obj.del();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/api/delete_comment", { id: data.id }, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
return;
|
||||
}
|
||||
return;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,146 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="style"}
|
||||
<style>
|
||||
.layui-unselect dl {
|
||||
max-height: 188px;
|
||||
}
|
||||
</style>
|
||||
{/block}
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<div class="gg-form-bar border-t border-x">
|
||||
<form id="taskForm" class="layui-form" lay-filter="barsearchform">
|
||||
<div class="layui-input-inline" style="width:100px;">
|
||||
<select name="status" lay-filter="status">
|
||||
<option value="">任务状态</option>
|
||||
{volist name=":get_task_status()" id="vo"}
|
||||
{gt name="$key" value="0"}
|
||||
<option value="{$key}">{$vo}</option>
|
||||
{/gt}
|
||||
{/volist}
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:100px;">
|
||||
<select name="priority" lay-filter="priority">
|
||||
<option value="">优先级</option>
|
||||
{volist name=":get_priority()" id="vo"}
|
||||
{gt name="$key" value="0"}
|
||||
<option value="{$key}">{$vo}</option>
|
||||
{/gt}
|
||||
{/volist}
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:100px;">
|
||||
<select name="work_id" lay-filter="cate">
|
||||
<option value="">工作类型</option>
|
||||
{volist name=":get_base_data('WorkCate')" id="vo"}
|
||||
<option value="{$vo.id}">{$vo.title}</option>
|
||||
{/volist}
|
||||
</select>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:240px;">
|
||||
<input type="text" name="project_name" placeholder="所属项目" readonly class="layui-input picker-oa" data-types="project" autocomplete="off" />
|
||||
<input name="project_id" style="display: none;" value="" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:160px;">
|
||||
<input type="text" name="director" placeholder="任务负责人,可多选" readonly class="layui-input picker-admin" data-type="2" autocomplete="off" />
|
||||
<input name="director_uid" style="display: none;" value="" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:240px;">
|
||||
<input type="text" name="keywords" placeholder="关键字,任务主题/描述内容" class="layui-input" autocomplete="off" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:150px;">
|
||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
|
||||
<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<table class="layui-hide" id="task" lay-filter="task"></table>
|
||||
</div>
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm" lay-event="add">+ 新建任务</button>
|
||||
</div>
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const moduleInit = ['tool','tablePlus','oaPicker'];
|
||||
function gouguInit() {
|
||||
var table = layui.tablePlus, form = layui.form, tool = layui.tool;
|
||||
|
||||
layui.taskTable = table.render({
|
||||
elem: '#task',
|
||||
title: '任务列表',
|
||||
toolbar: '#toolbarDemo',
|
||||
is_excel:true,
|
||||
cellMinWidth: 80,
|
||||
url: "/project/task/datalist", //数据接口
|
||||
height: 'full-114',
|
||||
cols: [[
|
||||
{field: 'id', title: '任务编号', width: 80, align: 'center', fixed: 'left', templet: function (d) {
|
||||
return 'T' + d.id;
|
||||
}}
|
||||
,{ field: 'status', title: '任务状态', align: 'center', width: 90, templet: function (d) {
|
||||
var html = '<span class="check-status-color-' + d.status + '">『' + d.status_name + '』</span>';
|
||||
return html;
|
||||
}
|
||||
}
|
||||
, { field: 'cate_name', title: '工作类型', width: 90, align: 'center'}
|
||||
,{field:'title',title: '任务主题', minWidth: 300,templet:function(d){
|
||||
var html = '<span class="layui-badge layui-bg-'+d.priority+'">'+d.priority_name+'</span> <a data-href="/project/task/view/id/'+d.id+'.html" class="side-a">'+d.title+'</a>';
|
||||
return html;
|
||||
}}
|
||||
,{field:'director_name',title: '负责人', align:'center',width: 80}
|
||||
,{field:'assist_admin_names',title: '协作人',width: 160}
|
||||
,{field:'plan_hours',title: '预估工时', align:'center',width: 80}
|
||||
,{field:'end_time',title: '预计结束日期', width: 150,templet:function(d){
|
||||
var html = d.end_time;
|
||||
if(d.delay>0){
|
||||
html+= '<span class="red ml-1" style="font-size:12px;">逾期'+d.delay+'天</span>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
,{field: 'right', title: '操作',fixed:'right', width:90, align:'center',templet:function(d){
|
||||
var html='<div class="layui-btn-group"><button class="layui-btn layui-btn-xs layui-btn-normal" lay-event="view">查看</button><button class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</button></div>';
|
||||
return html;
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
//触发事件
|
||||
table.on('toolbar(task)', function(obj){
|
||||
if(obj.event === 'add'){
|
||||
tool.side('/project/task/add');
|
||||
return;
|
||||
}
|
||||
});
|
||||
table.on('tool(task)', function(obj){
|
||||
if(obj.event === 'view'){
|
||||
tool.side('/project/task/view/id/'+obj.data.id);
|
||||
return;
|
||||
}
|
||||
if(obj.event === 'del'){
|
||||
layer.confirm('您确定要删除该任务?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.taskTable.reload();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/task/del", { id: obj.data.id }, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,234 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
{block name="style"}
|
||||
<style>
|
||||
.layui-unselect dl {max-height:188px;}
|
||||
</style>
|
||||
{/block}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<form class="layui-form gg-form-bar border-x border-t" lay-filter="barsearchform">
|
||||
<div class="layui-input-inline" style="width:180px;">
|
||||
<input type="text" class="layui-input tool-time" data-range="至" placeholder="选择时间区间" readonly name="range_time">
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:100px;">
|
||||
<input type="text" name="username" placeholder="请选择员工" class="layui-input picker-admin" readonly />
|
||||
<input type="text" name="uid" value="" style="display:none" />
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:300px;">
|
||||
<input type="text" name="keywords" placeholder="关键字,输入工作内容" class="layui-input"/>
|
||||
</div>
|
||||
<div class="layui-input-inline" style="width:150px;">
|
||||
<button class="layui-btn layui-btn-normal" lay-submit="" lay-filter="table-search"><i class="layui-icon layui-icon-search mr-1"></i>搜索</button>
|
||||
<button type="reset" class="layui-btn layui-btn-reset" lay-filter="table-reset">清空</button>
|
||||
</div>
|
||||
</form>
|
||||
<div>
|
||||
<table class="layui-hide" id="test" lay-filter="test"></table>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<h3>任务工时</h3>
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const is_leader = '{$is_leader}';
|
||||
const role_auth = '{$role_auth}';
|
||||
const hour_auth = '{$hour_auth}';
|
||||
const moduleInit = ['tool','tablePlus','oaPicker','oaSchedule'];
|
||||
function gouguInit() {
|
||||
var form = layui.form,table = layui.tablePlus,tool=layui.tool, work = layui.oaSchedule,laydate = layui.laydate;
|
||||
layui.scheduleTable = table.render({
|
||||
elem: '#test'
|
||||
,toolbar: '#toolbarDemo'
|
||||
,title:'工时列表'
|
||||
,url: "/project/task/hour"
|
||||
,cellMinWidth: 80
|
||||
,is_excel:true
|
||||
,height: 'full-114'
|
||||
,cols: [[ //表头
|
||||
{field: 'id', title: '序号',fixed: 'left', width:80, align:'center'}
|
||||
,{field: 'labor_type_string', title: '工作类型', align:'center',width:90,templet:function(d){
|
||||
var html='';
|
||||
if(d.labor_type==0){
|
||||
html='<span class="layui-color-'+d.labor_type+'">-</span>';
|
||||
}
|
||||
else if(d.labor_type == 1){
|
||||
html='<span class="layui-color-'+d.labor_type+'">案头工作</span>';
|
||||
}
|
||||
else if(d.labor_type == 2){
|
||||
html='<span class="layui-color-'+d.labor_type+'">外勤工作</span>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
,{field: 'work_cate', title: '工作类别', align:'center',width:80}
|
||||
,{field: 'start_time', title: '工作时间范围', align:'center',width:186,templet:function(d){
|
||||
var html=d.start_time+'至'+d.end_time;
|
||||
return html;
|
||||
}}
|
||||
,{field: 'name', title: '执行人', align:'center',width:80}
|
||||
,{field: 'labor_time', title: '工时', align:'center',width:80}
|
||||
,{field: 'title', title: '工作内容'}
|
||||
,{field: 'task', title: '关联任务', width:200}
|
||||
,{field: 'project', title: '关联项目', width:180}
|
||||
,{field: 'create_time', title: '记录时间', align:'center',width:150}
|
||||
,{field: 'right', title: '操作',fixed:'right', width:180, align:'center',templet:function(d){
|
||||
var html='<div class="layui-btn-group">';
|
||||
if(hour_auth==2 && d.admin_id==login_admin){
|
||||
//开放员工自己调整
|
||||
html+='<button class="layui-btn layui-btn-xs layui-bg-orange" lay-event="time">调整工时</button>';
|
||||
html+='<button class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</button>';
|
||||
}
|
||||
if(hour_auth==3 && is_leader > 0){
|
||||
//开放部门负责人调整
|
||||
html+='<button class="layui-btn layui-btn-xs layui-bg-orange" lay-event="time">调整工时</button>';
|
||||
html+='<button class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</button>';
|
||||
}
|
||||
if(hour_auth==4 && role_auth > 0){
|
||||
//开放日常办公数据管理员调整
|
||||
html+='<button class="layui-btn layui-btn-xs layui-bg-orange" lay-event="time">调整工时</button>';
|
||||
html+='<button class="layui-btn layui-btn-xs layui-btn-danger" lay-event="del">删除</button>';
|
||||
}
|
||||
if(d.admin_id==login_admin){
|
||||
html+='<button class="layui-btn layui-btn-xs" lay-event="edit">编辑</button>';
|
||||
}
|
||||
html+='<button class="layui-btn layui-btn-xs layui-btn-normal" lay-event="view">查看</button>';
|
||||
html+='</div>';
|
||||
return html;
|
||||
}}
|
||||
]]
|
||||
});
|
||||
//更改工时
|
||||
table.on('tool(test)', function(obj){
|
||||
var data = obj.data;
|
||||
if(obj.event === 'time'){
|
||||
var content='<form class="layui-form" style="width:568px">\
|
||||
<table class="layui-table" style="margin:15px 15px 0;">\
|
||||
<tr>\
|
||||
<td class="layui-td-gray-2">工作时间范围<font>*</font></td>\
|
||||
<td>\
|
||||
<input id="start_time_a" name="start_time_a" style="width:120px; display:inline-block;" autocomplete="off" class="layui-input" value="" readonly lay-verify="required" lay-reqText="请选择"><div style="display: inline-block; margin-left:5px; width: 80px;"><select lay-filter="start_time_b" id="start_time_b"></select></div> 至 <input id="end_time_a" name="end_time_a" style="width:120px; display:inline-block;" autocomplete="off" class="layui-input" value="" readonly lay-verify="required" lay-reqText="请选择"><div style="display: inline-block; margin-left:5px; width: 80px;"><select lay-filter="end_time_b" id="end_time_b"></select></div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</form>';
|
||||
layer.open({
|
||||
type:1,
|
||||
title:'调整工时',
|
||||
area:['600px','388px'],
|
||||
content:content,
|
||||
success:function(){
|
||||
//日期时间范围
|
||||
laydate.render({
|
||||
elem: '#start_time_a',
|
||||
type: 'date',
|
||||
max:0,
|
||||
format: 'yyyy-MM-dd',
|
||||
showBottom: false,
|
||||
done:function(a,b,c){
|
||||
$('#end_time_a').val(a);
|
||||
}
|
||||
});
|
||||
|
||||
//日期时间范围
|
||||
laydate.render({
|
||||
elem: '#end_time_a',
|
||||
type: 'date',
|
||||
max:0,
|
||||
format: 'yyyy-MM-dd',
|
||||
showBottom: false,
|
||||
done:function(a,b,c){
|
||||
$('#start_time_a').val(a);
|
||||
}
|
||||
});
|
||||
$('#start_time_b,#end_time_b').empty();
|
||||
|
||||
var hourArray=[];
|
||||
for(var h=0;h<24;h++){
|
||||
var t=h<10?'0'+h:h
|
||||
var t_1=t+':00',t_2=t+':15',t_3=t+':30',t_4=t+':45';
|
||||
hourArray.push(t_1,t_2,t_3,t_4);
|
||||
}
|
||||
|
||||
var html_1='', html_2='',def_h1='09:00',def_h2='09:30';
|
||||
for(var s=0;s<hourArray.length;s++){
|
||||
var check_1='',check_2='';
|
||||
if(hourArray[s]==def_h1){
|
||||
check_1='selected';
|
||||
}
|
||||
if(hourArray[s]==def_h2){
|
||||
check_2='selected';
|
||||
}
|
||||
html_1 += '<option value="'+hourArray[s]+'" '+check_1+'>'+hourArray[s]+'</option>';
|
||||
html_2 += '<option value="'+hourArray[s]+'" '+check_2+'>'+hourArray[s]+'</option>';
|
||||
}
|
||||
|
||||
$('#start_time_b').append(html_1);
|
||||
$('#end_time_b').append(html_2);
|
||||
form.render();
|
||||
|
||||
},
|
||||
btn: ['确定提交'],
|
||||
btnAlign: 'c',
|
||||
yes: function(idx){
|
||||
let start_time_a = $('#start_time_a').val();
|
||||
let end_time_a = $('#end_time_a').val();
|
||||
let start_time_b = $('#start_time_b').val();
|
||||
let end_time_b = $('#end_time_b').val();
|
||||
if(start_time_a=='' || end_time_a==''){
|
||||
layer.msg('请选择工作时间范围');
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
url: "/oa/api/update_schedule",
|
||||
type:'post',
|
||||
data:{
|
||||
id:data.id,
|
||||
admin_id:data.admin_id,
|
||||
start_time_a:start_time_a,
|
||||
end_time_a:end_time_a,
|
||||
start_time_b:start_time_b,
|
||||
end_time_b:end_time_b
|
||||
},
|
||||
success:function(e){
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
layer.close(idx);
|
||||
layui.scheduleTable.reload();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
else if(obj.event === 'edit'){
|
||||
work.add(0, obj.data);
|
||||
}
|
||||
else if(obj.event === 'view'){
|
||||
work.view(obj.data);
|
||||
}
|
||||
else if(obj.event === 'del'){
|
||||
layer.confirm('您确定要删除该工作记录?', {
|
||||
icon: 3,
|
||||
title: '提示'
|
||||
}, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.scheduleTable.reload();
|
||||
}
|
||||
}
|
||||
tool.delete("/oa/schedule/del", { id: obj.data.id }, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,255 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
{block name="style"}
|
||||
<style>
|
||||
.layui-tab-title .layui-this{background-color:#fff;}
|
||||
.layui-tab-card,.layui-card{box-shadow:0 0 0 0 rgb(0 0 0 / 10%); border-radius:0; border-top:none;}
|
||||
.layui-card-tips {color: #969696;}
|
||||
.layui-card-value {padding: 4px 0 16px;font-size: 18px;color: #1E9FFF;}
|
||||
|
||||
.content-content{line-height:1.6;}
|
||||
.content-content p{margin-bottom:6px;}
|
||||
.content-content img{max-width:100%; padding:8px; box-sizing: border-box;}
|
||||
|
||||
.log-item i{font-weight:800; color:#323232}
|
||||
.log-content strong{margin:0 4px; color:#323232}
|
||||
.layui-unselect dl {max-height:188px;}
|
||||
.layui-table td.table-content img{max-width:100%; height:auto;}
|
||||
</style>
|
||||
{/block}
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<h3 class="pb-3">任务详情</h3>
|
||||
<table class="layui-table layui-table-form" id="task">
|
||||
<tr>
|
||||
<td class="layui-td-gray">任务主题</td>
|
||||
<td colspan="3" class="click-edit" data-types="text" data-field="title">{$detail.title|default=''}</td>
|
||||
<td class="layui-td-gray">工作类型</td>
|
||||
<td class="click-edit" data-types="picker" data-field="work_id" data-type="1" data-picker="workcate">{$detail.cate_name|default='-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">负责人员</td>
|
||||
<td class="click-edit" data-types="adminpicker" data-field="director_uid" data-type="1" data-ids="{$detail.director_uid}" data-names="{$detail.director_name|default=''}">{$detail.director_name|default=''}</td>
|
||||
<td class="layui-td-gray">协作人</td>
|
||||
<td colspan="3" class="click-edit" data-types="adminpicker" data-field="assist_admin_ids" data-type="2" data-ids="{$detail.assist_admin_ids}" data-names="{$detail.assist_admin_names|default=''}">{$detail.assist_admin_names|default=''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">优先级</td>
|
||||
<td class="click-edit" data-types="dropdown" data-field="priority" data-array="priority" data-text="{$detail.priority}">{$detail.priority_name}</td>
|
||||
<td class="layui-td-gray">关联项目</td>
|
||||
<td colspan="3" class="click-edit" data-types="picker" data-field="project_id" data-type="1" data-picker="project">{$detail.project_name|default='-'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">完成进度</td>
|
||||
<td class="click-edit" data-types="num" data-field="done_ratio" data-text="{$detail.done_ratio}" data-min="0" data-max="100">{$detail.done_ratio|default='0'}%</td>
|
||||
<td class="layui-td-gray">估计结束日期</td>
|
||||
<td class="click-edit" data-types="oadate" data-field="end_time">{$detail.end_time|date='Y-m-d'}</span>{gt name="$detail.delay" value="0"}<span class="red">『逾期 {$detail.delay}天』</span>{/gt}</td>
|
||||
<td class="layui-td-gray-3">估计工作量(工时)</td>
|
||||
<td class="click-edit" data-types="num" data-field="plan_hours">{$detail.plan_hours|default=''}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">任务状态</td>
|
||||
<td class="click-edit" data-types="dropdown" data-field="status" data-array="status" data-text="{$detail.status}">{$detail.status_name}</td>
|
||||
<td class="layui-td-gray-2">实际完成日期</td>
|
||||
<td>{eq name="$detail.over_time" value="0"}-{else/}{$detail.over_time|date='Y-m-d'}{/eq}</td>
|
||||
<td class="layui-td-gray">实际工时</td>
|
||||
<td>{eq name="$detail.work_hours" value="0"}-{else/}{$detail.work_hours}{/eq}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="layui-td-gray">相关附件 <button type="button" class="layui-btn layui-btn-xs" id="uploadBtn">附件上传</button></td>
|
||||
<td colspan="5">
|
||||
<div class="layui-row" id="uploadBox">
|
||||
<input type="hidden" data-type="file" name="file_ids" value="{$detail.file_ids|default=''}">
|
||||
{notempty name="$file_array"}
|
||||
{volist name="$file_array" id="vo"}
|
||||
<div class="layui-col-md4" id="uploadFile{$vo.id}">{:file_card($vo)}</div>
|
||||
{/volist}
|
||||
{/notempty}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" class="click-edit" data-types="editor" data-field="content" data-target="content" style="background-color:#FAFAFA;"><strong>任务描述</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="6" id="content" class="table-content">{$detail.content|raw}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
<div class="layui-tab layui-tab-card" style="margin:0;" lay-filter="docDemoTabBrief">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">工作记录({$detail.schedules})</li>
|
||||
<li>员工评论(<span id="commentTotal">0</span>)</li>
|
||||
<li>操作日志(<span id="logListTotal">0</span>)</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content py-1 px-3" style="background-color:#fff;">
|
||||
<div class="layui-tab-item layui-show py-2">
|
||||
<table class="layui-hide" id="table_work" lay-filter="table_work"></table>
|
||||
</div>
|
||||
<div class="layui-tab-item comment-list">
|
||||
<div class="comment-input my-2">
|
||||
<input type="text" id="commentInput" readonly placeholder="发表一下你的看法" class="layui-input" value="">
|
||||
</div>
|
||||
<div id="commentBox"></div>
|
||||
</div>
|
||||
<div class="layui-tab-item logs-list">
|
||||
<div id="logList" class="log-timeline p-3"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<div>
|
||||
<div class="layui-input-inline" style="margin-right:12px;"><strong>工作日志</strong></div><div class="layui-input-inline"><button class="layui-btn layui-btn-xs" type="button" lay-event="add">+ 添加工作日志</button></div>
|
||||
</div>
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const admin_id = '{$detail.admin_id}';
|
||||
const detail_id = '{$detail.id}';
|
||||
const status_array = {:json_encode(get_task_status(1),JSON_UNESCAPED_UNICODE)};
|
||||
const priority_array = {:json_encode(get_priority(1),JSON_UNESCAPED_UNICODE)};
|
||||
const moduleInit = ['tool','oaPicker','oaEdit','oaSchedule','oaComment','uploadPlus'];
|
||||
function gouguInit() {
|
||||
const oaEdit = layui.oaEdit,work = layui.oaSchedule,comment = layui.oaComment, uploadPlus = layui.uploadPlus, tool = layui.tool, table = layui.table;
|
||||
|
||||
oaEdit.log('logList','Task',detail_id);
|
||||
|
||||
comment.init({
|
||||
"box":'commentBox',//容器id
|
||||
"input": 'commentInput',
|
||||
"topic_id":detail_id,
|
||||
"module": 'task',
|
||||
});
|
||||
|
||||
let edit_callback = function(e){
|
||||
layer.msg(e.msg);
|
||||
if(e.code==0){
|
||||
setTimeout(function(){
|
||||
location.reload();
|
||||
},1000)
|
||||
}
|
||||
}
|
||||
//附件上传
|
||||
var attachment = new uploadPlus({
|
||||
"target":'uploadBtn',
|
||||
"targetBox":'uploadBox',
|
||||
"attachment":{
|
||||
"type":1,//0ajax多文件模式,1ajax单文件单记录模式
|
||||
"uidDelete":true,//是否开启只有上传人自己才能删除自己的附件
|
||||
"ajaxSave":function(res){
|
||||
tool.post('/project/api/add_file',{'topic_id':detail_id,'file_id':res.data.id,'file_name': res.data.name, 'module': 'task'},edit_callback);
|
||||
},
|
||||
"ajaxDelete":function(file_id){
|
||||
tool.delete('/project/api/delete_file', {id: file_id}, edit_callback);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
//快捷编辑
|
||||
oaEdit.init({
|
||||
box:'task',
|
||||
id:detail_id,
|
||||
url: "/project/task/add",
|
||||
dropdown:{
|
||||
status:status_array,
|
||||
priority:priority_array
|
||||
}
|
||||
});
|
||||
|
||||
//工作记录相关
|
||||
layui.scheduleTable = table.render({
|
||||
elem: "#table_work"
|
||||
, toolbar: "#toolbarDemo"
|
||||
,url: "/oa/api/get_schedule"
|
||||
,page: true
|
||||
,limit: 20
|
||||
,where:{task_id:detail_id}
|
||||
,cellMinWidth: 80
|
||||
,cols: [[
|
||||
{field:'id',width:80, title: 'ID号', align:'center'}
|
||||
,{field:'title',title: '工作内容',minWidth:240}
|
||||
,{field: 'name', title: '所属人员', align:'center',width:80}
|
||||
,{field: 'start_time', title: '工作时间范围', align:'center',width:260,templet:function(d){
|
||||
var html=d.start_time+' 至 '+d.end_time;
|
||||
return html;
|
||||
}}
|
||||
,{field: 'labor_type_string', title: '工作类型', align:'center',width:80}
|
||||
,{field: 'labor_time', title: '工时', align:'center',width:80}
|
||||
,{field:'create_time', title: '创建时间',width:150,align:'center'}
|
||||
,{width:90,fixed:'right',title: '操作', align:'center',ignoreExport:true,templet: function(d){
|
||||
var html='';
|
||||
var btn1='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="view">详细</a>';
|
||||
if(d.admin_id !== login_admin){
|
||||
return btn1;
|
||||
}
|
||||
else{
|
||||
var btn2='<a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a>';
|
||||
html = '<div class="layui-btn-group">'+btn1+btn2+'</div>';
|
||||
return html;
|
||||
}
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
table.on('toolbar(table_work)',function (obj) {
|
||||
if (obj.event === 'add') {
|
||||
work.add(detail_id,{'id':0});
|
||||
}
|
||||
});
|
||||
table.on('tool(table_work)',function (obj) {
|
||||
var checkStatus = table.checkStatus(obj.config.id); //获取选中行状态
|
||||
var data = obj.data;
|
||||
if (obj.event === 'view') {
|
||||
work.view(data);
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'edit') {
|
||||
work.add(data.task_id,data);
|
||||
return;
|
||||
}
|
||||
if (obj.event === 'del') {
|
||||
layer.confirm('确定要删除该内容吗?', { icon: 3, title: '提示' }, function (index) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
obj.del();
|
||||
}
|
||||
}
|
||||
tool.delete("/project/task/del", { id: data.id }, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
//工作记录相关
|
||||
$('.add-schedule').on('click', function () {
|
||||
work.add(detail_id,{'id':0});
|
||||
})
|
||||
//回复
|
||||
$('#comment_task_' + detail_id).on('click', '[data-event="replay"]', function () {
|
||||
let pid = $(this).data('id');
|
||||
let to_uid = $(this).data('uid');
|
||||
let to_unames = $(this).data('unames');
|
||||
comment.textarea(0,detail_id,'task','',pid,to_uid,to_unames);
|
||||
})
|
||||
//编辑
|
||||
$('#comment_task_' + detail_id).on('click', '[data-event="edit"]', function () {
|
||||
let id = $(this).data('id');
|
||||
let content = $('#comment_' + id).data('content');
|
||||
comment.textarea(id, detail_id, 'task', content,0,0,'');
|
||||
})
|
||||
|
||||
//删除
|
||||
$('#comment_task_' + detail_id).on('click', '[data-event="del"]', function () {
|
||||
let id = $(this).data('id');
|
||||
comment.del(id, detail_id, 'task');
|
||||
})
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
@@ -0,0 +1,124 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
|
||||
<div class="p-page">
|
||||
<table class="layui-hide" id="table_work_cate" lay-filter="table_work_cate"></table>
|
||||
</div>
|
||||
|
||||
<script type="text/html" id="toolbarDemo">
|
||||
<div class="layui-btn-container">
|
||||
<button class="layui-btn layui-btn-sm add-new" type="button">+ 添加工作类型</button>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
|
||||
<!-- 脚本 -->
|
||||
{block name="script"}
|
||||
<script>
|
||||
const moduleInit = ['tool'];
|
||||
function gouguInit() {
|
||||
var table = layui.table, tool = layui.tool;
|
||||
|
||||
layui.pageTable = table.render({
|
||||
elem: "#table_work_cate"
|
||||
,toolbar: '#toolbarDemo'
|
||||
,url: "/project/work/datalist"
|
||||
,page: false
|
||||
,limit: 999
|
||||
,cellMinWidth: 80
|
||||
,cols: [[
|
||||
{field:'id',width:80, title: 'ID号', align:'center'}
|
||||
,{field:'title',title: '类型名称'}
|
||||
,{field:'status', title: '状态',width:80,align:'center',templet: function(d){
|
||||
var html1='<span class="green">正常</span>';
|
||||
var html2='<span class="yellow">禁用</span>';
|
||||
if(d.status==1){
|
||||
return html1;
|
||||
}
|
||||
else{
|
||||
return html2;
|
||||
}
|
||||
}}
|
||||
,{width:100,title: '操作', align:'center',ignoreExport:true,templet: function(d){
|
||||
var html='';
|
||||
var btn='<a class="layui-btn layui-btn-normal layui-btn-xs" lay-event="edit">编辑</a>';
|
||||
var btn1='<a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="disable">禁用</a>';
|
||||
var btn2='<a class="layui-btn layui-btn-xs" lay-event="open">启用</a>';
|
||||
if(d.status==1){
|
||||
html = '<div class="layui-btn-group">'+btn+btn1+'</div>';
|
||||
}
|
||||
else{
|
||||
html = '<div class="layui-btn-group">'+btn+btn2+'</div>';
|
||||
}
|
||||
return html;
|
||||
}}
|
||||
]]
|
||||
});
|
||||
|
||||
table.on('tool(table_work_cate)',function (obj) {
|
||||
if(obj.event === 'edit'){
|
||||
add_cate(obj.data.id,obj.data.title);
|
||||
}
|
||||
if(obj.event === 'disable'){
|
||||
layer.confirm('确定要禁用该记录吗?', {icon: 3, title:'提示'}, function(index){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/work/set", {id:obj.data.id,status: 0}, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
if(obj.event === 'open'){
|
||||
layer.confirm('确定要启用该记录吗?', {icon: 3, title:'提示'}, function(index){
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/work/set", {id:obj.data.id,status:1}, callback);
|
||||
layer.close(index);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$('body').on('click','.add-new',function(){
|
||||
add_cate(0,'');
|
||||
});
|
||||
|
||||
function add_cate(id,val){
|
||||
var title = '新增类型';
|
||||
if(id>0){
|
||||
title = '编辑类型';
|
||||
}
|
||||
layer.prompt({
|
||||
title: title,
|
||||
value: val,
|
||||
yes: function(index, layero) {
|
||||
// 获取文本框输入的值
|
||||
var value = layero.find(".layui-layer-input").val();
|
||||
if (value) {
|
||||
let callback = function (e) {
|
||||
layer.msg(e.msg);
|
||||
if (e.code == 0) {
|
||||
layui.pageTable.reload();
|
||||
}
|
||||
}
|
||||
tool.post("/project/work/add", {id: id,title: value}, callback);
|
||||
layer.close(index);
|
||||
} else {
|
||||
layer.msg('请填写类型名称');
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{/block}
|
||||
<!-- /脚本 -->
|
||||
@@ -0,0 +1,16 @@
|
||||
{extend name="../../base/view/common/base" /}
|
||||
<!-- 主体 -->
|
||||
{block name="body"}
|
||||
<div class="p-page">
|
||||
<h3 class="pb-3">工作类型详情</h3>
|
||||
<table class="layui-table layui-table-form">
|
||||
<tr>
|
||||
<td class="layui-td-gray">工作类型名称</td>
|
||||
<td>{$detail.title|default=''}"></td>
|
||||
<td class="layui-td-gray">排序</td>
|
||||
<td>{$detail.sort|default=0}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
{/block}
|
||||
<!-- /主体 -->
|
||||
Reference in New Issue
Block a user