Browse Source

考核评分模块

dev
巴林闲侠 2 years ago
parent
commit
8753881f65
  1. 25
      api/app/lib/controllers/data/assess.js
  2. 40
      scripts/1.2.3/schema/1.create_assess.sql
  3. 2
      web/client/src/sections/fillion/actions/assess.js
  4. 108
      web/client/src/sections/fillion/components/assessModal.js
  5. 155
      web/client/src/sections/fillion/containers/assess.js
  6. 3
      web/client/src/sections/fillion/containers/index.js
  7. 6
      web/client/src/sections/fillion/nav-item.js
  8. 12
      web/client/src/sections/fillion/routes.js
  9. 2
      web/client/src/utils/webapi.js

25
api/app/lib/controllers/data/assess.js

@ -4,7 +4,7 @@ const moment = require('moment')
async function assessGet (ctx) { async function assessGet (ctx) {
try { try {
const models = ctx.fs.dc.models; const models = ctx.fs.dc.models;
const { unit, month } = ctx.query; const { unit, month, page, limit } = ctx.query;
let findOption = { let findOption = {
where: { where: {
@ -21,7 +21,14 @@ async function assessGet (ctx) {
findOption.where.unit = unit findOption.where.unit = unit
} }
const roadRes = await models.Assess.findAll(findOption) if (limit) {
findOption.limit = limit
}
if (page && limit) {
findOption.offset = (page - 1) * limit
}
const roadRes = await models.Assess.findAndCountAll(findOption)
ctx.status = 200; ctx.status = 200;
ctx.body = roadRes ctx.body = roadRes
@ -39,9 +46,23 @@ async function assessEdit (ctx) {
const models = ctx.fs.dc.models; const models = ctx.fs.dc.models;
const data = ctx.request.body; const data = ctx.request.body;
const repeatRes = await models.Assess.findOne({
where: {
unit: data.unit,
month: { $between: [moment(data.month).startOf('month').format(), moment(data.month).endOf('month').format()] }
}
})
if (!data.assessId) { if (!data.assessId) {
if (repeatRes) {
throw '已有相同月份的考核记录'
}
await models.Assess.create(data) await models.Assess.create(data)
} else { } else {
if (repeatRes && repeatRes.id != data.assessId) {
throw '已有相同月份的考核记录'
}
await models.Assess.update( await models.Assess.update(
data, { data, {
where: { where: {

40
scripts/1.2.3/schema/1.create_assess.sql

@ -0,0 +1,40 @@
create table if not exists assess
(
id serial not null
constraint assess_pk
primary key,
unit varchar(64),
month timestamp with time zone,
total_points double precision,
industry_points double precision,
industry_out_points double precision,
plus_or_subtract double precision,
"industry_deduction_reason " varchar(1024),
industry_out_deduction_reason varchar(1024),
remark varchar(1024)
);
comment on table assess is '考核评分';
comment on column assess.unit is '考核单位';
comment on column assess.month is '考核月份';
comment on column assess.total_points is '总分';
comment on column assess.industry_points is '业内得分';
comment on column assess.industry_out_points is '业外得分';
comment on column assess.plus_or_subtract is '加减得分';
comment on column assess."industry_deduction_reason " is '业内扣分原因
';
comment on column assess.industry_out_deduction_reason is '业外扣分原因';
comment on column assess.remark is '备注';
create unique index if not exists assess_id_uindex
on assess (id);

2
web/client/src/sections/fillion/actions/assess.js

@ -30,6 +30,6 @@ export function editAssess (query) {
data: query, data: query,
actionType: 'PUT_ASSESS', actionType: 'PUT_ASSESS',
url: ApiTable.editAssess, url: ApiTable.editAssess,
msg: { option: '编辑新增考核评分信息' }, msg: { option: '编辑/新增考核评分信息' },
}); });
} }

108
web/client/src/sections/fillion/components/assessModal.js

@ -0,0 +1,108 @@
import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux';
import { Form, Input, Select, DatePicker, InputNumber, Button, Modal } from 'antd';
import { unitList } from '../containers/assess'
import { getAssess, delAssess, editAssess } from '../actions/assess';
import moment from 'moment';
const { Option } = Select;
const AssessModal = ({ editData, check, visible, onCancel, dispatch }) => {
const [form] = Form.useForm();
return (
<Modal
title="考核评分"
open={visible}
visible={visible}
cancelButtonProps={{
disabled: check,
}}
onOk={() => {
if (check) {
return onCancel()
}
form.validateFields().then(values => {
dispatch(editAssess({
...values,
month: moment(values.month).format('YYYY-MM-DD'),
assessId: editData ? editData.id : undefined
})).then(res => {
if (res.success) {
onCancel()
}
})
})
}}
onCancel={() => {
onCancel()
}}
>
<Form
form={form}
initialValues={editData ? {
...editData,
month: moment(editData.month),
} : {}}
disabled={check}
labelCol={{
span: 6,
}}
wrapperCol={{
span: 18,
}}
>
<Form.Item name="unit" label="管养责任单位" rules={[{ required: true, message: '请填写' }]}>
<Select>
{
unitList.map(item => (
<Option value={item} key={item} />
))
}
</Select>
</Form.Item>
<Form.Item name="month" label="考核月份" rules={[{ required: true, message: '请填写' }]}>
<DatePicker picker="month" />
</Form.Item>
<Form.Item name="totalPoints" label="考核总分" rules={[{ required: true, message: '请填写' }]}>
<InputNumber step={0.1} precision={1} />
</Form.Item>
<Form.Item name="industryPoints" label="内业得分">
<InputNumber step={0.1} precision={1} />
</Form.Item>
<Form.Item name="industryOutPoints" label="外业得分">
<InputNumber step={0.1} precision={1} />
</Form.Item>
<Form.Item name="plusOrSubtract" label="加减分">
<InputNumber step={0.1} precision={1} />
</Form.Item>
<Form.Item name="industryDeductionReason" label="内业扣分原因">
<Input.TextArea rows={4} maxLength={1024} />
</Form.Item>
<Form.Item name="industryOutDeductionReason" label="外业扣分原因">
<Input.TextArea rows={4} maxLength={1024} />
</Form.Item>
<Form.Item name="remark" label="备注">
<Input.TextArea rows={4} maxLength={1024} />
</Form.Item>
</Form>
</Modal>
);
};
function mapStateToProps (state) {
const { auth, assess } = state
return {
user: auth.user,
assess: assess.data || []
}
}
export default connect(mapStateToProps)(AssessModal);

155
web/client/src/sections/fillion/containers/assess.js

@ -1,24 +1,167 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { getAssess, delAssess, editAssess } from '../actions/assess';
import ProTable from '@ant-design/pro-table';
import AssessModal from '../components/assessModal';
import { Form, Space, DatePicker, Button, Select, Popconfirm } from 'antd'
import moment from 'moment';
function Assess () { export const unitList = [
'县道',
'蒋巷镇',
'三江镇',
'塔城乡',
'泾口乡',
'八一乡',
'冈上镇',
'南新乡',
'富山乡',
'莲塘镇',
'金湖管理处',
'武阳镇',
'向塘镇',
'幽兰镇',
'广福镇',
'塘南镇',
'银三角管委会',
'黄马乡',
]
function Assess (props) {
const { dispatch, assess } = props;
const [assessModalVisible, setAssessModalVisible] = useState(false);
const [editData, setEditData] = useState(null);
const [query, setQuery] = useState({ page: 1, pageSize: 10 })
const [loading, setLoading] = useState(false);
const [isCheck, setIsCheck] = useState(false)
useEffect(() => { useEffect(() => {
return () => { };
return () => {
};
}, []); }, []);
useEffect(() => {
getData()
}, [query])
const getData = () => {
setLoading(true)
dispatch(getAssess(query)).then(res => {
setLoading(false)
})
}
return ( return (
<div> <div>
<div style={{ marginBottom: '20px', display: 'flex', justifyContent: 'space-between' }}>
<Form layout="inline" onFinish={(v) => {
setQuery({ ...query, unit: v.unit, month: v.month ? moment(v.month).format() : undefined })
}}>
<Form.Item name="unit" label="责任单位" >
<Select style={{ width: 200 }} placeholder="全部" allowClear>
{
unitList.map(item => (
<Option value={item} key={item} />
))
}
</Select>
</Form.Item>
<Form.Item name="month" label="考核月份">
<DatePicker picker="month" style={{ width: 200 }} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">搜索</Button>
</Form.Item>
</Form>
<Button type="primary" onClick={() => {
setAssessModalVisible(true)
}}>新增</Button>
</div>
<ProTable
columns={[{
title: '责任单位',
dataIndex: 'unit',
key: 'unit',
},
{
title: '考核月份',
dataIndex: 'month',
key: 'month',
render: (text, record) => (
text ? moment(record.month).format('YYYY-MM') : ''
)
},
{
title: '考核得分',
dataIndex: 'totalPoints',
key: 'totalPoints',
},
{
title: '操作',
key: 'action',
render: (text, record) => (
<span>
<Button type="link" onClick={() => {
setAssessModalVisible(true)
setEditData(record)
setIsCheck(true)
}}>详情</Button>
<Button type="link" onClick={() => {
setAssessModalVisible(true)
setEditData(record)
}}>编辑</Button>
<Popconfirm
title="确定删除此条数据吗?"
onConfirm={() => {
setLoading(true)
dispatch(delAssess({ id: record.id })).then(res => {
setLoading(false)
if (res.success) {
getData()
}
})
}}
>
<Button type="link" danger>删除</Button>
</Popconfirm>
</span>
),
},]}
dataSource={assess.rows || []}
loading={loading}
pagination={{
total: assess?.count || 0,
pageSize: 10,
defaultPageSize: 10,
showSizeChanger: false,
onChange: (page, pageSize) => {
setQuery({
...query,
page, limit: pageSize
})
}
}}
rowKey="key"
toolBarRender={false}
search={false}
/>
{
assessModalVisible ? <AssessModal check={isCheck} visible={assessModalVisible} editData={editData} onCancel={() => {
getData()
setIsCheck(false)
setEditData(null)
setAssessModalVisible(false)
}} /> : ''
}
</div> </div>
); );
} }
function mapStateToProps (state) { function mapStateToProps (state) {
const { auth } = state const { auth, assess } = state
return { return {
user: auth.user, user: auth.user,
assess: assess.data || [],
} }
} }
export default connect(mapStateToProps)(Assess); export default connect(mapStateToProps)(Assess);

3
web/client/src/sections/fillion/containers/index.js

@ -14,4 +14,5 @@ import Patrol from './patrol';
import File from './file'; import File from './file';
import Jiekouguanli from './jiekouguanli'; import Jiekouguanli from './jiekouguanli';
import Task from './task' import Task from './task'
export { Infor, transportation, BridgeTable, HigHways, OperaTional, Enforce, Public, Videois, PromoTional, Maintenance, Patrol, File, Jiekouguanli, Task }; import Assess from './assess'
export { Infor, transportation, BridgeTable, HigHways, OperaTional, Enforce, Public, Videois, PromoTional, Maintenance, Patrol, File, Jiekouguanli, Task, Assess };

6
web/client/src/sections/fillion/nav-item.js

@ -3,7 +3,7 @@ import { Link } from 'react-router-dom';
import { Menu } from 'antd'; import { Menu } from 'antd';
import { ReadOutlined } from '@ant-design/icons'; import { ReadOutlined } from '@ant-design/icons';
const SubMenu = Menu.SubMenu; const SubMenu = Menu.SubMenu;
export function getNavItem(user, dispatch) { export function getNavItem (user, dispatch) {
const isshow = user?.userResources?. const isshow = user?.userResources?.
filter(i => i.resourceId === 'OVERLOADMANAGE' || filter(i => i.resourceId === 'OVERLOADMANAGE' ||
i.resourceId === 'ROADMANAGE' || i.resourceId === 'ROADMANAGE' ||
@ -84,6 +84,10 @@ export function getNavItem(user, dispatch) {
<Menu.Item key="fillionpatrolroad"> <Menu.Item key="fillionpatrolroad">
<Link to="/fillion/patrol_road">建设上报</Link> <Link to="/fillion/patrol_road">建设上报</Link>
</Menu.Item> : ''} </Menu.Item> : ''}
<Menu.Item key="fillionassess">
<Link to="/fillion/assess">考核评分</Link>
</Menu.Item>
</SubMenu> : null </SubMenu> : null
); );
} }

12
web/client/src/sections/fillion/routes.js

@ -12,7 +12,8 @@ import { Maintenance } from './containers'
import { Patrol } from './containers' import { Patrol } from './containers'
import { File } from './containers'; import { File } from './containers';
import { Jiekouguanli } from './containers' import { Jiekouguanli } from './containers'
import { Task } from './containers' import { Task, Assess } from './containers'
export default [{ export default [{
type: 'inner', type: 'inner',
route: { route: {
@ -116,13 +117,18 @@ export default [{
menuSelectKeys: ['jiekouguanli'], menuSelectKeys: ['jiekouguanli'],
component: Jiekouguanli, component: Jiekouguanli,
breadcrumb: '接口管理', breadcrumb: '接口管理',
} }, {
, {
path: '/promotional', path: '/promotional',
key: 'fillionpromotional', key: 'fillionpromotional',
menuSelectKeys: ['fillionpromotional'], menuSelectKeys: ['fillionpromotional'],
component: PromoTional, component: PromoTional,
breadcrumb: '视频管理', breadcrumb: '视频管理',
}, {
path: '/assess',
key: 'fillionassess',
menuSelectKeys: ['fillionassess'],
component: Assess,
breadcrumb: '考核评分',
} }
] ]
} }

2
web/client/src/utils/webapi.js

@ -168,7 +168,7 @@ export const ApiTable = {
// 考核评分 // 考核评分
getAssess: 'assess', getAssess: 'assess',
putAssess: 'assess', editAssess: 'assess',
delAssess: 'assess/{assessId}', delAssess: 'assess/{assessId}',
//工程数据 //工程数据

Loading…
Cancel
Save