feat: 新增很多页面

This commit is contained in:
2026-01-14 01:06:25 +08:00
parent d437b4eded
commit 18f0fbce15
46 changed files with 7926 additions and 10 deletions

View File

@@ -0,0 +1,358 @@
<template>
<div class="layout-padding">
<div class="layout-padding-auto layout-padding-view">
<!-- 搜索表单 -->
<el-row v-show="showSearch">
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch">
<el-form-item label="楼号" prop="buildingNo">
<el-select
v-model="searchForm.buildingNo"
placeholder="请选择楼号"
clearable
filterable
style="width: 200px">
<el-option
v-for="item in buildingList"
:key="item.buildingNo"
:label="item.buildingNo"
:value="item.buildingNo">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="月份" prop="month">
<el-date-picker
v-model="searchForm.month"
type="month"
placeholder="请选择月份"
format="YYYY-MM"
value-format="YYYY-MM"
clearable
style="width: 200px" />
</el-form-item>
<el-form-item label="班号" prop="classCode">
<el-select
v-model="searchForm.classCode"
placeholder="请选择班号"
clearable
filterable
style="width: 200px">
<el-option
v-for="item in classList"
:key="item.classCode"
:label="item.classNo"
:value="item.classCode">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" plain icon="Search" @click="handleSearch">查询</el-button>
<el-button icon="Refresh" @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</el-row>
<!-- 操作按钮 -->
<el-row>
<div class="mb8" style="width: 100%">
<right-toolbar
v-model:showSearch="showSearch"
class="ml10 mr20"
style="float: right;"
@queryTable="getDataList">
</right-toolbar>
</div>
</el-row>
<!-- 表格 -->
<el-table
:data="state.dataList"
v-loading="state.loading"
border
:cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle"
@sort-change="sortChangeHandle">
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column prop="totalScore" label="总分" show-overflow-tooltip align="center" />
<el-table-column prop="rank" label="排名" show-overflow-tooltip align="center" />
<el-table-column prop="classNo" label="班级" show-overflow-tooltip />
<!-- 动态日期列 -->
<el-table-column
v-for="day in dayColumns"
:key="day"
:prop="`day${day}`"
:label="`${day}日`"
show-overflow-tooltip
align="center"
width="80" />
<el-table-column label="操作" width="150" align="center" fixed="right">
<template #default="scope">
<el-button
icon="Plus"
text
type="success"
@click="handleAddScore(scope.row)">
加分
</el-button>
<el-button
icon="Minus"
text
type="danger"
@click="handleSubtractScore(scope.row)">
减分
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 此接口不支持分页不显示分页组件 -->
</div>
<!-- 加分/减分对话框 -->
<el-dialog
v-model="scoreDialogVisible"
:title="scoreDialogTitle"
:close-on-click-modal="false"
draggable
width="500px">
<el-form
ref="scoreFormRef"
:model="scoreForm"
label-width="100px">
<el-form-item label="班级" prop="classNo">
<el-input
v-model="scoreForm.classNo"
disabled />
</el-form-item>
<el-form-item label="日期" prop="date">
<el-date-picker
v-model="scoreForm.date"
type="date"
placeholder="请选择日期"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
style="width: 100%" />
</el-form-item>
<el-form-item label="分数" prop="score">
<el-input-number
v-model="scoreForm.score"
:precision="0"
:step="1"
:min="0"
placeholder="请输入分数"
style="width: 100%" />
</el-form-item>
<el-form-item label="说明" prop="note">
<el-input
v-model="scoreForm.note"
type="textarea"
:rows="3"
placeholder="请输入说明"
maxlength="500"
show-word-limit />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="scoreDialogVisible = false"> </el-button>
<el-button type="primary" @click="submitScore"> </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts" name="ClassHygieneDailyAnalysis">
import { ref, reactive, defineAsyncComponent, onMounted, computed } from 'vue'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { fetchList } from "/@/api/stuwork/classhygienedailyanalysis";
import { useMessage } from "/@/hooks/message";
import { getClassListByRole } from '/@/api/basic/basicclass'
import { getBuildingList } from '/@/api/stuwork/dormbuilding'
// 定义变量内容
const searchFormRef = ref()
const scoreFormRef = ref()
// 搜索变量
const showSearch = ref(true)
const classList = ref<any[]>([])
const buildingList = ref<any[]>([])
const scoreDialogVisible = ref(false)
const scoreDialogTitle = ref('加分')
const isAddScore = ref(true) // true: 加分, false: 减分
// 加分/减分表单
const scoreForm = reactive({
classCode: '',
classNo: '',
date: '',
score: 0,
note: ''
})
// 搜索表单
const searchForm = reactive({
buildingNo: '',
month: '',
classCode: ''
})
// 计算月份的天数列
const dayColumns = computed(() => {
if (!searchForm.month) {
return []
}
const [year, month] = searchForm.month.split('-').map(Number)
const daysInMonth = new Date(year, month, 0).getDate()
return Array.from({ length: daysInMonth }, (_, i) => i + 1)
})
// 配置 useTable - 需要将月份转换为开始和结束时间,且不传分页参数
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: searchForm,
pageList: async (queryParams: any) => {
// 如果选择了月份,转换为开始和结束时间
const params: any = {}
// 如果选择了月份,转换为开始和结束时间
if (searchForm.month) {
const [year, month] = searchForm.month.split('-').map(Number)
const daysInMonth = new Date(year, month, 0).getDate()
params.startTime = `${year}-${String(month).padStart(2, '0')}-01`
params.endTime = `${year}-${String(month).padStart(2, '0')}-${String(daysInMonth).padStart(2, '0')}`
}
// 如果选择了班号转换为数组格式接口要求classCode是数组
if (searchForm.classCode) {
params.classCode = Array.isArray(searchForm.classCode) ? searchForm.classCode : [searchForm.classCode]
}
// 楼号参数 - 接口文档中没有buildingNo参数可能需要通过其他方式处理
// 暂时不传递buildingNo如果需要可以后续添加
// 不传递分页参数current、size
return await fetchList(params)
},
props: {
item: 'records',
totalCount: 'total'
},
createdIsNeed: false // 不自动加载,需要手动调用
})
// table hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
sortChangeHandle,
tableStyle
} = useTable(state)
// 查询
const handleSearch = () => {
if (!searchForm.month) {
useMessage().warning('请选择月份')
return
}
getDataList()
}
// 重置
const handleReset = () => {
searchFormRef.value?.resetFields()
searchForm.buildingNo = ''
searchForm.month = ''
searchForm.classCode = ''
getDataList()
}
// 加分
const handleAddScore = (row: any) => {
isAddScore.value = true
scoreDialogTitle.value = '加分'
Object.assign(scoreForm, {
classCode: row.classCode || '',
classNo: row.classNo || '',
date: '',
score: 0,
note: ''
})
scoreDialogVisible.value = true
}
// 减分
const handleSubtractScore = (row: any) => {
isAddScore.value = false
scoreDialogTitle.value = '减分'
Object.assign(scoreForm, {
classCode: row.classCode || '',
classNo: row.classNo || '',
date: '',
score: 0,
note: ''
})
scoreDialogVisible.value = true
}
// 提交加分/减分
const submitScore = async () => {
if (!scoreForm.date) {
useMessage().warning('请选择日期')
return
}
if (!scoreForm.score || scoreForm.score <= 0) {
useMessage().warning('请输入有效的分数')
return
}
try {
// TODO: 调用加分/减分接口
// const api = isAddScore.value ? addScore : subtractScore
// await api(scoreForm)
useMessage().success(isAddScore.value ? '加分成功' : '减分成功')
scoreDialogVisible.value = false
getDataList()
} catch (err: any) {
useMessage().error(err.msg || (isAddScore.value ? '加分失败' : '减分失败'))
}
}
// 获取班号列表
const getClassListData = async () => {
try {
const res = await getClassListByRole()
if (res.data) {
classList.value = Array.isArray(res.data) ? res.data : []
}
} catch (err) {
console.error('获取班号列表失败', err)
classList.value = []
}
}
// 获取楼号列表
const getBuildingListData = async () => {
try {
const res = await getBuildingList()
if (res.data) {
// 处理返回的数据,可能是分页数据
if (res.data.records) {
buildingList.value = Array.isArray(res.data.records) ? res.data.records : []
} else if (Array.isArray(res.data)) {
buildingList.value = res.data
} else {
buildingList.value = []
}
}
} catch (err) {
console.error('获取楼号列表失败', err)
buildingList.value = []
}
}
// 初始化
onMounted(() => {
getClassListData()
getBuildingListData()
})
</script>