diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php
index 03d0da18..d421363c 100755
--- a/app/Http/Controllers/Api/ProjectController.php
+++ b/app/Http/Controllers/Api/ProjectController.php
@@ -60,6 +60,10 @@ class ProjectController extends AbstractController
/**
* 获取项目列表
*
+ * @apiParam {String} [archived] 归档状态
+ * - no:未归档(默认)
+ * - yes:已归档
+ *
* @apiParam {Number} [page] 当前页,默认:1
* @apiParam {Number} [pagesize] 每页显示数量,默认:100,最大:200
*/
@@ -67,10 +71,15 @@ class ProjectController extends AbstractController
{
User::auth();
//
- $list = Project::select(Project::projectSelect)
- ->authData()
- ->orderByDesc('projects.id')
- ->paginate(Base::getPaginate(200, 100));
+ $archived = Request::input('archived', 'no');
+ //
+ $builder = Project::select(Project::projectSelect)->authData();
+ if ($archived == 'yes') {
+ $builder->whereNotNull('archived_at');
+ } elseif ($archived == 'no') {
+ $builder->whereNull('archived_at');
+ }
+ $list = $builder->orderByDesc('projects.id')->paginate(Base::getPaginate(200, 100));
//
return Base::retSuccess('success', $list);
}
@@ -357,6 +366,26 @@ class ProjectController extends AbstractController
return Base::retSuccess('退出成功', ['id' => $project->id]);
}
+ /**
+ * 归档项目
+ *
+ * @apiParam {Number} project_id 项目ID
+ */
+ public function archived()
+ {
+ User::auth();
+ //
+ $project_id = intval(Request::input('project_id'));
+ //
+ $project = Project::userProject($project_id);
+ if (!$project->owner) {
+ return Base::retError('你不是项目负责人');
+ }
+ //
+ $project->archivedProject(Carbon::now());
+ return Base::retSuccess('设置成功', ['id' => $project->id]);
+ }
+
/**
* 删除项目
*
@@ -513,6 +542,9 @@ class ProjectController extends AbstractController
* - all:所有(默认)
* - yes:已完成
* - no:未完成
+ * @apiParam {String} [archived] 归档状态
+ * - yes:已归档
+ * - no:未归档(默认)
*/
public function task__lists()
{
@@ -525,7 +557,8 @@ class ProjectController extends AbstractController
$name = Request::input('name');
$time = Request::input('time');
$time_before = Request::input('time_before');
- $complete = Request::input('complete');
+ $complete = Request::input('complete', 'all');
+ $archived = Request::input('archived', 'no');
//
if ($parent_id > 0) {
ProjectTask::userTask($parent_id);
@@ -563,6 +596,12 @@ class ProjectController extends AbstractController
$builder->whereNull('complete_at');
}
//
+ if ($archived == 'yes') {
+ $builder->whereNotNull('archived_at');
+ } elseif ($archived == 'no') {
+ $builder->whereNull('archived_at');
+ }
+ //
$list = $builder->orderByDesc('id')->paginate(Base::getPaginate(200, 100));
//
return Base::retSuccess('success', $list);
diff --git a/app/Models/Project.php b/app/Models/Project.php
index 6f852090..ab95a868 100644
--- a/app/Models/Project.php
+++ b/app/Models/Project.php
@@ -4,6 +4,7 @@ namespace App\Models;
use App\Exceptions\ApiException;
use App\Tasks\PushTask;
+use Carbon\Carbon;
use Hhxsv5\LaravelS\Swoole\Task\Task;
use Illuminate\Database\Eloquent\SoftDeletes;
use Request;
@@ -17,6 +18,7 @@ use Request;
* @property string|null $desc 描述、备注
* @property int|null $userid 创建人
* @property int|mixed $dialog_id 聊天会话ID
+ * @property string|null $archived_at 归档时间
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property \Illuminate\Support\Carbon|null $deleted_at
@@ -38,6 +40,7 @@ use Request;
* @method static \Illuminate\Database\Eloquent\Builder|Project newQuery()
* @method static \Illuminate\Database\Query\Builder|Project onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|Project query()
+ * @method static \Illuminate\Database\Eloquent\Builder|Project whereArchivedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Project whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Project whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Project whereDesc($value)
@@ -70,7 +73,7 @@ class Project extends AbstractModel
];
/**
- * 生成子任务数据
+ * 生成任务数据
*/
private function generateTaskData()
{
@@ -281,6 +284,29 @@ class Project extends AbstractModel
return $user->owner ? 2 : 1;
}
+ /**
+ * 归档任务、取消归档
+ * @param Carbon|null $archived_at 归档时间
+ * @return bool
+ */
+ public function archivedProject($archived_at)
+ {
+ AbstractModel::transaction(function () use ($archived_at) {
+ if ($archived_at === null) {
+ // 取消归档
+ $this->archived_at = null;
+ $this->addLog("项目取消归档");
+ } else {
+ // 归档任务
+ $this->archived_at = $archived_at;
+ $this->addLog("项目归档");
+ $this->pushMsg('archived');
+ }
+ $this->save();
+ });
+ return true;
+ }
+
/**
* 删除项目
* @return bool
@@ -354,6 +380,7 @@ class Project extends AbstractModel
{
$project = self::select(self::projectSelect)
->authData()
+ ->whereNull('archived_at')
->where('projects.id', intval($project_id))
->first();
if (empty($project)) {
diff --git a/resources/assets/js/pages/manage/components/ProjectList.vue b/resources/assets/js/pages/manage/components/ProjectList.vue
index f77fa9ab..7f22083a 100644
--- a/resources/assets/js/pages/manage/components/ProjectList.vue
+++ b/resources/assets/js/pages/manage/components/ProjectList.vue
@@ -33,7 +33,8 @@
{{$L('项目设置')}}
{{$L('成员管理')}}
- {{$L('移交项目')}}
+ {{$L('归档项目')}}
+ {{$L('移交项目')}}
{{$L('删除项目')}}
@@ -857,6 +858,23 @@ export default {
});
},
+ onArchived() {
+ $A.modalConfirm({
+ title: '归档项目',
+ content: '你确定要归档项目【' + this.projectData.name + '】吗?',
+ loading: true,
+ onOk: () => {
+ this.$store.dispatch("archivedProject", this.projectId).then(({msg}) => {
+ $A.messageSuccess(msg);
+ this.$Modal.remove();
+ }).catch(({msg}) => {
+ $A.modalError(msg, 301);
+ this.$Modal.remove();
+ });
+ }
+ });
+ },
+
onDelete() {
$A.modalConfirm({
title: '删除项目',
@@ -913,6 +931,10 @@ export default {
this.transferShow = true;
break;
+ case "archived":
+ this.onArchived();
+ break;
+
case "delete":
this.onDelete();
break;
diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js
index 9e72f000..6f2b5bea 100644
--- a/resources/assets/js/store/actions.js
+++ b/resources/assets/js/store/actions.js
@@ -373,6 +373,29 @@ export default {
});
},
+ /**
+ * 归档项目
+ * @param dispatch
+ * @param project_id
+ */
+ archivedProject({dispatch}, project_id) {
+ return new Promise(function (resolve, reject) {
+ dispatch("call", {
+ url: 'project/archived',
+ data: {
+ project_id,
+ },
+ }).then(result => {
+ dispatch("forgetProject", project_id)
+ resolve(result)
+ }).catch(e => {
+ console.error(e);
+ dispatch("getProjectOne", project_id);
+ reject(e)
+ });
+ });
+ },
+
/**
* 删除项目
* @param dispatch
@@ -1323,6 +1346,7 @@ export default {
case 'detail':
dispatch("getProjectOne", data);
break;
+ case 'archived':
case 'delete':
dispatch("forgetProject", data.id);
break;