mirror of
https://github.com/kuaifan/dootask.git
synced 2026-03-17 19:23:26 +00:00
perf: 优化签到数据
This commit is contained in:
parent
0a84a8718e
commit
b5059c13a3
@ -1513,6 +1513,7 @@ class UsersController extends AbstractController
|
|||||||
* @apiName checkin__list
|
* @apiName checkin__list
|
||||||
*
|
*
|
||||||
* @apiParam {String} ym 年-月(如:2020-01)
|
* @apiParam {String} ym 年-月(如:2020-01)
|
||||||
|
* @apiParam {Number} [before] 取月份之前的数据(单位:月数,最大3)
|
||||||
*
|
*
|
||||||
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
* @apiSuccess {Number} ret 返回状态码(1正确、0错误)
|
||||||
* @apiSuccess {String} msg 返回信息(错误描述)
|
* @apiSuccess {String} msg 返回信息(错误描述)
|
||||||
@ -1526,6 +1527,11 @@ class UsersController extends AbstractController
|
|||||||
$start = Carbon::parse(date("Y-m-01 00:00:00", strtotime($ym)));
|
$start = Carbon::parse(date("Y-m-01 00:00:00", strtotime($ym)));
|
||||||
$end = (clone $start)->addMonth()->subSecond();
|
$end = (clone $start)->addMonth()->subSecond();
|
||||||
//
|
//
|
||||||
|
$before = min(3, intval(Request::input('before')));
|
||||||
|
if ($before > 0) {
|
||||||
|
$start = $start->subMonths($before);
|
||||||
|
}
|
||||||
|
//
|
||||||
$recordTimes = UserCheckinRecord::getTimes($user->userid, [$start, $end]);
|
$recordTimes = UserCheckinRecord::getTimes($user->userid, [$start, $end]);
|
||||||
$array = [];
|
$array = [];
|
||||||
$startT = $start->timestamp;
|
$startT = $start->timestamp;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<Button v-if="hasNextMonth" class="calendar-header-back" size="small" @click="nowMonth">{{$L('返回本月')}}</Button>
|
<Button v-if="hasNextMonth" class="calendar-header-back" size="small" @click="nowMonth">{{$L('返回本月')}}</Button>
|
||||||
</div>
|
</div>
|
||||||
<table class="sign_tab" border="0px" cellpadding="0px" cellspacing="0px">
|
<table class="check-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{{$L('日')}}</th>
|
<th>{{$L('日')}}</th>
|
||||||
@ -21,32 +21,25 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="item in dateArr" v-if="contains(item)">
|
<tr v-for="item in dateArray">
|
||||||
<template v-for="data in item">
|
<template v-for="data in item">
|
||||||
<td v-if="isCheck(data.date)"
|
<td v-if="data.month" :class="{today: data.today, checkin:isCheck(data.date)}">
|
||||||
:class="{'disa':monthClass(data.month), 'cur_day': doCheck(data.date),'check_day': isCheck(data.date) }">
|
<ETooltip max-width="auto" :disabled="!isCheck(data.date)">
|
||||||
<Tooltip max-width="auto" transfer>
|
|
||||||
<div slot="content" v-html="getTimes(data.date)"></div>
|
<div slot="content" v-html="getTimes(data.date)"></div>
|
||||||
<template v-if="doCheck(data.date)">{{$L('今天')}}</template>
|
<div class="item-day">
|
||||||
<template v-else>{{data.date | getCD}}</template>
|
<div v-if="data.today">{{$L('今天')}}</div>
|
||||||
<span :class="{'ui-state-down': true }">{{$L('已签到')}}</span>
|
<div v-else>{{data.day}}</div>
|
||||||
</Tooltip>
|
|
||||||
|
<div v-if="isCheck(data.date)" class="ui-state-down">{{$L('已签到')}}</div>
|
||||||
|
<span v-else-if="data.today" class="ui-state-default">{{$L('尚未签到')}}</span>
|
||||||
|
</div>
|
||||||
|
</ETooltip>
|
||||||
</td>
|
</td>
|
||||||
<template v-if="(!isCheck(data.date) && (doCheck(data.date) && !hasCheckin))">
|
<td v-else class="disabled">
|
||||||
<td v-if="!monthClass(data.month)"
|
<div class="item-day">
|
||||||
@click="checkNow"
|
<div>{{data.day}}</div>
|
||||||
:class="{'disa':monthClass(data.month), 'over':data.date == '', 'cur_day': doCheck(data.date) }">
|
<div v-if="isCheck(data.date)" class="ui-state-down">{{$L('已签到')}}</div>
|
||||||
{{$L('今天')}}
|
</div>
|
||||||
<span :class="{'ui-state-default': true }">{{$L('尚未签到')}}</span>
|
|
||||||
</td>
|
|
||||||
<td v-else
|
|
||||||
:class="{'disa':monthClass(data.month), 'over':data.date == '', 'cur_day': doCheck(data.date) }">
|
|
||||||
{{data.date | getCD}}
|
|
||||||
</td>
|
|
||||||
</template>
|
|
||||||
<td v-if="!isCheck(data.date) && (!doCheck(data.date)) "
|
|
||||||
:class="{'disa':monthClass(data.month), 'over':data.date == '', 'cur_day': doCheck(data.date) }">
|
|
||||||
{{data.date | getCD}}
|
|
||||||
</td>
|
</td>
|
||||||
</template>
|
</template>
|
||||||
</tr>
|
</tr>
|
||||||
@ -71,135 +64,85 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
today: new Date(),
|
|
||||||
year: '',
|
year: '',
|
||||||
month: '',
|
month: '',
|
||||||
day: '',
|
|
||||||
date: '',
|
|
||||||
startTime: '',
|
startTime: '',
|
||||||
endTime: '',
|
endTime: '',
|
||||||
dateArr: [],
|
|
||||||
hasCheckin: false,
|
dateArray: [],
|
||||||
|
historys: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.year = this.today.getFullYear();
|
const today = new Date()
|
||||||
this.month = this.today.getMonth() + 1;
|
this.year = today.getFullYear();
|
||||||
this.day = this.today.getDay();
|
this.month = today.getMonth() + 1;
|
||||||
this.date = this.today.getDate();
|
|
||||||
|
|
||||||
this.getCalendar();
|
this.generateCalendar();
|
||||||
},
|
|
||||||
filters: {
|
|
||||||
getCD(val) {
|
|
||||||
return val.split('/')[2]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
dateArr: {
|
checkin: {
|
||||||
deep: true,
|
handler(arr) {
|
||||||
handler: function (val, oldVal) {
|
arr.some(({date, section}) => {
|
||||||
this.startTime = val[0][0].date;
|
date = date.replace(/-0?/g, '/')
|
||||||
this.endTime = val[5][6].date;
|
let index = this.historys.findIndex(item => item.date == date)
|
||||||
this.setMonth(this.year + '/' + this.month, [this.startTime, this.endTime]);
|
if (index > -1) {
|
||||||
|
this.historys.splice(index, 1, {date, section})
|
||||||
|
} else {
|
||||||
|
this.historys.push({date, section})
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
hasNextMonth() {
|
hasNextMonth() {
|
||||||
const {year, month} = this;
|
const {year, month} = this;
|
||||||
const {y, m} = {y: $A.formatDate("Y"), m: $A.formatDate("m")};
|
return parseInt(year) != $A.formatDate("Y") || parseInt(month) < $A.formatDate("m");
|
||||||
return parseInt(year) != y || parseInt(month) < parseInt(m);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
checkNow() {
|
ym() {
|
||||||
this.$emit('checkIn')
|
return this.year + '-' + (this.month < 10 ? ('0' + this.month) : this.month);
|
||||||
},
|
},
|
||||||
setMonth(date,) {
|
isCheck(date) {
|
||||||
|
return !!this.historys.find(item => item.date == date)
|
||||||
|
},
|
||||||
|
setMonth(date) {
|
||||||
this.$emit('setMonth', date, [this.startTime, this.endTime])
|
this.$emit('setMonth', date, [this.startTime, this.endTime])
|
||||||
},
|
},
|
||||||
monthClass(type) {
|
getTimes(date) {
|
||||||
return type != 'cur';
|
const data = this.historys.find(item => item.date == date)
|
||||||
},
|
return data?.section.map(item => {
|
||||||
getTimes(thisDay) {
|
|
||||||
for (let i in this.checkin) {
|
|
||||||
if (this.checkin.hasOwnProperty(i)) {
|
|
||||||
if (new Date(thisDay).getTime() == $A.Date(this.checkin[i].date).getTime()) {
|
|
||||||
return this.checkin[i].section.map(item => {
|
|
||||||
return `${item[0]} - ${item[1] || 'None'}`
|
return `${item[0]} - ${item[1] || 'None'}`
|
||||||
}).join('<br/>');
|
}).join('<br/>')
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
isLeap() {
|
generateCalendar() {
|
||||||
const year = this.year;
|
let today = new Date($A.formatDate("Y/m/d"))
|
||||||
if (year % 4 == 0 && year % 100 > 0) {
|
let one = new Date(this.year, this.month - 1, 1)
|
||||||
return true;
|
let calcTime = one.getTime() - one.getDay() * 86400 * 1000
|
||||||
} else return year % 400 == 0 && year % 3200 > 0;
|
let array = []
|
||||||
},
|
|
||||||
getLen(m) {
|
|
||||||
const month = m || this.month;
|
|
||||||
if (month == 2) {
|
|
||||||
if (this.isLeap) {
|
|
||||||
return 29;
|
|
||||||
} else {
|
|
||||||
return 28;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (month < 8) {
|
|
||||||
if (month % 2 > 0) {
|
|
||||||
return 31;
|
|
||||||
} else {
|
|
||||||
return 30;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (month % 2 > 0) {
|
|
||||||
return 30;
|
|
||||||
} else {
|
|
||||||
return 31;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getCalendarTime() {
|
|
||||||
return this.year + '-' + this.month + '-' + this.date;
|
|
||||||
},
|
|
||||||
getCalendar() {
|
|
||||||
let len = this.getLen();
|
|
||||||
let d = new Date(this.year, this.month - 1, 1);
|
|
||||||
let dfw = d.getDay();
|
|
||||||
let arr = [];
|
|
||||||
let tem = 0;
|
|
||||||
let nextTem = 1;
|
|
||||||
let pre = dfw - 1
|
|
||||||
|
|
||||||
let _lastLen = this.getLen(this.month - 1)
|
|
||||||
|
|
||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < 6; i++) {
|
||||||
arr[i] = [];
|
array[i] = []
|
||||||
for (let j = 0; j < 7; j++) {
|
for (let j = 0; j < 7; j++) {
|
||||||
tem++;
|
let curDate = new Date(calcTime)
|
||||||
if (tem - dfw > 0 && tem - dfw <= len) {
|
let curMonth = curDate.getMonth() + 1
|
||||||
arr[i][j] = {date: this.year + '/' + (this.month) + '/' + (tem - dfw), month: 'cur'};
|
array[i][j] = {
|
||||||
} else {
|
day: curDate.getDate(),
|
||||||
if (tem <= dfw) {
|
date: `${curDate.getFullYear()}/${curMonth}/${curDate.getDate()}`,
|
||||||
arr[i][j] = {
|
today: today.getTime() == curDate.getTime(),
|
||||||
date: this.year + '/' + (this.month - 1) + '/' + (_lastLen - pre),
|
future: today.getTime() < curDate.getTime(),
|
||||||
month: 'pre'
|
month: curMonth == this.month
|
||||||
};
|
}
|
||||||
pre--;
|
calcTime += 86400 * 1000
|
||||||
|
|
||||||
} else {
|
|
||||||
arr[i][j] = {date: this.year + '/' + (this.month + 1) + '/' + (nextTem), month: 'next'};
|
|
||||||
nextTem++
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
this.dateArray = array
|
||||||
}
|
this.startTime = array[0][0].date;
|
||||||
this.dateArr = arr;
|
this.endTime = array[5][6].date;
|
||||||
|
this.setMonth(this.year + '/' + this.month, [this.startTime, this.endTime]);
|
||||||
},
|
},
|
||||||
nextMonth() {
|
nextMonth() {
|
||||||
if (this.month == 12) {
|
if (this.month == 12) {
|
||||||
@ -208,7 +151,7 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.month++;
|
this.month++;
|
||||||
}
|
}
|
||||||
this.getCalendar();
|
this.generateCalendar();
|
||||||
this.$emit('changeMonth', this.ym())
|
this.$emit('changeMonth', this.ym())
|
||||||
},
|
},
|
||||||
prevMonth() {
|
prevMonth() {
|
||||||
@ -218,39 +161,14 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.month--;
|
this.month--;
|
||||||
}
|
}
|
||||||
this.getCalendar();
|
this.generateCalendar();
|
||||||
this.$emit('changeMonth', this.ym())
|
this.$emit('changeMonth', this.ym())
|
||||||
},
|
},
|
||||||
nowMonth() {
|
nowMonth() {
|
||||||
this.year = parseInt($A.formatDate("Y"));
|
this.year = parseInt($A.formatDate("Y"));
|
||||||
this.month = parseInt($A.formatDate("m"));
|
this.month = parseInt($A.formatDate("m"));
|
||||||
this.getCalendar();
|
this.generateCalendar();
|
||||||
this.$emit('changeMonth', this.ym())
|
this.$emit('changeMonth', this.ym())
|
||||||
},
|
|
||||||
contains(arr) {
|
|
||||||
return !((arr[0] == '') && (arr[1] == '') && (arr[2] == '') && (arr[3] == '') && (arr[4] == '') && (arr[5] == '') && (arr[6] == ''));
|
|
||||||
},
|
|
||||||
isCheck(index) {
|
|
||||||
const todayDate = new Date();
|
|
||||||
for (let i in this.checkin) {
|
|
||||||
if ($A.Date(todayDate.getFullYear() + '/' + todayDate.getMonth() + '/' + todayDate.getDate()).getTime() == $A.Date(this.checkin[i].date).getTime()) {
|
|
||||||
//今日已经签到
|
|
||||||
this.hasCheckin = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new Date(index).getTime() == $A.Date(this.checkin[i].date).getTime()) {
|
|
||||||
//console.log('已经签到')
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
doCheck(d) {
|
|
||||||
let dString = new Date().getFullYear() + '/' + (new Date().getMonth() + 1) + '/' + new Date().getDate();
|
|
||||||
return new Date(d).getTime() == new Date(dString).getTime();
|
|
||||||
},
|
|
||||||
ym() {
|
|
||||||
return this.year + '-' + (this.month < 10 ? ('0' + this.month) : this.month);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -308,8 +226,11 @@ export default {
|
|||||||
right: 10px;
|
right: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.sign_tab {
|
.check-table {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
border: 0;
|
||||||
|
border-spacing: 0;
|
||||||
|
border-collapse: collapse;
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
th {
|
th {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -318,48 +239,38 @@ export default {
|
|||||||
}
|
}
|
||||||
td {
|
td {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 15px 0;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 14px;
|
|
||||||
border-right: 1px solid #eee;
|
border-right: 1px solid #eee;
|
||||||
border-top: 1px solid #eee;
|
border-top: 1px solid #eee;
|
||||||
|
font-size: 14px;
|
||||||
|
height: 52px;
|
||||||
|
.item-day {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
&:last-child {
|
&:last-child {
|
||||||
border-right: 0;
|
border-right: 0;
|
||||||
}
|
}
|
||||||
&.over {
|
&.disabled {
|
||||||
background-color: #fff;
|
color: #ccc;
|
||||||
border-left: 0;
|
background: none;
|
||||||
border-right: 0;
|
|
||||||
}
|
|
||||||
&.disa {
|
|
||||||
color: #ccc !important;
|
|
||||||
background: none !important;
|
|
||||||
|
|
||||||
* {
|
* {
|
||||||
color: #ccc !important;
|
color: #ccc;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.check_day {
|
&.today {
|
||||||
background-color: #f8f8f8;
|
background-color: #F29D38;
|
||||||
color: #58ce7a;
|
color: #FFF;
|
||||||
position: relative;
|
|
||||||
font-size: 14px;
|
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
.ivu-tooltip {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
.ivu-tooltip-rel {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
line-height: 26px;
|
|
||||||
padding-top: 4px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
&.checkin {
|
||||||
|
color: #58ce7a;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -367,25 +278,9 @@ export default {
|
|||||||
.ui-state-down,
|
.ui-state-down,
|
||||||
.ui-state-default {
|
.ui-state-default {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 3px;
|
|
||||||
left: 0;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sign_tab {
|
|
||||||
td {
|
|
||||||
&.cur_day {
|
|
||||||
background-color: #F29D38;
|
|
||||||
color: #FFF;
|
|
||||||
padding-top: 2px;
|
|
||||||
line-height: 26px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -162,7 +162,8 @@ export default {
|
|||||||
this.$store.dispatch("call", {
|
this.$store.dispatch("call", {
|
||||||
url: 'users/checkin/list',
|
url: 'users/checkin/list',
|
||||||
data: {
|
data: {
|
||||||
ym: $A.formatDate("Y-m")
|
ym: $A.formatDate("Y-m"),
|
||||||
|
before: 1
|
||||||
}
|
}
|
||||||
}).then(({data}) => {
|
}).then(({data}) => {
|
||||||
this.latelyFormat(data)
|
this.latelyFormat(data)
|
||||||
@ -173,15 +174,12 @@ export default {
|
|||||||
|
|
||||||
latelyFormat(data) {
|
latelyFormat(data) {
|
||||||
const time = $A.Time();
|
const time = $A.Time();
|
||||||
const Ym = $A.formatDate("Ym", time)
|
|
||||||
this.latelyData = [];
|
this.latelyData = [];
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
if (Ym == $A.formatDate("Ym", time - i * 86400)) {
|
|
||||||
const ymd = $A.formatDate("Y-m-d", time - i * 86400)
|
const ymd = $A.formatDate("Y-m-d", time - i * 86400)
|
||||||
const item = data.find(({date}) => date == ymd) || {date: ymd, section: []}
|
const item = data.find(({date}) => date == ymd) || {date: ymd, section: []}
|
||||||
this.latelyData.push(item)
|
this.latelyData.push(item)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
latelySection(section) {
|
latelySection(section) {
|
||||||
@ -196,7 +194,10 @@ export default {
|
|||||||
}, 600)
|
}, 600)
|
||||||
this.$store.dispatch("call", {
|
this.$store.dispatch("call", {
|
||||||
url: 'users/checkin/list',
|
url: 'users/checkin/list',
|
||||||
data: {ym}
|
data: {
|
||||||
|
ym,
|
||||||
|
before: 1
|
||||||
|
}
|
||||||
}).then(({data}) => {
|
}).then(({data}) => {
|
||||||
if (this.$refs.calendar.ym() != ym) {
|
if (this.$refs.calendar.ym() != ym) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user