diff --git a/api/app/lib/controllers/organization/user.js b/api/app/lib/controllers/organization/user.js
index aa7e2e9..8aaf88b 100644
--- a/api/app/lib/controllers/organization/user.js
+++ b/api/app/lib/controllers/organization/user.js
@@ -170,15 +170,31 @@ async function delDept(ctx, next) {
async function getUser(ctx, next) {
try {
const models = ctx.fs.dc.models;
- const { depId } = ctx.params
- const userRes = await models.User.findAll({
- where: {
- departmentId: parseInt(depId),
- delete: false
- },
- attributes: { exclude: ['password'] },
- order: [['id', 'asc']],
- })
+ const { depId } = ctx.params;
+ let userRes = null;
+ if (depId !== 'null') {
+ userRes = await models.User.findAll({
+ where: {
+ departmentId: parseInt(depId),
+ delete: false
+ },
+ attributes: { exclude: ['password'] },
+ order: [['id', 'asc']],
+ })
+ } else {
+ userRes = await models.User.findAll({
+ where: {
+ delete: false
+ },
+ attributes: { exclude: ['password'] },
+ order: [['id', 'asc']],
+ include: [{
+ required: true,
+ model: models.Department,
+ attributes: ['id', 'name'],
+ }]
+ })
+ }
ctx.status = 200;
ctx.body = userRes
diff --git a/api/app/lib/controllers/patrolPlan/patrolPlan.js b/api/app/lib/controllers/patrolPlan/patrolPlan.js
new file mode 100644
index 0000000..6de5a45
--- /dev/null
+++ b/api/app/lib/controllers/patrolPlan/patrolPlan.js
@@ -0,0 +1,113 @@
+'use strict';
+
+async function getPatrolPlan(ctx, next) {
+ try {
+ const models = ctx.fs.dc.models;
+ const { limit, page } = ctx.query;
+ let options = {
+ include: [{
+ required: true,
+ model: models.User,
+ attributes: ['id', 'name'],
+ include: [{
+ required: true,
+ model: models.Department,
+ attributes: ['id', 'name'],
+ }]
+ }, {
+ required: true,
+ model: models.Project,
+ attributes: ['id', 'name'],
+ }]
+ };
+ if (limit) {
+ options.limit = Number(limit);
+ }
+ if (page && limit) {
+ options.offset = Number(page) * Number(limit);
+ }
+ let res = await models.PatrolPlan.findAndCountAll(options);
+ ctx.status = 200;
+ ctx.body = res;
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = {
+ "message": "获取巡检计划失败"
+ }
+ }
+}
+
+async function createPatrolPlan(ctx, next) {
+ try {
+ const models = ctx.fs.dc.models;
+ const data = ctx.request.body;
+ const { name, way, structureId, startTime, endTime, frequency, points, userId } = data;
+
+ let plan = { name, way, structureId, startTime, endTime, frequency, points, userId };
+
+ await models.PatrolPlan.create(plan);
+
+ ctx.status = 204;
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = {
+ "message": '新增巡检计划失败'
+ }
+ }
+}
+
+async function updatePatrolPlan(ctx, next) {
+ try {
+ let errMsg = '修改巡检计划失败';
+ const models = ctx.fs.dc.models;
+ const data = ctx.request.body;
+ const { name, startTime, endTime, frequency, patrolPerson } = data;
+
+ let plan = { name, startTime, endTime, frequency, patrolPerson };
+
+ if (data && data.id) {
+ await models.PatrolPlan.update(plan, {
+ where: { id: data.id }
+ })
+ } else {
+ errMsg = '请传入巡检计划id';
+ throw errMsg;
+ }
+
+ ctx.status = 204;
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = {
+ "message": errMsg
+ }
+ }
+}
+
+async function delPatrolPlan(ctx, next) {
+ try {
+ const models = ctx.fs.dc.models;
+ const { id } = ctx.params;
+
+ await models.PatrolPlan.destroy({
+ where: { id }
+ })
+
+ ctx.status = 204;
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = {
+ "message": '删除巡检计划失败'
+ }
+ }
+}
+
+module.exports = {
+ getPatrolPlan,
+ createPatrolPlan,
+ updatePatrolPlan,
+ delPatrolPlan,
+}
\ No newline at end of file
diff --git a/api/app/lib/index.js b/api/app/lib/index.js
index 2cc3d93..5cb7374 100644
--- a/api/app/lib/index.js
+++ b/api/app/lib/index.js
@@ -53,8 +53,7 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq
require(`./models/${filename}`)(dc)
});
- const { Camera, Company, Department, Post, RoleGroup, Role, RoleResource, User, UserDepartment, UserPost, Site, ProjectDisclosure, ProjectDisclosureFiles, Coordinate, ProblemReport, ProblemReportFile, Worker, WorkerAttendance,
- RiskReport, Metting, HideDangerRectify, HideDangerRectifySites, HideDangerDispose, UserResource, Resource, Project, Point
+ const { Department, User, UserResource, Resource, Project, Point, PatrolPlan
} = dc.models;
UserResource.belongsTo(User, { foreignKey: 'userId', targetKey: 'id' });
@@ -69,4 +68,10 @@ module.exports.models = function (dc) { // dc = { orm: Sequelize对象, ORM: Seq
Point.belongsTo(Project, { foreignKey: 'projectId', targetKey: 'id' });
Project.hasMany(Point, { foreignKey: 'projectId', sourceKey: 'id' });
+
+ PatrolPlan.belongsTo(Project, { foreignKey: 'structureId', targetKey: 'id' });
+ Project.hasMany(PatrolPlan, { foreignKey: 'structureId', sourceKey: 'id' });
+
+ PatrolPlan.belongsTo(User, { foreignKey: 'userId', targetKey: 'id' });
+ User.hasMany(PatrolPlan, { foreignKey: 'userId', sourceKey: 'id' });
};
diff --git a/api/app/lib/models/patrol_plan.js b/api/app/lib/models/patrol_plan.js
new file mode 100644
index 0000000..91e5ddd
--- /dev/null
+++ b/api/app/lib/models/patrol_plan.js
@@ -0,0 +1,105 @@
+/* eslint-disable*/
+'use strict';
+
+module.exports = dc => {
+ const DataTypes = dc.ORM;
+ const sequelize = dc.orm;
+ const PatrolPlan = sequelize.define("PatrolPlan", {
+ id: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: true,
+ field: "id",
+ autoIncrement: true,
+ unique: "patrol_plan_id_uindex"
+ },
+ name: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "name",
+ autoIncrement: false
+ },
+ way: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "way",
+ autoIncrement: false
+ },
+ structureId: {
+ type: DataTypes.INTEGER,
+ allowNull: true,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "structure_id",
+ autoIncrement: false
+ },
+ startTime: {
+ type: DataTypes.DATE,
+ allowNull: true,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "start_time",
+ autoIncrement: false
+ },
+ endTime: {
+ type: DataTypes.DATE,
+ allowNull: true,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "end_time",
+ autoIncrement: false
+ },
+ frequency: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "frequency",
+ autoIncrement: false
+ },
+ points: {
+ type: DataTypes.JSONB,
+ allowNull: true,
+ defaultValue: null,
+ comment: null,
+ primaryKey: false,
+ field: "points",
+ autoIncrement: false
+ },
+ userId: {
+ type: DataTypes.INTEGER,
+ allowNull: true,
+ comment: null,
+ primaryKey: false,
+ field: "user_id",
+ autoIncrement: false,
+ },
+ patrolCount: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: 0,
+ comment: null,
+ primaryKey: false,
+ field: "patrol_count",
+ autoIncrement: false
+ },
+ }, {
+ tableName: "patrol_plan",
+ comment: "",
+ indexes: []
+ });
+ dc.models.PatrolPlan = PatrolPlan;
+ return PatrolPlan;
+};
\ No newline at end of file
diff --git a/api/app/lib/routes/patrolPlan/patrolPlan.js b/api/app/lib/routes/patrolPlan/patrolPlan.js
new file mode 100644
index 0000000..5f0e455
--- /dev/null
+++ b/api/app/lib/routes/patrolPlan/patrolPlan.js
@@ -0,0 +1,17 @@
+'use strict';
+
+const patrolPlan = require('../../controllers/patrolPlan/patrolPlan');
+
+module.exports = function (app, router, opts) {
+ app.fs.api.logAttr['GET/patrolPlan'] = { content: '获取巡检计划', visible: false };
+ router.get('/patrolPlan', patrolPlan.getPatrolPlan);
+
+ app.fs.api.logAttr['POST/patrolPlan'] = { content: '新增巡检计划', visible: true };
+ router.post('/patrolPlan', patrolPlan.createPatrolPlan);
+
+ app.fs.api.logAttr['PUT/patrolPlan'] = { content: '修改巡检计划', visible: true };
+ router.put('/patrolPlan', patrolPlan.updatePatrolPlan);
+
+ app.fs.api.logAttr['DELETE/patrolPlan/:id'] = { content: '删除巡检计划', visible: true };
+ router.del('/patrolPlan/:id', patrolPlan.delPatrolPlan);
+};
\ No newline at end of file
diff --git a/web/client/src/sections/patrolManage/actions/plan.js b/web/client/src/sections/patrolManage/actions/plan.js
index cf3d5f8..6b94bca 100644
--- a/web/client/src/sections/patrolManage/actions/plan.js
+++ b/web/client/src/sections/patrolManage/actions/plan.js
@@ -43,4 +43,38 @@ export function updatePatrolPlan(data) {
url: ApiTable.patrolPlan,
msg: { error: '修改巡检计划失败' },
});
+}
+
+export function getUserList() {
+ return dispatch => basicAction({
+ type: 'get',
+ dispatch: dispatch,
+ actionType: 'GET_USER_LIST',
+ url: ApiTable.getDepUser.replace('{depId}', null),
+ msg: { error: '获取人员列表失败' },
+ reducer: { name: 'userList' }
+ });
+}
+
+export function getProjectList(query) {
+ return (dispatch) => basicAction({
+ type: 'get',
+ query,
+ dispatch,
+ actionType: 'GET_PROJEECT_LIST',
+ url: ApiTable.getProjectList,
+ msg: { error: '获取结构物列表失败', },
+ reducer: { name: 'structureList' }
+ });
+}
+
+export function positionList(query) {
+ return (dispatch) => basicAction({
+ type: 'get',
+ query,
+ dispatch,
+ actionType: 'POSITION_LIST',
+ url: ApiTable.position,
+ msg: { error: '获取点位列表失败', },
+ });
}
\ No newline at end of file
diff --git a/web/client/src/sections/patrolManage/components/planModal.js b/web/client/src/sections/patrolManage/components/planModal.js
new file mode 100644
index 0000000..6cf9e39
--- /dev/null
+++ b/web/client/src/sections/patrolManage/components/planModal.js
@@ -0,0 +1,177 @@
+import { Button, Form, Input, Modal, Select, DatePicker } from 'antd';
+import React, { useState, useEffect } from 'react';
+import { connect } from 'react-redux';
+import { getUserList, getProjectList, positionList } from '../actions/plan';
+
+const { RangePicker } = DatePicker;
+
+const PlanModal = ({ visible, onCreate, onCancel, dispatch, userLoading, userList, structureList, struLoading }) => {
+ const [userOpt, setUserOpt] = useState();
+ const [struOpt, setStruOpt] = useState();
+ const [pointOpt, setPointOpt] = useState();
+ const [unit, setUnit] = useState('次/天');
+ const [form] = Form.useForm();
+
+ useEffect(() => {
+ dispatch(getUserList())
+ dispatch(getProjectList())
+ }, [])
+
+ useEffect(() => {
+ if (userList.length) {
+ setUserOpt(userList.map(u => ({ label: u.name, value: u.id })))
+ }
+ }, [userList])
+
+ useEffect(() => {
+ if (structureList?.rows?.length) {
+ setStruOpt(structureList?.rows?.map(s => ({ label: s.name, value: s.id })))
+ }
+ }, [structureList])
+
+ const selectAfter = (
+
+ );
+ return (
+ {
+ form.resetFields();
+ onCancel();
+ }}
+ onOk={() => {
+ form
+ .validateFields()
+ .then((values) => {
+ form.resetFields();
+ const params = {
+ frequency: values.frequency + unit,
+ startTime: values.time[0],
+ endTime: values.time[1],
+ points: pointOpt.filter(p => p.id == values.points),
+ ...values
+ }
+ onCreate(params);
+ })
+ .catch((info) => {
+ console.log('Validate Failed:', info);
+ });
+ }}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+function mapStateToProps(state) {
+ const { auth, userList, structureList } = state
+ return {
+ user: auth.user,
+ userList: userList.data || [],
+ structureList: structureList.data || [],
+ userLoading: userList.isRequesting,
+ struLoading: structureList.isRequesting
+ }
+}
+export default connect(mapStateToProps)(PlanModal);
\ No newline at end of file
diff --git a/web/client/src/sections/patrolManage/components/userModal.js b/web/client/src/sections/patrolManage/components/userModal.js
deleted file mode 100644
index f527e73..0000000
--- a/web/client/src/sections/patrolManage/components/userModal.js
+++ /dev/null
@@ -1,72 +0,0 @@
-import { Button, Form, Input, Modal } from 'antd';
-import React, { useState } from 'react';
-
-const UserModal = ({ visible, onCreate, onCancel }) => {
- const [form] = Form.useForm();
- const reg_tel = /^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/;
- return (
- {
- form.resetFields();
- onCancel();
- }}
- onOk={() => {
- form
- .validateFields()
- .then((values) => {
- form.resetFields();
- onCreate(values);
- })
- .catch((info) => {
- console.log('Validate Failed:', info);
- });
- }}
- >
-
-
-
-
-
-
-
-
-
-
-
- );
-};
-
-export default UserModal;
\ No newline at end of file
diff --git a/web/client/src/sections/patrolManage/containers/patrolPlan.js b/web/client/src/sections/patrolManage/containers/patrolPlan.js
index 2c20320..45e5805 100644
--- a/web/client/src/sections/patrolManage/containers/patrolPlan.js
+++ b/web/client/src/sections/patrolManage/containers/patrolPlan.js
@@ -2,7 +2,7 @@ import React, { useState, useRef } from 'react';
import { connect } from 'react-redux';
import { Button, Popconfirm } from 'antd';
import ProTable from '@ant-design/pro-table';
-import UserModal from '../components/userModal';
+import PlanModal from '../components/planModal';
import { createPatrolPlan, delPatrolPlan, updatePatrolPlan, getPatrolPlan } from '../actions/plan';
function PatrolPlan(props) {
@@ -13,12 +13,12 @@ function PatrolPlan(props) {
const onCreate = (values) => {
console.log(values, 'values')
- // dispatch(createEarthquakeUser(values)).then(res => {
- // if (res.success) {
- // tableRef.current.reload();
- // }
- // })
- // setVisible(false);
+ dispatch(createPatrolPlan(values)).then(res => {
+ if (res.success) {
+ tableRef.current.reload();
+ }
+ })
+ setVisible(false);
};
const columns = [{
@@ -98,7 +98,6 @@ function PatrolPlan(props) {
search={false}
request={async (params = {}) => {
const res = await dispatch(getPatrolPlan(params));
- console.log(res, 'res')
setDataSource(res?.payload.data?.rows);
return { ...res };
}}
@@ -111,13 +110,16 @@ function PatrolPlan(props) {
>新增巡检计划
]}
/>
- {
- setVisible(false);
- }}
- />
+ {
+ visible ?
+ {
+ setVisible(false);
+ }}
+ /> : null
+ }
>
)
}