Merge remote-tracking branch 'origin/main' into main

main
jiangxucong 1 month ago
commit 5a06e35d94

@ -35,7 +35,7 @@ export default [
path: '/topnavbar00/hrefficiency/staffsheet',
// icon: 'bank',
name: 'staffsheet',
component: './hrefficiency_staffsheet/StaffSheetList',
component: './safe_majorHazard/SafeMajorHazardList',
},
{
path: '/topnavbar00/hrefficiency/staffuph',

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.95512 11.5156L13.7801 5.58875C13.9159 5.42196 13.9992 5.2229 14.0206 5.01406C14.0421 4.80522 14.0008 4.59491 13.9015 4.4069C13.8021 4.21889 13.6487 4.06067 13.4585 3.95012C13.2683 3.83956 13.0489 3.78107 12.8251 3.78125H3.17662C2.9529 3.78124 2.73364 3.83986 2.54359 3.95049C2.35353 4.06111 2.20024 4.21935 2.10103 4.40732C2.00181 4.5953 1.96063 4.80553 1.98211 5.01429C2.00359 5.22305 2.0869 5.42202 2.22262 5.58875L7.04762 11.5156C7.15961 11.6531 7.30393 11.7646 7.46935 11.8413C7.63476 11.918 7.81682 11.9579 8.00137 11.9579C8.18591 11.9579 8.36797 11.918 8.53338 11.8413C8.6988 11.7646 8.84312 11.6531 8.95512 11.5156Z" fill="white" fill-opacity="0.66"/>
</svg>

After

Width:  |  Height:  |  Size: 774 B

@ -115,6 +115,7 @@
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
gap: 20px;
}
// 面包屑项文本样式
@ -135,7 +136,7 @@
.breadcrumb-close-icon {
font-size: 14px;
// color: #7D9CD8;
margin-left: 8px;
// margin-left: 8px;
display: flex;
align-items: center;
justify-content: center;

@ -6,7 +6,7 @@ import { formatRoute, getDefaultRoute } from '@/utils/routeUtils'
import styles from './TopNavBar.less'
import { Row, Col, Avatar, Dropdown, Button } from 'antd'
import { userInfo } from '@/utils/globalCommon'
import { HomeOutlined, LogoutOutlined, AppstoreOutlined, UserOutlined, SettingOutlined, DatabaseOutlined, FileTextOutlined, LockOutlined, AreaChartOutlined } from '@ant-design/icons'
import { HomeOutlined, LogoutOutlined, AppstoreOutlined, UserOutlined, SettingOutlined, DatabaseOutlined, FileTextOutlined, LockOutlined, AreaChartOutlined, CaretDownOutlined, BellOutlined, SearchOutlined, QuestionCircleOutlined } from '@ant-design/icons'
import { getPageQuery } from '@/utils/utils'
import menuTitle from '@/assets/img/智能管控平台.svg'
import menuTitle1 from '@/assets/img/智能管控平台-1.svg'
@ -21,6 +21,7 @@ import people from '@/assets/img/people.svg'
import risk from '@/assets/img/risk.svg'
import { CustomBreadcrumb } from '@/components/GlobalComponent'
// 自定义菜单项渲染组件,支持根据激活状态显示不同图片
const CustomMenuItem = ({ item, selectedKeys }) => {
const isActive = selectedKeys.includes(item.key);
@ -63,6 +64,7 @@ const SystemContentList = (props) => {
const [selectedKey, setSelectedKey] = useState([])
const [menuItems, setMenuItems] = useState([])
const [systemType, setSystemType] = useState('安全管理系统')
const [isMenuCollapsed, setIsMenuCollapsed] = useState(false); // 添加菜单收缩状态
let defaultKey = ''
useEffect(() => {
@ -95,7 +97,7 @@ const SystemContentList = (props) => {
"path": "/topnavbar00/hrefficiency/staffsheet",
icon: <img src={danger} alt="工时仪表盘" style={{ width: '16px', height: '16px' }} />,
"key": "/topnavbar00/hrefficiency/staffsheet",
"label": "员工仪表盘"
"label": "重大危险源管理"
},
{
"path": "/topnavbar00/hrefficiency/staffuph",
@ -169,6 +171,11 @@ const SystemContentList = (props) => {
history.replace(curKey)
}
// 切换菜单收缩状态
const toggleMenu = () => {
setIsMenuCollapsed(!isMenuCollapsed);
};
const { initialState: { menu }, setInitialState } = useModel('@@initialState')
const loginOut = async () => {
@ -212,12 +219,27 @@ const SystemContentList = (props) => {
return (
<div className='pageContainer systemContent'>
<div className='leftMenu'>
<div className='menuTitle' style={{ marginBottom: '10px' }}>
<div
className='leftMenu'
style={{
width: isMenuCollapsed ? '80px' : '230px',
transition: 'width 0.3s ease',
position: 'relative', // 添加相对定位,使按钮可以相对于菜单定位
overflow: 'unset'
}}
>
<div className='menuTitle' style={{
marginBottom: '10px',
display: isMenuCollapsed ? 'none' : 'flex'
}}>
<img src={menuTitle} alt='menuTitle' style={{ marginTop: '20px', marginBottom: '2px', width: '172.44px', height: '51.28px' }} />
<img src={menuTitle1} alt='menuTitle1' style={{ width: '172.44px', height: '51.28px' }} />
</div>
<div style={{ textAlign: 'center', marginBottom: 16 }}>
<div style={{
textAlign: 'center',
marginBottom: 16,
display: isMenuCollapsed ? 'none' : 'block'
}}>
<Select
value={systemType}
onChange={setSystemType}
@ -241,6 +263,7 @@ const SystemContentList = (props) => {
}}
popupClassName="custom-select-dropdown"
className="custom-select"
suffixIcon={<CaretDownOutlined style={{ color: '#fff', fontSize: '16px' }} />}
/>
</div>
<style jsx>{`
@ -262,6 +285,8 @@ const SystemContentList = (props) => {
justify-content: center !important;
padding: 0 !important;
padding-right: 50px !important;
font-size: 16px !important;
font-weight: 500 !important;
}
.custom-select .ant-select-arrow {
opacity: 0.66 !important;
@ -280,7 +305,43 @@ const SystemContentList = (props) => {
font-size: 16px !important;
font-weight: 600 !important;
}
.menuToggleBtn {
position: absolute;
right: -15px;
top: 50%;
width: 30px;
height: 30px;
background: #FDFDFF;
color: #5C5C5C;
border: 1px solid #FFFFFF;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 9999; /* 增加z-index确保按钮在最上层 */
font-size: 16px;
font-weight: bold;
outline: none;
transition: all 0.3s ease;
box-shadow: 0 0 5px 3px rgba(169, 185, 255, 0.33);
}
.menuToggleBtn:hover {
border: 1px solid #3D81FF;
background: #3D81FF;
color: white;
transform: scale(1.1);
}
`}</style>
{/* 菜单收缩按钮 */}
<button
className="menuToggleBtn"
onClick={toggleMenu}
aria-label={isMenuCollapsed ? "展开菜单" : "收缩菜单"}
>
{isMenuCollapsed ? ">" : "<"}
</button>
<Menu
openKeys={openKey}
selectedKeys={selectedKey}
@ -322,15 +383,27 @@ const SystemContentList = (props) => {
return { ...child };
});
return { ...item, icon, children };
return {
...item,
icon,
children,
// 根据菜单收缩状态决定是否显示标签文本
label: isMenuCollapsed ? null : item.label
};
})}
onClick={value => setRouteActive(value)}
onOpenChange={value => setOpenKey(value)}
mode='inline'
mode={isMenuCollapsed ? 'vertical' : 'inline'}
/>
</div>
<div className='rightContent'>
<div
className='rightContent'
style={{
width: isMenuCollapsed ? 'calc(100% - 80px)' : 'calc(100% - 230px)',
transition: 'width 0.3s ease'
}}
>
{/* <div style={{ width: '100%', backgroundColor: '#fff', marginBottom: '10px' }}> */}
<div className='tabBarHeader'>
<Row className='tabBarRow'>
@ -344,6 +417,9 @@ const SystemContentList = (props) => {
<CustomBreadcrumb />
</Col>
<Col xs={4} sm={4} md={4} lg={4} xl={4} className='tabBarRight'>
<Button type='text' className='tabBarRightBtn'><BellOutlined /></Button>
<Button type='text' className='tabBarRightBtn'><SearchOutlined /></Button>
<Button type='text' className='tabBarRightBtn'><QuestionCircleOutlined /></Button>
<Avatar className='tabBarRightAvaTor' src='https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201707%2F31%2F20170731021444_2YUfe.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1669779871&t=ec025ed48a1668dee9cfa0e803b6f787' />
<span className='tabBarRightName'>{userInfo?.user_name_cn ? userInfo.user_name_cn : (userInfo?.user_name || '')}</span>

@ -79,7 +79,8 @@
overflow-x: hidden;
background-color: #2E4CD4;
.ant-menu-inline {
.ant-menu-inline,
.ant-menu-vertical {
background: #2E4CD4 !important;
}

@ -0,0 +1,860 @@
import React, {Fragment, PureComponent} from 'react';
import {
DeleteOutlined,
EditOutlined,
PlusOutlined,
SearchOutlined,
RedoOutlined,
DownOutlined,
ExclamationCircleFilled,
UpOutlined,
} from '@ant-design/icons';
import {connect, history} from '@umijs/max';
import {Button, Card, Divider, Dropdown, message, Modal, Popconfirm, Space, Switch, Tag,Row,Col} from 'antd';
import StandardTable from '@/components/StandardTable';
import { MyIcon } from "@/components/Icon"
import style from "@/global.less";
import StaffSheetCreateForm from './form/StaffSheetCreateForm'; //新增表单
import StaffSheetUpdateForm from './form/StaffSheetUpdateForm'; //修改表单
import StaffSheetViewForm from './form/StaffSheetViewForm'; //查看表单
import StaffSheetRenderSimpleForm from './form/StaffSheetRenderSimpleForm'; //简单查询表单
import StaffSheetRenderAdvancedForm from './form/StaffSheetRenderAdvancedForm'; //高级查询表单
import styles from './StaffSheetList.less';
import datadictionary from "@/utils/dataDictionary";
import {formatDate} from "@/utils/formatUtils";
import { formatDictText, checkButtonAuthority } from "@/utils/globalCommon";
const { confirm } = Modal;
//预约类型
const sex_type = datadictionary.sex
const user_status = datadictionary.user_status
const sys_user_post = datadictionary.sys_user_post
const mockData = {
list: [
{
gx: "--",
gslx: "排班",
ks: "中医科",
lc: "11",
kssj: "08:00",
jssj: "18:00",
cxsc: "8",
sjly: ""
},
{
gx: "--",
gslx: "考勤",
ks: "中医科",
lc: "11",
kssj: "07:00",
jssj: "20:00",
cxsc: "11",
sjly: ""
},
{
gx: "照顾A",
gslx: "照顾",
ks: "中医科",
lc: "11",
kssj: "09:00",
jssj: "10:00",
cxsc: "1",
sjly: "人工上传"
},
{
gx: "照顾B",
gslx: "照顾",
ks: "中医科",
lc: "11",
kssj: "10:00",
jssj: "11:00",
cxsc: "1",
sjly: "人工上传"
},
{
gx: "照顾C",
gslx: "照顾",
ks: "中医科",
lc: "11",
kssj: "11:00",
jssj: "13:00",
cxsc: "2",
sjly: "人工上传"
},
{
gx: "接病人D",
gslx: "接送",
ks: "急诊",
lc: "1",
kssj: "14:00",
jssj: "16:00",
cxsc: "2",
sjly: "his"
},
{
gx: "照顾A",
gslx: "照顾",
ks: "心脏内科",
lc: "9",
kssj: "16:00",
jssj: "18:00",
cxsc: "2",
sjly: "his"
},
{
gx: "送病人B",
gslx: "接送",
ks: "急诊",
lc: "1",
kssj: "18:00",
jssj: "20:00",
cxsc: "2",
sjly: "his"
},
{
gx: "照顾C",
gslx: "照顾",
ks: "中医科",
lc: "11",
kssj: "20:00",
jssj: "21:00",
cxsc: "1",
sjly: "系统采集"
},
],
pagination: {},
}
@connect(({ staffsheet, loading }) => ({
staffsheet,
loading: loading.models.staffsheet,
}))
class StaffSheetList extends PureComponent {
state = {
modalVisible: false,
updateModalVisible: false,
viewModalVisible: false,
expandForm: false,
selectedRows: [],
formValues: {},
updateFormValues: {},
viewFormValues: {},
toggleExpand: false,
}
columns = [
{
title: '工序',
dataIndex: 'gx',
key: 'gx',
width: 80,
fixed: 'left',
}, {
title: '工时类型',
dataIndex: 'gslx',
key: 'gslx',
width: 100,
fixed: 'left',
},{
title: '科室',
dataIndex: 'ks',
key: 'ks',
width: 80,
}, {
title: '楼层',
dataIndex: 'lc',
key: 'lc',
width: 80,
},{
title: '开始时间',
dataIndex: 'kssj',
key: 'kssj',
width: 100,
}, {
title: '结束时间',
dataIndex: 'jssj',
key: 'jssj',
width: 100,
}, {
title: '持续时长(小时)',
dataIndex: 'cxsc',
key: 'cxsc',
width: 100,
},
{
title: <div className={styles.timeGraphic}>
<span>6</span>
<span>7</span>
<span>8</span>
<span>9</span>
<span>10</span>
<span>11</span>
<span>12</span>
<span>13</span>
<span>14</span>
<span>15</span>
<span>16</span>
<span>17</span>
<span>18</span>
<span>19</span>
<span>20</span>
<span>21</span>
<span>22</span>
<span>23</span>
<span>0</span>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</div>,
dataIndex: 'tj',
key: 'tj',
width: 750,
render: (text, record,index) => {
console.log(record,77777)
if(index == 0) {
return (
<Fragment>
<div className={styles.pbsjStyle}></div>
<div className={styles.pbsjStyle} style={{marginLeft: 73}}></div>
</Fragment>
)
} else if(index == 1) {
return (
<Fragment>
<div className={styles.kqsjStyle}></div>
<div className={styles.kqsjStyle} style={{marginLeft: 36,width: 232}}></div>
</Fragment>
)
} else if(index == 2) {
return (
<Fragment>
<div className={styles.xzStyle}></div>
<div className={styles.zjgsStyle}></div>
</Fragment>
)
} else if(index == 3) {
return (
<Fragment>
<div className={styles.zjgsStyle} style={{marginLeft: 118}}></div>
</Fragment>
)
} else if(index == 4) {
return (
<Fragment>
<div className={styles.zjgsStyle} style={{marginLeft: 148, width: 60}}></div>
</Fragment>
)
} else if(index == 5) {
return (
<Fragment>
<div className={styles.zjgsStyle} style={{marginLeft: 246, width: 60}}></div>
</Fragment>
)
} else if(index == 6) {
return (
<Fragment>
<div className={styles.zjgsStyle} style={{marginLeft: 310, width: 60}}></div>
</Fragment>
)
} else if(index == 7) {
return (
<Fragment>
<div className={styles.zjgsStyle} style={{marginLeft: 370, width: 60}}></div>
</Fragment>
)
} else if(index == 8) {
return (
<Fragment>
<div className={styles.zjgsStyle} style={{marginLeft: 430, width: 30}}></div>
</Fragment>
)
}
}
},
{
title: '数据来源',
dataIndex: 'sjly',
key: 'sjly',
width: 100,
},
{
title: '操作',
fixed: 'right',
width: 100,
render: (text, record) => {
return (
<Fragment>
<a className={style.iconstyle}> 修改 </a>
</Fragment>
)
}
},
]
componentDidMount() {
// const { dispatch, staffsheet: { params } } = this.props
// dispatch({
// type: 'timesheet/query_page_for_prouser',
// })
// this.setState({
// expandForm: params?.expandForm || false,
// })
}
handleStandardTableChange = (pagination, sorter) => {
const { dispatch } = this.props
const { formValues } = this.state
const params = {
currentPage: pagination.current,
pageSize: pagination.pageSize,
...formValues
}
sorter.field && (params.sorter = `${sorter.field}_${sorter.order}`)
// dispatch({
// type: 'prouser/query_page_for_prouser',
// payload: params
// })
}
handleFormReset = () => {
const { dispatch } = this.props
this.setState({
formValues: {}
})
// dispatch({
// type: 'prouser/query_page_for_prouser',
// payload: {
// resetFlag: true
// }
// })
}
toggleForm = () => {
const { expandForm } = this.state
this.setState({
expandForm: !expandForm
})
}
handleSelectRows = rows => {
this.setState({
selectedRows: rows
})
}
handleSearch = values => {
const { dispatch } = this.props
const { expandForm } = this.state
this.setState({
formValues: values
})
// dispatch({
// type: 'prouser/query_page_for_prouser',
// payload: {
// ...values,
// resetFlag: true,
// expandForm
// }
// })
}
handleModalVisible = flag => {
this.setState({
modalVisible: !!flag
})
}
handleUpdateModalVisible = (flag, record) => {
this.setState({
updateModalVisible: !!flag,
updateFormValues: record || {}
})
}
handleViewModalVisible = (flag, record) => {
this.setState({
viewModalVisible: !!flag,
viewFormValues: record || {}
})
}
handleAdd = fields => {
const { dispatch } = this.props
dispatch({
type: 'prouser/insert_for_prouser',
payload: {
user_id: fields.user_id,
user_name: fields.user_name,
user_name_cn: fields.user_name_cn,
user_name_en: fields.user_name_en,
password: fields.password,
email: fields.email,
phone: fields.phone,
landline: fields.landline,
sex: fields.sex,
avatar: fields.avatar,
sign: fields.sign,
tags: fields.tags,
id_card: fields.id_card,
birthday: fields.birthday,
job_status: fields.job_status,
hiredate: fields.hiredate,
departure_time: fields.departure_time,
user_type: fields.user_type,
emp_no: fields.emp_no,
access_card_no: fields.access_card_no,
country: fields.country,
province: fields.province,
city: fields.city,
address: fields.address,
work_addr: fields.work_addr,
floor: fields.floor,
inprovince: fields.inprovince,
// dept_code: fields.dept_code,
// dept_name: fields.dept_name,
inner_dept_code: fields.inner_dept_code,
org_code: fields.org_code,
org_name: fields.org_name,
inner_org_code: fields.inner_org_code,
posts: fields.posts,
wx_openid: fields.wx_openid,
wx_mpopenid: fields.wx_mpopenid,
wx_miniopenid: fields.wx_miniopenid,
wx_unionid: fields.wx_unionid,
mobile_imei: fields.mobile_imei,
device_num: fields.device_num,
al_taobao: fields.al_taobao,
al_alipay: fields.al_alipay,
al_dingding: fields.al_dingding,
is_system_user: fields.is_system_user,
mgr_type: fields.mgr_type,
pwd_security_level: fields.pwd_security_level,
pwd_update_date: fields.pwd_update_date,
last_login_ip: fields.last_login_ip,
last_login_date: fields.last_login_date,
freeze_date: fields.freeze_date,
freeze_cause: fields.freeze_cause,
zindex: fields.zindex,
wx_msg: fields.wx_msg,
email_msg: fields.email_msg,
system_msg: fields.system_msg,
remarks: fields.remarks,
status: fields.status,
creator: fields.creator,
create_date: fields.create_date,
updater: fields.updater,
update_date: fields.update_date
},
callback: (res) => {
if(res.success == true) {
message.success('添加成功')
this.handleModalVisible()
}
}
})
}
handleDeleteRecord = record => {
const { dispatch } = this.props
dispatch({
type: 'prouser/delete_by_primarykey_for_prouser',
payload: {
recordid: record.user_id
},
callback: res => {
if (res.success) {
message.success('删除成功')
this.setState({
selectedRows: []
})
}
}
})
}
handleUpdate = fields => {
const { dispatch } = this.props
dispatch({
type: 'prouser/update_for_prouser',
payload: {
user_id: fields.user_id,
user_name: fields.user_name,
user_name_cn: fields.user_name_cn,
user_name_en: fields.user_name_en,
password: fields.password,
email: fields.email,
phone: fields.phone,
landline: fields.landline,
sex: fields.sex,
avatar: fields.avatar,
sign: fields.sign,
tags: fields.tags,
id_card: fields.id_card,
birthday: fields.birthday,
job_status: fields.job_status,
hiredate: fields.hiredate,
departure_time: fields.departure_time,
user_type: fields.user_type,
emp_no: fields.emp_no,
access_card_no: fields.access_card_no,
country: fields.country,
province: fields.province,
city: fields.city,
address: fields.address,
work_addr: fields.work_addr,
floor: fields.floor,
inprovince: fields.inprovince,
// dept_code: fields.dept_code,
// dept_name: fields.dept_name,
inner_dept_code: fields.inner_dept_code,
org_code: fields.org_code,
org_name: fields.org_name,
inner_org_code: fields.inner_org_code,
posts: fields.posts,
wx_openid: fields.wx_openid,
wx_mpopenid: fields.wx_mpopenid,
wx_miniopenid: fields.wx_miniopenid,
wx_unionid: fields.wx_unionid,
mobile_imei: fields.mobile_imei,
device_num: fields.device_num,
al_taobao: fields.al_taobao,
al_alipay: fields.al_alipay,
al_dingding: fields.al_dingding,
is_system_user: fields.is_system_user,
mgr_type: fields.mgr_type,
pwd_security_level: fields.pwd_security_level,
pwd_update_date: fields.pwd_update_date,
last_login_ip: fields.last_login_ip,
last_login_date: fields.last_login_date,
freeze_date: fields.freeze_date,
freeze_cause: fields.freeze_cause,
zindex: fields.zindex,
wx_msg: fields.wx_msg,
email_msg: fields.email_msg,
system_msg: fields.system_msg,
remarks: fields.remarks,
status: fields.status,
creator: fields.creator,
create_date: fields.create_date,
updater: fields.updater,
update_date: fields.update_date
},
callback: (res) => {
if(res.success === true) {
message.success('修改成功')
this.handleUpdateModalVisible()
}
}
})
}
// 修改用户状态
handleUpdateUserStatus = (fields, status, msg) => {
const { dispatch } = this.props
confirm({
title: `确定要 ${ msg } 当前用户的吗?`,
icon: <ExclamationCircleFilled />,
onOk() {
dispatch({
type: 'prouser/update_for_prouser',
payload: {
user_id: fields.user_id,
status: status,
},
callback: (res) => {
if(res.success === true) {
message.success('修改成功')
}
}
})
}
})
}
// 修改用户密码
handleUpdateUserPassword = fields => {
const { dispatch } = this.props
confirm({
title: '确定要重置当前用户的密码吗?',
icon: <ExclamationCircleFilled />,
onOk() {
dispatch({
type: 'prouser/resetpwd_for_prouser',
payload: {
user_id: fields.user_id
},
callback: (res) => {
if(res.success === true) {
message.success('重置成功')
}
}
})
}
})
}
renderSimpleForm() {
const { staffsheet: { params } } = this.props
const parentMethods = {
handleSearch: this.handleSearch,
handleFormReset: this.handleFormReset,
toggleForm: this.toggleForm,
params
}
return <StaffSheetRenderSimpleForm {...parentMethods} />
}
renderAdvancedForm() {
const { dispatch, prouser: { selectDeptTree, selectOrganTree, params } } = this.props
const parentMethods = {
handleSearch: this.handleSearch,
handleFormReset: this.handleFormReset,
toggleForm: this.toggleForm,
dispatch: dispatch,
selectDeptTree: selectDeptTree,
selectOrganTree: selectOrganTree,
params
}
return <StaffSheetRenderAdvancedForm {...parentMethods} />
}
renderForm() {
const { expandForm } = this.state
return expandForm ? this.renderAdvancedForm() : this.renderSimpleForm()
}
handleCollapse = () => {
const { toggleExpand } = this.state
this.setState({
toggleExpand: !toggleExpand
})
}
render() {
const {
staffsheet: {
data,
selectDeptTree,
selectOrganTree
},
loading,
dispatch
} = this.props
const {
selectedRows,
modalVisible,
updateModalVisible,
viewModalVisible,
updateFormValues,
viewFormValues,
toggleExpand
} = this.state
const parentMethods = {
handleAdd: this.handleAdd,
handleModalVisible: this.handleModalVisible,
dispatch: dispatch,
loading,
selectDeptTree: selectDeptTree,
selectOrganTree: selectOrganTree
}
const updateMethods = {
handleUpdateModalVisible: this.handleUpdateModalVisible,
handleUpdate: this.handleUpdate,
dispatch: dispatch,
loading,
selectDeptTree: selectDeptTree,
selectOrganTree: selectOrganTree
}
const viewMethods = {
handleViewModalVisible: this.handleViewModalVisible
}
return (
<>
<Card bordered={false}>
<div className={styles.proUsertableList}>
<div className={styles.proUsertableListForm}>{this.renderForm()}</div>
<Divider style={{ borderColor: '#cccccc',margin:0 }}>
<div className={styles.summaryButton} onClick={() => this.handleCollapse()}>
{toggleExpand ? <><UpOutlined /> 收起</> : <><DownOutlined /> 展开</>}
</div>
</Divider>
<div style={{display: toggleExpand?'block':'none'}}>
<div className={styles.summaryContent}>
<div style={{paddingLeft: 0}}>
<div className={styles.titleLabel}>名称</div>
<div className={styles.titleVal}>张三</div>
</div>
<div>
<div className={styles.titleLabel}>考勤类型</div>
<div className={styles.titleVal}>排班制</div>
</div>
<div>
<div className={styles.titleLabel}>出勤人效(/小时)</div>
<div className={styles.titleVal}>10000</div>
</div>
<div>
<div className={styles.titleLabel}>作业人效(/小时)</div>
<div className={styles.titleVal}>12000</div>
</div>
<div>
<div className={styles.titleLabel}>人效出勤工时(小时)</div>
<div className={styles.titleVal}>8</div>
</div>
<div>
<div className={styles.titleLabel}>出勤工时占比(%)</div>
<div className={styles.titleVal}>100%</div>
</div>
</div>
<div className={styles.summaryContent}>
<div style={{paddingLeft: 0}}>
<div className={styles.titleLabel}>工号</div>
<div className={styles.titleVal}>123456</div>
</div>
<div>
<div className={styles.titleLabel}>在职时长(小时)</div>
<div className={styles.titleVal}>1200</div>
</div>
<div>
<div className={styles.titleLabel}>外出就餐时长(小时)</div>
<div className={styles.titleVal}>0</div>
</div>
<div>
<div className={styles.titleLabel}>直接作业工时(小时)</div>
<div className={styles.titleVal}>7</div>
</div>
<div>
<div className={styles.titleLabel}>间接作业工时(小时)</div>
<div className={styles.titleVal}>1</div>
</div>
<div>
<div className={styles.titleLabel}>闲置工时(小时)</div>
<div className={styles.titleVal}>0</div>
</div>
</div>
<div className={styles.summaryContent}>
<div style={{paddingLeft: 0}}>
<div className={styles.titleLabel}>工作性质</div>
<div className={styles.titleVal}>外包</div>
</div>
<div>
<div className={styles.titleLabel}>总件数()</div>
<div className={styles.titleVal}>9000</div>
</div>
<div>
<div className={styles.titleLabel}>离岗休息时长(小时)</div>
<div className={styles.titleVal}>0</div>
</div>
<div>
<div className={styles.titleLabel}>直接作业工时占比(%)</div>
<div className={styles.titleVal}>84</div>
</div>
<div>
<div className={styles.titleLabel}>闲置工时占比(%)</div>
<div className={styles.titleVal}>0</div>
</div>
<div>
<div className={styles.titleLabel}>闲置工时(小时)</div>
<div className={styles.titleVal}>0</div>
</div>
</div>
</div>
<div className={styles.operateContent}>
<div>
<Button type='primary' style={{marginRight: 50}}>
同步
</Button>
<Button type='primary' danger>
考勤排查
</Button>
</div>
<div>
<div style={{display: 'inline-block'}}>
<div className={styles.workClass} style={{background: '#faf07a'}}></div>
排班时间
</div>
<div style={{display: 'inline-block'}}>
<div className={styles.workClass} style={{background: '#9cc5fc'}}></div>
考勤时间
</div>
<div style={{display: 'inline-block'}}>
<div className={styles.workClass} style={{background: '#aa02cf'}}></div>
修改状态
</div>
<div style={{display: 'inline-block'}}>
<div className={styles.workClass} style={{background: '#454545'}}></div>
闲置工时
</div>
<div style={{display: 'inline-block'}}>
<div className={styles.workClass} style={{background: '#8ddd15'}}></div>
直接工时
</div>
<div style={{display: 'inline-block'}}>
<div className={styles.workClass} style={{background: '#cecece'}}></div>
离岗休息
</div>
</div>
</div>
<div style={{display: 'flex',justifyContent: "space-between"}}>
<div>共20项</div>
</div>
<StandardTable
rowKey={'user_id'}
selectedRows={selectedRows}
loading={loading}
data={mockData}
columns={this.columns}
onSelectRow={this.handleSelectRows}
onChange={this.handleStandardTableChange}
scroll={{ x: 1000,y: 600 }}
showTotal={(total, range) => total}
/>
</div>
</Card>
{modalVisible && <StaffSheetCreateForm {...parerntMethods} modalVisible={modalVisible} />}
{updateFormValues && Object.keys(updateFormValues).length ? (
<StaffSheetUpdateForm
{...updateMethods}
updateModalVisible={updateModalVisible}
values={updateFormValues}
/>
) : null}
{viewFormValues && Object.keys(viewFormValues).length ? (
<StaffSheetViewForm
{...viewMethods}
viewModalVisible={viewModalVisible}
values={viewFormValues}
/>
) : null}
</>
)
}
}
export default StaffSheetList

@ -0,0 +1,128 @@
@import '~@/utils/utils.less';
.proUsertableList {
.proUsertableListOperator {
margin-bottom: 16px;
button {
margin-right: 8px;
}
}
.editColumn {
> div:last-child {
display: none;
}
}
}
.proUsertableListForm {
height: 45px;
:global {
.ant-form-item {
display: flex;
margin-right: 0;
margin-bottom: 24px;
.ant-form-item-label {
// width: 80px;
// padding-right: 8px;
line-height: 32px;
text-align: left;
}
.ant-form-item-control {
line-height: 32px;
width: calc(100% - 80px);
.ant-form-item-control-input-content {
height: 32px;
}
}
> .ant-row {
flex-wrap: nowrap;
}
}
.ant-form-item-control-wrapper {
flex: 1;
}
}
}
.summaryButton {
width: 80px;
height: 30px;
line-height: 30px;
font-size: 12px;
background-color: #eff1f3;
border-radius: 20px;
cursor: pointer;
}
.summaryContent {
display: flex;
margin-top: 10px;
> div {
flex: 2;
height: 60px;
border-right: 2px solid #eeeeee;
padding-left: 10px;
// background-color: #1890FF
}
.titleLabel {
color: #b2b2b2;
font-weight: 500;
margin-bottom: 10px;
}
.titleVal {
font-weight: 500;
}
}
.operateContent {
display: flex;
margin: 20px 0;
justify-content: space-between;
.workClass {
display: inline-block;
width: 10px;
height: 10px;
margin-left: 10px;
}
}
.pbsjStyle {
display: inline-block;
width: 120px;
height: 40px;
margin-left: 56px;
background-color: #faf07a;
}
.kqsjStyle {
display: inline-block;
width: 180px;
height: 40px;
margin-left: 29px;
background-color: #9cc5fc;
}
.xzStyle {
display: inline-block;
width: 60px;
height: 40px;
margin-left: 29px;
background-color: #454545;
}
.zjgsStyle {
display: inline-block;
width: 30px;
height: 40px;
background-color: #8ddd15;
}
.timeGraphic {
span {
padding: 0 10px;
}
}

@ -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 (
<Modal
width={800}
height={550}
bodyStyle={{ height: '500px', overflowY: 'auto' }}
className={style.createForm}
centered
destroyOnClose
title='新增'
open={modalVisible}
onOk={okHandle}
onCancel={() => handleModalVisible()}
afterClose={() => afterClose()}
confirmLoading={loading}
>
<Form form={form} layout='vertical' requiredMark={false}>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='登录账号' name='user_name' rules={[{ required: true, message: '请输入至少2个字符的用户名', min: 2 }]}>
<Input placeholder='请输入' />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='用户名称' name='user_name_cn' rules={[{ required: true, message: '请输入至少2个字符的用户名称', min: 2 }]}>
<Input placeholder='请输入' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='用户性别' name='sex'>
<Select options={formatDictOptions(dictData.sys_user_sex, 'dict_label', 'dict_value')} placeholder='请选择' />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='用户生日' name='birthday'>
<DatePicker format='YYYY-MM-DD' placeholder='请选择' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='手机号码' name='phone' rules={[{ required: false, min: 1, validator: verifyPhone }]}>
<NumberInput placeholder='请输入' style={{width: '100%'}} maxLength={11} />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='电子邮箱' name='email' rules={[{ type: 'email' }]}>
<Input placeholder='请输入' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='机构名称' name='org_code'>
<SelectOrganTree {...parentOrganTreeMethod} />
</FormItem>
</Col>
{/*<Col md={12} sm={24}>*/}
{/* <FormItem label='部门名称' name='dept_code'>*/}
{/* <SelectDeptTree {...parentDeptTreeMethod} placeholder={'请选择部门'} />*/}
{/* </FormItem>*/}
{/*</Col>*/}
<Col md={12} sm={24}>
<FormItem label='所属岗位' name='posts'>
<Select
mode='multiple'
allowClear
placeholder='请选择'
options={formatDictOptions(dictData.sys_user_post, 'dict_label', 'dict_value')}
/>
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
{/*<Col md={12} sm={24}>
<FormItem
label={
<span>
密码
<em className={styles.optional}>
<Tooltip title='默认密码123456'>
<InfoCircleOutlined style={{ marginLeft: 4 }} />
</Tooltip>
</em>
</span>
}
name='password'
initialValue={'123456'}
rules={[{required: true, message: '请输入至少6个字符的密码', min: 6}]}>
<Input placeholder='请输入' type='password'/>
</FormItem>
</Col>*/}
<Col md={12} sm={24}>
<FormItem label='在职状态' name='job_status'>
<Select
placeholder='请选择'
options={formatDictOptions(dictData.sys_job_status, 'dict_label', 'dict_value')}
onChange={handleJobStatusChange}
/>
</FormItem>
</Col>
{jobStatus === '1' ?
<Col md={12} sm={24}>
<FormItem label='入职时间' name='hiredate' initialValue={dayjs().endOf('day')}>
<DatePicker format='YYYY-MM-DD' placeholder='请选择' />
</FormItem>
</Col>
:
<Col md={12} sm={24}>
<FormItem label='离职时间' name='departure_time'>
<DatePicker format='YYYY-MM-DD' placeholder='请选择' />
</FormItem>
</Col>
}
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='员工类型' name='user_type'>
<Select
placeholder='请选择'
options={formatDictOptions(dictData.sys_user_type, 'dict_label', 'dict_value')}
/>
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='员工工号' name='emp_no'>
<Input placeholder='请输入' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='门禁卡号' name='access_card_no'>
<Input placeholder='请输入' />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='是否是管理员' name='mgr_type'>
<Select
style={{width: '100%'}}
placeholder='请选择'
options={formatDictOptions(dictData.sys_mgr_type, 'dict_label', 'dict_value')}
/>
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={24} sm={24}>
<FormItem label='备注' name='remarks'>
<TextArea rows={4} />
</FormItem>
</Col>
</Row>
</Form>
</Modal>
)
})
export default StaffSheetCreateForm

@ -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 (
<Form form={form} onFinish={onFinish} layout='inline'>
<Row gutter={{ md: 8, lg: 24, xl: 48 }} className={style.searchInput}>
<Col md={8} sm={24}>
<FormItem label='用户名' name='user_name'>
<Input placeholder='请输入' />
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label='用户名称' name='user_name_cn'>
<Input placeholder='请输入' />
</FormItem>
</Col>
<Col md={8} sm={24}>
<FormItem label='机构代码' name='orgname'>
<SelectOrganTree {...parentOrganTreeMethod} />
</FormItem>
</Col>
</Row>
<Row gutter={{md: 8, lg: 24, xl: 48}} className={style.searchBox}>
{/*<Col md={8} sm={24}>*/}
{/* <FormItem label='部门名称' name='deptname'>*/}
{/* <SelectDeptTree placeholder={'请选择部门'} {...parentDeptTreeMethod} />*/}
{/* </FormItem>*/}
{/*</Col>*/}
<Col md={24} sm={24}>
<div className={style.searchBtn}>
<Button type='primary' htmlType='submit'>
查询
</Button>
<Button onClick={myHandleFormReset}>
重置
</Button>
<a onClick={() => toggleForm(form)}>
收起 <UpOutlined />
</a>
</div>
</Col>
</Row>
</Form>
)
}
export default StaffSheetRenderAdvancedForm

@ -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 (
<Form form={form} onFinish={onFinish} layout='inline'>
<Row gutter={{ md: 8, lg: 24, xl: 48 }} className={style.searchInput}>
<Col md={4} sm={24}>
<FormItem label='我的查询条件' name='wdcxtj'>
<Select
placeholder='请选择'
options={[]}
/>
</FormItem>
</Col>
<Col md={4} sm={24}>
<FormItem label='日期' name='rq' rules={[{ required: true, message: '请选择日期!' }]}>
<DatePicker defaultValue={dayjs('2025-04-10', 'YYYY-MM-DD')} format='YYYY-MM-DD' />
</FormItem>
</Col>
<Col md={4} sm={24}>
<FormItem label='工作地点' name='gzdd'>
<Input placeholder='请输入' />
</FormItem>
</Col>
<Col md={4} sm={24}>
<FormItem label='工号' name='gh'>
<Input placeholder='请输入' defaultValue="123456"/>
</FormItem>
</Col>
<Col md={4} sm={24}>
<FormItem label='名称' name='gh'>
<Input placeholder='请输入'/>
</FormItem>
</Col>
<Col md={4} sm={24}>
<div className={style.searchBtn}>
<Button type='primary' htmlType='submit'>
查询
</Button>
<Button onClick={myHandleFormReset}>
重置
</Button>
</div>
</Col>
</Row>
</Form>
)
}
export default StaffSheetRenderSimpleForm

@ -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 (
<Modal
width={800}
height={550}
bodyStyle={{ height: '500px', overflowY: 'auto' }}
className={style.updateForm}
centered
destroyOnClose
title='修改'
open={updateModalVisible}
onOk={() => handleLocalUpdate()}
onCancel={() => handleUpdateModalVisible()}
afterClose={() => afterClose()}
confirmLoading={loading}
>
<Form form={form} layout='vertical' requiredMark={false}>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='登录账号' name='user_name' rules={[{ required: true, message: '请输入至少2个字符的用户名', min: 2 }]}>
<Input placeholder='请输入' />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='用户名称' name='user_name_cn' rules={[{ required: true, message: '请输入至少2个字符的用户名称', min: 2 }]}>
<Input placeholder='请输入' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='用户性别' name='sex'>
<Select options={formatDictOptions(dictData.sys_user_sex, 'dict_label', 'dict_value')} placeholder='请选择' />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='用户生日' name='birthday'>
<DatePicker format='YYYY-MM-DD' placeholder='请选择' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='手机号码' name='phone' rules={[{ required: false, min: 1, validator: verifyPhone }]}>
<NumberInput placeholder='请输入' style={{width: '100%'}} maxLength={11} />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='电子邮箱' name='email' rules={[{ type: 'email' }]}>
<Input placeholder='请输入' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='机构名称' name='org_code'>
<SelectOrganTree {...parentOrganTreeMethod} />
</FormItem>
</Col>
{/*<Col md={12} sm={24}>*/}
{/* <FormItem label='部门名称' name='dept_code'>*/}
{/* <SelectDeptTree {...parentDeptTreeMethod} placeholder={'请选择部门'} />*/}
{/* </FormItem>*/}
{/*</Col>*/}
<Col md={12} sm={24}>
<FormItem label='所属岗位' name='posts'>
<Select
mode='multiple'
allowClear
placeholder='请选择'
options={formatDictOptions(dictData.sys_user_post, 'dict_label', 'dict_value')}
/>
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
{/*<Col md={12} sm={24}>
<FormItem
label={
<span>
密码
<em className={styles.optional}>
<Tooltip title='默认密码123456'>
<InfoCircleOutlined style={{ marginLeft: 4 }} />
</Tooltip>
</em>
</span>
}
name='password'
initialValue={'123456'}
rules={[{required: true, message: '请输入至少6个字符的密码', min: 6}]}>
<Input placeholder='请输入' type='password'/>
</FormItem>
</Col>*/}
<Col md={12} sm={24}>
<FormItem label='在职状态' name='job_status'>
<Select
placeholder='请选择'
options={formatDictOptions(dictData.sys_job_status, 'dict_label', 'dict_value')}
onChange={handleJobStatusChange}
/>
</FormItem>
</Col>
{jobStatus === '1' ?
<Col md={12} sm={24}>
<FormItem label='入职时间' name='hiredate' initialValue={dayjs().endOf('day')}>
<DatePicker format='YYYY-MM-DD' placeholder='请选择' />
</FormItem>
</Col>
:
<Col md={12} sm={24}>
<FormItem label='离职时间' name='departure_time'>
<DatePicker format='YYYY-MM-DD' placeholder='请选择' />
</FormItem>
</Col>
}
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='员工类型' name='user_type'>
<Select
placeholder='请选择'
options={formatDictOptions(dictData.sys_user_type, 'dict_label', 'dict_value')}
/>
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='员工工号' name='emp_no'>
<Input placeholder='请输入' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='门禁卡号' name='access_card_no'>
<Input placeholder='请输入' />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='是否是管理员' name='mgr_type'>
<Select
style={{width: '100%'}}
placeholder='请选择'
options={formatDictOptions(dictData.sys_mgr_type, 'dict_label', 'dict_value')}
/>
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='状态' name='status'>
<Select
placeholder='请选择'
options={formatDictOptions(dictData.user_status, 'dict_label', 'dict_value')}
onChange={handleUserStatusChange}
/>
</FormItem>
</Col>
{ userStatus === '3' &&
<Col md={12} sm={24}>
<FormItem label='冻结原因' name='freeze_cause'>
<Input placeholder='请输入' />
</FormItem>
</Col>
}
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={24} sm={24}>
<FormItem label='备注' name='remarks'>
<TextArea rows={4} />
</FormItem>
</Col>
</Row>
</Form>
</Modal>
)
}
export default StaffSheetUpdateForm

@ -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 (
<Modal
width={800}
height={550}
bodyStyle={{ height: '500px', overflowY: 'auto' }}
className={style.viewForm}
centered
destroyOnClose
title='查看'
open={viewModalVisible}
onOk={() => handleViewModalVisible()}
onCancel={() => handleViewModalVisible()}
afterClose={() => afterClose()}
>
<Form form={form} layout='vertical' requiredMark={false} style={{pointerEvents: 'none'}}>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='登录账号' name='user_name' rules={[{ required: true, message: '请输入至少2个字符的用户名', min: 2 }]}>
<Input placeholder='请输入' />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='用户名称' name='user_name_cn' rules={[{ required: true, message: '请输入至少2个字符的用户名称', min: 2 }]}>
<Input placeholder='请输入' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='用户性别' name='sex'>
<Select options={formatDictOptions(dictData.sys_user_sex, 'dict_label', 'dict_value')} placeholder='请选择' />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='用户生日' name='birthday'>
<DatePicker format='YYYY-MM-DD' placeholder='请选择' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='手机号码' name='phone' rules={[{ required: false, min: 1, validator: verifyPhone }]}>
<NumberInput placeholder='请输入' style={{width: '100%'}} maxLength={11} />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='电子邮箱' name='email' rules={[{ type: 'email' }]}>
<Input placeholder='请输入' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='机构名称' name='org_name'>
<Input placeholder='请输入' />
</FormItem>
</Col>
{/*<Col md={12} sm={24}>*/}
{/* <FormItem label='部门名称' name='dept_code'>*/}
{/* <SelectDeptTree {...parentDeptTreeMethod} placeholder={'请选择部门'} />*/}
{/* </FormItem>*/}
{/*</Col>*/}
<Col md={12} sm={24}>
<FormItem label='所属岗位' name='posts'>
<Select
mode='multiple'
allowClear
placeholder='请选择'
options={formatDictOptions(dictData.sys_user_post, 'dict_label', 'dict_value')}
/>
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
{/*<Col md={12} sm={24}>
<FormItem
label={
<span>
密码
<em className={styles.optional}>
<Tooltip title='默认密码123456'>
<InfoCircleOutlined style={{ marginLeft: 4 }} />
</Tooltip>
</em>
</span>
}
name='password'
initialValue={'123456'}
rules={[{required: true, message: '请输入至少6个字符的密码', min: 6}]}>
<Input placeholder='请输入' type='password'/>
</FormItem>
</Col>*/}
<Col md={12} sm={24}>
<FormItem label='在职状态' name='job_status'>
<Select
placeholder='请选择'
options={formatDictOptions(dictData.sys_job_status, 'dict_label', 'dict_value')}
onChange={handleJobStatusChange}
/>
</FormItem>
</Col>
{jobStatus === '1' ?
<Col md={12} sm={24}>
<FormItem label='入职时间' name='hiredate' initialValue={dayjs().endOf('day')}>
<DatePicker format='YYYY-MM-DD' placeholder='请选择' />
</FormItem>
</Col>
:
<Col md={12} sm={24}>
<FormItem label='离职时间' name='departure_time'>
<DatePicker format='YYYY-MM-DD' placeholder='请选择' />
</FormItem>
</Col>
}
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='员工类型' name='user_type'>
<Select
placeholder='请选择'
options={formatDictOptions(dictData.sys_user_type, 'dict_label', 'dict_value')}
/>
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='员工工号' name='emp_no'>
<Input placeholder='请输入' />
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='门禁卡号' name='access_card_no'>
<Input placeholder='请输入' />
</FormItem>
</Col>
<Col md={12} sm={24}>
<FormItem label='是否是管理员' name='mgr_type'>
<Select
style={{width: '100%'}}
placeholder='请选择'
options={formatDictOptions(dictData.sys_mgr_type, 'dict_label', 'dict_value')}
/>
</FormItem>
</Col>
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={12} sm={24}>
<FormItem label='状态' name='status'>
<Select
placeholder='请选择'
options={formatDictOptions(dictData.user_status, 'dict_label', 'dict_value')}
onChange={handleUserStatusChange}
/>
</FormItem>
</Col>
{ userStatus === '3' &&
<Col md={12} sm={24}>
<FormItem label='冻结原因' name='freeze_cause'>
<Input placeholder='请输入' />
</FormItem>
</Col>
}
</Row>
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={24} sm={24}>
<FormItem label='备注' name='remarks'>
<TextArea rows={4} />
</FormItem>
</Col>
</Row>
</Form>
</Modal>
)
}
export default StaffSheetViewForm

@ -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,
};
},
},
};
Loading…
Cancel
Save