Browse Source

最后调整

master
xiangshunpu 4 years ago
parent
commit
859f432fbf
  1. 2
      app.wxss
  2. 33
      components/calendar/func/config.js
  3. 1036
      components/calendar/func/convertSolarLunar.js
  4. 543
      components/calendar/func/day.js
  5. 375
      components/calendar/func/render.js
  6. 182
      components/calendar/func/todo.js
  7. 367
      components/calendar/func/utils.js
  8. 601
      components/calendar/func/week.js
  9. 26
      components/calendar/func/wxData.js
  10. 309
      components/calendar/index.js
  11. 3
      components/calendar/index.json
  12. 66
      components/calendar/index.wxml
  13. 214
      components/calendar/index.wxss
  14. 877
      components/calendar/main.js
  15. 29
      components/calendar/theme/iconfont.wxss
  16. 56
      components/calendar/theme/theme-default.wxss
  17. 49
      components/calendar/theme/theme-elegant.wxss
  18. 1
      components/detail-announcement/detail-announcement.wxss
  19. 21
      components/detail-basis/detail-basis.js
  20. 4
      components/detail-basis/detail-basis.json
  21. 12
      components/detail-basis/detail-basis.wxml
  22. 4
      components/detail-basis/detail-basis.wxss
  23. 22
      components/detail-senior/detail-senior.js
  24. 4
      components/detail-senior/detail-senior.json
  25. 181
      components/detail-senior/detail-senior.wxml
  26. 64
      components/detail-senior/detail-senior.wxss
  27. 40
      components/table/table.js
  28. 4
      components/table/table.json
  29. 17
      components/table/table.wxml
  30. 51
      components/table/table.wxss
  31. 2
      custom-tab-bar/index.js
  32. 27
      custom-tab-bar/index.wxml
  33. 11
      custom-tab-bar/index.wxss
  34. 6
      pages/calculation/calculation.js
  35. 49
      pages/calendar/calendar.js
  36. 3
      pages/calendar/calendar.json
  37. 21
      pages/calendar/calendar.wxml
  38. 15
      pages/calendar/calendar.wxss
  39. 8
      pages/feasibility-study/feasibility-study.js
  40. 2
      pages/feasibility-study/feasibility-study.wxml
  41. 19
      pages/index/index.js
  42. 2
      pages/index/index.wxml
  43. 8
      pages/land-promotion/land-promotion.js
  44. 2
      pages/land-promotion/land-promotion.wxml
  45. 131
      pages/look-detail/look-detail.js
  46. 7
      pages/look-detail/look-detail.wxml
  47. 46
      pages/look-detail/look-detail.wxss
  48. 8
      pages/periodic-report/periodic-report.js
  49. 2
      pages/periodic-report/periodic-report.wxml
  50. 8
      pages/special-research/special-research.js
  51. 2
      pages/special-research/special-research.wxml

2
app.wxss

@ -137,7 +137,7 @@
.table-title {
font-size: 30rpx;
font-weight: bold;
color: #F69F06;
color: #565a6b;
line-height: 90rpx;
}

33
components/calendar/func/config.js

@ -0,0 +1,33 @@
import WxData from './wxData'
class Config extends WxData {
constructor(component) {
super(component)
this.Component = component
}
getCalendarConfig() {
if (!this.Component || !this.Component.config) return {}
return this.Component.config
}
setCalendarConfig(config) {
return new Promise((resolve, reject) => {
if (!this.Component || !this.Component.config) {
reject('异常:未找到组件配置信息')
return
}
let conf = { ...this.Component.config, ...config }
this.Component.config = conf
this.setData(
{
calendarConfig: conf
},
() => {
resolve(conf)
}
)
})
}
}
export default component => new Config(component)

1036
components/calendar/func/convertSolarLunar.js

File diff suppressed because it is too large Load Diff

543
components/calendar/func/day.js

@ -0,0 +1,543 @@
import WxData from './wxData'
import CalendarConfig from './config'
import convertSolarLunar from './convertSolarLunar'
import {
Logger,
GetDate,
getDateTimeStamp,
uniqueArrayByDate,
delRepeatedEnableDay,
convertEnableAreaToTimestamp,
converEnableDaysToTimestamp
} from './utils'
const logger = new Logger()
const getDate = new GetDate()
const toString = Object.prototype.toString
class Day extends WxData {
constructor(component) {
super(component)
this.Component = component
}
getCalendarConfig() {
return this.Component.config
}
/**
*
* @param {number} year
* @param {number} month
*/
buildDate(year, month) {
const today = getDate.todayDate()
const thisMonthDays = getDate.thisMonthDays(year, month)
const dates = []
for (let i = 1; i <= thisMonthDays; i++) {
const isToday =
+today.year === +year && +today.month === +month && i === +today.date
const config = this.getCalendarConfig()
const date = {
year,
month,
day: i,
choosed: false,
week: getDate.dayOfWeek(year, month, i),
isToday: isToday && config.highlightToday,
lunar: convertSolarLunar.solar2lunar(+year, +month, +i)
}
dates.push(date)
}
return dates
}
/**
* 指定可选日期范围
* @param {array} area 日期访问数组
*/
enableArea(dateArea = []) {
if (dateArea.length === 2) {
const isRight = this.__judgeParam(dateArea)
if (isRight) {
let { days = [], selectedDay = [] } = this.getData('calendar')
const { startTimestamp, endTimestamp } = convertEnableAreaToTimestamp(
dateArea
)
const dataAfterHandle = this.__handleEnableArea(
{
dateArea,
days,
startTimestamp,
endTimestamp
},
selectedDay
)
this.setData({
'calendar.enableArea': dateArea,
'calendar.days': dataAfterHandle.dates,
'calendar.selectedDay': dataAfterHandle.selectedDay,
'calendar.enableAreaTimestamp': [startTimestamp, endTimestamp]
})
}
} else {
logger.warn(
'enableArea()参数需为时间范围数组,形如:["2018-8-4" , "2018-8-24"]'
)
}
}
/**
* 指定特定日期可选
* @param {array} days 指定日期数组
*/
enableDays(dates = []) {
const { enableArea = [] } = this.getData('calendar')
let expectEnableDaysTimestamp = []
if (enableArea.length) {
expectEnableDaysTimestamp = delRepeatedEnableDay(dates, enableArea)
} else {
expectEnableDaysTimestamp = converEnableDaysToTimestamp(dates)
}
let { days = [], selectedDay = [] } = this.getData('calendar')
const dataAfterHandle = this.__handleEnableDays(
{
days,
expectEnableDaysTimestamp
},
selectedDay
)
this.setData({
'calendar.days': dataAfterHandle.dates,
'calendar.selectedDay': dataAfterHandle.selectedDay,
'calendar.enableDays': dates,
'calendar.enableDaysTimestamp': expectEnableDaysTimestamp
})
}
/**
* 设置多个日期选中
* @param {array} selected 需选中日期
*/
setSelectedDays(selected) {
const config = CalendarConfig(this.Component).getCalendarConfig()
if (!config.multi) {
return logger.warn('单选模式下不能设置多日期选中,请配置 multi')
}
let { days } = this.getData('calendar')
let newSelectedDay = []
if (!selected) {
days.map(item => {
item.choosed = true
item.showTodoLabel = false
})
newSelectedDay = days
} else if (selected && selected.length) {
const { dates, selectedDates } = this.__handleSelectedDays(
days,
newSelectedDay,
selected
)
days = dates
newSelectedDay = selectedDates
}
CalendarConfig(this.Component).setCalendarConfig('multi', true)
this.setData({
'calendar.days': days,
'calendar.selectedDay': newSelectedDay
})
}
/**
* 禁用指定日期
* @param {array} dates 禁用
*/
disableDays(dates) {
const { disableDays = [], days } = this.getData('calendar')
if (Object.prototype.toString.call(dates) !== '[object Array]') {
return logger.warn('disableDays 参数为数组')
}
let _disableDays = []
if (dates.length) {
_disableDays = uniqueArrayByDate(dates.concat(disableDays))
const disableDaysCol = _disableDays.map(d => getDate.toTimeStr(d))
days.forEach(item => {
const cur = getDate.toTimeStr(item)
if (disableDaysCol.includes(cur)) item.disable = true
})
} else {
days.forEach(item => {
item.disable = false
})
}
this.setData({
'calendar.days': days,
'calendar.disableDays': _disableDays
})
}
/**
* 设置连续日期选择区域
* @param {array} dateArea 区域开始结束日期数组
*/
chooseArea(dateArea = []) {
return new Promise((resolve, reject) => {
if (dateArea.length === 1) {
dateArea = dateArea.concat(dateArea)
}
if (dateArea.length === 2) {
const isRight = this.__judgeParam(dateArea)
if (isRight) {
const config = CalendarConfig(this.Component).getCalendarConfig()
const { startTimestamp, endTimestamp } = convertEnableAreaToTimestamp(
dateArea
)
this.setData(
{
calendarConfig: {
...config,
chooseAreaMode: true,
mulit: true
},
'calendar.chooseAreaTimestamp': [startTimestamp, endTimestamp]
},
() => {
this.__chooseContinuousDates(startTimestamp, endTimestamp)
.then(resolve)
.catch(reject)
}
)
}
}
})
}
__pusheNextMonthDateArea(item, startTimestamp, endTimestamp, selectedDates) {
const days = this.buildDate(item.year, item.month)
let daysLen = days.length
for (let i = 0; i < daysLen; i++) {
const item = days[i]
const timeStamp = getDateTimeStamp(item)
if (timeStamp <= endTimestamp && timeStamp >= startTimestamp) {
selectedDates.push({
...item,
choosed: true
})
}
if (i === daysLen - 1 && timeStamp < endTimestamp) {
this.__pusheNextMonthDateArea(
getDate.nextMonth(item),
startTimestamp,
endTimestamp,
selectedDates
)
}
}
}
__pushPrevMonthDateArea(item, startTimestamp, endTimestamp, selectedDates) {
const days = getDate.sortDates(
this.buildDate(item.year, item.month),
'desc'
)
let daysLen = days.length
let firstDate = getDateTimeStamp(days[0])
for (let i = 0; i < daysLen; i++) {
const item = days[i]
const timeStamp = getDateTimeStamp(item)
if (timeStamp >= startTimestamp && timeStamp <= endTimestamp) {
selectedDates.push({
...item,
choosed: true
})
}
if (i === daysLen - 1 && firstDate > startTimestamp) {
this.__pushPrevMonthDateArea(
getDate.prevMonth(item),
startTimestamp,
endTimestamp,
selectedDates
)
}
}
}
/**
* 当设置日期区域非当前时保存其他月份的日期至已选日期数组
* @param {object} info
*/
__calcDateWhenNotInOneMonth(info) {
const {
firstDate,
lastDate,
startTimestamp,
endTimestamp,
filterSelectedDate
} = info
if (getDateTimeStamp(firstDate) > startTimestamp) {
this.__pushPrevMonthDateArea(
getDate.prevMonth(firstDate),
startTimestamp,
endTimestamp,
filterSelectedDate
)
}
if (getDateTimeStamp(lastDate) < endTimestamp) {
this.__pusheNextMonthDateArea(
getDate.nextMonth(lastDate),
startTimestamp,
endTimestamp,
filterSelectedDate
)
}
const newSelectedDates = [...getDate.sortDates(filterSelectedDate)]
return newSelectedDates
}
/**
* 设置连续日期段
* @param {number} startTimestamp 连续日期段开始日期时间戳
* @param {number} endTimestamp 连续日期段结束日期时间戳
*/
__chooseContinuousDates(startTimestamp, endTimestamp) {
return new Promise((resolve, reject) => {
const { days, selectedDay = [] } = this.getData('calendar')
const selectedDateStr = []
let filterSelectedDate = []
selectedDay.forEach(item => {
const timeStamp = getDateTimeStamp(item)
if (timeStamp >= startTimestamp && timeStamp <= endTimestamp) {
filterSelectedDate.push(item)
selectedDateStr.push(getDate.toTimeStr(item))
}
})
days.forEach(item => {
const timeStamp = getDateTimeStamp(item)
const dateInSelecedArray = selectedDateStr.includes(
getDate.toTimeStr(item)
)
if (timeStamp >= startTimestamp && timeStamp <= endTimestamp) {
if (dateInSelecedArray) {
return
}
item.choosed = true
filterSelectedDate.push(item)
} else {
item.choosed = false
if (dateInSelecedArray) {
const idx = filterSelectedDate.findIndex(
selectedDate =>
getDate.toTimeStr(selectedDate) === getDate.toTimeStr(item)
)
if (idx > -1) {
filterSelectedDate.splice(idx, 1)
}
}
}
})
const firstDate = days[0]
const lastDate = days[days.length - 1]
const newSelectedDates = this.__calcDateWhenNotInOneMonth({
firstDate,
lastDate,
startTimestamp,
endTimestamp,
filterSelectedDate
})
try {
this.setData(
{
'calendar.days': [...days],
'calendar.selectedDay': newSelectedDates
},
() => {
resolve(newSelectedDates)
}
)
} catch (err) {
reject(err)
}
})
}
/**
* 设置指定日期样式
* @param {array} dates 待设置特殊样式的日期
*/
setDateStyle(dates) {
if (toString.call(dates) !== '[object Array]') return
const { days, specialStyleDates } = this.getData('calendar')
if (toString.call(specialStyleDates) === '[object Array]') {
dates = uniqueArrayByDate([...specialStyleDates, ...dates])
}
const _specialStyleDates = dates.map(
item => `${item.year}_${item.month}_${item.day}`
)
const _days = days.map(item => {
const idx = _specialStyleDates.indexOf(
`${item.year}_${item.month}_${item.day}`
)
if (idx > -1) {
return {
...item,
class: dates[idx].class
}
} else {
return { ...item }
}
})
this.setData({
'calendar.days': _days,
'calendar.specialStyleDates': dates
})
}
__judgeParam(dateArea) {
const {
start,
end,
startTimestamp,
endTimestamp
} = convertEnableAreaToTimestamp(dateArea)
if (!start || !end) return
const startMonthDays = getDate.thisMonthDays(start[0], start[1])
const endMonthDays = getDate.thisMonthDays(end[0], end[1])
if (start[2] > startMonthDays || 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] > endMonthDays || 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
}
}
__getDisableDateTimestamp() {
let disableDateTimestamp
const { date, type } = this.getCalendarConfig().disableMode || {}
if (date) {
const t = date.split('-')
if (t.length < 3) {
logger.warn('配置 disableMode.date 格式错误')
return {}
}
disableDateTimestamp = getDateTimeStamp({
year: +t[0],
month: +t[1],
day: +t[2]
})
}
return {
disableDateTimestamp,
disableType: type
}
}
__handleEnableArea(data = {}, selectedDay = []) {
const { area, days, startTimestamp, endTimestamp } = data
const enableDays = this.getData('calendar.enableDays') || []
let expectEnableDaysTimestamp = []
if (enableDays.length) {
expectEnableDaysTimestamp = delRepeatedEnableDay(enableDays, area)
}
const {
disableDateTimestamp,
disableType
} = this.__getDisableDateTimestamp()
const dates = [...days]
dates.forEach(item => {
const timestamp = +getDate
.newDate(item.year, item.month, item.day)
.getTime()
const ifOutofArea =
(+startTimestamp > timestamp || timestamp > +endTimestamp) &&
!expectEnableDaysTimestamp.includes(timestamp)
if (
ifOutofArea ||
(disableType === 'before' &&
disableDateTimestamp &&
timestamp < disableDateTimestamp) ||
(disableType === 'after' &&
disableDateTimestamp &&
timestamp > disableDateTimestamp)
) {
item.disable = true
if (item.choosed) {
item.choosed = false
selectedDay = selectedDay.filter(
d => getDate.toTimeStr(item) !== getDate.toTimeStr(d)
)
}
} else if (item.disable) {
item.disable = false
}
})
return {
dates,
selectedDay
}
}
__handleEnableDays(data = {}, selectedDay = []) {
const { days, expectEnableDaysTimestamp } = data
const { enableAreaTimestamp = [] } = this.getData('calendar')
const dates = [...days]
dates.forEach(item => {
const timestamp = getDate
.newDate(item.year, item.month, item.day)
.getTime()
let setDisable = false
if (enableAreaTimestamp.length) {
if (
(+enableAreaTimestamp[0] > +timestamp ||
+timestamp > +enableAreaTimestamp[1]) &&
!expectEnableDaysTimestamp.includes(+timestamp)
) {
setDisable = true
}
} else if (!expectEnableDaysTimestamp.includes(+timestamp)) {
setDisable = true
}
if (setDisable) {
item.disable = true
if (item.choosed) {
item.choosed = false
selectedDay = selectedDay.filter(
d => getDate.toTimeStr(item) !== getDate.toTimeStr(d)
)
}
} else {
item.disable = false
}
})
return {
dates,
selectedDay
}
}
__handleSelectedDays(days = [], newSelectedDay = [], selected) {
const { selectedDay, showLabelAlways } = this.getData('calendar')
if (selectedDay && selectedDay.length) {
newSelectedDay = uniqueArrayByDate(selectedDay.concat(selected))
} else {
newSelectedDay = selected
}
const { year: curYear, month: curMonth } = days[0]
const currentSelectedDays = []
newSelectedDay.forEach(item => {
if (+item.year === +curYear && +item.month === +curMonth) {
currentSelectedDays.push(getDate.toTimeStr(item))
}
})
;[...days].map(item => {
if (currentSelectedDays.includes(getDate.toTimeStr(item))) {
item.choosed = true
if (showLabelAlways && item.showTodoLabel) {
item.showTodoLabel = true
} else {
item.showTodoLabel = false
}
}
})
return {
dates: days,
selectedDates: newSelectedDay
}
}
}
export default component => new Day(component)

