Merge branch 'main' of http://113.45.157.195:3003/linfeng/staff_data
This commit is contained in:
commit
5289ae69d5
|
@ -57,10 +57,8 @@ export default function StaffTable() {
|
||||||
const [paginationEnabled, setPaginationEnabled] = useState(true);
|
const [paginationEnabled, setPaginationEnabled] = useState(true);
|
||||||
const [importVisible, setImportVisible] = useState(false);
|
const [importVisible, setImportVisible] = useState(false);
|
||||||
const [selectedRows, setSelectedRows] = useState<any[]>([]);
|
const [selectedRows, setSelectedRows] = useState<any[]>([]);
|
||||||
|
|
||||||
const handleConfirm = async () => {
|
const handleConfirm = async () => {
|
||||||
setFileNameVisible(true);
|
setFileNameVisible(true);
|
||||||
|
|
||||||
};
|
};
|
||||||
// 添加导出处理函数
|
// 添加导出处理函数
|
||||||
const handleFileNameConfirm = () => {
|
const handleFileNameConfirm = () => {
|
||||||
|
@ -69,7 +67,6 @@ export default function StaffTable() {
|
||||||
console.error('Grid API 未正确初始化');
|
console.error('Grid API 未正确初始化');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改获取节点方式(使用更可靠的 getRenderedNodes)
|
// 修改获取节点方式(使用更可靠的 getRenderedNodes)
|
||||||
const rowNodes = gridApi.getRenderedNodes();
|
const rowNodes = gridApi.getRenderedNodes();
|
||||||
|
|
||||||
|
@ -147,7 +144,6 @@ export default function StaffTable() {
|
||||||
gridApi.onFilterChanged(); // 触发筛选更新
|
gridApi.onFilterChanged(); // 触发筛选更新
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const columnDefs: (ColDef | ColGroupDef)[] = [
|
const columnDefs: (ColDef | ColGroupDef)[] = [
|
||||||
{
|
{
|
||||||
field: 'username',
|
field: 'username',
|
||||||
|
@ -329,8 +325,6 @@ export default function StaffTable() {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
const defaultColDef: ColDef = {
|
const defaultColDef: ColDef = {
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filter: 'agSetColumnFilter',
|
filter: 'agSetColumnFilter',
|
||||||
|
@ -474,7 +468,6 @@ export default function StaffTable() {
|
||||||
utils.book_append_sheet(wb, ws, "员工模板");
|
utils.book_append_sheet(wb, ws, "员工模板");
|
||||||
writeFile(wb, `员工数据模板_${new Date().toISOString().slice(0, 10)}.xlsx`);
|
writeFile(wb, `员工数据模板_${new Date().toISOString().slice(0, 10)}.xlsx`);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 添加导入API钩子
|
// 添加导入API钩子
|
||||||
const createManyMutation = api.staff.create.useMutation({
|
const createManyMutation = api.staff.create.useMutation({
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
|
@ -486,7 +479,6 @@ export default function StaffTable() {
|
||||||
message.error(`导入失败: ${error.message}`);
|
message.error(`导入失败: ${error.message}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 处理Excel导入数据
|
// 处理Excel导入数据
|
||||||
const handleImportData = (excelData: any[]) => {
|
const handleImportData = (excelData: any[]) => {
|
||||||
// 转换Excel数据为后端接受的格式
|
// 转换Excel数据为后端接受的格式
|
||||||
|
|
|
@ -0,0 +1,542 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Button, Form, Input, Select, DatePicker, Radio, message, Modal, Cascader, InputNumber } from "antd";
|
||||||
|
import { useState } from "react";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { useStaff } from "@nice/client";
|
||||||
|
import DepartmentChildrenSelect from "@web/src/components/models/department/department-children-select";
|
||||||
|
import { areaOptions } from './area-options';
|
||||||
|
import DepartmentSelect from "@web/src/components/models/department/department-select";
|
||||||
|
import { addLog } from "@web/src/app/main/systemlog/SystemLogPage";
|
||||||
|
const { TextArea } = Input;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const StaffInformation = () => {
|
||||||
|
const [modalForm] = Form.useForm();
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||||
|
const [modalType, setModalType] = useState<'awards' | 'punishments' | 'equipment' | 'projects'>('awards');
|
||||||
|
const [rewardsList, setRewardsList] = useState<string[]>([]);
|
||||||
|
const [punishmentsList, setPunishmentsList] = useState<string[]>([]);
|
||||||
|
const [equipmentList, setEquipmentList] = useState<string[]>([]); // 新增装备列表
|
||||||
|
const [projectsList, setProjectsList] = useState<string[]>([]); // 新增任务列表
|
||||||
|
const {create, update} = useStaff();
|
||||||
|
|
||||||
|
const showModal = (type: 'awards' | 'punishments' | 'equipment' | 'projects') => {
|
||||||
|
setModalType(type);
|
||||||
|
setIsModalVisible(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleModalOk = async () => {
|
||||||
|
try {
|
||||||
|
const values = await modalForm.validateFields();
|
||||||
|
const value = values[modalType];
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
switch(modalType) {
|
||||||
|
case 'awards':
|
||||||
|
setRewardsList([...rewardsList, value]);
|
||||||
|
break;
|
||||||
|
case 'punishments':
|
||||||
|
setPunishmentsList([...punishmentsList, value]);
|
||||||
|
break;
|
||||||
|
case 'equipment':
|
||||||
|
setEquipmentList([...equipmentList, value]);
|
||||||
|
break;
|
||||||
|
case 'projects':
|
||||||
|
setProjectsList([...projectsList, value]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
modalForm.resetFields();
|
||||||
|
setIsModalVisible(false);
|
||||||
|
message.success(
|
||||||
|
modalType === 'awards' ? '奖励信息添加成功' :
|
||||||
|
modalType === 'punishments' ? '处分信息添加成功' :
|
||||||
|
modalType === 'equipment' ? '装备信息添加成功' : '任务信息添加成功'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
message.warning('请输入内容');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const onFinish = async (values: any) => {
|
||||||
|
console.log('开始提交表单');
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const formattedValues = {
|
||||||
|
...values,
|
||||||
|
birthplace: values.birthplace?.join('/'), // 将数组转换为以'/'分隔的字符串
|
||||||
|
awards: rewardsList.join(','),
|
||||||
|
punishments: punishmentsList.join(','),
|
||||||
|
equipment: equipmentList.join(','),
|
||||||
|
projects: projectsList.join(','),
|
||||||
|
hireDate: values.hireDate?.toISOString(),
|
||||||
|
seniority: values.seniority?.toISOString(),
|
||||||
|
currentPositionDate: values.currentPositionDate?.toISOString(),
|
||||||
|
rankDate: values.rankDate?.toISOString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
await create.mutateAsync(
|
||||||
|
{
|
||||||
|
data: formattedValues
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log('提交的表单数据:', formattedValues);
|
||||||
|
console.log('奖励列表:', rewardsList);
|
||||||
|
console.log('处分列表:', punishmentsList);
|
||||||
|
|
||||||
|
// 添加日志记录
|
||||||
|
addLog(`用户 ${values.username || '未知'} 的人员信息已成功添加`);
|
||||||
|
addLog(`提交的数据: 姓名=${values.username}, 身份证号=${values.idNumber}, 警号=${values.officerId}, 部门ID=${values.deptId}`);
|
||||||
|
|
||||||
|
if (rewardsList.length > 0) {
|
||||||
|
addLog(`${values.username} 的奖励信息: ${rewardsList.join(' | ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (punishmentsList.length > 0) {
|
||||||
|
addLog(`${values.username} 的处分信息: ${punishmentsList.join(' | ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (equipmentList.length > 0) {
|
||||||
|
addLog(`${values.username} 的装备信息: ${equipmentList.join(' | ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (projectsList.length > 0) {
|
||||||
|
addLog(`${values.username} 的任务信息: ${projectsList.join(' | ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.success("信息提交成功");
|
||||||
|
} catch (error) {
|
||||||
|
console.error('提交出错:', error);
|
||||||
|
// 添加错误日志
|
||||||
|
addLog(`提交人员信息失败: ${error instanceof Error ? error.message : '未知错误'}`);
|
||||||
|
message.error("提交失败,请重试");
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = (e: React.MouseEvent) => {
|
||||||
|
e.preventDefault(); // 阻止默认行为
|
||||||
|
console.log('提交按钮被点击');
|
||||||
|
form.submit();
|
||||||
|
};
|
||||||
|
|
||||||
|
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}
|
||||||
|
onFinishFailed={(errorInfo) => {
|
||||||
|
console.log('表单验证失败:', errorInfo);
|
||||||
|
}}
|
||||||
|
className="space-y-6"
|
||||||
|
>
|
||||||
|
{/* 个人基本信息 */}
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
<h2 className="text-lg font-semibold mb-4">个人基本信息</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<Form.Item label="姓名" name="username" rules={[{ required: true }]}>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="身份证号" name="idNumber" rules={[{required: true}]}>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="警号" name="officerId">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="手机号" name="phoneNumber">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="人员类型" name="type">
|
||||||
|
<Select>
|
||||||
|
<Select.Option value="警官">警官</Select.Option>
|
||||||
|
<Select.Option value="文职">文职</Select.Option>
|
||||||
|
<Select.Option value="警士">警士</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="性别" name="sex">
|
||||||
|
<Radio.Group>
|
||||||
|
<Radio value={true}>男</Radio>
|
||||||
|
<Radio value={false}>女</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label='年龄' name='age'>
|
||||||
|
<InputNumber />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="血型" name="bloodType">
|
||||||
|
<Select>
|
||||||
|
<Select.Option value="A">A型</Select.Option>
|
||||||
|
<Select.Option value="B">B型</Select.Option>
|
||||||
|
<Select.Option value="O">O型</Select.Option>
|
||||||
|
<Select.Option value="AB">AB型</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
label="籍贯"
|
||||||
|
name="birthplace"
|
||||||
|
rules={[{ required: true, message: '请选择籍贯' }]}
|
||||||
|
>
|
||||||
|
<Cascader
|
||||||
|
options={areaOptions}
|
||||||
|
placeholder="请选择省/市/区"
|
||||||
|
className="w-full"
|
||||||
|
expandTrigger="hover"
|
||||||
|
showSearch={{
|
||||||
|
filter: (inputValue, path) => {
|
||||||
|
return path.some(option =>
|
||||||
|
typeof option.label === 'string' &&
|
||||||
|
option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
changeOnSelect
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 政治信息 */}
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
<h2 className="text-lg font-semibold mb-4">政治信息</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<Form.Item label="政治面貌" name="politicalStatus">
|
||||||
|
<Select>
|
||||||
|
<Select.Option value="中共党员">中共党员</Select.Option>
|
||||||
|
<Select.Option value="中共预备党员">中共预备党员</Select.Option>
|
||||||
|
<Select.Option value="共青团员">共青团员</Select.Option>
|
||||||
|
<Select.Option value="群众">群众</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="党内职务" name="partyPosition">
|
||||||
|
<Select>
|
||||||
|
<Select.Option value="党委书记">党委书记</Select.Option>
|
||||||
|
<Select.Option value="委员">委员</Select.Option>
|
||||||
|
<Select.Option value="党支部书记">党支部书记</Select.Option>
|
||||||
|
<Select.Option value="党支部委员">党支部委员</Select.Option>
|
||||||
|
<Select.Option value="无">无</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 职务信息 */}
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
<h2 className="text-lg font-semibold mb-4">职务信息</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<Form.Item label = "部门" name="deptId" >
|
||||||
|
<DepartmentSelect/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="衔职级别" name="rank">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="衔职时间" name="rankDate">
|
||||||
|
<DatePicker className="w-full" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="代理职务" name="proxyPosition">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="岗位" name="post">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 入职信息 */}
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
<h2 className="text-lg font-semibold mb-4">入职信息</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<Form.Item label="入职时间" name="hireDate">
|
||||||
|
<DatePicker className="w-full" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="工龄认定时间" name="seniority">
|
||||||
|
<DatePicker className="w-full" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="是否二次入职" name="isReentry" initialValue={false}>
|
||||||
|
<Radio.Group>
|
||||||
|
<Radio value={true}>是</Radio>
|
||||||
|
<Radio value={false}>否</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="来源类别" name="source">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="现岗位开始时间" name="currentPositionDate">
|
||||||
|
<DatePicker className="w-full" />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="是否延期服役" name="isExtended" initialValue={false}>
|
||||||
|
<Radio.Group>
|
||||||
|
<Radio value={true}>是</Radio>
|
||||||
|
<Radio value={false}>否</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 教育背景 */}
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
<h2 className="text-lg font-semibold mb-4">教育背景</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<Form.Item label="学历" name="education">
|
||||||
|
<Select>
|
||||||
|
<Select.Option value="高中">高中</Select.Option>
|
||||||
|
<Select.Option value="专科">专科</Select.Option>
|
||||||
|
<Select.Option value="本科">本科</Select.Option>
|
||||||
|
<Select.Option value="硕士">硕士</Select.Option>
|
||||||
|
<Select.Option value="博士">博士</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="学历形式" name="educationType">
|
||||||
|
<Select>
|
||||||
|
<Select.Option value="全日制">全日制</Select.Option>
|
||||||
|
<Select.Option value="非全日制">非全日制</Select.Option>
|
||||||
|
</Select>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="是否毕业" name="isGraduated">
|
||||||
|
<Radio.Group>
|
||||||
|
<Radio value={true}>是</Radio>
|
||||||
|
<Radio value={false}>否</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="专业" name="major">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="外语能力" name="foreignLang">
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 培训信息 */}
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
<h2 className="text-lg font-semibold mb-4">培训信息</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<Form.Item label="是否参加培训" name="hasTrain" initialValue={false}>
|
||||||
|
<Radio.Group>
|
||||||
|
<Radio value={true}>是</Radio>
|
||||||
|
<Radio value={false}>否</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
noStyle
|
||||||
|
shouldUpdate={(prevValues, currentValues) => prevValues.hasTrain !== currentValues.hasTrain}
|
||||||
|
>
|
||||||
|
{({ getFieldValue }) => (
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-1 gap-4">
|
||||||
|
<Form.Item label="培训类型" name="trainType">
|
||||||
|
<Input disabled={!getFieldValue('hasTrain')} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="培训机构" name="trainInstitute">
|
||||||
|
<Input disabled={!getFieldValue('hasTrain')} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="培训专业" name="trainMajor">
|
||||||
|
<Input disabled={!getFieldValue('hasTrain')} />
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 鉴定信息 */}
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
<h2 className="text-lg font-semibold mb-4">鉴定信息</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<Form.Item label="是否参加鉴定" name="hasCert" initialValue={false}>
|
||||||
|
<Radio.Group>
|
||||||
|
<Radio value={true}>是</Radio>
|
||||||
|
<Radio value={false}>否</Radio>
|
||||||
|
</Radio.Group>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item
|
||||||
|
noStyle
|
||||||
|
shouldUpdate={(prevValues, currentValues) => prevValues.hasCert !== currentValues.hasCert}
|
||||||
|
>
|
||||||
|
{({ getFieldValue }) => (
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-1 gap-4">
|
||||||
|
<Form.Item label="鉴定等级" name="certRank">
|
||||||
|
<Input disabled={!getFieldValue('hasCert')} />
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="鉴定工种" name="certWork">
|
||||||
|
<Input disabled={!getFieldValue('hasCert')} />
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</Form.Item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* 工作信息 */}
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
<h2 className="text-lg font-semibold mb-4">工作信息</h2>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
|
<div>
|
||||||
|
<div className="flex justify-between items-center mb-2">
|
||||||
|
<label>操作维护装备</label>
|
||||||
|
<Button type="primary" onClick={() => showModal('equipment')}>
|
||||||
|
添加装备
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="border p-2 min-h-[100px] rounded">
|
||||||
|
{equipmentList.map((equipment, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="mb-2 p-2 bg-gray-50 rounded-md border border-gray-200 flex justify-between items-center"
|
||||||
|
>
|
||||||
|
<span>{equipment}</span>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
danger
|
||||||
|
onClick={() => {
|
||||||
|
setEquipmentList(equipmentList.filter((_, i) => i !== index));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="flex justify-between items-center mb-2">
|
||||||
|
<label>任务经历</label>
|
||||||
|
<Button type="primary" onClick={() => showModal('projects')}>
|
||||||
|
添加任务
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="border p-2 min-h-[100px] rounded">
|
||||||
|
{projectsList.map((mission, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="mb-2 p-2 bg-gray-50 rounded-md border border-gray-200 flex justify-between items-center"
|
||||||
|
>
|
||||||
|
<span>{mission}</span>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
danger
|
||||||
|
onClick={() => {
|
||||||
|
setProjectsList(projectsList.filter((_, i) => i !== index));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="flex justify-between items-center mb-2">
|
||||||
|
<label>奖励信息</label>
|
||||||
|
<Button type="primary" onClick={() => showModal('awards')}>
|
||||||
|
添加奖励
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="border p-2 min-h-[100px] rounded">
|
||||||
|
{rewardsList.map((reward, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="mb-2 p-2 bg-gray-50 rounded-md border border-gray-200 flex justify-between items-center"
|
||||||
|
>
|
||||||
|
<span>{reward}</span>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
danger
|
||||||
|
onClick={() => {
|
||||||
|
setRewardsList(rewardsList.filter((_, i) => i !== index));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div className="flex justify-between items-center mb-2">
|
||||||
|
<label>处分信息</label>
|
||||||
|
<Button type="primary" onClick={() => showModal('punishments')}>
|
||||||
|
添加处分
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div className="border p-2 min-h-[100px] rounded">
|
||||||
|
{punishmentsList.map((punishment, index) => (
|
||||||
|
<div
|
||||||
|
key={index}
|
||||||
|
className="mb-2 p-2 bg-gray-50 rounded-md border border-gray-200 flex justify-between items-center"
|
||||||
|
>
|
||||||
|
<span>{punishment}</span>
|
||||||
|
<Button
|
||||||
|
type="text"
|
||||||
|
danger
|
||||||
|
onClick={() => {
|
||||||
|
setPunishmentsList(punishmentsList.filter((_, i) => i !== index));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
<div className="flex justify-end space-x-4">
|
||||||
|
<Button onClick={() => form.resetFields()}>重置</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={handleSubmit}
|
||||||
|
loading={loading}
|
||||||
|
>
|
||||||
|
提交
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Form>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
title={
|
||||||
|
modalType === 'awards' ? '添加奖励信息' :
|
||||||
|
modalType === 'punishments' ? '添加处分信息' :
|
||||||
|
modalType === 'equipment' ? '添加装备信息' : '添加任务信息'
|
||||||
|
}
|
||||||
|
open={isModalVisible}
|
||||||
|
onOk={handleModalOk}
|
||||||
|
onCancel={() => {
|
||||||
|
setIsModalVisible(false);
|
||||||
|
modalForm.resetFields();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Form form={modalForm}>
|
||||||
|
<Form.Item
|
||||||
|
label={
|
||||||
|
modalType === 'awards' ? '奖励内容' :
|
||||||
|
modalType === 'punishments' ? '处分内容' :
|
||||||
|
modalType === 'equipment' ? '装备信息' : '任务信息'
|
||||||
|
}
|
||||||
|
name={modalType}
|
||||||
|
rules={[{ required: true, message: '请输入内容' }]}
|
||||||
|
>
|
||||||
|
<TextArea
|
||||||
|
rows={4}
|
||||||
|
placeholder={
|
||||||
|
modalType === 'awards' ? '请输入获得的表彰奖励信息' :
|
||||||
|
modalType === 'punishments' ? '请输入处分信息' :
|
||||||
|
modalType === 'equipment' ? '请输入装备信息' : '请输入任务经历详情'
|
||||||
|
}
|
||||||
|
maxLength={500}
|
||||||
|
/>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default StaffInformation;
|
|
@ -1,3 +1,49 @@
|
||||||
export default function SystemLogPage() {
|
"use client";
|
||||||
return <div>SystemLogPage</div>;
|
|
||||||
}
|
import React, { useState, useEffect } from 'react';
|
||||||
|
|
||||||
|
// 创建一个全局变量来存储日志
|
||||||
|
let globalLogs: string[] = [];
|
||||||
|
|
||||||
|
// 添加日志的函数
|
||||||
|
export const addLog = (log: string) => {
|
||||||
|
const timestamp = new Date().toLocaleString();
|
||||||
|
const formattedLog = `[${timestamp}] ${log}`;
|
||||||
|
globalLogs = [...globalLogs, formattedLog];
|
||||||
|
// 如果需要,可以将日志保存到localStorage
|
||||||
|
localStorage.setItem('systemLogs', JSON.stringify(globalLogs));
|
||||||
|
};
|
||||||
|
|
||||||
|
const SystemLogPage = () => {
|
||||||
|
const [logs, setLogs] = useState<string[]>([]);
|
||||||
|
// 组件加载时从全局变量或localStorage获取日志
|
||||||
|
useEffect(() => {
|
||||||
|
// 尝试从localStorage获取日志
|
||||||
|
const storedLogs = localStorage.getItem('systemLogs');
|
||||||
|
if (storedLogs) {
|
||||||
|
setLogs(JSON.parse(storedLogs));
|
||||||
|
} else {
|
||||||
|
setLogs(globalLogs);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div className="max-w-4xl mx-auto p-6">
|
||||||
|
<h1 className="text-2xl font-bold mb-6">系统日志</h1>
|
||||||
|
<div className="bg-white p-6 rounded-lg shadow">
|
||||||
|
{logs.length === 0 ? (
|
||||||
|
<p className="text-gray-500">暂无系统日志</p>
|
||||||
|
) : (
|
||||||
|
<ul className="space-y-2">
|
||||||
|
{logs.map((log, index) => (
|
||||||
|
<li key={index} className="p-2 border-b border-gray-200">
|
||||||
|
{log}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default SystemLogPage;
|
||||||
|
|
Loading…
Reference in New Issue