cli 模版文件调整
This commit is contained in:
parent
5defc25061
commit
7bee9b5f45
|
|
@ -61,6 +61,7 @@ out
|
|||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
build
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
|
@ -86,5 +87,5 @@ dist
|
|||
.pnp.*
|
||||
|
||||
package-lock.json
|
||||
src/wechatMp/dist
|
||||
oak-app-domain
|
||||
oak-app-domain
|
||||
*/public/locales
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
module.exports = {
|
||||
customSyntax: 'postcss-less',
|
||||
extends: 'stylelint-config-standard',
|
||||
|
|
@ -16,9 +15,14 @@ module.exports = {
|
|||
'no-duplicate-selectors': null,
|
||||
'selector-class-pattern': null,
|
||||
'font-family-no-missing-generic-family-keyword': null,
|
||||
'function-no-unknown': [true, { ignoreFunctions: ['alpha', 'constant', 'fadeout'] }],
|
||||
'function-no-unknown': [
|
||||
true,
|
||||
{ ignoreFunctions: ['alpha', 'constant', 'fadeout'] },
|
||||
],
|
||||
'declaration-block-no-shorthand-property-overrides': null,
|
||||
'no-empty-source': null,
|
||||
'selector-type-no-unknown': null
|
||||
'selector-type-no-unknown': null,
|
||||
'function-url-quotes': null,
|
||||
'max-line-length': null,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,21 @@
|
|||
import { GeneralRuntimeContext } from 'oak-general-business';
|
||||
import { EntityDict } from 'oak-app-domain';
|
||||
import { RowStore } from 'oak-domain/lib/types';
|
||||
|
||||
export class RuntimeContext extends GeneralRuntimeContext<EntityDict> {
|
||||
|
||||
}
|
||||
static FromCxtStr(cxtStr?: string) {
|
||||
const { token, applicationId, scene } = cxtStr
|
||||
? GeneralRuntimeContext.fromString(cxtStr)
|
||||
: {
|
||||
token: undefined,
|
||||
applicationId: undefined,
|
||||
scene: undefined,
|
||||
};
|
||||
return (store: RowStore<EntityDict, RuntimeContext>) => {
|
||||
const context = new RuntimeContext(store, applicationId);
|
||||
context.setScene(scene);
|
||||
context.setToken(token);
|
||||
return context;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
import { RuntimeContext } from "../RuntimeContext";
|
||||
import { AspectDict as GeneralAspectDict } from 'oak-general-business/src/aspects/AspectDict';
|
||||
import { EntityDict } from "oak-app-domain";
|
||||
|
||||
export type AspectDict = {
|
||||
test: (params: string, context: RuntimeContext) => Promise<any>;
|
||||
} & GeneralAspectDict<EntityDict, RuntimeContext>;
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
import { Aspect } from 'oak-domain/lib/types';
|
||||
import { aspectDict as GeneralAspectDict } from 'oak-general-business';
|
||||
import { test } from './sample';
|
||||
import { aspectDict as generalAspectDict } from 'oak-general-business';
|
||||
import { AspectDict as GeneralAspectDict } from 'oak-general-business/src/aspects/AspectDict';
|
||||
import { AspectDict } from './AspectDict';
|
||||
import { EntityDict } from 'oak-app-domain';
|
||||
import { RuntimeContext } from '../RuntimeContext';
|
||||
|
||||
import { test } from './sample';
|
||||
|
||||
const aspectDict = Object.assign({
|
||||
const aspectDict = {
|
||||
test,
|
||||
}, GeneralAspectDict as Record<keyof typeof GeneralAspectDict, Aspect<EntityDict, RuntimeContext>>);
|
||||
...generalAspectDict,
|
||||
} as AspectDict & GeneralAspectDict<EntityDict, RuntimeContext>;
|
||||
|
||||
export {
|
||||
aspectDict,
|
||||
}
|
||||
export { aspectDict };
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
import { EntityDict } from 'oak-app-domain';
|
||||
import { Checker } from 'oak-domain/lib/types';
|
||||
import { checkers as GeneralCheckers } from 'oak-general-business';
|
||||
import { processCheckers } from 'oak-general-business/src/utils/check';
|
||||
import { checkers as generalCheckers } from 'oak-general-business';
|
||||
import { RuntimeContext } from '../RuntimeContext';
|
||||
import { checkers as houseCheckers } from './house';
|
||||
|
||||
export const checkers = [...houseCheckers, ...GeneralCheckers] as Checker<EntityDict, keyof EntityDict, RuntimeContext>[];
|
||||
const checkers = [...houseCheckers, ...generalCheckers] as Checker<
|
||||
EntityDict,
|
||||
keyof EntityDict,
|
||||
RuntimeContext
|
||||
>[];
|
||||
processCheckers(checkers);
|
||||
export { checkers };
|
||||
|
|
|
|||
|
|
@ -1,9 +1,33 @@
|
|||
import { appid, projectname } from '../../wechatMp/src/project.config.json';
|
||||
import WechatMpConfig from '../../wechatMp/src/project.config.json';
|
||||
|
||||
export default {
|
||||
weChatMp: { // 第一个小程序的配置
|
||||
appId: appid, // 请到progjection.config.json中修改
|
||||
appSecret: 'b40433d3b20e1eea5544fcf6f4bbe291', // appSecret
|
||||
appName: projectname, // 请到progjection.config.json中修改
|
||||
weChatMp: {
|
||||
// 第一个小程序的配置
|
||||
appId: WechatMpConfig.appid, // 请到progjection.config.json中修改
|
||||
appSecret: 'b40433d3b20e1eea5544fcf6f4bbe291', // appSecret
|
||||
appName: WechatMpConfig.projectname, // 请到progjection.config.json中修改
|
||||
},
|
||||
System: {
|
||||
develop: {
|
||||
name: 'develop',
|
||||
description: '开发用的system',
|
||||
config: {
|
||||
Map: {
|
||||
amap: {
|
||||
webApiKey: '',
|
||||
},
|
||||
},
|
||||
Cos: {
|
||||
qiniu: {
|
||||
accessKey: '',
|
||||
secretKey: '',
|
||||
uploadHost: 'https://up.qiniup.com', //七牛上传域名
|
||||
bucket: 'test',
|
||||
domain: '',
|
||||
protocol: 'http',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import { CreateOperationData as Application } from 'oak-app-domain/Application/Schema';
|
||||
import { DEV_SYSTEM_ID } from './system';
|
||||
const DEV_WECHATMP_APPLICATION_ID = 'MY_DEV_WECHATMP_APPLICATION_ID';
|
||||
import {
|
||||
DEV_SYSTEM_ID,
|
||||
DEV_WECHATMP_APPLICATION_ID,
|
||||
DEV_WEB_APPLICATION_ID,
|
||||
} from 'oak-general-business';
|
||||
import Config from '../config';
|
||||
|
||||
export const applications: Application[] = [
|
||||
|
|
@ -15,5 +18,15 @@ export const applications: Application[] = [
|
|||
appSecret: Config.weChatMp.appSecret,
|
||||
},
|
||||
description: '小程序应用,指向dev_system',
|
||||
}
|
||||
];
|
||||
},
|
||||
{
|
||||
id: DEV_WEB_APPLICATION_ID,
|
||||
name: 'devWeb',
|
||||
type: 'web',
|
||||
systemId: DEV_SYSTEM_ID,
|
||||
config: {
|
||||
type: 'web',
|
||||
},
|
||||
description: 'web应用,指向dev_system',
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import { CreateOperationData as Domain } from 'oak-app-domain/Domain/Schema';
|
||||
import { DEV_SYSTEM_ID, DEV_DOMAIN_ID } from 'oak-general-business';
|
||||
|
||||
export const domains: Domain[] = [
|
||||
{
|
||||
id: DEV_DOMAIN_ID,
|
||||
protocol: 'http',
|
||||
url: 'localhost',
|
||||
port: 3001,
|
||||
apiPath: '/rest/aspect',
|
||||
systemId: DEV_SYSTEM_ID,
|
||||
},
|
||||
];
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
import { applications } from './application';
|
||||
import { systems } from './system';
|
||||
import { data as GeneralData } from 'oak-general-business';
|
||||
import { domains } from './domain';
|
||||
import { data as generalData } from 'oak-general-business';
|
||||
|
||||
export const data = Object.assign({
|
||||
export const data = {
|
||||
application: applications,
|
||||
system: systems,
|
||||
}, GeneralData);
|
||||
...generalData,
|
||||
domain: domains,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import { CreateOperationData as System } from 'oak-app-domain/System/Schema';
|
||||
export const DEV_SYSTEM_ID = 'MY_DEV_SYSTEM_ID';
|
||||
import { DEV_SYSTEM_ID } from 'oak-general-business';
|
||||
|
||||
import Config from '../config';
|
||||
|
||||
export const systems: System[] = [
|
||||
{
|
||||
id: DEV_SYSTEM_ID,
|
||||
name: 'develop',
|
||||
description: '开发用的system',
|
||||
config: {},
|
||||
}
|
||||
];
|
||||
name: Config.System.develop.name,
|
||||
description: Config.System.develop.description,
|
||||
config: Config.System.develop.config,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
import { ExceptionRouters } from 'oak-frontend-base';
|
||||
import { exceptionRouters as GenenralExceptionRouters } from 'oak-general-business';
|
||||
import { ExampleException } from './types/Exception';
|
||||
import { exceptionRouters as generalExceptionRouter } from 'oak-general-business';
|
||||
|
||||
export const routers = ([
|
||||
[ExampleException, {
|
||||
router: '/url/url',
|
||||
}]
|
||||
] as ExceptionRouters).concat(GenenralExceptionRouters);
|
||||
export const routers = [
|
||||
[
|
||||
ExampleException,
|
||||
{
|
||||
router: '/url/url',
|
||||
},
|
||||
],
|
||||
...generalExceptionRouter,
|
||||
] as ExceptionRouters;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,26 @@
|
|||
import { EntityDict } from 'oak-app-domain';
|
||||
import { BasicFeatures } from 'oak-frontend-base';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import * as Sample from './Sample';
|
||||
import { aspectDict } from '../aspects';
|
||||
import { AspectDict } from '../aspects/AspectDict';
|
||||
import { RuntimeContext } from '../RuntimeContext';
|
||||
import { GeneralRuntimeContext } from 'oak-general-business';
|
||||
import { AspectWrapper } from 'oak-domain/lib/types';
|
||||
|
||||
export function initialize(basicFeatures: BasicFeatures<EntityDict, RuntimeContext, typeof aspectDict>) {
|
||||
export function initialize(
|
||||
aspectWrapper: AspectWrapper<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
|
||||
>,
|
||||
basicFeatures: BasicFeatures<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
|
||||
>
|
||||
) {
|
||||
const { cache } = basicFeatures;
|
||||
|
||||
const sample = new Sample.Sample(cache);
|
||||
const sample = new Sample.Sample(aspectWrapper, cache);
|
||||
|
||||
return {
|
||||
sample,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
import './utils/polyfill';
|
||||
import { initialize as init } from 'oak-frontend-base/src/initialize.dev';
|
||||
|
||||
import { EntityDict, storageSchema, ActionDefDict } from 'oak-app-domain';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { RuntimeContext } from './RuntimeContext';
|
||||
|
||||
import { initialize as initializeGeneralFeatures } from 'oak-general-business/src/features';
|
||||
|
||||
import { initialize as initializeFeatures } from './features';
|
||||
import { data } from './data';
|
||||
import { routers } from './exceptionRouters';
|
||||
import { checkers } from './checkers';
|
||||
|
||||
|
||||
// dev需要将下面内容也传入
|
||||
import { AspectDict } from './aspects/AspectDict';
|
||||
import { aspectDict } from './aspects';
|
||||
import { triggers } from './triggers';
|
||||
import { watchers } from './watchers';
|
||||
|
||||
import { AspectWrapper } from 'oak-domain/lib/types';
|
||||
import { BasicFeatures } from 'oak-frontend-base';
|
||||
import { AppType } from 'oak-app-domain/Application/Schema';
|
||||
|
||||
export default function initialize(type: AppType, url?: string) {
|
||||
let wholeFeatures = {};
|
||||
const createFeatures = (
|
||||
aspectWrapper: AspectWrapper<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
|
||||
>,
|
||||
basicFeatures: BasicFeatures<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
|
||||
>,
|
||||
context: RuntimeContext
|
||||
) => {
|
||||
const { token, extraFile, application } = initializeGeneralFeatures<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict
|
||||
>(aspectWrapper, basicFeatures, type, context);
|
||||
|
||||
const features = initializeFeatures(aspectWrapper, basicFeatures);
|
||||
const features2 = Object.assign(
|
||||
{
|
||||
token,
|
||||
extraFile,
|
||||
application,
|
||||
},
|
||||
features
|
||||
);
|
||||
|
||||
Object.assign(wholeFeatures, features2, basicFeatures);
|
||||
return features2;
|
||||
};
|
||||
|
||||
const { i18n } = init<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict,
|
||||
ReturnType<typeof createFeatures>
|
||||
>(
|
||||
storageSchema,
|
||||
createFeatures,
|
||||
RuntimeContext.FromCxtStr,
|
||||
aspectDict,
|
||||
routers,
|
||||
triggers,
|
||||
checkers,
|
||||
watchers,
|
||||
data as any,
|
||||
ActionDefDict,
|
||||
);
|
||||
|
||||
return {
|
||||
i18n,
|
||||
features: wholeFeatures as BasicFeatures<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
|
||||
> &
|
||||
ReturnType<typeof createFeatures>,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
import './utils/polyfill';
|
||||
import { initialize as init } from 'oak-frontend-base/src/initialize.prod';
|
||||
import { SimpleConnector } from 'oak-domain/lib/utils/SimpleConnector';
|
||||
|
||||
import { AspectWrapper } from 'oak-domain/lib/types';
|
||||
import { EntityDict, storageSchema, ActionDefDict } from 'oak-app-domain';
|
||||
import { CommonAspectDict } from 'oak-common-aspect';
|
||||
import { RuntimeContext } from './RuntimeContext';
|
||||
|
||||
import { initialize as initializeGeneralFeatures } from 'oak-general-business/src/features';
|
||||
|
||||
import { initialize as initializeFeatures } from './features';
|
||||
import { routers } from './exceptionRouters';
|
||||
import { checkers } from './checkers';
|
||||
import { makeException } from './types/Exception';
|
||||
import { AspectDict } from './aspects/AspectDict';
|
||||
|
||||
import { BasicFeatures } from 'oak-frontend-base';
|
||||
import { AppType } from 'oak-app-domain/Application/Schema';
|
||||
|
||||
|
||||
export default function initialize(type: AppType, url: string) {
|
||||
let wholeFeatures = {};
|
||||
const createFeatures = (
|
||||
aspectWrapper: AspectWrapper<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
|
||||
>,
|
||||
basicFeatures: BasicFeatures<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
|
||||
>,
|
||||
context: RuntimeContext
|
||||
) => {
|
||||
const { token, extraFile, application } = initializeGeneralFeatures<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict
|
||||
>(aspectWrapper, basicFeatures, type, context);
|
||||
|
||||
const features = initializeFeatures(aspectWrapper, basicFeatures);
|
||||
const features2 = Object.assign(
|
||||
{
|
||||
token,
|
||||
extraFile,
|
||||
application,
|
||||
},
|
||||
features
|
||||
);
|
||||
|
||||
Object.assign(wholeFeatures, features2, basicFeatures);
|
||||
return features2;
|
||||
};
|
||||
|
||||
let URL: string;
|
||||
/**
|
||||
* 如果是本地前后端联调,可以显示import initialize.prod走到这里
|
||||
*/
|
||||
if (type === 'wechatMp') {
|
||||
// 如果是小程序,需要显式传入url
|
||||
const apiPath = process.env.NODE_ENV === 'development' ? '3001': '/oak-api'; // 生产环境通过路径映射增加oak-api
|
||||
const protocol = process.env.NODE_ENV === 'development' ? 'http://' : 'https://';
|
||||
URL = `${protocol}${url}${apiPath}/aspect`;
|
||||
}
|
||||
else if (process.env.NODE_ENV === 'development') {
|
||||
URL = 'http://localhost:3001/aspect';
|
||||
}
|
||||
else {
|
||||
// web和public环境只需要传相对路径
|
||||
URL = `/oak-api/aspect`;
|
||||
}
|
||||
const connector = new SimpleConnector(URL, makeException, RuntimeContext.FromCxtStr);
|
||||
const { i18n } = init<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict,
|
||||
ReturnType<typeof createFeatures>
|
||||
>(
|
||||
storageSchema,
|
||||
createFeatures,
|
||||
RuntimeContext.FromCxtStr,
|
||||
routers,
|
||||
connector,
|
||||
checkers,
|
||||
ActionDefDict,
|
||||
);
|
||||
|
||||
return {
|
||||
i18n,
|
||||
features: wholeFeatures as BasicFeatures<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
|
||||
> &
|
||||
ReturnType<typeof createFeatures>,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,40 +1,4 @@
|
|||
import './utils/polyfill';
|
||||
import { initializeFeatures as initializeGeneralFeatures } from 'oak-general-business';
|
||||
import { BasicFeatures, } from 'oak-frontend-base';
|
||||
import { EntityDict } from 'oak-app-domain';
|
||||
import { RuntimeContext } from './RuntimeContext';
|
||||
import { aspectDict } from './aspects';
|
||||
import { initialize } from './features';
|
||||
import { checkers } from './checkers';
|
||||
import { watchers } from './watchers';
|
||||
import { triggers } from './triggers';
|
||||
import { data } from './data';
|
||||
import { routers } from './exceptionRouters';
|
||||
import initialize from './initialize.dev';
|
||||
export default initialize;
|
||||
|
||||
const { token, extraFile, application } = initializeGeneralFeatures<EntityDict, RuntimeContext, typeof aspectDict>();
|
||||
|
||||
const createFeatures = (basicFeatures: BasicFeatures<EntityDict, RuntimeContext, typeof aspectDict>) => {
|
||||
const features = initialize(basicFeatures);
|
||||
const wholeFeatures = Object.assign(
|
||||
{
|
||||
token,
|
||||
extraFile,
|
||||
application,
|
||||
},
|
||||
features
|
||||
);
|
||||
return wholeFeatures;
|
||||
};
|
||||
|
||||
export {
|
||||
createFeatures,
|
||||
aspectDict,
|
||||
triggers,
|
||||
checkers,
|
||||
watchers,
|
||||
data,
|
||||
routers,
|
||||
|
||||
token,
|
||||
application,
|
||||
}
|
||||
console.log('不应该走到这里');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
/** index.wxss **/
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
export default OakPage({
|
||||
path: 'house:list',
|
||||
entity: 'house',
|
||||
projection: {
|
||||
id: 1,
|
||||
iState: 1,
|
||||
coordinate: 1,
|
||||
decorative: 1,
|
||||
orientation: 1,
|
||||
space: 1,
|
||||
},
|
||||
isList: true,
|
||||
formData: async function ({ data, features }) {
|
||||
const application = await features.application.getApplication();
|
||||
return {};
|
||||
},
|
||||
// filters: [],
|
||||
// sorters: [],
|
||||
methods: {
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import * as React from 'react';
|
||||
|
||||
export default function render() {
|
||||
const { t } = this;
|
||||
const { searchValue } = this.state;
|
||||
return (
|
||||
<div style={{ height: '100vh' }}>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<!--index.wxml-->
|
||||
<view class="container">
|
||||
|
||||
</view>
|
||||
|
|
@ -1,7 +1,10 @@
|
|||
import { triggers as generalTriggers } from 'oak-general-business';
|
||||
import { triggers as houseTriggers } from './house';
|
||||
import { triggers as GenenralTriggers } from 'oak-general-business';
|
||||
import { Trigger } from 'oak-domain/lib/types';
|
||||
import { EntityDict } from 'oak-app-domain';
|
||||
import { RuntimeContext } from '../RuntimeContext';
|
||||
|
||||
export const triggers = [...houseTriggers, ...GenenralTriggers] as Trigger<EntityDict, keyof EntityDict, RuntimeContext>[];
|
||||
export const triggers = [
|
||||
...houseTriggers,
|
||||
...generalTriggers,
|
||||
] as Trigger<EntityDict, keyof EntityDict, RuntimeContext>[];
|
||||
|
|
|
|||
|
|
@ -1,3 +1,23 @@
|
|||
import { OakException } from "oak-domain/lib/types";
|
||||
import { OakException } from 'oak-domain/lib/types';
|
||||
import { makeException as makeGeneralException } from 'oak-general-business/lib/types/Exceptions';
|
||||
|
||||
export class ExampleException extends OakException {};
|
||||
export class ExampleException extends OakException {}
|
||||
|
||||
export function makeException(msg: string | object) {
|
||||
const data = typeof msg === 'string' ? JSON.parse(msg) : msg;
|
||||
|
||||
const exception = makeGeneralException(data);
|
||||
if (exception) {
|
||||
return exception;
|
||||
}
|
||||
|
||||
const { name, message } = data;
|
||||
switch (name) {
|
||||
case ExampleException.name: {
|
||||
return new ExampleException(message);
|
||||
}
|
||||
default: {
|
||||
throw new OakException(`不可解读的exception信息「${msg}」`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,43 @@
|
|||
import { GenerateIdOption } from '../utils/polyfill';
|
||||
import { MakeOakComponent, MakeOakPage } from 'oak-frontend-base/src/page.mp';
|
||||
import {
|
||||
MakeOakComponent as MakeOakWebComponent,
|
||||
MakeOakPage as MakeOakWebPage,
|
||||
} from 'oak-frontend-base/src/page.web';
|
||||
import { EntityDict } from 'oak-app-domain';
|
||||
import { RuntimeContext } from '../RuntimeContext';
|
||||
import { aspectDict } from '../aspects';
|
||||
import { initialize } from '../initialize';
|
||||
|
||||
declare global {
|
||||
const generateNewId: () => Promise<string>;
|
||||
const __DEV__: boolean;
|
||||
const generateNewId: (option?: GenerateIdOption) => Promise<string>;
|
||||
const getRandomValues: (length: number) => Promise<Uint8Array>;
|
||||
const OakPage:
|
||||
| MakeOakPage<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
typeof aspectDict,
|
||||
ReturnType<typeof initialize>['features']
|
||||
>
|
||||
| MakeOakWebPage<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
typeof aspectDict,
|
||||
ReturnType<typeof initialize>['features']
|
||||
>;
|
||||
const OakComponent:
|
||||
| MakeOakComponent<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
typeof aspectDict,
|
||||
ReturnType<typeof initialize>['features']
|
||||
>
|
||||
| MakeOakWebComponent<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
typeof aspectDict,
|
||||
ReturnType<typeof initialize>['features']
|
||||
>;
|
||||
}
|
||||
export {}
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
import { v4 } from 'uuid';
|
||||
import { v4, v1 } from 'uuid';
|
||||
|
||||
async function generateNewId() {
|
||||
return v4({ random: await getRandomValues(16) });
|
||||
export type GenerateIdOption = {
|
||||
shuffle?: boolean;
|
||||
};
|
||||
|
||||
async function generateNewId(option?: GenerateIdOption) {
|
||||
if (option?.shuffle && process.env.NODE_ENV === 'development') {
|
||||
return v4({ random: await getRandomValues(16) });
|
||||
}
|
||||
return v1({ random: await getRandomValues(16) });
|
||||
}
|
||||
|
||||
Object.assign(global, {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
import { watchers as generalWatchers } from 'oak-general-business';
|
||||
import { Watcher } from 'oak-domain/lib/types';
|
||||
import { EntityDict } from 'oak-app-domain';
|
||||
import { RuntimeContext } from '../RuntimeContext';
|
||||
|
||||
export const watchers = [...generalWatchers] as Watcher<
|
||||
EntityDict,
|
||||
keyof EntityDict,
|
||||
RuntimeContext
|
||||
>[];
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
|
|
@ -0,0 +1,43 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@import 'tdesign-react/es/style/index.css'; // 少量公共样式
|
||||
|
||||
@import 'tdesign-mobile-react/es/style/index.css'; // 少量公共样式
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import React from 'react';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
|
||||
import './App.less';
|
||||
import LazyLoad from './utils/lazyLoad';
|
||||
const Console = LazyLoad(() => import('./template/console'));
|
||||
const Frontend = LazyLoad(() => import('./template/frontend'));
|
||||
const NotFound = LazyLoad(() => import('./template/notFound'));
|
||||
const Message = LazyLoad(() =>import('@oak-general-business/components/message'));
|
||||
|
||||
type Router = {
|
||||
path: string;
|
||||
element: ReturnType<typeof LazyLoad>;
|
||||
title: string;
|
||||
}
|
||||
|
||||
function getRoutes(routers2: Router[], namespace?: string) {
|
||||
return routers2.map((router, index) => {
|
||||
const { path, element } = router;
|
||||
return (
|
||||
<Route
|
||||
key={`route_${namespace ? `${namespace}_` : ''}${index}`}
|
||||
path={path}
|
||||
element={element}
|
||||
></Route>
|
||||
);
|
||||
});
|
||||
}
|
||||
// routers非常重要,不能删除
|
||||
let routers: Router[] = [];
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{Message}
|
||||
<Routes>
|
||||
<Route path="/console" element={Console}>
|
||||
{getRoutes(routers, 'console')}
|
||||
</Route>
|
||||
<Route path="/" element={Frontend}>
|
||||
{getRoutes(routers)}
|
||||
</Route>
|
||||
<Route path="*" element={NotFound} />
|
||||
</Routes>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"pages": [
|
||||
"@project/pages/house/list/index",
|
||||
"@project/pages/house/info/index",
|
||||
"@project/pages/lease/list/index",
|
||||
"@project/pages/lease/info/index",
|
||||
"@project/pages/lease/detail/index",
|
||||
"@project/pages/lease/upsert/index",
|
||||
"@project/pages/house/upsert/index",
|
||||
"@project/pages/house/detail/index",
|
||||
"@project/pages/house/rental/index",
|
||||
"@project/pages/house/picture/index",
|
||||
"@project/pages/pickers/tag/index",
|
||||
"@project/pages/tag/upsert/index",
|
||||
"@oak-general-business/pages/userRelation/onUser/index",
|
||||
"@oak-general-business/pages/userRelation/onEntity/index",
|
||||
"@oak-general-business/pages/address/list/index",
|
||||
"@oak-general-business/pages/address/upsert/index",
|
||||
"@oak-general-business/pages/token/me/index",
|
||||
"@oak-general-business/pages/pickers/area/index",
|
||||
"@oak-general-business/pages/mobile/me/index",
|
||||
"@oak-general-business/pages/mobile/login/index",
|
||||
"@oak-general-business/pages/user/manage/index",
|
||||
"@oak-general-business/pages/user/manage/detail/index",
|
||||
"@oak-general-business/pages/user/manage/upsert/index",
|
||||
"@oak-general-business/pages/userEntityGrant/grant/index",
|
||||
"@oak-general-business/pages/wechatQrCode/scan/index",
|
||||
"@oak-general-business/pages/userEntityGrant/detail/index",
|
||||
"@oak-general-business/pages/userEntityGrant/confirm/index"
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
import './utils/polyfill';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import './index.less';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
import { ResponsiveProvider } from 'oak-frontend-base/src/platforms/web/responsive';
|
||||
import { getAppType } from './utils/env';
|
||||
import initialize from '../../src/initialize';
|
||||
|
||||
const appType = getAppType();
|
||||
const { features, i18n } = initialize(appType, window.location.hostname);
|
||||
Object.assign(global, {
|
||||
features,
|
||||
})
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
|
||||
features.application.getApplication()
|
||||
.then(
|
||||
() => {
|
||||
root.render(
|
||||
// <React.StrictMode>
|
||||
<BrowserRouter>
|
||||
<I18nextProvider i18n={i18n as any}>
|
||||
<ResponsiveProvider>
|
||||
<App />
|
||||
</ResponsiveProvider>
|
||||
</I18nextProvider>
|
||||
</BrowserRouter>
|
||||
// </React.StrictMode>
|
||||
);
|
||||
}
|
||||
)
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
||||
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
|
|
@ -0,0 +1 @@
|
|||
/// <reference types="react-scripts" />
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import { ReportHandler } from 'web-vitals';
|
||||
|
||||
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom';
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
import React from 'react';
|
||||
import { useNavigate, useParams, useSearchParams, useLocation } from 'react-router-dom';
|
||||
import { Routes, Route, Outlet } from 'react-router-dom';
|
||||
|
||||
|
||||
// function Console() {
|
||||
// const n = useNavigate();
|
||||
// const d = useParams();
|
||||
// const [search, setSearch] = useSearchParams();
|
||||
// const id = search.get('id');
|
||||
// const l = useLocation();
|
||||
// console.log(d, id, l);
|
||||
// return <div onClick={() => {
|
||||
// n('', { state: { name: '212' } })
|
||||
// }}>console</div>;
|
||||
// }
|
||||
|
||||
// export default Console;
|
||||
|
||||
|
||||
function Console() {
|
||||
return (
|
||||
<Outlet />
|
||||
);
|
||||
}
|
||||
|
||||
export default Console;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
import React from 'react';
|
||||
import { useNavigate, useParams, useSearchParams, useLocation } from 'react-router-dom';
|
||||
import { Outlet, Route } from 'react-router-dom';
|
||||
|
||||
function Frontend() {
|
||||
return <Outlet />;
|
||||
}
|
||||
|
||||
export default Frontend;
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import React from 'react';
|
||||
|
||||
|
||||
const NotFound = () => {
|
||||
return <div>你来到了未知的区域</div>;
|
||||
};
|
||||
|
||||
export default NotFound;
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
import React, { useEffect } from 'react';
|
||||
|
||||
import NProgress from 'nprogress';
|
||||
import 'nprogress/nprogress.css';
|
||||
|
||||
function Loading() {
|
||||
//componentDidMount
|
||||
useEffect(() => {
|
||||
NProgress.start();
|
||||
}, []);
|
||||
//componentWillUnmount
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
NProgress.done();
|
||||
};
|
||||
}, []);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default Loading
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export function getAppType() {
|
||||
if (/MicroMessenger/i.test(window.navigator.userAgent)) {
|
||||
return 'wechatPublic';
|
||||
}
|
||||
return 'web';
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import React from "react";
|
||||
import Loading from './Loading';
|
||||
|
||||
const LazyLoad = (factory: () => Promise<{ default: any }>) => {
|
||||
const Component = React.lazy(factory);
|
||||
return (
|
||||
<React.Suspense fallback={<Loading />}>
|
||||
<Component />
|
||||
</React.Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
export default LazyLoad;
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
Object.assign(global, {
|
||||
fetch: fetch,
|
||||
getRandomValues: async function getRandomValues(length: number) {
|
||||
if (length > 65536) {
|
||||
throw new Error('Can only request a maximum of 65536 bytes');
|
||||
}
|
||||
const randomValues = window.crypto.getRandomValues(
|
||||
new Uint8Array(length)
|
||||
);
|
||||
|
||||
|
||||
return new Uint8Array(randomValues);
|
||||
},
|
||||
});
|
||||
|
|
@ -1,12 +1,24 @@
|
|||
/**app.wxss**/
|
||||
@import url("https://fonts.googleapis.com/icon?family=Material+Icons");
|
||||
/** app.wxss **/
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 200rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Material Symbols Rounded";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(https://fonts.gstatic.com/s/sandbox/materialsymbolsrounded/v7/syl0-zNym6YjUruM-QrEh7-nyTnjDwKNJ_190FjpZIvDmUSVOK7BDB_Qb9vUSzq3wzLK-P0J-V_Zs-QtQth3-jOc7TOVpeRL2w5rwZu2rIelXxc.woff2) format("woff2");
|
||||
}
|
||||
|
||||
.material-symbols-rounded {
|
||||
font-family: "Material Symbols Rounded";
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 44rpx;
|
||||
line-height: 1;
|
||||
letter-spacing: normal;
|
||||
text-transform: none;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
word-wrap: normal;
|
||||
direction: ltr;
|
||||
font-feature-settings: "liga";
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
|
@ -1,4 +1,12 @@
|
|||
import { features } from './init';
|
||||
import './utils/polyfill';
|
||||
|
||||
import initialize from '../../src/initialize';
|
||||
|
||||
/**
|
||||
* 初始化,小程序这里必须输入访问的目标域名,系统根据domain和system的关系来判定appId
|
||||
*/
|
||||
const url = 'localhost';
|
||||
const { features } = initialize('wechatMp', url);
|
||||
|
||||
export interface IAppOption {
|
||||
globalData: {
|
||||
|
|
@ -11,7 +19,9 @@ App<IAppOption>({
|
|||
features,
|
||||
},
|
||||
async onLaunch() {
|
||||
await features.token.loginWechatMp('app:onLaunch');
|
||||
// 等application初始化完成后进行登录
|
||||
await features.application.getApplication();
|
||||
features.token.loginWechatMp();
|
||||
},
|
||||
|
||||
onHide() {
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"component": true
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
.t-message {
|
||||
width: 750rpx;
|
||||
height: 0;
|
||||
border-radius: 0rpx 0rpx 16rpx 16rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
opacity: 0;
|
||||
box-shadow: 0rpx 6rpx 16rpx 0rpx rgb(217 212 191 / 50%);
|
||||
transform: translateX(-50%) translateZ(0) translateY(-100%);
|
||||
transition: all 0.4s ease-in-out;
|
||||
|
||||
&-success {
|
||||
background-color: #34bfa3;
|
||||
}
|
||||
|
||||
&-error {
|
||||
background-color: #f4516c;
|
||||
}
|
||||
|
||||
&-warning {
|
||||
background-color: #ffe57f;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
&-primary {
|
||||
background-color: #3963bc;
|
||||
}
|
||||
}
|
||||
|
||||
.t-message-show {
|
||||
transform: translateX(-50%) translateZ(0) translateY(0);
|
||||
height: 72rpx;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.t-message-image {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
},
|
||||
externalClasses: ['t-class', 't-image-class', 't-class-image'],
|
||||
properties: {
|
||||
zIndex: {
|
||||
type: Number,
|
||||
value: 777,
|
||||
},
|
||||
show: Boolean,
|
||||
image: String,
|
||||
content: String,
|
||||
type: {
|
||||
type: String,
|
||||
value: 'primary',
|
||||
options: ['primary', 'warning', 'success', 'error'],
|
||||
},
|
||||
duration: {
|
||||
type: Number,
|
||||
value: 1500,
|
||||
},
|
||||
openApi: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
/**
|
||||
* message距离顶部的距离
|
||||
*/
|
||||
top: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
},
|
||||
|
||||
data: {
|
||||
status: false,
|
||||
},
|
||||
|
||||
// 解决 addListener undefined 的错误
|
||||
observers: {
|
||||
show: function (show) {
|
||||
show && this.changeStatus();
|
||||
if (!show)
|
||||
this.setData({
|
||||
status: show,
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
attached() {
|
||||
this.initMessage();
|
||||
},
|
||||
|
||||
pageLifetimes: {
|
||||
show() {
|
||||
this.initMessage();
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
changeStatus() {
|
||||
this.setData({
|
||||
status: true,
|
||||
});
|
||||
// @ts-ignore
|
||||
if (this.data.timer) clearTimeout(this.data.timer);
|
||||
// @ts-ignore
|
||||
this.data.timer = setTimeout(() => {
|
||||
this.setData({
|
||||
status: false,
|
||||
});
|
||||
// @ts-ignore
|
||||
if (this.data.success) this.data.success();
|
||||
// @ts-ignore
|
||||
this.data.timer = null;
|
||||
}, this.properties.duration);
|
||||
},
|
||||
initMessage() {
|
||||
// @ts-ignore
|
||||
wx.oak = wx.oak || {};
|
||||
// @ts-ignore
|
||||
wx.oak.showMessage = (options = {}) => {
|
||||
// @ts-ignore
|
||||
const { content = '', image = '', type = 'primary', duration = 1500, success = null, top = 0,
|
||||
} = options;
|
||||
// @ts-ignore
|
||||
this.data.success = success;
|
||||
this.setData({
|
||||
content,
|
||||
image,
|
||||
duration,
|
||||
type,
|
||||
top,
|
||||
});
|
||||
this.changeStatus();
|
||||
return this;
|
||||
};
|
||||
// @ts-ignore
|
||||
wx.oak.hideMessage = () => {
|
||||
this.setData({
|
||||
status: false,
|
||||
});
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
<!-- index.wxml -->
|
||||
<view class="t-message t-class {{'t-message-'+type}} {{status?'t-message-show':''}}" style="z-index:{{zIndex}};top:{{top}}rpx">
|
||||
<block wx:if="{{status}}">
|
||||
<view style="margin-right:15rpx">
|
||||
<slot name="icon" />
|
||||
</view>
|
||||
<image wx:if="{{image}}" src="{{image}}" class="t-message-image t-class-image t-image-class" />
|
||||
{{content}}
|
||||
<slot />
|
||||
</block>
|
||||
</view>
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
export default {
|
||||
fallbackLocale: 'zh-CN',
|
||||
defaultLocale: 'zh-CN',
|
||||
translations: {},
|
||||
};
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
var Interpreter = (function (r) {
|
||||
var o = '';
|
||||
function i(r, n) {
|
||||
return r
|
||||
? 'string' == typeof r
|
||||
? r
|
||||
: r
|
||||
.reduce(function (r, t) {
|
||||
return r.concat([
|
||||
(function (n, e) {
|
||||
if (((e = e || {}), 'string' == typeof n))
|
||||
return n;
|
||||
{
|
||||
var r, t, u;
|
||||
if (n[2] && 'object' == typeof n[2])
|
||||
return (
|
||||
(r = Object.keys(n[2]).reduce(
|
||||
function (r, t) {
|
||||
return (
|
||||
(r[t] = i(
|
||||
n[2][t],
|
||||
e
|
||||
)),
|
||||
r
|
||||
);
|
||||
},
|
||||
{}
|
||||
)),
|
||||
(t = r[e[0]]),
|
||||
void 0 !== (u = e[n[0]])
|
||||
? r[u.toString()] ||
|
||||
r.other ||
|
||||
o
|
||||
: t || r.other || o
|
||||
);
|
||||
}
|
||||
if ('object' == typeof n && 0 < n.length)
|
||||
return (function r(t, n, e) {
|
||||
void 0 === e && (e = 0);
|
||||
if (!n || !t || t.length <= 0)
|
||||
return '';
|
||||
n = n[t[e]];
|
||||
if ('string' == typeof n) return n;
|
||||
if ('number' == typeof n)
|
||||
return n.toString();
|
||||
if (!n)
|
||||
return '{'.concat(
|
||||
t.join('.'),
|
||||
'}'
|
||||
);
|
||||
return r(t, n, ++e);
|
||||
})(n[0].split('.'), e, 0);
|
||||
return '';
|
||||
})(t, n),
|
||||
]);
|
||||
}, [])
|
||||
.join('')
|
||||
: o;
|
||||
}
|
||||
function c(r, t, n) {
|
||||
return (
|
||||
('object' == typeof r &&
|
||||
((t = t).constructor && 'Array' === t.constructor
|
||||
? t
|
||||
: t
|
||||
.replace(getRegExp('\[', 'ig'), '.')
|
||||
.replace(getRegExp('\]', 'ig'), '')
|
||||
.split('.')
|
||||
).reduce(function (r, t) {
|
||||
return (r || {})[t];
|
||||
}, r)) ||
|
||||
n
|
||||
);
|
||||
}
|
||||
function f(r) {
|
||||
var t = r;
|
||||
return (t =
|
||||
r && -1 !== r.indexOf(':')
|
||||
? r.replace(getRegExp(':', 'ig'), '.')
|
||||
: t);
|
||||
}
|
||||
function g(r, t, n) {
|
||||
var e = f(n),
|
||||
r = r[t];
|
||||
return (r && (r[e] || c(r, e))) || n;
|
||||
}
|
||||
return (
|
||||
(r.getMessageInterpreter = function () {
|
||||
function u(r, t, n, e) {
|
||||
return i(
|
||||
(function (r, t, n, e) {
|
||||
var u = f(r);
|
||||
if (!(n = t[n])) return g(t, e, r);
|
||||
var o = n[u];
|
||||
return (o = o || c(n, u)) ? o : g(t, e, r);
|
||||
})(r, e, n, n),
|
||||
t
|
||||
);
|
||||
}
|
||||
return function (r, t, n, e) {
|
||||
return 3 === arguments.length
|
||||
? u(r, null, t, n)
|
||||
: 4 === arguments.length
|
||||
? u(r, t, n, e)
|
||||
: '';
|
||||
};
|
||||
}),
|
||||
r
|
||||
);
|
||||
})({});
|
||||
|
||||
module.exports = {
|
||||
t: Interpreter.getMessageInterpreter()
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
import "./utils/polyfill";
|
||||
import { InitializeWechatMp, initI18n } from 'oak-frontend-base';
|
||||
import { EntityDict } from 'oak-app-domain';
|
||||
import { storageSchema, ActionDefDict } from 'oak-app-domain';
|
||||
import { RuntimeContext } from '../../src/RuntimeContext';
|
||||
import { aspectDict, createFeatures, routers, triggers, checkers,
|
||||
watchers, data, token, application } from '../../src/initialize';
|
||||
|
||||
// 每个应用都要初始化applicationId(generalbusiness的要求)
|
||||
const applicationId = data.application[0].id;
|
||||
const { OakComponent, OakPage, features } = InitializeWechatMp<EntityDict, RuntimeContext, typeof aspectDict, ReturnType<typeof createFeatures>>(
|
||||
storageSchema,
|
||||
createFeatures,
|
||||
(store, scene) => new RuntimeContext(store, applicationId, () => token.getToken(), scene),
|
||||
routers,
|
||||
triggers,
|
||||
checkers,
|
||||
watchers,
|
||||
aspectDict,
|
||||
data as any,
|
||||
ActionDefDict);
|
||||
|
||||
// 因为依赖的问题,general库中的部分feature暂时只能在这里注入。以后再修改
|
||||
token.setCache(features.cache);
|
||||
application.setCache(features.cache);
|
||||
application.setApplicationId(applicationId);
|
||||
|
||||
Object.assign(global, {
|
||||
OakPage,
|
||||
OakComponent,
|
||||
});
|
||||
|
||||
export {
|
||||
features,
|
||||
createFeatures,
|
||||
};
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/** index.wxss **/
|
||||
|
||||
.userinfo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.userinfo-avatar {
|
||||
overflow: hidden;
|
||||
width: 128rpx;
|
||||
height: 128rpx;
|
||||
margin: 20rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.usermotto {
|
||||
margin-top: 200px;
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
// index.ts
|
||||
|
||||
Page({
|
||||
data: {
|
||||
motto: 'Hello World',
|
||||
userInfo: {},
|
||||
hasUserInfo: false,
|
||||
canIUse: wx.canIUse('button.open-type.getUserInfo'),
|
||||
canIUseGetUserProfile: false,
|
||||
canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false
|
||||
},
|
||||
// 事件处理函数
|
||||
bindViewTap() {
|
||||
wx.navigateTo({
|
||||
url: '../logs/logs',
|
||||
})
|
||||
},
|
||||
onLoad() {
|
||||
// @ts-ignore
|
||||
if (wx.getUserProfile) {
|
||||
this.setData({
|
||||
canIUseGetUserProfile: true
|
||||
})
|
||||
}
|
||||
},
|
||||
getUserProfile() {
|
||||
// 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
|
||||
wx.getUserProfile({
|
||||
desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
this.setData({
|
||||
userInfo: res.userInfo,
|
||||
hasUserInfo: true
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getUserInfo(e: any) {
|
||||
// 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息
|
||||
console.log(e)
|
||||
this.setData({
|
||||
userInfo: e.detail.userInfo,
|
||||
hasUserInfo: true
|
||||
})
|
||||
}
|
||||
})
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
<!--index.wxml-->
|
||||
<view class="container">
|
||||
<view class="userinfo">
|
||||
<block wx:if="{{canIUseOpenData}}">
|
||||
<view class="userinfo-avatar" bindtap="bindViewTap">
|
||||
<open-data type="userAvatarUrl"></open-data>
|
||||
</view>
|
||||
<open-data type="userNickName"></open-data>
|
||||
</block>
|
||||
<block wx:elif="{{!hasUserInfo}}">
|
||||
<button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
|
||||
<button wx:elif="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
|
||||
<view wx:else> 请使用1.4.4及以上版本基础库 </view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
|
||||
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
|
||||
</block>
|
||||
</view>
|
||||
<view class="usermotto">
|
||||
<text class="user-motto">{{motto}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -1,11 +1,21 @@
|
|||
import { MakeOakComponent, MakeOakPage } from 'oak-frontend-base';
|
||||
import { EntityDict } from 'oak-app-domain/EntityDict';
|
||||
import { MakeOakComponent, MakeOakPage } from 'oak-frontend-base/src/page.mp';
|
||||
import { EntityDict } from 'oak-app-domain';
|
||||
import { RuntimeContext } from '../../../src/RuntimeContext';
|
||||
import { aspectDict } from '../../../src/aspects';
|
||||
import { createFeatures } from '../init';
|
||||
import { initialize } from '../../../src/initialize';
|
||||
|
||||
declare global {
|
||||
const OakPage: MakeOakPage<EntityDict, RuntimeContext, typeof aspectDict, ReturnType<typeof createFeatures>>;
|
||||
const OakComponent: MakeOakComponent<EntityDict, RuntimeContext, typeof aspectDict, ReturnType<typeof createFeatures>>;
|
||||
const OakPage: MakeOakPage<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
typeof aspectDict,
|
||||
ReturnType<typeof initialize>['features']
|
||||
>;
|
||||
const OakComponent: MakeOakComponent<
|
||||
EntityDict,
|
||||
RuntimeContext,
|
||||
typeof aspectDict,
|
||||
ReturnType<typeof initialize>['features']
|
||||
>;
|
||||
}
|
||||
export {}
|
||||
export {};
|
||||
|
|
|
|||
|
|
@ -1,75 +1,76 @@
|
|||
// import '../../../src/utils/polyfill';
|
||||
|
||||
Object.assign(global, {
|
||||
/**
|
||||
* 封装wx环境下的fetch,注意有部分属性并非完全吻合,请谨慎使用
|
||||
* @param url
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
fetch: async (url: string, options?: Parameters<typeof global.fetch>[1]) => {
|
||||
const params = Object.assign({
|
||||
method: 'GET',
|
||||
dataType: '其他',
|
||||
responseType: 'text',
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
* @param url
|
||||
* @param options
|
||||
* @returns
|
||||
*/
|
||||
fetch: async (
|
||||
url: string,
|
||||
options?: Parameters<typeof global.fetch>[1]
|
||||
) => {
|
||||
const params = Object.assign(
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-type': 'application/json',
|
||||
},
|
||||
},
|
||||
}, options);
|
||||
const { method, headers, dataType, responseType, body } = params;
|
||||
|
||||
let responseType2 = responseType;
|
||||
if ((headers as Record<string, string>)['Accept'] === 'application/octet-stream') {
|
||||
responseType2 = 'arraybuffer';
|
||||
}
|
||||
|
||||
if (!['text', 'arraybuffer'].includes(responseType2)) {
|
||||
throw new Error(`传入不支持的responseType: ${responseType2}`);
|
||||
}
|
||||
|
||||
let dataType2 = dataType === 'json' ? dataType : '其他';
|
||||
if (responseType2 === 'arraybuffer') {
|
||||
dataType2 = '其他';
|
||||
}
|
||||
|
||||
return new Promise(
|
||||
(resolve, reject) => {
|
||||
wx.request({
|
||||
url,
|
||||
data: body || {},
|
||||
method: method as any,
|
||||
header: headers,
|
||||
dataType: dataType2 as any,
|
||||
responseType: responseType2 as any,
|
||||
success: (res) => {
|
||||
const { statusCode, data, header } = res;
|
||||
const result = Object.assign({}, res, {
|
||||
status: statusCode,
|
||||
ok: statusCode === 200,
|
||||
headers: header,
|
||||
arrayBuffer: async () => data as ArrayBuffer,
|
||||
json: async () => JSON.parse(data as string),
|
||||
text: async () => data as string,
|
||||
clone: () => result!,
|
||||
url,
|
||||
statusText: statusCode === 200 ? 'ok' : 'error',
|
||||
});
|
||||
return resolve(result);
|
||||
},
|
||||
fail: reject,
|
||||
});
|
||||
}
|
||||
options
|
||||
);
|
||||
const { method, headers, body } = params;
|
||||
|
||||
let responseType: 'arraybuffer' | 'text' | undefined;
|
||||
const accept = (headers as Record<string, string>)['Accept'];
|
||||
if (
|
||||
[
|
||||
'image/jpg',
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'application/octet-stream',
|
||||
].includes(accept)
|
||||
) {
|
||||
responseType = 'arraybuffer';
|
||||
} else {
|
||||
responseType = 'text';
|
||||
}
|
||||
const dataType = '其他';
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.request({
|
||||
url,
|
||||
data: body || {},
|
||||
method: method as any,
|
||||
header: headers,
|
||||
dataType,
|
||||
responseType,
|
||||
success: (res) => {
|
||||
const { statusCode, data, header } = res;
|
||||
const result = Object.assign({}, res, {
|
||||
status: statusCode,
|
||||
ok: statusCode === 200,
|
||||
headers: header,
|
||||
arrayBuffer: async () => data as ArrayBuffer,
|
||||
json: async () => JSON.parse(data as string),
|
||||
text: async () => data as string,
|
||||
clone: () => result!,
|
||||
url,
|
||||
statusText: statusCode === 200 ? 'ok' : 'error',
|
||||
});
|
||||
return resolve(result);
|
||||
},
|
||||
fail: reject,
|
||||
});
|
||||
});
|
||||
},
|
||||
getRandomValues: async function getRandomValues(length: number) {
|
||||
if (length > 65536) {
|
||||
throw new Error('Can only request a maximum of 65536 bytes')
|
||||
throw new Error('Can only request a maximum of 65536 bytes');
|
||||
}
|
||||
|
||||
|
||||
const { randomValues } = await wx.getRandomValues({
|
||||
length,
|
||||
});
|
||||
return new Uint8Array(randomValues);
|
||||
}
|
||||
,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue