lin
This commit is contained in:
parent
91c436b4a3
commit
c868f8cc73
|
@ -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 = [
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ const StaffFieldTable: React.FC<StaffFieldTableProps> = ({
|
||||||
handleDelete,
|
handleDelete,
|
||||||
handleBatchDelete
|
handleBatchDelete
|
||||||
}) => {
|
}) => {
|
||||||
|
console.log(fields);
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '字段名称',
|
title: '字段名称',
|
||||||
|
|
|
@ -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;
|
|
@ -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;
|
|
|
@ -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;
|
|
@ -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";
|
||||||
|
|
Loading…
Reference in New Issue