375
components/calendar/func/render.js

@ -0,0 +1,375 @@
import Day from './day'
import Todo from './todo'
import WxData from './wxData'
import convertSolarLunar from './convertSolarLunar'
import {
Logger,
GetDate,
delRepeatedEnableDay,
getDateTimeStamp,
converEnableDaysToTimestamp
} from './utils'
const getDate = new GetDate()
const logger = new Logger()
class Calendar extends WxData {
constructor(component) {
super(component)
this.Component = component
}
getCalendarConfig() {
return this.Component.config
}
/**
* 渲染日历
* @param {number} curYear 年份
* @param {number} curMonth 月份
* @param {number} curDate 日期
* @param {boolean} disableSelect 是否禁用选中
*/
renderCalendar(curYear, curMonth, curDate, disableSelect) {
return new Promise(resolve => {
const config = this.getCalendarConfig()
this.calculateEmptyGrids(curYear, curMonth)
this.calculateDays(curYear, curMonth, curDate, disableSelect).then(() => {
const { todoLabels, specialStyleDates, enableDays, selectedDay } =
this.getData('calendar') || {}
if (
todoLabels &&
todoLabels.find(
item => +item.month === +curMonth && +item.year === +curYear
)
) {
Todo(this.Component).setTodoLabels()
}
if (
specialStyleDates &&
specialStyleDates.length &&
specialStyleDates.find(
item => +item.month === +curMonth && +item.year === +curYear
)
) {
Day(this.Component).setDateStyle(specialStyleDates)
}
if (
enableDays &&
enableDays.length &&
enableDays.find(item => {
let ymd = item.split('-')
return +ymd[1] === +curMonth && +ymd[0] === +curYear
})
) {
Day(this.Component).enableDays(enableDays)
}
if (
selectedDay &&
selectedDay.length &&
selectedDay.find(
item => +item.month === +curMonth && +item.year === +curYear
) &&
config.mulit
) {
Day(this.Component).setSelectedDays(selectedDay)
}
if (!this.Component.firstRender) {
resolve({
firstRender: true
})
} else {
resolve({
firstRender: false
})
}
})
})
}
/**
* 计算当前月份前后两月应占的格子
* @param {number} year 年份
* @param {number} month 月份
*/
calculateEmptyGrids(year, month) {
this.calculatePrevMonthGrids(year, month)
this.calculateNextMonthGrids(year, month)
}
/**
* 计算上月应占的格子
* @param {number} year 年份
* @param {number} month 月份
*/
calculatePrevMonthGrids(year, month) {
let empytGrids = []
const prevMonthDays = getDate.thisMonthDays(year, month - 1)
let firstDayOfWeek = getDate.firstDayOfWeek(year, month)
const config = this.getCalendarConfig() || {}
if (config.firstDayOfWeek === 'Mon') {
if (firstDayOfWeek === 0) {
firstDayOfWeek = 6
} else {
firstDayOfWeek -= 1
}
}
if (firstDayOfWeek > 0) {
const len = prevMonthDays - firstDayOfWeek
const { onlyShowCurrentMonth } = config
const { showLunar } = this.getCalendarConfig()
for (let i = prevMonthDays; i > len; i--) {
if (onlyShowCurrentMonth) {
empytGrids.push('')
} else {
empytGrids.push({
day: i,
lunar: showLunar
? convertSolarLunar.solar2lunar(year, month - 1, i)
: null
})
}
}
this.setData({
'calendar.empytGrids': empytGrids.reverse()
})
} else {
this.setData({
'calendar.empytGrids': null
})
}
}
/**
* 计算下一月日期是否需要多展示的日期
* 某些月份日期为5排某些月份6排统一为6排
* @param {number} year
* @param {number} month
* @param {object} config
*/
calculateExtraEmptyDate(year, month, config) {
let extDate = 0
if (+month === 2) {
extDate += 7
let firstDayofMonth = getDate.dayOfWeek(year, month, 1)
if (config.firstDayOfWeek === 'Mon') {
if (+firstDayofMonth === 1) extDate += 7
} else {
if (+firstDayofMonth === 0) extDate += 7
}
} else {
let firstDayofMonth = getDate.dayOfWeek(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 月份
*/
calculateNextMonthGrids(year, month) {
let lastEmptyGrids = []
const thisMonthDays = getDate.thisMonthDays(year, month)
let lastDayWeek = getDate.dayOfWeek(year, month, thisMonthDays)
const config = this.getCalendarConfig() || {}
if (config.firstDayOfWeek === 'Mon') {
if (lastDayWeek === 0) {
lastDayWeek = 6
} else {
lastDayWeek -= 1
}
}
let len = 7 - (lastDayWeek + 1)
const { onlyShowCurrentMonth, showLunar } = config
if (!onlyShowCurrentMonth) {
len = len + this.calculateExtraEmptyDate(year, month, config)
}
for (let i = 1; i <= len; i++) {
if (onlyShowCurrentMonth) {
lastEmptyGrids.push('')
} else {
lastEmptyGrids.push({
day: i,
lunar: showLunar
? convertSolarLunar.solar2lunar(year, month + 1, i)
: null
})
}
}
this.setData({
'calendar.lastEmptyGrids': lastEmptyGrids
})
}
/**
* 日历初始化将默认值写入 selectDay
* @param {number} year
* @param {number} month
* @param {number} curDate
*/
setSelectedDay(year, month, curDate) {
let selectedDay = []
const config = this.getCalendarConfig()
if (config.noDefault) {
selectedDay = []
config.noDefault = false
} else {
const data = this.getData('calendar') || {}
const { showLunar } = this.getCalendarConfig()
selectedDay = curDate
? [
{
year,
month,
day: curDate,
choosed: true,
week: getDate.dayOfWeek(year, month, curDate),
lunar: showLunar
? convertSolarLunar.solar2lunar(year, month, curDate)
: null
}
]
: data.selectedDay
}
return selectedDay
}
__getDisableDateTimestamp() {
let disableDateTimestamp
const { date, type } = this.getCalendarConfig().disableMode || {}
if (date) {
const t = date.split('-')
if (t.length < 3) {
logger.warn('配置 disableMode.date 格式错误')
return {}
}
disableDateTimestamp = getDateTimeStamp({
year: +t[0],
month: +t[1],
day: +t[2]
})
}
return {
disableDateTimestamp,
disableType: type
}
}
resetDates() {
this.setData({
'calendar.days': []
})
}
/**
* 设置日历面板数据
* @param {number} year 年份
* @param {number} month 月份
* @param {number} curDate 日期
* @param {boolean} disableSelect 是否禁用选中
*/
calculateDays(year, month, curDate, disableSelect) {
return new Promise(resolve => {
// 避免切换日期时样式残影
this.resetDates()
let days = []
const {
disableDays = [],
chooseAreaTimestamp = [],
selectedDay: selectedDates = []
} = this.getData('calendar')
days = Day(this.Component).buildDate(year, month)
let selectedDay = selectedDates
if (!disableSelect) {
selectedDay = this.setSelectedDay(year, month, curDate)
}
const selectedDayStr = selectedDay.map(d => getDate.toTimeStr(d))
const disableDaysStr = disableDays.map(d => getDate.toTimeStr(d))
const [areaStart, areaEnd] = chooseAreaTimestamp
days.forEach(item => {
const cur = getDate.toTimeStr(item)
const timestamp = getDateTimeStamp(item)
if (selectedDayStr.includes(cur) && !disableSelect) {
item.choosed = true
if (timestamp > areaEnd || timestamp < areaStart) {
const idx = selectedDay.findIndex(
selectedDate =>
getDate.toTimeStr(selectedDate) === getDate.toTimeStr(item)
)
selectedDay.splice(idx, 1)
}
} else if (
areaStart &&
areaEnd &&
timestamp >= areaStart &&
timestamp <= areaEnd &&
!disableSelect
) {
item.choosed = true
selectedDay.push(item)
}
if (disableDaysStr.includes(cur)) item.disable = true
const {
disableDateTimestamp,
disableType
} = this.__getDisableDateTimestamp()
let disabelByConfig = false
if (disableDateTimestamp) {
if (
(disableType === 'before' && timestamp < disableDateTimestamp) ||
(disableType === 'after' && timestamp > disableDateTimestamp)
) {
disabelByConfig = true
}
}
const isDisable = disabelByConfig || this.__isDisable(timestamp)
if (isDisable) {
item.disable = true
item.choosed = false
}
})
this.setData(
{
'calendar.days': days,
'calendar.selectedDay': [...selectedDay] || []
},
() => {
resolve()
}
)
})
}
__isDisable(timestamp) {
const {
enableArea = [],
enableDays = [],
enableAreaTimestamp = []
} = this.getData('calendar')
let setDisable = false
let expectEnableDaysTimestamp = converEnableDaysToTimestamp(enableDays)
if (enableArea.length) {
expectEnableDaysTimestamp = delRepeatedEnableDay(enableDays, enableArea)
}
if (enableAreaTimestamp.length) {
if (
(+enableAreaTimestamp[0] > +timestamp ||
+timestamp > +enableAreaTimestamp[1]) &&
!expectEnableDaysTimestamp.includes(+timestamp)
) {
setDisable = true
}
} else if (
expectEnableDaysTimestamp.length &&
!expectEnableDaysTimestamp.includes(+timestamp)
) {
setDisable = true
}
return setDisable
}
}
export default component => new Calendar(component)

182
components/calendar/func/todo.js

@ -0,0 +1,182 @@
import WxData from './wxData'
import { Logger, uniqueArrayByDate, GetDate } from './utils'
const logger = new Logger()
const getDate = new GetDate()
class Todo extends WxData {
constructor(component) {
super(component)
this.Component = component
}
/**
* 设置待办事项标志
* @param {object} options 待办事项配置
*/
setTodoLabels(options) {
if (options) this.Component.todoConfig = options
const calendar = this.getData('calendar')
if (!calendar || !calendar.days) {
return logger.warn('请等待日历初始化完成后再调用该方法')
}
const dates = [...calendar.days]
const { curYear, curMonth } = calendar
const {
circle,
dotColor = '',
pos = 'bottom',
showLabelAlways,
days: todoDays = []
} = options || this.Component.todoConfig || {}
const { todoLabels = [] } = calendar
const currentMonthTodoLabels = this.getTodoLabels({
year: curYear,
month: curMonth
})
let newTodoLabels = todoDays.filter(
item => +item.year === +curYear && +item.month === +curMonth
)
if (this.Component.weekMode) {
newTodoLabels = todoDays
}
const allTodos = currentMonthTodoLabels.concat(newTodoLabels)
for (let todo of allTodos) {
let target
if (this.Component.weekMode) {
target = dates.find(
date =>
+todo.year === +date.year &&
+todo.month === +date.month &&
+todo.day === +date.day
)
} else {
target = dates[todo.day - 1]
}
if (!target) continue
if (showLabelAlways) {
target.showTodoLabel = true
} else {
target.showTodoLabel = !target.choosed
}
if (target.showTodoLabel) {
target.todoText = todo.todoText
}
target.color = todo.color
}
const o = {
'calendar.days': dates,
'calendar.todoLabels': uniqueArrayByDate(todoLabels.concat(todoDays))
}
if (!circle) {
o['calendar.todoLabelPos'] = pos
o['calendar.todoLabelColor'] = dotColor
}
o['calendar.todoLabelCircle'] = circle || false
o['calendar.showLabelAlways'] = showLabelAlways || false
this.setData(o)
}
/**
* 删除指定日期的待办事项
* @param {array} todos 需要删除待办事项的日期
*/
deleteTodoLabels(todos) {
if (!(todos instanceof Array) || !todos.length) return
const todoLabels = this.filterTodos(todos)
const { days: dates, curYear, curMonth } = this.getData('calendar')
const currentMonthTodoLabels = todoLabels.filter(
item => curYear === +item.year && curMonth === +item.month
)
dates.forEach(item => {
item.showTodoLabel = false
})
currentMonthTodoLabels.forEach(item => {
dates[item.day - 1].showTodoLabel = !dates[item.day - 1].choosed
})
this.setData({
'calendar.days': dates,
'calendar.todoLabels': todoLabels
})
}
/**
* 清空所有待办事项
*/
clearTodoLabels() {
const { days = [] } = this.getData('calendar')
const dates = [].concat(days)
dates.forEach(item => {
item.showTodoLabel = false
})
this.setData({
'calendar.days': dates,
'calendar.todoLabels': []
})
}
/**
* 获取所有待办事项
* @param {object} target 指定年月
* @param {number} [target.year]
* @param {number} [target.month]
*/
getTodoLabels(target) {
const { todoLabels = [] } = this.getData('calendar')
if (target) {
const { year, month } = target
const _todoLabels = todoLabels.filter(
item => +item.year === +year && +item.month === +month
)
return _todoLabels
}
return todoLabels
}
/**
* 过滤将删除的待办事项
* @param {array} todos 需要删除待办事项
*/
filterTodos(todos) {
const todoLabels = this.getData('calendar.todoLabels') || []
const deleteTodo = todos.map(item => getDate.toTimeStr(item))
return todoLabels.filter(
item => !deleteTodo.includes(getDate.toTimeStr(item))
)
}
/**
* 单选时显示待办事项
* @param {array} todoDays
* @param {array} days
* @param {array} selectedDays
*/
showTodoLabels(todoDays, days, selectedDays) {
todoDays.forEach(item => {
if (this.Component.weekMode) {
days.forEach((_item, idx) => {
if (+_item.day === +item.day) {
const day = days[idx]
day.hasTodo = true
day.todoText = item.todoText
if (
selectedDays &&
selectedDays.length &&
+selectedDays[0].day === +item.day
) {
day.showTodoLabel = true
}
}
})
} else {
const day = days[item.day - 1]
if (!day) return
day.hasTodo = true
day.todoText = item.todoText
if (
selectedDays &&
selectedDays.length &&
+selectedDays[0].day === +item.day
) {
days[selectedDays[0].day - 1].showTodoLabel = true
}
}
})
}
}
export default component => new Todo(component)

367
components/calendar/func/utils.js

@ -0,0 +1,367 @@
import convertSolarLunar from './convertSolarLunar'
let systemInfo
export function getSystemInfo() {
if (systemInfo) return systemInfo
systemInfo = wx.getSystemInfoSync()
return systemInfo
}
export function isComponent(target) {
return (
target &&
target.__wxExparserNodeId__ !== void 0 &&
typeof target.setData === 'function'
)
}
export 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'
)
}
}
export class Slide {
/**
* 上滑
* @param {object} e 事件对象
* @returns {boolean} 布尔值
*/
isUp(gesture = {}, touche = {}) {
const { startX, startY } = gesture
const deltaX = touche.clientX - startX
const deltaY = touche.clientY - startY
if (deltaY < -60 && deltaX < 20 && deltaX > -20) {
this.slideLock = false
return true
} else {
return false
}
}
/**
* 下滑
* @param {object} e 事件对象
* @returns {boolean} 布尔值
*/
isDown(gesture = {}, touche = {}) {
const { startX, startY } = gesture
const deltaX = touche.clientX - startX
const deltaY = touche.clientY - startY
if (deltaY > 60 && deltaX < 20 && deltaX > -20) {
return true
} else {
return false
}
}
/**
* 左滑
* @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
}
}
}
export class GetDate {
/**
* new Date 区分平台
* @param {number} year
* @param {number} month
* @param {number} day
*/
newDate(year, month, day) {
let cur = `${+year}-${+month}-${+day}`
if (isIos()) {
cur = `${+year}/${+month}/${+day}`
}
return new Date(cur)
}
/**
* 计算指定月份共多少天
* @param {number} year 年份
* @param {number} month 月份
*/
thisMonthDays(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 日期
*/
dayOfWeek(year, month, date) {
return new Date(Date.UTC(year, month - 1, date)).getUTCDay()
}
todayDate() {
const _date = new Date()
const year = _date.getFullYear()
const month = _date.getMonth() + 1
const date = _date.getDate()
return {
year,
month,
date
}
}
todayTimestamp() {
const { year, month, date } = this.todayDate()
const timestamp = this.newDate(year, month, date).getTime()
return timestamp
}
toTimeStr(dateInfo) {
if (dateInfo.day) {
dateInfo.date = dateInfo.day
}
return `${+dateInfo.year}-${+dateInfo.month}-${+dateInfo.date}`
}
sortDates(dates, sortType) {
return dates.sort(function(a, b) {
const at = getDateTimeStamp(a)
const bt = getDateTimeStamp(b)
if (at < bt && sortType !== 'desc') {
return -1
} else {
return 1
}
})
}
prevMonth(dataInfo) {
const prevMonthInfo =
+dataInfo.month > 1
? {
year: dataInfo.year,
month: dataInfo.month - 1
}
: {
year: dataInfo.year - 1,
month: 12
}
return prevMonthInfo
}
nextMonth(dataInfo) {
const nextMonthInfo =
+dataInfo.month < 12
? {
year: dataInfo.year,
month: dataInfo.month + 1
}
: {
year: dataInfo.year + 1,
month: 1
}
return nextMonthInfo
}
convertLunar(dates = []) {
const datesWithLunar = dates.map(date => {
if (date) {
date.lunar = convertSolarLunar.solar2lunar(
+date.year,
+date.month,
+date.day
)
}
return date
})
return datesWithLunar
}
}
export function isIos() {
const sys = getSystemInfo()
return /iphone|ios/i.test(sys.platform)
}
/**
* 浅比较对象是否相等
* @param {Object} origin 对比源
* @param {Object} target 对比目标
* @return {Boolean} true 为相等false 为不等
*/
export function shallowEqual(origin, target) {
if (origin === target) {
return true
} else if (
typeof origin === 'object' &&
origin != null &&
typeof target === 'object' &&
target != null
) {
if (Object.keys(origin).length !== Object.keys(target).length) return false
for (var prop in origin) {
if (target.hasOwnProperty(prop)) {
if (!shallowEqual(origin[prop], target[prop])) return false
} else return false
}
return true
} else return false
}
/**
* 获取当前页面实例
*/
export function getCurrentPage() {
const pages = getCurrentPages()
const last = pages.length - 1
return pages[last]
}
export function getComponent(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('该基础库暂不支持多个小程序日历组件')
}
}
/**
* 日期数组根据日期去重
* @param {array} array 数组
*/
export function uniqueArrayByDate(array = []) {
let uniqueObject = {}
let uniqueArray = []
array.forEach(item => {
uniqueObject[`${item.year}-${item.month}-${item.day}`] = item
})
for (let i in uniqueObject) {
uniqueArray.push(uniqueObject[i])
}
return uniqueArray
}
/**
* 指定可选日期及可选日期数组去重
* @param {array} enableDays 特定可选日期数组
* @param {array} enableArea 可选日期区域数组
*/
export function delRepeatedEnableDay(enableDays = [], enableArea = []) {
let _startTimestamp
let _endTimestamp
if (enableArea.length === 2) {
const { startTimestamp, endTimestamp } = convertEnableAreaToTimestamp(
enableArea
)
_startTimestamp = startTimestamp
_endTimestamp = endTimestamp
}
const enableDaysTimestamp = converEnableDaysToTimestamp(enableDays)
const tmp = enableDaysTimestamp.filter(
item => item < _startTimestamp || item > _endTimestamp
)
return tmp
}
/**
* 指定日期区域转时间戳
* @param {array} timearea 时间区域
*/
export function convertEnableAreaToTimestamp(timearea = []) {
const getDate = new GetDate()
const start = timearea[0].split('-')
const end = timearea[1].split('-')
const logger = new Logger()
if (start.length !== 3 || end.length !== 3) {
logger.warn('enableArea() 参数格式为: ["2018-2-1", "2018-3-1"]')
return {}
}
const startTimestamp = getDate.newDate(start[0], start[1], start[2]).getTime()
const endTimestamp = getDate.newDate(end[0], end[1], end[2]).getTime()
return {
start,
end,
startTimestamp,
endTimestamp
}
}
/**
* 计算指定日期时间戳
* @param {object} dateInfo
*/
export function getDateTimeStamp(dateInfo) {
if (Object.prototype.toString.call(dateInfo) !== '[object Object]') return
const getDate = new GetDate()
return getDate.newDate(dateInfo.year, dateInfo.month, dateInfo.day).getTime()
}
/**
* 指定特定日期数组转时间戳
* @param {array} enableDays 指定时间数组
*/
export function converEnableDaysToTimestamp(enableDays = []) {
const logger = new Logger()
const getDate = new GetDate()
const enableDaysTimestamp = []
enableDays.forEach(item => {
if (typeof item !== 'string')
return logger.warn('enableDays()入参日期格式错误')
const tmp = item.split('-')
if (tmp.length !== 3) return logger.warn('enableDays()入参日期格式错误')
const timestamp = getDate.newDate(tmp[0], tmp[1], tmp[2]).getTime()
enableDaysTimestamp.push(timestamp)
})
return enableDaysTimestamp
}
// 同一页面多个日历组件按先后顺序渲染
export const initialTasks = {
flag: 'finished', // process 处理中,finished 处理完成
tasks: []
}

