cli 模版文件调整

This commit is contained in:
Wang Kejun 2022-07-23 09:03:51 +08:00
parent 5defc25061
commit 7bee9b5f45
63 changed files with 926 additions and 587 deletions

5
template/.gitignore vendored
View File

@ -61,6 +61,7 @@ out
# Nuxt.js build / generate output
.nuxt
dist
build
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
@ -86,5 +87,5 @@ dist
.pnp.*
package-lock.json
src/wechatMp/dist
oak-app-domain
oak-app-domain
*/public/locales

View File

@ -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,
},
};
};

View File

@ -1,6 +1,21 @@
import { GeneralRuntimeContext } from 'oak-general-business';
import { EntityDict } from 'oak-app-domain';
import { RowStore } from 'oak-domain/lib/types';
export class RuntimeContext extends GeneralRuntimeContext<EntityDict> {
}
static FromCxtStr(cxtStr?: string) {
const { token, applicationId, scene } = cxtStr
? GeneralRuntimeContext.fromString(cxtStr)
: {
token: undefined,
applicationId: undefined,
scene: undefined,
};
return (store: RowStore<EntityDict, RuntimeContext>) => {
const context = new RuntimeContext(store, applicationId);
context.setScene(scene);
context.setToken(token);
return context;
};
}
}

View File

@ -0,0 +1,7 @@
import { RuntimeContext } from "../RuntimeContext";
import { AspectDict as GeneralAspectDict } from 'oak-general-business/src/aspects/AspectDict';
import { EntityDict } from "oak-app-domain";
export type AspectDict = {
test: (params: string, context: RuntimeContext) => Promise<any>;
} & GeneralAspectDict<EntityDict, RuntimeContext>;

View File

@ -1,14 +1,13 @@
import { Aspect } from 'oak-domain/lib/types';
import { aspectDict as GeneralAspectDict } from 'oak-general-business';
import { test } from './sample';
import { aspectDict as generalAspectDict } from 'oak-general-business';
import { AspectDict as GeneralAspectDict } from 'oak-general-business/src/aspects/AspectDict';
import { AspectDict } from './AspectDict';
import { EntityDict } from 'oak-app-domain';
import { RuntimeContext } from '../RuntimeContext';
import { test } from './sample';
const aspectDict = Object.assign({
const aspectDict = {
test,
}, GeneralAspectDict as Record<keyof typeof GeneralAspectDict, Aspect<EntityDict, RuntimeContext>>);
...generalAspectDict,
} as AspectDict & GeneralAspectDict<EntityDict, RuntimeContext>;
export {
aspectDict,
}
export { aspectDict };

View File

@ -1,7 +1,14 @@
import { EntityDict } from 'oak-app-domain';
import { Checker } from 'oak-domain/lib/types';
import { checkers as GeneralCheckers } from 'oak-general-business';
import { processCheckers } from 'oak-general-business/src/utils/check';
import { checkers as generalCheckers } from 'oak-general-business';
import { RuntimeContext } from '../RuntimeContext';
import { checkers as houseCheckers } from './house';
export const checkers = [...houseCheckers, ...GeneralCheckers] as Checker<EntityDict, keyof EntityDict, RuntimeContext>[];
const checkers = [...houseCheckers, ...generalCheckers] as Checker<
EntityDict,
keyof EntityDict,
RuntimeContext
>[];
processCheckers(checkers);
export { checkers };

View File

@ -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',
},
},
},
},
},
};

View File

