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); } }