将所有任务都取出全部显示,子任务判断显示主任务
This commit is contained in:
parent
cc1c425ecf
commit
78f88db560
@ -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);
|
||||
|
@ -152,7 +152,7 @@ class Project extends AbstractModel
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取任务统计
|
||||
* 获取任务统计数据
|
||||
* @param $userid
|
||||
* @return array
|
||||
*/
|
||||
|
@ -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>';
|
||||
|
@ -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);
|
||||
|
@ -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"></i></div>
|
||||
<div><i class="taskfont"></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')"></i>
|
||||
<i class="taskfont" @click="$store.dispatch('toggleProjectParameters', 'showMy')"></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')"></i>
|
||||
<i class="taskfont" @click="$store.dispatch('toggleProjectParameters', 'showHelp')"></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')"></i>
|
||||
<i class="taskfont" @click="$store.dispatch('toggleProjectParameters', 'showUndone')"></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')"></i>
|
||||
<i class="taskfont" @click="$store.dispatch('toggleProjectParameters', 'showCompleted')"></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>
|
||||
|
@ -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) {
|
||||
|
@ -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"></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>
|
||||
|
@ -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"></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>
|
||||
|
@ -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: {
|
||||
|
37
resources/assets/js/store/actions.js
vendored
37
resources/assets/js/store/actions.js
vendored
@ -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) {
|
||||
|
172
resources/assets/js/store/getters.js
vendored
172
resources/assets/js/store/getters.js
vendored
@ -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,
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
3
resources/assets/js/store/state.js
vendored
3
resources/assets/js/store/state.js
vendored
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -145,7 +145,7 @@
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-top: 2px;
|
||||
margin-right: 4px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
}
|
||||
.item-icon {
|
||||
|
Loading…
x
Reference in New Issue
Block a user