feat: 添加手机端审批重新申请功能 (#1273)
Reviewed-on: https://git.daoyoucloud.com:8443/daoyoucloud/tachybase/pulls/1273 Reviewed-by: sealday <zhanglin@daoyoucloud.com> Co-authored-by: wjh <wwwjh0710@163.com> Co-committed-by: wjh <wwwjh0710@163.com>
This commit is contained in:
parent
b470ac1b12
commit
a094b9670d
@ -52,18 +52,24 @@ import {
|
|||||||
APIClientProvider,
|
APIClientProvider,
|
||||||
ApplicationContext,
|
ApplicationContext,
|
||||||
AssociationOrCollectionProvider,
|
AssociationOrCollectionProvider,
|
||||||
|
Checkbox,
|
||||||
CollectionFieldOptions_deprecated,
|
CollectionFieldOptions_deprecated,
|
||||||
CollectionRecordProvider,
|
CollectionRecordProvider,
|
||||||
createDesignable,
|
createDesignable,
|
||||||
DataSourceApplicationProvider,
|
DataSourceApplicationProvider,
|
||||||
|
DatePicker,
|
||||||
Designable,
|
Designable,
|
||||||
findFormBlock,
|
findFormBlock,
|
||||||
FormDialog,
|
FormDialog,
|
||||||
FormProvider,
|
FormProvider,
|
||||||
|
Radio,
|
||||||
RemoteSchemaComponent,
|
RemoteSchemaComponent,
|
||||||
SchemaComponent,
|
SchemaComponent,
|
||||||
SchemaComponentContext,
|
SchemaComponentContext,
|
||||||
SchemaComponentOptions,
|
SchemaComponentOptions,
|
||||||
|
Select,
|
||||||
|
Cascader as TCascader,
|
||||||
|
Input as TInput,
|
||||||
useAPIClient,
|
useAPIClient,
|
||||||
useApp,
|
useApp,
|
||||||
useBlockRequestContext,
|
useBlockRequestContext,
|
||||||
@ -1009,6 +1015,17 @@ export const SchemaSettingsModalItem: FC<SchemaSettingsModalItemProps> = (props)
|
|||||||
...others
|
...others
|
||||||
} = props;
|
} = props;
|
||||||
const options = useContext(SchemaOptionsContext);
|
const options = useContext(SchemaOptionsContext);
|
||||||
|
options.components = {
|
||||||
|
...options.components,
|
||||||
|
Input: TInput,
|
||||||
|
'Input.TextArea': TInput.TextArea,
|
||||||
|
'Radio.Group': Radio.Group,
|
||||||
|
'Checkbox.Group': Checkbox.Group,
|
||||||
|
DatePicker,
|
||||||
|
Select,
|
||||||
|
AlternativeAssociationSelect: undefined,
|
||||||
|
Cascader: TCascader,
|
||||||
|
};
|
||||||
const { styles } = useStyles();
|
const { styles } = useStyles();
|
||||||
const collection = useCollection_deprecated();
|
const collection = useCollection_deprecated();
|
||||||
const apiClient = useAPIClient();
|
const apiClient = useAPIClient();
|
||||||
|
@ -57,6 +57,8 @@ export const APPROVAL_ACTION_STATUS = {
|
|||||||
PROCESSING: 3,
|
PROCESSING: 3,
|
||||||
/** 4:已完结 */
|
/** 4:已完结 */
|
||||||
APPROVED: 4,
|
APPROVED: 4,
|
||||||
|
/**5:重新提交 */
|
||||||
|
RESUBMIT: 5,
|
||||||
/** -1:拒收 */
|
/** -1:拒收 */
|
||||||
REJECTED: -1,
|
REJECTED: -1,
|
||||||
};
|
};
|
||||||
@ -73,6 +75,7 @@ export const ApprovalStatusEnums = [
|
|||||||
{ value: APPROVAL_ACTION_STATUS.PROCESSING, label: `Processing`, color: 'gold' },
|
{ value: APPROVAL_ACTION_STATUS.PROCESSING, label: `Processing`, color: 'gold' },
|
||||||
{ value: APPROVAL_ACTION_STATUS.APPROVED, label: `Approved`, color: 'green' },
|
{ value: APPROVAL_ACTION_STATUS.APPROVED, label: `Approved`, color: 'green' },
|
||||||
{ value: APPROVAL_ACTION_STATUS.REJECTED, label: `Rejected`, color: 'red' },
|
{ value: APPROVAL_ACTION_STATUS.REJECTED, label: `Rejected`, color: 'red' },
|
||||||
|
{ value: APPROVAL_ACTION_STATUS.RESUBMIT, label: 'ReSubmit', color: 'blue', editable: true },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const ApprovalPriorityType = [
|
export const ApprovalPriorityType = [
|
||||||
|
@ -16,8 +16,6 @@ import { UserInitiationsItem } from './component/UserInitiationsItem';
|
|||||||
|
|
||||||
import '../style/style.css';
|
import '../style/style.css';
|
||||||
|
|
||||||
import { createGlobalStyle } from '@tachybase/client';
|
|
||||||
|
|
||||||
export const InitiationsBlockContext = createContext({});
|
export const InitiationsBlockContext = createContext({});
|
||||||
|
|
||||||
export const InitiationsBlock = observer((props) => {
|
export const InitiationsBlock = observer((props) => {
|
||||||
@ -67,28 +65,6 @@ export const InitiationsBlock = observer((props) => {
|
|||||||
setContextFilter(filter);
|
setContextFilter(filter);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Tabs.Tab title="发起申请" key="initiations">
|
|
||||||
<SchemaComponent
|
|
||||||
components={{
|
|
||||||
InitiationsItem,
|
|
||||||
}}
|
|
||||||
schema={{
|
|
||||||
type: 'void',
|
|
||||||
name: 'initiations',
|
|
||||||
title: t('Initiations'),
|
|
||||||
'x-settings': 'ApprovalSettings',
|
|
||||||
'x-component': 'InitiationsItem',
|
|
||||||
'x-component-props': {
|
|
||||||
...props,
|
|
||||||
collectionName: 'workflows',
|
|
||||||
settingBlock: true,
|
|
||||||
tabKey: 'initiations',
|
|
||||||
parantUid: fieldSchema['x-uid'],
|
|
||||||
parantParams: props['params'],
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Tabs.Tab>
|
|
||||||
<Tabs.Tab title="我的发起" key="userInitiations">
|
<Tabs.Tab title="我的发起" key="userInitiations">
|
||||||
<SchemaComponent
|
<SchemaComponent
|
||||||
components={{
|
components={{
|
||||||
@ -111,6 +87,28 @@ export const InitiationsBlock = observer((props) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Tabs.Tab>
|
</Tabs.Tab>
|
||||||
|
<Tabs.Tab title="发起申请" key="initiations">
|
||||||
|
<SchemaComponent
|
||||||
|
components={{
|
||||||
|
InitiationsItem,
|
||||||
|
}}
|
||||||
|
schema={{
|
||||||
|
type: 'void',
|
||||||
|
name: 'initiations',
|
||||||
|
title: t('Initiations'),
|
||||||
|
'x-settings': 'ApprovalSettings',
|
||||||
|
'x-component': 'InitiationsItem',
|
||||||
|
'x-component-props': {
|
||||||
|
...props,
|
||||||
|
collectionName: 'workflows',
|
||||||
|
settingBlock: true,
|
||||||
|
tabKey: 'initiations',
|
||||||
|
parantUid: fieldSchema['x-uid'],
|
||||||
|
parantParams: props['params'],
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Tabs.Tab>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
</InitiationsBlockContext.Provider>
|
</InitiationsBlockContext.Provider>
|
||||||
</BlockItem>
|
</BlockItem>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { useAPIClient, useCurrentUserContext } from '@tachybase/client';
|
import { useAPIClient, useCollectionManager, useCompile, useCurrentUserContext } from '@tachybase/client';
|
||||||
import { observer } from '@tachybase/schema';
|
import { observer } from '@tachybase/schema';
|
||||||
|
import { dayjs } from '@tachybase/utils/client';
|
||||||
|
|
||||||
import { useDeepCompareEffect } from 'ahooks';
|
import { useDeepCompareEffect } from 'ahooks';
|
||||||
import { Badge, Empty, List, Space, Tag } from 'antd-mobile';
|
import { Badge, Empty, List, Space, Tag } from 'antd-mobile';
|
||||||
@ -20,8 +21,10 @@ export const ApprovalItem = observer((props) => {
|
|||||||
const user = useCurrentUserContext();
|
const user = useCurrentUserContext();
|
||||||
const contextFilter = useContext(InitiationsBlockContext);
|
const contextFilter = useContext(InitiationsBlockContext);
|
||||||
const inputFilter = contextFilter['key'] === 'userInitiations' ? contextFilter['inputFilter'] : '';
|
const inputFilter = contextFilter['key'] === 'userInitiations' ? contextFilter['inputFilter'] : '';
|
||||||
|
const cm = useCollectionManager();
|
||||||
|
const compile = useCompile();
|
||||||
useDeepCompareEffect(() => {
|
useDeepCompareEffect(() => {
|
||||||
changService(api, setData, user, { ...params?.[tabKey], ...filter }, t, setDefaultData);
|
changService(api, setData, user, { ...params?.[tabKey], ...filter }, t, setDefaultData, cm, compile);
|
||||||
}, [filter, params]);
|
}, [filter, params]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (inputFilter && defaultData.length) {
|
if (inputFilter && defaultData.length) {
|
||||||
@ -40,7 +43,7 @@ export const ApprovalItem = observer((props) => {
|
|||||||
<List.Item
|
<List.Item
|
||||||
key={index}
|
key={index}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate(`/mobile/approval/${item.id}/page`);
|
navigate(`/mobile/approval/${item.latestExecutionId}/page`);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* <Badge color="#6ac3ff" content={Badge.dot} style={{ '--right': '100%' }}> */}
|
{/* <Badge color="#6ac3ff" content={Badge.dot} style={{ '--right': '100%' }}> */}
|
||||||
@ -54,7 +57,9 @@ export const ApprovalItem = observer((props) => {
|
|||||||
</Tag>
|
</Tag>
|
||||||
</Space>
|
</Space>
|
||||||
{/* </Badge> */}
|
{/* </Badge> */}
|
||||||
<Space block> 事由:{item.reason}</Space>
|
{item.reason?.map((reasonItem, index) => {
|
||||||
|
return <Space block key={index}>{`${reasonItem.label}:${reasonItem.value}`}</Space>;
|
||||||
|
})}
|
||||||
</List.Item>
|
</List.Item>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
@ -71,7 +76,7 @@ const approvalTodoListStatus = (item, t) => {
|
|||||||
return ApprovalStatusEnums.find((value) => value.value === status);
|
return ApprovalStatusEnums.find((value) => value.value === status);
|
||||||
};
|
};
|
||||||
|
|
||||||
const changService = (api, setData, user, filter, t, setDefaultData) => {
|
const changService = (api, setData, user, filter, t, setDefaultData, cm, compile) => {
|
||||||
api
|
api
|
||||||
.request({
|
.request({
|
||||||
url: 'approvals:listCentralized',
|
url: 'approvals:listCentralized',
|
||||||
@ -82,13 +87,27 @@ const changService = (api, setData, user, filter, t, setDefaultData) => {
|
|||||||
const priorityType = ApprovalPriorityType.find((priorityItem) => priorityItem.value === item.data.priority);
|
const priorityType = ApprovalPriorityType.find((priorityItem) => priorityItem.value === item.data.priority);
|
||||||
const statusType = approvalTodoListStatus(item, t);
|
const statusType = approvalTodoListStatus(item, t);
|
||||||
const categoryTitle = item.workflow.title.replace('审批流:', '');
|
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 field = cm.getCollectionField(`${collectionName}.${key}`);
|
||||||
|
let resonValue = value;
|
||||||
|
if (field.type === 'date' && value) {
|
||||||
|
resonValue = dayjs(value as string).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
label: compile(field?.uiSchema?.title || key),
|
||||||
|
value:
|
||||||
|
(Object.prototype.toString.call(value) === '[object Object]' ? resonValue?.['name'] : resonValue) || '',
|
||||||
|
};
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
title: `${user.data.data.nickname}的${categoryTitle}`,
|
title: `${user.data.data.nickname}的${categoryTitle}`,
|
||||||
categoryTitle: categoryTitle,
|
categoryTitle: categoryTitle,
|
||||||
statusTitle: t(statusType.label),
|
statusTitle: t(statusType.label),
|
||||||
statusColor: statusType.color,
|
statusColor: statusType.color,
|
||||||
reason: item.data.reason || item.data.reason_pay,
|
reason: summary || [],
|
||||||
priorityTitle: priorityType.label,
|
priorityTitle: priorityType.label,
|
||||||
priorityColor: priorityType.color,
|
priorityColor: priorityType.color,
|
||||||
};
|
};
|
||||||
|
@ -103,6 +103,7 @@ export const ViewActionInitiationsContent = () => {
|
|||||||
scope={{
|
scope={{
|
||||||
useSubmit: useCreateSubmit,
|
useSubmit: useCreateSubmit,
|
||||||
useWithdrawAction,
|
useWithdrawAction,
|
||||||
|
useActionResubmit,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -111,6 +112,10 @@ export const ViewActionInitiationsContent = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function useActionResubmit() {
|
||||||
|
return { run() {} };
|
||||||
|
}
|
||||||
|
|
||||||
export function WithdrawActionProvider() {
|
export function WithdrawActionProvider() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,9 @@ import '../../style/style.css';
|
|||||||
|
|
||||||
import { MobileProvider } from '@tachybase/plugin-mobile-client/client';
|
import { MobileProvider } from '@tachybase/plugin-mobile-client/client';
|
||||||
|
|
||||||
|
import { useActionResubmit } from '../hook/useActionResubmit';
|
||||||
|
import { ProviderActionResubmit } from '../provider/ActionResubmit.provider';
|
||||||
|
|
||||||
export const ViewActionUserInitiationsContent = () => {
|
export const ViewActionUserInitiationsContent = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -41,7 +44,7 @@ export const ViewActionUserInitiationsContent = () => {
|
|||||||
.request({
|
.request({
|
||||||
url: 'approvalExecutions:get',
|
url: 'approvalExecutions:get',
|
||||||
params: {
|
params: {
|
||||||
filter: { approvalId: id },
|
filterByTk: id,
|
||||||
appends: [
|
appends: [
|
||||||
'execution',
|
'execution',
|
||||||
'execution.jobs',
|
'execution.jobs',
|
||||||
@ -70,7 +73,7 @@ export const ViewActionUserInitiationsContent = () => {
|
|||||||
.catch(() => {
|
.catch(() => {
|
||||||
console.error;
|
console.error;
|
||||||
});
|
});
|
||||||
}, []);
|
}, [id]);
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const { approval, execution, ...approvalValue } = recordData || {};
|
const { approval, execution, ...approvalValue } = recordData || {};
|
||||||
const { workflow } = approval || {};
|
const { workflow } = approval || {};
|
||||||
@ -147,6 +150,7 @@ const UserInitiationsComponent = (applyDetail) => {
|
|||||||
WithdrawActionProvider,
|
WithdrawActionProvider,
|
||||||
DetailsBlockProvider,
|
DetailsBlockProvider,
|
||||||
MobileProvider,
|
MobileProvider,
|
||||||
|
ProviderActionResubmit,
|
||||||
}}
|
}}
|
||||||
scope={{
|
scope={{
|
||||||
useForm,
|
useForm,
|
||||||
@ -155,6 +159,7 @@ const UserInitiationsComponent = (applyDetail) => {
|
|||||||
useDetailsBlockProps: useFormBlockContext,
|
useDetailsBlockProps: useFormBlockContext,
|
||||||
useWithdrawAction,
|
useWithdrawAction,
|
||||||
useDestroyAction,
|
useDestroyAction,
|
||||||
|
useActionResubmit,
|
||||||
}}
|
}}
|
||||||
schema={formContextSchema}
|
schema={formContextSchema}
|
||||||
/>
|
/>
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
import { useAPIClient } from '@tachybase/client';
|
||||||
|
import { useFlowContext } from '@tachybase/plugin-workflow/client';
|
||||||
|
import { useField } from '@tachybase/schema';
|
||||||
|
|
||||||
|
import { Toast } from 'antd-mobile';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { APPROVAL_ACTION_STATUS, APPROVAL_STATUS } from '../../constants';
|
||||||
|
import { useContextApprovalExecution } from '../../context/ApprovalExecution';
|
||||||
|
|
||||||
|
// 重新发起
|
||||||
|
export function useActionResubmit() {
|
||||||
|
const field = useField();
|
||||||
|
const api = useAPIClient();
|
||||||
|
const { approval } = useContextApprovalExecution();
|
||||||
|
const { workflow } = approval;
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return {
|
||||||
|
async run() {
|
||||||
|
try {
|
||||||
|
field.data = field.data ?? {};
|
||||||
|
|
||||||
|
field.data.loading = true;
|
||||||
|
|
||||||
|
const appendsConfigs = [...workflow.config.appends];
|
||||||
|
const summaryConfigs = [...workflow.config.summary];
|
||||||
|
const appends = _.intersection(appendsConfigs, summaryConfigs);
|
||||||
|
|
||||||
|
const { data: approvalData } = await api.resource('approvals').get({
|
||||||
|
filterByTk: approval.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { collectionName, data, workflowId } = approvalData.data;
|
||||||
|
|
||||||
|
const newData = _.omit(data, ['id', 'createdAt', 'updatedAt', 'createdBy', 'updatedBy']);
|
||||||
|
|
||||||
|
api
|
||||||
|
.resource('approvals')
|
||||||
|
.reSubmit({
|
||||||
|
values: {
|
||||||
|
collectionName: collectionName,
|
||||||
|
data: newData,
|
||||||
|
status: APPROVAL_ACTION_STATUS.RESUBMIT,
|
||||||
|
workflowId: workflowId,
|
||||||
|
collectionAppends: appends,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res?.data?.data) {
|
||||||
|
Toast.show({
|
||||||
|
icon: 'success',
|
||||||
|
content: '申请成功',
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate(-1);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
return;
|
||||||
|
});
|
||||||
|
field.data.loading = false;
|
||||||
|
} catch (v) {
|
||||||
|
if (field.data) {
|
||||||
|
field.data.loading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
@ -36,7 +36,9 @@ export function useCreateSubmit() {
|
|||||||
content: '提交成功',
|
content: '提交成功',
|
||||||
});
|
});
|
||||||
from.reset();
|
from.reset();
|
||||||
navigate(`/mobile/approval/${res.data.data.id}/page`);
|
setTimeout(() => {
|
||||||
|
navigate(-1);
|
||||||
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
field.data.loading = false;
|
field.data.loading = false;
|
||||||
|
@ -3,31 +3,34 @@ import { useField, useForm } from '@tachybase/schema';
|
|||||||
|
|
||||||
import { Toast } from 'antd-mobile';
|
import { Toast } from 'antd-mobile';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { useContextApprovalExecution } from '../../context/ApprovalExecution';
|
import { useContextApprovalExecution } from '../../context/ApprovalExecution';
|
||||||
import { useContextApprovalStatus } from '../provider/ApplyActionStatus';
|
import { useContextApprovalStatus } from '../provider/ApplyActionStatus';
|
||||||
|
|
||||||
export function useUpdateSubmit() {
|
export function useUpdateSubmit() {
|
||||||
const from = useForm();
|
const form = useForm();
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const { approval } = useContextApprovalExecution();
|
const { approval } = useContextApprovalExecution();
|
||||||
const { setSubmitted } = useActionContext() as any;
|
const { setSubmitted } = useActionContext() as any;
|
||||||
const { workflow, id } = approval;
|
const { workflow, id } = approval;
|
||||||
const contextApprovalStatus = useContextApprovalStatus();
|
const contextApprovalStatus = useContextApprovalStatus();
|
||||||
const apiClient = useAPIClient();
|
const apiClient = useAPIClient();
|
||||||
|
const navigate = useNavigate();
|
||||||
return {
|
return {
|
||||||
async run() {
|
async run() {
|
||||||
try {
|
try {
|
||||||
from.submit();
|
form.submit();
|
||||||
|
|
||||||
_.set(field, ['data', 'loading'], true);
|
_.set(field, ['data', 'loading'], true);
|
||||||
|
|
||||||
const res = await apiClient.resource('approvals').update({
|
const res = await apiClient.resource('approvals').update({
|
||||||
filterByTk: id,
|
filterByTk: id,
|
||||||
values: {
|
values: {
|
||||||
collectionName: workflow.config.collection,
|
collectionName: workflow.config.collection,
|
||||||
data: from.values,
|
data: form.values,
|
||||||
status: contextApprovalStatus,
|
status: contextApprovalStatus,
|
||||||
|
schemaFormId: workflow.config.applyForm,
|
||||||
|
summaryConfig: workflow.config.summary,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
@ -36,7 +39,7 @@ export function useUpdateSubmit() {
|
|||||||
content: '处理成功',
|
content: '处理成功',
|
||||||
});
|
});
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
location.reload();
|
navigate(-1);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
setSubmitted(true);
|
setSubmitted(true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,34 +2,34 @@ import { useActionContext, useAPIClient } from '@tachybase/client';
|
|||||||
import { useField } from '@tachybase/schema';
|
import { useField } from '@tachybase/schema';
|
||||||
|
|
||||||
import { Toast } from 'antd-mobile';
|
import { Toast } from 'antd-mobile';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { useContextApprovalExecution } from '../../context/ApprovalExecution';
|
import { useContextApprovalExecution } from '../../context/ApprovalExecution';
|
||||||
|
|
||||||
// 撤回
|
// 撤回
|
||||||
export function useWithdrawAction() {
|
export function useWithdrawAction() {
|
||||||
const field = useField();
|
const field = useField();
|
||||||
const { setVisible, setSubmitted } = useActionContext() as any;
|
|
||||||
const { approval } = useContextApprovalExecution();
|
const { approval } = useContextApprovalExecution();
|
||||||
const api = useAPIClient();
|
const api = useAPIClient();
|
||||||
|
const navigate = useNavigate();
|
||||||
return {
|
return {
|
||||||
async run() {
|
async run() {
|
||||||
try {
|
try {
|
||||||
field.data = field.data ?? {};
|
field.data = field.data ?? {};
|
||||||
field.data.loading = true;
|
field.data.loading = true;
|
||||||
|
|
||||||
const res = await api.resource('approvals').withdraw({
|
const res = await await api.resource('approvals').withdraw({
|
||||||
filterByTk: approval.id,
|
filterByTk: approval.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.status === 202) {
|
if (res.status === 202) {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
icon: 'success',
|
icon: 'success',
|
||||||
content: '撤回成功',
|
content: '撤回成功',
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
location.reload();
|
navigate(-1);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
setSubmitted(true);
|
|
||||||
} else {
|
} else {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
icon: 'fail',
|
icon: 'fail',
|
||||||
|
@ -14,6 +14,7 @@ export function ActionBarProvider(props) {
|
|||||||
APPROVAL_ACTION_STATUS.DRAFT,
|
APPROVAL_ACTION_STATUS.DRAFT,
|
||||||
APPROVAL_ACTION_STATUS.RETURNED,
|
APPROVAL_ACTION_STATUS.RETURNED,
|
||||||
APPROVAL_ACTION_STATUS.SUBMITTED,
|
APPROVAL_ACTION_STATUS.SUBMITTED,
|
||||||
|
APPROVAL_ACTION_STATUS.RESUBMIT,
|
||||||
].includes(status);
|
].includes(status);
|
||||||
|
|
||||||
if (!isSameId || !isSameExcutionId || !isExcutionDid) {
|
if (!isSameId || !isSameExcutionId || !isExcutionDid) {
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
import { useCurrentUserContext } from '@tachybase/client';
|
||||||
|
|
||||||
|
import { useContextApprovalExecution } from '../../context/ApprovalExecution';
|
||||||
|
|
||||||
|
export function ProviderActionResubmit(props) {
|
||||||
|
const { data } = useCurrentUserContext();
|
||||||
|
const { approval } = useContextApprovalExecution();
|
||||||
|
const { status, createdById } = approval;
|
||||||
|
|
||||||
|
const isSameId = data.data.id === createdById;
|
||||||
|
// const isEnabledWithdraw = workflow.enabled && workflow.config.withdrawable;
|
||||||
|
// const isNotDraft = status !== APPROVAL_STATUS.DRAFT;
|
||||||
|
|
||||||
|
if (isSameId) {
|
||||||
|
return props.children;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
@ -18,7 +18,11 @@ export function ApplyActionStatusProvider(props) {
|
|||||||
const { data } = useCurrentUserContext();
|
const { data } = useCurrentUserContext();
|
||||||
const isSameId = data.data.id === createdById;
|
const isSameId = data.data.id === createdById;
|
||||||
const isEnbled = workflow.enabled;
|
const isEnbled = workflow.enabled;
|
||||||
const isStatusDid = [APPROVAL_ACTION_STATUS.DRAFT, APPROVAL_ACTION_STATUS.RETURNED].includes(status);
|
const isStatusDid = [
|
||||||
|
APPROVAL_ACTION_STATUS.DRAFT,
|
||||||
|
APPROVAL_ACTION_STATUS.RETURNED,
|
||||||
|
APPROVAL_ACTION_STATUS.RESUBMIT,
|
||||||
|
].includes(status);
|
||||||
|
|
||||||
if (isSameId && isEnbled && isStatusDid) {
|
if (isSameId && isEnbled && isStatusDid) {
|
||||||
return <ContextApprovalStatus.Provider value={value}>{children}</ContextApprovalStatus.Provider>;
|
return <ContextApprovalStatus.Provider value={value}>{children}</ContextApprovalStatus.Provider>;
|
||||||
|
@ -105,7 +105,7 @@ const changeApprovalRecordsService = (api, params, filter, cm, compile, t, setDa
|
|||||||
const field = cm.getCollectionField(`${collectionName}.${key}`);
|
const field = cm.getCollectionField(`${collectionName}.${key}`);
|
||||||
let resonValue = value;
|
let resonValue = value;
|
||||||
if (field.type === 'date' && value) {
|
if (field.type === 'date' && value) {
|
||||||
resonValue = dayjs(value as string).format('YYYY-MM-DD');
|
resonValue = dayjs(value as string).format('YYYY-MM-DD HH:mm:ss');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -220,7 +220,7 @@ export const changeWorkflowNoticeService = (api, t, cm, compile, input, setData,
|
|||||||
const field = cm.getCollectionField(`${collectionName}.${key}`);
|
const field = cm.getCollectionField(`${collectionName}.${key}`);
|
||||||
let resonValue = value;
|
let resonValue = value;
|
||||||
if (field.type === 'date' && value) {
|
if (field.type === 'date' && value) {
|
||||||
resonValue = dayjs(value as string).format('YYYY-MM-DD');
|
resonValue = dayjs(value as string).format('YYYY-MM-DD HH:mm:ss');
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
label: compile(field?.uiSchema?.title || key),
|
label: compile(field?.uiSchema?.title || key),
|
||||||
|
@ -67,5 +67,6 @@
|
|||||||
"UserInitiations":"UserInitiations",
|
"UserInitiations":"UserInitiations",
|
||||||
"Processed":"Processed",
|
"Processed":"Processed",
|
||||||
"Duplicate":"Duplicate",
|
"Duplicate":"Duplicate",
|
||||||
"Executed":"Executed"
|
"Executed":"Executed",
|
||||||
|
"ReSubmit":"ReSubmit"
|
||||||
}
|
}
|
||||||
|
@ -98,5 +98,6 @@
|
|||||||
"Manually canceled whole execution when waiting.": "等待时被手动取消整个执行。",
|
"Manually canceled whole execution when waiting.": "等待时被手动取消整个执行。",
|
||||||
"Rejected from a manual node.": "被人工节点拒绝继续。",
|
"Rejected from a manual node.": "被人工节点拒绝继续。",
|
||||||
"General failed but should do another try.": "执行失败,需重试。",
|
"General failed but should do another try.": "执行失败,需重试。",
|
||||||
"Queueing": "队列中"
|
"Queueing": "队列中",
|
||||||
|
"ReSubmit":"重新提交"
|
||||||
}
|
}
|
||||||
|
@ -80,10 +80,12 @@ export const AntdSelect = observer((props) => {
|
|||||||
const checkedPopup = () => {
|
const checkedPopup = () => {
|
||||||
if (collectionName) {
|
if (collectionName) {
|
||||||
run();
|
run();
|
||||||
} else {
|
} else if (fieldSchema['x-collection-field']) {
|
||||||
const field = cm.getCollectionField(fieldSchema['x-collection-field']);
|
const field = cm.getCollectionField(fieldSchema['x-collection-field']);
|
||||||
const data = field.uiSchema?.enum;
|
const data = field.uiSchema?.enum;
|
||||||
setOptions(data);
|
setOptions(data);
|
||||||
|
} else {
|
||||||
|
setOptions(fieldSchema.enum);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -122,7 +124,7 @@ export const AntdSelect = observer((props) => {
|
|||||||
addData(data);
|
addData(data);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<CollectionProvider name={collectionName || collection.name}>
|
<CollectionProvider name={collectionName || collection?.name}>
|
||||||
<BlockItem>
|
<BlockItem>
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
Loading…
Reference in New Issue
Block a user