@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,1035 @@
1
+ <script setup lang="ts">
2
+ import { ElDatePicker, ElInputNumber, ElTimeSelect } from 'element-plus';
3
+ import { computed, onMounted, ref, watch } from 'vue';
4
+ import {
5
+ OButton,
6
+ OForm,
7
+ OFormItem,
8
+ OIcon,
9
+ OInput,
10
+ OOption,
11
+ OPopover,
12
+ ORadio,
13
+ ORadioGroup,
14
+ OSelect,
15
+ OSwitch,
16
+ OTextarea,
17
+ OIconTime,
18
+ useMessage,
19
+ } from '@opensig/opendesign';
20
+ import IconHelp from '~icons/meeting/icon-help.svg';
21
+ import IconTip from '~icons/meeting/icon-tip.svg';
22
+ import type { MeetingItemT, MeetingPostT, OptionItemT } from './types';
23
+ import dayjs from 'dayjs';
24
+ import { findLabelFromOptions, formatDateNumber, getDateNumber } from './utils';
25
+ import {
26
+ EMAIL_REGEX,
27
+ INTERVAL_DAY,
28
+ INTERVAL_MONTH,
29
+ CYCLE_TYPE_OPTIONS0,
30
+ INTERVAL_WEEK,
31
+ INTERVAL_WEEK_OPTIONS,
32
+ } from './config';
33
+ import OMeetingCalendarSelector from './components/OMeetingCalendarSelector.vue';
34
+ import { useScreen } from '@opendesign-plus/composables';
35
+ import { useI18n } from '@/i18n';
36
+
37
+ const { t, locale } = useI18n();
38
+
39
+ const props = withDefaults(defineProps<{
40
+ data?: MeetingItemT;
41
+ isSub?: boolean;
42
+ isEdit?: boolean;
43
+ subId?: string;
44
+ createMeetingRequest: any,
45
+ editMeetingRequest: any;
46
+ editSubMeetingRequest: any;
47
+ getPlatformsRequest: any;
48
+ getGroupsRequest: any;
49
+ showBtns?: boolean
50
+ }>(), {
51
+ isSub: false,
52
+ isEdit: false,
53
+ showBtns: true,
54
+ });
55
+ const message = useMessage();
56
+
57
+ const cycleTypeOptions = ref(CYCLE_TYPE_OPTIONS0);
58
+
59
+ const weekOptions = ref(INTERVAL_WEEK_OPTIONS);
60
+
61
+ const intervalTypeMax = computed(() => {
62
+ return findLabelFromOptions(form.value.cycle_type, cycleTypeOptions.value, 'max');
63
+ });
64
+ const initForm = {
65
+ is_record: false,
66
+ agenda: '',
67
+ email_list: '',
68
+ platform: '',
69
+ topic: '',
70
+ group_name: '',
71
+ etherpad: '',
72
+ date: '',
73
+ date_range: [],
74
+ start: '',
75
+ end: '',
76
+ time: '',
77
+ is_cycle: false,
78
+ cycle_interval: 1,
79
+ cycle_type: INTERVAL_DAY,
80
+ cycle_point: [],
81
+ }
82
+ const form = ref<MeetingPostT>(Object.assign({}, initForm) as unknown as MeetingPostT); // 表单数据
83
+ const formRef = ref(null); // 表单实例
84
+ const loading = ref(false); // 提交状态
85
+ // 表单校验规则
86
+ const rules = ref({
87
+ topic: [
88
+ { required: true, message: t('meeting.enterMeetingName') },
89
+ {
90
+ validator: (value: string) => {
91
+ if (value.length > 128) {
92
+ return {
93
+ type: 'danger',
94
+ message: t('meeting.meetingNameTooLong'),
95
+ };
96
+ }
97
+ },
98
+ },
99
+ ],
100
+ agenda: [
101
+ {
102
+ validator: (value: string) => {
103
+ if (value.length > 4096) {
104
+ return {
105
+ type: 'danger',
106
+ message: t('meeting.meetingAgendaTooLong'),
107
+ };
108
+ }
109
+ },
110
+ },
111
+ ],
112
+ group_name: [{ required: true, message: t('meeting.selectSig') }],
113
+ etherpad: [{ required: true, message: t('meeting.enterEtherpad') }],
114
+ date: [{ required: true, message: t('meeting.selectDate') }],
115
+ time: [
116
+ {
117
+ validator: (value: string) => {
118
+ const { is_cycle, cycle_type, cycle_interval, cycle_point, date, date_range } = form.value;
119
+ if (is_cycle) {
120
+ const msg = {
121
+ type: 'danger',
122
+ message: t('meeting.finishMeetingConfig'),
123
+ };
124
+ if (cycle_type === INTERVAL_DAY) {
125
+ if (!cycle_interval) return msg;
126
+ }
127
+ if (cycle_type === INTERVAL_WEEK) {
128
+ if (!cycle_interval || !cycle_point?.length) return msg;
129
+ }
130
+ if (cycle_type === INTERVAL_MONTH) {
131
+ if (!cycle_interval || !cycle_point?.length) return msg;
132
+ }
133
+ if (!date_range?.length) {
134
+ return {
135
+ type: 'danger',
136
+ message: t('meeting.selectMeetingDate'),
137
+ };
138
+ }
139
+ const NONE_MSG = t('meeting.invalidMeetingDuration');
140
+ let start = date_range[0];
141
+ const end = date_range[1];
142
+ if (cycle_type === INTERVAL_WEEK) {
143
+ const weeks = new Set();
144
+ while (!dayjs(start).isAfter(dayjs(end))) {
145
+ weeks.add(dayjs(start).day());
146
+ start = dayjs(start).add(1, 'day');
147
+ }
148
+ if (cycle_point.every((point) => !weeks.has(point))) {
149
+ return {
150
+ type: 'danger',
151
+ message: NONE_MSG,
152
+ };
153
+ }
154
+ }
155
+ if (cycle_type === INTERVAL_MONTH) {
156
+ const days = new Set();
157
+ while (!dayjs(start).isAfter(dayjs(end))) {
158
+ days.add(dayjs(start).date());
159
+ start = dayjs(start).add(1, 'day');
160
+ }
161
+ if (cycle_point.every((point) => !days.has(point))) {
162
+ return {
163
+ type: 'danger',
164
+ message: NONE_MSG,
165
+ };
166
+ }
167
+ }
168
+ } else {
169
+ if (!date) {
170
+ return {
171
+ type: 'danger',
172
+ message: t('meeting.selectMeetingDate'),
173
+ };
174
+ }
175
+ }
176
+ if (!value?.trim()?.length) {
177
+ return {
178
+ type: 'danger',
179
+ message: t('meeting.selectMeetingTime'),
180
+ };
181
+ }
182
+ const arr = value.split('-').map((v) => v.split(':').map(Number));
183
+ if (arr[0][0] > arr[1][0] || (arr[0][0] === arr[1][0] && arr[0][1] >= arr[1][1])) {
184
+ return {
185
+ type: 'danger',
186
+ message: t('meeting.endTimeAfterStartTime'),
187
+ };
188
+ }
189
+ if (!form.value.is_cycle && form.value.date && form.value.start) {
190
+ const start = dayjs(`${ form.value.date } ${ form.value.start }`);
191
+ if (new Date(start).getTime() < new Date().getTime()) {
192
+ return {
193
+ type: 'danger',
194
+ message: t('meeting.startTimeBeforeEndTime'),
195
+ };
196
+ }
197
+ }
198
+ },
199
+ triggers: ['blur', 'change'],
200
+ },
201
+ ],
202
+ platform: [{ required: true, message: t('meeting.selectPlatform') }],
203
+ email_list: [
204
+ {
205
+ validator: (value: string) => {
206
+ if (props.isEdit) {
207
+ return {};
208
+ }
209
+ const str = value.replaceAll(' ', '') || '';
210
+ if (str.length) {
211
+ if (str.length > 1020) {
212
+ return {
213
+ type: 'danger',
214
+ message: t('meeting.emailTooLong'),
215
+ };
216
+ }
217
+ const list = str.split(';') || [];
218
+ if (list.some((v) => !EMAIL_REGEX.test(v))) {
219
+ return {
220
+ type: 'danger',
221
+ message: t('meeting.emailInvalid'),
222
+ };
223
+ }
224
+ if (list.some((v) => v.length > 50)) {
225
+ return {
226
+ type: 'danger',
227
+ message: t('meeting.singleEmailTooLong'),
228
+ };
229
+ }
230
+ if (list.length > 20) {
231
+ return {
232
+ type: 'danger',
233
+ message: t('meeting.emailCountTooLong'),
234
+ };
235
+ }
236
+ }
237
+ },
238
+ triggers: ['blur', 'change'],
239
+ },
240
+ ],
241
+ });
242
+
243
+ const sigOptions = ref<OptionItemT[]>([]); // sig组选项列表
244
+ const getSigOptions = async () => {
245
+ if (!props.getGroupsRequest) {
246
+ return;
247
+ }
248
+ const res = await props.getGroupsRequest();
249
+ sigOptions.value = res.map((v) => ({ label: v.group_name, value: v.group_name, ...v }));
250
+ if (props.data) {
251
+ changeSig(form.value.group_name);
252
+ }
253
+ };
254
+ // 会议平台选项列表
255
+ const typeOptions = ref<OptionItemT[]>([]);
256
+ const getPlatformOptions = async () => {
257
+ if (!props.getPlatformsRequest) {
258
+ return;
259
+ }
260
+ const res = await props.getPlatformsRequest();
261
+ typeOptions.value = res.map((v) => ({ label: v, value: v }));
262
+ if (!props.data) {
263
+ form.value.platform = typeOptions.value[0].value;
264
+ }
265
+ };
266
+
267
+ const emits = defineEmits(['confirm', 'cancel']);
268
+ watch(
269
+ () => props.data,
270
+ (data) => {
271
+ if (data) {
272
+ const sub = data?.cycle_sub?.find((v) => v.sub_id === props.subId) || {};
273
+ const { mid, date, start, end, sub_id } = sub;
274
+ Object.assign(
275
+ form.value,
276
+ data,
277
+ props.isSub
278
+ ? {
279
+ is_cycle: false,
280
+ mid,
281
+ date,
282
+ start,
283
+ end,
284
+ sub_id,
285
+ }
286
+ : {},
287
+ );
288
+ } else {
289
+ const today = dayjs().format('YYYY-MM-DD');
290
+ const now = dayjs().format('HH:mm');
291
+
292
+ let start = '';
293
+ let end = '';
294
+ const nowNum = getDateNumber(now);
295
+ if (nowNum <= getDateNumber('08:00')) {
296
+ start = '08:00';
297
+ end = '09:00';
298
+ } else if (getDateNumber('22:15') <= nowNum) {
299
+ start = '08:00';
300
+ end = '09:00';
301
+ } else {
302
+ let [h, m] = now.split(':').map(Number);
303
+ if (m >= 45) {
304
+ h++;
305
+ m = 0;
306
+ } else {
307
+ m = (Math.floor(m / 15) + 1) * 15;
308
+ }
309
+ start = formatDateNumber(h * 60 + m).slice(3);
310
+ end = formatDateNumber(h * 60 + m + 60).slice(3);
311
+ }
312
+ const date_range = [dayjs().format('YYYY-MM-DD'), dayjs().add(1, 'month').format('YYYY-MM-DD')];
313
+
314
+ Object.assign(form.value, {
315
+ date: today,
316
+ start,
317
+ end,
318
+ time: `${ start }-${ end }`,
319
+ date_range,
320
+ });
321
+ }
322
+ },
323
+ { immediate: true, deep: true },
324
+ );
325
+ const cancel = () => {
326
+ form.value = Object.assign({}, initForm);
327
+ formRef.value.clearValidate();
328
+ formRef.value.resetFields();
329
+ emits('cancel');
330
+ };
331
+
332
+ const changeIntervalType = () => {
333
+ form.value.cycle_point = [];
334
+ form.value.cycle_interval = 1;
335
+ };
336
+
337
+ const changeIsCycle = () => {
338
+ form.value.platform = 'WELINK';
339
+ };
340
+
341
+ const { lePadV } = useScreen();
342
+ const confirm = async () => {
343
+ let type = props.isEdit ? t('meeting.editSuccess') : t('meeting.booSuccess');
344
+ try {
345
+ loading.value = true;
346
+ const valid = await formRef.value.validate();
347
+ if (valid.some((v) => !!v)) {
348
+ return;
349
+ }
350
+ const {
351
+ topic,
352
+ etherpad,
353
+ group_name,
354
+ platform,
355
+ date,
356
+ start,
357
+ end,
358
+ agenda,
359
+ is_record,
360
+ is_cycle,
361
+ date_range,
362
+ cycle_type,
363
+ cycle_interval,
364
+ cycle_point,
365
+ } =
366
+ form.value;
367
+ let params = {
368
+ topic,
369
+ etherpad,
370
+ agenda,
371
+ is_record,
372
+ group_name,
373
+ platform,
374
+ is_cycle,
375
+ } as MeetingPostT;
376
+ if (is_cycle) {
377
+ params = {
378
+ ...params,
379
+ cycle_interval,
380
+ cycle_type,
381
+ cycle_start_date: date_range?.[0] || '',
382
+ cycle_end_date: date_range?.[1] || '',
383
+ cycle_start: start,
384
+ cycle_end: end,
385
+ };
386
+ if (cycle_type !== INTERVAL_DAY) {
387
+ params = {
388
+ ...params,
389
+ cycle_point: cycle_point.join(','),
390
+ };
391
+ }
392
+ } else {
393
+ params = {
394
+ ...params,
395
+ date: date?.split(' ')[0] || '',
396
+ start,
397
+ end,
398
+ };
399
+ }
400
+ if (props.isEdit) {
401
+ if (props.isSub) {
402
+ const { mid, sub_id } = form.value;
403
+ const { date, start, end } = params;
404
+ await props?.editSubMeetingRequest(sub_id, {
405
+ mid,
406
+ date,
407
+ start,
408
+ end,
409
+ is_notify: true,
410
+ });
411
+ } else {
412
+ const { email_list, platform, group_name, etherpad, ...data } = params;
413
+ await props?.editMeetingRequest(props.data.id, {
414
+ ...data,
415
+ is_notify: true,
416
+ });
417
+ }
418
+ } else {
419
+ await props?.creatMeetingRequest({
420
+ ...params,
421
+ email_list: form.value.email_list.replaceAll(' ', ''),
422
+ });
423
+ }
424
+ const msg = t('meeting.meetingHandleSuccess', [form.value.topic, type]);
425
+ message.success({
426
+ content: msg,
427
+ });
428
+
429
+ emits('confirm');
430
+ } finally {
431
+ loading.value = false;
432
+ }
433
+ };
434
+ onMounted(() => {
435
+ getSigOptions();
436
+ getPlatformOptions();
437
+ });
438
+
439
+ const changeSig = (sig) => {
440
+ const find = sigOptions.value.find((v) => v.value === sig);
441
+ if (!props.isEdit) {
442
+ form.value.etherpad = find?.etherpad || '';
443
+ form.value.email_list = find?.email_list || '';
444
+ }
445
+ };
446
+ const disabledDate = (date) => {
447
+ return date.getTime() < Date.now() - 24 * 60 * 60 * 1000;
448
+ };
449
+ const changeTime = () => {
450
+ if (form.value.start && form.value.end) {
451
+ form.value.time = `${ form.value.start }-${ form.value.end }`;
452
+ } else {
453
+ form.value.time = '';
454
+ }
455
+ };
456
+
457
+ defineExpose({
458
+ confirm,
459
+ });
460
+ </script>
461
+
462
+ <template>
463
+ <div class="o-meeting-form">
464
+ <OForm :model="form" ref="formRef" has-required :layout="lePadV ? 'v' : 'h'" class="form-wrapper">
465
+ <OFormItem :rules="rules.topic" :label="t('meeting.meetingName')" field="topic">
466
+ <OInput
467
+ :disabled="isSub"
468
+ size="large"
469
+ :placeholder="t('meeting.enterMeetingName')"
470
+ style="width: 100%"
471
+ v-model="form.topic" />
472
+ </OFormItem>
473
+ <OFormItem :rules="rules.group_name" :label="t('meeting.meetingSig')" field="group_name">
474
+ <OSelect
475
+ :disabled="isEdit"
476
+ :placeholder="t('meeting.selectSig')"
477
+ size="large"
478
+ style="width: 100%"
479
+ v-model="form.group_name"
480
+ @change="changeSig"
481
+ >
482
+ <OOption v-for="t in sigOptions" :key="t.value" :value="t.value">{{ t.label }}</OOption>
483
+ </OSelect>
484
+ </OFormItem>
485
+ <OFormItem :rules="rules.etherpad" label="Etherpad" field="etherpad" v-if="form.group_name">
486
+ <template #label>
487
+ <div class="label-wrapper">
488
+ <span>Etherpad&nbsp;</span>
489
+ <OPopover>
490
+ <div class="o-meeting-form-popover-content etherpad">{{ t('meeting.etherpadDesc') }}</div>
491
+ <template #target>
492
+ <OIcon>
493
+ <IconHelp />
494
+ </OIcon>
495
+ </template>
496
+ </OPopover>
497
+ </div>
498
+ </template>
499
+ <OInput
500
+ :disabled="isEdit"
501
+ size="large"
502
+ :placeholder="t('meeting.enterEtherpad')"
503
+ style="width: 100%"
504
+ v-model="form.etherpad"
505
+ />
506
+ </OFormItem>
507
+
508
+ <OFormItem :label="t('meeting.meetingTime')" field="time" :rules="rules.time" class="repeat-row" required>
509
+ <div class="repeat-config-wrapper">
510
+ <OFormItem field="repeat" class="repeat-item" v-if="!isSub">
511
+ <ORadioGroup v-model="form.is_cycle" @change="changeIsCycle" :disabled="isEdit">
512
+ <ORadio :value="false">{{ t('meeting.nonRepeat') }}</ORadio>
513
+ <ORadio :value="true">{{ t('meeting.isRepeat') }}</ORadio>
514
+ </ORadioGroup>
515
+ </OFormItem>
516
+ <div class="repeat-config">
517
+ <template v-if="form.is_cycle">
518
+ <OFormItem :label="t('meeting.every')" class="full-width-item">
519
+ <div class="repeat-config-item">
520
+ <OFormItem v-if="form.cycle_type !== INTERVAL_MONTH">
521
+ <ElInputNumber size="large" v-model="form.cycle_interval" :min="1" :max="intervalTypeMax" />
522
+ </OFormItem>
523
+ <OFormItem>
524
+ <OSelect
525
+ size="large"
526
+ v-model="form.cycle_type"
527
+ class="interval-select"
528
+ optionWrapClass="o-meeting-form-interval-select-options"
529
+ @change="changeIntervalType"
530
+ >
531
+ <OOption v-for="o in cycleTypeOptions" :key="o.value" :value="o.value" :label="o.label" />
532
+ </OSelect>
533
+ </OFormItem>
534
+ </div>
535
+ </OFormItem>
536
+ <OFormItem
537
+ :label="t('meeting.in')"
538
+ field="cycle_point"
539
+ class="point-item"
540
+ v-if="form.cycle_type !== INTERVAL_DAY"
541
+ >
542
+ <OSelect
543
+ v-if="form.cycle_type === INTERVAL_WEEK"
544
+ size="large"
545
+ multiple
546
+ v-model="form.cycle_point"
547
+ :placeholder="t('meeting.selectRepeatDate')"
548
+ :max-tag-count="1"
549
+ >
550
+ <OOption v-for="o in weekOptions" :key="o.value" :value="o.value" :label="o.label" />
551
+ </OSelect>
552
+ <OMeetingCalendarSelector v-if="form.cycle_type === INTERVAL_MONTH" v-model="form.cycle_point" />
553
+ </OFormItem>
554
+ <OFormItem :label="t('meeting.meetingDuration')" field="date_range">
555
+ <ElDatePicker
556
+ size="large"
557
+ v-model="form.date_range"
558
+ :start-placeholder="t('meeting.startDate')"
559
+ :end-placeholder="t('meeting.endDate')"
560
+ style="width: 100%"
561
+ value-format="YYYY-MM-DD"
562
+ :disabled-date="disabledDate"
563
+ :clearable="false"
564
+ type="daterange"
565
+ popper-class="o-meeting-form-date-picker-popper"
566
+ />
567
+ </OFormItem>
568
+ </template>
569
+ <template v-else>
570
+ <OFormItem :label="t('meeting.meetingDate')" field="date">
571
+ <ElDatePicker
572
+ popper-class="o-meeting-form-date-picker-popper"
573
+ size="large"
574
+ v-model="form.date"
575
+ :placeholder="t('meeting.selectDate')"
576
+ style="width: 100%"
577
+ value-format="YYYY-MM-DD"
578
+ :disabled-date="disabledDate"
579
+ :clearable="false"
580
+ />
581
+ </OFormItem>
582
+ </template>
583
+
584
+ <OFormItem :label="t('meeting.meetingTime')">
585
+ <div class="time-select-wrapper">
586
+ <OFormItem field="start">
587
+ <ElTimeSelect
588
+ popper-class="meeting-form-time-popover"
589
+ step="00:15"
590
+ start="08:00"
591
+ end="22:45"
592
+ :placeholder="t('meeting.startTime')"
593
+ v-model="form.start"
594
+ size="large"
595
+ :clearable="false"
596
+ @change="changeTime"
597
+ />
598
+ </OFormItem>
599
+ <span>-</span>
600
+ <OFormItem field="end">
601
+ <ElTimeSelect
602
+ popper-class="meeting-form-time-popover"
603
+ step="00:15"
604
+ start="08:00"
605
+ end="22:45"
606
+ :placeholder="t('meeting.endTime')"
607
+ v-model="form.end"
608
+ size="large"
609
+ :clearable="false"
610
+ @change="changeTime"
611
+ />
612
+ </OFormItem>
613
+ <OIconTime />
614
+ </div>
615
+ </OFormItem>
616
+ </div>
617
+ </div>
618
+ </OFormItem>
619
+ <OFormItem :label="t('meeting.meetingPlatform')" field="platform" :rules="rules.platform">
620
+ <ORadioGroup v-model="form.platform" v-if="!data" :disabled="form.is_cycle">
621
+ <ORadio v-for="item in typeOptions" :key="item.value" :value="item.value">{{ item.label }}</ORadio>
622
+ </ORadioGroup>
623
+ <span v-else>{{ form.platform }}</span>
624
+ </OFormItem>
625
+ <OFormItem field="agenda" :label="t('meeting.meetingAgenda')" :rules="rules.genda">
626
+ <OTextarea
627
+ :disabled="isSub"
628
+ size="large"
629
+ :placeholder="t('meeting.enterMeetingAgenda')"
630
+ style="width: 100%"
631
+ :rows="4" v-model="form.agenda" />
632
+ </OFormItem>
633
+ <OFormItem :label="t('meeting.meetingRecord')" field="is_record" class="record-item full-width-item">
634
+ <template v-if="lePadV">
635
+ <OSwitch v-model="form.is_record" :disabled="isSub" />
636
+ </template>
637
+ <template v-else>
638
+ <div class="switch-wrapper">
639
+ <OSwitch v-model="form.is_record" :disabled="isSub" />
640
+ <div class="switch-text">
641
+ <OIcon>
642
+ <IconTip />
643
+ </OIcon>
644
+ <span>{{ t('meeting.meetingRecordDesc', [form.platform]) }}</span>
645
+ </div>
646
+ </div>
647
+ </template>
648
+
649
+ </OFormItem>
650
+ <template v-if="lePadV">
651
+ <div class="switch-wrapper">
652
+ <div class="switch-text">
653
+ <OIcon>
654
+ <IconTip />
655
+ </OIcon>
656
+ <span>{{ t('meeting.meetingRecordDesc', [form.platform]) }}</span>
657
+ </div>
658
+ </div>
659
+ </template>
660
+ <OFormItem field="email_list" :rules="rules.email_list">
661
+ <template #label>
662
+ <div class="label-wrapper">
663
+ <span>{{ t('meeting.meetingEmail') }}&nbsp;</span>
664
+ <OPopover>
665
+ <div class="o-meeting-form-popover-content">
666
+ {{ t('meeting.meetingEmailDesc') }}
667
+ <a class="link-text" :href="`/${locale}/sig`">{{ t('meeting.sigGroupEmail') }}</a>
668
+ </div>
669
+ <template #target>
670
+ <OIcon>
671
+ <IconHelp />
672
+ </OIcon>
673
+ </template>
674
+ </OPopover>
675
+ </div>
676
+ </template>
677
+ <OTextarea
678
+ :disabled="isEdit"
679
+ size="large"
680
+ :placeholder="t('meeting.enterEmail')"
681
+ style="width: 100%"
682
+ :rows="4"
683
+ v-model="form.email_list" />
684
+ </OFormItem>
685
+ </OForm>
686
+ <div class="form-btns" v-if="showBtns">
687
+ <OButton color="primary" variant="solid" size="large" @click="confirm" :loading="loading">
688
+ {{ isEdit ? t('common.save') : t('meeting.book') }}
689
+ </OButton>
690
+ <OButton color="primary" variant="outline" size="large" @click="cancel">{{ t('common.cancel') }}</OButton>
691
+ </div>
692
+ </div>
693
+ </template>
694
+
695
+ <style lang="scss">
696
+ .o-meeting-form {
697
+ .el-input {
698
+ --el-border-color: var(--o-color-control1);
699
+ --el-input-border-color: var(--o-color-control1);
700
+ --el-input-hover-border-color:var(--o-color-control2);
701
+ --el-input-focus-border-color:var(--o-color-control3);
702
+ }
703
+ .form-wrapper {
704
+ & > .o-form-item {
705
+ max-width: 592px;
706
+ }
707
+
708
+ .repeat-row,
709
+ .full-width-item {
710
+ width: 100%;
711
+ }
712
+ }
713
+
714
+ .o-form {
715
+ --o-input-color: var(--o-color-info2);
716
+ --o-placeholder-color: var(--o-color-info4);
717
+
718
+
719
+ &.o-form-layout-v {
720
+ --form-item-gap: var(--o-gap-3);
721
+ .o-form-item-label {
722
+ margin-bottom: var(--o-gap-2);
723
+ }
724
+
725
+ .o-form-item-main {
726
+ margin-left: 0;
727
+ }
728
+ }
729
+
730
+ input,
731
+ textarea {
732
+ color: var(--o-input-color);
733
+ @include text1;
734
+
735
+ &::placeholder {
736
+ color: var(--o-placeholder-color);
737
+ }
738
+ }
739
+
740
+ .o-form-item-label {
741
+ flex: 0 0 100px;
742
+ height: var(--o-control_size-l);
743
+ display: flex;
744
+ align-items: center;
745
+ --form-label-gap-top: 0;
746
+ @include respond-to('<=pad_v') {
747
+ height: fit-content;
748
+ }
749
+ }
750
+
751
+ .o-form-item-main {
752
+ margin-left: var(--o-gap-3);
753
+ }
754
+
755
+ .record-item {
756
+ @include respond-to('<=pad_v') {
757
+ display: flex;
758
+ align-items: center;
759
+ justify-content: space-between;
760
+ --form-item-gap: var(--o-gap-2);
761
+ }
762
+
763
+ .o-form-item-label {
764
+ margin: 0;
765
+ }
766
+
767
+ .o-form-item-main {
768
+ @include respond-to('<=pad_v') {
769
+ flex-grow: 0;
770
+ }
771
+ }
772
+ }
773
+
774
+ .switch-wrapper {
775
+ display: flex;
776
+ align-items: flex-start;
777
+ column-gap: var(--o-gap-4);
778
+ row-gap: var(--o-gap-2);
779
+
780
+ @include respond-to('<=pad_v') {
781
+ margin-bottom: var(--o-gap-3);
782
+ flex-direction: column;
783
+ align-items: flex-start;
784
+ }
785
+
786
+ .switch-text {
787
+ display: flex;
788
+ align-items: flex-start;
789
+ column-gap: var(--o-gap-1);
790
+ color: var(--o-color-info3);
791
+ @include tip1;
792
+
793
+ .o-icon {
794
+ font-size: 16px;
795
+ position: relative;
796
+ top: 2px;
797
+ }
798
+ }
799
+ }
800
+
801
+ input::placeholder {
802
+ @include text1;
803
+ }
804
+
805
+ .label-wrapper {
806
+ display: flex;
807
+ align-items: center;
808
+
809
+ .o-svg-icon {
810
+ font-size: 1.5em;
811
+ }
812
+ }
813
+ }
814
+
815
+ .form-btns {
816
+ margin-top: var(--o-gap-5);
817
+ display: flex;
818
+ align-items: center;
819
+
820
+ .o-btn {
821
+ height: 40px !important;
822
+ font-size: 16px !important;
823
+ line-height: 24px !important;
824
+ border-radius: 20px !important;
825
+ --btn-min-width: 90px;
826
+ }
827
+ }
828
+
829
+ .time-select-wrapper {
830
+ width: 100%;
831
+ display: flex;
832
+ align-items: center;
833
+ border: 1px solid var(--o-color-control1);
834
+ border-radius: var(--o-radius_control-s);
835
+ padding: 0 15px;
836
+ background-color: var(--o-color-fill2);
837
+
838
+ & > span {
839
+ padding: 0 var(--o-gap-2);
840
+ }
841
+
842
+ &:hover {
843
+ border-color: var(--o-color-control2);
844
+ }
845
+
846
+ @include respond-to('phone') {
847
+ background-color: var(--o-color-fill2);
848
+ }
849
+
850
+ .o-form-item {
851
+ margin-bottom: 0;
852
+ flex-grow: 1;
853
+ --o-input-color: var(--o-color-info1);
854
+
855
+ .o-form-item-label {
856
+ display: none;
857
+ }
858
+
859
+ .el-select__wrapper {
860
+ box-shadow: none;
861
+ padding: calc((var(--o-control_size-l) - 24px) / 2) 0;
862
+ min-height: var(--o-control_size-l);
863
+ gap: 0;
864
+ }
865
+
866
+ .el-select__placeholder {
867
+ @include text1;
868
+ }
869
+
870
+ .el-select__caret,
871
+ .el-input__prefix-icon {
872
+ display: none;
873
+ }
874
+
875
+ div.o-form-item-main {
876
+ margin-left: 0;
877
+ @include respond-to('phone') {
878
+ margin-top: 0;
879
+ }
880
+ }
881
+ }
882
+
883
+ .o-svg-icon {
884
+ flex-shrink: 0;
885
+ font-size: 24px;
886
+ color: var(--o-color-info2);
887
+ }
888
+ }
889
+
890
+ @include respond-to('phone') {
891
+ width: auto;
892
+ .o-form {
893
+ .o-form-item-main {
894
+ margin-left: 0;
895
+ }
896
+ }
897
+ }
898
+
899
+ .repeat-config-wrapper {
900
+ width: 100%;
901
+
902
+ .repeat-item {
903
+ .o-form-item-label {
904
+ display: none;
905
+ }
906
+
907
+ .o-form-item-main {
908
+ margin-left: 0;
909
+ }
910
+
911
+ @include respond-to('pad_v') {
912
+ margin-bottom: var(--o-gap-4);
913
+ }
914
+ @include respond-to('phone') {
915
+ margin-bottom: var(--o-gap-3);
916
+ }
917
+ }
918
+
919
+ .repeat-config {
920
+ background-color: var(--o-color-control2-light);
921
+ padding: var(--o-gap-5);
922
+ border-radius: var(--o-radius-xs);
923
+ @include respond-to('<=pad_v') {
924
+ padding: var(--o-gap-4);
925
+ }
926
+
927
+ .o-form-item {
928
+ align-items: center;
929
+ }
930
+
931
+ .o-form-item-label {
932
+ .o-form-require-symbol {
933
+ display: none;
934
+ }
935
+
936
+ flex: 0 0 4em;
937
+ }
938
+
939
+ .o-form-item-main {
940
+ margin-left: var(--o-gap-6);
941
+ @include respond-to('pad_v') {
942
+ margin-left: 0;
943
+ }
944
+ @include respond-to('phone') {
945
+ margin-left: 0;
946
+ max-width: 100%;
947
+ }
948
+ }
949
+
950
+ .full-width-item {
951
+ .o-form-item-main {
952
+ max-width: 100%;
953
+ }
954
+ }
955
+
956
+ .repeat-config-item {
957
+ width: 100%;
958
+ display: flex;
959
+ flex-wrap: nowrap;
960
+ align-items: center;
961
+ gap: var(--o-gap-4);
962
+
963
+ .o-form-item {
964
+ margin-bottom: 0;
965
+ width: calc(50% - var(--o-gap-4) / 2);
966
+
967
+ .o-form-item-label {
968
+ display: none;
969
+ }
970
+
971
+ .o-form-item-main {
972
+ margin-left: 0;
973
+ }
974
+ }
975
+ }
976
+
977
+ .point-item {
978
+ .o-select {
979
+ width: 100%;
980
+ }
981
+ }
982
+ }
983
+ }
984
+ }
985
+ </style>
986
+
987
+ <style lang="scss">
988
+ .meeting-form-time-popover, o-meeting-form-date-picker-popper {
989
+ --el-color-primary: var(--o-color-primary1);
990
+ --el-datepicker-active-color: var(--o-color-primary1);
991
+ --el-fill-color-light: var(--o-color-control2-light);
992
+ --el-input-bg-color: var(--o-color-control-light);
993
+ --el-fill-color-blank: var(--o-color-control-light);
994
+ }
995
+ .o-meeting-form-popover-content {
996
+ max-width: 256px;
997
+ text-align: left;
998
+ @include tip1;
999
+
1000
+ &.etherpad {
1001
+ width: 191px;
1002
+ }
1003
+
1004
+ .link-text {
1005
+ color: var(--o-color-primary1);
1006
+ cursor: pointer;
1007
+ }
1008
+ }
1009
+
1010
+ .o-meeting-form-interval-select-options {
1011
+ .o-option-item {
1012
+ justify-content: center;
1013
+ }
1014
+ }
1015
+
1016
+ .o-meeting-form-date-picker-popper {
1017
+ @include respond-to('phone') {
1018
+ .el-picker-panel {
1019
+ width: min(var(--grid-content-width), 400px);
1020
+
1021
+ .el-picker-panel__body {
1022
+ display: flex;
1023
+ flex-direction: column;
1024
+ min-width: auto;
1025
+
1026
+ .el-picker-panel__content {
1027
+ border-right: none;
1028
+ width: 100%;
1029
+ padding: 12px 16px;
1030
+ }
1031
+ }
1032
+ }
1033
+ }
1034
+ }
1035
+ </style>