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