|
|
@@ -1,8 +1,15 @@
|
|
|
<script setup>
|
|
|
import { reactive, ref, watch } from "vue"
|
|
|
-import { getTableDataApi } from "@/api/table"
|
|
|
-import { ElMessageBox } from "element-plus"
|
|
|
+import {
|
|
|
+ getActivityApplyPages,
|
|
|
+ exportActivityApplyExcel,
|
|
|
+ getExamineActivity,
|
|
|
+ getDetailInfoById
|
|
|
+} from "@/api/activityManagement"
|
|
|
+import { getQueryCollegesApi, getQueryPeriodsApi, getQueryMajorsApi, getQueryClassesApi } from "@/api/alumniManager"
|
|
|
+import { ElMessageBox, ElMessage } from "element-plus"
|
|
|
import { usePagination } from "@/hooks/usePagination"
|
|
|
+// import { cloneDeep } from "lodash-es"
|
|
|
|
|
|
const loading = ref(false)
|
|
|
const { paginationData, handleCurrentChange, handleSizeChange } = usePagination()
|
|
|
@@ -10,9 +17,14 @@ const { paginationData, handleCurrentChange, handleSizeChange } = usePagination(
|
|
|
//#region 详情
|
|
|
const dialogVisible = ref(false)
|
|
|
const formData = ref({})
|
|
|
-const handleUpdate = (row) => {
|
|
|
+const handleUpdate = async (row) => {
|
|
|
dialogVisible.value = true
|
|
|
- formData.value = cloneDeep(row)
|
|
|
+
|
|
|
+ const res = await getDetailInfoById({
|
|
|
+ id: row.id
|
|
|
+ })
|
|
|
+ // console.log(res)
|
|
|
+ formData.value = res.data
|
|
|
}
|
|
|
//#endregion
|
|
|
|
|
|
@@ -20,40 +32,46 @@ const handleUpdate = (row) => {
|
|
|
const tableData = ref([])
|
|
|
const searchFormRef = ref(null)
|
|
|
const searchData = reactive({
|
|
|
- organizationName: undefined,
|
|
|
- initiator: undefined,
|
|
|
+ orgName: undefined,
|
|
|
+ userName: undefined,
|
|
|
theme: undefined,
|
|
|
- college: undefined,
|
|
|
- stage: undefined,
|
|
|
- major: undefined,
|
|
|
- class: undefined,
|
|
|
- status: undefined,
|
|
|
+ collegeId: undefined,
|
|
|
+ colleges: [],
|
|
|
+ periodId: undefined,
|
|
|
+ periods: [],
|
|
|
+ majorId: undefined,
|
|
|
+ majors: [],
|
|
|
+ classId: undefined,
|
|
|
+ classList: [],
|
|
|
+ isPass: undefined,
|
|
|
createTime: null,
|
|
|
activityTime: null,
|
|
|
registrationTime: null
|
|
|
})
|
|
|
const getTableData = () => {
|
|
|
loading.value = true
|
|
|
- getTableDataApi({
|
|
|
+ getActivityApplyPages({
|
|
|
currentPage: paginationData.currentPage,
|
|
|
- size: paginationData.pageSize,
|
|
|
- organizationName: searchData.organizationName,
|
|
|
- initiator: searchData.initiator,
|
|
|
+ pageCount: paginationData.pageSize,
|
|
|
+ orgName: searchData.orgName,
|
|
|
+ userName: searchData.userName,
|
|
|
theme: searchData.theme,
|
|
|
- college: searchData.college,
|
|
|
- stage: searchData.stage,
|
|
|
- major: searchData.major,
|
|
|
- class: searchData.class,
|
|
|
- status: searchData.status,
|
|
|
- starTime: searchData.createTime ? searchData.createTime[0] : undefined,
|
|
|
- endTime: searchData.createTime ? searchData.createTime[1] : undefined,
|
|
|
- starTime2: searchData.activityTime ? searchData.activityTime[0] : undefined,
|
|
|
- endTime2: searchData.activityTime ? searchData.activityTime[1] : undefined,
|
|
|
- starTime3: searchData.registrationTime ? searchData.registrationTime[0] : undefined,
|
|
|
- endTime3: searchData.registrationTime ? searchData.registrationTime[1] : undefined
|
|
|
+ collegeId: searchData.collegeId,
|
|
|
+ periodId: searchData.periodId,
|
|
|
+ majorId: searchData.majorId,
|
|
|
+ classId: searchData.classId,
|
|
|
+ isPass: searchData.isPass,
|
|
|
+ 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 }) => {
|
|
|
- paginationData.total = data.total
|
|
|
+ // console.log(data)
|
|
|
+
|
|
|
+ paginationData.total = data.totalCount
|
|
|
tableData.value = data.list
|
|
|
})
|
|
|
.catch(() => {
|
|
|
@@ -70,11 +88,45 @@ 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
|
|
|
+}
|
|
|
//#endregion
|
|
|
|
|
|
/** 监听分页参数的变化 */
|
|
|
watch([() => paginationData.currentPage, () => paginationData.pageSize], getTableData, { immediate: true })
|
|
|
|
|
|
+watch([() => paginationData.currentPage, () => paginationData.pageSize], getColleges, { immediate: true })
|
|
|
+
|
|
|
/** 通过 */
|
|
|
const handlePass = (row) => {
|
|
|
ElMessageBox.confirm("确认通过?", "提示", {
|
|
|
@@ -82,27 +134,80 @@ const handlePass = (row) => {
|
|
|
cancelButtonText: "取消",
|
|
|
type: "warning"
|
|
|
}).then(() => {
|
|
|
- // todo 调用通过接口
|
|
|
- console.log(row)
|
|
|
+ checkReq(2, row.id)
|
|
|
})
|
|
|
}
|
|
|
|
|
|
/** 拒绝 */
|
|
|
const handleReject = (row) => {
|
|
|
- ElMessageBox.confirm("确认拒绝?", "提示", {
|
|
|
+ ElMessageBox.prompt("确认拒绝?", "提示", {
|
|
|
confirmButtonText: "确定",
|
|
|
cancelButtonText: "取消",
|
|
|
- type: "warning"
|
|
|
- }).then(() => {
|
|
|
- // todo 调用拒绝接口
|
|
|
- console.log(row)
|
|
|
+ inputPlaceholder: "请输入拒绝的原因"
|
|
|
+ }).then(({ value }) => {
|
|
|
+ if (value && value.trim()) {
|
|
|
+ checkReq(3, row.id, value)
|
|
|
+ } else {
|
|
|
+ ElMessage.warning("拒绝原因为必填")
|
|
|
+ handleReject(row)
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 审核请求
|
|
|
+const checkReq = async (isPass, id, passValue = "") => {
|
|
|
+ await getExamineActivity({
|
|
|
+ id,
|
|
|
+ isPass,
|
|
|
+ passValue
|
|
|
})
|
|
|
+
|
|
|
+ ElMessage.success("操作成功")
|
|
|
+ getTableData()
|
|
|
}
|
|
|
|
|
|
/** 导出 */
|
|
|
const handleDownload = () => {
|
|
|
- // todo 调用导出接口
|
|
|
- console.log("导出")
|
|
|
+ ElMessageBox.confirm("确认导出吗?", "提示", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ }).then(() => {
|
|
|
+ downloadReq()
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 导出请求
|
|
|
+const downloadReq = async () => {
|
|
|
+ const res = await exportActivityApplyExcel({
|
|
|
+ orgName: searchData.orgName,
|
|
|
+ userName: searchData.userName,
|
|
|
+ theme: searchData.theme,
|
|
|
+ collegeId: searchData.collegeId,
|
|
|
+ periodId: searchData.periodId,
|
|
|
+ majorId: searchData.majorId,
|
|
|
+ classId: searchData.classId,
|
|
|
+ isPass: searchData.isPass,
|
|
|
+ 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>
|
|
|
|
|
|
@@ -111,38 +216,57 @@ const handleDownload = () => {
|
|
|
<el-card v-loading="loading" header="审核列表">
|
|
|
<div class="toolbar-wrapper">
|
|
|
<el-form ref="searchFormRef" :inline="true" :model="searchData">
|
|
|
- <el-form-item prop="organizationName" label="组织名称">
|
|
|
- <el-input v-model="searchData.organizationName" placeholder="请输入" />
|
|
|
+ <el-form-item prop="orgName" label="组织名称">
|
|
|
+ <el-input v-model="searchData.orgName" placeholder="请输入" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item prop="initiator" label="发起人">
|
|
|
- <el-input v-model="searchData.initiator" placeholder="请输入" />
|
|
|
+ <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="college" label="学院">
|
|
|
- <el-select v-model="searchData.college" placeholder="请选择" style="width: 178px">
|
|
|
- <el-option label="todo" value="todo" />
|
|
|
+ <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="stage" label="学段">
|
|
|
- <el-select v-model="searchData.stage" placeholder="请选择" style="width: 178px">
|
|
|
- <el-option label="todo" value="todo" />
|
|
|
+ <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="major" label="专业">
|
|
|
- <el-select v-model="searchData.major" placeholder="请选择" style="width: 178px">
|
|
|
- <el-option label="todo" value="todo" />
|
|
|
+ <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="class" label="班级">
|
|
|
- <el-select v-model="searchData.class" placeholder="请选择" style="width: 178px">
|
|
|
- <el-option label="todo" value="todo" />
|
|
|
+ <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="status" label="状态">
|
|
|
- <el-select v-model="searchData.status" placeholder="请选择" style="width: 178px">
|
|
|
- <el-option label="todo" value="todo" />
|
|
|
+ <el-form-item prop="isPass" label="状态">
|
|
|
+ <el-select v-model="searchData.isPass" placeholder="请选择" style="width: 178px">
|
|
|
+ <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="创建时间">
|
|
|
@@ -151,7 +275,7 @@ const handleDownload = () => {
|
|
|
type="datetimerange"
|
|
|
start-placeholder="开始时间"
|
|
|
end-placeholder="结束时间"
|
|
|
- value-format="x"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<el-form-item prop="activityTime" label="活动时间">
|
|
|
@@ -160,7 +284,7 @@ const handleDownload = () => {
|
|
|
type="datetimerange"
|
|
|
start-placeholder="开始时间"
|
|
|
end-placeholder="结束时间"
|
|
|
- value-format="x"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<el-form-item prop="registrationTime" label="报名时间">
|
|
|
@@ -169,7 +293,7 @@ const handleDownload = () => {
|
|
|
type="datetimerange"
|
|
|
start-placeholder="开始时间"
|
|
|
end-placeholder="结束时间"
|
|
|
- value-format="x"
|
|
|
+ value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
@@ -183,27 +307,44 @@ const handleDownload = () => {
|
|
|
</div>
|
|
|
<div class="table-wrapper">
|
|
|
<el-table :data="tableData" max-height="500">
|
|
|
- <el-table-column type="index" label="序号" width="100" align="center" />
|
|
|
- <el-table-column prop="initiator" label="发起人" align="center" />
|
|
|
- <el-table-column prop="college" label="学院" align="center" />
|
|
|
- <el-table-column prop="stage" label="学段" align="center" />
|
|
|
- <el-table-column prop="major" label="专业" align="center" />
|
|
|
- <el-table-column prop="class" label="班级" align="center" />
|
|
|
- <el-table-column prop="organizationName" label="所属组织" align="center" />
|
|
|
- <el-table-column prop="theme" label="活动主题" align="center" />
|
|
|
- <el-table-column prop="activityTime" label="活动开始时间" align="center" />
|
|
|
- <el-table-column prop="registrationTime" label="报名开始时间" align="center" />
|
|
|
- <el-table-column prop="todo" label="已报名" align="center" />
|
|
|
- <el-table-column prop="todo" label="已签到" align="center" />
|
|
|
- <el-table-column prop="status" label="状态" align="center" />
|
|
|
- <el-table-column prop="todo" label="审核人" align="center" />
|
|
|
- <el-table-column prop="todo" label="审核时间" align="center" />
|
|
|
- <el-table-column prop="createTime" label="创建时间" align="center" />
|
|
|
+ <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" show-overflow-tooltip />
|
|
|
+ <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" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="theme" label="活动主题" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="startTime" label="活动开始时间" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="signsTime" label="报名开始时间" align="center" show-overflow-tooltip />
|
|
|
+ <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 label="状态" align="center" show-overflow-tooltip>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <div style="color: #366fff" v-if="row.passName == '已通过'">已通过</div>
|
|
|
+ <div style="color: #e6a23c" v-if="row.passName == '待审核'">待审核</div>
|
|
|
+ <div style="color: #d43030" v-if="row.passName == '已拒绝'">已拒绝</div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+
|
|
|
+ <el-table-column prop="applyUserAdmin" label="审核人" align="center" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="passTime" label="审核时间" align="center" show-overflow-tooltip />
|
|
|
+ <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="handleReject(scope.row)">拒绝</el-link>
|
|
|
- <el-link type="success" @click="handlePass(scope.row)">同意</el-link>
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-link type="primary" @click="handleUpdate(row)">详情</el-link>
|
|
|
+ <el-link type="danger" v-if="row.passName == '待审核'" @click="handleReject(row)">拒绝</el-link>
|
|
|
+ <el-link type="success" v-if="row.passName == '待审核'" @click="handlePass(row)">同意</el-link>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
@@ -222,25 +363,25 @@ const handleDownload = () => {
|
|
|
</div>
|
|
|
</el-card>
|
|
|
<!-- 详情 -->
|
|
|
- <el-dialog v-model="dialogVisible" title="详情" @closed="resetForm" width="50%">
|
|
|
- <div>
|
|
|
- <h2>欢迎加入上海足球协会</h2>
|
|
|
- <p>时间:2024-02-0216:53至2024-12-31 20:53</p>
|
|
|
- <p>地点:上海市嘉定区安辰路999号</p>
|
|
|
- <img src="@/assets/image.png" width="100%" />
|
|
|
- <p>详情...</p>
|
|
|
- <h3>已报名 (12 人)</h3>
|
|
|
+ <el-dialog v-model="dialogVisible" title="详情" width="50%" top="5vh">
|
|
|
+ <div v-if="formData">
|
|
|
+ <h2>{{ formData.theme }}</h2>
|
|
|
+ <p>时间:{{ formData.startTime }}至{{ formData.endTime }}</p>
|
|
|
+ <p>地点:{{ formData.address }}</p>
|
|
|
+ <img v-if="formData.poster" :src="formData.poster" width="100%" />
|
|
|
+ <div class="rich" v-html="formData.themeDetail" />
|
|
|
+ <h3>已报名 ({{ formData?.reportDatas?.length }} 人)</h3>
|
|
|
<div class="user-list">
|
|
|
- <div class="user-item" v-for="(item, index) in 10" :key="index">
|
|
|
+ <div class="user-item" v-for="(item, index) in formData.reportDatas" :key="index">
|
|
|
<el-avatar :size="40" src="" />
|
|
|
- <span>姓名</span>
|
|
|
+ <span>{{ item.name }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <h3>签到人员 (12 人)</h3>
|
|
|
+ <h3>签到人员 ({{ formData?.signinDatas?.length }} 人)</h3>
|
|
|
<div class="user-list">
|
|
|
- <div class="user-item" v-for="(item, index) in 10" :key="index">
|
|
|
+ <div class="user-item" v-for="(item, index) in formData.signinDatas" :key="index">
|
|
|
<el-avatar :size="40" src="" />
|
|
|
- <span>姓名</span>
|
|
|
+ <span>{{ item.name }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -265,6 +406,12 @@ const handleDownload = () => {
|
|
|
justify-content: flex-end;
|
|
|
}
|
|
|
|
|
|
+.rich {
|
|
|
+ ::v-deep(img) {
|
|
|
+ height: 200px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
.user-list {
|
|
|
display: flex;
|
|
|
flex-wrap: wrap;
|