601
components/calendar/func/week.js

@ -0,0 +1,601 @@
import Day from './day'
import WxData from './wxData'
import Render from './render'
import CalendarConfig from './config'
import convertSolarLunar from './convertSolarLunar'
import { GetDate, Logger, getDateTimeStamp } from './utils'
const getDate = new GetDate()
const logger = new Logger()
class WeekMode extends WxData {
constructor(component) {
super(component)
this.Component = component
this.getCalendarConfig = CalendarConfig(this.Component).getCalendarConfig
}
/**
* 月视图切换
* @param {string} view 视图 [week, month]
* @param {object} date {year: 2017, month: 11, day: 1}
*/
switchWeek(view, date) {
return new Promise((resolve, reject) => {
const config = CalendarConfig(this.Component).getCalendarConfig()
if (config.multi) return logger.warn('多选模式不能切换周月视图')
const { selectedDay = [], curYear, curMonth } = this.getData('calendar')
let currentDate = []
let disableSelected = false
if (!selectedDay.length) {
currentDate = getDate.todayDate()
currentDate.day = currentDate.date
disableSelected = true
// return this.__tipsWhenCanNotSwtich();
} else {
currentDate = selectedDay[0]
}
let selectedDate = date || currentDate
const { year, month } = selectedDate
const notInCurrentMonth = curYear !== year || curMonth !== month
if (view === 'week') {
if (this.Component.weekMode) return
if ((selectedDay.length && notInCurrentMonth) || !selectedDay.length) {
// return this.__tipsWhenCanNotSwtich();
disableSelected = true
selectedDate = {
year: curYear,
month: curMonth,
day: selectedDate.day
}
}
this.Component.weekMode = true
this.setData({
'calendarConfig.weekMode': true
})
this.jump(selectedDate, disableSelected)
.then(resolve)
.catch(reject)
} else {
this.Component.weekMode = false
this.setData({
'calendarConfig.weekMode': false
})
const disableSelected =
(selectedDay.length && notInCurrentMonth) || !selectedDay.length
Render(this.Component)
.renderCalendar(curYear, curMonth, selectedDate.day, disableSelected)
.then(resolve)
.catch(reject)
}
})
}
/**
* 更新当前年月
*/
updateCurrYearAndMonth(type) {
let { days, curYear, curMonth } = this.getData('calendar')
const { month: firstMonth } = days[0]
const { month: lastMonth } = days[days.length - 1]
const lastDayOfThisMonth = getDate.thisMonthDays(curYear, curMonth)
const lastDayOfThisWeek = days[days.length - 1]
const firstDayOfThisWeek = days[0]
if (
(lastDayOfThisWeek.day + 7 > lastDayOfThisMonth ||
(curMonth === firstMonth && firstMonth !== lastMonth)) &&
type === 'next'
) {
curMonth = curMonth + 1
if (curMonth > 12) {
curYear = curYear + 1
curMonth = 1
}
} else if (
(+firstDayOfThisWeek.day <= 7 ||
(curMonth === lastMonth && firstMonth !== lastMonth)) &&
type === 'prev'
) {
curMonth = curMonth - 1
if (curMonth <= 0) {
curYear = curYear - 1
curMonth = 12
}
}
return {
Uyear: curYear,
Umonth: curMonth
}
}
/**
* 计算周视图下当前这一周和当月的最后一天
*/
calculateLastDay() {
const { days = [], curYear, curMonth } = this.getData('calendar')
const lastDayInThisWeek = days[days.length - 1].day
const lastDayInThisMonth = getDate.thisMonthDays(curYear, curMonth)
return { lastDayInThisWeek, lastDayInThisMonth }
}
/**
* 计算周视图下当前这一周第一天
*/
calculateFirstDay() {
const { days } = this.getData('calendar')
const firstDayInThisWeek = days[0].day
return { firstDayInThisWeek }
}
/**
* 当月第一周所有日期范围
* @param {number} year
* @param {number} month
* @param {boolean} firstDayOfWeekIsMon 每周是否配置为以周一开始
*/
firstWeekInMonth(year, month, firstDayOfWeekIsMon) {
let firstDay = getDate.dayOfWeek(year, month, 1)
if (firstDayOfWeekIsMon && firstDay === 0) {
firstDay = 7
}
const [, end] = [0, 7 - firstDay]
let days = this.getData('calendar.days') || []
if (this.Component.weekMode) {
days = Day(this.Component).buildDate(year, month)
}
const daysCut = days.slice(0, firstDayOfWeekIsMon ? end + 1 : end)
return daysCut
}
/**
* 当月最后一周所有日期范围
* @param {number} year
* @param {number} month
* @param {boolean} firstDayOfWeekIsMon 每周是否配置为以周一开始
*/
lastWeekInMonth(year, month, firstDayOfWeekIsMon) {
const lastDay = getDate.thisMonthDays(year, month)
const lastDayWeek = getDate.dayOfWeek(year, month, lastDay)
const [start, end] = [lastDay - lastDayWeek, lastDay]
let days = this.getData('calendar.days') || []
if (this.Component.weekMode) {
days = Day(this.Component).buildDate(year, month)
}
const daysCut = days.slice(firstDayOfWeekIsMon ? start : start - 1, end)
return daysCut
}
__getDisableDateTimestamp(config) {
const { date, type } = config.disableMode || {}
let disableDateTimestamp
if (date) {
const t = date.split('-')
if (t.length < 3) {
logger.warn('配置 disableMode.date 格式错误')
return {}
}
disableDateTimestamp = getDateTimeStamp({
year: +t[0],
month: +t[1],
day: +t[2]
})
}
return {
disableDateTimestamp,
disableType: type
}
}
/**
* 渲染日期之前初始化已选日期
* @param {array} dates 当前日期数组
*/
initSelectedDay(dates) {
let datesCopy = [...dates]
const { selectedDay = [] } = this.getData('calendar')
const selectedDayStr = selectedDay.map(
item => `${+item.year}-${+item.month}-${+item.day}`
)
const config = this.getCalendarConfig()
const {
disableDateTimestamp,
disableType
} = this.__getDisableDateTimestamp(config)
datesCopy = datesCopy.map(item => {
if (!item) return {}
const dateTimestamp = getDateTimeStamp(item)
let date = { ...item }
if (
selectedDayStr.includes(`${+date.year}-${+date.month}-${+date.day}`)
) {
date.choosed = true
} else {
date.choosed = false
}
if (
(disableType === 'after' && dateTimestamp > disableDateTimestamp) ||
(disableType === 'before' && dateTimestamp < disableDateTimestamp)
) {
date.disable = true
}
date = this.__setTodoWhenJump(date, config)
if (config.showLunar) {
date = this.__setSolarLunar(date)
}
if (config.highlightToday) {
date = this.__highlightToday(date)
}
return date
})
return datesCopy
}
/**
* 周视图下设置可选日期范围
* @param {object} days 当前展示的日期
*/
setEnableAreaOnWeekMode(dates = []) {
let { enableAreaTimestamp = [], enableDaysTimestamp = [] } = this.getData(
'calendar'
)
dates.forEach(item => {
const timestamp = getDate
.newDate(item.year, item.month, item.day)
.getTime()
let setDisable = false
if (enableAreaTimestamp.length) {
if (
(+enableAreaTimestamp[0] > +timestamp ||
+timestamp > +enableAreaTimestamp[1]) &&
!enableDaysTimestamp.includes(+timestamp)
) {
setDisable = true
}
} else if (
enableDaysTimestamp.length &&
!enableDaysTimestamp.includes(+timestamp)
) {
setDisable = true
}
if (setDisable) {
item.disable = true
item.choosed = false
}
const config = CalendarConfig(this.Component).getCalendarConfig()
const {
disableDateTimestamp,
disableType
} = this.__getDisableDateTimestamp(config)
if (
(disableType === 'before' && timestamp < disableDateTimestamp) ||
(disableType === 'after' && timestamp > disableDateTimestamp)
) {
item.disable = true
}
})
}
updateYMWhenSwipeCalendarHasSelected(dates) {
const hasSelectedDate = dates.filter(date => date.choosed)
if (hasSelectedDate && hasSelectedDate.length) {
const { year, month } = hasSelectedDate[0]
return {
year,
month
}
}
return {}
}
/**
* 计算下一周的日期
*/
calculateNextWeekDays() {
let { lastDayInThisWeek, lastDayInThisMonth } = this.calculateLastDay()
let { curYear, curMonth } = this.getData('calendar')
let days = []
if (lastDayInThisMonth - lastDayInThisWeek >= 7) {
const { Uyear, Umonth } = this.updateCurrYearAndMonth('next')
curYear = Uyear
curMonth = Umonth
for (let i = lastDayInThisWeek + 1; i <= lastDayInThisWeek + 7; i++) {
days.push({
year: curYear,
month: curMonth,
day: i,
week: getDate.dayOfWeek(curYear, curMonth, i)
})
}
} else {
for (let i = lastDayInThisWeek + 1; i <= lastDayInThisMonth; i++) {
days.push({
year: curYear,
month: curMonth,
day: i,
week: getDate.dayOfWeek(curYear, curMonth, i)
})
}
const { Uyear, Umonth } = this.updateCurrYearAndMonth('next')
curYear = Uyear
curMonth = Umonth
for (let i = 1; i <= 7 - (lastDayInThisMonth - lastDayInThisWeek); i++) {
days.push({
year: curYear,
month: curMonth,
day: i,
week: getDate.dayOfWeek(curYear, curMonth, i)
})
}
}
days = this.initSelectedDay(days)
const {
year: updateYear,
month: updateMonth
} = this.updateYMWhenSwipeCalendarHasSelected(days)
if (updateYear && updateMonth) {
curYear = updateYear
curMonth = updateMonth
}
this.setEnableAreaOnWeekMode(days)
this.setData(
{
'calendar.curYear': curYear,
'calendar.curMonth': curMonth,
'calendar.days': days
},
() => {
Day(this.Component).setDateStyle()
}
)
}
/**
* 计算上一周的日期
*/
calculatePrevWeekDays() {
let { firstDayInThisWeek } = this.calculateFirstDay()
let { curYear, curMonth } = this.getData('calendar')
let days = []
if (firstDayInThisWeek - 7 > 0) {
const { Uyear, Umonth } = this.updateCurrYearAndMonth('prev')
curYear = Uyear
curMonth = Umonth
for (let i = firstDayInThisWeek - 7; i < firstDayInThisWeek; i++) {
days.push({
year: curYear,
month: curMonth,
day: i,
week: getDate.dayOfWeek(curYear, curMonth, i)
})
}
} else {
let temp = []
for (let i = 1; i < firstDayInThisWeek; i++) {
temp.push({
year: curYear,
month: curMonth,
day: i,
week: getDate.dayOfWeek(curYear, curMonth, i)
})
}
const { Uyear, Umonth } = this.updateCurrYearAndMonth('prev')
curYear = Uyear
curMonth = Umonth
const prevMonthDays = getDate.thisMonthDays(curYear, curMonth)
for (
let i = prevMonthDays - Math.abs(firstDayInThisWeek - 7);
i <= prevMonthDays;
i++
) {
days.push({
year: curYear,
month: curMonth,
day: i,
week: getDate.dayOfWeek(curYear, curMonth, i)
})
}
days = days.concat(temp)
}
days = this.initSelectedDay(days)
const {
year: updateYear,
month: updateMonth
} = this.updateYMWhenSwipeCalendarHasSelected(days)
if (updateYear && updateMonth) {
curYear = updateYear
curMonth = updateMonth
}
this.setEnableAreaOnWeekMode(days)
this.setData(
{
'calendar.curYear': curYear,
'calendar.curMonth': curMonth,
'calendar.days': days
},
() => {
Day(this.Component).setDateStyle()
}
)
}
calculateDatesWhenJump(
{ year, month, day },
{ firstWeekDays, lastWeekDays },
firstDayOfWeekIsMon
) {
const inFirstWeek = this.__dateIsInWeek({ year, month, day }, firstWeekDays)
const inLastWeek = this.__dateIsInWeek({ year, month, day }, lastWeekDays)
let dates = []
if (inFirstWeek) {
dates = this.__calculateDatesWhenInFirstWeek(
firstWeekDays,
firstDayOfWeekIsMon
)
} else if (inLastWeek) {
dates = this.__calculateDatesWhenInLastWeek(
lastWeekDays,
firstDayOfWeekIsMon
)
} else {
dates = this.__calculateDates({ year, month, day }, firstDayOfWeekIsMon)
}
return dates
}
jump({ year, month, day }, disableSelected) {
return new Promise(resolve => {
if (!day) return
const config = this.getCalendarConfig()
const firstDayOfWeekIsMon = config.firstDayOfWeek === 'Mon'
const firstWeekDays = this.firstWeekInMonth(
year,
month,
firstDayOfWeekIsMon
)
let lastWeekDays = this.lastWeekInMonth(year, month, firstDayOfWeekIsMon)
let dates = this.calculateDatesWhenJump(
{ year, month, day },
{
firstWeekDays,
lastWeekDays
},
firstDayOfWeekIsMon
)
dates = dates.map(d => {
let date = { ...d }
if (
+date.year === +year &&
+date.month === +month &&
+date.day === +day &&
!disableSelected
) {
date.choosed = true
}
date = this.__setTodoWhenJump(date, config)
if (config.showLunar) {
date = this.__setSolarLunar(date)
}
if (config.highlightToday) {
date = this.__highlightToday(date)
}
return date
})
this.setEnableAreaOnWeekMode(dates)
const tmpData = {
'calendar.days': dates,
'calendar.curYear': year,
'calendar.curMonth': month,
'calendar.empytGrids': [],
'calendar.lastEmptyGrids': []
}
if (!disableSelected) {
tmpData['calendar.selectedDay'] = dates.filter(item => item.choosed)
}
this.setData(tmpData, () => {
Day(this.Component).setDateStyle()
resolve({ year, month, date: day })
})
})
}
__setTodoWhenJump(dateInfo) {
const date = { ...dateInfo }
const { todoLabels = [], showLabelAlways } = this.getData('calendar')
const todosStr = todoLabels.map(d => `${+d.year}-${+d.month}-${+d.day}`)
const idx = todosStr.indexOf(`${+date.year}-${+date.month}-${+date.day}`)
if (idx !== -1) {
if (showLabelAlways) {
date.showTodoLabel = true
} else {
date.showTodoLabel = !date.choosed
}
const todo = todoLabels[idx] || {}
if (date.showTodoLabel && todo.todoText) date.todoText = todo.todoText
if (todo.color) date.color = todo.color
}
return date
}
__setSolarLunar(dateInfo) {
const date = { ...dateInfo }
date.lunar = convertSolarLunar.solar2lunar(
+date.year,
+date.month,
+date.day
)
return date
}
__highlightToday(dateInfo) {
const date = { ...dateInfo }
const today = getDate.todayDate()
const isToday =
+today.year === +date.year &&
+today.month === +date.month &&
+date.day === +today.date
date.isToday = isToday
return date
}
__calculateDatesWhenInFirstWeek(firstWeekDays) {
const dates = [...firstWeekDays]
if (dates.length < 7) {
let { year, month } = dates[0]
let len = 7 - dates.length
let lastDate
if (month > 1) {
month -= 1
lastDate = getDate.thisMonthDays(year, month)
} else {
month = 12
year -= 1
lastDate = getDate.thisMonthDays(year, month)
}
while (len) {
dates.unshift({
year,
month,
day: lastDate,
week: getDate.dayOfWeek(year, month, lastDate)
})
lastDate -= 1
len -= 1
}
}
return dates
}
__calculateDatesWhenInLastWeek(lastWeekDays) {
const dates = [...lastWeekDays]
if (dates.length < 7) {
let { year, month } = dates[0]
let len = 7 - dates.length
let firstDate = 1
if (month > 11) {
month = 1
year += 1
} else {
month += 1
}
while (len) {
dates.push({
year,
month,
day: firstDate,
week: getDate.dayOfWeek(year, month, firstDate)
})
firstDate += 1
len -= 1
}
}
return dates
}
__calculateDates({ year, month, day }, firstDayOfWeekIsMon) {
const week = getDate.dayOfWeek(year, month, day)
let range = [day - week, day + (6 - week)]
if (firstDayOfWeekIsMon) {
range = [day + 1 - week, day + (7 - week)]
}
const dates = Day(this.Component).buildDate(year, month)
const weekDates = dates.slice(range[0] - 1, range[1])
return weekDates
}
__dateIsInWeek(date, week) {
return week.find(
item =>
+item.year === +date.year &&
+item.month === +date.month &&
+item.day === +date.day
)
}
__tipsWhenCanNotSwtich() {
logger.info(
'当前月份未选中日期下切换为周视图,不能明确该展示哪一周的日期,故此情况不允许切换'
)
}
}
export default component => new WeekMode(component)