@ -1,6 +1,9 @@
import { CreateOperationData as Application } from 'oak-app-domain/Application/Schema';
import { DEV_SYSTEM_ID } from './system';
const DEV_WECHATMP_APPLICATION_ID = 'MY_DEV_WECHATMP_APPLICATION_ID';
import {
DEV_SYSTEM_ID,
DEV_WECHATMP_APPLICATION_ID,
DEV_WEB_APPLICATION_ID,
} from 'oak-general-business';
import Config from '../config';
export const applications: Application[] = [
@ -15,5 +18,15 @@ export const applications: Application[] = [
appSecret: Config.weChatMp.appSecret,
},
description: '小程序应用指向dev_system',
}
];
},
{
id: DEV_WEB_APPLICATION_ID,
name: 'devWeb',
type: 'web',
systemId: DEV_SYSTEM_ID,
config: {
type: 'web',
},
description: 'web应用指向dev_system',
},
];

View File

@ -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,
},
];

View File

@ -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,
};

View File

@ -1,11 +1,13 @@
import { CreateOperationData as System } from 'oak-app-domain/System/Schema';
export const DEV_SYSTEM_ID = 'MY_DEV_SYSTEM_ID';
import { DEV_SYSTEM_ID } from 'oak-general-business';
import Config from '../config';
export const systems: System[] = [
{
id: DEV_SYSTEM_ID,
name: 'develop',
description: '开发用的system',
config: {},
}
];
name: Config.System.develop.name,
description: Config.System.develop.description,
config: Config.System.develop.config,
},
];

View File

@ -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;

View File

