日历完成

This commit is contained in:
kuaifan 2021-06-17 11:59:42 +08:00
parent b417020b9d
commit 5c68caa18a
7 changed files with 217 additions and 132 deletions

View File

@ -25,7 +25,8 @@
:theme="calendarTheme"
:template="calendarTemplate"
:calendars="calendarList"
:schedules="scheduleLists"
:schedules="calendarTasks"
@beforeCreateSchedule="onBeforeCreateSchedule"
@beforeClickSchedule="onBeforeClickSchedule"
@beforeUpdateSchedule="onBeforeUpdateSchedule"/>
</div>
@ -71,7 +72,6 @@ export default {
calendarList: [],
scheduleLoad: 0,
scheduleList: [],
}
},
@ -84,10 +84,10 @@ export default {
},
computed: {
...mapState(['projectList']),
...mapState(['projectList', 'calendarTask']),
scheduleLists() {
return this.scheduleList.filter(({complete_at}) => !complete_at)
calendarTasks() {
return this.calendarTask.filter(({complete_at}) => !complete_at)
}
},
@ -99,7 +99,7 @@ export default {
projectList(data) {
const list = data.map((project) => {
return {
id: project.id,
id: String(project.id),
name: project.name,
}
});
@ -121,6 +121,9 @@ export default {
titlePlaceholder: () => {
return this.$L("任务描述")
},
popupSave: () => {
return this.$L("保存");
},
popupEdit: () => {
return this.$L("详情");
},
@ -143,34 +146,7 @@ export default {
}).then(({data}) => {
this.scheduleLoad--;
data.data.some((task) => {
let schedule = {
id: task.id,
calendarId: task.project_id,
title: task.name,
category: 'allday',
start: new Date(task.start_at).toISOString(),
end: new Date(task.end_at).toISOString(),
color: "#515a6e",
bgColor: task.color || '#E3EAFD',
borderColor: task.p_color,
complete_at: task.complete_at,
preventClick: true,
isChecked: false,
};
if (task.p_name) {
schedule.priority = '<span class="priority" style="background-color:' + task.p_color + '">' + task.p_name + '</span>';
}
if (task.overdue) {
schedule.color = "#f56c6c"
schedule.bgColor = "#fef0f0"
schedule.priority+= '<span class="overdue">' + this.$L('超期未完成') + '</span>';
}
let index = this.scheduleList.findIndex(({id}) => id === task.id);
if (index > -1) {
this.scheduleList.splice(index, 1, schedule)
} else {
this.scheduleList.push(schedule)
}
this.$store.dispatch("saveCalendarTask", task)
});
}).catch(() => {
this.scheduleLoad--;
@ -224,8 +200,20 @@ export default {
return currentDate.format(format);
},
onBeforeCreateSchedule(res) {
this.$store.dispatch("taskAdd", {
project_id: res.calendarId,
times: [res.start.toDate(), res.end.toDate()],
name: res.title
}).then(({msg}) => {
$A.messageSuccess(msg);
}).catch(({msg}) => {
$A.modalError(msg);
});
},
onBeforeClickSchedule({type, schedule}) {
let data = this.scheduleList.find(({id}) => id === schedule.id);
let data = this.calendarTask.find(({id}) => id === schedule.id);
if (!data) {
return;
}
@ -253,7 +241,6 @@ export default {
content: '你确定要删除任务【' + data.title + '】吗?',
loading: true,
onOk: () => {
this.scheduleList = this.scheduleList.filter(({id}) => id !== data.id);
this.$store.dispatch("taskArchivedOrRemove", {
task_id: data.id,
type: 'delete',
@ -272,9 +259,27 @@ export default {
},
onBeforeUpdateSchedule(res) {
console.group('onBeforeUpdateSchedule');
console.log('BeforeUpdate : ', res);
console.groupEnd();
const {changes, schedule} = res;
let data = this.calendarTask.find(({id}) => id === schedule.id);
if (!data) {
return;
}
if (changes.start || changes.end) {
const cal = this.$refs.cal.getInstance();
cal.updateSchedule(schedule.id, schedule.calendarId, changes);
//
this.$store.dispatch("taskUpdate", {
task_id: data.id,
times: [
(changes.start || schedule.start).toDate(),
(changes.end || schedule.end).toDate(),
],
}).then(({msg}) => {
$A.messageSuccess(msg);
}).catch(({msg}) => {
$A.modalError(msg);
});
}
}
}
}

View File

@ -108,10 +108,10 @@ export default {
watch: {
calendars(newValue) {
this.calendarInstance.setCalendars(newValue);
this.$nextTick(this.resetRender)
},
schedules() {
this.calendarInstance.clear();
this.reflectSchedules();
this.resetRender();
},
view(newValue) {
this.calendarInstance.changeView(newValue, true);

View File

@ -6,9 +6,6 @@
<h1>{{projectDetail.name}}</h1>
<div v-if="projectLoad > 0" class="project-load"><Loading/></div>
</div>
<div v-if="projectDetail.desc" class="project-subtitle">{{projectDetail.desc}}</div>
</div>
<div class="project-icobox">
<ul class="project-icons">
<li>
<UserAvatar :userid="projectDetail.owner_userid" :size="36">
@ -45,14 +42,15 @@
</EDropdown>
</li>
</ul>
<div class="project-switch">
<div v-if="completedCount > 0" class="project-checkbox">
<Checkbox :value="projectCompleteHide" @on-change="toggleBoolean('projectCompleteHide', $event)">{{$L('隐藏已完成')}}</Checkbox>
</div>
<div :class="['project-switch-button', !projectTablePanel ? 'menu' : '']" @click="toggleBoolean('projectTablePanel')">
<div><i class="iconfont">&#xe60c;</i></div>
<div><i class="iconfont">&#xe66a;</i></div>
</div>
</div>
<div v-if="projectDetail.desc" class="project-subtitle">{{projectDetail.desc}}</div>
<div class="project-switch">
<div v-if="completedCount > 0" class="project-checkbox">
<Checkbox :value="projectCompleteShow" @on-change="toggleBoolean('projectCompleteShow', $event)">{{$L('显示已完成')}}</Checkbox>
</div>
<div :class="['project-switch-button', !projectTablePanel ? 'menu' : '']" @click="toggleBoolean('projectTablePanel')">
<div><i class="iconfont">&#xe60c;</i></div>
<div><i class="iconfont">&#xe66a;</i></div>
</div>
</div>
</div>
@ -450,7 +448,7 @@ export default {
'projectChatShow',
'projectTablePanel',
'projectCompleteHide',
'projectCompleteShow',
'taskMyShow',
'taskUndoneShow',
'taskCompletedShow'
@ -463,9 +461,9 @@ export default {
},
panelTask() {
const {searchText, projectCompleteHide} = this;
const {searchText, projectCompleteShow} = this;
return function (project_task) {
if (projectCompleteHide) {
if (!projectCompleteShow) {
project_task = project_task.filter(({complete_at}) => {
return !complete_at;
});
@ -480,11 +478,11 @@ export default {
},
myList() {
const {searchText, projectCompleteHide, userId, projectDetail} = this;
const {searchText, projectCompleteShow, userId, projectDetail} = this;
const array = [];
projectDetail.project_column.forEach(({project_task, name}) => {
project_task.some((task) => {
if (projectCompleteHide) {
if (!projectCompleteShow) {
if (task.complete_at) {
return false;
}
@ -512,11 +510,11 @@ export default {
},
undoneList() {
const {searchText, projectCompleteHide, projectDetail} = this;
const {searchText, projectCompleteShow, projectDetail} = this;
const array = [];
projectDetail.project_column.forEach(({project_task, name}) => {
project_task.some((task) => {
if (projectCompleteHide) {
if (!projectCompleteShow) {
if (task.complete_at) {
return false;
}
@ -553,11 +551,11 @@ export default {
},
completedList() {
const {searchText, projectCompleteHide, projectDetail} = this;
const {searchText, projectCompleteShow, projectDetail} = this;
const array = [];
projectDetail.project_column.forEach(({project_task, name}) => {
project_task.some((task) => {
if (projectCompleteHide) {
if (!projectCompleteShow) {
if (task.complete_at) {
return false;
}
@ -1032,8 +1030,8 @@ export default {
taskHidden(task) {
const {name, desc, complete_at} = task;
const {searchText, projectCompleteHide} = this;
if (projectCompleteHide) {
const {searchText, projectCompleteShow} = this;
if (!projectCompleteShow) {
if (complete_at) {
return true;
}

View File

@ -378,9 +378,10 @@ export default {
/**
* 保存任务信息
* @param state
* @param dispatch
* @param data
*/
saveTask({state}, data) {
saveTask({state, dispatch}, data) {
state.projectDetail.project_column.some(({project_task}) => {
let index = project_task.findIndex(({id}) => id === data.id);
if (index > -1) {
@ -396,6 +397,46 @@ export default {
state.projectOpenTask.sub_task.splice(index, 1, Object.assign(state.projectOpenTask.sub_task[index], data))
}
}
dispatch("saveCalendarTask", data)
},
/**
* 保存任务信息日历任务
* @param state
* @param data
*/
saveCalendarTask({state}, 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>';
}
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)
}
},
/**
@ -560,7 +601,7 @@ export default {
*/
taskAdd({state, dispatch}, data) {
return new Promise(function (resolve, reject) {
const post = state.method.cloneJSON(data);
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)
}
@ -587,6 +628,7 @@ export default {
}
}
}
dispatch("saveCalendarTask", task);
dispatch("getProjectOne", task.project_id);
resolve(result)
}).catch(result => {
@ -628,7 +670,7 @@ export default {
*/
taskUpdate({state, dispatch}, data) {
return new Promise(function (resolve, reject) {
const post = state.method.cloneJSON(data);
const post = state.method.cloneJSON(state.method.date2string(data));
if (state.method.isArray(post.owner)) {
post.owner = post.owner.find((id) => id)
}
@ -684,6 +726,11 @@ export default {
state.projectOpenTask.sub_task.splice(index, 1)
}
}
let index = state.calendarTask.findIndex(({id}) => id === data.id);
if (index > -1) {
state.calendarTask.splice(index, 1)
}
dispatch("getProjectOne", data.project_id);
resolve(result);
}).catch(result => {
reject(result)

View File

@ -236,7 +236,7 @@ const state = { method };
[
'projectChatShow', // 项目聊天显示
'projectCompleteHide' // 项目面板显示已完成列表
'projectCompleteShow' // 项目面板显示已完成列表
].forEach((key) => {
state[key] = state.method.getStorageBoolean("boolean:" + key, false)
});
@ -275,6 +275,7 @@ state.projectOpenTask = {_show: false, id: 0, task_user: [], task_tag: []};
state.projectTaskContent = {};
state.projectTaskFiles = {};
state.projectSubTask = {};
state.calendarTask = [];
// 会话聊天
state.dialogId = 0;

View File

@ -3,11 +3,15 @@
flex-direction: column;
.project-head {
display: flex;
flex-direction: column;
align-items: flex-start;
margin: 32px 32px 0;
.project-titbox {
flex: 1;
margin-bottom: 16px;
width: 100%;
display: flex;
align-items: flex-start;
justify-content: space-between;
margin-bottom: 36px;
.project-title {
display: flex;
align-items: center;
@ -26,23 +30,11 @@
}
}
}
.project-subtitle {
color: #999999;
margin-top: 18px;
line-height: 24px;
}
}
.project-icobox {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
margin-top: 2px;
margin-left: 80px;
.project-icons {
display: flex;
align-items: center;
flex-shrink: 0;
margin-top: 3px;
> li {
list-style: none;
display: flex;
@ -84,63 +76,78 @@
}
}
}
.project-switch {
}
.project-subtitle {
width: 100%;
color: #999999;
line-height: 24px;
margin-top: -18px;
margin-bottom: 6px;
padding-right: 260px;
}
.project-switch {
width: 100%;
display: flex;
justify-content: flex-end;
.project-checkbox {
display: flex;
justify-content: flex-end;
margin-top: 24px;
.project-checkbox {
display: flex;
align-items: center;
margin-right: 14px;
opacity: 0.9;
align-items: center;
margin-right: 14px;
opacity: 0.9;
.ivu-checkbox-focus {
box-shadow: none;
}
.project-switch-button {
}
.project-switch-button {
display: flex;
align-items: center;
background-color: #ffffff;
border-radius: 6px;
position: relative;
transition: box-shadow 0.2s;
&:hover {
box-shadow: 0 0 10px #e6ecfa;
}
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
z-index: 0;
color: #2d8cf0;
border-radius: 6px;
border: 1px solid #2d8cf0;
background-color: #e6f7ff;
transition: left 0.2s;
}
> div {
z-index: 1;
width: 32px;
height: 30px;
display: flex;
align-items: center;
background-color: #ffffff;
justify-content: center;
border-radius: 6px;
position: relative;
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 100%;
z-index: 0;
cursor: pointer;
color: #515a6e;
> i {
font-size: 17px;
}
&:first-child {
color: #2d8cf0;
border-radius: 6px;
border: 1px solid #2d8cf0;
background-color: #e6f7ff;
transition: left 0.2s;
}
> div {
z-index: 1;
width: 32px;
height: 30px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
cursor: pointer;
}
&.menu {
&:before {
left: 50%;
}
> div:first-child {
color: #515a6e;
> i {
font-size: 17px;
}
&:first-child {
color: #2d8cf0;
}
}
&.menu {
&:before {
left: 50%;
}
> div:first-child {
color: #515a6e;
}
> div:last-child {
color: #2d8cf0;
}
> div:last-child {
color: #2d8cf0;
}
}
}

View File

@ -56,6 +56,18 @@
background-color: #ffffff;
z-index: 1;
}
.tui-full-calendar-popup {
box-shadow: none;
.tui-full-calendar-popup-container {
border: 0;
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
border-radius: 6px;
}
.tui-full-calendar-arrow-top .tui-full-calendar-popup-arrow-border {
top: -8px;
border-bottom-color: rgba(217, 217, 217, .5);
}
}
.tui-full-calendar-popup-creation {
.tui-full-calendar-icon {
&.tui-full-calendar-ic-title,
@ -73,10 +85,21 @@
.tui-full-calendar-popup-section {
display: flex;
justify-content: space-between;
margin-bottom: 6px;
margin-bottom: 10px;
.tui-full-calendar-popup-section-item {
height: 36px;
border-color: #e8e8e8;
border-radius: 4px;
}
.tui-full-calendar-popup-section-item input {
height: 34px;
}
}
.tui-full-calendar-section-title {
width: 100%;
input {
width: 100%;
}
}
.tui-full-calendar-section-start-date,
.tui-full-calendar-section-end-date {
@ -119,12 +142,16 @@
top: -2px;
background-image: url("data:image/svg+xml;base64,PHN2ZyB0PSIxNjIzODU5MzMwMTc2IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9Ijc5MiIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPjxwYXRoIGQ9Ik04OTIuMjg4IDI1NmgtMTkxLjE2OEEyMDIuMjQgMjAyLjI0IDAgMCAwIDUwOS42MzIgNjIuMDggMjAxLjIxNiAyMDEuMjE2IDAgMCAwIDMxOC44NDggMjU2SDEyOGMtMTguNjg4IDAtNjYuMDQ4LTQuMjI0LTY2LjA0OCAyNC43NjhDNjEuOTUyIDMyNy43NDQgMTA5LjM3NiAzMjAgMTI4IDMyMGg2NHY1MTJhMTQ2LjQ5NiAxNDYuNDk2IDAgMCAwIDEyNy40MjQgMTI4aDM4Mi4yNzJBMTUwLjAxNiAxNTAuMDE2IDAgMCAwIDgzMiA4MzJsLTMuMzkyLTUxMmg2NGMxOC4zNjggMCA2NS4wMjQgMS40NzIgNjUuMDI0LTM5Ljc0NEE3Mi4zODQgNzIuMzg0IDAgMCAwIDg5Mi4yODggMjU2ek01MDkuNjMyIDEyOC41MTJBMTM4LjE3NiAxMzguMTc2IDAgMCAxIDYzNy40NCAyNTZIMzgyLjU5MmExMzcuOTIgMTM3LjkyIDAgMCAxIDEyNy4wNC0xMjcuNDg4ek03NjggODMyYTk3Ljk4NCA5Ny45ODQgMCAwIDEtNjYuODggNjRIMzE4Ljg0OGE5My41NjggOTMuNTY4IDAgMCAxLTY0LTY0VjMyMEg3Njh2NTEyeiBtLTM4NS40MDgtNjRWNTEyYzAtMTguNDk2IDAuOTYtNjAuOTkyIDM2LjczNi02MC45OTIgMjcuMzI4IDAgMjYuNDk2IDQzLjAwOCAyNi45NDQgNjAuOTkydjI1NmMwIDE4LjQ5Ni02LjQgMjAuMDMyLTI0Ljk2IDIwLjAzMnMtMzguNzItMS41MzYtMzguNzItMjAuMDMyeiBtMTkxLjE2OCAwVjUxMmE2NCA2NCAwIDAgMSAyMy44MDgtNjAuOTkyYzQyLjQzMiAwIDM5LjM2IDQzLjAwOCAzOS44NzIgNjAuOTkydjI1NmMwIDE4LjQ5Ni0xOS41ODQgMjAuMDMyLTM3Ljk1MiAyMC4wMzJzLTI1Ljc5Mi0xLjUzNi0yNS43OTItMjAuMDMyeiIgcC1pZD0iNzkzIiBmaWxsPSIjNTE1MTUxIj48L3BhdGg+PC9zdmc+");
}
.tui-full-calendar-popup-detail-item-separate {
padding-left: 22px;
}
}
.tui-datepicker {
border-color: #e8e8e8;
.tui-calendar {
th,
td {
height: 35px;
height: 32px;
}
.tui-calendar-prev-month.tui-calendar-date,
.tui-calendar-next-month.tui-calendar-date {