| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429 |
- <template>
- <div class="app-container">
- <el-card>
- <!-- 第一行:科室班组个人按钮组 -->
- <div class="filter-container">
- <div class="button-group">
- <span class="button-group-label">查询范围:</span>
- <el-button v-for="item in queryTypeOptions" :key="item.value"
- :type="queryType === item.value ? 'primary' : 'default'"
- :class="queryType === item.value ? 'active' : 'inactive'" @click="handleQueryTypeChange(item.value)">
- {{ item.label }}
- </el-button>
- </div>
- <div class="button-group" style="margin-left: 20px;">
- <span class="button-group-label">时间范围:</span>
- <el-button v-for="item in timeRangeOptions" :key="item.value"
- :type="timeRange === item.value ? 'primary' : 'default'"
- :class="timeRange === item.value ? 'active' : 'inactive'" @click="handleTimeRangeChange(item.value)">
- {{ item.label }}
- </el-button>
- <!-- 自定义时间范围选择器 -->
- <el-date-picker v-if="timeRange === 'custom'" v-model="customDateRange" type="daterange" range-separator="至"
- start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD"
- style="margin-left: 10px; width: 240px;" @change="handleCustomDateChange" />
- </div>
- </div>
- <!-- 第二行:查询条件 -->
- <el-form :model="queryParams" ref="queryFormRef" :inline="true" class="search-form">
- <el-form-item label="主管" prop="deptId" v-if="queryType === '2' || queryType === '1'">
- <el-select v-model="queryParams.deptId" placeholder="请选择主管" clearable style="width: 200px"
- @change="handleQuery">
- <el-option v-for="item in departmentOptions" :key="item.value" :label="item.text" :value="item.value" />
- </el-select>
- </el-form-item>
- <el-form-item label="班组" prop="teamId" v-if="queryType === '2' || queryType === '1'">
- <el-select v-model="queryParams.teamId" placeholder="请选择班组" clearable style="width: 200px"
- @change="handleQuery">
- <el-option v-for="item in teamOptions" :key="item.value" :label="item.text" :value="item.value" />
- </el-select>
- </el-form-item>
- <el-form-item label="姓名" prop="userName" v-if="queryType === '1'">
- <el-input v-model="queryParams.userName" placeholder="请输入姓名" clearable style="width: 200px"
- @input="handleQuery" />
- </el-form-item>
- <!-- <el-form-item>
- <el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
- <el-button icon="Refresh" @click="resetQuery">重置</el-button>
- </el-form-item> -->
- </el-form>
- <!-- 导出按钮 -->
- <div class="export-container">
- <el-button type="warning" icon="Download" @click="handleExport">导出</el-button>
- </div>
- <!-- 表格 -->
- <el-table v-loading="loading" :data="performanceList" border fit highlight-current-row
- style="width: 100%; margin-top: 20px;">
- <!-- 动态列 -->
- <el-table-column v-if="queryType === '3' || queryType === '2' || queryType === '1'" label="主管"
- :prop="queryType === '3' ? 'name' : 'deptName'" align="center" min-width="120" />
- <el-table-column v-if="queryType === '2' || queryType === '1'" label="班组"
- :prop="queryType === '2' ? 'name' : 'className'" align="center" min-width="120" />
- <el-table-column v-if="queryType === '1'" label="姓名" prop="name" align="center" min-width="100" />
- <!-- 固定列 -->
- <el-table-column label="总分" prop="totalScore" align="center" min-width="100" sortable
- :sort-orders="['ascending', 'descending']" @sort-change="handleSortChange('totalScore', $event)" />
- <el-table-column label="查获效率" prop="seizureEfficiency" align="center" min-width="120" sortable
- :sort-orders="['ascending', 'descending']" @sort-change="handleSortChange('seizureEfficiency', $event)" />
- <el-table-column label="抽问抽答正确率" prop="trainingScore" align="center" min-width="100" sortable
- :sort-orders="['ascending', 'descending']" @sort-change="handleSortChange('trainingScore', $event)" />
- <el-table-column label="巡检合格率" prop="inspectionPassRate" align="center" min-width="120" sortable
- :sort-orders="['ascending', 'descending']" @sort-change="handleSortChange('inspectionPassRate', $event)" />
- </el-table>
- <!-- 分页 -->
- <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
- v-model:limit="queryParams.pageSize" @pagination="getList" />
- </el-card>
- </div>
- </template>
- <script setup>
- import { ref, reactive, onMounted, getCurrentInstance, watch } from 'vue'
- import { getPerformanceList } from '@/api/performance/performance.js'
- import { listDept } from '@/api/system/dept.js'
- import { getDownload } from '@/utils/request.js'
- // 查询类型选项
- const queryTypeOptions = [
- { label: '主管', value: '3' },
- { label: '班组', value: '2' },
- { label: '个人', value: '1' }
- ]
- // 时间范围选项
- const timeRangeOptions = [
- { label: '近三个月', value: 'threeMonths' },
- { label: '近六个月', value: 'sixMonths' },
- { label: '自定义', value: 'custom' }
- ]
- // 响应式数据
- const queryType = ref('3') // 默认查询科室
- const timeRange = ref('threeMonths') // 默认近三个月
- const customDateRange = ref([])
- const loading = ref(false)
- const total = ref(0)
- const queryFormRef = ref()
- // 查询参数
- const queryParams = reactive({
- pageNum: 1,
- pageSize: 10,
- deptId: '',
- teamId: '',
- userName: '',
- sortField: '',
- sortOrder: ''
- })
- // 绩效数据列表
- const performanceList = ref([])
- // 部门数据
- const deptList = ref([])
- const departmentOptions = ref([])
- const teamOptions = ref([])
- // 监听科室变化,获取对应班组
- watch(() => queryParams.deptId, async (newDeptId) => {
- if (newDeptId) {
- await fetchTeamByDept(newDeptId)
- } else {
- // 如果清空科室选择,重置班组选项为所有班组
- teamOptions.value = deptList.value.filter(item => item.deptType === 'TEAMS').map(item => ({
- value: item.deptId,
- text: item.deptName
- }))
- queryParams.teamId = '' // 清空班组选择
- }
- })
- // 获取部门数据
- const fetchDeptData = async () => {
- try {
- const response = await listDept({})
- if (response.code === 200) {
- deptList.value = response.data || []
- // 生成科室选项
- departmentOptions.value = deptList.value.filter(item => item.deptType === 'MANAGER').map(item => ({
- value: item.deptId,
- text: item.deptName
- }))
- // 生成班组选项
- teamOptions.value = deptList.value.filter(item => item.deptType === 'TEAMS').map(item => ({
- value: item.deptId,
- text: item.deptName
- }))
- }
- } catch (error) {
- console.error('获取部门数据失败:', error)
- }
- }
- // 根据科室ID获取班组列表
- const fetchTeamByDept = async (deptId) => {
- try {
- const response = await listDept({ parentId: deptId })
- if (response.code === 200 && response.data) {
- teamOptions.value = response.data.map(item => ({
- value: item.deptId,
- text: item.deptName
- }))
- // 清空班组选择,让用户重新选择
- queryParams.teamId = ''
- }
- } catch (error) {
- console.error('获取班组列表失败:', error)
- // 如果获取失败,重置为所有班组
- teamOptions.value = deptList.value.filter(item => item.deptType === 'TEAMS').map(item => ({
- value: item.deptId,
- text: item.deptName
- }))
- }
- }
- // 查询类型变化
- const handleQueryTypeChange = (type) => {
- queryType.value = type
- getList()
- }
- // 时间范围变化
- const handleTimeRangeChange = (range) => {
- timeRange.value = range
- if (range !== 'custom') {
- getList()
- }
- }
- // 格式化日期为 YYYY-MM-DD
- const formatDate = (date) => {
- const year = date.getFullYear()
- const month = String(date.getMonth() + 1).padStart(2, '0')
- const day = String(date.getDate()).padStart(2, '0')
- return `${year}-${month}-${day}`
- }
- // 计算时间范围
- const calculateTimeRange = (range) => {
- const now = new Date()
- const startTime = new Date()
- switch (range) {
- case 'threeMonths':
- startTime.setMonth(now.getMonth() - 3)
- break
- case 'sixMonths':
- startTime.setMonth(now.getMonth() - 6)
- break
- case 'custom':
- if (customDateRange.value && customDateRange.value.length === 2) {
- // 结束时间加一天
- const endDate = new Date(customDateRange.value[1])
- endDate.setDate(endDate.getDate() + 1)
- return {
- startTime: customDateRange.value[0],
- endTime: formatDate(endDate)
- }
- }
- return { startTime: '', endTime: '' }
- default:
- return { startTime: '', endTime: '' }
- }
- return {
- startTime: formatDate(startTime),
- endTime: formatDate(now)
- }
- }
- // 自定义时间范围变化
- const handleCustomDateChange = () => {
- if (customDateRange.value && customDateRange.value.length === 2) {
- getList()
- }
- }
- // 排序处理
- const handleSortChange = (field, { order }) => {
- queryParams.sortField = field
- queryParams.sortOrder = order === 'ascending' ? 'asc' : 'desc'
- getList()
- }
- // 查询
- const handleQuery = () => {
- queryParams.pageNum = 1
- getList()
- }
- // 重置查询
- const resetQuery = () => {
- queryFormRef.value.resetFields()
- queryParams.pageNum = 1
- queryParams.sortField = ''
- queryParams.sortOrder = ''
- getList()
- }
- // 获取绩效列表
- const getList = async () => {
- loading.value = true
- try {
- // 计算时间范围
- const timeRangeParams = calculateTimeRange(timeRange.value)
- // 构建请求参数
- const params = {
- ...queryParams,
- dimension: queryType.value,
- ...timeRangeParams
- }
- // 根据查询类型清理不必要的参数
- if (queryType.value === '3') {
- // 科室查询:不需要班组参数
- params.teamId = ''
- params.deptId = ''
- } else if (queryType.value === '2') {
- // 班组查询:需要科室参数
- // params.deptId = ''
- // 班组查询:不需要个人参数
- } else if (queryType.value === '1') {
- // 个人查询:需要所有参数
- }
- // 调用API
- const response = await getPerformanceList(params)
- if (response.code === 200) {
- performanceList.value = response.data || []
- total.value = response.total || 0
- } else {
- console.error('获取绩效列表失败:', response.msg)
- performanceList.value = []
- total.value = 0
- }
- } catch (error) {
- console.error('获取绩效列表异常:', error)
- performanceList.value = []
- total.value = 0
- } finally {
- loading.value = false
- }
- }
- // 获取当前实例
- const { proxy } = getCurrentInstance()
- // 导出
- const handleExport = () => {
- try {
- // 计算时间范围
- const timeRangeParams = calculateTimeRange(timeRange.value)
- // 构建请求参数
- const params = {
- ...queryParams,
- dimension: queryType.value,
- ...timeRangeParams
- }
- // 根据查询类型清理不必要的参数
- if (queryType.value === '3') {
- // 科室查询:不需要班组参数
- params.teamId = ''
- } else if (queryType.value === '2') {
- // 班组查询:不需要个人参数
- } else if (queryType.value === '1') {
- // 个人查询:需要所有参数
- }
- // 使用proxy.getDownload下载文件(GET请求)
- getDownload('/item/indicators/export', params, `绩效查询数据_${new Date().getTime()}.xlsx`)
- } catch (error) {
- console.error('导出异常:', error)
- proxy.$modal.msgError('导出异常,请重试')
- }
- }
- onMounted(() => {
- fetchDeptData()
- getList()
- })
- </script>
- <style lang="less" scoped>
- .app-container {
- padding: 20px;
- }
- .filter-container {
- display: flex;
- align-items: center;
- margin-bottom: 20px;
- }
- .button-group {
- display: flex;
- align-items: center;
- .button-group-label {
- margin-right: 10px;
- font-weight: 600;
- color: #606266;
- }
- .el-button {
- margin-right: 10px;
- &.active {
- background-color: #409EFF;
- border-color: #409EFF;
- color: #fff;
- }
- &.inactive {
- background-color: #fff;
- border-color: #409EFF;
- color: #409EFF;
- }
- }
- }
- .search-form {
- margin-bottom: 20px;
- }
- .export-container {
- margin-bottom: 20px;
- }
- :deep(.el-table) {
- .el-table__header-wrapper {
- th {
- background-color: #f5f7fa;
- font-weight: 600;
- }
- }
- }
- </style>
|