26
components/calendar/func/wxData.js

@ -0,0 +1,26 @@
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, cb = () => {}) {
if (!data) return
if (typeof data === 'object') {
this.Component.setData(data, cb)
}
}
}
export default WxData

309
components/calendar/index.js

@ -0,0 +1,309 @@
import Week from './func/week'
import {
Logger,
Slide,
GetDate,
initialTasks
} from './func/utils'
import initCalendar, {
jump,
getCurrentYM,
whenChangeDate,
renderCalendar,
whenMulitSelect,
whenSingleSelect,
whenChooseArea,
getCalendarDates
} from './main.js'
const slide = new Slide()
const logger = new Logger()
const getDate = new GetDate()
Component({
options: {
styleIsolation: 'apply-shared',
multipleSlots: true, // 在组件定义时的选项中启用多slot支持
addGlobalClass: true
},
properties: {
calendarConfig: {
type: Object,
value: {}
}
},
data: {
handleMap: {
prev_year: 'chooseYear',
prev_month: 'chooseMonth',
next_month: 'chooseMonth',
next_year: 'chooseYear',
calendarDisplayTime: ''
}
},
lifetimes: {
attached: function () {
this.initComp()
this.backToday()
},
detached: function () {
initialTasks.flag = 'finished'
initialTasks.tasks.length = 0
}
},
methods: {
initComp() {
const calendarConfig = this.setDefaultDisableDate()
this.setConfig(calendarConfig)
},
setDefaultDisableDate() {
const calendarConfig = this.properties.calendarConfig || {}
if (calendarConfig.disableMode && !calendarConfig.disableMode.date) {
calendarConfig.disableMode.date = getDate.toTimeStr(getDate.todayDate())
}
return calendarConfig
},
setConfig(config) {
if (config.markToday && typeof config.markToday === 'string') {
config.highlightToday = true
}
config.theme = config.theme || 'default'
this.weekMode = config.weekMode
this.setData({
calendarConfig: config
},
() => {
initCalendar(this, config)
}
)
},
chooseDate(e) {
const {
type
} = e.currentTarget.dataset
if (!type) return
const methodName = this.data.handleMap[type]
this[methodName](type)
},
chooseYear(type) {
const {
curYear,
curMonth
} = this.data.calendar
if (!curYear || !curMonth) return logger.warn('异常:未获取到当前年月')
if (this.weekMode) {
return console.warn('周视图下不支持点击切换年月')
}
let newYear = +curYear
let newMonth = +curMonth
if (type === 'prev_year') {
newYear -= 1
} else if (type === 'next_year') {
newYear += 1
}
this.render(curYear, curMonth, newYear, newMonth)
},
chooseMonth(type) {
const {
curYear,
curMonth
} = this.data.calendar
if (!curYear || !curMonth) return logger.warn('异常:未获取到当前年月')
if (this.weekMode) return console.warn('周视图下不支持点击切换年月')
let newYear = +curYear
let newMonth = +curMonth
if (type === 'prev_month') {
newMonth = newMonth - 1
if (newMonth < 1) {
newYear -= 1
newMonth = 12
}
} else if (type === 'next_month') {
newMonth += 1
if (newMonth > 12) {
newYear += 1
newMonth = 1
}
}
this.render(curYear, curMonth, newYear, newMonth)
},
render(curYear, curMonth, newYear, newMonth) {
whenChangeDate.call(this, {
curYear,
curMonth,
newYear,
newMonth
})
let myMonth = newMonth < 10 ? '0' + newMonth : newMonth;
let calendarDisplayTime = `${newYear}-${myMonth}`;
this.setData({
'calendar.curYear': newYear,
'calendar.curMonth': myMonth,
calendarDisplayTime
})
renderCalendar.call(this, newYear, newMonth)
},
bindDateChange(res) {
let value = res.detail.value;
let arr = value.split('-');
let newYear = parseInt(arr[0]);
let newMonth = parseInt(arr[1]);
this.setData({
'calendar.curYear': newYear,
'calendar.curMonth': newMonth,
calendarDisplayTime: value
})
renderCalendar.call(this, newYear, newMonth)
},
backToday() {
let timer = new Date()
let year = timer.getFullYear()
let month = timer.getMonth() + 1
month = month.length > 1 ? month : '0' + month
let date = `${year}-${month}`
if (date !== this.data.calendarDisplayTime) {
this.setData({
calendarDisplayTime: date
})
}
},
/**
* 日期点击事件
* @param {!object} e 事件对象
*/
tapDayItem(e) {
const {
idx,
date = {}
} = e.currentTarget.dataset
const {
day,
disable
} = date
if (disable || !day) return
const config = this.data.calendarConfig || this.config || {}
const {
multi,
chooseAreaMode
} = config
if (multi) {
whenMulitSelect.call(this, idx)
} else if (chooseAreaMode) {
whenChooseArea.call(this, idx)
} else {
whenSingleSelect.call(this, idx)
}
this.setData({
'calendar.noDefault': false
})
},
doubleClickToToday() {
if (this.config.multi || this.weekMode) return
if (this.count === undefined) {
this.count = 1
} else {
this.count += 1
}
if (this.lastClick) {
const difference = new Date().getTime() - this.lastClick
if (difference < 500 && this.count >= 2) {
jump.call(this)
}
this.count = undefined
this.lastClick = undefined
} else {
this.lastClick = new Date().getTime()
}
},
/**
* 日历滑动开始
* @param {object} e
*/
calendarTouchstart(e) {
const t = e.touches[0]
const startX = t.clientX
const startY = t.clientY
this.slideLock = true // 滑动事件加锁
this.setData({
'gesture.startX': startX,
'gesture.startY': startY
})
},
/**
* 日历滑动中
* @param {object} e
*/
calendarTouchmove(e) {
const {
gesture
} = this.data
const {
preventSwipe
} = this.properties.calendarConfig
if (!this.slideLock || preventSwipe) return
if (slide.isLeft(gesture, e.touches[0])) {
this.handleSwipe('left')
this.slideLock = false
}
if (slide.isRight(gesture, e.touches[0])) {
this.handleSwipe('right')
this.slideLock = false
}
},
calendarTouchend(e) {
this.setData({
'calendar.leftSwipe': 0,
'calendar.rightSwipe': 0
})
},
handleSwipe(direction) {
let swipeKey = 'calendar.leftSwipe'
let swipeCalendarType = 'next_month'
let weekChangeType = 'next_week'
if (direction === 'right') {
swipeKey = 'calendar.rightSwipe'
swipeCalendarType = 'prev_month'
weekChangeType = 'prev_week'
}
this.setData({
[swipeKey]: 1
})
this.currentYM = getCurrentYM()
if (this.weekMode) {
this.slideLock = false
this.currentDates = getCalendarDates()
if (weekChangeType === 'prev_week') {
Week(this).calculatePrevWeekDays()
} else if (weekChangeType === 'next_week') {
Week(this).calculateNextWeekDays()
}
this.onSwipeCalendar(weekChangeType)
this.onWeekChange(weekChangeType)
return
}
this.chooseMonth(swipeCalendarType)
this.onSwipeCalendar(swipeCalendarType)
},
onSwipeCalendar(direction) {
this.triggerEvent('onSwipe', {
directionType: direction,
currentYM: this.currentYM
})
},
onWeekChange(direction) {
this.triggerEvent('whenChangeWeek', {
current: {
currentYM: this.currentYM,
dates: [...this.currentDates]
},
next: {
currentYM: getCurrentYM(),
dates: getCalendarDates()
},
directionType: direction
})
this.currentDates = null
this.currentYM = null
}
},
})

