forked from ccsens_fe/tall-mui-3
13 changed files with 1 additions and 1128 deletions
@ -1,473 +0,0 @@ |
|||||
<template> |
|
||||
<view class="zzx-calendar"> |
|
||||
<view class="calendar-heander"> |
|
||||
{{ timeStr }} |
|
||||
</view> |
|
||||
|
|
||||
<!-- 星期几标题 --> |
|
||||
<view class="calendar-weeks"> |
|
||||
<view class="calendar-week" :class="{ 'text-red-500': week === '六' || week === '日' }" v-for="(week, index) in weeks" :key="index"> |
|
||||
{{ week }} |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="calendar-content"> |
|
||||
<swiper |
|
||||
class="calendar-swiper" |
|
||||
:style="{ |
|
||||
width: '100%', |
|
||||
height: sheight, |
|
||||
}" |
|
||||
:indicator-dots="false" |
|
||||
:autoplay="false" |
|
||||
:duration="duration" |
|
||||
:current="current" |
|
||||
@change="changeSwp" |
|
||||
:circular="true" |
|
||||
> |
|
||||
<swiper-item class="calendar-item" v-for="sitem in swiper" :key="sitem"> |
|
||||
<view class="calendar-days"> |
|
||||
<!-- 当前的 --> |
|
||||
<template v-if="sitem === current"> |
|
||||
<view |
|
||||
class="calendar-day" |
|
||||
v-for="(item, index) in days" |
|
||||
:key="index" |
|
||||
:class="{ 'day-hidden': !item.show }" |
|
||||
@click="clickItem(item)" |
|
||||
> |
|
||||
<view class="date" :class="[item.isToday ? todayClass : '', item.fullDate === selectedDate ? checkedClass : '']"> |
|
||||
{{ item.time.getDate() }} |
|
||||
</view> |
|
||||
<view class="dot-show" v-if="item.info === '0'" :style="dotStyle"> </view> |
|
||||
</view> |
|
||||
</template> |
|
||||
<template v-else> |
|
||||
<!-- 下一个月/周 --> |
|
||||
<template v-if="current - sitem === 1 || current - sitem === -2"> |
|
||||
<view |
|
||||
class="calendar-day" |
|
||||
v-for="(item, index) in predays" |
|
||||
:key="index" |
|
||||
:class="{ |
|
||||
'day-hidden': !item.show, |
|
||||
}" |
|
||||
> |
|
||||
<view class="date" :class="[item.isToday ? todayClass : '']"> |
|
||||
{{ item.time.getDate() }} |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
<!-- 上一个月/周 --> |
|
||||
<template v-else> |
|
||||
<view |
|
||||
class="calendar-day" |
|
||||
v-for="(item, index) in nextdays" |
|
||||
:key="index" |
|
||||
:class="{ |
|
||||
'day-hidden': !item.show, |
|
||||
}" |
|
||||
> |
|
||||
<view class="date" :class="[item.isToday ? todayClass : '']"> |
|
||||
{{ item.time.getDate() }} |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
</template> |
|
||||
</view> |
|
||||
</swiper-item> |
|
||||
</swiper> |
|
||||
|
|
||||
<!-- <view class="mode-change" @click="changeMode"> |
|
||||
<view :class="weekMode ? 'mode-arrow-bottom' : 'mode-arrow-top'"> </view> |
|
||||
</view> --> |
|
||||
</view> |
|
||||
|
|
||||
<view class="flex justify-center u-font-18" style="color: #3b82f6" @click="goToday"> 今日 </view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState } from 'vuex'; |
|
||||
import { gegerateDates, formatDate } from './generateDates.js'; |
|
||||
|
|
||||
export default { |
|
||||
props: { |
|
||||
duration: { type: Number, default: 500 }, |
|
||||
// 是否返回今日 |
|
||||
showBack: { type: Boolean, default: false }, |
|
||||
// 今日的自定义样式class |
|
||||
todayClass: { type: String, default: 'is-today' }, |
|
||||
// 选中日期的样式class |
|
||||
checkedClass: { type: String, default: 'is-checked' }, |
|
||||
// 打点日期的自定义样式 |
|
||||
dotStyle: { |
|
||||
type: Object, |
|
||||
default: () => { |
|
||||
return { background: '#4ade80' }; |
|
||||
}, |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
watch: { |
|
||||
dotList: function (newvalue) { |
|
||||
const days = this.days.slice(0); |
|
||||
const index = days.findIndex(day => day.show); |
|
||||
days.forEach((day, i) => { |
|
||||
newvalue.forEach((item, j) => { |
|
||||
if (i - index === j) { |
|
||||
day.info = item; |
|
||||
} |
|
||||
}); |
|
||||
}); |
|
||||
this.days = days; |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
data() { |
|
||||
return { |
|
||||
weeks: ['日', '一', '二', '三', '四', '五', '六'], // 周 |
|
||||
current: 1, |
|
||||
currentYear: '', |
|
||||
currentMonth: '', |
|
||||
currentDate: '', |
|
||||
days: [], |
|
||||
weekMode: false, // false -> 月 true -> 显示周 |
|
||||
swiper: [0, 1, 2], |
|
||||
selectedDate: formatDate(new Date(), 'yyyy-MM-dd'), // 当前选中的日期 |
|
||||
start: '', |
|
||||
end: '', |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: { |
|
||||
...mapState('project', ['dotList']), |
|
||||
sheight() { |
|
||||
// 根据年月判断有多少行 |
|
||||
// 判断该月有多少天 |
|
||||
let h = '35px'; |
|
||||
if (!this.weekMode) { |
|
||||
const d = new Date(this.currentYear, this.currentMonth, 0); |
|
||||
const days = d.getDate(); // 判断本月有多少天 |
|
||||
let day = new Date(d.setDate(1)).getDay(); |
|
||||
// if (day === 0) { |
|
||||
// day = 7; |
|
||||
// } |
|
||||
const pre = 8 - day; |
|
||||
const rows = Math.ceil((days - pre) / 7) + 1; |
|
||||
h = 35 * rows + 'px'; |
|
||||
} |
|
||||
return h; |
|
||||
}, |
|
||||
|
|
||||
// 当前日期 年月 |
|
||||
timeStr() { |
|
||||
let str = ''; |
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate); |
|
||||
const y = d.getFullYear(); |
|
||||
const m = d.getMonth() + 1 <= 9 ? `0${d.getMonth() + 1}` : d.getMonth() + 1; |
|
||||
str = `${y}年${m}月`; |
|
||||
return str; |
|
||||
}, |
|
||||
|
|
||||
// 上一周期的days书籍 |
|
||||
predays() { |
|
||||
let pres = []; |
|
||||
if (this.weekMode) { |
|
||||
// 周模式 |
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate); |
|
||||
d.setDate(d.getDate() - 7); |
|
||||
pres = gegerateDates(d, 'week'); |
|
||||
} else { |
|
||||
// 月模式 |
|
||||
const d = new Date(this.currentYear, this.currentMonth - 2, 1); |
|
||||
pres = gegerateDates(d, 'month'); |
|
||||
} |
|
||||
return pres; |
|
||||
}, |
|
||||
|
|
||||
// 下一周期的days书籍 |
|
||||
nextdays() { |
|
||||
let nexts = []; |
|
||||
if (this.weekMode) { |
|
||||
// 周模式 |
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate); |
|
||||
d.setDate(d.getDate() + 7); |
|
||||
nexts = gegerateDates(d, 'week'); |
|
||||
} else { |
|
||||
// 月模式 |
|
||||
const d = new Date(this.currentYear, this.currentMonth, 1); |
|
||||
nexts = gegerateDates(d, 'month'); |
|
||||
} |
|
||||
return nexts; |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
created() { |
|
||||
this.initDate(); |
|
||||
this.start = this.$moment().startOf('month').valueOf(); |
|
||||
this.end = this.$moment().endOf('month').valueOf(); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
// |
|
||||
/** |
|
||||
* 滑动切换上下周期 |
|
||||
* 根据前一个减去目前的值我们可以判断是下一个月/周还是上一个月/周 |
|
||||
* current - pre === 1, -2 下一个月/周 |
|
||||
* current - pre === -1, 2 上一个月或者上一周 |
|
||||
*/ |
|
||||
changeSwp(e) { |
|
||||
const pre = this.current; |
|
||||
const current = e.target.current; |
|
||||
this.current = current; |
|
||||
|
|
||||
if (current - pre === 1 || current - pre === -2) { |
|
||||
// 下一个月 或 下一周 |
|
||||
this.daysNext(); |
|
||||
const arr = this.days.filter(s => s.show); |
|
||||
const end = `${arr[arr.length - 1].fullDate} 23:59:59`; |
|
||||
this.start = this.$moment(arr[0].fullDate).valueOf(); |
|
||||
this.end = this.$moment(end).valueOf(); |
|
||||
this.$emit('handleFindPoint', this.start, this.end); |
|
||||
} else { |
|
||||
// 上一个月 或 上一周 |
|
||||
this.daysPre(); |
|
||||
const arr = this.days.filter(s => s.show); |
|
||||
const end = `${arr[arr.length - 1].fullDate} 23:59:59`; |
|
||||
this.start = this.$moment(arr[0].fullDate).valueOf(); |
|
||||
this.end = this.$moment(end).valueOf(); |
|
||||
this.$emit('handleFindPoint', this.start, this.end); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 初始化日历的方法 |
|
||||
initDate(cur) { |
|
||||
let date = ''; |
|
||||
if (cur) { |
|
||||
date = new Date(cur); |
|
||||
} else { |
|
||||
date = new Date(); |
|
||||
} |
|
||||
this.currentDate = date.getDate(); // 今日几号 |
|
||||
this.currentYear = date.getFullYear(); // 当前年份 |
|
||||
this.currentMonth = date.getMonth() + 1; // 当前月份 |
|
||||
this.currentWeek = date.getDay() === 0 ? 7 : date.getDay(); // 1...6,0 星期几 |
|
||||
// const nowY = new Date().getFullYear(); // 当前年份 |
|
||||
// const nowM = new Date().getMonth() + 1; |
|
||||
// const nowD = new Date().getDate(); // 今日日期 几号 |
|
||||
// const nowW = new Date().getDay(); |
|
||||
// this.selectedDate = formatDate(new Date(), 'yyyy-MM-dd') |
|
||||
this.days = []; |
|
||||
let days = []; |
|
||||
if (this.weekMode) { |
|
||||
days = gegerateDates(date, 'week'); |
|
||||
// this.selectedDate = days[0].fullDate; |
|
||||
} else { |
|
||||
days = gegerateDates(date, 'month'); |
|
||||
// const sel = new Date(this.selectedDate.replace('-', '/').replace('-', '/')); |
|
||||
// const isMonth = sel.getFullYear() === this.currentYear && (sel.getMonth() + 1) === this.currentMonth; |
|
||||
// if(!isMonth) { |
|
||||
// this.selectedDate = formatDate(new Date(this.currentYear, this.currentMonth-1,1), 'yyyy-MM-dd') |
|
||||
// } |
|
||||
} |
|
||||
// 设置小红点 |
|
||||
days.forEach((day, i) => { |
|
||||
this.dotList.forEach((item, j) => { |
|
||||
if (i === j) { |
|
||||
day.info = item; |
|
||||
} |
|
||||
}); |
|
||||
}); |
|
||||
this.days = days; |
|
||||
// 派发事件,时间发生改变 |
|
||||
let obj = { |
|
||||
start: '', |
|
||||
end: '', |
|
||||
}; |
|
||||
if (this.weekMode) { |
|
||||
obj.start = this.days[0].time; |
|
||||
obj.end = this.days[6].time; |
|
||||
} else { |
|
||||
const start = new Date(this.currentYear, this.currentMonth - 1, 1); |
|
||||
const end = new Date(this.currentYear, this.currentMonth, 0); |
|
||||
obj.start = start; |
|
||||
obj.end = end; |
|
||||
} |
|
||||
this.$emit('days-change', obj); |
|
||||
}, |
|
||||
|
|
||||
// 上一个 |
|
||||
daysPre() { |
|
||||
if (this.weekMode) { |
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate); |
|
||||
d.setDate(d.getDate() - 7); |
|
||||
this.initDate(d); |
|
||||
} else { |
|
||||
const d = new Date(this.currentYear, this.currentMonth - 2, 1); |
|
||||
this.initDate(d); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 下一个 |
|
||||
daysNext() { |
|
||||
if (this.weekMode) { |
|
||||
const d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate); |
|
||||
d.setDate(d.getDate() + 7); |
|
||||
this.initDate(d); |
|
||||
} else { |
|
||||
const d = new Date(this.currentYear, this.currentMonth, 1); |
|
||||
this.initDate(d); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 切换模式 |
|
||||
changeMode() { |
|
||||
const premode = this.weekMode; |
|
||||
let isweek = false; |
|
||||
if (premode) { |
|
||||
isweek = !!this.days.find(item => item.fullDate === this.selectedDate); |
|
||||
} |
|
||||
this.weekMode = !this.weekMode; |
|
||||
let d = new Date(this.currentYear, this.currentMonth - 1, this.currentDate); |
|
||||
const sel = new Date(this.selectedDate.replace('-', '/').replace('-', '/')); |
|
||||
const isMonth = sel.getFullYear() === this.currentYear && sel.getMonth() + 1 === this.currentMonth; |
|
||||
if ((this.selectedDate && isMonth) || isweek) { |
|
||||
d = new Date(this.selectedDate.replace('-', '/').replace('-', '/')); |
|
||||
} |
|
||||
this.initDate(d); |
|
||||
}, |
|
||||
|
|
||||
// 点击日期 |
|
||||
clickItem(e) { |
|
||||
this.selectedDate = e.fullDate; |
|
||||
this.$emit('selected-change', e); |
|
||||
}, |
|
||||
|
|
||||
// 返回 |
|
||||
goToday() { |
|
||||
const d = new Date(); |
|
||||
this.initDate(d); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.zzx-calendar { |
|
||||
width: 100%; |
|
||||
height: auto; |
|
||||
background-color: #fff; |
|
||||
padding-bottom: 10px; |
|
||||
|
|
||||
.calendar-heander { |
|
||||
text-align: center; |
|
||||
padding: 16px 0; |
|
||||
position: relative; |
|
||||
font-size: 15px; |
|
||||
} |
|
||||
|
|
||||
.calendar-weeks { |
|
||||
width: 100%; |
|
||||
display: flex; |
|
||||
flex-flow: row nowrap; |
|
||||
margin-bottom: 10px; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
font-size: 12px; |
|
||||
color: #9ca3af; |
|
||||
font-weight: bold; |
|
||||
|
|
||||
.calendar-week { |
|
||||
width: calc(100% / 7); |
|
||||
height: 100%; |
|
||||
text-align: center; |
|
||||
} |
|
||||
} |
|
||||
swiper { |
|
||||
width: 100%; |
|
||||
height: 60upx; |
|
||||
} |
|
||||
.calendar-content { |
|
||||
min-height: 30px; |
|
||||
} |
|
||||
.calendar-swiper { |
|
||||
min-height: 35px; |
|
||||
transition: height ease-out 0.3s; |
|
||||
} |
|
||||
.calendar-item { |
|
||||
margin: 0; |
|
||||
padding: 0; |
|
||||
height: 100%; |
|
||||
} |
|
||||
.calendar-days { |
|
||||
display: flex; |
|
||||
flex-flow: row wrap; |
|
||||
width: 100%; |
|
||||
height: 100%; |
|
||||
overflow: hidden; |
|
||||
font-size: 14px; |
|
||||
|
|
||||
.calendar-day { |
|
||||
width: calc(100% / 7); |
|
||||
height: 35px; |
|
||||
text-align: center; |
|
||||
display: flex; |
|
||||
flex-flow: column nowrap; |
|
||||
justify-content: flex-start; |
|
||||
align-items: center; |
|
||||
position: relative; |
|
||||
} |
|
||||
} |
|
||||
.day-hidden { |
|
||||
visibility: hidden; |
|
||||
} |
|
||||
|
|
||||
.mode-change { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
margin-top: 5px; |
|
||||
|
|
||||
.mode-arrow-top { |
|
||||
width: 0; |
|
||||
height: 0; |
|
||||
border-left: 6px solid transparent; |
|
||||
border-right: 6px solid transparent; |
|
||||
border-bottom: 5px solid #ff6633; |
|
||||
} |
|
||||
.mode-arrow-bottom { |
|
||||
width: 0; |
|
||||
height: 0; |
|
||||
border-left: 6px solid transparent; |
|
||||
border-right: 6px solid transparent; |
|
||||
border-top: 5px solid #ff6633; |
|
||||
} |
|
||||
} |
|
||||
.is-today { |
|
||||
background: #ffffff; |
|
||||
border: 1upx solid #ff6633; |
|
||||
border-radius: 50%; |
|
||||
color: #ff6633; |
|
||||
} |
|
||||
.is-checked { |
|
||||
background: #ff6633; |
|
||||
color: #ffffff; |
|
||||
} |
|
||||
.date { |
|
||||
width: 25px; |
|
||||
height: 25px; |
|
||||
line-height: 25px; |
|
||||
margin: 0 auto; |
|
||||
border-radius: 25px; |
|
||||
} |
|
||||
.dot-show { |
|
||||
width: 6px; |
|
||||
height: 6px; |
|
||||
// background: red; |
|
||||
border-radius: 5px; |
|
||||
position: absolute; |
|
||||
top: 2px; |
|
||||
right: 10px; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,136 +0,0 @@ |
|||||
/* |
|
||||
*此函数的作用是根据传入的一个日期,返回这一周的日期或者这一个月的日期, |
|
||||
* 如果是月的话注意还包含上个月和下个月的日期,月的话总共数据有 6 * 7 = 42个 |
|
||||
* |
|
||||
*/ |
|
||||
/* |
|
||||
* 时间格式化函数 |
|
||||
* 重要提示,微信小程序new Date('2020-04-16')在ios中无法获取时间对象 |
|
||||
* 解决方式: 建议将时间都格式化成'2020/04/16 00:00:00'的格式 |
|
||||
* 函数示例: formatDate(new Date(), 'YYYY/MM/dd hh:mm:ss') |
|
||||
*/ |
|
||||
export const formatDate = (date, fmt) => { |
|
||||
if (/(y+)/.test(fmt)) { |
|
||||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); |
|
||||
} |
|
||||
let o = { |
|
||||
'M+': date.getMonth() + 1, |
|
||||
'd+': date.getDate(), |
|
||||
'h+': date.getHours(), |
|
||||
'm+': date.getMinutes(), |
|
||||
's+': date.getSeconds(), |
|
||||
}; |
|
||||
for (let k in o) { |
|
||||
if (new RegExp(`(${k})`).test(fmt)) { |
|
||||
let str = o[k] + ''; |
|
||||
fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? str : padLeftZero(str)); |
|
||||
} |
|
||||
} |
|
||||
return fmt; |
|
||||
}; |
|
||||
const padLeftZero = str => { |
|
||||
return ('00' + str).substr(str.length); |
|
||||
}; |
|
||||
|
|
||||
// 判断是不是date对象
|
|
||||
export const judgeType = s => { |
|
||||
// 函数返回数据的具体类型
|
|
||||
return Object.prototype.toString.call(s).slice(8, -1); |
|
||||
}; |
|
||||
|
|
||||
export const equalDate = (d1, d2) => { |
|
||||
let result = false; |
|
||||
if (d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate()) { |
|
||||
result = true; |
|
||||
} |
|
||||
return result; |
|
||||
}; |
|
||||
|
|
||||
/* 比较时间,时间格式为2020-04-04 |
|
||||
*/ |
|
||||
export const dateEqual = (before, after) => { |
|
||||
before = new Date(before.replace('-', '/').replace('-', '/')); |
|
||||
after = new Date(after.replace('-', '/').replace('-', '/')); |
|
||||
if (before.getTime() - after.getTime() === 0) { |
|
||||
return true; |
|
||||
} else { |
|
||||
return false; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
export const gegerateDates = (date = new Date(), type = 'week') => { |
|
||||
const result = []; |
|
||||
if (judgeType(date) === 'Date') { |
|
||||
// 年,月,日
|
|
||||
const y = date.getFullYear(); |
|
||||
const m = date.getMonth(); |
|
||||
const d = date.getDate(); |
|
||||
const days = new Date(y, m + 1, 0).getDate(); |
|
||||
// 获取日期是星期几
|
|
||||
// let weekIndex = date.getDay() === 0 ? 7 : date.getDay();
|
|
||||
let weekIndex = date.getDay(); |
|
||||
if (type === 'month') { |
|
||||
const dobj = new Date(y, m, 1); |
|
||||
// weekIndex = dobj.getDay() === 0 ? 7 : dobj.getDay();
|
|
||||
weekIndex = dobj.getDay(); |
|
||||
} |
|
||||
if (type === 'week') { |
|
||||
for (let i = weekIndex; i > 0; i--) { |
|
||||
const dtemp = new Date(y, m, d); |
|
||||
dtemp.setDate(dtemp.getDate() - i); |
|
||||
result.push({ |
|
||||
time: dtemp, |
|
||||
show: true, |
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'), |
|
||||
isToday: equalDate(new Date(), dtemp), |
|
||||
}); |
|
||||
} |
|
||||
for (let i = 0; i <= 7 - weekIndex; i++) { |
|
||||
const dtemp = new Date(y, m, d); |
|
||||
dtemp.setDate(dtemp.getDate() + i); |
|
||||
result.push({ |
|
||||
time: dtemp, |
|
||||
show: true, |
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'), |
|
||||
isToday: equalDate(new Date(), dtemp), |
|
||||
}); |
|
||||
} |
|
||||
} else if (type === 'month') { |
|
||||
// 上个月
|
|
||||
for (let i = weekIndex; i > 0; i--) { |
|
||||
const dtemp = new Date(y, m, 1); |
|
||||
dtemp.setDate(dtemp.getDate() - i); |
|
||||
result.push({ |
|
||||
time: dtemp, |
|
||||
show: false, |
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'), |
|
||||
isToday: equalDate(new Date(), dtemp), |
|
||||
}); |
|
||||
} |
|
||||
// 这个月的日期
|
|
||||
for (let i = 0; i < days; i++) { |
|
||||
const dtemp = new Date(y, m, 1); |
|
||||
dtemp.setDate(dtemp.getDate() + i); |
|
||||
result.push({ |
|
||||
time: dtemp, |
|
||||
show: true, |
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'), |
|
||||
isToday: equalDate(new Date(), dtemp), |
|
||||
}); |
|
||||
} |
|
||||
const len = 42 - result.length; |
|
||||
// 下个月的日期
|
|
||||
for (let i = 1; i <= len; i++) { |
|
||||
const dtemp = new Date(y, m + 1, 0); |
|
||||
dtemp.setDate(dtemp.getDate() + i); |
|
||||
result.push({ |
|
||||
time: dtemp, |
|
||||
show: false, |
|
||||
fullDate: formatDate(dtemp, 'yyyy-MM-dd'), |
|
||||
isToday: equalDate(new Date(), dtemp), |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
return result; |
|
||||
}; |
|
@ -1,37 +0,0 @@ |
|||||
<template> |
|
||||
<!-- TODO: 设置默认图片 --> |
|
||||
<image :src="src" mode="aspectFit" class="image" @click="getCode"></image> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { src: '' }; |
|
||||
}, |
|
||||
|
|
||||
created() { |
|
||||
this.getCode(); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
// 获取图形验证码 |
|
||||
async getCode() { |
|
||||
try { |
|
||||
const data = await this.$u.api.getImageCode(); |
|
||||
const { imageBase64, verificationCodeId } = data; |
|
||||
this.src = imageBase64; |
|
||||
this.$emit('on-code', verificationCodeId); |
|
||||
} catch (error) { |
|
||||
console.error('error: ', error); |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.image { |
|
||||
width: 100px !important; |
|
||||
height: 35px !important; |
|
||||
} |
|
||||
</style> |
|
@ -1,7 +0,0 @@ |
|||||
<template> |
|
||||
<view class="flex items-center justify-between"> |
|
||||
这是子项目 |
|
||||
</template> |
|
||||
<script> |
|
||||
export default {}; |
|
||||
</script> |
|
@ -1,72 +0,0 @@ |
|||||
<template> |
|
||||
<view class="py-3 mt-4 bg-white u-font-15"> |
|
||||
<view v-for="(project, index) in projects" :key="index"> |
|
||||
<!-- 有子项目 --> |
|
||||
<view class="flex items-center justify-between p-3"> |
|
||||
<view class="text-blue-400 border border-blue-200 rounded-full order bg-blue-50"> |
|
||||
{{ index + 1 }} |
|
||||
</view> |
|
||||
|
|
||||
<view class="flex-1 px-3" @click="openProject(project)"> |
|
||||
<view class="flex items-center mb-1"> |
|
||||
<view class="mr-2">{{ project.name }}</view> |
|
||||
<!-- 状态 TODO: --> |
|
||||
<view class="px-2 text-xs text-green-400 bg-green-100 rounded-full">进行中</view> |
|
||||
</view> |
|
||||
|
|
||||
<view class="flex items-center text-xs text-gray-400"> |
|
||||
<view class="pr-2">{{ $moment(+project.startTime).format('MM-DD HH:mm') }}</view> |
|
||||
至 |
|
||||
<view class="pl-2"> {{ $moment(+project.endTime).format('MM-DD HH:mm') }}</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 箭头 --> |
|
||||
<u-icon name="arrow-right" class="text-gray-400" size="14px" @click="openProject(project)"></u-icon> |
|
||||
</view> |
|
||||
</view> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapGetters, mapState } from 'vuex'; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return {}; |
|
||||
}, |
|
||||
|
|
||||
computed: { |
|
||||
...mapState('project', ['projects']), |
|
||||
...mapGetters('user', ['userId']), |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
/** |
|
||||
* 打开项目 |
|
||||
* @param {object} project 所点击的项目的信息 |
|
||||
*/ |
|
||||
openProject(project) { |
|
||||
const { name, id, url } = project; |
|
||||
url && (uni.$t.domain = url); |
|
||||
this.$u.route('pages/project/project', { |
|
||||
u: this.userId, |
|
||||
p: id, |
|
||||
pname: name, |
|
||||
url: encodeURIComponent(url), |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.order { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
width: 32px; |
|
||||
height: 32px; |
|
||||
font-size: 13px; |
|
||||
} |
|
||||
</style> |
|
@ -1,130 +0,0 @@ |
|||||
<template> |
|
||||
<view class="flex flex-col h-full bg-gray-50"> |
|
||||
<view class="relative" @touchmove="onMove"> |
|
||||
<!-- 日历 --> |
|
||||
<Calendar @selected-change="onDateChange" :show-back="true" ref="calendar" @handleFindPoint="handleFindPoint" /> |
|
||||
<!-- 上传 导入wbs --> |
|
||||
<Upload @success="onUploadSuccess" @error="onUploadError" /> |
|
||||
</view> |
|
||||
|
|
||||
<!-- 项目列表 --> |
|
||||
<Projects class="flex-1 overflow-y-auto" /> |
|
||||
|
|
||||
<!-- 全局提示框 --> |
|
||||
<u-top-tips ref="uTips"></u-top-tips> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
import { mapState, mapMutations } from 'vuex'; |
|
||||
|
|
||||
let prevY = 0; |
|
||||
|
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
calendar: null, |
|
||||
days: [], |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
computed: mapState('user', ['token']), |
|
||||
|
|
||||
watch: { |
|
||||
token(value) { |
|
||||
if (!value) return; |
|
||||
this.getProjects(); |
|
||||
this.handleFindPoint(); |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
onShow() { |
|
||||
if (!this.token) return; |
|
||||
this.getProjects(); |
|
||||
this.handleFindPoint(); |
|
||||
}, |
|
||||
|
|
||||
onReady() { |
|
||||
this.calendar = this.$refs.calendar; |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
...mapMutations('project', ['setProjects', 'setDotList']), |
|
||||
|
|
||||
// 获取项目列表 |
|
||||
getProjects(start = this.$moment().startOf('day').valueOf(), end = this.$moment().endOf('day').valueOf()) { |
|
||||
// const data = await this.$u.api.getProjects(start, end); |
|
||||
this.$t.$q.getProjects(start, end, (err, data) => { |
|
||||
if (err) { |
|
||||
console.error('err: ', err); |
|
||||
} else { |
|
||||
this.setProjects(data); |
|
||||
} |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* 查询小红点 |
|
||||
* @param { string } endTime 结束时间 |
|
||||
* @param { string } startTime 开始时间 |
|
||||
*/ |
|
||||
async handleFindPoint(start, end) { |
|
||||
try { |
|
||||
const startTime = start || this.$moment().startOf('month').valueOf(); |
|
||||
const endTime = end || this.$moment().endOf('month').valueOf(); |
|
||||
const data = await this.$u.api.findRedPoint(startTime, endTime); |
|
||||
this.setDotList(data); |
|
||||
} catch (error) { |
|
||||
console.log('error: ', error); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 点击了某个日期 |
|
||||
onDateChange(event) { |
|
||||
const day = this.$moment(event.fullDate); |
|
||||
const start = day.startOf('date').valueOf(); |
|
||||
const end = day.endOf('date').valueOf(); |
|
||||
this.getProjects(start, end); |
|
||||
}, |
|
||||
|
|
||||
// 监听触摸滑动 切换日历的模式 月/周 |
|
||||
onMove(event) { |
|
||||
const y = event.changedTouches[0].pageY; |
|
||||
if (y - prevY > 0) { |
|
||||
// 向下滑动 如果是周视图weekMode=true 就 变成 月视图weekMode=false |
|
||||
this.calendar.weekMode && (this.calendar.weekMode = false); |
|
||||
} else if (y - prevY < 0) { |
|
||||
// 向上滑动 如果是月视图weekMode=false 就变成 周视图weekMode=true |
|
||||
!this.calendar.weekMode && (this.calendar.weekMode = true); |
|
||||
} |
|
||||
prevY = y; |
|
||||
this.calendar.initDate(); |
|
||||
}, |
|
||||
|
|
||||
// 导入成功 |
|
||||
onUploadSuccess() { |
|
||||
this.$refs.uTips.show({ |
|
||||
title: '导入成功,即将打开新项目', |
|
||||
type: 'success', |
|
||||
duration: '3000', |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
// 导入失败 |
|
||||
onUploadError(error) { |
|
||||
this.$refs.uTips.show({ |
|
||||
title: error || '导入失败', |
|
||||
type: 'error', |
|
||||
duration: '6000', |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
page { |
|
||||
height: 100%; |
|
||||
overflow: hidden; |
|
||||
} |
|
||||
</style> |
|
@ -1,189 +0,0 @@ |
|||||
<template> |
|
||||
<view class="wrap"> |
|
||||
<u-form :model="model" :rules="rules" ref="uForm" :errorType="errorType"> |
|
||||
<!-- 手机号 --> |
|
||||
<u-form-item :rightIconStyle="{ color: '#888', fontSize: '32rpx' }" label="手机号码" prop="phone" label-width="160"> |
|
||||
<u-input placeholder="请输入手机号" v-model="model.phone" type="number"></u-input> |
|
||||
</u-form-item> |
|
||||
|
|
||||
<u-form-item label="图形验证码" prop="imageValue" label-width="160"> |
|
||||
<u-input placeholder="输入计算结果" v-model="model.imageValue" type="number"></u-input> |
|
||||
<ImageCode slot="right" @on-code="codeId = $event" /> |
|
||||
</u-form-item> |
|
||||
|
|
||||
<u-form-item label="验证码" prop="code" label-width="160"> |
|
||||
<u-input placeholder="请输入短信验证码" v-model="model.code" type="number"></u-input> |
|
||||
<u-button slot="right" type="primary" size="mini" @click="getCode">{{ codeTips }}</u-button> |
|
||||
</u-form-item> |
|
||||
</u-form> |
|
||||
|
|
||||
<view class="mt-8"> |
|
||||
<u-button @click="submit" type="primary">提交</u-button> |
|
||||
</view> |
|
||||
<u-verification-code :seconds="seconds" ref="uCode" @change="codeChange"></u-verification-code> |
|
||||
|
|
||||
<u-top-tips ref="uTips"></u-top-tips> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
data() { |
|
||||
return { |
|
||||
model: { |
|
||||
phone: '', // 手机号 |
|
||||
imageValue: '', // 图形验证码计算结果 |
|
||||
code: '', // 短信验证码 |
|
||||
}, |
|
||||
codeId: '', // 图形验证码的id |
|
||||
|
|
||||
rules: { |
|
||||
phone: [ |
|
||||
{ |
|
||||
required: true, |
|
||||
message: '请输入手机号', |
|
||||
trigger: ['change', 'blur'], |
|
||||
}, |
|
||||
{ |
|
||||
validator: (rule, value) => { |
|
||||
return this.$u.test.mobile(value); |
|
||||
}, |
|
||||
message: '手机号码不正确', |
|
||||
trigger: ['change', 'blur'], |
|
||||
}, |
|
||||
], |
|
||||
code: [ |
|
||||
{ |
|
||||
required: true, |
|
||||
message: '请输入验证码', |
|
||||
trigger: ['change', 'blur'], |
|
||||
}, |
|
||||
{ |
|
||||
validator: (rule, value) => { |
|
||||
return this.$u.test.code(value, 4); |
|
||||
}, |
|
||||
message: '验证码格式不正确', |
|
||||
trigger: ['change', 'blur'], |
|
||||
}, |
|
||||
], |
|
||||
}, |
|
||||
seconds: 120, // 验证码倒计时时长 |
|
||||
codeTips: '', |
|
||||
errorType: ['message'], |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
onReady() { |
|
||||
this.$refs.uForm.setRules(this.rules); |
|
||||
}, |
|
||||
methods: { |
|
||||
submit() { |
|
||||
this.$refs.uForm.validate(async valid => { |
|
||||
if (valid) { |
|
||||
try { |
|
||||
const { phone, code } = this.model; |
|
||||
const data = await this.$u.api.phoneBind(phone, code); |
|
||||
console.log('data: ', data); |
|
||||
this.$refs.uTips.show({ |
|
||||
title: '手机号绑定成功, 即将跳转上一页', |
|
||||
type: 'success', |
|
||||
duration: '3000', |
|
||||
}); |
|
||||
setTimeout(() => uni.navigateBack(), 2000); |
|
||||
} catch (error) { |
|
||||
this.$refs.uTips.show({ |
|
||||
title: error.msg || '手机号绑定失败', |
|
||||
type: 'error', |
|
||||
duration: '3000', |
|
||||
}); |
|
||||
} |
|
||||
} else { |
|
||||
console.log('验证失败'); |
|
||||
} |
|
||||
}); |
|
||||
}, |
|
||||
|
|
||||
codeChange(text) { |
|
||||
this.codeTips = text; |
|
||||
}, |
|
||||
// 获取验证码 |
|
||||
async getCode() { |
|
||||
if (this.$refs.uCode.canGetCode) { |
|
||||
try { |
|
||||
if (!this.validateCodeParams()) return; |
|
||||
const params = { |
|
||||
phone: this.model.phone, |
|
||||
verificationCodeId: this.codeId, |
|
||||
verificationCodeValue: this.model.imageValue, |
|
||||
}; |
|
||||
const data = await this.$u.api.getSmsCode(params); |
|
||||
this.seconds = data.expiredInSeconds; |
|
||||
this.$refs.uTips.show({ |
|
||||
title: '短信发送成功, 请查收', |
|
||||
type: 'success', |
|
||||
duration: '3000', |
|
||||
}); |
|
||||
// 通知验证码组件内部开始倒计时 |
|
||||
this.$refs.uCode.start(); |
|
||||
} catch (error) { |
|
||||
this.$refs.uTips.show({ |
|
||||
title: error.msg || '发送失败', |
|
||||
type: 'error', |
|
||||
duration: '3000', |
|
||||
}); |
|
||||
} |
|
||||
} else { |
|
||||
this.$u.toast('倒计时结束后再发送'); |
|
||||
} |
|
||||
}, |
|
||||
|
|
||||
// 验证发送短信验证码的参数 |
|
||||
validateCodeParams() { |
|
||||
if (!this.$u.test.mobile(this.model.phone)) { |
|
||||
this.$refs.uTips.show({ |
|
||||
title: '手机号输入不正确', |
|
||||
type: 'error', |
|
||||
duration: '3000', |
|
||||
}); |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
if (!this.codeId) { |
|
||||
this.$refs.uTips.show({ |
|
||||
title: '点击刷新图形验证码重试', |
|
||||
type: 'error', |
|
||||
duration: '3000', |
|
||||
}); |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
if (!this.model.imageValue && this.model.imageValue !== 0) { |
|
||||
this.$refs.uTips.show({ |
|
||||
title: '请输入图形验证码', |
|
||||
type: 'error', |
|
||||
duration: '3000', |
|
||||
}); |
|
||||
return false; |
|
||||
} |
|
||||
return true; |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<style scoped lang="scss"> |
|
||||
.wrap { |
|
||||
padding: 30rpx; |
|
||||
} |
|
||||
|
|
||||
.agreement { |
|
||||
display: flex; |
|
||||
align-items: center; |
|
||||
margin: 40rpx 0; |
|
||||
|
|
||||
.agreement-text { |
|
||||
padding-left: 8rpx; |
|
||||
color: $u-tips-color; |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -1,11 +0,0 @@ |
|||||
<template> |
|
||||
<web-view src="" /> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
onLoad(options) { |
|
||||
console.log('options: ', options); |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
@ -1,55 +0,0 @@ |
|||||
<template> |
|
||||
<view class="container p-3"> |
|
||||
<u-button type="primary" class="mb-3" @click="add">add</u-button> |
|
||||
<u-button type="primary" class="mb-3" @click="findOne">findOne</u-button> |
|
||||
<u-button type="primary" class="mb-3" @click="find">find</u-button> |
|
||||
<u-button type="primary" class="mb-3" @click="update">更新update</u-button> |
|
||||
<u-button type="primary" class="mb-3" @click="remove">删除remove</u-button> |
|
||||
<u-button type="primary" class="mb-3" @click="createIndex">创建索引和查询</u-button> |
|
||||
</view> |
|
||||
</template> |
|
||||
|
|
||||
<script> |
|
||||
export default { |
|
||||
created() { |
|
||||
// this.$t.$q.getProjects(this.$moment().startOf('day').valueOf(), this.$moment().endOf('day').valueOf(), (err, data) => { |
|
||||
// if (err) { |
|
||||
// console.error(err); |
|
||||
// } else { |
|
||||
// console.log('data: ' + data); |
|
||||
// } |
|
||||
// }); |
|
||||
}, |
|
||||
|
|
||||
methods: { |
|
||||
add() { |
|
||||
this.$db.create('projects', { id: '124', sex: ' man' }); |
|
||||
}, |
|
||||
|
|
||||
async findOne() { |
|
||||
const data = await this.$db.findOne('projects', '124'); |
|
||||
console.log(data); |
|
||||
}, |
|
||||
|
|
||||
async find() { |
|
||||
const data = await this.$db.find('projects'); |
|
||||
console.log(data); |
|
||||
}, |
|
||||
|
|
||||
async update() { |
|
||||
const data = await this.$db.update('projects', { id: '125', sex: 'woman' }); |
|
||||
console.log('update data: ', data); |
|
||||
}, |
|
||||
|
|
||||
async remove() { |
|
||||
const data = await this.$db.remove('projects', '123'); |
|
||||
console.log('update data: ', data); |
|
||||
}, |
|
||||
|
|
||||
async createIndex() { |
|
||||
// const data = await this.$db.createIndex('projects', 'sex', 'woman'); |
|
||||
console.log('update data: '); |
|
||||
}, |
|
||||
}, |
|
||||
}; |
|
||||
</script> |
|
Before Width: | Height: | Size: 853 B |
Before Width: | Height: | Size: 3.9 KiB |
Loading…
Reference in new issue