创建版本

This commit is contained in:
2021-02-22 12:17:00 +08:00
commit af555f49c3
2332 changed files with 369202 additions and 0 deletions
@@ -0,0 +1,92 @@
<?php namespace Gdoo\Project\Controllers;
use Illuminate\Http\Request;
use DB;
use Validator;
use Auth;
use Session;
use Gdoo\User\Models\User;
use Gdoo\Project\Models\Project;
use Gdoo\Project\Models\Task;
use Gdoo\Project\Models\Log;
use Gdoo\Index\Controllers\DefaultController;
class CommentController extends DefaultController
{
public $permission = [];
// 添加评论
public function addAction(Request $request)
{
if ($request->method() == 'POST') {
$gets = $request->input();
if ($gets['content'] == '') {
return $this->json('评论内容必须填写。');
}
$gets['user'] = auth()->user()->name;
$gets['type'] = 'comment';
$log = new Log();
$log->fill($gets);
$log->save();
$log = Log::find($log->id);
$log->created_at = format_datetime($log->created_at);
return $this->json($log, true);
}
$task_id = $request->input('task_id');
return $this->render([
'task_id' => $task_id,
]);
}
// 编辑评论
public function editAction(Request $request)
{
if ($request->method() == 'POST') {
$gets = $request->input();
if ($gets['content'] == '') {
return $this->json('评论内容必须填写。');
}
$item = Log::find($gets['id']);
$item->fill($gets);
$item->save();
return $this->json('恭喜你,编辑评论成功。', true);
}
$id = $request->input('id');
$log = Log::find($id);
return $this->render([
'log' => $log,
]);
}
// 删除评论
public function deleteAction(Request $request)
{
if ($request->method() == 'POST') {
$id = $request->input('id');
$id = array_filter((array)$id);
if (empty($id)) {
return $this->json('请先选择数据。');
}
Log::whereIn('id', $id)->delete();
return $this->json('恭喜你,删除评论成功。', true);
}
}
}
@@ -0,0 +1,164 @@
<?php namespace Gdoo\Project\Controllers;
use Illuminate\Http\Request;
use DB;
use Validator;
use Auth;
use Gdoo\User\Models\User;
use Gdoo\Project\Models\Project;
use Gdoo\Project\Models\Task;
use Gdoo\Project\Models\Log;
use Gdoo\Index\Models\Attachment;
use Gdoo\Index\Models\Access;
use Gdoo\Index\Controllers\DefaultController;
use Gdoo\Index\Services\AttachmentService;
class ProjectController extends DefaultController
{
public $permission = [];
public function indexAction()
{
$search = search_form([
'referer' => 1,
'status' => 0
], [
['text', 'project.title', '名称'],
['text', 'project.user_id', '拥有者'],
]);
$query = $search['query'];
$model = Project::with(['tasks' => function ($q) {
$q->where('user_id', auth()->id())->whereRaw('isnull(progress, 0) < 1');
}])->where('status', $query['status'])
->orderBy('id', 'desc')
->select(['*']);
foreach ($search['where'] as $where) {
if ($where['active']) {
$model->search($where);
}
}
$auth_id = auth()->id();
// 不是全部权限
if ($this->access['index'] < 4) {
$sql = "(permission = 0
or (permission = 1
and (
exists (
select 1 from project_task
left join project_task_user on project_task.id = project_task_user.task_id
where project_task.project_id = project.id
and (project.user_id = ".$auth_id." or project_task.user_id = ".$auth_id." or project_task_user.user_id = ".$auth_id."))))
)";
$model->whereRaw($sql);
}
$rows = $model->paginate()->appends($query);
$tabs = [
'name' => 'status',
'items' => Project::$tabs
];
return $this->display([
'auth_id' => $auth_id,
'rows' => $rows,
'search' => $search,
'tabs' => $tabs,
]);
}
// 项目显示
public function showAction(Request $request)
{
return $this->display([]);
}
// 添加项目
public function addAction(Request $request)
{
if ($request->method() == 'POST') {
$gets = $request->input();
if ($gets['name'] == '') {
return $this->error('项目名称必须填写。');
}
if ($gets['user_id'] == '') {
return $this->error('项目拥有者填写。');
}
$task = new Project();
$task->fill($gets);
$task->save();
return $this->success('index', '恭喜你,添加项目成功。');
}
return $this->display([]);
}
// 编辑项目
public function editAction(Request $request)
{
if ($request->method() == 'POST') {
$gets = $request->input();
if ($gets['name'] == '') {
return $this->error('项目名称必须填写。');
}
if ($gets['user_id'] == '') {
return $this->error('项目拥有者填写。');
}
$task = Project::find($gets['id']);
$task->fill($gets);
$task->save();
return $this->success('index', '恭喜你,编辑项目成功。');
}
$id = $request->input('id');
$project = Project::find($id);
return $this->display([
'project' => $project,
]);
}
// 删除项目
public function deleteAction(Request $request)
{
$id = $request->input('id');
$id = array_filter((array)$id);
if (empty($id)) {
return $this->error('请先选择数据。');
}
$tasks = Task::whereIn('project_id', $id)->get();
foreach ($tasks as $task) {
$logs = Log::where('task_id', $task->id)->get();
foreach ($logs as $log) {
AttachmentService::remove($log->attachment);
$log->delete();
}
AttachmentService::remove($task->attachment);
$task->users()->sync([]);
$task->delete();
}
// 删除任务
Project::whereIn('id', $id)->delete();
return $this->success('index', '恭喜你,操作成功。');
}
}
@@ -0,0 +1,444 @@
<?php namespace Gdoo\Project\Controllers;
use Illuminate\Http\Request;
use DB;
use Validator;
use Auth;
use Session;
use Gdoo\User\Models\User;
use Gdoo\Project\Models\Project;
use Gdoo\Project\Models\Task;
use Gdoo\Project\Models\Item;
use Gdoo\Project\Models\Log;
use Gdoo\Index\Models\Attachment;
use Gdoo\Index\Controllers\DefaultController;
use Gdoo\Index\Services\AttachmentService;
use Illuminate\Support\Arr;
class TaskController extends DefaultController
{
public $permission = ['drag', 'sort'];
public function indexAction(Request $request)
{
$search = search_form([
'project_id' => '',
'tpl' => 'gantt',
'referer' => '',
], [
['text','project_task.name','任务名称'],
['text','project_task.user_id','执行者'],
]);
$query = $search['query'];
if ($request->ajax() && $request->wantsJson()) {
$tasks = $this->data($search);
$_tasks = array_nest($tasks, 'name');
$rows = [];
foreach($_tasks as $_task) {
$rows[] = $_task;
}
$json['data'] = $rows;
return response()->json($json);
}
if ($request->ajax()) {
$tasks = $this->data($search);
return response()->json(['data' => $tasks]);
}
$project = Project::find($query['project_id']);
// 生成权限
$user_id = auth()->id();
$permission = [
'add_item' => $project['user_id'] == $user_id,
'add_task' => $project['user_id'] == $user_id,
];
// 返回页面
$referer = session()->get('referer_'.$request->module().'_project_index');
return $this->display([
'project' => $project,
'search' => $search,
'query' => $query,
'referer' => $referer,
'permission' => $permission,
], 'index/'.$query['tpl']);
}
// 读取数据
public function data($search)
{
$query = $search['query'];
$user_id = auth()->id();
$_items = Task::where('project_id', $query['project_id'])
->leftJoin('project', 'project.id', '=', 'project_task.project_id')
->where('parent_id', 0)
->orderBy('project_task.sort', 'asc')
->orderBy('project_task.id', 'asc')
->get(['project_task.*', 'project.user_id as project_user_id'])->toArray();
$model = Task::with(['users' => function ($q) {
$q->select(['user.id','user.name as user_name']);
}]);
$model->where('project_task.project_id', $query['project_id'])
->leftJoin('project', 'project.id', '=', 'project_task.project_id')
->leftJoin('user', 'user.id', '=', 'project_task.user_id')
->where('parent_id', '>', 0);
foreach ($search['where'] as $where) {
if ($where['active']) {
$model->search($where);
}
}
$_tasks = $model->select(['project_task.*','user.name as user_name', 'project.user_id as project_user_id'])
->orderBy('project_task.sort', 'asc')
->orderBy('project_task.id', 'asc')
->get()->toArray();
foreach ($_items as $_item) {
$project_user_id = 0;
if ($_item['project_user_id'] == $user_id) {
$project_user_id = 1;
}
$tasks[] = [
'start_date' => '',
'parent_id' => 0,
'parent' => 0,
'duration' => '',
'loaded' => true,
'expanded' => true,
'id' => $_item['id'],
'name' => $_item['name'],
'type' => $_item['type'],
'created_at' => '',
'user_id' => '',
'user_name' => '',
'open' => true,
'option_edit' => $project_user_id,
'option_delete' => $project_user_id,
'dhm' => '',
];
}
foreach ($_tasks as $_task) {
$project_user_id = $task_user_id = 0;
if ($_task['user_id'] == $user_id) {
$task_user_id = 1;
}
// 显示保存按钮
if ($_task['project_user_id'] == $user_id) {
$task_user_id = $project_user_id = 1;
}
$_task['option_edit'] = $task_user_id;
$_task['option_delete'] = $project_user_id;
$_task['start_date'] = date('Y-m-d', $_task['start_at']);
$_task['name'] = $_task['name'];
$_task['parent'] = $_task['parent_id'];
$_task['users'] = join(',', Arr::pluck($_task['users'], 'user_name'));
$_task['open'] = true;
$_task['loaded'] = true;
$_task['expanded'] = true;
$_task['created_at'] = format_datetime($_item['created_at']);
if ($_task['start_at'] && $_task['end_at']) {
$remain = remain_time($_task['start_at'], $_task['end_at'], '');
$str = '';
if ($remain->d) {
$str .= $remain->d.'天';
}
if ($remain->h) {
$str .= $remain->h.'小时';
}
if ($remain->i) {
$str .= $remain->i.'分钟';
}
$_task['duration_date'] = $str;
}
$_task['duration'] = ($_task['end_at'] - $_task['start_at']) / 86400;
$_task['duration'] = $_task['duration'] > 0 ? $_task['duration'] : 1;
$tasks[] = $_task;
}
return $tasks;
}
// 显示任务
public function showAction(Request $request)
{
$search = search_form([
'project_id' => ''
], [
['text','project.title','任务名称'],
['text','project.created_at','执行者'],
]);
$project_id = $request->input('project_id');
$project = Project::find($project_id);
return $this->render([
'project' => $project,
'search' => $search,
]);
}
// 移动任务
public function dragAction(Request $request)
{
$gets = $request->input();
$task = Task::find($gets['id']);
$task->start_at = strtotime($gets['start_date']);
$task->end_at = strtotime($gets['end_date']);
$task->progress = $gets['progress'];
$task->save();
return $this->json('恭喜您,任务移动成功。', true);
}
// 移动任务
public function sortAction(Request $request)
{
$gets = $request->input();
$task = Task::find($gets['id']);
$task->parent_id = $gets['parent_id'];
$task->save();
$i = 0;
foreach ($gets['sort'] as $id) {
$task = Task::find($id);
$task->sort = $i;
$task->save();
$i++;
}
return $this->json('恭喜您,任务移动成功。', true);
}
// 添加任务
public function addAction(Request $request)
{
if ($request->method() == 'POST') {
$gets = $request->input();
if ($gets['name'] == '') {
return $this->json('名称必须填写。');
}
if ($gets['start_at'] == '') {
$gets['start_at'] = time();
}
$attachment = $gets['attachment'];
$gets['attachment'] = join(',', (array)$attachment);
$gets['start_at'] = strtotime($gets['start_at']);
$gets['end_at'] = strtotime($gets['end_at']);
$gets['user_id'] = $gets[$gets['type'].'_user_id'];
$task = new Task();
$task->fill($gets);
$task->save();
// 更新关系表
$task->syncUsers($gets);
// 附件发布
AttachmentService::publish($attachment);
if ($gets['is_item'] == '0') {
$task = Task::find($task->id);
$task->created_at = format_datetime($task->created_at);
$task->user_name = get_user($task->user_id, 'name', false);
return $this->json($task, true);
} else {
return $this->json('恭喜你,添加任务成功。', true);
}
}
$project_id = $request->input('project_id');
$parent_id = $request->input('parent_id');
$type = $request->input('type');
$items = Task::where('project_id', $project_id)
->where('parent_id', 0)
->orderBy('id', 'desc')
->get();
$tpl = $type == 'item' ? 'item/add' : 'add';
return $this->render([
'items' => $items,
'project_id' => $project_id,
'parent_id' => $parent_id,
'type' => $type,
], $tpl);
}
// 编辑任务
public function editAction(Request $request)
{
if ($request->method() == 'POST') {
$gets = $request->input();
if ($gets['name'] == '') {
return $this->json('名称必须填写。');
}
$gets['progress'] = (int)$gets['progress'];
$attachment = $gets['attachment'];
$gets['attachment'] = join(',', (array)$attachment);
$gets['start_at'] = strtotime($gets['start_at']);
$gets['end_at'] = strtotime($gets['end_at']);
$gets['user_id'] = $gets[$gets['type'].'_user_id'];
$task = Task::find($gets['id']);
$task->fill($gets);
$task->save();
// 更新关系表
$task->syncUsers($gets);
// 附件发布
AttachmentService::publish($attachment);
return $this->json('恭喜你,编辑任务成功。', true);
}
$id = $request->input('id');
$type = $request->input('type');
$task = Task::find($id);
$task->users = $task->users()->pluck('user_id')->implode(',');
$project = Project::find($task->project_id);
$tasks = Task::where('project_task.parent_id', $task->id)
->leftJoin('user', 'user.id', '=', 'project_task.user_id')
->orderBy('project_task.id', 'desc')
->get(['project_task.*', 'user.avatar']);
$items = Task::where('project_id', $task->project_id)
->where('parent_id', 0)
->orderBy('id', 'desc')
->get();
$logs = Log::where('project_task_log.task_id', $id)
->leftJoin('user', 'user.id', '=', 'project_task_log.created_id')
->orderBy('project_task_log.id', 'desc')
->get(['project_task_log.*', 'user.avatar']);
$auth_id = auth()->id();
$permission = [
'name' => 0,
'status' => 0,
'parent_id' => 0,
'date' => 0,
'user_id' => 0,
'users' => 0,
'remark' => 0,
'attachment' => 0,
'add-subtask' => 0,
'add-comment' => 0,
];
if ($project['user_id'] == $auth_id) {
$permission = [
'name' => 1,
'status' => 1,
'parent_id' => 1,
'date' => 1,
'user_id' => 1,
'users' => 1,
'remark' => 1,
'attachment' => 1,
'add-subtask' => 1,
'add-comment' => 1,
];
} elseif ($task['user_id'] == $auth_id) {
$permission = [
'name' => 1,
'status' => 1,
'parent_id' => 0,
'date' => 0,
'user_id' => 0,
'users' => 1,
'remark' => 1,
'attachment' => 1,
'add-subtask' => 0,
'add-comment' => 1,
];
} elseif (in_array($auth_id, (array)$task->users)) {
$permission = [
'name' => 0,
'status' => 0,
'parent_id' => 0,
'date' => 0,
'user_id' => 0,
'users' => 0,
'remark' => 0,
'attachment' => 0,
'add-subtask' => 0,
'add-comment' => 1,
];
}
$tpl = $type == 'item' ? 'item/edit' : 'edit';
return $this->render([
'task' => $task,
'logs' => $logs,
'items' => $items,
'tasks' => $tasks,
'type' => $type,
'permission' => $permission,
], $tpl);
}
// 删除任务
public function deleteAction(Request $request)
{
if ($request->method() == 'POST') {
$id = $request->input('id');
$id = array_filter((array)$id);
if (empty($id)) {
return $this->json('请先选择数据。');
}
$tasks = Task::whereIn('id', $id)->get();
foreach ($tasks as $task) {
$logs = Log::where('task_id', $task->id)->get();
foreach ($logs as $log) {
AttachmentService::remove($log->attachment);
$log->delete();
}
AttachmentService::remove($task->attachment);
$task->users()->sync([]);
$task->delete();
}
return $this->json('恭喜你,删除任务成功。', true);
}
}
}
@@ -0,0 +1,45 @@
<?php namespace Gdoo\Project\Controllers;
use DB;
use Auth;
use Request;
use Gdoo\Index\Controllers\DefaultController;
use Gdoo\Index\Services\InfoService;
class WidgetController extends DefaultController
{
public $permission = ['info'];
/**
* 项目任务信息
*/
public function infoAction()
{
$config = InfoService::getInfo('project_task');
$count = DB::table('project_task')
->where('user_id', Auth::id())
->whereRaw('isnull(progress, 0) < 1')
->whereRaw('('.$config['sql'].')')
->count();
$count2 = DB::table('project_task')
->where('user_id', Auth::id())
->whereRaw('isnull(progress, 0) < 1')
->whereRaw('('.$config['sql2'].')')
->count();
$rate = 0;
if ($count2 > 0) {
$rate = $count / $count2 * 100;
}
$res = [
'count' => $count,
'count2' => $count2,
'rate' => $rate,
];
return $this->render([
'dates' => $config['dates'],
'info' => $config['info'],
'res' => $res,
]);
}
}
+8
View File
@@ -0,0 +1,8 @@
<?php namespace Gdoo\Project\Models;
use Gdoo\Index\Models\BaseModel;
class Log extends BaseModel
{
protected $table = 'project_task_log';
}
+18
View File
@@ -0,0 +1,18 @@
<?php namespace Gdoo\Project\Models;
use Gdoo\Index\Models\BaseModel;
class Project extends BaseModel
{
protected $table = 'project';
public static $tabs = [
['id' => 0, 'name' => '进行中', 'color' => 'info'],
['id' => 1, 'name' => '已结束', 'color' => 'success'],
];
public function tasks()
{
return $this->hasMany('Gdoo\Project\Models\Task');
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php namespace Gdoo\Project\Models;
use Gdoo\Index\Models\BaseModel;
class Task extends BaseModel
{
protected $table = 'project_task';
public function project()
{
return $this->belongsTo('Gdoo\Project\Models\Project');
}
public function users()
{
return $this->belongsToMany('Gdoo\User\Models\User', 'project_task_user', 'task_id', 'user_id');
}
public function syncUsers($gets)
{
$users = $gets[$gets['type'].'_users'];
$users = $users == '' ? [] : explode(',', $users);
$this->users()->sync($users);
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php namespace Gdoo\Project\Services;
use DB;
use Auth;
class TaskService
{
/**
* 获取待办任务
*/
public static function getBadge()
{
$rows = DB::table('project_task')
->where('user_id', Auth::id())
->whereRaw('isnull(progress, 0) < 1')
->get();
$ret['total'] = sizeof($rows);
$ret['data'] = $rows;
return $ret;
}
}
+78
View File
@@ -0,0 +1,78 @@
<?php
return [
"name" => "项目管理",
"version" => "1.0",
"description" => "项目管理。",
'widgets' => [
'info_project_task' => [
'name' => '项目任务',
'type' => 2,
'url' => 'project/widget/info',
'more_url' => 'project/project/index',
],
],
'badges' => [
'project_project_index' => 'Gdoo\Project\Services\TaskService::getBadge',
],
'menus' => [
['name' => '工作', 'id' => 'work'],
['name' => '项目管理', 'id' => 'project_project', 'parent' => 'work'],
['name' => '项目列表', 'id' => 'project_project_index', 'parent' => 'project_project', 'url' => 'project/project/index'],
],
"controllers" => [
"project" => [
"name" => "项目",
"actions" => [
"index" => [
"name" => "列表"
],
"add" => [
"name" => "添加",
],
"show" => [
"name" => "显示"
],
"edit" => [
"name" => "编辑",
],
"delete" => [
"name" => "删除",
]
]
],
"task" => [
"name" => "任务",
"actions" => [
"index" => [
"name" => "列表"
],
"add" => [
"name" => "添加"
],
"edit" => [
"name" => "编辑"
],
"show" => [
"name" => "显示"
],
"delete" => [
"name" => "删除"
]
]
],
"comment" => [
"name" => "评论",
"actions" => [
"add" => [
"name" => "添加"
],
"edit" => [
"name" => "编辑"
],
"delete" => [
"name" => "删除"
]
]
]
]
];
@@ -0,0 +1,29 @@
<style>
.modal-body { overflow:hidden; }
</style>
<form method="post" action="{{url()}}" id="comment-form" name="comment-form">
<div class="panel m-b-none">
<table class="table table-form m-b-none">
<tr>
<td>
<textarea class="form-control" type="text" name="content" id="content"></textarea>
</td>
</tr>
<tr>
<td align="left">
{{attachment_uploader('comment_attachment', $comment['attachment'], 'project_task_log')}}
</td>
</tr>
</table>
</div>
</div>
<input type="hidden" name="task_id" value="{{$task_id}}">
</form>
@@ -0,0 +1,29 @@
<style>
.modal-body { overflow:hidden; }
</style>
<form method="post" action="{{url()}}" id="comment-form" name="comment-form">
<div class="panel m-b-none">
<table class="table table-form m-b-none">
<tr>
<td>
<textarea class="form-control" type="text" name="content" id="content"></textarea>
</td>
</tr>
<tr>
<td align="left">
{{attachment_uploader('comment_attachment', $comment['attachment'], 'project_task_log')}}
</td>
</tr>
</table>
</div>
</div>
<input type="hidden" name="id" value="{{$comment->id}}">
</form>
@@ -0,0 +1,48 @@
<form method="post" action="{{url()}}" id="myform" name="myform">
<div class="panel">
<div class="table-responsive">
<table class="table table-form m-b-none">
<tr>
<td align="right" width="10%">项目名称</td>
<td align="left">
<input type="text" name="name" id="name" class="form-control input-sm">
</td>
</tr>
<tr>
<td align="right">项目权限</td>
<td align="left">
<select class="form-control input-sm" name="permission">
<option value="0">公开</option>
<option value="1">私有</option>
</select>
</td>
</tr>
<tr>
<td align="right">项目拥有者</td>
<td align="left">
{{App\Support\Dialog::user('user','user_id', '', 0, 0)}}
</td>
</tr>
<tr>
<td align="right">项目描述</td>
<td align="left">
<textarea name="description" id="description" class="form-control input-sm"></textarea>
</td>
</tr>
<tr>
<td align="left" colspan="2">
<button type="button" onclick="history.back();" class="btn btn-default">返回</button>
<button type="submit" class="btn btn-success btn-large"><i class="fa fa-check-circle"></i> 提交</button>
</td>
</tr>
</table>
</div>
</div>
</form>
@@ -0,0 +1,49 @@
<form method="post" action="{{url()}}" id="myform" name="myform">
<div class="panel">
<div class="table-responsive">
<table class="table table-form m-b-none">
<tr>
<td align="right" width="10%">项目名称</td>
<td align="left">
<input type="text" name="name" id="name" value="{{$project['name']}}" class="form-control input-sm">
</td>
</tr>
<tr>
<td align="right">项目权限 <a href="javascript:;" class="fa fa-question-circle hinted" title="公开:所有人可以访问,成员编辑。私有:成员访问和编辑。"></a></td>
<td align="left">
<select class="form-control input-sm" name="permission">
<option value="0" @if($project['permission'] == '0') selected="selected" @endif>公开</option>
<option value="1" @if($project['permission'] == '1') selected="selected" @endif>私有</option>
</select>
</td>
</tr>
<tr>
<td align="right">项目拥有者</td>
<td align="left">
{{App\Support\Dialog::user('user','user_id', $project['user_id'], 0, 0)}}
</td>
</tr>
<tr>
<td align="right">项目描述</td>
<td align="left">
<textarea name="description" id="description" class="form-control input-sm">{{$project['description']}}</textarea>
</td>
</tr>
<tr>
<td align="left" colspan="2">
<input type="hidden" name="id" value="{{$project['id']}}">
<button type="button" onclick="history.back();" class="btn btn-default">返回</button>
<button type="submit" class="btn btn-success btn-large"><i class="fa fa-check-circle"></i> 提交</button>
</td>
</tr>
</table>
</div>
</div>
</form>
@@ -0,0 +1,56 @@
<div class="panel">
<div class="wrapper-sm">
@include('project/query')
</div>
<div class="padder b-t">
<div class="row m-t">
@if($rows)
@foreach($rows as $row)
<div class="col-xs-12 col-sm-4 col-md-3">
<div class="thumbnail" style="{{$upload_url}}/{{$row->image}}">
<div class="caption">
<h4 class="m-t-none">
<span class="pull-right text-muted text-xs hinted" title="项目拥有者">{{get_user($row->user_id, 'name', false)}}</span>
@if($row->tasks->count())
<span class="text-base badge bg-danger">{{$row->tasks->count()}}</span>
@endif
<a class="m-t-sm" href="{{url('task/index', ['project_id' => $row->id])}}">
{{$row->name}}
</a>
</h4>
<div class="text-muted">
<span class="pull-right">
<div class="btn-group">
@if(isset($access['edit']) && ($auth_id == $row['created_id'] || $auth_id == $row['user_id']))
<a class="btn btn-xs btn-default hinted" title="编辑项目" href="{{url('edit',['id'=>$row->id])}}"><i class="fa fa-pencil"></i></a>
@endif
@if(isset($access['delete']) && ($auth_id == $row['created_id'] || $auth_id == $row['user_id']))
<a class="btn btn-xs btn-default hinted" title="删除项目" onclick="app.confirm('{{url('delete',['id'=>$row->id])}}','确定要删除吗?');" href="javascript:;"><i class="fa fa-remove"></i></a>
@endif
</div>
</span>
<span class="hinted" title="创建时间">@datetime($row->created_at)</span>
</div>
</div>
</div>
</div>
@endforeach
@endif
</div>
</div>
<div class="panel-footer">
<div class="row">
<div class="col-sm-1 hidden-xs">
</div>
<div class="col-sm-11 text-right text-center-xs">
{{$rows->render()}}
</div>
</div>
</div>
</div>
@@ -0,0 +1,20 @@
<form id="search-form" class="form-inline" name="mysearch" action="{{url()}}" method="get">
@if(isset($access['add']))
<a href="{{url('add')}}" class="btn btn-sm btn-info"><i class="fa fa-plus"></i> 添加项目</a>
@endif
@include('searchForm')
</form>
<script type="text/javascript">
$(function() {
$('#search-form').searchForm({
data: {{json_encode($search['forms'])}},
init:function(e) {
var self = this;
}
});
});
</script>
+84
View File
@@ -0,0 +1,84 @@
<style>
.modal-body { overflow:hidden; }
</style>
<form method="post" action="{{url()}}" id="task-form" name="task-form">
<input type="hidden" name="type" value="{{$type}}">
@if($type == 'subtask')
<input type="hidden" name="parent_id" value="{{$parent_id}}">
@endif
<input type="hidden" name="project_id" value="{{$project_id}}">
<input type="hidden" name="is_item" value="0">
<div class="panel m-b-none">
<table class="table table-form m-b-none">
<tr>
<td align="right" width="10%">名称</td>
<td align="left">
<input type="text" name="name" value="{{$task['name']}}" class="form-control input-sm">
</td>
</tr>
@if($type == 'task')
<tr>
<td align="right">任务列表</td>
<td align="left">
<select class="form-control input-sm" name="parent_id">
<option value="0"> - </option>
@if($items)
@foreach($items as $item)
<option value="{{$item['id']}}" @if($item['id'] == $task['item_id']) selected="selected" @endif>{{$item['name']}}</option>
@endforeach
@endif
</select>
</td>
</tr>
@endif
<tr>
<td align="right">执行者</td>
<td align="left">
{{App\Support\Dialog::user('user', $type.'_user_id', '', 0, 0)}}
</td>
</tr>
<tr>
<td align="right">参与者</td>
<td align="left">
{{App\Support\Dialog::user('user', $type.'_users', '', 1, 0)}}
</td>
</tr>
<tr>
<td align="right">时间</td>
<td align="left">
<input type="text" name="start_at" autocomplete="off" data-toggle="datetime" value="@datetime($task->start_at,time())" class="form-control input-sm input-inline">
-
<input type="text" name="end_at" autocomplete="off" data-toggle="datetime" value="" class="form-control input-sm input-inline">
</td>
</tr>
<tr>
<td align="right">备注</td>
<td>
<textarea class="form-control" type="text" name="remark"></textarea>
</td>
</tr>
<tr>
<td align="right">附件</td>
<td align="left">
{{attachment_uploader('attachment', '', 'project_task')}}
</td>
</tr>
</table>
</div>
</div>
</form>
+234
View File
@@ -0,0 +1,234 @@
<style>
.modal-body {
overflow: hidden;
}
.wrapper-sm {
background-color: #f0f3f4;
}
</style>
<div class="wrapper-sm">
<form method="post" class="project-form" action="{{url()}}" id="task-form-{{$task['id']}}" name="task-form-{{$task['id']}}">
<input type="hidden" name="type" value="{{$type}}">
<input type="hidden" name="project_id" value="{{$task->project_id}}">
<input type="hidden" name="id" value="{{$task->id}}">
<input type="hidden" name="is_item" value="0">
<div class="panel b-a">
<table class="table table-form m-b-none">
<tr>
<td align="right" width="10%">名称</td>
<td align="left">
@if($permission['name'])
<div class="input-group">
<div class="input-group-check">
<label class="i-checks i-checks-lg m-b-none hinted" title="点击完成任务">
<input class="select-row" name="progress" type="checkbox" @if($task['progress']==1) checked="checked" @endif value="1"><i></i>
</label>
</div>
<input type="text" name="name" value="{{$task['name']}}" class="form-control input-sm">
</div>
@else
@if($task['progress'] == 1)
<span class="label label-success">完成</span>
@else
<span class="label label-info">执行中</span>
@endif
<input type="hidden" name="progress" value="{{$task['progress']}}">
<input type="hidden" name="name" value="{{$task['name']}}">
{{$task['name']}}
@endif
</td>
</tr>
@if($type == 'task')
<tr>
<td align="right">任务列表</td>
<td align="left">
@if($items)
@if($permission['parent_id'])
<select class="form-control input-sm" name="parent_id">
@foreach($items as $item)
<option value="{{$item['id']}}" @if($item['id']==$task['parent_id']) selected="selected" @endif>{{$item['name']}}</option>
@endforeach
</select>
@else
<input type="hidden" name="parent_id" value="{{$task['parent_id']}}">
@foreach($items as $item)
@if($item['id'] == $task['parent_id']) {{$item['name']}} @endif
@endforeach
@endif
@endif
</td>
</tr>
@endif
<tr>
<td align="right">执行者</td>
<td align="left">
@if($permission['user_id'])
{{App\Support\Dialog::user('user', $type.'_user_id', $task['user_id'], 0, 0)}}
@else
<input type="hidden" name="{{$type}}_user_id" value="{{$task['user_id']}}">
{{App\Support\Dialog::text('user', $task['user_id'])}}
@endif
</td>
</tr>
<tr>
<td align="right">参与者</td>
<td align="left">
@if($permission['users'])
{{App\Support\Dialog::user('user', $type.'_users', $task['users'], 1, 0)}}
@else
<input type="hidden" name="{{$type}}_users" value="{{$task['users']}}">
{{App\Support\Dialog::text('user', $task['users'])}}
@endif
</td>
</tr>
<tr>
<td align="right">时间</td>
<td align="left">
@if($permission['date'])
<input type="text" name="start_at" data-toggle="datetime" value="@datetime($task->start_at,time())" class="form-control input-sm input-inline">
-
<input type="text" name="end_at" data-toggle="datetime" value="@datetime($task->end_at)" class="form-control input-sm input-inline">
@else
<input type="hidden" name="start_at" value="@datetime($task->start_at)">
<input type="hidden" name="end_at" value="@datetime($task->end_at)">
@datetime($task->start_at)
-
@datetime($task->end_at)
@endif
</td>
</tr>
<tr>
<td align="right">备注</td>
<td>
@if($permission['remark'])
<textarea class="form-control" type="text" name="remark">{{$task->remark}}</textarea>
@else
{{$task->remark}}
@endif
</td>
</tr>
<tr>
<td align="right">附件</td>
<td align="left">
@if($permission['attachment'])
{{attachment_uploader('attachment', $task['attachment'], 'project_task')}}
@else
{{attachment_show('attachment', $task['attachment'], 'project_task')}}
@endif
</td>
</tr>
</table>
</div>
<div class="task-subtask" id="task-subtask-{{$task->id}}">
<div class="panel b-a">
<div class="panel-heading b-b b-light">
<span class="font-bold">子任务 <span class="label bg-light">{{count($tasks)}}</span></span>
@if($permission['add-subtask'] == 1)
<a href="javascript:addSubTask({{$task->id}});" class="option option-add"><i class="fa fa-fw fa-plus"></i>添加子任务</a>
@endif
</div>
<ul class="list-group list-group-lg no-bg auto">
@if($tasks)
@foreach($tasks as $v)
<li class="list-group-item clearfix">
<span class="pull-left thumb-sm avatar m-r">
<img src="{{avatar($v['avatar'])}}">
</span>
<span class="clear">
<span>
<span class="pull-right text-muted">@datetime($v->created_at)</span>
{{$v['created_by']}}
</span>
<small class="text-muted clear text-ellipsis">
@if($v->progress == 1)
<span class="label label-success">完成</span>
@else
@if(auth()->id() == $v->user_id)
<span class="label label-danger">执行中</span>
@else
<span class="label label-info">执行中</span>
@endif
@endif
<a href="javascript:editSubTask({{$v->id}});">{{$v->name}}</a>
</small>
</span>
</li>
@endforeach
@endif
</ul>
</div>
</div>
<div class="task-log" id="task-log-{{$task->id}}">
<div class="panel b-a m-b-none">
<div class="panel-heading b-b b-light">
<span class="font-bold">评论列表 <span class="label bg-light">{{count($tasks)}}</span></span>
@if($permission['add-comment'] == 1)
<a href="javascript:addComment({{$task->id}});" class="option option-add"><i class="fa fa-fw fa-plus"></i>添加回复</a>
@endif
</div>
<div class="panel-body">
@if($logs)
@foreach($logs as $log)
@if($log->type == 'comment')
<div class="m-l-lg">
<a class="pull-left thumb-sm avatar m-l-n-md">
<img src="{{avatar($log->avatar)}}" alt="{{$log->created_by}}">
</a>
<div class="m-l-lg panel b-a">
<div class="panel-heading pos-rlt b-b b-light">
<span class="arrow left"></span>
<span>{{$log->created_by}}</span>
<span class="text-muted m-l-sm pull-right">
<i class="fa fa-clock-o"></i> @datetime($log->created_at)
</span>
</div>
<div class="panel-body">
<div>{{$log->content}}</div>
</div>
</div>
</div>
@else
<p class="task-log-content"><span class="time">@datetime($log->created_at)</span>{{$log->user}} {{$log->content}}</p>
@endif
@endforeach
@endif
</div>
</div>
</div>
</div>
</div>
</form>
@@ -0,0 +1,355 @@
<script src="{{$asset_url}}/vendor/dhtmlxgantt/dhtmlxgantt.js" type="text/javascript"></script>
<script src="{{$asset_url}}/vendor/dhtmlxgantt/dhtmlxgantt_marker.js" type="text/javascript"></script>
<script src="{{$asset_url}}/vendor/dhtmlxgantt/dhtmlxgantt_tooltip.js" type="text/javascript"></script>
<script src="{{$asset_url}}/vendor/dhtmlxgantt/locale_cn.js" type="text/javascript"></script>
<link rel="stylesheet" href="{{$asset_url}}/vendor/dhtmlxgantt/dhtmlxgantt.css" type="text/css">
<!--
<script src="https://export.dhtmlx.com/gantt/api.js"></script>
-->
<style type="text/css">
/* 新样式 */
html, body {
overflow: hidden;
}
.gantt_side_content.gantt_right {
padding-left: 10px;
}
.gantt_task_line.gantt_selected {
box-shadow: 0 0 5px #fff;
}
.gantt_container {
border: 1px solid #eee;
border-top: 1px solid #cecece;
}
.project-item {
position: absolute;
height: 8px;
color: #fff;
background-color: #57b4f6;
}
.project-item div {
position: absolute;
}
.project-left, .project-right {
top: 8px;
background-color: transparent;
border-style: solid;
width: 0px;
height: 0px;
}
.project-left {
left: 0px;
border-width: 0px 0px 8px 7px;
border-top-color: transparent;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
border-left-color: #3399ff !important;
}
.project-right {
right: 0px;
border-width: 0px 7px 8px 0px;
border-top-color: transparent;
border-right-color: #3399ff;
border-bottom-color: transparent !important;
border-left-color: transparent;
}
.gantt_task_line {
background-color: #3399ff;
border-width: 0;
border-radius: 0;
}
.gantt_task_line.done {
background-color: #66cc33;
}
.gantt_task_line .gantt_task_progress {
background-color: #197de1;
border-width: 0;
opacity: 0;
}
.gantt_grid_data .gantt_cell {
border-right: 1px solid #ECECEC;
}
.gantt_grid_data .gantt_cell.gantt_last_cell {
border-right: none;
}
.gantt_task .gantt_task_scale .gantt_scale_cell, .gantt_grid_scale .gantt_grid_head_cell{
color:#5C5C5C;
}
.gantt_row, .gantt_cell {
border-color:#cecece;
}
.gantt_grid_scale .gantt_grid_head_cell {
border-right: 1px solid #cecece !important;
}
.gantt_grid_scale .gantt_grid_head_cell.gantt_last_cell {
border-right: none !important;
}
.gantt_tooltip {
background-color: #383838;
color: #fff;
border-radius: 4px;
box-shadow: 0 2px 2px rgba(56, 56, 56, 0.25);
word-break: break-all;
white-space: pre-line;
}
</style>
<div class="panel">
<div class="wrapper-sm b-b">
<span class="text-md">{{$project['name']}}</span> <span class="text-muted">{{$project['description']}}</span>
</div>
<div class="wrapper-xs" id="gantt-wrapper">
<form id="search-task-form" class="form-inline" name="mytasksearch" method="get">
<div class="pull-right">
<div class="btn-group">
<a href="{{url('index', ['project_id' => $project['id'], 'tpl' => 'index'])}}" class="btn btn-sm btn-default @if($query['tpl'] == 'index') active @endif">列表</a>
<a href="{{url('index', ['project_id' => $project['id'], 'tpl' => 'gantt'])}}" class="btn btn-sm btn-default @if($query['tpl'] == 'gantt') active @endif">甘特图</a>
<!--
<a href="{{url('index', ['project_id' => $project['id'], 'tpl' => 'board'])}}" class="btn btn-sm btn-default @if($query['tpl'] == 'board') active @endif">看板</a>
-->
</div>
<!--
<input value="导出PDF" class="btn btn-sm btn-default" type="button" onclick='exportToPDF()'>
-->
</div>
<a href="{{url($referer)}}" class="btn btn-sm btn-default"><i class="fa fa-reply"></i> 返回</a>
@if(isset($access['add']))
@if($permission['add_item'])
<a href="javascript:addItem();" title="添加列表" class="hinted btn btn-sm btn-info"><i class="icon icon-plus"></i> 添加列表</a>
@endif
@if($permission['add_task'])
<a href="javascript:addTask();" title="添加任务" class="hinted btn btn-sm btn-info"><i class="icon icon-plus"></i> 添加任务</a>
@endif
@endif
@include('searchForm')
<script type="text/javascript">
$(function() {
$('#search-task-form').searchForm({
data: {{json_encode($search['forms'])}},
init:function(e) {
var self = this;
}
});
});
</script>
</form>
</div>
<div id="gantt-view"></div>
</div>
<script type="text/javascript">
var project_id = "{{(int)$project['id']}}";
var params = {project_id:project_id};
gantt.config.columns = [
{name:"name", label:"任务列表", tree:true, width:'*', resize: true}
];
gantt.config.scale_unit = 'month';
gantt.config.date_scale = '%Y - %m';
gantt.config.scale_height = 50;
gantt.config.link_line_width = 1;
gantt.config.row_height = 28;
gantt.config.task_height = 16;
gantt.config.grid_resize = true;
gantt.config.drag_links = false;
gantt.config.drag_progress = false;
gantt.config.min_column_width = 60;
gantt.config.duration_unit = 'day';
gantt.config.grid_width = 220;
gantt.config.api_date = gantt.config.xml_date = '%Y-%m-%d %H:%i';
gantt.config.show_links = false;
gantt.config.order_branch = true;
// gantt.config.order_branch_free = true;
/*
var date_to_str = gantt.date.date_to_str(gantt.config.api_date);
var today = new Date();
gantt.addMarker({
start_date: today,
css: "today",
text: "今天",
title:"今天: "+ date_to_str(today)
});
*/
gantt.config.subscales = [
{unit:"day", step:1, date:"%d %D"}
];
gantt.config.types.project = 'item';
gantt.config.type_renderers['item'] = function(task) {
var el = document.createElement('div');
el.setAttribute(gantt.config.task_attribute, task.id);
var size = gantt.getTaskPosition(task);
el.innerHTML = '<div class="project-left"></div><div class="gantt_task_content"></div><div class="project-right"></div>';
el.className = 'project-item';
el.style.left = size.left + 'px';
el.style.top = size.top + 6 + 'px';
el.style.width = size.width + 'px';
return el;
};
gantt.templates.task_class = function(start, end, task) {
if(task.progress == 1) {
return 'done';
}
};
gantt.templates.task_text = function() {
return '';
};
gantt.templates.rightside_text = function(start, end, task) {
return task.user_name;
};
gantt.templates.tooltip_text = function(start, end, task) {
if(task.type == 'task' || task.type == 'subtask') {
return '<div>任务: '+task.name+'</div><div>执行者: ' + (task.user_name || '无') + '</div><div>参与者: ' + (task.users || '无') + '</div><div>开始时间: ' + gantt.templates.tooltip_date_format(start) + '</div><div>结束时间: '+gantt.templates.tooltip_date_format(end) + '</div><div>备注: '+task.remark+'</div>';
}
};
gantt.attachEvent('onTaskDblClick', function (task_id) {
var task = gantt.getTask(task_id);
if(task.type == 'item') {
editItem(task_id);
}
if(task.type == 'task') {
editTask(task_id);
}
if(task.type == 'subtask') {
editSubTask(task_id);
}
});
gantt.attachEvent('onBeforeRowDragEnd', function(task_id, parent, index) {
var task = gantt.getTask(task_id);
if(task.option_delete == 0) {
return false;
}
var data = gantt.getSiblings(task_id);
$.post('{{url("sort")}}', {id:task_id,parent_id:task.parent,sort:data}, function(res) {
toastrSuccess('恭喜您,任务排序成功。');
}, 'json');
return true;
});
gantt.attachEvent('onBeforeTaskDrag', function(task_id, mode, e) {
var task = gantt.getTask(task_id);
if(task.option_delete == 0) {
return false;
}
return true;
});
gantt.attachEvent('onAfterTaskDrag', function(task_id, mode, e) {
var task = gantt.getTask(task_id);
var data = {id: task.id,progress: task.progress};
var date_to_str = gantt.date.date_to_str(gantt.config.api_date);
data.start_date = date_to_str(task.start_date);
data.end_date = date_to_str(task.end_date);
$.post('{{url("drag")}}', data, function(res) {
gantt.render();
}, 'json');
});
gantt._do_autosize = function() {
// 设置高度
var height = $('#gantt-wrapper').outerHeight();
var iframeHeight = $(window).height();
$('#gantt-view').height(iframeHeight - height - 68 + 'px');
var resize = this._get_resize_options();
var boxSizes = this._get_box_styles();
if(resize.y) {
var reqHeight = this._calculate_content_height();
if(boxSizes.borderBox) {
reqHeight += boxSizes.vertPaddings;
}
this._obj.style.height = reqHeight + 'px';
}
if(resize.x) {
var reqWidth = this._calculate_content_width();
if(boxSizes.borderBox) {
reqWidth += boxSizes.horPaddings;
}
this._obj.style.width = reqWidth + 'px';
}
};
gantt.init("gantt-view");
gantt.load(app.url('project/task/index', params));
$('#search-submit').on('click', function() {
var query = $('#search-task-form').serializeArray();
$.map(query, function(row) {
params[row.name] = row.value;
});
dataReload();
return false;
});
function exportToPDF()
{
gantt.exportToPDF({
locale:"cn",
skin:'terrace',
});
}
function dataReload() {
gantt.clearAll();
gantt.load(app.url('project/task/index', params));
}
function getTask(id) {
return gantt.getTask(id);
}
</script>
@include('task/index/js')
@@ -0,0 +1,150 @@
<div class="panel">
<div class="wrapper-sm b-b">
<span class="text-md">{{$project['name']}}</span> <span class="text-muted">{{$project['description']}}</span>
</div>
<div class="wrapper-xs" id="index-wrapper">
<form id="search-task-form" class="form-inline" name="mytasksearch" method="get">
<div class="pull-right">
<div class="btn-group">
<a href="{{url('index', ['project_id' => $project['id'], 'tpl' => 'index'])}}" class="btn btn-sm btn-default @if($query['tpl'] == 'index') active @endif">列表</a>
<a href="{{url('index', ['project_id' => $project['id'], 'tpl' => 'gantt'])}}" class="btn btn-sm btn-default @if($query['tpl'] == 'gantt') active @endif">甘特图</a>
</div>
</div>
<a href="{{url($referer)}}" class="btn btn-sm btn-default"><i class="fa fa-reply"></i> 返回</a>
@if(isset($access['add']))
@if($permission['add_item'])
<a href="javascript:addItem();" title="添加列表" class="hinted btn btn-sm btn-info"><i class="icon icon-plus"></i> 添加列表</a>
@endif
@if($permission['add_task'])
<a href="javascript:addTask();" title="添加任务" class="hinted btn btn-sm btn-info"><i class="icon icon-plus"></i> 添加任务</a>
@endif
@endif
@include('searchForm')
</form>
</div>
<div class="list-jqgrid">
<div id="jqgrid-table" class="ag-theme-balham" style="width:100%;"></div>
</div>
</div>
<script>
var grid = null;
var project_id = "{{(int)$project['id']}}";
var params = {project_id:project_id};
var auth_id = '{{auth()->id()}}';
function progressRenderer(params) {
var data = params.data;
if (data.type == 'task' || data.type == 'subtask') {
if (params.value == 1) {
return '<span class="label label-success">已完成</span>';
} else {
return '<span class="label label-' + (auth_id == data.user_id ? 'danger' : 'info') + '">进行中</span>';
}
}
return '';
}
function durationRenderer(params) {
if (params.value) {
return '<span class="hinted" title="任务持续' + params.value + '">' + params.value + '</span>';
}
return '';
}
(function($) {
grid = new agGridOptions();
grid.remoteDataUrl = '{{url()}}';
grid.remoteParams = params;
grid.rowSelection = 'multiple';
grid.columnDefs = [
{field: "id", hide: true},
{field: "type", hide: true},
{field: "option_edit", hide: true},
{field: "option_delete", hide: true}
];
grid.autoGroupColumnDef = {
headerName: '任务',
width: 250,
cellRendererParams: {
checkbox: false,
suppressCount: false,
}
};
grid.treeData = true;
grid.groupDefaultExpanded = -1;
grid.getDataPath = function(data) {
return data.tree_path;
};
grid.columnDefs.push(
{cellClass:'text-center', sortable: false, field: 'user_name', headerName: '执行者', width: 140},
{cellClass:'text-center', sortable: false, field: 'users', headerName: '参与者', minWidth: 200},
{cellClass:'text-center', cellRenderer: progressRenderer, sortable: false, field: 'progress', headerName: '状态', width: 100},
{cellClass:'text-center', sortable: false, field: 'start_at', headerName: '开始时间', width: 120},
{cellClass:'text-center', sortable: false, field: 'end_at', headerName: '结束时间', width: 120},
{cellClass:'text-center', cellRenderer: durationRenderer, sortable: false, field: 'duration_date', headerName: '持续时间', width: 100},
{cellClass:'text-center', sortable: false, field: 'created_at', headerName: '创建时间', width: 140},
{cellClass:'text-center', field: 'id', headerName: 'ID', width: 80}
);
grid.onRowDoubleClicked = function (row) {
var data = row.data;
if(data.type == 'item') {
editItem(data.id);
}
if(data.type == 'task') {
editTask(data.id);
}
if(data.type == 'subtask') {
editSubTask(data.id);
}
};
var gridDiv = document.querySelector("#jqgrid-table");
gridDiv.style.height = getPanelHeight(12);
new agGrid.Grid(gridDiv, grid);
// 读取数据
grid.remoteData();
var search = $('#search-task-form').searchForm({
data: JSON.parse('{{json_encode($search["forms"])}}'),
init:function(e) {
var self = this;
}
});
search.find('#search-submit').on('click', function() {
var query = search.serializeArray();
params.page = 1;
grid.remoteData(params);
return false;
});
})(jQuery);
function dataReload() {
params.page = 1;
grid.remoteData(params);
}
function getTask(id) {
return grid.api.getRowNode(id);
}
</script>
@include('task/index/js')
@@ -0,0 +1,198 @@
<script>
function formsBox(title, url, id, success, remove, error)
{
var options = {
dialogClass: 'modal-lg',
backdrop: 'static',
title: title,
url: url,
buttons: []
};
if (typeof success === 'function') {
options.buttons.push({
text: '<i class="fa fa-check"></i> 提交',
class: 'btn-info',
click: function() {
var me = this;
var action = $('#'+id).attr('action');
var formData = $('#'+id).serialize();
$.post(action, formData, function(res) {
success.call(me, res);
},'json');
}
});
}
if (typeof remove === 'function') {
options.buttons.push({
text: '<i class="fa fa-remove"></i> 删除',
class: 'btn-danger',
click: function() {
var me = this;
remove.call(me);
}
});
}
options.buttons.push({
text: '取消',
class: 'btn-default',
click: function() {
var me = this;
if (typeof error === 'function') {
error.call(me);
} else {
$(me).dialog("close");
}
}
});
$.dialog(options);
}
function saveResult(res) {
if(res.status) {
dataReload();
toastrSuccess(res.data);
$(this).dialog("close");
} else {
toastrError(res.data);
}
}
function addItem() {
formsBox('添加任务列表', app.url('project/task/add', {type:'item',project_id:project_id}), 'item-form', function(res) {
saveResult.call(this, res);
});
}
function editItem(id) {
var fun_edit = null, fun_delete = null;
var task = getTask(id);
if(task.option_edit == 1) {
fun_edit = function(res) {
saveResult.call(this, res);
}
}
if(task.option_delete == 1) {
fun_delete = function() {
var me = this;
$.messager.confirm('操作警告', '确定要删除任务列表吗?', function(btn) {
if (btn == true) {
$.post(app.url('project/task/delete'), {id: id}, function(res) {
saveResult.call(me, res);
},'json');
}
});
}
}
formsBox('编辑任务列表', app.url('project/task/edit', {type:'item',id:id}), 'item-form-'+ id, fun_edit, fun_delete);
}
function addTask() {
formsBox('添加任务', app.url('project/task/add', {type:'task',project_id:project_id}), 'task-form', function(res) {
saveResult.call(this, res);
});
}
function editTask(id) {
var fun_edit = null, fun_delete = null;
var task = getTask(id);
if(task.option_edit == 1) {
fun_edit = function(res) {
saveResult.call(this, res);
}
}
if(task.option_delete == 1) {
fun_delete = function() {
var me = this;
$.messager.confirm('操作警告', '确定要删除任务吗?', function(btn) {
if (btn == true) {
$.post(app.url('project/task/delete'), {id: id}, function(res) {
saveResult.call(me, res);
}, 'json');
}
});
}
}
formsBox('编辑任务', app.url('project/task/edit', {type:'task',id:id}), 'task-form-'+ id, fun_edit, fun_delete);
}
function addSubTask(id) {
formsBox('添加子任务', app.url('project/task/add', {type:'subtask',project_id:project_id,parent_id:id}), 'task-form', function(res) {
if(res.status) {
dataReload();
$('#task-subtask-' + id).prepend('<p><span class="time">'+ res.data.created_at + '(' + res.data.user_name + ')</span><label class="i-checks i-checks-sm m-b-none"><input class="select-row" type="checkbox" name="progress" value="'+ res.data.progress + '"><i></i></label><a href="javascript:editSubTask(' + res.data.id + ');">'+ res.data.name + '</a></p>');
toastrSuccess('恭喜您,添加子任务成功。');
$(this).dialog("close");
} else {
toastrError(res.data);
}
});
}
function editSubTask(id) {
var fun_edit = null, fun_delete = null;
var task = getTask(id);
if(task.option_edit == 1) {
fun_edit = function(res) {
saveResult.call(this, res);
}
}
if(task.option_delete == 1) {
fun_delete = function() {
var me = this;
$.messager.confirm('操作警告', '确定要删除任务吗?', function(btn) {
if (btn == true) {
$.post(app.url('project/task/delete'), {id: id}, function(res) {
saveResult.call(me, res);
}, 'json');
}
});
}
}
formsBox('编辑子任务', app.url('project/task/edit', {type:'subtask',id:id}), 'task-form-'+ id, fun_edit, fun_delete);
}
function addComment(task_id) {
formsBox('添加评论', app.url('project/comment/add', {task_id:task_id}), 'comment-form', function(res) {
if(res.status) {
$('#task-log-' + task_id).prepend('<p class="task-log-comment"><span class="time">' + res.data.created_at + '</span><div class="task-log-user">' + res.data.user + '</div>' + res.data.content + '</p>');
toastrSuccess('恭喜您,添加评论成功。');
$(this).dialog("close");
} else {
toastrError(res.data);
}
});
}
function editComment(id) {
formsBox('编辑评论', app.url('project/comment/edit', {id:id}), 'comment-form', function(res) {
saveResult.call(this, res);
}, function() {
var me = this;
$.messager.confirm('操作警告', '确定要删除评论吗?', function(btn) {
if (btn == true) {
$.post(app.url('project/comment/delete'), {id:id}, function(res) {
saveResult.call(me, res);
}, 'json');
}
});
});
}
</script>
@@ -0,0 +1,34 @@
<style>
.modal-body { overflow:hidden; }
</style>
<form method="post" action="{{url()}}" id="item-form" name="item-form">
<div class="panel m-b-none">
<table class="table table-form m-b-none">
<tr>
<td align="right" width="10%">名称</td>
<td align="left">
<input type="text" name="name" value="{{$task['name']}}" class="form-control input-sm">
</td>
</tr>
<tr>
<td align="right">备注</td>
<td>
<textarea class="form-control" type="text" name="remark"></textarea>
</td>
</tr>
</table>
</div>
</div>
<input type="hidden" name="type" value="{{$type}}">
<input type="hidden" name="parent_id" value="{{$parent_id}}">
<input type="hidden" name="project_id" value="{{$project_id}}">
<input type="hidden" name="is_item" value="1">
</form>
@@ -0,0 +1,42 @@
<style>
.modal-body { overflow:hidden; }
</style>
<form method="post" class="project-form" action="{{url()}}" id="item-form-{{$task->id}}" name="item-form-{{$task->id}}">
<div class="panel m-b-none">
<table class="table table-form m-b-none">
<tr>
<td align="right" width="10%">名称</td>
<td align="left">
@if($permission['name'])
<input type="text" name="name" value="{{$task['name']}}" class="form-control input-sm">
@else
{{$task['name']}}
@endif
</td>
</tr>
<tr>
<td align="right">备注</td>
<td>
@if($permission['remark'])
<textarea class="form-control" type="text" name="remark">{{$task->remark}}</textarea>
@else
{{$task->remark}}
@endif
</td>
</tr>
</table>
</div>
</div>
<input type="hidden" name="type" value="{{$type}}">
<input type="hidden" name="project_id" value="{{$task->project_id}}">
<input type="hidden" name="id" value="{{$task->id}}">
<input type="hidden" name="is_item" value="1">
</form>
+106
View File
@@ -0,0 +1,106 @@
<style>
.modal-body { overflow:hidden; }
</style>
<form method="post" enctype="multipart/form-data" id="mytaskform" name="mytaskform">
<div class="panel m-b-none">
<table class="table table-form m-b-none">
<tr>
<td align="right" width="15%">名称</td>
<td align="left">
<input type="text" name="name" id="name" value="{{$task['name']}}" class="form-control input-sm">
</td>
</tr>
<tr>
<td align="right">列表</td>
<td align="left">
<select class="form-control input-inline input-sm" id="item_id" name="item_id">
<option value="1">测试日程1_</option>
<option value="2">abc123</option>
<option value="408">一般事件</option>
</select>
</td>
</tr>
<tr>
<td align="right">执行者</td>
<td align="left">
{{App\Support\Dialog::user('user','user_id', $task['user_id'], 0, 0)}}
</td>
</tr>
<tr>
<td align="right">参与者</td>
<td align="left">
{{App\Support\Dialog::user('user', 'users', $task['users'], 1, 0)}}
</td>
</tr>
<tr>
<td align="right">时间</td>
<td align="left">
<input type="text" name="start_at" autocomplete="off" data-toggle="datetime" value="@datetime($task->start_at,time())" id="start_at" class="form-control input-sm input-inline">
-
<input type="text" name="end_at" autocomplete="off" data-toggle="datetime" value="@datetime($task->end_at)" id="end_at" class="form-control input-sm input-inline">
</td>
</tr>
<tr>
<td align="right">备注</td>
<td>
<textarea class="form-control" type="text" name="purchase_plan[remark]" id="remark" placeholder="暂无备注"></textarea>
</td>
</tr>
<tr>
<td align="right">附件</td>
<td align="left">
{{attachment_uploader('attachment', $task['attachment'])}}
</td>
</tr>
<tr>
<td align="right">子任务</td>
<td>
<a href="#" class="option"><i class="fa fa-fw fa-plus"></i>添加子任务</a>
</div>
</td>
</tr>
<tr>
<td align="right">评论</td>
<td>
<a href="#" class="option"><i class="fa fa-fw fa-plus"></i>添加评论</a>
<!--
<textarea class="form-control" rows="2" type="text" name="comment" id="comment" placeholder="内容"></textarea>
{{attachment_uploader('comment_attachment', '', false)}}
<a href="#" class="btn btn-sm btn-success"> 提交</a>
-->
</td>
</tr>
<tr>
<td align="right">活动</td>
<td>
<div class="project-task-log">
@if($logs)
@foreach($logs as $log)
<p><span class="time">@datetime($log->created_at)</span>{{$log->description}}</p>
@endforeach
@endif
</div>
</td>
</tr>
</table>
</div>
</div>
<input type="hidden" name="id" value="{{$task->id}}">
<input type="hidden" name="project_id" value="{{$project_id}}">
</form>
@@ -0,0 +1,32 @@
<table id="widget-article-index">
<thead>
<tr>
<th data-field="title" data-formatter="titleFormatter" data-align="left">标题</th>
<th data-field="created_at" data-width="200" data-formatter="datetimeFormatter" data-sortable="true" data-align="center">发布时间</th>
</tr>
</thead>
</table>
<script>
function datetimeFormatter(value, row) {
return format_datetime(value);
}
function titleFormatter(value, row) {
return '<a href="'+app.url('article/article/view', {id: row.id})+'">' + value + '</a>';
}
(function($) {
var $table = $('#widget-article-index');
$table.bootstrapTable({
sidePagination: 'server',
showColumns: false,
showHeader: false,
height: 200,
pagination: false,
url: '{{url("article/widget/index")}}',
});
})(jQuery);
</script>
@@ -0,0 +1,15 @@
<div class="panel panel-shadow info-skin1">
<div class="info-l hidden-xs" style="background-color:{{$info['color']}}">
<i class="fa fa-2x {{$info['icon']}}"></i>
</div>
<div class="info-c">
<div class="info-name">{{$info['name']}}</div>
<a href="javascript:;" data-toggle="addtab" data-url="{{$info['more_url']}}" data-id="{{str_replace(['/', '?', '='], ['_', '_', '_'], $info['more_url'])}}" data-name="{{$info['name']}}">
<div class="text-info info-item" data-id="{{$info['id']}}" data-more_url="{{$info['more_url']}}">{{$res['count']}}</div>
</a>
</div>
<div class="info-r">
<div>{{$dates[$info['params']['date']]}}</div>
<div class="rate @if($res['rate'] > 100) red @endif">{{$res['rate']}}%</div>
</div>
</div>