| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563 |
- <script setup>
- import { reactive, ref, watch } from "vue"
- import {
- getActivityPages,
- createInsertActivity,
- updateActivity,
- getClubPage,
- deleteActivityById,
- exportActivityExcel
- } from "@/api/activityManagement"
- import { getQueryCollegesApi, getQueryPeriodsApi, getQueryMajorsApi, getQueryClassesApi } from "@/api/alumniManager"
- import { ElMessage, ElMessageBox } from "element-plus"
- import { usePagination } from "@/hooks/usePagination"
- import { cloneDeep } from "lodash-es"
- const loading = ref(false)
- const { paginationData, handleCurrentChange, handleSizeChange } = usePagination()
- //#region 设置管理员
- const SET_ADMIN_DEFAULT_FORM_DATA = {
- list: []
- }
- const setAdminDialogVisible = ref(false)
- const setAdminFormRef = ref(null)
- const setAdminFormData = ref(cloneDeep(SET_ADMIN_DEFAULT_FORM_DATA))
- const setAdminFormRules = {
- list: [{ required: true, trigger: "blur", message: "必填" }]
- }
- const handleSetAdmin = () => {
- setAdminFormRef.value?.validate((valid, fields) => {
- if (!valid) return console.error("表单校验不通过", fields)
- // todo 调用设置管理员接口
- })
- }
- const resetSetAdminForm = () => {
- setAdminFormRef.value?.clearValidate()
- setAdminFormData.value = cloneDeep(SET_ADMIN_DEFAULT_FORM_DATA)
- }
- //#endregion
- //#region 增
- const DEFAULT_FORM_DATA = {
- id: undefined,
- orgId: "",
- orgName: "",
- organization: [],
- theme: "",
- themeDetail: "",
- poster: "",
- activityTime: null,
- address: "",
- lng: "",
- lat: "",
- describes: "",
- registrationTime: null,
- totalNumber: undefined,
- scope: "",
- phone: "",
- isImage: false
- }
- const dialogVisible = ref(false)
- const formRef = ref(null)
- const formData = ref(cloneDeep(DEFAULT_FORM_DATA))
- const formRules = {
- orgId: [{ required: true, trigger: "blur", message: "必填" }],
- theme: [{ required: true, trigger: "blur", message: "必填" }],
- themeDetail: [{ required: true, trigger: "blur", message: "必填" }],
- activityTime: [{ required: true, trigger: "blur", message: "必填" }],
- address: [{ required: true, trigger: "blur", message: "必填" }],
- describes: [{ required: true, trigger: "blur", message: "必填" }],
- registrationTime: [{ required: true, trigger: "blur", message: "必填" }],
- totalNumber: [{ required: true, trigger: "blur", message: "必填" }],
- scope: [{ required: true, trigger: "blur", message: "必填" }],
- phone: [{ required: true, trigger: "blur", message: "必填" }]
- }
- const handleCreateOrUpdate = () => {
- formRef.value?.validate((valid, fields) => {
- if (!valid) return console.error("表单校验不通过", fields)
- loading.value = true
- const api = formData.value.id === undefined ? createInsertActivity : updateActivity
- api({
- ...formData.value,
- startTime: formData.value.activityTime ? formData.value.activityTime[0] : undefined,
- endTime: formData.value.activityTime ? formData.value.activityTime[1] : undefined,
- lng: "101",
- lat: "78",
- signsTime: formData.value.registrationTime ? formData.value.registrationTime[0] : undefined,
- signeTime: formData.value.registrationTime ? formData.value.registrationTime[1] : undefined
- })
- .then(() => {
- ElMessage.success("操作成功")
- dialogVisible.value = false
- getTableData()
- })
- .catch(() => {
- loading.value = false
- })
- })
- }
- const resetForm = () => {
- formRef.value?.clearValidate()
- formData.value = cloneDeep(DEFAULT_FORM_DATA)
- }
- //#endregion
- //#region 删
- const handleDelete = (row) => {
- ElMessageBox.confirm("确认删除?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- }).then(() => {
- deleteActivityById(row.id).then(() => {
- ElMessage.success("删除成功")
- getTableData()
- })
- })
- }
- //#endregion
- //#region 改
- const handleUpdate = (row) => {
- dialogVisible.value = true
- formData.value = cloneDeep(row)
- }
- //#endregion
- //#region 查
- const tableData = ref([])
- const searchFormRef = ref(null)
- const searchData = reactive({
- orgName: undefined,
- userName: undefined,
- theme: undefined,
- collegeId: undefined,
- colleges: [],
- periodId: undefined,
- periods: [],
- majorId: undefined,
- majors: [],
- classId: undefined,
- classList: [],
- statuId: undefined,
- createTime: null,
- activityTime: null,
- registrationTime: null
- })
- const getTableData = () => {
- loading.value = true
- getActivityPages({
- currentPage: paginationData.currentPage,
- pageCount: paginationData.pageSize,
- orgName: searchData.orgName,
- userName: searchData.userName,
- theme: searchData.theme,
- collegeId: searchData.collegeId,
- periodId: searchData.periodId,
- majorId: searchData.majorId,
- classId: searchData.classId,
- statuId: searchData.statuId,
- createStartTime: searchData.createTime ? searchData.createTime[0] : undefined,
- createEndTime: searchData.createTime ? searchData.createTime[1] : undefined,
- startTime: searchData.activityTime ? searchData.activityTime[0] : undefined,
- endTime: searchData.activityTime ? searchData.activityTime[1] : undefined,
- signsTime: searchData.registrationTime ? searchData.registrationTime[0] : undefined,
- signeTime: searchData.registrationTime ? searchData.registrationTime[1] : undefined
- })
- .then(({ data }) => {
- console.log(data)
- paginationData.total = data.totalCount
- tableData.value = data.list
- })
- .catch(() => {
- tableData.value = []
- })
- .finally(() => {
- loading.value = false
- })
- }
- const handleSearch = () => {
- paginationData.currentPage === 1 ? getTableData() : (paginationData.currentPage = 1)
- }
- const resetSearch = () => {
- searchFormRef.value?.resetFields()
- handleSearch()
- }
- // 获取学院集合
- const getColleges = async () => {
- const res = await getQueryCollegesApi()
- // console.log(res)
- searchData.colleges = res.data
- }
- // 学院筛选框切换回调
- const changeCollege = async (e) => {
- const res = await getQueryPeriodsApi({
- collegeId: e
- })
- // console.log(res)
- searchData.periods = res.data
- }
- // 学段筛选框切换回调
- const changePeriod = async (e) => {
- const res = await getQueryMajorsApi({
- periodId: e
- })
- searchData.majors = res.data
- }
- // 专业筛选框切换回调
- const changeMajorId = async (e) => {
- const res = await getQueryClassesApi({
- majorId: e
- })
- searchData.classList = res.data
- }
- // 新增按钮回调
- const handleAdd = () => {
- dialogVisible.value = true
- getOrgList()
- }
- // 获取弹窗组织列表
- const getOrgList = async () => {
- const res = await getClubPage({
- currentPage: 1,
- pageCount: 999
- })
- // console.log(res)
- formData.value.organization = res.data.list
- }
- // 切换 弹窗组织筛选框回调
- const changeOrg = (e) => {
- // console.log(e)
- const v = formData.value.organization.findIndex((item) => item.id == e)
- formData.value.orgName = formData.value.organization[v].name
- }
- //#endregion
- /** 监听分页参数的变化 */
- watch([() => paginationData.currentPage, () => paginationData.pageSize], getTableData, { immediate: true })
- watch([() => paginationData.currentPage, () => paginationData.pageSize], getColleges, { immediate: true })
- /** 导出 */
- const handleDownload = () => {
- ElMessageBox.confirm("确认导出吗?", "提示", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- }).then(() => {
- downloadReq()
- })
- }
- // 导出请求
- const downloadReq = async () => {
- const res = await exportActivityExcel({
- orgName: searchData.orgName,
- userName: searchData.userName,
- theme: searchData.theme,
- collegeId: searchData.collegeId,
- periodId: searchData.periodId,
- majorId: searchData.majorId,
- classId: searchData.classId,
- statuId: searchData.statuId,
- createStartTime: searchData.createTime ? searchData.createTime[0] : undefined,
- createEndTime: searchData.createTime ? searchData.createTime[1] : undefined,
- startTime: searchData.activityTime ? searchData.activityTime[0] : undefined,
- endTime: searchData.activityTime ? searchData.activityTime[1] : undefined,
- signsTime: searchData.registrationTime ? searchData.registrationTime[0] : undefined,
- signeTime: searchData.registrationTime ? searchData.registrationTime[1] : undefined
- })
- // console.log(res)
- // 请求成功返回后,获取到Excel文件的二进制数据
- const blob = new Blob([res], { type: "application/vnd.ms-excel" })
- // 创建下载链接
- const downloadUrl = URL.createObjectURL(blob)
- // 创建一个隐藏的a标签,设置下载链接和文件名,模拟点击下载
- const link = document.createElement("a")
- link.style.display = "none"
- link.href = downloadUrl
- link.download = "活动管理.xlsx"
- document.body.appendChild(link)
- link.click()
- document.body.removeChild(link)
- }
- </script>
- <template>
- <div class="app-container">
- <el-card v-loading="loading" header="活动管理">
- <div class="toolbar-wrapper">
- <el-form ref="searchFormRef" :inline="true" :model="searchData">
- <el-form-item prop="orgName" label="组织名称">
- <el-input v-model="searchData.orgName" placeholder="请输入" />
- </el-form-item>
- <el-form-item prop="userName" label="发起人">
- <el-input v-model="searchData.userName" placeholder="请输入" />
- </el-form-item>
- <el-form-item prop="theme" label="活动主题">
- <el-input v-model="searchData.theme" placeholder="请输入" />
- </el-form-item>
- <el-form-item prop="collegeId" label="学院">
- <el-select v-model="searchData.collegeId" placeholder="请选择" style="width: 178px" @change="changeCollege">
- <el-option v-for="item in searchData.colleges" :label="item.name" :value="item.id" :key="item.id" />
- </el-select>
- </el-form-item>
- <el-form-item prop="periodId" label="学段">
- <el-select
- v-model="searchData.periodId"
- placeholder="请选择"
- style="width: 178px"
- :disabled="!searchData.collegeId"
- @change="changePeriod"
- >
- <el-option v-for="item in searchData.periods" :label="item.name" :value="item.id" :key="item.id" />
- </el-select>
- </el-form-item>
- <el-form-item prop="majorId" label="专业">
- <el-select
- v-model="searchData.majorId"
- placeholder="请选择"
- style="width: 178px"
- :disabled="!searchData.periodId"
- @change="changeMajorId"
- >
- <el-option v-for="item in searchData.majors" :label="item.name" :value="item.id" :key="item.id" />
- </el-select>
- </el-form-item>
- <el-form-item prop="classId" label="班级">
- <el-select
- v-model="searchData.classId"
- placeholder="请选择"
- style="width: 178px"
- :disabled="!searchData.majorId"
- >
- <el-option v-for="item in searchData.classList" :label="item.name" :value="item.id" :key="item.id" />
- </el-select>
- </el-form-item>
- <el-form-item prop="statuId" label="状态">
- <el-select v-model="searchData.statuId" placeholder="请选择" style="width: 178px">
- <el-option label="全部" value="0" />
- <el-option label="未开始" value="1" />
- <el-option label="进行中" value="2" />
- <el-option label="已结束" value="3" />
- </el-select>
- </el-form-item>
- <el-form-item prop="createTime" label="创建时间">
- <el-date-picker
- v-model="searchData.createTime"
- type="datetimerange"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- value-format="YYYY-MM-DD HH:mm:ss"
- />
- </el-form-item>
- <el-form-item prop="activityTime" label="活动时间">
- <el-date-picker
- v-model="searchData.activityTime"
- type="datetimerange"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- value-format="YYYY-MM-DD HH:mm:ss"
- />
- </el-form-item>
- <el-form-item prop="registrationTime" label="报名时间">
- <el-date-picker
- v-model="searchData.registrationTime"
- type="datetimerange"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- value-format="YYYY-MM-DD HH:mm:ss"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleSearch">查询</el-button>
- <el-button @click="resetSearch" plain>重置</el-button>
- </el-form-item>
- </el-form>
- <div>
- <el-button type="primary" @click="setAdminDialogVisible = true">设置管理员</el-button>
- <el-button type="primary" @click="handleAdd">新增</el-button>
- <el-button plain @click="handleDownload">导出</el-button>
- </div>
- </div>
- <div class="table-wrapper">
- <el-table :data="tableData" max-height="500">
- <el-table-column type="index" label="序号" width="80" align="center" />
- <el-table-column prop="name" label="发起人" align="center" show-overflow-tooltip />
- <el-table-column prop="collegeName" label="学院" align="center" show-overflow-tooltip />
- <el-table-column prop="periodName" label="学段" align="center" />
- <el-table-column prop="majorName" label="专业" align="center" show-overflow-tooltip />
- <el-table-column prop="className" label="班级" align="center" />
- <el-table-column prop="orgName" label="所属组织" align="center" />
- <el-table-column prop="theme" label="活动主题" align="center" />
- <el-table-column label="活动时间" align="center" show-overflow-tooltip>
- <template #default="{ row }">
- <div>{{ row.startTime }} -- {{ row.endTime }}</div>
- </template>
- </el-table-column>
- <el-table-column label="报名时间" align="center" show-overflow-tooltip>
- <template #default="{ row }">
- <div>{{ row.signsTime }} -- {{ row.signeTime }}</div>
- </template>
- </el-table-column>
- <el-table-column label="状态" align="center">
- <template #default="{ row }">
- <div style="color: #366fff" v-if="row.activityStatuName == 1">未开始</div>
- <div style="color: #e6a23c" v-if="row.activityStatuName == 2">进行中</div>
- <div style="color: #d43030" v-if="row.activityStatuName == 3">已结束</div>
- </template>
- </el-table-column>
- <el-table-column label="已报名" align="center" show-overflow-tooltip>
- <template #default="{ row }">
- <div style="color: #d43030" v-if="row.reportNumber == 0">未报名</div>
- <div style="color: #366fff" v-else>已报名</div>
- </template>
- </el-table-column>
- <el-table-column label="已签到" align="center" show-overflow-tooltip>
- <template #default="{ row }">
- <div style="color: #d43030" v-if="row.signinNumber == 0">未签到</div>
- <div style="color: #366fff" v-else>已签到</div>
- </template>
- </el-table-column>
- <el-table-column prop="createTime" label="创建时间" align="center" show-overflow-tooltip />
- <el-table-column fixed="right" label="操作" width="200" align="center">
- <template #default="scope">
- <el-link type="primary" @click="handleUpdate(scope.row)">详情</el-link>
- <el-link type="danger" @click="handleDelete(scope.row)">删除</el-link>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <div class="pager-wrapper">
- <el-pagination
- background
- :layout="paginationData.layout"
- :page-sizes="paginationData.pageSizes"
- :total="paginationData.total"
- :page-size="paginationData.pageSize"
- :currentPage="paginationData.currentPage"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- />
- </div>
- </el-card>
- <!-- 新增/修改 -->
- <el-dialog
- v-model="dialogVisible"
- :title="formData.id === undefined ? '创建活动' : '编辑活动'"
- @closed="resetForm"
- width="50%"
- top="5vh"
- >
- <el-form ref="formRef" :model="formData" :rules="formRules" label-width="auto" size="large">
- <el-form-item prop="orgId" label="所属组织">
- <el-select v-model="formData.orgId" placeholder="请选择" @change="changeOrg">
- <el-option v-for="item in formData.organization" :label="item.name" :value="item.id" :key="item.id" />
- </el-select>
- </el-form-item>
- <el-form-item prop="theme" label="活动主题">
- <el-input v-model="formData.theme" placeholder="请输入" />
- </el-form-item>
- <el-form-item prop="themeDetail" label="活动详情">
- <el-input v-model="formData.themeDetail" type="textarea" :rows="5" placeholder="请输入" />
- </el-form-item>
- <el-form-item prop="activityTime" label="活动时间">
- <el-date-picker
- v-model="formData.activityTime"
- type="datetimerange"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- value-format="YYYY-MM-DD HH:mm:ss"
- />
- </el-form-item>
- <el-form-item prop="address" label="活动地址">
- <el-input v-model="formData.address" placeholder="请输入" />
- </el-form-item>
- <el-form-item prop="describes" label="参与说明">
- <el-input v-model="formData.describes" type="textarea" :rows="5" placeholder="请输入" />
- </el-form-item>
- <el-form-item prop="registrationTime" label="报名时间">
- <el-date-picker
- v-model="formData.registrationTime"
- type="datetimerange"
- start-placeholder="开始时间"
- end-placeholder="结束时间"
- value-format="YYYY-MM-DD HH:mm:ss"
- />
- </el-form-item>
- <el-form-item prop="totalNumber" label="报名总人数">
- <el-input v-model.number="formData.totalNumber" type="number" placeholder="请输入" />
- </el-form-item>
- <el-form-item prop="scope" label="报名范围">
- <el-select v-model="formData.scope" placeholder="请选择">
- <el-option label="全部" value="2" />
- <el-option label="组织成员" value="1" />
- </el-select>
- </el-form-item>
- <el-form-item prop="phone" label="咨询方式">
- <el-input v-model="formData.phone" placeholder="请输入" />
- </el-form-item>
- <el-form-item prop="isImage" label="活动相册">
- <el-switch v-model="formData.isImage" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="dialogVisible = false">取消</el-button>
- <el-button type="primary" @click="handleCreateOrUpdate" :loading="loading">确定</el-button>
- </template>
- </el-dialog>
- <!-- 设置管理员 -->
- <el-dialog v-model="setAdminDialogVisible" title="设置管理员" @closed="resetSetAdminForm" width="50%">
- <el-form
- ref="setAdminFormRef"
- :model="setAdminFormData"
- :rules="setAdminFormRules"
- label-width="auto"
- size="large"
- >
- <el-form-item prop="list" label="管理员">
- <el-select v-model="setAdminFormData.list" placeholder="请选择" multiple>
- <el-option label="todo" value="todo" />
- </el-select>
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="setAdminDialogVisible = false">取消</el-button>
- <el-button type="primary" @click="handleSetAdmin" :loading="loading">确定</el-button>
- </template>
- </el-dialog>
- </div>
- </template>
- <style lang="scss" scoped>
- .toolbar-wrapper {
- margin-bottom: 26px;
- }
- .table-wrapper {
- margin-bottom: 29px;
- .el-link {
- margin-right: 15px;
- }
- }
- .pager-wrapper {
- display: flex;
- justify-content: flex-end;
- }
- </style>
|