@ -1,14 +1,26 @@
import { EntityDict } from 'oak-app-domain';
import { BasicFeatures } from 'oak-frontend-base';
import { CommonAspectDict } from 'oak-common-aspect';
import * as Sample from './Sample';
import { aspectDict } from '../aspects';
import { AspectDict } from '../aspects/AspectDict';
import { RuntimeContext } from '../RuntimeContext';
import { GeneralRuntimeContext } from 'oak-general-business';
import { AspectWrapper } from 'oak-domain/lib/types';
export function initialize(basicFeatures: BasicFeatures<EntityDict, RuntimeContext, typeof aspectDict>) {
export function initialize(
aspectWrapper: AspectWrapper<
EntityDict,
RuntimeContext,
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
>,
basicFeatures: BasicFeatures<
EntityDict,
RuntimeContext,
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
>
) {
const { cache } = basicFeatures;
const sample = new Sample.Sample(cache);
const sample = new Sample.Sample(aspectWrapper, cache);
return {
sample,

View File

@ -0,0 +1,88 @@
import './utils/polyfill';
import { initialize as init } from 'oak-frontend-base/src/initialize.dev';
import { EntityDict, storageSchema, ActionDefDict } from 'oak-app-domain';
import { CommonAspectDict } from 'oak-common-aspect';
import { RuntimeContext } from './RuntimeContext';
import { initialize as initializeGeneralFeatures } from 'oak-general-business/src/features';
import { initialize as initializeFeatures } from './features';
import { data } from './data';
import { routers } from './exceptionRouters';
import { checkers } from './checkers';
// dev需要将下面内容也传入
import { AspectDict } from './aspects/AspectDict';
import { aspectDict } from './aspects';
import { triggers } from './triggers';
import { watchers } from './watchers';
import { AspectWrapper } from 'oak-domain/lib/types';
import { BasicFeatures } from 'oak-frontend-base';
import { AppType } from 'oak-app-domain/Application/Schema';
export default function initialize(type: AppType, url?: string) {
let wholeFeatures = {};
const createFeatures = (
aspectWrapper: AspectWrapper<
EntityDict,
RuntimeContext,
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
>,
basicFeatures: BasicFeatures<
EntityDict,
RuntimeContext,
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
>,
context: RuntimeContext
) => {
const { token, extraFile, application } = initializeGeneralFeatures<
EntityDict,
RuntimeContext,
AspectDict
>(aspectWrapper, basicFeatures, type, context);
const features = initializeFeatures(aspectWrapper, basicFeatures);
const features2 = Object.assign(
{
token,
extraFile,
application,
},
features
);
Object.assign(wholeFeatures, features2, basicFeatures);
return features2;
};
const { i18n } = init<
EntityDict,
RuntimeContext,
AspectDict,
ReturnType<typeof createFeatures>
>(
storageSchema,
createFeatures,
RuntimeContext.FromCxtStr,
aspectDict,
routers,
triggers,
checkers,
watchers,
data as any,
ActionDefDict,
);
return {
i18n,
features: wholeFeatures as BasicFeatures<
EntityDict,
RuntimeContext,
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
> &
ReturnType<typeof createFeatures>,
};
}

View File

@ -0,0 +1,99 @@
import './utils/polyfill';
import { initialize as init } from 'oak-frontend-base/src/initialize.prod';
import { SimpleConnector } from 'oak-domain/lib/utils/SimpleConnector';
import { AspectWrapper } from 'oak-domain/lib/types';
import { EntityDict, storageSchema, ActionDefDict } from 'oak-app-domain';
import { CommonAspectDict } from 'oak-common-aspect';
import { RuntimeContext } from './RuntimeContext';
import { initialize as initializeGeneralFeatures } from 'oak-general-business/src/features';
import { initialize as initializeFeatures } from './features';
import { routers } from './exceptionRouters';
import { checkers } from './checkers';
import { makeException } from './types/Exception';
import { AspectDict } from './aspects/AspectDict';
import { BasicFeatures } from 'oak-frontend-base';
import { AppType } from 'oak-app-domain/Application/Schema';
export default function initialize(type: AppType, url: string) {
let wholeFeatures = {};
const createFeatures = (
aspectWrapper: AspectWrapper<
EntityDict,
RuntimeContext,
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
>,
basicFeatures: BasicFeatures<
EntityDict,
RuntimeContext,
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
>,
context: RuntimeContext
) => {
const { token, extraFile, application } = initializeGeneralFeatures<
EntityDict,
RuntimeContext,
AspectDict
>(aspectWrapper, basicFeatures, type, context);
const features = initializeFeatures(aspectWrapper, basicFeatures);
const features2 = Object.assign(
{
token,
extraFile,
application,
},
features
);
Object.assign(wholeFeatures, features2, basicFeatures);
return features2;
};
let URL: string;
/**
* import initialize.prod走到这里
*/
if (type === 'wechatMp') {
// 如果是小程序需要显式传入url
const apiPath = process.env.NODE_ENV === 'development' ? '3001': '/oak-api'; // 生产环境通过路径映射增加oak-api
const protocol = process.env.NODE_ENV === 'development' ? 'http://' : 'https://';
URL = `${protocol}${url}${apiPath}/aspect`;
}
else if (process.env.NODE_ENV === 'development') {
URL = 'http://localhost:3001/aspect';
}
else {
// web和public环境只需要传相对路径
URL = `/oak-api/aspect`;
}
const connector = new SimpleConnector(URL, makeException, RuntimeContext.FromCxtStr);
const { i18n } = init<
EntityDict,
RuntimeContext,
AspectDict,
ReturnType<typeof createFeatures>
>(
storageSchema,
createFeatures,
RuntimeContext.FromCxtStr,
routers,
connector,
checkers,
ActionDefDict,
);
return {
i18n,
features: wholeFeatures as BasicFeatures<
EntityDict,
RuntimeContext,
AspectDict & CommonAspectDict<EntityDict, RuntimeContext>
> &
ReturnType<typeof createFeatures>,
};
}

View File

@ -1,40 +1,4 @@
import './utils/polyfill';
import { initializeFeatures as initializeGeneralFeatures } from 'oak-general-business';
import { BasicFeatures, } from 'oak-frontend-base';
import { EntityDict } from 'oak-app-domain';
import { RuntimeContext } from './RuntimeContext';
import { aspectDict } from './aspects';
import { initialize } from './features';
import { checkers } from './checkers';
import { watchers } from './watchers';
import { triggers } from './triggers';
import { data } from './data';
import { routers } from './exceptionRouters';
import initialize from './initialize.dev';
export default initialize;
const { token, extraFile, application } = initializeGeneralFeatures<EntityDict, RuntimeContext, typeof aspectDict>();
const createFeatures = (basicFeatures: BasicFeatures<EntityDict, RuntimeContext, typeof aspectDict>) => {
const features = initialize(basicFeatures);
const wholeFeatures = Object.assign(
{
token,
extraFile,
application,
},
features
);
return wholeFeatures;
};
export {
createFeatures,
aspectDict,
triggers,
checkers,
watchers,
data,
routers,
token,
application,
}
console.log('不应该走到这里');

View File

@ -0,0 +1,5 @@
/** index.wxss **/
.container {
display: flex;
}

View File

@ -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: {
},
});

View File

@ -0,0 +1,11 @@
import * as React from 'react';
export default function render() {
const { t } = this;
const { searchValue } = this.state;
return (
<div style={{ height: '100vh' }}>
</div>
);
}

View File

@ -0,0 +1,4 @@
<!--index.wxml-->
<view class="container">
</view>

View File

@ -1,7 +1,10 @@
import { triggers as generalTriggers } from 'oak-general-business';
import { triggers as houseTriggers } from './house';
import { triggers as GenenralTriggers } from 'oak-general-business';
import { Trigger } from 'oak-domain/lib/types';
import { EntityDict } from 'oak-app-domain';
import { RuntimeContext } from '../RuntimeContext';
export const triggers = [...houseTriggers, ...GenenralTriggers] as Trigger<EntityDict, keyof EntityDict, RuntimeContext>[];
export const triggers = [
...houseTriggers,
...generalTriggers,
] as Trigger<EntityDict, keyof EntityDict, RuntimeContext>[];

View File

@ -1,3 +1,23 @@
import { OakException } from "oak-domain/lib/types";
import { OakException } from 'oak-domain/lib/types';
import { makeException as makeGeneralException } from 'oak-general-business/lib/types/Exceptions';
export class ExampleException extends OakException {};
export class ExampleException extends OakException {}
export function makeException(msg: string | object) {
const data = typeof msg === 'string' ? JSON.parse(msg) : msg;
const exception = makeGeneralException(data);
if (exception) {
return exception;
}
const { name, message } = data;
switch (name) {
case ExampleException.name: {
return new ExampleException(message);
}
default: {
throw new OakException(`不可解读的exception信息「${msg}`);
}
}
}

View File

@ -1,6 +1,43 @@
import { GenerateIdOption } from '../utils/polyfill';
import { MakeOakComponent, MakeOakPage } from 'oak-frontend-base/src/page.mp';
import {
MakeOakComponent as MakeOakWebComponent,
MakeOakPage as MakeOakWebPage,
} from 'oak-frontend-base/src/page.web';
import { EntityDict } from 'oak-app-domain';
import { RuntimeContext } from '../RuntimeContext';
import { aspectDict } from '../aspects';
import { initialize } from '../initialize';
declare global {
const generateNewId: () => Promise<string>;
const __DEV__: boolean;
const generateNewId: (option?: GenerateIdOption) => Promise<string>;
const getRandomValues: (length: number) => Promise<Uint8Array>;
const OakPage:
| MakeOakPage<
EntityDict,
RuntimeContext,
typeof aspectDict,
ReturnType<typeof initialize>['features']
>
| MakeOakWebPage<
EntityDict,
RuntimeContext,
typeof aspectDict,
ReturnType<typeof initialize>['features']
>;
const OakComponent:
| MakeOakComponent<
EntityDict,
RuntimeContext,
typeof aspectDict,
ReturnType<typeof initialize>['features']
>
| MakeOakWebComponent<
EntityDict,
RuntimeContext,
typeof aspectDict,
ReturnType<typeof initialize>['features']
>;
}
export {}
export {};

View File

@ -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, {

View File

@ -0,0 +1,10 @@
import { watchers as generalWatchers } from 'oak-general-business';
import { Watcher } from 'oak-domain/lib/types';
import { EntityDict } from 'oak-app-domain';
import { RuntimeContext } from '../RuntimeContext';
export const watchers = [...generalWatchers] as Watcher<
EntityDict,
keyof EntityDict,
RuntimeContext
>[];

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@ -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"
}

View File

@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@ -0,0 +1,3 @@
@import 'tdesign-react/es/style/index.css'; // 少量公共样式
@import 'tdesign-mobile-react/es/style/index.css'; // 少量公共样式

View File

@ -0,0 +1,9 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

49
template/web/src/App.tsx Normal file
View File

@ -0,0 +1,49 @@
import React from 'react';
import { Routes, Route } from 'react-router-dom';
import './App.less';
import LazyLoad from './utils/lazyLoad';
const Console = LazyLoad(() => import('./template/console'));
const Frontend = LazyLoad(() => import('./template/frontend'));
const NotFound = LazyLoad(() => import('./template/notFound'));
const Message = LazyLoad(() =>import('@oak-general-business/components/message'));
type Router = {
path: string;
element: ReturnType<typeof LazyLoad>;
title: string;
}
function getRoutes(routers2: Router[], namespace?: string) {
return routers2.map((router, index) => {
const { path, element } = router;
return (
<Route
key={`route_${namespace ? `${namespace}_` : ''}${index}`}
path={path}
element={element}
></Route>
);
});
}
// routers非常重要不能删除
let routers: Router[] = [];
function App() {
return (
<React.Fragment>
{Message}
<Routes>
<Route path="/console" element={Console}>
{getRoutes(routers, 'console')}
</Route>
<Route path="/" element={Frontend}>
{getRoutes(routers)}
</Route>
<Route path="*" element={NotFound} />
</Routes>
</React.Fragment>
);
}
export default App;

31
template/web/src/app.json Normal file
View File

@ -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"
]
}

