diff --git a/src/assets/basic_information/Rectangle102.png b/src/assets/basic_information/Rectangle102.png deleted file mode 100644 index 44dff85..0000000 Binary files a/src/assets/basic_information/Rectangle102.png and /dev/null differ diff --git a/src/assets/basic_information/file-icon.png b/src/assets/basic_information/file-icon.png new file mode 100644 index 0000000..247a2dc Binary files /dev/null and b/src/assets/basic_information/file-icon.png differ diff --git a/src/pages/hrefficiency_basicinformation/BasicInformation.less b/src/pages/hrefficiency_basicinformation/BasicInformation.less index 729b9a5..a25c3d8 100644 --- a/src/pages/hrefficiency_basicinformation/BasicInformation.less +++ b/src/pages/hrefficiency_basicinformation/BasicInformation.less @@ -473,7 +473,7 @@ background: #FFD0D0; backdrop-filter: blur(4px); border-radius: 6px; - padding: 12px 16px; + padding: 10px 16px; // margin-bottom: 20px; // border: 1px solid rgba(255, 196, 209, 0.6); // box-shadow: 0 2px 8px rgba(255, 107, 53, 0.1); @@ -552,7 +552,7 @@ .org-connect-line-vertical { position: absolute; - top: 56px; + top: 43px; left: 50%; transform: translateX(-50%); width: 1px; @@ -563,7 +563,7 @@ .org-connect-line-horizontal { position: absolute; - top: 76px; + top: 53px; left: 20%; width: 60%; height: 1px; @@ -572,7 +572,7 @@ .org-connect-line-branch { position: absolute; - top: 70px; + top: 53px; width: 1px; height: 12px; border-left: 1px dashed #9ca3af; @@ -602,30 +602,35 @@ .org-department { text-align: center; position: relative; + // border: 1px solid #333; + background: #fff; + border-radius: 20px; + padding: 5px 15px 5px 5px; + box-shadow: 0 4px 16px rgba(46,76,212,0.10); } .org-department-icon { - width: 48px; - height: 48px; + width: 30px; + height: 30px; border-radius: 50%; - margin: 0 auto 8px; + // margin: 0 auto 8px; display: flex; align-items: center; justify-content: center; } .org-department-icon-safety { - background-color: #52c41a; + background-color: #3CC82D; box-shadow: 0 2px 8px rgba(82, 196, 26, 0.3); } .org-department-icon-production { - background-color: #1890ff; + background-color: #3F78FA; box-shadow: 0 2px 8px rgba(24, 144, 255, 0.3); } .org-department-icon-equipment { - background-color: #13c2c2; + background-color: #20C3FE; box-shadow: 0 2px 8px rgba(19, 194, 194, 0.3); } @@ -637,17 +642,17 @@ .org-department-connect-v { position: absolute; - top: 58px; + top: 45px; left: 50%; transform: translateX(-50%); width: 1px; - height: 20px; + height: 10px; border-left: 1px dashed #9ca3af; } .org-department-connect-h { position: absolute; - top: 78px; + top: 58px; left: 10%; width: 80%; height: 1px; @@ -656,9 +661,9 @@ .org-department-connect-sub { position: absolute; - top: 72px; + top: 58px; width: 1px; - height: 12px; + height: 20px; border-left: 1px dashed #9ca3af; } @@ -764,6 +769,152 @@ background-position: center; } +/* 组织机构图(仿图片样式,无图片引用) */ +.org-structure-title { + text-align: center; + font-size: 15px; + font-weight: 600; + color: #2E4CD4; + margin-bottom: 8px; +} + +.org-structure-chart { + width: 100%; + position: relative; +} + +/* 顶部主节点 */ +.org-main { + display: flex; + justify-content: center; + margin-bottom: 6px; +} +.org-main-label { + background: linear-gradient(90deg,#2E4CD4 0%,#5B8CFF 100%); + color: #fff; + padding: 6px 22px; + border-radius: 18px; + font-weight: 500; + box-shadow: 0 6px 18px rgba(46,76,212,0.12), inset 0 2px 0 rgba(255,255,255,0.12); +} + +/* 主节点到一级部门的虚线 */ +.org-dotted-line-vertical { + width: 100%; + display: flex; + justify-content: center; + margin: -2px 0 6px 0; +} +.org-dotted-line-vertical::after { + content: ""; + width: 2px; + height: 16px; + border-left: 2px dashed #2E4CD4; + border-color: rgba(46,76,212,0.5); + display: inline-block; +} + +/* 一级部门行 */ +.org-level1 { + display: flex; + justify-content: space-between; + align-items: flex-end; + padding: 0 6px; +} + +/* 单个部门 */ +.org-dept { + display: flex; + flex-direction: column; + align-items: center; + width: 32%; +} +.org-dept-icon { + width: 44px; + height: 44px; + border-radius: 22px; + display: flex; + align-items: center; + justify-content: center; + color: #fff; + font-weight: 700; + margin-bottom: 6px; + box-shadow: 0 6px 16px rgba(46,76,212,0.08); +} +.org-dept-green .org-dept-icon { background: #3BC371; } +.org-dept-blue .org-dept-icon { background: #3B6FFF; } +.org-dept-cyan .org-dept-icon { background: #2EC4D4; } + +.org-dept-label { + background: #fff; + padding: 6px 12px; + border-radius: 20px; + box-shadow: 0 4px 12px rgba(46,76,212,0.04); + color: #222; + font-size: 13px; + font-weight: 500; +} + +/* 一级到二级的虚线 */ +.org-dotted-line-horizontal { + width: 100%; + display: flex; + justify-content: center; + margin: 8px 0; +} +.org-dotted-line-horizontal::after { + content: ""; + width: 86%; + height: 2px; + border-top: 2px dashed rgba(46,76,212,0.5); + display: inline-block; +} + +/* 二级科室行 */ +.org-level2 { + display: flex; + justify-content: space-between; + padding: 0 6px; + margin-top: 4px; +} +.org-column { + width: 32%; + display: flex; + flex-direction: column; + align-items: center; +} + +/* 科室项 */ +.org-sub { + display: flex; + align-items: center; + margin: 6px 0; + width: 100%; + justify-content: flex-start; +} +.org-sub-icon { + width: 26px; + height: 26px; + border-radius: 13px; + margin-right: 8px; + box-shadow: 0 4px 12px rgba(46,76,212,0.06); +} +.org-sub-green .org-sub-icon { background: #3BC371; } +.org-sub-blue .org-sub-icon { background: #3B6FFF; } +.org-sub-cyan .org-sub-icon { background: #2EC4D4; } + +.org-sub-label { + font-size: 12px; + color: #0f1724; +} + +/* 响应式小屏适配 */ +@media (max-width: 1000px) { + .org-level1, .org-level2 { flex-direction: column; align-items: center; } + .org-dept, .org-column { width: 100%; margin-bottom: 6px; } + .org-dotted-line-horizontal::after { width: 60%; } +} + // 表单组件公共样式 .createForm { :global(.ant-modal-content) { @@ -782,6 +933,16 @@ text-align: center; } + :global(.ant-upload-drag) { + border: 1px dashed #ACC2E7; + background: #F6F7FF; + } + + :global(.ant-progress-text) { + color: #666; + font-size: 12px; + } + :global { .ant-form { margin-right: 24px; @@ -833,4 +994,216 @@ font-weight: 500; word-break: break-all; display: inline-block; +} + +//文件导入列表样式 +.import-file-list { + margin-top: 20px; + max-height: 240px; + overflow-y: auto; +} +.import-file-item { + background: #F6F7FF; + border-radius: 4px; + border: 1px solid #E6E9FB; + margin-bottom: 10px; + padding: 5px 10px; + display: flex; + align-items: center; + box-shadow: 0 2px 8px 0 rgba(46,76,212,0.03); + position: relative; +} +.import-file-icon { + width: 36px; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + margin-right: 10px; + flex-shrink: 0; +} +.import-file-info { + flex: 1; +} +.import-file-name { + color: #222; + font-size: 14px; + font-weight: 500; +} +.import-file-size { + color: #888; + font-size: 12px; + margin-bottom: 2px; +} +.import-file-remove { + margin-left: 12px; + cursor: pointer; + color: #666666; + font-size: 18px; + position: absolute; + right: 16px; + top: 6px; +} + +.import-file-list { + margin-top: 20px; + max-height: 240px; + overflow-y: auto; + /* 隐藏滚动条(兼容主流浏览器) */ + scrollbar-width: none; /* Firefox */ + -ms-overflow-style: none; /* IE 10+ */ +} +.import-file-list::-webkit-scrollbar { + display: none; /* Chrome/Safari/Webkit */ +} + +/* 新增样式类 - 基础信息模块 */ +.basic-info-container { + background: #F9FAFB; + border-radius: 8px; + padding: 24px; + margin-bottom: 24px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +.basic-info-title { + font-size: 18px; + font-weight: 600; + color: #111; + margin-bottom: 16px; +} + +.basic-info-item { + display: flex; + justify-content: space-between; + padding: 12px 0; + border-bottom: 1px solid #E5E7EB; +} + +.basic-info-item:last-child { + border-bottom: none; +} + +.basic-info-label { + font-size: 14px; + color: #6B7280; +} + +.basic-info-value { + font-size: 14px; + color: #374151; + font-weight: 500; +} + +/* 实时风险评估新增样式 */ +.risk-assessment-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 16px; +} + +.risk-assessment-title { + font-size: 16px; + font-weight: 500; + color: #333; +} + +.risk-assessment-refresh { + font-size: 14px; + color: #2E4CD4; + cursor: pointer; +} + +.risk-assessment-content { + display: flex; + flex-direction: column; + gap: 16px; +} + +.risk-assessment-item { + background: #FFFFFF; + border-radius: 8px; + padding: 16px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); +} + +.risk-assessment-item-title { + font-size: 14px; + font-weight: 500; + color: #111; + margin-bottom: 8px; +} + +.risk-assessment-item-value { + font-size: 22px; + font-weight: 600; + color: #2E4CD4; +} + +.risk-assessment-item-description { + font-size: 12px; + color: #666; + line-height: 1.5; +} + +/* 新增的组织架构样式 */ +.org-sub-row-group { + display: flex; + justify-content: space-between; + padding-left: 4%; + padding-right: 4%; +} +.org-sub-group { + display: flex; + gap: 16px; + margin-top: 12px; +} +.org-sub-item { + text-align: center; +} +.org-sub-icon-green { + width: 36px; + height: 36px; + border-radius: 50%; + background-color: #3CC82D; + margin: 0 auto 6px; + display: flex; + align-items: center; + justify-content: center; +} +.org-sub-icon-blue { + width: 36px; + height: 36px; + border-radius: 50%; + background-color: #3F78FA; + margin: 0 auto 6px; + display: flex; + align-items: center; + justify-content: center; +} +.org-sub-icon-cyan { + width: 36px; + height: 36px; + border-radius: 50%; + background-color: #20C3FE; + margin: 0 auto 6px; + display: flex; + align-items: center; + justify-content: center; +} +.org-sub-label-green { + font-size: 10px; + color: #3CC82D; + line-height: 1.2; +} +.org-sub-label-blue { + font-size: 10px; + color: #3F78FA; + line-height: 1.2; +} +.org-sub-label-cyan { + font-size: 10px; + color: #20C3FE; + line-height: 1.2; } \ No newline at end of file diff --git a/src/pages/hrefficiency_basicinformation/components/BasicInfoManagement.js b/src/pages/hrefficiency_basicinformation/components/BasicInfoManagement.js index 7c12699..1ca9d76 100644 --- a/src/pages/hrefficiency_basicinformation/components/BasicInfoManagement.js +++ b/src/pages/hrefficiency_basicinformation/components/BasicInfoManagement.js @@ -28,6 +28,7 @@ import style from "@/global.less"; import BasicInfoCreateForm from '../form/BasicInfoCreateForm'; //新增表单 import BasicInfoUpdateForm from '../form/BasicInfoUpdateForm'; //修改表单 import BasicInfoViewForm from '../form/BasicInfoViewForm'; //查看表单 +import BasicInfoImportForm from '../form/BasicInfoImportForm'; //修改表单 import styles from '../BasicInformation.less'; import datadictionary from "@/utils/dataDictionary"; import { formatDate } from "@/utils/formatUtils"; @@ -101,6 +102,7 @@ class BasicInfoManagement extends PureComponent { modalVisible: false, updateModalVisible: false, viewModalVisible: false, + importModalVisible: false, // 新增导入弹窗状态 expandForm: false, selectedRows: [], formValues: {}, @@ -223,7 +225,7 @@ class BasicInfoManagement extends PureComponent { legend: { orient: 'vertical', right: '20%', - top: '25%', + top: '27%', itemWidth: 16, itemHeight: 4, itemGap: 16, @@ -379,6 +381,12 @@ class BasicInfoManagement extends PureComponent { }) } + handleImportModalVisible = (flag) => { + this.setState({ + importModalVisible: !!flag + }); + } + render() { const { loading, @@ -392,6 +400,7 @@ class BasicInfoManagement extends PureComponent { updateFormValues, viewFormValues, toggleExpand, + importModalVisible, } = this.state const parentMethods = { @@ -453,7 +462,7 @@ class BasicInfoManagement extends PureComponent { type="primary" className={styles['org-top-button']} > - 项目安全管组织架构 + 项目安全管理组织架构 @@ -471,10 +480,12 @@ class BasicInfoManagement extends PureComponent { {/* 第一层部门 */}
-
- +
+
+ +
+
安监部
-
安监部
{/* 安监部连接线 */}
@@ -484,10 +495,12 @@ class BasicInfoManagement extends PureComponent {
-
- +
+
+ +
+
生产部
-
生产部
{/* 生产部连接线 */}
@@ -497,10 +510,12 @@ class BasicInfoManagement extends PureComponent {
-
- +
+
+ +
+
设备部
-
设备部
{/* 设备部连接线 */}
@@ -511,111 +526,50 @@ class BasicInfoManagement extends PureComponent {
{/* 第二层子部门 */} -
+
{/* 安监部子部门 */} -
-
-
+
+
+
-
安全监督科
+
安全监督岗
-
-
+
+
-
风险评估科
+
风险评估岗
- {/* 生产部子部门 */} -
-
-
+
+
+
-
生产调度科
+
生产调度岗
-
-
+
+
-
现场管理科
+
现场管理岗
- {/* 设备部子部门 */} -
-
-
+
+
+
-
设备维护科
+
设备维护岗
-
-
+
+
-
备件管理科
+
备件管理岗
@@ -748,13 +702,14 @@ class BasicInfoManagement extends PureComponent { @@ -799,6 +754,12 @@ class BasicInfoManagement extends PureComponent { values={viewFormValues} /> ) : null} + {importModalVisible && ( + + )} ) } diff --git a/src/pages/hrefficiency_basicinformation/components/PersonnelBasicInfo.js b/src/pages/hrefficiency_basicinformation/components/PersonnelBasicInfo.js index a1a1700..1639122 100644 --- a/src/pages/hrefficiency_basicinformation/components/PersonnelBasicInfo.js +++ b/src/pages/hrefficiency_basicinformation/components/PersonnelBasicInfo.js @@ -26,7 +26,7 @@ import ReactECharts from 'echarts-for-react'; import { MyIcon } from "@/components/Icon" import style from "@/global.less"; -import StaffSheetCreateForm from '../form/BasicInfoCreateForm'; //新增表单 +import PersonnelCreateForm from '../form/PersonnelCreateForm'; //新增表单 import StaffSheetUpdateForm from '../form/BasicInfoUpdateForm'; //修改表单 import StaffSheetViewForm from '../form/BasicInfoViewForm'; //查看表单 import styles from '../BasicInformation.less'; @@ -721,6 +721,7 @@ class PersonnelBasicInfo extends PureComponent { @@ -754,7 +755,7 @@ class PersonnelBasicInfo extends PureComponent { />
- {modalVisible && } + {modalVisible && } {updateFormValues && Object.keys(updateFormValues).length ? ( { + const { modalVisible, handleModalVisible, loading } = props; + const [fileList, setFileList] = useState([ + // 示例数据,实际可根据上传进度动态设置 + // { uid: '1', name: '文件名称', size: 3 * 1024 * 1024, status: 'uploading', percent: 60 }, + // ... + ]); + + const maxFiles = 10; + const maxSize = 100 * 1024 * 1024; // 100M + + const beforeUpload = (file) => { + if (file.size > maxSize) { + message.error('单个文件不能超过100M'); + return Upload.LIST_IGNORE; + } + if (fileList.length >= maxFiles) { + message.error(`最多只能上传${maxFiles}个文件`); + return Upload.LIST_IGNORE; + } + // 模拟上传进度 + file.status = 'uploading'; + file.percent = 60; + return true; + }; + + const handleChange = ({ fileList: newFileList }) => { + // 模拟每个文件60%进度 + const updatedList = newFileList.slice(0, maxFiles).map(file => ({ + ...file, + status: 'uploading', + percent: 60, + })); + setFileList(updatedList); + }; + + const handleRemove = (file) => { + setFileList(fileList.filter(item => item.uid !== file.uid)); + }; + + const handleOk = () => { + handleModalVisible(false); + setFileList([]); + }; + + const handleCancel = () => { + handleModalVisible(false); + setFileList([]); + }; + + // 文件列表渲染 + const renderFileList = () => ( +
+ {fileList.map(file => ( +
+
+ file +
+
+
{file.name || '文件名称'}
+
+ {file.size ? `${(file.size / (1024 * 1024)).toFixed(0)} MB` : '3 MB'} +
+ +
+
handleRemove(file)} + > + × +
+
+ ))} +
+ ); + + return ( + 取消, + + ]} + > +
+ {fileList.length > 0 && renderFileList()} +
+ +
+ +
+
+ 添加文件 {fileList.length}/{maxFiles} +
+
+
+
+ + 单个文件不超过 100M +
+
+
+ ); +}; + +export default BasicInfoImportForm; \ No newline at end of file diff --git a/src/pages/hrefficiency_basicinformation/form/PersonnelCreateForm.js b/src/pages/hrefficiency_basicinformation/form/PersonnelCreateForm.js new file mode 100644 index 0000000..76b3e56 --- /dev/null +++ b/src/pages/hrefficiency_basicinformation/form/PersonnelCreateForm.js @@ -0,0 +1,152 @@ +import { useState, useEffect } from 'react' +import { Col, DatePicker, Form, Input, Modal, Row, Select } from 'antd' +import SelectDeptTree from '@/components/SelectDeptTree' +import SelectOrganTree from '@/components/SelectOrganTree' +import datadictionary from '@/utils/dataDictionary' +import { formatDictOptions, verifyPhone } from '@/utils/globalCommon' +import { NumberInput } from '@/components/NumberInput' +import styles from '../BasicInformation.less' +import style from '@/global.less' +import dayjs from 'dayjs' +import { formatDate } from '@/utils/formatUtils' + +const { Item: FormItem } = Form +const { TextArea } = Input +const dictData = datadictionary + +//新增表单 +let getDeptTreeBySelectTree +let getOrganTreeBySelectTree + +const PersonnelCreateForm = (props => { + const [form] = Form.useForm() + + const { + modalVisible, + handleAdd, + handleModalVisible, + loading, + dispatch, + selectDeptTree, + selectOrganTree + } = props + + // 清空和初始化逻辑可保留 + useEffect(() => { + form.resetFields(); + }, [modalVisible]) + + const okHandle = () => { + form.validateFields() + .then(fieldsValue => { + form.resetFields() + handleAdd(fieldsValue) + }) + .catch(() => { }) + } + + const afterClose = () => { + form.resetFields(); + } + + return ( + handleModalVisible()} + afterClose={afterClose} + confirmLoading={loading} + footer={[ + , + + ]} + > +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ ) +}) + +export default PersonnelCreateForm