diff --git a/config/routes.js b/config/routes.js
index 0614436..b2e1d63 100644
--- a/config/routes.js
+++ b/config/routes.js
@@ -24,6 +24,12 @@ export default [
name: 'business',
component: './nav_system_content/SystemContentList',
routes: [
+ // 基础信息管理
+ {
+ path: '/topnavbar00/business/basic',
+ name: 'basic',
+ component: './business_basic/basic',
+ },
// 安全管理基础信息
{
path: '/topnavbar00/business/basicinformation',
diff --git a/src/assets/business_basic/Frame.png b/src/assets/business_basic/Frame.png
new file mode 100644
index 0000000..04c3628
Binary files /dev/null and b/src/assets/business_basic/Frame.png differ
diff --git a/src/pages/business_basic/basic.js b/src/pages/business_basic/basic.js
new file mode 100644
index 0000000..db6ea83
--- /dev/null
+++ b/src/pages/business_basic/basic.js
@@ -0,0 +1,66 @@
+import React, { useState } from 'react';
+import { Card, Row, Col, Statistic, Progress, Button, Space } from 'antd';
+import styles from './basic.less';
+import ResponsibilityImplementation from './module/ResponsibilityImplementation'; //责任落实
+import OnlineMonitoring from './module/OnlineMonitoring'; //在线监测预警
+import RiskAssessment from './module/RiskAssessment'; //风险管控
+import EvaluationReport from './module/EvaluationReport'; //评估报告
+
+
+
+const SafeMajorHazardList = () => {
+ const [activeModule, setActiveModule] = useState('organization');
+
+ const handleModuleClick = (module) => {
+ setActiveModule(module)
+ }
+
+
+ const renderModule = () => {
+ switch (activeModule) {
+ case 'organization':
+ return ;
+ case 'equipment':
+ return ;
+ case 'firefighting':
+ return ;
+ case 'other':
+ return ;
+ default:
+ return ;
+ }
+ };
+
+
+ return (
+
+
+
+
+
+
+
+
+ {renderModule()}
+
+
+ );
+};
+
+export default SafeMajorHazardList;
diff --git a/src/pages/business_basic/basic.less b/src/pages/business_basic/basic.less
new file mode 100644
index 0000000..b479169
--- /dev/null
+++ b/src/pages/business_basic/basic.less
@@ -0,0 +1,66 @@
+.container {
+ background-color: transparent;
+ width: 100%;
+ height: 89vh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+
+ .TopButton {
+ background-color: white;
+ width: 100%;
+ padding: 10px 30px;
+ display: flex;
+ gap: 24px;
+ margin-left: 6px;
+
+ .TopButtonItem {
+ background-color: transparent !important;
+ color: #333333 !important;
+ font-family: 'PingFang SC', sans-serif !important;
+ font-weight: 500 !important;
+ font-size: 14px !important;
+ line-height: 100% !important;
+ border-radius: 8px !important;
+ padding: 6px 10px !important;
+ height: auto !important;
+ border: none !important;
+ box-shadow: none !important;
+ position: relative !important;
+
+ &:hover {
+ color: #333333 !important;
+ border: none !important;
+ }
+
+ &:focus {
+ color: #2E4CD4 !important;
+ border: none !important;
+ }
+
+ &.active {
+ color: #2E4CD4 !important;
+
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: -10px;
+ left: 0;
+ right: 0;
+ width: 100%;
+ height: 4px;
+ background-color: #2E4CD4;
+ border-radius: 0;
+ opacity: 1;
+ }
+ }
+ }
+ }
+
+ .content {
+ // ======== 内容区域样式 ========
+ flex: 1; // ======== 占据剩余空间 ========
+ overflow-y: auto; // ======== 允许垂直滚动 ========
+ padding: 0; // ======== 无内边距 ========
+ }
+}
\ No newline at end of file
diff --git a/src/pages/business_basic/form/StaffSheetCreateForm.js b/src/pages/business_basic/form/StaffSheetCreateForm.js
new file mode 100644
index 0000000..6bdce8d
--- /dev/null
+++ b/src/pages/business_basic/form/StaffSheetCreateForm.js
@@ -0,0 +1,271 @@
+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 '../StaffSheetList.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 StaffSheetCreateForm = (props => {
+ const [form] = Form.useForm()
+ const [jobStatus, setJobStatus] = useState('1')
+
+ const {
+ modalVisible,
+ handleAdd,
+ handleModalVisible,
+ loading,
+ dispatch,
+ selectDeptTree,
+ selectOrganTree
+ } = props
+
+ useEffect(() => {
+ form.setFieldsValue({
+ user_type: 'employee',
+ job_status: '1',
+ mgr_type: '0'
+ })
+ }, [])
+
+ const selectedDeptTreeValue = (deptRecord) => {
+ getDeptTreeBySelectTree = deptRecord
+ }
+
+ const selectedOrganTreeValue = (orgRecord) => {
+ getOrganTreeBySelectTree = orgRecord
+ }
+
+ const parentDeptTreeMethod = {
+ dispatch: dispatch,
+ selectDeptTree: selectDeptTree,
+ selectedDeptTreeValue: selectedDeptTreeValue,
+ }
+
+ const parentOrganTreeMethod = {
+ dispatch: dispatch,
+ selectOrganTree: selectOrganTree,
+ selectedOrganTreeValue: selectedOrganTreeValue
+ }
+
+ const okHandle = () => {
+ form.validateFields()
+ .then(fieldsValue => {
+ form.resetFields()
+ fieldsValue.birthday = formatDate(fieldsValue.birthday, 'YYYY-MM-DD')
+ fieldsValue.hiredate = formatDate(fieldsValue.hiredate, 'YYYY-MM-DD')
+ fieldsValue.departure_time = formatDate(fieldsValue.departure_time, 'YYYY-MM-DD')
+ fieldsValue.posts = fieldsValue.posts ? JSON.stringify(fieldsValue.posts) : null
+
+ // if (getDeptTreeBySelectTree) {
+ // fieldsValue.dept_code = getDeptTreeBySelectTree.dept_code
+ // fieldsValue.dept_name = getDeptTreeBySelectTree.title
+ // }
+
+ if (getOrganTreeBySelectTree) {
+ fieldsValue.org_code = getOrganTreeBySelectTree.org_code
+ fieldsValue.org_name = getOrganTreeBySelectTree.title
+ }
+
+ handleAdd(fieldsValue)
+ })
+ .catch(errInfo => {})
+ }
+
+ const afterClose = () =>{
+ form.resetFields();
+ }
+
+ const handleJobStatusChange = (value) => {
+ setJobStatus(value)
+ }
+
+ return (
+ handleModalVisible()}
+ afterClose={() => afterClose()}
+ confirmLoading={loading}
+ >
+
+
+ )
+})
+
+export default StaffSheetCreateForm
diff --git a/src/pages/business_basic/form/StaffSheetRenderAdvancedForm.js b/src/pages/business_basic/form/StaffSheetRenderAdvancedForm.js
new file mode 100644
index 0000000..2625938
--- /dev/null
+++ b/src/pages/business_basic/form/StaffSheetRenderAdvancedForm.js
@@ -0,0 +1,113 @@
+import { useEffect } from 'react'
+import { Button, Col, Form, Input, Row } from 'antd'
+import { UpOutlined, SearchOutlined, RedoOutlined } from '@ant-design/icons'
+import SelectDeptTree from '@/components/SelectDeptTree'
+import SelectOrganTree from '@/components/SelectOrganTree'
+import style from '@/global.less'
+
+const { Item: FormItem } = Form
+let getDeptTreeBySelectTree
+let getOrganTreeBySelectTree
+
+const StaffSheetRenderAdvancedForm = (props) => {
+ const [form] = Form.useForm()
+ const { dispatch, handleSearch, handleFormReset, toggleForm, selectDeptTree, selectOrganTree, params } = props
+
+ useEffect(() => {
+ form.setFieldsValue({
+ user_name: params?.user_name,
+ user_name_cn: params?.user_name_cn,
+ deptname: params?.deptname,
+ orgname: params?.orgname,
+ })
+ }, [params])
+
+ const onFinish = values => {
+ // if (getDeptTreeBySelectTree) {
+ // values.dept_code = getDeptTreeBySelectTree.dept_code
+ // values.deptname = getDeptTreeBySelectTree.title
+ // }
+
+ if (getOrganTreeBySelectTree) {
+ values.org_code = getOrganTreeBySelectTree.org_code
+ values.orgname = getOrganTreeBySelectTree.title
+ }
+
+ handleSearch(values)
+ }
+
+ const myHandleFormReset = () => {
+ form.resetFields()
+ handleFormReset()
+ }
+
+ const selectedDeptTreeValue = (deptRecord) => {
+ getDeptTreeBySelectTree = deptRecord
+ }
+
+ const selectedOrganTreeValue = (orgRecord) => {
+ getOrganTreeBySelectTree = orgRecord
+ }
+
+ const parentDeptTreeMethod = {
+ dispatch: dispatch,
+ selectDeptTree: selectDeptTree,
+ selectedDeptTreeValue: selectedDeptTreeValue
+ }
+
+ const parentOrganTreeMethod = {
+ dispatch: dispatch,
+ selectOrganTree: selectOrganTree,
+ selectedOrganTreeValue: selectedOrganTreeValue
+ }
+
+ return (
+
+ )
+}
+
+export default StaffSheetRenderAdvancedForm
diff --git a/src/pages/business_basic/form/StaffSheetRenderSimpleForm.js b/src/pages/business_basic/form/StaffSheetRenderSimpleForm.js
new file mode 100644
index 0000000..0468e76
--- /dev/null
+++ b/src/pages/business_basic/form/StaffSheetRenderSimpleForm.js
@@ -0,0 +1,81 @@
+import { useEffect } from 'react'
+import {Button, Col, Form, Input, Row, DatePicker, Select} from 'antd'
+import {DownOutlined, RedoOutlined, SearchOutlined} from '@ant-design/icons'
+import style from '@/global.less'
+import dayjs from 'dayjs'
+const { Item: FormItem } = Form
+
+const StaffSheetRenderSimpleForm = (props) => {
+ const [form] = Form.useForm()
+ const { handleSearch, handleFormReset, toggleForm, params } = props
+
+ useEffect(() => {
+ form.setFieldsValue({
+ user_name: params?.user_name,
+ user_name_cn: params?.user_name_cn,
+ })
+ }, [params])
+
+ const onFinish = values => {
+ handleSearch(values)
+ }
+
+ const myHandleFormReset = () => {
+ form.resetFields()
+ handleFormReset()
+ }
+
+ return (
+
+ )
+}
+
+export default StaffSheetRenderSimpleForm
diff --git a/src/pages/business_basic/form/StaffSheetUpdateForm.js b/src/pages/business_basic/form/StaffSheetUpdateForm.js
new file mode 100644
index 0000000..f33d64b
--- /dev/null
+++ b/src/pages/business_basic/form/StaffSheetUpdateForm.js
@@ -0,0 +1,362 @@
+import { useState, useEffect } from 'react'
+import { Col, DatePicker, Form, Input, Modal, Row, Select } from 'antd'
+import SelectOrganTree from '@/components/SelectOrganTree'
+import datadictionary from '@/utils/dataDictionary'
+import { formatDictOptions, verifyPhone } from '@/utils/globalCommon'
+import { NumberInput } from '@/components/NumberInput'
+import styles from '../StaffSheetList.less'
+import style from '@/global.less'
+import dayjs from 'dayjs'
+import { formatDate, formatDateObject } from '@/utils/formatUtils'
+
+const { Item: FormItem } = Form
+const { TextArea } = Input
+const dictData = datadictionary
+
+//新增表单
+let getDeptTreeBySelectTree
+let getOrganTreeBySelectTree
+
+const StaffSheetUpdateForm = (props) => {
+ const [form] = Form.useForm()
+ const [jobStatus, setJobStatus] = useState('1')
+ const [userStatus, setUserStatus] = useState('0')
+
+ const {
+ handleUpdate,
+ updateModalVisible,
+ handleUpdateModalVisible,
+ values,
+ loading,
+ dispatch,
+ selectDeptTree,
+ selectOrganTree
+ } = props
+
+ const selectedDeptTreeValue = (deptRecord) => {
+ getDeptTreeBySelectTree = deptRecord
+ }
+
+ const selectedOrganTreeValue = (orgRecord) => {
+ getOrganTreeBySelectTree = orgRecord
+ }
+
+ const parentDeptTreeMethod = {
+ dispatch: dispatch,
+ selectDeptTree: selectDeptTree,
+ selectedDeptTreeValue: selectedDeptTreeValue,
+ }
+
+ const parentOrganTreeMethod = {
+ dispatch: dispatch,
+ selectOrganTree: selectOrganTree,
+ selectedOrganTreeValue: selectedOrganTreeValue
+ }
+
+ useEffect(() => {
+ setJobStatus(values.job_status)
+ setUserStatus(values.status)
+
+ form.setFieldsValue({
+ user_id: values.user_id,
+ user_name: values.user_name,
+ user_name_cn: values.user_name_cn,
+ user_name_en: values.user_name_en,
+ password: values.password,
+ email: values.email,
+ phone: values.phone,
+ landline: values.landline,
+ sex: values.sex,
+ avatar: values.avatar,
+ sign: values.sign,
+ tags: values.tags,
+ id_card: values.id_card,
+ birthday: formatDateObject(values.birthday, 'YYYY-MM-DD'),
+ job_status: values.job_status,
+ hiredate: formatDateObject(values.hiredate, 'YYYY-MM-DD'),
+ departure_time: formatDateObject(values.departure_time, 'YYYY-MM-DD'),
+ user_type: values.user_type,
+ emp_no: values.emp_no,
+ access_card_no: values.access_card_no,
+ country: values.country,
+ province: values.province,
+ city: values.city,
+ address: values.address,
+ work_addr: values.work_addr,
+ floor: values.floor,
+ inprovince: values.inprovince,
+ // dept_code: values.dept_code,
+ // dept_name: values.dept_name,
+ inner_dept_code: values.inner_dept_code,
+ org_code: values.org_code,
+ org_name: values.org_name,
+ inner_org_code: values.inner_org_code,
+ posts: values.posts ? JSON.parse(values.posts) : [],
+ wx_openid: values.wx_openid,
+ wx_mpopenid: values.wx_mpopenid,
+ wx_miniopenid: values.wx_miniopenid,
+ wx_unionid: values.wx_unionid,
+ mobile_imei: values.mobile_imei,
+ device_num: values.device_num,
+ al_taobao: values.al_taobao,
+ al_alipay: values.al_alipay,
+ al_dingding: values.al_dingding,
+ is_system_user: values.is_system_user,
+ mgr_type: values.mgr_type,
+ pwd_security_level: values.pwd_security_level,
+ pwd_update_date: values.pwd_update_date,
+ last_login_ip: values.last_login_ip,
+ last_login_date: values.last_login_date,
+ freeze_date: values.freeze_date,
+ freeze_cause: values.freeze_cause,
+ zindex: values.zindex,
+ wx_msg: values.wx_msg,
+ email_msg: values.email_msg,
+ system_msg: values.system_msg,
+ remarks: values.remarks,
+ status: values.status,
+ creator: values.creator,
+ create_date: values.create_date,
+ updater: values.updater,
+ update_date: values.update_date
+ })
+ }, [])
+
+ const handleLocalUpdate = () => {
+ form
+ .validateFields()
+ .then(fieldsValue => {
+ const formVals = {...values, ...fieldsValue}
+ formVals.birthday = formatDate(formVals.birthday, 'YYYY-MM-DD')
+ formVals.hiredate = formatDate(formVals.hiredate, 'YYYY-MM-DD')
+ formVals.departure_time = formatDate(formVals.departure_time, 'YYYY-MM-DD')
+ formVals.posts = formVals.posts ? JSON.stringify(formVals.posts) : null
+ formVals.freeze_date = '3' === formVals.status ? formatDate(dayjs().endOf('day'), 'YYYY-MM-DD') : null
+ formVals.freeze_cause = '3' === formVals.status ? formVals.freeze_cause : null
+
+ // if (getDeptTreeBySelectTree) {
+ // formVals.dept_code = getDeptTreeBySelectTree.dept_code
+ // formVals.dept_name = getDeptTreeBySelectTree.title
+ // }
+
+ if (getOrganTreeBySelectTree) {
+ formVals.org_code = getOrganTreeBySelectTree.org_code
+ formVals.org_name = getOrganTreeBySelectTree.title
+ }
+
+ handleUpdate(formVals)
+
+ })
+ .catch(errInfo => {})
+ }
+
+ const afterClose = () =>{
+ form.resetFields();
+ }
+
+ const handleJobStatusChange = (value) => {
+ setJobStatus(value)
+ }
+
+ const handleUserStatusChange = (value) => {
+ setUserStatus(value)
+ }
+
+ return (
+ handleLocalUpdate()}
+ onCancel={() => handleUpdateModalVisible()}
+ afterClose={() => afterClose()}
+ confirmLoading={loading}
+ >
+
+
+ )
+}
+
+export default StaffSheetUpdateForm
diff --git a/src/pages/business_basic/form/StaffSheetViewForm.js b/src/pages/business_basic/form/StaffSheetViewForm.js
new file mode 100644
index 0000000..9acb9c4
--- /dev/null
+++ b/src/pages/business_basic/form/StaffSheetViewForm.js
@@ -0,0 +1,299 @@
+import { useState, useEffect } from 'react'
+import {Col, DatePicker, Form, Input, Modal, Row, Select} from 'antd'
+import datadictionary from '@/utils/dataDictionary'
+import style from "@/global.less";
+import {formatDictOptions, verifyPhone} from "@/utils/globalCommon";
+import {NumberInput} from "@/components/NumberInput";
+import dayjs from "dayjs";
+import SelectOrganTree from "@/components/SelectOrganTree";
+import {formatDateObject} from "@/utils/formatUtils";
+
+const { Item: FormItem } = Form
+const { TextArea } = Input
+const dictData = datadictionary
+
+const StaffSheetViewForm = (props) => {
+ const [form] = Form.useForm()
+ const [jobStatus, setJobStatus] = useState('1')
+ const [userStatus, setUserStatus] = useState('0')
+
+ const { viewModalVisible, handleViewModalVisible, values } = props
+
+ useEffect(() => {
+ setJobStatus(values.job_status)
+ setUserStatus(values.status)
+
+ form.setFieldsValue({
+ user_id: values.user_id,
+ user_name: values.user_name,
+ user_name_cn: values.user_name_cn,
+ user_name_en: values.user_name_en,
+ password: values.password,
+ email: values.email,
+ phone: values.phone,
+ landline: values.landline,
+ sex: values.sex,
+ avatar: values.avatar,
+ sign: values.sign,
+ tags: values.tags,
+ id_card: values.id_card,
+ birthday: formatDateObject(values.birthday, 'YYYY-MM-DD'),
+ job_status: values.job_status,
+ hiredate: formatDateObject(values.hiredate, 'YYYY-MM-DD'),
+ departure_time: formatDateObject(values.departure_time, 'YYYY-MM-DD'),
+ user_type: values.user_type,
+ emp_no: values.emp_no,
+ access_card_no: values.access_card_no,
+ country: values.country,
+ province: values.province,
+ city: values.city,
+ address: values.address,
+ work_addr: values.work_addr,
+ floor: values.floor,
+ inprovince: values.inprovince,
+ // dept_code: values.dept_code,
+ // dept_name: values.dept_name,
+ inner_dept_code: values.inner_dept_code,
+ org_code: values.org_code,
+ org_name: values.org_name,
+ inner_org_code: values.inner_org_code,
+ posts: values.posts ? JSON.parse(values.posts) : [],
+ wx_openid: values.wx_openid,
+ wx_mpopenid: values.wx_mpopenid,
+ wx_miniopenid: values.wx_miniopenid,
+ wx_unionid: values.wx_unionid,
+ mobile_imei: values.mobile_imei,
+ device_num: values.device_num,
+ al_taobao: values.al_taobao,
+ al_alipay: values.al_alipay,
+ al_dingding: values.al_dingding,
+ is_system_user: values.is_system_user,
+ mgr_type: values.mgr_type,
+ pwd_security_level: values.pwd_security_level,
+ pwd_update_date: values.pwd_update_date,
+ last_login_ip: values.last_login_ip,
+ last_login_date: values.last_login_date,
+ freeze_date: values.freeze_date,
+ freeze_cause: values.freeze_cause,
+ zindex: values.zindex,
+ wx_msg: values.wx_msg,
+ email_msg: values.email_msg,
+ system_msg: values.system_msg,
+ remarks: values.remarks,
+ status: values.status,
+ creator: values.creator,
+ create_date: values.create_date,
+ updater: values.updater,
+ update_date: values.update_date
+ })
+ }, [])
+
+ const afterClose = () =>{
+ form.resetFields();
+ }
+
+ const handleJobStatusChange = (value) => {
+ setJobStatus(value)
+ }
+
+ const handleUserStatusChange = (value) => {
+ setUserStatus(value)
+ }
+
+ return (
+ handleViewModalVisible()}
+ onCancel={() => handleViewModalVisible()}
+ afterClose={() => afterClose()}
+ >
+
+
+ )
+}
+
+export default StaffSheetViewForm
diff --git a/src/pages/business_basic/models/StaffSheet.js b/src/pages/business_basic/models/StaffSheet.js
new file mode 100644
index 0000000..79b74c9
--- /dev/null
+++ b/src/pages/business_basic/models/StaffSheet.js
@@ -0,0 +1,319 @@
+import { deleteByPrimaryKeyForProUser, selectByPrimaryKeyForProUser, insertForProUser, updateForProUser, deleteByMapForProUser,updateByMapForProUser, getOneForProUser,getAllForProUser,queryPageForProUser, countForProUser, insertBatchForProUser, deleteBatchForProUser,updateBatchForProUser, resetPwdForProUser } from '@/services/system/api_prouser';
+
+export default {
+ namespace: 'safemajorhazard',
+
+ state: {
+ params: {},
+ data: {
+ list: [],
+ pagination: {},
+ },
+ },
+
+ effects: {
+ *delete_by_primarykey_for_prouser({ payload, callback }, { select, call, put }) {
+ const response = yield call(deleteByPrimaryKeyForProUser, payload)
+ yield put({
+ type: 'deleteByPrimaryKeyForProUser',
+ payload: response
+ })
+
+ if (!response.success) {
+ callback && callback(response)
+ return
+ }
+
+ const params = yield select(state => state.prouser.params)
+ const responseData = yield call(queryPageForProUser, params)
+ yield put({
+ type: 'queryPageForProUser',
+ payload: responseData
+ })
+
+ if (callback) callback(response)
+ },
+ *select_by_primarykey_for_prouser({ payload, callback }, { call, put }) {
+ const response = yield call(selectByPrimaryKeyForProUser, payload)
+ yield put({
+ type: 'selectByPrimaryKeyForProUser',
+ payload: response
+ })
+
+ if (callback) callback(response)
+ },
+ *insert_for_prouser({ payload, callback }, { select, call, put }) {
+ const response = yield call(insertForProUser, payload)
+ yield put({
+ type: 'insertForProUser',
+ payload: response
+ })
+
+ if (!response.success) {
+ callback && callback(response)
+ return
+ }
+
+ const params = yield select(state => state.prouser.params)
+ const responseData = yield call(queryPageForProUser, params)
+ yield put({
+ type: 'queryPageForProUser',
+ payload: responseData
+ })
+
+ if (callback) callback(response)
+ },
+ *update_for_prouser({ payload, callback }, { select, call, put }) {
+ const response = yield call(updateForProUser, payload)
+ yield put({
+ type: 'updateForProUser',
+ payload: response
+ })
+
+ if (!response.success) {
+ callback && callback(response)
+ return
+ }
+
+ const params = yield select(state => state.prouser.params)
+ const responseData = yield call(queryPageForProUser, params)
+ yield put({
+ type: 'queryPageForProUser',
+ payload: responseData
+ })
+
+ if (callback) callback(response)
+ },
+ *delete_by_map_for_prouser({ payload, callback }, { select, call, put }) {
+ const response = yield call(deleteByMapForProUser, payload);
+ yield put({
+ type: 'deleteByMapForProUser',
+ payload: response,
+ });
+
+ const params = yield select(state => state.prouser.params);
+ const responsedata = yield call(queryPageForProUser, params);
+ yield put({
+ type: 'queryPageForProUser',
+ payload: responsedata,
+ });
+
+ if (callback) callback(response);
+ },
+ *update_by_map_for_prouser({ payload, callback }, { select, call, put }) {
+ const response = yield call(updateByMapForProUser, payload);
+ yield put({
+ type: 'updateByMapForProUser',
+ payload: response,
+ });
+
+ const params = yield select(state => state.prouser.params);
+ const responsedata = yield call(queryPageForProUser, params);
+ yield put({
+ type: 'queryPageForProUser',
+ payload: responsedata,
+ });
+
+ if (callback) callback(response);
+ },
+ *get_one_for_prouser({ payload, callback }, { call, put }) {
+ const response = yield call(getOneForProUser, payload);
+ yield put({
+ type: 'getOneForProUser',
+ payload: response,
+ });
+
+ if (callback) callback(response);
+ },
+ *get_all_for_prouser({ payload, callback }, { call, put }) {
+ const response = yield call(getAllForProUser, payload);
+ yield put({
+ type: 'getAllForProUser',
+ payload: response,
+ });
+
+ if (callback) callback(response);
+ },
+ *query_page_for_prouser({ payload, callback }, { select, call, put }) {
+ const params = yield select(state => state.prouser.params);
+ const newParams = payload?.resetFlag ? payload : {...params, ...payload};
+ yield put({
+ type: 'setQueryPageByParams',
+ payload: newParams,
+ });
+ const response = yield call(queryPageForProUser, newParams);
+ yield put({
+ type: 'queryPageForProUser',
+ payload: response,
+ });
+
+ if (callback) callback(response);
+ },
+ *count_for_prouser({ payload, callback }, { call, put }) {
+ const response = yield call(countForProUser, payload);
+ yield put({
+ type: 'countForProUser',
+ payload: response,
+ });
+
+ if (callback) callback(response);
+ },
+ *insert_batch_for_prouser({ payload, callback }, { select, call, put }) {
+ const response = yield call(insertBatchForProUser, payload);
+ yield put({
+ type: 'insertBatchForProUser',
+ payload: response,
+ });
+
+ const params = yield select(state => state.prouser.params);
+ const responsedata = yield call(queryPageForProUser, params);
+ yield put({
+ type: 'queryPageForProUser',
+ payload: responsedata,
+ });
+
+ if (callback) callback(response);
+ },
+ *delete_batch_for_prouser({ payload, callback }, { select, call, put }) {
+ const response = yield call(deleteBatchForProUser, payload);
+ yield put({
+ type: 'deleteBatchForProUser',
+ payload: response,
+ });
+
+ const params = yield select(state => state.prouser.params);
+ const responsedata = yield call(queryPageForProUser, params);
+ yield put({
+ type: 'queryPageForProUser',
+ payload: responsedata,
+ });
+
+ if (callback) callback(response);
+ },
+ *update_batch_for_prouser({ payload, callback }, { select, call, put }) {
+ const response = yield call(updateBatchForProUser, payload);
+ yield put({
+ type: 'updateBatchForProUser',
+ payload: response,
+ });
+
+ const params = yield select(state => state.prouser.params);
+ const responsedata = yield call(queryPageForProUser, params);
+ yield put({
+ type: 'queryPageForProUser',
+ payload: responsedata,
+ });
+
+ if (callback) callback(response);
+ },
+ *resetpwd_for_prouser({ payload, callback }, { select, call, put }) {
+ const response = yield call(resetPwdForProUser, payload);
+ yield put({
+ type: 'resetPwdForProUser',
+ payload: response,
+ });
+
+ const params = yield select(state => state.prouser.params);
+ const responsedata = yield call(queryPageForProUser, params);
+ yield put({
+ type: 'queryPageForProUser',
+ payload: responsedata,
+ });
+
+ if (callback) callback(response);
+ },
+ },
+
+ reducers: {
+ setQueryPageByParams(state, { payload }) {
+ return {
+ ...state,
+ params: {...payload},
+ };
+ },
+ deleteByPrimaryKeyForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ selectByPrimaryKeyForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ insertForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ updateForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ deleteByMapForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ updateByMapForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ getOneForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ getAllForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ queryPageForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ countForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ insertBatchForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ deleteBatchForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ updateBatchForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ resetPwdForProUser(state, action) {
+ return {
+ ...state,
+ data: action.payload,
+ };
+ },
+ },
+};
diff --git a/src/pages/business_basic/module/EvaluationReport.js b/src/pages/business_basic/module/EvaluationReport.js
new file mode 100644
index 0000000..03872f5
--- /dev/null
+++ b/src/pages/business_basic/module/EvaluationReport.js
@@ -0,0 +1,300 @@
+import React, { useState, useEffect } from 'react';
+import { Card, Table, Button, Modal, Form, Input, Select, message, Space, Tag } from 'antd';
+import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined } from '@ant-design/icons';
+import './EvaluationReport.less';
+
+const { Option } = Select;
+
+const EvaluationReport = () => {
+ const [form] = Form.useForm();
+ const [dataSource, setDataSource] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const [modalVisible, setModalVisible] = useState(false);
+ const [editingRecord, setEditingRecord] = useState(null);
+ const [pagination, setPagination] = useState({
+ current: 1,
+ pageSize: 10,
+ total: 0,
+ });
+
+ // 模拟数据
+ const mockData = [
+ {
+ id: 1,
+ reportName: '2024年第一季度安全评估报告',
+ reportType: '季度评估',
+ assessmentPeriod: '2024-01-01 至 2024-03-31',
+ assessor: '张三',
+ status: '已完成',
+ createTime: '2024-04-01 10:00:00',
+ description: '对第一季度安全生产情况进行全面评估',
+ },
+ {
+ id: 2,
+ reportName: '2024年年度安全评估报告',
+ reportType: '年度评估',
+ assessmentPeriod: '2024-01-01 至 2024-12-31',
+ assessor: '李四',
+ status: '进行中',
+ createTime: '2024-01-15 14:30:00',
+ description: '年度安全生产综合评估',
+ },
+ ];
+
+ useEffect(() => {
+ fetchData();
+ }, [pagination.current, pagination.pageSize]);
+
+ const fetchData = async () => {
+ setLoading(true);
+ try {
+ // 模拟API调用
+ setTimeout(() => {
+ setDataSource(mockData);
+ setPagination(prev => ({ ...prev, total: mockData.length }));
+ setLoading(false);
+ }, 500);
+ } catch (error) {
+ message.error('获取数据失败');
+ setLoading(false);
+ }
+ };
+
+ const handleAdd = () => {
+ setEditingRecord(null);
+ form.resetFields();
+ setModalVisible(true);
+ };
+
+ const handleEdit = (record) => {
+ setEditingRecord(record);
+ form.setFieldsValue(record);
+ setModalVisible(true);
+ };
+
+ const handleDelete = (record) => {
+ Modal.confirm({
+ title: '确认删除',
+ content: `确定要删除评估报告"${record.reportName}"吗?`,
+ onOk: () => {
+ setDataSource(dataSource.filter(item => item.id !== record.id));
+ message.success('删除成功');
+ },
+ });
+ };
+
+ const handleView = (record) => {
+ Modal.info({
+ title: '查看评估报告',
+ content: (
+
+
报告名称:{record.reportName}
+
报告类型:{record.reportType}
+
评估周期:{record.assessmentPeriod}
+
评估人:{record.assessor}
+
状态:{record.status}
+
创建时间:{record.createTime}
+
描述:{record.description}
+
+ ),
+ width: 600,
+ });
+ };
+
+ const handleSubmit = async (values) => {
+ try {
+ if (editingRecord) {
+ // 编辑
+ setDataSource(dataSource.map(item =>
+ item.id === editingRecord.id ? { ...item, ...values } : item
+ ));
+ message.success('编辑成功');
+ } else {
+ // 新增
+ const newRecord = {
+ id: Date.now(),
+ ...values,
+ status: '进行中',
+ createTime: new Date().toLocaleString(),
+ };
+ setDataSource([...dataSource, newRecord]);
+ message.success('添加成功');
+ }
+ setModalVisible(false);
+ form.resetFields();
+ } catch (error) {
+ message.error('操作失败');
+ }
+ };
+
+ const columns = [
+ {
+ title: '报告名称',
+ dataIndex: 'reportName',
+ key: 'reportName',
+ width: 200,
+ },
+ {
+ title: '报告类型',
+ dataIndex: 'reportType',
+ key: 'reportType',
+ width: 120,
+ },
+ {
+ title: '评估周期',
+ dataIndex: 'assessmentPeriod',
+ key: 'assessmentPeriod',
+ width: 200,
+ },
+ {
+ title: '评估人',
+ dataIndex: 'assessor',
+ key: 'assessor',
+ width: 100,
+ },
+ {
+ title: '状态',
+ dataIndex: 'status',
+ key: 'status',
+ width: 100,
+ render: (status) => (
+
+ {status}
+
+ ),
+ },
+ {
+ title: '创建时间',
+ dataIndex: 'createTime',
+ key: 'createTime',
+ width: 150,
+ },
+ {
+ title: '操作',
+ key: 'action',
+ width: 200,
+ render: (_, record) => (
+
+ }
+ onClick={() => handleView(record)}
+ >
+ 查看
+
+ }
+ onClick={() => handleEdit(record)}
+ >
+ 编辑
+
+ }
+ onClick={() => handleDelete(record)}
+ >
+ 删除
+
+
+ ),
+ },
+ ];
+
+ return (
+
+
} onClick={handleAdd}>
+ 新增报告
+
+ }
+ >
+
+ `第 ${range[0]}-${range[1]} 条/共 ${total} 条`,
+ onChange: (page, pageSize) => {
+ setPagination(prev => ({
+ ...prev,
+ current: page,
+ pageSize: pageSize || prev.pageSize,
+ }));
+ },
+ }}
+ />
+
+
+ {
+ setModalVisible(false);
+ form.resetFields();
+ }}
+ onOk={() => form.submit()}
+ width={600}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default EvaluationReport;
diff --git a/src/pages/business_basic/module/EvaluationReport.less b/src/pages/business_basic/module/EvaluationReport.less
new file mode 100644
index 0000000..4186bb8
--- /dev/null
+++ b/src/pages/business_basic/module/EvaluationReport.less
@@ -0,0 +1,115 @@
+.evaluation-report {
+ padding: 20px;
+
+ .ant-card {
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ border-radius: 6px;
+
+ .ant-card-head {
+ border-bottom: 1px solid #f0f0f0;
+
+ .ant-card-head-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #262626;
+ }
+ }
+
+ .ant-card-body {
+ padding: 20px;
+ }
+ }
+
+ .ant-table {
+ .ant-table-thead > tr > th {
+ background-color: #fafafa;
+ font-weight: 600;
+ color: #262626;
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-table-tbody > tr > td {
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-table-tbody > tr:hover > td {
+ background-color: #f5f5f5;
+ }
+ }
+
+ .ant-btn {
+ border-radius: 4px;
+
+ &.ant-btn-primary {
+ background-color: #1890ff;
+ border-color: #1890ff;
+
+ &:hover {
+ background-color: #40a9ff;
+ border-color: #40a9ff;
+ }
+ }
+
+ &.ant-btn-link {
+ padding: 4px 8px;
+ height: auto;
+
+ &:hover {
+ background-color: #f5f5f5;
+ }
+ }
+ }
+
+ .ant-tag {
+ border-radius: 4px;
+ font-size: 12px;
+ padding: 2px 8px;
+ }
+
+ .ant-modal {
+ .ant-modal-header {
+ border-bottom: 1px solid #f0f0f0;
+
+ .ant-modal-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #262626;
+ }
+ }
+
+ .ant-modal-body {
+ padding: 24px;
+ }
+
+ .ant-form-item-label > label {
+ font-weight: 500;
+ color: #262626;
+ }
+
+ .ant-input,
+ .ant-select-selector {
+ border-radius: 4px;
+ border: 1px solid #d9d9d9;
+
+ &:hover {
+ border-color: #40a9ff;
+ }
+
+ &:focus,
+ &.ant-select-focused .ant-select-selector {
+ border-color: #40a9ff;
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
+ }
+ }
+ }
+
+ .ant-pagination {
+ margin-top: 16px;
+ text-align: right;
+
+ .ant-pagination-total-text {
+ color: #8c8c8c;
+ margin-right: 16px;
+ }
+ }
+}
diff --git a/src/pages/business_basic/module/OnlineMonitoring.js b/src/pages/business_basic/module/OnlineMonitoring.js
new file mode 100644
index 0000000..adfae54
--- /dev/null
+++ b/src/pages/business_basic/module/OnlineMonitoring.js
@@ -0,0 +1,344 @@
+import React, { useState, useEffect } from 'react';
+import { Card, Table, Button, Modal, Form, Input, Select, message, Space, Tag, Badge } from 'antd';
+import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, PlayCircleOutlined, PauseCircleOutlined } from '@ant-design/icons';
+import './OnlineMonitoring.less';
+
+const { Option } = Select;
+
+const OnlineMonitoring = () => {
+ const [form] = Form.useForm();
+ const [dataSource, setDataSource] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const [modalVisible, setModalVisible] = useState(false);
+ const [editingRecord, setEditingRecord] = useState(null);
+ const [pagination, setPagination] = useState({
+ current: 1,
+ pageSize: 10,
+ total: 0,
+ });
+
+ // 模拟数据
+ const mockData = [
+ {
+ id: 1,
+ deviceName: '温度传感器-001',
+ deviceType: '温度传感器',
+ location: '生产车间A区',
+ status: '在线',
+ lastUpdate: '2024-01-15 14:30:25',
+ value: '25.6°C',
+ threshold: '30°C',
+ description: '监测生产车间温度变化',
+ },
+ {
+ id: 2,
+ deviceName: '压力传感器-002',
+ deviceType: '压力传感器',
+ location: '储罐区B区',
+ status: '离线',
+ lastUpdate: '2024-01-15 12:15:30',
+ value: '--',
+ threshold: '2.5MPa',
+ description: '监测储罐压力状态',
+ },
+ {
+ id: 3,
+ deviceName: '气体检测器-003',
+ deviceType: '气体检测器',
+ location: '危险品仓库',
+ status: '在线',
+ lastUpdate: '2024-01-15 14:32:10',
+ value: '正常',
+ threshold: '50ppm',
+ description: '监测有害气体浓度',
+ },
+ ];
+
+ useEffect(() => {
+ fetchData();
+ }, [pagination.current, pagination.pageSize]);
+
+ const fetchData = async () => {
+ setLoading(true);
+ try {
+ // 模拟API调用
+ setTimeout(() => {
+ setDataSource(mockData);
+ setPagination(prev => ({ ...prev, total: mockData.length }));
+ setLoading(false);
+ }, 500);
+ } catch (error) {
+ message.error('获取数据失败');
+ setLoading(false);
+ }
+ };
+
+ const handleAdd = () => {
+ setEditingRecord(null);
+ form.resetFields();
+ setModalVisible(true);
+ };
+
+ const handleEdit = (record) => {
+ setEditingRecord(record);
+ form.setFieldsValue(record);
+ setModalVisible(true);
+ };
+
+ const handleDelete = (record) => {
+ Modal.confirm({
+ title: '确认删除',
+ content: `确定要删除监控设备"${record.deviceName}"吗?`,
+ onOk: () => {
+ setDataSource(dataSource.filter(item => item.id !== record.id));
+ message.success('删除成功');
+ },
+ });
+ };
+
+ const handleView = (record) => {
+ Modal.info({
+ title: '查看监控设备详情',
+ content: (
+
+
设备名称:{record.deviceName}
+
设备类型:{record.deviceType}
+
安装位置:{record.location}
+
运行状态:
+
+
+
当前数值:{record.value}
+
阈值设置:{record.threshold}
+
最后更新:{record.lastUpdate}
+
设备描述:{record.description}
+
+ ),
+ width: 600,
+ });
+ };
+
+ const handleStartStop = (record) => {
+ const newStatus = record.status === '在线' ? '离线' : '在线';
+ setDataSource(dataSource.map(item =>
+ item.id === record.id ? { ...item, status: newStatus } : item
+ ));
+ message.success(`设备已${newStatus === '在线' ? '启动' : '停止'}`);
+ };
+
+ const handleSubmit = async (values) => {
+ try {
+ if (editingRecord) {
+ // 编辑
+ setDataSource(dataSource.map(item =>
+ item.id === editingRecord.id ? { ...item, ...values } : item
+ ));
+ message.success('编辑成功');
+ } else {
+ // 新增
+ const newRecord = {
+ id: Date.now(),
+ ...values,
+ status: '离线',
+ lastUpdate: new Date().toLocaleString(),
+ value: '--',
+ };
+ setDataSource([...dataSource, newRecord]);
+ message.success('添加成功');
+ }
+ setModalVisible(false);
+ form.resetFields();
+ } catch (error) {
+ message.error('操作失败');
+ }
+ };
+
+ const columns = [
+ {
+ title: '设备名称',
+ dataIndex: 'deviceName',
+ key: 'deviceName',
+ width: 150,
+ },
+ {
+ title: '设备类型',
+ dataIndex: 'deviceType',
+ key: 'deviceType',
+ width: 120,
+ },
+ {
+ title: '安装位置',
+ dataIndex: 'location',
+ key: 'location',
+ width: 150,
+ },
+ {
+ title: '运行状态',
+ dataIndex: 'status',
+ key: 'status',
+ width: 100,
+ render: (status) => (
+
+ ),
+ },
+ {
+ title: '当前数值',
+ dataIndex: 'value',
+ key: 'value',
+ width: 100,
+ },
+ {
+ title: '阈值设置',
+ dataIndex: 'threshold',
+ key: 'threshold',
+ width: 100,
+ },
+ {
+ title: '最后更新',
+ dataIndex: 'lastUpdate',
+ key: 'lastUpdate',
+ width: 150,
+ },
+ {
+ title: '操作',
+ key: 'action',
+ width: 250,
+ render: (_, record) => (
+
+ }
+ onClick={() => handleView(record)}
+ >
+ 查看
+
+ }
+ onClick={() => handleEdit(record)}
+ >
+ 编辑
+
+ : }
+ onClick={() => handleStartStop(record)}
+ >
+ {record.status === '在线' ? '停止' : '启动'}
+
+ }
+ onClick={() => handleDelete(record)}
+ >
+ 删除
+
+
+ ),
+ },
+ ];
+
+ return (
+
+
} onClick={handleAdd}>
+ 新增设备
+
+ }
+ >
+
+ `第 ${range[0]}-${range[1]} 条/共 ${total} 条`,
+ onChange: (page, pageSize) => {
+ setPagination(prev => ({
+ ...prev,
+ current: page,
+ pageSize: pageSize || prev.pageSize,
+ }));
+ },
+ }}
+ />
+
+
+ {
+ setModalVisible(false);
+ form.resetFields();
+ }}
+ onOk={() => form.submit()}
+ width={600}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default OnlineMonitoring;
diff --git a/src/pages/business_basic/module/OnlineMonitoring.less b/src/pages/business_basic/module/OnlineMonitoring.less
new file mode 100644
index 0000000..680ed76
--- /dev/null
+++ b/src/pages/business_basic/module/OnlineMonitoring.less
@@ -0,0 +1,157 @@
+.online-monitoring {
+ padding: 20px;
+
+ .ant-card {
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ border-radius: 6px;
+
+ .ant-card-head {
+ border-bottom: 1px solid #f0f0f0;
+
+ .ant-card-head-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #262626;
+ }
+ }
+
+ .ant-card-body {
+ padding: 20px;
+ }
+ }
+
+ .ant-table {
+ .ant-table-thead > tr > th {
+ background-color: #fafafa;
+ font-weight: 600;
+ color: #262626;
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-table-tbody > tr > td {
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-table-tbody > tr:hover > td {
+ background-color: #f5f5f5;
+ }
+ }
+
+ .ant-btn {
+ border-radius: 4px;
+
+ &.ant-btn-primary {
+ background-color: #1890ff;
+ border-color: #1890ff;
+
+ &:hover {
+ background-color: #40a9ff;
+ border-color: #40a9ff;
+ }
+ }
+
+ &.ant-btn-link {
+ padding: 4px 8px;
+ height: auto;
+
+ &:hover {
+ background-color: #f5f5f5;
+ }
+ }
+ }
+
+ .ant-badge {
+ .ant-badge-status-dot {
+ width: 8px;
+ height: 8px;
+ }
+
+ .ant-badge-status-text {
+ margin-left: 8px;
+ font-size: 12px;
+ }
+ }
+
+ .ant-modal {
+ .ant-modal-header {
+ border-bottom: 1px solid #f0f0f0;
+
+ .ant-modal-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #262626;
+ }
+ }
+
+ .ant-modal-body {
+ padding: 24px;
+ }
+
+ .ant-form-item-label > label {
+ font-weight: 500;
+ color: #262626;
+ }
+
+ .ant-input,
+ .ant-select-selector {
+ border-radius: 4px;
+ border: 1px solid #d9d9d9;
+
+ &:hover {
+ border-color: #40a9ff;
+ }
+
+ &:focus,
+ &.ant-select-focused .ant-select-selector {
+ border-color: #40a9ff;
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
+ }
+ }
+ }
+
+ .ant-pagination {
+ margin-top: 16px;
+ text-align: right;
+
+ .ant-pagination-total-text {
+ color: #8c8c8c;
+ margin-right: 16px;
+ }
+ }
+
+ // 状态指示器样式
+ .status-indicator {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+
+ &.online {
+ color: #52c41a;
+ }
+
+ &.offline {
+ color: #ff4d4f;
+ }
+ }
+
+ // 数值显示样式
+ .value-display {
+ font-weight: 500;
+
+ &.normal {
+ color: #52c41a;
+ }
+
+ &.warning {
+ color: #faad14;
+ }
+
+ &.danger {
+ color: #ff4d4f;
+ }
+
+ &.unknown {
+ color: #8c8c8c;
+ }
+ }
+}
diff --git a/src/pages/business_basic/module/ResponsibilityImplementation.js b/src/pages/business_basic/module/ResponsibilityImplementation.js
new file mode 100644
index 0000000..e8daf90
--- /dev/null
+++ b/src/pages/business_basic/module/ResponsibilityImplementation.js
@@ -0,0 +1,233 @@
+
+import React from 'react';
+import { Card, Result, Timeline,Statistic, Table,Row, Input,Button,Col, Select} from 'antd';
+import StandardTable from '@/components/StandardTable';
+import styles from './ResponsibilityImplementation.less';
+
+
+
+const ResponsibilityImplementation = () => {
+
+ const columns = [
+ {
+ title:"编号",
+ dataIndex:"id",
+ key:"id",
+ width:60,
+ },
+ {
+ title:"责任区域",
+ dataIndex:"zrqy",
+ key:"zrqy",
+ width:120,
+ },
+ {
+ title:"设备型号",
+ dataIndex:"sbxh",
+ key:"sbxh",
+ width:120,
+ },
+ {
+ title:"危险源类型",
+ dataIndex:"wxlylx",
+ key:"wxlylx",
+ width:120,
+ },
+ {
+ title:"责任人",
+ dataIndex:"zrr",
+ key:"zrr",
+ width:120,
+ },
+ {
+ title:"联系方式",
+ dataIndex:"lxfs",
+ key:"lxfs",
+ width:120,
+ },
+ {
+ title:"巡检频率",
+ dataIndex:"xjpl",
+ key:"xjpl",
+ width:120,
+ },
+ {
+ title:"最近巡检",
+ dataIndex:"zjxj",
+ key:"zjxj",
+ width:120,
+ },
+ {
+ title:"状态",
+ dataIndex:"zt",
+ key:"zt",
+ width:120,
+ },
+ {
+ title:"操作",
+ dataIndex:"cz",
+ key:"cz",
+ width:120,
+ render: (text, record) => { // ======== 渲染操作列 ========
+ const handleView = (record) => { // ======== 定义查看函数 ========
+ console.log('查看记录:', record); // ======== 打印记录信息到控制台 ========
+ // 这里可以添加查看详情的逻辑 // ======== 注释:可以添加查看详情的逻辑 ========
+ }; // ======== 函数结束 ========
+
+ return ( // ======== 返回按钮组件 ========
+ // ======== 查看按钮,点击时调用handleView函数 ========
+ ); // ======== return语句结束 ========
+ } // ======== render函数结束 ========
+ }
+ ];
+
+ // 生成20条假数据
+ const generateMockData = () => { // ======== 定义生成假数据的函数 ========
+ const data = []; // ======== 创建空数组存储数据 ========
+ const areas = ['生产车间A区', '生产车间B区', '储罐区', '配电室', '锅炉房', '化学品仓库', '实验室', '办公区']; // ======== 责任区域选项 ========
+ const devices = ['压力容器', '储罐', '反应釜', '压缩机', '泵类设备', '电气设备', '管道系统', '安全阀']; // ======== 设备型号选项 ========
+ const statuses = ['正常', '维护中', '故障', '停用', '检修']; // ======== 状态选项 ========
+ const names = ['张三', '李四', '王五', '赵六', '孙七', '周八', '吴九', '郑十', '钱十一', '陈十二']; // ======== 责任人姓名选项 ========
+
+ for (let i = 1; i <= 20; i++) { // ======== 循环生成20条数据 ========
+ data.push({ // ======== 添加一条数据到数组 ========
+ key: i.toString(), // ======== 唯一标识 ========
+ id: `WX${String(i).padStart(3, '0')}`, // ======== 编号:WX001, WX002... ========
+ zrqy: areas[Math.floor(Math.random() * areas.length)], // ======== 随机选择责任区域 ========
+ sbxh: devices[Math.floor(Math.random() * devices.length)], // ======== 随机选择设备型号 ========
+ zrr: names[Math.floor(Math.random() * names.length)], // ======== 随机选择责任人 ========
+ zt: statuses[Math.floor(Math.random() * statuses.length)], // ======== 随机选择状态 ========
+ }); // ======== 数据对象结束 ========
+ } // ======== 循环结束 ========
+ return data; // ======== 返回生成的数据数组 ========
+ }; // ======== 函数结束 ========
+
+ const tableData = generateMockData(); // ======== 调用函数生成假数据 ========
+
+ return (
+
+ {/* 警告提示框 */}
+
+
})
+
+ 有5个消防设备需要维护,3个资质证书即将到期,请及时处理。
+
+
+
+
+
+
+ {/* 第一行:标题和按钮 */}
+
+
+
+
+
+
+
+
+ {/* 第二行:图片占位 */}
+
+
+
+
+ {/* 第一块:标题 + 下拉选择框 + 导出按钮 */}
+
+
+
+
+
+
+
+
+
+ {/* 第二块:图片内容 */}
+
+
+
+
+
+ {/* 第一个大块:标题 */}
+
+
+ {/* 第二个大块:搜索和按钮 */}
+
+
+
+
+
+
+
+
+
+
+ {/* 第三个大块:表格 */}
+
+ {}} // ======== 行选择事件处理函数 ========
+ onChange={() => {}} // ======== 表格变化事件处理函数 ========
+ />
+
+
+
+ );
+};
+export default ResponsibilityImplementation;
diff --git a/src/pages/business_basic/module/ResponsibilityImplementation.less b/src/pages/business_basic/module/ResponsibilityImplementation.less
new file mode 100644
index 0000000..91ffca9
--- /dev/null
+++ b/src/pages/business_basic/module/ResponsibilityImplementation.less
@@ -0,0 +1,413 @@
+.containerR {
+ padding: 8px 6px;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+
+ .warningBox {
+ width: 100%;
+ background-color: #FFF3CD;
+ border: 1px solid #F4E3AE;
+ border-radius: 4px;
+ padding: 8px 20px;
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 10px;
+
+ .warningIcon {
+ width: 18px;
+ height: 18px;
+ }
+
+ .warningText {
+ color: #8C6C0B;
+ font-size: 12px;
+ line-height: 1.4;
+ }
+ }
+
+ .containerOne {
+ height: 40%;
+ flex-shrink: 0;
+ display: flex;
+ margin-bottom: 10px;
+ gap: 10px;
+
+ .containerOneLeft{
+ background-color: white;
+ width: calc(50% - 5px);
+ display: flex;
+ flex-direction: column;
+ padding: 15px;
+ border: 1px solid #f0f0f0;
+ border-radius: 4px;
+
+ .leftTopSection {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+
+ .titleLeft {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-family: PingFang SC;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+
+ .titleIcon {
+ width: 3px;
+ height: 16px;
+ background-color: #2E4CD4;
+ }
+ }
+
+ .buttonGroup {
+ display: flex;
+ gap: 8px;
+
+ .actionBtn {
+ display: flex;
+ align-items: center;
+ gap: 4px;
+ border: 1px solid #DFE4F6;
+ border-radius: 4px;
+ color: #2E4CD4;
+ font-weight: 500;
+ font-size: 12px;
+ padding: 4px 8px;
+ background: transparent;
+ cursor: pointer;
+ transition: all 0.2s;
+
+ &:hover {
+ background-color: #F0F2FF;
+ border-color: #2E4CD4;
+ }
+
+ .btnIcon {
+ font-size: 12px;
+ }
+ }
+ }
+ }
+
+ .leftBottomSection {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background-color: #fafafa;
+ border: 1px dashed #d9d9d9;
+ border-radius: 4px;
+
+ .imagePlaceholder {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+ color: #999999;
+
+ .imageIcon {
+ font-size: 32px;
+ opacity: 0.6;
+ }
+
+ .imageText {
+ font-size: 14px;
+ font-weight: 400;
+ }
+ }
+ }
+ }
+
+ .containerOneRight{
+ background-color: white;
+ width: calc(50% - 5px);
+ display: flex;
+ flex-direction: column;
+ padding: 15px;
+ border: 1px solid #f0f0f0;
+ border-radius: 4px;
+
+ .rightTopSection {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+
+ .rightTopLeft {
+ display: flex;
+ align-items: center;
+
+ .titleLeft {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-family: PingFang SC;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+
+ .titleIcon {
+ width: 3px;
+ height: 16px;
+ background-color: #2E4CD4;
+ }
+ }
+ }
+
+ .rightTopRight {
+ .exportBtn {
+ background-color: #2E4CD4 !important;
+ border-color: #2E4CD4 !important;
+ color: #fff !important;
+ font-size: 14px !important;
+ font-weight: 500 !important;
+ height: 32px;
+ padding: 0 16px;
+
+ &:hover {
+ background-color: #1e3bb8 !important;
+ border-color: #1e3bb8 !important;
+ }
+ }
+ }
+ }
+
+ .rightBottomSection {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ .imagePlaceholder {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ height: 100%;
+ background-color: #f5f5f5;
+ border: 2px dashed #d9d9d9;
+ border-radius: 4px;
+
+ .imageIcon {
+ font-size: 48px;
+ margin-bottom: 10px;
+ }
+
+ .imageText {
+ font-size: 14px;
+ color: #999999;
+ }
+ }
+ }
+ }
+ }
+
+
+ .containerTwo{
+ flex: 1;
+ background-color: white;
+ display: flex;
+ flex-direction: column;
+ padding: 15px;
+ border: 1px solid #f0f0f0;
+ border-radius: 4px;
+
+ .containerTwoTitle {
+ margin-bottom: 15px;
+
+ .titleLeft {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ font-family: PingFang SC;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+
+ .titleIcon {
+ width: 3px;
+ height: 16px;
+ background-color: #2E4CD4;
+ }
+ }
+ }
+
+ .containerTwoActions {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+
+ .searchSection {
+ flex: 1;
+ max-width: 300px;
+
+ :global(.ant-input) {
+ height: 32px;
+ border-radius: 4px;
+ border: 1px solid #d9d9d9;
+
+ &:focus {
+ border-color: #2E4CD4;
+ box-shadow: 0 0 0 2px rgba(46, 76, 212, 0.2);
+ }
+ }
+ }
+
+ .buttonSection {
+ display: flex;
+ gap: 8px;
+
+ :global(.ant-btn) {
+ height: 32px;
+ padding: 0 16px;
+ border-radius: 4px;
+ font-size: 14px;
+ border: 1px solid #d9d9d9;
+ background-color: #fff;
+ color: #333;
+
+ &:hover {
+ border-color: #2E4CD4;
+ color: #2E4CD4;
+ }
+
+ &:focus {
+ border-color: #2E4CD4;
+ color: #2E4CD4;
+ }
+ }
+ }
+ }
+
+ .containerTwoTable {
+ flex: 1;
+ overflow: hidden;
+
+ :global(.ant-table) {
+ font-size: 12px;
+ }
+
+ :global(.ant-table-thead > tr > th) {
+ background-color: #f5f5fa;
+ font-weight: 500;
+ font-size: 14px;
+ color: #333333;
+ border-bottom: 1px solid #f0f0f0;
+ padding: 8px 12px;
+ text-align: center;
+ }
+
+ :global(.ant-table-tbody > tr > td) {
+ padding: 8px 12px;
+ border-bottom: 1px solid #f0f0f0;
+ text-align: center;
+ }
+
+ :global(.ant-table-tbody > tr:hover > td) {
+ background-color: #f5f5f5;
+ }
+
+ :global(.ant-pagination) {
+ margin-top: 16px;
+ text-align: right;
+ }
+ }
+ }
+}
+
+
+.rightTopSelect{
+ // 下拉框本身的样式
+ :global(.ant-select-selector) {
+ background-color: #f8f9fa !important;
+ border: 1px solid #d9d9d9 !important;
+ border-radius: 6px !important;
+ height: 32px !important;
+ min-height: 32px !important;
+
+ &:hover {
+ border-color: #2E4CD4 !important;
+ }
+
+ &:focus {
+ border-color: #2E4CD4 !important;
+ box-shadow: 0 0 0 2px rgba(46, 76, 212, 0.2) !important;
+ }
+ }
+
+ // 下拉框内的文字样式
+ :global(.ant-select-selection-item) {
+ color: #333333 !important;
+ font-size: 14px !important;
+ font-weight: 500 !important;
+ line-height: 30px !important;
+ }
+
+ // 下拉箭头样式
+ :global(.ant-select-arrow) {
+ color: #666666 !important;
+ font-size: 12px !important;
+ }
+
+ // 下拉菜单容器样式
+ :global(.ant-select-dropdown) {
+ background-color: #ffffff !important;
+ border: 1px solid #e8e8e8 !important;
+ border-radius: 8px !important;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15) !important;
+ padding: 4px 0 !important;
+ }
+
+ // 下拉选项样式
+ :global(.ant-select-item) {
+ color: #333333 !important;
+ font-size: 14px !important;
+ padding: 8px 12px !important;
+ border-radius: 4px !important;
+ margin: 2px 8px !important;
+
+ &:hover {
+ background-color: #f0f2ff !important;
+ color: #2E4CD4 !important;
+ }
+
+ &.ant-select-item-option-selected {
+ background-color: #e6f7ff !important;
+ color: #2E4CD4 !important;
+ font-weight: 600 !important;
+ }
+ }
+
+ // 选中状态的样式
+ :global(.ant-select-focused .ant-select-selector) {
+ border-color: #2E4CD4 !important;
+ box-shadow: 0 0 0 2px rgba(46, 76, 212, 0.2) !important;
+ }
+}
+
+// 自定义选项样式
+.customOption {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ padding: 4px 0;
+
+ .optionIcon {
+ font-size: 16px;
+ color: #2E4CD4;
+ }
+
+ .optionText {
+ font-size: 14px;
+ color: #333333;
+ font-weight: 500;
+ }
+}
\ No newline at end of file
diff --git a/src/pages/business_basic/module/RiskAssessment.js b/src/pages/business_basic/module/RiskAssessment.js
new file mode 100644
index 0000000..1895bfa
--- /dev/null
+++ b/src/pages/business_basic/module/RiskAssessment.js
@@ -0,0 +1,425 @@
+import React, { useState, useEffect } from 'react';
+import { Card, Table, Button, Modal, Form, Input, Select, message, Space, Tag, Rate, Progress } from 'antd';
+import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
+import './RiskAssessment.less';
+
+const { Option } = Select;
+
+const RiskAssessment = () => {
+ const [form] = Form.useForm();
+ const [dataSource, setDataSource] = useState([]);
+ const [loading, setLoading] = useState(false);
+ const [modalVisible, setModalVisible] = useState(false);
+ const [editingRecord, setEditingRecord] = useState(null);
+ const [pagination, setPagination] = useState({
+ current: 1,
+ pageSize: 10,
+ total: 0,
+ });
+
+ // 模拟数据
+ const mockData = [
+ {
+ id: 1,
+ riskName: '化学品泄漏风险',
+ riskType: '环境风险',
+ riskLevel: '高',
+ probability: 4,
+ impact: 5,
+ riskScore: 20,
+ assessor: '张三',
+ assessDate: '2024-01-15',
+ status: '待处理',
+ description: '生产过程中化学品可能发生泄漏,造成环境污染',
+ controlMeasures: '加强设备维护,安装泄漏检测装置',
+ },
+ {
+ id: 2,
+ riskName: '设备故障风险',
+ riskType: '设备风险',
+ riskLevel: '中',
+ probability: 3,
+ impact: 3,
+ riskScore: 9,
+ assessor: '李四',
+ assessDate: '2024-01-10',
+ status: '已处理',
+ description: '关键设备可能发生故障,影响生产安全',
+ controlMeasures: '定期维护保养,建立备件库存',
+ },
+ {
+ id: 3,
+ riskName: '人员操作风险',
+ riskType: '人员风险',
+ riskLevel: '低',
+ probability: 2,
+ impact: 2,
+ riskScore: 4,
+ assessor: '王五',
+ assessDate: '2024-01-08',
+ status: '监控中',
+ description: '操作人员误操作可能导致安全事故',
+ controlMeasures: '加强培训,完善操作规程',
+ },
+ ];
+
+ useEffect(() => {
+ fetchData();
+ }, [pagination.current, pagination.pageSize]);
+
+ const fetchData = async () => {
+ setLoading(true);
+ try {
+ // 模拟API调用
+ setTimeout(() => {
+ setDataSource(mockData);
+ setPagination(prev => ({ ...prev, total: mockData.length }));
+ setLoading(false);
+ }, 500);
+ } catch (error) {
+ message.error('获取数据失败');
+ setLoading(false);
+ }
+ };
+
+ const handleAdd = () => {
+ setEditingRecord(null);
+ form.resetFields();
+ setModalVisible(true);
+ };
+
+ const handleEdit = (record) => {
+ setEditingRecord(record);
+ form.setFieldsValue(record);
+ setModalVisible(true);
+ };
+
+ const handleDelete = (record) => {
+ Modal.confirm({
+ title: '确认删除',
+ content: `确定要删除风险评估"${record.riskName}"吗?`,
+ onOk: () => {
+ setDataSource(dataSource.filter(item => item.id !== record.id));
+ message.success('删除成功');
+ },
+ });
+ };
+
+ const handleView = (record) => {
+ Modal.info({
+ title: '查看风险评估详情',
+ content: (
+
+
风险名称:{record.riskName}
+
风险类型:{record.riskType}
+
风险等级:
+
+ {record.riskLevel}
+
+
+
发生概率:
+
+ ({record.probability}/5)
+
+
影响程度:
+
+ ({record.impact}/5)
+
+
风险评分:{record.riskScore}
+
评估人:{record.assessor}
+
评估日期:{record.assessDate}
+
处理状态:
+
+ {record.status}
+
+
+
风险描述:{record.description}
+
控制措施:{record.controlMeasures}
+
+ ),
+ width: 700,
+ });
+ };
+
+ const handleSubmit = async (values) => {
+ try {
+ const riskScore = values.probability * values.impact;
+ const riskLevel = riskScore >= 16 ? '高' : riskScore >= 9 ? '中' : '低';
+
+ const formData = {
+ ...values,
+ riskScore,
+ riskLevel,
+ };
+
+ if (editingRecord) {
+ // 编辑
+ setDataSource(dataSource.map(item =>
+ item.id === editingRecord.id ? { ...item, ...formData } : item
+ ));
+ message.success('编辑成功');
+ } else {
+ // 新增
+ const newRecord = {
+ id: Date.now(),
+ ...formData,
+ assessor: '当前用户',
+ assessDate: new Date().toISOString().split('T')[0],
+ status: '待处理',
+ };
+ setDataSource([...dataSource, newRecord]);
+ message.success('添加成功');
+ }
+ setModalVisible(false);
+ form.resetFields();
+ } catch (error) {
+ message.error('操作失败');
+ }
+ };
+
+ const getRiskLevelColor = (level) => {
+ switch (level) {
+ case '高': return 'red';
+ case '中': return 'orange';
+ case '低': return 'green';
+ default: return 'default';
+ }
+ };
+
+ const getStatusColor = (status) => {
+ switch (status) {
+ case '已处理': return 'green';
+ case '待处理': return 'red';
+ case '监控中': return 'blue';
+ default: return 'default';
+ }
+ };
+
+ const columns = [
+ {
+ title: '风险名称',
+ dataIndex: 'riskName',
+ key: 'riskName',
+ width: 150,
+ },
+ {
+ title: '风险类型',
+ dataIndex: 'riskType',
+ key: 'riskType',
+ width: 120,
+ },
+ {
+ title: '风险等级',
+ dataIndex: 'riskLevel',
+ key: 'riskLevel',
+ width: 100,
+ render: (level) => (
+
+ {level}
+
+ ),
+ },
+ {
+ title: '风险评分',
+ dataIndex: 'riskScore',
+ key: 'riskScore',
+ width: 100,
+ render: (score) => (
+
+
+ ),
+ },
+ {
+ title: '发生概率',
+ dataIndex: 'probability',
+ key: 'probability',
+ width: 120,
+ render: (probability) => (
+
+
+ ({probability}/5)
+
+ ),
+ },
+ {
+ title: '影响程度',
+ dataIndex: 'impact',
+ key: 'impact',
+ width: 120,
+ render: (impact) => (
+
+
+ ({impact}/5)
+
+ ),
+ },
+ {
+ title: '处理状态',
+ dataIndex: 'status',
+ key: 'status',
+ width: 100,
+ render: (status) => (
+
+ {status}
+
+ ),
+ },
+ {
+ title: '评估人',
+ dataIndex: 'assessor',
+ key: 'assessor',
+ width: 100,
+ },
+ {
+ title: '评估日期',
+ dataIndex: 'assessDate',
+ key: 'assessDate',
+ width: 120,
+ },
+ {
+ title: '操作',
+ key: 'action',
+ width: 200,
+ render: (_, record) => (
+
+ }
+ onClick={() => handleView(record)}
+ >
+ 查看
+
+ }
+ onClick={() => handleEdit(record)}
+ >
+ 编辑
+
+ }
+ onClick={() => handleDelete(record)}
+ >
+ 删除
+
+
+ ),
+ },
+ ];
+
+ return (
+
+
} onClick={handleAdd}>
+ 新增评估
+
+ }
+ >
+
+ `第 ${range[0]}-${range[1]} 条/共 ${total} 条`,
+ onChange: (page, pageSize) => {
+ setPagination(prev => ({
+ ...prev,
+ current: page,
+ pageSize: pageSize || prev.pageSize,
+ }));
+ },
+ }}
+ />
+
+
+ {
+ setModalVisible(false);
+ form.resetFields();
+ }}
+ onOk={() => form.submit()}
+ width={700}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default RiskAssessment;
diff --git a/src/pages/business_basic/module/RiskAssessment.less b/src/pages/business_basic/module/RiskAssessment.less
new file mode 100644
index 0000000..ea268cc
--- /dev/null
+++ b/src/pages/business_basic/module/RiskAssessment.less
@@ -0,0 +1,241 @@
+.risk-assessment {
+ padding: 20px;
+
+ .ant-card {
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ border-radius: 6px;
+
+ .ant-card-head {
+ border-bottom: 1px solid #f0f0f0;
+
+ .ant-card-head-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #262626;
+ }
+ }
+
+ .ant-card-body {
+ padding: 20px;
+ }
+ }
+
+ .ant-table {
+ .ant-table-thead > tr > th {
+ background-color: #fafafa;
+ font-weight: 600;
+ color: #262626;
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-table-tbody > tr > td {
+ border-bottom: 1px solid #f0f0f0;
+ }
+
+ .ant-table-tbody > tr:hover > td {
+ background-color: #f5f5f5;
+ }
+ }
+
+ .ant-btn {
+ border-radius: 4px;
+
+ &.ant-btn-primary {
+ background-color: #1890ff;
+ border-color: #1890ff;
+
+ &:hover {
+ background-color: #40a9ff;
+ border-color: #40a9ff;
+ }
+ }
+
+ &.ant-btn-link {
+ padding: 4px 8px;
+ height: auto;
+
+ &:hover {
+ background-color: #f5f5f5;
+ }
+ }
+ }
+
+ .ant-tag {
+ border-radius: 4px;
+ font-size: 12px;
+ padding: 2px 8px;
+ }
+
+ .ant-rate {
+ font-size: 14px;
+
+ .ant-rate-star {
+ margin-right: 2px;
+ }
+ }
+
+ .ant-progress {
+ .ant-progress-bg {
+ border-radius: 2px;
+ }
+
+ &.ant-progress-small {
+ .ant-progress-text {
+ font-size: 10px;
+ }
+ }
+ }
+
+ .ant-modal {
+ .ant-modal-header {
+ border-bottom: 1px solid #f0f0f0;
+
+ .ant-modal-title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #262626;
+ }
+ }
+
+ .ant-modal-body {
+ padding: 24px;
+ }
+
+ .ant-form-item-label > label {
+ font-weight: 500;
+ color: #262626;
+ }
+
+ .ant-input,
+ .ant-select-selector {
+ border-radius: 4px;
+ border: 1px solid #d9d9d9;
+
+ &:hover {
+ border-color: #40a9ff;
+ }
+
+ &:focus,
+ &.ant-select-focused .ant-select-selector {
+ border-color: #40a9ff;
+ box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
+ }
+ }
+ }
+
+ .ant-pagination {
+ margin-top: 16px;
+ text-align: right;
+
+ .ant-pagination-total-text {
+ color: #8c8c8c;
+ margin-right: 16px;
+ }
+ }
+
+ // 风险等级颜色
+ .risk-level-high {
+ color: #ff4d4f;
+ font-weight: 600;
+ }
+
+ .risk-level-medium {
+ color: #faad14;
+ font-weight: 600;
+ }
+
+ .risk-level-low {
+ color: #52c41a;
+ font-weight: 600;
+ }
+
+ // 状态指示器
+ .status-indicator {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+
+ &.processed {
+ color: #52c41a;
+ }
+
+ &.pending {
+ color: #ff4d4f;
+ }
+
+ &.monitoring {
+ color: #1890ff;
+ }
+ }
+
+ // 评分显示
+ .score-display {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+
+ .score-value {
+ font-weight: 600;
+ font-size: 14px;
+ }
+
+ .score-label {
+ font-size: 12px;
+ color: #8c8c8c;
+ }
+ }
+
+ // 概率和影响程度显示
+ .rate-display {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 4px;
+
+ .rate-stars {
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ }
+
+ .rate-text {
+ font-size: 12px;
+ color: #8c8c8c;
+ }
+ }
+
+ // 风险矩阵样式
+ .risk-matrix {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ gap: 8px;
+ margin: 16px 0;
+
+ .matrix-cell {
+ padding: 8px;
+ text-align: center;
+ border: 1px solid #d9d9d9;
+ border-radius: 4px;
+ font-size: 12px;
+
+ &.high-risk {
+ background-color: #fff2f0;
+ border-color: #ff4d4f;
+ color: #ff4d4f;
+ }
+
+ &.medium-risk {
+ background-color: #fffbe6;
+ border-color: #faad14;
+ color: #faad14;
+ }
+
+ &.low-risk {
+ background-color: #f6ffed;
+ border-color: #52c41a;
+ color: #52c41a;
+ }
+ }
+ }
+}
diff --git a/src/pages/nav_system_content/SystemContentList.js b/src/pages/nav_system_content/SystemContentList.js
index b637579..2de05d6 100644
--- a/src/pages/nav_system_content/SystemContentList.js
+++ b/src/pages/nav_system_content/SystemContentList.js
@@ -87,6 +87,12 @@ const SystemContentList = (props) => {
setMenuItems(newList)
const fixedMenuItems = [
+ {
+ path: '/topnavbar00/business/basic',
+ icon:
,
+ key: "/topnavbar00/business/basic",
+ "label": "基础信息管理"
+ },
{
"path": "/topnavbar00/business/basicinformation",
icon:
,
diff --git a/src/pages/topnavbar/TopNavBar.js b/src/pages/topnavbar/TopNavBar.js
index 48f9c89..0579cf3 100644
--- a/src/pages/topnavbar/TopNavBar.js
+++ b/src/pages/topnavbar/TopNavBar.js
@@ -8,6 +8,10 @@ import Logo from '@/assets/logo.png'
import { userInfo } from '@/utils/globalCommon'
const menuItem = [
+ {
+ label: '基础信息管理',
+ key: '/topnavbar00/business/basic',
+ },
{
label: '安全管理基础信息',
key: '/topnavbar00/business/basicinformation',