View File

@ -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;
}

View File

@ -0,0 +1,43 @@
import './utils/polyfill';
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { I18nextProvider } from 'react-i18next';
import './index.less';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { ResponsiveProvider } from 'oak-frontend-base/src/platforms/web/responsive';
import { getAppType } from './utils/env';
import initialize from '../../src/initialize';
const appType = getAppType();
const { features, i18n } = initialize(appType, window.location.hostname);
Object.assign(global, {
features,
})
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
features.application.getApplication()
.then(
() => {
root.render(
// <React.StrictMode>
<BrowserRouter>
<I18nextProvider i18n={i18n as any}>
<ResponsiveProvider>
<App />
</ResponsiveProvider>
</I18nextProvider>
</BrowserRouter>
// </React.StrictMode>
);
}
)
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

1
template/web/src/react-app-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="react-scripts" />

View File

@ -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;

View File

@ -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';

View File

@ -0,0 +1,28 @@
import React from 'react';
import { useNavigate, useParams, useSearchParams, useLocation } from 'react-router-dom';
import { Routes, Route, Outlet } from 'react-router-dom';
// function Console() {
// const n = useNavigate();
// const d = useParams();
// const [search, setSearch] = useSearchParams();
// const id = search.get('id');
// const l = useLocation();
// console.log(d, id, l);
// return <div onClick={() => {
// n('', { state: { name: '212' } })
// }}>console</div>;
// }
// export default Console;
function Console() {
return (
<Outlet />
);
}
export default Console;

