From 6fbbbc31afbae0b6c29e2e9e1f0ce40c3c1d2fc4 Mon Sep 17 00:00:00 2001 From: wangjiahui Date: Sat, 8 Jun 2024 04:01:26 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E6=8A=84=E9=80=81=E6=88=91=E7=9A=84=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E5=92=8C=E7=95=8C=E9=9D=A2=20(#1142)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reviewed-on: https://git.daoyoucloud.com/daoyoucloud/tachybase/pulls/1142 Reviewed-by: sealday Co-authored-by: wangjiahui Co-committed-by: wangjiahui --- .../approval/collection/notice.collection.ts | 143 ++++++++++++++++++ .../src/client/approval/index.ts | 2 + .../src/client/approval/todos/TodosBlock.tsx | 2 + .../todos/component/TabApprovalItem.tsx | 81 ++++++++-- .../component/ViewActionTodosContent.tsx | 9 +- .../component/ViewTodosDetailsContent.tsx | 36 +++++ .../component/ViewTodosUserJobsContent.tsx | 8 +- .../ViewTodosWorkflowNoticeContent.tsx | 137 +++++++++++++++++ .../client/approval/todos/componentSchema.tsx | 2 +- .../todos/hook/usePropsNoticeDetail.ts | 15 ++ .../src/client/index.tsx | 8 +- 11 files changed, 418 insertions(+), 25 deletions(-) create mode 100644 packages/plugins/@hera/plugin-approval-mobile/src/client/approval/collection/notice.collection.ts create mode 100644 packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosDetailsContent.tsx create mode 100644 packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosWorkflowNoticeContent.tsx create mode 100644 packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/hook/usePropsNoticeDetail.ts diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/collection/notice.collection.ts b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/collection/notice.collection.ts new file mode 100644 index 000000000..9045cd4f5 --- /dev/null +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/collection/notice.collection.ts @@ -0,0 +1,143 @@ +import { approvalStatusOptions } from '../constants'; +import { NAMESPACE, tval } from '../locale'; + +export const CollectionWorkflowNotice = { + title: tval('Notice Center'), + name: 'workflowNotice', + fields: [ + { + type: 'bigInt', + name: 'id', + interface: 'number', + uiSchema: { + type: 'number', + title: 'ID', + 'x-component': 'InputNumber', + }, + }, + { + type: 'belongsTo', + name: 'user', + target: 'users', + foreignKey: 'userId', + interface: 'm2o', + uiSchema: { + type: 'number', + title: tval('The Notified Person'), + 'x-component': 'RemoteSelect', + 'x-component-props': { + fieldNames: { + label: 'nickname', + value: 'id', + }, + service: { resource: 'users' }, + }, + }, + }, + { + type: 'belongsTo', + name: 'node', + target: 'flow_nodes', + foreignKey: 'nodeId', + interface: 'm2o', + isAssociation: true, + uiSchema: { + type: 'number', + title: `{{t("Task node", { ns: "${NAMESPACE}" })}}`, + 'x-component': 'RemoteSelect', + 'x-component-props': { + fieldNames: { + label: 'title', + value: 'id', + }, + service: { + resource: 'flow_nodes', + }, + }, + }, + }, + { + type: 'belongsTo', + name: 'workflow', + target: 'workflows', + foreignKey: 'workflowId', + interface: 'm2o', + uiSchema: { + type: 'number', + title: '{{t("Workflow", { ns: "workflow" })}}', + 'x-component': 'RemoteSelect', + 'x-component-props': { + fieldNames: { + label: 'title', + value: 'id', + }, + service: { resource: 'workflows' }, + }, + }, + }, + { + type: 'integer', + name: 'status', + interface: 'select', + uiSchema: { + type: 'number', + title: '{{t("Status", { ns: "workflow" })}}', + 'x-component': 'Select', + enum: approvalStatusOptions, + }, + }, + { + type: 'text', + name: 'comment', + interface: 'markdown', + uiSchema: { + type: 'string', + 'x-component': 'Markdown', + title: `{{t("Comment", { ns: "${NAMESPACE}" })}}`, + }, + }, + { + name: 'createdAt', + type: 'date', + interface: 'createdAt', + uiSchema: { + type: 'datetime', + title: '{{t("Created at")}}', + 'x-component': 'DatePicker', + 'x-component-props': { + showTime: true, + }, + }, + }, + { + name: 'updatedAt', + type: 'date', + interface: 'updatedAt', + uiSchema: { + type: 'datetime', + title: '{{t("Updated at")}}', + 'x-component': 'DatePicker', + 'x-component-props': { + showTime: true, + }, + }, + }, + { + type: 'string', + name: 'summary', + interface: 'input', + uiSchema: { + type: 'string', + title: tval('Summary'), + 'x-component': 'ApprovalsSummary', + 'x-component-props': { + style: { + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + }, + }, + }, + }, + ], +}; diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/index.ts b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/index.ts index c4c7490ad..43013e6b7 100644 --- a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/index.ts +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/index.ts @@ -8,6 +8,7 @@ import { ViewActionUserInitiationsContent } from './initiations/component/ViewAc import { LauncherActionConfigInitializer } from './initiations/config/LauncherActionConfig'; import { InitiationsBlock } from './initiations/InitiationsBlock'; import { ViewActionTodosContent } from './todos/component/ViewActionTodosContent'; +import { ViewTodosDetailsContent } from './todos/component/ViewTodosDetailsContent'; import { ViewTodosUserJobsContent } from './todos/component/ViewTodosUserJobsContent'; import { TodosBlock } from './todos/TodosBlock'; @@ -17,6 +18,7 @@ class PluginApproval extends Plugin { ApprovalBlockInitializer, InitiationsBlock, TodosBlock, + ViewTodosDetailsContent, ViewActionTodosContent, ViewActionUserInitiationsContent, ViewActionInitiationsContent, diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/TodosBlock.tsx b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/TodosBlock.tsx index 272791ad4..0d9acda46 100644 --- a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/TodosBlock.tsx +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/TodosBlock.tsx @@ -9,6 +9,7 @@ import '../style/style.css'; import { CollectionApprovals } from '../collection/Approvals.collection'; import { CollectionApprovalTodos } from '../collection/ApprovalTodos'; import { CollectionFlowNodes } from '../collection/FlowNodes.collection'; +import { CollectionWorkflowNotice } from '../collection/notice.collection'; import { nodeCollection, todoCollection, workflowCollection } from '../collection/UserJobs.collection'; import { CollectionWorkflows } from '../collection/Workflows.collection'; import { useTranslation } from '../locale'; @@ -34,6 +35,7 @@ export const TodosBlock = observer((props) => { nodeCollection, workflowCollection, todoCollection, + CollectionWorkflowNotice, ]} > diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/TabApprovalItem.tsx b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/TabApprovalItem.tsx index ae00d1a23..db099c748 100644 --- a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/TabApprovalItem.tsx +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/TabApprovalItem.tsx @@ -23,6 +23,8 @@ export const TabApprovalItem = observer((props) => { changeApprovalRecordsService(api, params?.[tabKey], filter, cm, compile, t, setData, input); } else if (collectionName === 'users_jobs') { changeUsersJobsService(api, t, cm, compile, input, setData, params?.[tabKey], filter); + } else if (collectionName === 'workflowNotice') { + changeWorkflowNoticeService(api, t, cm, compile, input, setData, params?.[tabKey], filter); } }, [filter, params, input]); @@ -35,12 +37,7 @@ export const TabApprovalItem = observer((props) => { { - let url; - if (collectionName === 'approvalRecords') { - url = `/mobile/approval/${item.id}/${item.categoryTitle}/detailspage`; - } else if (collectionName === 'users_jobs') { - url = `/mobile/approval/${item.id}/userJobspage`; - } + const url = `/mobile/approval/${collectionName}/${item.id}/${item.categoryTitle}/detailspage`; navigate(url); }} > @@ -98,20 +95,21 @@ const changeApprovalRecordsService = (api, params, filter, cm, compile, t, setDa const statusType = approvalTodoListStatus(item, t); const categoryTitle = item.workflow.title.replace('审批流:', ''); const collectionName = item.workflow?.config?.collection || item.execution?.context?.collectionName; - const summary = Object.entries(item.summary).map(([key, value]) => { + const summary = Object.entries(item.summary)?.map(([key, value]) => { const field = cm.getCollectionField(`${collectionName}.${key}`); return { label: compile(field?.uiSchema?.title || key), value: (Object.prototype.toString.call(value) === '[object Object]' ? value?.['name'] : value) || '', }; }); + const nickName = item.snapshot.createdBy?.nickname || item.execution?.context?.data.createdBy?.nickname; return { ...item, - title: `${item.snapshot.createdBy.nickname}的${categoryTitle}`, + title: `${nickName}的${categoryTitle}`, categoryTitle: categoryTitle, statusTitle: t(statusType.label), statusColor: statusType.color, - reason: summary, + reason: summary || [], priorityTitle: priorityType.label, priorityColor: priorityType.color, }; @@ -144,9 +142,10 @@ const changeUsersJobsService = (api, t, cm, compile, input, setData, params, fil ); const statusType = ExecutionStatusOptions.find((value) => value.value === item.status); const categoryTitle = item.workflow.title.replace('审批流:', ''); + const nickName = item.execution?.context?.data?.createdBy?.nickname; return { ...item, - title: `${item.user?.nickname}的${categoryTitle}`, + title: `${nickName}的${categoryTitle}`, categoryTitle: categoryTitle, statusTitle: t(statusType.label), statusColor: statusType.color, @@ -167,3 +166,65 @@ const changeUsersJobsService = (api, t, cm, compile, input, setData, params, fil console.error; }); }; + +export const changeWorkflowNoticeService = (api, t, cm, compile, input, setData, params, filter) => { + api + .request({ + url: 'workflowNotice:listCentralized', + params: { + pageSize: 9999, + filter: { ...params, ...filter }, + appends: [ + 'user.id', + 'user.nickname', + 'node.id', + 'node.title', + 'job.id', + 'job.status', + 'job.result', + 'workflow.id', + 'workflow.title', + 'workflow.enabled', + 'execution.id', + 'execution.status', + ], + }, + }) + .then((res) => { + const result = res.data?.data.map((item) => { + const priorityType = ApprovalPriorityType.find( + (priorityItem) => priorityItem.value === item.snapshot?.priority, + ); + const statusType = approvalStatusOptions.find((value) => value.value === item.status); + const categoryTitle = item.workflow.title.replace('审批流:', ''); + const collectionName = item.collectionName; + const summary = Object.entries(item.summary).map(([key, value]) => { + const field = cm.getCollectionField(`${collectionName}.${key}`); + return { + label: compile(field?.uiSchema?.title || key), + value: (Object.prototype.toString.call(value) === '[object Object]' ? value?.['name'] : value) || '', + }; + }); + return { + ...item, + title: `${item.user?.nickname}的${categoryTitle}`, + categoryTitle: categoryTitle, + statusTitle: t(statusType.label), + statusColor: statusType.color, + reason: summary, + priorityTitle: priorityType.label, + priorityColor: priorityType.color, + }; + }); + + const filterResult = result.filter((value) => value.title.includes(input)); + + filterResult.sort((a, b) => { + return Date.parse(b.createdAt) - Date.parse(a.createdAt); + }); + setData(filterResult); + }) + .catch(() => { + console.error; + }); +}; diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewActionTodosContent.tsx b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewActionTodosContent.tsx index ffd213f90..d7cfd5233 100644 --- a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewActionTodosContent.tsx +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewActionTodosContent.tsx @@ -27,13 +27,14 @@ import { ApprovalFormBlockDecorator } from '../provider/ApprovalFormBlock'; import '../../style/style.css'; import { MobileProvider } from '@tachybase/plugin-mobile-client/client'; +import { observer } from '@tachybase/schema'; // 审批-待办-查看: 内容 -export const ViewActionTodosContent = () => { +export const ViewActionTodosContent = observer((props) => { + const { id } = props as any; const { t } = useTranslation(); const navigate = useNavigate(); - const params = useParams(); - const { id } = params; + const api = useAPIClient(); const [noDate, setNoDate] = useState(false); const [recordData, setRecordDate] = useState({}); @@ -115,7 +116,7 @@ export const ViewActionTodosContent = () => { ); -}; +}); const todosComponent = (applyDetail) => { const formContextSchema = { diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosDetailsContent.tsx b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosDetailsContent.tsx new file mode 100644 index 000000000..9e447d2ad --- /dev/null +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosDetailsContent.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { SchemaComponent } from '@tachybase/client'; +import { observer } from '@tachybase/schema'; + +import { useParams } from 'react-router-dom'; + +import { ViewActionTodosContent } from './ViewActionTodosContent'; +import { ViewTodosUserJobsContent } from './ViewTodosUserJobsContent'; +import { ViewTodosWorkflowNoticeContent } from './ViewTodosWorkflowNoticeContent'; + +export const ViewTodosDetailsContent = () => { + const params = useParams(); + const { id, type } = params; + const schema = { + type: 'void', + name: 'TabProcessedItem', + title: 'TodosDetails', + 'x-component': component[type], + 'x-component-props': { + id, + }, + }; + + return ( + + ); +}; + +const component = { + approvalRecords: 'ViewActionTodosContent', + users_jobs: 'ViewTodosUserJobsContent', + workflowNotice: 'ViewTodosWorkflowNoticeContent', +}; diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosUserJobsContent.tsx b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosUserJobsContent.tsx index 4889817ad..b0705d4ad 100644 --- a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosUserJobsContent.tsx +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosUserJobsContent.tsx @@ -18,6 +18,7 @@ import { useTranslation } from '../../locale'; import '../../style/style.css'; import { MobileProvider } from '@tachybase/plugin-mobile-client/client'; +import { observer } from '@tachybase/schema'; import { Registry } from '@tachybase/utils/client'; import { ManualFormType } from '../../constants'; @@ -29,12 +30,11 @@ import { FormBlockProvider } from '../provider/FormBlockProvider'; import { ManualActionStatusProvider } from '../provider/ManualActionStatusProvider'; // 审批-执行处理-查看: 内容 -export const ViewTodosUserJobsContent = () => { +export const ViewTodosUserJobsContent = observer((props) => { + const { id } = props as any; const { t } = useTranslation(); const { actionEnabled } = useContext(ContextWithActionEnabled); const navigate = useNavigate(); - const params = useParams(); - const { id } = params; const api = useAPIClient(); const [noDate, setNoDate] = useState(false); const workflowPlugin = usePlugin(PluginWorkflowClient); @@ -138,7 +138,7 @@ export const ViewTodosUserJobsContent = () => { ); -}; +}); function useDetailsBlockProps() { const { form } = useFormBlockContext(); diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosWorkflowNoticeContent.tsx b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosWorkflowNoticeContent.tsx new file mode 100644 index 000000000..1c6e8ab24 --- /dev/null +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/component/ViewTodosWorkflowNoticeContent.tsx @@ -0,0 +1,137 @@ +import React, { useContext, useEffect, useState } from 'react'; +import { + CollectionProvider, + CollectionProvider_deprecated, + RemoteSchemaComponent, + SchemaComponent, + SchemaComponentProvider, + useAPIClient, + useFormBlockContext, + usePlugin, +} from '@tachybase/client'; +import { DetailsBlockProvider, FlowContext, linkNodes } from '@tachybase/plugin-workflow/client'; + +import { Result } from 'antd'; +import { NavBar, Skeleton } from 'antd-mobile'; +import _ from 'lodash'; +import { useNavigate } from 'react-router-dom'; + +import { useTranslation } from '../../locale'; + +import '../../style/style.css'; + +import { MobileProvider } from '@tachybase/plugin-mobile-client/client'; +import { observer } from '@tachybase/schema'; + +import { ContextApprovalExecution } from '../../context/ApprovalExecution'; +import { usePropsNoticeDetail } from '../hook/usePropsNoticeDetail'; + +// 审批-抄送-查看: 内容 +export const ViewTodosWorkflowNoticeContent = observer((props) => { + const { id } = props as any; + const { t } = useTranslation(); + const navigate = useNavigate(); + const api = useAPIClient(); + const [noDate, setNoDate] = useState(false); + const [noticeData, setNoticeData] = useState({}); + const [schemaId, setSchemaId] = useState(''); + const [flowContext, setFlowContext] = useState(null); + useEffect(() => { + api + .request({ + url: 'workflowNotice:get', + params: { + filterByTk: id, + appends: ['execution', 'node', 'job', 'workflow', 'workflow.nodes', 'execution.jobs', 'user'], + except: ['workflow.config', 'workflow.options', 'nodes.config'], + sort: ['-createdAt'], + }, + }) + .then(({ data }) => { + if (!data.data) setNoDate(true); + const { node, workflow: { nodes = [], ...workflow } = {}, execution, ...userJob } = data?.data ?? {}; + linkNodes(nodes); + setFlowContext({ + userJob, + workflow, + nodes, + execution, + }); + setSchemaId(node?.config.showNoticeDetail); + setNoticeData(data.data); + return; + }) + .catch(() => { + console.error; + }); + }, []); + + if (noDate) { + return ; + } + return ( +
+ { + navigate(-1); + }} + className="navBarStyle" + > + {'抄送'} + +
+ {noticeData && schemaId ? ( + + + + + + + + ) : ( +
+ + +
+ )} +
+
+ ); +}); diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/componentSchema.tsx b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/componentSchema.tsx index 6b19b4f74..cf5d0092d 100644 --- a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/componentSchema.tsx +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/componentSchema.tsx @@ -43,7 +43,7 @@ export const tabDuplicateSchema = (t, props, parantUid) => { 'x-component': 'TabDuplicateItem', 'x-component-props': { ...props, - collectionName: 'approvalRecords', + collectionName: 'workflowNotice', settingBlock: true, tabKey: 'duplicate', parantUid, diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/hook/usePropsNoticeDetail.ts b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/hook/usePropsNoticeDetail.ts new file mode 100644 index 000000000..8e15a9b4c --- /dev/null +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/approval/todos/hook/usePropsNoticeDetail.ts @@ -0,0 +1,15 @@ +import { useEffect } from 'react'; +import { useFormBlockContext } from '@tachybase/client'; + +import { useContextApprovalExecution } from '../../context/ApprovalExecution'; + +export function usePropsNoticeDetail() { + const { snapshot } = useContextApprovalExecution(); + const { form } = useFormBlockContext(); + + useEffect(() => { + form.setValues(snapshot); + }, [form, snapshot]); + + return { form }; +} diff --git a/packages/plugins/@hera/plugin-approval-mobile/src/client/index.tsx b/packages/plugins/@hera/plugin-approval-mobile/src/client/index.tsx index 905a4535d..9a9f8f70b 100644 --- a/packages/plugins/@hera/plugin-approval-mobile/src/client/index.tsx +++ b/packages/plugins/@hera/plugin-approval-mobile/src/client/index.tsx @@ -19,12 +19,8 @@ export class PluginApprovalMobileClient extends Plugin { Component: 'ViewActionUserInitiationsContent', }); this.app.router.add('mobile.approval.detailspage', { - path: '/mobile/:name/:id/:category/detailspage', - Component: 'ViewActionTodosContent', - }); - this.app.router.add('mobile.approval.userJobspage', { - path: '/mobile/:name/:id/userJobspage', - Component: 'ViewTodosUserJobsContent', + path: '/mobile/:name/:type/:id/:category/detailspage', + Component: 'ViewTodosDetailsContent', }); } }