Skip to content

Commit 1e5af5a

Browse files
authored
Merge pull request #89 from lyx1213812138/main
feat: 更新招新时间
2 parents 46468e7 + 3570552 commit 1e5af5a

6 files changed

Lines changed: 283 additions & 20 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,5 @@ dist-ssr
2222
*.njsproj
2323
*.sln
2424
*.sw?
25+
CLAUDE.md
26+
dist.zip

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# 联创团队SSO系统-前端
2-
2+
hr2024.hustunique.com
33
## 🚀技术栈
44

55
```

pnpm-lock.yaml

Lines changed: 0 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
<template>
2+
<a-modal
3+
v-model:visible="visible"
4+
:title="$t('common.operation.updateRecruitment')"
5+
:on-before-ok="sendForm"
6+
draggable
7+
>
8+
<a-space direction="vertical" size="mini">
9+
<a-form ref="recruitmentForm" :model="formData" layout="vertical">
10+
<a-form-item field="select_recruitment" label="选择招新">
11+
<a-select
12+
v-model="selectedRid"
13+
placeholder="请选择要修改的招新"
14+
@change="onRecruitmentChange"
15+
>
16+
<a-option
17+
v-for="rec in recruitmentStore.data"
18+
:key="rec.uid"
19+
:value="rec.uid"
20+
:label="rec.name"
21+
>
22+
{{ rec.name }}
23+
</a-option>
24+
</a-select>
25+
</a-form-item>
26+
27+
<a-form-item field="rec_name" :label="$t('common.createRec.recName')">
28+
<a-input
29+
v-model="formData.name"
30+
:placeholder="$t('common.createRec.inputRecName')"
31+
/>
32+
</a-form-item>
33+
34+
<a-form-item
35+
field="rec_time_range"
36+
:label="$t('common.createRec.recTimeRange')"
37+
>
38+
<a-range-picker
39+
v-model="timeRange1"
40+
show-time
41+
:time-picker-props="{ defaultValue: ['00:00:00', '00:00:00'] }"
42+
format="YYYY-MM-DD HH:mm"
43+
@ok="onOk1"
44+
/>
45+
</a-form-item>
46+
47+
<a-form-item field="deadline" label="报名结束时间">
48+
<a-date-picker
49+
v-model="deadline"
50+
show-time
51+
:time-picker-props="{ defaultValue: '00:00:00' }"
52+
format="YYYY-MM-DD HH:mm"
53+
@ok="onDeadlineChange"
54+
/>
55+
</a-form-item>
56+
</a-form>
57+
</a-space>
58+
</a-modal>
59+
</template>
60+
61+
<script setup lang="ts">
62+
import { ref, watch } from 'vue';
63+
import { Message } from '@arco-design/web-vue';
64+
import { useI18n } from 'vue-i18n';
65+
import useRecruitmentStore from '@/store/modules/recruitment';
66+
import type { UpdateParams } from '@/store/modules/recruitment/types';
67+
68+
const { t } = useI18n();
69+
const recruitmentStore = useRecruitmentStore();
70+
71+
const visible = defineModel<boolean>('visible', {
72+
type: Boolean,
73+
default: false,
74+
required: true,
75+
});
76+
77+
const selectedRid = ref<string>('');
78+
79+
const formData = ref<{
80+
name?: string;
81+
beginning?: string;
82+
deadline?: string;
83+
end?: string;
84+
}>({
85+
name: '',
86+
beginning: '',
87+
deadline: '',
88+
end: '',
89+
});
90+
91+
const emit = defineEmits<{
92+
(e: 'recruitmentUpdated'): void;
93+
}>();
94+
95+
const timeRange1 = ref<string[]>([]);
96+
const deadline = ref<string>('');
97+
98+
// 当选择招新时,填充表单数据
99+
const onRecruitmentChange = (rid: string) => {
100+
const recruitment = recruitmentStore.data.find((rec) => rec.uid === rid);
101+
if (recruitment) {
102+
formData.value = {
103+
name: recruitment.name || '',
104+
beginning: recruitment.beginning || '',
105+
deadline: recruitment.deadline || '',
106+
end: recruitment.end || '',
107+
};
108+
109+
// 填充时间选择器(转换为本地时间)
110+
if (recruitment.beginning && recruitment.end) {
111+
timeRange1.value = [
112+
new Date(recruitment.beginning).toLocaleString().replace(' ', ' '),
113+
new Date(recruitment.end).toLocaleString().replace(' ', ' '),
114+
];
115+
} else {
116+
timeRange1.value = [];
117+
}
118+
119+
// 填充报名结束时间(转换为本地时间)
120+
if (recruitment.deadline) {
121+
deadline.value = new Date(recruitment.deadline)
122+
.toLocaleString()
123+
.replace(' ', ' ');
124+
} else {
125+
deadline.value = '';
126+
}
127+
128+
console.log('timeRange1.value:', timeRange1.value);
129+
console.log('deadline.value:', deadline.value);
130+
}
131+
};
132+
133+
// 当 modal 打开时,清空表单
134+
watch(
135+
() => visible.value,
136+
(newValue) => {
137+
if (!newValue) {
138+
// modal 关闭时,清空表单
139+
selectedRid.value = '';
140+
formData.value = {
141+
name: '',
142+
beginning: '',
143+
deadline: '',
144+
end: '',
145+
};
146+
timeRange1.value = [];
147+
deadline.value = '';
148+
}
149+
},
150+
);
151+
152+
const formatName = (name: string) => {
153+
let normalizedName = name.trim();
154+
if (normalizedName.includes('')) {
155+
normalizedName = normalizedName.replace(/.*/, 'S');
156+
} else if (normalizedName.includes('')) {
157+
normalizedName = normalizedName.replace(/.*/, 'C');
158+
} else if (normalizedName.includes('')) {
159+
normalizedName = normalizedName.replace(/.*/, 'A');
160+
}
161+
return normalizedName;
162+
};
163+
164+
const formValidate = () => {
165+
const errors: { [key: string]: string } = {};
166+
const originalName = formData.value.name;
167+
168+
// 名称验证(如果提供了名称)
169+
if (originalName) {
170+
const formattedName = formatName(originalName);
171+
const nameRegex = /^\d{4}[SAC]$/;
172+
if (!nameRegex.test(formattedName)) {
173+
errors.name = t('common.createRec.nameFormat');
174+
} else {
175+
formData.value.name = formattedName;
176+
}
177+
}
178+
179+
// 时间范围验证
180+
if (formData.value.beginning && formData.value.end) {
181+
const beginningTime = new Date(formData.value.beginning).getTime();
182+
const endTime = new Date(formData.value.end).getTime();
183+
184+
if (beginningTime >= endTime) {
185+
errors.rec_time_range = '招新开始时间必须早于结束时间';
186+
}
187+
}
188+
189+
if (formData.value.deadline && formData.value.end) {
190+
const endTime = new Date(formData.value.end).getTime();
191+
const deadlineTime = new Date(formData.value.deadline).getTime();
192+
193+
if (deadlineTime >= endTime) {
194+
errors.signup_time_range = t(
195+
'common.createRec.signupEndTimeBeforeRecEndTime',
196+
);
197+
}
198+
}
199+
200+
if (Object.keys(errors).length > 0) {
201+
Message.error(Object.values(errors).join('; '));
202+
return false;
203+
}
204+
205+
return true;
206+
};
207+
208+
const sendForm = async () => {
209+
try {
210+
// 检查是否选择了招新
211+
if (!selectedRid.value) {
212+
Message.error('请先选择要修改的招新');
213+
return false;
214+
}
215+
216+
const isValid = formValidate();
217+
if (!isValid) {
218+
return false;
219+
}
220+
221+
// 只发送有值的字段
222+
const updateData: UpdateParams = {};
223+
if (formData.value.name) {
224+
updateData.name = formData.value.name;
225+
}
226+
if (formData.value.beginning) {
227+
updateData.beginning = formData.value.beginning;
228+
}
229+
if (formData.value.deadline) {
230+
updateData.deadline = formData.value.deadline;
231+
}
232+
if (formData.value.end) {
233+
updateData.end = formData.value.end;
234+
}
235+
236+
// 如果没有任何更新,提示用户
237+
if (Object.keys(updateData).length === 0) {
238+
Message.warning('没有任何修改');
239+
return false;
240+
}
241+
242+
await recruitmentStore.updateRecruitment(selectedRid.value, updateData);
243+
Message.success('招新更新成功');
244+
emit('recruitmentUpdated');
245+
return true;
246+
} catch (error) {
247+
Message.error((error as any).message || '更新失败');
248+
return false;
249+
}
250+
};
251+
252+
const onOk1 = (dateString: string[], _date: any) => {
253+
formData.value.beginning = new Date(dateString[0]).toISOString();
254+
formData.value.end = new Date(dateString[1]).toISOString();
255+
};
256+
257+
const onDeadlineChange = (dateString: string, _date: any) => {
258+
formData.value.deadline = new Date(dateString).toISOString();
259+
};
260+
</script>

0 commit comments

Comments
 (0)