From 7bee9b5f45f80fc7d933f22d4f2a058545b2e922 Mon Sep 17 00:00:00 2001 From: wkj <278599135@qq.com> Date: Sat, 23 Jul 2022 09:03:51 +0800 Subject: [PATCH] =?UTF-8?q?cli=20=E6=A8=A1=E7=89=88=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- template/.gitignore | 5 +- template/.stylelintrc.js | 12 +- template/src/RunningContext.ts | 19 ++- template/src/aspects/AspectDict.ts | 7 + template/src/aspects/index.ts | 17 ++- template/src/checkers/index.ts | 11 +- template/src/config/index.ts | 34 ++++- template/src/data/application.ts | 21 ++- template/src/data/domain.ts | 13 ++ template/src/data/index.ts | 9 +- template/src/data/system.ts | 14 +- template/src/exceptionRouters.ts | 16 ++- template/src/features/index.ts | 20 ++- template/src/initialize.dev.ts | 88 ++++++++++++ template/src/initialize.prod.ts | 99 ++++++++++++++ template/src/initialize.ts | 42 +----- .../{wechatMp => }/src/pages/index/index.json | 0 template/src/pages/index/index.less | 5 + template/src/pages/index/index.ts | 22 +++ template/src/pages/index/index.tsx | 11 ++ template/src/pages/index/index.wxml | 4 + template/src/triggers/index.ts | 7 +- template/src/types/Exception.ts | 24 +++- template/src/typings/polyfill.d.ts | 41 +++++- template/src/utils/polyfill.ts | 13 +- template/src/watchers/index.ts | 10 ++ template/web/public/favicon.ico | Bin 0 -> 3870 bytes template/web/public/index.html | 43 ++++++ template/web/public/logo192.png | Bin 0 -> 5347 bytes template/web/public/logo512.png | Bin 0 -> 9664 bytes template/web/public/manifest.json | 25 ++++ template/web/public/robots.txt | 3 + template/web/src/App.less | 3 + template/web/src/App.test.tsx | 9 ++ template/web/src/App.tsx | 49 +++++++ template/web/src/app.json | 31 +++++ template/web/src/index.less | 13 ++ template/web/src/index.tsx | 43 ++++++ template/web/src/logo.svg | 1 + template/web/src/react-app-env.d.ts | 1 + template/web/src/reportWebVitals.ts | 15 +++ template/web/src/setupTests.ts | 5 + template/web/src/template/console/index.tsx | 28 ++++ template/web/src/template/frontend/index.tsx | 10 ++ template/web/src/template/notFound/index.tsx | 8 ++ template/web/src/utils/Loading.tsx | 22 +++ template/web/src/utils/env.ts | 6 + template/web/src/utils/lazyLoad.tsx | 13 ++ template/web/src/utils/polyfill.ts | 15 +++ template/wechatMp/src/app.less | 34 +++-- template/wechatMp/src/app.ts | 14 +- .../src/components/message/index.json | 3 - .../src/components/message/index.less | 45 ------- .../wechatMp/src/components/message/index.ts | 107 --------------- .../src/components/message/index.wxml | 11 -- template/wechatMp/src/i18n/locales.ts | 5 - template/wechatMp/src/i18n/locales.wxs | 114 ---------------- template/wechatMp/src/init.ts | 36 ----- template/wechatMp/src/pages/index/index.less | 20 --- template/wechatMp/src/pages/index/index.ts | 47 ------- template/wechatMp/src/pages/index/index.wxml | 23 ---- template/wechatMp/src/typings/polyfill.d.ts | 22 ++- template/wechatMp/src/utils/polyfill.ts | 125 +++++++++--------- 63 files changed, 926 insertions(+), 587 deletions(-) create mode 100644 template/src/aspects/AspectDict.ts create mode 100644 template/src/data/domain.ts create mode 100644 template/src/initialize.dev.ts create mode 100644 template/src/initialize.prod.ts rename template/{wechatMp => }/src/pages/index/index.json (100%) create mode 100644 template/src/pages/index/index.less create mode 100644 template/src/pages/index/index.ts create mode 100644 template/src/pages/index/index.tsx create mode 100644 template/src/pages/index/index.wxml create mode 100644 template/src/watchers/index.ts create mode 100644 template/web/public/favicon.ico create mode 100644 template/web/public/index.html create mode 100644 template/web/public/logo192.png create mode 100644 template/web/public/logo512.png create mode 100644 template/web/public/manifest.json create mode 100644 template/web/public/robots.txt create mode 100644 template/web/src/App.less create mode 100644 template/web/src/App.test.tsx create mode 100644 template/web/src/App.tsx create mode 100644 template/web/src/app.json create mode 100644 template/web/src/index.less create mode 100644 template/web/src/index.tsx create mode 100644 template/web/src/logo.svg create mode 100644 template/web/src/react-app-env.d.ts create mode 100644 template/web/src/reportWebVitals.ts create mode 100644 template/web/src/setupTests.ts create mode 100644 template/web/src/template/console/index.tsx create mode 100644 template/web/src/template/frontend/index.tsx create mode 100644 template/web/src/template/notFound/index.tsx create mode 100644 template/web/src/utils/Loading.tsx create mode 100644 template/web/src/utils/env.ts create mode 100644 template/web/src/utils/lazyLoad.tsx create mode 100644 template/web/src/utils/polyfill.ts delete mode 100644 template/wechatMp/src/components/message/index.json delete mode 100644 template/wechatMp/src/components/message/index.less delete mode 100644 template/wechatMp/src/components/message/index.ts delete mode 100644 template/wechatMp/src/components/message/index.wxml delete mode 100644 template/wechatMp/src/i18n/locales.ts delete mode 100644 template/wechatMp/src/i18n/locales.wxs delete mode 100644 template/wechatMp/src/init.ts delete mode 100644 template/wechatMp/src/pages/index/index.less delete mode 100644 template/wechatMp/src/pages/index/index.ts delete mode 100644 template/wechatMp/src/pages/index/index.wxml diff --git a/template/.gitignore b/template/.gitignore index 7bc388e..9dc9b7d 100644 --- a/template/.gitignore +++ b/template/.gitignore @@ -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 \ No newline at end of file +oak-app-domain +*/public/locales \ No newline at end of file diff --git a/template/.stylelintrc.js b/template/.stylelintrc.js index 969b363..99446b0 100644 --- a/template/.stylelintrc.js +++ b/template/.stylelintrc.js @@ -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, }, -}; \ No newline at end of file +}; diff --git a/template/src/RunningContext.ts b/template/src/RunningContext.ts index 72d1fe9..26eadde 100644 --- a/template/src/RunningContext.ts +++ b/template/src/RunningContext.ts @@ -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 { - -} \ No newline at end of file + static FromCxtStr(cxtStr?: string) { + const { token, applicationId, scene } = cxtStr + ? GeneralRuntimeContext.fromString(cxtStr) + : { + token: undefined, + applicationId: undefined, + scene: undefined, + }; + return (store: RowStore) => { + const context = new RuntimeContext(store, applicationId); + context.setScene(scene); + context.setToken(token); + return context; + }; + } +} diff --git a/template/src/aspects/AspectDict.ts b/template/src/aspects/AspectDict.ts new file mode 100644 index 0000000..68c1a3e --- /dev/null +++ b/template/src/aspects/AspectDict.ts @@ -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; +} & GeneralAspectDict; diff --git a/template/src/aspects/index.ts b/template/src/aspects/index.ts index 807975f..d564e2c 100644 --- a/template/src/aspects/index.ts +++ b/template/src/aspects/index.ts @@ -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>); + ...generalAspectDict, +} as AspectDict & GeneralAspectDict; -export { - aspectDict, -} \ No newline at end of file +export { aspectDict }; diff --git a/template/src/checkers/index.ts b/template/src/checkers/index.ts index 705d67f..900b4dd 100644 --- a/template/src/checkers/index.ts +++ b/template/src/checkers/index.ts @@ -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[]; \ No newline at end of file +const checkers = [...houseCheckers, ...generalCheckers] as Checker< + EntityDict, + keyof EntityDict, + RuntimeContext +>[]; +processCheckers(checkers); +export { checkers }; diff --git a/template/src/config/index.ts b/template/src/config/index.ts index 09ac130..2ba233b 100644 --- a/template/src/config/index.ts +++ b/template/src/config/index.ts @@ -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', + }, + }, + }, + }, }, }; diff --git a/template/src/data/application.ts b/template/src/data/application.ts index 7b8184f..ecbaffb 100644 --- a/template/src/data/application.ts +++ b/template/src/data/application.ts @@ -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', - } -]; \ No newline at end of file + }, + { + id: DEV_WEB_APPLICATION_ID, + name: 'devWeb', + type: 'web', + systemId: DEV_SYSTEM_ID, + config: { + type: 'web', + }, + description: 'web应用,指向dev_system', + }, +]; diff --git a/template/src/data/domain.ts b/template/src/data/domain.ts new file mode 100644 index 0000000..21a4d7d --- /dev/null +++ b/template/src/data/domain.ts @@ -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, + }, +]; \ No newline at end of file diff --git a/template/src/data/index.ts b/template/src/data/index.ts index 4ded7fc..ff56687 100644 --- a/template/src/data/index.ts +++ b/template/src/data/index.ts @@ -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, +}; diff --git a/template/src/data/system.ts b/template/src/data/system.ts index 273f122..f03c0d4 100644 --- a/template/src/data/system.ts +++ b/template/src/data/system.ts @@ -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: {}, - } -]; \ No newline at end of file + name: Config.System.develop.name, + description: Config.System.develop.description, + config: Config.System.develop.config, + }, +]; diff --git a/template/src/exceptionRouters.ts b/template/src/exceptionRouters.ts index ec43d04..c786cc8 100644 --- a/template/src/exceptionRouters.ts +++ b/template/src/exceptionRouters.ts @@ -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; diff --git a/template/src/features/index.ts b/template/src/features/index.ts index 6751934..27fec8e 100644 --- a/template/src/features/index.ts +++ b/template/src/features/index.ts @@ -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) { +export function initialize( + aspectWrapper: AspectWrapper< + EntityDict, + RuntimeContext, + AspectDict & CommonAspectDict + >, + basicFeatures: BasicFeatures< + EntityDict, + RuntimeContext, + AspectDict & CommonAspectDict + > +) { const { cache } = basicFeatures; - const sample = new Sample.Sample(cache); + const sample = new Sample.Sample(aspectWrapper, cache); return { sample, diff --git a/template/src/initialize.dev.ts b/template/src/initialize.dev.ts new file mode 100644 index 0000000..5df762d --- /dev/null +++ b/template/src/initialize.dev.ts @@ -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 + >, + basicFeatures: BasicFeatures< + EntityDict, + RuntimeContext, + AspectDict & CommonAspectDict + >, + 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 + >( + storageSchema, + createFeatures, + RuntimeContext.FromCxtStr, + aspectDict, + routers, + triggers, + checkers, + watchers, + data as any, + ActionDefDict, + ); + + return { + i18n, + features: wholeFeatures as BasicFeatures< + EntityDict, + RuntimeContext, + AspectDict & CommonAspectDict + > & + ReturnType, + }; +} diff --git a/template/src/initialize.prod.ts b/template/src/initialize.prod.ts new file mode 100644 index 0000000..941371a --- /dev/null +++ b/template/src/initialize.prod.ts @@ -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 + >, + basicFeatures: BasicFeatures< + EntityDict, + RuntimeContext, + AspectDict & CommonAspectDict + >, + 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 + >( + storageSchema, + createFeatures, + RuntimeContext.FromCxtStr, + routers, + connector, + checkers, + ActionDefDict, + ); + + return { + i18n, + features: wholeFeatures as BasicFeatures< + EntityDict, + RuntimeContext, + AspectDict & CommonAspectDict + > & + ReturnType, + }; +} diff --git a/template/src/initialize.ts b/template/src/initialize.ts index 4ff8747..34c4a48 100644 --- a/template/src/initialize.ts +++ b/template/src/initialize.ts @@ -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(); - -const createFeatures = (basicFeatures: BasicFeatures) => { - 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('不应该走到这里'); diff --git a/template/wechatMp/src/pages/index/index.json b/template/src/pages/index/index.json similarity index 100% rename from template/wechatMp/src/pages/index/index.json rename to template/src/pages/index/index.json diff --git a/template/src/pages/index/index.less b/template/src/pages/index/index.less new file mode 100644 index 0000000..1086664 --- /dev/null +++ b/template/src/pages/index/index.less @@ -0,0 +1,5 @@ +/** index.wxss **/ + +.container { + display: flex; +} diff --git a/template/src/pages/index/index.ts b/template/src/pages/index/index.ts new file mode 100644 index 0000000..457a238 --- /dev/null +++ b/template/src/pages/index/index.ts @@ -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: { + }, +}); diff --git a/template/src/pages/index/index.tsx b/template/src/pages/index/index.tsx new file mode 100644 index 0000000..07ddfd0 --- /dev/null +++ b/template/src/pages/index/index.tsx @@ -0,0 +1,11 @@ +import * as React from 'react'; + +export default function render() { + const { t } = this; + const { searchValue } = this.state; + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/template/src/pages/index/index.wxml b/template/src/pages/index/index.wxml new file mode 100644 index 0000000..e65a4b8 --- /dev/null +++ b/template/src/pages/index/index.wxml @@ -0,0 +1,4 @@ + + + + diff --git a/template/src/triggers/index.ts b/template/src/triggers/index.ts index 3cb05b3..1b6bdde 100644 --- a/template/src/triggers/index.ts +++ b/template/src/triggers/index.ts @@ -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[]; +export const triggers = [ + ...houseTriggers, + ...generalTriggers, +] as Trigger[]; diff --git a/template/src/types/Exception.ts b/template/src/types/Exception.ts index adb8d17..c21a9dd 100644 --- a/template/src/types/Exception.ts +++ b/template/src/types/Exception.ts @@ -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 {}; \ No newline at end of file +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}」`); + } + } +} diff --git a/template/src/typings/polyfill.d.ts b/template/src/typings/polyfill.d.ts index a1a19da..29b1e07 100644 --- a/template/src/typings/polyfill.d.ts +++ b/template/src/typings/polyfill.d.ts @@ -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; + const __DEV__: boolean; + const generateNewId: (option?: GenerateIdOption) => Promise; const getRandomValues: (length: number) => Promise; + const OakPage: + | MakeOakPage< + EntityDict, + RuntimeContext, + typeof aspectDict, + ReturnType['features'] + > + | MakeOakWebPage< + EntityDict, + RuntimeContext, + typeof aspectDict, + ReturnType['features'] + >; + const OakComponent: + | MakeOakComponent< + EntityDict, + RuntimeContext, + typeof aspectDict, + ReturnType['features'] + > + | MakeOakWebComponent< + EntityDict, + RuntimeContext, + typeof aspectDict, + ReturnType['features'] + >; } -export {} \ No newline at end of file +export {}; diff --git a/template/src/utils/polyfill.ts b/template/src/utils/polyfill.ts index c233aba..cee4cea 100644 --- a/template/src/utils/polyfill.ts +++ b/template/src/utils/polyfill.ts @@ -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, { diff --git a/template/src/watchers/index.ts b/template/src/watchers/index.ts new file mode 100644 index 0000000..57e139d --- /dev/null +++ b/template/src/watchers/index.ts @@ -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 +>[]; diff --git a/template/web/public/favicon.ico b/template/web/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a11777cc471a4344702741ab1c8a588998b1311a GIT binary patch literal 3870 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 baj7?x%VD!5Cxk2YbYLNVeiXvvpMCWYo=by@ literal 0 HcmV?d00001 diff --git a/template/web/public/index.html b/template/web/public/index.html new file mode 100644 index 0000000..aa069f2 --- /dev/null +++ b/template/web/public/index.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + + React App + + + +
+ + + diff --git a/template/web/public/logo192.png b/template/web/public/logo192.png new file mode 100644 index 0000000000000000000000000000000000000000..fc44b0a3796c0e0a64c3d858ca038bd4570465d9 GIT binary patch literal 5347 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 b{|{}U^kRn2wo}j7|0ATu<;8xA7zX}7|B6mN literal 0 HcmV?d00001 diff --git a/template/web/public/manifest.json b/template/web/public/manifest.json new file mode 100644 index 0000000..080d6c7 --- /dev/null +++ b/template/web/public/manifest.json @@ -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" +} diff --git a/template/web/public/robots.txt b/template/web/public/robots.txt new file mode 100644 index 0000000..e9e57dc --- /dev/null +++ b/template/web/public/robots.txt @@ -0,0 +1,3 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * +Disallow: diff --git a/template/web/src/App.less b/template/web/src/App.less new file mode 100644 index 0000000..72c3a54 --- /dev/null +++ b/template/web/src/App.less @@ -0,0 +1,3 @@ +@import 'tdesign-react/es/style/index.css'; // 少量公共样式 + +@import 'tdesign-mobile-react/es/style/index.css'; // 少量公共样式 diff --git a/template/web/src/App.test.tsx b/template/web/src/App.test.tsx new file mode 100644 index 0000000..2a68616 --- /dev/null +++ b/template/web/src/App.test.tsx @@ -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(); + const linkElement = screen.getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); +}); diff --git a/template/web/src/App.tsx b/template/web/src/App.tsx new file mode 100644 index 0000000..c5a93a1 --- /dev/null +++ b/template/web/src/App.tsx @@ -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; + title: string; +} + +function getRoutes(routers2: Router[], namespace?: string) { + return routers2.map((router, index) => { + const { path, element } = router; + return ( + + ); + }); +} +// routers非常重要,不能删除 +let routers: Router[] = []; + +function App() { + return ( + + {Message} + + + {getRoutes(routers, 'console')} + + + {getRoutes(routers)} + + + + + ); +} + +export default App; diff --git a/template/web/src/app.json b/template/web/src/app.json new file mode 100644 index 0000000..76f8803 --- /dev/null +++ b/template/web/src/app.json @@ -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" + ] +} diff --git a/template/web/src/index.less b/template/web/src/index.less new file mode 100644 index 0000000..ec2585e --- /dev/null +++ b/template/web/src/index.less @@ -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; +} diff --git a/template/web/src/index.tsx b/template/web/src/index.tsx new file mode 100644 index 0000000..6137c37 --- /dev/null +++ b/template/web/src/index.tsx @@ -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( + // + + + + + + + + // + ); + } +) + +// 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(); diff --git a/template/web/src/logo.svg b/template/web/src/logo.svg new file mode 100644 index 0000000..9dfc1c0 --- /dev/null +++ b/template/web/src/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/template/web/src/react-app-env.d.ts b/template/web/src/react-app-env.d.ts new file mode 100644 index 0000000..6889c6b --- /dev/null +++ b/template/web/src/react-app-env.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/template/web/src/reportWebVitals.ts b/template/web/src/reportWebVitals.ts new file mode 100644 index 0000000..49a2a16 --- /dev/null +++ b/template/web/src/reportWebVitals.ts @@ -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; diff --git a/template/web/src/setupTests.ts b/template/web/src/setupTests.ts new file mode 100644 index 0000000..8f2609b --- /dev/null +++ b/template/web/src/setupTests.ts @@ -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'; diff --git a/template/web/src/template/console/index.tsx b/template/web/src/template/console/index.tsx new file mode 100644 index 0000000..2d77cd3 --- /dev/null +++ b/template/web/src/template/console/index.tsx @@ -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
{ +// n('', { state: { name: '212' } }) +// }}>console
; +// } + +// export default Console; + + +function Console() { + return ( + + ); +} + +export default Console; \ No newline at end of file diff --git a/template/web/src/template/frontend/index.tsx b/template/web/src/template/frontend/index.tsx new file mode 100644 index 0000000..272240a --- /dev/null +++ b/template/web/src/template/frontend/index.tsx @@ -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 ; +} + +export default Frontend; \ No newline at end of file diff --git a/template/web/src/template/notFound/index.tsx b/template/web/src/template/notFound/index.tsx new file mode 100644 index 0000000..4adee22 --- /dev/null +++ b/template/web/src/template/notFound/index.tsx @@ -0,0 +1,8 @@ +import React from 'react'; + + +const NotFound = () => { + return
你来到了未知的区域
; +}; + +export default NotFound; diff --git a/template/web/src/utils/Loading.tsx b/template/web/src/utils/Loading.tsx new file mode 100644 index 0000000..a20c2d2 --- /dev/null +++ b/template/web/src/utils/Loading.tsx @@ -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 \ No newline at end of file diff --git a/template/web/src/utils/env.ts b/template/web/src/utils/env.ts new file mode 100644 index 0000000..88e2d4b --- /dev/null +++ b/template/web/src/utils/env.ts @@ -0,0 +1,6 @@ +export function getAppType() { + if (/MicroMessenger/i.test(window.navigator.userAgent)) { + return 'wechatPublic'; + } + return 'web'; +} \ No newline at end of file diff --git a/template/web/src/utils/lazyLoad.tsx b/template/web/src/utils/lazyLoad.tsx new file mode 100644 index 0000000..4069fda --- /dev/null +++ b/template/web/src/utils/lazyLoad.tsx @@ -0,0 +1,13 @@ +import React from "react"; +import Loading from './Loading'; + +const LazyLoad = (factory: () => Promise<{ default: any }>) => { + const Component = React.lazy(factory); + return ( + }> + + + ); +}; + +export default LazyLoad; \ No newline at end of file diff --git a/template/web/src/utils/polyfill.ts b/template/web/src/utils/polyfill.ts new file mode 100644 index 0000000..1fac444 --- /dev/null +++ b/template/web/src/utils/polyfill.ts @@ -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); + }, +}); diff --git a/template/wechatMp/src/app.less b/template/wechatMp/src/app.less index 7b74cf1..27ce786 100644 --- a/template/wechatMp/src/app.less +++ b/template/wechatMp/src/app.less @@ -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; +} \ No newline at end of file diff --git a/template/wechatMp/src/app.ts b/template/wechatMp/src/app.ts index 9aa3305..de4a6f4 100644 --- a/template/wechatMp/src/app.ts +++ b/template/wechatMp/src/app.ts @@ -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({ features, }, async onLaunch() { - await features.token.loginWechatMp('app:onLaunch'); + // 等application初始化完成后进行登录 + await features.application.getApplication(); + features.token.loginWechatMp(); }, onHide() { diff --git a/template/wechatMp/src/components/message/index.json b/template/wechatMp/src/components/message/index.json deleted file mode 100644 index 32640e0..0000000 --- a/template/wechatMp/src/components/message/index.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "component": true -} \ No newline at end of file diff --git a/template/wechatMp/src/components/message/index.less b/template/wechatMp/src/components/message/index.less deleted file mode 100644 index 653d78e..0000000 --- a/template/wechatMp/src/components/message/index.less +++ /dev/null @@ -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; -} diff --git a/template/wechatMp/src/components/message/index.ts b/template/wechatMp/src/components/message/index.ts deleted file mode 100644 index 9d8b8ad..0000000 --- a/template/wechatMp/src/components/message/index.ts +++ /dev/null @@ -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, - }); - }; - }, - }, -}); diff --git a/template/wechatMp/src/components/message/index.wxml b/template/wechatMp/src/components/message/index.wxml deleted file mode 100644 index 3911cbc..0000000 --- a/template/wechatMp/src/components/message/index.wxml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - {{content}} - - - \ No newline at end of file diff --git a/template/wechatMp/src/i18n/locales.ts b/template/wechatMp/src/i18n/locales.ts deleted file mode 100644 index 9c7ab6d..0000000 --- a/template/wechatMp/src/i18n/locales.ts +++ /dev/null @@ -1,5 +0,0 @@ -export default { - fallbackLocale: 'zh-CN', - defaultLocale: 'zh-CN', - translations: {}, -}; diff --git a/template/wechatMp/src/i18n/locales.wxs b/template/wechatMp/src/i18n/locales.wxs deleted file mode 100644 index 2b25da4..0000000 --- a/template/wechatMp/src/i18n/locales.wxs +++ /dev/null @@ -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() -} \ No newline at end of file diff --git a/template/wechatMp/src/init.ts b/template/wechatMp/src/init.ts deleted file mode 100644 index 7dd4998..0000000 --- a/template/wechatMp/src/init.ts +++ /dev/null @@ -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>( - 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, -}; \ No newline at end of file diff --git a/template/wechatMp/src/pages/index/index.less b/template/wechatMp/src/pages/index/index.less deleted file mode 100644 index e1a30da..0000000 --- a/template/wechatMp/src/pages/index/index.less +++ /dev/null @@ -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; -} diff --git a/template/wechatMp/src/pages/index/index.ts b/template/wechatMp/src/pages/index/index.ts deleted file mode 100644 index 667d115..0000000 --- a/template/wechatMp/src/pages/index/index.ts +++ /dev/null @@ -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 - }) - } -}) diff --git a/template/wechatMp/src/pages/index/index.wxml b/template/wechatMp/src/pages/index/index.wxml deleted file mode 100644 index f00d294..0000000 --- a/template/wechatMp/src/pages/index/index.wxml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - 请使用1.4.4及以上版本基础库 - - - - {{userInfo.nickName}} - - - - {{motto}} - - diff --git a/template/wechatMp/src/typings/polyfill.d.ts b/template/wechatMp/src/typings/polyfill.d.ts index 284fa07..9673d96 100644 --- a/template/wechatMp/src/typings/polyfill.d.ts +++ b/template/wechatMp/src/typings/polyfill.d.ts @@ -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>; - const OakComponent: MakeOakComponent>; + const OakPage: MakeOakPage< + EntityDict, + RuntimeContext, + typeof aspectDict, + ReturnType['features'] + >; + const OakComponent: MakeOakComponent< + EntityDict, + RuntimeContext, + typeof aspectDict, + ReturnType['features'] + >; } -export {} \ No newline at end of file +export {}; diff --git a/template/wechatMp/src/utils/polyfill.ts b/template/wechatMp/src/utils/polyfill.ts index f237941..4c804ea 100644 --- a/template/wechatMp/src/utils/polyfill.ts +++ b/template/wechatMp/src/utils/polyfill.ts @@ -1,75 +1,76 @@ -// import '../../../src/utils/polyfill'; - Object.assign(global, { /** * 封装wx环境下的fetch,注意有部分属性并非完全吻合,请谨慎使用 - * @param url - * @param options - * @returns - */ - fetch: async (url: string, options?: Parameters[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[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)['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)['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); - } - , -}); \ No newline at end of file + }, +});