View File

@ -0,0 +1,10 @@
import React from 'react';
import { useNavigate, useParams, useSearchParams, useLocation } from 'react-router-dom';
import { Outlet, Route } from 'react-router-dom';
function Frontend() {
return <Outlet />;
}
export default Frontend;

View File

@ -0,0 +1,8 @@
import React from 'react';
const NotFound = () => {
return <div></div>;
};
export default NotFound;

View File

@ -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

View File

@ -0,0 +1,6 @@
export function getAppType() {
if (/MicroMessenger/i.test(window.navigator.userAgent)) {
return 'wechatPublic';
}
return 'web';
}

View File

@ -0,0 +1,13 @@
import React from "react";
import Loading from './Loading';
const LazyLoad = (factory: () => Promise<{ default: any }>) => {
const Component = React.lazy(factory);
return (
<React.Suspense fallback={<Loading />}>
<Component />
</React.Suspense>
);
};
export default LazyLoad;

View File

@ -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);
},
});

View File

@ -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;
}

View File

@ -1,4 +1,12 @@
import { features } from './init';
import './utils/polyfill';
import initialize from '../../src/initialize';
/**
* 访domain和system的关系来判定appId
*/
const url = 'localhost';
const { features } = initialize('wechatMp', url);
export interface IAppOption {
globalData: {
@ -11,7 +19,9 @@ App<IAppOption>({
features,
},
async onLaunch() {
await features.token.loginWechatMp('app:onLaunch');
// 等application初始化完成后进行登录
await features.application.getApplication();
features.token.loginWechatMp();
},
onHide() {

View File

@ -1,3 +0,0 @@
{
"component": true
}

View File

@ -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;
}

View File

@ -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,
});
};
},
},
});

