将所有任务都取出全部显示,子任务判断显示主任务

This commit is contained in:
kuaifan 2022-01-05 09:30:00 +08:00
parent cc1c425ecf
commit 78f88db560
14 changed files with 268 additions and 234 deletions

View File

@ -63,14 +63,18 @@ class ProjectController extends AbstractController
"archived_userid": 0,
"created_at": "2022-01-02 06:23:15",
"updated_at": "2022-01-02 07:12:33",
"owner": 1, // 是否项目负责人
"owner_userid": 1, // 项目负责人ID
"project_user": [], // 为空数据在one接口返回
"task_num": 9,
"task_complete": 0,
"task_percent": 0,
"task_my_num": 8,
"task_my_complete": 0,
"task_my_percent": 0
"task_my_percent": 0,
},
],
"current_page": 1, // 当前页数
@ -114,7 +118,9 @@ class ProjectController extends AbstractController
//
$list = $builder->orderByDesc('projects.id')->paginate(Base::getPaginate(100, 50));
$list->transform(function (Project $project) use ($user) {
return array_merge($project->toArray(), $project->getTaskStatistics($user->userid));
return array_merge($project->toArray(), $project->getTaskStatistics($user->userid), [
'project_user' => []
]);
});
//
$data = $list->toArray();
@ -151,14 +157,18 @@ class ProjectController extends AbstractController
"archived_userid": 0,
"created_at": "2022-01-02 06:23:15",
"updated_at": "2022-01-02 07:12:33",
"owner": 1, // 是否项目负责人
"owner_userid": 1, // 项目负责人ID
"project_user": [], // 项目成员
"task_num": 9,
"task_complete": 0,
"task_percent": 0,
"task_my_num": 8,
"task_my_complete": 0,
"task_my_percent": 0
"task_my_percent": 0,
}
*/
public function one()
@ -168,7 +178,9 @@ class ProjectController extends AbstractController
$project_id = intval(Request::input('project_id'));
//
$project = Project::userProject($project_id);
$data = array_merge($project->toArray(), $project->getTaskStatistics($user->userid));
$data = array_merge($project->toArray(), $project->getTaskStatistics($user->userid), [
'project_user' => $project->projectUser
]);
//
return Base::retSuccess('success', $data);
}
@ -1122,8 +1134,7 @@ class ProjectController extends AbstractController
'parent_id' => $task->id,
'project_id' => $task->project_id,
'column_id' => $task->column_id,
'start_at' => $task->start_at,
'end_at' => $task->end_at,
'times' => [$task->start_at, $task->end_at],
'owner' => [User::userid()]
]);
$data = [
@ -1198,7 +1209,7 @@ class ProjectController extends AbstractController
$task->updateTask($data, $updateContent, $updateSubTask);
}
$data = ProjectTask::with(['taskUser', 'taskTag'])->find($task->id)->toArray();
$data['is_update_complete'] = $task->parent_id == 0 && $updateComplete;
$data['is_update_complete'] = $updateComplete;
$data['is_update_content'] = $updateContent;
$data['is_update_subtask'] = $updateSubTask;
$task->pushMsg('update', $data);

View File

@ -152,7 +152,7 @@ class Project extends AbstractModel
}
/**
* 获取任务统计
* 获取任务统计数据
* @param $userid
* @return array
*/

View File