3
components/calendar/index.json

@ -0,0 +1,3 @@
{
"component": true
}

66
components/calendar/index.wxml

@ -0,0 +1,66 @@
<view class="calendar" wx:if="{{calendar}}">
<!-- 头部操作栏 -->
<view class="timer flex-center">
<text class="back-now" bindtap="backToday">回到今天</text>
<view class="t-box flex-center">
<picker mode="date" value="{{calendarDisplayTime}}" fields="month" start="1970-01" bindchange="bindDateChange">
<view class="p-time">{{calendarDisplayTime}}</view>
</picker>
<view class="year">{{calendar.curYear || "--"}}年</view>
<view class="month">{{calendar.curMonth || "--"}}月</view>
</view>
</view>
<!-- 星期栏 -->
<view class="weeks b lr ac {{calendarConfig.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" bindtouchstart="calendarTouchstart" catchtouchmove="calendarTouchmove"
catchtouchend="calendarTouchend">
<!-- 上月日期格子 -->
<view class="grid b ac pc {{calendarConfig.theme}}_prev-month-date" wx:if="{{calendar.empytGrids}}"
wx:for="{{calendar.empytGrids}}" wx:key="index" data-idx="{{index}}">
<view class="date-wrap b cc">
<view class="date">
{{item.day}}
<view wx:if="{{calendarConfig.showLunar && item.lunar}}" class="date-desc date-desc-bottom">
{{item.lunar.Term || item.lunar.IDayCn}}
</view>
</view>
</view>
</view>
<!-- 本月日期格子 -->
<view wx:for="{{calendar.days}}" wx:key="index" data-idx="{{index}}" data-date="{{item}}" bindtap="tapDayItem"
class="grid {{item.class ? item.class : ''}} b ac pc">
<view
class="date-wrap b cc {{(item.week === 0 || item.week === 6) ? calendarConfig.theme + '_weekend-color' : ''}}">
<view
class="date b ac pc {{item.class ? item.class : ''}} {{calendarConfig.chooseAreaMode ? 'date-area-mode' : ''}} {{calendar.todoLabelCircle && item.showTodoLabel && !item.choosed ? calendarConfig.theme + '_todo-circle todo-circle' : '' }} {{item.isToday ? calendarConfig.theme + '_today' : ''}} {{item.choosed ? calendarConfig.theme + '_choosed' : ''}} {{item.disable ? calendarConfig.theme + '_date-disable' : ''}}">
{{calendarConfig.markToday && item.isToday ? calendarConfig.markToday : item.day}}
<view
wx:if="{{(calendarConfig.showLunar && item.lunar && !item.showTodoLabel) || (item.showTodoLabel && calendar.todoLabelPos !== 'bottom')}}"
class="date-desc {{calendarConfig.theme}}_date-desc date-desc-bottom {{(item.choosed || item.isToday) ? 'date-desc-bottom-always' : ''}} {{item.disable ? calendarConfig.theme + '_date-desc-disable' : ''}}">
{{item.lunar.Term || item.lunar.IDayCn}}
</view>
<view wx:if="{{item.showTodoLabel && !calendar.todoLabelCircle}}"
class="{{item.todoText ? 'date-desc' : calendarConfig.theme + '_todo-dot todo-dot'}} {{calendarConfig.showLunar ? calendarConfig.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 {{calendarConfig.theme}}_next-month-date" wx:for="{{calendar.lastEmptyGrids}}"
wx:key="index" data-idx="{{index}}">
<view class="date-wrap b cc">
<view class="date">
{{item.day}}
<view wx:if="{{calendarConfig.showLunar && item.lunar}}" class="date-desc date-desc-bottom">
{{item.lunar.Term || item.lunar.IDayCn}}
</view>
</view>
</view>
</view>
</view>
</view>

214
components/calendar/index.wxss

@ -0,0 +1,214 @@
@import './theme/iconfont.wxss';
@import './theme/theme-default.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: 80rpx;
}
.prev-handle,
.next-handle {
padding: 20rpx;
}
.date-in-handle {
height: 80rpx;
}
/* 星期栏 */
.weeks {
height: 72rpx;
line-height: 72rpx;
padding: 10rpx 0;
}
.week {
text-align: center;
}
.grid,
.week {
width: 14.286014285714286%;
}
.date-wrap {
width: 100%;
height: 80rpx;
position: relative;
left: 0;
top: 0;
}
.date {
position: relative;
left: 0;
top: 0;
width: 72rpx;
height: 72rpx;
text-align: center;
line-height: 72rpx;
font-size: 30rpx;
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;
}
.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;
}

877
components/calendar/main.js

@ -0,0 +1,877 @@
import Day from './func/day'
import Week from './func/week'
import Todo from './func/todo'
import WxData from './func/wxData'
import Calendar from './func/render'
import CalendarConfig from './func/config'
import convertSolarLunar from './func/convertSolarLunar'
import {
Logger,
GetDate,
isComponent,
initialTasks,
getCurrentPage,
getComponent,
getDateTimeStamp
} from './func/utils'
let Component = {}
let logger = new Logger()
let getDate = new GetDate()
let dataInstance = null
/**
* 全局赋值正在操作的组件实例方便读/写各自的 data
* @param {string} componentId 要操作的日历组件ID
*/
function bindCurrentComponent(componentId) {
if (componentId) {
Component = getComponent(componentId)
}
return Component
}
/**
* 获取日历内部数据
* @param {string} key 获取值的键名
* @param {string} componentId 要操作的日历组件ID
*/
function getData(key, componentId) {
bindCurrentComponent(componentId)
dataInstance = new WxData(Component)
return dataInstance.getData(key)
}
/**
* 设置日历内部数据
* @param {object}} data 待设置的数据
* @param {function} callback 设置成功回调函数
*/
function setData(data, callback = () => {}) {
const dataInstance = new WxData(Component)
return dataInstance.setData(data, callback)
}
const conf = {
/**
* 渲染日历
* @param {number} curYear
* @param {number} curMonth
* @param {number} curDate
*/
renderCalendar(curYear, curMonth, curDate) {
if (isComponent(this)) Component = this
return new Promise((resolve, reject) => {
Calendar(Component)
.renderCalendar(curYear, curMonth, curDate)
.then((info = {}) => {
if (!info.firstRender) {
return resolve({
year: curYear,
month: curMonth,
date: curDate
})
}
mountEventsOnPage(getCurrentPage())
Component.triggerEvent('afterCalendarRender', Component)
Component.firstRender = true
initialTasks.flag = 'finished'
if (initialTasks.tasks.length) {
initialTasks.tasks.shift()()
}
resolve({
year: curYear,
month: curMonth,
date: curDate
})
})
.catch(err => {
reject(err)
})
})
},
/**
* 当改变月份时触发
* @param {object} param
*/
whenChangeDate({ curYear, curMonth, newYear, newMonth }) {
Component.triggerEvent('whenChangeMonth', {
current: {
year: curYear,
month: curMonth
},
next: {
year: newYear,
month: newMonth
}
})
},
/**
* 多选
* @param {number} dateIdx 当前选中日期索引值
*/
whenMulitSelect(dateIdx) {
if (isComponent(this)) Component = this
const { calendar = {} } = getData()
const { days, todoLabels } = calendar
const config = CalendarConfig(Component).getCalendarConfig()
let { selectedDay: selectedDays = [] } = calendar
const currentDay = days[dateIdx]
if (!currentDay) return
currentDay.choosed = !currentDay.choosed
if (!currentDay.choosed) {
currentDay.cancel = true // 该次点击是否为取消日期操作
const currentDayStr = getDate.toTimeStr(currentDay)
selectedDays = selectedDays.filter(
item => currentDayStr !== getDate.toTimeStr(item)
)
if (todoLabels) {
todoLabels.forEach(item => {
if (currentDayStr === getDate.toTimeStr(item)) {
currentDay.showTodoLabel = true
}
})
}
} else {
currentDay.cancel = false
const { showLabelAlways } = getData('calendar')
if (showLabelAlways && currentDay.showTodoLabel) {
currentDay.showTodoLabel = true
} else {
currentDay.showTodoLabel = false
}
if (!config.takeoverTap) {
selectedDays.push(currentDay)
}
}
if (config.takeoverTap) {
return Component.triggerEvent('onTapDay', currentDay)
}
setData({
'calendar.days': days,
'calendar.selectedDay': selectedDays
})
conf.afterTapDay(currentDay, selectedDays)
},
/**
* 单选
* @param {number} dateIdx 当前选中日期索引值
*/
whenSingleSelect(dateIdx) {
if (isComponent(this)) Component = this
const { calendar = {} } = getData()
const { days, selectedDay: selectedDays = [], todoLabels } = calendar
let shouldMarkerTodoDay = []
const currentDay = days[dateIdx]
if (!currentDay) return
const preSelectedDate = [...selectedDays].pop() || {}
const { month: dMonth, year: dYear } = days[0] || {}
const config = CalendarConfig(Component).getCalendarConfig()
if (config.takeoverTap) {
return Component.triggerEvent('onTapDay', currentDay)
}
conf.afterTapDay(currentDay)
if (!config.inverse && preSelectedDate.day === currentDay.day) return
days.forEach((item, idx) => {
if (+item.day === +preSelectedDate.day) days[idx].choosed = false
})
if (todoLabels) {
// 筛选当月待办事项的日期
shouldMarkerTodoDay = todoLabels.filter(
item => +item.year === dYear && +item.month === dMonth
)
}
Todo(Component).showTodoLabels(shouldMarkerTodoDay, days, selectedDays)
const tmp = {
'calendar.days': days
}
if (preSelectedDate.day !== currentDay.day) {
preSelectedDate.choosed = false
currentDay.choosed = true
if (!calendar.showLabelAlways || !currentDay.showTodoLabel) {
currentDay.showTodoLabel = false
}
tmp['calendar.selectedDay'] = [currentDay]
} else if (config.inverse) {
if (currentDay.choosed) {
if (currentDay.showTodoLabel && calendar.showLabelAlways) {
currentDay.showTodoLabel = true
} else {
currentDay.showTodoLabel = false
}
}
tmp['calendar.selectedDay'] = []
}
if (config.weekMode) {
tmp['calendar.curYear'] = currentDay.year
tmp['calendar.curMonth'] = currentDay.month
}
setData(tmp)
},
gotoSetContinuousDates(start, end) {
return chooseDateArea([
`${getDate.toTimeStr(start)}`,
`${getDate.toTimeStr(end)}`
])
},
timeRangeHelper(currentDate, selectedDay) {
const currentDateTimestamp = getDateTimeStamp(currentDate)
const startDate = selectedDay[0]
let endDate
let endDateTimestamp
let selectedLen = selectedDay.length
if (selectedLen > 1) {
endDate = selectedDay[selectedLen - 1]
endDateTimestamp = getDateTimeStamp(endDate)
}
const startTimestamp = getDateTimeStamp(startDate)
return {
endDate,
startDate,
currentDateTimestamp,
endDateTimestamp,
startTimestamp
}
},
/**
* 计算连续日期选择的开始及结束日期
* @param {object} currentDate 当前选择日期
* @param {array} selectedDay 已选择的的日期
*/
calculateDateRange(currentDate, selectedDay) {
const {
endDate,
startDate,
currentDateTimestamp,
endDateTimestamp,
startTimestamp
} = this.timeRangeHelper(currentDate, selectedDay)
let range = []
let selectedLen = selectedDay.length
const isWantToChooseOneDate = selectedDay.filter(
item => getDate.toTimeStr(item) === getDate.toTimeStr(currentDate)
)
if (selectedLen === 2 && isWantToChooseOneDate.length) {
range = [currentDate, currentDate]
return range
}
if (
currentDateTimestamp >= startTimestamp &&
endDateTimestamp &&
currentDateTimestamp <= endDateTimestamp
) {
const currentDateIdxInChoosedDateArea = selectedDay.findIndex(
item => getDate.toTimeStr(item) === getDate.toTimeStr(currentDate)
)
if (selectedLen / 2 > currentDateIdxInChoosedDateArea) {
range = [currentDate, endDate]
} else {
range = [startDate, currentDate]
}
} else if (currentDateTimestamp < startTimestamp) {
range = [currentDate, endDate]
} else if (currentDateTimestamp > startTimestamp) {
range = [startDate, currentDate]
}
return range
},
chooseAreaWhenExistArea(currentDate, selectedDay) {
return new Promise((resolve, reject) => {
const range = conf.calculateDateRange(
currentDate,
getDate.sortDates(selectedDay)
)
conf
.gotoSetContinuousDates(...range)
.then(data => {
resolve(data)
conf.afterTapDay(currentDate)
})
.catch(err => {
reject(err)
conf.afterTapDay(currentDate)
})
})
},
chooseAreaWhenHasOneDate(currentDate, selectedDay, lastChoosedDate) {
return new Promise((resolve, reject) => {
const startDate = lastChoosedDate || selectedDay[0]
let range = [startDate, currentDate]
const currentDateTimestamp = getDateTimeStamp(currentDate)
const lastChoosedDateTimestamp = getDateTimeStamp(startDate)
if (lastChoosedDateTimestamp > currentDateTimestamp) {
range = [currentDate, startDate]
}
conf
.gotoSetContinuousDates(...range)
.then(data => {
resolve(data)
conf.afterTapDay(currentDate)
})
.catch(err => {
reject(err)
conf.afterTapDay(currentDate)
})
})
},
/**
* 日期范围选择模式
* @param {number} dateIdx 当前选中日期索引值
*/
whenChooseArea(dateIdx) {
return new Promise((resolve, reject) => {
if (isComponent(this)) Component = this
if (Component.weekMode) return
const { days = [], selectedDay, lastChoosedDate } = getData('calendar')
const currentDate = days[dateIdx]
if (currentDate.disable) return
const config = CalendarConfig(Component).getCalendarConfig()
if (config.takeoverTap) {
return Component.triggerEvent('onTapDay', currentDate)
}
if (selectedDay && selectedDay.length > 1) {
conf
.chooseAreaWhenExistArea(currentDate, selectedDay)
.then(dates => {
resolve(dates)
})
.catch(err => {
reject(err)
})
} else if (lastChoosedDate || (selectedDay && selectedDay.length === 1)) {
conf
.chooseAreaWhenHasOneDate(currentDate, selectedDay, lastChoosedDate)
.then(dates => {
resolve(dates)
})
.catch(err => {
reject(err)
})
} else {
days.forEach(date => {
if (+date.day === +currentDate.day) {
date.choosed = true
} else {
date.choosed = false
}
})
const dataInstance = new WxData(Component)
dataInstance.setData({
'calendar.days': [...days],
'calendar.lastChoosedDate': currentDate
})
}
})
},
/**
* 点击日期后触发事件
* @param {object} currentSelected 当前选择的日期
* @param {array} selectedDates 多选状态下选中的日期
*/
afterTapDay(currentSelected, selectedDates) {
const config = CalendarConfig(Component).getCalendarConfig()
const { multi } = config
if (!multi) {
Component.triggerEvent('afterTapDay', currentSelected)
} else {
Component.triggerEvent('afterTapDay', {
currentSelected,
selectedDates
})
}
},
/**
* 跳转至今天
*/
jumpToToday() {
return new Promise((resolve, reject) => {
const { year, month, date } = getDate.todayDate()
const timestamp = getDate.todayTimestamp()
const config = CalendarConfig(Component).getCalendarConfig()
setData({
'calendar.curYear': year,
'calendar.curMonth': month,
'calendar.selectedDay': [
{
year: year,
day: date,
month: month,
choosed: true,
lunar: config.showLunar
? convertSolarLunar.solar2lunar(year, month, date)
: null
}
],
'calendar.todayTimestamp': timestamp
})
conf
.renderCalendar(year, month, date)
.then(() => {
resolve({ year, month, date })
})
.catch(() => {
reject('jump failed')
})
})
}
}
export const whenChangeDate = conf.whenChangeDate
export const renderCalendar = conf.renderCalendar
export const whenSingleSelect = conf.whenSingleSelect
export const whenChooseArea = conf.whenChooseArea
export const whenMulitSelect = conf.whenMulitSelect
export const calculatePrevWeekDays = conf.calculatePrevWeekDays
export const calculateNextWeekDays = conf.calculateNextWeekDays
/**
* 获取当前年月
* @param {string} componentId 要操作的日历组件ID
*/
export function getCurrentYM(componentId) {
bindCurrentComponent(componentId)
return {
year: getData('calendar.curYear'),
month: getData('calendar.curMonth')
}
}
/**
* 获取已选择的日期
* @param {object } options 日期配置选项 {lunar} 是否返回农历信息
* @param {string} componentId 要操作的日历组件ID
*/
export function getSelectedDay(options = {}, componentId) {
bindCurrentComponent(componentId)
const config = getCalendarConfig()
const dates = getData('calendar.selectedDay') || []
if (options.lunar && !config.showLunar) {
const datesWithLunar = getDate.convertLunar(dates)
return datesWithLunar
} else {
return dates
}
}
/**
* 取消选中日期
* @param {array} dates 需要取消的日期不传则取消所有已选择的日期
* @param {string} componentId 要操作的日历组件ID
*/
export function cancelSelectedDates(dates, componentId) {
bindCurrentComponent(componentId)
const { days = [], selectedDay = [] } = getData('calendar') || {}
if (!dates || !dates.length) {
days.forEach(item => {
item.choosed = false
})
setData({
'calendar.days': days,
'calendar.selectedDay': []
})
} else {
const cancelDatesStr = dates.map(
date => `${+date.year}-${+date.month}-${+date.day}`
)
const filterSelectedDates = selectedDay.filter(
date =>
!cancelDatesStr.includes(`${+date.year}-${+date.month}-${+date.day}`)
)
days.forEach(date => {
if (
cancelDatesStr.includes(`${+date.year}-${+date.month}-${+date.day}`)
) {
date.choosed = false
}
})
setData({
'calendar.days': days,
'calendar.selectedDay': filterSelectedDates
})
}
}
/**
* 周视图跳转
* @param {object} date info
* @param {boolean} disableSelected 跳转时是否需要选中周视图切换调用该方法如未选择日期时不选中日期
*/
function jumpWhenWeekMode({ year, month, day }, disableSelected) {
return new Promise((resolve, reject) => {
Week(Component)
.jump(
{
year: +year,
month: +month,
day: +day
},
disableSelected
)
.then(date => {
resolve(date)
Component.triggerEvent('afterCalendarRender', Component)
})
.catch(err => {
reject(err)
Component.triggerEvent('afterCalendarRender', Component)
})
})
}
/**
* 月视图跳转
* @param {object} date info
*/
function jumpWhenNormalMode({ year, month, day }) {
return new Promise((resolve, reject) => {
if (typeof +year !== 'number' || typeof +month !== 'number') {
return logger.warn('jump 函数年月日参数必须为数字')
}
const timestamp = getDate.todayTimestamp()
let tmp = {
'calendar.curYear': +year,
'calendar.curMonth': +month,
'calendar.todayTimestamp': timestamp
}
setData(tmp, () => {
conf
.renderCalendar(+year, +month, +day)
.then(date => {
resolve(date)
})
.catch(err => {
reject(err)
})
})
})
}
/**
* 跳转至指定日期
* @param {number} year
* @param {number} month
* @param {number} day
* @param {string} componentId 要操作的日历组件ID
*/
export function jump(year, month, day, componentId) {
return new Promise((resolve, reject) => {
bindCurrentComponent(componentId)
const { selectedDay = [] } = getData('calendar') || {}
const { weekMode } = getData('calendarConfig') || {}
const { year: y, month: m, day: d } = selectedDay[0] || {}
if (+y === +year && +m === +month && +d === +day) {
return
}
if (weekMode) {
let disableSelected = false
if (!year || !month || !day) {
const today = getDate.todayDate()
year = today.year
month = today.month
day = today.date
disableSelected = true
}
jumpWhenWeekMode({ year, month, day }, disableSelected)
.then(date => {
resolve(date)
})
.catch(err => {
reject(err)
})
mountEventsOnPage(getCurrentPage())
return
}
if (year && month) {
jumpWhenNormalMode({ year, month, day })
.then(date => {
resolve(date)
})
.catch(err => {
reject(err)
})
} else {
conf
.jumpToToday()
.then(date => {
resolve(date)
})
.catch(err => {
reject(err)
})
}
})
}
/**
* 设置待办事项日期标记
* @param {object} todos 待办事项配置
* @param {string} [todos.pos] 标记显示位置默认值'bottom' ['bottom', 'top']
* @param {string} [todos.dotColor] 标记点颜色backgroundColor 支持的值都行
* @param {object[]} [todos.days] 需要标记的所有日期[{year: 2015, month: 5, day: 12}]其中年月日字段必填
* @param {string} componentId 要操作的日历组件ID
*/
export function setTodoLabels(todos, componentId) {
bindCurrentComponent(componentId)
Todo(Component).setTodoLabels(todos)
}
/**
* 删除指定日期待办事项
* @param {array} todos 需要删除的待办日期数组
* @param {string} componentId 要操作的日历组件ID
*/
export function deleteTodoLabels(todos, componentId) {
bindCurrentComponent(componentId)
Todo(Component).deleteTodoLabels(todos)
}
/**
* 清空所有待办事项
* @param {string} componentId 要操作的日历组件ID
*/
export function clearTodoLabels(componentId) {
bindCurrentComponent(componentId)
Todo(Component).clearTodoLabels()
}
/**
* 获取所有待办事项
* @param {object } options 日期配置选项 {lunar} 是否返回农历信息
* @param {string} componentId 要操作的日历组件ID
*/
export function getTodoLabels(options = {}, componentId) {
bindCurrentComponent(componentId)
const config = getCalendarConfig()
const todoDates = Todo(Component).getTodoLabels() || []
if (options.lunar && !config.showLunar) {
const todoDatesWithLunar = getDate.convertLunar(todoDates)
return todoDatesWithLunar
} else {
return todoDates
}
}
/**
* 禁用指定日期
* @param {array} days 日期
* @param {number} [days.year]
* @param {number} [days.month]
* @param {number} [days.day]
* @param {string} componentId 要操作的日历组件ID
*/
export function disableDay(days = [], componentId) {
bindCurrentComponent(componentId)
Day(Component).disableDays(days)
}
/**
* 指定可选日期范围
* @param {array} area 日期访问数组
* @param {string} componentId 要操作的日历组件ID
*/
export function enableArea(area = [], componentId) {
bindCurrentComponent(componentId)
Day(Component).enableArea(area)
}
/**
* 指定特定日期可选
* @param {array} days 指定日期数组
* @param {string} componentId 要操作的日历组件ID
*/
export function enableDays(days = [], componentId) {
bindCurrentComponent(componentId)
Day(Component).enableDays(days)
}
/**
* 设置选中日期多选模式下
* @param {array} selected 需选中日期
* @param {string} componentId 要操作的日历组件ID
*/
export function setSelectedDays(selected, componentId) {
bindCurrentComponent(componentId)
Day(Component).setSelectedDays(selected)
}
/**
* 获取当前日历配置
* @param {string} componentId 要操作的日历组件ID
*/
export function getCalendarConfig(componentId) {
bindCurrentComponent(componentId)
return CalendarConfig(Component).getCalendarConfig()
}
/**
* 设置日历配置
* @param {object} config
* @param {string} componentId 要操作的日历组件ID
*/
export function setCalendarConfig(config, componentId) {
bindCurrentComponent(componentId)
if (!config || Object.keys(config).length === 0) {
return logger.warn('setCalendarConfig 参数必须为非空对象')
}
const existConfig = getCalendarConfig()
return new Promise((resolve, reject) => {
CalendarConfig(Component)
.setCalendarConfig(config)
.then(conf => {
resolve(conf)
const { date, type } = existConfig.disableMode || {}
const { _date, _type } = config.disableMode || {}
if (type !== _type || date !== _date) {
const { year, month } = getCurrentYM()
jump(year, month)
}
})
.catch(err => {
reject(err)
})
})
}
/**
* 获取当前日历面板日期
* @param {object } options 日期配置选项 {lunar} 是否返回农历信息
* @param {string} componentId 要操作的日历组件ID
*/
export function getCalendarDates(options = {}, componentId) {
bindCurrentComponent(componentId)
const config = getCalendarConfig()
const dates = getData('calendar.days', componentId) || []
if (options.lunar && !config.showLunar) {
const datesWithLunar = getDate.convertLunar(dates)
return datesWithLunar
} else {
return dates
}
}
/**
* 选择连续日期范围
* @param {string} componentId 要操作的日历组件ID
*/
export function chooseDateArea(dateArea, componentId) {
bindCurrentComponent(componentId)
return Day(Component).chooseArea(dateArea)
}
/**
* 设置指定日期样式
* @param {array} dates 待设置特殊样式的日期
* @param {string} componentId 要操作的日历组件ID
*/
export function setDateStyle(dates, componentId) {
if (!dates) return
bindCurrentComponent(componentId)
Day(Component).setDateStyle(dates)
}
/**
* 切换周月视图
* 切换视图时可传入指定日期: {year: 2019, month: 1, day: 3}
* args[0] view 视图模式[week, month]
* args[1]|args[2]为day object或者 componentId
*/
export function switchView(...args) {
return new Promise((resolve, reject) => {
const view = args[0]
if (!args[1]) {
return Week(Component)
.switchWeek(view)
.then(resolve)
.catch(reject)
}
if (typeof args[1] === 'string') {
bindCurrentComponent(args[1], this)
Week(Component)
.switchWeek(view, args[2])
.then(resolve)
.catch(reject)
} else if (typeof args[1] === 'object') {
if (typeof args[2] === 'string') {
bindCurrentComponent(args[1], this)
}
Week(Component)
.switchWeek(view, args[1])
.then(resolve)
.catch(reject)
}
})
}
/**
* 绑定日历事件至当前页面实例
* @param {object} page 当前页面实例
*/
function mountEventsOnPage(page) {
page.calendar = {
jump,
switchView,
disableDay,
enableArea,
enableDays,
chooseDateArea,
getCurrentYM,
getSelectedDay,
cancelSelectedDates,
setDateStyle,
setTodoLabels,
getTodoLabels,
deleteTodoLabels,
clearTodoLabels,
setSelectedDays,
getCalendarConfig,
setCalendarConfig,
getCalendarDates
}
}
function setWeekHeader(firstDayOfWeek) {
let weeksCh = ['日', '一', '二', '三', '四', '五', '六']
if (firstDayOfWeek === 'Mon') {
weeksCh = ['一', '二', '三', '四', '五', '六', '日']
}
setData({
'calendar.weeksCh': weeksCh
})
}
function autoSelectDay(defaultDay) {
Component.firstRenderWeekMode = true
if (defaultDay && typeof defaultDay === 'string') {
const day = defaultDay.split('-')
if (day.length < 3) {
return logger.warn('配置 jumpTo 格式应为: 2018-4-2 或 2018-04-02')
}
jump(+day[0], +day[1], +day[2])
} else {
if (!defaultDay) {
Component.config.noDefault = true
setData({
'config.noDefault': true
})
}
jump()
}
}
function init(component, config) {
initialTasks.flag = 'process'
Component = component
Component.config = config
setWeekHeader(config.firstDayOfWeek)
autoSelectDay(config.defaultDay)
logger.tips(
'使用中若遇问题请反馈至 https://github.com/treadpit/wx_calendar/issues ✍'
)
}
export default (component, config = {}) => {
if (initialTasks.flag === 'process') {
return initialTasks.tasks.push(function() {
init(component, config)
})
}
init(component, config)
}

