diff --git a/api/app/lib/controllers/workOrder/index.js b/api/app/lib/controllers/workOrder/index.js index 456b763..4fe4164 100644 --- a/api/app/lib/controllers/workOrder/index.js +++ b/api/app/lib/controllers/workOrder/index.js @@ -21,6 +21,7 @@ async function getEnabledWorkflowProcess (ctx) { WHERE workflow_process.deleted = 0 AND workflow_process.is_enable = 1 + order by workflow_process.update_time desc `).toPromise() ctx.status = 200; @@ -34,6 +35,59 @@ async function getEnabledWorkflowProcess (ctx) { } } +async function basicDataAllProject (ctx) { + try { + const { models } = ctx.fs.dc; + const { clickHouse } = ctx.app.fs + + const proRes = await models.ProjectCorrelation.findAll({ + where: { + del: false, + }, + order: [['updateTime', 'desc']], + }) + + let pepProjectIds = new Set() + for (let p of proRes) { + if (p.pepProjectId) { + pepProjectIds.add(p.pepProjectId) + } + } + + const pepProjectRes = pepProjectIds.size ? + await clickHouse.projectManage.query( + ` + SELECT + t_pim_project.id AS id, + t_pim_project.project_name AS project_name, + t_pim_project.isdelete AS isdelete + FROM t_pim_project + WHERE id IN (${[...pepProjectIds].join(',')}, -1) + ` + ).toPromise() || [] : + [] + + const list = proRes.map(p => { + const corPro = pepProjectRes.find(pp => pp.id == p.pepProjectId) || {} + return { + value: p.id, + label: corPro.project_name || p.name, + disabled: corPro.isdelete == 1 + } + }) + + ctx.status = 200; + ctx.body = list + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + message: typeof error == 'string' ? error : undefined + } + } +} + module.exports = { - getEnabledWorkflowProcess + getEnabledWorkflowProcess, + basicDataAllProject }; \ No newline at end of file diff --git a/api/app/lib/routes/workOrder/index.js b/api/app/lib/routes/workOrder/index.js index fc669e4..c7004d1 100644 --- a/api/app/lib/routes/workOrder/index.js +++ b/api/app/lib/routes/workOrder/index.js @@ -5,4 +5,8 @@ const workOrder = require('../../controllers/workOrder'); module.exports = function (app, router, opts) { app.fs.api.logAttr['GET/workflow/process/enabled'] = { content: '获取工作流可用表单', visible: true }; router.get('/workflow/process/enabled', workOrder.getEnabledWorkflowProcess); + + // 单一数据源 + app.fs.api.logAttr['GET/basic-data/workflow/single/allProject'] = { content: '查询所有项目', visible: false }; + router.get('/basic-data/workflow/single/allProject', workOrder.basicDataAllProject); }; \ No newline at end of file diff --git a/api/config.js b/api/config.js index d56d4ee..46055d0 100644 --- a/api/config.js +++ b/api/config.js @@ -160,7 +160,8 @@ const product = { { p: '/alarm/service/api', o: 'POST' }, //后端服务告警入库 { p: '/data/continuity/api', o: 'POST' }, //数据连续性监控入库 { p: '/page/performance/api', o: 'POST' }, //页面加载性能入库 - { p: '/alarm/video/added_log', o: 'POST' } + { p: '/alarm/video/added_log', o: 'POST' }, + { p: '/basic-data/workflow/single/allProject', o: 'GET' }, ], // 不做认证的路由,也可以使用 exclude: ["*"] 跳过所有路由 apMergeDeVeAnxinProjectId: AP_MERGE_DEVE_ANXINPROJECT_ID, anxinCloud: { diff --git a/web/client/assets/images/fs-logo.png b/web/client/assets/images/fs-logo.png new file mode 100644 index 0000000..44814f3 Binary files /dev/null and b/web/client/assets/images/fs-logo.png differ diff --git a/web/client/src/components/index.js b/web/client/src/components/index.js index 04b40ae..1815aaa 100644 --- a/web/client/src/components/index.js +++ b/web/client/src/components/index.js @@ -6,7 +6,7 @@ import { SkeletonScreen } from './skeletonScreen' import OutHidden from './outHidden' import Uploads from './Uploads/index' import WorkflowModal from './workflow'; - +import WorkFlowViewModal from './workflow/view' export { SimpleFileDownButton, ReminderBox, @@ -14,5 +14,6 @@ export { SkeletonScreen, OutHidden, Uploads, - WorkflowModal + WorkflowModal, + WorkFlowViewModal }; diff --git a/web/client/src/components/workflow/index.jsx b/web/client/src/components/workflow/index.jsx index e5f6044..a1e8868 100644 --- a/web/client/src/components/workflow/index.jsx +++ b/web/client/src/components/workflow/index.jsx @@ -2,9 +2,9 @@ import React from 'react'; import { connect } from 'react-redux'; -import { Modal, Spin, Notification, Row } from '@douyinfe/semi-ui'; +import { Modal, Spin, Notification, Row, Space, Button } from '@douyinfe/semi-ui'; import { RouteTable } from '../../utils/webapi'; -import { RouteRequest } from '@peace/utils'; +import { EmisRequest, EmisApiTable } from '$utils'; import { useState } from 'react'; import { useEffect } from 'react'; import { IconClose } from '@douyinfe/semi-icons'; @@ -14,10 +14,9 @@ import './index.less' const { confirm } = Modal; const WorkFlowModal = (props) => { - const { successCallBack = () => { }, title, visible, clientHeight, postData, processId, user, dispatch, webEmis } = props; + const { successCallBack = () => { }, title, visible, clientHeight, postData, processId, user, dispatch, webEmis, webOa, onCancel } = props; const [loading, setLoading] = useState(true); const [ifShowMessage, setIfShowMessage] = useState(true); - const [webUrl, setWebUrl] = useState(null); const [customVisible, setCustomVisible] = useState(false); const [draftId, setDraftId] = useState(); const iframeRef = React.createRef(); @@ -26,7 +25,6 @@ const WorkFlowModal = (props) => { if (draftId) { setCustomVisible(false); } else { - const { onCancel } = props; onCancel && onCancel(); setLoading(false); } @@ -47,11 +45,9 @@ const WorkFlowModal = (props) => { } const handelApprovalCenter = (activeKey) => { - RouteRequest.get(RouteTable.getWebUrl + `?sys=emisWebUrl`).then(res => { - if (res.url) { - window.open(res.url + "/approval/center?activeKey=" + activeKey); - } - }); + if (webOa) { + window.open(webOa + "/approval/center?activeKey=" + activeKey); + } } const handelOk = () => { @@ -63,18 +59,13 @@ const WorkFlowModal = (props) => { } const handelDeny = () => { - // dispatch(delDraft(draftId)).then(res => { - // if (res.success) { - // Notification.success({title:'删除草稿成功'}); - // const { onCancel } = props; - // onCancel && onCancel(); - // setLoading(false); - // setCustomVisible(false); - // setDraftId(null); - // } else { - // Notification.error({title:'删除草稿失败,请联系管理员'}); - // } - // }) + EmisRequest.delete(EmisApiTable.delDraftUrl.replace('{draftId}', draftId)).then(res => { + Notification.success({ title: '删除草稿成功' }); + onCancel && onCancel(); + setLoading(false); + setCustomVisible(false); + setDraftId(null); + }) } const cancel = () => { @@ -87,6 +78,7 @@ const WorkFlowModal = (props) => { let data = JSON.parse(event.data); const { type, isSaveDraft, setIntervalSave, draftId, msg } = data; if (msg) { + console.log(msg); Notification.success({ title: msg }) } setDraftId(draftId); @@ -112,31 +104,21 @@ const WorkFlowModal = (props) => { } //监听message事件 window.addEventListener('message', receiveMessageFromIndex, false); - //获取企业统一认证管理平台web的URL - if (!webUrl) { - RouteRequest.get(RouteTable.getEmisWebUrl).then(res => { - if (res.url) { - setWebUrl(res.url); - } - }); - } }, []) + console.log(webEmis, processId); return (
@@ -152,7 +134,7 @@ const WorkFlowModal = (props) => { - {webUrl && processId ? : ''} - -
-
- + return ( +
+ + +
+
+ + + | + 让世间万物拥有感知,服务人类社会于美好 + + +
+
+ + {webEmis && processId ? : ''} + +
+
+
-
*/} -
+ + - ) + ) } -function mapStateToProps(state) { - const { auth, global } = state; - return { - user: auth.user, - clientHeight: global.clientHeight, - } +function mapStateToProps (state) { + const { auth, global } = state; + return { + user: auth.user, + clientHeight: global.clientHeight, + webEmis: global.webEmis, + webOa: global.webOa + } } export default connect(mapStateToProps)(WorkFlowViewModal); \ No newline at end of file diff --git a/web/client/src/layout/actions/global.js b/web/client/src/layout/actions/global.js index b8bb3cd..f85270e 100644 --- a/web/client/src/layout/actions/global.js +++ b/web/client/src/layout/actions/global.js @@ -49,6 +49,7 @@ export function initApiRoot () { dcWeb: res.dcWeb, qiniu: res.qiniu, webEmis: res.webEmis, + webOa: res.webOa, } }) }); diff --git a/web/client/src/layout/reducers/global.js b/web/client/src/layout/reducers/global.js index 5873b24..84be4a5 100644 --- a/web/client/src/layout/reducers/global.js +++ b/web/client/src/layout/reducers/global.js @@ -50,6 +50,8 @@ function global (state = { pomsNotebook: payload.pomsNotebook, dcWeb: payload.dcWeb, qiniu: payload.qiniu, + webEmis: payload.webEmis, + webOa: payload.webOa, }).toJS(); case PEPPROJECTID: return Immutable.fromJS(state).merge({ diff --git a/web/client/src/sections/workOrder/containers/jobOrder.jsx b/web/client/src/sections/workOrder/containers/jobOrder.jsx index ddb69ab..20f0a90 100644 --- a/web/client/src/sections/workOrder/containers/jobOrder.jsx +++ b/web/client/src/sections/workOrder/containers/jobOrder.jsx @@ -1,76 +1,83 @@ import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import moment from 'moment'; -import { WorkflowModal } from "$components" +import { WorkflowModal, WorkFlowViewModal } from "$components" import { EmisRequest, EmisApiTable } from "$utils" -import { Card, Notification, Space, Button } from '@douyinfe/semi-ui'; +import { Card, Notification, Space, Button, Spin } from '@douyinfe/semi-ui'; import { IconArticle } from '@douyinfe/semi-icons'; import '../style.less' const { Meta } = Card; const JobOrder = (props) => { - const { dispatch, actions, user, workflowProcess } = props + const { dispatch, actions, user, workflowProcess, clientHeight } = props const { workOrder } = actions const [workflowModalVisible, setWorkflowModalVisible] = useState(false) const [launchProcessId, setLaunchProcessId] = useState(null) + const [formStateRequestingIndex, setFormStateRequestingIndex] = useState(false) useEffect(() => { dispatch(workOrder.getEnabledWorkflowProcess()) }, []) return ( -
- { - workflowProcess.map(p => { - return ( - { - EmisRequest.get(EmisApiTable.getProcessByName, { - name: decodeURIComponent(p.name), - resource: p.id - }).then(res => { - console.log(res); - if (res) { - // if (res.deleted) { - // Notification.error({ title: '该表单流程已删除,请尝试退出账号重新登录或联系项企管理员' }) - // } else if (res.isEdited) { - // Notification.error({ title: '该表单流程已修改,请尝试退出账号重新登录或联系项企管理员' }) - // } else if (!res.isEnable) { - // Notification.error({ title: '该表单流程已停用,请尝试退出账号重新登录或联系项企管理员' }) - // } else - if (res.id) { - setLaunchProcessId(res.id) - setWorkflowModalVisible(true) +
+
+ { + workflowProcess.map((p, index) => { + return ( + { + if (formStateRequestingIndex) return; + setFormStateRequestingIndex(index + 1) + EmisRequest.get(EmisApiTable.getProcessByName, { + name: decodeURIComponent(p.name), + resource: p.id + }).then(res => { + setFormStateRequestingIndex(false) + if (res) { + // if (res.deleted) { + // Notification.error({ title: '该表单流程已删除,请尝试退出账号重新登录或联系项企管理员' }) + // } else if (res.isEdited) { + // Notification.error({ title: '该表单流程已修改,请尝试退出账号重新登录或联系项企管理员' }) + // } else if (!res.isEnable) { + // Notification.error({ title: '该表单流程已停用,请尝试退出账号重新登录或联系项企管理员' }) + // } else + if (res.id) { + setLaunchProcessId(res.id) + setWorkflowModalVisible(true) + } + } else { + Notification.error({ title: `获取指定流程失败` }); } - } else { - Notification.error({ title: `获取指定流程失败` }); - } - }) - }} - > -
- - } - /> -
-
- ) - }) - } + }) + }} + > +
+ {p.name} + } + avatar={ + + } + /> +
+ + ) + }) + } +
{ onCancel={() => { setWorkflowModalVisible(false) }} successCallBack={() => { setWorkflowModalVisible(false) }} /> + {/* */}
) } function mapStateToProps (state) { const { auth, global, workflowProcess } = state; + console.log(global); return { user: auth.user, actions: global.actions, - workflowProcess: workflowProcess.data || [] + workflowProcess: workflowProcess.data || [], + clientHeight: global.clientHeight }; } diff --git a/web/client/src/utils/webapi.js b/web/client/src/utils/webapi.js index 23f49b6..e266dd2 100644 --- a/web/client/src/utils/webapi.js +++ b/web/client/src/utils/webapi.js @@ -86,8 +86,11 @@ export const ApiTable = { export const EmisApiTable = { //通过流程名称查找指定流程 getProcessByName: 'workflow/process/name', + processInstancemMyApplyList: 'process-instance/my-apply-list', processInstancemMyAuditList: 'process-instance/my-audit-list?', + //删除草稿 + delDraftUrl: 'process/drafts/{draftId}', } export const RouteTable = { diff --git a/web/config.js b/web/config.js index 356d192..8ac8a60 100644 --- a/web/config.js +++ b/web/config.js @@ -15,7 +15,8 @@ args.option(['u', 'api-url'], 'webapi的URL'); args.option('apiPomsUrl', 'webapi的URL 外网可访问'); args.option('apiAnxinyunUrl', '安心云 api'); args.option('apiEmisUrl', '企业管理 api'); -args.option('webEmisUrl', '企业管理 web'); +args.option('webEmisUrl', '统一认证 web - 统一认证 配置表单的'); +args.option('webOaUrl', 'OA web - 项企填表单的'); args.option('iotVcmpWeb', 'IOT 视频服务'); args.option('pomsMonitor', '运维监控 web'); args.option('pomsKubesphere', 'kubesphere web'); @@ -39,6 +40,7 @@ const API_URL = process.env.API_URL || flags.apiUrl; const API_POMS_URL = process.env.API_POMS_URL || flags.apiPomsUrl; const API_EMIS_URL = process.env.API_EMIS_URL || flags.apiEmisUrl; const WEB_EMIS_URL = process.env.WEB_EMIS_URL || flags.webEmisUrl; +const WEB_OA_URL = process.env.WEB_OA_URL || flags.webOaUrl; const API_ANXINYUN_URL = process.env.API_ANXINYUN_URL || flags.apiAnxinyunUrl; const IOT_VIDEO_WEB = process.env.IOT_VIDEO_WEB || flags.iotVcmpWeb; const POMS_MONITOR = process.env.POMS_MONITOR || flags.pomsMonitor; @@ -59,7 +61,7 @@ const ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE = process.env.ANXINCLOUD_QINIU_DOMA if ( !API_URL - || !API_EMIS_URL || !WEB_EMIS_URL + || !API_EMIS_URL || !WEB_EMIS_URL || !WEB_OA_URL || !API_ANXINYUN_URL || !POMS_MONITOR || !DC_WEB || !ANXINCLOUD_QINIU_AK || !ANXINCLOUD_QINIU_SK || !ANXINCLOUD_QINIU_BUCKET_RESOURCE || !ANXINCLOUD_QINIU_DOMAIN_QNDMN_RESOURCE || !IOT_VIDEO_WEB) { @@ -106,6 +108,7 @@ const product = { opts: { apiUrl: API_POMS_URL, webEmis: WEB_EMIS_URL, + webOa: WEB_OA_URL, iotVcmpWeb: IOT_VIDEO_WEB, pomsMonitor: POMS_MONITOR, pomsKubesphere: POMS_KUBESPHERE, diff --git a/web/package.json b/web/package.json index 83f661d..4484060 100644 --- a/web/package.json +++ b/web/package.json @@ -7,7 +7,7 @@ "test": "mocha", "start-vite": "cross-env NODE_ENV=developmentVite npm run start-params", "start": "cross-env NODE_ENV=development npm run start-params", - "start-params": "node server -p 5600 -u http://localhost:4600 --apiPomsUrl http://localhost:4600 --apiAnxinyunUrl http://10.8.30.112:4100 --apiEmisUrl http://10.8.30.161:1111 --webEmisUrl http://10.8.30.161:1111 --qnak 5XrM4wEB9YU6RQwT64sPzzE6cYFKZgssdP5Kj3uu --qnsk w6j2ixR_i-aelc6I7S3HotKIX-ukMzcKmDfH6-M5 --qnbkt anxinyun-test --qndmn http://test.resources.anxinyun.cn --iotVcmpWeb https://mediaconsole.ngaiot.com --pomsMonitor http://monitor.anxinyun.cn/goto/PaEDLE84z?orgId=1 --pomsKubesphere https://k8sadmin.anxinyun.cn/ --pomsAmbari https://ambari.anxinyun.cn/ --pomsKowl https://kafka.anxinyun.cn/ --pomsPghero https://pghero.anxinyun.cn/ --pomsEs https://esc.anxinyun.cn/ --pomsNotebook https://inotebook.anxinyun.cn/ --dcWeb https://fsiot-oamss.anxinyun.cn", + "start-params": "node server -p 5600 -u http://localhost:4600 --apiPomsUrl http://localhost:4600 --apiAnxinyunUrl http://10.8.30.112:4100 --apiEmisUrl http://10.8.30.161:1111 --webEmisUrl http://10.8.30.161:1112 --webOaUrl http://10.8.30.161:8668 --qnak 5XrM4wEB9YU6RQwT64sPzzE6cYFKZgssdP5Kj3uu --qnsk w6j2ixR_i-aelc6I7S3HotKIX-ukMzcKmDfH6-M5 --qnbkt anxinyun-test --qndmn http://test.resources.anxinyun.cn --iotVcmpWeb https://mediaconsole.ngaiot.com --pomsMonitor http://monitor.anxinyun.cn/goto/PaEDLE84z?orgId=1 --pomsKubesphere https://k8sadmin.anxinyun.cn/ --pomsAmbari https://ambari.anxinyun.cn/ --pomsKowl https://kafka.anxinyun.cn/ --pomsPghero https://pghero.anxinyun.cn/ --pomsEs https://esc.anxinyun.cn/ --pomsNotebook https://inotebook.anxinyun.cn/ --dcWeb https://fsiot-oamss.anxinyun.cn", "deploy": "export NODE_ENV=production&& npm run build && node server", "build-dev": "cross-env NODE_ENV=development&&webpack --config webpack.config.js", "build": "cross-env NODE_ENV=production&&webpack --config webpack.config.prod.js" diff --git a/web/routes/attachment/index.js b/web/routes/attachment/index.js index 48b16ef..b4e88ef 100644 --- a/web/routes/attachment/index.js +++ b/web/routes/attachment/index.js @@ -19,7 +19,7 @@ module.exports = { entry: function (app, router, opts) { const getApiRoot = async function (ctx) { - const { apiUrl, iotVcmpWeb, pomsMonitor, pomsKubesphere, pomsAmbari, pomsKowl, pomsPghero, pomsEs, pomsNotebook, dcWeb, qiniu, webEmis, } = opts; + const { apiUrl, iotVcmpWeb, pomsMonitor, pomsKubesphere, pomsAmbari, pomsKowl, pomsPghero, pomsEs, pomsNotebook, dcWeb, qiniu, webEmis, webOa } = opts; ctx.status = 200; ctx.body = { @@ -35,6 +35,7 @@ module.exports = { dcWeb: dcWeb, qiniu: qiniu, webEmis, + webOa, }; };