@ -76,10 +76,10 @@ export default {
computed: {
...mapState(['userId', 'projects', 'tasks']),
...mapGetters(['myTask']),
...mapGetters(['myTasks', 'transforTasks']),
list() {
const datas = $A.cloneJSON(this.myTask.filter(({end_at}) => {
const datas = this.transforTasks(this.myTasks.filter(({end_at}) => {
return end_at;
}));
return datas.map(data => {
@ -104,11 +104,14 @@ export default {
if (data.p_name) {
task.priority = '<span class="priority" style="background-color:' + data.p_color + '">' + data.p_name + '</span>';
}
if (data.top_task === true) {
task.title = '[' + this.$L('子任务') + '] ' + task.title
if (data.sub_my && data.sub_my.length > 0) {
task.title = `[+${data.sub_my.length}] ${task.title}`
}
if (data.sub_top === true) {
task.title = `[${this.$L('子任务')}] ${task.title}`
}
if (data.overdue) {
task.title = '[' + this.$L('超期') + '] ' + task.title
task.title = `[${this.$L('超期')}] ${task.title}`
task.color = "#f56c6c"
task.bgColor = "#fef0f0"
task.priority+= '<span class="overdue">' + this.$L('超期未完成') + '</span>';

View File

@ -387,7 +387,7 @@ export default {
loadNextPage() {
let topId = this.dialogMsgList[0].id;
this.$store.dispatch('getDialogMsgNextPage', this.dialogId).then(() => {
this.$store.dispatch('getDialogMoreMsgs', this.dialogId).then(() => {
this.$nextTick(() => {
this.topId = topId;
let dom = document.getElementById("view_" + topId);

View File

@ -24,7 +24,7 @@
</div>
</Tooltip>
</li>
<li :class="['project-icon', tablePanel('chat') ? 'active' : '']" @click="$store.dispatch('toggleTablePanel', 'chat')">
<li :class="['project-icon', projectParameters('chat') ? 'active' : '']" @click="$store.dispatch('toggleProjectParameters', 'chat')">
<Icon class="menu-icon" type="ios-chatbubbles" />
<Badge class="menu-badge" :count="msgUnread"></Badge>
</li>
@ -53,24 +53,24 @@
<div v-if="projectData.desc" class="project-subtitle">{{projectData.desc}}</div>
<div class="project-switch">
<div v-if="completedCount > 0" class="project-checkbox">
<Checkbox :value="tablePanel('completedTask')" @on-change="toggleCompleted">{{$L('显示已完成')}}</Checkbox>
<Checkbox :value="projectParameters('completedTask')" @on-change="toggleCompleted">{{$L('显示已完成')}}</Checkbox>
</div>
<div :class="['project-switch-button', !tablePanel('card') ? 'menu' : '']" @click="$store.dispatch('toggleTablePanel', 'card')">
<div :class="['project-switch-button', !projectParameters('card') ? 'menu' : '']" @click="$store.dispatch('toggleProjectParameters', 'card')">
<div><i class="taskfont">&#xe60c;</i></div>
<div><i class="taskfont">&#xe66a;</i></div>
</div>
</div>
</div>
<div v-if="tablePanel('card')" class="project-column">
<div v-if="projectParameters('card')" class="project-column">
<Draggable
:list="projectData.columns"
:list="columnList"
:animation="150"
:disabled="sortDisabled || $store.state.windowMax768"
class="column-list"
tag="ul"
draggable=".column-item"
@sort="sortUpdate(true)">
<li v-for="column in projectData.columns" class="column-item">
<li v-for="column in columnList" class="column-item">
<div
:class="['column-head', column.color ? 'custom-color' : '']"
:style="column.color ? {backgroundColor: column.color} : {}">
@ -255,10 +255,10 @@
</Row>
</div>
<!--我的任务-->
<div :class="['project-table-body', !tablePanel('showMy') ? 'project-table-hide' : '']">
<div :class="['project-table-body', !projectParameters('showMy') ? 'project-table-hide' : '']">
<Row class="task-row">
<Col span="12" class="row-title">
<i class="taskfont" @click="$store.dispatch('toggleTablePanel', 'showMy')">&#xe689;</i>
<i class="taskfont" @click="$store.dispatch('toggleProjectParameters', 'showMy')">&#xe689;</i>
<div class="row-h1">{{$L('我的任务')}}</div>
<div class="row-num">({{myList.length}})</div>
</Col>
@ -267,13 +267,13 @@
<Col span="3"></Col>
<Col span="3"></Col>
</Row>
<TaskRow v-if="tablePanel('showMy')" :list="myList" open-key="my" @command="dropTask" @on-priority="addTaskOpen" fast-add-task/>
<TaskRow v-if="projectParameters('showMy')" :list="transforTasks(myList)" open-key="my" @command="dropTask" @on-priority="addTaskOpen" fast-add-task/>
</div>
<!--协助的任务-->
<div v-if="helpList.length" :class="['project-table-body', !tablePanel('showHelp') ? 'project-table-hide' : '']">
<div v-if="helpList.length" :class="['project-table-body', !projectParameters('showHelp') ? 'project-table-hide' : '']">
<Row class="task-row">
<Col span="12" class="row-title">
<i class="taskfont" @click="$store.dispatch('toggleTablePanel', 'showHelp')">&#xe689;</i>
<i class="taskfont" @click="$store.dispatch('toggleProjectParameters', 'showHelp')">&#xe689;</i>
<div class="row-h1">{{$L('协助的任务')}}</div>
<div class="row-num">({{helpList.length}})</div>
</Col>
@ -282,28 +282,28 @@
<Col span="3"></Col>
<Col span="3"></Col>
</Row>
<TaskRow v-if="tablePanel('showHelp')" :list="helpList" open-key="help" @command="dropTask" @on-priority="addTaskOpen"/>
<TaskRow v-if="projectParameters('showHelp')" :list="helpList" open-key="help" @command="dropTask" @on-priority="addTaskOpen"/>
</div>
<!--未完成任务-->
<div v-if="projectData.task_num > 0" :class="['project-table-body', !tablePanel('showUndone') ? 'project-table-hide' : '']">
<div v-if="projectData.task_num > 0" :class="['project-table-body', !projectParameters('showUndone') ? 'project-table-hide' : '']">
<Row class="task-row">
<Col span="12" class="row-title">
<i class="taskfont" @click="$store.dispatch('toggleTablePanel', 'showUndone')">&#xe689;</i>
<i class="taskfont" @click="$store.dispatch('toggleProjectParameters', 'showUndone')">&#xe689;</i>
<div class="row-h1">{{$L('未完成任务')}}</div>
<div class="row-num">({{undoneList.length}})</div>
<div class="row-num">({{unList.length}})</div>
</Col>
<Col span="3"></Col>
<Col span="3"></Col>
<Col span="3"></Col>
<Col span="3"></Col>
</Row>
<TaskRow v-if="tablePanel('showUndone')" :list="undoneList" open-key="undone" @command="dropTask" @on-priority="addTaskOpen"/>
<TaskRow v-if="projectParameters('showUndone')" :list="unList" open-key="undone" @command="dropTask" @on-priority="addTaskOpen"/>
</div>
<!--已完成任务-->
<div v-if="projectData.task_num > 0" :class="['project-table-body', !tablePanel('showCompleted') ? 'project-table-hide' : '']">
<div v-if="projectData.task_num > 0" :class="['project-table-body', !projectParameters('showCompleted') ? 'project-table-hide' : '']">
<Row class="task-row">
<Col span="12" class="row-title">
<i class="taskfont" @click="$store.dispatch('toggleTablePanel', 'showCompleted')">&#xe689;</i>
<i class="taskfont" @click="$store.dispatch('toggleProjectParameters', 'showCompleted')">&#xe689;</i>
<div class="row-h1">{{$L('已完成任务')}}</div>
<div class="row-num">({{completedList.length}})</div>
</Col>
@ -312,7 +312,7 @@
<Col span="3"></Col>
<Col span="3"></Col>
</Row>
<TaskRow v-if="tablePanel('showCompleted')" :list="completedList" open-key="completed" @command="dropTask" @on-priority="addTaskOpen"/>
<TaskRow v-if="projectParameters('showCompleted')" :list="completedList" open-key="completed" @command="dropTask" @on-priority="addTaskOpen"/>
</div>
</div>
@ -504,7 +504,7 @@ export default {
}, 1000);
//
this.projectDialogSubscribe = Store.subscribe('onProjectDialogBack', () => {
this.$store.dispatch('toggleTablePanel', 'chat');
this.$store.dispatch('toggleProjectParameters', 'chat');
});
},
@ -530,9 +530,7 @@ export default {
'columns',
]),
...mapGetters(['projectData', 'tablePanel']),
...mapGetters(['myTask']),
...mapGetters(['projectData', 'projectParameters', 'myTasks', 'transforTasks']),
userWaitRemove() {
const {userids, useridbak} = this.userData;
@ -557,7 +555,7 @@ export default {
panelTask() {
const {searchText} = this;
return function (list) {
if (!this.tablePanel('completedTask')) {
if (!this.projectParameters('completedTask')) {
list = list.filter(({complete_at}) => {
return !complete_at;
});
@ -571,13 +569,36 @@ export default {
}
},
columnList() {
const {projectId, columns, tasks} = this;
let list = $A.cloneJSON(columns.filter(({project_id}) => {
return project_id == projectId
})).sort((a, b) => {
if (a.sort != b.sort) {
return a.sort - b.sort;
}
return a.id - b.id;
});
list.forEach((column) => {
column.tasks = this.transforTasks(tasks.filter((task) => {
return task.column_id == column.id;
})).sort((a, b) => {
if (a.sort != b.sort) {
return a.sort - b.sort;
}
return a.id - b.id;
});
})
return Object.freeze(list);
},
myList() {
const {projectId, myTask, searchText, completeTask, sortField, sortType} = this;
const array = myTask.filter((task) => {
const {projectId, myTasks, searchText, completeTask, sortField, sortType} = this;
const array = myTasks.filter((task) => {
if (task.project_id != projectId) {
return false;
}
if (!this.tablePanel('completedTask')) {
if (!this.projectParameters('completedTask')) {
if (task.complete_at && !completeTask.find(id => id == task.id)) {
return false;
}
@ -610,7 +631,7 @@ export default {
if (task.project_id != projectId || task.parent_id > 0) {
return false;
}
if (!this.tablePanel('completedTask')) {
if (!this.projectParameters('completedTask')) {
if (task.complete_at && !completeTask.find(id => id == task.id)) {
return false;
}
@ -637,13 +658,13 @@ export default {
});
},
undoneList() {
unList() {
const {projectId, tasks, searchText, completeTask, sortField, sortType} = this;
const array = tasks.filter((task) => {
if (task.project_id != projectId || task.parent_id > 0) {
return false;
}
if (!this.tablePanel('completedTask')) {
if (!this.projectParameters('completedTask')) {
if (task.complete_at && !completeTask.find(id => id == task.id)) {
return false;
}
@ -670,16 +691,6 @@ export default {
});
},
completedCount() {
const {projectId, tasks} = this;
return tasks.filter((task) => {
if (task.project_id != projectId || task.parent_id > 0) {
return false;
}
return task.complete_at;
}).length;
},
completedList() {
const {projectId, tasks, searchText} = this;
const array = tasks.filter((task) => {
@ -700,17 +711,14 @@ export default {
});
},
expiresFormat() {
const {nowTime} = this;
return function (date) {
let time = Math.round($A.Date(date).getTime() / 1000) - nowTime;
if (time < 86400 * 7 && time > 0 ) {
return this.formatSeconds(time);
} else if (time <= 0) {
return '-' + this.formatSeconds(time * -1);
completedCount() {
const {projectId, tasks} = this;
return tasks.filter((task) => {
if (task.project_id != projectId || task.parent_id > 0) {
return false;
}
return this.formatTime(date)
}
return task.complete_at;
}).length;
},
},
@ -726,7 +734,7 @@ export default {
methods: {
getSort() {
const sortData = [];
this.projectData.columns.forEach((column) => {
this.columnList.forEach((column) => {
sortData.push({
id: column.id,
task: column.tasks.map(({id}) => id)
@ -1168,7 +1176,7 @@ export default {
taskIsHidden(task) {
const {name, desc, complete_at} = task;
const {searchText} = this;
if (!this.tablePanel('completedTask')) {
if (!this.projectParameters('completedTask')) {
if (complete_at) {
return true;
}
@ -1221,7 +1229,7 @@ export default {
},
toggleCompleted() {
this.$store.dispatch('toggleTablePanel', 'completedTask');
this.$store.dispatch('toggleProjectParameters', 'completedTask');
this.completeTask = [];
},
@ -1260,6 +1268,16 @@ export default {
else if (seconds > 0) duration = this.formatBit(seconds) + "s";
return duration;
},
expiresFormat(date) {
let time = Math.round($A.Date(date).getTime() / 1000) - this.nowTime;
if (time < 86400 * 7 && time > 0 ) {
return this.formatSeconds(time);
} else if (time <= 0) {
return '-' + this.formatSeconds(time * -1);
}
return this.formatTime(date)
}
}
}
</script>

View File

@ -595,19 +595,6 @@ export default {
}
},
expiresFormat() {
const {nowTime} = this;
return function (date) {
let time = Math.round($A.Date(date).getTime() / 1000) - nowTime;
if (time < 86400 * 7 && time > 0 ) {
return this.formatSeconds(time);
} else if (time <= 0) {
return '-' + this.formatSeconds(time * -1);
}
return this.formatTime(date)
}
},
cutTime() {
const {nowTime, taskDetail} = this;
let string = "";
@ -800,6 +787,16 @@ export default {
return duration;
},
expiresFormat(date) {
let time = Math.round($A.Date(date).getTime() / 1000) - this.nowTime;
if (time < 86400 * 7 && time > 0 ) {
return this.formatSeconds(time);
} else if (time <= 0) {
return '-' + this.formatSeconds(time * -1);
}
return this.formatTime(date)
},
onNameKeydown(e) {
if (e.keyCode === 13) {
if (e.shiftKey) {

View File

@ -2,10 +2,10 @@
<div class="task-rows">
<div v-for="(item, key) in list" :key="key">
<Row class="task-row" :style="item.color ? {backgroundColor: item.color, borderBottomColor: item.color} : {}">
<em v-if="item.p_name && isTopTask(item)" class="priority-color" :style="{backgroundColor:item.p_color}"></em>
<em v-if="item.p_name" class="priority-color" :style="{backgroundColor:item.p_color}"></em>
<Col span="12" :class="['row-name', item.complete_at ? 'complete' : '']">
<Icon
v-if="item.sub_num > 0 || (item.parent_id===0 && fastAddTask)"
v-if="(item.sub_num > 0 && item.sub_top !== true) || (item.parent_id===0 && fastAddTask)"
:class="['sub-icon', taskOpen[item.id] ? 'active' : '']"
type="ios-arrow-forward"
@click="getSublist(item)"/>
@ -50,7 +50,11 @@
</template>
</EDropdownMenu>
</EDropdown>
<div class="item-title" @click="openTask(item)"><span v-if="item.top_task === true">{{$L('子任务')}}</span>{{item.name}}</div>
<div class="item-title" @click="openTask(item)">
<span v-if="item.sub_top === true">{{$L('子任务')}}</span>
<span v-if="item.sub_my && item.sub_my.length > 0">+{{item.sub_my.length}}</span>
{{item.name}}
</div>
<div class="item-icons" @click="openTask(item)">
<div v-if="item.desc" class="item-icon">
<i class="taskfont">&#xe71a;</i>
@ -71,11 +75,10 @@
</Col>
<Col span="3" class="row-column">
<EDropdown
v-if="isTopTask(item)"
trigger="click"
size="small"
placement="bottom"
:disabled="item.top_task === true"
:disabled="item.sub_top === true"
@command="dropTask(item, $event)">
<div class="task-column">{{columnName(item.column_id)}}</div>
<EDropdownMenu slot="dropdown">
@ -87,11 +90,10 @@
</Col>
<Col span="3" class="row-priority">
<EDropdown
v-if="item.p_name && isTopTask(item)"
trigger="click"
size="small"
placement="bottom"
:disabled="item.top_task === true"
:disabled="item.sub_top === true"
@command="dropTask(item, $event)">
<TaskPriority :backgroundColor="item.p_color">{{item.p_name}}</TaskPriority>
<EDropdownMenu slot="dropdown">
@ -197,25 +199,8 @@ export default {
});
}
},
expiresFormat() {
const {nowTime} = this;
return function (date) {
let time = Math.round($A.Date(date).getTime() / 1000) - nowTime;
if (time < 86400 * 7 && time > 0 ) {
return this.formatSeconds(time);
} else if (time <= 0) {
return '-' + this.formatSeconds(time * -1);
}
return this.formatTime(date)
}
},
},
methods: {
isTopTask(item) {
return item.parent_id === 0 || item.top_task === true
},
columnName(column_id) {
const column = this.columns.find(({id}) => id == column_id)
return column ? column.name : '';
@ -230,6 +215,10 @@ export default {
},
getSublist(task) {
if (task.sub_top === true) {
this.openTask(task);
return;
}
if (this.taskOpen[task.id] === true) {
this.$set(this.taskOpen, task.id, false);
return;
@ -304,7 +293,17 @@ export default {
else if (minutes > 0) duration = this.formatBit(minutes) + ":" + this.formatBit(seconds);
else if (seconds > 0) duration = this.formatBit(seconds) + "s";
return duration;
}
},
expiresFormat(date) {
let time = Math.round($A.Date(date).getTime() / 1000) - this.nowTime;
if (time < 86400 * 7 && time > 0 ) {
return this.formatSeconds(time);
} else if (time <= 0) {
return '-' + this.formatSeconds(time * -1);
}
return this.formatTime(date)
},
}
}
</script>

View File

@ -79,7 +79,11 @@
</template>
</EDropdownMenu>
</EDropdown>
<div class="item-title"><span v-if="item.top_task === true">{{$L('子任务')}}</span>{{item.name}}</div>
<div class="item-title">
<span v-if="item.sub_top === true">{{$L('子任务')}}</span>
<span v-if="item.sub_my && item.sub_my.length > 0">+{{item.sub_my.length}}</span>
{{item.name}}
</div>
<div v-if="item.desc" class="item-icon">
<i class="taskfont">&#xe71a;</i>
</div>
@ -137,7 +141,7 @@ export default {
computed: {
...mapState(['userInfo', 'projects', 'tasks', 'taskId']),
...mapGetters(['dashboardTask']),
...mapGetters(['dashboardTask', 'transforTasks']),
title() {
const {dashboard} = this;
@ -156,10 +160,10 @@ export default {
let data = [];
switch (dashboard) {
case 'today':
data = $A.cloneJSON(this.dashboardTask.today);
data = this.transforTasks(this.dashboardTask.today);
break
case 'overdue':
data = $A.cloneJSON(this.dashboardTask.overdue);
data = this.transforTasks(this.dashboardTask.overdue);
break
}
if (completeTask.length > 0) {
@ -173,19 +177,6 @@ export default {
return $A.Date(a.end_at) - $A.Date(b.end_at);
});
},
expiresFormat() {
const {nowTime} = this;
return function (date) {
let time = Math.round($A.Date(date).getTime() / 1000) - nowTime;
if (time < 86400 * 7 && time > 0 ) {
return this.formatSeconds(time);
} else if (time <= 0) {
return '-' + this.formatSeconds(time * -1);
}
return this.formatTime(date)
}
},
},
watch: {
@ -323,6 +314,16 @@ export default {
else if (seconds > 0) duration = this.formatBit(seconds) + "s";
return duration;
},
expiresFormat(date) {
let time = Math.round($A.Date(date).getTime() / 1000) - this.nowTime;
if (time < 86400 * 7 && time > 0 ) {
return this.formatSeconds(time);
} else if (time <= 0) {
return '-' + this.formatSeconds(time * -1);
}
return this.formatTime(date)
}
}
}
</script>

View File

@ -1,7 +1,7 @@
<template>
<div class="page-project">
<ProjectList/>
<ProjectDialog v-if="tablePanel('chat')"/>
<ProjectDialog v-if="projectParameters('chat')"/>
</div>
</template>
@ -22,7 +22,7 @@ export default {
},
computed: {
...mapGetters(['tablePanel']),
...mapGetters(['projectParameters']),
},
watch: {

View File

@ -138,8 +138,8 @@ export default {
* @param state
* @param data|{key, project_id}
*/
toggleTablePanel({state}, data) {
$A.execMainDispatch("toggleTablePanel", data)
toggleProjectParameters({state}, data) {
$A.execMainDispatch("toggleProjectParameters", data)
//
let key = data;
let project_id = state.projectId;
@ -148,9 +148,9 @@ export default {
project_id = data.project_id;
}
if (project_id) {
let index = state.cacheTablePanel.findIndex(item => item.project_id == project_id)
let index = state.cacheProjectParameters.findIndex(item => item.project_id == project_id)
if (index === -1) {
state.cacheTablePanel.push({
state.cacheProjectParameters.push({
project_id,
card: true,
cardInit: false,
@ -161,15 +161,15 @@ export default {
showCompleted: false,
completedTask: false,
});
index = state.cacheTablePanel.findIndex(item => item.project_id == project_id)
index = state.cacheProjectParameters.findIndex(item => item.project_id == project_id)
}
const cache = state.cacheTablePanel[index];
const cache = state.cacheProjectParameters[index];
if (!state.method.isJson(key)) {
key = {[key]: !cache[key]};
}
state.cacheTablePanel.splice(index, 1, Object.assign(cache, key))
state.cacheProjectParameters.splice(index, 1, Object.assign(cache, key))
setTimeout(() => {
state.method.setStorage("cacheTablePanel", state.cacheTablePanel);
state.method.setStorage("cacheProjectParameters", state.cacheProjectParameters);
});
}
},
@ -395,7 +395,7 @@ export default {
state.cacheColumns = state.columns = [];
state.cacheTasks = state.tasks = [];
//
state.method.setStorage("cacheTablePanel", state.cacheTablePanel);
state.method.setStorage("cacheProjectParameters", state.cacheProjectParameters);
state.method.setStorage("cacheServerUrl", state.cacheServerUrl);
state.method.setStorage("cacheLoginEmail", cacheLoginEmail);
dispatch("saveUserInfo", state.method.isJson(userInfo) ? userInfo : state.userInfo);
@ -787,9 +787,9 @@ export default {
dispatch("saveColumn", data.data);
// 判断只有1列的时候默认版面为表格模式
if (state.columns.filter(item => item.project_id == project_id).length === 1) {
const cache = state.cacheTablePanel.find(item => item.project_id == project_id) || {};
const cache = state.cacheProjectParameters.find(item => item.project_id == project_id) || {};
if (typeof cache.cardInit === "undefined" || cache.cardInit === false) {
dispatch("toggleTablePanel", {
dispatch("toggleProjectParameters", {
project_id,
key: {
card: false,
@ -942,14 +942,14 @@ export default {
if (data.project_id) {
state.projectLoad--;
}
//
const resData = result.data;
const ids = resData.data.map(({id}) => id)
if (ids.length > 0) {
if (data.project_id) {
if (data.project_id && resData.current_page == 1) {
const ids = resData.data.map(({id}) => id)
if (ids.length > 0) {
state.tasks = state.tasks.filter((item) => item.project_id != data.project_id || ids.includes(item.id));
}
}
dispatch("saveTask", resData.data);
//
if (resData.next_page_url) {
const nextData = Object.assign(data, {
@ -966,6 +966,8 @@ export default {
dispatch("getTasks", nextData)
}
}
//
dispatch("saveTask", resData.data);
}).catch(e => {
console.error(e);
if (data.project_id) {
@ -1559,6 +1561,7 @@ export default {
if (ids.length > 0) {
state.dialogMsgs = state.dialogMsgs.filter((item) => item.dialog_id != dialog_id || ids.includes(item.id));
}
//
dispatch("saveDialog", result.data.dialog);
dispatch("saveDialogMsg", result.data.data);
}).catch(e => {
@ -1568,12 +1571,12 @@ export default {
},
/**
* 获取下一页会话消息
* 获取更多(下一页)会话消息
* @param state
* @param dispatch
* @param dialog_id
*/
getDialogMsgNextPage({state, dispatch}, dialog_id) {
getDialogMoreMsgs({state, dispatch}, dialog_id) {
return new Promise(function (resolve, reject) {
const dialog = state.dialogs.find(({id}) => id == dialog_id);
if (!dialog) {

View File

@ -2,7 +2,7 @@ export default {
/**
* 当前打开的项目
* @param state
* @returns {unknown[]|{project_user: *[], columns: *[]}}
* @returns {{}|{readonly id?: *}}
*/
projectData(state) {
let projectId = state.projectId;
@ -11,33 +11,41 @@ export default {
}
if (projectId > 0) {
window.__projectId = projectId;
const project = state.method.cloneJSON(state.projects.find(({id}) => id == projectId));
const project = state.projects.find(({id}) => id == projectId);
if (project) {
project.columns = state.method.cloneJSON(state.columns.filter(({project_id}) => {
return project_id == project.id
})).sort((a, b) => {
if (a.sort != b.sort) {
return a.sort - b.sort;
}
return a.id - b.id;
});
project.columns.forEach((column) => {
column.tasks = state.method.cloneJSON(state.tasks.filter((task) => {
return task.column_id == column.id && task.parent_id == 0;
})).sort((a, b) => {
if (a.sort != b.sort) {
return a.sort - b.sort;
}
return a.id - b.id;
});
})
return Object.freeze(project);
return project;
}
}
return {
columns: [],
project_user: []
};
return {};
},
/**
* 当前打开的项目面板参数
* @param state
* @returns {(function(*): (boolean|*))|*}
*/
projectParameters(state) {
return function (key) {
if (!state.projectId) {
return false;
}
let cache = state.cacheProjectParameters.find(({project_id}) => project_id == state.projectId);
if (!cache) {
cache = {
project_id: state.projectId,
card: true,
cardInit: false,
chat: false,
showMy: true,
showHelp: true,
showUndone: true,
showCompleted: false,
completedTask: false,
}
state.cacheProjectParameters.push(cache);
}
return cache && !!cache[key];
}
},
/**
@ -60,79 +68,65 @@ export default {
return {};
},
/**
* 项目面板设置
* @param state
* @returns {(function(*): (boolean|*))|*}
*/
tablePanel(state) {
return function (key) {
if (!state.projectId) {
return false;
}
let cache = state.cacheTablePanel.find(({project_id}) => project_id == state.projectId);
if (!cache) {
cache = {
project_id: state.projectId,
card: true,
cardInit: false,
chat: false,
showMy: true,
showHelp: true,
showUndone: true,
showCompleted: false,
completedTask: false,
}
state.cacheTablePanel.push(cache);
}
return cache && !!cache[key];
}
},
/**
* 我所有的任务未完成
* @param state
* @returns {unknown[]}
*/
myTask(state) {
return state.tasks.filter(({complete_at, parent_id, end_at, owner}) => {
if (parent_id > 0) {
const index = state.tasks.findIndex(data => {
if (data.id != parent_id) {
return false;
}
if (data.complete_at) {
return false;
}
return data.owner;
});
if (index > -1) {
return false;
}
}
myTasks(state) {
return state.tasks.filter(({complete_at, owner}) => {
if (complete_at) {
return false;
}
return owner;
}).map(task => {
if (task.parent_id > 0) {
const tmp = state.tasks.find(({id}) => id == task.parent_id);
if (tmp) {
return Object.assign({}, tmp, {
id: task.id,
parent_id: task.parent_id,
name: task.name,
start_at: task.start_at,
end_at: task.end_at,
sub_num: 0,
top_task: true,
});
}
}
return task;
})
},
/**
* 转换任务列表
* @returns {function(*): *}
*/
transforTasks(state) {
return function (list) {
return list.filter(({parent_id}) => {
if (parent_id > 0) {
if (list.find(({id}) => id == parent_id)) {
return false;
}
}
return true;
}).map(task => {
if (task.parent_id <= 0) {
// 主任务
return Object.assign({}, task, {
sub_top: false,
sub_my: list.filter(({parent_id}) => parent_id == task.id),
});
} else {
// 子任务
const data = state.tasks.find(({id}) => id == task.parent_id);
if (data) {
return Object.assign({}, data, {
id: task.id,
parent_id: task.parent_id,
name: task.name,
start_at: task.start_at,
end_at: task.end_at,
sub_top: true,
sub_my: [],
});
} else {
return Object.assign({}, task, {
sub_top: true,
sub_my: [],
});
}
}
})
}
},
/**
* 仪表盘任务数据
* @param state
@ -143,7 +137,7 @@ export default {
const todayStart = $A.Date($A.formatDate("Y-m-d 00:00:00")),
todayEnd = $A.Date($A.formatDate("Y-m-d 23:59:59")),
todayNow = $A.Date($A.formatDate("Y-m-d H:i:s"));
const todayTasks = getters.myTask.filter(task => {
const todayTasks = getters.myTasks.filter(task => {
if (!task.end_at) {
return false;
}
@ -151,7 +145,7 @@ export default {
end = $A.Date(task.end_at);
return (start <= todayStart && todayStart <= end) || (start <= todayEnd && todayEnd <= end) || (start > todayStart && todayEnd > end);
})
const overdueTasks = getters.myTask.filter(task => {
const overdueTasks = getters.myTasks.filter(task => {
if (!task.end_at) {
return false;
}
@ -161,5 +155,5 @@ export default {
today: todayTasks,
overdue: overdueTasks,
}
}
},
}

View File

@ -266,8 +266,7 @@ state.cacheDialogs = state.method.getStorageArray("cacheDialogs");
state.cacheProjects = state.method.getStorageArray("cacheProjects");
state.cacheColumns = state.method.getStorageArray("cacheColumns");
state.cacheTasks = state.method.getStorageArray("cacheTasks");
// TablePanel
state.cacheTablePanel = state.method.getStorageArray("cacheTablePanel");
state.cacheProjectParameters = state.method.getStorageArray("cacheProjectParameters");
// ServerUrl
state.cacheServerUrl = state.method.getStorageString("cacheServerUrl")
if (state.cacheServerUrl && window.systemInformation) {

View File

@ -671,7 +671,7 @@
display: inline-block;
vertical-align: top;
margin-top: 3px;
margin-right: 4px;
margin-right: 3px;
}
}
.item-icons {
@ -773,6 +773,9 @@
}
.task-row {
background-color: #fcfcfd;
.priority-color {
display: none;
}
> div {
&.row-name {
padding-left: 56px;
@ -780,6 +783,12 @@
color: #6C7D8C;
}
}
&.row-column,
&.row-priority {
> div {
display: none;
}
}
}
}
.task-add-row {

View File

@ -145,7 +145,7 @@
display: inline-block;
vertical-align: top;
margin-top: 2px;
margin-right: 4px;
margin-right: 2px;
}
}
.item-icon {