liujiangyong
2 years ago
9 changed files with 495 additions and 98 deletions
@ -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, |
||||
|
} |
@ -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; |
||||
|
}; |
@ -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); |
||||
|
}; |
@ -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 = ( |
||||
|
<Select defaultValue="次/天" onChange={value => setUnit(value)}> |
||||
|
<Option value="次/天">次/天</Option> |
||||
|
<Option value="次/周">次/周</Option> |
||||
|
<Option value="次/月">次/月</Option> |
||||
|
</Select> |
||||
|
); |
||||
|
return ( |
||||
|
<Modal |
||||
|
visible={visible} |
||||
|
title="新增巡检计划" |
||||
|
okText="确定" |
||||
|
cancelText="取消" |
||||
|
onCancel={() => { |
||||
|
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); |
||||
|
}); |
||||
|
}} |
||||
|
> |
||||
|
<Form |
||||
|
form={form} |
||||
|
layout="vertical" |
||||
|
name="form_in_modal" |
||||
|
initialValues={{ |
||||
|
modifier: 'public', |
||||
|
}} |
||||
|
> |
||||
|
<Form.Item |
||||
|
name="structureId" |
||||
|
label="结构物名称" |
||||
|
rules={[ |
||||
|
{ required: true, message: '请选择结构物' }, |
||||
|
]} |
||||
|
> |
||||
|
<Select options={struOpt} loading={struLoading} onChange={(value) => { |
||||
|
dispatch(positionList({ projectId: value })).then(res => { |
||||
|
if (res.success) { |
||||
|
setPointOpt(res.payload.data?.rows[0]?.points?.map(p => ({ label: p.name, value: p.id }))) |
||||
|
} |
||||
|
}) |
||||
|
}} /> |
||||
|
</Form.Item> |
||||
|
<Form.Item |
||||
|
name="name" |
||||
|
label="巡检任务名称" |
||||
|
rules={[ |
||||
|
{ required: true, message: '请输入巡检任务名称' }, |
||||
|
]} |
||||
|
> |
||||
|
<Input /> |
||||
|
</Form.Item> |
||||
|
<Form.Item |
||||
|
name="way" |
||||
|
label="巡检方式" |
||||
|
rules={[ |
||||
|
{ required: true, message: '请选择巡检方式' }, |
||||
|
]} |
||||
|
initialValue='周期巡检' |
||||
|
> |
||||
|
<Select options={[{ |
||||
|
label: '周期巡检', |
||||
|
value: '周期巡检' |
||||
|
}]} disabled /> |
||||
|
</Form.Item> |
||||
|
<Form.Item |
||||
|
name="frequency" |
||||
|
label="巡检频次" |
||||
|
rules={[ |
||||
|
{ required: true, message: '请选择巡检频次' }, |
||||
|
]} |
||||
|
> |
||||
|
<Input addonAfter={selectAfter} /> |
||||
|
</Form.Item> |
||||
|
<Form.Item |
||||
|
name="time" |
||||
|
label="任务周期" |
||||
|
rules={[ |
||||
|
{ required: true, message: '请选择任务周期' }, |
||||
|
]} |
||||
|
> |
||||
|
<RangePicker /> |
||||
|
</Form.Item> |
||||
|
<Form.Item |
||||
|
name="points" |
||||
|
label="巡检点" |
||||
|
rules={[ |
||||
|
{ required: true, message: '请选择巡检点' }, |
||||
|
]} |
||||
|
> |
||||
|
<Select options={pointOpt} disabled={!pointOpt} /> |
||||
|
</Form.Item> |
||||
|
<Form.Item |
||||
|
name="userId" |
||||
|
label="巡检人员" |
||||
|
rules={[ |
||||
|
{ required: true, message: '请选择巡检人员' }, |
||||
|
]} |
||||
|
> |
||||
|
<Select options={userOpt} loading={userLoading} onChange={(value) => { |
||||
|
const curUser = userList.filter(u => u.id == value) |
||||
|
if (curUser.length) { |
||||
|
form.setFieldsValue({ |
||||
|
userDept: curUser[0].department.name |
||||
|
}); |
||||
|
} |
||||
|
}} /> |
||||
|
</Form.Item> |
||||
|
<Form.Item |
||||
|
name="userDept" |
||||
|
label="巡检单位" |
||||
|
> |
||||
|
<Input disabled /> |
||||
|
</Form.Item> |
||||
|
</Form> |
||||
|
</Modal> |
||||
|
); |
||||
|
}; |
||||
|
|
||||
|
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); |
@ -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 ( |
|
||||
<Modal |
|
||||
visible={visible} |
|
||||
title="新建用户" |
|
||||
okText="新建" |
|
||||
cancelText="取消" |
|
||||
onCancel={() => { |
|
||||
form.resetFields(); |
|
||||
onCancel(); |
|
||||
}} |
|
||||
onOk={() => { |
|
||||
form |
|
||||
.validateFields() |
|
||||
.then((values) => { |
|
||||
form.resetFields(); |
|
||||
onCreate(values); |
|
||||
}) |
|
||||
.catch((info) => { |
|
||||
console.log('Validate Failed:', info); |
|
||||
}); |
|
||||
}} |
|
||||
> |
|
||||
<Form |
|
||||
form={form} |
|
||||
layout="vertical" |
|
||||
name="form_in_modal" |
|
||||
initialValues={{ |
|
||||
modifier: 'public', |
|
||||
}} |
|
||||
> |
|
||||
<Form.Item |
|
||||
name="name" |
|
||||
label="姓名" |
|
||||
rules={[ |
|
||||
{ required: true, message: '请输入姓名' }, |
|
||||
{ max: 24, message: '姓名不能大于24个字符' }, |
|
||||
]} |
|
||||
> |
|
||||
<Input /> |
|
||||
</Form.Item> |
|
||||
<Form.Item |
|
||||
name="phone" |
|
||||
label="用户名(手机号)" |
|
||||
rules={[ |
|
||||
{ required: true, message: '请输入正确的手机号' }, |
|
||||
{ pattern: reg_tel, message: '请输入正确的手机号' }, |
|
||||
]} |
|
||||
> |
|
||||
<Input /> |
|
||||
</Form.Item> |
|
||||
<Form.Item |
|
||||
name="password" |
|
||||
label="密码" |
|
||||
rules={[ |
|
||||
{ required: true, message: '请填写密码' }, |
|
||||
{ min: 6, message: '请填写至少6位密码' }, |
|
||||
]} |
|
||||
> |
|
||||
<Input type="password" /> |
|
||||
</Form.Item> |
|
||||
</Form> |
|
||||
</Modal> |
|
||||
); |
|
||||
}; |
|
||||
|
|
||||
export default UserModal; |
|
Loading…
Reference in new issue