fineui是帆软报表和BI产品线所使用的前端框架。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

301 lines
8.3 KiB

import { Label, ButtonGroup } from "@/base";
import {
CenterLayout,
shortcut,
Widget,
getDate,
each,
range,
extend,
isLeapYear,
Date,
StartOfWeek,
checkDateVoid,
map,
createWidget,
createItems,
LogicFactory,
Controller,
getShortDayName,
getOffsetDate,
isNotEmptyString,
parseInt,
SIZE_CONSANTS
} from "@/core";
import { CalendarDateItem } from "./calendar.date.item";
/**
* Created by GUY on 2015/8/28.
* @class Calendar
* @extends Widget
*/
@shortcut()
export class Calendar extends Widget {
static xtype = "bi.calendar";
static getPageByDateJSON(json) {
const year = getDate().getFullYear();
const month = getDate().getMonth();
let page = (json.year - year) * 12;
page += json.month - 1 - month;
return page;
}
static getDateJSONByPage(v) {
const months = getDate().getMonth();
let page = v;
// 对当前page做偏移,使到当前年初
page = page + months;
let year = parseInt(page / 12);
if (page < 0 && page % 12 !== 0) {
year--;
}
const month = page >= 0 ? page % 12 : (12 + (page % 12)) % 12;
return {
year: getDate().getFullYear() + year,
month: month + 1,
};
}
_defaultConfig() {
const conf = super._defaultConfig(...arguments);
return extend(conf, {
baseCls: "bi-calendar",
logic: {
dynamic: false,
},
min: "1900-01-01", // 最小日期
max: "2099-12-31", // 最大日期
year: 2015,
month: 8,
day: 25,
});
}
_dateCreator(Y, M, D) {
const { min, max } = this.options,
log = {},
De = getDate();
const mins = min.match(/\d+/g);
const maxs = max.match(/\d+/g);
De.setFullYear(Y, M, D);
log.ymd = [De.getFullYear(), De.getMonth(), De.getDate()];
const MD = Date._MD.slice(0);
MD[1] = isLeapYear(log.ymd[0]) ? 29 : 28;
// 日期所在月第一天
De.setFullYear(log.ymd[0], log.ymd[1], 1);
// 是周几
log.FDay = De.getDay();
// 当前BI.StartOfWeek与周日对齐后的FDay是周几
const offSetFDay = (7 - StartOfWeek + log.FDay) % 7;
// 当前月页第一天是几号
log.PDay = MD[M === 0 ? 11 : M - 1] - offSetFDay + 1;
log.NDay = 1;
const items = [];
each(range(42), i => {
const td = {};
let YY = log.ymd[0],
MM = log.ymd[1] + 1,
DD;
// 上个月的日期
if (i < offSetFDay) {
td.lastMonth = true;
DD = i + log.PDay;
// 上一年
MM === 1 && (YY -= 1);
MM = MM === 1 ? 12 : MM - 1;
} else if (i >= offSetFDay && i < offSetFDay + MD[log.ymd[1]]) {
DD = i - offSetFDay + 1;
if (i - offSetFDay + 1 === log.ymd[2]) {
td.currentDay = true;
}
} else {
td.nextMonth = true;
DD = log.NDay++;
MM === 12 && (YY += 1);
MM = MM === 12 ? 1 : MM + 1;
}
if (checkDateVoid(YY, MM, DD, mins, maxs)[0]) {
td.disabled = true;
}
td.text = DD;
items.push(td);
});
return items;
}
_init() {
super._init(...arguments);
const { year, month, day, logic } = this.options;
const items = map(this._getWeekLabel(), (i, value) => {
return {
type: Label.xtype,
height: SIZE_CONSANTS.LIST_ITEM_HEIGHT,
text: value,
};
});
const title = createWidget({
type: ButtonGroup.xtype,
height: 44,
items,
layouts: [
{
type: CenterLayout.xtype,
hgap: 5,
vgap: 10,
}
],
});
this.days = createWidget({
type: ButtonGroup.xtype,
items: createItems(this._getItems(), {}),
value: `${year}-${month}-${day}`,
layouts: [
LogicFactory.createLogic(
"table",
extend({}, logic, {
columns: 7,
rows: 6,
columnSize: [1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7, 1 / 7],
rowSize: SIZE_CONSANTS.LIST_ITEM_HEIGHT + 8,
})
)
],
});
this.days.on(Controller.EVENT_CHANGE, (...args) => {
this.fireEvent(Controller.EVENT_CHANGE, ...args);
});
createWidget(
extend(
{
element: this,
},
LogicFactory.createLogic(
"vertical",
extend({}, logic, {
items: LogicFactory.createLogicItemsByDirection("top", title, {
el: this.days,
tgap: -5,
}),
})
)
)
);
}
_getWeekLabel() {
return map(range(0, 7), (idx, v) => getShortDayName((v + StartOfWeek) % 7));
}
isFrontDate() {
const { year, month, min, max } = this.options;
let Y = year;
const M = month,
De = getDate(),
day = De.getDay();
Y = Y | 0;
De.setFullYear(Y, M, 1);
const newDate = getOffsetDate(De, -1 * (day + 1));
return !!checkDateVoid(newDate.getFullYear(), newDate.getMonth(), newDate.getDate(), min, max)[0];
}
isFinalDate() {
const { year, month, min, max } = this.options;
let Y = year;
const M = month,
De = getDate(),
day = De.getDay();
Y = Y | 0;
De.setFullYear(Y, M, 1);
const newDate = getOffsetDate(De, 42 - day);
return !!checkDateVoid(newDate.getFullYear(), newDate.getMonth(), newDate.getDate(), min, max)[0];
}
_getItems() {
const o = this.options;
const days = this._dateCreator(o.year, o.month - 1, o.day);
const items = [];
items.push(days.slice(0, 7));
items.push(days.slice(7, 14));
items.push(days.slice(14, 21));
items.push(days.slice(21, 28));
items.push(days.slice(28, 35));
items.push(days.slice(35, 42));
return map(items, (i, item) =>
map(item, (j, td) => {
let month = td.lastMonth ? o.month - 1 : td.nextMonth ? o.month + 1 : o.month;
let year = o.year;
if (month > 12) {
month = 1;
year++;
} else if (month < 1) {
month = 12;
year--;
}
return extend(td, {
type: CalendarDateItem.xtype,
once: false,
forceSelected: true,
value: `${year}-${month}-${td.text}`,
disabled: td.disabled,
cls: td.lastMonth || td.nextMonth ? "bi-tips" : "",
lgap: 2,
rgap: 2,
tgap: 4,
bgap: 4,
// selected: td.currentDay
});
})
);
}
_populate() {
this.days.populate(this._getItems());
}
setMinDate(minDate) {
const o = this.options;
if (isNotEmptyString(o.min)) {
o.min = minDate;
this._populate();
}
}
setMaxDate(maxDate) {
const o = this.options;
if (isNotEmptyString(o.max)) {
o.max = maxDate;
this._populate();
}
}
setValue(ob) {
this.days.setValue([`${ob.year}-${ob.month}-${ob.day}`]);
}
getValue() {
const date = this.days.getValue()[0].match(/\d+/g);
return {
year: date[0] | 0,
month: date[1] | 0,
day: date[2] | 0,
};
}
}