29
components/calendar/theme/iconfont.wxss

@ -0,0 +1,29 @@
@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";
}

56
components/calendar/theme/theme-default.wxss

@ -0,0 +1,56 @@
/* 日历主要颜色相关样式 */
.default_color,
.default_weekend-color,
.default_handle-color,
.default_week-color {
color: #4a4a4a;
}
.default_today {
color: #fff;
background-color: #874fb4;
}
.default_choosed {
color: #fff;
background-color: #146ae7;
}
.default_date-disable {
color: #c7c7c7;
}
.default_prev-month-date,
.default_next-month-date {
color: #e2e2e2;
}
.default_prev-month-date .date,
.default_next-month-date .date {
display: none;
}
.default_normal-date {
color: #88d2ac;
}
.default_todo-circle {
border-color: #88d2ac;
}
.default_todo-dot {
background-color: #e54d42;
}
.default_date-desc {
color: #c2c2c2;
}
.default_date-desc-lunar {
color: #e54d42;
}
.default_date-desc-disable {
color: #e2e2e2;
}

49
components/calendar/theme/theme-elegant.wxss

@ -0,0 +1,49 @@
.elegant_color,
.elegant_weekend-color,
.elegant_handle-color,
.elegant_week-color {
color: #333;
}
.elegant_today {
color: #000;
background-color: #e1e7f5;
}
.elegant_choosed {
color: #000;
background-color: #e2e2e2;
}
.elegant_date-disable {
color: #c7c7c7;
}
.elegant_prev-month-date,
.elegant_next-month-date {
color: #e2e2e2;
}
.elegant_normal-date {
color: #333;
}
.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;
}

1
components/detail-announcement/detail-announcement.wxss

