任务数据逻辑

This commit is contained in:
kuaifan 2021-12-31 14:05:46 +08:00
parent ba5f635687
commit a1c7efeb85
9 changed files with 174 additions and 112 deletions

View File

@ -44,7 +44,7 @@ import 'tui-date-picker/dist/tui-date-picker.css';
import 'tui-time-picker/dist/tui-time-picker.css'; import 'tui-time-picker/dist/tui-time-picker.css';
import 'tui-calendar-hi/dist/tui-calendar-hi.css' import 'tui-calendar-hi/dist/tui-calendar-hi.css'
import {mapState} from "vuex"; import {mapState, mapGetters} from "vuex";
import Calendar from "./components/Calendar"; import Calendar from "./components/Calendar";
import moment from "moment"; import moment from "moment";
@ -76,17 +76,10 @@ export default {
computed: { computed: {
...mapState(['userId', 'projects', 'tasks']), ...mapState(['userId', 'projects', 'tasks']),
...mapGetters(['ownerTask']),
list() { list() {
let datas = $A.cloneJSON(this.tasks); const datas = $A.cloneJSON(this.ownerTask);
datas = datas.filter((data) => {
if (data.complete_at) {
return false;
}
if (!data.end_at) {
return false;
}
return data.owner;
})
return datas.map(data => { return datas.map(data => {
let isAllday = $A.rightExists(data.start_at, "00:00:00") && $A.rightExists(data.end_at, "23:59:59") let isAllday = $A.rightExists(data.start_at, "00:00:00") && $A.rightExists(data.end_at, "23:59:59")
let task = { let task = {
@ -109,11 +102,14 @@ export default {
if (data.p_name) { if (data.p_name) {
task.priority = '<span class="priority" style="background-color:' + data.p_color + '">' + data.p_name + '</span>'; 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.overdue) { if (data.overdue) {
task.title = '[' + $A.L('超期') + '] ' + task.title task.title = '[' + this.$L('超期') + '] ' + task.title
task.color = "#f56c6c" task.color = "#f56c6c"
task.bgColor = "#fef0f0" task.bgColor = "#fef0f0"
task.priority+= '<span class="overdue">' + $A.L('超期未完成') + '</span>'; task.priority+= '<span class="overdue">' + this.$L('超期未完成') + '</span>';
} }
if (!task.borderColor) { if (!task.borderColor) {
task.borderColor = task.bgColor; task.borderColor = task.bgColor;
@ -286,7 +282,7 @@ export default {
break; break;
case "edit": case "edit":
this.$store.dispatch("openTask", data.id) this.$store.dispatch("openTask", data)
break; break;
case "delete": case "delete":

View File

@ -532,6 +532,8 @@ export default {
...mapGetters(['projectData', 'tablePanel']), ...mapGetters(['projectData', 'tablePanel']),
...mapGetters(['ownerTask']),
userWaitRemove() { userWaitRemove() {
const {userids, useridbak} = this.userData; const {userids, useridbak} = this.userData;
if (!userids) { if (!userids) {
@ -570,8 +572,8 @@ export default {
}, },
myList() { myList() {
const {projectId, tasks, searchText, userId, completeTask, sortField, sortType} = this; const {projectId, ownerTask, searchText, completeTask, sortField, sortType} = this;
const array = tasks.filter((task) => { const array = ownerTask.filter((task) => {
if (task.project_id != projectId) { if (task.project_id != projectId) {
return false; return false;
} }
@ -585,7 +587,7 @@ export default {
return false; return false;
} }
} }
return task.task_user && task.task_user.find(({userid, owner}) => userid == userId && owner == 1); return true;
}); });
return array.sort((a, b) => { return array.sort((a, b) => {
if (sortType == 'asc') { if (sortType == 'asc') {
@ -605,7 +607,7 @@ export default {
helpList() { helpList() {
const {projectId, tasks, searchText, userId, completeTask, sortField, sortType} = this; const {projectId, tasks, searchText, userId, completeTask, sortField, sortType} = this;
const array = tasks.filter((task) => { const array = tasks.filter((task) => {
if (task.project_id != projectId) { if (task.project_id != projectId || task.parent_id > 0) {
return false; return false;
} }
if (!this.tablePanel('completedTask')) { if (!this.tablePanel('completedTask')) {
@ -638,7 +640,7 @@ export default {
undoneList() { undoneList() {
const {projectId, tasks, searchText, completeTask, sortField, sortType} = this; const {projectId, tasks, searchText, completeTask, sortField, sortType} = this;
const array = tasks.filter((task) => { const array = tasks.filter((task) => {
if (task.project_id != projectId) { if (task.project_id != projectId || task.parent_id > 0) {
return false; return false;
} }
if (!this.tablePanel('completedTask')) { if (!this.tablePanel('completedTask')) {
@ -671,7 +673,7 @@ export default {
completedCount() { completedCount() {
const {projectId, tasks} = this; const {projectId, tasks} = this;
return tasks.filter((task) => { return tasks.filter((task) => {
if (task.project_id != projectId) { if (task.project_id != projectId || task.parent_id > 0) {
return false; return false;
} }
return task.complete_at; return task.complete_at;
@ -681,7 +683,7 @@ export default {
completedList() { completedList() {
const {projectId, tasks, searchText} = this; const {projectId, tasks, searchText} = this;
const array = tasks.filter((task) => { const array = tasks.filter((task) => {
if (task.project_id != projectId) { if (task.project_id != projectId || task.parent_id > 0) {
return false; return false;
} }
if (searchText) { if (searchText) {
@ -1154,11 +1156,7 @@ export default {
}, },
openTask(task, receive) { openTask(task, receive) {
if (task.parent_id > 0) { this.$store.dispatch("openTask", task)
this.$store.dispatch("openTask", task.parent_id)
} else {
this.$store.dispatch("openTask", task.id)
}
if (receive === true) { if (receive === true) {
// //
setTimeout(() => { setTimeout(() => {

View File

@ -108,8 +108,7 @@
class="pick" class="pick"
:title="$L('你确认领取任务吗?')" :title="$L('你确认领取任务吗?')"
placement="bottom" placement="bottom"
@on-ok="onOwner(true)" @on-ok="onOwner(true)">
transfer>
<Button type="primary">{{$L('我要领取任务')}}</Button> <Button type="primary">{{$L('我要领取任务')}}</Button>
</Poptip> </Poptip>
<ETooltip v-if="$Electron" :content="$L('新窗口打开')"> <ETooltip v-if="$Electron" :content="$L('新窗口打开')">

View File

@ -2,7 +2,7 @@
<div class="task-rows"> <div class="task-rows">
<div v-for="(item, key) in list" :key="key"> <div v-for="(item, key) in list" :key="key">
<Row class="task-row" :style="item.color ? {backgroundColor: item.color, borderBottomColor: item.color} : {}"> <Row class="task-row" :style="item.color ? {backgroundColor: item.color, borderBottomColor: item.color} : {}">
<em v-if="item.p_name && item.parent_id === 0" class="priority-color" :style="{backgroundColor:item.p_color}"></em> <em v-if="item.p_name && isTopTask(item)" class="priority-color" :style="{backgroundColor:item.p_color}"></em>
<Col span="12" :class="['row-name', item.complete_at ? 'complete' : '']"> <Col span="12" :class="['row-name', item.complete_at ? 'complete' : '']">
<Icon <Icon
v-if="item.sub_num > 0 || (item.parent_id===0 && fastAddTask)" v-if="item.sub_num > 0 || (item.parent_id===0 && fastAddTask)"
@ -50,7 +50,7 @@
</template> </template>
</EDropdownMenu> </EDropdownMenu>
</EDropdown> </EDropdown>
<div class="item-title" @click="openTask(item)">{{item.name}}</div> <div class="item-title" @click="openTask(item)"><span v-if="item.top_task === true">{{$L('子任务')}}</span>{{item.name}}</div>
<div class="item-icons" @click="openTask(item)"> <div class="item-icons" @click="openTask(item)">
<div v-if="item.desc" class="item-icon"> <div v-if="item.desc" class="item-icon">
<i class="taskfont">&#xe71a;</i> <i class="taskfont">&#xe71a;</i>
@ -71,10 +71,11 @@
</Col> </Col>
<Col span="3" class="row-column"> <Col span="3" class="row-column">
<EDropdown <EDropdown
v-if="item.parent_id === 0" v-if="isTopTask(item)"
trigger="click" trigger="click"
size="small" size="small"
placement="bottom" placement="bottom"
:disabled="item.top_task === true"
@command="dropTask(item, $event)"> @command="dropTask(item, $event)">
<div class="task-column">{{columnName(item.column_id)}}</div> <div class="task-column">{{columnName(item.column_id)}}</div>
<EDropdownMenu slot="dropdown"> <EDropdownMenu slot="dropdown">
@ -86,10 +87,11 @@
</Col> </Col>
<Col span="3" class="row-priority"> <Col span="3" class="row-priority">
<EDropdown <EDropdown
v-if="item.p_name && item.parent_id === 0" v-if="item.p_name && isTopTask(item)"
trigger="click" trigger="click"
size="small" size="small"
placement="bottom" placement="bottom"
:disabled="item.top_task === true"
@command="dropTask(item, $event)"> @command="dropTask(item, $event)">
<TaskPriority :backgroundColor="item.p_color">{{item.p_name}}</TaskPriority> <TaskPriority :backgroundColor="item.p_color">{{item.p_name}}</TaskPriority>
<EDropdownMenu slot="dropdown"> <EDropdownMenu slot="dropdown">
@ -210,6 +212,10 @@ export default {
}, },
}, },
methods: { methods: {
isTopTask(item) {
return item.parent_id === 0 || item.top_task === true
},
columnName(column_id) { columnName(column_id) {
const column = this.columns.find(({id}) => id == column_id) const column = this.columns.find(({id}) => id == column_id)
return column ? column.name : ''; return column ? column.name : '';
@ -249,11 +255,7 @@ export default {
}, },
openTask(task, receive) { openTask(task, receive) {
if (task.parent_id > 0) { this.$store.dispatch("openTask", task)
this.$store.dispatch("openTask", task.parent_id)
} else {
this.$store.dispatch("openTask", task.id)
}
if (receive === true) { if (receive === true) {
// //
setTimeout(() => { setTimeout(() => {

View File

@ -35,9 +35,9 @@
:key="item.id" :key="item.id"
:class="{complete: item.complete_at}" :class="{complete: item.complete_at}"
:style="item.color ? {backgroundColor: item.color} : {}" :style="item.color ? {backgroundColor: item.color} : {}"
@click="$store.dispatch('openTask', item.id)"> @click="openTask(item)">
<em <em
v-if="item.p_name && item.parent_id === 0" v-if="item.p_name"
class="priority-color" class="priority-color"
:style="{backgroundColor:item.p_color}"></em> :style="{backgroundColor:item.p_color}"></em>
<EDropdown <EDropdown
@ -79,7 +79,7 @@
</template> </template>
</EDropdownMenu> </EDropdownMenu>
</EDropdown> </EDropdown>
<div class="item-title">{{item.name}}</div> <div class="item-title"><span v-if="item.top_task === true">{{$L('子任务')}}</span>{{item.name}}</div>
<div v-if="item.desc" class="item-icon"> <div v-if="item.desc" class="item-icon">
<i class="taskfont">&#xe71a;</i> <i class="taskfont">&#xe71a;</i>
</div> </div>
@ -102,6 +102,7 @@
<script> <script>
import {mapGetters, mapState} from "vuex"; import {mapGetters, mapState} from "vuex";
import AppDown from "../../components/AppDown"; import AppDown from "../../components/AppDown";
import {Store} from "le5le-store";
export default { export default {
components: {AppDown}, components: {AppDown},
@ -232,6 +233,10 @@ export default {
} }
}, },
openTask(task) {
this.$store.dispatch("openTask", task)
},
updateTask(task, updata) { updateTask(task, updata) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (this.taskLoad[task.id] === true) { if (this.taskLoad[task.id] === true) {

View File

@ -301,7 +301,7 @@ export default {
// //
let index = state.cacheUserBasic.findIndex(({userid}) => userid == data.userid); let index = state.cacheUserBasic.findIndex(({userid}) => userid == data.userid);
if (index > -1) { if (index > -1) {
data = Object.assign(state.cacheUserBasic[index], data) data = Object.assign({}, state.cacheUserBasic[index], data)
state.cacheUserBasic.splice(index, 1, data); state.cacheUserBasic.splice(index, 1, data);
} else { } else {
state.cacheUserBasic.push(data) state.cacheUserBasic.push(data)
@ -427,7 +427,7 @@ export default {
} else if (state.method.isJson(data)) { } else if (state.method.isJson(data)) {
let index = state.files.findIndex(({id}) => id == data.id); let index = state.files.findIndex(({id}) => id == data.id);
if (index > -1) { if (index > -1) {
state.files.splice(index, 1, Object.assign(state.files[index], data)); state.files.splice(index, 1, Object.assign({}, state.files[index], data));
} else { } else {
state.files.push(data) state.files.push(data)
} }
@ -525,7 +525,7 @@ export default {
} }
let index = state.projects.findIndex(({id}) => id == data.id); let index = state.projects.findIndex(({id}) => id == data.id);
if (index > -1) { if (index > -1) {
state.projects.splice(index, 1, Object.assign(state.projects[index], data)); state.projects.splice(index, 1, Object.assign({}, state.projects[index], data));
} else { } else {
state.projects.push(data); state.projects.push(data);
} }
@ -726,7 +726,7 @@ export default {
} else if (state.method.isJson(data)) { } else if (state.method.isJson(data)) {
let index = state.columns.findIndex(({id}) => id == data.id); let index = state.columns.findIndex(({id}) => id == data.id);
if (index > -1) { if (index > -1) {
state.columns.splice(index, 1, Object.assign(state.columns[index], data)); state.columns.splice(index, 1, Object.assign({}, state.columns[index], data));
} else { } else {
state.columns.push(data); state.columns.push(data);
} }
@ -854,12 +854,12 @@ export default {
} else if (state.method.isJson(data)) { } else if (state.method.isJson(data)) {
let index = state.tasks.findIndex(({id}) => id == data.id); let index = state.tasks.findIndex(({id}) => id == data.id);
if (index > -1) { if (index > -1) {
state.tasks.splice(index, 1, Object.assign(state.tasks[index], data)); state.tasks.splice(index, 1, Object.assign({}, state.tasks[index], data));
} else { } else {
state.tasks.push(data); state.tasks.push(data);
} }
// //
if (index > -1 && data.parent_id) { if (data.parent_id > 0 && state.tasks.findIndex(({id}) => id == data.parent_id) === -1) {
dispatch("getTaskOne", data.parent_id); dispatch("getTaskOne", data.parent_id);
} }
if (data.is_update_complete) { if (data.is_update_complete) {
@ -1008,23 +1008,19 @@ export default {
* @param dispatch * @param dispatch
*/ */
getDashboardTasks({state, dispatch}) { getDashboardTasks({state, dispatch}) {
return new Promise(function (resolve, reject) { if (state.cacheLoading["loadDashboardTasks"] === true) {
return;
}
state.cacheLoading["loadDashboardTasks"] = true;
//
let loadIng = 2; let loadIng = 2;
let error = 0; let call = () => {
let call = (err) => { if (loadIng <= 0) {
if (err) { state.cacheLoading["loadDashboardTasks"] = false;
error++; return;
} }
loadIng--; loadIng--;
if (loadIng == 0) { if (loadIng == 1) {
if (error > 0) {
reject()
} else {
resolve()
}
}
}
//
dispatch("getTasks", { dispatch("getTasks", {
complete: "no", complete: "no",
time: [ time: [
@ -1032,20 +1028,22 @@ export default {
$A.formatDate("Y-m-d 23:59:59") $A.formatDate("Y-m-d 23:59:59")
] ]
}).then(() => { }).then(() => {
call(); setTimeout(call);
}).catch(() => { }).catch(() => {
call(true); setTimeout(call);
}) })
// } else if (loadIng == 0) {
dispatch("getTasks", { dispatch("getTasks", {
complete: "no", complete: "no",
time_before: $A.formatDate("Y-m-d H:i:s") time_before: $A.formatDate("Y-m-d H:i:s")
}).then(() => { }).then(() => {
call(); setTimeout(call);
}).catch(() => { }).catch(() => {
call(true); setTimeout(call);
})
}) })
}
}
call();
}, },
/** /**
@ -1195,9 +1193,17 @@ export default {
* 打开任务详情页 * 打开任务详情页
* @param state * @param state
* @param dispatch * @param dispatch
* @param task_id * @param task
*/ */
openTask({state, dispatch}, task_id) { openTask({state, dispatch}, task) {
let task_id = task;
if (state.method.isJson(task)) {
if (task.parent_id > 0) {
task_id = task.parent_id;
} else {
task_id = task.id;
}
}
state.taskId = task_id; state.taskId = task_id;
if (task_id > 0) { if (task_id > 0) {
dispatch("getTaskOne", task_id).then(() => { dispatch("getTaskOne", task_id).then(() => {
@ -1346,7 +1352,7 @@ export default {
} else if (state.method.isJson(data)) { } else if (state.method.isJson(data)) {
let index = state.dialogs.findIndex(({id}) => id == data.id); let index = state.dialogs.findIndex(({id}) => id == data.id);
if (index > -1) { if (index > -1) {
state.dialogs.splice(index, 1, Object.assign(state.dialogs[index], data)); state.dialogs.splice(index, 1, Object.assign({}, state.dialogs[index], data));
} else { } else {
state.dialogs.push(data); state.dialogs.push(data);
} }
@ -1509,7 +1515,7 @@ export default {
} else if (state.method.isJson(data)) { } else if (state.method.isJson(data)) {
let index = state.dialogMsgs.findIndex(({id}) => id == data.id); let index = state.dialogMsgs.findIndex(({id}) => id == data.id);
if (index > -1) { if (index > -1) {
state.dialogMsgs.splice(index, 1, Object.assign(state.dialogMsgs[index], data)); state.dialogMsgs.splice(index, 1, Object.assign({}, state.dialogMsgs[index], data));
} else { } else {
state.dialogMsgs.push(data); state.dialogMsgs.push(data);
} }

View File

@ -18,7 +18,7 @@ export default {
}); });
project.columns.forEach((column) => { project.columns.forEach((column) => {
column.tasks = state.method.cloneJSON(state.tasks.filter((task) => { column.tasks = state.method.cloneJSON(state.tasks.filter((task) => {
return task.column_id == column.id; return task.column_id == column.id && task.parent_id == 0;
})).sort((a, b) => { })).sort((a, b) => {
if (a.sort != b.sort) { if (a.sort != b.sort) {
return a.sort - b.sort; return a.sort - b.sort;
@ -74,35 +74,63 @@ export default {
} }
}, },
dashboardData(state) {
ownerTask(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;
}
if (!data.end_at) {
return false;
}
return data.owner;
});
if (index > -1) {
return false;
}
}
if (complete_at) {
return false;
}
if (!end_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;
})
},
dashboardData(state, getters) {
const todayStart = $A.Date($A.formatDate("Y-m-d 00:00:00")), const todayStart = $A.Date($A.formatDate("Y-m-d 00:00:00")),
todayEnd = $A.Date($A.formatDate("Y-m-d 23:59:59")), todayEnd = $A.Date($A.formatDate("Y-m-d 23:59:59")),
todayNow = $A.Date($A.formatDate("Y-m-d H:i:s")); todayNow = $A.Date($A.formatDate("Y-m-d H:i:s"));
const todayTasks = state.tasks.filter(data => { const todayTasks = getters.ownerTask.filter(task => {
if (data.complete_at) { const start = $A.Date(task.start_at),
return false; end = $A.Date(task.end_at);
}
if (!data.end_at) {
return false;
}
if (!data.owner) {
return false;
}
const start = $A.Date(data.start_at),
end = $A.Date(data.end_at);
return (start <= todayStart && todayStart <= end) || (start <= todayEnd && todayEnd <= end) || (start > todayStart && todayEnd > end); return (start <= todayStart && todayStart <= end) || (start <= todayEnd && todayEnd <= end) || (start > todayStart && todayEnd > end);
}) })
const overdueTasks = state.tasks.filter(data => { const overdueTasks = getters.ownerTask.filter(task => {
if (data.complete_at) { return $A.Date(task.end_at) <= todayNow;
return false;
}
if (!data.end_at) {
return false;
}
if (!data.owner) {
return false;
}
return $A.Date(data.end_at) <= todayNow;
}) })
return { return {
today: todayTasks, today: todayTasks,

View File

@ -659,6 +659,20 @@
flex: 1; flex: 1;
padding: 0 22px 0 8px; padding: 0 22px 0 8px;
cursor: pointer; cursor: pointer;
> span {
font-size: 12px;
height: 18px;
line-height: 16px;
padding: 0 3px;
border-radius: 3px;
color: #8bcf70;
background-color: rgba(139, 207, 112, 0);
border: 1px solid #8bcf70;
display: inline-block;
vertical-align: top;
margin-top: 3px;
margin-right: 4px;
}
} }
.item-icons { .item-icons {
display: flex; display: flex;

View File

@ -133,6 +133,20 @@
flex: 1; flex: 1;
padding-left: 6px; padding-left: 6px;
line-height: 22px; line-height: 22px;
> span {
font-size: 12px;
height: 18px;
line-height: 16px;
padding: 0 3px;
border-radius: 3px;
color: #8bcf70;
background-color: rgba(139, 207, 112, 0);
border: 1px solid #8bcf70;
display: inline-block;
vertical-align: top;
margin-top: 2px;
margin-right: 4px;
}
} }
.item-icon { .item-icon {
display: flex; display: flex;