View File

@ -1,11 +0,0 @@
<!-- index.wxml -->
<view class="t-message t-class {{'t-message-'+type}} {{status?'t-message-show':''}}" style="z-index:{{zIndex}};top:{{top}}rpx">
<block wx:if="{{status}}">
<view style="margin-right:15rpx">
<slot name="icon" />
</view>
<image wx:if="{{image}}" src="{{image}}" class="t-message-image t-class-image t-image-class" />
{{content}}
<slot />
</block>
</view>

View File

@ -1,5 +0,0 @@
export default {
fallbackLocale: 'zh-CN',
defaultLocale: 'zh-CN',
translations: {},
};

View File

@ -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()
}

View File

@ -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';
// 每个应用都要初始化applicationIdgeneralbusiness的要求
const applicationId = data.application[0].id;
const { OakComponent, OakPage, features } = InitializeWechatMp<EntityDict, RuntimeContext, typeof aspectDict, ReturnType<typeof createFeatures>>(
storageSchema,
createFeatures,
(store, scene) => new RuntimeContext(store, applicationId, () => token.getToken(), scene),
routers,
triggers,
checkers,
watchers,
aspectDict,
data as any,
ActionDefDict);
// 因为依赖的问题general库中的部分feature暂时只能在这里注入。以后再修改
token.setCache(features.cache);
application.setCache(features.cache);
application.setApplicationId(applicationId);
Object.assign(global, {
OakPage,
OakComponent,
});
export {
features,
createFeatures,
};

View File

@ -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;
}

View File

@ -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
})
}
})

View File

@ -1,23 +0,0 @@
<!--index.wxml-->
<view class="container">
<view class="userinfo">
<block wx:if="{{canIUseOpenData}}">
<view class="userinfo-avatar" bindtap="bindViewTap">
<open-data type="userAvatarUrl"></open-data>
</view>
<open-data type="userNickName"></open-data>
</block>
<block wx:elif="{{!hasUserInfo}}">
<button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 获取头像昵称 </button>
<button wx:elif="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 获取头像昵称 </button>
<view wx:else> 请使用1.4.4及以上版本基础库 </view>
</block>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
</view>

View File