@ -9,7 +9,6 @@
font-size: 30rpx;
line-height: 80rpx;
font-weight: bold;
color: #F69F06;
}
.list-info {

21
components/detail-basis/detail-basis.js

@ -14,7 +14,24 @@ Component({
* 组件的初始数据
*/
data: {
tableData:[{LandPrices:'起拍价',FloorPrice:5800,LandAllPrice:51780}]
tabHDate: ['土地价格', '楼面价', '土地总价', '净利率', '溢价率'], // 标题内容
tabW: ['167', '114', '157', '134', '120'],
rowKey: ['Tprice', 'Lprice', 'AllPrice', 'Interest', 'PremiumRate'],
rowData: [{
Tprice: '起拍价',
Lprice: '5800',
AllPrice: '51780',
Interest: '13.90%',
PremiumRate: '0.25%'
},
{
Tprice: '预测-成交价',
Lprice: '6800',
AllPrice: '62158',
Interest: '9.90%',
PremiumRate: '10.85%'
},
],
},
/**
@ -23,4 +40,4 @@ Component({
methods: {
}
})
})

4
components/detail-basis/detail-basis.json

@ -1,4 +1,6 @@
{
"component": true,
"usingComponents": {}
"usingComponents": {
"table": "/components/table/table"
}
}

12
components/detail-basis/detail-basis.wxml

@ -59,7 +59,7 @@
<input class="form-input input-back" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item">
<view class="form-item col-do">
<text class="form-lable">商务配比:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
@ -75,7 +75,7 @@
<input class="form-input input-back" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item">
<view class="form-item col-do">
<text class="form-lable">销售费率:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
@ -91,10 +91,6 @@
<view class="table-box">
<view class="table-title">测算指标</view>
<view class="table-column">
<view class="table-th">
<view class="table-td"></view>
</view>
<table tabHDate="{{tabHDate}}" tabW="{{tabW}}" rowData="{{rowData}}" rowKey="{{rowKey}}" />
</view>
</view>
</view>

4
components/detail-basis/detail-basis.wxss

@ -37,4 +37,8 @@
.unit {
text-indent: 8rpx;
}
.table-column{
padding: 30rpx 0;
}

22
components/detail-senior/detail-senior.js

@ -1,5 +1,8 @@
// components/detail-senior/detail-senior.js
Component({
options: {
addGlobalClass: true
},
/**
* 组件的属性列表
*/
@ -11,7 +14,24 @@ Component({
* 组件的初始数据
*/
data: {
tabHDate: ['土地价格', '楼面价', '土地总价', '净利率', '溢价率'], // 标题内容
tabW: ['167', '114', '157', '134', '120'],
rowKey: ['Tprice', 'Lprice', 'AllPrice', 'Interest', 'PremiumRate'],
rowData: [{
Tprice: '起拍价',
Lprice: '5800',
AllPrice: '51780',
Interest: '13.90%',
PremiumRate: '0.25%'
},
{
Tprice: '预测-成交价',
Lprice: '6800',
AllPrice: '62158',
Interest: '9.90%',
PremiumRate: '10.85%'
},
],
},
/**

4
components/detail-senior/detail-senior.json

@ -1,4 +1,6 @@
{
"component": true,
"usingComponents": {}
"usingComponents": {
"table": "/components/table/table"
}
}

181
components/detail-senior/detail-senior.wxml

@ -1,2 +1,181 @@
<!--components/detail-senior/detail-senior.wxml-->
<text>components/detail-senior/detail-senior.wxml</text>
<view class="table-box">
<view class="table-title">产品定价</view>
<view class="table-form">
<view class="form-item">
<text class="form-lable">住宅定价:</text>
<input class="form-input input-back" type="number" />
<text class="unit">元/m</text>
</view>
<view class="form-item">
<text class="form-lable">商业定价:</text>
<input class="form-input" type="number" />
<text class="unit">元/m</text>
</view>
<view class="form-item">
<text class="form-lable">商务定价:</text>
<input class="form-input" type="number" />
<text class="unit">元/m</text>
</view>
<view class="form-item">
<text class="form-lable">车位定价:</text>
<input class="form-input" type="number" />
<text class="unit">元/m</text>
</view>
</view>
</view>
<view class="table-box">
<view class="table-title">指标定义</view>
<view class="table-form">
<view class="form-item">
<text class="form-lable">车配配比:</text>
<input class="form-input input-back" type="number" />
<text class="unit">个/100m</text>
</view>
<view class="form-item">
<text class="form-lable">单车指标:</text>
<input class="form-input" type="number" />
<text class="unit">个/m</text>
</view>
<view class="form-item">
<text class="form-lable">车位可售:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item">
<text class="form-lable">单方成本:</text>
<input class="form-input" type="number" />
<text class="unit">元/m</text>
</view>
<view class="form-item">
<text class="form-lable">商业配比:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item col-do">
<text class="form-lable">商务配比:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
</view>
</view>
</view>
<view class="table-box">
<view class="table-title">三费费率</view>
<view class="table-form">
<view class="form-item">
<text class="form-lable">管理费率:</text>
<input class="form-input input-back" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item col-do">
<text class="form-lable">销售费率:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item">
<text class="form-lable">财务费率:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
</view>
</view>
</view>
<view class="table-box">
<view class="table-title">融资</view>
<view class="table-form">
<view class="form-item">
<text class="form-lable">前融比例:</text>
<input class="form-input input-back" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item">
<text class="form-lable">开发贷比例:</text>
<input class="form-input" type="number" />
<text class="unit">个/m</text>
</view>
<view class="form-item">
<text class="form-lable">前融利率:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item col-do">
<text class="form-lable">开发贷利率:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item">
<text class="form-lable">前融周期:</text>
<input class="form-input" type="number" />
<text class="unit">年</text>
</view>
<view class="form-item col-do">
<text class="form-lable">开发贷周期:</text>
<input class="form-input" type="number" />
<text class="unit">年</text>
</view>
</view>
</view>
<view class="table-box">
<view class="table-title">无偿移交</view>
<view class="table-form">
<view class="form-item-row">
<text class="form-lable">住宅计容占比:</text>
<input class="form-input input-back" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item-row">
<text class="form-lable">商业计容占比:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
</view>
<view class="form-item-row">
<text class="form-lable">商务计容占比:</text>
<input class="form-input" type="number" />
<text class="unit">%</text>
</view>
</view>
</view>
<view class="table-box">
<view class="table-title">自持部分</view>
<view class="table-form">
<view class="form-item-row">
<text class="form-lable">住宅计容占比:</text>
<input class="form-input-mini" type="number" />
<text class="unit">%,</text>
<input class="form-input-mini" type="number" />
<text class="unit">可售,可售价格</text>
<input class="form-input" type="number" />
<text class="unit">元/㎡</text>
</view>
<view class="form-item-row">
<text class="form-lable">商业计容占比:</text>
<input class="form-input-mini" type="number" />
<text class="unit">%,</text>
<input class="form-input-mini" type="number" />
<text class="unit">可售,可售价格</text>
<input class="form-input" type="number" />
<text class="unit">元/㎡</text>
</view>
<view class="form-item-row">
<text class="form-lable">商务计容占比:</text>
<input class="form-input-mini" type="number" />
<text class="unit">%, </text>
<input class="form-input-mini" type="number" />
<text class="unit">可售,可售价格 </text>
<input class="form-input" type="number" />
<text class="unit">元/㎡</text>
</view>
</view>
</view>
<view class="table-box">
<view class="table-title">测算指标</view>
<view class="table-column">
<table tabHDate="{{tabHDate}}" tabW="{{tabW}}" rowData="{{rowData}}" rowKey="{{rowKey}}" />
</view>
</view>

64
components/detail-senior/detail-senior.wxss

@ -1 +1,63 @@
/* components/detail-senior/detail-senior.wxss */
/* components/detail-senior/detail-senior.wxss */
.form-item-row {
width: 100%;
height: 50rpx;
display: flex;
align-items: center;
color: #838b99;
}
.table-box {
padding: 20rpx;
min-height: 192rpx;
box-sizing: border-box;
}
.table-title {
line-height: 50rpx;
}
.table-form {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.form-input {
width: 90rpx;
min-height: 34rpx;
height: 34rpx;
background: #FFFFFF;
border: 1px solid #838B99;
border-radius: 4rpx;
text-align: center;
}
.input-back {
background-color: #DEE5F0;
}
.form-item {
display: flex;
align-items: center;
padding-top: 14rpx;
font-size: 26rpx;
color: #838B99;
}
.unit {
text-indent: 8rpx;
}
.table-column {
padding: 30rpx 0;
}
.form-input-mini {
width: 60rpx;
height: 34rpx;
min-height: 34rpx;
border: 2rpx solid #838b99;
border-radius: 4rpx;
text-align: center;
}

40
components/table/table.js

@ -0,0 +1,40 @@
// components/table/table.js
Component({
/**
* 组件的属性列表
*/
properties: {
tabW: {
// 表格每一列的宽度
type: Array,
value: []
},
tabHDate: {
// 标题内容
type: Array,
value: []
},
rowData: {
type: Array, // 表格数据
value: []
},
rowKey: { // row属性
type: Array,
value: []
}
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
}
})

4
components/table/table.json

@ -0,0 +1,4 @@
{
"component": true,
"usingComponents": {}
}

17
components/table/table.wxml

@ -0,0 +1,17 @@
<!--components/table/table.wxml-->
<view class='container'>
<view class="tab-header">
<view class="tab-header-td" wx:for="{{tabHDate}}" wx:key="index" style="width:{{tabW[index]}}rpx">
{{item}}
</view>
</view>
<view>
<view class="tab-row" wx:for="{{rowData}}" wx:key="index">
<view class="tab-row-td" wx:for="{{rowKey}}" wx:key="idx" wx:for-index="idx" wx:for-item="row"
style="width:{{tabW[idx]}}rpx;">
<view>{{item[row]}}</view>
</view>
</view>
<view wx:if="{{rowData.length===0}}" class="no-text">暂无内容</view>
</view>
</view>

51
components/table/table.wxss

@ -0,0 +1,51 @@
/* components/table/table.wxss */
.container{
border: 2rpx solid #838b99;
}
.tab-header,
.tab-row {
width: 100%;
height: 50rpx;
display: flex;
align-items: center;
background: #F4F7FD;
}
.tab-header-td,
.tab-row-td {
height: 100%;
border-right: 2rpx solid #838b99;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
overflow: hidden;
font-size: 24rpx;
color: #838b99;
}
.tab-header-td:last-child,
.tab-row-td:last-child {
border-right: none;
}
.tab-row {
background: #fff;
border-top: 2rpx solid #838b99;
}
.tab-row-td view {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.no-text {
text-align: center;
font-size: 28rpx;
color: #838b99;
margin-top: 20rpx;
}

2
custom-tab-bar/index.js

@ -3,6 +3,7 @@ Component({
selected: 0,
color: "#e2e2e2",
selectedColor: "#000000",
bordImg: "../assets/images/tabIcon/my-bord.png",
list: [{
pagePath: "/pages/calendar/calendar",
iconPath: "../assets/images/tabIcon/calendar.png",
@ -36,6 +37,7 @@ Component({
switchTab(e) {
const data = e.currentTarget.dataset
const url = data.path
console.log(data)
wx.switchTab({url})
this.setData({
selected: data.index

27
custom-tab-bar/index.wxml

@ -1,14 +1,15 @@
<!--miniprogram/custom-tab-bar/index.wxml-->
<view class="tab-box">
<image class="tab-bord" src="../assets/images/tabIcon/my-bord.png"></image>
<view class="tab-bar">
<view wx:for="{{list}}" wx:key="index" class="tab-bar-item" data-path="{{item.pagePath}}" data-index="{{index}}"
bindtap="switchTab">
<image src="{{selected === index ? item.selectedIconPath : item.iconPath}}" wx:if="{{item.text!=='首页'}}">
</image>
<image class="tab-index" src="{{item.selectedIconPath}}" wx:else></image>
<view class="tab-title" style="color: {{selected === index ? selectedColor : color}}" wx:if="{{item.text!=='首页'}}">
{{item.text}}</view>
</view>
</view>
</view>
<cover-view class="tab-box">
<cover-image class="tab-bord" src="{{bordImg}}"></cover-image>
<cover-view class="tab-bar">
<cover-view wx:for="{{list}}" wx:key="index" class="tab-bar-item" data-path="{{item.pagePath}}"
data-index="{{index}}" bindtap="switchTab">
<cover-image class="tab-index" src="{{item.selectedIconPath}}" wx:if="{{item.text==='首页'}}"></cover-image>
<cover-image src="{{selected === index ? item.selectedIconPath : item.iconPath}}" wx:else>
</cover-image>
<cover-view class="tab-title" style="color: {{selected === index ? selectedColor : color}}"
wx:if="{{item.text!=='首页'}}">
{{item.text}}</cover-view>
</cover-view>
</cover-view>
</cover-view>

11
custom-tab-bar/index.wxss

@ -1,9 +1,10 @@
.tab-box{
position: relative;
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 166rpx;
z-index: 99;
}
.tab-bar {
display: flex;
@ -12,8 +13,7 @@
left: 0;
bottom: 0;
width: 100%;
background-color: #fff;
height: 120rpx;
height: 144rpx;
z-index: 2;
}
@ -33,7 +33,7 @@
flex-direction: column;
}
.tab-bar-item image {
.tab-bar-item cover-image {
width: 35rpx;
height: 35rpx;
}
@ -47,5 +47,6 @@
.tab-title{
font-size: 22rpx;
line-height: 72rpx;
line-height: 48rpx;
padding-bottom: 14rpx;
}

6
pages/calculation/calculation.js

@ -34,6 +34,12 @@ Page({
})
},
comeDetail(){
wx.navigateTo({
url: '/pages/look-detail/look-detail?active=4',
})
},
tabDowm(e) {
let active = e.currentTarget.dataset.id
if (active === this.data.active) {

49
pages/calendar/calendar.js

@ -101,6 +101,12 @@ Page({
})
}
},
// 跳转
navigate(){
wx.navigateTo({
url: '/pages/look-detail/look-detail',
})
},
/**
* 生命周期函数--监听页面加载
@ -113,13 +119,6 @@ Page({
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
@ -132,41 +131,7 @@ Page({
}
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
},
// 日历点击跳转(请求接口获取列表数据)
onCalendarDayTap(res) {
let timer = res.detail;
timer = `${timer.year}/${formatNumber(timer.month)}/${formatNumber(timer.day)}`

3
pages/calendar/calendar.json

@ -1,6 +1,7 @@
{
"usingComponents": {
"mp-navigation-bar": "weui-miniprogram/navigation-bar/navigation-bar",
"ui-calendar": "../../components/ui-calendar/ui-calendar"
"ui-calendar": "../../components/ui-calendar/ui-calendar",
"calendar":"/components/calendar/index"
}
}

21
pages/calendar/calendar.wxml

@ -25,21 +25,11 @@
</view>
<view class="cal-box">
<image class="cal-back" src="../../assets/images/cal-back.png"></image>
<view class="calendar">
<view class="timer flex-center">
<text class="back-now" bindtap="backToday">回到今天</text>
<view class="t-box flex-center">
<picker mode="date" value="{{calendarDisplayTime}}" fields="month" start="1970-01"
bindchange="bindDateChange">
<view class="p-time">{{calendarDisplayTime}}</view>
</picker>
<view class="year">{{tools.setTime(calendarDisplayTime, 'year')}}年</view>
<view class="month">{{tools.setTime(calendarDisplayTime, 'month')}}月</view>
</view>
</view>
<ui-calendar ex-class="calendar-cm-month" bindonDayTap="onCalendarDayTap"
<view class="calendar-box">
<calendar />
<!-- <ui-calendar ex-class="calendar-cm-month" bindonDayTap="onCalendarDayTap"
displayTime="{{calendarDisplayTime}}" selectedDate="{{calendarSelectedDate}}"
displayMonthNum="{{calendarDisplayMonthNum}}" is-show="{{isCalendarShow}}"></ui-calendar>
displayMonthNum="{{calendarDisplayMonthNum}}" is-show="{{isCalendarShow}}"></ui-calendar> -->
</view>
</view>
</view>
@ -52,7 +42,8 @@
</view>
<!-- 展示部分 -->
<view class="list">
<view class="item one-title" wx:key="id" wx:for="{{info}}" wx:for-index="id" wx:for-item="item">
<view class="item one-title" wx:key="id" wx:for="{{info}}" wx:for-index="id" wx:for-item="item"
bindtap="navigate">
{{item.name}}
</view>
</view>

15
pages/calendar/calendar.wxss

@ -20,25 +20,28 @@
.cal-box {
margin-top: 16rpx;
width: 100%;
height: 860rpx;
height: 760rpx;
position: relative;
}
.cal-back {
width: 100%;
height: 860rpx;
height: 760rpx;
position: absolute;
z-index: 1;
left: 0;
top: 0;
}
.calendar {
.calendar-box {
position: absolute;
z-index: 2;
left: 30rpx;
top: 80rpx;
width: 684rpx;
display: flex;
flex-direction: column;
height: 700rpx;
}
.timer {
@ -133,4 +136,10 @@
.active .tab-tag {
display: block;
}
.calendar-info{
flex: 1;
width: 100%;
display: flex;
}

8
pages/feasibility-study/feasibility-study.js

@ -127,5 +127,11 @@ Page({
refresher: false
})
}, 200)
}
},
// 跳转
navigate(){
wx.navigateTo({
url: '/pages/air-report/air-report',
})
},
})

2
pages/feasibility-study/feasibility-study.wxml

@ -15,7 +15,7 @@
<view class="main">
<scroll-view class="list" scroll-y="true" refresher-enabled refresher-triggered="{{refresher}}"
bindscrolltolower="getList" bindrefresherrefresh="refresh">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item" bindtap="navigate">
<image class="list-img"
src="https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/cb8065380cd791230f4870a5ac345982b3b780b3.jpg">
</image>

19
pages/index/index.js

@ -50,6 +50,17 @@ Page({
onReady() {
this.refresh()
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
if (typeof this.getTabBar === 'function' &&
this.getTabBar()) {
this.getTabBar().setData({
selected: 2
})
}
},
getList() {
let list = this.data.list.concat(this.data.list);
this.setData({
@ -94,5 +105,11 @@ Page({
wx.navigateTo({
url
})
}
},
// 跳转
navigate(){
wx.navigateTo({
url: '/pages/air-report/air-report',
})
},
})

2
pages/index/index.wxml

@ -57,7 +57,7 @@
<view class="list-box">
<scroll-view class="list" scroll-y="true" refresher-enabled refresher-triggered="{{refresher}}"
bindscrolltolower="getList" bindrefresherrefresh="refresh">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item" bindtap="comeDetail" data-id="1">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item" bindtap="comeDetail" data-id="1" bindtap="navigate">
<image class="item-img"
src="https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/cb8065380cd791230f4870a5ac345982b3b780b3.jpg">
</image>

8
pages/land-promotion/land-promotion.js

@ -127,5 +127,11 @@ Page({
refresher: false
})
}, 200)
}
},
// 跳转
navigate(){
wx.navigateTo({
url: '/pages/air-report/air-report',
})
},
})

2
pages/land-promotion/land-promotion.wxml

@ -8,7 +8,7 @@
<view class="main">
<scroll-view class="list" scroll-y="true" refresher-enabled refresher-triggered="{{refresher}}"
bindscrolltolower="getList" bindrefresherrefresh="refresh">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item" bindtap="navigate">
<image class="list-img"
src="https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/cb8065380cd791230f4870a5ac345982b3b780b3.jpg">
</image>

131
pages/look-detail/look-detail.js

@ -6,11 +6,26 @@ Page({
*/
data: {
state: true,
tabList: [{id:1,name:'公告信息'},{id:2,name:'成交信息'},{id:3,name:'呈现项目'}],
sedTabList: [{id:4,name:'基础测算'},{id:5,name:'高级测算'}],
tabList: [{
id: 1,
name: '公告信息'
}, {
id: 2,
name: '成交信息'
}, {
id: 3,
name: '呈现项目'
}],
sedTabList: [{
id: 4,
name: '基础测算'
}, {
id: 5,
name: '高级测算'
}],
active: 1,
markShow: false,
annoutInfo:{},
annoutInfo: {},
clinchInfo: {
list: [{
lable: '是否成交',
@ -55,82 +70,114 @@ Page({
],
message: []
},
presentInfo:{
detail:[{
presentInfo: {
detail: [{
lable: '项目状态',
info: '在售'
},{
}, {
lable: '楼盘名称',
info: '海纳九龙'
},{
}, {
lable: '项目公司',
info: '重庆筑品房地产开发有限公司'
},{
}, {
lable: '经营企业',
info: '融信34 + 金科35 + 荣安33'
},{
}, {
lable: '首开时间',
info: '2021/02/01'
}],
list:[{
list: [{
lable: '合计预售',
info: '120套'
},{
}, {
lable: '去化',
info: '37套'
},{
}, {
lable: '去化率',
info: '56%'
},{
}, {
lable: '预售住宅均价',
info: '10000元/m'
},{
}, {
lable: '预售商业均价',
info: '12000元/m'
}],
more:[{
msg:'2021XXX号',
booking:'72/34/56%',
timer:'2020/01/02'
},
{
msg:'2021XXX号',
booking:'48/34/46%',
timer:'2020/01/02'
}]
more: [{
msg: '2021XXX号',
booking: '72/34/56%',
timer: '2020/01/02'
},
{
msg: '2021XXX号',
booking: '48/34/46%',
timer: '2020/01/02'
}
]
},
basisInfo:{},
seniorInfo:{},
basisInfo: {},
seniorInfo: {},
},
setMark(e){
let {markShow} = this.data
if(markShow){
setMark(e) {
let {
markShow
} = this.data
if (markShow) {
let active = Number(e.currentTarget.dataset.id)
this.setData({state:false,markShow:false,active})
}else{
this.setData({markShow:true})
this.setData({
state: false,
markShow: false,
active
})
} else {
this.setData({
markShow: true
})
}
},
tabDowm(e){
tabDowm(e) {
let active = Number(e.currentTarget.dataset.id)
if(active!==this.data.active){
this.setData({active})
if (active !== this.data.active) {
this.setData({
active
})
}
},
comeBack(){
comeBack() {
wx.navigateBack({
delta: 1
})
},
markHide() {
this.setData({
markShow: false
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log(options)
let active = options.active;
if (active) {
active = Number(active);
console.log(active)
if (active > 3) {
this.setData({
state: false,
active
})
} else {
this.setData({
active
})
}
}
},
/**
@ -145,10 +192,10 @@ Page({
*/
onShow: function () {
if (typeof this.getTabBar === 'function' &&
this.getTabBar()) {
this.getTabBar().setData({
selected: 1
})
}
this.getTabBar()) {
this.getTabBar().setData({
selected: 1
})
}
},
})

7
pages/look-detail/look-detail.wxml

@ -87,8 +87,13 @@
<detail-present info="{{presentInfo}}" wx:if="{{active===3}}"/>
<detail-basis info="{{basisInfo}}" wx:if="{{active===4}}"/>
<detail-senior info="{{seniorInfo}}" wx:if="{{active===5}}"/>
<view class="btn-box" wx:if="{{active>3}}">
<button class="btn btn-warning">重做</button>
<button class="btn btn-primy">保存</button>
<button class="btn btn-primy">提交</button>
</view>
</view>
<view class="mark" wx:if="{{markShow}}" bindtap="setMark">
<view class="mark" wx:if="{{markShow}}" bindtap="markHide">
<view class="carBtn center" catchtap="setMark" data-id="4">基础测算</view>
<view class="hevyBtn" catchtap="setMark" data-id="5">
<text class="hevy-text">高级测算</text>

46
pages/look-detail/look-detail.wxss

@ -35,7 +35,7 @@
.active .tab-title {
font-size: 34rpx;
color: #262936;
color: #146ae7;
}
.active .tab-tag {
@ -113,7 +113,7 @@
.carBtn {
width: 514rpx;
height: 85rpx;
background: linear-gradient(171deg, #FFBF15, #F69F06);
background: linear-gradient(171deg,#3d7dfc 0%, #0e63df 100%);
border-radius: 43rpx;
font-size: 32rpx;
color: #FFFFFF;
@ -122,7 +122,7 @@
.hevyBtn {
width: 514rpx;
height: 85rpx;
background: linear-gradient(171deg, #262936, #48494E);
background: linear-gradient(171deg, #FFBF15, #F69F06);
border-radius: 43rpx;
margin-top: 36rpx;
margin-bottom: 304rpx;
@ -140,4 +140,44 @@
.hevy-lable {
font-size: 22rpx;
color: rgba(255, 255, 255, .4);
}
.table .table-item {
border-bottom: 1px solid #E1E1E1;
}
.table .table-item:last-of-type {
border-bottom: none;
}
.btn-box {
padding: 50rpx 80rpx;
width: 100%;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
}
.btn {
display: flex;
align-items: center;
justify-content: center;
width: 182rpx !important;
height: 62rpx;
font-size: 28rpx;
border-radius: 30rpx;
color: #fff;
}
.btn-warning {
background: linear-gradient(171deg, #ffc27a 0%, #f1a142 100%);
}
.btn-primy {
background: linear-gradient(171deg, #3d7dfc 0%, #0e63df 100%);
}
.col-do{
padding-right: 36rpx;
}

8
pages/periodic-report/periodic-report.js

@ -124,5 +124,11 @@ Page({
refresher: false
})
}, 200)
}
},
// 跳转
navigate(){
wx.navigateTo({
url: '/pages/air-report/air-report',
})
},
})

2
pages/periodic-report/periodic-report.wxml

@ -11,7 +11,7 @@
<view class="main">
<scroll-view class="list" scroll-y="true" refresher-enabled refresher-triggered="{{refresher}}"
bindscrolltolower="getList" bindrefresherrefresh="refresh">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item" bindtap="navigate">
<image class="list-img"
src="https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/cb8065380cd791230f4870a5ac345982b3b780b3.jpg">
</image>

8
pages/special-research/special-research.js

@ -127,5 +127,11 @@ Page({
refresher: false
})
}, 200)
}
},
// 跳转
navigate(){
wx.navigateTo({
url: '/pages/air-report/air-report',
})
},
})

2
pages/special-research/special-research.wxml

@ -8,7 +8,7 @@
<view class="main">
<scroll-view class="list" scroll-y="true" refresher-enabled refresher-triggered="{{refresher}}"
bindscrolltolower="getList" bindrefresherrefresh="refresh">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item">
<view class="list-item" wx:for="{{list}}" wx:for-index="i" wx:for-item="item" bindtap="navigate">
<image class="list-img"
src="https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/cb8065380cd791230f4870a5ac345982b3b780b3.jpg">
</image>

Loading…
Cancel
Save