econtrol-tools-calendar 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -97,6 +97,10 @@ const holidays = {
97
97
 
98
98
  // 事件处理函数
99
99
  function handleEventAdded(event: EventInput) {
100
+ // 如果事件没有ID,生成一个唯一ID(事件ID应该由外部提供)
101
+ if (!event.id) {
102
+ event.id = `event-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
103
+ }
100
104
  events.value.push(event);
101
105
  ElMessage.success("事件已添加");
102
106
  }
@@ -109,9 +113,11 @@ function handleEventUpdated(event: EventInput) {
109
113
  }
110
114
  }
111
115
 
112
- function handleEventDeleted(eventId: string) {
113
- events.value = events.value.filter((e) => e.id !== eventId);
114
- ElMessage.success("事件已删除");
116
+ function handleEventDeleted(event: EventInput) {
117
+ events.value = events.value.filter((e) => e.id !== event.id);
118
+ ElMessage.success(`事件"${event.title}"已删除`);
119
+ // 可以在这里调用 API 删除事件
120
+ // await deleteEventFromAPI(event);
115
121
  }
116
122
 
117
123
  function handleEventsChange(newEvents: EventInput[]) {
@@ -217,8 +223,9 @@ interface HolidayData {
217
223
  | `quickAddSaved` | `event: EventInput` | 快速添加事件保存后触发 |
218
224
  | `eventAdded` | `event: EventInput` | 事件添加后触发 |
219
225
  | `eventUpdated` | `event: EventInput` | 事件更新后触发 |
220
- | `eventDeleted` | `eventId: string` | 事件删除后触发 |
226
+ | `eventDeleted` | `event: EventInput` | 事件删除后触发,包含完整的事件详情 |
221
227
  | `eventsChange` | `events: EventInput[]` | 事件列表变化后触发,包含当前所有事件 |
228
+ | `deviceClick` | `deviceId: string` | 点击设备名称时触发,传递设备 ID |
222
229
 
223
230
  ### EventInput 类型
224
231
 
@@ -337,6 +344,10 @@ const quickAddTimeRange = ref({
337
344
 
338
345
  // 事件处理函数
339
346
  function handleEventAdded(event: EventInput) {
347
+ // 如果事件没有ID,生成一个唯一ID(事件ID应该由外部提供)
348
+ if (!event.id) {
349
+ event.id = `event-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
350
+ }
340
351
  events.value.push(event);
341
352
  ElMessage.success("事件已添加");
342
353
  // 可以在这里调用 API 保存事件
@@ -353,11 +364,11 @@ function handleEventUpdated(event: EventInput) {
353
364
  }
354
365
  }
355
366
 
356
- function handleEventDeleted(eventId: string) {
357
- events.value = events.value.filter((e) => e.id !== eventId);
358
- ElMessage.success("事件已删除");
367
+ function handleEventDeleted(event: EventInput) {
368
+ events.value = events.value.filter((e) => e.id !== event.id);
369
+ ElMessage.success(`事件"${event.title}"已删除`);
359
370
  // 可以在这里调用 API 删除事件
360
- // await deleteEventFromAPI(eventId);
371
+ // await deleteEventFromAPI(event);
361
372
  }
362
373
 
363
374
  function handleEventsChange(newEvents: EventInput[]) {
@@ -366,6 +377,12 @@ function handleEventsChange(newEvents: EventInput[]) {
366
377
  // await syncEventsToAPI(newEvents);
367
378
  }
368
379
 
380
+ function handleDeviceClick(deviceId: string) {
381
+ console.log("点击了设备:", deviceId);
382
+ // 可以在这里处理设备点击逻辑,比如打开设备详情页面、跳转路由等
383
+ // router.push(`/device/${deviceId}`);
384
+ }
385
+
369
386
  function handleQuickAddSaved(event: EventInput) {
370
387
  console.log("快速添加的事件:", event);
371
388
  // 处理快速添加逻辑
@@ -387,8 +404,9 @@ function handleQuickAddSaved(event: EventInput) {
387
404
  :userinfo="userinfo"
388
405
  @event-added="(event) => handleEventAdded(device.id, event)"
389
406
  @event-updated="(event) => handleEventUpdated(device.id, event)"
390
- @event-deleted="(eventId) => handleEventDeleted(device.id, eventId)"
407
+ @event-deleted="(event) => handleEventDeleted(device.id, event)"
391
408
  @events-change="(events) => handleEventsChange(device.id, events)"
409
+ @device-click="(deviceId) => handleDeviceClick(deviceId)"
392
410
  />
393
411
  </div>
394
412
  </template>
@@ -426,17 +444,27 @@ function handleEventUpdated(deviceId: string, event: EventInput) {
426
444
  }
427
445
  }
428
446
 
429
- function handleEventDeleted(deviceId: string, eventId: string) {
447
+ function handleEventDeleted(deviceId: string, event: EventInput) {
430
448
  if (deviceEvents.value[deviceId]) {
431
449
  deviceEvents.value[deviceId] = deviceEvents.value[deviceId].filter(
432
- (e) => e.id !== eventId
450
+ (e) => e.id !== event.id
433
451
  );
452
+ ElMessage.success(`事件"${event.title}"已删除`);
453
+ // 可以在这里调用 API 删除事件
454
+ // await deleteEventFromAPI(event);
434
455
  }
435
456
  }
457
+ }
436
458
 
437
459
  function handleEventsChange(deviceId: string, events: EventInput[]) {
438
460
  deviceEvents.value[deviceId] = events;
439
461
  }
462
+
463
+ function handleDeviceClick(deviceId: string) {
464
+ console.log("点击了设备:", deviceId);
465
+ // 可以在这里处理设备点击逻辑,比如打开设备详情页面、跳转路由等
466
+ // router.push(`/device/${deviceId}`);
467
+ }
440
468
  </script>
441
469
  ```
442
470
 
@@ -521,15 +549,17 @@ pnpm preview
521
549
 
522
550
  2. **事件格式**:事件的时间格式必须使用 ISO 8601 格式(`YYYY-MM-DDTHH:mm:ss`),例如:`"2025-01-15T10:00:00"`。
523
551
 
524
- 3. **权限控制**:通过 `userinfo` prop 控制事件的可编辑性,只有 `extendedProps.organizerId` 匹配 `userinfo.userid` 的事件才能被修改。
552
+ 3. **事件 ID**:组件不会自动生成事件 ID,事件 ID 应该由外部(App.vue)的事件列表提供。当组件 emit `eventAdded` 事件时,如果事件没有 ID,父组件应该生成 ID 并更新 `events` prop。
553
+
554
+ 4. **权限控制**:通过 `userinfo` prop 控制事件的可编辑性,只有 `extendedProps.organizerId` 匹配 `userinfo.userid` 的事件才能被修改。
525
555
 
526
- 4. **用户信息**:组件会显示 `username` 作为预订人,并在事件数据中保存 `username` 和 `organizerId`。
556
+ 5. **用户信息**:组件会显示 `username` 作为预订人,并在事件数据中保存 `username` 和 `organizerId`。
527
557
 
528
- 5. **设备信息**:组件头部显示设备名称(`deviceInfo.name`),设备 ID(`deviceId`)作为关键字段保存在事件数据中。
558
+ 6. **设备信息**:组件头部显示设备名称(`deviceInfo.name`),设备 ID(`deviceId`)作为关键字段保存在事件数据中。
529
559
 
530
- 6. **时间冲突**:当 `allowOverlap` 为 `false` 时,组件会自动检查时间冲突,不允许创建重叠的事件。
560
+ 7. **时间冲突**:当 `allowOverlap` 为 `false` 时,组件会自动检查时间冲突,不允许创建重叠的事件。
531
561
 
532
- 7. **节假日显示**:节假日数据格式为 `{ "YYYY-MM-DD": "节假日名称" }`,传入 `holidays` prop 后会在日历上高亮显示。
562
+ 8. **节假日显示**:节假日数据格式为 `{ "YYYY-MM-DD": "节假日名称" }`,传入 `holidays` prop 后会在日历上高亮显示。
533
563
 
534
564
  ## 📄 许可证
535
565
 
package/dist/calendar.js CHANGED
@@ -100,7 +100,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
100
100
  holidays: { default: null },
101
101
  events: { default: () => [] }
102
102
  },
103
- emits: ["quickAddSaved", "eventAdded", "eventUpdated", "eventDeleted", "eventsChange"],
103
+ emits: ["quickAddSaved", "eventAdded", "eventUpdated", "eventDeleted", "eventsChange", "deviceClick"],
104
104
  setup(__props, { emit: __emit }) {
105
105
  const emit = __emit;
106
106
  const props = __props;
@@ -200,11 +200,45 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
200
200
  const eventOrganizerId = ((_a = event.extendedProps) == null ? void 0 : _a.organizerId) || "";
201
201
  return eventOrganizerId === currentUserId.value;
202
202
  }
203
- const events = ref([...props.events]);
203
+ function normalizeEventTime(time) {
204
+ if (!time) return void 0;
205
+ if (time instanceof Date) {
206
+ return time;
207
+ }
208
+ if (typeof time === "number") {
209
+ return new Date(time);
210
+ }
211
+ if (typeof time === "string") {
212
+ if (time.includes("T")) {
213
+ return time;
214
+ }
215
+ const dateOnlyPattern = /^\d{4}-\d{2}-\d{2}$/;
216
+ if (dateOnlyPattern.test(time)) {
217
+ const normalizedTime = `${time} 00:00:00`;
218
+ return formatToISO(normalizedTime);
219
+ }
220
+ const dateTimePattern = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;
221
+ if (dateTimePattern.test(time)) {
222
+ return formatToISO(time);
223
+ }
224
+ return time;
225
+ }
226
+ return time;
227
+ }
228
+ function normalizeEvent(event) {
229
+ return {
230
+ ...event,
231
+ start: normalizeEventTime(event.start),
232
+ end: normalizeEventTime(event.end)
233
+ };
234
+ }
235
+ const events = ref(
236
+ (props.events || []).map((event) => normalizeEvent(event))
237
+ );
204
238
  watch(
205
239
  () => props.events,
206
240
  (newEvents) => {
207
- events.value = [...newEvents || []];
241
+ events.value = (newEvents || []).map((event) => normalizeEvent(event));
208
242
  },
209
243
  { deep: true, immediate: true }
210
244
  );
@@ -803,7 +837,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
803
837
  if (!props.deviceId) {
804
838
  return;
805
839
  }
806
- deviceDialogVisible.value = true;
840
+ emit("deviceClick", props.deviceId);
807
841
  }
808
842
  function handleAddEvent() {
809
843
  if (props.isOccupied) {
@@ -869,15 +903,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
869
903
  ElMessage.error("该时间段与其他事件冲突,请选择其他时间");
870
904
  return;
871
905
  }
872
- const eventId = `event-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
873
906
  const taskId = formData.taskid || props.taskid || "";
907
+ const tempEventId = taskId && taskId === props.taskid ? taskId : void 0;
874
908
  const colorInfo = assignEventColor(
875
909
  startStr,
876
910
  endStr,
877
911
  void 0,
878
912
  currentUser.value,
879
- eventId,
880
- // 传入事件ID用于颜色分配
913
+ tempEventId,
914
+ // 传入临时ID用于颜色分配(如果taskid匹配)
881
915
  taskId
882
916
  // 传入 taskid 用于颜色分配
883
917
  );
@@ -887,7 +921,7 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
887
921
  const eventOrganizerId = currentUserId.value;
888
922
  const editable = !currentUserId.value || eventOrganizerId === currentUserId.value;
889
923
  const newEvent = {
890
- id: eventId,
924
+ // 不设置 id,由外部 App.vue 的事件列表提供
891
925
  title: props.quickAddTaskName,
892
926
  start: startISO,
893
927
  end: endISO,
@@ -1083,21 +1117,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1083
1117
  ElMessage.error("该时间段与其他事件冲突,请选择其他时间");
1084
1118
  return;
1085
1119
  }
1086
- let eventId = (_b = editingEvent.value) == null ? void 0 : _b.id;
1087
- if (!eventId) {
1088
- if (formData.taskid && formData.taskid.trim() && formData.taskid === props.taskid) {
1089
- eventId = formData.taskid;
1090
- } else {
1091
- eventId = `event-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
1092
- }
1093
- }
1120
+ const eventId = (_b = editingEvent.value) == null ? void 0 : _b.id;
1121
+ const tempEventId = eventId || (formData.taskid && formData.taskid === props.taskid ? formData.taskid : void 0);
1094
1122
  const colorInfo = assignEventColor(
1095
1123
  formData.start,
1096
1124
  formData.end,
1097
1125
  (_c = editingEvent.value) == null ? void 0 : _c.id,
1098
1126
  formData.organizer || currentUser.value,
1099
- eventId,
1100
- // 传入事件ID用于颜色分配
1127
+ tempEventId,
1128
+ // 传入临时ID用于颜色分配(编辑时使用eventId,新增时如果taskid匹配使用taskid)
1101
1129
  formData.taskid
1102
1130
  // 传入 taskid 用于颜色分配
1103
1131
  );
@@ -1167,8 +1195,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1167
1195
  const eventOrganizerId = formData.organizerId || currentUserId.value;
1168
1196
  const editable = !currentUserId.value || eventOrganizerId === currentUserId.value;
1169
1197
  const newEvent = {
1170
- id: eventId,
1171
- // 使用之前生成的事件ID
1198
+ // 不设置 id,由外部 App.vue 的事件列表提供
1199
+ // 如果 taskid 匹配 props.taskid,可以设置 id 为 taskid(可选)
1200
+ ...formData.taskid && formData.taskid === props.taskid ? { id: formData.taskid } : {},
1172
1201
  title: formData.title,
1173
1202
  start: startISO,
1174
1203
  end: endISO,
@@ -1198,12 +1227,26 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1198
1227
  resetForm();
1199
1228
  }
1200
1229
  function handleDelete() {
1230
+ var _a, _b, _c;
1201
1231
  if (editingEvent.value) {
1202
1232
  const eventId = editingEvent.value.id;
1233
+ const deletedEvent = {
1234
+ id: eventId || "",
1235
+ title: editingEvent.value.title,
1236
+ start: ((_a = editingEvent.value.start) == null ? void 0 : _a.toISOString()) || "",
1237
+ end: (_b = editingEvent.value.end) == null ? void 0 : _b.toISOString(),
1238
+ allDay: editingEvent.value.allDay || false,
1239
+ backgroundColor: editingEvent.value.backgroundColor,
1240
+ borderColor: editingEvent.value.borderColor,
1241
+ editable: (_c = editingEvent.value.extendedProps) == null ? void 0 : _c.editable,
1242
+ extendedProps: {
1243
+ ...editingEvent.value.extendedProps || {}
1244
+ }
1245
+ };
1203
1246
  editingEvent.value.remove();
1204
1247
  dialogVisible.value = false;
1205
1248
  resetForm();
1206
- emit("eventDeleted", eventId || "");
1249
+ emit("eventDeleted", deletedEvent);
1207
1250
  const newEventsList = events.value.filter((e) => e.id !== eventId);
1208
1251
  emit("eventsChange", newEventsList);
1209
1252
  }
@@ -1465,6 +1508,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1465
1508
  "value-format": "YYYY-MM-DD HH:mm:ss",
1466
1509
  "disabled-date": disabledPastDate,
1467
1510
  key: `start-${formData.start || "empty"}`,
1511
+ "append-to-body": "",
1512
+ "z-index": 3001,
1468
1513
  style: { "width": "100%" }
1469
1514
  }, null, 8, ["modelValue"]))
1470
1515
  ]),
@@ -1481,6 +1526,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
1481
1526
  "value-format": "YYYY-MM-DD HH:mm:ss",
1482
1527
  "disabled-date": disabledPastDate,
1483
1528
  key: `end-${formData.end || "empty"}`,
1529
+ "append-to-body": "",
1530
+ "z-index": 3001,
1484
1531
  style: { "width": "100%" }
1485
1532
  }, null, 8, ["modelValue"]))
1486
1533
  ]),
@@ -1612,7 +1659,7 @@ const _export_sfc = (sfc, props) => {
1612
1659
  }
1613
1660
  return target;
1614
1661
  };
1615
- const SCalendarComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-337c51f8"]]);
1662
+ const SCalendarComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-c28885e3"]]);
1616
1663
  function getHolidays(year) {
1617
1664
  const holidays = {};
1618
1665
  if (year === 2026) {