Files
school-developer/src/views/stuwork/dormhygieneevalrule/index.vue
吴红兵 b997b3ba48 fix
2026-03-07 12:35:45 +08:00

451 lines
14 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="modern-page-container">
<div class="page-wrapper">
<!-- 搜索表单卡片 -->
<el-card v-show="showSearch" class="search-card" shadow="never">
<template #header>
<div class="card-header">
<span class="card-title">
<el-icon class="title-icon"><Search /></el-icon>
筛选条件
</span>
</div>
</template>
<el-form :model="searchForm" ref="searchFormRef" :inline="true" @keyup.enter="handleSearch" class="search-form">
<el-form-item label="规则名称" prop="ruleName">
<el-input v-model="searchForm.ruleName" placeholder="请输入规则名称" clearable style="width: 200px" />
</el-form-item>
<el-form-item label="规则类型" prop="ruleType">
<el-select v-model="searchForm.ruleType" placeholder="请选择规则类型" clearable style="width: 150px">
<el-option label="加分规则" value="1" />
<el-option label="扣分规则" value="2" />
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="searchForm.status" placeholder="请选择状态" clearable style="width: 120px">
<el-option label="启用" value="1" />
<el-option label="禁用" value="0" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleSearch">查询</el-button>
<el-button icon="Refresh" @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<!-- 内容卡片 -->
<el-card class="content-card" shadow="never">
<template #header>
<div class="card-header">
<span class="card-title">
<el-icon class="title-icon"><Setting /></el-icon>
评比规则列表
</span>
<div class="header-actions">
<el-button type="primary" icon="Plus" @click="handleAdd">新增</el-button>
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
</div>
</div>
</template>
<!-- 表格 -->
<el-table
:data="dataList"
v-loading="loading"
stripe
:cell-style="tableStyle.cellStyle"
:header-cell-style="tableStyle.headerCellStyle"
class="modern-table"
>
<el-table-column type="index" label="序号" width="70" align="center">
<template #default="{ $index }">
{{ (page.currentPage - 1) * page.pageSize + $index + 1 }}
</template>
</el-table-column>
<el-table-column prop="ruleCode" label="规则编码" min-width="120" />
<el-table-column prop="ruleName" label="规则名称" min-width="150" />
<el-table-column prop="ruleType" label="规则类型" width="100" align="center">
<template #default="{ row }">
<el-tag :type="row.ruleType === '1' ? 'success' : 'danger'" size="small">
{{ row.ruleType === '1' ? '加分' : '扣分' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="rankCondition" label="排名条件" width="120" align="center">
<template #default="{ row }">
<el-tag type="info" size="small">
{{ formatRankCondition(row.rankCondition) }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="rankValue" label="排名值" width="80" align="center">
<template #default="{ row }">
{{ row.rankCondition === '3' ? '-' : row.rankValue + '%' }}
</template>
</el-table-column>
<el-table-column prop="evalScore" label="考核分数" width="100" align="center">
<template #default="{ row }">
<span :style="{ color: row.evalScore > 0 ? '#67c23a' : '#f56c6c' }"> {{ row.evalScore > 0 ? '+' : '' }}{{ row.evalScore }} </span>
</template>
</el-table-column>
<el-table-column prop="priority" label="优先级" width="80" align="center" />
<el-table-column prop="status" label="状态" width="80" align="center">
<template #default="{ row }">
<el-switch v-model="row.status" active-value="1" inactive-value="0" @change="handleStatusChange(row)" />
</template>
</el-table-column>
<el-table-column prop="remark" label="规则说明" min-width="200" show-overflow-tooltip />
<el-table-column label="操作" width="150" align="center" fixed="right">
<template #default="{ row }">
<el-button icon="Edit" link type="primary" @click="handleEdit(row)">编辑</el-button>
<el-button icon="Delete" link type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-pagination
v-model:current-page="page.currentPage"
v-model:page-size="page.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="page.total"
layout="total, sizes, prev, pager, next, jumper"
class="pagination"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-card>
</div>
<!-- 新增/编辑弹窗 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="650px" :close-on-click-modal="false">
<el-form :model="form" ref="formRef" :rules="rules" label-width="100px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="规则编码" prop="ruleCode">
<el-input v-model="form.ruleCode" placeholder="请输入规则编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="规则名称" prop="ruleName">
<el-input v-model="form.ruleName" placeholder="请输入规则名称" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="规则类型" prop="ruleType">
<el-select v-model="form.ruleType" placeholder="请选择规则类型" style="width: 100%">
<el-option label="加分规则" value="1" />
<el-option label="扣分规则" value="2" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="排名条件" prop="rankCondition">
<el-select v-model="form.rankCondition" placeholder="请选择排名条件" style="width: 100%" @change="handleRankConditionChange">
<el-option label="前N%" value="1" />
<el-option label="后N%" value="2" />
<el-option label="分数区间" value="3" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12" v-if="form.rankCondition !== '3'">
<el-form-item label="排名值" prop="rankValue">
<el-input-number v-model="form.rankValue" :min="1" :max="100" placeholder="请输入排名值" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.rankCondition === '3'">
<el-form-item label="最高分数" prop="scoreMax">
<el-input-number v-model="form.scoreMax" :min="0" :max="100" :precision="2" placeholder="最高分数" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="考核分数" prop="evalScore">
<el-input-number v-model="form.evalScore" :min="-10" :max="10" :precision="2" placeholder="请输入考核分数" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="整改上限" prop="reformLimit">
<el-input-number v-model="form.reformLimit" :min="-1" :max="10" placeholder="-1表示不限" style="width: 100%" />
<div class="form-tip">宿舍整改次数上限-1表示不限制</div>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="优先级" prop="priority">
<el-input-number v-model="form.priority" :min="0" :max="100" placeholder="数字越大优先级越高" style="width: 100%" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="生效月份" prop="effectiveMonths">
<el-checkbox-group v-model="effectiveMonthList">
<el-checkbox v-for="m in 12" :key="m" :label="String(m)">{{ m }}</el-checkbox>
</el-checkbox-group>
<div class="form-tip">不选择表示全年生效</div>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="规则说明" prop="remark">
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入规则说明" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm" :loading="submitLoading">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup lang="ts" name="DormHygieneEvalRule">
import { reactive, ref, onMounted, computed } from 'vue';
import { fetchList, addObj, editObj, delObj } from '/@/api/stuwork/dormhygieneevalrule';
import { useMessage } from '/@/hooks/message';
import { Search, Setting, Plus, Edit, Delete } from '@element-plus/icons-vue';
// 定义变量内容
const searchFormRef = ref();
const formRef = ref();
const showSearch = ref(true);
const loading = ref(false);
const submitLoading = ref(false);
const dataList = ref<any[]>([]);
const dialogVisible = ref(false);
const dialogTitle = ref('新增评比规则');
const effectiveMonthList = ref<string[]>([]);
// 分页
const page = reactive({
currentPage: 1,
pageSize: 20,
total: 0,
});
// 搜索表单
const searchForm = reactive({
ruleName: '',
ruleType: '',
status: '',
});
// 表单
const form = reactive({
id: '',
ruleCode: '',
ruleName: '',
ruleType: '1',
rankCondition: '1',
rankValue: 20,
scoreMax: null as number | null,
evalScore: 1,
reformLimit: -1,
effectiveMonths: '',
priority: 10,
remark: '',
});
// 表单校验规则
const rules = {
ruleCode: [{ required: true, message: '请输入规则编码', trigger: 'blur' }],
ruleName: [{ required: true, message: '请输入规则名称', trigger: 'blur' }],
ruleType: [{ required: true, message: '请选择规则类型', trigger: 'change' }],
rankCondition: [{ required: true, message: '请选择排名条件', trigger: 'change' }],
evalScore: [{ required: true, message: '请输入考核分数', trigger: 'blur' }],
};
// 表格样式
const tableStyle = {
cellStyle: { textAlign: 'center' },
headerCellStyle: {
textAlign: 'center',
background: 'var(--el-table-row-hover-bg-color)',
color: 'var(--el-text-color-primary)',
},
};
// 格式化排名条件
const formatRankCondition = (value: string) => {
const map: Record<string, string> = {
'1': '前N%',
'2': '后N%',
'3': '分数区间',
};
return map[value] || value;
};
// 排名条件改变
const handleRankConditionChange = () => {
if (form.rankCondition === '3') {
form.rankValue = 0;
form.scoreMax = 59.99;
} else {
form.scoreMax = null;
}
};
// 查询
const handleSearch = () => {
page.currentPage = 1;
getDataList();
};
// 重置
const handleReset = () => {
searchFormRef.value?.resetFields();
getDataList();
};
// 分页
const handleSizeChange = (val: number) => {
page.pageSize = val;
getDataList();
};
const handleCurrentChange = (val: number) => {
page.currentPage = val;
getDataList();
};
// 获取数据列表
const getDataList = async () => {
loading.value = true;
try {
const res = await fetchList({
current: page.currentPage,
size: page.pageSize,
...searchForm,
});
if (res.data && res.data.records) {
dataList.value = res.data.records;
page.total = res.data.total;
} else {
dataList.value = [];
page.total = 0;
}
} catch (err: any) {
useMessage().error(err.msg || '获取数据失败');
} finally {
loading.value = false;
}
};
// 新增
const handleAdd = () => {
resetForm();
dialogTitle.value = '新增评比规则';
dialogVisible.value = true;
};
// 编辑
const handleEdit = (row: any) => {
resetForm();
dialogTitle.value = '编辑评比规则';
Object.assign(form, row);
// 解析生效月份
if (row.effectiveMonths) {
effectiveMonthList.value = row.effectiveMonths.split(',');
} else {
effectiveMonthList.value = [];
}
dialogVisible.value = true;
};
// 删除
const handleDelete = async (row: any) => {
try {
await useMessage().confirm('确定要删除该规则吗?');
await delObj([row.id]);
useMessage().success('删除成功');
getDataList();
} catch (err: any) {
if (err !== 'cancel') {
useMessage().error(err.msg || '删除失败');
}
}
};
// 状态切换
const handleStatusChange = async (row: any) => {
try {
await editObj(row);
useMessage().success('状态更新成功');
} catch (err: any) {
useMessage().error(err.msg || '状态更新失败');
row.status = row.status === '1' ? '0' : '1';
}
};
// 重置表单
const resetForm = () => {
Object.assign(form, {
id: '',
ruleCode: '',
ruleName: '',
ruleType: '1',
rankCondition: '1',
rankValue: 20,
scoreMax: null,
evalScore: 1,
reformLimit: -1,
effectiveMonths: '',
priority: 10,
remark: '',
});
effectiveMonthList.value = [];
};
// 提交表单
const submitForm = async () => {
try {
await formRef.value?.validate();
submitLoading.value = true;
// 组装生效月份
form.effectiveMonths = effectiveMonthList.value.join(',');
// 组装关联条件
if (form.reformLimit >= 0) {
form.relatedCondition = JSON.stringify({ reformLimit: form.reformLimit });
}
if (form.id) {
await editObj(form);
useMessage().success('修改成功');
} else {
await addObj(form);
useMessage().success('新增成功');
}
dialogVisible.value = false;
getDataList();
} catch (err: any) {
if (err !== false) {
useMessage().error(err.msg || '操作失败');
}
} finally {
submitLoading.value = false;
}
};
// 初始化
onMounted(() => {
getDataList();
});
</script>
<style scoped lang="scss">
@import '/@/assets/styles/modern-page.scss';
.form-tip {
font-size: 12px;
color: #999;
margin-top: 4px;
}
</style>