CODE 1 year ago
parent
commit
35518c1eb3
  1. 27
      api/app/lib/controllers/project/group.js
  2. 4
      api/app/lib/models/form_data_table.js
  3. 39
      api/app/lib/schedule/workOrder.js
  4. 2
      api/config.js
  5. 1
      web/client/src/layout/actions/workOrders.js
  6. 42
      web/client/src/sections/projectGroup/containers/bigscreen.jsx

27
api/app/lib/controllers/project/group.js

@ -587,30 +587,30 @@ async function groupProject (ctx) {
}
async function getProjectWorkOrders(){
async function getProjectWorkOrders(ctx){
try{
// 计算一个月前的日期
const oneMonthAgo = moment().subtract(1, 'months').toDate()
const { models } = ctx.fs.dc
const {Op, fn, col} = ctx.fs.dc.ORM.sequelize
const sequelize = ctx.fs.dc.ORM
const { projectIds } = ctx.query
if(projectIds&&projectIds.length){
const projectIdsArr=projectIds.split(',').map(Number)
const res= await models.FormDataTable.findAll({
attributes: [
'projectId',
[fn('COUNT', col('id')), 'count'],
[sequelize.fn('COUNT', sequelize.col('id')), 'count'],
],
where: {
projectIds: {
[Op.in]: projectIdsArr,
projectId: {
$in: projectIdsArr,
},
startTime: {
[Op.gte]: oneMonthAgo,
$gte: oneMonthAgo,
},
},
group: ['projectId'],
order: [[fn('COUNT', col('id')), 'DESC']],
order: [[sequelize.fn('COUNT', sequelize.col('id')), 'DESC']],
})
ctx.body=res
ctx.status=200
@ -628,24 +628,25 @@ async function getProjectWorkOrders(){
}
}
async function getWorkOrdersRepairRank(){
async function getWorkOrdersRepairRank(ctx){
try{
const oneMonthAgo = moment().subtract(1, 'months').toDate()
const { models } = ctx.fs.dc
const {Op, fn, col} = ctx.fs.dc.ORM.sequelize
const sequelize = ctx.fs.dc.ORM
const { projectIds } = ctx.query
if(projectIds&&projectIds.length){
const res= await models.FormDataTable.findAll({
where: {
projectIds: {
[Op.in]: projectIds.split(',').map(Number),
projectId: {
$in: projectIds.split(',').map(Number)
},
startTime: {
[Op.gte]: oneMonthAgo,
$gte: oneMonthAgo,
}
},
order: [
[fn('TIMESTAMPDIFF', literal('SECOND'), col('endTime'), col('startTime')), 'DESC']
[sequelize.literal('(EXTRACT(EPOCH FROM "end_time" - "start_time"))'), 'DESC']
]
})
ctx.body=res

4
api/app/lib/models/form_data_table.js

@ -9,11 +9,11 @@ module.exports = dc => {
id: {
type: DataTypes.INTEGER,
allowNull: false,
defaultValue: "nextval(\"formDataTable_id_seq\"::regclass)",
defaultValue: null,
comment: "id",
primaryKey: true,
field: "id",
autoIncrement: false
autoIncrement: true
},
projectId: {
type: DataTypes.INTEGER,

39
api/app/lib/schedule/workOrder.js

@ -1,9 +1,11 @@
const schedule = require('node-schedule');
const moment = require('moment')
const request = require('superagent');
let isDev = true
module.exports = function (app, opts) {
module.exports = function (app, opts,ctx) {
const workOrder = app.fs.scheduleInit(
{
interval: '0 * * * *',//一小时执行一次
@ -14,16 +16,18 @@ module.exports = function (app, opts) {
try{
//前一次执行时间
console.log('工单数据抽取开始')
const username = "admin"
const password = "fs-workflow"
let lastExecutionTime = null;
const { parseProcessData } = app.fs.utils
const startTime = moment()
const startTime = moment().format('YYYY-MM-DD HH:mm:ss')
const { models } = app.fs.dc
const { clickHouse } = app.fs
const { database: camWorkflow } = clickHouse.camWorkflow.opts.config
//新建表是否有数据
const rescount=await models.FormDataTable.count()
if (lastExecutionTime === null) {
lastExecutionTime = moment().subtract(1, 'hour');
lastExecutionTime = moment().subtract(1, 'hour').format('YYYY-MM-DD HH:mm:ss')
}
const formRes = await clickHouse.pepEmis.query(
`SELECT
@ -53,37 +57,48 @@ module.exports = function (app, opts) {
ON fgroup.id = fprocess.group_id
INNER JOIN ${camWorkflow}.act_hi_procinst AS procin
ON procin.id_ = story.procinst_id
AND procin.state_='COMPLETED'
${rescount ?` WHERE procin.end_time_ is not null
AND procin.end_time_ > '${lastExecutionTime}'
AND procin.end_time_ <='${startTime}'`
: ''}`
).toPromise()
console.log('formRes1',formRes)
const procinstIds = [...new Set(formRes.map(e => e.procinstId))];
// 获取流程实例变量
console.log('formRes1',procinstIds)
// 获取流程实例变量
if(formRes && formRes.length > 0){
let procinstsVariables = await ctx.app.camunda.request.post(encodeURI(`/engine-rest/history/variable-instance`), {
processInstanceIdIn: procinstIds
})
for (let f of formRes) {
let procinstsVariables = await request.post(encodeURI(opts.camundarest.host+'/'+opts.camundarest.root+`/engine-rest/history/variable-instance`))
.auth(username, password)
.set('Content-Type', 'application/json')
.send({processInstanceIdIn: procinstIds})
console.log('formRes2',procinstsVariables)
if(procinstsVariables.body&&procinstsVariables.body.length){
for (let f of formRes) {
const parseData = parseProcessData({
formSchema: JSON.parse(f.formSchema),
formData: JSON.parse(f.formData)
})
await models.Workorder.create({
const res=await models.FormDataTable.create({
projectId:parseData.pomsProjectId.value || null,
formname:procinstsVariables.find(item=>item.id===f.procinstId).name||null,
formname:procinstsVariables.body.find(t => t.name == 'fsEmisBusinessName') ? procinstsVariables.body.find(t => t.name == 'fsEmisBusinessName').value : '',
state: f.state||null,
endTime:f.endTime||null,
startTime:f.createTime||null
})
console.log('formRes3',res)
console.log('工单数据抽取结束')
}
}else{
console.log('未查询到数据')
}
}else{
console.log('未查询到数据')
}
}catch(error){
console.error(error)
console.error('失败原因',error)
}
}
);

2
api/config.js

@ -206,6 +206,8 @@ const product = {
{ p: '/project/group/statistic/alarm', o: 'GET' },
{ p: '/project/group/list', o: 'GET' },
{ p: '/project/group/:groupId/detail', o: 'GET' },
{p:'/project/workOrders/repairRank',o:'GET'},
{p:'/project/workOrders',o:'GET'}
], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由
apMergeDeVeAnxinProjectId: AP_MERGE_DEVE_ANXINPROJECT_ID,
anxinCloud: {

1
web/client/src/layout/actions/workOrders.js

@ -3,7 +3,6 @@
import { ApiTable, basicAction } from '$utils'
export function getWorkOrders () { //获取工单的待办
console.log('xxxxx',ApiTable.workOrders)
return dispatch => basicAction({
type: 'get',
dispatch: dispatch,

42
web/client/src/sections/projectGroup/containers/bigscreen.jsx

@ -25,7 +25,7 @@ const Bigscreen = (props) => {
const [proportion, setProportion] = useState([])
const [formatter, setFormatter] = useState({})
const [groupDetail, setGroupDetail] = useState({})
const [allProjects,setAllProjects]=useState([])
const [alarmData, setAlarmData] = useState()//
const [biggest, setBiggest] = useState()//
const [mockData, setMockData] = useState()//
@ -36,6 +36,7 @@ const Bigscreen = (props) => {
useEffect(() => {
let groupIdLocal = JSON.parse(localStorage.getItem('project_group'))?.find(v => user?.id == v.userId)?.projectGroupId
let search = restProps?.location?.search || '';
@ -67,7 +68,11 @@ const Bigscreen = (props) => {
setGroupDetail(res.payload.data)
}
})
dispatch(actions.workOrder.getPomsProjectBasicAll()).then(res => {
if (res.success) {
setAllProjects(res.payload.data)
}
})
@ -135,27 +140,27 @@ const Bigscreen = (props) => {
}
}, [mockData])
console.log('xxx1',actions)
useEffect(() => {
if(groupDetail?.pomsProjectIds&&groupDetail?.pomsProjectIds.length){
if(groupDetail?.pomsProjectIds&&groupDetail?.pomsProjectIds.length&&allProjects&&allProjects.length){
const query=groupDetail?.pomsProjectIds+''
dispatch(actions.projectGroup.getProjectWorkOrders({projectIds:query})).then(res=>{
if(res.success){
setProportion([...res.payload.data?.slice(0, 3)?.map(v => ({ name: pomsProjectBasicAll.find(item=>item.valiue===v.projectId)?.label, value: v.count })),
{ value: res.payload.data&&res.payload.data.length>3?res.payload.data?.slice(3)?.reduce((p,c)=>{
return p+c.count
},0):0, name: '其它' }])
setProportion([...res.payload.data?.slice(0, 3)?.map(v => ({ name: allProjects?.find(item=>item.value===v.projectId)?.label, value: Number(v.count) })),
{ name: '其它', value: res.payload.data&&res.payload.data.length>3?res.payload.data?.slice(3)?.reduce((p,c)=>{
return p+Number(c.count)
},0):0 }])
}
})
dispatch(actions.projectGroup.getProjectWorkOrders({projectIds:query})).then(res=>{
dispatch(actions.projectGroup.getWorkOrdersRepairRank({projectIds:query})).then(res=>{
if(res.success){
setGroupProject(res.payload.data?.slice(0, 10).map(v => ({name:v.formname,duration:v?.endTime.diff(v?.startTime,'hours') })) || [])
setGroupProject(res.payload.data?.slice(0, 10).map(v => ({name:v.formname,startTime:moment(v?.startTime).format('YYYY-MM-DD'),duration:moment(v?.endTime).add(8, 'hours').diff(v?.startTime,'hours') })) || [])
}
})
}
},[groupDetail])
},[groupDetail,allProjects])
let statisticOnline = (groupId) => {
dispatch(actions.projectGroup.groupStatisticOnline({ groupId })).then(res => {
@ -225,6 +230,7 @@ console.log('xxx1',actions)
}, [proportion]);
return (
<div className='project-group'>
<Header match={match} history={history} {...props} groupDetail={groupDetail} />
<Body>
<div style={{ width: "100%", height: '100%' }}>
@ -321,8 +327,8 @@ console.log('xxx1',actions)
return index < 10 ? <div style={{ display: "flex", background: index % 2 == 1 ? "#F6F9FF" : '', padding: 6, height: 50, alignItems: 'center' }}>
<div style={{ textAlign: 'center', width: '25%', fontFamily: 'SourceHanSansCN-Regular', color: '#2C66F3', fontWeight: 400 }}>
NO.{index + 1}</div>
<div title={c.fromname} style={{ textAlign: 'center', padding: '0 6px', width: '49%', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
{c.fromname}</div>
<div title={`${c.name}(${c.startTime})`} style={{ textAlign: 'center', padding: '0 6px', width: '49%', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
{c.name}({c.startTime})</div>
<div style={{ textAlign: 'center', width: '25%', fontFamily: 'SourceHanSansCN-Regular', fontWeight: 400 }}>
{c.duration}h</div>
</div> : <></>
@ -485,7 +491,7 @@ console.log('xxx1',actions)
return <div style={{ display: "flex", background: index % 2 == 1 ? "#F6F9FF" : '', height: 40, alignItems: 'center' }}>
<div style={{ textAlign: 'center', width: '33%', fontFamily: 'SourceHanSansCN-Regular', color: '#2C66F3', fontWeight: 400 }}>{c.name}</div>
<div style={{ textAlign: 'center', width: '33%' }}>{title}</div>
<div style={{ textAlign: 'center', width: '33%', fontFamily: 'SourceHanSansCN-Regular', color: '#F33B3B', fontWeight: 400 }}>{c.offnum + '/' + c.totnum+`(${(c.offnum/c.totnum).toFixed(4)*100}%)`}</div>
<div style={{ textAlign: 'center', width: '33%', fontFamily: 'SourceHanSansCN-Regular', color: '#F33B3B', fontWeight: 400 }}>{c.offnum + '/' + c.totnum+`(${((c.offnum/c.totnum)*100).toFixed(2)}%)`}</div>
</div>
})}</> } containerStyle={{ position: "relative", height: "85%", }}
divHeight={"100%"} divId={"interruptchart"}/>
@ -500,14 +506,16 @@ console.log('xxx1',actions)
</div >
)
}
function mapStateToProps (state) {
const { auth, global, groupStatisticOnline } = state;
const { auth, global, groupStatisticOnline,pomsProjectBasicAll } = state;
return {
user: auth.user,
actions: global.actions,
clientHeight: global.clientHeight,
groupStatisticOnline: groupStatisticOnline?.data
groupStatisticOnline: groupStatisticOnline?.data,
pomsProjectBasicAll: pomsProjectBasicAll.data || [],
};
}

Loading…
Cancel
Save