From 855a0467c2b2d5e338959732aaf31bd3017bfdd1 Mon Sep 17 00:00:00 2001 From: "Xc@centOs" Date: Sun, 21 Apr 2024 17:49:59 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 69 +++++++++ package.json | 212 ++++++++++++++++++++++++++ src/aspects/AspectDict.ts | 6 + src/aspects/index.ts | 12 ++ src/aspects/sample.ts | 6 + src/checkers/index.ts | 9 ++ src/checkers/store.ts | 33 ++++ src/components/AbstractComponents.ts | 45 ++++++ src/config/connector.ts | 9 ++ src/config/constants.ts | 1 + src/config/message.ts | 1 + src/config/styles/mp/index.less | 2 + src/config/styles/mp/mixins.less | 7 + src/config/styles/web/index.less | 1 + src/configuration/access.dev.ts | 10 ++ src/configuration/access.prod.ts | 11 ++ src/configuration/access.ts | 3 + src/configuration/attrUpdateMatrix.ts | 15 ++ src/configuration/cache.ts | 4 + src/configuration/dependency.ts | 3 + src/configuration/index.ts | 19 +++ src/configuration/relation.ts | 19 +++ src/configuration/render.ts | 7 + src/configuration/server.ts | 13 ++ src/context/BackendRuntimeContext.ts | 12 ++ src/context/DependentContext.ts | 1 + src/context/FrontendRuntimeContext.ts | 17 +++ src/context/RuntimeContext.ts | 5 + src/data/actionAuth.ts | 8 + src/data/i18n.ts | 5 + src/data/index.ts | 13 ++ src/data/path.ts | 5 + src/data/relationAuth.ts | 8 + src/entities/Order.ts | 121 +++++++++++++++ src/entities/Pay.ts | 125 +++++++++++++++ src/entities/PayChannel.ts | 41 +++++ src/exceptionHandler.ts | 59 +++++++ src/features/Console.ts | 26 ++++ src/features/Menu.ts | 99 ++++++++++++ src/features/Sample.ts | 26 ++++ src/features/index.ts | 20 +++ src/hooks/useFeatures.ts | 9 ++ src/initialize.ts | 4 + src/locales/common/zh_CN.json | 49 ++++++ src/page.mp.ts | 1 + src/page.native.ts | 1 + src/page.ts | 2 + src/page.web.ts | 1 + src/ports/index.ts | 15 ++ src/routines/start.ts | 28 ++++ src/timers/index.ts | 30 ++++ src/triggers/index.ts | 10 ++ src/types/DependentExceptions.ts | 13 ++ src/types/Exception.ts | 30 ++++ src/types/RuntimeCxt.ts | 12 ++ src/watchers/index.ts | 11 ++ tsconfig.build.json | 37 +++++ tsconfig.build.paths.json | 17 +++ tsconfig.json | 44 ++++++ tsconfig.mp.json | 45 ++++++ tsconfig.paths.json | 17 +++ tsconfig.web.json | 47 ++++++ typings/index.d.ts | 5 + typings/polyfill.d.ts | 13 ++ typings/react-app-env.d.ts | 1 + 65 files changed, 1550 insertions(+) create mode 100644 .gitignore create mode 100644 package.json create mode 100644 src/aspects/AspectDict.ts create mode 100644 src/aspects/index.ts create mode 100644 src/aspects/sample.ts create mode 100644 src/checkers/index.ts create mode 100644 src/checkers/store.ts create mode 100644 src/components/AbstractComponents.ts create mode 100644 src/config/connector.ts create mode 100644 src/config/constants.ts create mode 100644 src/config/message.ts create mode 100644 src/config/styles/mp/index.less create mode 100644 src/config/styles/mp/mixins.less create mode 100644 src/config/styles/web/index.less create mode 100644 src/configuration/access.dev.ts create mode 100644 src/configuration/access.prod.ts create mode 100644 src/configuration/access.ts create mode 100644 src/configuration/attrUpdateMatrix.ts create mode 100644 src/configuration/cache.ts create mode 100644 src/configuration/dependency.ts create mode 100644 src/configuration/index.ts create mode 100644 src/configuration/relation.ts create mode 100644 src/configuration/render.ts create mode 100644 src/configuration/server.ts create mode 100644 src/context/BackendRuntimeContext.ts create mode 100644 src/context/DependentContext.ts create mode 100644 src/context/FrontendRuntimeContext.ts create mode 100644 src/context/RuntimeContext.ts create mode 100644 src/data/actionAuth.ts create mode 100644 src/data/i18n.ts create mode 100644 src/data/index.ts create mode 100644 src/data/path.ts create mode 100644 src/data/relationAuth.ts create mode 100644 src/entities/Order.ts create mode 100644 src/entities/Pay.ts create mode 100644 src/entities/PayChannel.ts create mode 100644 src/exceptionHandler.ts create mode 100644 src/features/Console.ts create mode 100644 src/features/Menu.ts create mode 100644 src/features/Sample.ts create mode 100644 src/features/index.ts create mode 100644 src/hooks/useFeatures.ts create mode 100644 src/initialize.ts create mode 100644 src/locales/common/zh_CN.json create mode 100644 src/page.mp.ts create mode 100644 src/page.native.ts create mode 100644 src/page.ts create mode 100644 src/page.web.ts create mode 100644 src/ports/index.ts create mode 100644 src/routines/start.ts create mode 100644 src/timers/index.ts create mode 100644 src/triggers/index.ts create mode 100644 src/types/DependentExceptions.ts create mode 100644 src/types/Exception.ts create mode 100644 src/types/RuntimeCxt.ts create mode 100644 src/watchers/index.ts create mode 100644 tsconfig.build.json create mode 100644 tsconfig.build.paths.json create mode 100644 tsconfig.json create mode 100644 tsconfig.mp.json create mode 100644 tsconfig.paths.json create mode 100644 tsconfig.web.json create mode 100644 typings/index.d.ts create mode 100644 typings/polyfill.d.ts create mode 100644 typings/react-app-env.d.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..90ab921a --- /dev/null +++ b/.gitignore @@ -0,0 +1,69 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +# typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + + +.idea/ + + +.vscode + +build +package-lock.json +scripts/local +*tsbuildinfo +src/oak-app-domain \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..3c7fc556 --- /dev/null +++ b/package.json @@ -0,0 +1,212 @@ +{ + "name": "oak_template", + "version": "1.0.0", + "description": "", + "scripts": { + "make:domain": "cross-env COMPLING_AS_LIB=yes oak-cli make:domain", + "make:locale": "oak-cli make:locale -m", + "make:dep": "oak-cli make:dependency", + "clean:cache": "rimraf node_modules/.cache", + "copy-config-json": "copyfiles -u 1 src/config/*.json lib/", + "start:mp": "oak-cli start --target mp --mode development", + "start:mp:prod": "oak-cli start --target mp --mode development --prod", + "build:mp:staging": "oak-cli build --target mp --mode staging", + "build-analyze:mp:staging": "oak-cli build --target mp --mode staging --analyze", + "build:mp": "oak-cli build --target mp --mode production", + "build-analyze:mp": "oak-cli build --target mp --mode production --analyze", + "start:web": "oak-cli start --target web --mode development", + "start:web:prod": "oak-cli start --target web --mode development --prod", + "start:native": "oak-cli start --target rn --mode development", + "start:native:prod": "oak-cli start --target rn --mode development --prod", + "build:web:staging": "oak-cli build --target web --mode staging", + "build-analyze:web:staging": "oak-cli build --target web --mode staging --analyze", + "build:web": "oak-cli build --target web --mode production", + "build-analyze:web": "oak-cli build --target web --mode production --analyze", + "build-sourcemap-analyze:web": "oak-cli build --target web --mode production --sourcemap --analyze", + "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && npm run copy-config-json", + "prebuild": "npm run make:locale", + "run:ios": "oak-cli run -p ios", + "run:android": "oak-cli run -p android", + "server:init": "cross-env NODE_ENV=development cross-env OAK_PLATFORM=server node scripts/initServer.js", + "server:start": "cross-env NODE_ENV=development cross-env OAK_PLATFORM=server node scripts/startServer.js", + "postinstall": "npm run make:dep" + }, + "keywords": [], + "author": "", + "license": "", + "typings": "typings/index.d.ts", + "dependencies": { + "@ant-design/cssinjs": "^1.16.2", + "@ant-design/icons": "^5.2.6", + "@react-native-async-storage/async-storage": "^1.19.8", + "@react-native-masked-view/masked-view": "^0.3.0", + "@react-navigation/bottom-tabs": "^6.5.11", + "@react-navigation/native": "^6.1.9", + "@react-navigation/stack": "^6.3.20", + "@wangeditor/basic-modules": "^1.1.3", + "@wangeditor/editor": "^5.1.14", + "@wangeditor/editor-for-react": "^1.0.4", + "antd": "^5.8.3", + "antd-mobile": "^5.32.0", + "antd-mobile-icons": "^0.3.0", + "classnames": "^2.3.1", + "crypto-browserify": "^3.12.0", + "crypto-js": "^4.1.1", + "dayjs": "^1.11.5", + "echarts": "^5.3.0", + "echarts-for-react": "^3.0.2", + "history": "^5.3.0", + "hmacsha1": "^1.0.0", + "js-base64": "^3.7.2", + "lodash": "^4.17.21", + "nprogress": "^0.2.0", + "oak-backend-base": "file:../oak-backend-base", + "oak-common-aspect": "file:../oak-common-aspect", + "oak-db": "file:../oak-db", + "oak-domain": "file:../oak-domain", + "oak-external-sdk": "file:../oak-external-sdk", + "oak-frontend-base": "file:../oak-frontend-base", + "oak-memory-tree-store": "file:../oak-memory-tree-store", + "oak-general-business": "file:../oak-general-business", + "react": "^18.2.0", + "react-dom": "^18.1.0", + "react-image-gallery": "^1.2.11", + "react-native": "0.72.7", + "react-native-exception-handler": "^2.10.10", + "react-native-gesture-handler": "^2.14.0", + "react-native-localize": "^3.0.4", + "react-native-quick-base64": "^2.0.7", + "react-native-quick-crypto": "^0.6.1", + "react-native-reanimated": "^3.5.4", + "react-native-safe-area-context": "^4.7.4", + "react-native-screens": "^3.27.0", + "react-native-url-polyfill": "^2.0.0", + "react-responsive": "^9.0.0-beta.10", + "react-router-dom": "^6.4.0", + "react-slick": "^0.29.0", + "rmc-pull-to-refresh": "^1.0.13", + "slick-carousel": "^1.8.1", + "uuid": "^8.3.2" + }, + "devDependencies": { + "@babel/cli": "^7.12.13", + "@babel/core": "^7.12.13", + "@babel/plugin-proposal-class-properties": "^7.12.13", + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", + "@babel/preset-env": "^7.12.13", + "@babel/preset-typescript": "^7.12.13", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3", + "@react-native/metro-config": "^0.72.11", + "@svgr/webpack": "^5.5.0", + "@testing-library/jest-dom": "^5.16.4", + "@testing-library/react": "^13.3.0", + "@testing-library/user-event": "^13.5.0", + "@tsconfig/react-native": "^3.0.0", + "@types/assert": "^1.5.6", + "@types/crypto-js": "^4.1.1", + "@types/fs-extra": "^9.0.13", + "@types/isomorphic-fetch": "^0.0.36", + "@types/jest": "^27.5.2", + "@types/lodash": "^4.14.179", + "@types/luxon": "^2.3.2", + "@types/mocha": "^8.2.0", + "@types/node": "^20.10.2", + "@types/nprogress": "^0.2.0", + "@types/react": "^18.0.12", + "@types/react-dom": "^18.0.5", + "@types/react-image-gallery": "^1.2.0", + "@types/shelljs": "^0.8.11", + "@types/urlsafe-base64": "^1.0.28", + "@types/uuid": "^8.3.0", + "@types/wechat-miniprogram": "^3.4.0", + "@xuchangzju/oak-cli": "file:../oak-cli", + "assert": "^2.0.0", + "babel-jest": "^27.4.2", + "babel-loader": "^8.2.3", + "babel-plugin-named-asset-import": "^0.3.8", + "babel-plugin-module-resolver": "^5.0.0", + "babel-preset-react-app": "^10.0.1", + "bfj": "^7.0.2", + "browserify-zlib": "^0.2.0", + "browserslist": "^4.18.1", + "camelcase": "^6.2.1", + "case-sensitive-paths-webpack-plugin": "^2.4.0", + "chalk": "^4.1.2", + "clean-webpack-plugin": "^4.0.0", + "copy-webpack-plugin": "^10.2.4", + "copyfiles": "^2.4.1", + "cross-env": "^7.0.3", + "css-loader": "^6.6.0", + "css-minimizer-webpack-plugin": "^3.2.0", + "dotenv": "^10.0.0", + "dotenv-expand": "^5.1.0", + "dotenv-webpack": "^7.1.0", + "ensure-posix-path": "^1.1.1", + "eslint": "^8.3.0", + "eslint-config-react-app": "^7.0.1", + "eslint-webpack-plugin": "^3.1.1", + "file-loader": "^6.2.0", + "fs-extra": "^10.0.0", + "globby": "^11.1.0", + "html-webpack-plugin": "^5.5.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.4.3", + "jest-resolve": "^27.4.2", + "jest-watch-typeahead": "^1.0.0", + "less": "^4.1.2", + "less-loader": "^10.2.0", + "metro-react-native-babel-preset": "0.76.8", + "mini-css-extract-plugin": "^2.5.3", + "miniprogram-api-typings": "^3.4.5", + "mocha": "^8.2.1", + "postcss": "^8.4.4", + "postcss-flexbugs-fixes": "^5.0.2", + "postcss-less": "^6.0.0", + "postcss-loader": "^6.2.1", + "postcss-normalize": "^10.0.1", + "postcss-preset-env": "^7.0.1", + "progress": "^2.0.3", + "progress-bar-webpack-plugin": "^2.1.0", + "prompts": "^2.4.2", + "react-app-polyfill": "^3.0.0", + "react-dev-utils": "^12.0.1", + "react-refresh": "^0.11.0", + "required-path": "^1.0.1", + "resolve": "^1.20.0", + "resolve-url-loader": "^4.0.0", + "sass-loader": "^12.3.0", + "semver": "^7.3.5", + "shelljs": "^0.8.5", + "source-map-loader": "^3.0.0", + "style-loader": "^3.3.1", + "stylelint": "^14.4.0", + "stylelint-config-standard": "^25.0.0", + "stylelint-webpack-plugin": "^3.1.1", + "tailwindcss": "^3.0.2", + "terser-webpack-plugin": "^5.2.5", + "ts-loader": "^9.3.0", + "ts-node": "^10.9.1", + "tsc-alias": "^1.8.2", + "tslib": "^2.4.0", + "typescript": "^5.2.2", + "ui-extract-webpack-plugin": "^1.0.0", + "web-vitals": "^2.1.4", + "webpack": "^5.86.0", + "webpack-dev-server": "^4.15.1", + "webpack-manifest-plugin": "^4.0.2", + "workbox-webpack-plugin": "^6.4.1" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "copyWebpack": [] +} \ No newline at end of file diff --git a/src/aspects/AspectDict.ts b/src/aspects/AspectDict.ts new file mode 100644 index 00000000..e6b900fc --- /dev/null +++ b/src/aspects/AspectDict.ts @@ -0,0 +1,6 @@ +import { BackendRuntimeContext } from '../context/BackendRuntimeContext'; +import { EntityDict } from '@oak-app-domain'; + +export type AspectDict = { + test: (params: string, context: BackendRuntimeContext) => Promise; +}; diff --git a/src/aspects/index.ts b/src/aspects/index.ts new file mode 100644 index 00000000..39a46825 --- /dev/null +++ b/src/aspects/index.ts @@ -0,0 +1,12 @@ +import { AspectDict } from './AspectDict'; +import { test } from './sample'; + +const aspectDict = { + test, +} as AspectDict; + +export default aspectDict; +export { + AspectDict, +}; + diff --git a/src/aspects/sample.ts b/src/aspects/sample.ts new file mode 100644 index 00000000..d4f1cd2f --- /dev/null +++ b/src/aspects/sample.ts @@ -0,0 +1,6 @@ +import { EntityDict } from '@oak-app-domain'; +import { BackendRuntimeContext } from '../context/BackendRuntimeContext'; + +export async function test(params: string, context: BackendRuntimeContext) { + return 'hello world'; +} diff --git a/src/checkers/index.ts b/src/checkers/index.ts new file mode 100644 index 00000000..32fb152d --- /dev/null +++ b/src/checkers/index.ts @@ -0,0 +1,9 @@ +import { EntityDict } from '@oak-app-domain'; +import { Checker } from 'oak-domain/lib/types'; +import { RuntimeCxt } from '../types/RuntimeCxt'; + +const checkers = [ + +] as Checker[]; + +export default checkers; diff --git a/src/checkers/store.ts b/src/checkers/store.ts new file mode 100644 index 00000000..14606669 --- /dev/null +++ b/src/checkers/store.ts @@ -0,0 +1,33 @@ +import { EntityDict } from '@oak-app-domain'; +import { Checker } from 'oak-domain/lib/types'; +import { RuntimeCxt } from '../types/RuntimeCxt'; +import { checkAttributesNotNull } from 'oak-domain/lib/utils/validator'; +import { CreateOperationData as CreateStoreData } from '@oak-app-domain/Store/Schema'; + +export const checkers: Checker[] = [ + { + type: 'data', + action: 'create', + entity: 'store', + checker: (data, context) => { + if (data instanceof Array) { + data.forEach((ele) => { + checkAttributesNotNull('store', data, [ + 'coordinate', + 'name', + 'addrDetail', + 'areaId', + ]); + }); + } else { + checkAttributesNotNull('store', data, [ + 'coordinate', + 'name', + 'addrDetail', + 'areaId', + ]); + } + return 0; + }, + }, +]; diff --git a/src/components/AbstractComponents.ts b/src/components/AbstractComponents.ts new file mode 100644 index 00000000..75660871 --- /dev/null +++ b/src/components/AbstractComponents.ts @@ -0,0 +1,45 @@ +/** + * 抽象组件在业务层根据EntityDict的重新声明 + * by Xc 20230807 + */ + +import { EntityDict } from '@project/oak-app-domain'; + +import { TableProps, PaginationProps } from 'antd'; +import { ReactComponentProps, ColumnProps, RowWithActions, OakExtraActionProps, + OakAbsAttrDef, onActionFnDef, ListButtonProps, OakAbsAttrUpsertDef, ColumnMapType } from 'oak-frontend-base'; +import AbsFilterPanel from 'oak-frontend-base/es/components/filterPanel'; +import AbsList from 'oak-frontend-base/es/components/list'; +import AbsListPro from 'oak-frontend-base/es/components/listPro'; +import AbsDetail from 'oak-frontend-base/es/components/detail'; +import AbsUpsert from 'oak-frontend-base/es/components/upsert'; + +const FilterPanel = AbsFilterPanel as ( + ...props: Parameters> +) => React.ReactElement; + +const List = AbsList as ( + ...props: Parameters> +) => React.ReactElement; + +const ListPro = AbsListPro as ( + ...props: Parameters> +) => React.ReactElement; + +const Detail = AbsDetail as ( + ...props: Parameters> +) => React.ReactElement; + +const Upsert = AbsUpsert as ( + ...props: Parameters> +) => React.ReactElement; + +export { + FilterPanel, + List, + ListPro, + Detail, + Upsert, + + ReactComponentProps, ColumnProps, RowWithActions, OakExtraActionProps, OakAbsAttrDef, onActionFnDef, +} diff --git a/src/config/connector.ts b/src/config/connector.ts new file mode 100644 index 00000000..2efef79e --- /dev/null +++ b/src/config/connector.ts @@ -0,0 +1,9 @@ +import SimpleConnector from 'oak-domain/lib/utils/SimpleConnector'; +import accessConfiguration from '@project/configuration/access'; +import { makeException } from '@project/types/Exception'; +import { EntityDict } from '@project/oak-app-domain'; +import FrontendRuntimeContext from '@project/context/FrontendRuntimeContext'; + +const connector = new SimpleConnector(accessConfiguration, makeException); + +export default connector; \ No newline at end of file diff --git a/src/config/constants.ts b/src/config/constants.ts new file mode 100644 index 00000000..75ad8976 --- /dev/null +++ b/src/config/constants.ts @@ -0,0 +1 @@ +export const DATA_SUBSCRIBER_KEYS = {}; \ No newline at end of file diff --git a/src/config/message.ts b/src/config/message.ts new file mode 100644 index 00000000..213c0702 --- /dev/null +++ b/src/config/message.ts @@ -0,0 +1 @@ +export const MessageTypes = {}; diff --git a/src/config/styles/mp/index.less b/src/config/styles/mp/index.less new file mode 100644 index 00000000..f5b74250 --- /dev/null +++ b/src/config/styles/mp/index.less @@ -0,0 +1,2 @@ +//小程序使用 +@import "oak-frontend-base/es/config/styles/mp/index.less"; diff --git a/src/config/styles/mp/mixins.less b/src/config/styles/mp/mixins.less new file mode 100644 index 00000000..e9be3cc0 --- /dev/null +++ b/src/config/styles/mp/mixins.less @@ -0,0 +1,7 @@ +// 解决全屏幕机型底部适配问题 +.safe-area-inset-bottom() { + padding-bottom: constant(safe-area-inset-bottom) !important; + /* 兼容 iOS < 11.2 */ + padding-bottom: env(safe-area-inset-bottom) !important; + /* 兼容 iOS >= 11.2 */ +} \ No newline at end of file diff --git a/src/config/styles/web/index.less b/src/config/styles/web/index.less new file mode 100644 index 00000000..eb01491f --- /dev/null +++ b/src/config/styles/web/index.less @@ -0,0 +1 @@ +@import 'oak-frontend-base/es/config/styles/web/index.less'; // 少量公共样式 \ No newline at end of file diff --git a/src/configuration/access.dev.ts b/src/configuration/access.dev.ts new file mode 100644 index 00000000..4e09c440 --- /dev/null +++ b/src/configuration/access.dev.ts @@ -0,0 +1,10 @@ +import { AccessConfiguration } from 'oak-domain/lib/types/Configuration'; + +const accessConfiguration: AccessConfiguration = { + http: { + hostname: 'localhost', + port: 3001, + }, +}; + +export default accessConfiguration; diff --git a/src/configuration/access.prod.ts b/src/configuration/access.prod.ts new file mode 100644 index 00000000..ebadff4a --- /dev/null +++ b/src/configuration/access.prod.ts @@ -0,0 +1,11 @@ +import { AccessConfiguration } from 'oak-domain/lib/types/Configuration'; +import devConfiguration from './access.dev'; +const accessConfiguration: AccessConfiguration = { + http: { + hostname: 'www.oak-framework.test', + ssl: true, + path: 'oak-api', // 配置在nginx中的映射 + }, +}; + +export default process.env.NODE_ENV === 'development' ? devConfiguration : accessConfiguration; diff --git a/src/configuration/access.ts b/src/configuration/access.ts new file mode 100644 index 00000000..7cdf47a3 --- /dev/null +++ b/src/configuration/access.ts @@ -0,0 +1,3 @@ +import accessConfiguration from './access.dev'; +export default accessConfiguration; +console.log('不应该跑到这里'); \ No newline at end of file diff --git a/src/configuration/attrUpdateMatrix.ts b/src/configuration/attrUpdateMatrix.ts new file mode 100644 index 00000000..1e6e4a5a --- /dev/null +++ b/src/configuration/attrUpdateMatrix.ts @@ -0,0 +1,15 @@ +import { AttrUpdateMatrix } from 'oak-domain/lib/types/EntityDesc'; +import { EntityDict } from '@project/oak-app-domain'; + + +const attrUpdateMatrix: AttrUpdateMatrix = { + store: { + name: { + filter: { + iState: 'offline', + }, + }, + }, +} + +export default attrUpdateMatrix; \ No newline at end of file diff --git a/src/configuration/cache.ts b/src/configuration/cache.ts new file mode 100644 index 00000000..730d9fb9 --- /dev/null +++ b/src/configuration/cache.ts @@ -0,0 +1,4 @@ +import { EntityDict } from '@project/oak-app-domain'; +const cacheSavedEntities: (keyof EntityDict)[] = []; + +export default cacheSavedEntities; diff --git a/src/configuration/dependency.ts b/src/configuration/dependency.ts new file mode 100644 index 00000000..15a01cb8 --- /dev/null +++ b/src/configuration/dependency.ts @@ -0,0 +1,3 @@ +import { DependencyConfiguration } from 'oak-domain/lib/types/Configuration'; +const dependencyConfiguration: DependencyConfiguration = ["oak-general-business"]; +export default dependencyConfiguration; \ No newline at end of file diff --git a/src/configuration/index.ts b/src/configuration/index.ts new file mode 100644 index 00000000..d902eb75 --- /dev/null +++ b/src/configuration/index.ts @@ -0,0 +1,19 @@ +/** + * index中汇总了前端启动需要的引用配置 + */ +import attrUpdateMatrix from './attrUpdateMatrix'; +import { CommonConfiguration } from 'oak-domain/lib/types/Configuration'; +import { actionDefDict } from '@project/oak-app-domain/ActionDefDict'; +import { selectFreeEntities, authDeduceRelationMap, updateFreeDict } from './relation'; +import cacheSavedEntities from './cache'; +import { EntityDict } from '@project/oak-app-domain'; + +export default { + attrUpdateMatrix, + actionDefDict, + authDeduceRelationMap, + selectFreeEntities, + updateFreeDict, + cacheSavedEntities, + // cacheKeepFreshPeriod: 600 * 1000, // cache默认对缓存对象的刷新间隔时长(在这个间隔内不刷新) +} as CommonConfiguration; \ No newline at end of file diff --git a/src/configuration/relation.ts b/src/configuration/relation.ts new file mode 100644 index 00000000..d577ef2f --- /dev/null +++ b/src/configuration/relation.ts @@ -0,0 +1,19 @@ +import { AuthDeduceRelationMap, SelectFreeEntities, UpdateFreeDict } from 'oak-domain/lib/types/Entity'; +import { EntityDict } from '@project/oak-app-domain'; + +// 此对象所标识的entity的权限由其外键指向的父对象判定 +export const authDeduceRelationMap: AuthDeduceRelationMap = { +}; + +export const selectFreeEntities = [ + 'payChannel', +]; + +export const updateFreeDict: UpdateFreeDict = { +}; + +export default { + authDeduceRelationMap, + selectFreeEntities, + updateFreeDict, +}; \ No newline at end of file diff --git a/src/configuration/render.ts b/src/configuration/render.ts new file mode 100644 index 00000000..2956820c --- /dev/null +++ b/src/configuration/render.ts @@ -0,0 +1,7 @@ +import { RenderConfiguration } from 'oak-domain/lib/types/Configuration'; +import { styleDict } from '@project/oak-app-domain/StyleDict'; +import { EntityDict } from '@project/oak-app-domain'; + +export default { + styleDict, +} as RenderConfiguration; diff --git a/src/configuration/server.ts b/src/configuration/server.ts new file mode 100644 index 00000000..4af294d1 --- /dev/null +++ b/src/configuration/server.ts @@ -0,0 +1,13 @@ +import { ServerConfiguration } from 'oak-domain/lib/types/Configuration'; +import { EntityDict } from '@project/oak-app-domain'; +import { BackendRuntimeContext } from '@project/context/BackendRuntimeContext'; +import { join } from 'path'; + +const serverConfiguration: ServerConfiguration = { + database: require('../../configuration/mysql.json'), + workDir: { + path: join(__dirname, '..', '..'), + }, +}; + +export default serverConfiguration; diff --git a/src/context/BackendRuntimeContext.ts b/src/context/BackendRuntimeContext.ts new file mode 100644 index 00000000..e52e6bff --- /dev/null +++ b/src/context/BackendRuntimeContext.ts @@ -0,0 +1,12 @@ +import { EntityDict } from '@project/oak-app-domain'; +import { RuntimeContext } from './RuntimeContext'; +import { BackendRuntimeContext as DependentBackendRuntimeContext } from './DependentContext'; + +export class BackendRuntimeContext extends DependentBackendRuntimeContext implements RuntimeContext { + async toString() { + const data = await this.getSerializedData(); + return JSON.stringify(data); + } +}; + +export default BackendRuntimeContext; \ No newline at end of file diff --git a/src/context/DependentContext.ts b/src/context/DependentContext.ts new file mode 100644 index 00000000..28487359 --- /dev/null +++ b/src/context/DependentContext.ts @@ -0,0 +1 @@ +export { BackendRuntimeContext, FrontendRuntimeContext } from "oak-general-business"; \ No newline at end of file diff --git a/src/context/FrontendRuntimeContext.ts b/src/context/FrontendRuntimeContext.ts new file mode 100644 index 00000000..40e97f93 --- /dev/null +++ b/src/context/FrontendRuntimeContext.ts @@ -0,0 +1,17 @@ +import { EntityDict } from '@project/oak-app-domain'; +import { + FrontendRuntimeContext as DependentFrontendRuntimeContext, +} from './DependentContext'; +import { RuntimeContext } from './RuntimeContext'; + +export class FrontendRuntimeContext + extends DependentFrontendRuntimeContext + implements RuntimeContext +{ + async toString() { + const data = await this.getSerializedData(); + return JSON.stringify(data); + } +} + +export default FrontendRuntimeContext; \ No newline at end of file diff --git a/src/context/RuntimeContext.ts b/src/context/RuntimeContext.ts new file mode 100644 index 00000000..c08cf469 --- /dev/null +++ b/src/context/RuntimeContext.ts @@ -0,0 +1,5 @@ + +/** + * 若业务逻辑需要更多的上下文之间的数据传递,可以放在这里 + */ +export interface RuntimeContext {} diff --git a/src/data/actionAuth.ts b/src/data/actionAuth.ts new file mode 100644 index 00000000..3bafae47 --- /dev/null +++ b/src/data/actionAuth.ts @@ -0,0 +1,8 @@ +import { CreateOperationData as ActionAuth } from '@oak-app-domain/ActionAuth/Schema'; + + +const actionAuths: ActionAuth[] = [ + +]; + +export default actionAuths; diff --git a/src/data/i18n.ts b/src/data/i18n.ts new file mode 100644 index 00000000..4ed525c1 --- /dev/null +++ b/src/data/i18n.ts @@ -0,0 +1,5 @@ +// 本文件为自动编译产生,请勿直接修改 + +import { CreateOperationData as I18n } from "../oak-app-domain/I18n/Schema"; +const i18ns: I18n[] = []; +export default i18ns; \ No newline at end of file diff --git a/src/data/index.ts b/src/data/index.ts new file mode 100644 index 00000000..510e8ec3 --- /dev/null +++ b/src/data/index.ts @@ -0,0 +1,13 @@ +import { relations } from '@project/oak-app-domain/Relation'; +import actionAuth from './actionAuth'; +import relationAuth from './relationAuth'; +import path from './path'; +import i18n from './i18n'; + +export default { + relation: relations, + actionAuth, + relationAuth, + path, + i18n, +}; diff --git a/src/data/path.ts b/src/data/path.ts new file mode 100644 index 00000000..5e459cfa --- /dev/null +++ b/src/data/path.ts @@ -0,0 +1,5 @@ +import { CreateOperationData as Path } from '@oak-app-domain/Path/Schema'; + +const paths: Path[] = []; + +export default paths; diff --git a/src/data/relationAuth.ts b/src/data/relationAuth.ts new file mode 100644 index 00000000..0ae57eda --- /dev/null +++ b/src/data/relationAuth.ts @@ -0,0 +1,8 @@ +import { CreateOperationData as RelationAuth } from '@oak-app-domain/RelationAuth/Schema'; + + +const relationAuths: RelationAuth[] = [ + +] + +export default relationAuths; \ No newline at end of file diff --git a/src/entities/Order.ts b/src/entities/Order.ts new file mode 100644 index 00000000..4a8fae95 --- /dev/null +++ b/src/entities/Order.ts @@ -0,0 +1,121 @@ +import { + String, + Text, + Price, + Boolean, + Datetime, +} from 'oak-domain/lib/types/DataType'; +import { EntityShape } from 'oak-domain/lib/types/Entity'; +import { EntityDesc, ActionDef } from 'oak-domain/lib/types'; + +export interface Schema extends EntityShape { + price: Price; + paid: Price; + refunded: Price; + title: String<32>; + desc: String<64>; + timeoutAt: Datetime; +}; + +type IAction = 'startPaying' | 'payAll' | 'payPartially' | 'payNone' | 'timeout' | 'cancel' | 'startRefunding' | 'refundAll' | 'refundPartially' | 'refundNone'; +type IState = 'paid' | 'unPaid' | 'timeout' | 'cancelled' | 'paying' | 'partiallyPaid' | 'paid' | 'refunding' | 'partiallyRefunded' | 'refunded'; + +export const IActionDef: ActionDef = { + stm: { + startPaying: ['unPaid', 'paying'], + payAll: [['unPaid', 'paying', 'partiallyPaid'], 'paid'], + payPartially: [['unPaid', 'paying'], 'partiallyPaid'], + payNone: ['paying', 'unPaid'], + timeout: ['unPaid', 'timeout'], + cancel: ['unPaid', 'cancelled'], + startRefunding: [['paid', 'partiallyPaid'], 'refunding'], + refundAll: [['paid', 'refunding', 'partiallyPaid', 'partiallyRefunded'], 'refunded'], + refundPartially: [['paid', 'refunding', 'partiallyPaid', 'partiallyRefunded'], 'partiallyRefunded'], + refundNone: ['refunding', 'paid'], + + }, + is: 'unPaid', +}; +type Action = IAction; + +export const entityDesc: EntityDesc = { + indexes: [ + //索引 + { + name: 'index_iState', + attributes: [ + { + name: 'iState', + }, + ], + }, + ], + locales: { + zh_CN: { + name: '订单', + attr: { + price: '订单金额', + paid: '已支付金额', + refunded: '已退款金额', + iState: '订单状态', + title: '订单标题', + desc: "订单描述", + timeoutAt: '过期时间' + }, + action: { + startPaying: '开始支付', + payAll: '全部支付', + payPartially: '部分支付', + payNone: '支付失败', + timeout: '过期', + cancel: '放弃', + startRefunding: '开始退款', + refundAll: '完全退款', + refundNone: '退款失败', + refundPartially: '部分退款', + }, + v: { + iState: { + paid: '已付款', + partiallyPaid: '部分支付', + paying: '支付中', + unPaid: '待付款', + timeout: '已超时', + cancelled: '已取消', + refunded: '已退款', + partiallyRefunded: '已部分退款', + refunding: '退款中', + }, + } + }, + }, + style: { + icon: { + startPaying: '', + payAll: '', + payPartially: '', + payNone: '', + timeout: '', + cancel: '', + startRefunding: '', + refundAll: '', + refundNone: '', + refundPartially: '', + }, + color: { + iState: { + unPaid: '#52BE80', + partiallyPaid: '#5DADE2', + cancelled: '#D6DBDF', + paid: '#2E86C1', + paying: '#D2B4DE', + timeout: '#2C3E50', + refunded: '#BA4A00', + partiallyRefunded: '#EDBB99', + refunding: '#FBEEE6' + }, + } + } +}; diff --git a/src/entities/Pay.ts b/src/entities/Pay.ts new file mode 100644 index 00000000..8d95b245 --- /dev/null +++ b/src/entities/Pay.ts @@ -0,0 +1,125 @@ +import { + String, + Text, + Price, + Boolean, + Datetime, +} from 'oak-domain/lib/types/DataType'; +import { EntityShape } from 'oak-domain/lib/types/Entity'; +import { EntityDesc, ActionDef } from 'oak-domain/lib/types'; +import { Schema as Order } from './Order'; +import { Schema as PayChannel } from './PayChannel'; + +export interface Schema extends EntityShape { + price: Price; + paid: Price; + refunded: Price; + order: Order; + channel: PayChannel; + timeoutAt: Datetime; + forbidRefundAt?: Datetime; +}; + +type IAction = 'startPaying' | 'payAll' | 'payPartially' | 'payNone' | 'timeout' | 'cancel' | 'startRefunding' | 'refundAll' | 'refundPartially' | 'refundNone'; +type IState = 'paid' | 'unPaid' | 'timeout' | 'cancelled' | 'paying' | 'partiallyPaid' | 'paid' | 'refunding' | 'partiallyRefunded' | 'refunded'; + + +export const IActionDef: ActionDef = { + stm: { + startPaying: ['unPaid', 'paying'], + payAll: [['unPaid', 'paying', 'partiallyPaid'], 'paid'], + payPartially: [['unPaid', 'paying'], 'partiallyPaid'], + payNone: ['paying', 'unPaid'], + timeout: ['unPaid', 'timeout'], + cancel: ['unPaid', 'cancelled'], + startRefunding: [['paid', 'partiallyPaid'], 'refunding'], + refundAll: [['paid', 'refunding', 'partiallyPaid', 'partiallyRefunded'], 'refunded'], + refundPartially: [['paid', 'refunding', 'partiallyPaid', 'partiallyRefunded'], 'partiallyRefunded'], + refundNone: ['refunding', 'paid'], + }, + is: 'unPaid', +}; +type Action = IAction; + +export const entityDesc: EntityDesc = { + indexes: [ + //索引 + { + name: 'index_iState', + attributes: [ + { + name: 'iState', + }, + ], + }, + ], + locales: { + zh_CN: { + name: '订单', + attr: { + price: '订单金额', + paid: '已支付金额', + refunded: '已退款金额', + iState: '支付状态', + channel: '支付渠道', + order: '所属订单', + timeoutAt: '过期时间', + forbidRefundAt: '停止退款时间', + }, + action: { + startPaying: '开始支付', + payAll: '全部支付', + payPartially: '部分支付', + payNone: '支付失败', + timeout: '过期', + cancel: '放弃', + startRefunding: '开始退款', + refundAll: '完全退款', + refundNone: '退款失败', + refundPartially: '部分退款', + }, + v: { + iState: { + paid: '已付款', + partiallyPaid: '部分支付', + paying: '支付中', + unPaid: '待付款', + timeout: '已超时', + cancelled: '已取消', + refunded: '已退款', + partiallyRefunded: '已部分退款', + refunding: '退款中', + }, + } + }, + }, + style: { + icon: { + startPaying: '', + payAll: '', + payPartially: '', + payNone: '', + timeout: '', + cancel: '', + startRefunding: '', + refundAll: '', + refundNone: '', + refundPartially: '', + }, + color: { + iState: { + unPaid: '#52BE80', + partiallyPaid: '#5DADE2', + cancelled: '#D6DBDF', + paid: '#2E86C1', + paying: '#D2B4DE', + timeout: '#2C3E50', + refunded: '#BA4A00', + partiallyRefunded: '#EDBB99', + refunding: '#FBEEE6' + }, + } + } +}; diff --git a/src/entities/PayChannel.ts b/src/entities/PayChannel.ts new file mode 100644 index 00000000..278f7e6e --- /dev/null +++ b/src/entities/PayChannel.ts @@ -0,0 +1,41 @@ +import { + String, + Text, + Price, + Boolean, + Datetime, +} from 'oak-domain/lib/types/DataType'; +import { EntityShape } from 'oak-domain/lib/types/Entity'; +import { EntityDesc, ActionDef } from 'oak-domain/lib/types'; + +export interface Schema extends EntityShape { + name: String<16>; + code: String<16>; + svg: Text; +}; + +export const entityDesc: EntityDesc = { + locales: { + zh_CN: { + name: '支付通道', + attr: { + name: '名称', + code: '代号', + svg: 'svg', + } + }, + }, + indexes: [ + { + name: 'code_uniqe', + attributes: [ + { + name: 'code', + } + ], + config: { + unique: true, + }, + }, + ], +}; diff --git a/src/exceptionHandler.ts b/src/exceptionHandler.ts new file mode 100644 index 00000000..ba441802 --- /dev/null +++ b/src/exceptionHandler.ts @@ -0,0 +1,59 @@ +import { + OakException, + OakUnloggedInException, + OakUserUnpermittedException, + OakAttrNotNullException, + OakInputIllegalException, +} from 'oak-domain/lib/types/Exception'; +import { + ExampleException, +} from '@project/types/Exception'; +import { FeatureDict } from '@project/features'; +import { AFD } from '@project/types/RuntimeCxt'; + +/** + * 构造backUrl + * @param location + * @param encode + * @returns + */ + +export const handler = async (reason: any, features: AFD) => { + if (reason instanceof OakException) { + if (reason instanceof OakUnloggedInException) { + // await features.token.logout(); + features.navigator.navigateTo( + { + url: '/login', + }, + { isGoBack: true }, + true + ); + } else if (reason instanceof OakInputIllegalException) { + features.message.setMessage({ + content: reason.message, + type: 'error', + }); + } else if (reason instanceof OakAttrNotNullException) { + features.message.setMessage({ + content: reason.message, + type: 'error', + }); + } else if (reason instanceof ExampleException) { + console.log('在此处理ExampleException'); + } else { + console.warn(reason); + features.message.setMessage({ + content: reason.message, + type: 'error', + }); + } + return true; + } + console.error(reason); + features.message.setMessage({ + content: reason.message, + type: 'error', + }); + return false; +}; diff --git a/src/features/Console.ts b/src/features/Console.ts new file mode 100644 index 00000000..7853304f --- /dev/null +++ b/src/features/Console.ts @@ -0,0 +1,26 @@ +import { EntityDict } from '@project/oak-app-domain'; +import { Feature } from 'oak-frontend-base'; +import { Cache } from 'oak-frontend-base/es/features/cache'; + +type IMode = 'systemProvider' | 'store'; // 控制台的访问模式,一般是业务的顶层结点对象 + +export default class Console extends Feature { + private cache: Cache; + + constructor(cache: Cache) { + super(); + this.cache = cache; + } + + getMode(allowUninitialized?: boolean): IMode { + return 'systemProvider'; + } + + async initialize() { + + } + + async destroy() { + + } +} \ No newline at end of file diff --git a/src/features/Menu.ts b/src/features/Menu.ts new file mode 100644 index 00000000..3c5dd206 --- /dev/null +++ b/src/features/Menu.ts @@ -0,0 +1,99 @@ +import { EntityDict } from '@project/oak-app-domain'; +import { Feature } from 'oak-frontend-base'; +import { ContextMenuFactory } from 'oak-frontend-base/es/features/contextMenuFactory'; +import Console from './Console'; + +type GroupName = 'System'; + +type Groups = { + icon: string; + name: GroupName; +}[]; + +interface IMenu { + name: string; + icon: string; + url: string; + entity?: T; + paths?: string[]; + action?: EntityDict[T]['Action']; + parent?: GroupName; +}; + +export interface OMenu { + name: GroupName | string; + icon: string; + url?: string; + children?: Array; +}; + + +const groups: Groups = [ + { + name: 'System', // 系统级别配置 + icon: 'setup_fill', + }, +]; + +const menus: IMenu[] = [ + { + name: 'Dashboard', + icon: 'document', + url: '', + }, + { + name: 'relationManage', + icon: 'share', + url: '/relation/entityList', + parent: 'System', + entity: 'relation', + action: 'create', + paths: [], + }, +]; + +export default class Menu extends Feature { + private contextMenuFactory: ContextMenuFactory; + private console: Console; + private menus?: OMenu[]; + + constructor( + contextMenuFactory: ContextMenuFactory, + console: Console + ) { + super(); + this.contextMenuFactory = contextMenuFactory; + this.contextMenuFactory.setMenus(menus); + this.console = console; + this.console.subscribe( + () => { + this.refreshMenus(); + } + ); + } + + refreshMenus() { + /* const roomId = this.console.getRoomId(); + const menus = this.contextMenuFactory.getMenusByContext>('room', roomId); + const menuGroup = groupBy(menus, 'parent'); + this.menus = (menus as any[]).filter(ele => !ele.parent).concat( + groups.map((ele) => { + const { name, icon } = ele; + const children = menuGroup[name]; + return { + name, + icon, + children, + }; + }).filter((ele) => !!ele.children) + ); + this.publish(); */ + } + + getMenus() { + if (!this.menus) { + this.refreshMenus(); + } + return this.menus; + } +} diff --git a/src/features/Sample.ts b/src/features/Sample.ts new file mode 100644 index 00000000..1c68e3d0 --- /dev/null +++ b/src/features/Sample.ts @@ -0,0 +1,26 @@ +import { EntityDict } from '@oak-app-domain'; +import { BasicFeatures, Feature } from 'oak-frontend-base'; + +type DoSthAcion = { + type: 'doSth'; + payload: { + args: string; + }; +}; + +export default class Sample extends Feature { + get(params: any) { + throw new Error('Method not implemented.'); + } + action(action: DoSthAcion) { + throw new Error('Method not implemented.'); + } + cache: BasicFeatures['cache']; + + constructor( + cache: BasicFeatures['cache'] + ) { + super(); + this.cache = cache; + } +} diff --git a/src/features/index.ts b/src/features/index.ts new file mode 100644 index 00000000..762a66fb --- /dev/null +++ b/src/features/index.ts @@ -0,0 +1,20 @@ +import { EntityDict } from '@project/oak-app-domain'; +import { BasicFeatures } from 'oak-frontend-base'; +import Sample from './Sample'; +import Console from './Console'; +import Menu from './Menu'; +import { FeatureDict as Ogb0FeatureDict } from "oak-general-business"; +export function create(features: BasicFeatures & Ogb0FeatureDict) { + const { cache, contextMenuFactory, } = features; + const sample = new Sample(cache); + const console = new Console(cache); + const menu = new Menu(contextMenuFactory, console); + return { + sample, + console, + menu, + }; +} +export type FeatureDict = ReturnType; +export async function initialize(features: FeatureDict & BasicFeatures & Ogb0FeatureDict) { +} \ No newline at end of file diff --git a/src/hooks/useFeatures.ts b/src/hooks/useFeatures.ts new file mode 100644 index 00000000..33613e96 --- /dev/null +++ b/src/hooks/useFeatures.ts @@ -0,0 +1,9 @@ +import { useFeatures as useCommonFeatures } from 'oak-frontend-base/es/platforms/web'; +import { AFD } from '@project/types/RuntimeCxt'; + +// react 独有 +// 这里因为开发时要引用src,而AFD定义中引用lib,所以有编译的warning. by Xc +export default function useFeatures() { + // @ts-ignore + return useCommonFeatures() +}; \ No newline at end of file diff --git a/src/initialize.ts b/src/initialize.ts new file mode 100644 index 00000000..34c4a48d --- /dev/null +++ b/src/initialize.ts @@ -0,0 +1,4 @@ +import initialize from './initialize.dev'; +export default initialize; + +console.log('不应该走到这里'); diff --git a/src/locales/common/zh_CN.json b/src/locales/common/zh_CN.json new file mode 100644 index 00000000..2562132f --- /dev/null +++ b/src/locales/common/zh_CN.json @@ -0,0 +1,49 @@ +{ + "ptrActivate": "松开刷新", + "ptrDeactivate": "下拉刷新", + "ptrRelease": "正在刷新...", + "ptrFinish": "刷新完成", + "noData": "暂无数据", + "areYouSure": "请确认", + "action": { + "create": "创建", + "update": "更新", + "delete": "删除", + "remove": "删除", + "cancel": "取消", + "grant": "授权", + "revoke": "回收", + "tip": "提示", + "detail": "详情", + "editor": "编辑", + "newAdd": "新增", + "add": "添加", + "commit": "提交", + "save": "保存", + "upload": "上传", + "import": "导入" + }, + "confirm": "确定", + "submit": "提交", + "reset": "重置", + "select": "查询", + "expand": "展开", + "shrink": "收起", + "back": "返回", + "$$createAt$$": "创建时间", + "$$updateAt$$": "更新时间", + "$$deleteAt$$": "删除时间", + "$$seq$$": "序号", + "message": "消息", + "more": "更多", + "view": "查看", + "scan": "扫一扫", + "bind": "绑定", + "true": "是", + "false": "否", + "open": "开", + "close": "关", + "enter": "请输入", + "change": "修改", + "finish": "完成" +} diff --git a/src/page.mp.ts b/src/page.mp.ts new file mode 100644 index 00000000..9add80d7 --- /dev/null +++ b/src/page.mp.ts @@ -0,0 +1 @@ +export { createComponent } from 'oak-frontend-base/es/page.mp'; \ No newline at end of file diff --git a/src/page.native.ts b/src/page.native.ts new file mode 100644 index 00000000..038039d7 --- /dev/null +++ b/src/page.native.ts @@ -0,0 +1 @@ +export { createComponent } from 'oak-frontend-base/es/page.native'; \ No newline at end of file diff --git a/src/page.ts b/src/page.ts new file mode 100644 index 00000000..772c56f0 --- /dev/null +++ b/src/page.ts @@ -0,0 +1,2 @@ +// for 编译 +export { createComponent } from 'oak-frontend-base/es/page.web'; \ No newline at end of file diff --git a/src/page.web.ts b/src/page.web.ts new file mode 100644 index 00000000..62ab72c8 --- /dev/null +++ b/src/page.web.ts @@ -0,0 +1 @@ +export { createComponent } from 'oak-frontend-base/es/page.web'; \ No newline at end of file diff --git a/src/ports/index.ts b/src/ports/index.ts new file mode 100644 index 00000000..ad04b686 --- /dev/null +++ b/src/ports/index.ts @@ -0,0 +1,15 @@ +import { Importation, Exportation } from "oak-domain/lib/types/Port"; +import { EntityDict } from "@oak-app-domain"; +import { BackendRuntimeContext } from '../context/BackendRuntimeContext'; + + +export const importations: Importation< + EntityDict, + keyof EntityDict, + any, + BackendRuntimeContext +>[] = []; + +export const exportations = [ + +] as Exportation[]; diff --git a/src/routines/start.ts b/src/routines/start.ts new file mode 100644 index 00000000..286de5db --- /dev/null +++ b/src/routines/start.ts @@ -0,0 +1,28 @@ +import { Routine } from 'oak-domain/lib/types/Timer'; +import { EntityDict } from '@oak-app-domain'; +import { BackendRuntimeContext } from '../context/BackendRuntimeContext'; + + +const startRoutines: Array> = [ + { + name: '示例性routine', + entity: 'extraFile', + filter: { + uploadState: 'uploading', + }, + projection: { + id: 1, + uploadMeta: 1, + uploadState: 1, + entity: 1, + entityId: 1, + objectId: 1, + }, + fn: async (context, data) => { + console.log('示例性routine执行,请在src/routine/start.ts中关闭'); + return context.opResult; + }, + }, +]; + +export default startRoutines; diff --git a/src/timers/index.ts b/src/timers/index.ts new file mode 100644 index 00000000..eface0d5 --- /dev/null +++ b/src/timers/index.ts @@ -0,0 +1,30 @@ +import { Timer } from 'oak-domain/lib/types/Timer'; +import { EntityDict } from '@oak-app-domain'; +import { BackendRuntimeContext } from '../context/BackendRuntimeContext'; + +const timers: Array> = [ + { + name: '示例timer', + cron: '30 * * * * *', + entity: 'extraFile', + filter: { + uploadState: 'uploading', + }, + projection: { + id: 1, + uploadMeta: 1, + uploadState: 1, + entity: 1, + entityId: 1, + objectId: 1, + }, + fn: async (context, data) => { + console.log( + '这是示例timer程序,每30秒执行一次,请在src/timer/index中关闭' + ); + return context.opResult; + }, + }, +]; + +export default timers; diff --git a/src/triggers/index.ts b/src/triggers/index.ts new file mode 100644 index 00000000..f4a0d0a0 --- /dev/null +++ b/src/triggers/index.ts @@ -0,0 +1,10 @@ +import { EntityDict } from '@oak-app-domain'; +import { Trigger } from 'oak-domain/lib/types'; +import { BackendRuntimeContext } from '../context/BackendRuntimeContext'; + + +const triggers = [ + +] as Trigger[]; + +export default triggers; diff --git a/src/types/DependentExceptions.ts b/src/types/DependentExceptions.ts new file mode 100644 index 00000000..fa3a45e0 --- /dev/null +++ b/src/types/DependentExceptions.ts @@ -0,0 +1,13 @@ +import { EntityDict } from '@project/oak-app-domain'; +import { SelectOpResult } from 'oak-domain/lib/types/Entity'; +import { makeException as makeDomainException } from 'oak-domain/lib/types/Exception'; +import { makeException as makeOgb0Exception } from "oak-general-business"; +export default function makeException(data: { + name: string; + message?: string; + opRecords: SelectOpResult; + [A: string]: any; +}) { + const e = makeDomainException(data) || makeOgb0Exception(data); + return e; +} \ No newline at end of file diff --git a/src/types/Exception.ts b/src/types/Exception.ts new file mode 100644 index 00000000..2a65bf9e --- /dev/null +++ b/src/types/Exception.ts @@ -0,0 +1,30 @@ +import { OakException, OakUserException } from 'oak-domain/lib/types'; +import { EntityDict } from '@oak-app-domain'; +import makeDepedentException from './DependentExceptions'; + +export class ExampleException extends OakException {}; + +export class ConsoleModeIllegalException extends OakException {}; + +export class ConsoleLoadingDataException extends OakException {}; + +export class ExistsNewBidException extends OakUserException {}; + +export function makeException(msg: string | object) { + const data = typeof msg === 'string' ? JSON.parse(msg) : msg; + + const exception = makeDepedentException(data); + if (exception) { + return exception; + } + + const { name, message } = data; + switch (name) { + case 'ExampleException': { + return new ExampleException(message); + } + default: { + throw new OakException(`不可解读的exception信息「${msg}」`); + } + } +} diff --git a/src/types/RuntimeCxt.ts b/src/types/RuntimeCxt.ts new file mode 100644 index 00000000..e8d8e97d --- /dev/null +++ b/src/types/RuntimeCxt.ts @@ -0,0 +1,12 @@ +import { AspectDict } from "@project/aspects/AspectDict"; +import { FeatureDict } from "@project/features"; +import { EntityDict } from "@project/oak-app-domain"; +import { BasicFeatures } from "oak-frontend-base"; +import { BackendRuntimeContext } from "@project/context/BackendRuntimeContext"; +import { FrontendRuntimeContext } from "@project/context/FrontendRuntimeContext"; +import { FeatureDict as Ogb0FeatureDict, AspectDict as Ogb0AspectDict } from "oak-general-business"; +type BRC = BackendRuntimeContext; +type FRC = FrontendRuntimeContext; +export type RuntimeCxt = FRC | BRC; +export type AAD = AspectDict & Ogb0AspectDict; +export type AFD = FeatureDict & BasicFeatures & Ogb0FeatureDict; \ No newline at end of file diff --git a/src/watchers/index.ts b/src/watchers/index.ts new file mode 100644 index 00000000..30bcf040 --- /dev/null +++ b/src/watchers/index.ts @@ -0,0 +1,11 @@ +import { Watcher } from 'oak-domain/lib/types'; +import { EntityDict } from '@oak-app-domain'; +import { BackendRuntimeContext } from '../context/BackendRuntimeContext'; + +const watchers = [] as Watcher< + EntityDict, + keyof EntityDict, + BackendRuntimeContext +>[]; + +export default watchers; diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 00000000..a8a14bcb --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,37 @@ +{ + "extends": "./tsconfig.build.paths.json", + "compilerOptions": { + "jsx": "react-jsx", + "module": "commonjs", + "target": "esnext", + "allowJs": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "skipLibCheck": true, + "strict": true, + "importHelpers": true, + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "outDir": "lib", /* Redirect output structure to the directory. */ + "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "types": [ + // "node", + // "wechat-miniprogram" + // ], + "resolveJsonModule": true + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts", + "test", + "src/pages/**/*", + "src/components/**/*" + ] +} \ No newline at end of file diff --git a/tsconfig.build.paths.json b/tsconfig.build.paths.json new file mode 100644 index 00000000..9570f41c --- /dev/null +++ b/tsconfig.build.paths.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "baseUrl": "./", + "paths": { + "@project/*": [ + "src/*" + ], + "@oak-app-domain": [ + "src/oak-app-domain/index" + ], + "@oak-app-domain/*": [ + "src/oak-app-domain/*" + ], + }, + "typeRoots": ["./typings"] + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..7b638cc7 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,44 @@ +{ + "extends": "./tsconfig.paths.json", + "compilerOptions": { + "jsx": "react-jsx", + "module": "commonjs", + "target": "es5", + "allowJs": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "skipLibCheck": true, + "strict": true, + "importHelpers": true, + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + //"outDir": "lib", /* Redirect output structure to the directory. */ + //"rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "types": [ + "node", + "wechat-miniprogram" + ], + "resolveJsonModule": true + }, + "include": [ + "./src/**/*.js", + "./src/**/*.ts", + "./src/**/*.tsx", + "./web/src/**/*.ts", + "./web/src/**/*.tsx", + "./wechatMp/src/**/*.js", + "./wechatMp/src/**/*.ts", + "./typings/*.d.ts" + ], + "exclude": [ + "node_modules", + "**/*.spec.ts", + "test", + "scripts", + "lib" + ] +} \ No newline at end of file diff --git a/tsconfig.mp.json b/tsconfig.mp.json new file mode 100644 index 00000000..9fde24ee --- /dev/null +++ b/tsconfig.mp.json @@ -0,0 +1,45 @@ +{ + "extends": "./tsconfig.paths.json", + "compilerOptions": { + "module": "ESNext", + "target": "ESNext", + "allowJs": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "strict": true, + "downlevelIteration": true, + "importHelpers": true, + "moduleResolution": "Node", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + // "outDir": "lib", /* Redirect output structure to the directory. */ + // "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "types": [ + "node", + "wechat-miniprogram" + ], + "resolveJsonModule": true, + "jsx": "react" + }, + "include": [ + "./src/**/*.js", + "./src/**/*.ts", + "./wechatMp/src/**/*.js", + "./wechatMp/src/**/*.ts", + "./typings/*.d.ts" + ], + "exclude": [ + "node_modules", + "scripts", + "test", + "**/*.spec.ts", + "**/*.test.ts", + "**/*.test.tsx", + "./web", + "./native" + ] +} \ No newline at end of file diff --git a/tsconfig.paths.json b/tsconfig.paths.json new file mode 100644 index 00000000..2b37be54 --- /dev/null +++ b/tsconfig.paths.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "baseUrl": "./", + "paths": { + "@project/*": [ + "src/*" + ], + "@oak-app-domain": [ + "src/oak-app-domain/index" + ], + "@oak-app-domain/*": [ + "src/oak-app-domain/*" + ], + }, + "typeRoots": ["./typings"] + } +} \ No newline at end of file diff --git a/tsconfig.web.json b/tsconfig.web.json new file mode 100644 index 00000000..3931296f --- /dev/null +++ b/tsconfig.web.json @@ -0,0 +1,47 @@ +{ + "extends": "./tsconfig.paths.json", + "compilerOptions": { + "module": "ESNext", + "target": "ESNext", + "allowJs": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "importHelpers": true, + "strict": true, + "moduleResolution": "Node", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + // "outDir": "lib", /* Redirect output structure to the directory. */ + // "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + "types": [ + "node", + "wechat-miniprogram", + "react" + ], + "resolveJsonModule": true, + "jsx": "react" + }, + "include": [ + "./src/**/*.js", + "./src/**/*.ts", + "./src/**/*.tsx", + "./web/src/**/*.js", + "./web/src/**/*.ts", + "./web/src/**/*.tsx", + "./typings/*.d.ts" + ], + "exclude": [ + "node_modules", + "scripts", + "test", + "**/*.spec.ts", + "**/*.test.ts", + "**/*.test.tsx", + "./wechatMp", + "./native" + ] +} \ No newline at end of file diff --git a/typings/index.d.ts b/typings/index.d.ts new file mode 100644 index 00000000..a471ae47 --- /dev/null +++ b/typings/index.d.ts @@ -0,0 +1,5 @@ +/// + + +declare global { +} \ No newline at end of file diff --git a/typings/polyfill.d.ts b/typings/polyfill.d.ts new file mode 100644 index 00000000..d91f05dc --- /dev/null +++ b/typings/polyfill.d.ts @@ -0,0 +1,13 @@ +import { MakeOakComponent } from 'oak-frontend-base'; +import { EntityDict } from '@oak-app-domain'; +import { AspectDict } from '@project/aspects/AspectDict'; +import { FeatureDict } from '@project/features'; +import { BackendRuntimeContext } from '@project/context/BackendRuntimeContext'; +import { FrontendRuntimeContext } from '@project/context/FrontendRuntimeContext'; +import { FeatureDict as Ogb0FeatureDict } from "oak-general-business/es/features"; +import { AspectDict as Ogb0AspectDict } from "oak-general-business/es/aspects"; +declare global { + const OakComponent: MakeOakComponent, FeatureDict & Ogb0FeatureDict>; + const features: FeatureDict & Ogb0FeatureDict; +} +export {}; \ No newline at end of file diff --git a/typings/react-app-env.d.ts b/typings/react-app-env.d.ts new file mode 100644 index 00000000..f5056a92 --- /dev/null +++ b/typings/react-app-env.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file