libf 2 lat temu
rodzic
commit
f022d1a7d2
3 zmienionych plików z 410 dodań i 163 usunięć
  1. 12 6
      src/App.vue
  2. 10 37
      src/components/calendar/Calendar.vue
  3. 388 120
      src/components/calendar/CalendarData.js

+ 12 - 6
src/App.vue

@@ -38,6 +38,7 @@
               style="flex: 1 1 auto; margin: 10px"
               :calendars="calendars"
               :events="selectedevents"
+              @changeRange="changeRange"
               @update="updateEvent"
               @delete="deleteEvent"
             ></Calendar>
@@ -64,6 +65,7 @@ import CalList from "./components/calendar/CalList.vue";
 import {
   events,
   calendars,
+  loadCalendarEvents,
   onCalendarEventsLoaded,
   updateEvent,
   deleteEvent,
@@ -110,13 +112,13 @@ export default {
       this.indexcals = events;
       this.indextitles = titles;
       this.calendars = calendars;
-      if (!this.indexcals[this.key]) {
-        this.key = "ALL";
-      }
-      this.selectedevents = this.indexcals[this.key].events;
+      this.menuselect(this.key);
     });
   },
   methods: {
+    changeRange(range) {
+      loadCalendarEvents(range);
+    },
     // 更新一个日历事件
     updateEvent(event) {
       updateEvent(event);
@@ -128,10 +130,14 @@ export default {
     // 从菜单选择一项日历
     menuselect(key) {
       this.key = key;
-      if (!this.indexcals[this.key]) {
+      if (!this.indexcals[this.key] && this.key[0] == "T") {
         this.key = "ALL";
       }
-      this.selectedevents = this.indexcals[this.key].events;
+      if (this.indexcals[this.key] && this.indexcals[this.key].events) {
+        this.selectedevents = this.indexcals[this.key].events;
+      } else {
+        this.selectedevents = [];
+      }
     },
   },
 };

+ 10 - 37
src/components/calendar/Calendar.vue

@@ -54,7 +54,6 @@
         }"
         :grid-selection="true"
         :calendars="calendars"
-        :attendees="attendees"
         :notices="notices"
         :events="events"
         @customFormPopup="onCustomFormPopup"
@@ -79,7 +78,7 @@ import "./tuical/toastui-calendar.css";
 import "tui-date-picker/dist/tui-date-picker.min.css";
 import "tui-time-picker/dist/tui-time-picker.min.css";
 
-import { events, calendars } from "./CalendarData";
+import { newID } from "./CalendarData";
 import { theme } from "./theme";
 import "./calendar.css";
 
@@ -92,17 +91,12 @@ export default {
     EventForm,
   },
   props: {
-    key: "",
     events: {
       type: Array,
     },
     calendars: {
       type: Array,
     },
-    attendees: {
-      type: Array,
-      default: () => ["ids from app"],
-    },
   },
   data() {
     return {
@@ -169,8 +163,8 @@ export default {
     },
   },
   watch: {
-    attendees(value) {
-      this.calendarInstance.setAttendees(value);
+    events(v) {
+      this.closePopup(v);
     },
     selectedView(newView) {
       this.calendarInstance.changeView(newView);
@@ -178,29 +172,6 @@ export default {
     },
   },
   mounted() {
-    // m3.callFS("/matrix/calendar/load.js")
-    //   .then((res) => {
-    //     //console.log(res)
-    //     if (
-    //       res.status == "ok" &&
-    //       res.message &&
-    //       res.message.data &&
-    //       res.message.data.length > 0
-    //     ) {
-    //       var cals = [];
-    //       for (var i in calendars) {
-    //         cals.push(calendars[i]);
-    //       }
-    //       for (var i in res.message.calendars) {
-    //         cals.push(res.message.calendars[i]);
-    //       }
-    //       this.calendarInstance.setCalendars(cals);
-    //       // this.events = events;
-    //     }
-    //   })
-    //   .catch((err) => {
-    //     console.error(err);
-    //   });
     this.setDateRangeText();
   },
   methods: {
@@ -238,6 +209,9 @@ export default {
       const cls = "toastui-calendar-more-title-date";
       return `<span class="${cls}">${month}月${date}日</span><span>【${ld.IMonthCn}${ld.IDayCn}】${ld.ncWeek}</span>`;
     },
+    closePopup() {
+      this.$refs["eventform"].$el.style.display = "none";
+    },
     onCustomFormPopup(eventData) {
       eventData.CustomEventForm = true;
 
@@ -257,7 +231,7 @@ export default {
       }
       const eventcopy = {
         calendarId: event.calendarId || "work",
-        id: event.id || String(Math.random()),
+        id: event.id || newID(),
         title: event.title,
         isAllday: event.isAllday,
         start: event.start,
@@ -268,7 +242,6 @@ export default {
         state: event.state,
         isPrivate: event.isPrivate,
         body: event.body,
-        attendees: event.attendees || this.attendees,
       };
 
       this.$refs["eventform"].event = eventcopy;
@@ -356,13 +329,12 @@ export default {
           this.dateRangeText = `${date.getFullYear()}年${
             date.getMonth() + 1
           }月`;
-
-          return;
+          break;
         case "day":
           this.dateRangeText = `${date.getFullYear()}年${
             date.getMonth() + 1
           }月${date.getDate()}日`;
-          return;
+          break;
         default:
           this.dateRangeText = `${startYear}年${
             start.getMonth() + 1
@@ -370,6 +342,7 @@ export default {
             startYear !== endYear ? `${endYear}年` : ""
           }${end.getMonth() + 1}月${end.getDate()}日`;
       }
+      this.$emit("changeRange", {year: date.getFullYear(), month: date.getMonth()+1});
     },
   },
 };

+ 388 - 120
src/components/calendar/CalendarData.js

@@ -4,6 +4,211 @@ import { addDate, addHours, diffDays, subDate, subtractDate } from './utils';
 
 const today = new TZDate();
 
+/*
+drop class /matrix/system/calendar;
+create class if not exists /matrix/system/calendar (
+  name              varchar,
+  title             varchar,
+  desc              varchar,  
+  calid             varchar,
+  catid             varchar,
+  calstart          timestamp,
+  calend            timestamp,
+  repeatcount       int,
+  repeattype        varchar,
+  periodstartmonth  int,
+  periodstartweek   int,
+  periodstartdate   int,
+  periodstarthour   int,
+  periodstartminute int,
+  periodexclude     set<varchar>,
+  keys(name)
+) with autosearch=false, version=true, alias='calendar';
+*/
+
+/*
+// 输入输出参数格式化
+input = INPUT;
+output = {};
+try {
+    input = decodeURIComponent(input);
+} catch (e) { }
+try {
+    input = base64.decode(input);
+} catch (e) { }
+try {
+    input = JSON.parse(input);
+    input = JSON.parse(input); // 解析可能存在的重复编码
+} catch (e) { }
+
+// 主执行阶段
+try {
+    main(input, output);
+} catch (e) {
+    // 错误信息输出处理,抛出 ok 表示正常结束    
+    if (e != "ok") {
+        if (typeof (e) == "object") {
+            output.error = e;
+        } else if (typeof (e) == "string") {
+            output.error = "错误:" + e;
+        } else {
+            output.error = JSON.stringify(e);
+        }
+        log.error(output.error);
+        STATUS = "error";
+    }
+}
+
+function main(input,output) {
+    var mql = "select * from /matrix/system/calendar";
+    if (input.year && input.month) {
+        var nyear = input.year;
+        var nmonth = input.month + 1;
+        if (nmonth > 12) {
+            nmonth -= 12;
+            nyear += 1;
+        }
+        mql += " where calstart < '" + nyear + "-" + nmonth + "-15'";
+        var pyear = input.year;
+        var pmonth = input.month - 1;
+        if (pmonth < 1) {
+            pmonth += 12;
+            pyear -= 1;
+        }
+        mql += " and calend > '" + pyear + "-" + pmonth + "-15'";
+    }
+    var ret = odb.mql(mql);
+    output.data = [];
+    
+    for (var i = 0; i < ret.data.length; i++) {
+        output.data.push({
+            id: ret.data[i].name,
+            title: ret.data[i].title,
+            body: ret.data[i].desc,
+            start: ret.data[i].calstart,
+            end: ret.data[i].calend,
+            calendarId: ret.data[i].calid,
+            category: ret.data[i].catid,
+            repeatcount: ret.data[i].repeatcount,
+            repeattype: ret.data[i].repeattype,
+            periodstartmonth: ret.data[i].periodstartmonth,
+            periodstartweek: ret.data[i].periodstartweek,
+            periodstartdate: ret.data[i].periodstartdate,
+            periodstarthour: ret.data[i].periodstarthour,
+            periodstartminute: ret.data[i].periodstartminute,
+            periodexclude: ret.data[i].periodexclude,
+        });
+    }
+}
+
+// 返回输出信息
+OUTPUT = output;
+*/
+
+/*
+// 输入输出参数格式化
+input = INPUT;
+output = {};
+try {
+    input = decodeURIComponent(input);
+} catch (e) { }
+try {
+    input = base64.decode(input);
+} catch (e) { }
+try {
+    input = JSON.parse(input);
+    input = JSON.parse(input); // 解析可能存在的重复编码
+} catch (e) { }
+
+// 主执行阶段
+try {
+    main(input, output);
+} catch (e) {
+    // 错误信息输出处理,抛出 ok 表示正常结束    
+    if (e != "ok") {
+        if (typeof (e) == "object") {
+            output.error = e;
+        } else if (typeof (e) == "string") {
+            output.error = "错误:" + e;
+        } else {
+            output.error = JSON.stringify(e);
+        }
+        log.error(output.error);
+        STATUS = "error";
+    }
+}
+
+function main(input,output) {
+    output.param = input;
+    var mql = "insert into /matrix/system/calendar";
+    mql += "(name, title, desc, calstart, calend, calid, catid, repeatcount, repeattype, periodstartmonth, periodstartweek, periodstartdate, periodstarthour, periodstartminute, periodexclude)";
+    mql += "values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
+    output.result = odb.mql(mql, 
+      input.id, 
+      input.title || "", 
+      input.body || "", 
+      input.start || 0, 
+      input.end || 0, 
+      input.calendarId || "", 
+      input.category || "", 
+      input.repeatcount || 0, 
+      input.repeattype || "", 
+      input.periodstartmonth || 0, 
+      input.periodstartweek || 0, 
+      input.periodstartdate || 0, 
+      input.periodstarthour || 0, 
+      input.periodstartminute || 0, 
+      input.periodexclude || []);
+}
+
+// 返回输出信息
+OUTPUT = output;
+*/
+
+/*
+// 输入输出参数格式化
+input = INPUT;
+output = {};
+try {
+    input = decodeURIComponent(input);
+} catch (e) { }
+try {
+    input = base64.decode(input);
+} catch (e) { }
+try {
+    input = JSON.parse(input);
+    input = JSON.parse(input); // 解析可能存在的重复编码
+} catch (e) { }
+
+// 主执行阶段
+try {
+    main(input, output);
+} catch (e) {
+    // 错误信息输出处理,抛出 ok 表示正常结束    
+    if (e != "ok") {
+        if (typeof (e) == "object") {
+            output.error = e;
+        } else if (typeof (e) == "string") {
+            output.error = "错误:" + e;
+        } else {
+            output.error = JSON.stringify(e);
+        }
+        log.error(output.error);
+        STATUS = "error";
+    }
+}
+
+function main(input,output) {
+    output.params = input;
+    var mql = "delete from /matrix/system/calendar";
+    mql += " where name=?";
+    output.result = odb.mql(mql, input.id);
+}
+
+// 返回输出信息
+OUTPUT = output;
+*/
+
 /*
 * @property {string} [id] - Event id.
 * @property {string} [calendarId] - Calendar id.
@@ -27,82 +232,68 @@ const today = new TZDate();
 * @property {boolean} [isPrivate] - Whether the event is private or not.
 */
 
-var allevents = [
-  {
-    id: '444',
-    calendarId: 'work',
-    title: '国产化设备投产',
-    category: 'allday',
-    start: addDate(today, 5),
-    end: addDate(today, 15),
-  },
-  {
-    id: '555',
-    calendarId: 'work',
-    title: '网银服务变更',
-    category: 'time',
-    start: addHours(today, 24),
-    end: addHours(today, 27),
-  },
-  {
-    id: '666',
-    calendarId: 'work',
-    title: '本地网络升级',
-    category: 'time',
-    start: addHours(today, 24),
-    end: addHours(today, 27),
-  },
-  {
-    id: '777',
-    calendarId: 'work',
-    title: '离中考还有 ' + diffDays(new TZDate('2023-06-18'), today) + " 天",
-    category: 'milestone',
-    start: today,
-    end: today,
-    isReadOnly: true,
-  },
-  {
-    id: '888',
-    calendarId: 'work',
-    title: '离高考还有 ' + diffDays(new TZDate('2023-06-7'), today) + " 天",
-    category: 'milestone',
-    start: today,
-    end: today,
-    isReadOnly: true,
-  },
-  {
-    id: '991',
-    calendarId: 'work',
-    title: '测试吐司日历',
-    category: 'time',
-    start: addHours(today, 24),
-    end: addHours(today, 27),
-  },
-  {
-    id: '992',
-    calendarId: 'rest',
-    title: '测试完成',
-    category: 'milestone',
-    start: addDate(today, 5),
-    end: addDate(today, 5),
-  },
-  {
-    id: '993',
-    calendarId: 'maintain',
-    title: '全天维护',
-    category: 'allday',
-    start: subtractDate(today, 2),
-    end: subtractDate(today, 1),
-  },
-  {
-    id: '994',
-    calendarId: 'work',
-    title: '报表开发',
-    category: 'task',
-    start: addHours(today, 48),
-    end: addHours(today, 51),
-  },
-];
+function defaultEvents() {
+  return [
+    {
+      id: '444',
+      calendarId: 'work',
+      title: '国产化设备投产',
+      category: 'allday',
+      start: addDate(today, 5),
+      end: addDate(today, 15),
+    },
+    {
+      id: '555',
+      calendarId: 'rest',
+      title: '网银服务变更',
+      category: 'time',
+      start: addHours(today, 24),
+      end: addHours(today, 27),
+    },
+    {
+      id: '777',
+      calendarId: 'work',
+      title: '离中考还有 ' + diffDays(new TZDate('2023-06-18'), today) + " 天",
+      category: 'milestone',
+      start: today,
+      end: today,
+      isReadOnly: true,
+    },
+    {
+      id: '888',
+      calendarId: 'work',
+      title: '离高考还有 ' + diffDays(new TZDate('2023-06-7'), today) + " 天",
+      category: 'milestone',
+      start: today,
+      end: today,
+      isReadOnly: true,
+    },
+    {
+      id: '991',
+      calendarId: 'work',
+      title: '日历功能开发',
+      category: 'time',
+      start: addHours(today, -72).getTime(),
+      end: addHours(today, -24).getTime(),
+    },
+    {
+      id: '993',
+      calendarId: 'maintain',
+      title: '全天维护',
+      category: 'allday',
+      start: subtractDate(today, 2),
+      end: subtractDate(today, 1),
+    },
+    {
+      id: '994',
+      calendarId: 'work',
+      title: '报表开发',
+      category: 'task',
+      start: addHours(today, 48),
+      end: addHours(today, 51),
+    },
+  ];
+}
 
 var calendars = [
   {
@@ -128,11 +319,21 @@ var calendars = [
   },
 ];
 
+function newIndexEvents() {
+  return { "ALL": { name: "所有日历", events: [] } };
+}
+
+var allevents = {};
 var indexcalendars = {};
-var indexevents = { "ALL": { name: "所有日历", events: allevents } };
+var indexevents = newIndexEvents();
 var titleidmap = {};
 var maxtitleid = 1;
 
+function clearTitleID() {
+  titleidmap = {};
+  maxtitleid = 1;
+}
+
 function getTitleID(title) {
   if (titleidmap[title]) {
     return titleidmap[title];
@@ -142,53 +343,94 @@ function getTitleID(title) {
   return titleidmap[title];
 }
 
-let param = encodeURIComponent(JSON.stringify({ start: '', end: '' }));
-m3.callFS("/matrix/calendar/load.js", param).then((res) => {
-  //console.log(res)
-  for (var i in calendars) {
-    indexcalendars[calendars[i].id] = calendars[i];
+var newID = function () {
+  if (typeof crypto === 'object') {
+    if (typeof crypto.randomUUID === 'function') {
+      return crypto.randomUUID();
+    }
+    if (typeof crypto.getRandomValues === 'function' && typeof Uint8Array === 'function') {
+      const callback = (c) => {
+        const num = Number(c);
+        return (num ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (num / 4)))).toString(16);
+      };
+      return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, callback);
+    }
   }
-  if (res.status == "ok" && res.message && res.message.data && res.message.data.length > 0) {
-    for (var i in res.message.data) {
-      var dat = res.message.data[i];
-      dat.id = allevents.length;
-      // console.log(dat);
-      allevents.push(dat);
-      for (var i in res.message.calendars) {
-        if (indexcalendars[res.message.calendars[i].id]) {
-          indexcalendars[res.message.calendars[i].id] = res.message.calendars[i];
-          for (var ni = 0; ni < calendars.length; ni++) {
-            calendars[ni] = res.message.calendars[i];
+  let timestamp = new Date().getTime();
+  let perforNow = (typeof performance !== 'undefined' && performance.now && performance.now() * 1000) || 0;
+  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
+    let random = Math.random() * 16;
+    if (timestamp > 0) {
+      random = (timestamp + random) % 16 | 0;
+      timestamp = Math.floor(timestamp / 16);
+    } else {
+      random = (perforNow + random) % 16 | 0;
+      perforNow = Math.floor(perforNow / 16);
+    }
+    return (c === 'x' ? random : (random & 0x3) | 0x8).toString(16);
+  });
+};
+
+var loadCalendarEvents = function (range) {
+  let param = encodeURIComponent(JSON.stringify(range));
+  m3.callFS("/matrix/calendar/load.js", param).then((res) => {
+    //console.log(res)
+    for (var i in calendars) {
+      indexcalendars[calendars[i].id] = calendars[i];
+    }
+    if (res.status == "ok" && res.message && res.message.data && res.message.data.length >= 0) {
+      allevents = {};
+      for (var i in res.message.data) {
+        var dat = res.message.data[i];
+        // console.log(dat);
+        allevents[dat.id] = dat
+        for (var i in res.message.calendars) {
+          if (indexcalendars[res.message.calendars[i].id]) {
+            indexcalendars[res.message.calendars[i].id] = res.message.calendars[i];
+            for (var ni = 0; ni < calendars.length; ni++) {
+              calendars[ni] = res.message.calendars[i];
+            }
+          } else {
+            calendars.push(res.message.calendars[i]);
+            indexcalendars[res.message.calendars[i].id] = res.message.calendars[i];
           }
-        } else {
-          calendars.push(res.message.calendars[i]);
-          indexcalendars[res.message.calendars[i].id] = res.message.calendars[i];
         }
       }
-    }
-    for (var i = 0; i < allevents.length; i++) {
-      var event = allevents[i];
-      if (!indexevents[event.calendarId]) {
-        var cal = indexcalendars[event.calendarId];
-        if (cal && cal.name) {
-          indexevents[event.calendarId] = { name: "所有" + cal.name, events: [] };
-        } else {
-          indexevents[event.calendarId] = { name: "all " + event.calendarId, events: [] };
-        }
+      var defaultevents = defaultEvents();
+      for (var i in defaultevents) {
+        allevents[defaultevents[i].id] = defaultevents[i];
       }
-      var tid = getTitleID(event.title);
-      if (!indexevents[tid]) {
-        indexevents[tid] = { name: event.title, events: [] };
+      clearTitleID();
+      indexevents = newIndexEvents();
+      for (var id in allevents) {
+        var event = allevents[id];
+        if (event.start > event.end) {
+          var t = event.end;
+          event.end = event.start;
+          event.start = t;
+        }
+        if (!indexevents[event.calendarId]) {
+          var cal = indexcalendars[event.calendarId];
+          if (cal && cal.name) {
+            indexevents[event.calendarId] = { name: "所有" + cal.name, events: [] };
+          } else {
+            indexevents[event.calendarId] = { name: "all " + event.calendarId, events: [] };
+          }
+        }
+        var tid = getTitleID(event.title);
+        if (!indexevents[tid]) {
+          indexevents[tid] = { name: event.title, events: [] };
+        }
+        indexevents[event.calendarId].events.push(event);
+        indexevents[tid].events.push(event);
+        indexevents["ALL"].events.push(event);
       }
-      indexevents[event.calendarId].events.push(event);
-      indexevents[tid].events.push(event);
+      updateproc();
     }
-    // indexevents["ALL"].events.push(event); // indexevents["ALL"].events == allevents
-    updateproc();
-  }
-}).catch((err) => {
-  console.error(err);
-});
+  }).catch((err) => {
+    console.error(err);
+  });
+}
 
 var calendarEventsLoadedProc;
 var onCalendarEventsLoaded = function (fp) {
@@ -199,7 +441,7 @@ var updateproc = function () {
   var indextitles = [];
   indextitles.push({ id: "ALL", name: indexevents["ALL"].name });
   for (var k in indexcalendars) {
-    indextitles.push({ id: k, name: indexevents[k].name });
+    indextitles.push({ id: k, name: indexcalendars[k].name });
   }
   var titles = Object.keys(titleidmap);
   titles.sort();
@@ -212,7 +454,6 @@ var updateproc = function () {
   }
 }
 
-
 var updateEvent = function (event) {
   var target = {};
   var newdata = {};
@@ -228,6 +469,11 @@ var updateEvent = function (event) {
       newdata[k] = event.change[k];
     }
   }
+  if (newdata.start.getTime() > newdata.end.getTime()) {
+    var t = newdata.end;
+    newdata.end = newdata.start;
+    newdata.start = t;
+  }
   var otid = getTitleID(target.title);
   var ntid = getTitleID(newdata.title);
   if (!indexevents[ntid]) {
@@ -274,6 +520,20 @@ var updateEvent = function (event) {
     }
   }
   updateproc();
+  var sdata = {};
+  for (var k in newdata) {
+    sdata[k] = newdata[k];
+  }
+  sdata.start = sdata.start.getTime();
+  sdata.end = sdata.end.getTime();
+  let param = encodeURIComponent(JSON.stringify(sdata));
+  m3.callFS("/matrix/calendar/save.js", param).then((res) => {
+    if (res.status != "ok") {
+      console.error(res);
+    }
+  }).catch((err) => {
+    console.error(err);
+  });
   return indexevents;
 }
 
@@ -303,7 +563,15 @@ var deleteEvent = function (event) {
     delete titleidmap[target.title];
   }
   updateproc();
+  let param = encodeURIComponent(JSON.stringify(target));
+  m3.callFS("/matrix/calendar/delete.js", param).then((res) => {
+    if (res.status != "ok") {
+      console.error(res);
+    }
+  }).catch((err) => {
+    console.error(err);
+  });
   return indexevents;
 }
 
-export var events = indexevents, calendars = calendars, onCalendarEventsLoaded = onCalendarEventsLoaded, updateEvent = updateEvent, deleteEvent = deleteEvent;
+export var events = indexevents, calendars = calendars, newID = newID, loadCalendarEvents = loadCalendarEvents, onCalendarEventsLoaded = onCalendarEventsLoaded, updateEvent = updateEvent, deleteEvent = deleteEvent;