tangweijie fdc6bf58e0 fix: 代码审查修复 - 前端TypeScript类型和UI优化
前端修复:
- 完善TypeScript类型定义(QuestionnairePageParams, QuestionPageParams等)
- 移除未使用的导入(Dayjs等)
- 日期格式化统一使用dateFormatter替代自定义函数
- 问题类型选项使用字典替代硬编码
- 优化API参数传递方式

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

229 lines
7.1 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>
<Dialog :title="dialogTitle" v-model="dialogVisible" width="600px">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="监区名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入监区名称" />
</el-form-item>
<el-form-item label="监区编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入监区编码" />
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="级别" prop="level">
<el-select v-model="formData.level" placeholder="请选择级别" @change="handleLevelChange">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.PRISON_AREA_LEVEL)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="父级监区" prop="parentId">
<el-select v-model="formData.parentId" placeholder="请选择父级监区" clearable :disabled="formData.level === 1">
<el-option
v-for="area in parentAreaOptions"
:key="area.id"
:label="area.name"
:value="area.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="监区类型" prop="type">
<el-select v-model="formData.type" placeholder="请选择监区类型">
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.PRISON_AREA_TYPE)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="容纳人数" prop="capacity">
<el-input-number v-model="formData.capacity" :min="0" placeholder="请输入容纳人数" controls-position="right" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="排序" prop="sort">
<el-input-number v-model="formData.sort" :min="0" placeholder="请输入排序" controls-position="right" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.PRISON_CELL_STATUS)"
:key="dict.value"
:value="dict.value"
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" type="textarea" placeholder="请输入备注" :rows="3" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { AreaApi, AreaSaveReqVO } from '@/api/prison/area'
/** 监区信息 表单 */
defineOptions({ name: 'PrisonAreaForm' })
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // 弹窗的是否展示
const dialogTitle = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中1修改时的数据加载2提交的按钮禁用
const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref({
id: undefined,
name: undefined,
code: undefined,
parentId: undefined as number | undefined,
level: 1,
type: 1,
capacity: 0,
sort: 0,
status: 1,
remark: undefined
})
const formRules = reactive({
name: [{ required: true, message: t('prison.area.nameRequired'), trigger: 'blur' }],
code: [{ required: true, message: t('prison.area.codeRequired'), trigger: 'blur' }],
level: [{ required: true, message: t('prison.area.levelRequired'), trigger: 'blur' }],
type: [{ required: true, message: t('prison.area.typeRequired'), trigger: 'blur' }],
status: [{ required: true, message: t('prison.area.statusRequired'), trigger: 'blur' }]
})
const formRef = ref() // 表单 Ref
const parentAreaOptions = ref<{ id: number; name: string }[]>([]) // 父级监区选项
/** 加载父级监区列表 */
const loadParentAreas = async () => {
// 加载级别为1的监区作为父级选项
try {
const data = await AreaApi.getParentAreas(1)
parentAreaOptions.value = data
} catch {
parentAreaOptions.value = []
}
}
/** 级别变化时处理 */
const handleLevelChange = (level: number) => {
// 选择监区级别时,不能选择自己为父级
if (formData.value.id && level === 2) {
parentAreaOptions.value = parentAreaOptions.value.filter(
(area) => area.id !== formData.value.id
)
}
// 重置父级选择
if (level === 1) {
formData.value.parentId = undefined
}
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
formType.value = type
// 加载父级监区选项
await loadParentAreas()
resetForm()
// 修改时,设置数据
if (id) {
formLoading.value = true
try {
const data = await AreaApi.getArea(id)
formData.value = {
id: data.id,
name: data.name,
code: data.code,
parentId: data.parentId || undefined,
level: data.level || 1,
type: data.type,
capacity: data.capacity,
sort: data.sort,
status: data.status,
remark: data.remark
}
} finally {
formLoading.value = false
}
}
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
/** 提交表单 */
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
const submitForm = async () => {
// 校验表单
await formRef.value.validate()
// 提交请求
formLoading.value = true
try {
const data = formData.value as unknown as AreaSaveReqVO
// 监区级别不能选择自己为父级
if (data.level === 2 && data.parentId === data.id) {
message.error(t('prison.area.parentNotSelf'))
return
}
if (formType.value === 'create') {
await AreaApi.createArea(data)
message.success(t('common.createSuccess'))
} else {
await AreaApi.updateArea(data)
message.success(t('common.updateSuccess'))
}
dialogVisible.value = false
// 发送操作成功的事件
emit('success')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
name: undefined,
code: undefined,
parentId: undefined,
level: 1,
type: 1,
capacity: 0,
sort: 0,
status: 1,
remark: undefined
}
formRef.value?.resetFields()
}
</script>