大量逻辑代码
This commit is contained in:
parent
9734af84e0
commit
288426babb
|
|
@ -0,0 +1,4 @@
|
|||
import { BRC } from '../types/RuntimeCxt';
|
||||
export type AspectDict = {
|
||||
test: (params: string, context: BRC) => Promise<any>;
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export {};
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { AspectDict } from './AspectDict';
|
||||
declare const aspectDict: AspectDict;
|
||||
export default aspectDict;
|
||||
export { AspectDict, };
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { test } from './sample';
|
||||
const aspectDict = {
|
||||
test,
|
||||
};
|
||||
export default aspectDict;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
import { BRC } from '../types/RuntimeCxt';
|
||||
export declare function test(params: string, context: BRC): Promise<string>;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
export async function test(params, context) {
|
||||
return 'hello world';
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { Checker } from 'oak-domain/lib/types/Auth';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import { RuntimeCxt } from '../types/RuntimeCxt';
|
||||
declare const checkers: Checker<EntityDict, 'account', RuntimeCxt>[];
|
||||
export default checkers;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const checkers = [];
|
||||
export default checkers;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { Checker } from 'oak-domain/lib/types/Auth';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import { RuntimeCxt } from '../types/RuntimeCxt';
|
||||
declare const checkers: Checker<EntityDict, 'accountOper', RuntimeCxt>[];
|
||||
export default checkers;
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
import assert from 'assert';
|
||||
import { OakInputIllegalException } from 'oak-domain/lib/types';
|
||||
const checkers = [
|
||||
{
|
||||
entity: 'accountOper',
|
||||
action: 'create',
|
||||
type: 'row',
|
||||
filter: {
|
||||
account: {
|
||||
ableState: 'enabled',
|
||||
},
|
||||
},
|
||||
errMsg: 'account.update.accountDisabled',
|
||||
},
|
||||
{
|
||||
entity: 'accountOper',
|
||||
action: 'create',
|
||||
type: 'data',
|
||||
checker(data, context) {
|
||||
assert(!(data instanceof Array));
|
||||
const { type, totalPlus, availPlus } = data;
|
||||
if (typeof totalPlus !== 'number') {
|
||||
throw new OakInputIllegalException('accountOper', ['totalPlus'], 'accountOper中的totalPlus不是数字');
|
||||
}
|
||||
if (typeof availPlus !== 'number') {
|
||||
throw new OakInputIllegalException('accountOper', ['availPlus'], 'accountOper中的availPlus不是数字');
|
||||
}
|
||||
switch (type) {
|
||||
case 'consume': {
|
||||
if (totalPlus >= 0 || availPlus > 0 || totalPlus > availPlus) {
|
||||
throw new OakInputIllegalException('accountOper', ['availPlus'], 'accountOper为consume时,其totalPlus/availPlus必须为0或负数,且totalPlus的绝对值要更大');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'deposit': {
|
||||
if (totalPlus < 0 || availPlus < 0 || totalPlus !== availPlus) {
|
||||
throw new OakInputIllegalException('accountOper', ['availPlus'], 'accountOper为deposit时,其totalPlus/availPlus必须为正数且相等');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'loan': {
|
||||
if (totalPlus !== 0 || availPlus >= 0) {
|
||||
throw new OakInputIllegalException('accountOper', ['availPlus'], 'accountOper为loan时,其totalPlus必须为0,且availPlus必须为负数');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'repay': {
|
||||
if (totalPlus !== 0 || availPlus <= 0) {
|
||||
throw new OakInputIllegalException('accountOper', ['availPlus'], 'accountOper为repay时,其totalPlus必须为0,且availPlus必须为正数');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'withdraw': {
|
||||
if (totalPlus >= 0 || availPlus >= 0 || totalPlus !== availPlus) {
|
||||
throw new OakInputIllegalException('accountOper', ['availPlus'], 'accountOper为withdraw时,其totalPlus和availPlus必须为不相等的负数');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'withdrawBack': {
|
||||
if (totalPlus <= 0 || availPlus <= 0 || totalPlus !== availPlus) {
|
||||
throw new OakInputIllegalException('accountOper', ['availPlus'], 'accountOper为withdraw时,其totalPlus和availPlus必须为不相等的正数');
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
export default checkers;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { EntityDict } from '../oak-app-domain/index';
|
||||
import { Checker } from 'oak-domain/lib/types';
|
||||
import { RuntimeCxt } from '../types/RuntimeCxt';
|
||||
declare const checkers: Checker<EntityDict, keyof EntityDict, RuntimeCxt>[];
|
||||
export default checkers;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import aoCheckers from './accountOper';
|
||||
const checkers = [
|
||||
...aoCheckers,
|
||||
];
|
||||
export default checkers;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { Checker } from 'oak-domain/lib/types/Auth';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import { RuntimeCxt } from '../types/RuntimeCxt';
|
||||
declare const checkers: Checker<EntityDict, 'pay', RuntimeCxt>[];
|
||||
export default checkers;
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import { OakInputIllegalException } from 'oak-domain/lib/types';
|
||||
import { PAY_CHANNEL_ACCOUNT_NAME } from '../types/PayConfig';
|
||||
const checkers = [
|
||||
{
|
||||
entity: 'pay',
|
||||
type: 'logical',
|
||||
action: 'create',
|
||||
checker(operation, context) {
|
||||
const { data } = operation;
|
||||
data.refunded = 0;
|
||||
data.paid = 0;
|
||||
data.applicationId = context.getApplicationId();
|
||||
},
|
||||
},
|
||||
{
|
||||
entity: 'pay',
|
||||
type: 'data',
|
||||
action: 'create',
|
||||
checker(data) {
|
||||
const { channel, price, orderId, accountId } = data;
|
||||
if (price <= 0) {
|
||||
throw new OakInputIllegalException('pay', ['price'], '支付金额必须大于0');
|
||||
}
|
||||
if (!orderId) {
|
||||
// 充值类订单
|
||||
if (!accountId) {
|
||||
throw new OakInputIllegalException('pay', ['accountId'], '充值类支付必须指定accountId');
|
||||
}
|
||||
else if (channel === PAY_CHANNEL_ACCOUNT_NAME) {
|
||||
throw new OakInputIllegalException('pay', ['channel'], '充值类支付不能使用帐户支付');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (channel === PAY_CHANNEL_ACCOUNT_NAME) {
|
||||
if (!accountId) {
|
||||
throw new OakInputIllegalException('pay', ['accountId'], '使用account支付必须指向accountId');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
entity: 'pay',
|
||||
type: 'logicalData',
|
||||
action: 'create',
|
||||
checker(operation, context) {
|
||||
const { data } = operation;
|
||||
const { orderId, price } = data;
|
||||
if (orderId) {
|
||||
// 所有已经支付和正在支付的pay之和不能超过订单总和
|
||||
const order = context.select('order', {
|
||||
data: {
|
||||
id: 1,
|
||||
price: 1,
|
||||
pay$order: {
|
||||
$entity: 'pay',
|
||||
data: {
|
||||
id: 1,
|
||||
price: 1,
|
||||
},
|
||||
filter: {
|
||||
iState: {
|
||||
$in: ['paying', 'paid'],
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
id: orderId,
|
||||
}
|
||||
}, {});
|
||||
const checkPays = (order) => {
|
||||
const { price: orderPrice, pay$order: pays } = order;
|
||||
let pricePaying = 0;
|
||||
pays.forEach((pay) => pricePaying += pay.price);
|
||||
if (pricePaying + price > orderPrice) {
|
||||
throw new OakInputIllegalException('pay', ['price'], 'pay.create.priceOverflow');
|
||||
}
|
||||
};
|
||||
if (order instanceof Promise) {
|
||||
return order.then(([o]) => checkPays(o));
|
||||
}
|
||||
return checkPays(order[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
export default checkers;
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* 抽象组件在业务层根据EntityDict的重新声明
|
||||
* by Xc 20230807
|
||||
*/
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import { ReactComponentProps, ColumnProps, RowWithActions, OakExtraActionProps, OakAbsAttrDef, onActionFnDef, ListButtonProps, OakAbsAttrUpsertDef } from 'oak-frontend-base';
|
||||
declare const FilterPanel: <T extends keyof EntityDict>(props: ReactComponentProps<EntityDict, T, false, {
|
||||
entity: T;
|
||||
columns: ColumnProps<EntityDict, T>[];
|
||||
}>) => React.ReactElement;
|
||||
declare const List: <T extends keyof EntityDict>(props: ReactComponentProps<EntityDict, T, false, {
|
||||
entity: T;
|
||||
extraActions: OakExtraActionProps[] | ((row: RowWithActions<EntityDict, T>) => OakExtraActionProps[]);
|
||||
onAction: onActionFnDef;
|
||||
disabledOp: boolean;
|
||||
attributes: OakAbsAttrDef[];
|
||||
data: RowWithActions<EntityDict, T>[];
|
||||
loading: boolean;
|
||||
tablePagination?: any;
|
||||
rowSelection?: {
|
||||
type: "checkbox" | "radio";
|
||||
selectedRowKeys?: string[] | undefined;
|
||||
onChange: (selectedRowKeys: string[], row: RowWithActions<EntityDict, T>[], info?: {
|
||||
type: "multiple" | "none" | "single";
|
||||
} | undefined) => void;
|
||||
} | undefined;
|
||||
hideHeader: boolean;
|
||||
size?: "small" | "middle" | "large" | undefined;
|
||||
scroll?: any;
|
||||
locale?: any;
|
||||
}>) => React.ReactElement;
|
||||
declare const ListPro: <T extends keyof EntityDict>(props: {
|
||||
title?: any;
|
||||
extraContent?: any;
|
||||
hideDefaultButtons?: boolean | undefined;
|
||||
buttonGroup?: ListButtonProps[] | undefined;
|
||||
onReload?: (() => void) | undefined;
|
||||
entity: T;
|
||||
extraActions?: OakExtraActionProps[] | ((row: RowWithActions<EntityDict, T>) => OakExtraActionProps[]) | undefined;
|
||||
onAction?: onActionFnDef | undefined;
|
||||
disabledOp?: boolean | undefined;
|
||||
attributes: OakAbsAttrDef[];
|
||||
data: RowWithActions<EntityDict, T>[];
|
||||
loading?: boolean | undefined;
|
||||
tablePagination?: any;
|
||||
rowSelection?: {
|
||||
type: "checkbox" | "radio";
|
||||
selectedRowKeys?: string[] | undefined;
|
||||
onChange: (selectedRowKeys: string[], row: RowWithActions<EntityDict, T>[], info?: {
|
||||
type: "multiple" | "none" | "single";
|
||||
} | undefined) => void;
|
||||
} | undefined;
|
||||
disableSerialNumber?: boolean | undefined;
|
||||
size?: "small" | "middle" | "large" | undefined;
|
||||
scroll?: any;
|
||||
locale?: any;
|
||||
}) => React.ReactElement;
|
||||
declare const Detail: <T extends keyof EntityDict>(props: ReactComponentProps<EntityDict, T, false, {
|
||||
column?: number | Record<Breakpoint, number> | undefined;
|
||||
entity: T;
|
||||
attributes: OakAbsAttrDef[];
|
||||
data: Partial<EntityDict[T]["Schema"]>;
|
||||
title?: string | undefined;
|
||||
bordered?: boolean | undefined;
|
||||
layout?: "vertical" | "horizontal" | undefined;
|
||||
}>) => React.ReactElement;
|
||||
declare const Upsert: <T extends keyof EntityDict>(props: ReactComponentProps<EntityDict, T, false, {
|
||||
helps: Record<string, string>;
|
||||
entity: T;
|
||||
attributes: OakAbsAttrUpsertDef<EntityDict, T, string | number>[];
|
||||
data: EntityDict[T]["Schema"];
|
||||
layout: "vertical" | "horizontal";
|
||||
mode: "default" | "card";
|
||||
}>) => React.ReactElement;
|
||||
export { FilterPanel, List, ListPro, Detail, Upsert, ReactComponentProps, ColumnProps, RowWithActions, OakExtraActionProps, OakAbsAttrDef, onActionFnDef, };
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* 抽象组件在业务层根据EntityDict的重新声明
|
||||
* by Xc 20230807
|
||||
*/
|
||||
import AbsFilterPanel from 'oak-frontend-base/es/components/filterPanel';
|
||||
import AbsList from 'oak-frontend-base/es/components/list';
|
||||
import AbsListPro from 'oak-frontend-base/es/components/listPro';
|
||||
import AbsDetail from 'oak-frontend-base/es/components/detail';
|
||||
import AbsUpsert from 'oak-frontend-base/es/components/upsert';
|
||||
const FilterPanel = AbsFilterPanel;
|
||||
const List = AbsList;
|
||||
const ListPro = AbsListPro;
|
||||
const Detail = AbsDetail;
|
||||
const Upsert = AbsUpsert;
|
||||
export { FilterPanel, List, ListPro, Detail, Upsert, };
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
/// <reference types="wechat-miniprogram" />
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "system", false, WechatMiniprogram.Component.DataOption>) => React.ReactElement;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
export default OakComponent({
|
||||
entity: 'system',
|
||||
isList: false,
|
||||
projection: {
|
||||
id: 1,
|
||||
payConfig: 1,
|
||||
application$system: {
|
||||
$entity: 'application',
|
||||
data: {
|
||||
id: 1,
|
||||
payConfig: 1,
|
||||
name: 1,
|
||||
type: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
formData({ data, features }) {
|
||||
const operation = this.state.oakFullpath && this.features.runningTree.getOperations(this.state.oakFullpath);
|
||||
return {
|
||||
operation: operation && operation[0].operation,
|
||||
system: data,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"system": "系统配置",
|
||||
"appsBelow": "以下为application",
|
||||
"mayLossUpdate": "%{name}上的更新可能会丢失,请尽快保存"
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import React from 'react';
|
||||
import { RowWithActions, WebComponentProps } from 'oak-frontend-base';
|
||||
import { EntityDict } from '../../../oak-app-domain';
|
||||
/**
|
||||
*
|
||||
* @param channel [label, value]
|
||||
*/
|
||||
export declare function registerSystemPayChannel(channel: [string, string]): void;
|
||||
/**
|
||||
*
|
||||
* @param type
|
||||
* @param channel [label, value]
|
||||
*/
|
||||
export declare function registerApplicationPayChannel(type: EntityDict['application']['OpSchema']['type'], channel: [string, string]): void;
|
||||
export default function render(props: WebComponentProps<EntityDict, 'system', false, {
|
||||
system: RowWithActions<EntityDict, 'system'>;
|
||||
operation?: EntityDict['system']['Update'];
|
||||
}>): React.JSX.Element | null;
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Button, Row, Tabs } from 'antd';
|
||||
import Styles from './web.pc.module.less';
|
||||
import PayConfigUpsert from '../upsert';
|
||||
import { PAY_CHANNEL_WECHAT_JS_NAME, PAY_CHANNEL_WECHAT_H5_NAME, PAY_CHANNEL_WECHAT_MP_NAME, PAY_CHANNEL_WECHAT_NATIVE_NAME } from '../../../types/PayConfig';
|
||||
import { generateNewId } from 'oak-domain/lib/utils/uuid';
|
||||
const SystemPayChannels = []; // [label, value]
|
||||
const ApplicationPayChannels = {};
|
||||
/**
|
||||
*
|
||||
* @param channel [label, value]
|
||||
*/
|
||||
export function registerSystemPayChannel(channel) {
|
||||
SystemPayChannels.push(channel);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param type
|
||||
* @param channel [label, value]
|
||||
*/
|
||||
export function registerApplicationPayChannel(type, channel) {
|
||||
if (ApplicationPayChannels[type]) {
|
||||
ApplicationPayChannels[type].push(channel);
|
||||
}
|
||||
else {
|
||||
ApplicationPayChannels[type] = [channel];
|
||||
}
|
||||
}
|
||||
const DefaultApplicationPayChannels = {
|
||||
web: [PAY_CHANNEL_WECHAT_JS_NAME, PAY_CHANNEL_WECHAT_H5_NAME, PAY_CHANNEL_WECHAT_NATIVE_NAME],
|
||||
wechatMp: [PAY_CHANNEL_WECHAT_MP_NAME],
|
||||
wechatPublic: [PAY_CHANNEL_WECHAT_JS_NAME],
|
||||
};
|
||||
export default function render(props) {
|
||||
const { system, oakFullpath, operation, oakDirty } = props.data;
|
||||
const { t, update, setMessage, execute } = props.methods;
|
||||
const defaultApplicationPayChannelDict = {
|
||||
web: DefaultApplicationPayChannels.web.map(ele => [t(`payChannel::${ele}`), ele]),
|
||||
wechatMp: DefaultApplicationPayChannels.wechatMp.map(ele => [t(`payChannel::${ele}`), ele]),
|
||||
wechatPublic: DefaultApplicationPayChannels.wechatPublic.map(ele => [t(`payChannel::${ele}`), ele]),
|
||||
};
|
||||
const [key, setKey] = useState('');
|
||||
if (system && oakFullpath) {
|
||||
const { payConfig, application$system: applications } = system;
|
||||
return (<div className={Styles.container}>
|
||||
<Row justify="end" style={{ marginBottom: 12 }}>
|
||||
<Button type="primary" disabled={!oakDirty} onClick={() => execute()}>
|
||||
{t('common::action.save')}
|
||||
</Button>
|
||||
</Row>
|
||||
<Tabs tabPosition="left" items={[
|
||||
{
|
||||
label: (<div className={Styles.systemLabel}>
|
||||
{t('system')}
|
||||
</div>),
|
||||
key: 'system',
|
||||
children: (<PayConfigUpsert key="system" config={payConfig} update={(config) => update({ payConfig: config })} channels={SystemPayChannels.concat([[t('payChannel::ACCOUNT'), 'ACCOUNT'], [t('payChannel::OFFLINE'), 'OFFLINE']])} t={t}/>),
|
||||
},
|
||||
{
|
||||
label: (<div className={Styles.padding}>
|
||||
{t('appsBelow')}
|
||||
</div>),
|
||||
disabled: true,
|
||||
key: 'padding',
|
||||
},
|
||||
...applications.map((app) => {
|
||||
const { type, id, payConfig: appPayConfig } = app;
|
||||
return {
|
||||
key: id,
|
||||
label: (<div>
|
||||
{app.name}
|
||||
</div>),
|
||||
children: (<PayConfigUpsert key={id} config={appPayConfig} update={(config) => update({
|
||||
application$system: {
|
||||
id: generateNewId(),
|
||||
action: 'update',
|
||||
data: {
|
||||
payConfig: config,
|
||||
},
|
||||
filter: {
|
||||
id,
|
||||
}
|
||||
}
|
||||
})} channels={(defaultApplicationPayChannelDict[type] || []).concat(ApplicationPayChannels[type] || [])} t={t}/>),
|
||||
};
|
||||
})
|
||||
]} onTabClick={(activeKey) => {
|
||||
if (key && operation) {
|
||||
const { application$system } = operation.data;
|
||||
const { filter } = application$system;
|
||||
if (filter?.id === key) {
|
||||
setMessage({
|
||||
type: 'warning',
|
||||
content: t('mayLossUpdate', {
|
||||
name: applications?.find(ele => ele.id === key).name
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
setKey(activeKey);
|
||||
}}/>
|
||||
</div>);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
.container {
|
||||
background: var(--oak-bg-color-container);
|
||||
padding: 8px;
|
||||
height: 100%;
|
||||
|
||||
// .tabLabel {
|
||||
// writing-mode: vertical-rl;
|
||||
// letter-spacing: .2rem;
|
||||
// }
|
||||
.systemLabel {
|
||||
font-weight: bolder;
|
||||
}
|
||||
.padding {
|
||||
height: 10px;
|
||||
font-size: small;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { AccountPayConfig } from '../../../../types/PayConfig';
|
||||
import React from 'react';
|
||||
export default function Account(props: {
|
||||
config: AccountPayConfig;
|
||||
update: (config: AccountPayConfig) => void;
|
||||
t: (k: string) => string;
|
||||
}): React.JSX.Element;
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Alert } from 'antd';
|
||||
export default function Account(props) {
|
||||
const { t } = props;
|
||||
return <Alert type='info' message={t('tips')}/>;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"tips": "无需配置。开启后支持向系统帐户内充值,并使用帐户余额进行抵扣、支付等操作"
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import React from 'react';
|
||||
import { PayConfig, ConfigBase } from '../../../types/PayConfig';
|
||||
type FC<T extends ConfigBase> = React.FC<{
|
||||
config: T;
|
||||
update: (config: Omit<T, 'channel'>) => void;
|
||||
t: (k: string) => string;
|
||||
}>;
|
||||
export declare function registerPayConfigComponent<T extends ConfigBase>(channel: string, C: FC<T>): void;
|
||||
export default function Upsert(props: {
|
||||
config?: PayConfig | null;
|
||||
channels: [string, string][];
|
||||
update: (config: PayConfig) => void;
|
||||
t: (k: string) => string;
|
||||
}): React.JSX.Element;
|
||||
export {};
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Button, Alert, Modal, Space, Select, Card } from 'antd';
|
||||
import { CloseOutlined } from '@ant-design/icons';
|
||||
import classnames from 'classnames';
|
||||
import WechatPayConfigUpsert from './wechatPay';
|
||||
import AccountConfigUpsert from './account';
|
||||
import OfflineConfigUpsert from './offline';
|
||||
import assert from 'assert';
|
||||
import Styles from './web.pc.module.less';
|
||||
const PayConfigComponentsDict = {
|
||||
WECHAT_APP: WechatPayConfigUpsert,
|
||||
WECHAT_H5: WechatPayConfigUpsert,
|
||||
WECHAT_JS: WechatPayConfigUpsert,
|
||||
WECHAT_MP: WechatPayConfigUpsert,
|
||||
WECHAT_NATIVE: WechatPayConfigUpsert,
|
||||
ACCOUNT: AccountConfigUpsert,
|
||||
OFFLINE: OfflineConfigUpsert,
|
||||
};
|
||||
export function registerPayConfigComponent(channel, C) {
|
||||
PayConfigComponentsDict[channel] = C;
|
||||
}
|
||||
export default function Upsert(props) {
|
||||
const { config, channels, update, t } = props;
|
||||
const [open, setOpen] = useState(false);
|
||||
const AddButton = (<Button onClick={() => setOpen(true)} disabled={open}>
|
||||
{t('common::action.add')}
|
||||
</Button>);
|
||||
let C = (<>
|
||||
<Alert message={t('tips')} type="warning"/>
|
||||
<div className={classnames(Styles.empty, Styles.container)}>
|
||||
{AddButton}
|
||||
</div>
|
||||
</>);
|
||||
const availableChannels = channels.filter((ele) => !config?.find(ele2 => ele2.channel === ele[1]));
|
||||
if (config && config.length > 0) {
|
||||
C = (<div className={Styles.container}>
|
||||
<Space direction="vertical" size={16} style={{ width: '100%' }}>
|
||||
{config.map((cf, idx) => {
|
||||
const { channel } = cf;
|
||||
const C = PayConfigComponentsDict[channel];
|
||||
assert(C);
|
||||
return (<Card title={channels.find(ele => ele[1] === channel)[0]} style={{
|
||||
minWidth: 380,
|
||||
}} key={idx} extra={<Button icon={<CloseOutlined />} type="text" onClick={() => {
|
||||
config.splice(idx, 1);
|
||||
update(config);
|
||||
}}/>}>
|
||||
<C config={cf} update={(cf2) => {
|
||||
config.splice(idx, 1, {
|
||||
channel,
|
||||
...cf2,
|
||||
});
|
||||
update(config);
|
||||
}} t={t}/>
|
||||
</Card>);
|
||||
})}
|
||||
</Space>
|
||||
{availableChannels.length > 0 && <div style={{ marginTop: 24, alignSelf: 'flex-end' }}>
|
||||
{AddButton}
|
||||
</div>}
|
||||
</div>);
|
||||
}
|
||||
// 还没有配置config
|
||||
return (<>
|
||||
{C}
|
||||
<Modal open={open} onCancel={() => setOpen(false)} title={t('pickChannel')} onOk={() => { }} footer={null} destroyOnClose={true}>
|
||||
<Select style={{ width: 240 }} options={availableChannels.map(ele => ({
|
||||
label: ele[0],
|
||||
value: ele[1],
|
||||
}))} onSelect={(value) => {
|
||||
if (config) {
|
||||
config.push({
|
||||
channel: value,
|
||||
});
|
||||
update(config);
|
||||
}
|
||||
else {
|
||||
update([{
|
||||
channel: value,
|
||||
}]);
|
||||
}
|
||||
setOpen(false);
|
||||
}}/>
|
||||
</Modal>
|
||||
</>);
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"tips": "在此创建的支付设置将对所有app有效",
|
||||
"pickChannel": "选择支付通道"
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import React from 'react';
|
||||
import { OfflinePayConfig } from '../../../../types/PayConfig';
|
||||
export default function Offline(props: {
|
||||
config: OfflinePayConfig;
|
||||
update: (config: Omit<OfflinePayConfig, 'channel'>) => void;
|
||||
t: (k: string) => string;
|
||||
}): React.JSX.Element;
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { Alert, Flex, Input, Tag, Form, Switch, theme } from 'antd';
|
||||
import Styles from './web.pc.module.less';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
const tagInputStyle = {
|
||||
width: 64,
|
||||
height: 22,
|
||||
marginInlineEnd: 8,
|
||||
verticalAlign: 'top',
|
||||
};
|
||||
export default function Offline(props) {
|
||||
const { config, update, t } = props;
|
||||
const { options = [], allowUser = false } = config;
|
||||
const { token } = theme.useToken();
|
||||
const tagPlusStyle = {
|
||||
height: 22,
|
||||
background: token.colorBgContainer,
|
||||
borderStyle: 'dashed',
|
||||
};
|
||||
const [inputVisible, setInputVisible] = useState(false);
|
||||
const [option, setOption] = useState('');
|
||||
const inputRef = useRef(null);
|
||||
useEffect(() => {
|
||||
if (inputVisible) {
|
||||
inputRef.current?.focus();
|
||||
}
|
||||
}, [inputVisible]);
|
||||
const handleInputConfirm = () => {
|
||||
if (option) {
|
||||
options.push(option);
|
||||
update({
|
||||
options
|
||||
});
|
||||
}
|
||||
setOption('');
|
||||
setInputVisible(false);
|
||||
};
|
||||
return (<div className={Styles.container}>
|
||||
<Alert type='info' message={t('tips')}/>
|
||||
<Form labelCol={{ span: 6 }} wrapperCol={{ span: 12 }} layout="horizontal" style={{ minWidth: 600 }}>
|
||||
<Form.Item label={t('options')}>
|
||||
<Flex gap="4px 0" wrap="wrap" style={{ marginTop: 22 }}>
|
||||
{options.map((option, idx) => <Tag bordered={false} closable key={idx} onClose={() => {
|
||||
options.splice(idx, 1);
|
||||
update({
|
||||
options,
|
||||
});
|
||||
}}>
|
||||
{option}
|
||||
</Tag>)}
|
||||
{inputVisible ? (<Input ref={inputRef} type="text" size="small" style={tagInputStyle} value={option} onChange={({ currentTarget }) => setOption(currentTarget.value)} onBlur={handleInputConfirm} onPressEnter={handleInputConfirm}/>) : (<Tag style={tagPlusStyle} icon={<PlusOutlined />} onClick={() => setInputVisible(true)}>
|
||||
{t('newOption')}
|
||||
</Tag>)}
|
||||
</Flex>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('allowUser')}>
|
||||
<Switch value={allowUser} onChange={(v) => {
|
||||
config.allowUser = v;
|
||||
update(config);
|
||||
}}/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</div>);
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"tips": "配置后系统允许手动同步来自系统以外的支付",
|
||||
"newOption": "添加途径",
|
||||
"options": "收银途径",
|
||||
"allowUser": "用户主动发起"
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
.empty {
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { WechatPayConfig } from '../../../../types/PayConfig';
|
||||
import React from 'react';
|
||||
export default function WechatPay(props: {
|
||||
config: WechatPayConfig;
|
||||
update: (config: Omit<WechatPayConfig, 'channel'>) => void;
|
||||
t: (k: string) => string;
|
||||
}): React.JSX.Element;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import React from 'react';
|
||||
import { Form, Input } from 'antd';
|
||||
export default function WechatPay(props) {
|
||||
const { config, update, t } = props;
|
||||
return (<Form labelCol={{ span: 6 }} wrapperCol={{ span: 12 }} layout="horizontal" style={{ minWidth: 600 }}>
|
||||
<Form.Item label="mchId">
|
||||
<Input value={config.mchId} onChange={({ currentTarget }) => {
|
||||
config.mchId = currentTarget.value;
|
||||
update(config);
|
||||
}}/>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('label.privateKeyFilePath')}>
|
||||
<Input value={config.privateKeyFilePath} placeholder={t('placeholder.privateKeyFilePath')} onChange={({ currentTarget }) => {
|
||||
config.privateKeyFilePath = currentTarget.value;
|
||||
update(config);
|
||||
}}/>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('label.publicKeyFilePath')}>
|
||||
<Input value={config.publicKeyFilePath} placeholder={t('placeholder.publicKeyFilePath')} onChange={({ currentTarget }) => {
|
||||
config.publicKeyFilePath = currentTarget.value;
|
||||
update(config);
|
||||
}}/>
|
||||
</Form.Item>
|
||||
</Form>);
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"label": {
|
||||
"privateKeyFilePath": "私钥文件路径",
|
||||
"publicKeyFilePath": "公钥文件路径"
|
||||
},
|
||||
"placeholder": {
|
||||
"privateKeyFilePath": "服务器上存放微信支付帐户私钥文件的路径,注意访问权限",
|
||||
"publicKeyFilePath": "服务器上存放微信支付帐户公钥文件的路径,注意访问权限"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import SimpleConnector from 'oak-domain/lib/utils/SimpleConnector';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
import FrontendRuntimeContext from '../context/FrontendRuntimeContext';
|
||||
declare const connector: SimpleConnector<EntityDict, FrontendRuntimeContext>;
|
||||
export default connector;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import SimpleConnector from 'oak-domain/lib/utils/SimpleConnector';
|
||||
import accessConfiguration from '../configuration/access';
|
||||
import { makeException } from '../types/Exception';
|
||||
const connector = new SimpleConnector(accessConfiguration, makeException);
|
||||
export default connector;
|
||||
|
|
@ -0,0 +1 @@
|
|||
export declare const DATA_SUBSCRIBER_KEYS: {};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export const DATA_SUBSCRIBER_KEYS = {};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export declare const MessageTypes: {};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export const MessageTypes = {};
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
//小程序使用
|
||||
@import "oak-frontend-base/es/config/styles/mp/index.less";
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
// 解决全屏幕机型底部适配问题
|
||||
.safe-area-inset-bottom() {
|
||||
padding-bottom: constant(safe-area-inset-bottom) !important;
|
||||
/* 兼容 iOS < 11.2 */
|
||||
padding-bottom: env(safe-area-inset-bottom) !important;
|
||||
/* 兼容 iOS >= 11.2 */
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
@import 'oak-frontend-base/es/config/styles/web/index.less'; // 少量公共样式
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
import accessConfiguration from './access.dev';
|
||||
export default accessConfiguration;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { AccessConfiguration } from 'oak-domain/lib/types/Configuration';
|
||||
declare const accessConfiguration: AccessConfiguration;
|
||||
export default accessConfiguration;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
const accessConfiguration = {
|
||||
http: {
|
||||
hostname: 'localhost',
|
||||
port: 3001,
|
||||
},
|
||||
};
|
||||
export default accessConfiguration;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import accessConfiguration from './access.dev';
|
||||
export default accessConfiguration;
|
||||
console.log('不应该跑到这里');
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { AccessConfiguration } from 'oak-domain/lib/types/Configuration';
|
||||
declare const _default: AccessConfiguration;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import devConfiguration from './access.dev';
|
||||
const accessConfiguration = {
|
||||
http: {
|
||||
hostname: 'www.oak-framework.test',
|
||||
ssl: true,
|
||||
path: 'oak-api', // 配置在nginx中的映射
|
||||
},
|
||||
};
|
||||
export default process.env.NODE_ENV === 'development' ? devConfiguration : accessConfiguration;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { AttrUpdateMatrix } from 'oak-domain/lib/types/EntityDesc';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
declare const attrUpdateMatrix: AttrUpdateMatrix<EntityDict>;
|
||||
export default attrUpdateMatrix;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const attrUpdateMatrix = {};
|
||||
export default attrUpdateMatrix;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
declare const cacheSavedEntities: (keyof EntityDict)[];
|
||||
export default cacheSavedEntities;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const cacheSavedEntities = [];
|
||||
export default cacheSavedEntities;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { DependencyConfiguration } from 'oak-domain/lib/types/Configuration';
|
||||
declare const dependencyConfiguration: DependencyConfiguration;
|
||||
export default dependencyConfiguration;
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
const dependencyConfiguration = ["oak-general-business"];
|
||||
export default dependencyConfiguration;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { CommonConfiguration } from 'oak-domain/lib/types/Configuration';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
declare const _default: CommonConfiguration<EntityDict>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/**
|
||||
* index中汇总了前端启动需要的引用配置
|
||||
*/
|
||||
import attrUpdateMatrix from './attrUpdateMatrix';
|
||||
import { actionDefDict } from '../oak-app-domain/ActionDefDict';
|
||||
import { selectFreeEntities, authDeduceRelationMap, updateFreeDict } from './relation';
|
||||
import cacheSavedEntities from './cache';
|
||||
export default {
|
||||
attrUpdateMatrix,
|
||||
actionDefDict,
|
||||
authDeduceRelationMap,
|
||||
selectFreeEntities,
|
||||
updateFreeDict,
|
||||
cacheSavedEntities,
|
||||
// cacheKeepFreshPeriod: 600 * 1000, // cache默认对缓存对象的刷新间隔时长(在这个间隔内不刷新)
|
||||
};
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { AuthDeduceRelationMap, UpdateFreeDict } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
export declare const authDeduceRelationMap: AuthDeduceRelationMap<EntityDict>;
|
||||
export declare const selectFreeEntities: string[];
|
||||
export declare const updateFreeDict: UpdateFreeDict<EntityDict>;
|
||||
declare const _default: {
|
||||
authDeduceRelationMap: AuthDeduceRelationMap<EntityDict>;
|
||||
selectFreeEntities: string[];
|
||||
updateFreeDict: UpdateFreeDict<EntityDict>;
|
||||
};
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
// 此对象所标识的entity的权限由其外键指向的父对象判定
|
||||
export const authDeduceRelationMap = {};
|
||||
export const selectFreeEntities = [
|
||||
'payChannel',
|
||||
];
|
||||
export const updateFreeDict = {};
|
||||
export default {
|
||||
authDeduceRelationMap,
|
||||
selectFreeEntities,
|
||||
updateFreeDict,
|
||||
};
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { RenderConfiguration } from 'oak-domain/lib/types/Configuration';
|
||||
import { EntityDict } from '../oak-app-domain';
|
||||
declare const _default: RenderConfiguration<EntityDict>;
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import { styleDict } from '../oak-app-domain/StyleDict';
|
||||
export default {
|
||||
styleDict,
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { RuntimeContext } from './RuntimeContext';
|
||||
import { BackendRuntimeContext as DependentBackendRuntimeContext } from './DependentContext';
|
||||
export declare class BackendRuntimeContext<ED extends EntityDict & BaseEntityDict> extends DependentBackendRuntimeContext<ED> implements RuntimeContext {
|
||||
toString(): Promise<string>;
|
||||
}
|
||||
export default BackendRuntimeContext;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { BackendRuntimeContext as DependentBackendRuntimeContext } from './DependentContext';
|
||||
export class BackendRuntimeContext extends DependentBackendRuntimeContext {
|
||||
async toString() {
|
||||
const data = await this.getSerializedData();
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
}
|
||||
;
|
||||
export default BackendRuntimeContext;
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { BackendRuntimeContext, FrontendRuntimeContext, SerializedData } from "oak-general-business";
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { BackendRuntimeContext, FrontendRuntimeContext } from "oak-general-business";
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { FrontendRuntimeContext as DependentFrontendRuntimeContext, SerializedData } from './DependentContext';
|
||||
import { RuntimeContext } from './RuntimeContext';
|
||||
export { SerializedData, };
|
||||
export declare class FrontendRuntimeContext<ED extends EntityDict & BaseEntityDict> extends DependentFrontendRuntimeContext<ED> implements RuntimeContext {
|
||||
toString(): Promise<string>;
|
||||
}
|
||||
export default FrontendRuntimeContext;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { FrontendRuntimeContext as DependentFrontendRuntimeContext } from './DependentContext';
|
||||
export class FrontendRuntimeContext extends DependentFrontendRuntimeContext {
|
||||
async toString() {
|
||||
const data = await this.getSerializedData();
|
||||
return JSON.stringify(data);
|
||||
}
|
||||
}
|
||||
export default FrontendRuntimeContext;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
/**
|
||||
* 若业务逻辑需要更多的上下文之间的数据传递,可以放在这里
|
||||
*/
|
||||
export interface RuntimeContext {
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
export {};
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
import { CreateOperationData as I18n } from "../oak-app-domain/I18n/Schema";
|
||||
declare const i18ns: I18n[];
|
||||
export default i18ns;
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
// 本文件为自动编译产生,请勿直接修改
|
||||
const i18ns = [
|
||||
{
|
||||
id: "548c6f23c4d08f495b6eed1b757aceb5",
|
||||
namespace: "oak-pay-business-c-payConfig-system",
|
||||
language: "zh-CN",
|
||||
module: "oak-pay-business",
|
||||
position: "src/components/payConfig/system",
|
||||
data: {
|
||||
"system": "系统配置",
|
||||
"appsBelow": "以下为application",
|
||||
"mayLossUpdate": "%{name}上的更新可能会丢失,请尽快保存"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "b498c969e467aad958efb0c900eb6d27",
|
||||
namespace: "oak-pay-business-c-payConfig-upsert-account",
|
||||
language: "zh-CN",
|
||||
module: "oak-pay-business",
|
||||
position: "src/components/payConfig/upsert/account",
|
||||
data: {
|
||||
"tips": "无需配置。开启后支持向系统帐户内充值,并使用帐户余额进行抵扣、支付等操作"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "13dd1040fa574f095005854ea31fa913",
|
||||
namespace: "oak-pay-business-c-payConfig-upsert",
|
||||
language: "zh-CN",
|
||||
module: "oak-pay-business",
|
||||
position: "src/components/payConfig/upsert",
|
||||
data: {
|
||||
"tips": "在此创建的支付设置将对所有app有效",
|
||||
"pickChannel": "选择支付通道"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "4ceac38d67e35b7e9c76f0d2c1ad1e9a",
|
||||
namespace: "oak-pay-business-c-payConfig-upsert-offline",
|
||||
language: "zh-CN",
|
||||
module: "oak-pay-business",
|
||||
position: "src/components/payConfig/upsert/offline",
|
||||
data: {
|
||||
"tips": "配置后系统允许手动同步来自系统以外的支付",
|
||||
"newOption": "添加途径",
|
||||
"options": "收银途径",
|
||||
"allowUser": "用户主动发起"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "6fcb5b3689d3f682af148af94b385ae3",
|
||||
namespace: "oak-pay-business-c-payConfig-upsert-wechatPay",
|
||||
language: "zh-CN",
|
||||
module: "oak-pay-business",
|
||||
position: "src/components/payConfig/upsert/wechatPay",
|
||||
data: {
|
||||
"label": {
|
||||
"privateKeyFilePath": "私钥文件路径",
|
||||
"publicKeyFilePath": "公钥文件路径"
|
||||
},
|
||||
"placeholder": {
|
||||
"privateKeyFilePath": "服务器上存放微信支付帐户私钥文件的路径,注意访问权限",
|
||||
"publicKeyFilePath": "服务器上存放微信支付帐户公钥文件的路径,注意访问权限"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "2127948cb52e116e3ceccd93db8f319c",
|
||||
namespace: "oak-pay-business-l-common",
|
||||
language: "zh-CN",
|
||||
module: "oak-pay-business",
|
||||
position: "locales/common",
|
||||
data: {
|
||||
"ptrActivate": "松开刷新",
|
||||
"ptrDeactivate": "下拉刷新",
|
||||
"ptrRelease": "正在刷新...",
|
||||
"ptrFinish": "刷新完成",
|
||||
"noData": "暂无数据",
|
||||
"areYouSure": "请确认",
|
||||
"action": {
|
||||
"create": "创建",
|
||||
"update": "更新",
|
||||
"delete": "删除",
|
||||
"remove": "删除",
|
||||
"cancel": "取消",
|
||||
"grant": "授权",
|
||||
"revoke": "回收",
|
||||
"tip": "提示",
|
||||
"detail": "详情",
|
||||
"editor": "编辑",
|
||||
"newAdd": "新增",
|
||||
"add": "添加",
|
||||
"commit": "提交",
|
||||
"save": "保存",
|
||||
"upload": "上传",
|
||||
"import": "导入"
|
||||
},
|
||||
"confirm": "确定",
|
||||
"submit": "提交",
|
||||
"reset": "重置",
|
||||
"select": "查询",
|
||||
"expand": "展开",
|
||||
"shrink": "收起",
|
||||
"back": "返回",
|
||||
"$$createAt$$": "创建时间",
|
||||
"$$updateAt$$": "更新时间",
|
||||
"$$deleteAt$$": "删除时间",
|
||||
"$$seq$$": "序号",
|
||||
"message": "消息",
|
||||
"more": "更多",
|
||||
"view": "查看",
|
||||
"scan": "扫一扫",
|
||||
"bind": "绑定",
|
||||
"true": "是",
|
||||
"false": "否",
|
||||
"open": "开",
|
||||
"close": "关",
|
||||
"enter": "请输入",
|
||||
"change": "修改",
|
||||
"finish": "完成"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "e8c0a965783373d9117f9447ebbbad8d",
|
||||
namespace: "oak-pay-business-l-payChannel",
|
||||
language: "zh-CN",
|
||||
module: "oak-pay-business",
|
||||
position: "locales/payChannel",
|
||||
data: {
|
||||
"ACCOUNT": "系统内帐户",
|
||||
"OFFLINE": "系统外支付",
|
||||
"WECHAT_JS": "微信支付JS",
|
||||
"WECHAT_MP": "微信小程序",
|
||||
"WECHAT_NATIVE": "微信Native",
|
||||
"WECHAT_H5": "微信H5",
|
||||
"WECHAT_APP": "微信APP"
|
||||
}
|
||||
}
|
||||
];
|
||||
export default i18ns;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
declare const _default: {
|
||||
i18n: import("../oak-app-domain/I18n/Schema").CreateOperationData[];
|
||||
};
|
||||
export default _default;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
import i18n from "./i18n";
|
||||
export default {
|
||||
i18n,
|
||||
};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import { String, Price } from 'oak-domain/lib/types/DataType';
|
||||
import { AbleAction, AbleState } from 'oak-domain/lib/actions/action';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDesc, ActionDef } from 'oak-domain/lib/types';
|
||||
import { Schema as System } from 'oak-general-business/lib/entities/System';
|
||||
export interface Schema extends EntityShape {
|
||||
total: Price;
|
||||
avail: Price;
|
||||
system: System;
|
||||
entity: String<32>;
|
||||
entityId: String<64>;
|
||||
}
|
||||
type IAction = 'deposit' | 'withdraw' | 'withdrawBack' | 'consume' | 'loan' | 'repay';
|
||||
export type Action = AbleAction | IAction;
|
||||
export declare const AbleActionDef: ActionDef<AbleAction, AbleState>;
|
||||
export declare const entityDesc: EntityDesc<Schema, Action, '', {
|
||||
ableState: AbleState;
|
||||
}>;
|
||||
export {};
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
import { makeAbleActionDef } from 'oak-domain/lib/actions/action';
|
||||
;
|
||||
export const AbleActionDef = makeAbleActionDef('enabled');
|
||||
export const entityDesc = {
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '帐户',
|
||||
attr: {
|
||||
total: '总余额',
|
||||
avail: '可用余额',
|
||||
ableState: '状态',
|
||||
system: '系统',
|
||||
entity: '所属对象',
|
||||
entityId: '所属对象Id',
|
||||
},
|
||||
action: {
|
||||
enable: '启用',
|
||||
disable: '禁用',
|
||||
deposit: '充值',
|
||||
withdraw: '提现',
|
||||
withdrawBack: '提现退还',
|
||||
consume: '消费',
|
||||
loan: '抵押',
|
||||
repay: '偿还',
|
||||
},
|
||||
v: {
|
||||
ableState: {
|
||||
enabled: '可用的',
|
||||
disabled: '禁用的',
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
style: {
|
||||
icon: {
|
||||
enable: '',
|
||||
disable: '',
|
||||
deposit: '',
|
||||
withdraw: '',
|
||||
consume: '',
|
||||
loan: '',
|
||||
repay: '',
|
||||
},
|
||||
color: {
|
||||
ableState: {
|
||||
enabled: '#008000',
|
||||
disabled: '#A9A9A9'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import { String, Price } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDesc } from 'oak-domain/lib/types';
|
||||
import { Schema as Account } from './Account';
|
||||
type Type = 'deposit' | 'withdraw' | 'consume' | 'loan' | 'repay' | 'withdrawBack';
|
||||
export interface Schema extends EntityShape {
|
||||
account: Account;
|
||||
type: Type;
|
||||
totalPlus: Price;
|
||||
availPlus: Price;
|
||||
entity: String<32>;
|
||||
entityId: String<64>;
|
||||
}
|
||||
export declare const entityDesc: EntityDesc<Schema, '', '', {
|
||||
type: Type;
|
||||
}>;
|
||||
export {};
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
;
|
||||
export const entityDesc = {
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '帐号操作',
|
||||
attr: {
|
||||
account: '帐号',
|
||||
type: '类型',
|
||||
totalPlus: '余额变化',
|
||||
availPlus: '可用余额变化',
|
||||
entity: '关联对象',
|
||||
entityId: '关联对象Id',
|
||||
},
|
||||
v: {
|
||||
type: {
|
||||
deposit: '充值',
|
||||
withdraw: '提现',
|
||||
consume: '消费',
|
||||
loan: '抵押',
|
||||
repay: '偿还',
|
||||
withdrawBack: '提现失败',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
style: {
|
||||
color: {
|
||||
type: {
|
||||
deposit: '#3498DB',
|
||||
withdraw: '#F7DC6F',
|
||||
withdrawBack: '#F7DC6F',
|
||||
consume: '#A569BD',
|
||||
loan: '#CD6155',
|
||||
repay: '#82E0AA',
|
||||
}
|
||||
}
|
||||
},
|
||||
configuration: {
|
||||
actionType: 'appendOnly',
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { Schema as Application } from 'oak-general-business/lib/entities/Application';
|
||||
import { PayConfig } from '../types/PayConfig';
|
||||
export interface Schema extends Application {
|
||||
payConfig?: PayConfig;
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
;
|
||||
const entityDesc = {
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '应用',
|
||||
attr: {
|
||||
description: '描述',
|
||||
type: '类型',
|
||||
system: '系统',
|
||||
name: '名称',
|
||||
config: '设置',
|
||||
style: '样式',
|
||||
sessions: '会话',
|
||||
domain: '域名',
|
||||
payConfig: '支付配置',
|
||||
},
|
||||
v: {
|
||||
type: {
|
||||
web: '网站',
|
||||
wechatPublic: '微信公众号',
|
||||
wechatMp: '微信小程序',
|
||||
native: 'App',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
style: {
|
||||
color: {
|
||||
type: {
|
||||
wechatMp: '#32CD32',
|
||||
web: '#00FF7F',
|
||||
wechatPublic: '#90EE90',
|
||||
native: '#008000',
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
export {};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import { String, Price, Datetime } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDesc, ActionDef } from 'oak-domain/lib/types';
|
||||
export interface Schema extends EntityShape {
|
||||
price: Price;
|
||||
paid: Price;
|
||||
refunded: Price;
|
||||
title: String<32>;
|
||||
desc: String<64>;
|
||||
timeoutAt: Datetime;
|
||||
}
|
||||
type IAction = 'startPaying' | 'payAll' | 'payPartially' | 'payNone' | 'timeout' | 'cancel' | 'startRefunding' | 'refundAll' | 'refundPartially' | 'refundNone';
|
||||
type IState = 'paid' | 'unPaid' | 'timeout' | 'cancelled' | 'paying' | 'partiallyPaid' | 'paid' | 'refunding' | 'partiallyRefunded' | 'refunded';
|
||||
export declare const IActionDef: ActionDef<IAction, IState>;
|
||||
type Action = IAction;
|
||||
export declare const entityDesc: EntityDesc<Schema, Action, '', {
|
||||
iState: IState;
|
||||
}>;
|
||||
export {};
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
;
|
||||
export const IActionDef = {
|
||||
stm: {
|
||||
startPaying: ['unPaid', 'paying'],
|
||||
payAll: [['unPaid', 'paying', 'partiallyPaid'], 'paid'],
|
||||
payPartially: [['unPaid', 'paying'], 'partiallyPaid'],
|
||||
payNone: ['paying', 'unPaid'],
|
||||
timeout: ['unPaid', 'timeout'],
|
||||
cancel: ['unPaid', 'cancelled'],
|
||||
startRefunding: [['paid', 'partiallyPaid'], 'refunding'],
|
||||
refundAll: [['paid', 'refunding', 'partiallyPaid', 'partiallyRefunded'], 'refunded'],
|
||||
refundPartially: [['paid', 'refunding', 'partiallyPaid', 'partiallyRefunded'], 'partiallyRefunded'],
|
||||
refundNone: ['refunding', 'paid'],
|
||||
},
|
||||
is: 'unPaid',
|
||||
};
|
||||
export const entityDesc = {
|
||||
indexes: [
|
||||
//索引
|
||||
{
|
||||
name: 'index_iState',
|
||||
attributes: [
|
||||
{
|
||||
name: 'iState',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '订单',
|
||||
attr: {
|
||||
price: '订单金额',
|
||||
paid: '已支付金额',
|
||||
refunded: '已退款金额',
|
||||
iState: '订单状态',
|
||||
title: '订单标题',
|
||||
desc: "订单描述",
|
||||
timeoutAt: '过期时间'
|
||||
},
|
||||
action: {
|
||||
startPaying: '开始支付',
|
||||
payAll: '全部支付',
|
||||
payPartially: '部分支付',
|
||||
payNone: '支付失败',
|
||||
timeout: '过期',
|
||||
cancel: '放弃',
|
||||
startRefunding: '开始退款',
|
||||
refundAll: '完全退款',
|
||||
refundNone: '退款失败',
|
||||
refundPartially: '部分退款',
|
||||
},
|
||||
v: {
|
||||
iState: {
|
||||
paid: '已付款',
|
||||
partiallyPaid: '部分支付',
|
||||
paying: '支付中',
|
||||
unPaid: '待付款',
|
||||
timeout: '已超时',
|
||||
cancelled: '已取消',
|
||||
refunded: '已退款',
|
||||
partiallyRefunded: '已部分退款',
|
||||
refunding: '退款中',
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
style: {
|
||||
icon: {
|
||||
startPaying: '',
|
||||
payAll: '',
|
||||
payPartially: '',
|
||||
payNone: '',
|
||||
timeout: '',
|
||||
cancel: '',
|
||||
startRefunding: '',
|
||||
refundAll: '',
|
||||
refundNone: '',
|
||||
refundPartially: '',
|
||||
},
|
||||
color: {
|
||||
iState: {
|
||||
unPaid: '#52BE80',
|
||||
partiallyPaid: '#5DADE2',
|
||||
cancelled: '#D6DBDF',
|
||||
paid: '#2E86C1',
|
||||
paying: '#D2B4DE',
|
||||
timeout: '#2C3E50',
|
||||
refunded: '#BA4A00',
|
||||
partiallyRefunded: '#EDBB99',
|
||||
refunding: '#FBEEE6'
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { String, Price, Datetime, Int } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDesc, ActionDef } from 'oak-domain/lib/types';
|
||||
import { Schema as Order } from './Order';
|
||||
import { Schema as Account } from './Account';
|
||||
import { Schema as AccountOper } from './AccountOper';
|
||||
import { Schema as Application } from 'oak-general-business/lib/entities/Application';
|
||||
/**
|
||||
* 约定:充值类pay,其orderId为null,accountId指向要充值的帐户(channel不能是ACCOUNT)
|
||||
* 订单类pay,其orderId指向订单,accountId指向付款的帐户(channel必须是ACCOUNT)
|
||||
*/
|
||||
export interface Schema extends EntityShape {
|
||||
price: Price;
|
||||
paid: Price;
|
||||
refunded: Price;
|
||||
channel: String<32>;
|
||||
timeoutAt: Datetime;
|
||||
forbidRefundAt?: Datetime;
|
||||
account?: Account;
|
||||
order?: Order;
|
||||
externalId?: String<80>;
|
||||
meta: Object;
|
||||
opers: AccountOper[];
|
||||
application: Application;
|
||||
phantom1?: String<32>;
|
||||
phantom2?: String<32>;
|
||||
phantom3?: Int<4>;
|
||||
phantom4?: Int<8>;
|
||||
}
|
||||
type IAction = 'startPaying' | 'succeedPaying' | 'close' | 'startRefunding' | 'refundAll' | 'refundPartially';
|
||||
type IState = 'unpaid' | 'paying' | 'paid' | 'closed' | 'refunding' | 'partiallyRefunded' | 'refunded';
|
||||
export declare const IActionDef: ActionDef<IAction, IState>;
|
||||
type Action = IAction;
|
||||
export declare const entityDesc: EntityDesc<Schema, Action, '', {
|
||||
iState: IState;
|
||||
}>;
|
||||
export {};
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
;
|
||||
export const IActionDef = {
|
||||
stm: {
|
||||
startPaying: ['unpaid', 'paying'],
|
||||
succeedPaying: [['unpaid', 'paying'], 'paid'],
|
||||
close: [['unpaid', 'paying'], 'closed'],
|
||||
startRefunding: [['paid', 'partiallyRefunded', 'refunding'], 'refunding'],
|
||||
refundAll: [['paid', 'refunding', 'partiallyRefunded'], 'refunded'],
|
||||
refundPartially: [['paid', 'refunding', 'partiallyRefunded'], 'partiallyRefunded'],
|
||||
},
|
||||
is: 'unpaid',
|
||||
};
|
||||
export const entityDesc = {
|
||||
indexes: [
|
||||
//索引
|
||||
{
|
||||
name: 'index_iState',
|
||||
attributes: [
|
||||
{
|
||||
name: 'iState',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'index_externalId_channel',
|
||||
attributes: [
|
||||
{
|
||||
name: 'externalId',
|
||||
},
|
||||
{
|
||||
name: 'channel',
|
||||
}
|
||||
],
|
||||
config: {
|
||||
unique: true,
|
||||
}
|
||||
},
|
||||
],
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '订单',
|
||||
attr: {
|
||||
price: '订单金额',
|
||||
paid: '已支付金额',
|
||||
refunded: '已退款金额',
|
||||
iState: '支付状态',
|
||||
channel: '支付渠道',
|
||||
order: '所属订单',
|
||||
timeoutAt: '过期时间',
|
||||
forbidRefundAt: '停止退款时间',
|
||||
account: '充值帐户',
|
||||
meta: '支付metadata',
|
||||
externalId: '外部订单Id',
|
||||
opers: '被关联帐户操作',
|
||||
application: '关联应用',
|
||||
phantom1: '索引项一',
|
||||
phantom2: '索引项二',
|
||||
phantom3: '索引项三',
|
||||
phantom4: '索引项四',
|
||||
},
|
||||
action: {
|
||||
startPaying: '开始支付',
|
||||
succeedPaying: '支付成功',
|
||||
close: '关闭',
|
||||
startRefunding: '开始退款',
|
||||
refundAll: '完全退款',
|
||||
refundPartially: '部分退款',
|
||||
},
|
||||
v: {
|
||||
iState: {
|
||||
unpaid: '待付款',
|
||||
paying: '支付中',
|
||||
paid: '已付款',
|
||||
closed: '已关闭',
|
||||
refunding: '退款中',
|
||||
refunded: '已退款',
|
||||
partiallyRefunded: '已部分退款',
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
style: {
|
||||
icon: {
|
||||
startPaying: '',
|
||||
succeedPaying: '',
|
||||
close: '',
|
||||
startRefunding: '',
|
||||
refundAll: '',
|
||||
refundPartially: '',
|
||||
},
|
||||
color: {
|
||||
iState: {
|
||||
unpaid: '#48C9B0',
|
||||
paid: '#3498DB',
|
||||
paying: '#D6EAF8',
|
||||
closed: '#5D6D7E',
|
||||
refunded: '#FAE5D3',
|
||||
partiallyRefunded: '#F0B27A',
|
||||
refunding: '#CA6F1E'
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { EntityDesc } from 'oak-domain/lib/types/EntityDesc';
|
||||
import { Schema as System } from 'oak-general-business/lib/entities/System';
|
||||
import { PayConfig } from '../types/PayConfig';
|
||||
export interface Schema extends System {
|
||||
payConfig?: PayConfig;
|
||||
}
|
||||
export declare const entityDesc: EntityDesc<Schema>;
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
;
|
||||
export const entityDesc = {
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '系统',
|
||||
attr: {
|
||||
name: '名称',
|
||||
description: '描述',
|
||||
config: '设置',
|
||||
platform: '平台',
|
||||
super: '超级系统',
|
||||
folder: '代码目录名',
|
||||
style: '样式',
|
||||
entity: '关联对象',
|
||||
entityId: '关联对象id',
|
||||
payConfig: '支付配置',
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import { ActionDef } from 'oak-domain/lib/types/Action';
|
||||
import { EntityDesc } from 'oak-domain/lib/types/EntityDesc';
|
||||
import { Schema as User, IdAction, IdState, UserAction, UserState } from 'oak-general-business/lib/entities/User';
|
||||
import { Schema as Account } from './Account';
|
||||
export interface Schema extends User {
|
||||
accounts: Account[];
|
||||
}
|
||||
export type Action = UserAction | IdAction;
|
||||
export declare const IdActionDef: ActionDef<IdAction, IdState>;
|
||||
export declare const UserActionDef: ActionDef<UserAction, UserState>;
|
||||
export declare const entityDesc: EntityDesc<Schema, Action, '', {
|
||||
userState: UserState;
|
||||
idState: IdState;
|
||||
gender: Required<Schema>['gender'];
|
||||
idCardType: Required<Schema>['idCardType'];
|
||||
}>;
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
;
|
||||
export const IdActionDef = {
|
||||
stm: {
|
||||
verify: ['unverified', 'verifying'],
|
||||
accept: [['unverified', 'verifying'], 'verified'],
|
||||
reject: [['verifying', 'verified'], 'unverified'],
|
||||
},
|
||||
is: 'unverified',
|
||||
};
|
||||
export const UserActionDef = {
|
||||
stm: {
|
||||
activate: ['shadow', 'normal'],
|
||||
disable: [['normal', 'shadow'], 'disabled'],
|
||||
enable: ['disabled', 'normal'],
|
||||
mergeTo: [['normal', 'shadow'], 'merged'],
|
||||
mergeFrom: ['normal', 'normal'],
|
||||
},
|
||||
};
|
||||
export const entityDesc = {
|
||||
locales: {
|
||||
"zh_CN": {
|
||||
name: '用户',
|
||||
attr: {
|
||||
name: '姓名',
|
||||
nickname: '昵称',
|
||||
birth: '生日',
|
||||
password: '密码',
|
||||
passwordSha1: 'sha1加密密码',
|
||||
gender: '性别',
|
||||
idCardType: '证件类型',
|
||||
idNumber: '证件号码',
|
||||
ref: '指向用户',
|
||||
files: '相关文件',
|
||||
userState: '用户状态',
|
||||
idState: '身份验证状态',
|
||||
codes: '微信分享二维码',
|
||||
isRoot: '是否超级用户',
|
||||
addresses: '收货地址',
|
||||
accounts: '用户帐户',
|
||||
},
|
||||
action: {
|
||||
activate: '激活',
|
||||
accept: '同意',
|
||||
verify: '验证',
|
||||
reject: '拒绝',
|
||||
enable: '启用',
|
||||
disable: '禁用',
|
||||
mergeTo: '合并',
|
||||
mergeFrom: '使合并',
|
||||
},
|
||||
v: {
|
||||
userState: {
|
||||
shadow: '未激活',
|
||||
normal: '正常',
|
||||
disabled: '禁用',
|
||||
merged: '已被合并',
|
||||
},
|
||||
idState: {
|
||||
unverified: '未验证',
|
||||
verifying: '验证中',
|
||||
verified: '已验证',
|
||||
},
|
||||
gender: {
|
||||
male: '男',
|
||||
female: '女',
|
||||
},
|
||||
idCardType: {
|
||||
"ID-Card": '身份证',
|
||||
passport: '护照',
|
||||
"Mainland-passport": '港澳台通行证',
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
indexes: [
|
||||
{
|
||||
name: 'index_birth',
|
||||
attributes: [
|
||||
{
|
||||
name: 'birth',
|
||||
direction: 'ASC',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'index_fulltext',
|
||||
attributes: [
|
||||
{
|
||||
name: 'name',
|
||||
},
|
||||
{
|
||||
name: 'nickname',
|
||||
}
|
||||
],
|
||||
config: {
|
||||
type: 'fulltext',
|
||||
parser: 'ngram',
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'index_userState_refId',
|
||||
attributes: [
|
||||
{
|
||||
name: 'userState',
|
||||
},
|
||||
{
|
||||
name: 'ref',
|
||||
}
|
||||
]
|
||||
},
|
||||
],
|
||||
style: {
|
||||
icon: {
|
||||
verify: '',
|
||||
accept: '',
|
||||
reject: '',
|
||||
activate: '',
|
||||
enable: '',
|
||||
disable: '',
|
||||
mergeTo: '',
|
||||
mergeFrom: '',
|
||||
},
|
||||
color: {
|
||||
userState: {
|
||||
normal: '#0000FF',
|
||||
disabled: '#FF0000',
|
||||
merged: '#9A9A9A',
|
||||
shadow: '#D3D3D3',
|
||||
},
|
||||
idState: {
|
||||
unverified: '#FF0000',
|
||||
verified: '#0000FF',
|
||||
verifying: '#EEE8AA',
|
||||
},
|
||||
gender: {
|
||||
male: '#0000FF',
|
||||
female: '#EE82EE',
|
||||
},
|
||||
idCardType: {
|
||||
'ID-Card': '#E0FFFF',
|
||||
'Mainland-passport': '#2E8B57',
|
||||
'passport': '#2F4F4F',
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { Price } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDesc, ActionDef } from 'oak-domain/lib/types';
|
||||
import { Schema as Account } from './Account';
|
||||
import { Schema as WithdrawChannel } from './WithdrawChannel';
|
||||
import { Schema as AccountOper } from './AccountOper';
|
||||
export interface Schema extends EntityShape {
|
||||
account: Account;
|
||||
price: Price;
|
||||
channel: WithdrawChannel;
|
||||
opers: AccountOper[];
|
||||
}
|
||||
type IState = 'withdrawing' | 'successful' | 'failed';
|
||||
type IAction = 'succeed' | 'fail';
|
||||
export declare const IActionDef: ActionDef<IAction, IState>;
|
||||
type Action = IAction;
|
||||
export declare const entityDesc: EntityDesc<Schema, Action, '', {
|
||||
iState: IState;
|
||||
}>;
|
||||
export {};
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
;
|
||||
export const IActionDef = {
|
||||
stm: {
|
||||
succeed: ['withdrawing', 'successful'],
|
||||
fail: ['withdrawing', 'failed'],
|
||||
},
|
||||
is: 'withdrawing',
|
||||
};
|
||||
export const entityDesc = {
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '提现',
|
||||
attr: {
|
||||
account: '帐户',
|
||||
price: '金额',
|
||||
channel: '途径',
|
||||
iState: '状态',
|
||||
opers: '被关联帐户操作',
|
||||
},
|
||||
v: {
|
||||
iState: {
|
||||
withdrawing: '提现中',
|
||||
successful: '成功的',
|
||||
failed: '失败的',
|
||||
},
|
||||
},
|
||||
action: {
|
||||
succeed: '成功',
|
||||
fail: '失败',
|
||||
},
|
||||
},
|
||||
},
|
||||
style: {
|
||||
icon: {
|
||||
succeed: '',
|
||||
fail: '',
|
||||
},
|
||||
color: {
|
||||
iState: {
|
||||
withdrawing: '#D2B4DE',
|
||||
successful: '#2E86C1',
|
||||
failed: '#D6DBDF',
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import { String } from 'oak-domain/lib/types/DataType';
|
||||
import { EntityShape } from 'oak-domain/lib/types/Entity';
|
||||
import { EntityDesc } from 'oak-domain/lib/types';
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<64>;
|
||||
code: String<64>;
|
||||
data: Object;
|
||||
channel: String<32>;
|
||||
}
|
||||
export declare const entityDesc: EntityDesc<Schema>;
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
;
|
||||
export const entityDesc = {
|
||||
locales: {
|
||||
zh_CN: {
|
||||
name: '提现途径',
|
||||
attr: {
|
||||
name: '姓名',
|
||||
code: '帐号',
|
||||
data: 'metadata',
|
||||
channel: '提现通道',
|
||||
}
|
||||
},
|
||||
},
|
||||
indexes: [
|
||||
{
|
||||
name: 'code_uniqe',
|
||||
attributes: [
|
||||
{
|
||||
name: 'code',
|
||||
}
|
||||
],
|
||||
config: {
|
||||
unique: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { AFD } from './types/RuntimeCxt';
|
||||
/**
|
||||
* 构造backUrl
|
||||
* @param location
|
||||
* @param encode
|
||||
* @returns
|
||||
*/
|
||||
export declare const handler: (reason: any, features: AFD) => Promise<boolean>;
|
||||
|
|
@ -1,47 +1,35 @@
|
|||
import {
|
||||
OakException,
|
||||
OakUnloggedInException,
|
||||
OakUserUnpermittedException,
|
||||
OakAttrNotNullException,
|
||||
OakInputIllegalException,
|
||||
} from 'oak-domain/lib/types/Exception';
|
||||
import {
|
||||
ExampleException,
|
||||
} from '@project/types/Exception';
|
||||
import { FeatureDict } from '@project/features';
|
||||
import { AFD } from '@project/types/RuntimeCxt';
|
||||
|
||||
import { OakException, OakUnloggedInException, OakAttrNotNullException, OakInputIllegalException, } from 'oak-domain/lib/types/Exception';
|
||||
import { ExampleException, } from './types/Exception';
|
||||
/**
|
||||
* 构造backUrl
|
||||
* @param location
|
||||
* @param encode
|
||||
* @returns
|
||||
*/
|
||||
|
||||
export const handler = async (reason: any, features: AFD) => {
|
||||
export const handler = async (reason, features) => {
|
||||
if (reason instanceof OakException) {
|
||||
if (reason instanceof OakUnloggedInException) {
|
||||
// await features.token.logout();
|
||||
features.navigator.navigateTo(
|
||||
{
|
||||
url: '/login',
|
||||
},
|
||||
{ isGoBack: true },
|
||||
true
|
||||
);
|
||||
} else if (reason instanceof OakInputIllegalException) {
|
||||
features.navigator.navigateTo({
|
||||
url: '/login',
|
||||
}, { isGoBack: true }, true);
|
||||
}
|
||||
else if (reason instanceof OakInputIllegalException) {
|
||||
features.message.setMessage({
|
||||
content: reason.message,
|
||||
type: 'error',
|
||||
});
|
||||
} else if (reason instanceof OakAttrNotNullException) {
|
||||
}
|
||||
else if (reason instanceof OakAttrNotNullException) {
|
||||
features.message.setMessage({
|
||||
content: reason.message,
|
||||
type: 'error',
|
||||
});
|
||||
} else if (reason instanceof ExampleException) {
|
||||
}
|
||||
else if (reason instanceof ExampleException) {
|
||||
console.log('在此处理ExampleException');
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
console.warn(reason);
|
||||
features.message.setMessage({
|
||||
content: reason.message,
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { Feature } from 'oak-frontend-base';
|
||||
import { Cache } from 'oak-frontend-base/es/features/cache';
|
||||
type IMode = 'systemProvider' | 'store';
|
||||
export default class Console extends Feature {
|
||||
private cache;
|
||||
constructor(cache: Cache<EntityDict>);
|
||||
getMode(allowUninitialized?: boolean): IMode;
|
||||
initialize(): Promise<void>;
|
||||
destroy(): Promise<void>;
|
||||
}
|
||||
export {};
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import { Feature } from 'oak-frontend-base';
|
||||
export default class Console extends Feature {
|
||||
cache;
|
||||
constructor(cache) {
|
||||
super();
|
||||
this.cache = cache;
|
||||
}
|
||||
getMode(allowUninitialized) {
|
||||
return 'systemProvider';
|
||||
}
|
||||
async initialize() {
|
||||
}
|
||||
async destroy() {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { Feature } from 'oak-frontend-base';
|
||||
import { ContextMenuFactory } from 'oak-frontend-base/es/features/contextMenuFactory';
|
||||
import Console from './Console';
|
||||
type GroupName = 'System';
|
||||
export interface OMenu {
|
||||
name: GroupName | string;
|
||||
icon: string;
|
||||
url?: string;
|
||||
children?: Array<OMenu>;
|
||||
}
|
||||
export default class Menu extends Feature {
|
||||
private contextMenuFactory;
|
||||
private console;
|
||||
private menus?;
|
||||
constructor(contextMenuFactory: ContextMenuFactory<EntityDict>, console: Console);
|
||||
refreshMenus(): void;
|
||||
getMenus(): OMenu[] | undefined;
|
||||
}
|
||||
export {};
|
||||
|
|
@ -1,41 +1,13 @@
|
|||
import { EntityDict } from '@project/oak-app-domain';
|
||||
import { Feature } from 'oak-frontend-base';
|
||||
import { ContextMenuFactory } from 'oak-frontend-base/es/features/contextMenuFactory';
|
||||
import Console from './Console';
|
||||
|
||||
type GroupName = 'System';
|
||||
|
||||
type Groups = {
|
||||
icon: string;
|
||||
name: GroupName;
|
||||
}[];
|
||||
|
||||
interface IMenu<T extends keyof EntityDict> {
|
||||
name: string;
|
||||
icon: string;
|
||||
url: string;
|
||||
entity?: T;
|
||||
paths?: string[];
|
||||
action?: EntityDict[T]['Action'];
|
||||
parent?: GroupName;
|
||||
};
|
||||
|
||||
export interface OMenu {
|
||||
name: GroupName | string;
|
||||
icon: string;
|
||||
url?: string;
|
||||
children?: Array<OMenu>;
|
||||
};
|
||||
|
||||
|
||||
const groups: Groups = [
|
||||
;
|
||||
;
|
||||
const groups = [
|
||||
{
|
||||
name: 'System', // 系统级别配置
|
||||
name: 'System', // 系统级别配置
|
||||
icon: 'setup_fill',
|
||||
},
|
||||
];
|
||||
|
||||
const menus: IMenu<keyof EntityDict>[] = [
|
||||
const menus = [
|
||||
{
|
||||
name: 'Dashboard',
|
||||
icon: 'document',
|
||||
|
|
@ -51,27 +23,19 @@ const menus: IMenu<keyof EntityDict>[] = [
|
|||
paths: [],
|
||||
},
|
||||
];
|
||||
|
||||
export default class Menu extends Feature {
|
||||
private contextMenuFactory: ContextMenuFactory<EntityDict>;
|
||||
private console: Console;
|
||||
private menus?: OMenu[];
|
||||
|
||||
constructor(
|
||||
contextMenuFactory: ContextMenuFactory<EntityDict>,
|
||||
console: Console
|
||||
) {
|
||||
contextMenuFactory;
|
||||
console;
|
||||
menus;
|
||||
constructor(contextMenuFactory, console) {
|
||||
super();
|
||||
this.contextMenuFactory = contextMenuFactory;
|
||||
this.contextMenuFactory.setMenus(menus);
|
||||
this.console = console;
|
||||
this.console.subscribe(
|
||||
() => {
|
||||
this.refreshMenus();
|
||||
}
|
||||
);
|
||||
this.console.subscribe(() => {
|
||||
this.refreshMenus();
|
||||
});
|
||||
}
|
||||
|
||||
refreshMenus() {
|
||||
/* const roomId = this.console.getRoomId();
|
||||
const menus = this.contextMenuFactory.getMenusByContext<IMenu<keyof EntityDict>>('room', roomId);
|
||||
|
|
@ -89,7 +53,6 @@ export default class Menu extends Feature {
|
|||
);
|
||||
this.publish(); */
|
||||
}
|
||||
|
||||
getMenus() {
|
||||
if (!this.menus) {
|
||||
this.refreshMenus();
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue