Compare commits
No commits in common. 'dev' and 'master' have entirely different histories.
1059 changed files with 567 additions and 52389 deletions
@ -1,28 +1,35 @@ |
|||||||
{ |
{ |
||||||
"$schema": "http://json.schemastore.org/prettierrc", |
"$schema": "https://json.schemastore.org/prettierrc.json", |
||||||
"printWidth": 120, |
"printWidth": 120, |
||||||
"tabWidth": 2, |
"tabWidth": 2, |
||||||
"useTabs": false, |
"useTabs": false, |
||||||
"semi": false, |
"semi": true, |
||||||
"singleQuote": true, |
"singleQuote": true, |
||||||
"bracketSpacing": true, |
"bracketSpacing": true, |
||||||
"trailingComma": "all", |
"trailingComma": "all", |
||||||
"arrowParens": "always", |
"arrowParens": "always", |
||||||
"endOfLine": "lf", |
"endOfLine": "auto", |
||||||
"htmlWhitespaceSensitivity": "ignore", |
"htmlWhitespaceSensitivity": "ignore", |
||||||
"singleAttributePerLine": false, |
"singleAttributePerLine": false, |
||||||
|
"jsxSingleQuote": true, |
||||||
"overrides": [ |
"overrides": [ |
||||||
{ |
{ |
||||||
"files": "*.wxml", |
"files": "*.wxml", |
||||||
"options": { "parser": "html" } |
"options": { |
||||||
|
"parser": "html" |
||||||
|
} |
||||||
}, |
}, |
||||||
{ |
{ |
||||||
"files": "*.wxss", |
"files": "*.wxss", |
||||||
"options": { "parser": "css" } |
"options": { |
||||||
|
"parser": "css" |
||||||
|
} |
||||||
}, |
}, |
||||||
{ |
{ |
||||||
"files": "*.wxs", |
"files": "*.wxs", |
||||||
"options": { "parser": "babel" } |
"options": { |
||||||
|
"parser": "babel" |
||||||
|
} |
||||||
} |
} |
||||||
] |
] |
||||||
} |
} |
||||||
|
@ -1,7 +0,0 @@ |
|||||||
{ |
|
||||||
"version": 1.1, |
|
||||||
"properties": [{ "name": "foo", "description": "Foo property" }], |
|
||||||
"atDirectives": [{ "name": "@foo", "description": "Foo at directive" }], |
|
||||||
"pseudoClasses": [{ "name": ":foo", "description": "Foo pseudo class" }], |
|
||||||
"pseudoElements": [{ "name": "::foo", "description": "Foo pseudo elements" }] |
|
||||||
} |
|
@ -1,3 +1,3 @@ |
|||||||
{ |
{ |
||||||
"usingComponents": {} |
"usingComponents": {} |
||||||
} |
} |
@ -1,73 +1,75 @@ |
|||||||
{ |
{ |
||||||
"description": "项目配置文件", |
"description": "项目配置文件", |
||||||
"miniprogramRoot": "src/", |
"miniprogramRoot": "src/", |
||||||
"compileType": "miniprogram", |
"compileType": "miniprogram", |
||||||
"setting": { |
"setting": { |
||||||
"useCompilerPlugins": ["typescript", "sass"], |
"useCompilerPlugins": [ |
||||||
"babelSetting": { |
"typescript", |
||||||
"ignore": [], |
"sass" |
||||||
"disablePlugins": [], |
], |
||||||
"outputPath": "" |
"babelSetting": { |
||||||
}, |
"ignore": [], |
||||||
"coverView": false, |
"disablePlugins": [], |
||||||
"postcss": false, |
"outputPath": "" |
||||||
"minified": false, |
}, |
||||||
"enhance": true, |
"coverView": false, |
||||||
"showShadowRootInWxmlPanel": false, |
"postcss": false, |
||||||
"packNpmManually": true, |
"minified": false, |
||||||
"packNpmRelationList": [ |
"enhance": true, |
||||||
{ |
"showShadowRootInWxmlPanel": false, |
||||||
"packageJsonPath": "package.json", |
"packNpmManually": true, |
||||||
"miniprogramNpmDistDir": "./src" |
"packNpmRelationList": [ |
||||||
} |
{ |
||||||
], |
"packageJsonPath": "package.json", |
||||||
"ignoreUploadUnusedFiles": true, |
"miniprogramNpmDistDir": "./src" |
||||||
"compileHotReLoad": false, |
} |
||||||
"skylineRenderEnable": true, |
], |
||||||
"es6": true, |
"ignoreUploadUnusedFiles": true, |
||||||
"compileWorklet": false, |
"compileHotReLoad": false, |
||||||
"uglifyFileName": false, |
"skylineRenderEnable": true, |
||||||
"uploadWithSourceMap": true, |
"es6": true, |
||||||
"minifyWXSS": true, |
"compileWorklet": false, |
||||||
"minifyWXML": true, |
"uglifyFileName": false, |
||||||
"localPlugins": false, |
"uploadWithSourceMap": true, |
||||||
"disableUseStrict": false, |
"minifyWXSS": true, |
||||||
"condition": false, |
"minifyWXML": true, |
||||||
"swc": false, |
"localPlugins": false, |
||||||
"disableSWC": true |
"disableUseStrict": false, |
||||||
}, |
"condition": false, |
||||||
"simulatorType": "wechat", |
"swc": false, |
||||||
"simulatorPluginLibVersion": {}, |
"disableSWC": true |
||||||
"condition": {}, |
}, |
||||||
"srcMiniprogramRoot": "src/", |
"simulatorType": "wechat", |
||||||
"editorSetting": { |
"simulatorPluginLibVersion": {}, |
||||||
"tabIndent": "insertSpaces", |
"condition": {}, |
||||||
"tabSize": 2 |
"srcMiniprogramRoot": "src/", |
||||||
}, |
"editorSetting": { |
||||||
"libVersion": "3.7.7", |
"tabIndent": "insertSpaces", |
||||||
"ignore": [], |
"tabSize": 2 |
||||||
"packOptions": { |
}, |
||||||
"ignore": [ |
"libVersion": "3.7.7", |
||||||
{ |
"ignore": [], |
||||||
"value": "/images/*.*", |
"packOptions": { |
||||||
"type": "glob" |
"ignore": [ |
||||||
}, |
{ |
||||||
{ |
"value": "/images/*.*", |
||||||
"value": "/images/**/*.*", |
"type": "glob" |
||||||
"type": "glob" |
}, |
||||||
}, |
{ |
||||||
{ |
"value": "/images/**/*.*", |
||||||
"value": "/images/**/**/*.*", |
"type": "glob" |
||||||
"type": "glob" |
}, |
||||||
} |
{ |
||||||
], |
"value": "/images/**/**/*.*", |
||||||
"include": [ |
"type": "glob" |
||||||
{ |
} |
||||||
"value": "/images/tabbar/*.*", |
], |
||||||
"type": "glob" |
"include": [ |
||||||
} |
{ |
||||||
] |
"value": "/images/tabbar/*.*", |
||||||
}, |
"type": "glob" |
||||||
"appid": "wxf9ce8010f1ad24aa" |
} |
||||||
} |
] |
||||||
|
}, |
||||||
|
"appid": "wx71ac9c27c3c3e3f4" |
||||||
|
} |
@ -1,144 +0,0 @@ |
|||||||
import { dateUtil, getCalendarConfig } from './utils/index' |
|
||||||
|
|
||||||
/** |
|
||||||
* 计算当前月份前后两月应占的格子 |
|
||||||
* @param {number} year 年份 |
|
||||||
* @param {number} month 月份 |
|
||||||
*/ |
|
||||||
function calculateEmptyGrids(year, month, config) { |
|
||||||
const prevMonthGrids = calculatePrevMonthGrids(year, month, config) |
|
||||||
const nextMonthGrids = calculateNextMonthGrids(year, month, config) |
|
||||||
return { |
|
||||||
prevMonthGrids, |
|
||||||
nextMonthGrids |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 计算上月应占的格子 |
|
||||||
* @param {number} year 年份 |
|
||||||
* @param {number} month 月份 |
|
||||||
*/ |
|
||||||
function calculatePrevMonthGrids(year, month, config) { |
|
||||||
let emptyGrids = [] |
|
||||||
const prevMonthDays = dateUtil.getDatesCountOfMonth(year, month - 1) |
|
||||||
let firstDayOfWeek = dateUtil.firstDayOfWeek(year, month) |
|
||||||
if (config.firstDayOfWeek === 'Mon') { |
|
||||||
if (firstDayOfWeek === 0) { |
|
||||||
firstDayOfWeek = 6 |
|
||||||
} else { |
|
||||||
firstDayOfWeek -= 1 |
|
||||||
} |
|
||||||
} |
|
||||||
if (firstDayOfWeek > 0) { |
|
||||||
const len = prevMonthDays - firstDayOfWeek |
|
||||||
const { onlyShowCurrentMonth } = config |
|
||||||
const YMInfo = dateUtil.getPrevMonthInfo({ year, month }) |
|
||||||
for (let i = prevMonthDays; i > len; i--) { |
|
||||||
if (onlyShowCurrentMonth) { |
|
||||||
emptyGrids.push('') |
|
||||||
} else { |
|
||||||
const week = dateUtil.getDayOfWeek(+year, +month, i) |
|
||||||
emptyGrids.push({ |
|
||||||
...YMInfo, |
|
||||||
date: i, |
|
||||||
week |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
emptyGrids.reverse() |
|
||||||
} |
|
||||||
return emptyGrids |
|
||||||
} |
|
||||||
/** |
|
||||||
* 计算下一月日期是否需要多展示的日期 |
|
||||||
* 某些月份日期为5排,某些月份6排,统一为6排 |
|
||||||
* @param {number} year |
|
||||||
* @param {number} month |
|
||||||
* @param {object} config |
|
||||||
*/ |
|
||||||
function calculateExtraEmptyDate(year, month, config) { |
|
||||||
let extDate = 0 |
|
||||||
if (+month === 2) { |
|
||||||
extDate += 7 |
|
||||||
let firstDayofMonth = dateUtil.getDayOfWeek(year, month, 1) |
|
||||||
if (config.firstDayOfWeek === 'Mon') { |
|
||||||
if (+firstDayofMonth === 1) extDate += 7 |
|
||||||
} else { |
|
||||||
if (+firstDayofMonth === 0) extDate += 7 |
|
||||||
} |
|
||||||
} else { |
|
||||||
let firstDayofMonth = dateUtil.getDayOfWeek(year, month, 1) |
|
||||||
if (config.firstDayOfWeek === 'Mon') { |
|
||||||
if (firstDayofMonth !== 0 && firstDayofMonth < 6) { |
|
||||||
extDate += 7 |
|
||||||
} |
|
||||||
} else { |
|
||||||
if (firstDayofMonth <= 5) { |
|
||||||
extDate += 7 |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return extDate |
|
||||||
} |
|
||||||
/** |
|
||||||
* 计算下月应占的格子 |
|
||||||
* @param {number} year 年份 |
|
||||||
* @param {number} month 月份 |
|
||||||
*/ |
|
||||||
function calculateNextMonthGrids(year, month, config) { |
|
||||||
let emptyGrids = [] |
|
||||||
const datesCount = dateUtil.getDatesCountOfMonth(year, month) |
|
||||||
let lastDayWeek = dateUtil.getDayOfWeek(year, month, datesCount) |
|
||||||
if (config.firstDayOfWeek === 'Mon') { |
|
||||||
if (lastDayWeek === 0) { |
|
||||||
lastDayWeek = 6 |
|
||||||
} else { |
|
||||||
lastDayWeek -= 1 |
|
||||||
} |
|
||||||
} |
|
||||||
let len = 7 - (lastDayWeek + 1) |
|
||||||
const { onlyShowCurrentMonth } = config |
|
||||||
if (!onlyShowCurrentMonth) { |
|
||||||
len = len + calculateExtraEmptyDate(year, month, config) |
|
||||||
} |
|
||||||
const YMInfo = dateUtil.getNextMonthInfo({ year, month }) |
|
||||||
for (let i = 1; i <= len; i++) { |
|
||||||
const week = dateUtil.getDayOfWeek(+year, +month, i) |
|
||||||
if (onlyShowCurrentMonth) { |
|
||||||
emptyGrids.push('') |
|
||||||
} else { |
|
||||||
emptyGrids.push({ |
|
||||||
id: i - 1, |
|
||||||
...YMInfo, |
|
||||||
date: i, |
|
||||||
week: week || 7 |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
return emptyGrids |
|
||||||
} |
|
||||||
/** |
|
||||||
* 设置日历面板数据 |
|
||||||
* @param {number} year 年份 |
|
||||||
* @param {number} month 月份 |
|
||||||
* @param {number} curDate 日期 |
|
||||||
*/ |
|
||||||
function calculateCurrentMonthDates(year, month) { |
|
||||||
return dateUtil.calcDates(year, month) |
|
||||||
} |
|
||||||
|
|
||||||
export function calcJumpData({ dateInfo, config, component }) { |
|
||||||
dateInfo = dateInfo || dateUtil.todayFMD() |
|
||||||
const { year, month, date } = dateInfo |
|
||||||
const calendarConfig = config || getCalendarConfig(component) |
|
||||||
const emptyGrids = calculateEmptyGrids(year, month, calendarConfig) |
|
||||||
const calendar = { |
|
||||||
curYear: year, |
|
||||||
curMonth: month, |
|
||||||
curDate: date, |
|
||||||
dates: calculateCurrentMonthDates(year, month), |
|
||||||
...emptyGrids |
|
||||||
} |
|
||||||
return calendar |
|
||||||
} |
|
@ -1,12 +0,0 @@ |
|||||||
import { dateUtil } from './utils/index' |
|
||||||
|
|
||||||
export function calcTargetYMInfo() { |
|
||||||
return { |
|
||||||
right: dateUtil.getPrevMonthInfo, |
|
||||||
left: dateUtil.getNextMonthInfo, |
|
||||||
prev_month: dateUtil.getPrevMonthInfo, |
|
||||||
next_month: dateUtil.getNextMonthInfo, |
|
||||||
prev_year: dateUtil.getPrevYearInfo, |
|
||||||
next_year: dateUtil.getNextYearInfo |
|
||||||
} |
|
||||||
} |
|
@ -1,258 +0,0 @@ |
|||||||
import plugins from './plugins/index' |
|
||||||
import { calcJumpData } from './core' |
|
||||||
import { renderCalendar } from './render' |
|
||||||
import { calcTargetYMInfo } from './helper' |
|
||||||
import { dateUtil, calendarGesture, logger } from './utils/index' |
|
||||||
|
|
||||||
Component({ |
|
||||||
options: { |
|
||||||
styleIsolation: 'apply-shared', |
|
||||||
multipleSlots: true // 在组件定义时的选项中启用多slot支持
|
|
||||||
}, |
|
||||||
properties: { |
|
||||||
config: { |
|
||||||
type: Object, |
|
||||||
value: {} |
|
||||||
} |
|
||||||
}, |
|
||||||
lifetimes: { |
|
||||||
attached: function() { |
|
||||||
this.initComp() |
|
||||||
} |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
initComp() { |
|
||||||
const calendarConfig = this.setDefaultDisableDate() |
|
||||||
this.setConfig(calendarConfig) |
|
||||||
}, |
|
||||||
// 禁用某天日期配置默认为今天
|
|
||||||
setDefaultDisableDate() { |
|
||||||
const calendarConfig = this.properties.config || {} |
|
||||||
if (calendarConfig.disableMode && !calendarConfig.disableMode.date) { |
|
||||||
calendarConfig.disableMode.date = dateUtil.toTimeStr( |
|
||||||
dateUtil.todayFMD() |
|
||||||
) |
|
||||||
} |
|
||||||
return calendarConfig |
|
||||||
}, |
|
||||||
initCalendar(config) { |
|
||||||
const { defaultDate } = config |
|
||||||
let date = dateUtil.todayFMD() |
|
||||||
if (defaultDate && typeof defaultDate === 'string') { |
|
||||||
const dateInfo = defaultDate.split('-') |
|
||||||
if (dateInfo.length < 3) { |
|
||||||
return logger.warn('defaultDate配置格式应为: 2018-4-2 或 2018-04-02') |
|
||||||
} else { |
|
||||||
date = { |
|
||||||
year: +dateInfo[0], |
|
||||||
month: +dateInfo[1], |
|
||||||
date: +dateInfo[2] |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
const waitRenderData = calcJumpData({ |
|
||||||
dateInfo: date, |
|
||||||
config |
|
||||||
}) |
|
||||||
const timestamp = dateUtil.todayTimestamp() |
|
||||||
if (config.autoChoosedWhenJump) { |
|
||||||
const target = waitRenderData.dates.filter( |
|
||||||
item => dateUtil.toTimeStr(item) === dateUtil.toTimeStr(date) |
|
||||||
) |
|
||||||
if (target && target.length) { |
|
||||||
if (!waitRenderData.selectedDates) { |
|
||||||
waitRenderData.selectedDates = target |
|
||||||
} else { |
|
||||||
waitRenderData.selectedDates.push(target[0]) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return { |
|
||||||
...waitRenderData, |
|
||||||
todayTimestamp: timestamp, |
|
||||||
weeksCh: dateUtil.getWeekHeader(config.firstDayOfWeek) |
|
||||||
} |
|
||||||
}, |
|
||||||
setConfig(config) { |
|
||||||
if (config.markToday && typeof config.markToday === 'string') { |
|
||||||
config.highlightToday = true |
|
||||||
} |
|
||||||
config.theme = config.theme || 'default' |
|
||||||
this.setData( |
|
||||||
{ |
|
||||||
config |
|
||||||
}, |
|
||||||
() => { |
|
||||||
for (let plugin of plugins.installed) { |
|
||||||
const [, p] = plugin |
|
||||||
if (typeof p.install === 'function') { |
|
||||||
p.install(this) |
|
||||||
} |
|
||||||
if (typeof p.methods === 'function') { |
|
||||||
const methods = p.methods(this) |
|
||||||
for (let fnName in methods) { |
|
||||||
if (fnName.startsWith('__')) continue |
|
||||||
const fn = methods[fnName] |
|
||||||
if (typeof fn === 'function') { |
|
||||||
if (!this.calendar) this.calendar = {} |
|
||||||
this.calendar[fnName] = fn |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
const initData = this.initCalendar(config) |
|
||||||
renderCalendar.call(this, initData, config) |
|
||||||
} |
|
||||||
) |
|
||||||
}, |
|
||||||
tapDate(e) { |
|
||||||
const { info } = e.currentTarget.dataset |
|
||||||
const { date, disable } = info || {} |
|
||||||
if (disable || !date) return |
|
||||||
const { calendar, config } = this.data |
|
||||||
let calendarData = calendar |
|
||||||
let calendarConfig = config |
|
||||||
if (config.takeoverTap) { |
|
||||||
return this.triggerEvent('takeoverTap', info) |
|
||||||
} |
|
||||||
for (let plugin of plugins.installed) { |
|
||||||
const [, p] = plugin |
|
||||||
if (typeof p.onTapDate === 'function') { |
|
||||||
const { |
|
||||||
calendarData: __calendarData, |
|
||||||
calendarConfig: __calendarConfig |
|
||||||
} = p.onTapDate(info, calendarData, calendarConfig) |
|
||||||
calendarData = __calendarData |
|
||||||
calendarConfig = __calendarConfig |
|
||||||
} |
|
||||||
} |
|
||||||
renderCalendar.call(this, calendarData, calendarConfig).then(() => { |
|
||||||
this.triggerEvent('afterTapDate', info) |
|
||||||
}) |
|
||||||
}, |
|
||||||
/** |
|
||||||
* 日历滑动开始 |
|
||||||
* @param {object} e |
|
||||||
*/ |
|
||||||
calendarTouchstart(e) { |
|
||||||
const t = e.touches[0] |
|
||||||
const startX = t.clientX |
|
||||||
const startY = t.clientY |
|
||||||
this.swipeLock = true |
|
||||||
this.setData({ |
|
||||||
'gesture.startX': startX, |
|
||||||
'gesture.startY': startY |
|
||||||
}) |
|
||||||
}, |
|
||||||
/** |
|
||||||
* 日历滑动中 |
|
||||||
* @param {object} e |
|
||||||
*/ |
|
||||||
calendarTouchmove(e) { |
|
||||||
const { gesture } = this.data |
|
||||||
const { preventSwipe } = this.properties.config |
|
||||||
if (!this.swipeLock || preventSwipe) return |
|
||||||
if (calendarGesture.isLeft(gesture, e.touches[0])) { |
|
||||||
this.handleSwipe('left') |
|
||||||
this.swipeLock = false |
|
||||||
} |
|
||||||
if (calendarGesture.isRight(gesture, e.touches[0])) { |
|
||||||
this.handleSwipe('right') |
|
||||||
this.swipeLock = false |
|
||||||
} |
|
||||||
}, |
|
||||||
calendarTouchend(e) { |
|
||||||
this.setData({ |
|
||||||
'calendar.leftSwipe': 0, |
|
||||||
'calendar.rightSwipe': 0 |
|
||||||
}) |
|
||||||
}, |
|
||||||
handleSwipe(direction) { |
|
||||||
let swipeKey = 'calendar.leftSwipe' |
|
||||||
if (direction === 'right') { |
|
||||||
swipeKey = 'calendar.rightSwipe' |
|
||||||
} |
|
||||||
this.setData({ |
|
||||||
[swipeKey]: 1 |
|
||||||
}) |
|
||||||
const { calendar } = this.data |
|
||||||
let calendarData = calendar |
|
||||||
const { curYear, curMonth } = calendarData |
|
||||||
const getMonthInfo = calcTargetYMInfo()[direction] |
|
||||||
const target = getMonthInfo({ |
|
||||||
year: +curYear, |
|
||||||
month: +curMonth |
|
||||||
}) |
|
||||||
target.direction = direction |
|
||||||
this.renderCalendar(target) |
|
||||||
}, |
|
||||||
changeDate(e) { |
|
||||||
const { type } = e.currentTarget.dataset |
|
||||||
const { calendar: calendarData } = this.data |
|
||||||
const { curYear, curMonth } = calendarData |
|
||||||
const getMonthInfo = calcTargetYMInfo()[type] |
|
||||||
const target = getMonthInfo({ |
|
||||||
year: +curYear, |
|
||||||
month: +curMonth |
|
||||||
}) |
|
||||||
target.direction = type |
|
||||||
this.renderCalendar(target) |
|
||||||
}, |
|
||||||
renderCalendar(target) { |
|
||||||
let { calendar: calendarData, config } = this.data |
|
||||||
const { curYear, curMonth } = calendarData || {} |
|
||||||
for (let plugin of plugins.installed) { |
|
||||||
const [, p] = plugin |
|
||||||
if (typeof p.onSwitchCalendar === 'function') { |
|
||||||
calendarData = p.onSwitchCalendar(target, calendarData, this) |
|
||||||
} |
|
||||||
} |
|
||||||
return renderCalendar.call(this, calendarData, config).then(() => { |
|
||||||
let triggerEventName = 'whenChangeMonth' |
|
||||||
if (config.weekMode) { |
|
||||||
triggerEventName = 'whenChangeWeek' |
|
||||||
} |
|
||||||
this.triggerEvent(triggerEventName, { |
|
||||||
current: { |
|
||||||
year: +curYear, |
|
||||||
month: +curMonth |
|
||||||
}, |
|
||||||
next: target |
|
||||||
}) |
|
||||||
this.triggerEvent('onSwipe', { |
|
||||||
current: { |
|
||||||
year: +curYear, |
|
||||||
month: +curMonth |
|
||||||
}, |
|
||||||
next: target, |
|
||||||
type: triggerEventName |
|
||||||
}) |
|
||||||
}) |
|
||||||
}, |
|
||||||
doubleClickJumpToToday() { |
|
||||||
const { multi, weekMode } = this.calendar.getCalendarConfig() || {} |
|
||||||
if (multi || 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 && |
|
||||||
typeof this.calendar.jump === 'function' |
|
||||||
) { |
|
||||||
const today = dateUtil.todayFMD() |
|
||||||
this.calendar.jump(today) |
|
||||||
} |
|
||||||
this.count = undefined |
|
||||||
this.lastClick = undefined |
|
||||||
} else { |
|
||||||
this.lastClick = new Date().getTime() |
|
||||||
} |
|
||||||
this.triggerEvent('jumpToToday') |
|
||||||
} |
|
||||||
} |
|
||||||
}) |
|
@ -1,116 +0,0 @@ |
|||||||
<view class="flex b tb ac" wx:if="{{calendar}}"> |
|
||||||
<view class="calendar b tb"> |
|
||||||
<!-- 头部操作栏 --> |
|
||||||
<view |
|
||||||
wx:if="{{!config.hideHeader}}" |
|
||||||
class="handle {{config.theme}}_handle-color fs32 b lr ac pc" |
|
||||||
> |
|
||||||
<view class="prev fs36" wx:if="{{!config.weekMode}}"> |
|
||||||
<text |
|
||||||
wx:if="{{!config.hideSelectYear}}" |
|
||||||
class="prev-handle iconfont icon-doubleleft" |
|
||||||
bindtap="changeDate" |
|
||||||
data-type="prev_year" |
|
||||||
></text> |
|
||||||
<text |
|
||||||
class="prev-handle iconfont icon-left" |
|
||||||
bindtap="changeDate" |
|
||||||
data-type="prev_month" |
|
||||||
></text> |
|
||||||
</view> |
|
||||||
<view class="flex date-in-handle b lr cc blod" bindtap="doubleClickJumpToToday" |
|
||||||
>{{calendar.curYear || "--"}} 年 {{calendar.curMonth || "--"}} 月</view |
|
||||||
> |
|
||||||
<view class="next fs36" wx:if="{{!config.weekMode}}"> |
|
||||||
<text |
|
||||||
class="next-handle iconfont icon-right" |
|
||||||
bindtap="changeDate" |
|
||||||
data-type="next_month" |
|
||||||
></text> |
|
||||||
<text |
|
||||||
wx:if="{{!config.hideSelectYear}}" |
|
||||||
class="next-handle iconfont icon-doubleright" |
|
||||||
bindtap="changeDate" |
|
||||||
data-type="next_year" |
|
||||||
></text> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
<!-- 星期栏 --> |
|
||||||
<view class="weeks b lr ac {{config.theme}}_week-color"> |
|
||||||
<view class="week fs28" wx:for="{{calendar.weeksCh}}" wx:key="index" data-idx="{{index}}"> |
|
||||||
{{item}} |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
<!-- 日历面板主体 --> |
|
||||||
<view |
|
||||||
class="b lr wrap" |
|
||||||
bindtouchstart="calendarTouchstart" |
|
||||||
catchtouchmove="calendarTouchmove" |
|
||||||
catchtouchend="calendarTouchend" |
|
||||||
> |
|
||||||
<!-- 上月日期格子 --> |
|
||||||
<view |
|
||||||
class="grid b ac pc {{config.theme}}_prev-month-date" |
|
||||||
wx:for="{{calendar.prevMonthGrids}}" |
|
||||||
wx:key="index" |
|
||||||
data-idx="{{index}}" |
|
||||||
> |
|
||||||
<view class="date-wrap b cc"> |
|
||||||
<view class="date"> |
|
||||||
{{item.date}} |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
<!-- 本月日期格子 --> |
|
||||||
<view |
|
||||||
wx:for="{{calendar.dates}}" |
|
||||||
wx:key="index" |
|
||||||
data-idx="{{index}}" |
|
||||||
data-info="{{item}}" |
|
||||||
bindtap="tapDate" |
|
||||||
class="grid {{item.class ? item.class : ''}} {{config.theme}}_normal-date b ac pc" |
|
||||||
> |
|
||||||
<view |
|
||||||
class="date-wrap b cc {{config.emphasisWeek && (item.week === 0 || item.week === 6) ? config.theme + '_weekend-color' : ''}}" |
|
||||||
> |
|
||||||
<view |
|
||||||
class="date b ac pc {{item.class ? item.class : ''}} {{item.isToday && config.highlightToday ? config.theme + '_today' : ''}} {{item.choosed ? config.theme + '_choosed' : ''}} {{item.disable ? config.theme + '_date-disable' : ''}} {{config.chooseAreaMode ? 'date-area-mode' : ''}} {{calendar.todoLabelCircle && item.showTodoLabel && !item.choosed ? config.theme + '_todo-circle todo-circle' : '' }}" |
|
||||||
> |
|
||||||
{{config.markToday && item.isToday ? config.markToday : item.date}} |
|
||||||
<view |
|
||||||
wx:if="{{(config.showLunar && item.lunar && !item.showTodoLabel) || (item.showTodoLabel && calendar.todoLabelPos !== 'bottom') || config.showHolidays}}" |
|
||||||
class="date-desc {{config.theme}}_date-desc date-desc-bottom {{(item.choosed || item.isToday) ? 'date-desc-bottom-always' : ''}} {{item.disable ? config.theme + '_date-desc-disable' : ''}}" |
|
||||||
> |
|
||||||
<text |
|
||||||
class="{{config.showHolidays && !item.showTodoLabel && item.label && !item.choosed ? config.theme + '_date-desc-lunar' : ''}} {{item.type === 'festival' ? config.theme + '_festival' : ''}}" |
|
||||||
>{{item.label || item.lunar.Term || item.lunar.IDayCn}}</text |
|
||||||
> |
|
||||||
</view> |
|
||||||
<block wx:for="{{item.color}}" wx:for-item="col" wx:for-index="colIndex" wx:key="*this"> |
|
||||||
<view |
|
||||||
wx:if="{{item.showTodoLabel && !calendar.todoLabelCircle}}" |
|
||||||
class="{{item.todoText ? 'date-desc' : config.theme + '_todo-dot todo-dot'}} {{config.showLunar ? config.theme + '_date-desc-lunar' : ''}} {{calendar.todoLabelPos === 'bottom' ? 'date-desc-bottom todo-dot-bottom' : 'date-desc-top todo-dot-top'}} {{calendar.showLabelAlways && item.choosed && calendar.todoLabelPos === 'bottom' ? 'date-desc-bottom-always todo-dot-bottom-always' : ''}} {{calendar.showLabelAlways && item.choosed && calendar.todoLabelPos === 'top' ? 'date-desc-top-always todo-dot-top-always' : ''}}" |
|
||||||
style="background-color: {{item.todoText ? '' : col || calendar.todoLabelColor}}; color: {{col}};left:{{(item.color.length>1 ? 35 : 50)*(colIndex+1)}}%" |
|
||||||
> |
|
||||||
{{item.todoText}} |
|
||||||
</view> |
|
||||||
</block> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
<!-- 下月日期格子 --> |
|
||||||
<view |
|
||||||
class="grid b ac pc {{config.theme}}_next-month-date" |
|
||||||
wx:for="{{calendar.nextMonthGrids}}" |
|
||||||
wx:key="index" |
|
||||||
data-idx="{{index}}" |
|
||||||
> |
|
||||||
<view class="date-wrap b cc"> |
|
||||||
<view class="date"> |
|
||||||
{{item.date}} |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
@ -1,247 +0,0 @@ |
|||||||
@import "./theme/iconfont.wxss"; |
|
||||||
@import "./theme/theme-default.wxss"; |
|
||||||
@import "./theme/theme-elegant.wxss"; |
|
||||||
@import "./theme/theme-nuohe.wxss"; |
|
||||||
|
|
||||||
.blod { |
|
||||||
font-weight: bold; |
|
||||||
} |
|
||||||
|
|
||||||
.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: 50rpx; |
|
||||||
line-height: 50rpx; |
|
||||||
opacity: 0.5; |
|
||||||
} |
|
||||||
|
|
||||||
.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: 55rpx; |
|
||||||
height: 55rpx; |
|
||||||
text-align: center; |
|
||||||
line-height: 55rpx; |
|
||||||
font-size: 28rpx; |
|
||||||
font-weight: 200; |
|
||||||
border-radius: 50%; |
|
||||||
transition: all 0.3s; |
|
||||||
font-weight: bold; |
|
||||||
|
|
||||||
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: 16rpx; |
|
||||||
|
|
||||||
height: 16rpx; |
|
||||||
|
|
||||||
border-radius: 50%; |
|
||||||
|
|
||||||
position: absolute; |
|
||||||
|
|
||||||
left: 50%; |
|
||||||
bottom: -10rpx !important; |
|
||||||
|
|
||||||
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; |
|
||||||
} |
|
@ -1,212 +0,0 @@ |
|||||||
/* * |
|
||||||
@Author: drfu* |
|
||||||
@Description: 数据来源于国务院办公厅关于2020年部分节假日安排的通知(国办发明电〔2019〕16号)_政府信息公开专栏,http://www.gov.cn/zhengce/content/2019-11/21/content_5454164.htm
|
|
||||||
@Date: 2020-10-12 14:29:45* |
|
||||||
* @Last Modified by: drfu |
|
||||||
* @Last Modified time: 2020-10-16 17:38:08 |
|
||||||
*/ |
|
||||||
|
|
||||||
// 节日列表
|
|
||||||
export const festival = { |
|
||||||
// 农历固定日期节日
|
|
||||||
lunar: { |
|
||||||
1: { |
|
||||||
1: { |
|
||||||
type: 'festival', |
|
||||||
name: '春节', |
|
||||||
label: '春节' |
|
||||||
}, |
|
||||||
8: { |
|
||||||
type: 'festival', |
|
||||||
name: '腊八节', |
|
||||||
label: '腊八' |
|
||||||
}, |
|
||||||
15: { |
|
||||||
type: 'festival', |
|
||||||
name: '元宵节', |
|
||||||
label: '元宵' |
|
||||||
} |
|
||||||
}, |
|
||||||
7: { |
|
||||||
7: { |
|
||||||
type: 'festival', |
|
||||||
name: '七夕节', |
|
||||||
label: '七夕' |
|
||||||
}, |
|
||||||
15: { |
|
||||||
type: 'festival', |
|
||||||
name: '中元节', |
|
||||||
label: '中元节' |
|
||||||
} |
|
||||||
}, |
|
||||||
9: { |
|
||||||
9: { |
|
||||||
type: 'festival', |
|
||||||
name: '重阳节', |
|
||||||
label: '重阳节' |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
// 阳历固定日期节日
|
|
||||||
solar: { |
|
||||||
2: { |
|
||||||
14: { |
|
||||||
type: 'festival', |
|
||||||
name: '情人节', |
|
||||||
label: '情人节' |
|
||||||
} |
|
||||||
}, |
|
||||||
3: { |
|
||||||
12: { |
|
||||||
type: 'festival', |
|
||||||
name: '植树节', |
|
||||||
label: '植树节' |
|
||||||
} |
|
||||||
}, |
|
||||||
4: { |
|
||||||
1: { |
|
||||||
type: 'festival', |
|
||||||
name: '愚人节', |
|
||||||
label: '愚人节' |
|
||||||
}, |
|
||||||
5: { |
|
||||||
type: 'festival', |
|
||||||
name: '清明节', |
|
||||||
label: '清明节' |
|
||||||
} |
|
||||||
}, |
|
||||||
5: { |
|
||||||
1: { |
|
||||||
type: 'festival', |
|
||||||
name: '劳动节', |
|
||||||
label: '劳动节' |
|
||||||
} |
|
||||||
}, |
|
||||||
6: { |
|
||||||
1: { |
|
||||||
type: 'festival', |
|
||||||
name: '儿童节', |
|
||||||
label: '儿童节' |
|
||||||
} |
|
||||||
}, |
|
||||||
7: { |
|
||||||
1: { |
|
||||||
type: 'festival', |
|
||||||
name: '建党节', |
|
||||||
label: '建党节' |
|
||||||
} |
|
||||||
}, |
|
||||||
8: { |
|
||||||
1: { |
|
||||||
type: 'festival', |
|
||||||
name: '建军节', |
|
||||||
label: '建军节' |
|
||||||
} |
|
||||||
}, |
|
||||||
9: { |
|
||||||
10: { |
|
||||||
type: 'festival', |
|
||||||
name: '教师节', |
|
||||||
label: '教师节' |
|
||||||
} |
|
||||||
}, |
|
||||||
10: { |
|
||||||
1: { |
|
||||||
type: 'festival', |
|
||||||
name: '国庆节', |
|
||||||
label: '国庆节' |
|
||||||
} |
|
||||||
}, |
|
||||||
12: { |
|
||||||
25: { |
|
||||||
type: 'festival', |
|
||||||
name: '圣诞节', |
|
||||||
label: '圣诞节' |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export const holidays = { |
|
||||||
2020: { |
|
||||||
1: { |
|
||||||
1: { |
|
||||||
type: 'holiday', |
|
||||||
name: '元旦', |
|
||||||
label: '休' |
|
||||||
}, |
|
||||||
19: { |
|
||||||
type: 'work', |
|
||||||
name: '调班', |
|
||||||
label: '班' |
|
||||||
}, |
|
||||||
'24-30': { |
|
||||||
type: 'holiday', |
|
||||||
name: '春节', |
|
||||||
label: '休' |
|
||||||
} |
|
||||||
}, |
|
||||||
2: { |
|
||||||
1: { |
|
||||||
type: 'work', |
|
||||||
name: '调班', |
|
||||||
label: '班' |
|
||||||
} |
|
||||||
}, |
|
||||||
4: { |
|
||||||
'4-6': { |
|
||||||
type: 'holiday', |
|
||||||
name: '清明节', |
|
||||||
label: '休' |
|
||||||
}, |
|
||||||
26: { |
|
||||||
type: 'work', |
|
||||||
name: '调班', |
|
||||||
label: '班' |
|
||||||
} |
|
||||||
}, |
|
||||||
5: { |
|
||||||
'1-5': { |
|
||||||
type: 'holiday', |
|
||||||
name: '劳动节', |
|
||||||
label: '休' |
|
||||||
}, |
|
||||||
9: { |
|
||||||
type: 'work', |
|
||||||
name: '调班', |
|
||||||
label: '班' |
|
||||||
} |
|
||||||
}, |
|
||||||
6: { |
|
||||||
'25-27': { |
|
||||||
type: 'holiday', |
|
||||||
name: '端午节', |
|
||||||
label: '休' |
|
||||||
}, |
|
||||||
28: { |
|
||||||
type: 'work', |
|
||||||
name: '调班', |
|
||||||
label: '班' |
|
||||||
} |
|
||||||
}, |
|
||||||
9: { |
|
||||||
27: { |
|
||||||
type: 'work', |
|
||||||
name: '调班', |
|
||||||
label: '班' |
|
||||||
} |
|
||||||
}, |
|
||||||
10: { |
|
||||||
'1-8': { |
|
||||||
type: 'holiday', |
|
||||||
name: '国庆节/中秋节', |
|
||||||
label: '休' |
|
||||||
}, |
|
||||||
10: { |
|
||||||
type: 'work', |
|
||||||
name: '调班', |
|
||||||
label: '班' |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1 +0,0 @@ |
|||||||
export {}; |
|
@ -1,201 +0,0 @@ |
|||||||
/* * |
|
||||||
@Author: drfu* |
|
||||||
@Description: 显示法定节假日班/休情况 |
|
||||||
@Date: 2020-10-12 14:29:45* |
|
||||||
* @Last Modified by: drfu |
|
||||||
* @Last Modified time: 2020-10-16 17:34:13 |
|
||||||
*/ |
|
||||||
|
|
||||||
import { holidays, festival } from './holidays-map' |
|
||||||
import { dateUtil, getCalendarData, logger } from '../../utils/index' |
|
||||||
|
|
||||||
/** |
|
||||||
* 当前是否在休假期内 |
|
||||||
* @param {object} { year, month } |
|
||||||
* @param {object} { start, end, current } |
|
||||||
* @returns |
|
||||||
*/ |
|
||||||
function inHolidays({ year, month }, { start, end, current }) { |
|
||||||
const getTimeStamp = dateUtil.getTimeStamp |
|
||||||
const startTimestamp = getTimeStamp({ |
|
||||||
year, |
|
||||||
month, |
|
||||||
date: start |
|
||||||
}) |
|
||||||
const endTimestamp = getTimeStamp({ |
|
||||||
year, |
|
||||||
month, |
|
||||||
date: end |
|
||||||
}) |
|
||||||
const currentDateTimestamp = getTimeStamp({ |
|
||||||
year, |
|
||||||
month, |
|
||||||
date: current |
|
||||||
}) |
|
||||||
if ( |
|
||||||
currentDateTimestamp >= startTimestamp && |
|
||||||
currentDateTimestamp <= endTimestamp |
|
||||||
) { |
|
||||||
return true |
|
||||||
} |
|
||||||
return false |
|
||||||
} |
|
||||||
|
|
||||||
function addSpecialFestival(date, component) { |
|
||||||
const { convertlLunar2Solar, convertSolarLunar } = component.calendar || {} |
|
||||||
const lunarDateInfo = convertSolarLunar(date) |
|
||||||
const { lYear, lMonth } = lunarDateInfo || {} |
|
||||||
// 春节
|
|
||||||
const info = { |
|
||||||
type: 'festival', |
|
||||||
name: '除夕', |
|
||||||
label: '除夕' |
|
||||||
} |
|
||||||
if (lMonth === 12) { |
|
||||||
if (!festival.lunar['12']) festival.lunar['12'] = {} |
|
||||||
if (convertlLunar2Solar(`${lYear}-12-30`) === -1) { |
|
||||||
festival.lunar['12']['29'] = info |
|
||||||
} else { |
|
||||||
festival.lunar['12']['30'] = info |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 是否匹配到节日 |
|
||||||
* @param {object} [dateInfo={}] |
|
||||||
* @param {object} [component={}] |
|
||||||
* @returns {object|boolean} 匹配到的节日数据或者false |
|
||||||
*/ |
|
||||||
function hasFestivalDate(dateInfo = {}, component = {}) { |
|
||||||
const { month, date } = dateInfo |
|
||||||
let festivalDate = festival.solar[month] && festival.solar[month][date] |
|
||||||
if (!festivalDate) { |
|
||||||
const { convertSolarLunar } = component.calendar || {} |
|
||||||
const lunarDateInfo = convertSolarLunar(dateInfo) |
|
||||||
const { lMonth, lDay } = lunarDateInfo |
|
||||||
festivalDate = festival.lunar[lMonth] && festival.lunar[lMonth][lDay] |
|
||||||
if (!festivalDate) { |
|
||||||
const festivalOfMonth = festival.lunar[lMonth] || {} |
|
||||||
const festivalDateKey = Object.keys(festivalOfMonth).find(item => |
|
||||||
item.match(new RegExp(`\\b${lDay}\\b`)) |
|
||||||
) |
|
||||||
if (!festivalDateKey) { |
|
||||||
festivalDate = false |
|
||||||
} else { |
|
||||||
const festivalInfo = festival.lunar[lMonth][festivalDateKey] |
|
||||||
if (!festivalInfo) { |
|
||||||
festivalDate = false |
|
||||||
} else { |
|
||||||
const { condition } = festivalInfo |
|
||||||
if (typeof condition === 'function') { |
|
||||||
festivalDate = condition(lunarDateInfo) |
|
||||||
} else { |
|
||||||
festivalDate = false |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return festivalDate |
|
||||||
} |
|
||||||
|
|
||||||
export default () => { |
|
||||||
return { |
|
||||||
name: 'holidays', |
|
||||||
beforeRender(calendarData = {}, calendarConfig = {}, component) { |
|
||||||
let { dates = [] } = calendarData |
|
||||||
if (calendarConfig.showHolidays || calendarConfig.showFestival) { |
|
||||||
dates = dates.map(d => { |
|
||||||
let item = { ...d } |
|
||||||
const { year, month, date } = item |
|
||||||
const holidaysOfMonth = |
|
||||||
(holidays[year] && holidays[year][month]) || {} |
|
||||||
const holidayDate = holidaysOfMonth[date] |
|
||||||
if (holidayDate) { |
|
||||||
item = { |
|
||||||
...item, |
|
||||||
...holidayDate |
|
||||||
} |
|
||||||
} else { |
|
||||||
const holidayKeys = Object.keys(holidaysOfMonth).filter(item => |
|
||||||
item.includes('-') |
|
||||||
) |
|
||||||
let target = '' |
|
||||||
for (let v of holidayKeys) { |
|
||||||
const [start, end] = v.split('-') |
|
||||||
if (+d.date >= +start && +d.date <= +end) { |
|
||||||
target = v |
|
||||||
break |
|
||||||
} |
|
||||||
} |
|
||||||
const [start, end] = target.split('-') |
|
||||||
const isInHolidays = inHolidays( |
|
||||||
{ |
|
||||||
year, |
|
||||||
month |
|
||||||
}, |
|
||||||
{ |
|
||||||
start, |
|
||||||
end, |
|
||||||
current: date |
|
||||||
} |
|
||||||
) |
|
||||||
if (isInHolidays) { |
|
||||||
item = { |
|
||||||
...item, |
|
||||||
...holidaysOfMonth[target] |
|
||||||
} |
|
||||||
} else if (calendarConfig.showFestival) { |
|
||||||
const { convertSolarLunar, convertlLunar2Solar } = |
|
||||||
component.calendar || {} |
|
||||||
if ( |
|
||||||
typeof convertSolarLunar !== 'function' || |
|
||||||
typeof convertlLunar2Solar !== 'function' |
|
||||||
) { |
|
||||||
return logger.warn( |
|
||||||
'农历节日显示需要引入农历插件(/component/v2/plugins/solarLunar)' |
|
||||||
) |
|
||||||
} |
|
||||||
addSpecialFestival(item, component) |
|
||||||
const festivalDate = hasFestivalDate(item, component) |
|
||||||
if (festivalDate) { |
|
||||||
item = { |
|
||||||
...item, |
|
||||||
...festivalDate |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return item |
|
||||||
}) |
|
||||||
} |
|
||||||
return { |
|
||||||
calendarData: { |
|
||||||
...calendarData, |
|
||||||
dates: dates |
|
||||||
}, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
}, |
|
||||||
methods(component) { |
|
||||||
return { |
|
||||||
getHolidaysOfCurrentYear() { |
|
||||||
const calendar = getCalendarData('calendar', component) |
|
||||||
const { curYear } = calendar |
|
||||||
return this.methods(component).getHolidaysOfYear(curYear) |
|
||||||
}, |
|
||||||
getHolidaysOfYear(year) { |
|
||||||
if (!year) return logger.warn('getHolidaysOfCurrentYear() 入参错误') |
|
||||||
if (!holidays[year]) { |
|
||||||
logger.warn('未匹配到当前年份节假日信息,请自行补充') |
|
||||||
return { |
|
||||||
err: 'not match' |
|
||||||
} |
|
||||||
} |
|
||||||
return holidays[year] |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,18 +0,0 @@ |
|||||||
import preset from './preset/index' |
|
||||||
|
|
||||||
export default { |
|
||||||
installed: [...preset], |
|
||||||
use(plugin) { |
|
||||||
if (typeof plugin !== 'function') return |
|
||||||
const info = plugin() || {} |
|
||||||
const { name } = info |
|
||||||
if ( |
|
||||||
name && |
|
||||||
name !== 'methods' && |
|
||||||
!this.installed.some(p => p[0] === name) |
|
||||||
) { |
|
||||||
this.installed.unshift([name, info]) |
|
||||||
} |
|
||||||
return this |
|
||||||
} |
|
||||||
} |
|
@ -1,277 +0,0 @@ |
|||||||
/** |
|
||||||
* @Author: drfu* |
|
||||||
* @Description: 基础功能 |
|
||||||
* @Date: 2020-10-08 21:22:09* |
|
||||||
* @Last Modified by: drfu |
|
||||||
* @Last Modified time: 2020-10-11 13:28:52 |
|
||||||
* */ |
|
||||||
|
|
||||||
import { calcJumpData } from '../../core' |
|
||||||
import { renderCalendar } from '../../render' |
|
||||||
import { |
|
||||||
dateUtil, |
|
||||||
getCalendarData, |
|
||||||
setCalendarData, |
|
||||||
getCalendarConfig |
|
||||||
} from '../../utils/index' |
|
||||||
|
|
||||||
export default () => { |
|
||||||
return { |
|
||||||
name: 'base', |
|
||||||
beforeRender(calendarData = {}, calendarConfig) { |
|
||||||
const calendar = calendarData |
|
||||||
const { selectedDates = [], dates } = calendar |
|
||||||
let _dates = [...dates] |
|
||||||
if (selectedDates.length) { |
|
||||||
const selectedDatesStr = selectedDates.map(date => |
|
||||||
dateUtil.toTimeStr(date) |
|
||||||
) |
|
||||||
_dates.forEach(date => { |
|
||||||
const dateStr = dateUtil.toTimeStr(date) |
|
||||||
if (selectedDatesStr.includes(dateStr)) { |
|
||||||
date.choosed = true |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
return { |
|
||||||
calendarData: { |
|
||||||
...calendarData, |
|
||||||
dates: _dates |
|
||||||
}, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
}, |
|
||||||
onTapDate(tapedDate, calendarData = {}, calendarConfig = {}) { |
|
||||||
const calendar = { |
|
||||||
...calendarData |
|
||||||
} |
|
||||||
const dateIndex = dateUtil.findDateIndexInArray( |
|
||||||
tapedDate, |
|
||||||
calendarData.dates |
|
||||||
) |
|
||||||
const { multi, inverse } = calendarConfig |
|
||||||
let dates = [...calendar.dates] |
|
||||||
const { selectedDates = [] } = calendar |
|
||||||
if (!multi) { |
|
||||||
let preSelectedDate = {} |
|
||||||
if (selectedDates.length) { |
|
||||||
preSelectedDate = [...selectedDates].pop() || {} |
|
||||||
} |
|
||||||
const timeStr = dateUtil.toTimeStr |
|
||||||
if (!inverse && timeStr(preSelectedDate) === timeStr(tapedDate)) { |
|
||||||
return calendar |
|
||||||
} |
|
||||||
let _tapedDate = { ...tapedDate, choosed: !tapedDate.choosed } |
|
||||||
|
|
||||||
dates[dateIndex] = _tapedDate |
|
||||||
if (preSelectedDate.date) { |
|
||||||
const idx = dateUtil.findDateIndexInArray(preSelectedDate, dates) |
|
||||||
const date = dates[idx] |
|
||||||
if (date) { |
|
||||||
date.choosed = false |
|
||||||
} |
|
||||||
} |
|
||||||
if (dates[dateIndex].choosed) { |
|
||||||
calendar.selectedDates = [dates[dateIndex]] |
|
||||||
} else { |
|
||||||
calendar.selectedDates = [] |
|
||||||
} |
|
||||||
} else { |
|
||||||
dates[dateIndex] = { |
|
||||||
...dates[dateIndex], |
|
||||||
choosed: !dates[dateIndex].choosed |
|
||||||
} |
|
||||||
if (!calendar.selectedDates) { |
|
||||||
calendar.selectedDates = [] |
|
||||||
} |
|
||||||
if (dates[dateIndex].choosed) { |
|
||||||
calendar.selectedDates.push(dates[dateIndex]) |
|
||||||
} else { |
|
||||||
calendar.selectedDates = calendar.selectedDates.filter( |
|
||||||
date => |
|
||||||
dateUtil.toTimeStr(date) !== dateUtil.toTimeStr(dates[dateIndex]) |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
return { |
|
||||||
calendarData: { |
|
||||||
...calendar, |
|
||||||
dates |
|
||||||
}, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
}, |
|
||||||
onSwitchCalendar(date, calendarData = {}, component) { |
|
||||||
const calendarConfig = getCalendarConfig(component) |
|
||||||
if (calendarConfig.weekMode) { |
|
||||||
return calendarData |
|
||||||
} |
|
||||||
const updatedRenderData = calcJumpData({ |
|
||||||
dateInfo: date, |
|
||||||
config: calendarConfig |
|
||||||
}) |
|
||||||
return { |
|
||||||
...calendarData, |
|
||||||
...updatedRenderData |
|
||||||
} |
|
||||||
}, |
|
||||||
methods(component) { |
|
||||||
return { |
|
||||||
jump: dateInfo => { |
|
||||||
if (Object.prototype.toString.call(dateInfo) !== '[object Object]') |
|
||||||
return |
|
||||||
const updatedRenderData = calcJumpData({ |
|
||||||
dateInfo, |
|
||||||
component |
|
||||||
}) |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
const config = getCalendarConfig(component) |
|
||||||
if (config.autoChoosedWhenJump) { |
|
||||||
const target = updatedRenderData.dates[dateInfo.date - 1] |
|
||||||
if (!updatedRenderData.selectedDates) { |
|
||||||
updatedRenderData.selectedDates = [target] |
|
||||||
} else { |
|
||||||
updatedRenderData.selectedDates.push(target) |
|
||||||
} |
|
||||||
} |
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
...updatedRenderData |
|
||||||
}) |
|
||||||
}, |
|
||||||
getCalendarConfig() { |
|
||||||
return getCalendarConfig(component) |
|
||||||
}, |
|
||||||
setCalendarConfig(config) { |
|
||||||
return new Promise((resolve, reject) => { |
|
||||||
if (!component || !component.data.config) { |
|
||||||
reject('异常:未找到组件配置信息') |
|
||||||
return |
|
||||||
} |
|
||||||
let conf = { ...component.config, ...config } |
|
||||||
component.config = conf |
|
||||||
setCalendarData({ config: conf }, component) |
|
||||||
.then(resolve) |
|
||||||
.catch(reject) |
|
||||||
}) |
|
||||||
}, |
|
||||||
cancelSelectedDates(cancelDates = []) { |
|
||||||
const existCalendarData = getCalendarData('calendar', component) || {} |
|
||||||
const { dates = [], selectedDates = [] } = existCalendarData |
|
||||||
let updatedRenderData = {} |
|
||||||
const config = getCalendarConfig(component) |
|
||||||
let chooseAreaData = {} |
|
||||||
if (config.chooseAreaMode) { |
|
||||||
chooseAreaData = { |
|
||||||
chooseAreaTimestamp: [], |
|
||||||
tempChooseAreaTimestamp: [] |
|
||||||
} |
|
||||||
} |
|
||||||
if (!cancelDates.length) { |
|
||||||
dates.forEach(item => { |
|
||||||
item.choosed = false |
|
||||||
}) |
|
||||||
updatedRenderData = { |
|
||||||
dates, |
|
||||||
selectedDates: [] |
|
||||||
} |
|
||||||
} else { |
|
||||||
const cancelDatesStr = cancelDates.map(date => |
|
||||||
dateUtil.toTimeStr(date) |
|
||||||
) |
|
||||||
const filterSelectedDates = selectedDates.filter( |
|
||||||
date => !cancelDatesStr.includes(dateUtil.toTimeStr(date)) |
|
||||||
) |
|
||||||
dates.forEach(date => { |
|
||||||
if (cancelDatesStr.includes(dateUtil.toTimeStr(date))) { |
|
||||||
date.choosed = false |
|
||||||
} |
|
||||||
}) |
|
||||||
updatedRenderData = { |
|
||||||
dates, |
|
||||||
selectedDates: filterSelectedDates |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
...updatedRenderData, |
|
||||||
...chooseAreaData |
|
||||||
}) |
|
||||||
}, |
|
||||||
setSelectedDates: targetDates => { |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
let { dates, selectedDates = [] } = existCalendarData || {} |
|
||||||
let __selectedDates = [] |
|
||||||
let __dates = dates |
|
||||||
if (!targetDates) { |
|
||||||
__dates = dates.map(item => { |
|
||||||
const date = { ...item } |
|
||||||
date.choosed = true |
|
||||||
if (existCalendarData.showLabelAlways && date.showTodoLabel) { |
|
||||||
date.showTodoLabel = true |
|
||||||
} else { |
|
||||||
date.showTodoLabel = false |
|
||||||
} |
|
||||||
return date |
|
||||||
}) |
|
||||||
__selectedDates = dates |
|
||||||
} else if (targetDates && targetDates.length) { |
|
||||||
const allSelected = dateUtil.uniqueArrayByDate( |
|
||||||
selectedDates.concat(targetDates) |
|
||||||
) |
|
||||||
const allSelectedDateStr = allSelected.map(d => |
|
||||||
dateUtil.toTimeStr(d) |
|
||||||
) |
|
||||||
__dates = dates.map(item => { |
|
||||||
const date = { ...item } |
|
||||||
if (allSelectedDateStr.includes(dateUtil.toTimeStr(date))) { |
|
||||||
date.choosed = true |
|
||||||
__selectedDates.push(date) |
|
||||||
} |
|
||||||
if (existCalendarData.showLabelAlways && date.showTodoLabel) { |
|
||||||
date.showTodoLabel = true |
|
||||||
} else { |
|
||||||
date.showTodoLabel = false |
|
||||||
} |
|
||||||
return date |
|
||||||
}) |
|
||||||
} |
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
dates: __dates, |
|
||||||
selectedDates: __selectedDates |
|
||||||
}) |
|
||||||
}, |
|
||||||
setDateStyle: toSetDates => { |
|
||||||
if (!Array.isArray(toSetDates)) return Promise.reject() |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
const { dates = [], specialStyleDates } = existCalendarData || {} |
|
||||||
if (Array.isArray(specialStyleDates)) { |
|
||||||
toSetDates = dateUtil.uniqueArrayByDate([ |
|
||||||
...specialStyleDates, |
|
||||||
...toSetDates |
|
||||||
]) |
|
||||||
} |
|
||||||
const toSetDatesStr = toSetDates.map(item => dateUtil.toTimeStr(item)) |
|
||||||
const _dates = dates.map(item => { |
|
||||||
const idx = toSetDatesStr.indexOf(dateUtil.toTimeStr(item)) |
|
||||||
if (idx > -1) { |
|
||||||
return { |
|
||||||
...item, |
|
||||||
class: toSetDates[idx].class |
|
||||||
} |
|
||||||
} else { |
|
||||||
return item |
|
||||||
} |
|
||||||
}) |
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
dates: _dates, |
|
||||||
specialStyleDates: toSetDates |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,69 +0,0 @@ |
|||||||
/** |
|
||||||
* @Author: drfu* |
|
||||||
* @Description: 获取日历数据 |
|
||||||
* @Date: 2020-10-08 21:22:09* |
|
||||||
* @Last Modified by: drfu |
|
||||||
* @Last Modified time: 2020-10-11 13:42:37 |
|
||||||
* */ |
|
||||||
|
|
||||||
import { getCalendarData, logger, getCalendarConfig } from '../../utils/index' |
|
||||||
|
|
||||||
function wrapDateWithLunar(dates = [], convertFn) { |
|
||||||
const datesWithLunar = JSON.parse(JSON.stringify(dates)).map(date => ({ |
|
||||||
...date, |
|
||||||
lunar: convertFn(date) |
|
||||||
})) |
|
||||||
return datesWithLunar |
|
||||||
} |
|
||||||
|
|
||||||
export default () => { |
|
||||||
return { |
|
||||||
name: 'getData', |
|
||||||
methods(component) { |
|
||||||
return { |
|
||||||
getCurrentYM: () => { |
|
||||||
const { curYear, curMonth } = getCalendarData('calendar', component) |
|
||||||
return { |
|
||||||
year: curYear, |
|
||||||
month: curMonth |
|
||||||
} |
|
||||||
}, |
|
||||||
getSelectedDates: (options = {}) => { |
|
||||||
const dates = |
|
||||||
getCalendarData('calendar.selectedDates', component) || [] |
|
||||||
const config = getCalendarConfig(component) || {} |
|
||||||
if (options.lunar && !config.showLunar) { |
|
||||||
const injectedFns = component.calendar || {} |
|
||||||
if (typeof injectedFns.convertSolarLunar === 'function') { |
|
||||||
return wrapDateWithLunar(dates, injectedFns.convertSolarLunar) |
|
||||||
} else { |
|
||||||
logger.warn('获取农历信息需引入农历插件') |
|
||||||
} |
|
||||||
} else { |
|
||||||
return dates |
|
||||||
} |
|
||||||
}, |
|
||||||
getCalendarDates: (options = {}) => { |
|
||||||
const config = getCalendarConfig(component) || {} |
|
||||||
const dates = getCalendarData('calendar.dates', component) |
|
||||||
if (options.lunar && !config.showLunar) { |
|
||||||
const injectedFns = component.calendar || {} |
|
||||||
if (typeof injectedFns.convertSolarLunar === 'function') { |
|
||||||
return wrapDateWithLunar(dates, injectedFns.convertSolarLunar) |
|
||||||
} else { |
|
||||||
logger.warn('获取农历信息需引入农历插件') |
|
||||||
} |
|
||||||
} else { |
|
||||||
return dates |
|
||||||
} |
|
||||||
}, |
|
||||||
getCalendarAllData: () => { |
|
||||||
return { |
|
||||||
data: getCalendarData('calendar', component) || {}, |
|
||||||
config: getCalendarConfig(component) || {} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1 +0,0 @@ |
|||||||
export {}; |
|
@ -1,9 +0,0 @@ |
|||||||
import base from './base' |
|
||||||
import getCalendarData from './get-calendar-data' |
|
||||||
|
|
||||||
const preset = [ |
|
||||||
['base', base()], |
|
||||||
['get-calendar-data', getCalendarData()] |
|
||||||
] |
|
||||||
|
|
||||||
export default preset |
|
@ -1 +0,0 @@ |
|||||||
export {}; |
|
@ -1,221 +0,0 @@ |
|||||||
/** |
|
||||||
* @Author: drfu* |
|
||||||
* @Description: 禁用、启用日期选择 |
|
||||||
* @Date: 2020-10-08 21:22:09* |
|
||||||
* @Last Modified by: drfu |
|
||||||
* @Last Modified time: 2020-10-08 21:25:00 |
|
||||||
* */ |
|
||||||
|
|
||||||
import { getCalendarData, dateUtil, logger } from '../utils/index' |
|
||||||
import { renderCalendar } from '../render' |
|
||||||
|
|
||||||
function convertEnableAreaToTimestamp(timearea = []) { |
|
||||||
const start = timearea[0].split('-') |
|
||||||
const end = timearea[1].split('-') |
|
||||||
if (start.length !== 3 || end.length !== 3) { |
|
||||||
logger.warn('enableArea() 参数格式为: ["2018-2-1", "2018-3-1"]') |
|
||||||
return {} |
|
||||||
} |
|
||||||
const startTimestamp = dateUtil |
|
||||||
.newDate(start[0], start[1], start[2]) |
|
||||||
.getTime() |
|
||||||
const endTimestamp = dateUtil.newDate(end[0], end[1], end[2]).getTime() |
|
||||||
return { |
|
||||||
start, |
|
||||||
end, |
|
||||||
startTimestamp, |
|
||||||
endTimestamp |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function isValiditeOfDateArea(dateArea) { |
|
||||||
const { |
|
||||||
start, |
|
||||||
end, |
|
||||||
startTimestamp, |
|
||||||
endTimestamp |
|
||||||
} = convertEnableAreaToTimestamp(dateArea) |
|
||||||
if (!start || !end) return |
|
||||||
const datesCountOfStart = dateUtil.getDatesCountOfMonth(start[0], start[1]) |
|
||||||
const datesCountOfEnd = dateUtil.getDatesCountOfMonth(end[0], end[1]) |
|
||||||
if (start[2] > datesCountOfStart || start[2] < 1) { |
|
||||||
logger.warn('enableArea() 开始日期错误,指定日期不在指定月份天数范围内') |
|
||||||
return false |
|
||||||
} else if (start[1] > 12 || start[1] < 1) { |
|
||||||
logger.warn('enableArea() 开始日期错误,月份超出1-12月份') |
|
||||||
return false |
|
||||||
} else if (end[2] > datesCountOfEnd || end[2] < 1) { |
|
||||||
logger.warn('enableArea() 截止日期错误,指定日期不在指定月份天数范围内') |
|
||||||
return false |
|
||||||
} else if (end[1] > 12 || end[1] < 1) { |
|
||||||
logger.warn('enableArea() 截止日期错误,月份超出1-12月份') |
|
||||||
return false |
|
||||||
} else if (startTimestamp > endTimestamp) { |
|
||||||
logger.warn('enableArea()参数最小日期大于了最大日期') |
|
||||||
return false |
|
||||||
} else { |
|
||||||
return true |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function handleDisableMode(calendarConfig) { |
|
||||||
const { disableMode } = calendarConfig |
|
||||||
if (!disableMode) return {} |
|
||||||
const disableBound = |
|
||||||
dateUtil.getTimeStamp(disableMode.date) || dateUtil.todayTimestamp() |
|
||||||
return { |
|
||||||
disableBound, |
|
||||||
disableType: disableMode.type |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function disabledByConfig(dateInfo, currentDate, calendarConfig) { |
|
||||||
const date = { ...dateInfo } |
|
||||||
const { disableType, disableBound } = handleDisableMode(calendarConfig) |
|
||||||
if ( |
|
||||||
(disableType === 'before' && disableBound && currentDate < disableBound) || |
|
||||||
(disableType === 'after' && disableBound && currentDate > disableBound) |
|
||||||
) { |
|
||||||
date.disable = true |
|
||||||
} else { |
|
||||||
date.disable = false |
|
||||||
} |
|
||||||
return date |
|
||||||
} |
|
||||||
|
|
||||||
export default () => { |
|
||||||
return { |
|
||||||
name: 'enable', |
|
||||||
beforeRender(calendarData = {}, calendarConfig = {}) { |
|
||||||
const { |
|
||||||
dates, |
|
||||||
enableArea, |
|
||||||
enableDates, |
|
||||||
disableDates, |
|
||||||
renderCausedBy |
|
||||||
} = calendarData |
|
||||||
const _dates = [...dates].map(date => { |
|
||||||
let item = { ...date } |
|
||||||
const timeStr = dateUtil.toTimeStr(date) |
|
||||||
const timestamp = +dateUtil.getTimeStamp(item) |
|
||||||
if (renderCausedBy === 'enableDates') { |
|
||||||
if (enableDates && enableDates.length) { |
|
||||||
if (enableDates.includes(timeStr)) { |
|
||||||
item.disable = false |
|
||||||
} else { |
|
||||||
item.disable = true |
|
||||||
} |
|
||||||
return item |
|
||||||
} |
|
||||||
} else if (renderCausedBy === 'enableArea') { |
|
||||||
if (enableArea && enableArea.length) { |
|
||||||
const [startTimestamp, endTimestamp] = enableArea || [] |
|
||||||
const ifOutofArea = |
|
||||||
+startTimestamp > timestamp || timestamp > +endTimestamp |
|
||||||
item.disable = ifOutofArea |
|
||||||
return item |
|
||||||
} |
|
||||||
} else if (renderCausedBy === 'disableDates') { |
|
||||||
if (disableDates && disableDates.length) { |
|
||||||
if (disableDates && disableDates.includes(timeStr)) { |
|
||||||
item.disable = true |
|
||||||
} else { |
|
||||||
item.disable = false |
|
||||||
} |
|
||||||
return item |
|
||||||
} |
|
||||||
} |
|
||||||
return disabledByConfig(item, timestamp, calendarConfig) |
|
||||||
}) |
|
||||||
|
|
||||||
return { |
|
||||||
calendarData: { |
|
||||||
...calendarData, |
|
||||||
dates: _dates |
|
||||||
}, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
}, |
|
||||||
methods(component) { |
|
||||||
return { |
|
||||||
enableArea: (dateArea = []) => { |
|
||||||
if (dateArea.length === 2) { |
|
||||||
const validate = isValiditeOfDateArea(dateArea) |
|
||||||
if (validate) { |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
const { |
|
||||||
startTimestamp, |
|
||||||
endTimestamp |
|
||||||
} = convertEnableAreaToTimestamp(dateArea) |
|
||||||
|
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
renderCausedBy: 'enableArea', |
|
||||||
enableArea: [startTimestamp, endTimestamp] |
|
||||||
}) |
|
||||||
} |
|
||||||
} else { |
|
||||||
return Promise.inject( |
|
||||||
'enableArea()参数需为时间范围数组,形如:["2018-8-4" , "2018-8-24"]' |
|
||||||
) |
|
||||||
} |
|
||||||
}, |
|
||||||
enableDates: (toSet = []) => { |
|
||||||
if (!toSet.length) return |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
const { enableDates = [] } = existCalendarData || {} |
|
||||||
let toSetDates = toSet.map(item => { |
|
||||||
if (typeof item === 'string') { |
|
||||||
return dateUtil.transformDateRow2Dict(item) |
|
||||||
} |
|
||||||
return item |
|
||||||
}) |
|
||||||
if (enableDates.length) { |
|
||||||
toSetDates = dateUtil.uniqueArrayByDate([ |
|
||||||
...toSetDates, |
|
||||||
...enableDates.map(d => dateUtil.transformDateRow2Dict(d)) |
|
||||||
]) |
|
||||||
} |
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
renderCausedBy: 'enableDates', |
|
||||||
enableDates: toSetDates.map(date => { |
|
||||||
if (typeof date !== 'string') { |
|
||||||
return dateUtil.toTimeStr(date) |
|
||||||
} |
|
||||||
return date |
|
||||||
}) |
|
||||||
}) |
|
||||||
}, |
|
||||||
disableDates: toSet => { |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
const { disableDates = [], dates = [] } = existCalendarData || {} |
|
||||||
let toSetDates = toSet.map(item => { |
|
||||||
let date = { ...item } |
|
||||||
if (typeof date === 'string') { |
|
||||||
return dateUtil.transformDateRow2Dict(item) |
|
||||||
} |
|
||||||
return item |
|
||||||
}) |
|
||||||
if (disableDates && disableDates.length) { |
|
||||||
toSetDates = dateUtil.uniqueArrayByDate([ |
|
||||||
...toSetDates, |
|
||||||
...disableDates.map(d => dateUtil.transformDateRow2Dict(d)) |
|
||||||
]) |
|
||||||
} |
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
renderCausedBy: 'disableDates', |
|
||||||
dates, |
|
||||||
disableDates: toSetDates.map(date => { |
|
||||||
if (typeof date !== 'string') { |
|
||||||
return dateUtil.toTimeStr(date) |
|
||||||
} |
|
||||||
return date |
|
||||||
}) |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@ |
|||||||
export {}; |
|
@ -1,59 +0,0 @@ |
|||||||
import { dateUtil } from '../../utils/index' |
|
||||||
import convertSolarLunar from './convertSolarLunar' |
|
||||||
|
|
||||||
function getDateRow2Dict(dateInfo) { |
|
||||||
if (!dateInfo) return dateInfo |
|
||||||
if (typeof dateInfo === 'string' && dateInfo.includes('-')) { |
|
||||||
dateInfo = dateUtil.transformDateRow2Dict(dateInfo) |
|
||||||
} |
|
||||||
return dateInfo |
|
||||||
} |
|
||||||
|
|
||||||
export default () => { |
|
||||||
return { |
|
||||||
name: 'convertSolarLunar', |
|
||||||
beforeRender(calendarData = {}, calendarConfig = {}) { |
|
||||||
let { dates = [], selectedDates = [] } = calendarData |
|
||||||
if (calendarConfig.showLunar) { |
|
||||||
dates = dates.map(dataInfo => { |
|
||||||
const { year, month, date } = dataInfo |
|
||||||
return { |
|
||||||
...dataInfo, |
|
||||||
lunar: convertSolarLunar.solar2lunar(year, month, date) |
|
||||||
} |
|
||||||
}) |
|
||||||
selectedDates = selectedDates.map(dataInfo => { |
|
||||||
const { year, month, date } = dataInfo |
|
||||||
return { |
|
||||||
...dataInfo, |
|
||||||
lunar: convertSolarLunar.solar2lunar(year, month, date) |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
return { |
|
||||||
calendarData: { |
|
||||||
...calendarData, |
|
||||||
dates: dates, |
|
||||||
selectedDates: selectedDates |
|
||||||
}, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
}, |
|
||||||
methods() { |
|
||||||
return { |
|
||||||
convertSolarLunar: dateInfo => { |
|
||||||
dateInfo = getDateRow2Dict(dateInfo) |
|
||||||
if (!dateInfo) return dateInfo |
|
||||||
const { year, month, date } = dateInfo |
|
||||||
return convertSolarLunar.solar2lunar(year, month, date) |
|
||||||
}, |
|
||||||
convertlLunar2Solar: (dateInfo, isLeapMonth) => { |
|
||||||
dateInfo = getDateRow2Dict(dateInfo) |
|
||||||
if (!dateInfo) return dateInfo |
|
||||||
const { year, month, date } = dateInfo |
|
||||||
return convertSolarLunar.lunar2solar(year, month, date, isLeapMonth) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,305 +0,0 @@ |
|||||||
/** |
|
||||||
* @Author: drfu* |
|
||||||
* @Description: 时间区域选择 |
|
||||||
* @Date: 2020-10-08 21:22:09* |
|
||||||
* @Last Modified by: drfu |
|
||||||
* @Last Modified time: 2020-10-11 13:56:32 |
|
||||||
* */ |
|
||||||
|
|
||||||
import { renderCalendar } from '../render' |
|
||||||
import { |
|
||||||
logger, |
|
||||||
dateUtil, |
|
||||||
getCalendarConfig, |
|
||||||
getCalendarData |
|
||||||
} from '../utils/index' |
|
||||||
|
|
||||||
function pusheNextMonthDateArea( |
|
||||||
dateInfo = {}, |
|
||||||
startTimestamp, |
|
||||||
endTimestamp, |
|
||||||
selectedDates = [] |
|
||||||
) { |
|
||||||
let tempOfSelectedDate = [...selectedDates] |
|
||||||
const dates = dateUtil.calcDates(dateInfo.year, dateInfo.month) |
|
||||||
let datesLen = dates.length |
|
||||||
for (let i = 0; i < datesLen; i++) { |
|
||||||
const date = dates[i] |
|
||||||
const timeStamp = dateUtil.getTimeStamp(date) |
|
||||||
if (timeStamp <= endTimestamp && timeStamp >= startTimestamp) { |
|
||||||
tempOfSelectedDate.push({ |
|
||||||
...date, |
|
||||||
choosed: true |
|
||||||
}) |
|
||||||
} |
|
||||||
if (i === datesLen - 1 && timeStamp < endTimestamp) { |
|
||||||
pusheNextMonthDateArea( |
|
||||||
dateUtil.getNextMonthInfo(date), |
|
||||||
startTimestamp, |
|
||||||
endTimestamp, |
|
||||||
tempOfSelectedDate |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
return tempOfSelectedDate |
|
||||||
} |
|
||||||
function pushPrevMonthDateArea( |
|
||||||
dateInfo = {}, |
|
||||||
startTimestamp, |
|
||||||
endTimestamp, |
|
||||||
selectedDates = [] |
|
||||||
) { |
|
||||||
let tempOfSelectedDate = [...selectedDates] |
|
||||||
const dates = dateUtil.sortDatesByTime( |
|
||||||
dateUtil.calcDates(dateInfo.year, dateInfo.month), |
|
||||||
'desc' |
|
||||||
) |
|
||||||
let datesLen = dates.length |
|
||||||
let firstDate = dateUtil.getTimeStamp(dates[0]) |
|
||||||
for (let i = 0; i < datesLen; i++) { |
|
||||||
const date = dates[i] |
|
||||||
const timeStamp = dateUtil.getTimeStamp(date) |
|
||||||
if (timeStamp >= startTimestamp && timeStamp <= endTimestamp) { |
|
||||||
tempOfSelectedDate.push({ |
|
||||||
...date, |
|
||||||
choosed: true |
|
||||||
}) |
|
||||||
} |
|
||||||
if (i === datesLen - 1 && firstDate > startTimestamp) { |
|
||||||
pushPrevMonthDateArea( |
|
||||||
dateUtil.getPrevMonthInfo(date), |
|
||||||
startTimestamp, |
|
||||||
endTimestamp, |
|
||||||
tempOfSelectedDate |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
return tempOfSelectedDate |
|
||||||
} |
|
||||||
/** |
|
||||||
* 当设置日期区域非当前时保存其它月份的日期至已选日期数组 |
|
||||||
* @param {object} info |
|
||||||
*/ |
|
||||||
function calcDateWhenNotInOneMonth(info) { |
|
||||||
const { firstDate, lastDate, startTimestamp, endTimestamp } = info |
|
||||||
let { selectedDate } = info |
|
||||||
if (dateUtil.getTimeStamp(firstDate) > startTimestamp) { |
|
||||||
selectedDate = pushPrevMonthDateArea( |
|
||||||
dateUtil.getPrevMonthInfo(firstDate), |
|
||||||
startTimestamp, |
|
||||||
endTimestamp, |
|
||||||
selectedDate |
|
||||||
) |
|
||||||
} |
|
||||||
if (dateUtil.getTimeStamp(lastDate) < endTimestamp) { |
|
||||||
selectedDate = pusheNextMonthDateArea( |
|
||||||
dateUtil.getNextMonthInfo(lastDate), |
|
||||||
startTimestamp, |
|
||||||
endTimestamp, |
|
||||||
selectedDate |
|
||||||
) |
|
||||||
} |
|
||||||
return [...selectedDate] |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 指定日期区域转时间戳 |
|
||||||
* @param {array} timearea 时间区域 |
|
||||||
*/ |
|
||||||
export function convertTimeRangeToTimestamp(timearea = []) { |
|
||||||
const start = timearea[0].split('-') |
|
||||||
const end = timearea[1].split('-') |
|
||||||
if (start.length !== 3 || end.length !== 3) { |
|
||||||
logger.warn('enableArea() 参数格式为: ["2018-2-1", "2018-3-1"]') |
|
||||||
return {} |
|
||||||
} |
|
||||||
const startTimestamp = dateUtil |
|
||||||
.newDate(start[0], start[1], start[2]) |
|
||||||
.getTime() |
|
||||||
const endTimestamp = dateUtil.newDate(end[0], end[1], end[2]).getTime() |
|
||||||
return { |
|
||||||
start, |
|
||||||
end, |
|
||||||
startTimestamp, |
|
||||||
endTimestamp |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 校验时间区域是否合法 |
|
||||||
* @param {array} dateArea 时间区域 |
|
||||||
*/ |
|
||||||
function validateTimeRange(dateArea) { |
|
||||||
const { |
|
||||||
start, |
|
||||||
end, |
|
||||||
startTimestamp, |
|
||||||
endTimestamp |
|
||||||
} = convertTimeRangeToTimestamp(dateArea) |
|
||||||
if (!start || !end) return |
|
||||||
const startMonthDays = dateUtil.getDatesCountOfMonth(start[0], start[1]) |
|
||||||
const endMonthDays = dateUtil.getDatesCountOfMonth(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 |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default () => { |
|
||||||
return { |
|
||||||
name: 'timeRange', |
|
||||||
beforeRender(calendarData = {}, calendarConfig = {}) { |
|
||||||
const { |
|
||||||
chooseAreaTimestamp = [], |
|
||||||
dates = [], |
|
||||||
selectedDates = [] |
|
||||||
} = calendarData |
|
||||||
let __dates = dates |
|
||||||
let __selectedDates = selectedDates |
|
||||||
const [startDateTimestamp, endDateTimestamp] = chooseAreaTimestamp |
|
||||||
if (chooseAreaTimestamp.length === 2) { |
|
||||||
__selectedDates = [] |
|
||||||
__dates = dates.map(d => { |
|
||||||
const date = { ...d } |
|
||||||
const dateTimeStamp = dateUtil.getTimeStamp(date) |
|
||||||
if ( |
|
||||||
dateTimeStamp >= startDateTimestamp && |
|
||||||
endDateTimestamp >= dateTimeStamp |
|
||||||
) { |
|
||||||
date.choosed = true |
|
||||||
__selectedDates.push(date) |
|
||||||
} else { |
|
||||||
date.choosed = false |
|
||||||
__selectedDates = __selectedDates.filter( |
|
||||||
item => dateUtil.getTimeStamp(item) !== dateTimeStamp |
|
||||||
) |
|
||||||
} |
|
||||||
return date |
|
||||||
}) |
|
||||||
const monthOfStartDate = new Date(startDateTimestamp).getMonth() |
|
||||||
const monthOfEndDate = new Date(endDateTimestamp).getMonth() |
|
||||||
if (monthOfStartDate !== monthOfEndDate) { |
|
||||||
__selectedDates = calcDateWhenNotInOneMonth({ |
|
||||||
firstDate: __dates[0], |
|
||||||
lastDate: __dates[__dates.length - 1], |
|
||||||
startTimestamp: startDateTimestamp, |
|
||||||
endTimestamp: endDateTimestamp, |
|
||||||
selectedDate: __selectedDates |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
return { |
|
||||||
calendarData: { |
|
||||||
...calendarData, |
|
||||||
dates: __dates, |
|
||||||
selectedDates: dateUtil.sortDatesByTime( |
|
||||||
dateUtil.uniqueArrayByDate(__selectedDates) |
|
||||||
) |
|
||||||
}, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
}, |
|
||||||
onTapDate(tapedDate, calendarData = {}, calendarConfig = {}) { |
|
||||||
if (!calendarConfig.chooseAreaMode) { |
|
||||||
return { |
|
||||||
calendarData, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
} |
|
||||||
let { |
|
||||||
tempChooseAreaTimestamp = [], |
|
||||||
chooseAreaTimestamp: existChooseAreaTimestamp = [], |
|
||||||
selectedDates = [], |
|
||||||
dates = [] |
|
||||||
} = calendarData |
|
||||||
const timestamp = dateUtil.getTimeStamp(tapedDate) |
|
||||||
let __dates = [...dates] |
|
||||||
let __selectedDates = [...selectedDates] |
|
||||||
if ( |
|
||||||
tempChooseAreaTimestamp.length === 2 || |
|
||||||
existChooseAreaTimestamp.length === 2 |
|
||||||
) { |
|
||||||
tempChooseAreaTimestamp = [tapedDate] |
|
||||||
__selectedDates = [] |
|
||||||
__dates.forEach(d => (d.choosed = false)) |
|
||||||
} else if (tempChooseAreaTimestamp.length === 1) { |
|
||||||
const preChoosedDate = tempChooseAreaTimestamp[0] |
|
||||||
const preTimestamp = dateUtil.getTimeStamp(preChoosedDate) |
|
||||||
if (preTimestamp <= timestamp) { |
|
||||||
tempChooseAreaTimestamp.push(tapedDate) |
|
||||||
} else if (preTimestamp > timestamp) { |
|
||||||
tempChooseAreaTimestamp.unshift(tapedDate) |
|
||||||
} |
|
||||||
} else { |
|
||||||
tempChooseAreaTimestamp = [tapedDate] |
|
||||||
} |
|
||||||
let chooseAreaTimestamp = [] |
|
||||||
if (tempChooseAreaTimestamp.length === 2) { |
|
||||||
const [startDate, endDate] = tempChooseAreaTimestamp |
|
||||||
const startDateTimestamp = dateUtil.getTimeStamp(startDate) |
|
||||||
const endDateTimestamp = dateUtil.getTimeStamp(endDate) |
|
||||||
chooseAreaTimestamp = [startDateTimestamp, endDateTimestamp] |
|
||||||
} |
|
||||||
return { |
|
||||||
calendarData: { |
|
||||||
...calendarData, |
|
||||||
chooseAreaTimestamp, |
|
||||||
tempChooseAreaTimestamp, |
|
||||||
dates: __dates, |
|
||||||
selectedDates: __selectedDates |
|
||||||
}, |
|
||||||
calendarConfig: { |
|
||||||
...calendarConfig, |
|
||||||
multi: true |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
methods(component) { |
|
||||||
return { |
|
||||||
/** |
|
||||||
* 设置连续日期选择区域 |
|
||||||
* @param {array} dateArea 区域开始结束日期数组 |
|
||||||
*/ |
|
||||||
chooseDateArea: (dateArea = []) => { |
|
||||||
if (dateArea.length === 1) { |
|
||||||
dateArea = dateArea.concat(dateArea) |
|
||||||
} |
|
||||||
if (dateArea.length !== 2) return |
|
||||||
const isRight = validateTimeRange(dateArea) |
|
||||||
if (!isRight) return |
|
||||||
const config = getCalendarConfig(component) || {} |
|
||||||
const { startTimestamp, endTimestamp } = convertTimeRangeToTimestamp( |
|
||||||
dateArea |
|
||||||
) |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
return renderCalendar.call( |
|
||||||
component, |
|
||||||
{ |
|
||||||
...existCalendarData, |
|
||||||
chooseAreaTimestamp: [startTimestamp, endTimestamp] |
|
||||||
}, |
|
||||||
{ |
|
||||||
...config, |
|
||||||
multi: true, |
|
||||||
chooseAreaMode: true |
|
||||||
} |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,135 +0,0 @@ |
|||||||
/** |
|
||||||
* @Author: drfu* |
|
||||||
* @Description: 代办事项 |
|
||||||
* @Date: 2020-10-08 21:22:09* |
|
||||||
* @Last Modified by: drfu |
|
||||||
* @Last Modified time: 2020-10-11 14:23:02 |
|
||||||
* */ |
|
||||||
|
|
||||||
import { getCalendarData, dateUtil } from '../utils/index' |
|
||||||
import { renderCalendar } from '../render' |
|
||||||
|
|
||||||
function updateDatePropertyOfTodoLabel(todos, dates, showLabelAlways) { |
|
||||||
const datesInfo = [...dates] |
|
||||||
for (let todo of todos) { |
|
||||||
let targetIdx = datesInfo.findIndex( |
|
||||||
item => dateUtil.toTimeStr(item) === dateUtil.toTimeStr(todo) |
|
||||||
) |
|
||||||
let target = datesInfo[targetIdx] |
|
||||||
if (!target) continue |
|
||||||
if (showLabelAlways) { |
|
||||||
target.showTodoLabel = true |
|
||||||
} else { |
|
||||||
target.showTodoLabel = !target.choosed |
|
||||||
} |
|
||||||
if (target.showTodoLabel) { |
|
||||||
target.todoText = todo.todoText |
|
||||||
} |
|
||||||
target.color = todo.color |
|
||||||
} |
|
||||||
return datesInfo |
|
||||||
} |
|
||||||
|
|
||||||
export default () => { |
|
||||||
return { |
|
||||||
name: 'todo', |
|
||||||
beforeRender(calendarData = {}, calendarConfig = {}, component) { |
|
||||||
const { todos = [], dates = [], showLabelAlways } = calendarData |
|
||||||
const dateWithTodoInfo = updateDatePropertyOfTodoLabel( |
|
||||||
todos, |
|
||||||
dates, |
|
||||||
showLabelAlways |
|
||||||
) |
|
||||||
return { |
|
||||||
calendarData: { |
|
||||||
...calendarData, |
|
||||||
dates: dateWithTodoInfo |
|
||||||
}, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
}, |
|
||||||
methods(component) { |
|
||||||
return { |
|
||||||
setTodos: (options = {}) => { |
|
||||||
const calendar = getCalendarData('calendar', component) |
|
||||||
if (!calendar || !calendar.dates) { |
|
||||||
return Promise.reject('请等待日历初始化完成后再调用该方法') |
|
||||||
} |
|
||||||
const { |
|
||||||
circle, |
|
||||||
dotColor = '', |
|
||||||
pos = 'bottom', |
|
||||||
showLabelAlways, |
|
||||||
dates: todoDates = [] |
|
||||||
} = options |
|
||||||
const { todos = [] } = calendar |
|
||||||
const tranformStr2NumOfTodo = todoDates.map(date => |
|
||||||
dateUtil.tranformStr2NumOfDate(date) |
|
||||||
) |
|
||||||
const calendarData = { |
|
||||||
dates: calendar.dates, |
|
||||||
todos: dateUtil.uniqueArrayByDate( |
|
||||||
todos.concat(tranformStr2NumOfTodo) |
|
||||||
) |
|
||||||
} |
|
||||||
if (!circle) { |
|
||||||
calendarData.todoLabelPos = pos |
|
||||||
calendarData.todoLabelColor = dotColor |
|
||||||
} |
|
||||||
calendarData.todoLabelCircle = circle || false |
|
||||||
calendarData.showLabelAlways = showLabelAlways || false |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
...calendarData |
|
||||||
}) |
|
||||||
}, |
|
||||||
deleteTodos(todos = []) { |
|
||||||
if (!(todos instanceof Array) || !todos.length) |
|
||||||
return Promise.reject('deleteTodos()应为入参为非空数组') |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
const allTodos = existCalendarData.todos || [] |
|
||||||
const toDeleteTodos = todos.map(item => dateUtil.toTimeStr(item)) |
|
||||||
const remainTodos = allTodos.filter( |
|
||||||
item => !toDeleteTodos.includes(dateUtil.toTimeStr(item)) |
|
||||||
) |
|
||||||
const { dates, curYear, curMonth } = existCalendarData |
|
||||||
const _dates = [...dates] |
|
||||||
const currentMonthTodos = dateUtil.filterDatesByYM( |
|
||||||
{ |
|
||||||
year: curYear, |
|
||||||
month: curMonth |
|
||||||
}, |
|
||||||
remainTodos |
|
||||||
) |
|
||||||
_dates.forEach(item => { |
|
||||||
item.showTodoLabel = false |
|
||||||
}) |
|
||||||
currentMonthTodos.forEach(item => { |
|
||||||
_dates[item.date - 1].showTodoLabel = !_dates[item.date - 1].choosed |
|
||||||
}) |
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
dates: _dates, |
|
||||||
todos: remainTodos |
|
||||||
}) |
|
||||||
}, |
|
||||||
clearTodos() { |
|
||||||
const existCalendarData = getCalendarData('calendar', component) |
|
||||||
const _dates = [...existCalendarData.dates] |
|
||||||
_dates.forEach(item => { |
|
||||||
item.showTodoLabel = false |
|
||||||
}) |
|
||||||
return renderCalendar.call(component, { |
|
||||||
...existCalendarData, |
|
||||||
dates: _dates, |
|
||||||
todos: [] |
|
||||||
}) |
|
||||||
}, |
|
||||||
getTodos() { |
|
||||||
return getCalendarData('calendar.todos', component) || [] |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,432 +0,0 @@ |
|||||||
/** |
|
||||||
* @Author: drfu* |
|
||||||
* @Description: 周视图 |
|
||||||
* @Date: 2020-10-08 21:22:09* |
|
||||||
* @Last Modified by: drfu |
|
||||||
* @Last Modified time: 2020-10-12 14:39:45 |
|
||||||
* */ |
|
||||||
|
|
||||||
import { renderCalendar } from '../render' |
|
||||||
import { |
|
||||||
getCalendarConfig, |
|
||||||
getCalendarData, |
|
||||||
logger, |
|
||||||
dateUtil |
|
||||||
} from '../utils/index' |
|
||||||
import { calcJumpData } from '../core' |
|
||||||
|
|
||||||
/** |
|
||||||
* 当月第一周所有日期 |
|
||||||
*/ |
|
||||||
function firstWeekInMonth( |
|
||||||
target = {}, |
|
||||||
calendarDates = [], |
|
||||||
calendarConfig = {} |
|
||||||
) { |
|
||||||
const { firstDayOfWeek } = calendarConfig |
|
||||||
const firstDayOfWeekIsMon = firstDayOfWeek === 'Mon' |
|
||||||
const { year, month } = target |
|
||||||
let firstDay = dateUtil.getDayOfWeek(year, month, 1) |
|
||||||
if (firstDayOfWeekIsMon && firstDay === 0) { |
|
||||||
firstDay = 7 |
|
||||||
} |
|
||||||
const [, end] = [0, 7 - firstDay] |
|
||||||
return calendarDates.slice(0, firstDayOfWeekIsMon ? end + 1 : end) |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 当月最后一周所有日期 |
|
||||||
*/ |
|
||||||
function lastWeekInMonth(target = {}, calendarDates = [], calendarConfig = {}) { |
|
||||||
const { firstDayOfWeek } = calendarConfig |
|
||||||
const firstDayOfWeekIsMon = firstDayOfWeek === 'Mon' |
|
||||||
const { year, month } = target |
|
||||||
const lastDay = dateUtil.getDatesCountOfMonth(year, month) |
|
||||||
let lastDayWeek = dateUtil.getDayOfWeek(year, month, lastDay) |
|
||||||
if (firstDayOfWeekIsMon && lastDayWeek === 0) { |
|
||||||
lastDayWeek = 7 |
|
||||||
} |
|
||||||
const [start, end] = [lastDay - lastDayWeek, lastDay] |
|
||||||
return calendarDates.slice(firstDayOfWeekIsMon ? start : start - 1, end) |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 判断目标日期是否在某些指定日历内 |
|
||||||
*/ |
|
||||||
function dateIsInDatesRange(target, dates) { |
|
||||||
if (!target || !dates || !dates.length) return false |
|
||||||
const targetDateStr = dateUtil.toTimeStr(target) |
|
||||||
let rst = false |
|
||||||
for (let date of dates) { |
|
||||||
const dateStr = dateUtil.toTimeStr(date) |
|
||||||
if (dateStr === targetDateStr) { |
|
||||||
rst = true |
|
||||||
return rst |
|
||||||
} |
|
||||||
rst = false |
|
||||||
} |
|
||||||
return rst |
|
||||||
} |
|
||||||
|
|
||||||
function getDatesWhenTargetInFirstWeek(target, firstWeekDates) { |
|
||||||
const { year, month } = target |
|
||||||
const prevMonthInfo = dateUtil.getPrevMonthInfo({ year, month }) |
|
||||||
let lastMonthDatesCount = dateUtil.getDatesCountOfMonth( |
|
||||||
prevMonthInfo.year, |
|
||||||
prevMonthInfo.month |
|
||||||
) |
|
||||||
let dates = firstWeekDates |
|
||||||
let firstWeekCount = firstWeekDates.length |
|
||||||
for (let i = 0; i < 7 - firstWeekCount; i++) { |
|
||||||
const week = dateUtil.getDayOfWeek(+year, +month, lastMonthDatesCount) |
|
||||||
dates.unshift({ |
|
||||||
year: prevMonthInfo.year, |
|
||||||
month: prevMonthInfo.month, |
|
||||||
date: lastMonthDatesCount, |
|
||||||
week |
|
||||||
}) |
|
||||||
lastMonthDatesCount -= 1 |
|
||||||
} |
|
||||||
return dates |
|
||||||
} |
|
||||||
|
|
||||||
function getDatesWhenTargetInLastWeek(target, lastWeekDates) { |
|
||||||
const { year, month } = target |
|
||||||
const prevMonthInfo = dateUtil.getNextMonthInfo({ year, month }) |
|
||||||
let dates = lastWeekDates |
|
||||||
let lastWeekCount = lastWeekDates.length |
|
||||||
for (let i = 0; i < 7 - lastWeekCount; i++) { |
|
||||||
const week = dateUtil.getDayOfWeek(+year, +month, i + 1) |
|
||||||
dates.push({ |
|
||||||
year: prevMonthInfo.year, |
|
||||||
month: prevMonthInfo.month, |
|
||||||
date: i + 1, |
|
||||||
week |
|
||||||
}) |
|
||||||
} |
|
||||||
return dates |
|
||||||
} |
|
||||||
|
|
||||||
function getDates(target, calendarDates = [], calendarConfig = {}) { |
|
||||||
const { year, month, date } = target |
|
||||||
const targetDay = dateUtil.getDayOfWeek(year, month, date) |
|
||||||
const { firstDayOfWeek } = calendarConfig |
|
||||||
const firstDayOfWeekIsMon = firstDayOfWeek === 'Mon' |
|
||||||
if (firstDayOfWeekIsMon) { |
|
||||||
const startIdx = date - (targetDay || 7) |
|
||||||
return calendarDates.splice(startIdx, 7) |
|
||||||
} else { |
|
||||||
const startIdx = date - targetDay - 1 |
|
||||||
return calendarDates.splice(startIdx, 7) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function getTargetWeekDates(target, calendarConfig) { |
|
||||||
if (!target) return |
|
||||||
const { year, month } = target |
|
||||||
const calendarDates = dateUtil.calcDates(year, month) |
|
||||||
const firstWeekDates = firstWeekInMonth(target, calendarDates, calendarConfig) |
|
||||||
const lastWeekDates = lastWeekInMonth(target, calendarDates, calendarConfig) |
|
||||||
if (dateIsInDatesRange(target, firstWeekDates)) { |
|
||||||
return getDatesWhenTargetInFirstWeek(target, firstWeekDates) |
|
||||||
} else if (dateIsInDatesRange(target, lastWeekDates)) { |
|
||||||
return getDatesWhenTargetInLastWeek(target, lastWeekDates) |
|
||||||
} else { |
|
||||||
return getDates(target, calendarDates, calendarConfig) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 计算周视图下当前这一周最后一天 |
|
||||||
*/ |
|
||||||
function calculateLastDateOfCurrentWeek(calendarData = {}) { |
|
||||||
const { dates = [] } = calendarData |
|
||||||
return dates[dates.length - 1] |
|
||||||
} |
|
||||||
/** |
|
||||||
* 计算周视图下当前这一周第一天 |
|
||||||
*/ |
|
||||||
function calculateFirstDateOfCurrentWeek(calendarData = {}) { |
|
||||||
const { dates } = calendarData |
|
||||||
return dates[0] |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 计算下一周的日期 |
|
||||||
*/ |
|
||||||
function calculateNextWeekDates(calendarData = {}) { |
|
||||||
let { curYear, curMonth } = calendarData |
|
||||||
let calendarDates = [] |
|
||||||
let lastDateInThisWeek = calculateLastDateOfCurrentWeek(calendarData) |
|
||||||
const { year: LYear, month: LMonth } = lastDateInThisWeek |
|
||||||
if (curYear !== LYear || curMonth !== LMonth) { |
|
||||||
calendarDates = dateUtil.calcDates(LYear, LMonth) |
|
||||||
curYear = LYear |
|
||||||
curMonth = LMonth |
|
||||||
} else { |
|
||||||
calendarDates = dateUtil.calcDates(curYear, curMonth) |
|
||||||
} |
|
||||||
const lastDateInThisMonth = dateUtil.getDatesCountOfMonth(curYear, curMonth) |
|
||||||
const count = lastDateInThisMonth - lastDateInThisWeek.date |
|
||||||
const lastDateIdx = calendarDates.findIndex( |
|
||||||
date => dateUtil.toTimeStr(date) === dateUtil.toTimeStr(lastDateInThisWeek) |
|
||||||
) |
|
||||||
const startIdx = lastDateIdx + 1 |
|
||||||
if (count >= 7) { |
|
||||||
return { |
|
||||||
dates: calendarDates.splice(startIdx, 7), |
|
||||||
year: curYear, |
|
||||||
month: curMonth |
|
||||||
} |
|
||||||
} else { |
|
||||||
const nextMonth = dateUtil.getNextMonthInfo({ |
|
||||||
year: curYear, |
|
||||||
month: curMonth |
|
||||||
}) |
|
||||||
const { year, month } = nextMonth || {} |
|
||||||
const calendarDatesOfNextMonth = dateUtil.calcDates(year, month) |
|
||||||
const remainDatesOfThisMonth = calendarDates.splice(startIdx) |
|
||||||
const patchDatesOfNextMonth = calendarDatesOfNextMonth.splice( |
|
||||||
0, |
|
||||||
7 - remainDatesOfThisMonth.length |
|
||||||
) |
|
||||||
return { |
|
||||||
dates: [...remainDatesOfThisMonth, ...patchDatesOfNextMonth], |
|
||||||
...nextMonth |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 计算上一周的日期 |
|
||||||
*/ |
|
||||||
function calculatePrevWeekDates(calendarData = {}) { |
|
||||||
let { curYear, curMonth } = calendarData |
|
||||||
let firstDateInThisWeek = calculateFirstDateOfCurrentWeek(calendarData) |
|
||||||
let calendarDates = [] |
|
||||||
const { year: FYear, month: FMonth } = firstDateInThisWeek |
|
||||||
if (curYear !== FYear || curMonth !== FMonth) { |
|
||||||
calendarDates = dateUtil.calcDates(FYear, FMonth) |
|
||||||
curYear = FYear |
|
||||||
curMonth = FMonth |
|
||||||
} else { |
|
||||||
calendarDates = dateUtil.calcDates(curYear, curMonth) |
|
||||||
} |
|
||||||
const firstDateIdx = calendarDates.findIndex( |
|
||||||
date => dateUtil.toTimeStr(date) === dateUtil.toTimeStr(firstDateInThisWeek) |
|
||||||
) |
|
||||||
if (firstDateIdx - 7 >= 0) { |
|
||||||
const startIdx = firstDateIdx - 7 |
|
||||||
return { |
|
||||||
dates: calendarDates.splice(startIdx, 7), |
|
||||||
year: curYear, |
|
||||||
month: curMonth |
|
||||||
} |
|
||||||
} else { |
|
||||||
const prevMonth = dateUtil.getPrevMonthInfo({ |
|
||||||
year: curYear, |
|
||||||
month: curMonth |
|
||||||
}) |
|
||||||
const { year, month } = prevMonth || {} |
|
||||||
const calendarDatesOfPrevMonth = dateUtil.calcDates(year, month) |
|
||||||
const remainDatesOfThisMonth = calendarDates.splice( |
|
||||||
0, |
|
||||||
firstDateInThisWeek.date - 1 |
|
||||||
) |
|
||||||
const patchDatesOfPrevMonth = calendarDatesOfPrevMonth.splice( |
|
||||||
-(7 - remainDatesOfThisMonth.length) |
|
||||||
) |
|
||||||
return { |
|
||||||
dates: [...patchDatesOfPrevMonth, ...remainDatesOfThisMonth], |
|
||||||
...prevMonth |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default () => { |
|
||||||
return { |
|
||||||
name: 'week', |
|
||||||
beforeRender(calendarData = {}, calendarConfig = {}, component) { |
|
||||||
const { initializedWeekMode, selectedDates } = calendarData |
|
||||||
if (calendarConfig.weekMode && !initializedWeekMode) { |
|
||||||
const { defaultDate } = calendarConfig |
|
||||||
const target = |
|
||||||
(selectedDates && selectedDates[0]) || |
|
||||||
(defaultDate && dateUtil.transformDateRow2Dict(defaultDate)) || |
|
||||||
dateUtil.todayFMD() |
|
||||||
const waitRenderData = this.methods( |
|
||||||
component |
|
||||||
).__calcDatesWhenSwitchView('week', target) |
|
||||||
const { data, config } = waitRenderData || {} |
|
||||||
const setSelectDates = this.methods( |
|
||||||
component |
|
||||||
).__selectTargetDateWhenJump(target, data.dates, config) |
|
||||||
return { |
|
||||||
calendarData: { |
|
||||||
...data, |
|
||||||
...setSelectDates, |
|
||||||
weeksCh: dateUtil.getWeekHeader(calendarConfig.firstDayOfWeek), |
|
||||||
initializedWeekMode: true |
|
||||||
}, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
} |
|
||||||
return { |
|
||||||
calendarData, |
|
||||||
calendarConfig |
|
||||||
} |
|
||||||
}, |
|
||||||
onSwitchCalendar(target = {}, calendarData = {}, component) { |
|
||||||
const { direction } = target |
|
||||||
const { curYear, curMonth } = calendarData |
|
||||||
const calendarConfig = getCalendarConfig(component) |
|
||||||
let waitRenderData = {} |
|
||||||
if (calendarConfig.weekMode) { |
|
||||||
if (direction === 'left') { |
|
||||||
waitRenderData = calculateNextWeekDates(calendarData) |
|
||||||
} else { |
|
||||||
waitRenderData = calculatePrevWeekDates(calendarData) |
|
||||||
} |
|
||||||
const { dates, year, month } = waitRenderData |
|
||||||
return { |
|
||||||
...calendarData, |
|
||||||
dates, |
|
||||||
curYear: year || curYear, |
|
||||||
curMonth: month || curMonth |
|
||||||
} |
|
||||||
} |
|
||||||
return calendarData |
|
||||||
}, |
|
||||||
methods(component) { |
|
||||||
return { |
|
||||||
__selectTargetDateWhenJump: (target = {}, dates = [], config = {}) => { |
|
||||||
let selectedDate = target |
|
||||||
const weekDates = dates.map((date, idx) => { |
|
||||||
const tmp = { ...date } |
|
||||||
tmp.id = idx |
|
||||||
const isTarget = |
|
||||||
dateUtil.toTimeStr(target) === dateUtil.toTimeStr(tmp) |
|
||||||
if (isTarget && !target.choosed && config.autoChoosedWhenJump) { |
|
||||||
tmp.choosed = true |
|
||||||
selectedDate = tmp |
|
||||||
} |
|
||||||
return tmp |
|
||||||
}) |
|
||||||
return { |
|
||||||
dates: weekDates, |
|
||||||
selectedDates: [selectedDate] |
|
||||||
} |
|
||||||
}, |
|
||||||
__calcDatesForWeekMode(target, config = {}, calendarData = {}) { |
|
||||||
const { year, month } = target || {} |
|
||||||
const weekDates = getTargetWeekDates(target, config) |
|
||||||
weekDates.forEach((date, idx) => (date.id = idx)) |
|
||||||
return { |
|
||||||
data: { |
|
||||||
...calendarData, |
|
||||||
prevMonthGrids: null, |
|
||||||
nextMonthGrids: null, |
|
||||||
dates: weekDates, |
|
||||||
curYear: year, |
|
||||||
curMonth: month |
|
||||||
}, |
|
||||||
config: { |
|
||||||
...config, |
|
||||||
weekMode: true |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
__calcDatesForMonthMode(target, config = {}, calendarData = {}) { |
|
||||||
const { year, month } = target || {} |
|
||||||
const waitRenderData = calcJumpData({ |
|
||||||
dateInfo: target, |
|
||||||
config |
|
||||||
}) |
|
||||||
return { |
|
||||||
data: { |
|
||||||
...calendarData, |
|
||||||
...waitRenderData, |
|
||||||
curYear: year, |
|
||||||
curMonth: month |
|
||||||
}, |
|
||||||
config: { |
|
||||||
...config, |
|
||||||
weekMode: false |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
/** |
|
||||||
* 周、月视图切换 |
|
||||||
* @param {string} view 视图 [week, month] |
|
||||||
* @param {object} target |
|
||||||
*/ |
|
||||||
__calcDatesWhenSwitchView: (view, target) => { |
|
||||||
const calendarConfig = getCalendarConfig(component) |
|
||||||
if (calendarConfig.multi) |
|
||||||
return logger.warn('多选模式不能切换周月视图') |
|
||||||
const existCalendarData = getCalendarData('calendar', component) || {} |
|
||||||
const { |
|
||||||
selectedDates = [], |
|
||||||
dates = [], |
|
||||||
curYear, |
|
||||||
curMonth |
|
||||||
} = existCalendarData |
|
||||||
const currentMonthSelected = selectedDates.filter( |
|
||||||
item => curYear === +item.year || curMonth === +item.month |
|
||||||
) |
|
||||||
let jumpTarget = {} |
|
||||||
if (target) { |
|
||||||
jumpTarget = target |
|
||||||
} else { |
|
||||||
if (currentMonthSelected.length) { |
|
||||||
jumpTarget = currentMonthSelected.pop() |
|
||||||
} else { |
|
||||||
jumpTarget = dates[0] |
|
||||||
} |
|
||||||
} |
|
||||||
if (view === 'week') { |
|
||||||
return this.methods(component).__calcDatesForWeekMode( |
|
||||||
jumpTarget, |
|
||||||
calendarConfig, |
|
||||||
existCalendarData |
|
||||||
) |
|
||||||
} else { |
|
||||||
return this.methods(component).__calcDatesForMonthMode( |
|
||||||
jumpTarget, |
|
||||||
calendarConfig, |
|
||||||
existCalendarData |
|
||||||
) |
|
||||||
} |
|
||||||
}, |
|
||||||
weekModeJump: dateInfo => { |
|
||||||
const target = dateInfo || dateUtil.todayFMD() |
|
||||||
const existCalendarData = getCalendarData('calendar', component) || {} |
|
||||||
const waitRenderData = this.methods( |
|
||||||
component |
|
||||||
).__calcDatesWhenSwitchView('week', target) |
|
||||||
const { data, config } = waitRenderData || {} |
|
||||||
const setSelectDates = this.methods( |
|
||||||
component |
|
||||||
).__selectTargetDateWhenJump(target, data.dates, config) |
|
||||||
return renderCalendar.call( |
|
||||||
component, |
|
||||||
{ |
|
||||||
...existCalendarData, |
|
||||||
...data, |
|
||||||
...setSelectDates |
|
||||||
}, |
|
||||||
config |
|
||||||
) |
|
||||||
}, |
|
||||||
switchView: (view, target) => { |
|
||||||
const waitRenderData = this.methods( |
|
||||||
component |
|
||||||
).__calcDatesWhenSwitchView(view, target) |
|
||||||
const { data, config } = waitRenderData || {} |
|
||||||
if (!data) return logger.warn('当前状态不能切换为周视图') |
|
||||||
return renderCalendar.call(component, data, config) |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,49 +0,0 @@ |
|||||||
import plugins from "./plugins/index"; |
|
||||||
import { getCalendarConfig } from "./utils/index"; |
|
||||||
|
|
||||||
/** |
|
||||||
* 渲染日历 |
|
||||||
*/ |
|
||||||
export function renderCalendar(calendarData, calendarConfig) { |
|
||||||
return new Promise((resolve) => { |
|
||||||
const Component = this; |
|
||||||
if (Component.firstRender === void 0) { |
|
||||||
Component.firstRender = true; |
|
||||||
} else { |
|
||||||
Component.firstRender = false; |
|
||||||
} |
|
||||||
const exitData = Component.data.calendar || {}; |
|
||||||
for (let plugin of plugins.installed) { |
|
||||||
const [, p] = plugin; |
|
||||||
if (typeof p.beforeRender === "function") { |
|
||||||
const { calendarData: newData, calendarConfig: newConfig } = |
|
||||||
p.beforeRender( |
|
||||||
{ ...exitData, ...calendarData }, |
|
||||||
calendarConfig || getCalendarConfig(Component), |
|
||||||
Component |
|
||||||
); |
|
||||||
calendarData = newData; |
|
||||||
calendarConfig = newConfig; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
Component.setData( |
|
||||||
{ |
|
||||||
config: calendarConfig, |
|
||||||
calendar: calendarData, |
|
||||||
}, |
|
||||||
() => { |
|
||||||
const rst = { |
|
||||||
calendar: calendarData, |
|
||||||
config: calendarConfig, |
|
||||||
firstRender: Component.firstRender, |
|
||||||
}; |
|
||||||
resolve(rst); |
|
||||||
if (Component.firstRender) { |
|
||||||
Component.triggerEvent("afterCalendarRender", rst); |
|
||||||
Component.firstRender = false; |
|
||||||
} |
|
||||||
} |
|
||||||
); |
|
||||||
}); |
|
||||||
} |
|
@ -1,29 +0,0 @@ |
|||||||
@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"; |
|
||||||
} |
|
@ -1,61 +0,0 @@ |
|||||||
|
|
||||||
/* 日历主要颜色相关样式 */ |
|
||||||
|
|
||||||
.default_color, |
|
||||||
.default_weekend-color, |
|
||||||
.default_handle-color, |
|
||||||
.default_week-color { |
|
||||||
color: #ff629a; |
|
||||||
} |
|
||||||
|
|
||||||
.default_today { |
|
||||||
color: #fff; |
|
||||||
background-color: #874fb4; |
|
||||||
} |
|
||||||
|
|
||||||
.default_choosed { |
|
||||||
color: #fff; |
|
||||||
background-color: #ff629a; |
|
||||||
} |
|
||||||
|
|
||||||
.default_date-disable { |
|
||||||
color: #c7c7c7; |
|
||||||
} |
|
||||||
|
|
||||||
.default_choosed.default_date-disable { |
|
||||||
color: #e2e2e2; |
|
||||||
background-color: #c2afb6; |
|
||||||
} |
|
||||||
|
|
||||||
.default_prev-month-date, |
|
||||||
.default_next-month-date { |
|
||||||
color: #e2e2e2; |
|
||||||
} |
|
||||||
|
|
||||||
.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; |
|
||||||
} |
|
||||||
|
|
||||||
.default_festival { |
|
||||||
color: #c2c2c2; |
|
||||||
} |
|
@ -1,58 +0,0 @@ |
|||||||
.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_choosed.elegant_date-disable { |
|
||||||
color: #999; |
|
||||||
background-color: #ebebeb; |
|
||||||
} |
|
||||||
|
|
||||||
.elegant_prev-month-date, |
|
||||||
.elegant_next-month-date { |
|
||||||
color: #e2e2e2; |
|
||||||
} |
|
||||||
|
|
||||||
.elegant_normal-date { |
|
||||||
color: #777; |
|
||||||
} |
|
||||||
|
|
||||||
.elegant_todo-circle { |
|
||||||
border-color: #161035; |
|
||||||
} |
|
||||||
|
|
||||||
.elegant_todo-dot { |
|
||||||
background-color: #161035; |
|
||||||
} |
|
||||||
|
|
||||||
.elegant_date-desc { |
|
||||||
color: #c2c2c2; |
|
||||||
} |
|
||||||
|
|
||||||
.elegant_date-desc-lunar { |
|
||||||
color: #161035; |
|
||||||
} |
|
||||||
|
|
||||||
.elegant_date-desc-disable { |
|
||||||
color: #e2e2e2; |
|
||||||
} |
|
||||||
|
|
||||||
.elegant_festival { |
|
||||||
color: #c2c2c2; |
|
||||||
} |
|
@ -1,90 +0,0 @@ |
|||||||
/* 日历主要颜色相关样式 */ |
|
||||||
|
|
||||||
.nuohe_color, |
|
||||||
.nuohe_weekend-color, |
|
||||||
.nuohe_handle-color, |
|
||||||
.nuohe_week-color { |
|
||||||
color: rgba(51, 51, 51, 1); |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_today { |
|
||||||
color: #fff; |
|
||||||
background-color: #874fb4; |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_choosed { |
|
||||||
color: rgba(51, 51, 51, 1); |
|
||||||
background-color: rgba(189, 189, 189, 0.3); |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_date-disable { |
|
||||||
color: #c7c7c7; |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_choosed.nuohe_date-disable { |
|
||||||
color: #e2e2e2; |
|
||||||
background-color: #c2afb6; |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_prev-month-date, |
|
||||||
.nuohe_next-month-date { |
|
||||||
color: #e2e2e2; |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_normal-date { |
|
||||||
color: rgba(51, 51, 51, 1); |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_todo-circle { |
|
||||||
border-color: #88d2ac; |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_todo-dot { |
|
||||||
background-color: #e54d42; |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_date-desc { |
|
||||||
color: #c2c2c2; |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_date-desc-lunar { |
|
||||||
color: #e54d42; |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_date-desc-disable { |
|
||||||
color: #e2e2e2; |
|
||||||
} |
|
||||||
|
|
||||||
.nuohe_festival { |
|
||||||
color: #c2c2c2; |
|
||||||
} |
|
||||||
|
|
||||||
.date.doc { |
|
||||||
position: relative; |
|
||||||
background-color: #e5e5e5; |
|
||||||
} |
|
||||||
|
|
||||||
.date.doc::after { |
|
||||||
position: absolute; |
|
||||||
z-index: 1; |
|
||||||
top: -5rpx; |
|
||||||
right: -5rpx; |
|
||||||
content: ""; |
|
||||||
width: 17rpx; |
|
||||||
height: 24rpx; |
|
||||||
background-repeat: no-repeat; |
|
||||||
background-size: cover; |
|
||||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAABACAYAAABhspUgAAAAAXNSR0IArs4c6QAACAVJREFUaEPtmltsHFcZx/9nZu92bMdJSMitzoWkoXVKUrVV8wKk4gHxgJTwgKA8lhfgCZBoUJEqUYGA0AhRQUSpFJQIHlyqogZFIipUoKiAKJAYQkp9qR1ir9fe6+zuXM4FfWf2MrOJY+/aS0zlkRxZzsw5v/nP/3znO+c7DItcl4vFTWVl/7wg5EctKSK2knCVBFcKcrGH7vL3MvfwVnYeGbsaustgAAODCSDCDLU1Hp/Ym+o7fnrvB9+9U3NssT5ezWe+k5X8qwvCQ0FwVKSEswJg6sfmHH+cm2l0SZ3Tj8F84ChjiDID+1I9ly4ceuTjbQFfyM2MpDk/meEu8oKjJIUG9khh1YHEtUeupgPAWl3AAENEwzLEmIGd8dToq8OPDbcF/OLCrZFZ7p5Mcxc5wVEUAmQLT8mOLFHvfCwzF7ZEC3CcGdiRSIxeHD7WHvDZhZsjM56ngbMELDlsWVO4c4ExOd8E9i1R969vhzhj2BFPjv76cJvApPCtkMK8YYkVOALLUXh7PNE+8M/Iw553MiN8S1ii6eGVAI+mZ0PfhzHoAWfWBlyMMWyPJ0dfG368PUu8nJ8bWRD8ZPYOUWIlwH+YmQ4Dg8FoAPu22J5Ijb7ywKPtAV8uZZ/LC36qIH11q7UIIZRCp8CW5+Ly7M3bgVkzUlC0ONC74VcvHTj6ybaiBN38RmVhV9YxTBs2nrl08VTRrjy1gvEGZRh+HGu5epOp808ceehMFFEkDYN/f++Df1+sn0UnjtYHjB9+63tQ6ssrAV70WcZOyy8+/ZXltL0o8Hfzk3u4jc94Bh7nSm0uOZWNruvFozBMkzEG+iF3KGm5XJTAZFVIxRXCjnGkNB0pIwXPTWYcu6/MeYLAgh1HozHeE48VE6Y5vyFiXknFoufO73/4nWVZ4kwmc9BG5QVLiONcKSYYEFU0z/vd1P3rQaEiBYiwnSvr2Jgo5mFxTz9Gcbj+AjTjmczPKbbF41fej9jnzz5w9J/B9kMKP58e/1xO4ayjZNKlwaUUkqYJJZsDjRKfBcH1dN3pRa3dKpUwX61oqRs5RS1amLWpOmWYzv5k7xfO3X/0p/W+GsBnMtNPLQjvx1UlDUcKQDEkDKanYRJR6W+tMM0dzPPOYYMvmauWkStXfOBA1kYxWecWMJAwDHV/T9+Xzh088kLDSmfmpx9b8Lw3qpDxqv7MCilmaFBJ/9aMmZYcY05VK78aFw2DrGXBdp2AymSLQDIEAynD9B4c3PKRnwwduqIV/ubc5N+Kgj9EnqQEhxIQ+iwyEHPJIm+WSxBMj7TV4NX+lVIiXyzURGCg/NjP3ijdNEAzH/FsjcX/dWn42CH2g+zMJ9Ju5bWyFDrnFQB6GMGSur4N6Bpzq5hwnVUBbW2kWq3CcXyV6QoMvgZwghk43Dtwgn17burlrHBPaGAlEQFDnN68Bku41NDvrQLsVVK2FZhzAcsqNYCpP/rCZA2tsGGAgIeSvRfZs3Pj0wUhdpZr028vo/cj4OaHJ+WvVIpdUbfeaKHg26KpMoU3P7cgaALeHIun2TPpcaskeE9ZSp0v9DPTjwoB4Cytx+xyV4FLxSKE9FeL9TDnZ3D+KoSA+yIRm52aGVOWEiBLVKXEoBHRdtDRoXbNcQ9XuwxMliBrhIBr8VgDGwxJZoI9TcCSo6wkHCmxUQOHV8Zz3MVVu9JVha2SBR6YjCjlrK/1tCUMwwf+WgDYrQGLlsC1VoDJFiHgoMLBSLsWgClSJOvAJdncd6hbYi0B08DzLVFTeB24g+F5t0G3rnAHgt72yLrC93LieO952ARHVDWXQQVuYbqaWQ2rLtrGVJmhEljR6pyRFqS1fIKS+LjB/JmuNQ7vlrMYUs1dxp3udRwrvdJV4GedJ3BDbl6yj1UFdgsJVNMbQp0mt5UQ67OXBLknwOO/OILi2KYQXN++Bez99F/XJvA75x+G9e7GEFzvfTnsf/Iv68CNKhFla50OujWtsD3fA2tyMPSpM3/eBSebCv0tPljBlkfCm9i9Q1kkNofXiF0fdJO/HEb++tYlvXmnGwYOpTF04lrov7oOPDFyGIUb7+sIuP9gBns+Fd6zXgdunen+7xT+z28OIPOn3R1ZYsujU9jxsbf/tx6m3pQMVxzGLhyFNdUycezOYd9n3wrBMeP23c+ue/hO0q7pOLwOfC/Sy1uvfwDZa9tC4g8Oz2L78X8vOTjviYeXpLrLDSsC3qqy2KZyjeYH3EnsKf92JTxLPvti9UOYkv233eefWKEqE52rWGSJFNx9pxbu9Wbge2/VvOYVru/Ar+UN7cb+8FosGTRrz35RpulhE+zrs1TjoKKMf5BuIzN1cTFYRcpwD6NOd2scxRIVZZqbN/q0la7sN6tIumTwjdlxXUWqCAIW6KeiTMtxxXnh4boTPoK4ZJxq84ZssQgvAEwl3HpVXyusK0kG2HNzk/mSEP0VJfS5NCosKjq7USuAU15lKYkbXa4i3czlwOkUQe0KAtfrzf2RqMVOZ6Z+VxD8w1RUJEtElV9JDx4Ipd8nXFtX+btxOULg7ay/d9eohDL/tFX9PCZB70qk3mQ/ys0M5T3nWlXKXqrYcyaRpFtrRw7qiPQyRa3Aso8JLevdqAg/mptHwW1uZ9XPYxIwiUc/GyLRyuH+LcO6d4KuCv5SRYojrpQDFIcjMLTp60dcdMJel6D1YM+y0MI3uUIg57n4RyGLoueGE/xar2SLHsO0NsXi13b1DDz5/H0Hxv8Lo3UyF0Y2DrcAAAAASUVORK5CYII="); |
|
||||||
} |
|
||||||
|
|
||||||
.date.error { |
|
||||||
background-color: rgba(207, 83, 117, 1); |
|
||||||
border-radius: 50%; |
|
||||||
color: #fff; |
|
||||||
} |
|
||||||
|
|
||||||
.date.primary { |
|
||||||
background-color: rgba(37, 217, 200, 1); |
|
||||||
color: #fff; |
|
||||||
border-radius: 50%; |
|
||||||
} |
|
@ -1,275 +0,0 @@ |
|||||||
import Logger from "./logger"; |
|
||||||
import WxData from "./wxData"; |
|
||||||
|
|
||||||
let systemInfo; |
|
||||||
export function getSystemInfo() { |
|
||||||
if (systemInfo) return systemInfo; |
|
||||||
systemInfo = wx.getSystemInfoSync(); |
|
||||||
return systemInfo; |
|
||||||
} |
|
||||||
|
|
||||||
export function isIos() { |
|
||||||
const sys = getSystemInfo(); |
|
||||||
return /iphone|ios/i.test(sys.platform); |
|
||||||
} |
|
||||||
|
|
||||||
class Gesture { |
|
||||||
/** |
|
||||||
* 左滑 |
|
||||||
* @param {object} e 事件对象 |
|
||||||
* @returns {boolean} 布尔值 |
|
||||||
*/ |
|
||||||
isLeft(gesture = {}, touche = {}) { |
|
||||||
const { startX, startY } = gesture; |
|
||||||
const deltaX = touche.clientX - startX; |
|
||||||
const deltaY = touche.clientY - startY; |
|
||||||
if (deltaX < -60 && deltaY < 20 && deltaY > -20) { |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
/** |
|
||||||
* 右滑 |
|
||||||
* @param {object} e 事件对象 |
|
||||||
* @returns {boolean} 布尔值 |
|
||||||
*/ |
|
||||||
isRight(gesture = {}, touche = {}) { |
|
||||||
const { startX, startY } = gesture; |
|
||||||
const deltaX = touche.clientX - startX; |
|
||||||
const deltaY = touche.clientY - startY; |
|
||||||
|
|
||||||
if (deltaX > 60 && deltaY < 20 && deltaY > -20) { |
|
||||||
return true; |
|
||||||
} else { |
|
||||||
return false; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
class DateUtil { |
|
||||||
newDate(year, month, date) { |
|
||||||
let cur = `${+year}-${+month}-${+date}`; |
|
||||||
if (isIos()) { |
|
||||||
cur = `${+year}/${+month}/${+date}`; |
|
||||||
} |
|
||||||
return new Date(cur); |
|
||||||
} |
|
||||||
/** |
|
||||||
* 计算指定日期时间戳 |
|
||||||
* @param {object} date |
|
||||||
*/ |
|
||||||
getTimeStamp(dateInfo) { |
|
||||||
if (typeof dateInfo === "string") { |
|
||||||
dateInfo = this.transformDateRow2Dict(dateInfo); |
|
||||||
} |
|
||||||
if (Object.prototype.toString.call(dateInfo) !== "[object Object]") return; |
|
||||||
const dateUtil = new DateUtil(); |
|
||||||
return dateUtil.newDate(dateInfo.year, dateInfo.month, dateInfo.date).getTime(); |
|
||||||
} |
|
||||||
/** |
|
||||||
* 计算指定月份共多少天 |
|
||||||
* @param {number} year 年份 |
|
||||||
* @param {number} month 月份 |
|
||||||
*/ |
|
||||||
getDatesCountOfMonth(year, month) { |
|
||||||
return new Date(Date.UTC(year, month, 0)).getUTCDate(); |
|
||||||
} |
|
||||||
/** |
|
||||||
* 计算指定月份第一天星期几 |
|
||||||
* @param {number} year 年份 |
|
||||||
* @param {number} month 月份 |
|
||||||
*/ |
|
||||||
firstDayOfWeek(year, month) { |
|
||||||
return new Date(Date.UTC(year, month - 1, 1)).getUTCDay(); |
|
||||||
} |
|
||||||
/** |
|
||||||
* 计算指定日期星期几 |
|
||||||
* @param {number} year 年份 |
|
||||||
* @param {number} month 月份 |
|
||||||
* @param {number} date 日期 |
|
||||||
*/ |
|
||||||
getDayOfWeek(year, month, date) { |
|
||||||
return new Date(Date.UTC(year, month - 1, date)).getUTCDay(); |
|
||||||
} |
|
||||||
todayFMD() { |
|
||||||
const _date = new Date(); |
|
||||||
const year = _date.getFullYear(); |
|
||||||
const month = _date.getMonth() + 1; |
|
||||||
const date = _date.getDate(); |
|
||||||
return { |
|
||||||
year: +year, |
|
||||||
month: +month, |
|
||||||
date: +date, |
|
||||||
}; |
|
||||||
} |
|
||||||
todayTimestamp() { |
|
||||||
const { year, month, date } = this.todayFMD(); |
|
||||||
const timestamp = this.newDate(year, month, date).getTime(); |
|
||||||
return timestamp; |
|
||||||
} |
|
||||||
toTimeStr(dateInfo = {}) { |
|
||||||
return `${+dateInfo.year}-${+dateInfo.month}-${+dateInfo.date}`; |
|
||||||
} |
|
||||||
transformDateRow2Dict(dateStr) { |
|
||||||
if (typeof dateStr === "string" && dateStr.includes("-")) { |
|
||||||
const [year, month, date] = dateStr.split("-"); |
|
||||||
return this.tranformStr2NumOfDate({ |
|
||||||
year, |
|
||||||
month, |
|
||||||
date, |
|
||||||
}); |
|
||||||
} |
|
||||||
return {}; |
|
||||||
} |
|
||||||
tranformStr2NumOfDate(date = {}) { |
|
||||||
const target = { ...date }; |
|
||||||
// 可能传入字符串
|
|
||||||
target.year = +target.year; |
|
||||||
target.month = +target.month; |
|
||||||
target.date = +target.date; |
|
||||||
return target; |
|
||||||
} |
|
||||||
sortDatesByTime(dates = [], sortType) { |
|
||||||
return dates.sort((a, b) => { |
|
||||||
const at = this.getTimeStamp(a); |
|
||||||
const bt = this.getTimeStamp(b); |
|
||||||
if (at < bt && sortType !== "desc") { |
|
||||||
return -1; |
|
||||||
} else { |
|
||||||
return 1; |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
getPrevMonthInfo(date = {}) { |
|
||||||
const prevMonthInfo = |
|
||||||
Number(date.month) > 1 |
|
||||||
? { |
|
||||||
year: +date.year, |
|
||||||
month: Number(date.month) - 1, |
|
||||||
} |
|
||||||
: { |
|
||||||
year: Number(date.year) - 1, |
|
||||||
month: 12, |
|
||||||
}; |
|
||||||
return prevMonthInfo; |
|
||||||
} |
|
||||||
getNextMonthInfo(date = {}) { |
|
||||||
const nextMonthInfo = |
|
||||||
Number(date.month) < 12 |
|
||||||
? { |
|
||||||
year: +date.year, |
|
||||||
month: Number(date.month) + 1, |
|
||||||
} |
|
||||||
: { |
|
||||||
year: Number(date.year) + 1, |
|
||||||
month: 1, |
|
||||||
}; |
|
||||||
return nextMonthInfo; |
|
||||||
} |
|
||||||
getPrevYearInfo(date = {}) { |
|
||||||
return { |
|
||||||
year: Number(date.year) - 1, |
|
||||||
month: +date.month, |
|
||||||
}; |
|
||||||
} |
|
||||||
getNextYearInfo(date = {}) { |
|
||||||
return { |
|
||||||
year: Number(date.year) + 1, |
|
||||||
month: +date.month, |
|
||||||
}; |
|
||||||
} |
|
||||||
findDateIndexInArray(target, dates) { |
|
||||||
return dates.findIndex((item) => dateUtil.toTimeStr(item) === dateUtil.toTimeStr(target)); |
|
||||||
} |
|
||||||
calcDates(year, month) { |
|
||||||
const datesCount = this.getDatesCountOfMonth(year, month); |
|
||||||
const dates = []; |
|
||||||
const today = dateUtil.todayFMD(); |
|
||||||
for (let i = 1; i <= datesCount; i++) { |
|
||||||
const week = dateUtil.getDayOfWeek(+year, +month, i); |
|
||||||
const date = { |
|
||||||
year: +year, |
|
||||||
id: i - 1, |
|
||||||
month: +month, |
|
||||||
date: i, |
|
||||||
week, |
|
||||||
isToday: +today.year === +year && +today.month === +month && i === +today.date, |
|
||||||
}; |
|
||||||
dates.push(date); |
|
||||||
} |
|
||||||
return dates; |
|
||||||
} |
|
||||||
/** |
|
||||||
* 日期数组根据日期去重 |
|
||||||
* @param {array} array 数组 |
|
||||||
*/ |
|
||||||
uniqueArrayByDate(array = []) { |
|
||||||
let uniqueObject = {}; |
|
||||||
let uniqueArray = []; |
|
||||||
array.forEach((item) => { |
|
||||||
uniqueObject[dateUtil.toTimeStr(item)] = item; |
|
||||||
}); |
|
||||||
for (let i in uniqueObject) { |
|
||||||
uniqueArray.push(uniqueObject[i]); |
|
||||||
} |
|
||||||
return uniqueArray; |
|
||||||
} |
|
||||||
/** |
|
||||||
* 筛选指定年月日期 |
|
||||||
* @param {object} target 指定年月 |
|
||||||
* @param {array} dates 待筛选日期 |
|
||||||
*/ |
|
||||||
filterDatesByYM(target, dates) { |
|
||||||
if (target) { |
|
||||||
const { year, month } = target; |
|
||||||
const _dates = dates.filter((item) => +item.year === +year && +item.month === +month); |
|
||||||
return _dates; |
|
||||||
} |
|
||||||
return dates; |
|
||||||
} |
|
||||||
getWeekHeader(firstDayOfWeek) { |
|
||||||
let weeksCh = ["日", "一", "二", "三", "四", "五", "六"]; |
|
||||||
if (firstDayOfWeek === "Mon") { |
|
||||||
weeksCh = ["一", "二", "三", "四", "五", "六", "日"]; |
|
||||||
} |
|
||||||
return weeksCh; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* 获取当前页面实例 |
|
||||||
*/ |
|
||||||
export function getCurrentPage() { |
|
||||||
const pages = getCurrentPages() || []; |
|
||||||
const last = pages.length - 1; |
|
||||||
return pages[last] || {}; |
|
||||||
} |
|
||||||
|
|
||||||
export function getComponentById(componentId) { |
|
||||||
const logger = new Logger(); |
|
||||||
let page = getCurrentPage() || {}; |
|
||||||
if (page.selectComponent && typeof page.selectComponent === "function") { |
|
||||||
if (componentId) { |
|
||||||
return page.selectComponent(componentId); |
|
||||||
} else { |
|
||||||
logger.warn("请传入组件ID"); |
|
||||||
} |
|
||||||
} else { |
|
||||||
logger.warn("该基础库暂不支持多个小程序日历组件"); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export const logger = new Logger(); |
|
||||||
export const calendarGesture = new Gesture(); |
|
||||||
export const dateUtil = new DateUtil(); |
|
||||||
export const getCalendarData = (key, component) => new WxData(component).getData(key); |
|
||||||
export const setCalendarData = (data, component) => new WxData(component).setData(data); |
|
||||||
export const getCalendarConfig = (component) => getCalendarData("config", component); |
|
||||||
export const setCalendarConfig = (config, component) => |
|
||||||
setCalendarData( |
|
||||||
{ |
|
||||||
config, |
|
||||||
}, |
|
||||||
component, |
|
||||||
); |
|
@ -1,23 +0,0 @@ |
|||||||
export default class Logger { |
|
||||||
info(msg) { |
|
||||||
console.log( |
|
||||||
'%cInfo: %c' + msg, |
|
||||||
'color:#FF0080;font-weight:bold', |
|
||||||
'color: #FF509B' |
|
||||||
) |
|
||||||
} |
|
||||||
warn(msg) { |
|
||||||
console.log( |
|
||||||
'%cWarn: %c' + msg, |
|
||||||
'color:#FF6600;font-weight:bold', |
|
||||||
'color: #FF9933' |
|
||||||
) |
|
||||||
} |
|
||||||
tips(msg) { |
|
||||||
console.log( |
|
||||||
'%cTips: %c' + msg, |
|
||||||
'color:#00B200;font-weight:bold', |
|
||||||
'color: #00CC33' |
|
||||||
) |
|
||||||
} |
|
||||||
} |
|
@ -1,30 +0,0 @@ |
|||||||
class WxData { |
|
||||||
constructor(component) { |
|
||||||
this.Component = component |
|
||||||
} |
|
||||||
getData(key) { |
|
||||||
const data = this.Component.data |
|
||||||
if (!key) return data |
|
||||||
if (key.includes('.')) { |
|
||||||
let keys = key.split('.') |
|
||||||
const tmp = keys.reduce((prev, next) => { |
|
||||||
return prev[next] |
|
||||||
}, data) |
|
||||||
return tmp |
|
||||||
} else { |
|
||||||
return this.Component.data[key] |
|
||||||
} |
|
||||||
} |
|
||||||
setData(data) { |
|
||||||
return new Promise((resolve, reject) => { |
|
||||||
if (!data) return reject('no data to set') |
|
||||||
if (typeof data === 'object') { |
|
||||||
this.Component.setData(data, () => { |
|
||||||
resolve(data) |
|
||||||
}) |
|
||||||
} |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
export default WxData |
|
@ -1,160 +0,0 @@ |
|||||||
# 海报插件 |
|
||||||
|
|
||||||
## 基于[wxml2canvas](https://github.com/wg-front/wxml2canvas)插件 |
|
||||||
|
|
||||||
### 插件引入 |
|
||||||
|
|
||||||
```json |
|
||||||
{ |
|
||||||
"customPoster": "/components/customPoster/index" |
|
||||||
} |
|
||||||
``` |
|
||||||
|
|
||||||
```wxml |
|
||||||
<customPoster params="{{params}}"></customPoster> |
|
||||||
``` |
|
||||||
|
|
||||||
### 参数示例 |
|
||||||
|
|
||||||
```js |
|
||||||
const data = { |
|
||||||
params: { |
|
||||||
info: { id: 'circle-note_mp', title: '动态页', desc: '指定动态的页面,mp' }, |
|
||||||
body: { |
|
||||||
bgImg: |
|
||||||
'https://picsissiok-10049618.cos.ap-shanghai.myqcloud.com/a74018e725861534f1644cff04780f4e_16273677601587.png', |
|
||||||
width: '750', |
|
||||||
height: '1254', |
|
||||||
}, |
|
||||||
elements: [ |
|
||||||
{ |
|
||||||
id: 'circle-name', |
|
||||||
desc: '圈名称', |
|
||||||
type: 1, |
|
||||||
text: '治疗讨论', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '42', |
|
||||||
color: '#FFFFFF', |
|
||||||
'single-line': true, |
|
||||||
halign: 'center', |
|
||||||
top: '106', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'master-name', |
|
||||||
desc: '专家名称', |
|
||||||
type: 1, |
|
||||||
text: '健康小贴士', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '38', |
|
||||||
color: '#FFFFFF', |
|
||||||
'single-line': true, |
|
||||||
halign: 'center', |
|
||||||
top: '237', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'master-avatar', |
|
||||||
desc: '专家头像', |
|
||||||
type: 0, |
|
||||||
picType: 'avatar', |
|
||||||
src: 'https://picsissiok-10049618.cos.ap-shanghai.myqcloud.com/ceb31ac6137e873225b8cc826389a267_16655329078962.jpg', |
|
||||||
width: '120', |
|
||||||
height: '120', |
|
||||||
halign: 'center', |
|
||||||
shape: 'circle', |
|
||||||
top: '328', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-content', |
|
||||||
desc: '动态内容', |
|
||||||
type: 1, |
|
||||||
text: '11月5日上海组织进口博览会CIIE大会,邀请大家来我们的展馆现场交流。', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '45', |
|
||||||
color: '#18191A', |
|
||||||
width: '630', |
|
||||||
height: '348', |
|
||||||
left: '60', |
|
||||||
top: '495', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-title', |
|
||||||
desc: '长文标题', |
|
||||||
type: 1, |
|
||||||
text: '', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '42', |
|
||||||
color: '#18191A', |
|
||||||
width: '659', |
|
||||||
height: '116', |
|
||||||
left: '46', |
|
||||||
top: '495', |
|
||||||
'font-weight': 'bold', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-summary', |
|
||||||
desc: '长文摘要 ', |
|
||||||
type: 1, |
|
||||||
text: '', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '42', |
|
||||||
color: '#18191A', |
|
||||||
width: '672', |
|
||||||
height: '232', |
|
||||||
left: '39', |
|
||||||
top: '646', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-more', |
|
||||||
desc: '还有', |
|
||||||
type: 1, |
|
||||||
text: '还有3条精彩附件>', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '31', |
|
||||||
color: '#666666', |
|
||||||
'single-line': true, |
|
||||||
width: '292', |
|
||||||
height: '46', |
|
||||||
left: '60', |
|
||||||
top: '1024', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'scanText', |
|
||||||
desc: '扫描二维码查看详情', |
|
||||||
type: 1, |
|
||||||
text: '扫描二维码查看详情', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '31', |
|
||||||
color: '#666666', |
|
||||||
'single-line': true, |
|
||||||
width: '279', |
|
||||||
height: '43', |
|
||||||
left: '60', |
|
||||||
top: '1087', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-qrcode', |
|
||||||
desc: '专家列表的二维码', |
|
||||||
type: 0, |
|
||||||
picType: 'qrcode', |
|
||||||
src: 'https://family.devred.hbraas.com/proxy/mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQHJ8TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyUWhDdGhTWVNlTjMxMDAwMDAwN3gAAgSonPxjAwQAAAAA', |
|
||||||
width: '130', |
|
||||||
height: '130', |
|
||||||
left: '554', |
|
||||||
top: '1012', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'brand', |
|
||||||
desc: 'brand×华秉科技', |
|
||||||
type: 1, |
|
||||||
text: '做企业数字化转型的亲密伙伴×华秉科技', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '24', |
|
||||||
color: '#B2B3B4', |
|
||||||
'single-line': true, |
|
||||||
halign: 'center', |
|
||||||
top: '1192', |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
} |
|
||||||
``` |
|
@ -1,101 +0,0 @@ |
|||||||
import Wxml2Canvas from "./wxml2canvas/index.js"; // 根据具体路径修改,node_modules会被忽略
|
|
||||||
|
|
||||||
Component({ |
|
||||||
properties: { |
|
||||||
params: { |
|
||||||
type: Object, |
|
||||||
observer(newVal, _olVal) { |
|
||||||
if (Object.keys(newVal).length > 0) { |
|
||||||
this.paramsFormat(newVal); |
|
||||||
this.setData({ |
|
||||||
width: newVal.body.width, |
|
||||||
height: newVal.body.height, |
|
||||||
bgImg: newVal.body.bgImg, |
|
||||||
elementsMp: newVal.elements, |
|
||||||
}); |
|
||||||
this.drawImage1(); |
|
||||||
} |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
data: { |
|
||||||
imgUrl: "", |
|
||||||
width: "", |
|
||||||
height: "", |
|
||||||
imgheight: "", |
|
||||||
bgImg: "", |
|
||||||
elementsMp: [], |
|
||||||
}, |
|
||||||
lifetimes: { |
|
||||||
attached() {}, |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
paramsFormat(params) { |
|
||||||
params.elements.forEach((item) => { |
|
||||||
if (item.type === 0) { |
|
||||||
// 图片居中
|
|
||||||
if (item.halign === "center") { |
|
||||||
item.left = (params.body.width - item.width) / 2; |
|
||||||
} |
|
||||||
} else { |
|
||||||
item.text = item.text.replace(/[\r\n]/g, ""); |
|
||||||
// 文字居中(使文字标签宽度等于画布宽度,文字加上居中的className)
|
|
||||||
if (item.halign === "center") { |
|
||||||
item.width = item.width || params.body.width; |
|
||||||
item.left = (params.body.width - item.width) / 2; |
|
||||||
} |
|
||||||
if (item.halign === "right") { |
|
||||||
item.width = params.body.width; |
|
||||||
} |
|
||||||
if (item.id === "shareText" && item.text.length > 30) { |
|
||||||
item.text = item.text.slice(0, 30) + "..."; |
|
||||||
} |
|
||||||
if (item.id === "note-title" && item.text.length > 28) { |
|
||||||
item.text = item.text.slice(0, 28) + "..."; |
|
||||||
} |
|
||||||
if (item.id === "note-content" && item.text.length > 90) { |
|
||||||
item.text = item.text.slice(0, 90) + "..."; |
|
||||||
} |
|
||||||
let len = params.elements.some((x) => x.id === "note-title" && x.text.length); |
|
||||||
if (len && item.id === "note-summary" && item.text.length > 62) { |
|
||||||
item.text = item.text.slice(0, 62) + "..."; |
|
||||||
} else if (item.id === "note-summary" && item.text.length > 76) { |
|
||||||
item.text = item.text.slice(0, 76) + "..."; |
|
||||||
} |
|
||||||
} |
|
||||||
}); |
|
||||||
}, |
|
||||||
drawImage1() { |
|
||||||
let self = this; |
|
||||||
this.drawImage1 = new Wxml2Canvas({ |
|
||||||
obj: self, |
|
||||||
width: this.data.width, // 宽, 以iphone6为基准,传具体数值,其它机型自动适配
|
|
||||||
height: this.data.height, // 高
|
|
||||||
element: "canvas1", |
|
||||||
background: "transparent", |
|
||||||
progress(percent) {}, |
|
||||||
finish(url) { |
|
||||||
self.setData({ |
|
||||||
imgUrl: url, |
|
||||||
}); |
|
||||||
self.triggerEvent("finish", url); |
|
||||||
}, |
|
||||||
error(res) {}, |
|
||||||
}); |
|
||||||
|
|
||||||
let data = { |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
type: "wxml", |
|
||||||
class: "#canvas-bill-body-mp .draw_canvas", |
|
||||||
limit: "#canvas-bill-body-mp", |
|
||||||
x: 0, |
|
||||||
y: 0, |
|
||||||
}, |
|
||||||
], |
|
||||||
}; |
|
||||||
|
|
||||||
this.drawImage1.draw(data); |
|
||||||
}, |
|
||||||
}, |
|
||||||
}); |
|
@ -1,53 +0,0 @@ |
|||||||
.canvas-box { |
|
||||||
position: fixed; |
|
||||||
left: 1000000rpx; |
|
||||||
top: -1000000rpx; |
|
||||||
} |
|
||||||
.canvas-body { |
|
||||||
background-position: center; |
|
||||||
background-repeat: no-repeat; |
|
||||||
background-size: cover; |
|
||||||
background-color: #fff; |
|
||||||
} |
|
||||||
.draw_canvas { |
|
||||||
position: absolute; |
|
||||||
} |
|
||||||
.canvas-bill { |
|
||||||
position: fixed; |
|
||||||
width: 750rpx; |
|
||||||
left: 1000000rpx; |
|
||||||
top: -1000000rpx; |
|
||||||
visibility: hidden; |
|
||||||
} |
|
||||||
.lineOne { |
|
||||||
// overflow: hidden; |
|
||||||
// text-overflow: ellipsis; |
|
||||||
// white-space: nowrap; |
|
||||||
} |
|
||||||
.textCenter { |
|
||||||
text-align: center; |
|
||||||
} |
|
||||||
.textRight { |
|
||||||
text-align: right; |
|
||||||
} |
|
||||||
.billImg-box { |
|
||||||
position: fixed; |
|
||||||
left: 0; |
|
||||||
top: 0; |
|
||||||
z-index: 10; |
|
||||||
width: 750rpx; |
|
||||||
height: 100vh; |
|
||||||
display: flex; |
|
||||||
justify-content: center; |
|
||||||
align-items: center; |
|
||||||
background-color: rgba(0, 0, 0, 0.75); |
|
||||||
} |
|
||||||
.image-load-text { |
|
||||||
width: 750rpx; |
|
||||||
text-align: center; |
|
||||||
color: #fff; |
|
||||||
line-height: 50rpx; |
|
||||||
margin-top: 20rpx; |
|
||||||
font-size: 28rpx; |
|
||||||
letter-spacing: 2rpx; |
|
||||||
} |
|
@ -1,43 +0,0 @@ |
|||||||
<view id="canvas-bill-body-mp" class="canvas-box" style="height: {{ height }}rpx; width: {{ width }}rpx;"> |
|
||||||
<view |
|
||||||
data-type="{{bgImg ? 'background-image' : 'text'}}" |
|
||||||
style="height: {{ height }}rpx; width: {{ width }}rpx;background-image: url({{bgImg}})" |
|
||||||
class="canvas-body draw_canvas" |
|
||||||
> |
|
||||||
<view wx:for="{{elementsMp}}" wx:key="index" wx:for-item="item"> |
|
||||||
<image |
|
||||||
class="draw_canvas" |
|
||||||
data-type="{{item.shape === 'circle' ? 'radius-image' : 'image'}}" |
|
||||||
data-url="{{item.src}}" |
|
||||||
style="height: {{ item.height }}rpx; width: {{ item.width? item.width + 'rpx' : 'auto'}};left: {{item.left}}rpx;right: {{item.right}}rpx;top: {{item.top}}rpx;{{item.shape === 'circle'?'border-radius:50%;':''}}" |
|
||||||
src="{{item.src}}" |
|
||||||
wx:if="{{item.type === 0}}" |
|
||||||
data-delay="{{item.delay}}" |
|
||||||
></image> |
|
||||||
<view |
|
||||||
class="draw_canvas {{item['single-line'] ? 'lineOne' : ''}} {{item['halign'] === 'center' ? 'textCenter' : ''}} {{item['halign'] === 'right' ? 'textRight' : ''}}" |
|
||||||
wx:if="{{item.type === 1}}" |
|
||||||
data-background="{{item.bgcolor}}" |
|
||||||
style="font-style: {{item['font-style']}};font-weight: {{item['font-weight']}};background-color: {{item.bgcolor}};color: {{item.color}};font-size: {{item['font-size']}}rpx;font-family: {{item.font}};height: {{ item.height }}rpx; width: {{ item.width? item.width + 'rpx' : 'auto'}};left: {{item.left}}rpx;right: {{item.right}}rpx;top: {{item.top}}rpx;line-height:{{item.lineHeight}}rpx;" |
|
||||||
data-type="text" |
|
||||||
data-text="{{item.text}}" |
|
||||||
> |
|
||||||
{{item.text}} |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
|
|
||||||
<canvas |
|
||||||
canvas-id="canvas1" |
|
||||||
class="canvas-bill" |
|
||||||
style="height: {{ height }}rpx; width: {{ width }}rpx;transform: scale({{scale}})" |
|
||||||
></canvas> |
|
||||||
|
|
||||||
<!-- <image --> |
|
||||||
<!-- wx:if="{{imgUrl}}" --> |
|
||||||
<!-- src="{{imgUrl}}" --> |
|
||||||
<!-- mode="aspectFit" --> |
|
||||||
<!-- style="height: {{ height }}rpx; width: {{ width }}rpx;" --> |
|
||||||
<!-- show-menu-by-longpress --> |
|
||||||
<!-- ></image> --> |
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,160 +0,0 @@ |
|||||||
# 海报插件 |
|
||||||
|
|
||||||
## 基于[wxml2canvas](https://github.com/wg-front/wxml2canvas)插件 |
|
||||||
|
|
||||||
### 插件引入 |
|
||||||
|
|
||||||
```json |
|
||||||
{ |
|
||||||
"customPoster": "/components/customPoster/index" |
|
||||||
} |
|
||||||
``` |
|
||||||
|
|
||||||
```wxml |
|
||||||
<customPoster params="{{params}}"></customPoster> |
|
||||||
``` |
|
||||||
|
|
||||||
### 参数示例 |
|
||||||
|
|
||||||
```js |
|
||||||
const data = { |
|
||||||
params: { |
|
||||||
info: { id: 'circle-note_mp', title: '动态页', desc: '指定动态的页面,mp' }, |
|
||||||
body: { |
|
||||||
bgImg: |
|
||||||
'https://picsissiok-10049618.cos.ap-shanghai.myqcloud.com/a74018e725861534f1644cff04780f4e_16273677601587.png', |
|
||||||
width: '750', |
|
||||||
height: '1254', |
|
||||||
}, |
|
||||||
elements: [ |
|
||||||
{ |
|
||||||
id: 'circle-name', |
|
||||||
desc: '圈名称', |
|
||||||
type: 1, |
|
||||||
text: '治疗讨论', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '42', |
|
||||||
color: '#FFFFFF', |
|
||||||
'single-line': true, |
|
||||||
halign: 'center', |
|
||||||
top: '106', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'master-name', |
|
||||||
desc: '专家名称', |
|
||||||
type: 1, |
|
||||||
text: '健康小贴士', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '38', |
|
||||||
color: '#FFFFFF', |
|
||||||
'single-line': true, |
|
||||||
halign: 'center', |
|
||||||
top: '237', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'master-avatar', |
|
||||||
desc: '专家头像', |
|
||||||
type: 0, |
|
||||||
picType: 'avatar', |
|
||||||
src: 'https://picsissiok-10049618.cos.ap-shanghai.myqcloud.com/ceb31ac6137e873225b8cc826389a267_16655329078962.jpg', |
|
||||||
width: '120', |
|
||||||
height: '120', |
|
||||||
halign: 'center', |
|
||||||
shape: 'circle', |
|
||||||
top: '328', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-content', |
|
||||||
desc: '动态内容', |
|
||||||
type: 1, |
|
||||||
text: '11月5日上海组织进口博览会CIIE大会,邀请大家来我们的展馆现场交流。', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '45', |
|
||||||
color: '#18191A', |
|
||||||
width: '630', |
|
||||||
height: '348', |
|
||||||
left: '60', |
|
||||||
top: '495', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-title', |
|
||||||
desc: '长文标题', |
|
||||||
type: 1, |
|
||||||
text: '', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '42', |
|
||||||
color: '#18191A', |
|
||||||
width: '659', |
|
||||||
height: '116', |
|
||||||
left: '46', |
|
||||||
top: '495', |
|
||||||
'font-weight': 'bold', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-summary', |
|
||||||
desc: '长文摘要 ', |
|
||||||
type: 1, |
|
||||||
text: '', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '42', |
|
||||||
color: '#18191A', |
|
||||||
width: '672', |
|
||||||
height: '232', |
|
||||||
left: '39', |
|
||||||
top: '646', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-more', |
|
||||||
desc: '还有', |
|
||||||
type: 1, |
|
||||||
text: '还有3条精彩附件>', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '31', |
|
||||||
color: '#666666', |
|
||||||
'single-line': true, |
|
||||||
width: '292', |
|
||||||
height: '46', |
|
||||||
left: '60', |
|
||||||
top: '1024', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'scanText', |
|
||||||
desc: '扫描二维码查看详情', |
|
||||||
type: 1, |
|
||||||
text: '扫描二维码查看详情', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '31', |
|
||||||
color: '#666666', |
|
||||||
'single-line': true, |
|
||||||
width: '279', |
|
||||||
height: '43', |
|
||||||
left: '60', |
|
||||||
top: '1087', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'note-qrcode', |
|
||||||
desc: '专家列表的二维码', |
|
||||||
type: 0, |
|
||||||
picType: 'qrcode', |
|
||||||
src: 'https://family.devred.hbraas.com/proxy/mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQHJ8TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyUWhDdGhTWVNlTjMxMDAwMDAwN3gAAgSonPxjAwQAAAAA', |
|
||||||
width: '130', |
|
||||||
height: '130', |
|
||||||
left: '554', |
|
||||||
top: '1012', |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: 'brand', |
|
||||||
desc: 'brand×华秉科技', |
|
||||||
type: 1, |
|
||||||
text: '做企业数字化转型的亲密伙伴×华秉科技', |
|
||||||
font: '宋体', |
|
||||||
'font-size': '24', |
|
||||||
color: '#B2B3B4', |
|
||||||
'single-line': true, |
|
||||||
halign: 'center', |
|
||||||
top: '1192', |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
} |
|
||||||
``` |
|
@ -1,240 +0,0 @@ |
|||||||
const app = getApp(); |
|
||||||
import Wxml2Canvas from "./wxml2canvas/index.js"; // 根据具体路径修改,node_modules会被忽略
|
|
||||||
|
|
||||||
Component({ |
|
||||||
properties: { |
|
||||||
params: { |
|
||||||
type: Object, |
|
||||||
observer(newVal, _olVal) { |
|
||||||
if (Object.keys(newVal).length > 0) { |
|
||||||
this.drawImage1(); |
|
||||||
} |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
data: { |
|
||||||
imageUrl: app.globalData.imageUrl, |
|
||||||
imgUrl: "", |
|
||||||
width: "626", |
|
||||||
height: "980", |
|
||||||
imgheight: "", |
|
||||||
bgImg: "", |
|
||||||
elementsMp: [], |
|
||||||
tableData: [ |
|
||||||
{ |
|
||||||
title: "说话", |
|
||||||
key: "TalkingScore", |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
id: "1", |
|
||||||
title: "正常", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "2", |
|
||||||
title: "间或有点含糊或有鼻音", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "3", |
|
||||||
title: "经常含糊不清或者有鼻音,但是别人还能听懂", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "4", |
|
||||||
title: "别人听不太懂", |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "咀嚼", |
|
||||||
key: "ChewScore", |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
id: "1", |
|
||||||
title: "正常", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "2", |
|
||||||
title: "咀嚼固体食物会感到疲劳", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "3", |
|
||||||
title: "咀嚼松软食物会感到疲劳", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "4", |
|
||||||
title: "使用喂食管进食,如鼻胃管胃肠管等", |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "吞咽", |
|
||||||
key: "SwallowScore", |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
id: "1", |
|
||||||
title: "正常", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "2", |
|
||||||
title: "偶尔会噎到", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "3", |
|
||||||
title: "经常会噎到,因而需要改变饮食习惯", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "4", |
|
||||||
title: "使用喂食管进食,如鼻胃管胃肠管等", |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "呼吸", |
|
||||||
key: "BreathScore", |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
id: "1", |
|
||||||
title: "正常", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "2", |
|
||||||
title: "劳累后感到气促或呼吸不畅", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "3", |
|
||||||
title: "静止时感到气促或呼吸不畅", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "4", |
|
||||||
title: "依赖呼吸机", |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "刷牙梳头能力受损", |
|
||||||
key: "BrushTeethAndCombHairScore", |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
id: "1", |
|
||||||
title: "正常", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "2", |
|
||||||
title: "需要多费些力气但是不需要停下来", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "3", |
|
||||||
title: "需要停下来休息才能完成", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "4", |
|
||||||
title: "无法自己完成", |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "从椅子上起身能力受损", |
|
||||||
key: "GetUpFromChairScore", |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
id: "1", |
|
||||||
title: "正常", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "2", |
|
||||||
title: "轻度受损,有时需要用手帮忙", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "3", |
|
||||||
title: "中度受损,总是需要用手帮忙", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "4", |
|
||||||
title: "严重受损,需要他人帮助", |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "复视/重影", |
|
||||||
key: "DoubleVisionScore", |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
id: "1", |
|
||||||
title: "正常", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "2", |
|
||||||
title: "有,但不是每天", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "3", |
|
||||||
title: "每天,但不是持续一整天", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "4", |
|
||||||
title: "持续有", |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
{ |
|
||||||
title: "眼睑下垂", |
|
||||||
key: "DroopyEyelidsScore", |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
id: "1", |
|
||||||
title: "正常", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "2", |
|
||||||
title: "有,但不是每天", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "3", |
|
||||||
title: "每天,但不是持续一整天", |
|
||||||
}, |
|
||||||
{ |
|
||||||
id: "4", |
|
||||||
title: "持续有", |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
lifetimes: { |
|
||||||
attached() {}, |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
drawImage1() { |
|
||||||
let self = this; |
|
||||||
// destZoom: 10,
|
|
||||||
this.drawImage1 = new Wxml2Canvas({ |
|
||||||
obj: self, |
|
||||||
width: this.data.width, // 宽, 以iphone6为基准,传具体数值,其它机型自动适配
|
|
||||||
height: this.data.height, // 高
|
|
||||||
element: "canvas1", |
|
||||||
background: "#ffffff", |
|
||||||
progress(_percent) {}, |
|
||||||
finish(url) { |
|
||||||
self.setData({ |
|
||||||
imgUrl: url, |
|
||||||
}); |
|
||||||
self.triggerEvent("finish", url); |
|
||||||
}, |
|
||||||
error(_res) {}, |
|
||||||
}); |
|
||||||
|
|
||||||
let data = { |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
type: "wxml", |
|
||||||
class: "#canvas-bill-body-mp .draw_canvas", |
|
||||||
limit: "#canvas-bill-body-mp", |
|
||||||
x: 0, |
|
||||||
y: 0, |
|
||||||
}, |
|
||||||
], |
|
||||||
}; |
|
||||||
|
|
||||||
this.drawImage1.draw(data); |
|
||||||
}, |
|
||||||
}, |
|
||||||
}); |
|
@ -1,141 +0,0 @@ |
|||||||
.canvas-box { |
|
||||||
position: fixed; |
|
||||||
left: 1000000rpx; |
|
||||||
top: -1000000rpx; |
|
||||||
} |
|
||||||
.canvas-body { |
|
||||||
background-position: center; |
|
||||||
background-repeat: no-repeat; |
|
||||||
background-size: cover; |
|
||||||
background-color: #fff; |
|
||||||
.detail { |
|
||||||
width: 622rpx; |
|
||||||
border: 1rpx solid rgba(0, 0, 0, 0.1); |
|
||||||
background-color: rgba(0, 0, 0, 0.08); |
|
||||||
.d-header { |
|
||||||
display: flex; |
|
||||||
height: 40rpx; |
|
||||||
.none { |
|
||||||
flex-shrink: 0; |
|
||||||
width: 150rpx; |
|
||||||
background-color: rgba(228, 228, 228, 1); |
|
||||||
} |
|
||||||
.bar { |
|
||||||
flex: 1; |
|
||||||
display: flex; |
|
||||||
.num-normal { |
|
||||||
width: 64rpx; |
|
||||||
text-align: center; |
|
||||||
font-size: 24rpx; |
|
||||||
color: #fff; |
|
||||||
line-height: 40rpx; |
|
||||||
} |
|
||||||
.num { |
|
||||||
flex: 1; |
|
||||||
text-align: center; |
|
||||||
font-size: 24rpx; |
|
||||||
color: #fff; |
|
||||||
line-height: 40rpx; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
.d-body { |
|
||||||
display: flex; |
|
||||||
.d-aside { |
|
||||||
width: 28rpx; |
|
||||||
flex-shrink: 0; |
|
||||||
.da-item { |
|
||||||
text-align: center; |
|
||||||
font-size: 18rpx; |
|
||||||
color: rgba(102, 102, 102, 1); |
|
||||||
line-height: 1; |
|
||||||
background-color: #e5e5e5; |
|
||||||
} |
|
||||||
.da-item1 { |
|
||||||
padding-top: 150rpx; |
|
||||||
display: flex; |
|
||||||
height: 200rpx; |
|
||||||
margin-bottom: 1px; |
|
||||||
} |
|
||||||
.da-item2 { |
|
||||||
padding-top: 43rpx; |
|
||||||
height: 75rpx; |
|
||||||
margin-bottom: 1px; |
|
||||||
} |
|
||||||
.da-item3 { |
|
||||||
padding-top: 100rpx; |
|
||||||
height: 135rpx; |
|
||||||
margin-bottom: 1px; |
|
||||||
} |
|
||||||
.da-item4 { |
|
||||||
padding-top: 100rpx; |
|
||||||
height: 135rpx; |
|
||||||
} |
|
||||||
} |
|
||||||
.d-container { |
|
||||||
flex: 1; |
|
||||||
.dc-row { |
|
||||||
display: flex; |
|
||||||
height: 117rpx; |
|
||||||
line-height: 24rpx; |
|
||||||
margin-bottom: 1px; |
|
||||||
.dc-title { |
|
||||||
padding: 12rpx 12rpx 0; |
|
||||||
width: 100rpx; |
|
||||||
font-size: 18rpx; |
|
||||||
color: rgba(102, 102, 102, 1); |
|
||||||
} |
|
||||||
.dc-sub-title { |
|
||||||
width: 64rpx; |
|
||||||
text-align: center; |
|
||||||
font-size: 18rpx; |
|
||||||
color: rgba(102, 102, 102, 1); |
|
||||||
padding: 12rpx 0; |
|
||||||
margin-left: 1px; |
|
||||||
} |
|
||||||
.dc-col { |
|
||||||
margin-left: 1px; |
|
||||||
padding: 12rpx; |
|
||||||
flex: 1; |
|
||||||
font-size: 18rpx; |
|
||||||
color: rgba(102, 102, 102, 1); |
|
||||||
} |
|
||||||
.active { |
|
||||||
color: #fff !important; |
|
||||||
background-color: rgba(207, 83, 117, 1) !important; |
|
||||||
} |
|
||||||
} |
|
||||||
.dc-row:nth-of-type(2n-1) { |
|
||||||
.dc-title { |
|
||||||
background-color: #f6f6f6; |
|
||||||
} |
|
||||||
.dc-sub-title { |
|
||||||
background-color: #f6f6f6; |
|
||||||
} |
|
||||||
.dc-col { |
|
||||||
background-color: #f6f6f6; |
|
||||||
} |
|
||||||
} |
|
||||||
.dc-row:nth-of-type(2n-2) { |
|
||||||
.dc-title { |
|
||||||
background-color: #fff; |
|
||||||
} |
|
||||||
.dc-sub-title { |
|
||||||
background-color: #fff; |
|
||||||
} |
|
||||||
.dc-col { |
|
||||||
background-color: #fff; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.canvas-bill { |
|
||||||
position: fixed; |
|
||||||
width: 750rpx; |
|
||||||
left: 1000000rpx; |
|
||||||
top: -1000000rpx; |
|
||||||
visibility: hidden; |
|
||||||
} |
|
@ -1,55 +0,0 @@ |
|||||||
<view id="canvas-bill-body-mp" class="canvas-box" style="width: 750rpx"> |
|
||||||
<view class="canvas-body"> |
|
||||||
<view class="detail draw_canvas" data-type="text"> |
|
||||||
<view class="d-header draw_canvas" data-type="text"> |
|
||||||
<view class="none draw_canvas" data-type="text"></view> |
|
||||||
<view |
|
||||||
class="bar draw_canvas" |
|
||||||
style="background: url({{imageUrl}}za-images/1/adl-scurt.png?t={{Timestamp}}) no-repeat center / 100% 100% ;" |
|
||||||
data-type="background-image" |
|
||||||
> |
|
||||||
<view class="num-normal draw_canvas" data-type="text" data-text="0分">0分</view> |
|
||||||
<view class="num draw_canvas" data-type="text" data-text="1分">1分</view> |
|
||||||
<view class="num draw_canvas" data-type="text" data-text="2分">2分</view> |
|
||||||
<view class="num draw_canvas" data-type="text" data-text="3分">3分</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
<view class="d-body draw_canvas" data-type="text"> |
|
||||||
<view class="d-aside draw_canvas" data-type="text"> |
|
||||||
<view class="da-item da-item1 draw_canvas" data-type="text" data-text="延髓">延髓</view> |
|
||||||
<view class="da-item da-item2 draw_canvas" data-type="text" data-text="呼吸">呼吸</view> |
|
||||||
<view class="da-item da-item3 draw_canvas" data-type="text" data-text="四肢">四肢</view> |
|
||||||
<view class="da-item da-item4 draw_canvas" data-type="text" data-text="眼肌">眼肌</view> |
|
||||||
</view> |
|
||||||
<view class="d-container draw_canvas" data-type="text"> |
|
||||||
<view class="dc-row draw_canvas" wx:for="{{tableData}}" wx:key="index" data-type="text"> |
|
||||||
<view class="dc-title draw_canvas" data-type="text" data-text="{{item.title}}">{{item.title}}</view> |
|
||||||
<block wx:for="{{item.list}}" wx:for-item="lItem" wx:for-index="lIndex" wx:key="lIndex"> |
|
||||||
<view |
|
||||||
class="{{lIndex==0 ? 'dc-sub-title' :'dc-col'}} {{params[item.key] == lIndex && 'active'}} draw_canvas" |
|
||||||
data-type="text" |
|
||||||
data-text="{{lItem.title}}" |
|
||||||
> |
|
||||||
{{lItem.title}} |
|
||||||
</view> |
|
||||||
</block> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
|
|
||||||
<canvas |
|
||||||
canvas-id="canvas1" |
|
||||||
class="canvas-bill" |
|
||||||
style="height: {{ height }}rpx; width: {{ width }}rpx;transform: scale({{scale}})" |
|
||||||
></canvas> |
|
||||||
|
|
||||||
<image |
|
||||||
wx:if="{{imgUrl && false}}" |
|
||||||
src="{{imgUrl}}" |
|
||||||
mode="aspectFit" |
|
||||||
style="height: {{ height }}rpx; width: {{ width }}rpx;" |
|
||||||
></image> |
|
||||||
<!-- show-menu-by-longpress --> |
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,271 +0,0 @@ |
|||||||
import WxCanvas from './wx-canvas'; |
|
||||||
|
|
||||||
let ctx; |
|
||||||
let echarts; |
|
||||||
|
|
||||||
function compareVersion(v1, v2) { |
|
||||||
v1 = v1.split('.'); |
|
||||||
v2 = v2.split('.'); |
|
||||||
const len = Math.max(v1.length, v2.length); |
|
||||||
|
|
||||||
while (v1.length < len) { |
|
||||||
v1.push('0'); |
|
||||||
} |
|
||||||
while (v2.length < len) { |
|
||||||
v2.push('0'); |
|
||||||
} |
|
||||||
|
|
||||||
for (let i = 0; i < len; i++) { |
|
||||||
const num1 = parseInt(v1[i]); |
|
||||||
const num2 = parseInt(v2[i]); |
|
||||||
|
|
||||||
if (num1 > num2) { |
|
||||||
return 1; |
|
||||||
} else if (num1 < num2) { |
|
||||||
return -1; |
|
||||||
} |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
Component({ |
|
||||||
properties: { |
|
||||||
canvasId: { |
|
||||||
type: String, |
|
||||||
value: 'ec-canvas', |
|
||||||
}, |
|
||||||
|
|
||||||
ec: { |
|
||||||
type: Object, |
|
||||||
}, |
|
||||||
|
|
||||||
forceUseOldCanvas: { |
|
||||||
type: Boolean, |
|
||||||
value: false, |
|
||||||
}, |
|
||||||
}, |
|
||||||
|
|
||||||
data: { |
|
||||||
isUseNewCanvas: false, |
|
||||||
}, |
|
||||||
|
|
||||||
ready: async function () { |
|
||||||
echarts = await require.async('../../gift/compontnts/echart/echarts.js'); |
|
||||||
// Disable prograssive because drawImage doesn't support DOM as parameter
|
|
||||||
// See https://developers.weixin.qq.com/miniprogram/dev/api/canvas/CanvasContext.drawImage.html
|
|
||||||
echarts.registerPreprocessor((option) => { |
|
||||||
if (option && option.series) { |
|
||||||
if (option.series.length > 0) { |
|
||||||
option.series.forEach((series) => { |
|
||||||
series.progressive = 0; |
|
||||||
}); |
|
||||||
} else if (typeof option.series === 'object') { |
|
||||||
option.series.progressive = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
}); |
|
||||||
|
|
||||||
if (!this.data.ec) { |
|
||||||
console.warn( |
|
||||||
'组件需绑定 ec 变量,例:<ec-canvas id="mychart-dom-bar" ' + |
|
||||||
'canvas-id="mychart-bar" ec="{{ ec }}"></ec-canvas>', |
|
||||||
); |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
if (!this.data.ec.lazyLoad) { |
|
||||||
this.init(); |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
methods: { |
|
||||||
init: async function (callback) { |
|
||||||
echarts = await require.async('../../gift/compontnts/echart/echarts.js'); |
|
||||||
const version = wx.getSystemInfoSync().SDKVersion; |
|
||||||
|
|
||||||
const canUseNewCanvas = compareVersion(version, '2.9.0') >= 0; |
|
||||||
const forceUseOldCanvas = this.data.forceUseOldCanvas; |
|
||||||
const isUseNewCanvas = canUseNewCanvas && !forceUseOldCanvas; |
|
||||||
this.setData({ isUseNewCanvas }); |
|
||||||
|
|
||||||
if (forceUseOldCanvas && canUseNewCanvas) { |
|
||||||
console.warn('开发者强制使用旧canvas,建议关闭'); |
|
||||||
} |
|
||||||
|
|
||||||
if (isUseNewCanvas) { |
|
||||||
// console.log('微信基础库版本大于2.9.0,开始使用<canvas type="2d"/>');
|
|
||||||
// 2.9.0 可以使用 <canvas type="2d"></canvas>
|
|
||||||
this.initByNewWay(callback); |
|
||||||
} else { |
|
||||||
const isValid = compareVersion(version, '1.9.91') >= 0; |
|
||||||
if (!isValid) { |
|
||||||
console.error( |
|
||||||
'微信基础库版本过低,需大于等于 1.9.91。' + |
|
||||||
'参见:https://github.com/ecomfe/echarts-for-weixin' + |
|
||||||
'#%E5%BE%AE%E4%BF%A1%E7%89%88%E6%9C%AC%E8%A6%81%E6%B1%82', |
|
||||||
); |
|
||||||
return; |
|
||||||
} else { |
|
||||||
console.warn('建议将微信基础库调整大于等于2.9.0版本。升级后绘图将有更好性能'); |
|
||||||
this.initByOldWay(callback); |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
initByOldWay(callback) { |
|
||||||
// 1.9.91 <= version < 2.9.0:原来的方式初始化
|
|
||||||
ctx = wx.createCanvasContext(this.data.canvasId, this); |
|
||||||
const canvas = new WxCanvas(ctx, this.data.canvasId, false); |
|
||||||
|
|
||||||
echarts.setCanvasCreator(() => { |
|
||||||
return canvas; |
|
||||||
}); |
|
||||||
// const canvasDpr = wx.getSystemInfoSync().pixelRatio // 微信旧的canvas不能传入dpr
|
|
||||||
const canvasDpr = 1; |
|
||||||
var query = wx.createSelectorQuery().in(this); |
|
||||||
query |
|
||||||
.select('.ec-canvas') |
|
||||||
.boundingClientRect((res) => { |
|
||||||
if (typeof callback === 'function') { |
|
||||||
this.chart = callback(canvas, res.width, res.height, canvasDpr); |
|
||||||
} else if (this.data.ec && typeof this.data.ec.onInit === 'function') { |
|
||||||
this.chart = this.data.ec.onInit(canvas, res.width, res.height, canvasDpr); |
|
||||||
} else { |
|
||||||
this.triggerEvent('init', { |
|
||||||
canvas: canvas, |
|
||||||
width: res.width, |
|
||||||
height: res.height, |
|
||||||
canvasDpr: canvasDpr, // 增加了dpr,可方便外面echarts.init
|
|
||||||
}); |
|
||||||
} |
|
||||||
}) |
|
||||||
.exec(); |
|
||||||
}, |
|
||||||
|
|
||||||
initByNewWay(callback) { |
|
||||||
// version >= 2.9.0:使用新的方式初始化
|
|
||||||
const query = wx.createSelectorQuery().in(this); |
|
||||||
query |
|
||||||
.select('.ec-canvas') |
|
||||||
.fields({ node: true, size: true }) |
|
||||||
.exec((res) => { |
|
||||||
const canvasNode = res[0].node; |
|
||||||
this.canvasNode = canvasNode; |
|
||||||
|
|
||||||
const canvasDpr = wx.getSystemInfoSync().pixelRatio; |
|
||||||
const canvasWidth = res[0].width; |
|
||||||
const canvasHeight = res[0].height; |
|
||||||
|
|
||||||
const ctx = canvasNode.getContext('2d'); |
|
||||||
|
|
||||||
const canvas = new WxCanvas(ctx, this.data.canvasId, true, canvasNode); |
|
||||||
echarts.setCanvasCreator(() => { |
|
||||||
return canvas; |
|
||||||
}); |
|
||||||
|
|
||||||
if (typeof callback === 'function') { |
|
||||||
this.chart = callback(canvas, canvasWidth, canvasHeight, canvasDpr); |
|
||||||
} else if (this.data.ec && typeof this.data.ec.onInit === 'function') { |
|
||||||
this.chart = this.data.ec.onInit(canvas, canvasWidth, canvasHeight, canvasDpr); |
|
||||||
} else { |
|
||||||
this.triggerEvent('init', { |
|
||||||
canvas: canvas, |
|
||||||
width: canvasWidth, |
|
||||||
height: canvasHeight, |
|
||||||
dpr: canvasDpr, |
|
||||||
}); |
|
||||||
} |
|
||||||
}); |
|
||||||
}, |
|
||||||
canvasToTempFilePath(opt) { |
|
||||||
if (this.data.isUseNewCanvas) { |
|
||||||
// 新版
|
|
||||||
const query = wx.createSelectorQuery().in(this); |
|
||||||
query |
|
||||||
.select('.ec-canvas') |
|
||||||
.fields({ node: true, size: true }) |
|
||||||
.exec((res) => { |
|
||||||
const canvasNode = res[0].node; |
|
||||||
opt.canvas = canvasNode; |
|
||||||
wx.canvasToTempFilePath(opt); |
|
||||||
}); |
|
||||||
} else { |
|
||||||
// 旧的
|
|
||||||
if (!opt.canvasId) { |
|
||||||
opt.canvasId = this.data.canvasId; |
|
||||||
} |
|
||||||
ctx.draw(true, () => { |
|
||||||
wx.canvasToTempFilePath(opt, this); |
|
||||||
}); |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
touchStart(e) { |
|
||||||
if (this.chart && e.touches.length > 0) { |
|
||||||
var touch = e.touches[0]; |
|
||||||
var handler = this.chart.getZr().handler; |
|
||||||
handler.dispatch('mousedown', { |
|
||||||
zrX: touch.x, |
|
||||||
zrY: touch.y, |
|
||||||
preventDefault: () => {}, |
|
||||||
stopImmediatePropagation: () => {}, |
|
||||||
stopPropagation: () => {}, |
|
||||||
}); |
|
||||||
handler.dispatch('mousemove', { |
|
||||||
zrX: touch.x, |
|
||||||
zrY: touch.y, |
|
||||||
preventDefault: () => {}, |
|
||||||
stopImmediatePropagation: () => {}, |
|
||||||
stopPropagation: () => {}, |
|
||||||
}); |
|
||||||
handler.processGesture(wrapTouch(e), 'start'); |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
touchMove(e) { |
|
||||||
if (this.chart && e.touches.length > 0) { |
|
||||||
var touch = e.touches[0]; |
|
||||||
var handler = this.chart.getZr().handler; |
|
||||||
handler.dispatch('mousemove', { |
|
||||||
zrX: touch.x, |
|
||||||
zrY: touch.y, |
|
||||||
preventDefault: () => {}, |
|
||||||
stopImmediatePropagation: () => {}, |
|
||||||
stopPropagation: () => {}, |
|
||||||
}); |
|
||||||
handler.processGesture(wrapTouch(e), 'change'); |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
touchEnd(e) { |
|
||||||
if (this.chart) { |
|
||||||
const touch = e.changedTouches ? e.changedTouches[0] : {}; |
|
||||||
var handler = this.chart.getZr().handler; |
|
||||||
handler.dispatch('mouseup', { |
|
||||||
zrX: touch.x, |
|
||||||
zrY: touch.y, |
|
||||||
preventDefault: () => {}, |
|
||||||
stopImmediatePropagation: () => {}, |
|
||||||
stopPropagation: () => {}, |
|
||||||
}); |
|
||||||
handler.dispatch('click', { |
|
||||||
zrX: touch.x, |
|
||||||
zrY: touch.y, |
|
||||||
preventDefault: () => {}, |
|
||||||
stopImmediatePropagation: () => {}, |
|
||||||
stopPropagation: () => {}, |
|
||||||
}); |
|
||||||
handler.processGesture(wrapTouch(e), 'end'); |
|
||||||
} |
|
||||||
}, |
|
||||||
}, |
|
||||||
}); |
|
||||||
|
|
||||||
function wrapTouch(event) { |
|
||||||
for (let i = 0; i < event.touches.length; ++i) { |
|
||||||
const touch = event.touches[i]; |
|
||||||
touch.offsetX = touch.x; |
|
||||||
touch.offsetY = touch.y; |
|
||||||
} |
|
||||||
return event; |
|
||||||
} |
|
@ -1,4 +0,0 @@ |
|||||||
{ |
|
||||||
"component": true, |
|
||||||
"usingComponents": {} |
|
||||||
} |
|
@ -1,4 +0,0 @@ |
|||||||
<!-- 新的:接口对其了H5 --> |
|
||||||
<canvas wx:if="{{isUseNewCanvas}}" type="2d" class="ec-canvas" canvas-id="{{ canvasId }}" bindinit="init" bindtouchstart="{{ ec.disableTouch ? '' : 'touchStart' }}" bindtouchmove="{{ ec.disableTouch ? '' : 'touchMove' }}" bindtouchend="{{ ec.disableTouch ? '' : 'touchEnd' }}"></canvas> |
|
||||||
<!-- 旧的 --> |
|
||||||
<canvas wx:else class="ec-canvas" canvas-id="{{ canvasId }}" bindinit="init" bindtouchstart="{{ ec.disableTouch ? '' : 'touchStart' }}" bindtouchmove="{{ ec.disableTouch ? '' : 'touchMove' }}" bindtouchend="{{ ec.disableTouch ? '' : 'touchEnd' }}"></canvas> |
|
@ -1,5 +0,0 @@ |
|||||||
.ec-canvas { |
|
||||||
width: 100%; |
|
||||||
height: 100%; |
|
||||||
z-index: 1; |
|
||||||
} |
|
@ -1,111 +0,0 @@ |
|||||||
export default class WxCanvas { |
|
||||||
constructor(ctx, canvasId, isNew, canvasNode) { |
|
||||||
this.ctx = ctx; |
|
||||||
this.canvasId = canvasId; |
|
||||||
this.chart = null; |
|
||||||
this.isNew = isNew |
|
||||||
if (isNew) { |
|
||||||
this.canvasNode = canvasNode; |
|
||||||
} |
|
||||||
else { |
|
||||||
this._initStyle(ctx); |
|
||||||
} |
|
||||||
|
|
||||||
// this._initCanvas(zrender, ctx);
|
|
||||||
|
|
||||||
this._initEvent(); |
|
||||||
} |
|
||||||
|
|
||||||
getContext(contextType) { |
|
||||||
if (contextType === '2d') { |
|
||||||
return this.ctx; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// canvasToTempFilePath(opt) {
|
|
||||||
// if (!opt.canvasId) {
|
|
||||||
// opt.canvasId = this.canvasId;
|
|
||||||
// }
|
|
||||||
// return wx.canvasToTempFilePath(opt, this);
|
|
||||||
// }
|
|
||||||
|
|
||||||
setChart(chart) { |
|
||||||
this.chart = chart; |
|
||||||
} |
|
||||||
|
|
||||||
addEventListener() { |
|
||||||
// noop
|
|
||||||
} |
|
||||||
|
|
||||||
attachEvent() { |
|
||||||
// noop
|
|
||||||
} |
|
||||||
|
|
||||||
detachEvent() { |
|
||||||
// noop
|
|
||||||
} |
|
||||||
|
|
||||||
_initCanvas(zrender, ctx) { |
|
||||||
zrender.util.getContext = function () { |
|
||||||
return ctx; |
|
||||||
}; |
|
||||||
|
|
||||||
zrender.util.$override('measureText', function (text, font) { |
|
||||||
ctx.font = font || '12px sans-serif'; |
|
||||||
return ctx.measureText(text); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
_initStyle(ctx) { |
|
||||||
ctx.createRadialGradient = () => { |
|
||||||
return ctx.createCircularGradient(arguments); |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
_initEvent() { |
|
||||||
this.event = {}; |
|
||||||
const eventNames = [{ |
|
||||||
wxName: 'touchStart', |
|
||||||
ecName: 'mousedown' |
|
||||||
}, { |
|
||||||
wxName: 'touchMove', |
|
||||||
ecName: 'mousemove' |
|
||||||
}, { |
|
||||||
wxName: 'touchEnd', |
|
||||||
ecName: 'mouseup' |
|
||||||
}, { |
|
||||||
wxName: 'touchEnd', |
|
||||||
ecName: 'click' |
|
||||||
}]; |
|
||||||
eventNames.forEach(name => { |
|
||||||
this.event[name.wxName] = e => { |
|
||||||
const touch = e.touches[0]; |
|
||||||
this.chart.getZr().handler.dispatch(name.ecName, { |
|
||||||
zrX: name.wxName === 'tap' ? touch.clientX : touch.x, |
|
||||||
zrY: name.wxName === 'tap' ? touch.clientY : touch.y, |
|
||||||
preventDefault: () => {}, |
|
||||||
stopImmediatePropagation: () => {}, |
|
||||||
stopPropagation: () => {} |
|
||||||
}); |
|
||||||
}; |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
set width(w) { |
|
||||||
if (this.canvasNode) this.canvasNode.width = w |
|
||||||
} |
|
||||||
set height(h) { |
|
||||||
if (this.canvasNode) this.canvasNode.height = h |
|
||||||
} |
|
||||||
|
|
||||||
get width() { |
|
||||||
if (this.canvasNode) |
|
||||||
return this.canvasNode.width |
|
||||||
return 0 |
|
||||||
} |
|
||||||
get height() { |
|
||||||
if (this.canvasNode) |
|
||||||
return this.canvasNode.height |
|
||||||
return 0 |
|
||||||
} |
|
||||||
} |
|
@ -1,158 +0,0 @@ |
|||||||
<template> |
|
||||||
<!-- 音频播放器组件 --> |
|
||||||
<view v-if="url" class="flex justify-between align-center audio"> |
|
||||||
<view class="mr-3" @click="start(audioId)"> |
|
||||||
<image :src="startPic" class="icon" v-show="!status"></image> |
|
||||||
<image :src="endPic" class="icon" v-show="status"></image> |
|
||||||
</view> |
|
||||||
<view class="flex-1"> |
|
||||||
<slider |
|
||||||
@change="changeAudio" |
|
||||||
:activeColor="activeColor" |
|
||||||
:min="0" |
|
||||||
:max="duration.toFixed(0)" |
|
||||||
:value="currentTime.toFixed(0)" |
|
||||||
:step="0.1" |
|
||||||
></slider> |
|
||||||
</view> |
|
||||||
<view class="ml-3">{{ getTime(Math.round(currentTime)) }}</view> |
|
||||||
</view> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
export default { |
|
||||||
data() { |
|
||||||
return { |
|
||||||
context: null, |
|
||||||
currentTime: 0, |
|
||||||
duration: 100, |
|
||||||
status: false, |
|
||||||
}; |
|
||||||
}, |
|
||||||
props: { |
|
||||||
url: String, |
|
||||||
activeColor: { |
|
||||||
type: String, |
|
||||||
default: "#0E7EFC", |
|
||||||
}, |
|
||||||
startPic: String, |
|
||||||
endPic: String, |
|
||||||
audioId: [String, Number], |
|
||||||
}, |
|
||||||
created() { |
|
||||||
this.context = uni.createInnerAudioContext(); |
|
||||||
this.context.src = this.url; |
|
||||||
this.onTimeUpdate(); |
|
||||||
this.onCanplay(); |
|
||||||
this.onEnded(); |
|
||||||
uni.$on("stop", (id) => { |
|
||||||
if (id && id != this.audioId) { |
|
||||||
this.context.stop(); |
|
||||||
this.status = false; |
|
||||||
} else if (!id) { |
|
||||||
this.context.stop(); |
|
||||||
this.status = false; |
|
||||||
} |
|
||||||
}); |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
start(id) { |
|
||||||
//点击播放 |
|
||||||
let audioId = id; |
|
||||||
if (this.status) { |
|
||||||
this.context.pause(); |
|
||||||
this.status = !this.status; |
|
||||||
} else { |
|
||||||
uni.$emit("stop", id); |
|
||||||
this.context.play(); |
|
||||||
this.status = !this.status; |
|
||||||
} |
|
||||||
}, |
|
||||||
onCanplay() { |
|
||||||
//进入可播放状态 |
|
||||||
this.context.onCanplay(() => { |
|
||||||
this.context.duration; |
|
||||||
setTimeout(() => { |
|
||||||
this.duration = this.context.duration; |
|
||||||
}, 1000); |
|
||||||
}); |
|
||||||
}, |
|
||||||
onTimeUpdate() { |
|
||||||
//音频播放进度 |
|
||||||
this.context.onTimeUpdate(() => { |
|
||||||
if (!Number.isFinite(this.context.duration)) { |
|
||||||
this.duration = this.context.currentTime + 10; |
|
||||||
this.currentTime = this.context.currentTime; |
|
||||||
} else { |
|
||||||
this.duration = this.context.duration; |
|
||||||
this.currentTime = this.context.currentTime; |
|
||||||
} |
|
||||||
}); |
|
||||||
}, |
|
||||||
onEnded() { |
|
||||||
//播放结束 |
|
||||||
this.context.onEnded(() => { |
|
||||||
this.status = false; |
|
||||||
this.currentTime = 0; |
|
||||||
}); |
|
||||||
}, |
|
||||||
changeAudio(e) { |
|
||||||
let paused = this.context.paused; |
|
||||||
this.context.pause(); |
|
||||||
this.context.seek(e.detail.value); |
|
||||||
if (!paused) { |
|
||||||
this.context.play(); |
|
||||||
} |
|
||||||
}, |
|
||||||
getTime(time) { |
|
||||||
let m = parseInt(time / 60); |
|
||||||
let s = time % 60; |
|
||||||
return this.towNum(m) + ":" + this.towNum(s); |
|
||||||
}, |
|
||||||
towNum(num) { |
|
||||||
if (num >= 10) { |
|
||||||
return num; |
|
||||||
} else { |
|
||||||
return "0" + num; |
|
||||||
} |
|
||||||
}, |
|
||||||
}, |
|
||||||
}; |
|
||||||
</script> |
|
||||||
|
|
||||||
<style> |
|
||||||
.audio { |
|
||||||
background: #f4f4f4; |
|
||||||
padding: 20rpx; |
|
||||||
} |
|
||||||
|
|
||||||
.icon { |
|
||||||
width: 80rpx; |
|
||||||
height: 80rpx; |
|
||||||
} |
|
||||||
|
|
||||||
.flex { |
|
||||||
display: flex; |
|
||||||
flex-direction: row; |
|
||||||
} |
|
||||||
|
|
||||||
.justify-between { |
|
||||||
justify-content: between; |
|
||||||
} |
|
||||||
|
|
||||||
.align-center { |
|
||||||
align-items: center; |
|
||||||
} |
|
||||||
|
|
||||||
.flex-1 { |
|
||||||
flex: 1; |
|
||||||
} |
|
||||||
|
|
||||||
.ml-3 { |
|
||||||
margin-left: 30rpx; |
|
||||||
} |
|
||||||
|
|
||||||
.mr-3 { |
|
||||||
margin-right: 30rpx; |
|
||||||
} |
|
||||||
</style> |
|
@ -1,176 +0,0 @@ |
|||||||
const app = getApp(); |
|
||||||
import dayjs from "dayjs"; |
|
||||||
Component({ |
|
||||||
behaviors: [], |
|
||||||
properties: { |
|
||||||
audio: { |
|
||||||
type: Object, |
|
||||||
observer(val) { |
|
||||||
if (this.audioContext) { |
|
||||||
const { play } = this.data; |
|
||||||
if (play) { |
|
||||||
this.audioContext.pause(); |
|
||||||
this.setData({ |
|
||||||
play: false, |
|
||||||
progress: 0, |
|
||||||
time: "00", |
|
||||||
}); |
|
||||||
} |
|
||||||
this.audioContext.destroy(); |
|
||||||
} |
|
||||||
if (val) { |
|
||||||
this.audioAddEventListener(val); |
|
||||||
} |
|
||||||
}, |
|
||||||
}, |
|
||||||
}, |
|
||||||
data: { |
|
||||||
Timestamp: app.globalData.Timestamp, |
|
||||||
progress: 0, |
|
||||||
time: "00", |
|
||||||
duration: "00", |
|
||||||
play: false, |
|
||||||
loading: true, |
|
||||||
|
|
||||||
imageUrl: app.globalData.imageUrl, |
|
||||||
progressimg: true, |
|
||||||
}, |
|
||||||
lifetimes: { |
|
||||||
created() {}, |
|
||||||
async attached() {}, |
|
||||||
moved() {}, |
|
||||||
detached() { |
|
||||||
if (this.audioContext) { |
|
||||||
const { play } = this.data; |
|
||||||
if (play) { |
|
||||||
this.audioContext.pause(); |
|
||||||
} |
|
||||||
this.audioContext.destroy(); |
|
||||||
} |
|
||||||
this.audioAddEventListener = null; |
|
||||||
this.setData({ |
|
||||||
play: false, |
|
||||||
progress: 0, |
|
||||||
time: "00", |
|
||||||
}); |
|
||||||
}, |
|
||||||
}, |
|
||||||
pageLifetimes: { |
|
||||||
// 组件所在页面的生命周期函数
|
|
||||||
show: function () {}, |
|
||||||
hide: function () { |
|
||||||
const { play } = this.data; |
|
||||||
if (play) { |
|
||||||
this.audioContext.pause(); |
|
||||||
} |
|
||||||
}, |
|
||||||
resize: function () {}, |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
togglePlay() { |
|
||||||
const { play, loading } = this.data; |
|
||||||
if (loading) { |
|
||||||
wx.showToast({ |
|
||||||
title: "音频加载中", |
|
||||||
icon: "none", |
|
||||||
}); |
|
||||||
return; |
|
||||||
} |
|
||||||
if (play) { |
|
||||||
this.audioContext.pause(); |
|
||||||
} else { |
|
||||||
this.audioContext.play(); |
|
||||||
} |
|
||||||
}, |
|
||||||
formatTime(time) { |
|
||||||
let m = parseInt(time / 60); |
|
||||||
let s = parseInt(time % 60); |
|
||||||
return this.towNum(m) + ":" + this.towNum(s); |
|
||||||
}, |
|
||||||
towNum(num) { |
|
||||||
if (num >= 10) { |
|
||||||
return num; |
|
||||||
} else { |
|
||||||
return "0" + num; |
|
||||||
} |
|
||||||
}, |
|
||||||
audioAddEventListener(val) { |
|
||||||
const that = this; |
|
||||||
this.setData({ |
|
||||||
duration: this.formatTime(val.size), |
|
||||||
}); |
|
||||||
that.audioContext = wx.createInnerAudioContext(); |
|
||||||
that.audioContext.src = val.url; |
|
||||||
that.setData({ |
|
||||||
loading: false, |
|
||||||
}); |
|
||||||
that.audioContext.onError(({ errCode, ...reset }) => { |
|
||||||
console.log("reset: ", reset); |
|
||||||
console.log("errCode: ", errCode); |
|
||||||
if (errCode === 10004 || errCode == 10001 || errCode == -1) { |
|
||||||
that.audioContext.destroy(); |
|
||||||
that.setData({ |
|
||||||
loading: true, |
|
||||||
}); |
|
||||||
setTimeout(() => { |
|
||||||
that.audioAddEventListener(val); |
|
||||||
}, 300); |
|
||||||
} |
|
||||||
}); |
|
||||||
that.audioContext.onPlay(() => { |
|
||||||
that.setData({ |
|
||||||
play: true, |
|
||||||
}); |
|
||||||
}); |
|
||||||
that.audioContext.onPause(() => { |
|
||||||
console.log(1111111); |
|
||||||
that.setData({ |
|
||||||
play: false, |
|
||||||
}); |
|
||||||
}); |
|
||||||
that.audioContext.onEnded(() => { |
|
||||||
that.audioContext.seek(0); |
|
||||||
that.setData({ |
|
||||||
play: false, |
|
||||||
progress: 0, |
|
||||||
time: "00", |
|
||||||
}); |
|
||||||
}); |
|
||||||
that.audioContext.onTimeUpdate(() => { |
|
||||||
const duration = that.audioContext.duration || 0; |
|
||||||
const currentTime = that.audioContext.currentTime || 0; |
|
||||||
const progress = (currentTime / duration) * 100; |
|
||||||
if (duration == Infinity) { |
|
||||||
return; |
|
||||||
} |
|
||||||
that.setData({ |
|
||||||
play: true, |
|
||||||
duration: that.formatTime(duration), |
|
||||||
time: that.formatTime(currentTime), |
|
||||||
}); |
|
||||||
if (that.data.progressimg) { |
|
||||||
this.setData({ |
|
||||||
progress: progress, |
|
||||||
}); |
|
||||||
} |
|
||||||
}); |
|
||||||
}, |
|
||||||
handleAuthChangeimg() { |
|
||||||
console.log(11111); |
|
||||||
this.setData({ |
|
||||||
progressimg: false, |
|
||||||
}); |
|
||||||
}, |
|
||||||
handleAuthChange(e) { |
|
||||||
console.log(22222222222); |
|
||||||
let { duration } = this.data; |
|
||||||
const secods = this.audioContext.duration || duration.split(":")[0] * 60 + duration.split(":")[1] * 1; |
|
||||||
const progress = e.detail.value; |
|
||||||
let seek = ((secods / 100) * progress).toFixed(3) * 1; |
|
||||||
this.audioContext.seek(seek); |
|
||||||
this.setData({ |
|
||||||
progressimg: true, |
|
||||||
}); |
|
||||||
}, |
|
||||||
}, |
|
||||||
}); |
|
@ -1,5 +0,0 @@ |
|||||||
{ |
|
||||||
"navigationBarTitleText": "", |
|
||||||
"component": true, |
|
||||||
"usingComponents": {} |
|
||||||
} |
|
@ -1,54 +0,0 @@ |
|||||||
.audio { |
|
||||||
width: 100%; |
|
||||||
height: 86rpx; |
|
||||||
position: relative; |
|
||||||
.audio-bg { |
|
||||||
margin: 0 120rpx 0 80rpx; |
|
||||||
height: 100%; |
|
||||||
width: calc(100% - 200rpx); |
|
||||||
} |
|
||||||
.card-auth { |
|
||||||
position: absolute; |
|
||||||
left: 0; |
|
||||||
top: 0; |
|
||||||
width: 100%; |
|
||||||
padding: 14rpx 26rpx 12rpx; |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
justify-content: space-between; |
|
||||||
box-sizing: border-box; |
|
||||||
background: rgba(174, 182, 205, 0.1); |
|
||||||
border-radius: 50rpx 50rpx 50rpx 50rpx; |
|
||||||
border: 1rpx solid rgba(181, 205, 255, 0.1); |
|
||||||
.icon { |
|
||||||
width: 60rpx; |
|
||||||
height: 60rpx; |
|
||||||
flex-shrink: 0; |
|
||||||
} |
|
||||||
.center { |
|
||||||
position: relative; |
|
||||||
width: 100%; |
|
||||||
margin: 0 30rpx; |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
.progress-bg { |
|
||||||
width: 100%; |
|
||||||
height: 60rpx; |
|
||||||
} |
|
||||||
|
|
||||||
.progress { |
|
||||||
position: absolute; |
|
||||||
left: 0; |
|
||||||
top: 50%; |
|
||||||
transform: translateY(-50%); |
|
||||||
width: 100%; |
|
||||||
margin: 0; |
|
||||||
} |
|
||||||
} |
|
||||||
.time { |
|
||||||
flex-shrink: 0; |
|
||||||
font-size: 24rpx; |
|
||||||
color: #e04775; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,28 +0,0 @@ |
|||||||
<view class="audio"> |
|
||||||
<view class="card-auth"> |
|
||||||
<image |
|
||||||
class="icon extend-via-pseudo-elem" |
|
||||||
src="{{imageUrl}}za-images/1/audio-{{play?'pause':'play'}}.png?t={{Timestamp}}" |
|
||||||
catchtap="togglePlay" |
|
||||||
></image> |
|
||||||
<view class="center"> |
|
||||||
<image |
|
||||||
class="progress-bg" |
|
||||||
mode="aspectFill" |
|
||||||
src="https://m.zd.hbraas.com/zd/1/firee-audio-bg.png?t=1689998782161" |
|
||||||
></image> |
|
||||||
<slider |
|
||||||
active |
|
||||||
activeColor="#E04775" |
|
||||||
backgroundColor="#E04775" |
|
||||||
bind:changing="handleAuthChangeimg" |
|
||||||
bindchange="handleAuthChange" |
|
||||||
block-color="#E04775" |
|
||||||
block-size="12" |
|
||||||
class="progress" |
|
||||||
value="{{progress}}" |
|
||||||
/> |
|
||||||
</view> |
|
||||||
<text class="time" wx:if="{{duration}}">{{duration}}</text> |
|
||||||
</view> |
|
||||||
</view> |
|
@ -1,7 +0,0 @@ |
|||||||
{ |
|
||||||
"component": true, |
|
||||||
"usingComponents": { |
|
||||||
"van-nav-bar": "@vant/weapp/nav-bar/index", |
|
||||||
"van-icon": "@vant/weapp/icon/index" |
|
||||||
} |
|
||||||
} |
|
@ -1,24 +0,0 @@ |
|||||||
.navbar { |
|
||||||
padding: 0 20rpx 0 0; |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
.back-icon { |
|
||||||
margin-right: 40rpx; |
|
||||||
} |
|
||||||
.num { |
|
||||||
width: 64rpx; |
|
||||||
height: 64rpx; |
|
||||||
border-radius: 50%; |
|
||||||
border: 3rpx solid #e04876; |
|
||||||
text-align: center; |
|
||||||
line-height: 64rpx; |
|
||||||
margin-right: 24rpx; |
|
||||||
font-size: 40rpx; |
|
||||||
color: #e04876; |
|
||||||
font-weight: bold; |
|
||||||
&.active { |
|
||||||
background-color: #e04876; |
|
||||||
color: #fff; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,23 +0,0 @@ |
|||||||
const app = getApp<IAppOption>(); |
|
||||||
|
|
||||||
Component({ |
|
||||||
properties: { |
|
||||||
num: { |
|
||||||
type: Number, |
|
||||||
value: 0, |
|
||||||
}, |
|
||||||
back: { |
|
||||||
type: Boolean, |
|
||||||
value: false, |
|
||||||
}, |
|
||||||
}, |
|
||||||
data: { |
|
||||||
imageUrl: app.globalData.imageUrl, |
|
||||||
Timestamp: app.globalData.Timestamp, |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
handleBack() { |
|
||||||
this.triggerEvent("back"); |
|
||||||
}, |
|
||||||
}, |
|
||||||
}); |
|
@ -1,7 +0,0 @@ |
|||||||
<van-nav-bar title="" custom-style="background:transparent;"> |
|
||||||
<view class="navbar" slot="left"> |
|
||||||
<van-icon wx:if="{{back}}" class="back-icon" name="arrow-left" color="#333333" size="22" bind:tap="handleBack" /> |
|
||||||
<view class="num {{num>=1 && 'active'}}">1</view> |
|
||||||
<view class="num {{num>=2 && 'active'}}">2</view> |
|
||||||
</view> |
|
||||||
</van-nav-bar> |
|
@ -1,7 +0,0 @@ |
|||||||
{ |
|
||||||
"component": true, |
|
||||||
"usingComponents": { |
|
||||||
"van-nav-bar": "@vant/weapp/nav-bar/index", |
|
||||||
"van-icon": "@vant/weapp/icon/index" |
|
||||||
} |
|
||||||
} |
|
@ -1,16 +0,0 @@ |
|||||||
.navbar { |
|
||||||
padding: 0 20rpx 0 0; |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
.back-icon { |
|
||||||
margin-right: 40rpx; |
|
||||||
} |
|
||||||
.nav-img { |
|
||||||
width: 356rpx; |
|
||||||
height: 46rpx; |
|
||||||
} |
|
||||||
.drug-nav-img { |
|
||||||
width: 199rpx; |
|
||||||
height: 36rpx; |
|
||||||
} |
|
||||||
} |
|
@ -1,23 +0,0 @@ |
|||||||
const app = getApp<IAppOption>(); |
|
||||||
|
|
||||||
Component({ |
|
||||||
properties: { |
|
||||||
back: { |
|
||||||
type: Boolean, |
|
||||||
value: false, |
|
||||||
}, |
|
||||||
drug: { |
|
||||||
type: Boolean, |
|
||||||
value: false, |
|
||||||
}, |
|
||||||
}, |
|
||||||
data: { |
|
||||||
imageUrl: app.globalData.imageUrl, |
|
||||||
Timestamp: app.globalData.Timestamp, |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
handleBack() { |
|
||||||
wx.navigateBack(); |
|
||||||
}, |
|
||||||
}, |
|
||||||
}); |
|
@ -1,7 +0,0 @@ |
|||||||
<van-nav-bar title="" custom-style="background:transparent;"> |
|
||||||
<view class="navbar" slot="left"> |
|
||||||
<van-icon wx:if="{{back}}" class="back-icon" name="arrow-left" color="#333333" size="22" bind:tap="handleBack" /> |
|
||||||
<image wx:if="{{drug}}" class="drug-nav-img" src="{{imageUrl}}za-images/1.5/page-title.png?t={{Timestamp}}"></image> |
|
||||||
<image wx:else class="nav-img" src="{{imageUrl}}za-images/1/page-title.png?t={{Timestamp}}"></image> |
|
||||||
</view> |
|
||||||
</van-nav-bar> |
|
@ -1,25 +1,20 @@ |
|||||||
const app = getApp() |
const app = getApp(); |
||||||
|
|
||||||
Component({ |
Component({ |
||||||
externalClasses: ['external-class'], |
|
||||||
properties: { |
properties: { |
||||||
pagination: { |
pagination: { |
||||||
type: Object, |
type: Object, |
||||||
value() { |
value() { |
||||||
return {} |
return {}; |
||||||
}, |
}, |
||||||
}, |
}, |
||||||
customEmpty: { |
|
||||||
tyep: Boolean, |
|
||||||
value: false, |
|
||||||
}, |
|
||||||
}, |
}, |
||||||
data: { |
data: { |
||||||
imageUrl: app.globalData.imageUrl, |
imageUrl: app.globalData.imageUrl, |
||||||
}, |
}, |
||||||
methods: { |
methods: { |
||||||
handleTouchmove() { |
handleTouchmove() { |
||||||
return false |
return false; |
||||||
}, |
}, |
||||||
}, |
}, |
||||||
}) |
}); |
||||||
|
@ -1,7 +0,0 @@ |
|||||||
{ |
|
||||||
"component": true, |
|
||||||
"usingComponents": { |
|
||||||
"van-tabbar": "@vant/weapp/tabbar/index", |
|
||||||
"van-tabbar-item": "@vant/weapp/tabbar-item/index" |
|
||||||
} |
|
||||||
} |
|
@ -1,15 +0,0 @@ |
|||||||
/* custom-tab-bar/index.wxss */ |
|
||||||
|
|
||||||
.tab-item { |
|
||||||
.icon { |
|
||||||
width: 48rpx; |
|
||||||
height: 48rpx; |
|
||||||
} |
|
||||||
.name { |
|
||||||
font-size: 20rpx; |
|
||||||
color: rgba(105, 104, 110, 1); |
|
||||||
&.active { |
|
||||||
color: rgba(33, 29, 46, 1); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,82 +0,0 @@ |
|||||||
import { getCurrentPageUrl } from '@/utils/util' |
|
||||||
const app = getApp() |
|
||||||
|
|
||||||
Component({ |
|
||||||
properties: {}, |
|
||||||
data: { |
|
||||||
imageUrl: app.globalData.imageUrl, |
|
||||||
isChild: 0, |
|
||||||
active: 0, |
|
||||||
list: [ |
|
||||||
{ |
|
||||||
pagePath: '/patient/pages/index/index', |
|
||||||
text: '首页', |
|
||||||
icon: 'tab1', |
|
||||||
iconActive: 'tab-active1', |
|
||||||
}, |
|
||||||
{ |
|
||||||
pagePath: '/patient/pages/repository/index', |
|
||||||
text: '了解TED', |
|
||||||
icon: 'tab2', |
|
||||||
iconActive: 'tab-active2', |
|
||||||
}, |
|
||||||
{ |
|
||||||
pagePath: '/patient/pages/live/index', |
|
||||||
text: '大咖说', |
|
||||||
icon: 'tab5', |
|
||||||
iconActive: 'tab-active5', |
|
||||||
}, |
|
||||||
{ |
|
||||||
pagePath: '/patient/pages/my/index', |
|
||||||
text: '我的', |
|
||||||
icon: 'tab3', |
|
||||||
iconActive: 'tab-active3', |
|
||||||
}, |
|
||||||
], |
|
||||||
userInfo: {}, |
|
||||||
showRed: false, |
|
||||||
|
|
||||||
config: {} as any, |
|
||||||
}, |
|
||||||
observers: {}, |
|
||||||
lifetimes: { |
|
||||||
ready() { |
|
||||||
app.zdGetTheme().then((res) => { |
|
||||||
this.setData({ |
|
||||||
theme: res, |
|
||||||
}) |
|
||||||
}) |
|
||||||
|
|
||||||
const pagePath = getCurrentPageUrl() |
|
||||||
const active = this.data.list.findIndex((item) => item.pagePath === pagePath) |
|
||||||
this.setData({ |
|
||||||
active, |
|
||||||
}) |
|
||||||
this.setData({ |
|
||||||
showRed: app.globalData.showRed, |
|
||||||
}) |
|
||||||
// getApp().registerListener(() => {
|
|
||||||
// wx.ajax({
|
|
||||||
// method: 'GET',
|
|
||||||
// url: '?r=zd/common/get-config',
|
|
||||||
// }).then((res) => {
|
|
||||||
// this.setData({
|
|
||||||
// config: res,
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
}, |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
onChange() {}, |
|
||||||
handleNav(e) { |
|
||||||
const { index } = e.currentTarget.dataset |
|
||||||
const { list } = this.data |
|
||||||
const pagePath = list[index].pagePath |
|
||||||
app.globalData.BeginnerCardId = '' |
|
||||||
wx.reLaunch({ |
|
||||||
url: pagePath, |
|
||||||
}) |
|
||||||
}, |
|
||||||
}, |
|
||||||
}) |
|
@ -1,13 +0,0 @@ |
|||||||
<van-tabbar active="{{ active }}" active-color="#CF5375" bind:change="onChange" inactive-color="#CCCCCC"> |
|
||||||
<block wx:for="{{list}}" wx:key="*this"> |
|
||||||
<van-tabbar-item |
|
||||||
class="tab-item" |
|
||||||
bind:tap="handleNav" |
|
||||||
data-index="{{index}}" |
|
||||||
icon="{{imageUrl}}tabbar/{{active==index ? item.iconActive: item.icon}}.png?r=1" |
|
||||||
> |
|
||||||
<view class="name {{index==active && 'active'}}">{{item.text}}</view> |
|
||||||
<view class="hot"></view> |
|
||||||
</van-tabbar-item> |
|
||||||
</block> |
|
||||||
</van-tabbar> |
|
@ -1,7 +0,0 @@ |
|||||||
{ |
|
||||||
"component": true, |
|
||||||
"usingComponents": { |
|
||||||
"van-popup": "@vant/weapp/popup/index", |
|
||||||
"van-icon": "@vant/weapp/icon/index" |
|
||||||
} |
|
||||||
} |
|
@ -1,128 +0,0 @@ |
|||||||
.aside-share { |
|
||||||
position: fixed; |
|
||||||
right: 22rpx; |
|
||||||
bottom: 120rpx; |
|
||||||
width: 136rpx; |
|
||||||
height: 136rpx; |
|
||||||
} |
|
||||||
|
|
||||||
.popup { |
|
||||||
position: relative; |
|
||||||
background-color: #fff; |
|
||||||
.close { |
|
||||||
position: absolute; |
|
||||||
top: 52rpx; |
|
||||||
right: 32rpx; |
|
||||||
color: rgba(72, 72, 72, 1); |
|
||||||
font-size: 34rpx; |
|
||||||
} |
|
||||||
.p-header { |
|
||||||
padding: 46rpx 30rpx 0; |
|
||||||
.title { |
|
||||||
text-align: center; |
|
||||||
font-size: 36rpx; |
|
||||||
color: rgba(72, 72, 72, 1); |
|
||||||
font-weight: bold; |
|
||||||
} |
|
||||||
.tip { |
|
||||||
text-align: center; |
|
||||||
margin-top: 16rpx; |
|
||||||
font-size: 32rpx; |
|
||||||
color: rgba(72, 72, 72, 1); |
|
||||||
} |
|
||||||
.area { |
|
||||||
margin-top: 48rpx; |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
justify-content: space-between; |
|
||||||
gap: 14rpx; |
|
||||||
.item { |
|
||||||
flex: 1; |
|
||||||
padding: 18rpx 30rpx; |
|
||||||
box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(0, 0, 0, 0.11); |
|
||||||
border-radius: 12rpx 12rpx 12rpx 12rpx; |
|
||||||
border: 2rpx solid #e04775; |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
justify-content: space-between; |
|
||||||
.content { |
|
||||||
font-size: 32rpx; |
|
||||||
color: rgba(72, 72, 72, 1); |
|
||||||
max-width: 5em; |
|
||||||
overflow: hidden; |
|
||||||
white-space: nowrap; |
|
||||||
text-overflow: ellipsis; |
|
||||||
} |
|
||||||
.icon { |
|
||||||
width: 32rpx; |
|
||||||
height: 32rpx; |
|
||||||
} |
|
||||||
} |
|
||||||
.picker { |
|
||||||
flex: 1; |
|
||||||
} |
|
||||||
.btn { |
|
||||||
width: 126rpx; |
|
||||||
height: 76rpx; |
|
||||||
font-size: 32rpx; |
|
||||||
color: rgba(255, 255, 255, 1); |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
justify-content: center; |
|
||||||
background: #e04775; |
|
||||||
border-radius: 12rpx 12rpx 12rpx 12rpx; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
.select { |
|
||||||
margin-top: 44rpx; |
|
||||||
padding: 0 30rpx 0; |
|
||||||
display: grid; |
|
||||||
grid-template-columns: repeat(auto-fit, 68rpx); |
|
||||||
gap: 26rpx 20rpx; |
|
||||||
.s-item { |
|
||||||
width: 68rpx; |
|
||||||
height: 68rpx; |
|
||||||
text-align: center; |
|
||||||
line-height: 68rpx; |
|
||||||
font-size: 28rpx; |
|
||||||
color: rgba(158, 158, 158, 1); |
|
||||||
border-radius: 50%; |
|
||||||
background: #f7f8f9; |
|
||||||
&.active { |
|
||||||
color: #fff; |
|
||||||
background-color: rgba(224, 71, 117, 1); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
.scroll { |
|
||||||
padding: 0 30rpx; |
|
||||||
height: 45vh; |
|
||||||
box-sizing: border-box; |
|
||||||
.item { |
|
||||||
padding: 32rpx 0; |
|
||||||
font-size: 28rpx; |
|
||||||
color: rgba(72, 72, 72, 1); |
|
||||||
border-bottom: 2px solid #fbfbfb; |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
justify-content: space-between; |
|
||||||
.word { |
|
||||||
margin-right: 24rpx; |
|
||||||
display: inline-block; |
|
||||||
width: 1em; |
|
||||||
color: rgba(158, 158, 158, 1); |
|
||||||
} |
|
||||||
.icon { |
|
||||||
width: 36rpx; |
|
||||||
height: 36rpx; |
|
||||||
} |
|
||||||
&.active { |
|
||||||
color: rgba(224, 71, 117, 1); |
|
||||||
.word { |
|
||||||
color: rgba(224, 71, 117, 1); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,312 +0,0 @@ |
|||||||
const app = getApp<IAppOption>(); |
|
||||||
|
|
||||||
Component({ |
|
||||||
properties: { |
|
||||||
// 省份名称
|
|
||||||
pname: { |
|
||||||
type: String, |
|
||||||
value: '', |
|
||||||
}, |
|
||||||
// 省份ID
|
|
||||||
pid: { |
|
||||||
type: String, |
|
||||||
value: '', |
|
||||||
}, |
|
||||||
// 城市名称
|
|
||||||
cname: { |
|
||||||
type: String, |
|
||||||
value: '', |
|
||||||
}, |
|
||||||
// 城市ID
|
|
||||||
cid: { |
|
||||||
type: String, |
|
||||||
value: '', |
|
||||||
}, |
|
||||||
}, |
|
||||||
observers: { |
|
||||||
show(newVal: boolean) { |
|
||||||
this.triggerEvent('show', newVal); |
|
||||||
}, |
|
||||||
}, |
|
||||||
data: { |
|
||||||
show: false, |
|
||||||
word: '', |
|
||||||
imageUrl: app.globalData.imageUrl, |
|
||||||
Timestamp: app.globalData.Timestamp, |
|
||||||
|
|
||||||
active: 0, |
|
||||||
ProvinceName: '', |
|
||||||
ProvinceId: '', |
|
||||||
CityName: '', |
|
||||||
CityId: '', |
|
||||||
proList: { |
|
||||||
A: [ |
|
||||||
{ |
|
||||||
name: '安徽省', |
|
||||||
code: '340000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '澳门特别行政区', |
|
||||||
code: '820000', |
|
||||||
}, |
|
||||||
], |
|
||||||
B: [ |
|
||||||
{ |
|
||||||
name: '北京市', |
|
||||||
code: '110000', |
|
||||||
}, |
|
||||||
], |
|
||||||
C: [ |
|
||||||
{ |
|
||||||
name: '重庆市', |
|
||||||
code: '500000', |
|
||||||
}, |
|
||||||
], |
|
||||||
F: [ |
|
||||||
{ |
|
||||||
name: '福建省', |
|
||||||
code: '350000', |
|
||||||
}, |
|
||||||
], |
|
||||||
G: [ |
|
||||||
{ |
|
||||||
name: '甘肃省', |
|
||||||
code: '620000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '广东省', |
|
||||||
code: '440000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '广西壮族自治区', |
|
||||||
code: '450000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '贵州省', |
|
||||||
code: '520000', |
|
||||||
}, |
|
||||||
], |
|
||||||
H: [ |
|
||||||
{ |
|
||||||
name: '海南省', |
|
||||||
code: '460000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '河北省', |
|
||||||
code: '130000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '河南省', |
|
||||||
code: '410000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '黑龙江省', |
|
||||||
code: '230000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '湖北省', |
|
||||||
code: '420000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '湖南省', |
|
||||||
code: '430000', |
|
||||||
}, |
|
||||||
], |
|
||||||
J: [ |
|
||||||
{ |
|
||||||
name: '吉林省', |
|
||||||
code: '220000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '江苏省', |
|
||||||
code: '320000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '江西省', |
|
||||||
code: '360000', |
|
||||||
}, |
|
||||||
], |
|
||||||
L: [ |
|
||||||
{ |
|
||||||
name: '辽宁省', |
|
||||||
code: '210000', |
|
||||||
}, |
|
||||||
], |
|
||||||
N: [ |
|
||||||
{ |
|
||||||
name: '宁夏回族自治区', |
|
||||||
code: '640000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '内蒙古自治区', |
|
||||||
code: '150000', |
|
||||||
}, |
|
||||||
], |
|
||||||
Q: [ |
|
||||||
{ |
|
||||||
name: '青海省', |
|
||||||
code: '630000', |
|
||||||
}, |
|
||||||
], |
|
||||||
S: [ |
|
||||||
{ |
|
||||||
name: '山东省', |
|
||||||
code: '370000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '山西省', |
|
||||||
code: '140000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '陕西省', |
|
||||||
code: '610000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '上海市', |
|
||||||
code: '310000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '四川省', |
|
||||||
code: '510000', |
|
||||||
}, |
|
||||||
], |
|
||||||
T: [ |
|
||||||
{ |
|
||||||
name: '天津市', |
|
||||||
code: '120000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '台湾省', |
|
||||||
code: '710000', |
|
||||||
}, |
|
||||||
], |
|
||||||
X: [ |
|
||||||
{ |
|
||||||
name: '西藏自治区', |
|
||||||
code: '540000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '新疆维吾尔自治区', |
|
||||||
code: '650000', |
|
||||||
}, |
|
||||||
{ |
|
||||||
name: '香港特别行政区', |
|
||||||
code: '810000', |
|
||||||
}, |
|
||||||
], |
|
||||||
Y: [ |
|
||||||
{ |
|
||||||
name: '云南省', |
|
||||||
code: '530000', |
|
||||||
}, |
|
||||||
], |
|
||||||
Z: [ |
|
||||||
{ |
|
||||||
name: '浙江省', |
|
||||||
code: '330000', |
|
||||||
}, |
|
||||||
], |
|
||||||
}, |
|
||||||
area: [] as any, |
|
||||||
range: [], |
|
||||||
|
|
||||||
scrollIntoView0: '', |
|
||||||
scrollIntoView1: '', |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
handleShow() { |
|
||||||
this.setData({ |
|
||||||
show: true, |
|
||||||
ProvinceName: this.data.pname || '', |
|
||||||
ProvinceId: this.data.pid || '', |
|
||||||
CityName: this.data.cname || '', |
|
||||||
CityId: this.data.cid || '', |
|
||||||
|
|
||||||
scrollIntoView0: this.data.pid || '', |
|
||||||
scrollIntoView1: this.data.cid || '', |
|
||||||
}); |
|
||||||
this.getArea(); |
|
||||||
}, |
|
||||||
getArea() { |
|
||||||
wx.ajax({ |
|
||||||
method: 'GET', |
|
||||||
url: '/js/area.json', |
|
||||||
isJSON: true, |
|
||||||
}).then((res) => { |
|
||||||
this.setData({ |
|
||||||
area: res, |
|
||||||
}); |
|
||||||
this.getRangeList(); |
|
||||||
}); |
|
||||||
}, |
|
||||||
handleItem(e: any) { |
|
||||||
const { code, name } = e.currentTarget.dataset; |
|
||||||
this.setData({ |
|
||||||
ProvinceId: code, |
|
||||||
ProvinceName: name, |
|
||||||
CityId: '', |
|
||||||
CityName: '', |
|
||||||
}); |
|
||||||
this.getRangeList(); |
|
||||||
}, |
|
||||||
handleChangeCity(e: any) { |
|
||||||
const { code, name } = e.currentTarget.dataset; |
|
||||||
this.setData({ |
|
||||||
CityId: code, |
|
||||||
CityName: name, |
|
||||||
}); |
|
||||||
}, |
|
||||||
handleShare() { |
|
||||||
this.setData({ |
|
||||||
show: false, |
|
||||||
}); |
|
||||||
this.triggerEvent('ok', { |
|
||||||
ProvinceName: this.data.ProvinceName, |
|
||||||
ProvinceId: this.data.ProvinceId, |
|
||||||
CityName: this.data.CityName, |
|
||||||
CityId: this.data.CityId, |
|
||||||
}); |
|
||||||
}, |
|
||||||
handleSelect(e) { |
|
||||||
const { id } = e.currentTarget.dataset; |
|
||||||
this.setData({ |
|
||||||
word: id, |
|
||||||
scrollIntoView0: id, |
|
||||||
}); |
|
||||||
}, |
|
||||||
getRangeList() { |
|
||||||
const { area, ProvinceId } = this.data; |
|
||||||
if (!ProvinceId) return; |
|
||||||
const range = area.filter((item: any) => item.value == ProvinceId)[0].children; |
|
||||||
this.setData({ |
|
||||||
range, |
|
||||||
active: 1, |
|
||||||
scrollIntoView0: '', |
|
||||||
scrollIntoView1: `id${this.data.CityId}`, |
|
||||||
}); |
|
||||||
}, |
|
||||||
handleProvince() { |
|
||||||
this.setData({ |
|
||||||
active: 0, |
|
||||||
scrollIntoView0: this.data.word || `id${this.data.ProvinceId}`, |
|
||||||
scrollIntoView1: '', |
|
||||||
}); |
|
||||||
}, |
|
||||||
handleCity() { |
|
||||||
const { ProvinceId } = this.data; |
|
||||||
if (!ProvinceId) { |
|
||||||
wx.showToast({ |
|
||||||
title: '请先选择省份', |
|
||||||
icon: 'none', |
|
||||||
}); |
|
||||||
return; |
|
||||||
} |
|
||||||
this.getRangeList(); |
|
||||||
}, |
|
||||||
handleClose() { |
|
||||||
this.setData({ |
|
||||||
show: false, |
|
||||||
}); |
|
||||||
}, |
|
||||||
}, |
|
||||||
}); |
|
@ -1,87 +0,0 @@ |
|||||||
<slot bind:tap="handleShow"></slot> |
|
||||||
|
|
||||||
<van-popup show="{{ show }}" position="bottom" round close-on-click-overlay bind:click-overlay="handleClose"> |
|
||||||
<view class="popup"> |
|
||||||
<van-icon catch:tap="handleClose" class="close" name="cross" /> |
|
||||||
<view class="p-header"> |
|
||||||
<view class="title">选择省份和地区</view> |
|
||||||
<!-- <view class="tip">对方打开后自动定位此地区</view> --> |
|
||||||
<view class="area"> |
|
||||||
<view class="item" bind:tap="handleProvince"> |
|
||||||
<view class="content">{{ProvinceName || '请选择省份'}}</view> |
|
||||||
<image class="icon" src="{{imageUrl}}za-images/icon6.png?t={{Timestamp}}"></image> |
|
||||||
</view> |
|
||||||
<view class="item" bind:tap="handleCity"> |
|
||||||
<view class="content">{{CityName || '请选择城市'}}</view> |
|
||||||
<image class="icon" src="{{imageUrl}}za-images/icon6.png?t={{Timestamp}}"></image> |
|
||||||
</view> |
|
||||||
<view class="btn" bind:tap="handleShare">确定</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
<block wx:if="{{active===1}}"> |
|
||||||
<scroll-view |
|
||||||
class="scroll" |
|
||||||
scroll-y |
|
||||||
scroll-with-animation |
|
||||||
scroll-into-view="{{scrollIntoView1}}" |
|
||||||
show-scrollbar="{{false}}" |
|
||||||
> |
|
||||||
<view |
|
||||||
class="item {{item.value === CityId && 'active'}}" |
|
||||||
id="{{'id'+item.value}}" |
|
||||||
wx:for="{{range}}" |
|
||||||
wx:key="index" |
|
||||||
bind:tap="handleChangeCity" |
|
||||||
data-code="{{item.value}}" |
|
||||||
data-name="{{item.label}}" |
|
||||||
> |
|
||||||
<view class="left">{{item.label}}</view> |
|
||||||
<image wx:if="{{item.value === CityId}}" class="icon" src="{{imageUrl}}icon7.png?t={{Timestamp}}"></image> |
|
||||||
</view> |
|
||||||
</scroll-view> |
|
||||||
</block> |
|
||||||
<block wx:else> |
|
||||||
<view class="select"> |
|
||||||
<view |
|
||||||
class="s-item {{word===index && 'active'}}" |
|
||||||
wx:for="{{proList}}" |
|
||||||
wx:key="index" |
|
||||||
bind:tap="handleSelect" |
|
||||||
data-id="{{index}}" |
|
||||||
> |
|
||||||
{{index}} |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
<scroll-view |
|
||||||
class="scroll" |
|
||||||
scroll-y |
|
||||||
scroll-into-view="{{scrollIntoView0}}" |
|
||||||
scroll-with-animation |
|
||||||
show-scrollbar="{{false}}" |
|
||||||
> |
|
||||||
<block wx:for="{{proList}}" wx:for-item="list" wx:for-index="key" wx:key="key"> |
|
||||||
<block wx:for="{{list}}" wx:key="index"> |
|
||||||
<view wx:if="{{index==0}}" id="{{key}}"></view> |
|
||||||
<view |
|
||||||
class="item {{item.code=== ProvinceId && 'active'}}" |
|
||||||
id="{{'id'+item.code}}" |
|
||||||
bind:tap="handleItem" |
|
||||||
data-code="{{item.code}}" |
|
||||||
data-name="{{item.name}}" |
|
||||||
> |
|
||||||
<view class="left"> |
|
||||||
<text class="word">{{index===0 ? key : ''}}</text> |
|
||||||
{{item.name}} |
|
||||||
</view> |
|
||||||
<image |
|
||||||
wx:if="{{item.code=== ProvinceId}}" |
|
||||||
class="icon" |
|
||||||
src="{{imageUrl}}icon7.png?t={{Timestamp}}" |
|
||||||
></image> |
|
||||||
</view> |
|
||||||
</block> |
|
||||||
</block> |
|
||||||
</scroll-view> |
|
||||||
</block> |
|
||||||
</view> |
|
||||||
</van-popup> |
|
@ -1,6 +0,0 @@ |
|||||||
{ |
|
||||||
"component": true, |
|
||||||
"usingComponents": { |
|
||||||
"van-popup": "@vant/weapp/popup/index" |
|
||||||
} |
|
||||||
} |
|
@ -1,95 +0,0 @@ |
|||||||
.from { |
|
||||||
padding: 48rpx 40rpx; |
|
||||||
width: 650rpx; |
|
||||||
box-sizing: border-box; |
|
||||||
background: linear-gradient(349deg, #ffffff 0%, #e2f1f4 100%); |
|
||||||
border-radius: 24rpx 24rpx 24rpx 24rpx; |
|
||||||
border: 2rpx solid #ffffff; |
|
||||||
.title { |
|
||||||
font-size: 32rpx; |
|
||||||
color: #283031; |
|
||||||
font-weight: bold; |
|
||||||
} |
|
||||||
.date { |
|
||||||
margin-top: 24rpx; |
|
||||||
padding: 14rpx 32rpx; |
|
||||||
display: flex; |
|
||||||
align-items: center; |
|
||||||
justify-content: space-between; |
|
||||||
background-color: #f2f4f5; |
|
||||||
border-radius: 16rpx; |
|
||||||
|
|
||||||
.conetent { |
|
||||||
font-size: 32rpx; |
|
||||||
color: #283031; |
|
||||||
} |
|
||||||
.tril { |
|
||||||
width: 0; |
|
||||||
height: 0; |
|
||||||
border-style: solid; |
|
||||||
border-width: 10rpx 10rpx 0 10rpx; |
|
||||||
border-color: #aeb3b4 transparent transparent transparent; |
|
||||||
} |
|
||||||
} |
|
||||||
.select-title { |
|
||||||
margin-top: 48rpx; |
|
||||||
font-size: 32rpx; |
|
||||||
color: #283031; |
|
||||||
font-weight: bold; |
|
||||||
.sub { |
|
||||||
font-weight: normal; |
|
||||||
} |
|
||||||
} |
|
||||||
.list { |
|
||||||
margin-top: 26rpx; |
|
||||||
max-height: 55vh; |
|
||||||
overflow-y: auto; |
|
||||||
&::-webkit-scrollbar{ |
|
||||||
display: none; |
|
||||||
} |
|
||||||
.item { |
|
||||||
margin-bottom: 16rpx; |
|
||||||
padding: 14rpx 32rpx; |
|
||||||
font-size: 32rpx; |
|
||||||
color: #283031; |
|
||||||
line-height: 48rpx; |
|
||||||
background-color: #f2f4f5; |
|
||||||
border: 1px solid #f2f4f5; |
|
||||||
border-radius: 16rpx; |
|
||||||
&.active { |
|
||||||
border-color: #67baca; |
|
||||||
background-color: #e7f5f8; |
|
||||||
color: #67baca; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
.footer { |
|
||||||
margin-top: 32rpx; |
|
||||||
display: flex; |
|
||||||
justify-content: space-between; |
|
||||||
align-items: center; |
|
||||||
gap: 26rpx; |
|
||||||
text-align: center; |
|
||||||
.cancel { |
|
||||||
flex: 1; |
|
||||||
height: 80rpx; |
|
||||||
font-size: 36rpx; |
|
||||||
color: #67BACA; |
|
||||||
line-height: 80rpx; |
|
||||||
background: #ffffff; |
|
||||||
border-radius: 98rpx 98rpx 98rpx 98rpx; |
|
||||||
border: 2rpx solid #67baca; |
|
||||||
} |
|
||||||
|
|
||||||
.submit { |
|
||||||
flex: 1; |
|
||||||
height: 80rpx; |
|
||||||
font-size: 36rpx; |
|
||||||
color: #FFFFFF; |
|
||||||
line-height: 80rpx; |
|
||||||
background: #67baca; |
|
||||||
border-radius: 98rpx 98rpx 98rpx 98rpx; |
|
||||||
border: 2rpx solid #67baca; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -1,139 +0,0 @@ |
|||||||
import dayjs from 'dayjs' |
|
||||||
|
|
||||||
const _app = getApp<IAppOption>() |
|
||||||
|
|
||||||
// pages/story/a.ts
|
|
||||||
Component({ |
|
||||||
/** |
|
||||||
* 组件的属性列表 |
|
||||||
*/ |
|
||||||
properties: { |
|
||||||
show: { |
|
||||||
type: Boolean, |
|
||||||
value: false, |
|
||||||
}, |
|
||||||
params: { |
|
||||||
type: Object, |
|
||||||
value: undefined, |
|
||||||
}, |
|
||||||
}, |
|
||||||
|
|
||||||
observers: { |
|
||||||
show() { |
|
||||||
if (this.data.params) { |
|
||||||
this.setData({ |
|
||||||
...this.data.params, |
|
||||||
}) |
|
||||||
this.handleDateChange() |
|
||||||
} else { |
|
||||||
this.setData({ |
|
||||||
visitDateName: '', |
|
||||||
visitDate: '', |
|
||||||
hormone: 2, |
|
||||||
traditionalInhibitor: 2, |
|
||||||
gammaGlobulin: 2, |
|
||||||
plasmaExchange: 2, |
|
||||||
bCellInhibitor: 2, |
|
||||||
fcRnAntagonists: 2, |
|
||||||
c5ComplementInhibitor: 2, |
|
||||||
chineseMedicine: 2, |
|
||||||
other: 2, |
|
||||||
recordId: '', |
|
||||||
}) |
|
||||||
} |
|
||||||
}, |
|
||||||
}, |
|
||||||
data: { |
|
||||||
currentDate: dayjs().format('YYYY-MM-DD'), |
|
||||||
|
|
||||||
visitDateName: '', |
|
||||||
visitDate: '', |
|
||||||
hormone: 2, |
|
||||||
traditionalInhibitor: 2, |
|
||||||
gammaGlobulin: 2, |
|
||||||
plasmaExchange: 2, |
|
||||||
bCellInhibitor: 2, |
|
||||||
fcRnAntagonists: 2, |
|
||||||
c5ComplementInhibitor: 2, |
|
||||||
chineseMedicine: 2, |
|
||||||
other: 2, |
|
||||||
recordId: '', |
|
||||||
}, |
|
||||||
|
|
||||||
methods: { |
|
||||||
handleDateChange() { |
|
||||||
this.setData({ |
|
||||||
visitDateName: dayjs(this.data.visitDate).format('YYYY年MM月DD日'), |
|
||||||
}) |
|
||||||
}, |
|
||||||
handleSelect(e) { |
|
||||||
const { name } = e.currentTarget.dataset |
|
||||||
const value = this.data[name] |
|
||||||
this.setData({ |
|
||||||
[name]: value === 2 ? 1 : 2, |
|
||||||
}) |
|
||||||
}, |
|
||||||
submit() { |
|
||||||
const { visitDate, recordId } = this.data |
|
||||||
const params = { |
|
||||||
visitDate, |
|
||||||
recordId, |
|
||||||
} |
|
||||||
if(!visitDate){ |
|
||||||
wx.showToast({ |
|
||||||
title: '请选择复诊日期', |
|
||||||
icon: 'none', |
|
||||||
}) |
|
||||||
return |
|
||||||
} |
|
||||||
const selectKeys = [ |
|
||||||
'hormone', |
|
||||||
'traditionalInhibitor', |
|
||||||
'gammaGlobulin', |
|
||||||
'plasmaExchange', |
|
||||||
'bCellInhibitor', |
|
||||||
'fcRnAntagonists', |
|
||||||
'c5ComplementInhibitor', |
|
||||||
'chineseMedicine', |
|
||||||
'other', |
|
||||||
] |
|
||||||
selectKeys.forEach((item) => { |
|
||||||
params[item] = this.data[item] |
|
||||||
}) |
|
||||||
const onlySelect = selectKeys.some((item) => { |
|
||||||
return this.data[item] === 1 |
|
||||||
}) |
|
||||||
if (!onlySelect) { |
|
||||||
wx.showToast({ |
|
||||||
title: '请至少选择一种复诊后的方案', |
|
||||||
icon: 'none', |
|
||||||
}) |
|
||||||
return |
|
||||||
} |
|
||||||
wx.ajax({ |
|
||||||
method: 'POST', |
|
||||||
url: '?r=xd/re-visit/save-record', |
|
||||||
data: params, |
|
||||||
}).then(() => { |
|
||||||
if (recordId) { |
|
||||||
wx.showToast({ |
|
||||||
icon: 'none', |
|
||||||
title: '编辑成功', |
|
||||||
}) |
|
||||||
} else { |
|
||||||
wx.showToast({ |
|
||||||
icon: 'none', |
|
||||||
title: '添加成功', |
|
||||||
}) |
|
||||||
} |
|
||||||
this.handleCancel() |
|
||||||
this.triggerEvent('refresh', params) |
|
||||||
}) |
|
||||||
}, |
|
||||||
handleCancel() { |
|
||||||
this.setData({ |
|
||||||
show: false, |
|
||||||
}) |
|
||||||
}, |
|
||||||
}, |
|
||||||
}) |
|
@ -1,52 +0,0 @@ |
|||||||
<van-popup custom-style="background: transparent;" round z-index="{{100000}}" show="{{ show }}"> |
|
||||||
<view class="from"> |
|
||||||
<view class="title">您上一次复诊时间?</view> |
|
||||||
<picker mode="date" model:value="{{visitDate}}" end="{{currentDate}}" bind:change="handleDateChange"> |
|
||||||
<view class="date"> |
|
||||||
<view class="content">{{visitDateName||'请选择'}}</view> |
|
||||||
<view class="tril"></view> |
|
||||||
</view> |
|
||||||
</picker> |
|
||||||
<view class="select-title"> |
|
||||||
您复诊后的方案是? |
|
||||||
<text class="sub">(多选)</text> |
|
||||||
</view> |
|
||||||
<view class="list"> |
|
||||||
<view bind:tap="handleSelect" data-name="hormone" class="item {{hormone===1 && 'active'}}">1.激素</view> |
|
||||||
<view |
|
||||||
bind:tap="handleSelect" |
|
||||||
data-name="traditionalInhibitor" |
|
||||||
class="item {{traditionalInhibitor===1 && 'active'}}" |
|
||||||
> |
|
||||||
2.传统免疫抑制剂(如他克莫司、吗 替麦考酚酯等) |
|
||||||
</view> |
|
||||||
<view bind:tap="handleSelect" data-name="gammaGlobulin" class="item {{gammaGlobulin===1 && 'active'}}"> |
|
||||||
3.静脉输注丙种球蛋白 |
|
||||||
</view> |
|
||||||
<view bind:tap="handleSelect" data-name="plasmaExchange" class="item {{plasmaExchange===1 && 'active'}}"> |
|
||||||
4.血浆置换 |
|
||||||
</view> |
|
||||||
<view bind:tap="handleSelect" data-name="bCellInhibitor" class="item {{bCellInhibitor===1 && 'active'}}"> |
|
||||||
5.B细胞抑制剂(如:利妥昔单抗、泰 它西普、伊奈利珠单抗) |
|
||||||
</view> |
|
||||||
<view bind:tap="handleSelect" data-name="fcRnAntagonists" class="item {{fcRnAntagonists===1 && 'active'}}"> |
|
||||||
6.FcRn拮抗剂(如:艾加莫德) |
|
||||||
</view> |
|
||||||
<view |
|
||||||
bind:tap="handleSelect" |
|
||||||
data-name="c5ComplementInhibitor" |
|
||||||
class="item {{c5ComplementInhibitor===1 && 'active'}}" |
|
||||||
> |
|
||||||
7.C5补体抑制剂(如:依库珠单抗) |
|
||||||
</view> |
|
||||||
<view bind:tap="handleSelect" data-name="chineseMedicine" class="item {{chineseMedicine===1 && 'active'}}"> |
|
||||||
8.中药或中成药 |
|
||||||
</view> |
|
||||||
<view bind:tap="handleSelect" data-name="other" class="item {{other===1 && 'active'}}">9.其他</view> |
|
||||||
</view> |
|
||||||
<view class="footer"> |
|
||||||
<view class="cancel" bind:tap="handleCancel">取消</view> |
|
||||||
<view class="submit" bind:tap="submit">确定</view> |
|
||||||
</view> |
|
||||||
</view> |
|
||||||
</van-popup> |
|
@ -1,4 +0,0 @@ |
|||||||
{ |
|
||||||
"component": true, |
|
||||||
"usingComponents": {} |
|
||||||
} |
|
@ -1,204 +0,0 @@ |
|||||||
const app = getApp(); |
|
||||||
/** |
|
||||||
* >=min && <=max |
|
||||||
* @param min |
|
||||||
* @param max |
|
||||||
*/ |
|
||||||
function getRandom(min, max) { |
|
||||||
return min + Math.floor(Math.random() * (max - min + 1)); |
|
||||||
} |
|
||||||
Component({ |
|
||||||
options: {}, |
|
||||||
lifetimes: { |
|
||||||
attached() { |
|
||||||
const query = wx.createSelectorQuery().in(this); |
|
||||||
query |
|
||||||
.select("#thumsCanvas") |
|
||||||
.fields({ node: true, size: true }) |
|
||||||
.exec((res) => { |
|
||||||
const canvas = res[0].node; |
|
||||||
const context = canvas.getContext("2d"); |
|
||||||
this.setData({ |
|
||||||
context: context, |
|
||||||
}); |
|
||||||
|
|
||||||
const dpr = wx.getSystemInfoSync().pixelRatio; |
|
||||||
canvas.width = res[0].width * dpr; |
|
||||||
canvas.height = res[0].height * dpr; |
|
||||||
this.data.width = res[0].width * dpr; |
|
||||||
this.data.height = res[0].height * dpr; |
|
||||||
// context.fillStyle = "rgba(255, 255, 255, 0)";
|
|
||||||
const images = [ |
|
||||||
"za-images/star/icon1.png", |
|
||||||
"za-images/star/icon2.png", |
|
||||||
"za-images/star/icon3.png", |
|
||||||
"za-images/star/icon4.png", |
|
||||||
"za-images/star/icon5.png", |
|
||||||
"za-images/star/icon6.png", |
|
||||||
"za-images/star/icon7.png", |
|
||||||
"za-images/star/icon8.png", |
|
||||||
]; |
|
||||||
const promiseAll = [] as Array<Promise<any>>; |
|
||||||
images.forEach((src) => { |
|
||||||
const p = new Promise(function (resolve) { |
|
||||||
const img = canvas.createImage(); |
|
||||||
img.onerror = img.onload = resolve.bind(null, img); |
|
||||||
img.src = app.globalData.imageUrl + src; |
|
||||||
}); |
|
||||||
promiseAll.push(p); |
|
||||||
}); |
|
||||||
Promise.all(promiseAll).then((imgsList) => { |
|
||||||
const imgsLists = imgsList.filter((d) => { |
|
||||||
if (d && d.width > 0) return true; |
|
||||||
return false; |
|
||||||
}); |
|
||||||
this.setData({ |
|
||||||
imgsList: imgsLists, |
|
||||||
}); |
|
||||||
if (this.data.imgsList.length == 0) { |
|
||||||
// logger.error("imgsList load all error");
|
|
||||||
wx.showToast({ |
|
||||||
icon: "none", |
|
||||||
title: "imgsList load all error", |
|
||||||
}); |
|
||||||
return; |
|
||||||
} |
|
||||||
}); |
|
||||||
}); |
|
||||||
}, |
|
||||||
}, |
|
||||||
properties: {}, |
|
||||||
data: { |
|
||||||
imgsList: [] as WechatMiniprogram.ImageData[], |
|
||||||
width: 0, |
|
||||||
height: 0, |
|
||||||
context: null as any, |
|
||||||
scanning: false, |
|
||||||
renderList: [], |
|
||||||
scaleTime: 0.1, // 百分比
|
|
||||||
}, |
|
||||||
methods: { |
|
||||||
handleTap() { |
|
||||||
this.start(); |
|
||||||
}, |
|
||||||
createRender() { |
|
||||||
if (this.data.imgsList.length == 0) return null; |
|
||||||
const basicScale = [0.6, 0.9, 1.2][getRandom(0, 2)]; |
|
||||||
|
|
||||||
const getScale = (diffTime) => { |
|
||||||
if (diffTime < this.data.scaleTime) { |
|
||||||
return +(diffTime / this.data.scaleTime).toFixed(2) * basicScale; |
|
||||||
} else { |
|
||||||
return basicScale; |
|
||||||
} |
|
||||||
}; |
|
||||||
const context = this.data.context; |
|
||||||
// 随机读取一个图片来渲染
|
|
||||||
const image: any = this.data.imgsList[getRandom(0, this.data.imgsList.length - 1)]; |
|
||||||
const offset = 20; |
|
||||||
const basicX = this.data.width / 2 + getRandom(-offset, offset); |
|
||||||
const angle = getRandom(2, 10); |
|
||||||
let ratio = getRandom(10, 30) * (getRandom(0, 1) ? 1 : -1); |
|
||||||
const getTranslateX = (diffTime) => { |
|
||||||
if (diffTime < this.data.scaleTime) { |
|
||||||
// 放大期间,不进行摇摆位移
|
|
||||||
return basicX; |
|
||||||
} else { |
|
||||||
return basicX + ratio * Math.sin(angle * (diffTime - this.data.scaleTime)); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
const getTranslateY = (diffTime) => { |
|
||||||
return image.height / 2 + (this.data.height - image.height / 2) * (1 - diffTime); |
|
||||||
}; |
|
||||||
|
|
||||||
const fadeOutStage = getRandom(14, 18) / 100; |
|
||||||
const getAlpha = (diffTime) => { |
|
||||||
let left = 1 - +diffTime; |
|
||||||
if (left > fadeOutStage) { |
|
||||||
return 1; |
|
||||||
} else { |
|
||||||
return 1 - +((fadeOutStage - left) / fadeOutStage).toFixed(2); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
return (diffTime) => { |
|
||||||
// 差值满了,即结束了 0 ---》 1
|
|
||||||
if (diffTime >= 1) return true; |
|
||||||
context.save(); |
|
||||||
const scale = getScale(diffTime); |
|
||||||
// const rotate = getRotate();
|
|
||||||
const translateX = getTranslateX(diffTime); |
|
||||||
const translateY = getTranslateY(diffTime); |
|
||||||
context.translate(translateX, translateY); |
|
||||||
context.scale(scale, scale); |
|
||||||
// context.rotate(rotate * Math.PI / 180);
|
|
||||||
context.globalAlpha = getAlpha(diffTime); |
|
||||||
context.drawImage(image, -image.width / 2, -image.height / 2, image.width, image.height); |
|
||||||
context.restore(); |
|
||||||
}; |
|
||||||
}, |
|
||||||
scan() { |
|
||||||
this.data.context.clearRect(0, 0, this.data.width, this.data.height); |
|
||||||
this.data.context.fillStyle = "rgba(255, 255, 255, 0)"; |
|
||||||
this.data.context.fillRect(0, 0, 200, 400); |
|
||||||
let index = 0; |
|
||||||
let length = this.data.renderList.length; |
|
||||||
if (length > 0) { |
|
||||||
this.requestFrame(this.scan.bind(this)); |
|
||||||
this.setData({ |
|
||||||
scanning: true, |
|
||||||
}); |
|
||||||
} else { |
|
||||||
this.setData({ |
|
||||||
scanning: false, |
|
||||||
}); |
|
||||||
} |
|
||||||
while (index < length) { |
|
||||||
const child = this.data.renderList[index]; |
|
||||||
if (!child || !child.render || child.render.call(null, (Date.now() - child.timestamp) / child.duration)) { |
|
||||||
// 结束了,删除该动画
|
|
||||||
this.setData({ |
|
||||||
renderList: [...this.data.renderList].filter((_item, fIndex) => fIndex != index), |
|
||||||
}); |
|
||||||
length--; |
|
||||||
} else { |
|
||||||
// continue
|
|
||||||
index++; |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
start() { |
|
||||||
const render = this.createRender(); |
|
||||||
const duration = getRandom(1500, 3000); |
|
||||||
this.setData({ |
|
||||||
renderList: [ |
|
||||||
...this.data.renderList, |
|
||||||
{ |
|
||||||
render, |
|
||||||
duration, |
|
||||||
timestamp: Date.now(), |
|
||||||
}, |
|
||||||
], |
|
||||||
}); |
|
||||||
|
|
||||||
if (!this.data.scanning) { |
|
||||||
this.setData({ |
|
||||||
scanning: true, |
|
||||||
}); |
|
||||||
|
|
||||||
this.requestFrame(this.scan.bind(this)); |
|
||||||
// this.scan.bind(this)();
|
|
||||||
} |
|
||||||
return this; |
|
||||||
}, |
|
||||||
requestFrame(cb) { |
|
||||||
return ( |
|
||||||
this.data.context.requestAnimationFrame || |
|
||||||
(function (callback) { |
|
||||||
setTimeout(callback, 1000 / 60); |
|
||||||
})(cb) |
|
||||||
); |
|
||||||
}, |
|
||||||
}, |
|
||||||
}); |
|
@ -1 +0,0 @@ |
|||||||
<canvas id="thumsCanvas" type="2d" width="200" height="400" style="width: 100px; height: 200px"></canvas> |
|
@ -1,4 +0,0 @@ |
|||||||
{ |
|
||||||
"component": true, |
|
||||||
"usingComponents": {} |
|
||||||
} |
|
@ -1,62 +0,0 @@ |
|||||||
.text-expansion { |
|
||||||
display: flex; |
|
||||||
&__text { |
|
||||||
position: relative; |
|
||||||
width: 100%; |
|
||||||
font-size: 28rpx; |
|
||||||
color: var(--color); |
|
||||||
overflow: hidden; |
|
||||||
line-height: 1.5; |
|
||||||
max-height: 9em; |
|
||||||
text-align: justify; |
|
||||||
&::before { |
|
||||||
content: ""; |
|
||||||
float: right; |
|
||||||
height: 100%; |
|
||||||
margin-bottom: -40rpx; |
|
||||||
} |
|
||||||
&::after { |
|
||||||
content: ""; |
|
||||||
width: 100vw; |
|
||||||
height: 100vh; |
|
||||||
position: absolute; |
|
||||||
box-shadow: inset calc(120rpx - 100vw) calc(1.45em - 100vh) 0 0 #fff; |
|
||||||
margin-left: -120rpx; |
|
||||||
} |
|
||||||
} |
|
||||||
&__button { |
|
||||||
position: relative; |
|
||||||
font-size: 24rpx; |
|
||||||
font-weight: bold; |
|
||||||
float: right; |
|
||||||
clear: both; |
|
||||||
line-height: 42rpx; |
|
||||||
&::before { |
|
||||||
content: "..."; |
|
||||||
margin-right: 8rpx; |
|
||||||
} |
|
||||||
&::after { |
|
||||||
content: ""; |
|
||||||
display: inline-block; |
|
||||||
margin-bottom: 2rpx; |
|
||||||
margin-left: 4rpx; |
|
||||||
transition: transform 0.3s; |
|
||||||
border-top: 10rpx solid var(--color); |
|
||||||
border-left: 8rpx solid transparent; |
|
||||||
border-right: 8rpx solid transparent; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.text-expansion__text--expand { |
|
||||||
max-height: none; |
|
||||||
&::after { |
|
||||||
visibility: hidden; |
|
||||||
} |
|
||||||
.text-expansion__button::before { |
|
||||||
visibility: hidden; |
|
||||||
} |
|
||||||
.text-expansion__button::after { |
|
||||||
transform: rotate(180deg); |
|
||||||
} |
|
||||||
} |
|
@ -1,34 +0,0 @@ |
|||||||
Component({ |
|
||||||
properties: { |
|
||||||
text: { |
|
||||||
type: String, |
|
||||||
value: '', |
|
||||||
}, |
|
||||||
expandText: { |
|
||||||
type: String, |
|
||||||
value: '展开', |
|
||||||
}, |
|
||||||
collapseText: { |
|
||||||
type: String, |
|
||||||
value: '收起', |
|
||||||
}, |
|
||||||
color: { |
|
||||||
type: String, |
|
||||||
value: '#000', |
|
||||||
}, |
|
||||||
expendColor: { |
|
||||||
type: String, |
|
||||||
value: '#e04775', |
|
||||||
}, |
|
||||||
}, |
|
||||||
data: { |
|
||||||
isExpand: false, |
|
||||||
}, |
|
||||||
methods: { |
|
||||||
onClick() { |
|
||||||
this.setData({ |
|
||||||
isExpand: !this.data.isExpand, |
|
||||||
}) |
|
||||||
}, |
|
||||||
}, |
|
||||||
}) |
|
@ -1,6 +0,0 @@ |
|||||||
<view class="text-expansion" wx:if="{{text.length}}"> |
|
||||||
<view class="text-expansion__text {{ isExpand ? 'text-expansion__text--expand' : '' }}" style="--color:{{expendColor}}"> |
|
||||||
<text bindtap="onClick" class="text-expansion__button">{{ isExpand ? collapseText : expandText }}</text> |
|
||||||
<text style="color:{{color}}">{{ text }}</text> |
|
||||||
</view> |
|
||||||
</view> |
|
@ -1,4 +0,0 @@ |
|||||||
{ |
|
||||||
"component": true, |
|
||||||
"usingComponents": {} |
|
||||||
} |
|
@ -1,154 +0,0 @@ |
|||||||
.movearea { |
|
||||||
position: fixed; |
|
||||||
right: 0; |
|
||||||
top: 100rpx; |
|
||||||
height: calc(100vh - 200rpx); |
|
||||||
width: 0; |
|
||||||
.moveview { |
|
||||||
position: relative; |
|
||||||
width: 0; |
|
||||||
height: 0; |
|
||||||
.move-container { |
|
||||||
perspective: 1000px; |
|
||||||
position: absolute; |
|
||||||
left: -20rpx; |
|
||||||
top: 50%; |
|
||||||
width: 112rpx; |
|
||||||
height: 112rpx; |
|
||||||
transform: translate(-100%, -50%); |
|
||||||
.aside-out { |
|
||||||
width: 100%; |
|
||||||
height: 100%; |
|
||||||
position: relative; |
|
||||||
transition: 1.5s; |
|
||||||
transition-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1); |
|
||||||
transform-style: preserve-3d; |
|
||||||
transform-origin: center; |
|
||||||
.front { |
|
||||||
position: absolute; |
|
||||||
top: 0; |
|
||||||
left: 0; |
|
||||||
width: 100%; |
|
||||||
height: 100%; |
|
||||||
.progress { |
|
||||||
width: inherit; |
|
||||||
height: inherit; |
|
||||||
background: conic-gradient(#e04775 var(--progress), #fff 0%); |
|
||||||
border-radius: 50%; |
|
||||||
position: relative; |
|
||||||
box-sizing: border-box; |
|
||||||
box-shadow: |
|
||||||
0rpx 8rpx 18rpx 0rpx rgba(0, 0, 0, 0.12), |
|
||||||
-6rpx 0rpx 18rpx 0rpx rgba(0, 0, 0, 0.09); |
|
||||||
.progress-wrpa { |
|
||||||
position: absolute; |
|
||||||
left: 50%; |
|
||||||
top: 50%; |
|
||||||
transform: translate(-50%, -50%); |
|
||||||
width: 92rpx; |
|
||||||
height: 92rpx; |
|
||||||
background-color: #fff; |
|
||||||
border-radius: 50%; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
justify-content: center; |
|
||||||
align-items: center; |
|
||||||
.icon { |
|
||||||
width: 56rpx; |
|
||||||
height: 56rpx; |
|
||||||
} |
|
||||||
.content { |
|
||||||
margin-top: -12rpx; |
|
||||||
width: 68rpx; |
|
||||||
height: 26rpx; |
|
||||||
text-align: center; |
|
||||||
line-height: 26rpx; |
|
||||||
font-size: 20rpx; |
|
||||||
color: #eaeded; |
|
||||||
background: linear-gradient(180deg, #fddd39 0%, #f5ad1d 100%); |
|
||||||
border-radius: 16rpx; |
|
||||||
text-shadow: 0px 0px 6px #ba7000; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
.back { |
|
||||||
position: absolute; |
|
||||||
width: 100%; |
|
||||||
height: 100%; |
|
||||||
background-color: darkseagreen; |
|
||||||
transform: rotateY(180deg); |
|
||||||
backface-visibility: hidden; |
|
||||||
box-sizing: border-box; |
|
||||||
display: flex; |
|
||||||
flex-direction: column; |
|
||||||
justify-content: center; |
|
||||||
align-items: center; |
|
||||||
background-color: #fff; |
|
||||||
border-radius: 50%; |
|
||||||
// border: 7rpx solid #e04775; |
|
||||||
.icon { |
|
||||||
width: 56rpx; |
|
||||||
height: 56rpx; |
|
||||||
} |
|
||||||
.sub-icon { |
|
||||||
position: absolute; |
|
||||||
top: 40rpx; |
|
||||||
right: 16rpx; |
|
||||||
width: 20rpx; |
|
||||||
height: 20rpx; |
|
||||||
} |
|
||||||
.content { |
|
||||||
margin-top: -12rpx; |
|
||||||
width: 80rpx; |
|
||||||
height: 26rpx; |
|
||||||
text-align: center; |
|
||||||
line-height: 26rpx; |
|
||||||
font-size: 16rpx; |
|
||||||
color: #eaeded; |
|
||||||
background: linear-gradient(180deg, #fddd39 0%, #f5ad1d 100%); |
|
||||||
border-radius: 16rpx; |
|
||||||
text-shadow: 0px 0px 6px #ba7000; |
|
||||||
} |
|
||||||
} |
|
||||||
&.perspective { |
|
||||||
transform: rotateY(180deg); |
|
||||||
.front { |
|
||||||
.progress { |
|
||||||
background: conic-gradient(#fff var(--progress), #fff 0%); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.toast { |
|
||||||
padding: 50rpx; |
|
||||||
position: fixed; |
|
||||||
left: 50%; |
|
||||||
top: 50%; |
|
||||||
transform: translate(-50%, -50%); |
|
||||||
background-color: rgba(0, 0, 0, 0.74); |
|
||||||
border-radius: 32rpx; |
|
||||||
max-width: 80vw; |
|
||||||
.icon { |
|
||||||
display: block; |
|
||||||
margin: 0 auto; |
|
||||||
width: 80rpx; |
|
||||||
height: 80rpx; |
|
||||||
} |
|
||||||
.content { |
|
||||||
margin-top: 24rpx; |
|
||||||
text-align: center; |
|
||||||
font-size: 32rpx; |
|
||||||
color: #ffffff; |
|
||||||
.p { |
|
||||||
white-space: nowrap; |
|
||||||
} |
|
||||||
.num { |
|
||||||
color: #f5ad1d; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue