tangweijie 4bac14276a 重构评估报告模块为评估管理模块
- 重命名report为evaluation-report,更新相关API接口
- 重构评估模板、评估维度、评估报告、快捷评语等模块
- 新增评估管理页面,包含模板配置、维度管理、报告生成等功能
- 更新囚犯工作台,增加评估报告相关功能
- 删除旧的report相关组件
2026-01-19 22:19:23 +08:00

275 lines
8.6 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>
<el-dialog
v-model="dialogVisible"
title="新建评估报告"
width="600px"
:close-on-click-modal="false"
>
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="100px"
>
<el-form-item label="选择罪犯" prop="prisonerId">
<el-select
v-model="formData.prisonerId"
placeholder="请选择罪犯"
filterable
class="!w-full"
@change="handlePrisonerChange"
>
<el-option
v-for="prisoner in prisonerOptions"
:key="prisoner.id"
:label="`${prisoner.name} (${prisoner.prisonerNo})`"
:value="prisoner.id"
/>
</el-select>
</el-form-item>
<el-form-item label="罪犯编号">
<el-input v-model="formData.prisonerNo" disabled />
</el-form-item>
<el-form-item label="选择模板" prop="templateId">
<el-select
v-model="formData.templateId"
placeholder="请选择评估模板"
class="!w-full"
@change="handleTemplateChange"
>
<el-option
v-for="template in templateOptions"
:key="template.id"
:label="template.name"
:value="template.id"
/>
</el-select>
</el-form-item>
<el-form-item label="模板类型">
<el-input :value="getTemplateTypeLabel(formData.templateType)" disabled />
</el-form-item>
<el-form-item label="报告标题" prop="title">
<el-input v-model="formData.title" placeholder="请输入报告标题" />
</el-form-item>
<el-form-item label="评估日期" prop="evaluationDate">
<el-date-picker
v-model="formData.evaluationDate"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择评估日期"
class="!w-full"
/>
</el-form-item>
<el-form-item label="评估周期">
<el-input :value="getEvaluationCycleLabel(formData.evaluationCycle)" disabled />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">确定</el-button>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { EvaluationTemplateApi, EvaluationReportApi } from '@/api/prison/evaluation'
import { PrisonerSelectApi } from '@/api/prison/report'
import { PrisonerApi } from '@/api/prison/prisoner'
import { useMessage } from '@/hooks/web/useMessage'
defineOptions({ name: 'CreateReportDialog' })
const { message } = useMessage()
const emit = defineEmits(['success'])
const dialogVisible = ref(false)
const submitLoading = ref(false)
const formRef = ref()
const formData = reactive({
prisonerId: undefined as number | undefined,
prisonerNo: '',
prisonerName: '',
templateId: undefined as number | undefined,
templateName: '',
templateType: undefined as number | undefined,
evaluationCycle: undefined as number | undefined,
title: '',
evaluationDate: ''
})
const rules = {
prisonerId: [{ required: true, message: '请选择罪犯', trigger: 'change' }],
templateId: [{ required: true, message: '请选择模板', trigger: 'change' }],
title: [{ required: true, message: '报告标题不能为空', trigger: 'blur' }],
evaluationDate: [{ required: true, message: '请选择评估日期', trigger: 'change' }]
}
const prisonerOptions = ref<any[]>([])
const templateOptions = ref<any[]>([])
const templateTypeOptions = getIntDictOptions(DICT_TYPE.EVALUATION_TEMPLATE_TYPE)
const evaluationCycleOptions = getIntDictOptions(DICT_TYPE.PRISON_EVALUATION_CYCLE)
/** 打开弹窗 */
const open = (prisonerId?: number) => {
dialogVisible.value = true
resetForm()
loadOptions()
// 如果传入了罪犯ID自动填充
if (prisonerId) {
formData.prisonerId = prisonerId
// 延迟加载罪犯详情
loadPrisonerInfo(prisonerId)
}
}
/** 加载罪犯信息 */
const loadPrisonerInfo = async (id: number) => {
try {
const data = await PrisonerApi.get(id)
if (data) {
formData.prisonerNo = data.prisonerNo
formData.prisonerName = data.name
// 自动生成标题
if (data.name && formData.templateName) {
formData.title = `${data.name}${formData.templateName}`
}
}
} catch (error) {
console.error('加载服刑人员信息失败:', error)
message.error('加载服刑人员信息失败')
}
}
/** 重置表单 */
const resetForm = () => {
formData.prisonerId = undefined
formData.prisonerNo = ''
formData.prisonerName = ''
formData.templateId = undefined
formData.templateName = ''
formData.templateType = undefined
formData.evaluationCycle = undefined
formData.title = ''
formData.evaluationDate = ''
}
/** 加载选项数据 */
const loadOptions = async () => {
// 加载罪犯列表
const prisonerData = await PrisonerSelectApi.getPrisonerPage({ pageNo: 1, pageSize: 100 })
prisonerOptions.value = prisonerData.list
// 加载模板列表
const templateData = await EvaluationTemplateApi.getEnabledTemplateList()
templateOptions.value = templateData
}
/** 罪犯选择变化 */
const handlePrisonerChange = (prisonerId: number) => {
const prisoner = prisonerOptions.value.find((p) => p.id === prisonerId)
if (prisoner) {
formData.prisonerNo = prisoner.prisonerNo
formData.prisonerName = prisoner.name
// 自动生成标题
if (prisoner.name && formData.templateName) {
formData.title = `${prisoner.name}${formData.templateName}`
}
}
}
/** 模板选择变化 */
const handleTemplateChange = (templateId: number) => {
const template = templateOptions.value.find((t) => t.id === templateId)
if (template) {
formData.templateName = template.name
formData.templateType = template.type
formData.evaluationCycle = template.evaluationCycle
// 自动生成标题
if (formData.prisonerName && template.name) {
formData.title = `${formData.prisonerName}${template.name}`
}
}
}
/** 获取模板类型标签 */
const getTemplateTypeLabel = (type: number | undefined): string => {
if (!type) return '-'
const option = templateTypeOptions.find((t) => t.value === type)
return option ? option.label : '-'
}
/** 获取评估周期标签 */
const getEvaluationCycleLabel = (cycle: number | undefined): string => {
if (!cycle) return '-'
const option = evaluationCycleOptions.find((c) => c.value === cycle)
return option ? option.label : '-'
}
/** 提交 */
const handleSubmit = async () => {
try {
// 验证表单
await formRef.value?.validate()
// 额外验证:确保模板已选择(因为 evaluationType 和 evaluationCycle 从模板获取)
if (!formData.templateId) {
message.warning('请选择评估模板')
return
}
if (!formData.templateType) {
message.warning('模板信息不完整,请重新选择')
// 尝试手动从模板列表获取
const template = templateOptions.value.find((t) => t.id === formData.templateId)
if (template) {
formData.templateType = template.type
formData.evaluationCycle = template.evaluationCycle
message.info(`已自动填充模板信息:类型=${template.type}, 周期=${template.evaluationCycle}`)
}
return
}
if (!formData.evaluationCycle) {
message.warning('评估周期不能为空,请确认模板是否正确')
return
}
// 打印提交数据用于调试
console.log('提交数据:', {
prisonerId: formData.prisonerId,
prisonerNo: formData.prisonerNo,
templateId: formData.templateId,
templateType: formData.templateType,
evaluationCycle: formData.evaluationCycle,
title: formData.title,
evaluationDate: formData.evaluationDate
})
submitLoading.value = true
await EvaluationReportApi.createReport({
prisonerId: formData.prisonerId!,
prisonerNo: formData.prisonerNo,
templateId: formData.templateId!,
evaluationType: formData.templateType!,
evaluationCycle: formData.evaluationCycle!,
title: formData.title,
// 日期格式转换YYYY-MM-DD -> LocalDateTime
evaluationDate: formData.evaluationDate ? formData.evaluationDate + ' 00:00:00' : null
} as any)
message.success('创建成功')
dialogVisible.value = false
emit('success')
} catch (error: any) {
if (error?.msg) {
message.error(error.msg)
}
console.error('创建报告失败:', error)
} finally {
submitLoading.value = false
}
}
defineExpose({ open })
</script>