整理数据结构

This commit is contained in:
kuaifan 2021-06-20 17:02:45 +08:00
parent a9c763bb77
commit 11b4aea20c
14 changed files with 542 additions and 662 deletions

View File

@ -24,6 +24,39 @@ use Request;
*/
class ProjectController extends AbstractController
{
/**
* 任务统计
*/
public function statistics()
{
User::auth();
$data = [];
// 今日待完成
$between = [
Carbon::today()->startOfDay(),
Carbon::today()->endOfDay()
];
$data['today'] = ProjectTask::authData()
->whereNull('project_tasks.complete_at')
->where('project_tasks.parent_id', 0)
->where(function ($query) use ($between) {
$query->whereBetween('project_tasks.start_at', $between)->orWhereBetween('project_tasks.end_at', $between);
})
->count();
// 超期未完成
$data['overdue'] = ProjectTask::authData()
->whereNull('project_tasks.complete_at')
->where('project_tasks.parent_id', 0)
->whereNotNull('project_tasks.end_at')
->where('project_tasks.end_at', '<', Carbon::now())
->count();
return Base::retSuccess('success', $data);
}
/**
* 获取项目列表
*
@ -43,11 +76,11 @@ class ProjectController extends AbstractController
}
/**
* 获取项目基础信息
* 获取一个项目信息
*
* @apiParam {Number} project_id 项目ID
*/
public function basic()
public function one()
{
User::auth();
//
@ -58,46 +91,17 @@ class ProjectController extends AbstractController
return Base::retSuccess('success', $project);
}
/**
* 获取项目详细信息
*
* @apiParam {Number} project_id 项目ID
*/
public function detail()
{
User::auth();
//
$project_id = intval(Request::input('project_id'));
//
$project = Project::with(['projectColumn' => function($query) {
$query->with(['projectTask' => function($taskQuery) {
$taskQuery->with(['taskUser', 'taskTag'])->where('parent_id', 0);
}]);
}, 'projectUser'])
->select(project::projectSelect)
->authData()
->where('projects.id', $project_id)
->first();
if (empty($project)) {
return Base::retError('项目不存在或不在成员列表内');
}
$owner_user = $project->projectUser->where('owner', 1)->first();
$project->owner_userid = $owner_user ? $owner_user->userid : 0;
//
return Base::retSuccess('success', $project);
}
/**
* 添加项目
*
* @apiParam {String} name 项目名称
* @apiParam {String} [desc] 项目介绍
* @apiParam {Array} [columns] 流程,格式[流程1, 流程2]
* @apiParam {Array} [columns] 列表,格式[列表1, 列表2]
*/
public function add()
{
$user = User::auth();
//项目名称
// 项目名称
$name = trim(Request::input('name', ''));
$desc = trim(Request::input('desc', ''));
if (mb_strlen($name) < 2) {
@ -108,7 +112,7 @@ class ProjectController extends AbstractController
if (mb_strlen($desc) > 255) {
return Base::retError('项目介绍最多只能设置255个字');
}
//流程
// 列表
$columns = Request::input('columns');
if (!is_array($columns)) $columns = [];
$insertColumns = [];
@ -129,9 +133,9 @@ class ProjectController extends AbstractController
];
}
if (count($insertColumns) > 30) {
return Base::retError('项目流程最多不能超过30个');
return Base::retError('项目列表最多不能超过30个');
}
//开始创建
// 开始创建
$project = Project::createInstance([
'name' => $name,
'desc' => $desc,
@ -150,7 +154,7 @@ class ProjectController extends AbstractController
}
});
//
$data = $project->find($project->id);
$data = Project::find($project->id);
$data->addLog("创建项目");
$data->pushMsg('add', $data->toArray());
return Base::retSuccess('添加成功', $data);
@ -374,6 +378,30 @@ class ProjectController extends AbstractController
return Base::retSuccess('删除成功', ['id' => $project->id]);
}
/**
* 获取任务列表
*
* @apiParam {Number} project_id 项目ID
*
* @apiParam {Number} [page] 当前页,默认:1
* @apiParam {Number} [pagesize] 每页显示数量,默认:100,最大:200
*/
public function column__lists()
{
User::auth();
//
$project_id = intval(Request::input('project_id'));
// 项目
$project = Project::userProject($project_id);
//
$list = ProjectColumn::whereProjectId($project->id)
->orderBy('sort')
->orderBy('id')
->paginate(Base::getPaginate(200, 100));
//
return Base::retSuccess('success', $list);
}
/**
* 添加任务列表
*
@ -400,7 +428,7 @@ class ProjectController extends AbstractController
$column->save();
$column->addLog("创建列表:" . $column->name);
//
$data = $column->find($column->id);
$data = ProjectColumn::find($column->id);
$data->project_task = [];
$data->pushMsg("add", $data->toArray());
return Base::retSuccess('添加成功', $data);
@ -471,54 +499,46 @@ class ProjectController extends AbstractController
}
//
$column->deleteColumn();
return Base::retSuccess('删除成功', $column->toArray());
}
/**
* 任务统计
*/
public function task__statistics()
{
User::auth();
$data = [];
// 今日待完成
$between = [
Carbon::today()->startOfDay(),
Carbon::today()->endOfDay()
];
$data['today'] = ProjectTask::authData()->where(function($query) use ($between) {
$query->whereBetween('project_tasks.start_at', $between)->orWhereBetween('project_tasks.end_at', $between);
})->count();
// 超期未完成
$data['overdue'] = ProjectTask::authData()->whereNotNull('project_tasks.end_at')->where('project_tasks.end_at', '<', Carbon::now())->count();
return Base::retSuccess('success', $data);
return Base::retSuccess('删除成功', ['id' => $column->id]);
}
/**
* 任务列表
*
* @apiParam {String} name 任务名称(包含)
* @apiParam {Array} time 时间范围,如:['2020-12-12', '2020-12-30']
* @apiParam {String} time_before 指定时间之前2020-12-30 00:00:00填写此项时time参数无效
* @apiParam {Number} [project_id] 项目ID
* @apiParam {Number} [parent_id] 主任务ID填写后 project_id 无效)
* @apiParam {String} [name] 任务描述关键词
* @apiParam {Array} [time] 时间范围,如:['2020-12-12', '2020-12-30']
* @apiParam {String} [time_before] 指定时间之前2020-12-30 00:00:00填写此项时time参数无效
*/
public function task__lists()
{
User::auth();
//
$builder = ProjectTask::select(ProjectTask::taskSelect)->authData();
$builder = ProjectTask::with(['taskUser', 'taskTag']);
//
$parent_id = intval(Request::input('parent_id'));
$project_id = intval(Request::input('project_id'));
$name = Request::input('name');
$time = Request::input('time');
$time_before = Request::input('time_before');
//
if ($parent_id > 0) {
ProjectTask::userTask($parent_id);
$builder->where('parent_id', $parent_id)->whereNull('archived_at');
} elseif ($project_id > 0) {
Project::userProject($project_id);
$builder->where('project_id', $project_id)->whereNull('archived_at');
} else {
$builder->authData();
}
//
if ($name) {
$builder->where(function($query) use ($name) {
$query->where('project_tasks.name', 'like', '%,' . $name . ',%');
});
}
//
if (Base::isDateOrTime($time_before)) {
$builder->whereNotNull('project_tasks.end_at')->where('project_tasks.end_at', '<', Carbon::parse($time_before));
} elseif (is_array($time)) {
@ -539,11 +559,11 @@ class ProjectController extends AbstractController
}
/**
* 获取任务基础信息
* 获取单个任务信息
*
* @apiParam {Number} task_id 任务ID
*/
public function task__basic()
public function task__one()
{
User::auth();
//
@ -557,23 +577,6 @@ class ProjectController extends AbstractController
return Base::retSuccess('success', $task);
}
/**
* 获取子任务
*
* @apiParam {Number} task_id 任务ID
*/
public function task__sublist()
{
User::auth();
//
$task_id = intval(Request::input('task_id'));
//
$task = ProjectTask::userTask($task_id);
//
$data = ProjectTask::with(['taskUser', 'taskTag'])->where('parent_id', $task->id)->whereNull('archived_at')->get();
return Base::retSuccess('success', $data);
}
/**
* 获取任务详细描述
*
@ -661,10 +664,10 @@ class ProjectController extends AbstractController
]));
$data = [
'new_column' => $newColumn,
'in_top' => intval($data['top']),
'task' => ProjectTask::with(['taskUser', 'taskTag'])->find($task->id),
'task' => ProjectTask::with(['taskUser', 'taskTag'])->find($task->id)->toArray(),
];
$task->pushMsg('add', $data);
$data['task']['owner'] = 1;
return Base::retSuccess('添加成功', $data);
}
@ -691,10 +694,10 @@ class ProjectController extends AbstractController
]);
$data = [
'new_column' => null,
'in_top' => 0,
'task' => ProjectTask::with(['taskUser', 'taskTag'])->find($task->id),
'task' => ProjectTask::with(['taskUser', 'taskTag'])->find($task->id)->toArray(),
];
$task->pushMsg('add', $data);
$data['task']['owner'] = 1;
return Base::retSuccess('添加成功', $data);
}
@ -800,7 +803,8 @@ class ProjectController extends AbstractController
'userid' => $user->userid,
]);
$file->save();
$file = $file->find($file->id);
//
$file = ProjectTaskFile::find($file->id);
$task->addLog("上传文件:" . $file->name);
$task->pushMsg('upload', $file->toArray());
return Base::retSuccess("上传成功", $file);
@ -863,7 +867,7 @@ class ProjectController extends AbstractController
}
//
$task->archivedTask(Carbon::now());
return Base::retSuccess('保存成功', $task);
return Base::retSuccess('保存成功', ['id' => $task->id]);
}
/**
@ -880,7 +884,7 @@ class ProjectController extends AbstractController
$task = ProjectTask::userTask($task_id);
//
$task->deleteTask();
return Base::retSuccess('删除成功', $task);
return Base::retSuccess('删除成功', ['id' => $task->id]);
}
/**

View File

@ -20,6 +20,7 @@ use Request;
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property-read int $owner_userid
* @property-read int $task_complete
* @property-read int $task_my_complete
* @property-read int $task_my_num
@ -65,6 +66,7 @@ class Project extends AbstractModel
'task_my_num',
'task_my_complete',
'task_my_percent',
'owner_userid',
];
/**
@ -145,6 +147,19 @@ class Project extends AbstractModel
return $this->appendattrs['task_my_percent'];
}
/**
* 负责人会员ID
* @return int
*/
public function getOwnerUseridAttribute()
{
if (!isset($this->appendattrs['owner_userid'])) {
$ownerUser = $this->projectUser->where('owner', 1)->first();
$this->appendattrs['owner_userid'] = $ownerUser ? $ownerUser->userid : 0;
}
return $this->appendattrs['owner_userid'];
}
/**
* @param $value
* @return int|mixed
@ -338,7 +353,7 @@ class Project extends AbstractModel
*/
public static function userProject($project_id)
{
$project = Project::select(self::projectSelect)
$project = self::select(self::projectSelect)
->authData()
->where('projects.id', intval($project_id))
->first();

View File

@ -258,15 +258,16 @@ class ProjectTask extends AbstractModel
{
$pre = DB::getTablePrefix();
$user = $user ?: User::auth();
$query->join('project_task_users', 'project_tasks.id', '=', 'project_task_users.task_pid')
$query->select(ProjectTask::taskSelect)
->join('project_task_users', 'project_tasks.id', '=', 'project_task_users.task_pid')
->whereExists(function ($der) use ($pre) {
$der->select(DB::raw(1))
->from('project_task_users as B')
->where('B.owner', 1)
->whereColumn('project_task_users.task_pid', '=', 'B.task_pid')
->havingRaw("max({$pre}B.id) = {$pre}project_task_users.id");
})
->whereNull('project_tasks.archived_at')
->where('project_tasks.parent_id', 0)
->where('project_task_users.userid', $user->userid);
return $query;
}
@ -688,7 +689,7 @@ class ProjectTask extends AbstractModel
*/
public static function userTask($task_id, $with = [])
{
$task = ProjectTask::with($with)->whereId(intval($task_id))->first();
$task = self::with($with)->whereId(intval($task_id))->first();
if (empty($task)) {
throw new ApiException('任务不存在');
}

View File

@ -34,7 +34,7 @@
<li class="menu-project">
<ul>
<li
v-for="(item, key) in projectList"
v-for="(item, key) in projects"
:key="key"
:class="classNameRoute('project/' + item.id, openMenu[item.id])"
@click="toggleRoute('project/' + item.id)">
@ -103,20 +103,21 @@
<!--任务详情-->
<Modal
v-model="projectOpenTask._show"
:value="taskId > 0"
:mask-closable="false"
:styles="{
width: '90%',
maxWidth: projectOpenTask.dialog_id ? '1200px' : '640px'
maxWidth: taskData.dialog_id ? '1200px' : '640px'
}"
@on-visible-change="taskVisibleChange"
footer-hide>
<TaskDetail :open-task="projectOpenTask"/>
<TaskDetail :open-task="taskData"/>
</Modal>
</div>
</template>
<script>
import { mapState } from 'vuex'
import { mapState, mapGetters } from 'vuex'
import TaskDetail from "./manage/components/TaskDetail";
export default {
@ -174,18 +175,19 @@ export default {
'userId',
'userInfo',
'dialogMsgUnread',
'projectList',
'projectOpenTask',
'projectChatShow'
'projects',
'projectChatShow',
'taskId',
]),
...mapGetters(['taskData'])
},
watch: {
'$route' (route) {
this.curPath = route.path;
},
'projectOpenTask._show' (show) {
if (show) {
taskId (id) {
if (id > 0) {
if (this.projectChatShow) {
this._projectChatShow = true;
this.$store.dispatch("toggleBoolean", "projectChatShow");
@ -316,6 +318,12 @@ export default {
}
});
},
taskVisibleChange(visible) {
if (!visible) {
this.$store.dispatch('openTask', 0)
}
}
}
}
</script>

View File

@ -29,7 +29,7 @@
:theme="calendarTheme"
:template="calendarTemplate"
:calendars="calendarList"
:schedules="calendarTasks"
:schedules="list"
@beforeCreateSchedule="onBeforeCreateSchedule"
@beforeClickSchedule="onBeforeClickSchedule"
@beforeUpdateSchedule="onBeforeUpdateSchedule"
@ -47,21 +47,6 @@ import {mapState} from "vuex";
import Calendar from "./components/Calendar";
import moment from "moment";
const today = new Date();
const getDate = (type, start, value, operator) => {
start = new Date(start);
type = type.charAt(0).toUpperCase() + type.slice(1);
if (operator === '+') {
start[`set${type}`](start[`get${type}`]() + value);
} else {
start[`set${type}`](start[`get${type}`]() - value);
}
return start;
};
export default {
components: {Calendar},
data() {
@ -78,7 +63,7 @@ export default {
calendarTemplate: {},
calendarList: [],
scheduleLoad: 0,
loadIng: 0,
}
},
@ -91,10 +76,53 @@ export default {
},
computed: {
...mapState(['projectList', 'calendarTask']),
...mapState(['projects', 'tasks']),
calendarTasks() {
return this.calendarTask.filter(({complete_at}) => !complete_at)
list() {
let datas = $A.cloneJSON(this.tasks);
datas = datas.filter((data) => {
if (data.parent_id > 0) {
return false;
}
if (data.complete_at) {
return false;
}
if (!data.start_at || !data.end_at) {
return false;
}
return data.owner;
})
return datas.map(data => {
let task = {
id: data.id,
calendarId: String(data.project_id),
title: data.name,
body: data.desc,
category: 'allday',
start: new Date(data.start_at).toISOString(),
end: new Date(data.end_at).toISOString(),
color: "#515a6e",
bgColor: data.color || '#E3EAFD',
borderColor: data.p_color,
complete_at: data.complete_at,
priority: '',
preventClick: true,
isChecked: false,
};
if (data.p_name) {
task.priority = '<span class="priority" style="background-color:' + data.p_color + '">' + data.p_name + '</span>';
}
if (data.overdue) {
task.title = '[' + $A.L('超期') + '] ' + task.title
task.color = "#f56c6c"
task.bgColor = "#fef0f0"
task.priority+= '<span class="overdue">' + $A.L('超期未完成') + '</span>';
}
if (!task.borderColor) {
task.borderColor = task.bgColor;
}
return task;
});
}
},
@ -103,7 +131,7 @@ export default {
this.getTask(time);
},
projectList: {
projects: {
handler(data) {
const list = data.map((project) => {
return {
@ -155,20 +183,19 @@ export default {
},
getTask(time) {
if (this.scheduleLoad > 0) {
if (this.loadIng > 0) {
setTimeout(() => {
this.getTask(time)
}, 100)
return;
}
this.scheduleLoad++;
this.$store.dispatch("getTaskList", {
this.loadIng++;
this.$store.dispatch("getTasks", {
time
}).then(({data}) => {
this.scheduleLoad--;
this.$store.dispatch("saveCalendarTask", data.data)
}).then(() => {
this.loadIng--;
}).catch(() => {
this.scheduleLoad--;
this.loadIng--;
})
},
@ -232,7 +259,7 @@ export default {
},
onBeforeClickSchedule({type, schedule}) {
let data = this.calendarTask.find(({id}) => id === schedule.id);
let data = this.tasks.find(({id}) => id === schedule.id);
if (!data) {
return;
}
@ -251,17 +278,17 @@ export default {
break;
case "edit":
this.$store.dispatch("openTask", schedule.id)
this.$store.dispatch("openTask", data.id)
break;
case "delete":
$A.modalConfirm({
title: '删除任务',
content: '你确定要删除任务【' + data.title + '】吗?',
content: '你确定要删除任务【' + data.name + '】吗?',
loading: true,
onOk: () => {
this.$store.dispatch("taskArchivedOrRemove", {
task_id: data.id,
id: data.id,
type: 'delete',
}).then(({msg}) => {
$A.messageSuccess(msg);
@ -279,7 +306,7 @@ export default {
onBeforeUpdateSchedule(res) {
const {changes, schedule} = res;
let data = this.calendarTask.find(({id}) => id === schedule.id);
let data = this.tasks.find(({id}) => id === schedule.id);
if (!data) {
return;
}

View File

@ -4,11 +4,6 @@
<script>
import Calendar from 'tui-calendar-hi';
const scheduleNeedProp = [
'start',
'category'
];
export default {
name: 'Calendar',
props: {
@ -27,7 +22,7 @@ export default {
let notHave = false;
value.forEach(schedule => {
notHave = scheduleNeedProp.some(prop => !schedule.hasOwnProperty(prop));
notHave = [ 'start', 'category' ].some(prop => !schedule.hasOwnProperty(prop));
});
return !notHave;

View File

@ -318,10 +318,7 @@ export default {
if (!this.dialogDetail.group_info) {
return;
}
this.$store.dispatch("openTask", {
id: this.dialogDetail.group_info.id,
dialog_id: this.dialogDetail.id
});
this.$store.dispatch("openTask", this.dialogDetail.group_info.id);
},
loadNextPage() {

View File

@ -821,7 +821,7 @@ export default {
$A.messageSuccess(msg);
this.ownerLoad--;
this.ownerShow = false;
this.$store.dispatch("getTaskBasic", this.taskDetail.id);
this.$store.dispatch("getTaskOne", this.taskDetail.id);
}).catch(({msg}) => {
$A.modalError(msg);
this.ownerLoad--;
@ -851,7 +851,7 @@ export default {
$A.messageSuccess(msg);
this.assistLoad--;
this.assistShow = false;
this.$store.dispatch("getTaskBasic", this.taskDetail.id);
this.$store.dispatch("getTaskOne", this.taskDetail.id);
}).catch(({msg}) => {
$A.modalError(msg);
this.assistLoad--;

View File

@ -36,7 +36,7 @@ export default {
},
computed: {
...mapState(['userToken', 'projectOpenTask']),
...mapState(['userToken', 'taskId', 'taskFiles']),
headers() {
return {
@ -47,7 +47,7 @@ export default {
params() {
return {
task_id: this.projectOpenTask.id,
task_id: this.taskId,
}
},
},
@ -57,18 +57,19 @@ export default {
//
if (typeof file.tempId === "undefined") {
file.tempId = $A.randomString(8);
this.projectOpenTask.files.push(file);
file.task_id = this.taskId;
this.taskFiles.push(file);
}
},
handleSuccess({ret, data, msg}, file) {
//
let index = this.projectOpenTask.files.findIndex(({tempId}) => tempId == file.tempId);
let index = this.taskFiles.findIndex(({tempId}) => tempId == file.tempId);
if (index > -1) {
this.projectOpenTask.files.splice(index, 1);
this.taskFiles.splice(index, 1);
}
if (ret === 1) {
this.$store.commit("taskUploadSuccess", data)
this.taskFiles.push(data);
} else {
this.$refs.upload.fileList.pop();
$A.modalWarning({

View File

@ -5,33 +5,33 @@
<div class="dashboard-hello">{{$L('欢迎您,' + userInfo.nickname)}}</div>
<div class="dashboard-desc">{{$L('以下是你当前的任务统计数据')}}</div>
<ul class="dashboard-block">
<li @click="active='today'">
<li @click="dashboard='today'">
<div class="block-title">{{$L('今日待完成')}}</div>
<div class="block-data">
<div class="block-num">{{projectTaskStatistics.today || '...'}}</div>
<div class="block-num">{{projectStatistics.today || '...'}}</div>
<i class="iconfont">&#xe6f4;</i>
</div>
</li>
<li @click="active='overdue'">
<li @click="dashboard='overdue'">
<div class="block-title">{{$L('超期未完成')}}</div>
<div class="block-data">
<div class="block-num">{{projectTaskStatistics.overdue || '...'}}</div>
<div class="block-num">{{projectStatistics.overdue || '...'}}</div>
<i class="iconfont">&#xe603;</i>
</div>
</li>
<li>
<div class="block-title">{{$L('参与的项目')}}</div>
<div class="block-data">
<div class="block-num">{{projectList.length}}</div>
<div class="block-num">{{projects.length}}</div>
<i class="iconfont">&#xe6f9;</i>
</div>
</li>
</ul>
<div class="dashboard-title">{{getTitle}}</div>
<div class="dashboard-title">{{title}}</div>
<ul class="dashboard-list overlay-y">
<li v-for="item in taskList">
<li v-for="item in list" :key="item.id" @click="$store.dispatch('openTask', item.id)">
<i class="iconfont">&#xe625;</i>
<div class="item-title">{{item.title}}</div>
<div class="item-title">{{item.name}}</div>
<div class="item-time"></div>
</li>
</ul>
@ -46,22 +46,27 @@ export default {
data() {
return {
loadIng: 0,
active: 'today',
active: false,
dashboard: 'today',
}
},
activated() {
this.$store.dispatch("getTaskStatistics");
this.getDashboardTask();
this.getTask();
this.active = true;
this.$store.dispatch("getProjectStatistics");
},
deactivated() {
this.active = false;
},
computed: {
...mapState(['userInfo', 'projectList', 'projectTaskStatistics', 'calendarTask']),
...mapState(['userInfo', 'projects', 'projectStatistics', 'tasks', 'taskId']),
getTitle() {
const {active} = this;
switch (active) {
title() {
const {dashboard} = this;
switch (dashboard) {
case 'today':
return this.$L('今日任务');
case 'overdue':
@ -71,14 +76,20 @@ export default {
}
},
taskList() {
const {calendarTask, active} = this;
list() {
const {tasks, dashboard} = this;
const todayStart = new Date($A.formatDate("Y-m-d 00:00:00")),
todayEnd = new Date($A.formatDate("Y-m-d 23:59:59"));
return calendarTask.filter((item) => {
const start = new Date(item.start);
const end = new Date(item.end);
switch (active) {
return tasks.filter((data) => {
const start = new Date(data.start_at),
end = new Date(data.end_at);
if (data.parent_id > 0) {
return false;
}
if (data.complete_at) {
return false;
}
switch (dashboard) {
case 'today':
return (start >= todayStart && start <= todayEnd) || (end >= todayStart && end <= todayEnd);
case 'overdue':
@ -91,17 +102,23 @@ export default {
},
watch: {
active() {
this.getDashboardTask();
dashboard() {
this.getTask();
},
taskId(id) {
if (id == 0 && this.active) {
this.$store.dispatch("getProjectStatistics");
}
}
},
methods: {
getDashboardTask() {
let payload = {};
switch (this.active) {
getTask() {
let data = {};
switch (this.dashboard) {
case 'today':
payload = {
data = {
time: [
$A.formatDate("Y-m-d 00:00:00"),
$A.formatDate("Y-m-d 23:59:59")
@ -109,7 +126,7 @@ export default {
}
break;
case 'overdue':
payload = {
data = {
time_before: $A.formatDate("Y-m-d 00:00:00")
}
break;
@ -118,9 +135,8 @@ export default {
}
//
this.loadIng++;
this.$store.dispatch("getTaskList", payload).then(({data}) => {
this.$store.dispatch("getTasks", data).then(() => {
this.loadIng--;
this.$store.dispatch("saveCalendarTask", data.data)
}).catch(() => {
this.loadIng--;
})

View File

@ -168,7 +168,7 @@ export default {
state.userToken = userInfo.token;
state.userIsAdmin = state.method.inArray('admin', userInfo.identity);
state.method.setStorage("userInfo", state.userInfo);
dispatch("getProjectList");
dispatch("getProjects");
dispatch("getDialogMsgUnread");
dispatch("websocketConnection");
resolve()
@ -260,267 +260,304 @@ export default {
});
},
/** *****************************************************************************************/
/** ************************************** 项目 **********************************************/
/** *****************************************************************************************/
/**
* 保存项目信息
* 保存项目数据
* @param state
* @param dispatch
* @param data
*/
saveProject({state}, data) {
saveProject({state, dispatch}, data) {
if (state.method.isArray(data)) {
if (state.projectDetail.id) {
const project = data.find(({id}) => id == state.projectDetail.id);
if (project) {
state.projectDetail = Object.assign({}, state.projectDetail, project)
}
}
state.projectList = data;
data.forEach((project) => {
dispatch("saveProject", project)
});
return;
} else if (state.method.isJson(data)) {
if (data.id == state.projectDetail.id) {
state.projectDetail = Object.assign({}, state.projectDetail, data)
}
let index = state.projectList.findIndex(({id}) => id == data.id);
let index = state.projects.findIndex(({id}) => id == data.id);
if (index > -1) {
state.projectList.splice(index, 1, Object.assign({}, state.projectList[index], data));
state.projects.splice(index, 1, Object.assign(state.projects[index], data));
} else {
state.projectList.unshift(data);
state.projects.push(data);
}
}
state.method.setStorage("cacheProjectList", state.cacheProjectList = state.projectList);
state.method.setStorage("cacheProjects", state.cacheProjects = state.projects);
},
/**
* 获取项目列表
* 获取项目
* @param state
* @param dispatch
*/
getProjectList({state, dispatch}) {
getProjects({state, dispatch}) {
if (state.userId === 0) {
state.projectList = [];
state.projects = [];
return;
}
if (state.cacheProjectList.length > 0) {
state.projectList = state.cacheProjectList;
if (state.cacheProjects.length > 0) {
state.projects = state.cacheProjects;
}
dispatch("call", {
url: 'project/lists',
}).then(result => {
dispatch("saveProject", result.data.data);
}).catch(result => {
$A.modalError(result.msg);
//
});
},
/**
* 获取项目信息
* 获取单个项目
* @param state
* @param dispatch
* @param data {id}
*/
getProjectBasic({state, dispatch}, data) {
getProjectOne({state, dispatch}, data) {
if (state.method.runNum(data.id) === 0) {
return;
}
dispatch("call", {
url: 'project/basic',
url: 'project/one',
data: {
project_id: data.id,
},
}).then(result => {
dispatch("saveProject", result.data);
});
},
/**
* 获取项目详情
* @param state
* @param dispatch
* @param data {id}
*/
getProjectDetail({state, dispatch}, data) {
if (state.method.runNum(data.id) === 0) {
return;
}
const project = state.cacheProjectList.find(({id}) => id == data.id);
if (project) {
state.projectDetail = Object.assign({project_column: [], project_user: []}, project);
} else {
state.projectDetail.id = data.id;
}
//
state.projectLoad++;
dispatch("call", {
url: 'project/detail',
data: {
project_id: data.id,
},
}).then(result => {
state.projectLoad--;
dispatch("saveProject", result.data);
}).catch(result => {
state.projectLoad--;
$A.modalError(result.msg);
//
});
},
/**
* 删除项目信息
* 删除项目
* @param state
* @param data {id}
*/
removeProject({state}, data) {
let index = state.projectList.findIndex(({id}) => id == data.id);
if (index > -1) {
state.projectList.splice(index, 1);
state.method.setStorage("cacheProjectList", state.cacheProjectList = state.projectList);
if (state.method.runNum(data.id) === 0) {
return;
}
if (state.projectDetail.id == data.id) {
const project = state.projectList.find(({id}) => id && id != data.id);
let index = state.projects.findIndex(({id}) => id == data.id);
if (index > -1) {
state.projects.splice(index, 1);
}
if (state.projectId == data.id) {
const project = state.projects.find(({id}) => id && id != data.id);
if (project) {
$A.goForward({path: '/manage/project/' + project.id});
} else {
$A.goForward({path: '/manage/dashboard'});
}
}
//
dispatch("call", {
url: 'project/delete',
data: {
project_id: data.id,
},
}).then(result => {
state.method.setStorage("cacheProjects", state.cacheProjects = state.projects);
}).catch(result => {
//
});
},
/**
* 保存任务信息
* 获取项目统计
* @param state
* @param dispatch
*/
getProjectStatistics({state, dispatch}) {
dispatch("call", {
url: 'project/statistics',
}).then(({data}) => {
state.projectStatistics = data;
});
},
/** *****************************************************************************************/
/** ************************************** 列表 **********************************************/
/** *****************************************************************************************/
/**
* 保存列表数据
* @param state
* @param dispatch
* @param data
*/
saveColumn({state, dispatch}, data) {
if (state.method.isArray(data)) {
data.forEach((column) => {
dispatch("saveColumn", column)
});
return;
} else if (state.method.isJson(data)) {
let index = state.columns.findIndex(({id}) => id == data.id);
if (index > -1) {
state.columns.splice(index, 1, Object.assign(state.columns[index], data));
} else {
state.columns.push(data);
}
}
state.method.setStorage("cacheColumns", state.cacheColumns = state.columns);
},
/**
* 获取列表
* @param state
* @param dispatch
* @param data {project_id}
*/
getColumns({state, dispatch}, data) {
if (state.userId === 0) {
state.columns = [];
return;
}
if (state.cacheColumns.length > 0) {
state.columns = state.cacheColumns;
}
dispatch("call", {
url: 'project/column/lists',
data: {
project_id: data.project_id
}
}).then(result => {
dispatch("saveColumn", result.data.data);
}).catch(result => {
//
});
},
/**
* 删除列表
* @param state
* @param data {id}
*/
removeColumn({state}, data) {
if (state.method.runNum(data.id) === 0) {
return;
}
let index = state.columns.findIndex(({id}) => id == data.id);
if (index > -1) {
state.columns.splice(index, 1);
}
//
dispatch("call", {
url: 'project/column/delete',
data: {
column_id: data.id,
},
}).then(result => {
state.method.setStorage("cacheColumns", state.cacheColumns = state.columns);
}).catch(result => {
//
});
},
/** *****************************************************************************************/
/** ************************************** 任务 **********************************************/
/** *****************************************************************************************/
/**
* 保存任务数据
* @param state
* @param dispatch
* @param data
*/
saveTask({state, dispatch}, data) {
state.projectDetail.project_column.some(({project_task}) => {
let index = project_task.findIndex(({id}) => id === data.id);
if (index > -1) {
project_task.splice(index, 1, Object.assign(project_task[index], data))
return true;
}
});
if (data.id == state.projectOpenTask.id) {
state.projectOpenTask = Object.assign({}, state.projectOpenTask, data);
} else if (data.parent_id == state.projectOpenTask.id && state.projectOpenTask.sub_task) {
let index = state.projectOpenTask.sub_task.findIndex(({id}) => id === data.id);
if (index > -1) {
state.projectOpenTask.sub_task.splice(index, 1, Object.assign(state.projectOpenTask.sub_task[index], data))
}
}
dispatch("saveCalendarTask", data)
},
/**
* 保存任务信息日历任务
* @param state
* @param dispatch
* @param data
*/
saveCalendarTask({state, dispatch}, data) {
if (state.method.isArray(data)) {
data.forEach((task) => {
dispatch("saveCalendarTask", task)
dispatch("saveTask", task)
});
return;
}
if (data.parent_id > 0) {
return;
}
if (!data.start_at || !data.end_at) {
return;
}
if (!data.owner) {
return;
}
let task = {
id: data.id,
calendarId: String(data.project_id),
title: data.name,
body: data.desc,
category: 'allday',
start: new Date(data.start_at).toISOString(),
end: new Date(data.end_at).toISOString(),
color: "#515a6e",
bgColor: data.color || '#E3EAFD',
borderColor: data.p_color,
complete_at: data.complete_at,
priority: '',
preventClick: true,
isChecked: false,
};
if (data.p_name) {
task.priority = '<span class="priority" style="background-color:' + data.p_color + '">' + data.p_name + '</span>';
}
if (data.overdue) {
task.title = '[' + $A.L('超期') + '] ' + task.title
task.color = "#f56c6c"
task.bgColor = "#fef0f0"
task.priority+= '<span class="overdue">' + $A.L('超期未完成') + '</span>';
}
if (!task.borderColor) {
task.borderColor = task.bgColor;
}
let index = state.calendarTask.findIndex(({id}) => id === data.id);
if (index > -1) {
state.calendarTask.splice(index, 1, Object.assign(state.calendarTask[index], task))
} else {
state.calendarTask.push(task)
}
},
/**
* 获取任务统计
* @param state
* @param dispatch
*/
getTaskStatistics({state, dispatch}) {
dispatch("call", {
url: 'project/task/statistics',
}).then(({data}) => {
state.projectTaskStatistics = data;
});
},
/**
* 获取任务列表
* @param state
* @param dispatch
* @param whereData
* @returns {Promise<unknown>}
*/
getTaskList({state, dispatch}, whereData) {
return new Promise(function (resolve, reject) {
if (state.userId === 0) {
reject()
return;
} else if (state.method.isJson(data)) {
let index = state.tasks.findIndex(({id}) => id == data.id);
if (index > -1) {
state.tasks.splice(index, 1, Object.assign(state.tasks[index], data));
} else {
state.tasks.push(data);
}
dispatch("call", {
url: 'project/task/lists',
data: whereData,
}).then(result => {
resolve(result)
}).catch(result => {
reject(result)
});
}
state.method.setStorage("cacheTasks", state.cacheTasks = state.tasks);
},
/**
* 获取任务
* @param state
* @param dispatch
* @param data {project_id, parent_id}
*/
getTasks({state, dispatch}, data) {
if (state.userId === 0) {
state.tasks = [];
return;
}
if (state.cacheTasks.length > 0) {
state.tasks = state.cacheTasks;
}
dispatch("call", {
url: 'project/task/lists',
data: data
}).then(result => {
dispatch("saveTask", result.data.data);
}).catch(result => {
//
});
},
/**
* 获取任务信息
* 获取单个任务
* @param state
* @param dispatch
* @param task_id
*/
getTaskOne({state, dispatch}, task_id) {
if (state.method.runNum(task_id) === 0) {
return;
}
dispatch("call", {
url: 'project/task/one',
data: {
task_id,
},
}).then(result => {
dispatch("saveTask", result.data);
}).catch(result => {
//
});
},
/**
* 删除或归档任务
* @param state
* @param dispatch
* @param data {id, type}
* @returns {Promise<unknown>}
*/
getTaskBasic({state, dispatch}, task_id) {
taskArchivedOrRemove({state, dispatch}, data) {
return new Promise(function (resolve, reject) {
if (state.method.runNum(data.id) === 0) {
return;
}
let index = state.tasks.findIndex(({id}) => id == data.id);
if (index > -1) {
state.tasks.splice(index, 1);
}
//
dispatch("call", {
url: 'project/task/basic',
url: 'project/task/' + data.type,
data: {
task_id,
task_id: data.id,
},
}).then(result => {
dispatch("saveTask", result.data);
state.method.setStorage("cacheTasks", state.cacheTasks = state.tasks);
resolve(result)
}).catch(result => {
dispatch("getTaskOne", data.id);
reject(result)
});
});
@ -541,15 +578,14 @@ export default {
task_id,
},
}).then(result => {
const {content} = result.data;
state.projectTaskContent[task_id] = content;
if (task_id == state.projectOpenTask.id) {
state.projectOpenTask = Object.assign({}, state.projectOpenTask, {content: content || ''});
let index = state.taskContents.findIndex(({id}) => id == result.data.id)
if (index > -1) {
state.taskContents.splice(index, 1, result.data)
} else {
state.taskContents.push(result.data)
}
resolve(result)
}).catch(result => {
reject(result)
});
}).catch(reject);
});
},
@ -568,40 +604,16 @@ export default {
task_id,
},
}).then(result => {
state.projectTaskFiles[task_id] = result.data;
if (task_id == state.projectOpenTask.id) {
state.projectOpenTask = Object.assign({}, state.projectOpenTask, {files: result.data});
}
result.data.forEach((data) => {
let index = state.taskFiles.findIndex(({id}) => id == data.id)
if (index > -1) {
state.taskFiles.splice(index, 1, data)
} else {
state.taskFiles.push(data)
}
})
resolve(result)
}).catch(result => {
reject(result)
});
});
},
/**
* 获取子任务
* @param state
* @param dispatch
* @param task_id
* @returns {Promise<unknown>}
*/
getSubTask({state, dispatch}, task_id) {
return new Promise(function (resolve, reject) {
dispatch("call", {
url: 'project/task/sublist',
data: {
task_id,
},
}).then(result => {
state.projectSubTask[task_id] = result.data;
if (task_id == state.projectOpenTask.id) {
state.projectOpenTask = Object.assign({}, state.projectOpenTask, {sub_task: result.data});
}
resolve(result)
}).catch(result => {
reject(result)
});
}).catch(reject);
});
},
@ -612,35 +624,23 @@ export default {
* @param task_id
*/
openTask({state, dispatch}, task_id) {
let data = state.method.isJson(task_id) ? task_id : {id: task_id};
state.projectDetail.project_column.some(({project_task}) => {
const task = project_task.find(({id}) => id === data.id);
if (task) {
data = Object.assign(data, task);
return true
}
});
//
data.content = state.projectTaskContent[data.id] || ""
data.files = state.projectTaskFiles[data.id] || []
data.sub_task = state.projectSubTask[data.id] || []
//
state.projectOpenTask = Object.assign({}, data, {_show: true});
dispatch("getTaskBasic", data.id);
dispatch("getTaskContent", data.id);
dispatch("getTaskFiles", data.id);
dispatch("getSubTask", data.id);
state.taskId = task_id;
if (task_id > 0) {
dispatch("getTaskOne", task_id);
dispatch("getTaskContent", task_id);
dispatch("getTaskFiles", task_id);
dispatch("getTasks", {parent_id: task_id});
}
},
/**
* 添加任务
* @param state
* @param dispatch
* @param commit
* @param data
* @returns {Promise<unknown>}
*/
taskAdd({state, dispatch, commit}, data) {
taskAdd({state, dispatch}, data) {
return new Promise(function (resolve, reject) {
const post = state.method.cloneJSON(state.method.date2string(data));
if (state.method.isArray(post.column_id)) post.column_id = post.column_id.find((val) => val)
@ -651,32 +651,31 @@ export default {
data: post,
method: 'post',
}).then(result => {
commit("taskAddSuccess", result.data)
const {new_column, task} = result.data;
dispatch("saveColumn", new_column)
dispatch("saveTask", task)
resolve(result)
}).catch(result => {
reject(result)
});
}).catch(reject);
});
},
/**
* 添加子任务
* @param dispatch
* @param commit
* @param data {task_id, name}
* @returns {Promise<unknown>}
*/
taskAddSub({dispatch, commit}, data) {
taskAddSub({dispatch}, data) {
return new Promise(function (resolve, reject) {
dispatch("call", {
url: 'project/task/addsub',
data: data,
}).then(result => {
commit("taskAddSuccess", result.data)
const {new_column, task} = result.data;
dispatch("saveColumn", new_column)
dispatch("saveTask", task)
resolve(result)
}).catch(result => {
reject(result)
});
}).catch(reject);
});
},
@ -684,11 +683,10 @@ export default {
* 更新任务
* @param state
* @param dispatch
* @param commit
* @param data
* @returns {Promise<unknown>}
*/
taskUpdate({state, dispatch, commit}, data) {
taskUpdate({state, dispatch}, data) {
return new Promise(function (resolve, reject) {
const post = state.method.cloneJSON(state.method.date2string(data));
if (state.method.isArray(post.owner)) post.owner = post.owner.find((id) => id)
@ -698,42 +696,10 @@ export default {
data: post,
method: 'post',
}).then(result => {
const {data} = result;
if (data.is_update_content === true) {
state.projectTaskContent[data.id] = post['content'];
if (data.id == state.projectOpenTask.id) {
state.projectOpenTask = Object.assign({}, state.projectOpenTask, {content: post['content']});
}
data.is_update_content = false;
}
commit("taskUpdateSuccess", data)
dispatch("saveTask", result.data)
resolve(result)
}).catch(result => {
dispatch("getTaskBasic", post.task_id);
reject(result)
});
});
},
/**
* 删除或归档任务
* @param dispatch
* @param commit
* @param data {task_id, type}
* @returns {Promise<unknown>}
*/
taskArchivedOrRemove({dispatch, commit}, data) {
let {task_id, type} = data;
return new Promise(function (resolve, reject) {
dispatch("call", {
url: 'project/task/' + type,
data: {
task_id,
},
}).then(result => {
commit("taskDeleteSuccess", result.data);
resolve(result);
}).catch(result => {
dispatch("getTaskOne", post.task_id);
reject(result)
});
});
@ -752,12 +718,15 @@ export default {
}).then(result => {
state.taskPriority = result.data;
resolve(result)
}).catch(result => {
reject(result)
});
}).catch(reject);
});
},
/** *****************************************************************************************/
/** ************************************** 会话 **********************************************/
/** *****************************************************************************************/
/**
* 更新会话数据
* @param state
@ -980,10 +949,10 @@ export default {
return;
}
if (state.method.isJson(data)) {
state.projectDetail.project_column.some(({project_task}) => {
const task = project_task.find(({dialog_id}) => dialog_id === data.dialog_id);
if (task) task.msg_num++;
});
const task = state.tasks.find(({dialog_id}) => dialog_id === data.dialog_id);
if (task) {
task.msg_num++;
}
if (data.id && state.dialogMsgList.find(m => m.id == data.id)) {
data = null;
}
@ -1152,10 +1121,8 @@ export default {
commit("dialogMoveToTop", dialog_id);
}
// 新增任务消息数量
state.projectDetail.project_column.some(({project_task}) => {
const task = project_task.find(({dialog_id}) => dialog_id === data.dialog_id);
if (task) task.msg_num++;
});
const task = state.tasks.find(({dialog_id}) => dialog_id === data.dialog_id);
if (task) task.msg_num++;
// 新增总未读数
if (data.userid !== state.userId) state.dialogMsgUnread++;
}

View File

@ -1,3 +1,20 @@
export default {
taskData(state) {
let taskId = state.taskId;
if (taskId == 0) {
taskId = state.method.runNum(window.__taskId);
}
if (taskId > 0) {
window.__taskId = taskId;
const task = state.tasks.find(({id}) => id == taskId);
if (task) {
const content = state.taskContents.find(({task_id}) => task_id == taskId);
task.content = content ? content.content : '';
task.files = state.taskFiles.filter(({task_id}) => task_id == taskId);
task.sub_task = state.tasks.filter(({parent_id}) => parent_id == taskId);
return task;
}
}
return {};
},
}

View File

@ -1,174 +1,4 @@
export default {
/**
* 添加列表
* @param state
* @param data
*/
columnAddSuccess(state, data) {
if (state.projectDetail.id == data.project_id) {
let index = state.projectDetail.project_column.findIndex(({id}) => id === data.id);
if (index === -1) {
state.projectDetail.project_column.push(data);
}
}
},
/**
* 更新列表
* @param state
* @param data
*/
columnUpdateSuccess(state, data) {
if (state.projectDetail.id == data.project_id) {
let index = state.projectDetail.project_column.findIndex(({id}) => id === data.id);
if (index > -1) {
state.projectDetail.project_column.splice(index, 1, Object.assign({}, state.projectDetail.project_column[index], data));
}
}
},
/**
* 删除列表
* @param state
* @param data {id, project_id}
*/
columnDeleteSuccess(state, data) {
if (state.projectDetail.id == data.project_id) {
let index = state.projectDetail.project_column.findIndex(({id}) => id === data.id);
if (index > -1) {
state.projectDetail.project_column.splice(index, 1);
}
this.dispatch("getProjectBasic", {id: data.project_id});
}
},
/**
* 添加任务
* @param state
* @param data
*/
taskAddSuccess(state, data) {
const {task, in_top, new_column} = data;
if (task.parent_id == 0) {
// 添加任务
if (state.projectDetail.id == task.project_id) {
if (new_column) {
state.projectDetail.project_column.push(new_column);
}
const column = state.projectDetail.project_column.find(({id}) => id === task.column_id);
if (column) {
let index = column.project_task.findIndex(({id}) => id === task.id)
if (index === -1) {
if (in_top) {
column.project_task.unshift(task);
} else {
column.project_task.push(task);
}
}
}
}
this.dispatch("getProjectBasic", {id: task.project_id});
} else {
// 添加子任务
if (state.projectDetail.id == task.project_id) {
const column = state.projectDetail.project_column.find(({id}) => id === task.column_id);
if (column) {
const project_task = column.project_task.find(({id}) => id === task.parent_id)
if (project_task && project_task.sub_task) {
let index = project_task.sub_task.findIndex(({id}) => id === task.id)
if (index === -1) {
project_task.sub_task.push(task);
}
}
}
}
if (task.parent_id == state.projectOpenTask.id) {
let index = state.projectOpenTask.sub_task.findIndex(({id}) => id === task.id)
if (index === -1) {
state.projectOpenTask.sub_task.push(task);
}
}
this.dispatch("getTaskBasic", task.parent_id);
}
this.dispatch("saveTask", task);
},
/**
* 更新任务
* @param state
* @param data
*/
taskUpdateSuccess(state, data) {
if (data.parent_id) {
this.dispatch("getTaskBasic", data.parent_id);
}
if (data.is_update_complete === true) {
this.dispatch("getProjectBasic", {id: data.project_id});
}
if (data.is_update_content === true) {
this.dispatch("getTaskContent", data.id);
}
this.dispatch("saveTask", data);
},
/**
* 任务上传附件
* @param state
* @param data
*/
taskUploadSuccess(state, data) {
if (state.projectOpenTask.id == data.task_id) {
let index = state.projectOpenTask.files.findIndex(({id}) => id == data.id);
if (index > -1) {
state.projectOpenTask.files.splice(index, 1, data);
} else {
state.projectOpenTask.files.push(data)
}
}
state.projectDetail.project_column.some(({project_task}) => {
let task = project_task.find(({id}) => id === data.task_id);
if (task) {
if (!state.method.isJson(task._file_tmp)) task._file_tmp = {}
if (task._file_tmp[data.id] !== true) {
task._file_tmp[data.id] = true;
this.dispatch("saveTask", {
id: task.id,
file_num: task.file_num + 1,
});
}
return true;
}
});
},
/**
* 删除任务
* @param state
* @param data
*/
taskDeleteSuccess(state, data) {
const column = state.projectDetail.project_column.find(({id}) => id === data.column_id);
if (column) {
let index = column.project_task.findIndex(({id}) => id === data.id);
if (index > -1) {
column.project_task.splice(index, 1);
}
}
if (data.id == state.projectOpenTask.id) {
state.projectOpenTask = Object.assign({}, state.projectOpenTask, {_show: false});
} else if (data.parent_id == state.projectOpenTask.id && state.projectOpenTask.sub_task) {
let index = state.projectOpenTask.sub_task.findIndex(({id}) => id === data.id);
if (index > -1) {
state.projectOpenTask.sub_task.splice(index, 1)
}
}
let index = state.calendarTask.findIndex(({id}) => id === data.id);
if (index > -1) {
state.calendarTask.splice(index, 1)
}
this.dispatch("getProjectBasic", {id: data.project_id});
},
/**
* 会话消息列表
* @param state

View File

@ -249,7 +249,9 @@ state.ajaxWsListener = [];
// 数据缓存
state.cacheUserBasic = state.method.getStorageJson("cacheUserBasic");
state.cacheDialogMsg = state.method.getStorageJson("cacheDialogMsg");
state.cacheProjectList = state.method.getStorageArray("cacheProjectList");
state.cacheProjects = state.method.getStorageArray("cacheProjects");
state.cacheColumns = state.method.getStorageArray("cacheColumns");
state.cacheTasks = state.method.getStorageArray("cacheTasks");
// 会员信息
state.userInfo = state.method.getStorageJson("userInfo");
@ -268,15 +270,15 @@ state.wsReadTimeout = null;
state.wsReadWaitList = [];
// 项目任务
state.projectLoad = 0;
state.projectList = state.cacheProjectList;
state.projectDetail = {id: 0, project_column: [], project_user: []};
state.projectOpenTask = {_show: false, id: 0, task_user: [], task_tag: []};
state.projectTaskStatistics = {};
state.projectTaskContent = {};
state.projectTaskFiles = {};
state.projectSubTask = {};
state.calendarTask = [];
state.projects = [];
state.projectStatistics = {};
state.columns = [];
state.tasks = [];
state.taskContents = [];
state.taskFiles = [];
state.taskLogs = [];
state.projectId = 0;
state.taskId = 0;
// 会话聊天
state.dialogId = 0;