This commit is contained in:
linfeng 2025-03-26 10:31:29 +08:00
parent 91c436b4a3
commit c868f8cc73
7 changed files with 192 additions and 137 deletions

View File

@ -1,3 +1,5 @@
import { areaOptions } from "@web/src/data/area-options";
export const defaultFields = [ export const defaultFields = [
// 基本信息组 // 基本信息组
{ name: 'username', label: '用户名', type: 'text',required: true, group: '基本信息', order: 1 }, { name: 'username', label: '用户名', type: 'text',required: true, group: '基本信息', order: 1 },
@ -26,7 +28,12 @@ export const defaultFields = [
], ],
group: '基本信息', group: '基本信息',
order: 8 }, order: 8 },
{ name: 'birthplace', label: '籍贯', type: 'text', group: '基本信息', order: 9 }, { name: 'birthplace',
label: '籍贯',
type: 'cascader',
// options:areaOptions,
group: '基本信息',
order: 9 },
{ name: 'source', label: '来源', type: 'text', group: '基本信息', order: 10 }, { name: 'source', label: '来源', type: 'text', group: '基本信息', order: 10 },
// 政治信息组 // 政治信息组
@ -119,9 +126,9 @@ export const defaultFields = [
{ name: 'foreignLang', label: '外语能力', type: 'text', group: '教育信息', order: 27 }, { name: 'foreignLang', label: '外语能力', type: 'text', group: '教育信息', order: 27 },
// 培训信息组 // 培训信息组
{ name: 'trainType', label: '培训类型', type: 'text', group: '培训信息', order: 28 }, { name: 'trainType', label: '培训类型', type: 'text', group: '培训信息', order: 28 ,dependsOn:{field: 'hasTrain', value: '是'}},
{ name: 'trainInstitute', label: '培训机构', type: 'text', group: '培训信息', order: 29 }, { name: 'trainInstitute', label: '培训机构', type: 'text', group: '培训信息', order: 29 ,dependsOn: {field: 'hasTrain', value: '是'}},
{ name: 'trainMajor', label: '培训专业', type: 'text', group: '培训信息', order: 30 }, { name: 'trainMajor', label: '培训专业', type: 'text', group: '培训信息', order: 30 ,dependsOn: {field: 'hasTrain', value: '是'}},
{ name: 'hasTrain', { name: 'hasTrain',
label: '是否参加培训', label: '是否参加培训',
type: 'radio', type: 'radio',
@ -133,8 +140,18 @@ export const defaultFields = [
order: 31 }, order: 31 },
// 鉴定信息组 // 鉴定信息组
{ name: 'certRank', label: '鉴定等级', type: 'text', group: '鉴定信息', order: 32 }, { name: 'certRank',
{ name: 'certWork', label: '鉴定工种', type: 'text', group: '鉴定信息', order: 33 }, label: '鉴定等级',
type: 'text',
group: '鉴定信息',
order: 32 ,
dependsOn: {field: 'hasCert', value: '是'}},
{ name: 'certWork',
label: '鉴定工种',
type: 'text',
group: '鉴定信息',
order: 33 ,
dependsOn: {field: 'hasCert', value: '是'}},
{ name: 'hasCert', { name: 'hasCert',
label: '是否参加鉴定', label: '是否参加鉴定',
type: 'radio', type: 'radio',
@ -159,6 +176,7 @@ export const defaultFields = [
{ label: '选择', value: 'select' }, { label: '选择', value: 'select' },
{ label: '单选', value: 'radio' }, { label: '单选', value: 'radio' },
{ label: '多行文本', value: 'textarea' }, { label: '多行文本', value: 'textarea' },
{ label: '级联', value: 'cascader' },
]; ];
export const GroupOptions = [ export const GroupOptions = [

View File

@ -8,6 +8,7 @@ import StaffFieldTable from './staffFieldTable';
import StaffFieldModal from './staffFieldModal'; import StaffFieldModal from './staffFieldModal';
import { useWatch } from 'antd/es/form/Form'; import { useWatch } from 'antd/es/form/Form';
import { Form } from 'antd'; import { Form } from 'antd';
const StaffFieldManage = () => { const StaffFieldManage = () => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [isModalVisible, setIsModalVisible] = useState(false); const [isModalVisible, setIsModalVisible] = useState(false);
@ -19,7 +20,7 @@ const StaffFieldManage = () => {
useCustomFields useCustomFields
} = useStaff(); } = useStaff();
const { data: fields, isLoading } = useCustomFields(); const { data: fields, isLoading } = useCustomFields();
const optionFieldTypes = ['select', 'radio']; const optionFieldTypes = ['select', 'radio',];
const [showOptions, setShowOptions] = useState(false); const [showOptions, setShowOptions] = useState(false);
const typeValue = useWatch('type', form); const typeValue = useWatch('type', form);

View File

@ -30,6 +30,7 @@ const StaffFieldTable: React.FC<StaffFieldTableProps> = ({
handleDelete, handleDelete,
handleBatchDelete handleBatchDelete
}) => { }) => {
console.log(fields);
const columns = [ const columns = [
{ {
title: '字段名称', title: '字段名称',

View File

@ -0,0 +1,29 @@
import { Card, Button, Input, Space } from 'antd';
import React, { useState } from 'react';
type InfoCardProps = {
onAdd: (content: string) => void;
}
const InfoCard:React.FC<InfoCardProps> = ({onAdd}) => {
const [content, setContent] = useState('');
const handleAdd = () => {
if(content){
onAdd(content);
setContent('');
}
}
return (
<Card >
<Space>
<Input
placeholder='请输入内容'
value={content}
onChange={(e) => setContent(e.target.value)}
>
</Input>
<Button type='primary' onClick={handleAdd}></Button>
</Space>
</Card>
);
}
export default InfoCard;

View File

@ -1,129 +0,0 @@
"use client";
import { Button, Form, Input, Select, DatePicker, Radio, message, Modal, Cascader, InputNumber } from "antd";
import { useState, useMemo } from "react";
import { useStaff } from "@nice/client";
import { areaOptions } from './area-options';
const { TextArea } = Input;
const StaffInfoWrite = () => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const { create, useCustomFields } = useStaff();
const { data: fields, isLoading: fieldsLoading } = useCustomFields();
// 按分组组织字段
const fieldGroups = useMemo(() => {
if (!fields) return {};
return fields.reduce((groups: any, field: any) => {
const group = field.group || '其他信息';
if (!groups[group]) {
groups[group] = [];
}
groups[group].push(field);
return groups;
}, {});
}, [fields]);
const renderField = (field: any) => {
switch (field.type) {
case 'text':
return <Input />;
case 'number':
return <InputNumber />;
case 'date':
return <DatePicker />;
case 'select':
// 检查 field.options 是否存在且有数据
if (field.options && field.options.length > 0) {
return <Select options={field.options} />;
}
return <Input placeholder="选项数据缺失" />;
case 'radio':
// 检查 field.options 是否存在且有数据
if (field.options && field.options.length > 0) {
return <Radio.Group options={field.options} />;
}
return <Input placeholder="选项数据缺失" />;
case 'textarea':
return <Input.TextArea />;
default:
return <Input />;
}
};
const onFinish = async (values: any) => {
try {
setLoading(true);
const formattedValues = {
...values,
birthplace: values.birthplace?.join('/'),
};
await create.mutateAsync({
data: formattedValues
});
message.success("信息提交成功");
} catch (error) {
console.error('提交出错:', error);
message.error("提交失败,请重试");
} finally {
setLoading(false);
}
};
if (fieldsLoading) {
return <div>...</div>;
}
return (
<div className="max-w-4xl mx-auto p-6">
<h1 className="text-2xl font-bold mb-6"></h1>
{/* 信息填报表单 */}
<Form
form={form}
layout="vertical"
onFinish={onFinish}
className="space-y-6 mt-6"
>
{Object.entries(fieldGroups).map(([groupName, groupFields]) => (
<div key={groupName} className="bg-white p-6 rounded-lg shadow">
<h2 className="text-lg font-semibold mb-4">{groupName}</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{groupFields.map((field: any) => (
<Form.Item
key={field.id}
label={field.label}
name={field.name}
rules={[
{
required: field.required,
message: `请输入${field.label}`,
},
]}
>
{renderField(field)}
</Form.Item>
))}
</div>
</div>
))}
<div className="flex justify-end space-x-4">
<Button onClick={() => form.resetFields()}></Button>
<Button
type="primary"
htmlType="submit"
loading={loading}
>
</Button>
</div>
</Form>
</div>
);
};
export default StaffInfoWrite;

View File

@ -0,0 +1,135 @@
"use client";
import { Button, Form, Input, Select, DatePicker, Radio, message, Modal, Cascader, InputNumber } from "antd";
import { useState, useMemo } from "react";
import { useStaff } from "@nice/client";
import { areaOptions } from './area-options';
import InfoCard from './infoCard';
const StaffInfoWrite = () => {
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
const { create, useCustomFields } = useStaff();
const { data: fields, isLoading: fieldsLoading } = useCustomFields();
const [infoCards, setInfoCards] = useState<any[]>([]);
const handleAdd = ( content: string) => {
setInfoCards([...infoCards, { content }]);
}
// 按分组组织字段
const fieldGroups = useMemo(() => {
if (!fields) return {};
return fields.reduce((groups: any, field: any) => {
const group = field.group || '其他信息';
if (!groups[group]) {
groups[group] = [];
}
groups[group].push(field);
return groups;
}, {});
}, [fields]);
const renderField = (field: any) => {
switch (field.type) {
case 'text':
return <Input />;
case 'number':
return <InputNumber />;
case 'date':
return <DatePicker />;
case 'select':
if (field.options && field.options.length > 0) {
return <Select options={field.options} />;
}
return <Input placeholder="选项数据缺失" />;
case 'radio':
if (field.options && field.options.length > 0) {
return <Radio.Group options={field.options} />;
}
return <Input placeholder="选项数据缺失" />;
case 'textarea':
return <InfoCard onAdd={handleAdd} />;
case 'cascader':
if(field.label === '籍贯'){
return <Cascader options={areaOptions} />;
}else{
return <Input />;
}
default:
return <Input />;
}
};
const onFinish = async (values: any) => {
try {
setLoading(true);
const formattedValues = {
...values,
birthplace: values.birthplace?.join('/'),
};
await create.mutateAsync({
data: formattedValues
});
message.success("信息提交成功");
} catch (error) {
console.error('提交出错:', error);
message.error("提交失败,请重试");
} finally {
setLoading(false);
}
};
if (fieldsLoading) {
return <div>...</div>;
}
return (
<div className="max-w-4xl mx-auto p-6">
<h1 className="text-2xl font-bold mb-6"></h1>
<Form
form={form}
layout="vertical"
onFinish={onFinish}
className="space-y-6 mt-6"
>
{Object.entries(fieldGroups).map(([groupName, groupFields]) => (
<div key={groupName} className="bg-white p-6 rounded-lg shadow">
<h2 className="text-lg font-semibold mb-4">{groupName}</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{groupFields.map((field: any) => (
<Form.Item
key={field.id}
label={field.label}
name={field.name}
rules={[
{
required: field.required,
message: `请输入${field.label}`,
},
]}
>
{renderField(field)}
</Form.Item>
))}
</div>
</div>
))}
<div className="flex justify-end space-x-4">
<Button onClick={() => form.resetFields()}></Button>
<Button
type="primary"
htmlType="submit"
loading={loading}
>
</Button>
</div>
</Form>
</div>
);
};
export default StaffInfoWrite;

View File

@ -13,7 +13,7 @@ import MainLayout from "../app/main/layout/MainLayout";
import DailyPage from "../app/main/daily/page"; import DailyPage from "../app/main/daily/page";
import Dashboard from "../app/main/home/page"; import Dashboard from "../app/main/home/page";
import WeekPlanPage from "../app/main/plan/weekplan/page"; import WeekPlanPage from "../app/main/plan/weekplan/page";
import StaffInformation from "../app/main/staffinfo_write/page"; import StaffInformation from "../app/main/staffinfo_write/staffinfo_write.page";
import DeptSettingPage from "../app/main/admin/deptsettingpage/page"; import DeptSettingPage from "../app/main/admin/deptsettingpage/page";
import { adminRoute } from "./admin-route"; import { adminRoute } from "./admin-route";
import AdminLayout from "../components/layout/admin/AdminLayout"; import AdminLayout from "../components/layout/admin/AdminLayout";