Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
W
wandouchengzhang_coach
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
石盼盼
wandouchengzhang_coach
Commits
6a512a9f
Commit
6a512a9f
authored
Nov 20, 2020
by
吴颖
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
'修改页面样式'
parent
415adb62
Changes
28
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
2393 additions
and
500 deletions
+2393
-500
app.json
app.json
+3
-8
core.js
components/calendar/core.js
+144
-0
helper.js
components/calendar/helper.js
+12
-0
index.js
components/calendar/index.js
+220
-0
index.json
components/calendar/index.json
+3
-0
index.wxml
components/calendar/index.wxml
+63
-0
index.wxss
components/calendar/index.wxss
+224
-0
index.js
components/calendar/plugins/index.js
+18
-0
base.js
components/calendar/plugins/preset/base.js
+274
-0
get-calendar-data.js
components/calendar/plugins/preset/get-calendar-data.js
+69
-0
index.js
components/calendar/plugins/preset/index.js
+9
-0
selectable.js
components/calendar/plugins/selectable.js
+222
-0
todo.js
components/calendar/plugins/todo.js
+150
-0
render.js
components/calendar/render.js
+51
-0
iconfont.wxss
components/calendar/theme/iconfont.wxss
+29
-0
theme-elegant.wxss
components/calendar/theme/theme-elegant.wxss
+62
-0
index.js
components/calendar/utils/index.js
+285
-0
logger.js
components/calendar/utils/logger.js
+23
-0
wxData.js
components/calendar/utils/wxData.js
+30
-0
today.png
images/today.png
+0
-0
info.js
pages/sign/info/info.js
+19
-27
index.js
pages/tabbar/index/index.js
+74
-31
index.json
pages/tabbar/index/index.json
+2
-2
index.wxml
pages/tabbar/index/index.wxml
+9
-3
index.wxss
pages/tabbar/index/index.wxss
+17
-39
personal.js
pages/tabbar/personal/personal.js
+137
-144
personal.wxml
pages/tabbar/personal/personal.wxml
+60
-62
project.config.json
project.config.json
+184
-184
No files found.
app.json
View file @
6a512a9f
...
@@ -56,7 +56,8 @@
...
@@ -56,7 +56,8 @@
"backgroundTextStyle"
:
"light"
,
"backgroundTextStyle"
:
"light"
,
"navigationBarBackgroundColor"
:
"#fff"
,
"navigationBarBackgroundColor"
:
"#fff"
,
"navigationBarTitleText"
:
"豌豆队长"
,
"navigationBarTitleText"
:
"豌豆队长"
,
"navigationBarTextStyle"
:
"black"
"navigationBarTextStyle"
:
"black"
,
"enablePullDownRefresh"
:
false
},
},
"style"
:
"v2"
,
"style"
:
"v2"
,
"sitemapLocation"
:
"sitemap.json"
,
"sitemapLocation"
:
"sitemap.json"
,
...
@@ -76,11 +77,5 @@
...
@@ -76,11 +77,5 @@
"van-tag"
:
"components/vant/tag/index"
,
"van-tag"
:
"components/vant/tag/index"
,
"van-image"
:
"components/vant/image/index"
,
"van-image"
:
"components/vant/image/index"
,
"van-popup"
:
"components/vant/popup/index"
"van-popup"
:
"components/vant/popup/index"
},
}
"plugins"
:
{
"calendar"
:
{
"version"
:
"1.1.3"
,
"provider"
:
"wx92c68dae5a8bb046"
}
}
}
}
components/calendar/core.js
0 → 100644
View file @
6a512a9f
import
{
dateUtil
,
getCalendarConfig
}
from
'
./utils/index
'
/**
* 计算当前月份前后两月应占的格子
* @param {number} year 年份
* @param {number} month 月份
*/
function
calculateEmptyGrids
(
year
,
month
,
config
)
{
const
prevMonthGrids
=
calculatePrevMonthGrids
(
year
,
month
,
config
)
const
nextMonthGrids
=
calculateNextMonthGrids
(
year
,
month
,
config
)
return
{
prevMonthGrids
,
nextMonthGrids
}
}
/**
* 计算上月应占的格子
* @param {number} year 年份
* @param {number} month 月份
*/
function
calculatePrevMonthGrids
(
year
,
month
,
config
)
{
let
empytGrids
=
[]
const
prevMonthDays
=
dateUtil
.
getDatesCountOfMonth
(
year
,
month
-
1
)
let
firstDayOfWeek
=
dateUtil
.
firstDayOfWeek
(
year
,
month
)
if
(
config
.
firstDayOfWeek
===
'
Mon
'
)
{
if
(
firstDayOfWeek
===
0
)
{
firstDayOfWeek
=
6
}
else
{
firstDayOfWeek
-=
1
}
}
if
(
firstDayOfWeek
>
0
)
{
const
len
=
prevMonthDays
-
firstDayOfWeek
const
{
onlyShowCurrentMonth
}
=
config
const
YMInfo
=
dateUtil
.
getPrevMonthInfo
({
year
,
month
})
for
(
let
i
=
prevMonthDays
;
i
>
len
;
i
--
)
{
if
(
onlyShowCurrentMonth
)
{
empytGrids
.
push
(
''
)
}
else
{
const
week
=
dateUtil
.
getDayOfWeek
(
+
year
,
+
month
,
i
)
empytGrids
.
push
({
...
YMInfo
,
date
:
i
,
week
})
}
}
empytGrids
.
reverse
()
}
return
empytGrids
}
/**
* 计算下一月日期是否需要多展示的日期
* 某些月份日期为5排,某些月份6排,统一为6排
* @param {number} year
* @param {number} month
* @param {object} config
*/
function
calculateExtraEmptyDate
(
year
,
month
,
config
)
{
let
extDate
=
0
if
(
+
month
===
2
)
{
extDate
+=
7
let
firstDayofMonth
=
dateUtil
.
getDayOfWeek
(
year
,
month
,
1
)
if
(
config
.
firstDayOfWeek
===
'
Mon
'
)
{
if
(
+
firstDayofMonth
===
1
)
extDate
+=
7
}
else
{
if
(
+
firstDayofMonth
===
0
)
extDate
+=
7
}
}
else
{
let
firstDayofMonth
=
dateUtil
.
getDayOfWeek
(
year
,
month
,
1
)
if
(
config
.
firstDayOfWeek
===
'
Mon
'
)
{
if
(
firstDayofMonth
!==
0
&&
firstDayofMonth
<
6
)
{
extDate
+=
7
}
}
else
{
if
(
firstDayofMonth
<=
5
)
{
extDate
+=
7
}
}
}
return
extDate
}
/**
* 计算下月应占的格子
* @param {number} year 年份
* @param {number} month 月份
*/
function
calculateNextMonthGrids
(
year
,
month
,
config
)
{
let
emptyGrids
=
[]
const
datesCount
=
dateUtil
.
getDatesCountOfMonth
(
year
,
month
)
let
lastDayWeek
=
dateUtil
.
getDayOfWeek
(
year
,
month
,
datesCount
)
if
(
config
.
firstDayOfWeek
===
'
Mon
'
)
{
if
(
lastDayWeek
===
0
)
{
lastDayWeek
=
6
}
else
{
lastDayWeek
-=
1
}
}
let
len
=
7
-
(
lastDayWeek
+
1
)
const
{
onlyShowCurrentMonth
}
=
config
if
(
!
onlyShowCurrentMonth
)
{
len
=
len
+
calculateExtraEmptyDate
(
year
,
month
,
config
)
}
const
YMInfo
=
dateUtil
.
getNextMonthInfo
({
year
,
month
})
for
(
let
i
=
1
;
i
<=
len
;
i
++
)
{
const
week
=
dateUtil
.
getDayOfWeek
(
+
year
,
+
month
,
i
)
if
(
onlyShowCurrentMonth
)
{
emptyGrids
.
push
(
''
)
}
else
{
emptyGrids
.
push
({
id
:
i
-
1
,
...
YMInfo
,
date
:
i
,
week
:
week
||
7
})
}
}
return
emptyGrids
}
/**
* 设置日历面板数据
* @param {number} year 年份
* @param {number} month 月份
* @param {number} curDate 日期
*/
function
calculateCurrentMonthDates
(
year
,
month
)
{
return
dateUtil
.
calcDates
(
year
,
month
)
}
export
function
calcJumpData
({
dateInfo
,
config
,
component
})
{
dateInfo
=
dateInfo
||
dateUtil
.
todayFMD
()
const
{
year
,
month
,
date
}
=
dateInfo
const
calendarConfig
=
config
||
getCalendarConfig
(
component
)
const
emptyGrids
=
calculateEmptyGrids
(
year
,
month
,
calendarConfig
)
const
calendar
=
{
curYear
:
year
,
curMonth
:
month
,
curDate
:
date
,
dates
:
calculateCurrentMonthDates
(
year
,
month
),
...
emptyGrids
}
return
calendar
}
components/calendar/helper.js
0 → 100644
View file @
6a512a9f
import
{
dateUtil
}
from
'
./utils/index
'
export
function
calcTargetYMInfo
()
{
return
{
right
:
dateUtil
.
getPrevMonthInfo
,
left
:
dateUtil
.
getNextMonthInfo
,
prev_month
:
dateUtil
.
getPrevMonthInfo
,
next_month
:
dateUtil
.
getNextMonthInfo
,
prev_year
:
dateUtil
.
getPrevYearInfo
,
next_year
:
dateUtil
.
getNextYearInfo
}
}
components/calendar/index.js
0 → 100644
View file @
6a512a9f
import
plugins
from
'
./plugins/index
'
import
{
calcJumpData
}
from
'
./core
'
import
{
renderCalendar
}
from
'
./render
'
import
{
calcTargetYMInfo
}
from
'
./helper
'
import
{
dateUtil
,
calendarGesture
,
logger
}
from
'
./utils/index
'
Component
({
options
:
{
styleIsolation
:
'
apply-shared
'
,
multipleSlots
:
true
// 在组件定义时的选项中启用多slot支持
},
properties
:
{
config
:
{
type
:
Object
,
value
:
{}
}
},
lifetimes
:
{
attached
:
function
()
{
this
.
initComp
()
}
},
methods
:
{
initComp
()
{
const
calendarConfig
=
this
.
setDefaultDisableDate
()
this
.
setConfig
(
calendarConfig
)
},
// 禁用某天日期配置默认为今天
setDefaultDisableDate
()
{
const
calendarConfig
=
this
.
properties
.
config
||
{}
if
(
calendarConfig
.
disableMode
&&
!
calendarConfig
.
disableMode
.
date
)
{
calendarConfig
.
disableMode
.
date
=
dateUtil
.
toTimeStr
(
dateUtil
.
todayFMD
()
)
}
return
calendarConfig
},
initCalendar
(
config
)
{
const
{
defaultDate
}
=
config
let
date
=
dateUtil
.
todayFMD
()
if
(
defaultDate
&&
typeof
defaultDate
===
'
string
'
)
{
const
dateInfo
=
defaultDate
.
split
(
'
-
'
)
if
(
dateInfo
.
length
<
3
)
{
return
logger
.
warn
(
'
defaultDate配置格式应为: 2018-4-2 或 2018-04-02
'
)
}
else
{
date
=
{
year
:
+
dateInfo
[
0
],
month
:
+
dateInfo
[
1
],
date
:
+
dateInfo
[
2
]
}
}
}
const
waitRenderData
=
calcJumpData
({
dateInfo
:
date
,
config
})
const
timestamp
=
dateUtil
.
todayTimestamp
()
if
(
config
.
autoChoosedWhenJump
)
{
const
target
=
waitRenderData
.
dates
.
filter
(
item
=>
dateUtil
.
toTimeStr
(
item
)
===
dateUtil
.
toTimeStr
(
date
)
)
if
(
target
&&
target
.
length
)
{
if
(
!
waitRenderData
.
selectedDates
)
{
waitRenderData
.
selectedDates
=
target
}
else
{
waitRenderData
.
selectedDates
.
push
(
target
[
0
])
}
}
}
return
{
...
waitRenderData
,
todayTimestamp
:
timestamp
,
weeksCh
:
dateUtil
.
getWeekHeader
(
config
.
firstDayOfWeek
)
}
},
setConfig
(
config
)
{
if
(
config
.
markToday
&&
typeof
config
.
markToday
===
'
string
'
)
{
config
.
highlightToday
=
true
}
config
.
theme
=
config
.
theme
||
'
default
'
this
.
setData
(
{
config
},
()
=>
{
for
(
let
plugin
of
plugins
.
installed
)
{
const
[,
p
]
=
plugin
if
(
typeof
p
.
install
===
'
function
'
)
{
p
.
install
(
this
)
}
if
(
typeof
p
.
methods
===
'
function
'
)
{
const
methods
=
p
.
methods
(
this
)
for
(
let
fnName
in
methods
)
{
const
fn
=
methods
[
fnName
]
if
(
typeof
fn
===
'
function
'
)
{
if
(
!
this
.
calendar
)
this
.
calendar
=
{}
this
.
calendar
[
fnName
]
=
fn
}
}
}
}
const
initData
=
this
.
initCalendar
(
config
)
renderCalendar
.
call
(
this
,
initData
,
config
)
}
)
},
tapDate
(
e
)
{
const
{
info
}
=
e
.
currentTarget
.
dataset
const
{
date
,
disable
}
=
info
||
{}
if
(
disable
||
!
date
)
return
const
{
calendar
,
config
}
=
this
.
data
let
calendarData
=
calendar
let
calendarConfig
=
config
if
(
config
.
takeoverTap
)
{
return
this
.
triggerEvent
(
'
takeoverTap
'
,
info
)
}
for
(
let
plugin
of
plugins
.
installed
)
{
const
[,
p
]
=
plugin
if
(
typeof
p
.
onTapDate
===
'
function
'
)
{
const
{
calendarData
:
__calendarData
,
calendarConfig
:
__calendarConfig
}
=
p
.
onTapDate
(
info
,
calendarData
,
calendarConfig
)
calendarData
=
__calendarData
calendarConfig
=
__calendarConfig
}
}
renderCalendar
.
call
(
this
,
calendarData
,
calendarConfig
).
then
(()
=>
{
this
.
triggerEvent
(
'
afterTapDate
'
,
info
)
})
},
/**
* 日历滑动开始
* @param {object} e
*/
calendarTouchstart
(
e
)
{
const
t
=
e
.
touches
[
0
]
const
startX
=
t
.
clientX
const
startY
=
t
.
clientY
this
.
swipeLock
=
true
this
.
setData
({
'
gesture.startX
'
:
startX
,
'
gesture.startY
'
:
startY
})
},
/**
* 日历滑动中
* @param {object} e
*/
calendarTouchmove
(
e
)
{
const
{
gesture
}
=
this
.
data
const
{
preventSwipe
}
=
this
.
properties
.
config
if
(
!
this
.
swipeLock
||
preventSwipe
)
return
if
(
calendarGesture
.
isLeft
(
gesture
,
e
.
touches
[
0
]))
{
this
.
handleSwipe
(
'
left
'
)
this
.
swipeLock
=
false
}
if
(
calendarGesture
.
isRight
(
gesture
,
e
.
touches
[
0
]))
{
this
.
handleSwipe
(
'
right
'
)
this
.
swipeLock
=
false
}
},
calendarTouchend
(
e
)
{
this
.
setData
({
'
calendar.leftSwipe
'
:
0
,
'
calendar.rightSwipe
'
:
0
})
},
handleSwipe
(
direction
)
{
let
swipeKey
=
'
calendar.leftSwipe
'
if
(
direction
===
'
right
'
)
{
swipeKey
=
'
calendar.rightSwipe
'
}
this
.
setData
({
[
swipeKey
]:
1
})
const
{
calendar
}
=
this
.
data
let
calendarData
=
calendar
const
{
curYear
,
curMonth
}
=
calendarData
const
getMonthInfo
=
calcTargetYMInfo
()[
direction
]
const
target
=
getMonthInfo
({
year
:
+
curYear
,
month
:
+
curMonth
})
target
.
direction
=
direction
this
.
renderCalendar
(
target
)
},
changeDate
(
e
)
{
const
{
type
}
=
e
.
currentTarget
.
dataset
const
{
calendar
:
calendarData
}
=
this
.
data
const
{
curYear
,
curMonth
}
=
calendarData
const
getMonthInfo
=
calcTargetYMInfo
()[
type
]
const
target
=
getMonthInfo
({
year
:
+
curYear
,
month
:
+
curMonth
})
target
.
direction
=
type
this
.
renderCalendar
(
target
)
},
renderCalendar
(
target
)
{
let
{
calendar
:
calendarData
,
config
}
=
this
.
data
const
{
curYear
,
curMonth
}
=
calendarData
||
{}
for
(
let
plugin
of
plugins
.
installed
)
{
const
[,
p
]
=
plugin
if
(
typeof
p
.
onSwitchCalendar
===
'
function
'
)
{
calendarData
=
p
.
onSwitchCalendar
(
target
,
calendarData
,
this
)
}
}
return
renderCalendar
.
call
(
this
,
calendarData
,
config
).
then
(()
=>
{
this
.
triggerEvent
(
'
whenChangeMonth
'
,
{
current
:
{
year
:
+
curYear
,
month
:
+
curMonth
},
next
:
target
})
})
}
}
})
components/calendar/index.json
0 → 100644
View file @
6a512a9f
{
"component"
:
true
}
\ No newline at end of file
components/calendar/index.wxml
0 → 100644
View file @
6a512a9f
<view class=" flex b tb ac" wx:if="{{calendar}}">
<view class="calendar b tb">
<!-- 头部操作栏 -->
<view class="handle {{config.theme}}_handle-color fs28 b lr ac pc">
<view class="prev fs36" wx:if="{{!config.weekMode}}">
<text class="prev-handle iconfont icon-left" bindtap="changeDate" data-type="prev_month"></text>
</view>
<view class="flex date-in-handle b lr cc" bindtap="doubleClickToToday">
{{calendar.curYear || "--"}}年{{calendar.curMonth || "--"}}月</view>
<view class="next fs36" wx:if="{{!config.weekMode}}">
<text class="next-handle iconfont icon-right" bindtap="changeDate" data-type="next_month"></text>
</view>
</view>
<!-- 星期栏 -->
<view class="weeks b lr ac {{config.theme}}_week-color">
<view class="week fs28" wx:for="{{calendar.weeksCh}}" wx:key="index" data-idx="{{index}}">{{item}}</view>
</view>
<!-- 日历面板主体 -->
<view class="b lr wrap calendarboard" bindtouchstart="calendarTouchstart" catchtouchmove="calendarTouchmove"
catchtouchend="calendarTouchend">
<!-- 上月日期格子 -->
<view class="grid b ac pc {{config.theme}}_prev-month-date" wx:for="{{calendar.prevMonthGrids}}"
wx:key="index" data-idx="{{index}}">
<view class="date-wrap b cc">
<view class="date">
{{item.date}}
</view>
</view>
</view>
<!-- 本月日期格子 -->
<view wx:for="{{calendar.dates}}" wx:key="index" data-idx="{{index}}" data-info="{{item}}" bindtap="tapDate"
class="grid {{item.class ? item.class : ''}} {{config.theme}}_normal-date b ac pc">
<view
class="date-wrap b cc {{config.emphasisWeek && (item.week === 0 || item.week === 6) ? config.theme + '_weekend-color' : ''}}">
<view
class="date b ac pc {{item.class ? item.class : ''}} {{item.isToday && config.highlightToday ? config.theme + '_today' : ''}} {{item.choosed ? config.theme + '_choosed' : ''}} {{item.disable ? config.theme + '_date-disable' : ''}} {{config.chooseAreaMode ? 'date-area-mode' : ''}}">
{{config.markToday && item.isToday ? config.markToday : item.date}}
<view
wx:if="{{(config.showLunar && item.lunar && !item.showTodoLabel) || (item.showTodoLabel && calendar.todoLabelPos !== 'bottom') || config.showHolidays}}"
class="date-desc {{config.theme}}_date-desc date-desc-bottom {{(item.choosed || item.isToday) ? 'date-desc-bottom-always' : ''}} {{item.disable ? config.theme + '_date-desc-disable' : ''}}">
<text
class="{{config.showHolidays && !item.showTodoLabel && item.label && !item.choosed ? config.theme + '_date-desc-lunar' : ''}} {{item.type === 'festival' ? config.theme + '_festival' : ''}}">{{item.label || item.lunar.Term || item.lunar.IDayCn}}</text>
</view>
<view wx:if="{{item.showTodoLabel && !calendar.todoLabelCircle}}"
class="{{item.todoText ? 'date-desc' : config.theme + '_todo-dot todo-dot'}} {{config.showLunar ? config.theme + '_date-desc-lunar' : ''}} {{calendar.todoLabelPos === 'bottom' ? 'date-desc-bottom todo-dot-bottom' : 'date-desc-top todo-dot-top'}} {{calendar.showLabelAlways && item.choosed && calendar.todoLabelPos === 'bottom' ? 'date-desc-bottom-always todo-dot-bottom-always' : ''}} {{calendar.showLabelAlways && item.choosed && calendar.todoLabelPos === 'top' ? 'date-desc-top-always todo-dot-top-always' : ''}}"
style="background-color: {{item.todoText ? '' : item.color || calendar.todoLabelColor}}; color: {{item.color}}">
{{item.todoText}}
</view>
</view>
</view>
</view>
<!-- 下月日期格子 -->
<view class="grid b ac pc {{config.theme}}_next-month-date" wx:for="{{calendar.nextMonthGrids}}"
wx:key="index" data-idx="{{index}}">
<view class="date-wrap b cc">
<view class="date">
{{item.date}}
</view>
</view>
</view>
</view>
</view>
</view>
\ No newline at end of file
components/calendar/index.wxss
0 → 100644
View file @
6a512a9f
@import './theme/iconfont.wxss';
@import './theme/theme-elegant.wxss';
.b {
display: flex;
}
.lr {
flex-direction: row;
}
.tb {
flex-direction: column;
}
.pc {
justify-content: center;
}
.ac {
align-items: center;
}
.cc {
align-items: center;
justify-content: center;
}
.wrap {
flex-wrap: wrap;
}
.flex {
flex-grow: 1;
}
.bg {
background-image: linear-gradient(to bottom, #faefe7, #ffcbd7);
overflow: hidden;
}
.white-color {
color: #fff;
}
.fs24 {
font-size: 24rpx;
}
.fs28 {
font-size: 28rpx;
}
.fs32 {
font-size: 32rpx;
}
.fs36 {
font-size: 36rpx;
}
.calendar {
width: 100%;
box-sizing: border-box;
}
/* 日历操作栏 */
.handle {
height: 93rpx;
line-height: 93rpx;
width: 400rpx;
margin: auto;
font-size: 32rpx;
font-weight: bold;
color: #000000;
}
.prev-handle,
.next-handle {
padding: 10rpx;
}
.date-in-handle {
height: 80rpx;
}
/* 星期栏 */
.weeks {
height: 50rpx;
line-height: 50rpx;
background: #FFF3DA;
font-size: 26rpx;
font-weight: bold;
color: #000000;
}
.week {
text-align: center;
}
.grid,
.week {
width: 14.286014285714286%;
}
.calendarboard {
padding: 20rpx 0 10rpx 0;
}
.date-wrap {
width: 100%;
height: 80rpx;
position: relative;
left: 0;
top: 0;
}
.date {
position: relative;
left: 0;
top: 0;
width: 62rpx;
height: 62rpx;
text-align: center;
line-height: 62rpx;
font-size: 26rpx;
font-weight: bold;
border-radius: 50%;
transition: all 0.3s;
animation-name: choosed;
animation-duration: 0.5s;
animation-timing-function: linear;
animation-iteration-count: 1;
color: #000000;
}
.date-area-mode {
width: 100%;
border-radius: 0;
}
.date-desc {
width: 150%;
height: 32rpx;
font-size: 20rpx;
line-height: 32rpx;
position: absolute;
left: 50%;
transform: translateX(-50%);
overflow: hidden;
word-break: break-all;
text-overflow: ellipsis;
white-space: nowrap;
-webkit-line-clamp: 1;
text-align: center;
}
@keyframes choosed {
from {
transform: scale(1);
}
50% {
transform: scale(0.9);
}
to {
transform: scale(1);
}
}
/* 日期圆圈标记 */
.todo-circle {
border-width: 1rpx;
border-style: solid;
box-sizing: border-box;
}
/* 待办点标记相关样式 */
.todo-dot {
width: 10rpx;
height: 10rpx;
border-radius: 50%;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
.todo-dot-top {
top: 3rpx;
}
.todo-dot.todo-dot-top-always {
top: -8rpx;
}
.todo-dot.todo-dot-bottom {
bottom: 0;
}
.todo-dot.todo-dot-bottom-always {
bottom: -10rpx;
}
/* 日期描述文字(待办文字/农历)相关样式 */
.date-desc.date-desc-top {
top: -6rpx;
}
.date-desc.date-desc-top-always {
top: -20rpx;
}
.date-desc.date-desc-bottom {
bottom: -14rpx;
}
.todo-circle .date-desc.date-desc-bottom {
bottom: -30rpx;
}
.date-desc.date-desc-bottom-always {
bottom: -28rpx;
}
components/calendar/plugins/index.js
0 → 100644
View file @
6a512a9f
import
preset
from
'
./preset/index
'
export
default
{
installed
:
[...
preset
],
use
(
plugin
)
{
if
(
typeof
plugin
!==
'
function
'
)
return
const
info
=
plugin
()
||
{}
const
{
name
}
=
info
if
(
name
&&
name
!==
'
methods
'
&&
!
this
.
installed
.
some
(
p
=>
p
[
0
]
===
name
)
)
{
this
.
installed
.
unshift
([
name
,
info
])
}
return
this
}
}
components/calendar/plugins/preset/base.js
0 → 100644
View file @
6a512a9f
/**
* @Author: drfu*
* @Description: 基础功能
* @Date: 2020-10-08 21:22:09*
* @Last Modified by: drfu
* @Last Modified time: 2020-10-11 13:28:52
* */
import
{
calcJumpData
}
from
'
../../core
'
import
{
renderCalendar
}
from
'
../../render
'
import
{
dateUtil
,
getCalendarData
,
setCalendarData
,
getCalendarConfig
}
from
'
../../utils/index
'
export
default
()
=>
{
return
{
name
:
'
base
'
,
beforeRender
(
calendarData
=
{},
calendarConfig
)
{
const
calendar
=
calendarData
const
{
selectedDates
=
[],
dates
}
=
calendar
let
_dates
=
[...
dates
]
if
(
selectedDates
.
length
)
{
const
selectedDatesStr
=
selectedDates
.
map
(
date
=>
dateUtil
.
toTimeStr
(
date
)
)
_dates
.
forEach
(
date
=>
{
const
dateStr
=
dateUtil
.
toTimeStr
(
date
)
if
(
selectedDatesStr
.
includes
(
dateStr
))
{
date
.
choosed
=
true
}
})
}
return
{
calendarData
:
{
...
calendarData
,
dates
:
_dates
},
calendarConfig
}
},
onTapDate
(
tapedDate
,
calendarData
=
{},
calendarConfig
=
{})
{
const
calendar
=
{
...
calendarData
}
const
dateIndex
=
dateUtil
.
findDateIndexInArray
(
tapedDate
,
calendarData
.
dates
)
const
{
multi
,
inverse
}
=
calendarConfig
let
dates
=
[...
calendar
.
dates
]
const
{
selectedDates
=
[]
}
=
calendar
if
(
!
multi
)
{
let
preSelectedDate
=
{}
if
(
selectedDates
.
length
)
{
preSelectedDate
=
[...
selectedDates
].
pop
()
||
{}
}
if
(
!
inverse
&&
+
preSelectedDate
.
date
===
+
tapedDate
.
date
)
{
return
calendar
}
let
_tapedDate
=
{
...
tapedDate
,
choosed
:
!
tapedDate
.
choosed
}
dates
[
dateIndex
]
=
_tapedDate
if
(
preSelectedDate
.
date
)
{
const
idx
=
dateUtil
.
findDateIndexInArray
(
preSelectedDate
,
dates
)
const
date
=
dates
[
idx
]
if
(
date
)
{
date
.
choosed
=
false
}
}
if
(
dates
[
dateIndex
].
choosed
)
{
calendar
.
selectedDates
=
[
dates
[
dateIndex
]]
}
else
{
calendar
.
selectedDates
=
[]
}
}
else
{
dates
[
dateIndex
]
=
{
...
dates
[
dateIndex
],
choosed
:
!
dates
[
dateIndex
].
choosed
}
if
(
!
calendar
.
selectedDates
)
{
calendar
.
selectedDates
=
[]
}
if
(
dates
[
dateIndex
].
choosed
)
{
calendar
.
selectedDates
.
push
(
dates
[
dateIndex
])
}
else
{
calendar
.
selectedDates
=
calendar
.
selectedDates
.
filter
(
date
=>
dateUtil
.
toTimeStr
(
date
)
!==
dateUtil
.
toTimeStr
(
dates
[
dateIndex
])
)
}
}
return
{
calendarData
:
{
...
calendar
,
dates
},
calendarConfig
}
},
onSwitchCalendar
(
date
,
calendarData
=
{},
component
)
{
const
calendarConfig
=
getCalendarConfig
(
component
)
if
(
calendarConfig
.
weekMode
)
{
return
calendarData
}
const
updatedRenderData
=
calcJumpData
({
dateInfo
:
date
,
config
:
calendarConfig
})
return
{
...
calendarData
,
...
updatedRenderData
}
},
methods
(
component
)
{
return
{
jump
:
dateInfo
=>
{
if
(
Object
.
prototype
.
toString
.
call
(
dateInfo
)
!==
'
[object Object]
'
)
return
const
updatedRenderData
=
calcJumpData
({
dateInfo
,
component
})
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
const
config
=
getCalendarConfig
(
component
)
if
(
config
.
autoChoosedWhenJump
)
{
const
target
=
updatedRenderData
.
dates
[
dateInfo
.
date
-
1
]
if
(
!
updatedRenderData
.
selectedDates
)
{
updatedRenderData
.
selectedDates
=
[
target
]
}
else
{
updatedRenderData
.
selectedDates
.
push
(
target
)
}
}
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
...
updatedRenderData
})
},
getCalendarConfig
()
{
return
getCalendarConfig
(
component
)
},
setCalendarConfig
(
config
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
!
component
||
!
component
.
config
)
{
reject
(
'
异常:未找到组件配置信息
'
)
return
}
let
conf
=
{
...
component
.
config
,
...
config
}
component
.
config
=
conf
setCalendarData
(
'
calendar.config
'
,
conf
)
})
},
cancelSelectedDates
(
cancelDates
=
[])
{
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
||
{}
const
{
dates
=
[],
selectedDates
=
[]
}
=
existCalendarData
let
updatedRenderData
=
{}
const
config
=
getCalendarConfig
(
component
)
let
chooseAreaData
=
{}
if
(
config
.
chooseAreaMode
)
{
chooseAreaData
=
{
chooseAreaTimestamp
:
[],
tempChooseAreaTimestamp
:
[]
}
}
if
(
!
cancelDates
.
length
)
{
dates
.
forEach
(
item
=>
{
item
.
choosed
=
false
})
updatedRenderData
=
{
dates
,
selectedDates
:
[]
}
}
else
{
const
cancelDatesStr
=
cancelDates
.
map
(
date
=>
dateUtil
.
toTimeStr
(
date
)
)
const
filterSelectedDates
=
selectedDates
.
filter
(
date
=>
!
cancelDatesStr
.
includes
(
dateUtil
.
toTimeStr
(
date
))
)
dates
.
forEach
(
date
=>
{
if
(
cancelDatesStr
.
includes
(
dateUtil
.
toTimeStr
(
date
)))
{
date
.
choosed
=
false
}
})
updatedRenderData
=
{
dates
,
selectedDates
:
filterSelectedDates
}
}
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
...
updatedRenderData
,
...
chooseAreaData
})
},
setSelectedDates
:
targetDates
=>
{
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
let
{
dates
,
selectedDates
=
[]
}
=
existCalendarData
||
{}
let
__selectedDates
=
[]
let
__dates
=
dates
if
(
!
targetDates
)
{
__dates
=
dates
.
map
(
item
=>
{
const
date
=
{
...
item
}
date
.
choosed
=
true
if
(
existCalendarData
.
showLabelAlways
&&
date
.
showTodoLabel
)
{
date
.
showTodoLabel
=
true
}
else
{
date
.
showTodoLabel
=
false
}
return
date
})
__selectedDates
=
dates
}
else
if
(
targetDates
&&
targetDates
.
length
)
{
const
allSelected
=
dateUtil
.
uniqueArrayByDate
(
selectedDates
.
concat
(
targetDates
)
)
const
allSelectedDateStr
=
allSelected
.
map
(
d
=>
dateUtil
.
toTimeStr
(
d
)
)
__dates
=
dates
.
map
(
item
=>
{
const
date
=
{
...
item
}
if
(
allSelectedDateStr
.
includes
(
dateUtil
.
toTimeStr
(
date
)))
{
date
.
choosed
=
true
__selectedDates
.
push
(
date
)
}
if
(
existCalendarData
.
showLabelAlways
&&
date
.
showTodoLabel
)
{
date
.
showTodoLabel
=
true
}
else
{
date
.
showTodoLabel
=
false
}
return
date
})
}
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
dates
:
__dates
,
selectedDates
:
__selectedDates
})
},
setDateStyle
:
toSetDates
=>
{
if
(
!
Array
.
isArray
(
toSetDates
))
return
Promise
.
reject
()
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
const
{
dates
=
[],
specialStyleDates
}
=
existCalendarData
||
{}
if
(
Array
.
isArray
(
specialStyleDates
))
{
toSetDates
=
dateUtil
.
uniqueArrayByDate
([
...
specialStyleDates
,
...
toSetDates
])
}
const
toSetDatesStr
=
toSetDates
.
map
(
item
=>
dateUtil
.
toTimeStr
(
item
))
const
_dates
=
dates
.
map
(
item
=>
{
const
idx
=
toSetDatesStr
.
indexOf
(
dateUtil
.
toTimeStr
(
item
))
if
(
idx
>
-
1
)
{
return
{
...
item
,
class
:
toSetDates
[
idx
].
class
}
}
else
{
return
item
}
})
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
dates
:
_dates
,
specialStyleDates
:
toSetDates
})
}
}
}
}
}
components/calendar/plugins/preset/get-calendar-data.js
0 → 100644
View file @
6a512a9f
/**
* @Author: drfu*
* @Description: 获取日历数据
* @Date: 2020-10-08 21:22:09*
* @Last Modified by: drfu
* @Last Modified time: 2020-10-11 13:42:37
* */
import
{
getCalendarData
,
logger
,
getCalendarConfig
}
from
'
../../utils/index
'
function
wrapDateWithLunar
(
dates
=
[],
convertFn
)
{
const
datesWithLunar
=
JSON
.
parse
(
JSON
.
stringify
(
dates
)).
map
(
date
=>
({
...
date
,
lunar
:
convertFn
(
date
)
}))
return
datesWithLunar
}
export
default
()
=>
{
return
{
name
:
'
getData
'
,
methods
(
component
)
{
return
{
getCurrentYM
:
()
=>
{
const
{
curYear
,
curMonth
}
=
getCalendarData
(
'
calendar
'
,
component
)
return
{
year
:
curYear
,
month
:
curMonth
}
},
getSelectedDates
:
(
options
=
{})
=>
{
const
dates
=
getCalendarData
(
'
calendar.selectedDates
'
,
component
)
||
[]
const
config
=
getCalendarConfig
(
component
)
||
{}
if
(
options
.
lunar
&&
!
config
.
showLunar
)
{
const
injectedFns
=
component
.
calendar
||
{}
if
(
typeof
injectedFns
.
convertSolarLunar
===
'
function
'
)
{
return
wrapDateWithLunar
(
dates
,
injectedFns
.
convertSolarLunar
)
}
else
{
logger
.
warn
(
'
获取农历信息需引入农历插件
'
)
}
}
else
{
return
dates
}
},
getCalendarDates
:
(
options
=
{})
=>
{
const
config
=
getCalendarConfig
(
component
)
||
{}
const
dates
=
getCalendarData
(
'
calendar.dates
'
,
component
)
if
(
options
.
lunar
&&
!
config
.
showLunar
)
{
const
injectedFns
=
component
.
calendar
||
{}
if
(
typeof
injectedFns
.
convertSolarLunar
===
'
function
'
)
{
return
wrapDateWithLunar
(
dates
,
injectedFns
.
convertSolarLunar
)
}
else
{
logger
.
warn
(
'
获取农历信息需引入农历插件
'
)
}
}
else
{
return
dates
}
},
getCalendarAllData
:
()
=>
{
return
{
data
:
getCalendarData
(
'
calendar
'
,
component
)
||
{},
config
:
getCalendarConfig
(
component
)
||
{}
}
}
}
}
}
}
components/calendar/plugins/preset/index.js
0 → 100644
View file @
6a512a9f
import
base
from
'
./base
'
import
getCalendarData
from
'
./get-calendar-data
'
const
preset
=
[
[
'
base
'
,
base
()],
[
'
get-calendar-data
'
,
getCalendarData
()]
]
export
default
preset
components/calendar/plugins/selectable.js
0 → 100644
View file @
6a512a9f
/**
* @Author: drfu*
* @Description: 禁用、启用日期选择
* @Date: 2020-10-08 21:22:09*
* @Last Modified by: drfu
* @Last Modified time: 2020-10-08 21:25:00
* */
import
{
getCalendarData
,
dateUtil
,
logger
}
from
'
../utils/index
'
import
{
renderCalendar
}
from
'
../render
'
function
convertEnableAreaToTimestamp
(
timearea
=
[])
{
const
start
=
timearea
[
0
].
split
(
'
-
'
)
const
end
=
timearea
[
1
].
split
(
'
-
'
)
if
(
start
.
length
!==
3
||
end
.
length
!==
3
)
{
logger
.
warn
(
'
enableArea() 参数格式为: ["2018-2-1", "2018-3-1"]
'
)
return
{}
}
const
startTimestamp
=
dateUtil
.
newDate
(
start
[
0
],
start
[
1
],
start
[
2
])
.
getTime
()
const
endTimestamp
=
dateUtil
.
newDate
(
end
[
0
],
end
[
1
],
end
[
2
]).
getTime
()
return
{
start
,
end
,
startTimestamp
,
endTimestamp
}
}
function
isValiditeOfDateArea
(
dateArea
)
{
const
{
start
,
end
,
startTimestamp
,
endTimestamp
}
=
convertEnableAreaToTimestamp
(
dateArea
)
if
(
!
start
||
!
end
)
return
const
datesCountOfStart
=
dateUtil
.
getDatesCountOfMonth
(
start
[
0
],
start
[
1
])
const
datesCountOfEnd
=
dateUtil
.
getDatesCountOfMonth
(
end
[
0
],
end
[
1
])
if
(
start
[
2
]
>
datesCountOfStart
||
start
[
2
]
<
1
)
{
logger
.
warn
(
'
enableArea() 开始日期错误,指定日期不在指定月份天数范围内
'
)
return
false
}
else
if
(
start
[
1
]
>
12
||
start
[
1
]
<
1
)
{
logger
.
warn
(
'
enableArea() 开始日期错误,月份超出1-12月份
'
)
return
false
}
else
if
(
end
[
2
]
>
datesCountOfEnd
||
end
[
2
]
<
1
)
{
logger
.
warn
(
'
enableArea() 截止日期错误,指定日期不在指定月份天数范围内
'
)
return
false
}
else
if
(
end
[
1
]
>
12
||
end
[
1
]
<
1
)
{
logger
.
warn
(
'
enableArea() 截止日期错误,月份超出1-12月份
'
)
return
false
}
else
if
(
startTimestamp
>
endTimestamp
)
{
logger
.
warn
(
'
enableArea()参数最小日期大于了最大日期
'
)
return
false
}
else
{
return
true
}
}
function
handleDisableMode
(
calendarConfig
)
{
const
{
disableMode
}
=
calendarConfig
if
(
!
disableMode
)
return
{}
const
disableBound
=
dateUtil
.
getTimeStamp
(
disableMode
.
date
)
||
dateUtil
.
todayTimestamp
()
return
{
disableBound
,
disableType
:
disableMode
.
type
}
}
function
disabledByConfig
(
dateInfo
,
currentDate
,
calendarConfig
)
{
const
date
=
{
...
dateInfo
}
const
{
disableType
,
disableBound
}
=
handleDisableMode
(
calendarConfig
)
if
(
(
disableType
===
'
before
'
&&
disableBound
&&
currentDate
<
disableBound
)
||
(
disableType
===
'
after
'
&&
disableBound
&&
currentDate
>
disableBound
)
)
{
date
.
disable
=
true
}
else
{
date
.
disable
=
false
}
return
date
}
export
default
()
=>
{
return
{
name
:
'
enable
'
,
beforeRender
(
calendarData
=
{},
calendarConfig
=
{})
{
const
{
dates
,
enableArea
,
enableDates
,
disableDates
,
renderCausedBy
}
=
calendarData
const
_dates
=
[...
dates
].
map
(
date
=>
{
let
item
=
{
...
date
}
const
timeStr
=
dateUtil
.
toTimeStr
(
date
)
const
timestamp
=
+
dateUtil
.
getTimeStamp
(
item
)
if
(
renderCausedBy
===
'
enableDates
'
)
{
if
(
enableDates
&&
enableDates
.
length
)
{
if
(
enableDates
.
includes
(
timeStr
))
{
item
.
disable
=
false
}
else
{
item
.
disable
=
true
}
return
item
}
}
else
if
(
renderCausedBy
===
'
enableArea
'
)
{
if
(
enableArea
&&
enableArea
.
length
)
{
const
[
startTimestamp
,
endTimestamp
]
=
enableArea
||
[]
const
ifOutofArea
=
+
startTimestamp
>
timestamp
||
timestamp
>
+
endTimestamp
item
.
disable
=
ifOutofArea
return
item
}
}
else
if
(
renderCausedBy
===
'
disableDates
'
)
{
if
(
disableDates
&&
disableDates
.
length
)
{
if
(
disableDates
&&
disableDates
.
includes
(
timeStr
))
{
item
.
disable
=
true
}
else
{
item
.
disable
=
false
}
return
item
}
}
return
disabledByConfig
(
item
,
timestamp
,
calendarConfig
)
})
return
{
calendarData
:
{
...
calendarData
,
dates
:
_dates
},
calendarConfig
}
},
methods
(
component
)
{
return
{
enableArea
:
(
dateArea
=
[])
=>
{
if
(
dateArea
.
length
===
2
)
{
const
validate
=
isValiditeOfDateArea
(
dateArea
)
if
(
validate
)
{
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
const
{
startTimestamp
,
endTimestamp
}
=
convertEnableAreaToTimestamp
(
dateArea
)
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
renderCausedBy
:
'
enableArea
'
,
enableArea
:
[
startTimestamp
,
endTimestamp
]
})
}
}
else
{
return
Promise
.
inject
(
'
enableArea()参数需为时间范围数组,形如:["2018-8-4" , "2018-8-24"]
'
)
}
},
enableDates
:
(
toSet
=
[])
=>
{
if
(
!
toSet
.
length
)
return
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
const
{
enableDates
=
[]
}
=
existCalendarData
||
{}
let
toSetDates
=
toSet
.
map
(
item
=>
{
let
date
=
{
...
item
}
if
(
typeof
date
===
'
string
'
)
{
return
dateUtil
.
transformDateRow2Dict
(
item
)
}
return
item
})
if
(
enableDates
.
length
)
{
toSetDates
=
dateUtil
.
uniqueArrayByDate
([
...
toSetDates
,
...
enableDates
.
map
(
d
=>
dateUtil
.
transformDateRow2Dict
(
d
))
])
}
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
renderCausedBy
:
'
enableDates
'
,
enableDates
:
toSetDates
.
map
(
date
=>
{
if
(
typeof
date
!==
'
string
'
)
{
return
dateUtil
.
toTimeStr
(
date
)
}
return
date
})
})
},
disableDates
:
toSet
=>
{
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
const
{
disableDates
=
[],
dates
=
[]
}
=
existCalendarData
||
{}
let
toSetDates
=
toSet
.
map
(
item
=>
{
let
date
=
{
...
item
}
if
(
typeof
date
===
'
string
'
)
{
return
dateUtil
.
transformDateRow2Dict
(
item
)
}
return
item
})
if
(
disableDates
&&
disableDates
.
length
)
{
toSetDates
=
dateUtil
.
uniqueArrayByDate
([
...
toSetDates
,
...
disableDates
.
map
(
d
=>
dateUtil
.
transformDateRow2Dict
(
d
))
])
}
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
renderCausedBy
:
'
disableDates
'
,
dates
,
disableDates
:
toSetDates
.
map
(
date
=>
{
if
(
typeof
date
!==
'
string
'
)
{
return
dateUtil
.
toTimeStr
(
date
)
}
return
date
})
})
}
}
}
}
}
components/calendar/plugins/todo.js
0 → 100644
View file @
6a512a9f
/**
* @Author: drfu*
* @Description: 代办事项
* @Date: 2020-10-08 21:22:09*
* @Last Modified by: drfu
* @Last Modified time: 2020-10-11 14:23:02
* */
import
{
getCalendarData
,
dateUtil
}
from
'
../utils/index
'
import
{
renderCalendar
}
from
'
../render
'
function
filterTodos
({
curYear
,
curMonth
,
exsitedTodos
,
toSetTodos
})
{
const
exsitedCurrentMonthTodos
=
dateUtil
.
filterDatesByYM
(
{
year
:
curYear
,
month
:
curMonth
},
exsitedTodos
)
const
toSetTodosOfThisMonth
=
dateUtil
.
filterDatesByYM
(
{
year
:
curYear
,
month
:
curMonth
},
toSetTodos
)
const
allTodosOfThisMonths
=
dateUtil
.
uniqueArrayByDate
(
exsitedCurrentMonthTodos
.
concat
(
toSetTodosOfThisMonth
)
)
return
allTodosOfThisMonths
}
function
updateDatePropertyOfTodoLabel
(
todos
,
dates
,
showLabelAlways
)
{
const
datesInfo
=
[...
dates
]
for
(
let
todo
of
todos
)
{
let
target
=
datesInfo
[
todo
.
date
-
1
]
if
(
!
target
)
continue
if
(
showLabelAlways
)
{
target
.
showTodoLabel
=
true
}
else
{
target
.
showTodoLabel
=
!
target
.
choosed
}
if
(
target
.
showTodoLabel
&&
todo
.
todoText
)
{
target
.
todoText
=
todo
.
todoText
}
if
(
todo
.
color
)
target
.
color
=
todo
.
color
}
return
datesInfo
}
export
default
()
=>
{
return
{
name
:
'
todo
'
,
methods
(
component
)
{
return
{
setTodos
:
(
options
=
{})
=>
{
const
calendar
=
getCalendarData
(
'
calendar
'
,
component
)
if
(
!
calendar
||
!
calendar
.
dates
)
{
return
Promise
.
reject
(
'
请等待日历初始化完成后再调用该方法
'
)
}
let
dates
=
[...
calendar
.
dates
]
const
{
curYear
,
curMonth
}
=
calendar
const
{
circle
,
dotColor
=
''
,
pos
=
'
bottom
'
,
showLabelAlways
,
dates
:
todoDates
=
[]
}
=
options
const
{
todos
=
[]
}
=
calendar
const
allTodosOfThisMonths
=
filterTodos
({
curYear
,
curMonth
,
exsitedTodos
:
todos
,
toSetTodos
:
todoDates
})
dates
=
updateDatePropertyOfTodoLabel
(
allTodosOfThisMonths
,
dates
,
showLabelAlways
)
const
calendarData
=
{
dates
,
todos
:
dateUtil
.
uniqueArrayByDate
(
todos
.
concat
(
todoDates
.
map
(
date
=>
dateUtil
.
tranformStr2NumOfDate
(
date
))
)
)
}
if
(
!
circle
)
{
if
(
pos
)
calendarData
.
todoLabelPos
=
pos
if
(
dotColor
)
calendarData
.
todoLabelColor
=
dotColor
}
calendarData
.
todoLabelCircle
=
circle
||
false
calendarData
.
showLabelAlways
=
showLabelAlways
||
false
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
...
calendarData
})
},
deleteTodos
(
todos
=
[])
{
if
(
!
(
todos
instanceof
Array
)
||
!
todos
.
length
)
return
Promise
.
reject
(
'
deleteTodos()应为入参为非空数组
'
)
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
const
allTodos
=
existCalendarData
.
todos
||
[]
const
toDeleteTodos
=
todos
.
map
(
item
=>
dateUtil
.
toTimeStr
(
item
))
const
remainTodos
=
allTodos
.
filter
(
item
=>
!
toDeleteTodos
.
includes
(
dateUtil
.
toTimeStr
(
item
))
)
const
{
dates
,
curYear
,
curMonth
}
=
existCalendarData
const
_dates
=
[...
dates
]
const
currentMonthTodos
=
dateUtil
.
filterDatesByYM
(
{
year
:
curYear
,
month
:
curMonth
},
remainTodos
)
_dates
.
forEach
(
item
=>
{
item
.
showTodoLabel
=
false
})
currentMonthTodos
.
forEach
(
item
=>
{
_dates
[
item
.
date
-
1
].
showTodoLabel
=
!
_dates
[
item
.
date
-
1
].
choosed
})
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
dates
:
_dates
,
todos
:
remainTodos
})
},
clearTodos
()
{
const
existCalendarData
=
getCalendarData
(
'
calendar
'
,
component
)
const
_dates
=
[...
existCalendarData
.
dates
]
_dates
.
forEach
(
item
=>
{
item
.
showTodoLabel
=
false
})
return
renderCalendar
.
call
(
component
,
{
...
existCalendarData
,
dates
:
_dates
,
todos
:
[]
})
},
getTodos
()
{
return
getCalendarData
(
'
calendar.todos
'
,
component
)
||
[]
}
}
}
}
}
components/calendar/render.js
0 → 100644
View file @
6a512a9f
import
plugins
from
'
./plugins/index
'
import
{
getCalendarConfig
}
from
'
./utils/index
'
/**
* 渲染日历
*/
export
function
renderCalendar
(
calendarData
,
calendarConfig
)
{
return
new
Promise
(
resolve
=>
{
const
Component
=
this
if
(
Component
.
firstRender
===
void
0
)
{
Component
.
firstRender
=
true
}
else
{
Component
.
firstRender
=
false
}
const
exitData
=
Component
.
data
.
calendar
||
{}
for
(
let
plugin
of
plugins
.
installed
)
{
const
[,
p
]
=
plugin
if
(
typeof
p
.
beforeRender
===
'
function
'
)
{
const
{
calendarData
:
newData
,
calendarConfig
:
newConfig
}
=
p
.
beforeRender
(
{
...
exitData
,
...
calendarData
},
calendarConfig
||
getCalendarConfig
(
Component
),
Component
)
calendarData
=
newData
calendarConfig
=
newConfig
}
}
Component
.
setData
(
{
config
:
calendarConfig
,
calendar
:
calendarData
},
()
=>
{
const
rst
=
{
calendar
:
calendarData
,
config
:
calendarConfig
,
firstRender
:
Component
.
firstRender
}
resolve
(
rst
)
if
(
Component
.
firstRender
)
{
Component
.
triggerEvent
(
'
afterCalendarRender
'
,
rst
)
Component
.
firstRender
=
false
}
}
)
})
}
components/calendar/theme/iconfont.wxss
0 → 100644
View file @
6a512a9f
@font-face {
font-family: 'iconfont';
src: url(data:font/truetype;charset=utf-8;base64,AAEAAAANAIAAAwBQRkZUTYda3jUAAAfEAAAAHEdERUYAKQANAAAHpAAAAB5PUy8yPllJ4AAAAVgAAABWY21hcAAP65kAAAHIAAABQmdhc3D//wADAAAHnAAAAAhnbHlmLotR3AAAAxwAAAGkaGVhZBTU+ykAAADcAAAANmhoZWEHKwOFAAABFAAAACRobXR4DasB4gAAAbAAAAAWbG9jYQC0AR4AAAMMAAAAEG1heHABEwAyAAABOAAAACBuYW1lKeYRVQAABMAAAAKIcG9zdEoLnOYAAAdIAAAAUgABAAAAAQAAiPM8al8PPPUACwQAAAAAANjbW5YAAAAA2NtblgCzAAQDTQL8AAAACAACAAAAAAAAAAEAAAOA/4AAXAQAAAAAAANNAAEAAAAAAAAAAAAAAAAAAAAEAAEAAAAHACYAAgAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQQAAZAABQAAAokCzAAAAI8CiQLMAAAB6wAyAQgAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA5+vn7gOA/4AAXAOAAIAAAAABAAAAAAAABAAAAAAAAAAEAAAABAABLgD4ALQAswAAAAAAAwAAAAMAAAAcAAEAAAAAADwAAwABAAAAHAAEACAAAAAEAAQAAQAA5+7//wAA5+v//xgYAAEAAAAAAAABBgAAAQAAAAAAAAABAgAAAAIAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJgBMAI4A0gABAS4ABAMKAvwAEgAACQEmBh0BFBcJAQYdARQWNwE2NAL+/j0ECQYBaP6YBgkEAcMMAZkBYAMEBU0IBf7n/ucFCE0FBAMBYAoeAAAAAQD4AAQC1AL8ABIAAAE1NCYHAQYUFwEWNj0BNCcJATYC1AkE/j0MDAHDBAkG/pgBaAYCpk0FBAP+oAoeCv6gAwQFTQgFARkBGQUAAAIAtAAgA00C4AASACUAAAkBNiYrASIHAwYUFwEWOwEyNicTATYmKwEiBwMGFBcBFjsBMjYnAREBCQMEBU0IBf8HBwD/BQhNBQQDJwEJAwQFTQgF/wcHAP8FCE0FBAMBgAFTBAkG/roJFgn+ugYJBAFTAVMECQb+ugkWCf66BgkEAAAAAAIAswAgA0wC4AASACUAAAEDJisBIgYXCQEGFjsBMjcBNjQlAyYrASIGFwkBBhY7ATI3ATY0AhX/BQhNBQQDAQn+9wMEBU0IBQD/BwEp/wUITQUEAwEJ/vcDBAVNCAUA/wcBlAFGBgkE/q3+rQQJBgFGCRYJAUYGCQT+rf6tBAkGAUYJFgAAAAAAABIA3gABAAAAAAAAABUALAABAAAAAAABAAgAVAABAAAAAAACAAcAbQABAAAAAAADAAgAhwABAAAAAAAEAAgAogABAAAAAAAFAAsAwwABAAAAAAAGAAgA4QABAAAAAAAKACsBQgABAAAAAAALABMBlgADAAEECQAAACoAAAADAAEECQABABAAQgADAAEECQACAA4AXQADAAEECQADABAAdQADAAEECQAEABAAkAADAAEECQAFABYAqwADAAEECQAGABAAzwADAAEECQAKAFYA6gADAAEECQALACYBbgAKAEMAcgBlAGEAdABlAGQAIABiAHkAIABpAGMAbwBuAGYAbwBuAHQACgAACkNyZWF0ZWQgYnkgaWNvbmZvbnQKAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABSAGUAZwB1AGwAYQByAABSZWd1bGFyAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABWAGUAcgBzAGkAbwBuACAAMQAuADAAAFZlcnNpb24gMS4wAABpAGMAbwBuAGYAbwBuAHQAAGljb25mb250AABHAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAHMAdgBnADIAdAB0AGYAIABmAHIAbwBtACAARgBvAG4AdABlAGwAbABvACAAcAByAG8AagBlAGMAdAAuAABHZW5lcmF0ZWQgYnkgc3ZnMnR0ZiBmcm9tIEZvbnRlbGxvIHByb2plY3QuAABoAHQAdABwADoALwAvAGYAbwBuAHQAZQBsAGwAbwAuAGMAbwBtAABodHRwOi8vZm9udGVsbG8uY29tAAACAAAAAAAAAAoAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAcAAAABAAIBAgEDAQQBBQVyaWdodARsZWZ0CmRvdWJsZWxlZnQLZG91YmxlcmlnaHQAAAAAAAH//wACAAEAAAAMAAAAFgAAAAIAAQADAAYAAQAEAAAAAgAAAAAAAAABAAAAANWkJwgAAAAA2NtblgAAAADY21uW) format('truetype');
font-weight: normal;
font-style: normal;
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
}
.icon-right::before {
content: "\e7eb";
}
.icon-left::before {
content: "\e7ec";
}
.icon-doubleleft::before {
content: "\e7ed";
}
.icon-doubleright::before {
content: "\e7ee";
}
components/calendar/theme/theme-elegant.wxss
0 → 100644
View file @
6a512a9f
.elegant_color,
.elegant_weekend-color,
.elegant_handle-color,
.elegant_week-color {
color: #000;
}
.elegant_today {
color: #000;
background: url('https://wdty.xueyoubangedu.com/wandou/today.png') no-repeat;
background-size: 62rpx 62rpx;
background-color: transparent;
}
.elegant_choosed {
color: #000;
background: url('https://wdty.xueyoubangedu.com/wandou/today.png') no-repeat;
background-size: 62rpx 62rpx;
background-color: transparent;
}
.elegant_date-disable {
color: #c7c7c7;
}
.elegant_choosed.elegant_date-disable {
color: #999;
background-color: #ebebeb;
}
.elegant_prev-month-date,
.elegant_next-month-date {
color: #e2e2e2;
}
.elegant_normal-date {
color: #000;
}
.elegant_todo-circle {
border-color: #161035;
}
.elegant_todo-dot {
background-color: #161035;
}
.elegant_date-desc {
color: #c2c2c2;
}
.elegant_date-desc-lunar {
color: #161035;
}
.elegant_date-desc-disable {
color: #e2e2e2;
}
.elegant_festival {
color: #c2c2c2;
}
components/calendar/utils/index.js
0 → 100644
View file @
6a512a9f
import
Logger
from
'
./logger
'
import
WxData
from
'
./wxData
'
let
systemInfo
export
function
getSystemInfo
()
{
if
(
systemInfo
)
return
systemInfo
systemInfo
=
wx
.
getSystemInfoSync
()
return
systemInfo
}
export
function
isIos
()
{
const
sys
=
getSystemInfo
()
return
/iphone|ios/i
.
test
(
sys
.
platform
)
}
class
Gesture
{
/**
* 左滑
* @param {object} e 事件对象
* @returns {boolean} 布尔值
*/
isLeft
(
gesture
=
{},
touche
=
{})
{
const
{
startX
,
startY
}
=
gesture
const
deltaX
=
touche
.
clientX
-
startX
const
deltaY
=
touche
.
clientY
-
startY
if
(
deltaX
<
-
60
&&
deltaY
<
20
&&
deltaY
>
-
20
)
{
return
true
}
else
{
return
false
}
}
/**
* 右滑
* @param {object} e 事件对象
* @returns {boolean} 布尔值
*/
isRight
(
gesture
=
{},
touche
=
{})
{
const
{
startX
,
startY
}
=
gesture
const
deltaX
=
touche
.
clientX
-
startX
const
deltaY
=
touche
.
clientY
-
startY
if
(
deltaX
>
60
&&
deltaY
<
20
&&
deltaY
>
-
20
)
{
return
true
}
else
{
return
false
}
}
}
class
DateUtil
{
newDate
(
year
,
month
,
date
)
{
let
cur
=
`
${
+
year
}
-
${
+
month
}
-
${
+
date
}
`
if
(
isIos
())
{
cur
=
`
${
+
year
}
/
${
+
month
}
/
${
+
date
}
`
}
return
new
Date
(
cur
)
}
/**
* 计算指定日期时间戳
* @param {object} date
*/
getTimeStamp
(
dateInfo
)
{
if
(
typeof
dateInfo
===
'
string
'
)
{
dateInfo
=
this
.
transformDateRow2Dict
(
dateInfo
)
}
if
(
Object
.
prototype
.
toString
.
call
(
dateInfo
)
!==
'
[object Object]
'
)
return
const
dateUtil
=
new
DateUtil
()
return
dateUtil
.
newDate
(
dateInfo
.
year
,
dateInfo
.
month
,
dateInfo
.
date
)
.
getTime
()
}
/**
* 计算指定月份共多少天
* @param {number} year 年份
* @param {number} month 月份
*/
getDatesCountOfMonth
(
year
,
month
)
{
return
new
Date
(
Date
.
UTC
(
year
,
month
,
0
)).
getUTCDate
()
}
/**
* 计算指定月份第一天星期几
* @param {number} year 年份
* @param {number} month 月份
*/
firstDayOfWeek
(
year
,
month
)
{
return
new
Date
(
Date
.
UTC
(
year
,
month
-
1
,
1
)).
getUTCDay
()
}
/**
* 计算指定日期星期几
* @param {number} year 年份
* @param {number} month 月份
* @param {number} date 日期
*/
getDayOfWeek
(
year
,
month
,
date
)
{
return
new
Date
(
Date
.
UTC
(
year
,
month
-
1
,
date
)).
getUTCDay
()
}
todayFMD
()
{
const
_date
=
new
Date
()
const
year
=
_date
.
getFullYear
()
const
month
=
_date
.
getMonth
()
+
1
const
date
=
_date
.
getDate
()
return
{
year
:
+
year
,
month
:
+
month
,
date
:
+
date
}
}
todayTimestamp
()
{
const
{
year
,
month
,
date
}
=
this
.
todayFMD
()
const
timestamp
=
this
.
newDate
(
year
,
month
,
date
).
getTime
()
return
timestamp
}
toTimeStr
(
dateInfo
=
{})
{
return
`
${
+
dateInfo
.
year
}
-
${
+
dateInfo
.
month
}
-
${
+
dateInfo
.
date
}
`
}
transformDateRow2Dict
(
dateStr
)
{
if
(
typeof
dateStr
===
'
string
'
&&
dateStr
.
includes
(
'
-
'
))
{
const
[
year
,
month
,
date
]
=
dateStr
.
split
(
'
-
'
)
return
this
.
tranformStr2NumOfDate
({
year
,
month
,
date
})
}
return
{}
}
tranformStr2NumOfDate
(
date
=
{})
{
const
target
=
{
...
date
}
// 可能传入字符串
target
.
year
=
+
target
.
year
target
.
month
=
+
target
.
month
target
.
date
=
+
target
.
date
return
target
}
sortDatesByTime
(
dates
=
[],
sortType
)
{
return
dates
.
sort
((
a
,
b
)
=>
{
const
at
=
this
.
getTimeStamp
(
a
)
const
bt
=
this
.
getTimeStamp
(
b
)
if
(
at
<
bt
&&
sortType
!==
'
desc
'
)
{
return
-
1
}
else
{
return
1
}
})
}
getPrevMonthInfo
(
date
=
{})
{
const
prevMonthInfo
=
Number
(
date
.
month
)
>
1
?
{
year
:
+
date
.
year
,
month
:
Number
(
date
.
month
)
-
1
}
:
{
year
:
Number
(
date
.
year
)
-
1
,
month
:
12
}
return
prevMonthInfo
}
getNextMonthInfo
(
date
=
{})
{
const
nextMonthInfo
=
Number
(
date
.
month
)
<
12
?
{
year
:
+
date
.
year
,
month
:
Number
(
date
.
month
)
+
1
}
:
{
year
:
Number
(
date
.
year
)
+
1
,
month
:
1
}
return
nextMonthInfo
}
getPrevYearInfo
(
date
=
{})
{
return
{
year
:
Number
(
date
.
year
)
-
1
,
month
:
+
date
.
month
}
}
getNextYearInfo
(
date
=
{})
{
return
{
year
:
Number
(
date
.
year
)
+
1
,
month
:
+
date
.
month
}
}
findDateIndexInArray
(
target
,
dates
)
{
return
dates
.
findIndex
(
item
=>
dateUtil
.
toTimeStr
(
item
)
===
dateUtil
.
toTimeStr
(
target
)
)
}
calcDates
(
year
,
month
)
{
const
datesCount
=
this
.
getDatesCountOfMonth
(
year
,
month
)
const
dates
=
[]
const
today
=
dateUtil
.
todayFMD
()
for
(
let
i
=
1
;
i
<=
datesCount
;
i
++
)
{
const
week
=
dateUtil
.
getDayOfWeek
(
+
year
,
+
month
,
i
)
const
date
=
{
year
:
+
year
,
id
:
i
-
1
,
month
:
+
month
,
date
:
i
,
week
,
isToday
:
+
today
.
year
===
+
year
&&
+
today
.
month
===
+
month
&&
i
===
+
today
.
date
}
dates
.
push
(
date
)
}
return
dates
}
/**
* 日期数组根据日期去重
* @param {array} array 数组
*/
uniqueArrayByDate
(
array
=
[])
{
let
uniqueObject
=
{}
let
uniqueArray
=
[]
array
.
forEach
(
item
=>
{
uniqueObject
[
dateUtil
.
toTimeStr
(
item
)]
=
item
})
for
(
let
i
in
uniqueObject
)
{
uniqueArray
.
push
(
uniqueObject
[
i
])
}
return
uniqueArray
}
/**
* 筛选指定年月日期
* @param {object} target 指定年月
* @param {array} dates 待筛选日期
*/
filterDatesByYM
(
target
,
dates
)
{
if
(
target
)
{
const
{
year
,
month
}
=
target
const
_dates
=
dates
.
filter
(
item
=>
+
item
.
year
===
+
year
&&
+
item
.
month
===
+
month
)
return
_dates
}
return
dates
}
getWeekHeader
(
firstDayOfWeek
)
{
let
weeksCh
=
[
'
日
'
,
'
一
'
,
'
二
'
,
'
三
'
,
'
四
'
,
'
五
'
,
'
六
'
]
if
(
firstDayOfWeek
===
'
Mon
'
)
{
weeksCh
=
[
'
一
'
,
'
二
'
,
'
三
'
,
'
四
'
,
'
五
'
,
'
六
'
,
'
日
'
]
}
return
weeksCh
}
}
/**
* 获取当前页面实例
*/
export
function
getCurrentPage
()
{
const
pages
=
getCurrentPages
()
||
[]
const
last
=
pages
.
length
-
1
return
pages
[
last
]
||
{}
}
export
function
getComponentById
(
componentId
)
{
const
logger
=
new
Logger
()
let
page
=
getCurrentPage
()
||
{}
if
(
page
.
selectComponent
&&
typeof
page
.
selectComponent
===
'
function
'
)
{
if
(
componentId
)
{
return
page
.
selectComponent
(
componentId
)
}
else
{
logger
.
warn
(
'
请传入组件ID
'
)
}
}
else
{
logger
.
warn
(
'
该基础库暂不支持多个小程序日历组件
'
)
}
}
export
const
logger
=
new
Logger
()
export
const
calendarGesture
=
new
Gesture
()
export
const
dateUtil
=
new
DateUtil
()
export
const
getCalendarData
=
(
key
,
component
)
=>
new
WxData
(
component
).
getData
(
key
)
export
const
setCalendarData
=
(
data
,
component
)
=>
new
WxData
(
component
).
setData
(
data
)
export
const
getCalendarConfig
=
component
=>
getCalendarData
(
'
config
'
,
component
)
export
const
setCalendarConfig
=
(
config
,
component
)
=>
setCalendarData
(
{
config
},
component
)
components/calendar/utils/logger.js
0 → 100644
View file @
6a512a9f
export
default
class
Logger
{
info
(
msg
)
{
console
.
log
(
'
%cInfo: %c
'
+
msg
,
'
color:#FF0080;font-weight:bold
'
,
'
color: #FF509B
'
)
}
warn
(
msg
)
{
console
.
log
(
'
%cWarn: %c
'
+
msg
,
'
color:#FF6600;font-weight:bold
'
,
'
color: #FF9933
'
)
}
tips
(
msg
)
{
console
.
log
(
'
%cTips: %c
'
+
msg
,
'
color:#00B200;font-weight:bold
'
,
'
color: #00CC33
'
)
}
}
components/calendar/utils/wxData.js
0 → 100644
View file @
6a512a9f
class
WxData
{
constructor
(
component
)
{
this
.
Component
=
component
}
getData
(
key
)
{
const
data
=
this
.
Component
.
data
if
(
!
key
)
return
data
if
(
key
.
includes
(
'
.
'
))
{
let
keys
=
key
.
split
(
'
.
'
)
const
tmp
=
keys
.
reduce
((
prev
,
next
)
=>
{
return
prev
[
next
]
},
data
)
return
tmp
}
else
{
return
this
.
Component
.
data
[
key
]
}
}
setData
(
data
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
!
data
)
return
reject
(
'
no data to set
'
)
if
(
typeof
data
===
'
object
'
)
{
this
.
Component
.
setData
(
data
,
()
=>
{
resolve
(
data
)
})
}
})
}
}
export
default
WxData
images/today.png
0 → 100644
View file @
6a512a9f
2.77 KB
pages/sign/info/info.js
View file @
6a512a9f
...
@@ -3,43 +3,40 @@ import {
...
@@ -3,43 +3,40 @@ import {
Base
Base
}
from
'
../../../utils/base.js
'
;
}
from
'
../../../utils/base.js
'
;
const
base
=
new
Base
()
const
base
=
new
Base
()
var
qiniuUploader
=
require
(
"
../../../utils/qiniuUploader
"
);
Page
({
Page
({
/**
/**
* 页面的初始数据
* 页面的初始数据
*/
*/
data
:
{
data
:
{
// telphone
: '',
coach_id
:
''
,
name
:
''
,
name
:
''
,
headImg
:
''
headImg
:
''
},
},
/**
* 生命周期函数--监听页面加载
*/
onLoad
:
function
(
options
)
{
onLoad
:
function
(
options
)
{
this
.
setData
({
coach_id
:
app
.
globalData
.
coach_id
})
this
.
getInfo
()
this
.
getInfo
()
},
},
getInfo
()
{
getInfo
()
{
let
params
=
{
let
params
=
{
url
:
'
user/getChildInfo
'
,
url
:
'
coach/info
'
,
type
:
'
POST
'
,
data
:
{
callback
:
(
data
)
=>
{
coach_id
:
this
.
data
.
coach_id
},
callback
:(
data
)
=>
{
this
.
setData
({
this
.
setData
({
// telphone: data.tel,
name
:
data
.
wx_user
.
nickname
,
name
:
data
.
nickname
,
headImg
:
data
.
wx_user
.
avatarurl
,
headImg
:
data
.
avatarurl
})
})
}
}
}
}
base
.
newRequest
(
params
)
base
.
newRequest
(
params
)
},
},
// changeTel(e) {
// this.setData({
// telphone: e.detail.value
// })
// },
changeName
(
e
)
{
changeName
(
e
)
{
this
.
setData
({
this
.
setData
({
name
:
e
.
detail
.
value
name
:
e
.
detail
.
value
...
@@ -65,14 +62,6 @@ Page({
...
@@ -65,14 +62,6 @@ Page({
})
})
},
},
saveInfo
()
{
saveInfo
()
{
// const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
// else if(this.data.telphone == '') {
// base.toast('请输入手机号')
// return
// } else if (!reg.test(this.data.telphone)) {
// base.toast('手机号格式不正确')
// return
// }
if
(
this
.
data
.
name
==
''
)
{
if
(
this
.
data
.
name
==
''
)
{
base
.
toast
(
'
请输入姓名
'
)
base
.
toast
(
'
请输入姓名
'
)
return
return
...
@@ -81,9 +70,12 @@ Page({
...
@@ -81,9 +70,12 @@ Page({
return
return
}
}
let
params
=
{
let
params
=
{
url
:
''
,
url
:
'
coach/save_info
'
,
type
:
'
POST
'
,
data
:
{
data
:
{
coach_id
:
this
.
data
.
coach_id
,
avatarurl
:
this
.
data
.
headImg
,
nickname
:
this
.
data
.
name
},
},
callback
:(
data
)
=>
{
callback
:(
data
)
=>
{
base
.
toast
(
'
修改信息成功
'
)
base
.
toast
(
'
修改信息成功
'
)
...
...
pages/tabbar/index/index.js
View file @
6a512a9f
...
@@ -4,7 +4,6 @@ import {
...
@@ -4,7 +4,6 @@ import {
}
from
'
../../../utils/base.js
'
;
}
from
'
../../../utils/base.js
'
;
const
base
=
new
Base
()
const
base
=
new
Base
()
const
util
=
require
(
'
../../../utils/util
'
);
const
util
=
require
(
'
../../../utils/util
'
);
Page
({
Page
({
/**
/**
...
@@ -18,7 +17,19 @@ Page({
...
@@ -18,7 +17,19 @@ Page({
curDate
:
''
,
curDate
:
''
,
list
:
[],
list
:
[],
allList
:
[],
allList
:
[],
month
:
''
month
:
''
,
calendarConfig
:
{
multi
:
true
,
// 是否开启多选,
weekMode
:
false
,
// 周视图模式
theme
:
'
elegant
'
,
// 日历主题,目前共两款可选择,默认 default 及 elegant,自定义主题色在参考 /theme 文件夹
inverse
:
true
,
// 单选模式下是否支持取消选中,
markToday
:
'
今
'
,
// 当天日期展示不使用默认数字,用特殊文字标记
takeoverTap
:
false
,
// 是否完全接管日期点击事件(日期不会选中)
emphasisWeek
:
true
,
// 是否高亮显示周末日期
chooseAreaMode
:
false
,
// 开启日期范围选择模式,该模式下只可选择时间段
preventSwipe
:
true
,
// 是否禁用日历滑动切换月份
onlyShowCurrentMonth
:
true
,
// 日历面板是否只显示本月日期
}
},
},
/**
/**
...
@@ -41,7 +52,7 @@ Page({
...
@@ -41,7 +52,7 @@ Page({
},
},
getAllList
()
{
getAllList
()
{
wx
.
showLoading
({
wx
.
showLoading
({
title
:
'
加载中...
'
,
title
:
'
加载中...
'
,
})
})
let
params
=
{
let
params
=
{
url
:
'
coach/timetable
'
,
url
:
'
coach/timetable
'
,
...
@@ -50,23 +61,11 @@ Page({
...
@@ -50,23 +61,11 @@ Page({
month
:
this
.
data
.
month
month
:
this
.
data
.
month
},
},
callback
:
(
data
)
=>
{
callback
:
(
data
)
=>
{
console
.
log
(
data
)
wx
.
hideLoading
()
wx
.
hideLoading
()
let
daysColor
=
[];
data
.
forEach
(
function
(
el
,
index
)
{
daysColor
.
push
({
month
:
'
current
'
,
day
:
el
.
class_date
.
split
(
'
-
'
)[
2
],
color
:
'
#fff
'
,
background
:
'
#B4BC4D
'
})
})
this
.
setData
({
this
.
setData
({
daysColor
:
daysColor
,
allList
:
data
allList
:
data
})
})
console
.
log
(
this
.
data
.
daysColor
)
this
.
afterCalendarRender
()
}
}
}
}
base
.
newRequest
(
params
)
base
.
newRequest
(
params
)
...
@@ -87,26 +86,36 @@ Page({
...
@@ -87,26 +86,36 @@ Page({
}
}
base
.
newRequest
(
params
)
base
.
newRequest
(
params
)
},
},
prev
:
function
(
event
)
{
afterCalendarRender
(
e
)
{
let
currentMonth
=
util
.
formatNumber
(
event
.
detail
.
currentMonth
)
let
daysColor
=
[];
this
.
setData
({
this
.
data
.
allList
.
forEach
(
function
(
el
)
{
month
:
event
.
detail
.
currentYear
+
currentMonth
daysColor
.
push
({
})
year
:
el
.
class_date
.
split
(
'
-
'
)[
0
],
this
.
getAllList
();
month
:
el
.
class_date
.
split
(
'
-
'
)[
1
],
},
date
:
el
.
class_date
.
split
(
'
-
'
)[
2
],
next
:
function
(
event
)
{
class
:
'
circle_data
'
let
currentMonth
=
util
.
formatNumber
(
event
.
detail
.
currentMonth
)
})
this
.
setData
({
month
:
event
.
detail
.
currentYear
+
currentMonth
})
})
this
.
getAllList
();
const
calendar
=
this
.
selectComponent
(
'
#calendar
'
).
calendar
calendar
.
setDateStyle
(
daysColor
)
},
},
dayClick
:
function
(
event
)
{
afterTapDate
(
e
)
{
console
.
log
(
event
)
const
calendar
=
this
.
selectComponent
(
'
#calendar
'
).
calendar
calendar
.
cancelSelectedDates
()
this
.
setData
({
this
.
setData
({
curDate
:
e
vent
.
detail
.
year
+
'
-
'
+
util
.
formatNumber
(
event
.
detail
.
month
)
+
'
-
'
+
util
.
formatNumber
(
event
.
detail
.
day
)
curDate
:
e
.
detail
.
year
+
'
-
'
+
util
.
formatNumber
(
e
.
detail
.
month
)
+
'
-
'
+
util
.
formatNumber
(
e
.
detail
.
date
)
})
})
const
toSet
=
[
{
year
:
e
.
detail
.
year
,
month
:
e
.
detail
.
month
,
date
:
e
.
detail
.
date
,
class
:
'
orange-date
'
// 页面定义的 class,多个 class 由空格隔开
}
]
calendar
.
setSelectedDates
(
toSet
)
if
(
!
this
.
data
.
locked
)
{
if
(
!
this
.
data
.
locked
)
{
this
.
setData
({
this
.
setData
({
locked
:
true
,
locked
:
true
,
...
@@ -115,6 +124,40 @@ Page({
...
@@ -115,6 +124,40 @@ Page({
this
.
getList
();
this
.
getList
();
}
}
},
},
whenChangeMonth
(
e
)
{
let
currentMonth
=
util
.
formatNumber
(
e
.
detail
.
next
.
month
)
this
.
setData
({
month
:
e
.
detail
.
next
.
year
+
currentMonth
})
this
.
getAllList
();
},
// prev: function (event) {
// let currentMonth = util.formatNumber(event.detail.currentMonth)
// this.setData({
// month: event.detail.currentYear + currentMonth
// })
// this.getAllList();
// },
// next: function (event) {
// let currentMonth = util.formatNumber(event.detail.currentMonth)
// this.setData({
// month: event.detail.currentYear + currentMonth
// })
// this.getAllList();
// },
// dayClick: function (event) {
// console.log(event)
// this.setData({
// curDate: event.detail.year + '-' + util.formatNumber(event.detail.month) + '-' + util.formatNumber(event.detail.day)
// })
// if (!this.data.locked) {
// this.setData({
// locked: true,
// courseList: [],
// })
// this.getList();
// }
// },
onChange
(
e
)
{
onChange
(
e
)
{
let
index
=
e
.
currentTarget
.
dataset
.
index
let
index
=
e
.
currentTarget
.
dataset
.
index
...
...
pages/tabbar/index/index.json
View file @
6a512a9f
{
{
"usingComponents"
:
{
"usingComponents"
:
{
"van-count-down"
:
"/components/vant/count-down/index"
,
"van-count-down"
:
"/components/vant/count-down/index"
,
"
calendar"
:
"plugin://calendar/calendar
"
,
"
van-empty"
:
"/components/vant/empty/index
"
,
"
van-empty"
:
"/components/vant/empty
/index"
"
calendar"
:
"/components/calendar
/index"
},
},
"navigationBarTitleText"
:
"课表"
"navigationBarTitleText"
:
"课表"
}
}
\ No newline at end of file
pages/tabbar/index/index.wxml
View file @
6a512a9f
<view class="tabContent">
<view class="tabContent">
<view class="rili">
<view class="rili">
<calendar weeks-type='cn' calendar-style="calendar" header-style="rili_header"
<view class="board {{isOpen? 'heightBoard' : ''}}">
board-style="board {{isOpen? 'heightBoard' : ''}}" show-more-days='true' active-type='rounded'
<calendar
days-color='{{daysColor}}' cell-size='29' bindprevMonth="prev" bindnextMonth="next" binddayClick="dayClick"/>
id="calendar"
config="{{calendarConfig}}"
bind:afterCalendarRender="afterCalendarRender"
bind:afterTapDate="afterTapDate"
bind:whenChangeMonth="whenChangeMonth"
/>
</view>
<view class="riliShow">
<view class="riliShow">
<view class="flex-h flex-vc flex-hc" catchtap="open">
<view class="flex-h flex-vc flex-hc" catchtap="open">
<text>{{isOpen ? '收起':'更多日期'}}</text>
<text>{{isOpen ? '收起':'更多日期'}}</text>
...
...
pages/tabbar/index/index.wxss
View file @
6a512a9f
.date.circle_data::after{
position: absolute;
content: '';
left: 27rpx;
bottom: -4rpx;
width: 8rpx;
height: 8rpx;
background: #FF6E00;
border-radius: 50%;
}
.date.orange-date {
background: url('https://wdty.xueyoubangedu.com/wandou/today.png') no-repeat;
background-size: 62rpx 62rpx;
}
.rili {
.rili {
margin: auto;
margin: auto;
width:
690rpx
;
width:
100%
;
padding-bottom: 38rpx;
padding-bottom: 38rpx;
margin-top: 40rpx;
margin-top: 40rpx;
}
}
.rili_header {
width: 360rpx;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: bold;
color: #000000;
margin: 0 auto 30rpx auto !important;
}
.calendar--calendar-weeks {
background: #FFF3DA;
}
.board {
.board {
background: #FFFFFF;
background: #FFFFFF;
border-radius: 0;
border-radius: 0;
overflow: hidden;
overflow: hidden;
height:
16
0rpx;
height:
22
0rpx;
}
}
.heightBoard {
.heightBoard {
height: auto;
height: auto;
}
}
.board>view:nth-child(1) {
line-height: 54rpx;
height: 54rpx;
font-size: 24rpx;
color: #999999;
font-weight: normal;
}
.board>view:nth-child(2) {
padding: 30rpx 0;
}
.board>view:nth-child(2)>view {
font-size: 26rpx;
font-family: PingFang SC;
font-weight: bold;
color: #000000;
line-height: 54rpx;
}
.riliShow {
.riliShow {
width: 100%;
width: 100%;
background: #fff;
background: #fff;
text-align: center;
text-align: center;
padding
-bottom: 40rpx
;
padding
: 30rpx 0
;
}
}
.riliShow>view {
.riliShow>view {
...
...
pages/tabbar/personal/personal.js
View file @
6a512a9f
...
@@ -5,150 +5,143 @@ import {
...
@@ -5,150 +5,143 @@ import {
const
base
=
new
Base
()
const
base
=
new
Base
()
Page
({
Page
({
/**
/**
* 页面的初始数据
* 页面的初始数据
*/
*/
data
:
{
data
:
{
showUserInfo
:
true
,
//用户信息是否显示
coach_id
:
''
,
noticeCount
:
9
,
// 家长回复小红点
showUserInfo
:
true
,
//用户信息是否显示
show
:
false
,
userInfo
:
''
,
subjectShow
:
false
,
userTel
:
''
,
subjectList
:[],
noticeCount
:
0
,
// 家长回复小红点
// subjectList:[
show
:
false
,
// {
subjectShow
:
false
,
// name: '跳绳'
subjectList
:
[],
// },
// {
// name: '篮球'
// },
// {
// name: '足球'
// },
// {
// name: '轮滑'
// },
// {
// name: '平衡车'
// },
// {
// name: '跆拳道'
// },
// ]
},
},
onLoad
:
function
(
options
)
{
onLoad
:
function
(
options
)
{
this
.
setData
({
this
.
getSubjectlist
()
coach_id
:
app
.
globalData
.
coach_id
},
})
onShow
()
{
this
.
getSubjectlist
()
let
userInfo
=
wx
.
getStorageSync
(
'
userInfo
'
);
},
let
userTel
=
wx
.
getStorageSync
(
'
userTel
'
)
onShow
()
{
if
(
userInfo
&&
userTel
)
{
let
userInfo
=
wx
.
getStorageSync
(
'
userInfo
'
);
this
.
setData
({
let
userTel
=
wx
.
getStorageSync
(
'
userTel
'
)
showUserInfo
:
true
if
(
userInfo
&&
userTel
)
{
})
this
.
setData
({
this
.
getChildInf
();
showUserInfo
:
true
}
else
{
})
this
.
setData
({
this
.
getInfo
()
showUserInfo
:
false
}
else
{
})
this
.
setData
({
}
showUserInfo
:
false
},
})
}
goLogin
()
{
},
wx
.
navigateTo
({
// 登录
getInfo
()
{
url
:
'
/pages/sign/login/login
'
,
let
params
=
{
})
url
:
'
coach/info
'
,
},
data
:
{
goUserInfo
()
{
// 账户信息修改
coach_id
:
this
.
data
.
coach_id
wx
.
navigateTo
({
},
url
:
'
/pages/sign/info/info
'
,
callback
:(
data
)
=>
{
})
this
.
setData
({
},
userInfo
:
data
.
wx_user
,
goparents
:
function
()
{
userTel
:
data
.
wx_user
.
tel
.
substr
(
0
,
3
)
+
'
****
'
+
data
.
wx_user
.
tel
.
substring
(
7
,
11
)
wx
.
navigateTo
({
})
url
:
'
../../my/parents/parents
'
,
}
})
}
},
base
.
newRequest
(
params
)
goteachingArea
:
function
()
{
},
wx
.
navigateTo
({
goLogin
()
{
url
:
'
../../my/teachingArea/teachingArea
'
,
wx
.
navigateTo
({
// 登录
})
url
:
'
/pages/sign/login/login
'
,
},
})
getSubjectlist
:
function
()
{
},
let
params
=
{
goUserInfo
()
{
// 账户信息修改
url
:
'
coach/course
'
,
wx
.
navigateTo
({
callback
:
(
data
)
=>
{
url
:
'
/pages/sign/info/info
'
,
console
.
log
(
data
)
})
this
.
setData
({
},
subjectList
:
data
goparents
:
function
()
{
})
wx
.
navigateTo
({
url
:
'
../../my/parents/parents
'
,
}
})
}
},
base
.
newRequest
(
params
)
goteachingArea
:
function
()
{
},
wx
.
navigateTo
({
//教学科目弹窗
url
:
'
../../my/teachingArea/teachingArea
'
,
tcHold
:
function
(
e
)
{
})
this
.
setData
({
},
subjectShow
:
!
this
.
data
.
subjectShow
getSubjectlist
:
function
()
{
})
let
params
=
{
},
url
:
'
coach/course
'
,
chooseOne
(
e
)
{
callback
:
(
data
)
=>
{
let
index
=
e
.
currentTarget
.
dataset
.
index
this
.
setData
({
let
list
=
this
.
data
.
subjectList
subjectList
:
data
if
(
list
[
index
].
isChecked
)
{
})
list
[
index
].
isChecked
=
false
}
}
else
{
}
list
[
index
].
isChecked
=
true
base
.
newRequest
(
params
)
}
},
this
.
setData
({
//教学科目弹窗
subjectList
:
list
tcHold
:
function
(
e
)
{
})
this
.
setData
({
},
subjectShow
:
!
this
.
data
.
subjectShow
confirm
()
{
})
var
arr
=
[]
},
var
newArr
=
[]
chooseOne
(
e
)
{
for
(
var
i
=
0
;
i
<
this
.
data
.
subjectList
.
length
;
i
++
)
{
let
index
=
e
.
currentTarget
.
dataset
.
index
if
(
this
.
data
.
subjectList
[
i
].
isChecked
==
true
)
{
let
list
=
this
.
data
.
subjectList
arr
.
push
(
this
.
data
.
subjectList
[
i
])
if
(
list
[
index
].
isChecked
)
{
newArr
.
push
(
this
.
data
.
subjectList
[
i
].
id
)
list
[
index
].
isChecked
=
false
}
}
else
{
}
list
[
index
].
isChecked
=
true
console
.
log
(
arr
)
}
console
.
log
(
newArr
)
this
.
setData
({
if
(
arr
.
length
==
0
)
{
subjectList
:
list
base
.
toast
(
'
教学科目至少选择一项
'
)
})
}
else
{
},
let
params
=
{
confirm
()
{
url
:
'
coach/save_course
'
,
var
arr
=
[]
data
:
{
var
newArr
=
[]
coach_id
:
4
,
for
(
var
i
=
0
;
i
<
this
.
data
.
subjectList
.
length
;
i
++
)
{
course_ids
:
JSON
.
stringify
(
newArr
)
if
(
this
.
data
.
subjectList
[
i
].
isChecked
==
true
)
{
},
arr
.
push
(
this
.
data
.
subjectList
[
i
])
type
:
'
POST
'
,
newArr
.
push
(
this
.
data
.
subjectList
[
i
].
id
)
callback
:
(
data
)
=>
{
}
base
.
toast
(
'
保存科目成功
'
)
}
this
.
setData
({
if
(
arr
.
length
==
0
)
{
subjectShow
:
false
base
.
toast
(
'
教学科目至少选择一项
'
)
})
}
else
{
}
let
params
=
{
}
url
:
'
coach/save_course
'
,
base
.
newRequest
(
params
)
data
:
{
}
coach_id
:
4
,
},
course_ids
:
JSON
.
stringify
(
newArr
)
goCall
:
function
(
e
)
{
},
wx
.
showModal
({
type
:
'
POST
'
,
content
:
'
确定要拨打电话吗?
'
,
callback
:
(
data
)
=>
{
success
(
res
)
{
base
.
toast
(
'
保存科目成功
'
)
if
(
res
.
confirm
)
{
this
.
setData
({
wx
.
makePhoneCall
({
subjectShow
:
false
phoneNumber
:
'
400-181-5358
'
})
})
}
}
}
}
base
.
newRequest
(
params
)
})
}
}
},
goCall
:
function
(
e
)
{
wx
.
showModal
({
content
:
'
确定要拨打电话吗?
'
,
success
(
res
)
{
if
(
res
.
confirm
)
{
wx
.
makePhoneCall
({
phoneNumber
:
'
400-181-5358
'
})
}
}
})
}
})
})
\ No newline at end of file
pages/tabbar/personal/personal.wxml
View file @
6a512a9f
<view class="personInf">
<view class="personInf">
<view class="head flex-h flex-vc flex-hb" wx:if='{{showUserInfo}}' catchtap="goUserInfo">
<view class="head flex-h flex-vc flex-hb" wx:if='{{showUserInfo}}' catchtap="goUserInfo">
<view class="headLeft flex-h flex-vc">
<view class="headLeft flex-h flex-vc">
<image src="../../../images/course_login.png
"></image>
<image src="{{userInfo.avatarurl}}
"></image>
<view>
<view>
<view class="name">王教练
</view>
<view class="name">{{userInfo.nickname}}
</view>
<view class="tel">183****6092
</view>
<view class="tel">{{userTel}}
</view>
</view>
</view>
</view>
</view>
<text class="iconfont icongengduo"></text>
<text class="iconfont icongengduo"></text>
</view>
</view>
<view wx:else class="head flex-h flex-vc flex-hb">
<view wx:else class="head flex-h flex-vc flex-hb">
<view class="headLeft flex-v">
<view class="headLeft flex-v">
<view class='head_title'>欢迎来到豌豆成长</view>
<view class='head_title'>欢迎来到豌豆成长</view>
<view class="login" catchtap="goLogin">立即登录</view>
<view class="login" catchtap="goLogin">立即登录</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="centerNav">
<view class="centerNav">
<view class="every flex-h flex-vc flex-hb" catchtap="goparents">
<view class="every flex-h flex-vc flex-hb" catchtap="goparents">
<view class="flex-vc flex-h title">
<view class="flex-vc flex-h title">
<image src="/images/my/per_icon_01.png"></image>
<image src="/images/my/per_icon_01.png"></image>
<view>家长回复</view>
<view>家长回复</view>
</view>
</view>
<view class="flex-vc flex-h unreadBox">
<text class="iconfont icongengduo"></text>
<view class="unread" wx:if="{{ noticeCount > 0 }}"></view>
</view>
<text class="iconfont icongengduo"></text>
</view>
</view>
</view>
</view>
<view class="centerNav">
<view class="centerNav">
<view class="every flex-h flex-vc flex-hb" catchtap="goteachingArea">
<view class="every flex-h flex-vc flex-hb" catchtap="goteachingArea">
<view class="row title">
<view class="row title">
<image src="../../../images/my/per_icon_02.png"></image>
<image src="../../../images/my/per_icon_02.png"></image>
<view>教学区域</view>
<view>教学区域</view>
</view>
</view>
<text class="iconfont icongengduo"></text>
<text class="iconfont icongengduo"></text>
</view>
</view>
<view class="every flex-h flex-vc flex-hb" catchtap="tcHold">
<view class="every flex-h flex-vc flex-hb" catchtap="tcHold">
<view class="row title">
<view class="row title">
<image src="../../../images/my/per_icon_03.png"></image>
<image src="../../../images/my/per_icon_03.png"></image>
<view>教学科目</view>
<view>教学科目</view>
</view>
</view>
<view class="row">
<view class="row">
<text class="num">5
</text>
<text class="num">{{userInfo.coach_course_count? userInfo.coach_course_count: 0}}
</text>
<text class="iconfont icongengduo"></text>
<text class="iconfont icongengduo"></text>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="centerNav">
<view class="centerNav">
<view class="every flex-h flex-vc flex-hb" catchtap="goCall">
<view class="every flex-h flex-vc flex-hb" catchtap="goCall">
<view class="row title">
<view class="row title">
<image src="/images/my/per_icon_04.png"></image>
<image src="/images/my/per_icon_04.png"></image>
<view>联系客服</view>
<view>联系客服</view>
</view>
</view>
<text class="iconfont icongengduo"></text>
<text class="iconfont icongengduo"></text>
</view>
</view>
</view>
</view>
<van-popup show="{{ subjectShow }}" closeable round bind:close="tcHold">
<van-popup show="{{ subjectShow }}" closeable round bind:close="tcHold">
<view class="tc">
<view class="tc">
<view class="top">
<view class="top">
<view class="til">请选择教学科目</view>
<view class="til">请选择教学科目</view>
<view class="select">(可多选)</view>
<view class="select">(可多选)</view>
</view>
</view>
<view class="subject flex-h flex-hw flex-ha">
<view class="subject flex-h flex-hw flex-ha">
<block wx:for='{{subjectList}}' wx:key='index'>
<block wx:for='{{subjectList}}' wx:key='index'>
<view class="{{item.isChecked ? 'active' : ''}}" catchtap="chooseOne" data-index='{{index}}' data-item='{{item}}'>{{item.name}}</view>
<view class="{{item.isChecked ? 'active' : ''}}" catchtap="chooseOne" data-index='{{index}}'
</block>
data-item='{{item}}'>{{item.name}}</view>
</view>
</block>
<view class="confirm" catchtap="confirm">确定</view>
</view>
</view>
<view class="confirm" catchtap="confirm">确定</view>
</view>
</van-popup>
</van-popup>
\ No newline at end of file
project.config.json
View file @
6a512a9f
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment