@opendesign-plus-test/components 0.0.1-rc.21 → 0.0.1-rc.23

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.
Files changed (149) hide show
  1. package/dist/chunk-OElCookieNotice.cjs.js +1 -1
  2. package/dist/chunk-OElCookieNotice.es.js +428 -137
  3. package/dist/components/OBanner.vue.d.ts +10 -1
  4. package/dist/components/OFooter.vue.d.ts +1 -1
  5. package/dist/components/OHeaderSearch.vue.d.ts +4 -4
  6. package/dist/components/activity/OActivityApproval.vue.d.ts +277 -0
  7. package/dist/components/activity/OActivityForm.vue.d.ts +140 -0
  8. package/dist/components/activity/OMyActivityCalendar.vue.d.ts +578 -0
  9. package/dist/components/activity/config.d.ts +15 -0
  10. package/dist/components/activity/data.d.ts +51 -0
  11. package/dist/components/activity/index.d.ts +623 -0
  12. package/dist/components/activity/types.d.ts +76 -0
  13. package/dist/components/meeting/OMeetingCalendar.vue.d.ts +309 -0
  14. package/dist/components/meeting/OMeetingForm.vue.d.ts +156 -0
  15. package/dist/components/meeting/OMyMeetingCalendar.vue.d.ts +582 -0
  16. package/dist/components/meeting/OSigMeetingCalendar.vue.d.ts +24 -0
  17. package/dist/components/meeting/components/OMeetingCalendarList.vue.d.ts +27 -0
  18. package/dist/components/meeting/components/OMeetingCalendarSelector.vue.d.ts +664 -0
  19. package/dist/components/meeting/components/OMeetingDetail.vue.d.ts +12 -0
  20. package/dist/components/meeting/components/OMeetingPlaybackSubtitles.vue.d.ts +5 -0
  21. package/dist/components/meeting/components/OMeetingPlaybackVideo.vue.d.ts +17 -0
  22. package/dist/components/meeting/components/OSigMeetingAside.vue.d.ts +16 -0
  23. package/dist/components/meeting/config.d.ts +27 -0
  24. package/dist/components/meeting/types.d.ts +140 -0
  25. package/dist/components/meeting/utils.d.ts +21 -0
  26. package/dist/components.cjs.js +224 -3
  27. package/dist/components.css +1 -1
  28. package/dist/components.es.js +43544 -2307
  29. package/dist/index.d.ts +2 -0
  30. package/package.json +6 -3
  31. package/scripts/generate-components-index.js +4 -0
  32. package/src/assets/meeting/svg-icons/icon-all.svg +3 -0
  33. package/src/assets/meeting/svg-icons/icon-backward.svg +4 -0
  34. package/src/assets/meeting/svg-icons/icon-calendar.svg +3 -0
  35. package/src/assets/meeting/svg-icons/icon-cancel.svg +4 -0
  36. package/src/assets/meeting/svg-icons/icon-captions.svg +4 -0
  37. package/src/assets/meeting/svg-icons/icon-close-captions.svg +6 -0
  38. package/src/assets/meeting/svg-icons/icon-close-fullscreen.svg +6 -0
  39. package/src/assets/meeting/svg-icons/icon-copy.svg +3 -0
  40. package/src/assets/meeting/svg-icons/icon-create.svg +5 -0
  41. package/src/assets/meeting/svg-icons/icon-delete.svg +7 -0
  42. package/src/assets/meeting/svg-icons/icon-empty.svg +31 -0
  43. package/src/assets/meeting/svg-icons/icon-empty_dark.svg +49 -0
  44. package/src/assets/meeting/svg-icons/icon-event.svg +3 -0
  45. package/src/assets/meeting/svg-icons/icon-export.svg +3 -0
  46. package/src/assets/meeting/svg-icons/icon-forward.svg +4 -0
  47. package/src/assets/meeting/svg-icons/icon-fullscreen.svg +6 -0
  48. package/src/assets/meeting/svg-icons/icon-help.svg +3 -0
  49. package/src/assets/meeting/svg-icons/icon-important.svg +4 -0
  50. package/src/assets/meeting/svg-icons/icon-info.svg +3 -0
  51. package/src/assets/meeting/svg-icons/icon-meet.svg +3 -0
  52. package/src/assets/meeting/svg-icons/icon-meeting-message.svg +5 -0
  53. package/src/assets/meeting/svg-icons/icon-meeting.svg +4 -0
  54. package/src/assets/meeting/svg-icons/icon-play.svg +5 -0
  55. package/src/assets/meeting/svg-icons/icon-playing-tip.svg +7 -0
  56. package/src/assets/meeting/svg-icons/icon-playing.svg +5 -0
  57. package/src/assets/meeting/svg-icons/icon-question.svg +4 -0
  58. package/src/assets/meeting/svg-icons/icon-sound.svg +5 -0
  59. package/src/assets/meeting/svg-icons/icon-speaker.svg +3 -0
  60. package/src/assets/meeting/svg-icons/icon-summit.svg +3 -0
  61. package/src/assets/meeting/svg-icons/icon-telligent.svg +3 -0
  62. package/src/assets/meeting/svg-icons/icon-tip.svg +3 -0
  63. package/src/assets/meeting/svg-icons/icon-todo.svg +4 -0
  64. package/src/assets/meeting/transparent.png +0 -0
  65. package/src/assets/svg-icons/icon-chevron-up.svg +3 -0
  66. package/src/assets/svg-icons/icon-filter.svg +3 -0
  67. package/src/assets/svg-icons/icon-loading.svg +4 -0
  68. package/src/assets/svg-icons/icon-search.svg +3 -0
  69. package/src/assets/svg-icons/icon-tips.svg +3 -0
  70. package/src/components/OBanner.vue +11 -3
  71. package/src/components/OFooter.vue +1 -1
  72. package/src/components/activity/OActivityApproval.vue +775 -0
  73. package/src/components/activity/OActivityForm.vue +465 -0
  74. package/src/components/activity/OMyActivityCalendar.vue +1342 -0
  75. package/src/components/activity/config.ts +130 -0
  76. package/src/components/activity/data.ts +365 -0
  77. package/src/components/activity/index.ts +24 -0
  78. package/src/components/activity/types.ts +83 -0
  79. package/src/components/common/MoreText.vue +119 -0
  80. package/src/components/common/ThFilter.vue +326 -0
  81. package/src/components/events/OEventsApply.vue +2 -86
  82. package/src/components/events/OEventsCalendar.vue +0 -25
  83. package/src/components/events/OEventsList.vue +0 -51
  84. package/src/components/events/index.ts +1 -0
  85. package/src/components/meeting/OMeetingCalendar.vue +865 -0
  86. package/src/components/meeting/OMeetingForm.vue +1035 -0
  87. package/src/components/meeting/OMeetingPlayback.vue +439 -0
  88. package/src/components/meeting/OMyMeetingCalendar.vue +1501 -0
  89. package/src/components/meeting/OSigMeetingCalendar.vue +411 -0
  90. package/src/components/meeting/components/OMeetingCalendarList.vue +462 -0
  91. package/src/components/meeting/components/OMeetingCalendarSelector.vue +206 -0
  92. package/src/components/meeting/components/OMeetingDetail.vue +189 -0
  93. package/src/components/meeting/components/OMeetingPlaybackSubtitles.vue +611 -0
  94. package/src/components/meeting/components/OMeetingPlaybackVideo.vue +741 -0
  95. package/src/components/meeting/components/OMyCalendarWrapper.vue +160 -0
  96. package/src/components/meeting/components/OSigMeetingAside.vue +197 -0
  97. package/src/components/meeting/config.ts +110 -0
  98. package/src/components/meeting/index.ts +45 -0
  99. package/src/components/meeting/types.ts +167 -0
  100. package/src/components/meeting/utils.ts +106 -0
  101. package/src/draft/Footer.vue +4 -4
  102. package/src/env.d.ts +15 -0
  103. package/src/i18n/en.ts +140 -0
  104. package/src/i18n/index.ts +18 -4
  105. package/src/i18n/zh.ts +140 -0
  106. package/src/index.ts +2 -0
  107. package/tsconfig.json +6 -2
  108. package/vite.config.ts +25 -9
  109. package/npmcachae/_cacache/content-v2/sha512/05/f7/dd881de8b21208ea65cfce17c65f29964c3897505819f81151b9798a3a6ab1a1114324192354ead15cd2c8d93f76cc9929af168066ec9cc7878d0fd87578 +0 -1
  110. package/npmcachae/_cacache/content-v2/sha512/08/b7/879230f8c2f3765920a6fd6113f4687141f1f645f96af7d95a0dee9113d1095d000fb78a5dd55c1860bbfb9b698ef6281b3874b03b2384222f61fe055fc4 +0 -1
  111. package/npmcachae/_cacache/content-v2/sha512/10/a0/a6626613c03ee052925a762e8675878efdf83dac64fafea43beb2a875f7d7c3907bb0ee30761253cd16021fd58911449594e1d3358675cbb7c48e62f220a +0 -1
  112. package/npmcachae/_cacache/content-v2/sha512/2e/a6/7cbcf55a98bbe2ca881d10e982ebf59211a0ec051eaf46eb1914df66cc35ae502ed6888850e51d8f45cd92695bac16961a642bc41508f8d5160a9ab617ab +0 -1
  113. package/npmcachae/_cacache/content-v2/sha512/92/8d/e5259c5d5cc2a625247f3c4d809192ca9482467e23683d74924a11e91a7997ad890b3d26adaf34df66d5329cc7a5fbde6713110cad05107a0b504e4fd4e8 +0 -1
  114. package/npmcachae/_cacache/content-v2/sha512/e9/45/9597d870127c35681155cec5fe52fde4e1aa0f778b996ee371e856aca850ee4c13aba74b0c3d3a89ff0ea4c9e1d33e64e53c31dc9cede0b31012695ee659 +0 -1
  115. package/npmcachae/_cacache/index-v5/16/4a/7195fcc6857299c4ab7e26014a8ae6e3c396507a2c8db3da1b74b005d574 +0 -3
  116. package/npmcachae/_cacache/index-v5/58/f0/4fe556f104b09be642895a82afa463fe560d9a0dc8f507efeef825a6905e +0 -3
  117. package/npmcachae/_cacache/index-v5/67/7d/0b50dc4c09555fc922ccf43c46994f1a0a5ff47dc0a5d5cf41437ac2d3e6 +0 -3
  118. package/npmcachae/_cacache/index-v5/8f/28/353f8839e030ab11aab3e7d9f1b8c053403e9f593cf6d4aa6ec8fdd7610d +0 -3
  119. package/npmcachae/_cacache/index-v5/97/10/0fcf20eb29d0726bd820822f6729718464b591b0e6901217c956740e943c +0 -3
  120. package/npmcachae/_cacache/index-v5/db/89/a0a4f35f593105624ab39339962d9e9b5cc65ed0c346b0732fb8dd73721d +0 -3
  121. package/npmcachae/_logs/2026-03-26T14_10_35_885Z-debug-0.log +0 -171
  122. package/npmcachae/_logs/2026-03-26T14_10_38_617Z-debug-0.log +0 -4227
  123. package/npmcachae/_logs/2026-03-26T14_10_45_316Z-debug-0.log +0 -4228
  124. package/npmcachae/_logs/2026-03-26T14_10_48_169Z-debug-0.log +0 -4228
  125. package/npmcachae/_logs/2026-03-26T14_10_51_306Z-debug-0.log +0 -464
  126. package/npmcachae/_logs/2026-03-26T14_10_53_911Z-debug-0.log +0 -464
  127. package/npmcachae/_logs/2026-03-26T14_10_56_398Z-debug-0.log +0 -464
  128. package/npmcachae/_logs/2026-03-26T14_10_58_861Z-debug-0.log +0 -464
  129. package/npmcachae/_logs/2026-03-26T14_11_01_337Z-debug-0.log +0 -464
  130. package/npmcachae/_logs/2026-03-26T14_11_03_851Z-debug-0.log +0 -464
  131. package/npmcachae/_logs/2026-03-26T14_11_08_024Z-debug-0.log +0 -464
  132. package/npmcachae/_update-notifier-last-checked +0 -0
  133. package/src/components/meeting/npmcachae/_cacache/content-v2/sha512/3e/17/1865217b9acb9f4921c53a09b5c76587cd2ab748beb2699ff6cfb1341d73b1aa56ed91ffc5ab2c9c9b3fbe626103b35d9a79ff29ff6b8cbb8d89755fe1a2 +0 -1
  134. package/src/components/meeting/npmcachae/_cacache/content-v2/sha512/a6/15/47bb7552ec9248079e839a5feecc1742d4de19524fdf041cf581701cf4760a5025106036145e279ba193b07c8fa5b07ae3d75f1b6032f0cb2219115b6167 +0 -1
  135. package/src/components/meeting/npmcachae/_cacache/content-v2/sha512/d1/4c/133b32e09c97101a27a07cc4432f94e470cff02d120d21babcea77c3f5cd436793516dc1a8e282ee1a568f923c148b1a48f4a43233462a530d35e8b41c67 +0 -1
  136. package/src/components/meeting/npmcachae/_cacache/index-v5/54/0d/a4909047714a0a7198bb9bd37020992464e47c79a791889919b84d90aab0 +0 -3
  137. package/src/components/meeting/npmcachae/_cacache/index-v5/8e/2b/21a79778e2ac08cf5663baf83cb35f951995a496007eb2e2f7fba54021a4 +0 -3
  138. package/src/components/meeting/npmcachae/_cacache/index-v5/eb/a0/b70c8132e5b57a0f1e129b8cc941796420a9c147c0baa680710083740898 +0 -2
  139. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_03_54_955Z-debug-0.log +0 -277
  140. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_03_57_842Z-debug-0.log +0 -277
  141. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_04_00_016Z-debug-0.log +0 -277
  142. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_04_02_191Z-debug-0.log +0 -277
  143. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_04_04_425Z-debug-0.log +0 -277
  144. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_04_06_642Z-debug-0.log +0 -277
  145. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_04_08_826Z-debug-0.log +0 -277
  146. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_25_36_140Z-debug-0.log +0 -433
  147. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_25_39_573Z-debug-0.log +0 -433
  148. package/src/components/meeting/npmcachae/_logs/2026-03-20T07_25_42_134Z-debug-0.log +0 -212
  149. package/src/components/meeting/npmcachae/_update-notifier-last-checked +0 -0
@@ -0,0 +1,1342 @@
1
+ <script setup lang="ts">
2
+ import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue';
3
+ import {
4
+ OButton,
5
+ ODivider,
6
+ OIcon,
7
+ OScroller,
8
+ OCollapse,
9
+ OCollapseItem,
10
+ OTag,
11
+ ODialog,
12
+ useMessage,
13
+ OIconArrowLeft,
14
+ OIconArrowRight,
15
+ OIconChevronLeft,
16
+ OIconChevronRight,
17
+ } from '@opensig/opendesign';
18
+ import { ElCalendar } from 'element-plus';
19
+ import dayjs from 'dayjs';
20
+ import { useDebounceFn } from '@vueuse/core';
21
+
22
+ import IconEvent from '~icons/meeting/icon-event.svg';
23
+
24
+ import type { ActivityItemT, MyActivityCalendarPropsT, ParamsItemT } from './types';
25
+ import { useScreen } from '@opendesign-plus/composables';
26
+ import { formatDate, getDateNumber } from '../meeting/utils';
27
+ import { statusMap, acticityTypeMap } from './config';
28
+ import { PageParamsT } from '../meeting/types';
29
+ import OMeetingDetail from '@/components/meeting/components/OMeetingDetail.vue';
30
+
31
+ const message = useMessage(null);
32
+ const { isPhone } = useScreen();
33
+
34
+ const props = defineProps<MyActivityCalendarPropsT>();
35
+
36
+ const emits = defineEmits(['edit']);
37
+ const list = ref<ActivityItemT[]>([]); // 列表数据
38
+ const originList = ref([]); // 原始数据
39
+
40
+ const currentPage = ref(1); // 分页-当前页
41
+ const pageSize = ref(50); // 分页-每页数量
42
+ const total = ref(null); // 分页-总数
43
+ const reloadAll = ref(false); // 是否需要清空数据
44
+
45
+ const expanded = ref([]); // 展开的数据,id
46
+
47
+ const nextLoading = ref(false);
48
+ const bottomReached = ref(false);
49
+
50
+ const canLoadMore = computed(() => originList.value.length < total.value || total.value === null);
51
+
52
+ const getList = async () => {
53
+ if (!props.getListRequest) {
54
+ return;
55
+ }
56
+ if (nextLoading.value) {
57
+ return;
58
+ }
59
+ try {
60
+ if (total.value > 0 && (currentPage.value - 1) * pageSize.value > total.value) {
61
+ return;
62
+ }
63
+ // 当月数据已加载完,手动切换下一月
64
+ if (!canLoadMore.value && isPhone.value) {
65
+ changeMonth('next-month');
66
+ return;
67
+ }
68
+ nextLoading.value = true;
69
+ const res = await props.getListRequest({
70
+ page: currentPage.value,
71
+ size: pageSize.value,
72
+ } as unknown as PageParamsT);
73
+ console.log(res);
74
+ const tempList = (res.data || [])
75
+ .map((item: ActivityItemT) => {
76
+ const { start_date, end_date, start, end } = item;
77
+ return [
78
+ {
79
+ ...item,
80
+ time: `${ start_date }-${ end }`,
81
+ start_date_time: `${ start_date } ${ start }`,
82
+ end_date_time: `${ end_date } ${ end }`,
83
+ type: 'activity',
84
+ dateRange: `${ start_date } ${ start }-${ end_date } ${ end }`,
85
+ isExpired: dayjs(`${ start_date } ${ start }`).isBefore(dayjs()),
86
+ },
87
+ ];
88
+ })
89
+ .flat()
90
+ .filter((v) => {
91
+ console.log(v.start_date, formatDate(selectedDate.value, 'YYYY-MM-DD'));
92
+ return v.start_date.slice(0, 7) === formatDate(selectedDate.value, 'YYYY-MM-DD').slice(0, 7);
93
+ });
94
+ if (reloadAll.value) {
95
+ originList.value = res.data || [];
96
+ list.value = tempList;
97
+ console.log(list.value);
98
+ } else {
99
+ if (currentPage.value === 1 && !isPhone.value) {
100
+ originList.value = res.data || [];
101
+ list.value = tempList;
102
+ } else {
103
+ originList.value = [...originList.value, ...(res.data || [])];
104
+ list.value = [...list.value, ...tempList];
105
+ }
106
+ }
107
+ list.value.sort((a, b) => {
108
+ if (a.start_date === b.start_date) {
109
+ return getDateNumber(a.start) > getDateNumber(b.start) ? 1 : -1;
110
+ } else {
111
+ return dayjs(a.start_date).isAfter(dayjs(b.start_date)) ? 1 : -1;
112
+ }
113
+ });
114
+ total.value = res?.total || 0;
115
+ nextTick(() => {
116
+ getSelectedDate();
117
+ // 监听滚动事件以自动加载下一页
118
+ if (scrollerRef.value && !isPhone.value) {
119
+ updateScroller();
120
+ }
121
+ });
122
+ } finally {
123
+ nextLoading.value = false;
124
+ bottomReached.value = false;
125
+ reloadAll.value = false;
126
+ }
127
+ };
128
+
129
+ const expandList = ref<number[]>([]);
130
+ const getActivityDetail = (val: number) => {
131
+ if (!props.getActivityDetailRequest) {
132
+ return;
133
+ }
134
+ if (!expandList.value.includes(val)) {
135
+ expandList.value.push(val);
136
+ props.getActivityDetailRequest(val).then((res) => {
137
+ list.value?.forEach((item) => {
138
+ if (item.id === res.id) {
139
+ item.approve_record = res.approve_record;
140
+ }
141
+ });
142
+ });
143
+ }
144
+ };
145
+
146
+ const change = (val: number[]) => {
147
+ if (val.length) {
148
+ val.forEach((item: number) => {
149
+ getActivityDetail(item);
150
+ });
151
+ }
152
+ };
153
+
154
+ const calcIfApproved = (date) => {
155
+ const activityOfDate = list.value.filter((v) => v.start_date === date);
156
+ return activityOfDate.length && activityOfDate.every((v) => v.status === 3 || v.status === 4);
157
+ };
158
+
159
+ const scrollerScroll = (el) => {
160
+ const container = el.target;
161
+ if (!container) return;
162
+ const scrollTop = container.scrollTop; // 已经滚动的距离
163
+ const scrollHeight = container.scrollHeight; // 内容总高度
164
+ const clientHeight = container.clientHeight; // 容器可视高度
165
+ if (scrollTop + clientHeight >= scrollHeight) {
166
+ load();
167
+ }
168
+ };
169
+ const updateScroller = () => {
170
+ const scrollerContainerEl = scrollerRef.value.getContainerEl();
171
+ scrollerContainerEl.addEventListener('scroll', scrollerScroll);
172
+ };
173
+
174
+ // -------------------- 日历 --------------------
175
+ const calendarRef = ref();
176
+ const selectedDate = ref();
177
+ const allDateList = computed<string[]>(() => [...new Set(list.value.map((v) => v.start_date))].sort((a, b) => (dayjs(a).isBefore(dayjs(b)) ? -1 : 1)));
178
+ const dateList = computed<string[]>(() =>
179
+ [...new Set(list.value.filter((v) => !v.isExpired && !v.is_delete).map((v) => v.start_date))].sort((a, b) => (dayjs(a).isBefore(dayjs(b)) ? -1 : 1)),
180
+ );
181
+ const getSelectedDate = () => {
182
+ const latest = dateList.value.find((v) => !dayjs(v).isBefore(dayjs(new Date()).format('YYYY-MM-DD')));
183
+ if (latest) {
184
+ selectedDate.value = latest;
185
+ } else if (!selectedDate.value) {
186
+ selectedDate.value = dayjs().format('YYYY-MM-DD');
187
+ }
188
+ calendarRef.value?.pickDay(dayjs(selectedDate.value));
189
+ selectedDate.value = dayjs(selectedDate.value).format('YYYY-MM-DD');
190
+ // 根据天再计算出需要展开的最近的会议
191
+ const needExpand = list.value.find((v) => v.start_date === selectedDate.value && !v.isExpired && !v.is_delete);
192
+ if (needExpand) {
193
+ getActivityDetail(needExpand.id);
194
+ expanded.value = [needExpand.id];
195
+ }
196
+ };
197
+
198
+ const cellClick = (e: PointerEvent & any, clickable: boolean) => {
199
+ if (!clickable || !e.target?.className.includes('date-cell-text')) {
200
+ e.stopPropagation();
201
+ e.preventDefault();
202
+ }
203
+ };
204
+
205
+ const changeMonth = (val: string) => {
206
+ if (!calendarRef.value) return;
207
+ currentPage.value = 1;
208
+ total.value = null;
209
+ expandList.value = [];
210
+ window.scrollTo({
211
+ top: 0,
212
+ behavior: 'smooth',
213
+ });
214
+ calendarRef.value.selectDate(val);
215
+ reloadAll.value = true;
216
+ nextTick(() => {
217
+ selectedDate.value = dayjs(calendarRef.value.selectedDay).format('YYYY-MM-DD');
218
+ getList();
219
+ });
220
+ };
221
+
222
+
223
+ // -------------------- 活动列表 --------------------
224
+ const activityList = computed(() => {
225
+ return list.value.reduce((prev, cur) => {
226
+ if (!prev.length) {
227
+ return [
228
+ {
229
+ start_date: cur.start_date,
230
+ list: [cur],
231
+ },
232
+ ];
233
+ } else {
234
+ const last = prev.at(-1);
235
+ if (last?.start_date === cur.start_date) {
236
+ last?.list.push(cur);
237
+ } else {
238
+ prev.push({
239
+ start_date: cur.start_date,
240
+ list: [cur],
241
+ });
242
+ }
243
+ return prev;
244
+ }
245
+ }, []);
246
+ });
247
+
248
+ // -------------------- 活动详情组件实例 --------------------
249
+ const detailRefs = ref({});
250
+ const getDetailRefs = (insRef, id) => {
251
+ if (insRef && id) {
252
+ detailRefs.value[id] = insRef;
253
+ }
254
+ };
255
+
256
+ // -------------------- 处理滚动事件 --------------------
257
+ const scrollerRef = ref();
258
+ const scrollToSelectedDate = (date: string) => {
259
+ const key = dayjs(date).format('YYYY-MM-DD');
260
+ const targetEle = document.querySelector(`#group-title-${ key }`);
261
+ if (targetEle) {
262
+ if (isPhone.value) {
263
+ window.scrollTo({
264
+ top: (targetEle.parentElement?.offsetTop || 0) - 52,
265
+ behavior: 'smooth',
266
+ });
267
+ } else {
268
+ scrollerRef.value?.scrollTo({
269
+ top: targetEle.parentElement?.offsetTop || 0,
270
+ behavior: 'smooth',
271
+ });
272
+ }
273
+ }
274
+ };
275
+
276
+ watch(
277
+ () => selectedDate.value,
278
+ () => {
279
+ scrollToSelectedDate(selectedDate.value);
280
+ },
281
+ );
282
+
283
+ // -------------------- 自动加载下一页 --------------------
284
+ const load = useDebounceFn(() => {
285
+ if (!canLoadMore.value) return;
286
+ if (isPhone.value) return;
287
+ bottomReached.value = true;
288
+ currentPage.value++;
289
+ getList();
290
+ }, 200);
291
+
292
+ // -------------------- 活动操作 --------------------
293
+ const dialogLoading = ref(false); // 弹窗按钮状态
294
+ const currentRow = ref<ActivityItemT | null>(null); // 当前活动详情
295
+ // 撤销审核
296
+ const revokeVisible = ref(false);
297
+ const handleRevokeItem = (val: ActivityItemT) => {
298
+ currentRow.value = val;
299
+ revokeVisible.value = true;
300
+ };
301
+ const confirm = () => {
302
+ if (!props.revokeActivityRequest) {
303
+ return;
304
+ }
305
+ dialogLoading.value = true;
306
+ props.revokeActivityRequest(currentRow.value?.id)
307
+ .then(() => {
308
+ message.success({
309
+ content: `“${ currentRow.value.title }”活动撤销审核成功`,
310
+ });
311
+ reloadAll.value = true;
312
+ getList();
313
+ })
314
+ .catch(() => {
315
+ message.danger({
316
+ content: `“${ currentRow.value.title }”活动撤销审核失败`,
317
+ });
318
+ })
319
+ .finally(() => {
320
+ revokeVisible.value = false;
321
+ dialogLoading.value = false;
322
+ });
323
+ };
324
+ const cancel = () => {
325
+ revokeVisible.value = false;
326
+ };
327
+ // 修改活动
328
+ const handleEditItem = (val: ActivityItemT) => {
329
+ emits('edit', val);
330
+
331
+ };
332
+ // 提交审核
333
+ const handleSubmitReviewItem = (val: ActivityItemT) => {
334
+ if (!props.editActivityRequest) {
335
+ return;
336
+ }
337
+ const {
338
+ title,
339
+ start_date,
340
+ end_date,
341
+ register_end_date,
342
+ activity_type,
343
+ synopsis,
344
+ register_url,
345
+ content_url,
346
+ address,
347
+ start,
348
+ end,
349
+ approver,
350
+ } = val;
351
+ let params = {
352
+ title,
353
+ start_date,
354
+ end_date,
355
+ register_end_date,
356
+ activity_type,
357
+ synopsis,
358
+ register_url,
359
+ content_url,
360
+ address,
361
+ start,
362
+ end,
363
+ approver,
364
+ is_publish: 'true',
365
+ } as ParamsItemT;
366
+ props.editActivityRequest(val.id, params)
367
+ .then(() => {
368
+ message.success({
369
+ content: `“${ val.title }”活动提交审核成功`,
370
+ });
371
+ reloadAll.value = true;
372
+ getList();
373
+ })
374
+ .catch(() => {
375
+ message.danger({
376
+ content: `“${ val.title }”活动提交审核失败`,
377
+ });
378
+ });
379
+ };
380
+ // 删除活动
381
+ const deleteVisible = ref(false);
382
+ const handleDeleteItem = (val: ActivityItemT) => {
383
+ currentRow.value = val;
384
+ deleteVisible.value = true;
385
+ };
386
+ const confirmDelete = () => {
387
+ if (!props.deleteActivityRequest) {
388
+ return;
389
+ }
390
+ dialogLoading.value = true;
391
+ props.deleteActivityRequest(currentRow.value?.id)
392
+ .then(() => {
393
+ message.success({
394
+ content: `“${ currentRow.value.title }”活动删除成功`,
395
+ });
396
+ reloadAll.value = true;
397
+ getList();
398
+ })
399
+ .catch(() => {
400
+ message.danger({
401
+ content: `“${ currentRow.value.title }”活动删除失败`,
402
+ });
403
+ })
404
+ .finally(() => {
405
+ deleteVisible.value = false;
406
+ dialogLoading.value = false;
407
+ });
408
+ };
409
+ const cancelDelete = () => {
410
+ deleteVisible.value = false;
411
+ };
412
+
413
+ // -------------------- 获取header高度 --------------------
414
+ const headerRef = ref();
415
+ const headerHeight = ref(0);
416
+ const getHeaderHeight = () => {
417
+ headerHeight.value = headerRef.value?.clientHeight || 0;
418
+ };
419
+
420
+ const handleScroll = useDebounceFn(() => {
421
+ if (!canLoadMore.value) return;
422
+ if (!isPhone.value) return;
423
+ const scrollPosition = window.scrollY || window.pageYOffset;
424
+ // 检测是否接近底部
425
+ const windowHeight = window.innerHeight;
426
+ const docHeight = document.documentElement.scrollHeight;
427
+ const distanceToBottom = docHeight - (scrollPosition + windowHeight);
428
+ // 当距离底部300px时开始加载
429
+ if (distanceToBottom <= 300 && !nextLoading.value) {
430
+ bottomReached.value = true;
431
+ // 加载下一页
432
+ currentPage.value++;
433
+ getList();
434
+ }
435
+ }, 200);
436
+
437
+ onMounted(() => {
438
+ getList();
439
+ // 添加滚动事件监听
440
+ window.addEventListener('scroll', handleScroll);
441
+ // 添加resize监听器
442
+ window.addEventListener('resize', handleScroll);
443
+ getHeaderHeight();
444
+ window.addEventListener('resize', getHeaderHeight);
445
+ });
446
+ onUnmounted(() => {
447
+ window.removeEventListener('scroll', handleScroll);
448
+ window.removeEventListener('resize', handleScroll);
449
+ window.removeEventListener('resize', getHeaderHeight);
450
+ const scrollerContainerEl = scrollerRef.value?.getContainerEl();
451
+ scrollerContainerEl?.removeEventListener('scroll', scrollerScroll);
452
+ });
453
+ </script>
454
+
455
+ <template>
456
+ <div class="o-my-activity-calendar">
457
+ <div class="activity-list">
458
+ <div v-if="isPhone" class="list-calendar-mb">
459
+ <span>{{ (selectedDate ? dayjs(new Date(selectedDate)) : dayjs()).format('YYYY MM月') }}</span>
460
+ <span>
461
+ <OIcon @click="changeMonth('prev-month')"><OIconArrowLeft /></OIcon>
462
+ <OIcon @click="changeMonth('next-month')"><OIconArrowRight /></OIcon>
463
+ </span>
464
+ </div>
465
+ <div class="left-calendar">
466
+ <ElCalendar ref="calendarRef">
467
+ <template #header>
468
+ <span>{{ (selectedDate ? dayjs(new Date(selectedDate)) : dayjs()).format('YYYY MM月') }}</span>
469
+ <div>
470
+ <OIcon @click="changeMonth('prev-month')">
471
+ <OIconArrowLeft />
472
+ </OIcon>
473
+ <OIcon @click="changeMonth('next-month')">
474
+ <OIconArrowRight />
475
+ </OIcon>
476
+ </div>
477
+ </template>
478
+ <template #date-cell="{ data }">
479
+ <div
480
+ @click="(e) => cellClick(e, allDateList.includes(data.day))"
481
+ :class="{
482
+ 'date-cell': true,
483
+ 'is-selected': data.isSelected,
484
+ 'is-today': formatDate(data.day) === formatDate(),
485
+ clickable: allDateList.includes(data.day),
486
+ approved: calcIfApproved(data.day),
487
+ }"
488
+ >
489
+ <div class="date-cell-text">
490
+ {{ Number(data.day.split('-')[2]) }}
491
+ </div>
492
+ </div>
493
+ </template>
494
+ </ElCalendar>
495
+ </div>
496
+ <div class="right-meeting">
497
+ <OScroller
498
+ v-if="list.length"
499
+ ref="scrollerRef"
500
+ @scrollend="load"
501
+ :style="{ '--header-height': headerHeight }"
502
+ show-type="hover"
503
+ class="scroller-container"
504
+ >
505
+ <div class="list-body">
506
+ <OCollapse v-model="expanded" :accordion="isPhone" @change="change">
507
+ <template v-for="(act, idx) in activityList" :key="act.start_date">
508
+ <div class="list-month-change prev-month" v-if="idx === 0" @click="changeMonth('prev-month')">
509
+ <OIcon>
510
+ <OIconChevronLeft />
511
+ </OIcon>
512
+ <span>上个月</span>
513
+ </div>
514
+ <div class="act-item" :class="idx === activityList.length - 1 && 'last-item'">
515
+ <div
516
+ :class="{
517
+ 'act-bar': true,
518
+ 'is-active': dayjs(selectedDate).format('YYYY-MM-DD') === act.start_date,
519
+ 'is-end': act.list.every((row) => row.isExpired),
520
+ approved: act.list.every((row) => row.status === 3 || row.status === 4),
521
+ }"
522
+ >
523
+ <div class="act-bar-line"></div>
524
+ <div class="act-bar-dot"></div>
525
+ </div>
526
+ <div
527
+ :class="{
528
+ 'group-title': true,
529
+ 'is-end': act.list.every((row) => row.isExpired),
530
+ }"
531
+ :id="`group-title-${dayjs(new Date(act.start_date)).format('YYYY-MM-DD')}`"
532
+ >
533
+ {{ dayjs(act.start_date).format('MM/DD') }}
534
+ </div>
535
+ <OCollapseItem
536
+ v-for="(row, rowIdx) in act.list"
537
+ :key="row.sub_id || row.id"
538
+ :value="row.sub_id || row.id"
539
+ :class="{
540
+ 'last-item': idx === activityList.length - 1 && rowIdx === act.list.length - 1,
541
+ }"
542
+ >
543
+ <template #title>
544
+ <div class="item-header-left">
545
+ <div class="act-icon"
546
+ :class="[`act-icon-${row.is_delete ? 'delete' : statusMap.get(row.status)?.id}`]">
547
+ <OIcon>
548
+ <IconEvent />
549
+ </OIcon>
550
+ </div>
551
+ <div class="header-info">
552
+ <div
553
+ :class="{
554
+ 'act-title': true,
555
+ 'is-delete': row.is_delete,
556
+ 'is-end': row.isExpired,
557
+ }"
558
+ >
559
+ <div class="title-text">{{ row.title }}</div>
560
+ <OTag
561
+ color="primary"
562
+ variant="outline"
563
+ :class="[`tag-${row.is_delete ? 'delete' : statusMap.get(row.status)?.id}`]">
564
+ {{
565
+ row.is_delete === 1 ? '已取消' : statusMap.get(row.status)?.text
566
+ }}
567
+ </OTag>
568
+ </div>
569
+ <div class="act-info">
570
+ <span class="date-range">{{ row.dateRange }}</span>
571
+ <ODivider direction="v"></ODivider>
572
+ <span>{{ acticityTypeMap.get(row.activity_type)?.label }}</span>
573
+ </div>
574
+ </div>
575
+ </div>
576
+ <div class="item-header-right" v-if="!row.is_delete">
577
+ <OButton
578
+ v-if="
579
+ row.status === 3 ||
580
+ row.status === 4 ||
581
+ (row.status === 2 && row.update_activity_id && new Date(row.register_end_date).getTime() > new Date().getTime())
582
+ "
583
+ color="primary"
584
+ :href="row.register_url"
585
+ target="_blank"
586
+ rel="noopener noreferrer"
587
+ >我要报名
588
+ </OButton
589
+ >
590
+ </div>
591
+ </template>
592
+ <div class="activity-detail">
593
+ <OMeetingDetail
594
+ :show="expanded.includes(row.id)"
595
+ :data="row"
596
+ :ref="(insRef) => getDetailRefs(insRef, row.id)"
597
+ />
598
+ <div class="activity-btn" v-if="!row.isExpired && !row.is_delete">
599
+ <OButton v-if="row.status === 2" variant="text" @click="handleRevokeItem(row)">撤销审核
600
+ </OButton>
601
+ <OButton v-if="row.status === 1 || row.status === 3 || row.status === 4 || row.status === 7"
602
+ variant="text" @click="handleEditItem(row)"
603
+ >修改活动
604
+ </OButton
605
+ >
606
+ <OButton v-if="row.status === 1 || row.status === 7" variant="text"
607
+ @click="handleDeleteItem(row)">删除活动
608
+ </OButton>
609
+ <OButton v-if="row.status === 1 || row.status === 7" variant="text"
610
+ @click="handleSubmitReviewItem(row)">提交审核
611
+ </OButton>
612
+ </div>
613
+ </div>
614
+ </OCollapseItem>
615
+ <div class="height-placeholder"></div>
616
+ </div>
617
+ <template v-if="idx === activityList.length - 1">
618
+ <div class="load-text" v-if="bottomReached">加载中···</div>
619
+ <div class="list-month-change next-month" @click="changeMonth('next-month')">
620
+ <OIcon>
621
+ <OIconChevronRight />
622
+ </OIcon>
623
+ <span>下个月</span>
624
+ </div>
625
+ </template>
626
+ </template>
627
+ </OCollapse>
628
+ </div>
629
+ </OScroller>
630
+ <slot v-else name="empty">
631
+ </slot>
632
+ </div>
633
+ </div>
634
+ </div>
635
+ <!-- 撤销审核弹窗 -->
636
+ <ODialog v-model:visible="revokeVisible" main-class="handle-dialog-active">
637
+ <template #header>撤销审核</template>
638
+ <div class="dialog-content">是否确认要撤销“{{ currentRow.title }}”活动?撤销审核后活动将变成草稿状态。</div>
639
+ <template #footer>
640
+ <div class="dialog-footer">
641
+ <OButton color="primary" variant="outline" size="large" round="pill" @click="confirm" :loading="dialogLoading">
642
+ 确定
643
+ </OButton>
644
+ <OButton color="primary" variant="solid" size="large" round="pill" @click="cancel">取消</OButton>
645
+ </div>
646
+ </template>
647
+ </ODialog>
648
+ <!-- 删除活动弹窗 -->
649
+ <ODialog v-model:visible="deleteVisible" main-class="handle-dialog-active">
650
+ <template #header>删除活动</template>
651
+ <div class="dialog-content">是否确认删除“{{ currentRow.title }}”活动?删除后记录将不再我的个人中心呈现。</div>
652
+ <template #footer>
653
+ <div class="dialog-footer">
654
+ <OButton color="primary" variant="outline" size="large" round="pill" @click="confirmDelete"
655
+ :loading="dialogLoading">确定
656
+ </OButton>
657
+ <OButton color="primary" variant="solid" size="large" round="pill" @click="cancelDelete">取消</OButton>
658
+ </div>
659
+ </template>
660
+ </ODialog>
661
+ </template>
662
+
663
+ <style lang="scss">
664
+
665
+ .o-my-activity-calendar {
666
+ height: 100%;
667
+ display: flex;
668
+ flex-direction: column;
669
+
670
+ .header {
671
+ display: flex;
672
+ align-items: center;
673
+ justify-content: space-between;
674
+ }
675
+
676
+ .title {
677
+ color: var(--o-color-info1);
678
+ font-weight: 500;
679
+ @include h2;
680
+ }
681
+
682
+ .desc {
683
+ color: var(--o-color-info2);
684
+ margin-top: 12px;
685
+ @include tip1;
686
+ }
687
+
688
+ .activity-list {
689
+ display: flex;
690
+ flex-wrap: nowrap;
691
+ height: calc(100% - var(--o-gap-6) * 5);
692
+ --table-bg: rgba(243, 246, 250);
693
+ --cell-bg: rgba(235, 241, 250);
694
+ --cell-bg-hover: rgba(213, 227, 253);
695
+ @include respond-to('<=pad_v') {
696
+ flex-direction: column;
697
+ }
698
+
699
+ .o-loading {
700
+ .o-layer-mask {
701
+ background-color: transparent;
702
+ }
703
+
704
+ .o-loading-icon {
705
+ color: var(--layer-mask);
706
+ }
707
+ }
708
+ }
709
+
710
+ .list-calendar-mb {
711
+ align-items: center;
712
+ justify-content: space-between;
713
+ padding: 0 var(--grid--layout-padding);
714
+
715
+ span:first-child {
716
+ font-weight: 500;
717
+ @include display2;
718
+ }
719
+
720
+ span:last-child {
721
+ display: flex;
722
+ align-items: center;
723
+ }
724
+
725
+ .o-icon {
726
+ font-size: 24px;
727
+ cursor: pointer;
728
+
729
+ &:last-child {
730
+ margin-left: 24px;
731
+ }
732
+ }
733
+
734
+ @include respond-to('phone') {
735
+ padding-top: var(--o-gap-7);
736
+ background-color: var(--o-color-ubmc-bg);
737
+ padding-bottom: var(--o-gap-4);
738
+ --phone-padding-top: calc(28px + var(--o-gap-7) + var(--o-gap-4));
739
+ display: flex;
740
+ position: fixed;
741
+ height: var(--phone-padding-top);
742
+ z-index: 1;
743
+ top: var(--layout-header-height);
744
+ left: 0;
745
+ right: 0;
746
+ }
747
+ }
748
+
749
+ .left-calendar {
750
+ width: 336px;
751
+ flex-shrink: 0;
752
+
753
+ .el-calendar {
754
+ min-height: 460px;
755
+ height: 100%;
756
+ background-color: var(--table-bg);
757
+ border-radius: var(--o-radius-xs);
758
+
759
+ .el-calendar__header {
760
+ border-bottom: 1px solid var(--o-color-control4);
761
+
762
+ & > span {
763
+ font-weight: 500;
764
+ color: var(--o-color-info1);
765
+ @include h1;
766
+ }
767
+
768
+ & > div {
769
+ display: flex;
770
+ align-items: center;
771
+ gap: var(--o-gap-5);
772
+
773
+ .o-icon {
774
+ font-size: 24px;
775
+ cursor: pointer;
776
+
777
+ &:hover {
778
+ color: var(--o-color-primary1);
779
+ }
780
+ }
781
+ }
782
+ }
783
+
784
+ .el-calendar__body {
785
+ .el-calendar-table {
786
+ th {
787
+ text-align: center;
788
+ }
789
+
790
+ td {
791
+ background-color: var(--table-bg);
792
+ border: none;
793
+ text-align: center;
794
+ transition: none;
795
+
796
+ .el-calendar-day {
797
+ padding: 0;
798
+ height: fit-content;
799
+ }
800
+
801
+ div {
802
+ cursor: default !important;
803
+ }
804
+
805
+ &:hover {
806
+ .el-calendar-day {
807
+ background-color: transparent;
808
+ }
809
+ }
810
+ }
811
+
812
+ .date-cell {
813
+ height: 56px;
814
+ width: 42px;
815
+ padding: var(--o-gap-1);
816
+ position: relative;
817
+ cursor: default !important;
818
+
819
+ .date-cell-text {
820
+ font-size: 14px;
821
+ line-height: 36px;
822
+ border-radius: var(--o-radius-xs);
823
+ background-color: var(--cell-bg);
824
+ }
825
+
826
+ .date-cell-text {
827
+ cursor: not-allowed !important;
828
+ }
829
+
830
+ &.clickable {
831
+ .date-cell-text {
832
+ cursor: pointer !important;
833
+ }
834
+
835
+ &:not(.is-selected) {
836
+ .date-cell-text:hover {
837
+ background-color: var(--cell-bg-hover);
838
+ }
839
+ }
840
+ }
841
+
842
+ &::after {
843
+ content: '';
844
+ position: absolute;
845
+ bottom: 2px;
846
+ left: 50%;
847
+ transform: translateX(-50%);
848
+ width: 8px;
849
+ height: 8px;
850
+ border-radius: 50%;
851
+ }
852
+
853
+ &.is-today {
854
+ .date-cell-text {
855
+ color: #000;
856
+ background-color: var(--cell-bg-hover);
857
+ }
858
+ }
859
+
860
+ &.is-selected {
861
+ .date-cell-text {
862
+ color: #fff;
863
+ background-color: var(--o-color-primary1);
864
+ }
865
+ }
866
+
867
+ &.clickable {
868
+ &::after {
869
+ background-color: rgb(var(--o-mixedgray-6));
870
+ }
871
+
872
+ &.approved::after {
873
+ background-color: rgba(255, 165, 0, 1);
874
+ }
875
+ }
876
+ }
877
+
878
+ .is-today {
879
+ color: inherit;
880
+ }
881
+ }
882
+ }
883
+ }
884
+
885
+ @include respond-to('pad_h') {
886
+ width: 240px;
887
+ .el-calendar {
888
+ .el-calendar__body {
889
+ padding-left: 12px;
890
+ padding-right: 12px;
891
+
892
+ .el-calendar-table .date-cell {
893
+ height: 40px;
894
+ width: 28px;
895
+
896
+ .date-cell-text {
897
+ line-height: 24px;
898
+ @include tip2;
899
+ }
900
+ }
901
+ }
902
+ }
903
+ }
904
+ @include respond-to('pad_v') {
905
+ width: 100%;
906
+ }
907
+ @include respond-to('phone') {
908
+ display: none;
909
+ }
910
+ }
911
+
912
+ .right-meeting {
913
+ flex-grow: 1;
914
+ background-color: var(--o-color-fill2);
915
+ margin-left: 16px;
916
+ @include respond-to('phone') {
917
+ margin-top: calc(24px + var(--o-gap-7));
918
+ margin-left: 0;
919
+ }
920
+
921
+ .o-scroller {
922
+ .o-scrollbar-rail {
923
+ right: -16px;
924
+ }
925
+ }
926
+
927
+ .scroller-container {
928
+ height: 100%;
929
+ max-height: calc(var(--layout-left-height) - 4 * var(--o-gap-5) - var(--header-height) * 1px);
930
+ @include respond-to('phone') {
931
+ max-height: fit-content;
932
+ }
933
+
934
+ .act-item {
935
+ padding-left: var(--o-gap-5);
936
+ position: relative;
937
+
938
+ &.last-item {
939
+ flex-grow: 1;
940
+ }
941
+
942
+ @include respond-to('phone') {
943
+ padding-left: var(--o-gap-2);
944
+ }
945
+
946
+ .act-bar {
947
+ position: absolute;
948
+ left: 0;
949
+ width: 16px;
950
+ top: 0;
951
+ bottom: 0;
952
+ overflow: hidden;
953
+
954
+ --active-color: rgb(222, 222, 227);
955
+
956
+ &::before {
957
+ content: '';
958
+ width: 2px;
959
+ position: absolute;
960
+ top: 0;
961
+ bottom: 0;
962
+ left: 50%;
963
+ transform: translateX(-50%);
964
+ background-color: var(--o-color-control4);
965
+ }
966
+
967
+ .act-bar-dot {
968
+ width: 16px;
969
+ height: 26px;
970
+ position: relative;
971
+ @include respond-to('laptop') {
972
+ height: 24px;
973
+ }
974
+ @include respond-to('pad_h') {
975
+ height: 22px;
976
+ }
977
+ @include respond-to('<=pad_v') {
978
+ height: 22px;
979
+ }
980
+
981
+ &::before,
982
+ &::after {
983
+ content: '';
984
+ border-radius: 50%;
985
+ position: absolute;
986
+ top: 50%;
987
+ left: 50%;
988
+ transform: translateY(-50%) translateX(-50%);
989
+ }
990
+
991
+ &::before {
992
+ width: 16px;
993
+ height: 16px;
994
+ background-color: transparent;
995
+ }
996
+
997
+ &::after {
998
+ width: 8px;
999
+ height: 8px;
1000
+ background-color: var(--active-color);
1001
+ }
1002
+ }
1003
+
1004
+ &.is-active {
1005
+ .act-bar-dot {
1006
+ &::before {
1007
+ background-color: var(--active-color);
1008
+ }
1009
+
1010
+ &::after {
1011
+ background-color: var(--o-color-fill2);
1012
+ }
1013
+ }
1014
+ }
1015
+
1016
+ &.is-end {
1017
+ --active-color: rgb(222, 222, 227);
1018
+ }
1019
+ }
1020
+
1021
+ .approved {
1022
+ --active-color: rgba(255, 165, 0, 1);
1023
+ }
1024
+
1025
+ .group-title {
1026
+ font-weight: 500;
1027
+ margin-bottom: var(--o-gap-2);
1028
+ color: var(--o-color-info1);
1029
+ @include text2;
1030
+ @include respond-to('phone') {
1031
+ padding-left: var(--o-gap-4);
1032
+ }
1033
+
1034
+ &.is-end {
1035
+ color: var(--o-color-info3);
1036
+ }
1037
+ }
1038
+ }
1039
+ }
1040
+ }
1041
+
1042
+ .list-body {
1043
+ height: 100%;
1044
+
1045
+ @include respond-to('phone') {
1046
+ height: fit-content;
1047
+ padding: var(--o-gap-4) !important;
1048
+ }
1049
+
1050
+ .list-month-change {
1051
+ flex-shrink: 0;
1052
+ display: flex;
1053
+ align-items: center;
1054
+ gap: var(--o-gap-5);
1055
+ cursor: pointer;
1056
+ --btn-color: var(--o-color-primary1);
1057
+ @include hover {
1058
+ --btn-color: var(--o-color-primary2);
1059
+ }
1060
+ @include respond-to('phone') {
1061
+ display: none;
1062
+ }
1063
+
1064
+ &.prev-month {
1065
+ margin-bottom: var(--o-gap-6);
1066
+ }
1067
+
1068
+ &.next-month {
1069
+ margin-top: var(--o-gap-6);
1070
+ padding-bottom: 32px;
1071
+ }
1072
+
1073
+ .o-icon {
1074
+ font-size: 24px;
1075
+ color: var(--btn-color);
1076
+ }
1077
+
1078
+ span {
1079
+ color: var(--btn-color);
1080
+ @include text1;
1081
+ }
1082
+ }
1083
+
1084
+ .o-collapse {
1085
+ padding: 0;
1086
+ border-radius: 0;
1087
+ height: 100%;
1088
+ display: flex;
1089
+ flex-direction: column;
1090
+
1091
+ .o-collapse-item-expanded + .o-collapse-item-expanded {
1092
+ margin-top: var(--o-gap-4);
1093
+ }
1094
+
1095
+ .height-placeholder {
1096
+ height: 0;
1097
+ transition: margin var(--o-easing-standard) var(--o-duration-s);
1098
+ }
1099
+
1100
+ .o-collapse-item-expanded + .height-placeholder {
1101
+ height: var(--o-gap-4);
1102
+ }
1103
+
1104
+ .o-collapse-item {
1105
+ padding: var(--o-gap-4) var(--o-gap-5);
1106
+ border-top: none;
1107
+ border-radius: var(--o-radius-xs);
1108
+ transition: margin var(--o-easing-standard) var(--o-duration-s);
1109
+
1110
+ &.o-collapse-item-expanded {
1111
+ background-color: var(--table-bg);
1112
+ }
1113
+
1114
+ @include respond-to('<=pad_v') {
1115
+ padding: 8px 12px;
1116
+ }
1117
+ }
1118
+
1119
+ .o-collapse-item-header {
1120
+ border-bottom: 1px solid var(--o-color-control4);
1121
+ padding-top: 0;
1122
+ padding-bottom: var(--o-gap-4);
1123
+ display: flex;
1124
+ align-items: center;
1125
+ gap: var(--o-gap-4);
1126
+
1127
+ .o-collapse-item-icon {
1128
+ flex-shrink: 0;
1129
+ }
1130
+
1131
+ .o-collapse-item-title {
1132
+ flex: 1;
1133
+ width: 0;
1134
+ display: flex;
1135
+ align-items: center;
1136
+ justify-content: space-between;
1137
+ flex-wrap: nowrap;
1138
+
1139
+ .item-header-left {
1140
+ display: flex;
1141
+ align-items: flex-start;
1142
+ gap: var(--o-gap-3);
1143
+ flex: 1;
1144
+ width: 0;
1145
+
1146
+ .act-icon {
1147
+ width: 24px;
1148
+ height: 24px;
1149
+ border-radius: 50%;
1150
+ background-color: rgba(var(--o-cyan-6));
1151
+ color: #fff;
1152
+ display: flex;
1153
+ align-items: center;
1154
+ justify-content: center;
1155
+ flex-shrink: 0;
1156
+ @include respond-to('phone') {
1157
+ width: 20px;
1158
+ height: 20px;
1159
+ }
1160
+
1161
+ svg path {
1162
+ fill: currentColor
1163
+ }
1164
+ }
1165
+
1166
+ .act-icon-registration,
1167
+ .act-icon-in-progress {
1168
+ background-color: rgba(255, 165, 0, 1);
1169
+ }
1170
+
1171
+ .act-icon-delete {
1172
+ background-color: rgba(222, 222, 227, 1);
1173
+ }
1174
+
1175
+ .header-info {
1176
+ width: calc(100% - var(--o-gap-3) - 24px);
1177
+
1178
+ .act-title {
1179
+ font-weight: 500;
1180
+ display: flex;
1181
+ align-items: center;
1182
+ @include text2;
1183
+
1184
+ &.is-delete,
1185
+ &.is-end {
1186
+ color: var(--o-color-info3);
1187
+ }
1188
+
1189
+ .title-text {
1190
+ flex: 0 1 auto;
1191
+ min-width: 0;
1192
+ max-width: 100%;
1193
+ @include text-truncate(1);
1194
+ }
1195
+
1196
+ .o-tag {
1197
+ margin-left: 8px;
1198
+ --tag-radius: var(--o-radius-xs);
1199
+ --tag-bg-color: var(--o-color-primary1);
1200
+ --tag-color: #fff;
1201
+ --tag-bd-color: transparent;
1202
+ --tag-padding: 2px 8px;
1203
+ }
1204
+
1205
+ .tag-draft,
1206
+ .tag-ended,
1207
+ .tag-delete {
1208
+ --tag-color: var(--o-color-info3);
1209
+ --tag-bg-color: rgba(222, 222, 227, 1);
1210
+ }
1211
+
1212
+ .tag-registration,
1213
+ .tag-in-progress {
1214
+ --tag-color: rgba(36, 171, 54, 1);
1215
+ --tag-bg-color: rgba(36, 171, 54, 0.1);
1216
+ }
1217
+
1218
+ .tag-reject {
1219
+ --tag-color: rgba(294, 118, 17, 1);
1220
+ --tag-bg-color: rgba(294, 118, 17, 0.1);
1221
+ }
1222
+ }
1223
+
1224
+ .act-info {
1225
+ color: var(--o-color-info3);
1226
+ display: flex;
1227
+ align-items: center;
1228
+ @include tip1;
1229
+
1230
+ .date-range {
1231
+ flex: 0 1 auto;
1232
+ min-width: 0;
1233
+ @include text-truncate(1);
1234
+ }
1235
+ }
1236
+ }
1237
+ }
1238
+
1239
+ .item-header-right {
1240
+ flex-shrink: 0;
1241
+ display: flex;
1242
+ align-items: center;
1243
+ padding-left: var(--o-gap-4);
1244
+ }
1245
+ }
1246
+
1247
+ @include respond-to('phone') {
1248
+ .o-collapse-item-icon {
1249
+ align-self: flex-end;
1250
+ position: relative;
1251
+ bottom: 4px;
1252
+ }
1253
+ .o-collapse-item-title {
1254
+ flex-direction: column;
1255
+ align-items: flex-start;
1256
+
1257
+ .item-header-left {
1258
+ flex-grow: 1;
1259
+ width: 100%;
1260
+ align-self: stretch;
1261
+ flex-shrink: 0;
1262
+ }
1263
+
1264
+ .item-header-right {
1265
+ padding-left: 24px;
1266
+ margin-top: 8px;
1267
+ }
1268
+ }
1269
+ }
1270
+ }
1271
+
1272
+ .o-collapse-item-body {
1273
+ margin-bottom: 0;
1274
+ padding: var(--o-gap-4) 0 0;
1275
+
1276
+ .activity-detail {
1277
+ padding-left: calc(var(--o-gap-5) + var(--o-gap-3));
1278
+ @include respond-to('phone') {
1279
+ padding-left: 0;
1280
+ }
1281
+
1282
+ .activity-btn {
1283
+ border-top: 1px solid var(--o-color-control4);
1284
+ margin-top: var(--o-gap-5);
1285
+ padding-top: var(--o-gap-4);
1286
+ display: flex;
1287
+ align-items: center;
1288
+ justify-content: flex-end;
1289
+
1290
+ .o-btn + .o-btn {
1291
+ margin-left: 16px;
1292
+ }
1293
+ }
1294
+ }
1295
+ }
1296
+
1297
+ .o-btn-text {
1298
+ @include hover {
1299
+ background-color: transparent;
1300
+ color: var(--o-color-primary1);
1301
+ }
1302
+ }
1303
+
1304
+ .o-btn.o-btn-text {
1305
+ padding-left: 0 !important;
1306
+ padding-right: 0 !important;
1307
+ min-width: auto;
1308
+ }
1309
+ }
1310
+
1311
+ .load-text {
1312
+ text-align: center;
1313
+ color: var(--o-color-info3);
1314
+ @include tip1;
1315
+ }
1316
+ }
1317
+ }
1318
+
1319
+ </style>
1320
+
1321
+ <style lang="scss">
1322
+ .handle-dialog-active {
1323
+ width: 450px;
1324
+ --dlg-radius: 16px;
1325
+
1326
+ .o-dlg-header {
1327
+ margin-bottom: var(--o-gap-5);
1328
+ }
1329
+
1330
+ .o-dlg-body-content {
1331
+ display: flex;
1332
+ justify-content: center;
1333
+ }
1334
+
1335
+ .dialog-footer {
1336
+ display: flex;
1337
+ justify-content: center;
1338
+ margin-top: var(--o-gap-4);
1339
+ column-gap: var(--o-gap-4);
1340
+ }
1341
+ }
1342
+ </style>