diff --git a/api/app/lib/controllers/organization/depUsers.js b/api/app/lib/controllers/organization/depUsers.js new file mode 100644 index 00000000..255bb7cf --- /dev/null +++ b/api/app/lib/controllers/organization/depUsers.js @@ -0,0 +1,65 @@ +'use strict'; + +async function getDepUsers(ctx) { + try { + const models = ctx.fs.dc.models; + //所有部门 + const departments = await models.Department.findAll({ + attributes: ['id', 'name', 'dependence'], + order: [['id', 'asc']], + where: { + delete: false, + }, + }) + //所有用户 + const allusers = await models.User.findAll({ + attributes: ['id', 'name', 'username', 'department_id'], + order: [['id', 'asc']], + where: { + delete: false, + }, + }) + const employees = [...new Set(allusers)] + function collectEmployees(departments, employees) { + const result = []; + const processDepartment = (department) => { + const departmentData = { + depId: department.id, + depName: department.name, + users: [], + expanded: false, // 初始状态折叠 + }; + const departmentEmployees = employees.filter(employee => + //console.log('employee.dataVaules.department_id', employee.department_id) + employee.dataValues.department_id === department.id + ); + departmentData.users.push(...departmentEmployees); + departments.forEach(subDepartment => { + if (subDepartment.dependence === department.id) { + const subDepartmentData = processDepartment(subDepartment); + departmentData.users.push(...subDepartmentData.users); + } + }); + return departmentData; + }; + departments.forEach(department => { + if (department.dependence === null) { + const departmentData = processDepartment(department); + result.push(departmentData); + } + }); + return result; + } + const result = collectEmployees(departments, employees); + ctx.status = 200; + ctx.body = result + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = {} + } +} + +module.exports = { + getDepUsers +}; \ No newline at end of file diff --git a/api/app/lib/routes/organization/index.js b/api/app/lib/routes/organization/index.js index f9c7a949..b0c4a19d 100644 --- a/api/app/lib/routes/organization/index.js +++ b/api/app/lib/routes/organization/index.js @@ -63,4 +63,6 @@ module.exports = function (app, router, opts) { + + }; \ No newline at end of file diff --git a/api/app/lib/routes/report/index.js b/api/app/lib/routes/report/index.js index d3fd64dd..708692b5 100644 --- a/api/app/lib/routes/report/index.js +++ b/api/app/lib/routes/report/index.js @@ -1,6 +1,7 @@ 'use strict'; const report = require('../../controllers/report'); +const Department = require('../../controllers/organization/depUsers') module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/report/list'] = { content: '获取上报列表', visible: false }; @@ -20,4 +21,7 @@ module.exports = function (app, router, opts) { app.fs.api.logAttr['DEL/report/:reportId'] = { content: '删除上报', visible: false }; router.del('/report/:reportId', report.deleteReport); + + app.fs.api.logAttr['get/allDepUsers'] = { content: '查询所有部门的员工', visible: false }; + router.get('allDepUsers', Department.getDepUsers); } \ No newline at end of file diff --git a/web/client/src/sections/fillion/actions/allDepUsers.js b/web/client/src/sections/fillion/actions/allDepUsers.js new file mode 100644 index 00000000..7aac192b --- /dev/null +++ b/web/client/src/sections/fillion/actions/allDepUsers.js @@ -0,0 +1,14 @@ +import { basicAction } from '@peace/utils' +import { ApiTable } from '$utils' + +export function getAllDepUsers(query) { + return dispatch => basicAction({ + type: 'get', + dispatch: dispatch, + query: query, + actionType: 'GET_AllDEPUSERS', + url: ApiTable.getAllDepUsers, + msg: { option: '获取部门下的所有员工' },//子部门算在第一级部门下面 + reducer: { name: 'allDepUsers' } + }); +} \ No newline at end of file diff --git a/web/client/src/sections/fillion/actions/index.js b/web/client/src/sections/fillion/actions/index.js index 1a7ae700..cde430de 100644 --- a/web/client/src/sections/fillion/actions/index.js +++ b/web/client/src/sections/fillion/actions/index.js @@ -4,10 +4,12 @@ import * as infor from './infor' import * as patrol from './patrol' import * as file from './file' import * as assess from './assess' +import * as allDepUsers from './allDepUsers' export default { ...infor, ...patrol, ...file, ...assess, + ...allDepUsers } \ No newline at end of file diff --git a/web/client/src/sections/fillion/components/maintenanceTable.js b/web/client/src/sections/fillion/components/maintenanceTable.js index a0d29e11..801c2a90 100644 --- a/web/client/src/sections/fillion/components/maintenanceTable.js +++ b/web/client/src/sections/fillion/components/maintenanceTable.js @@ -1,14 +1,17 @@ import { connect } from 'react-redux'; import './protable.less' -import { Card, Button, DatePicker, Input, Modal, Spin, Image, message, Popover } from 'antd'; +import { Card, Button, DatePicker, Input, Modal, Spin, Image, message, Popover, Tree, Tooltip } from 'antd'; +import { DownOutlined, RightOutlined, CaretDownOutlined, CaretRightOutlined } from '@ant-design/icons'; import ProTable from '@ant-design/pro-table'; import { getReportList, getReportDetail } from '../actions/patrol'; -import React, { useEffect, useState } from 'react'; +import React, { useEffect, useState, useMemo } from 'react'; import { httpDel } from '@peace/utils' import { PinyinHelper } from '@peace/utils'; // @ts-ignore import styles from './protable.less'; import moment from 'moment'; +import { getAllDepUsers } from '../actions/allDepUsers' +import { getDepMessage, getDepUser, createUser, updateUser, delUser, resetPwd, createDep, delDep, updateDep } from '../../organization/actions/user' import { reportTypeText } from './patrolTable' const DetailForm = (props) => { @@ -219,9 +222,162 @@ const DetailList = (props) => { const PatrolNameList = (props) => { + const { Search } = Input; const [users, setUsers] = useState([]); - const { onChange, record, userList, loading } = props; + const { onChange, record, userList, loading, depMessage, depUser, clientHeight, dispatch } = props; const [selectRoad, setSelectRoad] = useState(); + const [selectedTree, setSelectedTree] = useState(); + const [depSelectedKeys, setDepSelectedKeys] = useState([]) + const [depAllUser, setDepAllUser] = useState([]) + const [depMessagedata, setdepMessagedata] = useState(depMessage) + const [expandedKeys, setExpandedKeys] = useState([]); + const [searchValue, setSearchValue] = useState(''); + const [autoExpandParent, setAutoExpandParent] = useState(true); + //const [departments, setDepartments] = useState([]) + + // useEffect(() => { + // if (depAllUser && depAllUser.length > 0) { + // depAllUser.map((item) => { + // item.expanded = false + // departments.push(item) + // }) + // } + // console.log('departments1', departments) + // }, [depAllUser]) + const departments = [ + { + id: 1, + name: '部门A', + users: [{ id: 1, name: '癌病' }, { id: 2, name: 'zjah' }], + expanded: true, // 初始状态展开 + }, + { + id: 2, + name: '部门B', + users: [{ id: 3, name: '癌病' }, { id: 4, name: 'zjah' }], + expanded: false, // 初始状态折叠 + }, + ]; + const defaultData = []; + const generateData = (data, _preKey, _tns) => { + const preKey = _preKey || '0'; + const tns = _tns || defaultData; + const children = []; + data.forEach(department => { + const key = `${preKey}-${department.id}`; + const node = { + title: department.name, + key, + children: [], + }; + console.log('lenght', department) + if (department.users.length > 0) { // 仅当部门有用户时添加子节点 + department.users.forEach(user => { + node.children.push({ + title: user.name, + key: `${key}-${user.id}`, + isLeaf: true, // 用户节点为叶子节点 + }); + }); + } + + if (department.children && department.children.length > 0) { + node.children = generateData(department.children, key, node.children); + } + + tns.push(node); + if (node.children.length > 0 && department.expanded) { // 仅当部门展开时添加子节点 + children.push(key); + } + }); + + return children; + }; + console.log(depAllUser, 'sssllg') + generateData(depAllUser); + + const dataList = []; + const generateList = (data) => { + for (let i = 0; i < data.length; i++) { + const item = data[i]; + const { key, title } = item; + dataList.push({ + key, + title, + }); + if (item.children && item.children.length > 0) { + generateList(item.children); + } + } + }; + generateList(defaultData); + + const getParentKey = (key, tree) => { + let parentKey; + for (let i = 0; i < tree.length; i++) { + const node = tree[i]; + if (node.children) { + if (node.children.some((item) => item.key === key)) { + parentKey = node.key; + } else if (getParentKey(key, node.children)) { + parentKey = getParentKey(key, node.children); + } + } + } + return parentKey; + }; + + const handleSearch = (value) => { + const expandedKeys = dataList + .map((item) => { + if (item.title.indexOf(value) > -1) { + return getParentKey(item.key, defaultData); + } + return null; + }) + .filter((item, i, self) => item && self.indexOf(item) === i); + + setSearchValue(value); + setExpandedKeys(expandedKeys); + }; + + const handleExpand = (expandedKeys) => { + setExpandedKeys(expandedKeys); + }; + const treeData = useMemo(() => { + const loop = (data) => + data.map((item) => { + const { title, key, children } = item; + const strTitle = title.toString(); + const index = strTitle.indexOf(searchValue); + const beforeStr = strTitle.substring(0, index); + const afterStr = strTitle.slice(index + searchValue.length); + const titleNode = index > -1 ? ( + + {beforeStr} + {searchValue} + {afterStr} + + ) : ( + {strTitle} + ); + + if (children && children.length > 0) { + return { + title: titleNode, + key, + children: loop(children), + }; + } + + return { + title: titleNode, + key, + }; + }); + + return loop(defaultData); + }, [searchValue]); useEffect(() => { if (userList && userList instanceof Array && userList.length) { @@ -229,67 +385,32 @@ const PatrolNameList = (props) => { // onChange(userList[0]); } }, [userList]) - const columns = [ - { - title: '养护人员', - key: 'name', - dataIndex: 'name', - align: 'center' - }, - - ]; - + useEffect(() => { + dispatch(getAllDepUsers()).then((res) => { + if (res.success) setDepAllUser(res?.payload?.data) + }) + }, []) useEffect(() => { if (userList && userList instanceof Array) { let users = userList.filter(user => user.remark != 'sp'); setUsers(users); } }, [userList]) - - var timer = null; - const doUserNameSearch = (e) => { - const name = e.target.value; - if (timer) { - clearTimeout(timer) - } else { - setTimeout(() => { - let users = userList.filter(user => PinyinHelper.isSearchMatched(user.name, name) && user.remark != 'sp'); - setUsers(users); - }, 500); - } + if (loading) { + return
Loading...
} - return (
- { - return record.id == selectRoad ? 'list-row-actived' : ''; - }} - toolBarRender={() => [ - - ]} - options={false} - pagination={false} - search={false} - onRow={(record) => { - return { - onClick: () => { - if (record) { - let id = record.id - if (selectRoad == record.id) { - id = null - } - setSelectRoad(id); - onChange(id ? record : null); - } - }, - }; - }} - />
+ handleSearch(e.target.value)} + /> + {depAllUser.length > 0 && depAllUser && ( + + + )} + ); }; @@ -297,7 +418,7 @@ const PatrolNameList = (props) => { const MaintenanceTable = (props) => { - const { userList, user, reportList, dispatch, reportListLoading, reportDetail, reportDetailLoading, userLoading, exports } = props; + const { userList, user, reportList, dispatch, reportListLoading, reportDetail, reportDetailLoading, userLoading, exports, depMessage, depUser, clientHeight } = props; const [record, setRecord] = useState(); const [dateRange, setDateRange] = useState(); const [detailVisible, setDetailVisible] = useState(false) @@ -360,7 +481,9 @@ const MaintenanceTable = (props) => { return (
- setRecord(record)} record={record} userList={userList} loading={userLoading} handelRefresh={handelRefresh} /> + setRecord(record)} record={record} userList={userList} loading={userLoading} handelRefresh={handelRefresh} />
@@ -386,8 +509,8 @@ const MaintenanceTable = (props) => { ); }; -function mapStateToProps (state) { - const { auth, depMessage, userList, reportList, reportDetail } = state; +function mapStateToProps(state) { + const { auth, depMessage, userList, reportList, reportDetail, depUser, global } = state; const pakData = (dep) => { return dep.map((d) => { return { @@ -399,6 +522,7 @@ function mapStateToProps (state) { } let depData = pakData(depMessage.data || []) return { + clientHeight: global.clientHeight, user: auth.user, depMessage: depMessage.data || [], depLoading: depMessage.isRequesting, @@ -409,6 +533,8 @@ function mapStateToProps (state) { reportListLoading: reportList.isRequesting, reportDetail: reportDetail.data, reportDetailLoading: reportDetail.isRequesting, + depUser: depUser.data || [], + }; } export default connect(mapStateToProps)(MaintenanceTable); \ No newline at end of file diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js index c436c43c..580f4f23 100644 --- a/web/client/src/utils/webapi.js +++ b/web/client/src/utils/webapi.js @@ -293,7 +293,9 @@ export const ApiTable = { //养护费用 getMaintenance: '/road/maintenance/cost/nanchang/query', //任务信息 - getTask: 'task', delTask: 'task/{taskId}', editTask: 'task' + getTask: 'task', delTask: 'task/{taskId}', editTask: 'task', + //部门下所有员工 + getAllDepUsers: 'allDepUsers' }; diff --git a/web/package.json b/web/package.json index 398df73a..a9ec44d9 100644 --- a/web/package.json +++ b/web/package.json @@ -6,7 +6,11 @@ "scripts": { "test": "mocha", "start": "cross-env NODE_ENV=development npm run start-params", +<<<<<<< Updated upstream "start-params": "node server -p 5000 -u http://localhost:13400 --qndmn http://rfkimpwbb.hn-bkt.clouddn.com --vcmpWebUrl https://mediaconsole.ngaiot.com --vcmpMirrorId 24461524032354", +======= + "start-params": "node server -p 5000 -u http://localhost:13401 --qndmn http://rfkimpwbb.hn-bkt.clouddn.com", +>>>>>>> Stashed changes "deploy": "export NODE_ENV=production&&npm run color && npm run build && node server", "build-dev": "export NODE_ENV=development&&webpack --config webpack.config.js", "build": "export NODE_ENV=production&&webpack --config webpack.config.prod.js", @@ -95,4 +99,4 @@ "webpack-dev-server": "^3.11.2", "xlsx": "^0.16.9" } -} +} \ No newline at end of file