tangweijie bbf4c64391 feat(prison): 新增评估报告等前端页面,优化问卷与罪犯管理
核心变更:
1. 新增页面模块
   - 快捷评语管理 (quick-comment)
   - 报告模板管理 (report-template)
   - 评估报告编辑 (report)
   - 风险分析页面 (risk)
   - 预警管理 (warning)
   - 服刑情况跟踪 (situation)

2. 功能优化
   - 罪犯管理: 新增Workbench工作台页面
   - 问卷模块: 完善QuestionForm组件
   - 计分考核: 优化ScoreForm支持多种评分方式
   - 危险评估: 完善RiskAssessmentForm

3. UI改进
   - 登录页面: 新增监狱特色Loading动画
   - 罪犯详情: 优化展示效果
   - 消费记录: 增强查询功能

4. 基础设施
   - 新增JusticeIcon图标组件
   - 优化字典格式化工具
   - 更新路由配置

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-16 20:15:17 +08:00

274 lines
8.0 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>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="80px"
>
<el-form-item label="罪犯编号" prop="prisonerNo">
<el-input
v-model="queryParams.prisonerNo"
placeholder="请输入罪犯编号"
clearable
@keyup.enter="handleQuery"
class="!w-140px"
/>
</el-form-item>
<el-form-item label="罪犯姓名" prop="prisonerName">
<el-input
v-model="queryParams.prisonerName"
placeholder="请输入罪犯姓名"
clearable
@keyup.enter="handleQuery"
class="!w-120px"
/>
</el-form-item>
<el-form-item label="考核年份" prop="year">
<el-input
v-model="queryParams.year"
placeholder="请输入"
clearable
@keyup.enter="handleQuery"
class="!w-80px"
/>
</el-form-item>
<el-form-item label="考核等级" prop="level">
<el-select
v-model="queryParams.level"
placeholder="请选择"
clearable
class="!w-90px"
>
<el-option
v-for="dict in levelOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择"
clearable
class="!w-90px"
>
<el-option
v-for="dict in statusOptions"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button
type="primary"
plain
@click="openForm('create')"
v-hasPermi="['prison:score:create']"
>
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
<el-button
type="success"
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['prison:score:export']"
>
<Icon icon="ep:download" class="mr-5px" /> 导出
</el-button>
<el-button
type="danger"
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['prison:score:delete']"
>
<Icon icon="ep:delete" class="mr-5px" /> 批量删除
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
v-loading="loading"
:data="list"
@selection-change="handleRowCheckboxChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="记录ID" align="center" prop="id" width="80" />
<el-table-column label="罪犯姓名" align="center" prop="prisonerName" width="100" />
<el-table-column label="罪犯编号" align="center" prop="prisonerNo" width="120" />
<el-table-column label="监区" align="center" prop="prisonAreaName" width="100" />
<el-table-column label="监室" align="center" prop="prisonCellName" width="100" />
<el-table-column label="年份" align="center" prop="year" width="80" />
<el-table-column label="月份" align="center" prop="month" width="70" />
<el-table-column label="基础分" align="center" prop="baseScore" width="80" />
<el-table-column label="加分" align="center" prop="rewardScore" width="70" />
<el-table-column label="扣分" align="center" prop="penaltyScore" width="70" />
<el-table-column label="总分" align="center" prop="totalScore" width="80" />
<el-table-column label="考核等级" align="center" prop="level" width="90">
<template #default="scope">
<dict-tag :type="DICT_TYPE.PRISON_SCORE_LEVEL" :value="scope.row.level" />
</template>
</el-table-column>
<el-table-column label="考核人" align="center" prop="assessorName" width="100" />
<el-table-column label="状态" align="center" prop="status" width="90">
<template #default="scope">
<dict-tag :type="DICT_TYPE.PRISON_SCORE_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
<template #default="scope">
{{ formatDateTime(scope.row.createTime) }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="120" fixed="right">
<template #default="scope">
<el-button
type="primary"
link
@click="openForm('update', scope.row.id)"
v-hasPermi="['prison:score:update']"
>
修改
</el-button>
<el-button
type="danger"
link
@click="handleDelete(scope.row.id)"
v-hasPermi="['prison:score:delete']"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<ScoreForm ref="formRef" @success="getList" />
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { formatDateTime } from '@/utils/formatTime'
import download from '@/utils/download'
import { ScoreApi, Score } from '@/api/prison/score'
import ScoreForm from './ScoreForm.vue'
defineOptions({ name: 'Score' })
const message = useMessage()
const { t } = useI18n()
const loading = ref(true)
const list = ref<Score[]>([])
const total = ref(0)
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
prisonerNo: undefined,
prisonerName: undefined,
year: undefined,
level: undefined,
status: undefined
})
const queryFormRef = ref()
const exportLoading = ref(false)
// 使用字典获取选项
const levelOptions = getIntDictOptions(DICT_TYPE.PRISON_SCORE_LEVEL)
const statusOptions = getIntDictOptions(DICT_TYPE.PRISON_SCORE_STATUS)
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const data = await ScoreApi.getScorePage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
await message.delConfirm()
await ScoreApi.deleteScore(id)
message.success(t('common.delSuccess'))
await getList()
} catch {}
}
/** 批量删除按钮操作 */
const checkedIds = ref<number[]>([])
const handleRowCheckboxChange = (rows: Score[]) => {
checkedIds.value = rows.map((row) => row.id!)
}
const handleDeleteBatch = async () => {
try {
await message.delConfirm()
await ScoreApi.deleteScoreList(checkedIds.value)
checkedIds.value = []
message.success(t('common.delSuccess'))
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {
await message.exportConfirm()
exportLoading.value = true
const data = await ScoreApi.exportScore(queryParams)
download.excel(data, '计分考核.xls')
} catch {
} finally {
exportLoading.value = false
}
}
/** 初始化 */
onMounted(() => {
getList()
})
</script>