@ -1,11 +1,21 @@
import { MakeOakComponent, MakeOakPage } from 'oak-frontend-base';
import { EntityDict } from 'oak-app-domain/EntityDict';
import { MakeOakComponent, MakeOakPage } from 'oak-frontend-base/src/page.mp';
import { EntityDict } from 'oak-app-domain';
import { RuntimeContext } from '../../../src/RuntimeContext';
import { aspectDict } from '../../../src/aspects';
import { createFeatures } from '../init';
import { initialize } from '../../../src/initialize';
declare global {
const OakPage: MakeOakPage<EntityDict, RuntimeContext, typeof aspectDict, ReturnType<typeof createFeatures>>;
const OakComponent: MakeOakComponent<EntityDict, RuntimeContext, typeof aspectDict, ReturnType<typeof createFeatures>>;
const OakPage: MakeOakPage<
EntityDict,
RuntimeContext,
typeof aspectDict,
ReturnType<typeof initialize>['features']
>;
const OakComponent: MakeOakComponent<
EntityDict,
RuntimeContext,
typeof aspectDict,
ReturnType<typeof initialize>['features']
>;
}
export {}
export {};

View File

@ -1,75 +1,76 @@
// import '../../../src/utils/polyfill';
Object.assign(global, {
/**
* wx环境下的fetch使
* @param url
* @param options
* @returns
*/
fetch: async (url: string, options?: Parameters<typeof global.fetch>[1]) => {
const params = Object.assign({
method: 'GET',
dataType: '其他',
responseType: 'text',
headers: {
'Content-type': 'application/json',
* @param url
* @param options
* @returns
*/
fetch: async (
url: string,
options?: Parameters<typeof global.fetch>[1]
) => {
const params = Object.assign(
{
method: 'GET',
headers: {
'Content-type': 'application/json',
},
},
}, options);
const { method, headers, dataType, responseType, body } = params;
let responseType2 = responseType;
if ((headers as Record<string, string>)['Accept'] === 'application/octet-stream') {
responseType2 = 'arraybuffer';
}
if (!['text', 'arraybuffer'].includes(responseType2)) {
throw new Error(`传入不支持的responseType: ${responseType2}`);
}
let dataType2 = dataType === 'json' ? dataType : '其他';
if (responseType2 === 'arraybuffer') {
dataType2 = '其他';
}
return new Promise(
(resolve, reject) => {
wx.request({
url,
data: body || {},
method: method as any,
header: headers,
dataType: dataType2 as any,
responseType: responseType2 as any,
success: (res) => {
const { statusCode, data, header } = res;
const result = Object.assign({}, res, {
status: statusCode,
ok: statusCode === 200,
headers: header,
arrayBuffer: async () => data as ArrayBuffer,
json: async () => JSON.parse(data as string),
text: async () => data as string,
clone: () => result!,
url,
statusText: statusCode === 200 ? 'ok' : 'error',
});
return resolve(result);
},
fail: reject,
});
}
options
);
const { method, headers, body } = params;
let responseType: 'arraybuffer' | 'text' | undefined;
const accept = (headers as Record<string, string>)['Accept'];
if (
[
'image/jpg',
'image/jpeg',
'image/png',
'application/octet-stream',
].includes(accept)
) {
responseType = 'arraybuffer';
} else {
responseType = 'text';
}
const dataType = '其他';
return new Promise((resolve, reject) => {
wx.request({
url,
data: body || {},
method: method as any,
header: headers,
dataType,
responseType,
success: (res) => {
const { statusCode, data, header } = res;
const result = Object.assign({}, res, {
status: statusCode,
ok: statusCode === 200,
headers: header,
arrayBuffer: async () => data as ArrayBuffer,
json: async () => JSON.parse(data as string),
text: async () => data as string,
clone: () => result!,
url,
statusText: statusCode === 200 ? 'ok' : 'error',
});
return resolve(result);
},
fail: reject,
});
});
},
getRandomValues: async function getRandomValues(length: number) {
if (length > 65536) {
throw new Error('Can only request a maximum of 65536 bytes')
throw new Error('Can only request a maximum of 65536 bytes');
}
const { randomValues } = await wx.getRandomValues({
length,
});
return new Uint8Array(randomValues);
}
,
});
},
});