567e4aabdb
- 新增 updateSelfUser 方法,用于修改当前登录用户的个人资料 - 个人中心调用接口由原 updateUser 切换为 updateSelfUser,避免学生账号权限不足导致的保存失败 - 更新了头像保存、个人信息保存等相关调用代码,添加异常捕获和提示 - 修正环境变量 .env.development 中 API URL 配置为生产地址 - 优化审核记录排序逻辑,新增获取最新审核记录和编辑入口显示判断函数 - 调整审核状态标签使用统一排序规则,防止显示和编辑状态不一致 - 新增社团活动、社团编辑、志愿时长录入、学分记录编辑、社会实践学分申报、青马学员编辑等多个新增组件及表单功能 - 各新增功能支持表单验证、操作反馈和数据加载优化
191 lines
6.3 KiB
Vue
191 lines
6.3 KiB
Vue
<!-- 发起社团活动 -->
|
|
<template>
|
|
<ele-modal
|
|
:width="720"
|
|
:visible="visible"
|
|
:maskClosable="false"
|
|
:confirm-loading="loading"
|
|
title="发起社团活动"
|
|
:body-style="{ paddingBottom: '24px' }"
|
|
@update:visible="updateVisible"
|
|
@ok="save"
|
|
>
|
|
<a-form ref="formRef" :model="form" :rules="rules" layout="vertical">
|
|
<a-row :gutter="16">
|
|
<a-col :span="12">
|
|
<a-form-item label="所属社团" name="clubId">
|
|
<a-select
|
|
v-model:value="form.clubId"
|
|
show-search
|
|
option-filter-prop="label"
|
|
:options="clubOptions"
|
|
:loading="clubLoading"
|
|
placeholder="请选择社团"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
<a-col :span="12">
|
|
<a-form-item label="活动名称" name="title">
|
|
<a-input v-model:value="form.title" allow-clear placeholder="请输入活动名称" />
|
|
</a-form-item>
|
|
</a-col>
|
|
</a-row>
|
|
<a-row :gutter="16">
|
|
<a-col :span="12">
|
|
<a-form-item label="活动类型" name="category">
|
|
<a-select
|
|
v-model:value="form.category"
|
|
allow-clear
|
|
:options="categoryOptions"
|
|
placeholder="请选择活动类型"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
<a-col :span="12">
|
|
<a-form-item label="活动地点" name="place">
|
|
<a-input v-model:value="form.place" allow-clear placeholder="请输入活动地点" />
|
|
</a-form-item>
|
|
</a-col>
|
|
</a-row>
|
|
<a-row :gutter="16">
|
|
<a-col :span="12">
|
|
<a-form-item label="开始时间" name="startTime">
|
|
<a-date-picker
|
|
v-model:value="startTime"
|
|
show-time
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
class="ele-fluid"
|
|
placeholder="请选择开始时间"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
<a-col :span="12">
|
|
<a-form-item label="结束时间" name="endTime">
|
|
<a-date-picker
|
|
v-model:value="endTime"
|
|
show-time
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
class="ele-fluid"
|
|
placeholder="请选择结束时间"
|
|
/>
|
|
</a-form-item>
|
|
</a-col>
|
|
</a-row>
|
|
<a-row :gutter="16">
|
|
<a-col :span="12">
|
|
<a-form-item label="预计参与人数" name="scale">
|
|
<a-input-number v-model:value="form.scale" :min="0" class="ele-fluid" placeholder="请输入人数" />
|
|
</a-form-item>
|
|
</a-col>
|
|
<a-col :span="12">
|
|
<a-form-item label="预算金额" name="budget">
|
|
<a-input-number v-model:value="form.budget" :min="0" :step="100" class="ele-fluid" placeholder="请输入预算" />
|
|
</a-form-item>
|
|
</a-col>
|
|
</a-row>
|
|
<a-form-item label="活动方案" name="content">
|
|
<a-textarea v-model:value="form.content" :rows="4" allow-clear placeholder="请简述活动方案" />
|
|
</a-form-item>
|
|
<a-form-item label="活动材料" name="attachments">
|
|
<MultiFileUpload v-model="attachments" :max-count="5" />
|
|
</a-form-item>
|
|
<a-form-item label="提交方式" name="status">
|
|
<a-radio-group v-model:value="form.status">
|
|
<a-radio :value="1">提交审核</a-radio>
|
|
<a-radio :value="0">保存草稿</a-radio>
|
|
</a-radio-group>
|
|
</a-form-item>
|
|
</a-form>
|
|
</ele-modal>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { computed, reactive, ref, watch } from 'vue';
|
|
import { Form, message } from 'ant-design-vue';
|
|
import MultiFileUpload from '@/components/MultiFileUpload/index.vue';
|
|
import { listClubs, submitClubActivity } from '@/api/growth/club';
|
|
import type { ClubActivity } from '@/api/growth/club';
|
|
|
|
const props = defineProps<{ visible: boolean }>();
|
|
const emit = defineEmits<{
|
|
(e: 'done'): void;
|
|
(e: 'update:visible', visible: boolean): void;
|
|
}>();
|
|
|
|
const formRef = ref();
|
|
const loading = ref(false);
|
|
const form = reactive<ClubActivity>({});
|
|
const startTime = ref<any>();
|
|
const endTime = ref<any>();
|
|
const attachments = ref('');
|
|
const clubLoading = ref(false);
|
|
const clubList = ref<{ label: string; value: number }[]>([]);
|
|
const clubOptions = computed(() => clubList.value);
|
|
|
|
const categoryOptions = [
|
|
{ label: '社团日常活动', value: '社团日常活动' },
|
|
{ label: '志愿服务', value: '志愿服务' },
|
|
{ label: '学术讲座', value: '学术讲座' },
|
|
{ label: '文体比赛', value: '文体比赛' },
|
|
{ label: '社会实践活动', value: '社会实践活动' }
|
|
];
|
|
|
|
const rules = {
|
|
clubId: [{ required: true, message: '请选择社团', trigger: 'change' }],
|
|
title: [{ required: true, message: '请输入活动名称', trigger: 'blur' }],
|
|
startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
|
|
endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }]
|
|
};
|
|
|
|
const loadClubs = async () => {
|
|
clubLoading.value = true;
|
|
try {
|
|
const list = await listClubs({ status: 1 });
|
|
clubList.value = list
|
|
.filter((item) => item.id)
|
|
.map((item) => ({ label: item.clubName || '', value: item.id as number }));
|
|
} catch (e: any) {
|
|
message.error(e?.message || '加载社团失败');
|
|
} finally {
|
|
clubLoading.value = false;
|
|
}
|
|
};
|
|
|
|
watch(
|
|
() => props.visible,
|
|
(value) => {
|
|
if (!value) return;
|
|
Object.keys(form).forEach((key) => delete (form as any)[key]);
|
|
startTime.value = undefined;
|
|
endTime.value = undefined;
|
|
attachments.value = '';
|
|
form.status = 1;
|
|
loadClubs();
|
|
}
|
|
);
|
|
|
|
const updateVisible = (value: boolean) => emit('update:visible', value);
|
|
|
|
const save = () => {
|
|
formRef.value
|
|
?.validate?.()
|
|
.then(async () => {
|
|
loading.value = true;
|
|
try {
|
|
form.startTime = startTime.value;
|
|
form.endTime = endTime.value;
|
|
form.attachments = attachments.value || undefined;
|
|
const msg = await submitClubActivity(form);
|
|
message.success(msg);
|
|
updateVisible(false);
|
|
emit('done');
|
|
} catch (e: any) {
|
|
message.error(e?.message || '提交失败');
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
})
|
|
.catch(() => undefined);
|
|
};
|
|
</script>
|