This commit is contained in:
guochunsi
2026-01-09 18:46:41 +08:00
parent bacf93c33e
commit 4b46d3cc0d
40 changed files with 1977 additions and 939 deletions

View File

@@ -0,0 +1,284 @@
<template>
<el-dialog
v-model="visible"
:title="formData.id ? '编辑' : '新增'"
width="800px"
:close-on-click-modal="false"
destroy-on-close
@close="handleClose"
>
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="120px"
class="form-content"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="班级名称" prop="companyId">
<el-select
v-model="formData.companyId"
filterable
clearable
placeholder="请选择班级"
style="width: 100%"
>
<el-option
v-for="item in companyList"
:key="item.id"
:label="item.companyName"
:value="item.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="学员编号" prop="employeeNo">
<el-input
v-model="formData.employeeNo"
placeholder="系统自动生成"
disabled
clearable
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="姓名" prop="realName">
<el-input
v-model="formData.realName"
placeholder="请输入姓名"
clearable
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="身份证" prop="idCard">
<el-input
v-model="formData.idCard"
placeholder="请输入身份证号"
clearable
maxlength="18"
@input="handleIdCardInput"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="手机" prop="mobile">
<el-input
v-model="formData.mobile"
type="number"
placeholder="请输入手机号"
clearable
maxlength="11"
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="允许进出" prop="inoutFlag">
<el-select
v-model="formData.inoutFlag"
clearable
placeholder="请选择"
style="width: 100%"
>
<el-option
v-for="item in yesNoDict"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remarks">
<el-input
v-model="formData.remarks"
type="textarea"
:rows="3"
placeholder="请输入备注"
clearable
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="handleSubmit" :loading="submitLoading">确定</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { useDict } from '/@/hooks/dict'
import { useMessage } from '/@/hooks/message'
import { putObj } from '/@/api/professional/stayschool/outercompanyemployee'
// Props
interface Props {
modelValue: boolean
formData: {
id?: string
companyId?: string
companyName?: string
employeeNo?: string
realName?: string
idCard?: string
mobile?: string
inoutFlag?: string
remarks?: string
}
companyList: any[]
saveApi?: (data: any) => Promise<any> // 自定义保存 API 函数
}
const props = withDefaults(defineProps<Props>(), {
modelValue: false,
formData: () => ({
id: '',
companyId: '',
companyName: '',
employeeNo: '',
realName: '',
idCard: '',
mobile: '',
inoutFlag: '',
remarks: ''
}),
companyList: () => [],
saveApi: undefined
})
// Emits
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void
(e: 'success'): void
}>()
// 字典数据
const { yes_no_type: yesNoDict } = useDict('yes_no_type')
// 消息提示
const message = useMessage()
// 表单引用
const formRef = ref()
// 提交加载状态
const submitLoading = ref(false)
// 弹窗显示状态
const visible = ref(false)
watch(() => props.modelValue, (val) => {
visible.value = val
})
watch(visible, (val) => {
emit('update:modelValue', val)
})
// 表单验证规则
const formRules = {
companyId: [
{ required: true, message: '请选择班级', trigger: 'change' }
],
realName: [
{ required: true, message: '请填写姓名', trigger: 'blur' }
],
idCard: [
{ required: true, message: '请输入正确身份证', trigger: 'blur' },
{ min: 15, max: 18, message: '长度在 15 到 18 个字符', trigger: 'blur' },
{ pattern: /^(\d{15}|\d{17}[\dXx])$/, message: '身份证号格式不正确', trigger: 'blur' }
],
mobile: [
{ required: true, message: '请填写手机号', trigger: 'blur' },
{ pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号', trigger: 'blur' }
],
inoutFlag: [
{ required: true, message: '请选择是否允许进出', trigger: 'change' }
]
}
// 关闭弹窗
const handleClose = () => {
visible.value = false
formRef.value?.resetFields()
}
// 身份证号输入限制只允许数字和X/x最大长度18
const handleIdCardInput = (value: string) => {
// 只保留数字和X/x
const filtered = value.replace(/[^\dXx]/g, '')
if (filtered !== value) {
props.formData.idCard = filtered
}
}
// 提交表单
const handleSubmit = async () => {
if (!formRef.value) return
await formRef.value.validate(async (valid: boolean) => {
if (valid) {
submitLoading.value = true
try {
// 设置班级名称
const selectedCompany = props.companyList.find(item => item.id === props.formData.companyId)
const submitData = {
...props.formData,
companyName: selectedCompany?.companyName || ''
}
if (props.formData.id) {
await putObj(submitData)
message.success('修改成功')
} else {
// 使用自定义保存函数
if (props.saveApi) {
await props.saveApi(submitData)
} else {
message.error('请提供保存 API 函数')
return
}
message.success('添加成功')
}
handleClose()
emit('success')
} catch (error: any) {
message.error(error?.msg || '操作失败')
} finally {
submitLoading.value = false
}
}
})
}
</script>
<style lang="scss" scoped>
.form-content {
:deep(.el-row) {
margin-bottom: 18px;
&:last-child {
margin-bottom: 0;
}
}
:deep(.el-row .el-form-item) {
margin-bottom: 0;
}
}
</style>