增加了application和system中的相关数据结构,用于检查和控制应用升级
This commit is contained in:
parent
f8635876c6
commit
7021b0e548
|
|
@ -89,6 +89,7 @@ export type AspectDict<ED extends EntityDict> = {
|
|||
type: 'login' | 'changePassword' | 'confirm';
|
||||
}, context: BackendRuntimeContext<ED>) => Promise<string>;
|
||||
getApplication: (params: {
|
||||
version: string;
|
||||
type: AppType;
|
||||
domain: string;
|
||||
data: ED['application']['Projection'];
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { WebEnv } from 'oak-domain/lib/types/Environment';
|
|||
import { File } from 'formidable';
|
||||
import { BRC } from '../types/RuntimeCxt';
|
||||
export declare function getApplication<ED extends EntityDict>(params: {
|
||||
version: string;
|
||||
type: AppType;
|
||||
domain: string;
|
||||
data: ED['application']['Projection'];
|
||||
|
|
|
|||
|
|
@ -2,8 +2,10 @@ import { assert } from 'oak-domain/lib/utils/assert';
|
|||
import { applicationProjection } from '../types/Projection';
|
||||
import WechatSDK from 'oak-external-sdk/lib/WechatSDK';
|
||||
import fs from 'fs';
|
||||
import { cloneDeep } from 'oak-domain/lib/utils/lodash';
|
||||
import { cloneDeep, unset } from 'oak-domain/lib/utils/lodash';
|
||||
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
||||
import { compareVersion } from 'oak-domain/lib/utils/version';
|
||||
import { OakApplicationHasToUpgrade } from 'oak-domain/lib/types/Exception';
|
||||
async function getApplicationByDomain(context, options) {
|
||||
const { data, type, domain } = options;
|
||||
let applications = await context.select('application', {
|
||||
|
|
@ -39,8 +41,26 @@ async function getApplicationByDomain(context, options) {
|
|||
}
|
||||
return applications;
|
||||
}
|
||||
function checkAppVersionSafe(application, version) {
|
||||
const { dangerousVersions, warningVersions, system } = application;
|
||||
const { oldestVersion, platform } = system;
|
||||
const { oldestVersion: pfOldestVersion } = platform || {};
|
||||
const oldest = pfOldestVersion || oldestVersion;
|
||||
if (oldest) {
|
||||
if (compareVersion(version, oldest) < 0) {
|
||||
throw new OakApplicationHasToUpgrade();
|
||||
}
|
||||
}
|
||||
if (dangerousVersions && dangerousVersions.includes(version)) {
|
||||
throw new OakApplicationHasToUpgrade();
|
||||
}
|
||||
unset(application, 'dangerousVersions');
|
||||
if (warningVersions) {
|
||||
application.warningVersions = warningVersions.filter(ele => ele === version);
|
||||
}
|
||||
}
|
||||
export async function getApplication(params, context) {
|
||||
const { type, domain, data, appId } = params;
|
||||
const { type, domain, data, appId, version } = params;
|
||||
// 先找指定domain的应用,如果不存在再找系统下面的domain, 但无论怎么样都必须一项
|
||||
const applications = await getApplicationByDomain(context, {
|
||||
type,
|
||||
|
|
@ -51,11 +71,13 @@ export async function getApplication(params, context) {
|
|||
case 'wechatMp': {
|
||||
assert(applications.length === 1, `微信小程序环境下,同一个系统必须存在唯一的【${type}】应用,域名「${domain}」`);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
case 'native': {
|
||||
assert(applications.length === 1, `APP环境下,同一个系统必须存在唯一的【${type}】应用,域名「${domain}」`);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
case 'wechatPublic': {
|
||||
|
|
@ -68,15 +90,18 @@ export async function getApplication(params, context) {
|
|||
});
|
||||
assert(webApplications.length === 1, `微信公众号环境下, 可以未配置公众号,但必须存在web应用,域名「${domain}」`);
|
||||
const application = webApplications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
assert(applications.length === 1, `微信公众号环境下,同一个系统必须存在唯一的【${type}】应用 或 多个${type}应用必须配置域名,域名「${domain}」`);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
case 'web': {
|
||||
assert(applications.length === 1, `web环境下,同一个系统必须存在唯一的【${type}】应用 或 多个${type}应用必须配置域名,域名「${domain}」`);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
default: {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,18 @@
|
|||
import { OakInputIllegalException } from 'oak-domain/lib/types';
|
||||
import { checkAttributesNotNull } from 'oak-domain/lib/utils/validator';
|
||||
import { isVersion } from 'oak-domain/lib/utils/version';
|
||||
function checkVersion(data) {
|
||||
const { dangerousVersions, warningVersions, soaVersion } = data;
|
||||
if (dangerousVersions && dangerousVersions.find(ele => !isVersion(ele))) {
|
||||
throw new OakInputIllegalException('application', ['dangerousVersions'], 'error::illegalVersionData');
|
||||
}
|
||||
if (warningVersions && warningVersions.find(ele => !isVersion(ele))) {
|
||||
throw new OakInputIllegalException('application', ['warningVersions'], 'error::illegalVersionData');
|
||||
}
|
||||
if (soaVersion && !isVersion(soaVersion)) {
|
||||
throw new OakInputIllegalException('application', ['soaVersion'], 'error::illegalVersionData');
|
||||
}
|
||||
}
|
||||
const checkers = [
|
||||
{
|
||||
type: 'data',
|
||||
|
|
@ -14,6 +28,7 @@ const checkers = [
|
|||
};
|
||||
if (data instanceof Array) {
|
||||
data.forEach((ele) => {
|
||||
checkVersion(ele);
|
||||
checkAttributesNotNull('application', ele, [
|
||||
'name',
|
||||
'type',
|
||||
|
|
@ -23,6 +38,7 @@ const checkers = [
|
|||
});
|
||||
}
|
||||
else {
|
||||
checkVersion(data);
|
||||
checkAttributesNotNull('application', data, [
|
||||
'name',
|
||||
'type',
|
||||
|
|
@ -33,5 +49,13 @@ const checkers = [
|
|||
return;
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'data',
|
||||
action: 'update',
|
||||
entity: 'application',
|
||||
checker(data) {
|
||||
checkVersion(data);
|
||||
}
|
||||
}
|
||||
];
|
||||
export default checkers;
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
declare const checkers: (import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "mobile", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "applicationPassport", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "token", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "message", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "parasite", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>>)[];
|
||||
declare const checkers: (import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "applicationPassport", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "token", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "mobile", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "message", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "parasite", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "system", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "platform", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>>)[];
|
||||
export default checkers;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import wechatPublicTagChecker from './wechatPublicTag';
|
|||
import messageChecker from './message';
|
||||
import parasite from './parasite';
|
||||
import applicationPassport from './applicationPassport';
|
||||
import systems from './system';
|
||||
import platforms from './platform';
|
||||
const checkers = [
|
||||
...mobileChecker,
|
||||
...addressCheckers,
|
||||
|
|
@ -21,5 +23,7 @@ const checkers = [
|
|||
...messageChecker,
|
||||
...parasite,
|
||||
...applicationPassport,
|
||||
...systems,
|
||||
...platforms
|
||||
];
|
||||
export default checkers;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { OakInputIllegalException } from 'oak-domain/lib/types';
|
||||
import { checkAttributesNotNull } from 'oak-domain/lib/utils/validator';
|
||||
import { isVersion } from 'oak-domain/lib/utils/version';
|
||||
const checkers = [
|
||||
{
|
||||
type: 'data',
|
||||
|
|
@ -15,11 +17,17 @@ const checkers = [
|
|||
if (data instanceof Array) {
|
||||
data.forEach((ele) => {
|
||||
checkAttributesNotNull('platform', ele, ['name']);
|
||||
if (ele.oldestVersion && !isVersion(ele.oldestVersion)) {
|
||||
throw new OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData', 'oak-general-business');
|
||||
}
|
||||
setData(ele);
|
||||
});
|
||||
}
|
||||
else {
|
||||
checkAttributesNotNull('platform', data, ['name']);
|
||||
if (data.oldestVersion && !isVersion(data.oldestVersion)) {
|
||||
throw new OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData', 'oak-general-business');
|
||||
}
|
||||
setData(data);
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
import { OakInputIllegalException } from 'oak-domain/lib/types';
|
||||
import { checkAttributesNotNull } from 'oak-domain/lib/utils/validator';
|
||||
import { isVersion } from 'oak-domain/lib/utils/version';
|
||||
const checkers = [
|
||||
{
|
||||
type: 'data',
|
||||
|
|
@ -20,15 +22,32 @@ const checkers = [
|
|||
if (data instanceof Array) {
|
||||
data.forEach((ele) => {
|
||||
checkAttributesNotNull('system', ele, ['name', 'platformId']);
|
||||
if (ele.oldestVersion && !isVersion(ele.oldestVersion)) {
|
||||
throw new OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData', 'oak-general-business');
|
||||
}
|
||||
setData(ele);
|
||||
});
|
||||
}
|
||||
else {
|
||||
checkAttributesNotNull('system', data, ['name', 'platformId']);
|
||||
if (data.oldestVersion && !isVersion(data.oldestVersion)) {
|
||||
throw new OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData', 'oak-general-business');
|
||||
}
|
||||
setData(data);
|
||||
}
|
||||
return;
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'data',
|
||||
action: 'update',
|
||||
entity: 'system',
|
||||
checker(data) {
|
||||
const { oldestVersion } = data;
|
||||
if (oldestVersion && !isVersion(oldestVersion)) {
|
||||
throw new OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData');
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
export default checkers;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
export default OakComponent({
|
||||
isList: false,
|
||||
entity: 'application',
|
||||
formData({ data }) {
|
||||
formData({ data, features }) {
|
||||
const { dangerousVersions, warningVersions } = data;
|
||||
return {
|
||||
dv: dangerousVersions ? features.locales.t('whole', { count: dangerousVersions.length }) : features.locales.t('common::unset'),
|
||||
wv: warningVersions ? features.locales.t('whole', { count: warningVersions.length }) : features.locales.t('common::unset'),
|
||||
...data,
|
||||
oakExecutable: this.tryExecute(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"whole": "共%{count}项"
|
||||
}
|
||||
|
|
@ -8,4 +8,7 @@ export default function Render(props: WebComponentProps<EntityDict, 'application
|
|||
tabValue: 'detail';
|
||||
type: EntityDict['application']['Schema']['type'];
|
||||
oakExecutable: boolean;
|
||||
soaVersion?: string;
|
||||
dv: string;
|
||||
wv: string;
|
||||
}>): React.JSX.Element | undefined;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ import React, { useState } from 'react';
|
|||
import { Row, Descriptions, Typography, Button, Modal, Space } from 'antd';
|
||||
import ApplicationUpsert from '../upsert';
|
||||
export default function Render(props) {
|
||||
const { id, name, description, type, oakFullpath, oakExecutable, oakExecuting } = props.data;
|
||||
const { id, name, description, type, oakFullpath, oakDirty, oakExecuting, dv, wv, soaVersion } = props.data;
|
||||
const { t, clean, execute } = props.methods;
|
||||
const [open, setOpen] = useState(false);
|
||||
if (id && oakFullpath) {
|
||||
return (<>
|
||||
<Modal open={open} width={500} onCancel={() => {
|
||||
<Modal destroyOnClose open={open} width={500} onCancel={() => {
|
||||
clean();
|
||||
setOpen(false);
|
||||
}} footer={<Space>
|
||||
|
|
@ -20,7 +20,7 @@ export default function Render(props) {
|
|||
<Button type="primary" onClick={async () => {
|
||||
await execute();
|
||||
setOpen(false);
|
||||
}} disabled={oakExecutable !== true || oakExecuting}>
|
||||
}} disabled={!oakDirty || oakExecuting}>
|
||||
{t('common::action.confirm')}
|
||||
</Button>
|
||||
</Space>}>
|
||||
|
|
@ -41,6 +41,15 @@ export default function Render(props) {
|
|||
<Descriptions.Item label={t('application:attr.type')}>
|
||||
{t(`application:v.type.${type}`)}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t('application:attr.soaVersion')}>
|
||||
{soaVersion || t('common::unset')}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t('application:attr.dangerousVersions')}>
|
||||
{dv}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t('application:attr.warningVersions')}>
|
||||
{wv}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item span={2}>
|
||||
<Row justify="end">
|
||||
<Button type="primary" onClick={() => setOpen(true)}>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ export default OakComponent({
|
|||
config: 1,
|
||||
description: 1,
|
||||
type: 1,
|
||||
dangerousVersions: 1,
|
||||
warningVersions: 1,
|
||||
soaVersion: 1,
|
||||
systemId: 1,
|
||||
domainId: 1,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ export default OakComponent({
|
|||
name: 1,
|
||||
config: 1,
|
||||
description: 1,
|
||||
dangerousVersions: 1,
|
||||
warningVersions: 1,
|
||||
soaVersion: 1,
|
||||
type: 1,
|
||||
systemId: 1,
|
||||
domainId: 1,
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@ export default function Render(props: WebComponentProps<EntityDict, 'application
|
|||
$$createAt$$: number;
|
||||
domainId: string;
|
||||
domains: EntityDict['domain']['Schema'][];
|
||||
dangerousVersions: EntityDict['application']['OpSchema']['dangerousVersions'];
|
||||
warningVersions: EntityDict['application']['OpSchema']['warningVersions'];
|
||||
soaVersion: string;
|
||||
}, {
|
||||
confirm: () => void;
|
||||
getDomains: (systemId: string) => Promise<void>;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,62 @@
|
|||
import React from 'react';
|
||||
import { Form, Select, Input } from 'antd';
|
||||
import React, { useState, useRef } from 'react';
|
||||
import { Form, Flex, Tag, Tooltip, Select, Input, theme } from 'antd';
|
||||
import { PlusOutlined, CloseOutlined } from '@ant-design/icons';
|
||||
function renderVersions(props) {
|
||||
const { versions, onChange, t } = props;
|
||||
const [inputVisible, setInputVisible] = useState(false);
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const inputRef = useRef(null);
|
||||
const tagInputStyle = {
|
||||
width: 64,
|
||||
height: 22,
|
||||
marginInlineEnd: 8,
|
||||
verticalAlign: 'top',
|
||||
};
|
||||
const { token } = theme.useToken();
|
||||
const tagPlusStyle = {
|
||||
height: 22,
|
||||
background: token.colorBgContainer,
|
||||
borderStyle: 'dashed',
|
||||
};
|
||||
const handleInputChange = (e) => {
|
||||
setInputValue(e.target.value);
|
||||
};
|
||||
const handleInputConfirm = () => {
|
||||
if (inputValue && !versions?.includes(inputValue)) {
|
||||
onChange([...versions || [], inputValue]);
|
||||
}
|
||||
setInputVisible(false);
|
||||
setInputValue('');
|
||||
};
|
||||
const handleClose = (removedTag) => {
|
||||
const versions2 = versions.filter((tag) => tag !== removedTag);
|
||||
onChange(versions2);
|
||||
};
|
||||
const showInput = () => {
|
||||
setInputVisible(true);
|
||||
};
|
||||
return (<Flex gap="4px 0" wrap="wrap">
|
||||
{(versions || []).map((tag, index) => {
|
||||
const isLongTag = tag.length > 20;
|
||||
const tagElem = (<Tag closeIcon={<CloseOutlined />} key={tag} onClose={() => handleClose(tag)}>
|
||||
<span>
|
||||
{isLongTag ? `${tag.slice(0, 20)}...` : tag}
|
||||
</span>
|
||||
</Tag>);
|
||||
return isLongTag ? (<Tooltip title={tag} key={tag}>
|
||||
{tagElem}
|
||||
</Tooltip>) : (tagElem);
|
||||
})}
|
||||
{inputVisible ? (<Input ref={inputRef} type="text" size="small" style={tagInputStyle} value={inputValue} onChange={handleInputChange} onBlur={handleInputConfirm} onPressEnter={handleInputConfirm}/>) : (<Tag style={tagPlusStyle} icon={<PlusOutlined />} onClick={showInput}>
|
||||
{t('common::action.add')}
|
||||
</Tag>)}
|
||||
</Flex>);
|
||||
}
|
||||
export default function Render(props) {
|
||||
const { systemId, name, description, type, typeArr, $$createAt$$, domainId, domains, } = props.data;
|
||||
const { systemId, name, description, type, typeArr, $$createAt$$, domainId, domains, dangerousVersions, warningVersions, soaVersion, } = props.data;
|
||||
const { t, update, confirm, getDomains } = props.methods;
|
||||
return (<Form colon={true} labelCol={{ span: 6 }} wrapperCol={{ span: 16 }}>
|
||||
<Form.Item label="名称" required>
|
||||
<Form.Item label={t('application:attr.name')} required>
|
||||
<>
|
||||
<Input onChange={(e) => {
|
||||
update({
|
||||
|
|
@ -13,7 +65,34 @@ export default function Render(props) {
|
|||
}} value={name}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="描述">
|
||||
<Form.Item label={t('application:attr.soaVersion')} required>
|
||||
<>
|
||||
<Input onChange={(e) => {
|
||||
update({
|
||||
soaVersion: e.target.value,
|
||||
});
|
||||
}} value={soaVersion}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('application:attr.dangerousVersions')}>
|
||||
{renderVersions({
|
||||
versions: dangerousVersions,
|
||||
onChange: (v) => update({
|
||||
dangerousVersions: v
|
||||
}),
|
||||
t,
|
||||
})}
|
||||
</Form.Item>
|
||||
<Form.Item label={t('application:attr.warningVersions')}>
|
||||
{renderVersions({
|
||||
versions: warningVersions,
|
||||
onChange: (v) => update({
|
||||
warningVersions: v
|
||||
}),
|
||||
t,
|
||||
})}
|
||||
</Form.Item>
|
||||
<Form.Item label={t('application:attr.description')}>
|
||||
<>
|
||||
<Input.TextArea onChange={(e) => {
|
||||
update({
|
||||
|
|
@ -22,7 +101,7 @@ export default function Render(props) {
|
|||
}} value={description}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="应用类型" required>
|
||||
<Form.Item label={t('application:attr.type')} required>
|
||||
<>
|
||||
<Select value={type} style={{ width: 120 }} disabled={$$createAt$$ > 1} options={typeArr.map((ele) => ({
|
||||
label: t(`application:v.type.${ele.value}`),
|
||||
|
|
@ -34,7 +113,7 @@ export default function Render(props) {
|
|||
}}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label="域名">
|
||||
<Form.Item label={t('domain:name')}>
|
||||
<>
|
||||
<Select allowClear value={domainId} style={{ width: 120 }} options={domains?.map((ele) => ({
|
||||
label: ele.url,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "article", true, {
|
||||
articleMenuId: string | undefined;
|
||||
onChildEditArticleChange: (data: string) => void;
|
||||
show: "preview" | "edit" | "doc";
|
||||
show: "edit" | "doc" | "preview";
|
||||
getBreadcrumbItemsByParent: (breadcrumbItems: string[]) => void;
|
||||
breadcrumbItems: string[];
|
||||
drawerOpen: boolean;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ declare const _default: (props: import("oak-frontend-base").ReactComponentProps<
|
|||
onRemove: () => void;
|
||||
onUpdateName: (name: string) => Promise<void>;
|
||||
onChildEditArticleChange: (data: string) => void;
|
||||
show: "preview" | "edit" | "doc";
|
||||
show: "edit" | "doc" | "preview";
|
||||
getBreadcrumbItemsByParent: (breadcrumbItems: string[]) => void;
|
||||
breadItems: string[];
|
||||
drawerOpen: boolean;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ declare const _default: (props: import("oak-frontend-base").ReactComponentProps<
|
|||
entityId: string;
|
||||
parentId: string | undefined;
|
||||
onGrandChildEditArticleChange: (data: string) => void;
|
||||
show: "preview" | "edit" | "doc";
|
||||
show: "edit" | "doc" | "preview";
|
||||
articleMenuId: string;
|
||||
articleId: string;
|
||||
getBreadcrumbItems: (breadcrumbItems: string[]) => void;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, "articleMenu", true, {
|
||||
entity: string;
|
||||
entityId: string;
|
||||
show: "preview" | "edit" | "doc";
|
||||
show: "edit" | "doc" | "preview";
|
||||
articleMenuId: string;
|
||||
articleId: string;
|
||||
tocPosition: "none" | "left" | "right";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Style } from '../../../../types/Style';
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../../oak-app-domain").EntityDict, keyof import("../../../../oak-app-domain").EntityDict, false, {
|
||||
style: Style;
|
||||
entity: "application" | "system" | "platform";
|
||||
entity: "application" | "platform" | "system";
|
||||
entityId: string;
|
||||
name: string;
|
||||
}>) => React.ReactElement;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { Config } from '../../../types/Config';
|
||||
declare const _default: (props: import("oak-frontend-base").ReactComponentProps<import("../../../oak-app-domain").EntityDict, keyof import("../../../oak-app-domain").EntityDict, false, {
|
||||
config: Config;
|
||||
entity: "system" | "platform";
|
||||
entity: "platform" | "system";
|
||||
name: string;
|
||||
entityId: string;
|
||||
}>) => React.ReactElement;
|
||||
|
|
|
|||
|
|
@ -15,16 +15,16 @@ declare const _default: <ED2 extends EntityDict & BaseEntityDict, T2 extends key
|
|||
type?: ButtonProps['type'] | AmButtonProps['type'];
|
||||
executeText?: string | undefined;
|
||||
buttonProps?: (ButtonProps & {
|
||||
color?: "default" | "success" | "primary" | "warning" | "danger" | undefined;
|
||||
color?: "default" | "success" | "warning" | "primary" | "danger" | undefined;
|
||||
fill?: "none" | "solid" | "outline" | undefined;
|
||||
size?: "small" | "large" | "middle" | "mini" | undefined;
|
||||
size?: "small" | "middle" | "large" | "mini" | undefined;
|
||||
block?: boolean | undefined;
|
||||
loading?: boolean | "auto" | undefined;
|
||||
loadingText?: string | undefined;
|
||||
loadingIcon?: import("react").ReactNode;
|
||||
disabled?: boolean | undefined;
|
||||
onClick?: ((event: import("react").MouseEvent<HTMLButtonElement, MouseEvent>) => unknown) | undefined;
|
||||
type?: "button" | "reset" | "submit" | undefined;
|
||||
type?: "button" | "submit" | "reset" | undefined;
|
||||
shape?: "default" | "rounded" | "rectangular" | undefined;
|
||||
children?: import("react").ReactNode;
|
||||
} & Pick<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement>, "id" | "onMouseDown" | "onMouseUp" | "onTouchEnd" | "onTouchStart"> & {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { WebComponentProps } from 'oak-frontend-base';
|
|||
export default function Render(props: WebComponentProps<EntityDict, 'platform', false, {
|
||||
name: string;
|
||||
description: string;
|
||||
oldestVersion: string;
|
||||
style: EntityDict['system']['Schema']['style'];
|
||||
}, {
|
||||
confirm: () => void;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Form, Input } from 'antd';
|
||||
export default function Render(props) {
|
||||
const { name, description, style } = props.data;
|
||||
const { name, description, oldestVersion } = props.data;
|
||||
const { t, update, navigateBack, confirm } = props.methods;
|
||||
return (<Form colon={true} labelCol={{ span: 4 }} wrapperCol={{ span: 16 }}>
|
||||
<Form.Item label="名称" required>
|
||||
|
|
@ -21,6 +21,15 @@ export default function Render(props) {
|
|||
});
|
||||
}} value={description}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('platform:attr.oldestVersion')}>
|
||||
<>
|
||||
<Input onChange={(e) => {
|
||||
update({
|
||||
oldestVersion: e.target.value,
|
||||
});
|
||||
}} value={oldestVersion}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
</Form>);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@ export default function Render(props: WebComponentProps<EntityDict, 'platform',
|
|||
oakId: string;
|
||||
super: boolean;
|
||||
oakExecutable: boolean;
|
||||
oldestVersion: string;
|
||||
}>): React.JSX.Element | null;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { Row, Modal, Descriptions, Typography, Button, Space } from 'antd';
|
|||
import SystemUpsert from '../upsert';
|
||||
import Styles from './web.pc.module.less';
|
||||
export default function Render(props) {
|
||||
const { oakId, name, description, 'super': isSuper, oakFullpath, oakExecutable, oakExecuting } = props.data;
|
||||
const { oakId, name, description, 'super': isSuper, oakFullpath, oakExecutable, oakExecuting, oldestVersion } = props.data;
|
||||
const { t, execute, clean } = props.methods;
|
||||
const [open, setOpen] = useState(false);
|
||||
if (oakFullpath) {
|
||||
|
|
@ -43,6 +43,9 @@ export default function Render(props) {
|
|||
<Descriptions.Item label={t('system:attr.description')}>
|
||||
{description}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t('system:attr.oldestVersion')}>
|
||||
{oldestVersion || t('common::unset')}
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label={t('system:attr.super')}>
|
||||
{isSuper ? '是' : '否'}
|
||||
</Descriptions.Item>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export default OakComponent({
|
|||
name: 1,
|
||||
config: 1,
|
||||
description: 1,
|
||||
oldestVersion: 1,
|
||||
super: 1,
|
||||
domain$system: {
|
||||
$entity: 'domain',
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ export default OakComponent({
|
|||
name: 1,
|
||||
config: 1,
|
||||
description: 1,
|
||||
oldestVersion: 1,
|
||||
super: 1,
|
||||
},
|
||||
formData({ data }) {
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
"tips": {
|
||||
"isSuper": "超级系统属性可能影响程序的运行逻辑,请谨慎修改"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"tips": {
|
||||
"isSuper": "超级系统属性可能影响程序的运行逻辑,请谨慎修改",
|
||||
"oldestVersion": "系统能兼容的最低应用版本号,格式为X.X.X"
|
||||
}
|
||||
}
|
||||
|
|
@ -5,4 +5,5 @@ export default function Render(props: WebComponentProps<EntityDict, 'system', fa
|
|||
name: string;
|
||||
description: string;
|
||||
super: boolean;
|
||||
oldestVersion: string;
|
||||
}>): React.JSX.Element;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Form, Switch, Input } from 'antd';
|
||||
export default function Render(props) {
|
||||
const { name, description, super: super2, } = props.data;
|
||||
const { name, description, super: super2, oldestVersion, } = props.data;
|
||||
const { t, update } = props.methods;
|
||||
return (<Form colon={true} labelCol={{ span: 6 }} wrapperCol={{ span: 16 }}>
|
||||
<Form.Item label={t('system:attr.name')} required>
|
||||
|
|
@ -22,9 +22,18 @@ export default function Render(props) {
|
|||
}} value={description}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('system:attr.oldestVersion')} tooltip={t('tips.oldestVersion')}>
|
||||
<>
|
||||
<Input onChange={(e) => {
|
||||
update({
|
||||
oldestVersion: e.target.value,
|
||||
});
|
||||
}} value={oldestVersion}/>
|
||||
</>
|
||||
</Form.Item>
|
||||
<Form.Item label={t('system:attr.super')} required tooltip={t('tips.isSuper')}>
|
||||
<>
|
||||
<Switch checkedChildren={t('common::yes')} unCheckedChildren={t('common::no')} checked={super2} onChange={(checked) => {
|
||||
<Switch checkedChildren={t('common::true')} unCheckedChildren={t('common::false')} checked={super2} onChange={(checked) => {
|
||||
update({
|
||||
super: checked,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { RuntimeContext } from './RuntimeContext';
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { SerializedData } from './FrontendRuntimeContext';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { OakException } from 'oak-domain/lib/types/Exception';
|
||||
import { BackendRuntimeContext as BRC } from 'oak-frontend-base/lib/context/BackendRuntimeContext';
|
||||
/**
|
||||
* general数据结构要求的后台上下文
|
||||
|
|
@ -14,15 +15,16 @@ export declare abstract class BackendRuntimeContext<ED extends EntityDict & Base
|
|||
protected rootMode?: boolean;
|
||||
private userId?;
|
||||
protected platformManager?: boolean;
|
||||
protected appVersion?: string;
|
||||
protected applicationProjection: EntityDict['user']['Projection'];
|
||||
refineOpRecords(): Promise<void>;
|
||||
setPlatformManager(tokenValue?: string, userId?: string): Promise<void>;
|
||||
setTokenValue(tokenValue?: string, userId?: string): Promise<void>;
|
||||
setApplication(appId: string): Promise<void>;
|
||||
initialize(data?: SerializedData, later?: boolean): Promise<void>;
|
||||
getApplicationId(): ED["application"]["Schema"]["id"] | undefined;
|
||||
getSystemId(): ED["application"]["Schema"]["systemId"] | undefined;
|
||||
getApplication(): Partial<ED["application"]["Schema"]> | undefined;
|
||||
getApplicationId<P extends true | undefined>(allowNull?: P): P extends undefined ? (string | undefined) : string;
|
||||
getSystemId<P extends true | undefined>(allowNull?: P): P extends undefined ? (string | undefined) : string;
|
||||
getApplication<P extends true | undefined>(allowNull?: P): P extends undefined ? (Partial<ED['application']['Schema']> | undefined) : Partial<ED['application']['Schema']>;
|
||||
openRootMode(): () => void;
|
||||
getTokenValue(allowUnloggedIn?: boolean): "oak-root-token" | ED["token"]["Schema"]["value"] | undefined;
|
||||
getToken(allowUnloggedIn?: boolean): Partial<ED["token"]["Schema"]> | undefined;
|
||||
|
|
@ -38,5 +40,6 @@ export declare abstract class BackendRuntimeContext<ED extends EntityDict & Base
|
|||
* http://www.xxx.com/oak-api
|
||||
*/
|
||||
composeAccessPath(): string;
|
||||
tryDeduceException(err: Error): Promise<OakException<any> | void>;
|
||||
}
|
||||
export default BackendRuntimeContext;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { OakTokenExpiredException, OakUserDisabledException, } from '../types/Exception';
|
||||
import { OakApplicationLoadingException, OakTokenExpiredException, OakUserDisabledException, } from '../types/Exception';
|
||||
import { OakUnloggedInException, } from 'oak-domain/lib/types/Exception';
|
||||
import { ROOT_TOKEN_ID } from '../constants';
|
||||
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
||||
import { OakApplicationHasToUpgrade } from 'oak-domain/lib/types';
|
||||
import { applicationProjection } from '../types/Projection';
|
||||
import { getMpUnlimitWxaCode } from '../aspects/wechatQrCode';
|
||||
import { BackendRuntimeContext as BRC } from 'oak-frontend-base/lib/context/BackendRuntimeContext';
|
||||
import { cloneDeep, unset } from 'oak-domain/lib/utils/lodash';
|
||||
import { composeServerUrl } from '../utils/domain';
|
||||
import { maskPassword } from '../utils/user';
|
||||
import { compareVersion } from 'oak-domain/lib/utils/version';
|
||||
/**
|
||||
* general数据结构要求的后台上下文
|
||||
*/
|
||||
|
|
@ -20,6 +22,7 @@ export class BackendRuntimeContext extends BRC {
|
|||
rootMode;
|
||||
userId;
|
||||
platformManager;
|
||||
appVersion;
|
||||
applicationProjection = cloneDeep(applicationProjection);
|
||||
async refineOpRecords() {
|
||||
const isRoot = this.isRoot();
|
||||
|
|
@ -259,7 +262,8 @@ export class BackendRuntimeContext extends BRC {
|
|||
if (data) {
|
||||
const closeRootMode = this.openRootMode();
|
||||
try {
|
||||
const { a: appId, t: tokenValue, rm, userId } = data;
|
||||
const { a: appId, t: tokenValue, rm, userId, v } = data;
|
||||
this.appVersion = v;
|
||||
const promises = [];
|
||||
if (appId) {
|
||||
promises.push(this.setApplication(appId));
|
||||
|
|
@ -285,13 +289,31 @@ export class BackendRuntimeContext extends BRC {
|
|||
this.rootMode = true;
|
||||
}
|
||||
}
|
||||
getApplicationId() {
|
||||
getApplicationId(allowNull) {
|
||||
if (!allowNull) {
|
||||
if (!this.application) {
|
||||
throw new OakApplicationLoadingException();
|
||||
}
|
||||
return this.application.id;
|
||||
}
|
||||
return this.application?.id;
|
||||
}
|
||||
getSystemId() {
|
||||
getSystemId(allowNull) {
|
||||
if (!allowNull) {
|
||||
if (!this.application) {
|
||||
throw new OakApplicationLoadingException();
|
||||
}
|
||||
return this.application.systemId;
|
||||
}
|
||||
return this.application?.systemId;
|
||||
}
|
||||
getApplication() {
|
||||
getApplication(allowNull) {
|
||||
if (!allowNull) {
|
||||
if (!this.application) {
|
||||
throw new OakApplicationLoadingException();
|
||||
}
|
||||
return this.application;
|
||||
}
|
||||
return this.application;
|
||||
}
|
||||
openRootMode() {
|
||||
|
|
@ -342,6 +364,7 @@ export class BackendRuntimeContext extends BRC {
|
|||
a: this.application?.id,
|
||||
rm: this.rootMode,
|
||||
userId: this.getCurrentUserId(true),
|
||||
v: this.appVersion,
|
||||
};
|
||||
}
|
||||
isRoot() {
|
||||
|
|
@ -394,6 +417,16 @@ export class BackendRuntimeContext extends BRC {
|
|||
const [domain] = domains;
|
||||
return composeServerUrl(domain);
|
||||
}
|
||||
async tryDeduceException(err) {
|
||||
if (this.application && this.appVersion) {
|
||||
const { soaVersion } = this.application;
|
||||
if (soaVersion && compareVersion(this.appVersion, soaVersion) < 0) {
|
||||
// 说明客户端可以升级
|
||||
return new OakApplicationHasToUpgrade();
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
;
|
||||
export default BackendRuntimeContext;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export interface SerializedData extends Fsd {
|
|||
t?: string;
|
||||
userId?: string;
|
||||
rm?: boolean;
|
||||
v?: string;
|
||||
}
|
||||
export declare abstract class FrontendRuntimeContext<ED extends EntityDict & BaseEntityDict> extends Frc<ED> implements RuntimeContext {
|
||||
private application;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ export class FrontendRuntimeContext extends Frc {
|
|||
// appId必须要取到,不能失败
|
||||
const setInner = (resolve, reject) => {
|
||||
try {
|
||||
if (!this.application) {
|
||||
// 有可能在系统初始化的时候调用,this.application还没建立
|
||||
resolve(undefined);
|
||||
return;
|
||||
}
|
||||
const appId = this.application.getApplicationId();
|
||||
assert(appId);
|
||||
Object.assign(data, {
|
||||
|
|
@ -42,6 +47,11 @@ export class FrontendRuntimeContext extends Frc {
|
|||
const setTokenValue = async () => {
|
||||
const setInner = (resolve, reject) => {
|
||||
try {
|
||||
if (!this.token) {
|
||||
// 有可能在系统初始化的时候调用,this.token还没建立
|
||||
resolve(undefined);
|
||||
return;
|
||||
}
|
||||
const tokenValue = this.token.getTokenValue();
|
||||
if (tokenValue) {
|
||||
Object.assign(data, {
|
||||
|
|
@ -65,6 +75,9 @@ export class FrontendRuntimeContext extends Frc {
|
|||
return new Promise((resolve, reject) => setInner(resolve, reject));
|
||||
};
|
||||
await setTokenValue();
|
||||
Object.assign(data, {
|
||||
v: this.application.getVersion(),
|
||||
});
|
||||
return data;
|
||||
}
|
||||
getApplicationId() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,15 @@
|
|||
// 本文件为自动编译产生,请勿直接修改
|
||||
const i18ns = [
|
||||
{
|
||||
id: "c0ce3f84c8cd6f70457b7e57a8ac8b8f",
|
||||
namespace: "oak-general-business-c-application-detail",
|
||||
language: "zh-CN",
|
||||
module: "oak-general-business",
|
||||
position: "src/components/application/detail",
|
||||
data: {
|
||||
"whole": "共%{count}项"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "2ebe552614a81e57fa1a1c21b5dc84f8",
|
||||
namespace: "oak-general-business-c-application-panel",
|
||||
|
|
@ -249,6 +259,19 @@ const i18ns = [
|
|||
"login": "登录管理"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "819147f0564533e19aacf71c13d6f366",
|
||||
namespace: "oak-general-business-c-system-upsert",
|
||||
language: "zh-CN",
|
||||
module: "oak-general-business",
|
||||
position: "src/components/system/upsert",
|
||||
data: {
|
||||
"tips": {
|
||||
"isSuper": "超级系统属性可能影响程序的运行逻辑,请谨慎修改",
|
||||
"oldestVersion": "系统能兼容的最低应用版本号,格式为X.X.X"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "7bcbb4dbb525e9a575095102f673f7ba",
|
||||
namespace: "oak-general-business-c-token-me",
|
||||
|
|
@ -645,7 +668,8 @@ const i18ns = [
|
|||
"mpHaveToSubscribe": "需要订阅小程序消息",
|
||||
"userInfoLoading": "正在加载用户信息",
|
||||
"applicationLoading": "应用正在初始化",
|
||||
"uploadFailed": "上传失败"
|
||||
"uploadFailed": "上传失败",
|
||||
"illegalVersionData": "版本号必须是x.x.x的形式"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export type NativeConfig = {
|
|||
port: string;
|
||||
};
|
||||
};
|
||||
type Versions = string[];
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<32>;
|
||||
description?: Text;
|
||||
|
|
@ -82,6 +83,10 @@ export interface Schema extends EntityShape {
|
|||
system: System;
|
||||
config: WebConfig | WechatMpConfig | WechatPublicConfig | NativeConfig;
|
||||
style?: Style;
|
||||
dangerousVersions: Versions;
|
||||
warningVersions: Versions;
|
||||
soaVersion: String<12>;
|
||||
sessions?: Session[];
|
||||
domain?: Domain;
|
||||
}
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ const entityDesc = {
|
|||
style: '样式',
|
||||
sessions: '会话',
|
||||
domain: '域名',
|
||||
dangerousVersions: '强制升级版本',
|
||||
warningVersions: '建议升级版本',
|
||||
soaVersion: '最新发布版本'
|
||||
},
|
||||
v: {
|
||||
type: {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export interface Schema extends EntityShape {
|
|||
name: String<32>;
|
||||
description?: Text;
|
||||
config: Config;
|
||||
oldestVersion?: String<32>;
|
||||
style?: Style;
|
||||
entity?: String<32>;
|
||||
entityId?: String<64>;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export const entityDesc = {
|
|||
style: '样式',
|
||||
entity: '关联对象',
|
||||
entityId: '关联对象id',
|
||||
oldestVersion: '支持app最低版本'
|
||||
},
|
||||
r: {
|
||||
owner: '拥有者',
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export interface Schema extends EntityShape {
|
|||
config: Config;
|
||||
platform?: Platform;
|
||||
folder?: String<16>;
|
||||
oldestVersion?: String<32>;
|
||||
super?: Boolean;
|
||||
style?: Style;
|
||||
entity?: String<32>;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ export const entityDesc = {
|
|||
style: '样式',
|
||||
entity: '关联对象',
|
||||
entityId: '关联对象id',
|
||||
oldestVersion: '支持app最低版本'
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,17 @@ import { Feature } from 'oak-frontend-base/es/types/Feature';
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { MediaType, MediaVideoDescription } from '../types/WeChat';
|
||||
export declare class Application<ED extends EntityDict> extends Feature {
|
||||
private version;
|
||||
private applicationId?;
|
||||
private application?;
|
||||
private cache;
|
||||
private storage;
|
||||
private projection;
|
||||
private sensitiveEntities;
|
||||
constructor(cache: Cache<ED>, storage: LocalStorage);
|
||||
constructor(cache: Cache<ED>, storage: LocalStorage, version: string);
|
||||
private getApplicationFromCache;
|
||||
private loadApplicationInfo;
|
||||
initialize(domain: string, appId?: string | null, projection?: EntityDict['application']['Projection']): Promise<void>;
|
||||
initialize(version: string, domain: string, appId?: string | null, projection?: EntityDict['application']['Projection']): Promise<void>;
|
||||
getApplication(): Partial<ED["application"]["Schema"]>;
|
||||
getApplicationId(allowUnInitialized?: boolean): string | undefined;
|
||||
uploadWechatMedia(params: {
|
||||
|
|
@ -23,4 +24,5 @@ export declare class Application<ED extends EntityDict> extends Feature {
|
|||
isPermanent?: boolean;
|
||||
description?: MediaVideoDescription;
|
||||
}): Promise<any>;
|
||||
getVersion(): string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,15 +5,17 @@ import { traverseProjection } from 'oak-domain/lib/utils/projection';
|
|||
import { applicationProjection } from '../types/Projection';
|
||||
import { OakApplicationLoadingException, } from '../types/Exception';
|
||||
export class Application extends Feature {
|
||||
version;
|
||||
applicationId;
|
||||
application;
|
||||
cache;
|
||||
storage;
|
||||
projection;
|
||||
sensitiveEntities = [];
|
||||
constructor(cache, storage) {
|
||||
constructor(cache, storage, version) {
|
||||
super();
|
||||
this.cache = cache;
|
||||
this.version = version;
|
||||
this.storage = storage;
|
||||
this.projection = cloneDeep(applicationProjection);
|
||||
// this.application做一层缓存,有时候更新了一些相关的属性还是要更新的
|
||||
|
|
@ -50,7 +52,7 @@ export class Application extends Feature {
|
|||
this.application = data[0];
|
||||
return this.application;
|
||||
}
|
||||
async loadApplicationInfo(domain) {
|
||||
async loadApplicationInfo(version, domain) {
|
||||
let applicationId;
|
||||
let appType = 'web';
|
||||
if (process.env.OAK_PLATFORM === 'wechatMp') {
|
||||
|
|
@ -65,6 +67,7 @@ export class Application extends Feature {
|
|||
}
|
||||
}
|
||||
const { result } = await this.cache.exec('getApplication', {
|
||||
version,
|
||||
type: appType,
|
||||
domain,
|
||||
data: this.projection,
|
||||
|
|
@ -79,16 +82,17 @@ export class Application extends Feature {
|
|||
// }
|
||||
this.publish();
|
||||
}
|
||||
async initialize(domain, appId, projection) {
|
||||
async initialize(version, domain, appId, projection) {
|
||||
// const applicationId = await this.storage.load(LOCAL_STORAGE_KEYS.appId);
|
||||
// this.applicationId = applicationId;
|
||||
//接收外层注入的projection
|
||||
this.version = version;
|
||||
this.projection = merge(this.projection, projection);
|
||||
if (process.env.NODE_ENV === 'development' && appId) {
|
||||
// development环境下允许注入一个线上的appId
|
||||
this.applicationId = appId;
|
||||
}
|
||||
return await this.loadApplicationInfo(domain);
|
||||
return await this.loadApplicationInfo(version, domain);
|
||||
}
|
||||
getApplication() {
|
||||
if (this.applicationId === undefined) {
|
||||
|
|
@ -119,4 +123,7 @@ export class Application extends Feature {
|
|||
const callBack = await this.cache.exec('uploadWechatMedia', formData);
|
||||
return callBack.result;
|
||||
}
|
||||
getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ import { WechatMenu } from './wechatMenu';
|
|||
import { WechatPublicTag } from './wechatPublicTag';
|
||||
import { UserWechatPublicTag } from './userWechatPublicTag';
|
||||
import Theme from './theme';
|
||||
import { oakGetPackageJsonVersion } from '../utils/appVersion';
|
||||
export function create(basicFeatures) {
|
||||
const application = new Application(basicFeatures.cache, basicFeatures.localStorage);
|
||||
const application = new Application(basicFeatures.cache, basicFeatures.localStorage, oakGetPackageJsonVersion());
|
||||
const token = new Token(basicFeatures.cache, basicFeatures.localStorage, basicFeatures.environment, application);
|
||||
const wechatMenu = new WechatMenu(basicFeatures.cache, basicFeatures.localStorage);
|
||||
const wechatPublicTag = new WechatPublicTag(basicFeatures.cache, basicFeatures.localStorage);
|
||||
|
|
@ -33,7 +34,7 @@ export function create(basicFeatures) {
|
|||
};
|
||||
}
|
||||
export async function initialize(features, access, config, clazzes) {
|
||||
await features.application.initialize(access.http.hostname, undefined, config?.applicationExtraProjection);
|
||||
await features.application.initialize(oakGetPackageJsonVersion(), access.http.hostname, undefined, config?.applicationExtraProjection);
|
||||
if (process.env.OAK_PLATFORM === 'web') {
|
||||
features.wechatSdk.setLandingUrl(window.location.href);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,5 +22,6 @@
|
|||
"mpHaveToSubscribe": "需要订阅小程序消息",
|
||||
"userInfoLoading": "正在加载用户信息",
|
||||
"applicationLoading": "应用正在初始化",
|
||||
"uploadFailed": "上传失败"
|
||||
"uploadFailed": "上传失败",
|
||||
"illegalVersionData": "版本号必须是x.x.x的形式"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,21 @@ export const desc = {
|
|||
style: {
|
||||
type: "object"
|
||||
},
|
||||
dangerousVersions: {
|
||||
notNull: true,
|
||||
type: "object"
|
||||
},
|
||||
warningVersions: {
|
||||
notNull: true,
|
||||
type: "object"
|
||||
},
|
||||
soaVersion: {
|
||||
notNull: true,
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 12
|
||||
}
|
||||
},
|
||||
domainId: {
|
||||
type: "ref",
|
||||
ref: "domain"
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export type NativeConfig = {
|
|||
port: string;
|
||||
};
|
||||
};
|
||||
type Versions = string[];
|
||||
export type OpSchema = EntityShape & {
|
||||
name: String<32>;
|
||||
description?: Text | null;
|
||||
|
|
@ -82,6 +83,9 @@ export type OpSchema = EntityShape & {
|
|||
systemId: ForeignKey<"system">;
|
||||
config: WebConfig | WechatMpConfig | WechatPublicConfig | NativeConfig;
|
||||
style?: Style | null;
|
||||
dangerousVersions: Versions;
|
||||
warningVersions: Versions;
|
||||
soaVersion: String<12>;
|
||||
domainId?: ForeignKey<"domain"> | null;
|
||||
} & {
|
||||
[A in ExpressionKey]?: any;
|
||||
|
|
@ -98,6 +102,9 @@ export type OpFilter = {
|
|||
systemId: Q_StringValue;
|
||||
config: JsonFilter<WebConfig | WechatMpConfig | WechatPublicConfig | NativeConfig>;
|
||||
style: JsonFilter<Style>;
|
||||
dangerousVersions: JsonFilter<Versions>;
|
||||
warningVersions: JsonFilter<Versions>;
|
||||
soaVersion: Q_StringValue;
|
||||
domainId: Q_StringValue;
|
||||
} & ExprOp<OpAttr | string>;
|
||||
export type OpProjection = {
|
||||
|
|
@ -113,6 +120,9 @@ export type OpProjection = {
|
|||
systemId?: number;
|
||||
config?: number | JsonProjection<WebConfig | WechatMpConfig | WechatPublicConfig | NativeConfig>;
|
||||
style?: number | JsonProjection<Style>;
|
||||
dangerousVersions?: number | JsonProjection<Versions>;
|
||||
warningVersions?: number | JsonProjection<Versions>;
|
||||
soaVersion?: number;
|
||||
domainId?: number;
|
||||
} & Partial<ExprOp<OpAttr | string>>;
|
||||
export type OpSortAttr = Partial<{
|
||||
|
|
@ -124,7 +134,11 @@ export type OpSortAttr = Partial<{
|
|||
description: number;
|
||||
type: number;
|
||||
style: number;
|
||||
dangerousVersions: number;
|
||||
warningVersions: number;
|
||||
soaVersion: number;
|
||||
[k: string]: any;
|
||||
} | ExprOp<OpAttr | string>>;
|
||||
export type OpAction = OakMakeAction<GenericAction | string>;
|
||||
export type OpUpdateAction = "update" | string;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@
|
|||
"config": "设置",
|
||||
"style": "样式",
|
||||
"sessions": "会话",
|
||||
"domain": "域名"
|
||||
"domain": "域名",
|
||||
"dangerousVersions": "强制升级版本",
|
||||
"warningVersions": "建议升级版本",
|
||||
"soaVersion": "最新发布版本"
|
||||
},
|
||||
"v": {
|
||||
"type": {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,12 @@ export const desc = {
|
|||
notNull: true,
|
||||
type: "object"
|
||||
},
|
||||
oldestVersion: {
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 32
|
||||
}
|
||||
},
|
||||
style: {
|
||||
type: "object"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ export type OpSchema = EntityShape & {
|
|||
name: String<32>;
|
||||
description?: Text | null;
|
||||
config: Config;
|
||||
oldestVersion?: String<32> | null;
|
||||
style?: Style | null;
|
||||
entity?: String<32> | null;
|
||||
entityId?: String<64> | null;
|
||||
|
|
@ -24,6 +25,7 @@ export type OpFilter = {
|
|||
name: Q_StringValue;
|
||||
description: Q_StringValue;
|
||||
config: JsonFilter<Config>;
|
||||
oldestVersion: Q_StringValue;
|
||||
style: JsonFilter<Style>;
|
||||
entity: Q_StringValue;
|
||||
entityId: Q_StringValue;
|
||||
|
|
@ -38,6 +40,7 @@ export type OpProjection = {
|
|||
name?: number;
|
||||
description?: number;
|
||||
config?: number | JsonProjection<Config>;
|
||||
oldestVersion?: number;
|
||||
style?: number | JsonProjection<Style>;
|
||||
entity?: number;
|
||||
entityId?: number;
|
||||
|
|
@ -50,6 +53,7 @@ export type OpSortAttr = Partial<{
|
|||
name: number;
|
||||
description: number;
|
||||
config: number;
|
||||
oldestVersion: number;
|
||||
style: number;
|
||||
entity: number;
|
||||
entityId: number;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
"config": "设置",
|
||||
"style": "样式",
|
||||
"entity": "关联对象",
|
||||
"entityId": "关联对象id"
|
||||
"entityId": "关联对象id",
|
||||
"oldestVersion": "支持app最低版本"
|
||||
},
|
||||
"r": {
|
||||
"owner": "拥有者",
|
||||
|
|
|
|||
|
|
@ -25,6 +25,12 @@ export const desc = {
|
|||
length: 16
|
||||
}
|
||||
},
|
||||
oldestVersion: {
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 32
|
||||
}
|
||||
},
|
||||
super: {
|
||||
type: "boolean"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export type OpSchema = EntityShape & {
|
|||
config: Config;
|
||||
platformId?: ForeignKey<"platform"> | null;
|
||||
folder?: String<16> | null;
|
||||
oldestVersion?: String<32> | null;
|
||||
super?: Boolean | null;
|
||||
style?: Style | null;
|
||||
entity?: String<32> | null;
|
||||
|
|
@ -29,6 +30,7 @@ export type OpFilter = {
|
|||
config: JsonFilter<Config>;
|
||||
platformId: Q_StringValue;
|
||||
folder: Q_StringValue;
|
||||
oldestVersion: Q_StringValue;
|
||||
super: Q_BooleanValue;
|
||||
style: JsonFilter<Style>;
|
||||
entity: Q_StringValue;
|
||||
|
|
@ -46,6 +48,7 @@ export type OpProjection = {
|
|||
config?: number | JsonProjection<Config>;
|
||||
platformId?: number;
|
||||
folder?: number;
|
||||
oldestVersion?: number;
|
||||
super?: number;
|
||||
style?: number | JsonProjection<Style>;
|
||||
entity?: number;
|
||||
|
|
@ -60,6 +63,7 @@ export type OpSortAttr = Partial<{
|
|||
description: number;
|
||||
config: number;
|
||||
folder: number;
|
||||
oldestVersion: number;
|
||||
super: number;
|
||||
style: number;
|
||||
entity: number;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
"folder": "代码目录名",
|
||||
"style": "样式",
|
||||
"entity": "关联对象",
|
||||
"entityId": "关联对象id"
|
||||
"entityId": "关联对象id",
|
||||
"oldestVersion": "支持app最低版本"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "system", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "passport", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "system", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "passport", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export declare function createToDo<ED extends EntityDict & BaseEntityDict, T ext
|
|||
redirectTo: EntityDict['toDo']['OpSchema']['redirectTo'];
|
||||
entity: any;
|
||||
entityId: string;
|
||||
}, userIds?: string[]): Promise<0 | 1>;
|
||||
}, userIds?: string[]): Promise<1 | 0>;
|
||||
/**
|
||||
* 完成todo例程,当在entity对象上进行action操作时(操作条件是filter),将对应的todo完成
|
||||
* 必须在entity的action的后trigger中调用
|
||||
|
|
|
|||
|
|
@ -143,6 +143,9 @@ export const applicationProjection = {
|
|||
type: 1,
|
||||
systemId: 1,
|
||||
style: 1,
|
||||
dangerousVersions: 1,
|
||||
warningVersions: 1,
|
||||
soaVersion: 1,
|
||||
description: 1,
|
||||
system: {
|
||||
id: 1,
|
||||
|
|
@ -150,6 +153,7 @@ export const applicationProjection = {
|
|||
config: 1,
|
||||
platformId: 1,
|
||||
style: 1,
|
||||
oldestVersion: 1,
|
||||
super: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
|
|
@ -158,6 +162,7 @@ export const applicationProjection = {
|
|||
config: 1,
|
||||
style: 1,
|
||||
entity: 1,
|
||||
oldestVersion: 1,
|
||||
entityId: 1,
|
||||
},
|
||||
domain$system: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
export declare function oakGetPackageJsonVersion(): string;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// 命名为这个函数,将在编译时被注入项目根目录的package.json中的version
|
||||
export function oakGetPackageJsonVersion() {
|
||||
return '1.0.0';
|
||||
}
|
||||
|
|
@ -89,6 +89,7 @@ export type AspectDict<ED extends EntityDict> = {
|
|||
type: 'login' | 'changePassword' | 'confirm';
|
||||
}, context: BackendRuntimeContext<ED>) => Promise<string>;
|
||||
getApplication: (params: {
|
||||
version: string;
|
||||
type: AppType;
|
||||
domain: string;
|
||||
data: ED['application']['Projection'];
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import { WebEnv } from 'oak-domain/lib/types/Environment';
|
|||
import { File } from 'formidable';
|
||||
import { BRC } from '../types/RuntimeCxt';
|
||||
export declare function getApplication<ED extends EntityDict>(params: {
|
||||
version: string;
|
||||
type: AppType;
|
||||
domain: string;
|
||||
data: ED['application']['Projection'];
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ const WechatSDK_1 = tslib_1.__importDefault(require("oak-external-sdk/lib/Wechat
|
|||
const fs_1 = tslib_1.__importDefault(require("fs"));
|
||||
const lodash_1 = require("oak-domain/lib/utils/lodash");
|
||||
const uuid_1 = require("oak-domain/lib/utils/uuid");
|
||||
const version_1 = require("oak-domain/lib/utils/version");
|
||||
const Exception_1 = require("oak-domain/lib/types/Exception");
|
||||
async function getApplicationByDomain(context, options) {
|
||||
const { data, type, domain } = options;
|
||||
let applications = await context.select('application', {
|
||||
|
|
@ -43,8 +45,26 @@ async function getApplicationByDomain(context, options) {
|
|||
}
|
||||
return applications;
|
||||
}
|
||||
function checkAppVersionSafe(application, version) {
|
||||
const { dangerousVersions, warningVersions, system } = application;
|
||||
const { oldestVersion, platform } = system;
|
||||
const { oldestVersion: pfOldestVersion } = platform || {};
|
||||
const oldest = pfOldestVersion || oldestVersion;
|
||||
if (oldest) {
|
||||
if ((0, version_1.compareVersion)(version, oldest) < 0) {
|
||||
throw new Exception_1.OakApplicationHasToUpgrade();
|
||||
}
|
||||
}
|
||||
if (dangerousVersions && dangerousVersions.includes(version)) {
|
||||
throw new Exception_1.OakApplicationHasToUpgrade();
|
||||
}
|
||||
(0, lodash_1.unset)(application, 'dangerousVersions');
|
||||
if (warningVersions) {
|
||||
application.warningVersions = warningVersions.filter(ele => ele === version);
|
||||
}
|
||||
}
|
||||
async function getApplication(params, context) {
|
||||
const { type, domain, data, appId } = params;
|
||||
const { type, domain, data, appId, version } = params;
|
||||
// 先找指定domain的应用,如果不存在再找系统下面的domain, 但无论怎么样都必须一项
|
||||
const applications = await getApplicationByDomain(context, {
|
||||
type,
|
||||
|
|
@ -55,11 +75,13 @@ async function getApplication(params, context) {
|
|||
case 'wechatMp': {
|
||||
(0, assert_1.assert)(applications.length === 1, `微信小程序环境下,同一个系统必须存在唯一的【${type}】应用,域名「${domain}」`);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
case 'native': {
|
||||
(0, assert_1.assert)(applications.length === 1, `APP环境下,同一个系统必须存在唯一的【${type}】应用,域名「${domain}」`);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
case 'wechatPublic': {
|
||||
|
|
@ -72,15 +94,18 @@ async function getApplication(params, context) {
|
|||
});
|
||||
(0, assert_1.assert)(webApplications.length === 1, `微信公众号环境下, 可以未配置公众号,但必须存在web应用,域名「${domain}」`);
|
||||
const application = webApplications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
(0, assert_1.assert)(applications.length === 1, `微信公众号环境下,同一个系统必须存在唯一的【${type}】应用 或 多个${type}应用必须配置域名,域名「${domain}」`);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
case 'web': {
|
||||
(0, assert_1.assert)(applications.length === 1, `web环境下,同一个系统必须存在唯一的【${type}】应用 或 多个${type}应用必须配置域名,域名「${domain}」`);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id;
|
||||
}
|
||||
default: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,20 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const types_1 = require("oak-domain/lib/types");
|
||||
const validator_1 = require("oak-domain/lib/utils/validator");
|
||||
const version_1 = require("oak-domain/lib/utils/version");
|
||||
function checkVersion(data) {
|
||||
const { dangerousVersions, warningVersions, soaVersion } = data;
|
||||
if (dangerousVersions && dangerousVersions.find(ele => !(0, version_1.isVersion)(ele))) {
|
||||
throw new types_1.OakInputIllegalException('application', ['dangerousVersions'], 'error::illegalVersionData');
|
||||
}
|
||||
if (warningVersions && warningVersions.find(ele => !(0, version_1.isVersion)(ele))) {
|
||||
throw new types_1.OakInputIllegalException('application', ['warningVersions'], 'error::illegalVersionData');
|
||||
}
|
||||
if (soaVersion && !(0, version_1.isVersion)(soaVersion)) {
|
||||
throw new types_1.OakInputIllegalException('application', ['soaVersion'], 'error::illegalVersionData');
|
||||
}
|
||||
}
|
||||
const checkers = [
|
||||
{
|
||||
type: 'data',
|
||||
|
|
@ -16,6 +30,7 @@ const checkers = [
|
|||
};
|
||||
if (data instanceof Array) {
|
||||
data.forEach((ele) => {
|
||||
checkVersion(ele);
|
||||
(0, validator_1.checkAttributesNotNull)('application', ele, [
|
||||
'name',
|
||||
'type',
|
||||
|
|
@ -25,6 +40,7 @@ const checkers = [
|
|||
});
|
||||
}
|
||||
else {
|
||||
checkVersion(data);
|
||||
(0, validator_1.checkAttributesNotNull)('application', data, [
|
||||
'name',
|
||||
'type',
|
||||
|
|
@ -35,5 +51,13 @@ const checkers = [
|
|||
return;
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'data',
|
||||
action: 'update',
|
||||
entity: 'application',
|
||||
checker(data) {
|
||||
checkVersion(data);
|
||||
}
|
||||
}
|
||||
];
|
||||
exports.default = checkers;
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
declare const checkers: (import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "mobile", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "applicationPassport", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "token", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "message", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "parasite", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>>)[];
|
||||
declare const checkers: (import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "address", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "application", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "applicationPassport", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "token", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "user", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "mobile", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "message", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "parasite", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "system", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Checker<import("../oak-app-domain").EntityDict, "platform", import("..").RuntimeCxt<import("../oak-app-domain").EntityDict>>)[];
|
||||
export default checkers;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ const wechatPublicTag_1 = tslib_1.__importDefault(require("./wechatPublicTag"));
|
|||
const message_1 = tslib_1.__importDefault(require("./message"));
|
||||
const parasite_1 = tslib_1.__importDefault(require("./parasite"));
|
||||
const applicationPassport_1 = tslib_1.__importDefault(require("./applicationPassport"));
|
||||
const system_1 = tslib_1.__importDefault(require("./system"));
|
||||
const platform_1 = tslib_1.__importDefault(require("./platform"));
|
||||
const checkers = [
|
||||
...mobile_1.default,
|
||||
...address_1.default,
|
||||
|
|
@ -24,5 +26,7 @@ const checkers = [
|
|||
...message_1.default,
|
||||
...parasite_1.default,
|
||||
...applicationPassport_1.default,
|
||||
...system_1.default,
|
||||
...platform_1.default
|
||||
];
|
||||
exports.default = checkers;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const types_1 = require("oak-domain/lib/types");
|
||||
const validator_1 = require("oak-domain/lib/utils/validator");
|
||||
const version_1 = require("oak-domain/lib/utils/version");
|
||||
const checkers = [
|
||||
{
|
||||
type: 'data',
|
||||
|
|
@ -17,11 +19,17 @@ const checkers = [
|
|||
if (data instanceof Array) {
|
||||
data.forEach((ele) => {
|
||||
(0, validator_1.checkAttributesNotNull)('platform', ele, ['name']);
|
||||
if (ele.oldestVersion && !(0, version_1.isVersion)(ele.oldestVersion)) {
|
||||
throw new types_1.OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData', 'oak-general-business');
|
||||
}
|
||||
setData(ele);
|
||||
});
|
||||
}
|
||||
else {
|
||||
(0, validator_1.checkAttributesNotNull)('platform', data, ['name']);
|
||||
if (data.oldestVersion && !(0, version_1.isVersion)(data.oldestVersion)) {
|
||||
throw new types_1.OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData', 'oak-general-business');
|
||||
}
|
||||
setData(data);
|
||||
}
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const types_1 = require("oak-domain/lib/types");
|
||||
const validator_1 = require("oak-domain/lib/utils/validator");
|
||||
const version_1 = require("oak-domain/lib/utils/version");
|
||||
const checkers = [
|
||||
{
|
||||
type: 'data',
|
||||
|
|
@ -22,15 +24,32 @@ const checkers = [
|
|||
if (data instanceof Array) {
|
||||
data.forEach((ele) => {
|
||||
(0, validator_1.checkAttributesNotNull)('system', ele, ['name', 'platformId']);
|
||||
if (ele.oldestVersion && !(0, version_1.isVersion)(ele.oldestVersion)) {
|
||||
throw new types_1.OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData', 'oak-general-business');
|
||||
}
|
||||
setData(ele);
|
||||
});
|
||||
}
|
||||
else {
|
||||
(0, validator_1.checkAttributesNotNull)('system', data, ['name', 'platformId']);
|
||||
if (data.oldestVersion && !(0, version_1.isVersion)(data.oldestVersion)) {
|
||||
throw new types_1.OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData', 'oak-general-business');
|
||||
}
|
||||
setData(data);
|
||||
}
|
||||
return;
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'data',
|
||||
action: 'update',
|
||||
entity: 'system',
|
||||
checker(data) {
|
||||
const { oldestVersion } = data;
|
||||
if (oldestVersion && !(0, version_1.isVersion)(oldestVersion)) {
|
||||
throw new types_1.OakInputIllegalException('system', ['oldestVersion'], 'error::illegalVersionData');
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
exports.default = checkers;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { RuntimeContext } from './RuntimeContext';
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { SerializedData } from './FrontendRuntimeContext';
|
||||
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/types/Entity';
|
||||
import { OakException } from 'oak-domain/lib/types/Exception';
|
||||
import { BackendRuntimeContext as BRC } from 'oak-frontend-base/lib/context/BackendRuntimeContext';
|
||||
/**
|
||||
* general数据结构要求的后台上下文
|
||||
|
|
@ -14,15 +15,16 @@ export declare abstract class BackendRuntimeContext<ED extends EntityDict & Base
|
|||
protected rootMode?: boolean;
|
||||
private userId?;
|
||||
protected platformManager?: boolean;
|
||||
protected appVersion?: string;
|
||||
protected applicationProjection: EntityDict['user']['Projection'];
|
||||
refineOpRecords(): Promise<void>;
|
||||
setPlatformManager(tokenValue?: string, userId?: string): Promise<void>;
|
||||
setTokenValue(tokenValue?: string, userId?: string): Promise<void>;
|
||||
setApplication(appId: string): Promise<void>;
|
||||
initialize(data?: SerializedData, later?: boolean): Promise<void>;
|
||||
getApplicationId(): ED["application"]["Schema"]["id"] | undefined;
|
||||
getSystemId(): ED["application"]["Schema"]["systemId"] | undefined;
|
||||
getApplication(): Partial<ED["application"]["Schema"]> | undefined;
|
||||
getApplicationId<P extends true | undefined>(allowNull?: P): P extends undefined ? (string | undefined) : string;
|
||||
getSystemId<P extends true | undefined>(allowNull?: P): P extends undefined ? (string | undefined) : string;
|
||||
getApplication<P extends true | undefined>(allowNull?: P): P extends undefined ? (Partial<ED['application']['Schema']> | undefined) : Partial<ED['application']['Schema']>;
|
||||
openRootMode(): () => void;
|
||||
getTokenValue(allowUnloggedIn?: boolean): "oak-root-token" | ED["token"]["Schema"]["value"] | undefined;
|
||||
getToken(allowUnloggedIn?: boolean): Partial<ED["token"]["Schema"]> | undefined;
|
||||
|
|
@ -38,5 +40,6 @@ export declare abstract class BackendRuntimeContext<ED extends EntityDict & Base
|
|||
* http://www.xxx.com/oak-api
|
||||
*/
|
||||
composeAccessPath(): string;
|
||||
tryDeduceException(err: Error): Promise<OakException<any> | void>;
|
||||
}
|
||||
export default BackendRuntimeContext;
|
||||
|
|
|
|||
|
|
@ -6,12 +6,14 @@ const Exception_1 = require("../types/Exception");
|
|||
const Exception_2 = require("oak-domain/lib/types/Exception");
|
||||
const constants_1 = require("../constants");
|
||||
const uuid_1 = require("oak-domain/lib/utils/uuid");
|
||||
const types_1 = require("oak-domain/lib/types");
|
||||
const Projection_1 = require("../types/Projection");
|
||||
const wechatQrCode_1 = require("../aspects/wechatQrCode");
|
||||
const BackendRuntimeContext_1 = require("oak-frontend-base/lib/context/BackendRuntimeContext");
|
||||
const lodash_1 = require("oak-domain/lib/utils/lodash");
|
||||
const domain_1 = require("../utils/domain");
|
||||
const user_1 = require("../utils/user");
|
||||
const version_1 = require("oak-domain/lib/utils/version");
|
||||
/**
|
||||
* general数据结构要求的后台上下文
|
||||
*/
|
||||
|
|
@ -23,6 +25,7 @@ class BackendRuntimeContext extends BackendRuntimeContext_1.BackendRuntimeContex
|
|||
rootMode;
|
||||
userId;
|
||||
platformManager;
|
||||
appVersion;
|
||||
applicationProjection = (0, lodash_1.cloneDeep)(Projection_1.applicationProjection);
|
||||
async refineOpRecords() {
|
||||
const isRoot = this.isRoot();
|
||||
|
|
@ -262,7 +265,8 @@ class BackendRuntimeContext extends BackendRuntimeContext_1.BackendRuntimeContex
|
|||
if (data) {
|
||||
const closeRootMode = this.openRootMode();
|
||||
try {
|
||||
const { a: appId, t: tokenValue, rm, userId } = data;
|
||||
const { a: appId, t: tokenValue, rm, userId, v } = data;
|
||||
this.appVersion = v;
|
||||
const promises = [];
|
||||
if (appId) {
|
||||
promises.push(this.setApplication(appId));
|
||||
|
|
@ -288,13 +292,31 @@ class BackendRuntimeContext extends BackendRuntimeContext_1.BackendRuntimeContex
|
|||
this.rootMode = true;
|
||||
}
|
||||
}
|
||||
getApplicationId() {
|
||||
getApplicationId(allowNull) {
|
||||
if (!allowNull) {
|
||||
if (!this.application) {
|
||||
throw new Exception_1.OakApplicationLoadingException();
|
||||
}
|
||||
return this.application.id;
|
||||
}
|
||||
return this.application?.id;
|
||||
}
|
||||
getSystemId() {
|
||||
getSystemId(allowNull) {
|
||||
if (!allowNull) {
|
||||
if (!this.application) {
|
||||
throw new Exception_1.OakApplicationLoadingException();
|
||||
}
|
||||
return this.application.systemId;
|
||||
}
|
||||
return this.application?.systemId;
|
||||
}
|
||||
getApplication() {
|
||||
getApplication(allowNull) {
|
||||
if (!allowNull) {
|
||||
if (!this.application) {
|
||||
throw new Exception_1.OakApplicationLoadingException();
|
||||
}
|
||||
return this.application;
|
||||
}
|
||||
return this.application;
|
||||
}
|
||||
openRootMode() {
|
||||
|
|
@ -345,6 +367,7 @@ class BackendRuntimeContext extends BackendRuntimeContext_1.BackendRuntimeContex
|
|||
a: this.application?.id,
|
||||
rm: this.rootMode,
|
||||
userId: this.getCurrentUserId(true),
|
||||
v: this.appVersion,
|
||||
};
|
||||
}
|
||||
isRoot() {
|
||||
|
|
@ -397,6 +420,16 @@ class BackendRuntimeContext extends BackendRuntimeContext_1.BackendRuntimeContex
|
|||
const [domain] = domains;
|
||||
return (0, domain_1.composeServerUrl)(domain);
|
||||
}
|
||||
async tryDeduceException(err) {
|
||||
if (this.application && this.appVersion) {
|
||||
const { soaVersion } = this.application;
|
||||
if (soaVersion && (0, version_1.compareVersion)(this.appVersion, soaVersion) < 0) {
|
||||
// 说明客户端可以升级
|
||||
return new types_1.OakApplicationHasToUpgrade();
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
exports.BackendRuntimeContext = BackendRuntimeContext;
|
||||
;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export interface SerializedData extends Fsd {
|
|||
t?: string;
|
||||
userId?: string;
|
||||
rm?: boolean;
|
||||
v?: string;
|
||||
}
|
||||
export declare abstract class FrontendRuntimeContext<ED extends EntityDict & BaseEntityDict> extends Frc<ED> implements RuntimeContext {
|
||||
private application;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,11 @@ class FrontendRuntimeContext extends FrontendRuntimeContext_1.FrontendRuntimeCon
|
|||
// appId必须要取到,不能失败
|
||||
const setInner = (resolve, reject) => {
|
||||
try {
|
||||
if (!this.application) {
|
||||
// 有可能在系统初始化的时候调用,this.application还没建立
|
||||
resolve(undefined);
|
||||
return;
|
||||
}
|
||||
const appId = this.application.getApplicationId();
|
||||
(0, assert_1.assert)(appId);
|
||||
Object.assign(data, {
|
||||
|
|
@ -45,6 +50,11 @@ class FrontendRuntimeContext extends FrontendRuntimeContext_1.FrontendRuntimeCon
|
|||
const setTokenValue = async () => {
|
||||
const setInner = (resolve, reject) => {
|
||||
try {
|
||||
if (!this.token) {
|
||||
// 有可能在系统初始化的时候调用,this.token还没建立
|
||||
resolve(undefined);
|
||||
return;
|
||||
}
|
||||
const tokenValue = this.token.getTokenValue();
|
||||
if (tokenValue) {
|
||||
Object.assign(data, {
|
||||
|
|
@ -68,6 +78,9 @@ class FrontendRuntimeContext extends FrontendRuntimeContext_1.FrontendRuntimeCon
|
|||
return new Promise((resolve, reject) => setInner(resolve, reject));
|
||||
};
|
||||
await setTokenValue();
|
||||
Object.assign(data, {
|
||||
v: this.application.getVersion(),
|
||||
});
|
||||
return data;
|
||||
}
|
||||
getApplicationId() {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,16 @@
|
|||
// 本文件为自动编译产生,请勿直接修改
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const i18ns = [
|
||||
{
|
||||
id: "c0ce3f84c8cd6f70457b7e57a8ac8b8f",
|
||||
namespace: "oak-general-business-c-application-detail",
|
||||
language: "zh-CN",
|
||||
module: "oak-general-business",
|
||||
position: "src/components/application/detail",
|
||||
data: {
|
||||
"whole": "共%{count}项"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "2ebe552614a81e57fa1a1c21b5dc84f8",
|
||||
namespace: "oak-general-business-c-application-panel",
|
||||
|
|
@ -251,6 +261,19 @@ const i18ns = [
|
|||
"login": "登录管理"
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "819147f0564533e19aacf71c13d6f366",
|
||||
namespace: "oak-general-business-c-system-upsert",
|
||||
language: "zh-CN",
|
||||
module: "oak-general-business",
|
||||
position: "src/components/system/upsert",
|
||||
data: {
|
||||
"tips": {
|
||||
"isSuper": "超级系统属性可能影响程序的运行逻辑,请谨慎修改",
|
||||
"oldestVersion": "系统能兼容的最低应用版本号,格式为X.X.X"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: "7bcbb4dbb525e9a575095102f673f7ba",
|
||||
namespace: "oak-general-business-c-token-me",
|
||||
|
|
@ -647,7 +670,8 @@ const i18ns = [
|
|||
"mpHaveToSubscribe": "需要订阅小程序消息",
|
||||
"userInfoLoading": "正在加载用户信息",
|
||||
"applicationLoading": "应用正在初始化",
|
||||
"uploadFailed": "上传失败"
|
||||
"uploadFailed": "上传失败",
|
||||
"illegalVersionData": "版本号必须是x.x.x的形式"
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export type NativeConfig = {
|
|||
port: string;
|
||||
};
|
||||
};
|
||||
type Versions = string[];
|
||||
export interface Schema extends EntityShape {
|
||||
name: String<32>;
|
||||
description?: Text;
|
||||
|
|
@ -82,6 +83,10 @@ export interface Schema extends EntityShape {
|
|||
system: System;
|
||||
config: WebConfig | WechatMpConfig | WechatPublicConfig | NativeConfig;
|
||||
style?: Style;
|
||||
dangerousVersions: Versions;
|
||||
warningVersions: Versions;
|
||||
soaVersion: String<12>;
|
||||
sessions?: Session[];
|
||||
domain?: Domain;
|
||||
}
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ const entityDesc = {
|
|||
style: '样式',
|
||||
sessions: '会话',
|
||||
domain: '域名',
|
||||
dangerousVersions: '强制升级版本',
|
||||
warningVersions: '建议升级版本',
|
||||
soaVersion: '最新发布版本'
|
||||
},
|
||||
v: {
|
||||
type: {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export interface Schema extends EntityShape {
|
|||
name: String<32>;
|
||||
description?: Text;
|
||||
config: Config;
|
||||
oldestVersion?: String<32>;
|
||||
style?: Style;
|
||||
entity?: String<32>;
|
||||
entityId?: String<64>;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ exports.entityDesc = {
|
|||
style: '样式',
|
||||
entity: '关联对象',
|
||||
entityId: '关联对象id',
|
||||
oldestVersion: '支持app最低版本'
|
||||
},
|
||||
r: {
|
||||
owner: '拥有者',
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ export interface Schema extends EntityShape {
|
|||
config: Config;
|
||||
platform?: Platform;
|
||||
folder?: String<16>;
|
||||
oldestVersion?: String<32>;
|
||||
super?: Boolean;
|
||||
style?: Style;
|
||||
entity?: String<32>;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ exports.entityDesc = {
|
|||
style: '样式',
|
||||
entity: '关联对象',
|
||||
entityId: '关联对象id',
|
||||
oldestVersion: '支持app最低版本'
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,16 +4,17 @@ import { Feature } from 'oak-frontend-base/es/types/Feature';
|
|||
import { EntityDict } from '../oak-app-domain';
|
||||
import { MediaType, MediaVideoDescription } from '../types/WeChat';
|
||||
export declare class Application<ED extends EntityDict> extends Feature {
|
||||
private version;
|
||||
private applicationId?;
|
||||
private application?;
|
||||
private cache;
|
||||
private storage;
|
||||
private projection;
|
||||
private sensitiveEntities;
|
||||
constructor(cache: Cache<ED>, storage: LocalStorage);
|
||||
constructor(cache: Cache<ED>, storage: LocalStorage, version: string);
|
||||
private getApplicationFromCache;
|
||||
private loadApplicationInfo;
|
||||
initialize(domain: string, appId?: string | null, projection?: EntityDict['application']['Projection']): Promise<void>;
|
||||
initialize(version: string, domain: string, appId?: string | null, projection?: EntityDict['application']['Projection']): Promise<void>;
|
||||
getApplication(): Partial<ED["application"]["Schema"]>;
|
||||
getApplicationId(allowUnInitialized?: boolean): string | undefined;
|
||||
uploadWechatMedia(params: {
|
||||
|
|
@ -23,4 +24,5 @@ export declare class Application<ED extends EntityDict> extends Feature {
|
|||
isPermanent?: boolean;
|
||||
description?: MediaVideoDescription;
|
||||
}): Promise<any>;
|
||||
getVersion(): string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,15 +8,17 @@ const projection_1 = require("oak-domain/lib/utils/projection");
|
|||
const Projection_1 = require("../types/Projection");
|
||||
const Exception_1 = require("../types/Exception");
|
||||
class Application extends Feature_1.Feature {
|
||||
version;
|
||||
applicationId;
|
||||
application;
|
||||
cache;
|
||||
storage;
|
||||
projection;
|
||||
sensitiveEntities = [];
|
||||
constructor(cache, storage) {
|
||||
constructor(cache, storage, version) {
|
||||
super();
|
||||
this.cache = cache;
|
||||
this.version = version;
|
||||
this.storage = storage;
|
||||
this.projection = (0, lodash_1.cloneDeep)(Projection_1.applicationProjection);
|
||||
// this.application做一层缓存,有时候更新了一些相关的属性还是要更新的
|
||||
|
|
@ -53,7 +55,7 @@ class Application extends Feature_1.Feature {
|
|||
this.application = data[0];
|
||||
return this.application;
|
||||
}
|
||||
async loadApplicationInfo(domain) {
|
||||
async loadApplicationInfo(version, domain) {
|
||||
let applicationId;
|
||||
let appType = 'web';
|
||||
if (process.env.OAK_PLATFORM === 'wechatMp') {
|
||||
|
|
@ -68,6 +70,7 @@ class Application extends Feature_1.Feature {
|
|||
}
|
||||
}
|
||||
const { result } = await this.cache.exec('getApplication', {
|
||||
version,
|
||||
type: appType,
|
||||
domain,
|
||||
data: this.projection,
|
||||
|
|
@ -82,16 +85,17 @@ class Application extends Feature_1.Feature {
|
|||
// }
|
||||
this.publish();
|
||||
}
|
||||
async initialize(domain, appId, projection) {
|
||||
async initialize(version, domain, appId, projection) {
|
||||
// const applicationId = await this.storage.load(LOCAL_STORAGE_KEYS.appId);
|
||||
// this.applicationId = applicationId;
|
||||
//接收外层注入的projection
|
||||
this.version = version;
|
||||
this.projection = (0, lodash_1.merge)(this.projection, projection);
|
||||
if (process.env.NODE_ENV === 'development' && appId) {
|
||||
// development环境下允许注入一个线上的appId
|
||||
this.applicationId = appId;
|
||||
}
|
||||
return await this.loadApplicationInfo(domain);
|
||||
return await this.loadApplicationInfo(version, domain);
|
||||
}
|
||||
getApplication() {
|
||||
if (this.applicationId === undefined) {
|
||||
|
|
@ -122,5 +126,8 @@ class Application extends Feature_1.Feature {
|
|||
const callBack = await this.cache.exec('uploadWechatMedia', formData);
|
||||
return callBack.result;
|
||||
}
|
||||
getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
}
|
||||
exports.Application = Application;
|
||||
|
|
|
|||
|
|
@ -12,8 +12,9 @@ const wechatMenu_1 = require("./wechatMenu");
|
|||
const wechatPublicTag_1 = require("./wechatPublicTag");
|
||||
const userWechatPublicTag_1 = require("./userWechatPublicTag");
|
||||
const theme_1 = tslib_1.__importDefault(require("./theme"));
|
||||
const appVersion_1 = require("../utils/appVersion");
|
||||
function create(basicFeatures) {
|
||||
const application = new application_1.Application(basicFeatures.cache, basicFeatures.localStorage);
|
||||
const application = new application_1.Application(basicFeatures.cache, basicFeatures.localStorage, (0, appVersion_1.oakGetPackageJsonVersion)());
|
||||
const token = new token_1.Token(basicFeatures.cache, basicFeatures.localStorage, basicFeatures.environment, application);
|
||||
const wechatMenu = new wechatMenu_1.WechatMenu(basicFeatures.cache, basicFeatures.localStorage);
|
||||
const wechatPublicTag = new wechatPublicTag_1.WechatPublicTag(basicFeatures.cache, basicFeatures.localStorage);
|
||||
|
|
@ -38,7 +39,7 @@ function create(basicFeatures) {
|
|||
}
|
||||
exports.create = create;
|
||||
async function initialize(features, access, config, clazzes) {
|
||||
await features.application.initialize(access.http.hostname, undefined, config?.applicationExtraProjection);
|
||||
await features.application.initialize((0, appVersion_1.oakGetPackageJsonVersion)(), access.http.hostname, undefined, config?.applicationExtraProjection);
|
||||
if (process.env.OAK_PLATFORM === 'web') {
|
||||
features.wechatSdk.setLandingUrl(window.location.href);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,5 +22,6 @@
|
|||
"mpHaveToSubscribe": "需要订阅小程序消息",
|
||||
"userInfoLoading": "正在加载用户信息",
|
||||
"applicationLoading": "应用正在初始化",
|
||||
"uploadFailed": "上传失败"
|
||||
"uploadFailed": "上传失败",
|
||||
"illegalVersionData": "版本号必须是x.x.x的形式"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,21 @@ exports.desc = {
|
|||
style: {
|
||||
type: "object"
|
||||
},
|
||||
dangerousVersions: {
|
||||
notNull: true,
|
||||
type: "object"
|
||||
},
|
||||
warningVersions: {
|
||||
notNull: true,
|
||||
type: "object"
|
||||
},
|
||||
soaVersion: {
|
||||
notNull: true,
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 12
|
||||
}
|
||||
},
|
||||
domainId: {
|
||||
type: "ref",
|
||||
ref: "domain"
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export type NativeConfig = {
|
|||
port: string;
|
||||
};
|
||||
};
|
||||
type Versions = string[];
|
||||
export type OpSchema = EntityShape & {
|
||||
name: String<32>;
|
||||
description?: Text | null;
|
||||
|
|
@ -82,6 +83,9 @@ export type OpSchema = EntityShape & {
|
|||
systemId: ForeignKey<"system">;
|
||||
config: WebConfig | WechatMpConfig | WechatPublicConfig | NativeConfig;
|
||||
style?: Style | null;
|
||||
dangerousVersions: Versions;
|
||||
warningVersions: Versions;
|
||||
soaVersion: String<12>;
|
||||
domainId?: ForeignKey<"domain"> | null;
|
||||
} & {
|
||||
[A in ExpressionKey]?: any;
|
||||
|
|
@ -98,6 +102,9 @@ export type OpFilter = {
|
|||
systemId: Q_StringValue;
|
||||
config: JsonFilter<WebConfig | WechatMpConfig | WechatPublicConfig | NativeConfig>;
|
||||
style: JsonFilter<Style>;
|
||||
dangerousVersions: JsonFilter<Versions>;
|
||||
warningVersions: JsonFilter<Versions>;
|
||||
soaVersion: Q_StringValue;
|
||||
domainId: Q_StringValue;
|
||||
} & ExprOp<OpAttr | string>;
|
||||
export type OpProjection = {
|
||||
|
|
@ -113,6 +120,9 @@ export type OpProjection = {
|
|||
systemId?: number;
|
||||
config?: number | JsonProjection<WebConfig | WechatMpConfig | WechatPublicConfig | NativeConfig>;
|
||||
style?: number | JsonProjection<Style>;
|
||||
dangerousVersions?: number | JsonProjection<Versions>;
|
||||
warningVersions?: number | JsonProjection<Versions>;
|
||||
soaVersion?: number;
|
||||
domainId?: number;
|
||||
} & Partial<ExprOp<OpAttr | string>>;
|
||||
export type OpSortAttr = Partial<{
|
||||
|
|
@ -124,7 +134,11 @@ export type OpSortAttr = Partial<{
|
|||
description: number;
|
||||
type: number;
|
||||
style: number;
|
||||
dangerousVersions: number;
|
||||
warningVersions: number;
|
||||
soaVersion: number;
|
||||
[k: string]: any;
|
||||
} | ExprOp<OpAttr | string>>;
|
||||
export type OpAction = OakMakeAction<GenericAction | string>;
|
||||
export type OpUpdateAction = "update" | string;
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@
|
|||
"config": "设置",
|
||||
"style": "样式",
|
||||
"sessions": "会话",
|
||||
"domain": "域名"
|
||||
"domain": "域名",
|
||||
"dangerousVersions": "强制升级版本",
|
||||
"warningVersions": "建议升级版本",
|
||||
"soaVersion": "最新发布版本"
|
||||
},
|
||||
"v": {
|
||||
"type": {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,12 @@ exports.desc = {
|
|||
notNull: true,
|
||||
type: "object"
|
||||
},
|
||||
oldestVersion: {
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 32
|
||||
}
|
||||
},
|
||||
style: {
|
||||
type: "object"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ export type OpSchema = EntityShape & {
|
|||
name: String<32>;
|
||||
description?: Text | null;
|
||||
config: Config;
|
||||
oldestVersion?: String<32> | null;
|
||||
style?: Style | null;
|
||||
entity?: String<32> | null;
|
||||
entityId?: String<64> | null;
|
||||
|
|
@ -24,6 +25,7 @@ export type OpFilter = {
|
|||
name: Q_StringValue;
|
||||
description: Q_StringValue;
|
||||
config: JsonFilter<Config>;
|
||||
oldestVersion: Q_StringValue;
|
||||
style: JsonFilter<Style>;
|
||||
entity: Q_StringValue;
|
||||
entityId: Q_StringValue;
|
||||
|
|
@ -38,6 +40,7 @@ export type OpProjection = {
|
|||
name?: number;
|
||||
description?: number;
|
||||
config?: number | JsonProjection<Config>;
|
||||
oldestVersion?: number;
|
||||
style?: number | JsonProjection<Style>;
|
||||
entity?: number;
|
||||
entityId?: number;
|
||||
|
|
@ -50,6 +53,7 @@ export type OpSortAttr = Partial<{
|
|||
name: number;
|
||||
description: number;
|
||||
config: number;
|
||||
oldestVersion: number;
|
||||
style: number;
|
||||
entity: number;
|
||||
entityId: number;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
"config": "设置",
|
||||
"style": "样式",
|
||||
"entity": "关联对象",
|
||||
"entityId": "关联对象id"
|
||||
"entityId": "关联对象id",
|
||||
"oldestVersion": "支持app最低版本"
|
||||
},
|
||||
"r": {
|
||||
"owner": "拥有者",
|
||||
|
|
|
|||
|
|
@ -28,6 +28,12 @@ exports.desc = {
|
|||
length: 16
|
||||
}
|
||||
},
|
||||
oldestVersion: {
|
||||
type: "varchar",
|
||||
params: {
|
||||
length: 32
|
||||
}
|
||||
},
|
||||
super: {
|
||||
type: "boolean"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export type OpSchema = EntityShape & {
|
|||
config: Config;
|
||||
platformId?: ForeignKey<"platform"> | null;
|
||||
folder?: String<16> | null;
|
||||
oldestVersion?: String<32> | null;
|
||||
super?: Boolean | null;
|
||||
style?: Style | null;
|
||||
entity?: String<32> | null;
|
||||
|
|
@ -29,6 +30,7 @@ export type OpFilter = {
|
|||
config: JsonFilter<Config>;
|
||||
platformId: Q_StringValue;
|
||||
folder: Q_StringValue;
|
||||
oldestVersion: Q_StringValue;
|
||||
super: Q_BooleanValue;
|
||||
style: JsonFilter<Style>;
|
||||
entity: Q_StringValue;
|
||||
|
|
@ -46,6 +48,7 @@ export type OpProjection = {
|
|||
config?: number | JsonProjection<Config>;
|
||||
platformId?: number;
|
||||
folder?: number;
|
||||
oldestVersion?: number;
|
||||
super?: number;
|
||||
style?: number | JsonProjection<Style>;
|
||||
entity?: number;
|
||||
|
|
@ -60,6 +63,7 @@ export type OpSortAttr = Partial<{
|
|||
description: number;
|
||||
config: number;
|
||||
folder: number;
|
||||
oldestVersion: number;
|
||||
super: number;
|
||||
style: number;
|
||||
entity: number;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
"folder": "代码目录名",
|
||||
"style": "样式",
|
||||
"entity": "关联对象",
|
||||
"entityId": "关联对象id"
|
||||
"entityId": "关联对象id",
|
||||
"oldestVersion": "支持app最低版本"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "system", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "passport", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
declare const _default: (import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "message", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "address", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "application", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "article", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "articleMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "extraFile", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "user", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "userEntityGrant", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatQrCode", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "notification", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatLogin", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "parasite", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "sessionMessage", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMenu", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatPublicTag", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "wechatMpJump", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "system", import("..").BRC<import("../oak-app-domain").EntityDict>> | import("oak-domain/lib/types").Trigger<import("../oak-app-domain").EntityDict, "passport", import("..").BRC<import("../oak-app-domain").EntityDict>>)[];
|
||||
export default _default;
|
||||
|
|
|
|||
|
|
@ -146,6 +146,9 @@ exports.applicationProjection = {
|
|||
type: 1,
|
||||
systemId: 1,
|
||||
style: 1,
|
||||
dangerousVersions: 1,
|
||||
warningVersions: 1,
|
||||
soaVersion: 1,
|
||||
description: 1,
|
||||
system: {
|
||||
id: 1,
|
||||
|
|
@ -153,6 +156,7 @@ exports.applicationProjection = {
|
|||
config: 1,
|
||||
platformId: 1,
|
||||
style: 1,
|
||||
oldestVersion: 1,
|
||||
super: 1,
|
||||
entity: 1,
|
||||
entityId: 1,
|
||||
|
|
@ -161,6 +165,7 @@ exports.applicationProjection = {
|
|||
config: 1,
|
||||
style: 1,
|
||||
entity: 1,
|
||||
oldestVersion: 1,
|
||||
entityId: 1,
|
||||
},
|
||||
domain$system: {
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
export declare function oakGetPackageJsonVersion(): string;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.oakGetPackageJsonVersion = void 0;
|
||||
// 命名为这个函数,将在编译时被注入项目根目录的package.json中的version
|
||||
function oakGetPackageJsonVersion() {
|
||||
return '1.0.0';
|
||||
}
|
||||
exports.oakGetPackageJsonVersion = oakGetPackageJsonVersion;
|
||||
|
|
@ -153,6 +153,7 @@ export type AspectDict<ED extends EntityDict> = {
|
|||
) => Promise<string>;
|
||||
getApplication: (
|
||||
params: {
|
||||
version: string;
|
||||
type: AppType;
|
||||
domain: string;
|
||||
data: ED['application']['Projection'];
|
||||
|
|
|
|||
|
|
@ -14,9 +14,11 @@ import WechatSDK, {
|
|||
} from 'oak-external-sdk/lib/WechatSDK';
|
||||
import fs from 'fs';
|
||||
import { File } from 'formidable';
|
||||
import { cloneDeep } from 'oak-domain/lib/utils/lodash';
|
||||
import { cloneDeep, unset } from 'oak-domain/lib/utils/lodash';
|
||||
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
|
||||
import { compareVersion } from 'oak-domain/lib/utils/version';
|
||||
import { BRC } from '../types/RuntimeCxt';
|
||||
import { OakApplicationHasToUpgrade } from 'oak-domain/lib/types/Exception';
|
||||
|
||||
async function getApplicationByDomain<ED extends EntityDict>(
|
||||
context: BRC<ED>,
|
||||
|
|
@ -70,8 +72,29 @@ async function getApplicationByDomain<ED extends EntityDict>(
|
|||
return applications;
|
||||
}
|
||||
|
||||
function checkAppVersionSafe<ED extends EntityDict>(application: Partial<ED['application']['Schema']>, version: string) {
|
||||
const { dangerousVersions, warningVersions, system } = application;
|
||||
const { oldestVersion, platform } = system!;
|
||||
const { oldestVersion: pfOldestVersion } = platform || {};
|
||||
|
||||
const oldest = pfOldestVersion || oldestVersion;
|
||||
if (oldest) {
|
||||
if (compareVersion(version, oldest) < 0) {
|
||||
throw new OakApplicationHasToUpgrade<ED>();
|
||||
}
|
||||
}
|
||||
if (dangerousVersions && dangerousVersions.includes(version)) {
|
||||
throw new OakApplicationHasToUpgrade<ED>();
|
||||
}
|
||||
unset(application, 'dangerousVersions');
|
||||
if (warningVersions) {
|
||||
application.warningVersions = warningVersions.filter(ele => ele === version);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getApplication<ED extends EntityDict>(
|
||||
params: {
|
||||
version: string;
|
||||
type: AppType;
|
||||
domain: string;
|
||||
data: ED['application']['Projection'];
|
||||
|
|
@ -79,7 +102,7 @@ export async function getApplication<ED extends EntityDict>(
|
|||
},
|
||||
context: BRC<ED>
|
||||
) {
|
||||
const { type, domain, data, appId } = params;
|
||||
const { type, domain, data, appId, version } = params;
|
||||
|
||||
// 先找指定domain的应用,如果不存在再找系统下面的domain, 但无论怎么样都必须一项
|
||||
const applications = await getApplicationByDomain(context, {
|
||||
|
|
@ -95,6 +118,7 @@ export async function getApplication<ED extends EntityDict>(
|
|||
`微信小程序环境下,同一个系统必须存在唯一的【${type}】应用,域名「${domain}」`
|
||||
);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id as string;
|
||||
}
|
||||
case 'native': {
|
||||
|
|
@ -103,6 +127,7 @@ export async function getApplication<ED extends EntityDict>(
|
|||
`APP环境下,同一个系统必须存在唯一的【${type}】应用,域名「${domain}」`
|
||||
);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id as string;
|
||||
}
|
||||
case 'wechatPublic': {
|
||||
|
|
@ -119,6 +144,7 @@ export async function getApplication<ED extends EntityDict>(
|
|||
`微信公众号环境下, 可以未配置公众号,但必须存在web应用,域名「${domain}」`
|
||||
);
|
||||
const application = webApplications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id as string;
|
||||
}
|
||||
assert(
|
||||
|
|
@ -126,6 +152,7 @@ export async function getApplication<ED extends EntityDict>(
|
|||
`微信公众号环境下,同一个系统必须存在唯一的【${type}】应用 或 多个${type}应用必须配置域名,域名「${domain}」`
|
||||
);
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id as string;
|
||||
}
|
||||
case 'web': {
|
||||
|
|
@ -135,6 +162,7 @@ export async function getApplication<ED extends EntityDict>(
|
|||
);
|
||||
|
||||
const application = applications[0];
|
||||
checkAppVersionSafe(application, version);
|
||||
return application.id as string;
|
||||
}
|
||||
default: {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue