|
|
|
import { shortcut, i18nText, createWidget, isKey, checkDateLegal, parseDateTime, bind, isNotNull, isNotEmptyString, isEqual, isEmptyObject, isEmptyString, isNull, getDate, each, isNumeric, checkDateVoid, parseInt, size, print } from "@/core";
|
|
|
|
import { Trigger } from "@/base";
|
|
|
|
import { SignEditor } from "@/case";
|
|
|
|
import { DynamicDateCombo, DynamicDateCard, DynamicDateHelper } from "../dynamicdate";
|
|
|
|
|
|
|
|
@shortcut()
|
|
|
|
export class DynamicDateTimeTrigger extends Trigger {
|
|
|
|
static xtype = "bi.dynamic_date_time_trigger"
|
|
|
|
|
|
|
|
_const = {
|
|
|
|
hgap: 4,
|
|
|
|
vgap: 2,
|
|
|
|
yearLength: 4,
|
|
|
|
yearMonthLength: 6,
|
|
|
|
yearFullMonthLength: 7,
|
|
|
|
compareFormat: "%Y-%X-%d %H:%M:%S",
|
|
|
|
iconWidth: 24,
|
|
|
|
};
|
|
|
|
|
|
|
|
static EVENT_BLUR = "EVENT_BLUR"
|
|
|
|
static EVENT_FOCUS = "EVENT_FOCUS"
|
|
|
|
static EVENT_START = "EVENT_START"
|
|
|
|
static EVENT_STOP = "EVENT_STOP"
|
|
|
|
static EVENT_CONFIRM = "EVENT_CONFIRM"
|
|
|
|
static EVENT_CHANGE = "EVENT_CHANGE"
|
|
|
|
static EVENT_VALID = "EVENT_VALID"
|
|
|
|
static EVENT_ERROR = "EVENT_ERROR"
|
|
|
|
static EVENT_TRIGGER_CLICK = "EVENT_TRIGGER_CLICK"
|
|
|
|
static EVENT_KEY_DOWN = "EVENT_KEY_DOWN"
|
|
|
|
|
|
|
|
props() {
|
|
|
|
return {
|
|
|
|
extraCls: "bi-date-time-trigger",
|
|
|
|
min: "1900-01-01", // 最小日期
|
|
|
|
max: "2099-12-31", // 最大日期
|
|
|
|
height: 24,
|
|
|
|
iconWidth: 24,
|
|
|
|
format: "", // 显示的日期格式化方式
|
|
|
|
allowEdit: true, // 是否允许编辑
|
|
|
|
watermark: i18nText("BI-Basic_Unrestricted"),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
_init() {
|
|
|
|
super._init(...arguments);
|
|
|
|
const o = this.options,
|
|
|
|
c = this._const;
|
|
|
|
this.storeTriggerValue = "";
|
|
|
|
this.editor = createWidget({
|
|
|
|
type: "bi.sign_editor",
|
|
|
|
simple: o.simple,
|
|
|
|
height: o.height,
|
|
|
|
validationChecker: v => {
|
|
|
|
const formatStr = this._getStandardDateStr(v);
|
|
|
|
const date = formatStr.match(/\d+/g);
|
|
|
|
!isKey(o.format) && this._autoAppend(v, date);
|
|
|
|
|
|
|
|
return this._dateCheck(formatStr) && checkDateLegal(formatStr) && this._checkVoid({
|
|
|
|
year: date[0] | 0,
|
|
|
|
month: date[1] | 0,
|
|
|
|
day: date[2] | 0,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
quitChecker () {
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
hgap: c.hgap,
|
|
|
|
vgap: c.vgap,
|
|
|
|
allowBlank: true,
|
|
|
|
watermark: o.watermark,
|
|
|
|
errorText: v => {
|
|
|
|
let str = "";
|
|
|
|
if (!isKey(o.format)) {
|
|
|
|
if (!this._dateCheck(v)) {
|
|
|
|
str = this.editor.isEditing() ? i18nText("BI-Date_Trigger_Error_Text") : i18nText("BI-Year_Trigger_Invalid_Text");
|
|
|
|
} else {
|
|
|
|
const start = parseDateTime(o.min, "%Y-%X-%d");
|
|
|
|
const end = parseDateTime(o.max, "%Y-%X-%d");
|
|
|
|
str = i18nText("BI-Basic_Date_Range_Error",
|
|
|
|
start.getFullYear(),
|
|
|
|
start.getMonth() + 1,
|
|
|
|
start.getDate(),
|
|
|
|
end.getFullYear(),
|
|
|
|
end.getMonth() + 1,
|
|
|
|
end.getDate()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
|
|
|
},
|
|
|
|
title: bind(this._getTitle, this),
|
|
|
|
});
|
|
|
|
this.editor.on(SignEditor.EVENT_KEY_DOWN, (...args) => {
|
|
|
|
this.fireEvent(DynamicDateTimeTrigger.EVENT_KEY_DOWN, ...args);
|
|
|
|
});
|
|
|
|
this.editor.on(SignEditor.EVENT_FOCUS, () => {
|
|
|
|
this.storeTriggerValue = this.getKey();
|
|
|
|
this.fireEvent(DynamicDateTimeTrigger.EVENT_FOCUS);
|
|
|
|
});
|
|
|
|
this.editor.on(SignEditor.EVENT_BLUR, () => {
|
|
|
|
this.fireEvent(DynamicDateTimeTrigger.EVENT_BLUR);
|
|
|
|
});
|
|
|
|
this.editor.on(SignEditor.EVENT_STOP, () => {
|
|
|
|
this.fireEvent(DynamicDateTimeTrigger.EVENT_STOP);
|
|
|
|
});
|
|
|
|
this.editor.on(SignEditor.EVENT_VALID, () => {
|
|
|
|
this.fireEvent(DynamicDateTimeTrigger.EVENT_VALID);
|
|
|
|
});
|
|
|
|
this.editor.on(SignEditor.EVENT_ERROR, () => {
|
|
|
|
this.fireEvent(DynamicDateTimeTrigger.EVENT_ERROR);
|
|
|
|
});
|
|
|
|
this.editor.on(SignEditor.EVENT_CONFIRM, () => {
|
|
|
|
const value = this.editor.getValue();
|
|
|
|
if (isNotNull(value)) {
|
|
|
|
this.editor.setState(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isNotEmptyString(value) && !isEqual(this.storeTriggerValue, this.getKey())) {
|
|
|
|
const formatStr = this._getStandardDateStr(value);
|
|
|
|
const date = formatStr.match(/\d+/g);
|
|
|
|
this.storeValue = {
|
|
|
|
type: DynamicDateCombo.Static,
|
|
|
|
value: {
|
|
|
|
year: date[0] | 0,
|
|
|
|
month: date[1] | 0,
|
|
|
|
day: date[2] | 0,
|
|
|
|
hour: date[3] | 0,
|
|
|
|
minute: date[4] | 0,
|
|
|
|
second: date[5] | 0,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
this.fireEvent(DynamicDateTimeTrigger.EVENT_CONFIRM);
|
|
|
|
});
|
|
|
|
this.editor.on(SignEditor.EVENT_START, () => {
|
|
|
|
this.fireEvent(DynamicDateTimeTrigger.EVENT_START);
|
|
|
|
});
|
|
|
|
this.editor.on(SignEditor.EVENT_CHANGE, () => {
|
|
|
|
this.fireEvent(DynamicDateTimeTrigger.EVENT_CHANGE);
|
|
|
|
});
|
|
|
|
createWidget({
|
|
|
|
type: "bi.htape",
|
|
|
|
element: this,
|
|
|
|
columnSize: ["", this._const.iconWidth],
|
|
|
|
items: [{
|
|
|
|
el: this.editor,
|
|
|
|
}, {
|
|
|
|
el: {
|
|
|
|
type: "bi.icon_button",
|
|
|
|
cls: "bi-trigger-icon-button date-font",
|
|
|
|
},
|
|
|
|
width: o.iconWidth,
|
|
|
|
}],
|
|
|
|
});
|
|
|
|
|
|
|
|
!o.allowEdit && createWidget({
|
|
|
|
type: "bi.absolute",
|
|
|
|
element: this,
|
|
|
|
items: [{
|
|
|
|
el: {
|
|
|
|
type: "bi.text",
|
|
|
|
title: bind(this._getTitle, this),
|
|
|
|
},
|
|
|
|
left: 0,
|
|
|
|
right: o.iconWidth,
|
|
|
|
top: 0,
|
|
|
|
bottom: 0,
|
|
|
|
}],
|
|
|
|
});
|
|
|
|
this.setValue(o.value);
|
|
|
|
}
|
|
|
|
|
|
|
|
_getTitle() {
|
|
|
|
const o = this.options;
|
|
|
|
const storeValue = this.storeValue || {};
|
|
|
|
if (isEmptyObject(storeValue)) {
|
|
|
|
return o.watermark;
|
|
|
|
}
|
|
|
|
const type = storeValue.type || DynamicDateCombo.Static;
|
|
|
|
const value = storeValue.value;
|
|
|
|
const text = this._getText(value);
|
|
|
|
const date = DynamicDateHelper.getCalculation(value);
|
|
|
|
const dateStr = print(date, this._getFormatString());
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case DynamicDateCombo.Dynamic:
|
|
|
|
return isEmptyString(text) ? dateStr : (`${text}:${dateStr}`);
|
|
|
|
case DynamicDateCombo.Static:
|
|
|
|
default:
|
|
|
|
if (isNull(value) || isNull(value.day)) {
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
return print(getDate(value.year, (value.month - 1), value.day, value.hour || 0, value.minute || 0,
|
|
|
|
value.second || 0), this._getFormatString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_getStandardDateStr(v) {
|
|
|
|
const c = this._const;
|
|
|
|
let result = [];
|
|
|
|
let hasSecond = false;
|
|
|
|
const formatArray = this._getFormatString().match(/%./g);
|
|
|
|
each(formatArray, (idx, v) => {
|
|
|
|
switch (v) {
|
|
|
|
case "%Y":
|
|
|
|
case "%y":
|
|
|
|
result[0] = idx;
|
|
|
|
break;
|
|
|
|
case "%X":
|
|
|
|
case "%x":
|
|
|
|
result[1] = idx;
|
|
|
|
break;
|
|
|
|
case "%d":
|
|
|
|
case "%e":
|
|
|
|
result[2] = idx;
|
|
|
|
break;
|
|
|
|
case "%S":
|
|
|
|
hasSecond = true;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
// 这边不能直接用\d+去切日期, 因为format格式可能是20190607这样的没有分割符的 = =
|
|
|
|
// 先看一下是否是合法的, 如果合法就变成标准格式的走原来的流程, 不合法不关心
|
|
|
|
const date = parseDateTime(v, this._getFormatString());
|
|
|
|
if (print(date, this._getFormatString()) === v) {
|
|
|
|
v = print(date, c.compareFormat);
|
|
|
|
result = [0, 1, 2];
|
|
|
|
}
|
|
|
|
const dateArray = v.match(/\d+/g) || [];
|
|
|
|
const newArray = [];
|
|
|
|
// 处理乱序的年月日
|
|
|
|
each(dateArray.slice(0, 3), idx => {
|
|
|
|
newArray[idx] = dateArray[result[idx]];
|
|
|
|
});
|
|
|
|
// 拼接时分秒和pm
|
|
|
|
const suffixArray = dateArray.slice(3);
|
|
|
|
// 时分秒补0
|
|
|
|
each(suffixArray, (idx, v) => {
|
|
|
|
isNumeric(v) && v.length === 1 && (suffixArray[idx] = `0${v}`);
|
|
|
|
});
|
|
|
|
// hh:mm
|
|
|
|
if (suffixArray.length === 2 && !hasSecond) {
|
|
|
|
suffixArray.push("00");
|
|
|
|
}
|
|
|
|
const suffixString = suffixArray.join(":");
|
|
|
|
let dateString = newArray.slice(0, 3).join("-");
|
|
|
|
if (isNotEmptyString(suffixString)) {
|
|
|
|
dateString += ` ${suffixString}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dateString;
|
|
|
|
}
|
|
|
|
|
|
|
|
_getFormatString() {
|
|
|
|
return this.options.format || this._const.compareFormat;
|
|
|
|
}
|
|
|
|
|
|
|
|
_dateCheck(date) {
|
|
|
|
return print(parseDateTime(date, "%Y-%x-%d %H:%M:%S"), "%Y-%x-%d %H:%M:%S") === date ||
|
|
|
|
print(parseDateTime(date, "%Y-%X-%d %H:%M:%S"), "%Y-%X-%d %H:%M:%S") === date ||
|
|
|
|
print(parseDateTime(date, "%Y-%x-%e %H:%M:%S"), "%Y-%x-%e %H:%M:%S") === date ||
|
|
|
|
print(parseDateTime(date, "%Y-%X-%e %H:%M:%S"), "%Y-%X-%e %H:%M:%S") === date ||
|
|
|
|
|
|
|
|
print(parseDateTime(date, "%Y-%x-%d"), "%Y-%x-%d") === date ||
|
|
|
|
print(parseDateTime(date, "%Y-%X-%d"), "%Y-%X-%d") === date ||
|
|
|
|
print(parseDateTime(date, "%Y-%x-%e"), "%Y-%x-%e") === date ||
|
|
|
|
print(parseDateTime(date, "%Y-%X-%e"), "%Y-%X-%e") === date;
|
|
|
|
}
|
|
|
|
|
|
|
|
_checkVoid(obj) {
|
|
|
|
return !checkDateVoid(obj.year, obj.month, obj.day, this.options.min, this.options.max)[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
_autoAppend(v, dateObj) {
|
|
|
|
if (isNotNull(dateObj) && checkDateLegal(v)) {
|
|
|
|
const splitMonth = v.split("-")[1];
|
|
|
|
switch (v.length) {
|
|
|
|
case this._const.yearLength:
|
|
|
|
if (this._yearCheck(v)) {
|
|
|
|
this.editor.setValue(`${v}-`);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case this._const.yearMonthLength:
|
|
|
|
case this._const.yearFullMonthLength:
|
|
|
|
if ((isNotNull(splitMonth) && splitMonth.length === 2) || this._monthCheck(v)) {
|
|
|
|
this.editor.setValue(`${v}-`);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_yearCheck(v) {
|
|
|
|
const date = print(parseDateTime(v, "%Y-%X-%d"), "%Y-%X-%d");
|
|
|
|
|
|
|
|
return print(parseDateTime(v, "%Y"), "%Y") === v && date >= this.options.min && date <= this.options.max;
|
|
|
|
}
|
|
|
|
|
|
|
|
_monthCheck(v) {
|
|
|
|
const date = parseDateTime(v, "%Y-%X-%d");
|
|
|
|
const dateStr = print(date, "%Y-%X-%d");
|
|
|
|
|
|
|
|
return (date.getMonth() > 0 && (print(parseDateTime(v, "%Y-%X"), "%Y-%X") === v ||
|
|
|
|
print(parseDateTime(v, "%Y-%x"), "%Y-%x") === v)) && dateStr >= this.options.min && dateStr <= this.options.max;
|
|
|
|
}
|
|
|
|
|
|
|
|
_setInnerValue(date) {
|
|
|
|
const dateStr = print(date, this._getFormatString());
|
|
|
|
this.editor.setState(dateStr);
|
|
|
|
this.editor.setValue(dateStr);
|
|
|
|
}
|
|
|
|
|
|
|
|
_getText(obj) {
|
|
|
|
let value = "";
|
|
|
|
let endText = "";
|
|
|
|
if (isNotNull(obj.year)) {
|
|
|
|
if (parseInt(obj.year) !== 0) {
|
|
|
|
value += Math.abs(obj.year) + i18nText("BI-Basic_Year") + (obj.year < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind"));
|
|
|
|
}
|
|
|
|
endText = getPositionText(i18nText("BI-Basic_Year"), obj.position);
|
|
|
|
}
|
|
|
|
if (isNotNull(obj.quarter)) {
|
|
|
|
if (parseInt(obj.quarter) !== 0) {
|
|
|
|
value += Math.abs(obj.quarter) + i18nText("BI-Basic_Single_Quarter") + (obj.quarter < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind"));
|
|
|
|
}
|
|
|
|
endText = getPositionText(i18nText("BI-Basic_Single_Quarter"), obj.position);
|
|
|
|
}
|
|
|
|
if (isNotNull(obj.month)) {
|
|
|
|
if (parseInt(obj.month) !== 0) {
|
|
|
|
value += Math.abs(obj.month) + i18nText("BI-Basic_Month") + (obj.month < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind"));
|
|
|
|
}
|
|
|
|
endText = getPositionText(i18nText("BI-Basic_Month"), obj.position);
|
|
|
|
}
|
|
|
|
if (isNotNull(obj.week)) {
|
|
|
|
if (parseInt(obj.week) !== 0) {
|
|
|
|
value += Math.abs(obj.week) + i18nText("BI-Basic_Week") + (obj.week < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind"));
|
|
|
|
}
|
|
|
|
endText = getPositionText(i18nText("BI-Basic_Week"), obj.position);
|
|
|
|
}
|
|
|
|
if (isNotNull(obj.day)) {
|
|
|
|
if (parseInt(obj.day) !== 0) {
|
|
|
|
value += Math.abs(obj.day) + i18nText("BI-Basic_Day") + (obj.day < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind"));
|
|
|
|
}
|
|
|
|
endText = size(obj) === 1 ? getPositionText(i18nText("BI-Basic_Month"), obj.position) : "";
|
|
|
|
}
|
|
|
|
if (isNotNull(obj.workDay) && parseInt(obj.workDay) !== 0) {
|
|
|
|
value += Math.abs(obj.workDay) + i18nText("BI-Basic_Work_Day") + (obj.workDay < 0 ? i18nText("BI-Basic_Front") : i18nText("BI-Basic_Behind"));
|
|
|
|
}
|
|
|
|
|
|
|
|
return value + endText;
|
|
|
|
|
|
|
|
function getPositionText(baseText, position) {
|
|
|
|
switch (position) {
|
|
|
|
case DynamicDateCard.OFFSET.BEGIN:
|
|
|
|
return baseText + i18nText("BI-Basic_Begin_Start");
|
|
|
|
case DynamicDateCard.OFFSET.END:
|
|
|
|
return baseText + i18nText("BI-Basic_End_Stop");
|
|
|
|
case DynamicDateCard.OFFSET.CURRENT:
|
|
|
|
default:
|
|
|
|
return i18nText("BI-Basic_Current_Day");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setMinDate(minDate) {
|
|
|
|
if (isNotEmptyString(this.options.min)) {
|
|
|
|
this.options.min = minDate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setMaxDate(maxDate) {
|
|
|
|
if (isNotEmptyString(this.options.max)) {
|
|
|
|
this.options.max = maxDate;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
setValue(v) {
|
|
|
|
let type, value;
|
|
|
|
let date = getDate();
|
|
|
|
this.storeValue = v;
|
|
|
|
if (isNotNull(v)) {
|
|
|
|
type = v.type || DynamicDateCombo.Static;
|
|
|
|
value = v.value || v;
|
|
|
|
}
|
|
|
|
const text = this._getText(value);
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
case DynamicDateCombo.Dynamic:
|
|
|
|
date = DynamicDateHelper.getCalculation(value);
|
|
|
|
this._setInnerValue(date, text);
|
|
|
|
break;
|
|
|
|
case DynamicDateCombo.Static:
|
|
|
|
default:
|
|
|
|
if (isNull(value) || isNull(value.day)) {
|
|
|
|
this.editor.setState("");
|
|
|
|
this.editor.setValue("");
|
|
|
|
} else {
|
|
|
|
const dateStr = print(getDate(value.year, (value.month - 1), value.day, value.hour || 0, value.minute || 0,
|
|
|
|
value.second || 0), this._getFormatString());
|
|
|
|
this.editor.setState(dateStr);
|
|
|
|
this.editor.setValue(dateStr);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
getKey() {
|
|
|
|
return this.editor.getValue();
|
|
|
|
}
|
|
|
|
|
|
|
|
getValue() {
|
|
|
|
return this.storeValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
isValid() {
|
|
|
|
return this.editor.isValid();
|
|
|
|
}
|
|
|
|
|
|
|
|
focus() {
|
|
|
|
this.editor.focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
blur() {
|
|
|
|
this.editor.blur();
|
|
|
|
}
|
|
|
|
|
|
|
|
setWaterMark(v) {
|
|
|
|
this.editor.setWaterMark(v);
|
|
|
|
}
|
|
|
|
}
|