create-umi 4.0.0-rc.9 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/cli.js +1 -5
  2. package/dist/index.js +30 -19
  3. package/dist/index.test.d.ts +1 -0
  4. package/dist/index.test.js +44 -0
  5. package/package.json +4 -4
  6. package/templates/app/.gitignore.tpl +1 -0
  7. package/templates/app/package.json.tpl +3 -3
  8. package/templates/app/{assets → src/assets}/yay.jpg +0 -0
  9. package/templates/app/{layouts → src/layouts}/index.less +0 -0
  10. package/templates/app/{layouts → src/layouts}/index.tsx.tpl +0 -0
  11. package/templates/app/{pages → src/pages}/docs.tsx +0 -0
  12. package/templates/app/{pages → src/pages}/index.tsx +2 -1
  13. package/templates/app/tsconfig.json.tpl +3 -0
  14. package/templates/app/typings.d.ts +1 -3
  15. package/templates/max/.gitignore.tpl +11 -0
  16. package/templates/max/.npmrc.tpl +1 -0
  17. package/templates/max/.prettierignore.tpl +3 -0
  18. package/templates/max/.prettierrc.tpl +8 -0
  19. package/templates/max/.umirc.ts.tpl +35 -0
  20. package/templates/max/README.md +3 -0
  21. package/templates/max/mock/userAPI.ts +20 -0
  22. package/templates/max/package.json.tpl +23 -0
  23. package/templates/max/src/access.ts +10 -0
  24. package/templates/max/src/app.ts +16 -0
  25. package/templates/max/src/assets/.gitkeep +0 -0
  26. package/templates/max/src/components/Guide/Guide.less +4 -0
  27. package/templates/max/src/components/Guide/Guide.tsx +23 -0
  28. package/templates/max/src/components/Guide/index.ts +2 -0
  29. package/templates/max/src/constants/index.ts +1 -0
  30. package/templates/max/src/models/global.ts +13 -0
  31. package/templates/max/src/pages/Access/index.tsx +20 -0
  32. package/templates/max/src/pages/Home/index.less +3 -0
  33. package/templates/max/src/pages/Home/index.tsx +17 -0
  34. package/templates/max/src/pages/Table/components/CreateForm.tsx +26 -0
  35. package/templates/max/src/pages/Table/components/UpdateForm.tsx +138 -0
  36. package/templates/max/src/pages/Table/index.tsx +270 -0
  37. package/templates/max/src/services/demo/UserController.ts +96 -0
  38. package/templates/max/src/services/demo/index.ts +7 -0
  39. package/templates/max/src/services/demo/typings.d.ts +68 -0
  40. package/templates/max/src/utils/format.ts +4 -0
  41. package/templates/max/tsconfig.json +3 -0
  42. package/templates/max/typings.d.ts +1 -0
  43. package/templates/vue-app/.gitignore.tpl +11 -0
  44. package/templates/vue-app/.npmrc.tpl +1 -0
  45. package/templates/vue-app/.umirc.ts.tpl +4 -0
  46. package/templates/vue-app/package.json.tpl +17 -0
  47. package/templates/vue-app/src/assets/yay.jpg +0 -0
  48. package/templates/vue-app/src/layouts/index.vue +28 -0
  49. package/templates/vue-app/src/pages/docs.vue +5 -0
  50. package/templates/vue-app/src/pages/index.vue +11 -0
  51. package/templates/vue-app/tsconfig.json.tpl +6 -0
  52. package/templates/vue-app/typings.d.ts +1 -0
  53. package/templates/app/tsconfig.json +0 -18
package/dist/cli.js CHANGED
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("@umijs/utils");
4
- const fs_1 = require("fs");
5
- const path_1 = require("path");
6
4
  const args = (0, utils_1.yParser)(process.argv.slice(2), {
7
5
  alias: {
8
6
  version: ['v'],
@@ -12,9 +10,7 @@ const args = (0, utils_1.yParser)(process.argv.slice(2), {
12
10
  });
13
11
  if (args.version && !args._[0]) {
14
12
  args._[0] = 'version';
15
- const local = (0, fs_1.existsSync)((0, path_1.join)(__dirname, '../.local'))
16
- ? utils_1.chalk.cyan('@local')
17
- : '';
13
+ const local = (0, utils_1.isLocalDev)() ? utils_1.chalk.cyan('@local') : '';
18
14
  const { name, version } = require('../package.json');
19
15
  console.log(`${name}@${version}${local}`);
20
16
  }
package/dist/index.js CHANGED
@@ -1,13 +1,4 @@
1
1
  "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
2
  Object.defineProperty(exports, "__esModule", { value: true });
12
3
  const utils_1 = require("@umijs/utils");
13
4
  const path_1 = require("path");
@@ -21,13 +12,25 @@ const testData = {
21
12
  npmClient: 'pnpm',
22
13
  registry: 'https://registry.npmjs.org/',
23
14
  };
24
- exports.default = ({ cwd, args, }) => __awaiter(void 0, void 0, void 0, function* () {
25
- const [_, name] = args._;
15
+ exports.default = async ({ cwd, args, }) => {
16
+ const [name] = args._;
26
17
  let npmClient = 'pnpm';
27
18
  let registry = 'https://registry.npmjs.org/';
19
+ let appTemplate = 'app';
28
20
  // test ignore prompts
29
21
  if (!args.default) {
30
- const response = yield (0, utils_1.prompts)([
22
+ const response = await (0, utils_1.prompts)([
23
+ {
24
+ type: 'select',
25
+ name: 'appTemplate',
26
+ message: 'Pick Umi App Template',
27
+ choices: [
28
+ { title: 'Simple App', value: 'app' },
29
+ { title: 'Ant Design Pro', value: 'max' },
30
+ { title: 'Vue Simple App', value: 'vue-app' },
31
+ ],
32
+ initial: 0,
33
+ },
31
34
  {
32
35
  type: 'select',
33
36
  name: 'npmClient',
@@ -54,9 +57,14 @@ exports.default = ({ cwd, args, }) => __awaiter(void 0, void 0, void 0, function
54
57
  { title: 'taobao', value: 'https://registry.npmmirror.com' },
55
58
  ],
56
59
  },
57
- ]);
60
+ ], {
61
+ onCancel() {
62
+ process.exit(1);
63
+ },
64
+ });
58
65
  npmClient = response.npmClient;
59
66
  registry = response.registry;
67
+ appTemplate = response.appTemplate;
60
68
  }
61
69
  const pluginPrompts = [
62
70
  {
@@ -86,21 +94,24 @@ exports.default = ({ cwd, args, }) => __awaiter(void 0, void 0, void 0, function
86
94
  message: `Which organization is your plugin stored under github?`,
87
95
  },
88
96
  ];
97
+ const target = name ? (0, path_1.join)(cwd, name) : cwd;
98
+ const templateName = args.plugin ? 'plugin' : appTemplate;
99
+ const version = require('../package').version;
89
100
  const generator = new utils_1.BaseGenerator({
90
- path: (0, path_1.join)(__dirname, '..', 'templates', args.plugin ? 'plugin' : 'app'),
91
- target: name ? (0, path_1.join)(cwd, name) : cwd,
101
+ path: (0, path_1.join)(__dirname, '..', 'templates', templateName),
102
+ target,
92
103
  data: args.default
93
104
  ? testData
94
105
  : {
95
- version: require('../package').version,
106
+ version: version.includes('-canary.') ? version : `^${version}`,
96
107
  npmClient,
97
108
  registry,
98
109
  },
99
110
  questions: args.default ? [] : args.plugin ? pluginPrompts : [],
100
111
  });
101
- yield generator.run();
112
+ await generator.run();
102
113
  if (!args.default) {
103
114
  // install
104
- (0, utils_1.installWithNpmClient)({ npmClient });
115
+ (0, utils_1.installWithNpmClient)({ npmClient, cwd: target });
105
116
  }
106
- });
117
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("@umijs/utils");
7
+ const fs_1 = require("fs");
8
+ const path_1 = require("path");
9
+ const index_1 = __importDefault(require("./index"));
10
+ const fixtures = (0, path_1.join)(__dirname, '..', 'fixtures');
11
+ let oldCwd = process.cwd();
12
+ beforeEach(() => {
13
+ oldCwd = process.cwd();
14
+ });
15
+ afterEach(() => {
16
+ process.chdir(oldCwd);
17
+ });
18
+ test('generate app', async () => {
19
+ const cwd = (0, path_1.join)(fixtures, 'app');
20
+ await (0, index_1.default)({
21
+ cwd,
22
+ args: {
23
+ _: [],
24
+ $0: '',
25
+ default: true,
26
+ },
27
+ });
28
+ expect((0, fs_1.existsSync)((0, path_1.join)(cwd, 'src', 'pages', 'index.tsx'))).toEqual(true);
29
+ utils_1.rimraf.sync(cwd);
30
+ });
31
+ test('generate plugin', async () => {
32
+ const cwd = (0, path_1.join)(fixtures, 'plugin');
33
+ await (0, index_1.default)({
34
+ cwd,
35
+ args: {
36
+ plugin: true,
37
+ _: [],
38
+ $0: '',
39
+ default: true,
40
+ },
41
+ });
42
+ expect((0, fs_1.existsSync)((0, path_1.join)(cwd, 'src', 'index.ts'))).toEqual(true);
43
+ utils_1.rimraf.sync(cwd);
44
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-umi",
3
- "version": "4.0.0-rc.9",
3
+ "version": "4.0.0",
4
4
  "description": "create-umi",
5
5
  "homepage": "https://github.com/umijs/umi-next/tree/master/packages/create-umi#readme",
6
6
  "bugs": "https://github.com/umijs/umi-next/issues",
@@ -20,12 +20,12 @@
20
20
  ],
21
21
  "scripts": {
22
22
  "build": "pnpm tsc",
23
- "build:deps": "pnpm esno ../../scripts/bundleDeps.ts",
23
+ "build:deps": "umi-scripts bundleDeps",
24
24
  "dev": "pnpm build -- --watch",
25
- "test": "jest -c ../../jest.turbo.config.ts"
25
+ "test": "umi-scripts jest-turbo"
26
26
  },
27
27
  "dependencies": {
28
- "@umijs/utils": "4.0.0-rc.9"
28
+ "@umijs/utils": "4.0.0"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"
@@ -6,5 +6,6 @@
6
6
  /src/.umi-production
7
7
  /.umi
8
8
  /.umi-production
9
+ /.umi-test
9
10
  /dist
10
11
  /.mfsu
@@ -7,11 +7,11 @@
7
7
  "start": "npm run dev"
8
8
  },
9
9
  "dependencies": {
10
- "umi": "^{{{ version }}}"
10
+ "umi": "{{{ version }}}"
11
11
  },
12
12
  "devDependencies": {
13
- "@types/react": "^17.0.0",
14
- "@types/react-dom": "^17.0.0",
13
+ "@types/react": "^18.0.0",
14
+ "@types/react-dom": "^18.0.0",
15
15
  "typescript": "^4.1.2"
16
16
  }
17
17
  }
File without changes
File without changes
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
+ import yayJpg from '../assets/yay.jpg';
2
3
 
3
4
  export default function HomePage() {
4
5
  return (
5
6
  <div>
6
7
  <h2>Yay! Welcome to umi!</h2>
7
8
  <p>
8
- <img src={require('../assets/yay.jpg')} width="388" />
9
+ <img src={yayJpg} width="388" />
9
10
  </p>
10
11
  <p>
11
12
  To get started, edit <code>pages/index.tsx</code> and save to reload.
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "./src/.umi/tsconfig.json"
3
+ }
@@ -1,3 +1 @@
1
- declare module '*.less';
2
- declare module '*.css';
3
- declare module '*.png';
1
+ import 'umi/typings';
@@ -0,0 +1,11 @@
1
+ /node_modules
2
+ /.env.local
3
+ /.umirc.local.ts
4
+ /config/config.local.ts
5
+ /src/.umi
6
+ /src/.umi-production
7
+ /.umi
8
+ /.umi-production
9
+ /.umi-test
10
+ /dist
11
+ /.mfsu
@@ -0,0 +1 @@
1
+ registry={{{ registry }}}
@@ -0,0 +1,3 @@
1
+ node_modules
2
+ .umi
3
+ .umi-production
@@ -0,0 +1,8 @@
1
+ {
2
+ "printWidth": 80,
3
+ "singleQuote": true,
4
+ "trailingComma": "all",
5
+ "proseWrap": "never",
6
+ "overrides": [{ "files": ".prettierrc", "options": { "parser": "json" } }],
7
+ "plugins": ["prettier-plugin-organize-imports", "prettier-plugin-packagejson"]
8
+ }
@@ -0,0 +1,35 @@
1
+ import { defineConfig } from '@umijs/max';
2
+
3
+ export default defineConfig({
4
+ antd: {},
5
+ access: {},
6
+ model: {},
7
+ initialState: {},
8
+ request: {},
9
+ layout: {
10
+ title: '@umijs/max',
11
+ },
12
+ routes: [
13
+ {
14
+ path: '/',
15
+ redirect: '/home',
16
+ },
17
+ {
18
+ name: '首页',
19
+ path: '/home',
20
+ component: './Home',
21
+ },
22
+ {
23
+ name: '权限演示',
24
+ path: '/access',
25
+ component: './Access',
26
+ },
27
+ {
28
+ name: ' CRUD 示例',
29
+ path: '/table',
30
+ component: './Table',
31
+ },
32
+ ],
33
+ npmClient: '{{{ npmClient }}}',
34
+ });
35
+
@@ -0,0 +1,3 @@
1
+ # README
2
+
3
+ `@umijs/max` 模板项目,更多功能参考 [Umi Max 简介](https://next.umijs.org/zh-CN/docs/max/introduce)
@@ -0,0 +1,20 @@
1
+ const users = [
2
+ { name: 'Umi', nickName: 'U', gender: 'MALE' },
3
+ { name: 'Fish', nickName: 'B', gender: 'FEMALE' },
4
+ ];
5
+
6
+ export default {
7
+ 'GET /api/v1/queryUserList': (req: any, res: any) => {
8
+ res.json({
9
+ success: true,
10
+ data: { list: users },
11
+ errorCode: 0,
12
+ });
13
+ },
14
+ 'PUT /api/v1/user/': (req: any, res: any) => {
15
+ res.json({
16
+ success: true,
17
+ errorCode: 0,
18
+ });
19
+ },
20
+ };
@@ -0,0 +1,23 @@
1
+ {
2
+ "private": true,
3
+ "scripts": {
4
+ "dev": "max dev",
5
+ "build": "max build",
6
+ "postinstall": "max setup",
7
+ "start": "npm run dev"
8
+ },
9
+ "dependencies": {
10
+ "@ant-design/icons": "^4.7.0",
11
+ "@ant-design/pro-components": "^1.1.3",
12
+ "@umijs/max": "{{{ version }}}",
13
+ "antd": "^4.20.7"
14
+ },
15
+ "devDependencies": {
16
+ "@types/react": "^18.0.0",
17
+ "@types/react-dom": "^18.0.0",
18
+ "typescript": "^4.1.2",
19
+ "prettier": "^2",
20
+ "prettier-plugin-organize-imports": "^2",
21
+ "prettier-plugin-packagejson": "^2"
22
+ }
23
+ }
@@ -0,0 +1,10 @@
1
+ export default (initialState: API.UserInfo) => {
2
+ // 在这里按照初始化数据定义项目中的权限,统一管理
3
+ // 参考文档 https://next.umijs.org/docs/max/access
4
+ const canSeeAdmin = !!(
5
+ initialState && initialState.name !== 'dontHaveAccess'
6
+ );
7
+ return {
8
+ canSeeAdmin,
9
+ };
10
+ };
@@ -0,0 +1,16 @@
1
+ // 运行时配置
2
+
3
+ // 全局初始化数据配置,用于 Layout 用户信息和权限初始化
4
+ // 更多信息见文档:https://next.umijs.org/docs/api/runtime-config#getinitialstate
5
+ export async function getInitialState(): Promise<{ name: string }> {
6
+ return { name: '@umijs/max' };
7
+ }
8
+
9
+ export const layout = () => {
10
+ return {
11
+ logo: 'https://img.alicdn.com/tfs/TB1YHEpwUT1gK0jSZFhXXaAtVXa-28-27.svg',
12
+ menu: {
13
+ locale: false,
14
+ },
15
+ };
16
+ };
File without changes
@@ -0,0 +1,4 @@
1
+ .title {
2
+ margin: 0 auto;
3
+ font-weight: 200;
4
+ }
@@ -0,0 +1,23 @@
1
+ import { Layout, Row, Typography } from 'antd';
2
+ import React from 'react';
3
+ import styles from './Guide.less';
4
+
5
+ interface Props {
6
+ name: string;
7
+ }
8
+
9
+ // 脚手架示例组件
10
+ const Guide: React.FC<Props> = (props) => {
11
+ const { name } = props;
12
+ return (
13
+ <Layout>
14
+ <Row>
15
+ <Typography.Title level={3} className={styles.title}>
16
+ 欢迎使用 <strong>{name}</strong> !
17
+ </Typography.Title>
18
+ </Row>
19
+ </Layout>
20
+ );
21
+ };
22
+
23
+ export default Guide;
@@ -0,0 +1,2 @@
1
+ import Guide from './Guide';
2
+ export default Guide;
@@ -0,0 +1 @@
1
+ export const DEFAULT_NAME = 'Umi Max';
@@ -0,0 +1,13 @@
1
+ // 全局共享数据示例
2
+ import { DEFAULT_NAME } from '@/constants';
3
+ import { useState } from 'react';
4
+
5
+ const useUser = () => {
6
+ const [name, setName] = useState<string>(DEFAULT_NAME);
7
+ return {
8
+ name,
9
+ setName,
10
+ };
11
+ };
12
+
13
+ export default useUser;
@@ -0,0 +1,20 @@
1
+ import { PageContainer } from '@ant-design/pro-components';
2
+ import { Access, useAccess } from '@umijs/max';
3
+ import { Button } from 'antd';
4
+ import React from 'react';
5
+
6
+ export default () => {
7
+ const access = useAccess();
8
+ return (
9
+ <PageContainer
10
+ ghost
11
+ header={{
12
+ title: '权限示例',
13
+ }}
14
+ >
15
+ <Access accessible={access.canSeeAdmin}>
16
+ <Button>只有 Admin 可以看到这个按钮</Button>
17
+ </Access>
18
+ </PageContainer>
19
+ );
20
+ };
@@ -0,0 +1,3 @@
1
+ .container {
2
+ padding-top: 80px;
3
+ }
@@ -0,0 +1,17 @@
1
+ import Guide from '@/components/Guide';
2
+ import { trim } from '@/utils/format';
3
+ import { PageContainer } from '@ant-design/pro-components';
4
+ import { useModel } from '@umijs/max';
5
+ import React from 'react';
6
+ import styles from './index.less';
7
+
8
+ export default () => {
9
+ const { name } = useModel('global');
10
+ return (
11
+ <PageContainer ghost>
12
+ <div className={styles.container}>
13
+ <Guide name={trim(name)} />
14
+ </div>
15
+ </PageContainer>
16
+ );
17
+ };
@@ -0,0 +1,26 @@
1
+ import { Modal } from 'antd';
2
+ import React, { PropsWithChildren } from 'react';
3
+
4
+ interface CreateFormProps {
5
+ modalVisible: boolean;
6
+ onCancel: () => void;
7
+ }
8
+
9
+ const CreateForm: React.FC<PropsWithChildren<CreateFormProps>> = (props) => {
10
+ const { modalVisible, onCancel } = props;
11
+
12
+ return (
13
+ <Modal
14
+ destroyOnClose
15
+ title="新建"
16
+ width={420}
17
+ visible={modalVisible}
18
+ onCancel={() => onCancel()}
19
+ footer={null}
20
+ >
21
+ {props.children}
22
+ </Modal>
23
+ );
24
+ };
25
+
26
+ export default CreateForm;
@@ -0,0 +1,138 @@
1
+ import {
2
+ ProFormDateTimePicker,
3
+ ProFormRadio,
4
+ ProFormSelect,
5
+ ProFormText,
6
+ ProFormTextArea,
7
+ StepsForm,
8
+ } from '@ant-design/pro-components';
9
+ import { Modal } from 'antd';
10
+ import React from 'react';
11
+
12
+ export interface FormValueType extends Partial<API.UserInfo> {
13
+ target?: string;
14
+ template?: string;
15
+ type?: string;
16
+ time?: string;
17
+ frequency?: string;
18
+ }
19
+
20
+ export interface UpdateFormProps {
21
+ onCancel: (flag?: boolean, formVals?: FormValueType) => void;
22
+ onSubmit: (values: FormValueType) => Promise<void>;
23
+ updateModalVisible: boolean;
24
+ values: Partial<API.UserInfo>;
25
+ }
26
+
27
+ const UpdateForm: React.FC<UpdateFormProps> = (props) => (
28
+ <StepsForm
29
+ stepsProps={{
30
+ size: 'small',
31
+ }}
32
+ stepsFormRender={(dom, submitter) => {
33
+ return (
34
+ <Modal
35
+ width={640}
36
+ bodyStyle={{ padding: '32px 40px 48px' }}
37
+ destroyOnClose
38
+ title="规则配置"
39
+ visible={props.updateModalVisible}
40
+ footer={submitter}
41
+ onCancel={() => props.onCancel()}
42
+ >
43
+ {dom}
44
+ </Modal>
45
+ );
46
+ }}
47
+ onFinish={props.onSubmit}
48
+ >
49
+ <StepsForm.StepForm
50
+ initialValues={{
51
+ name: props.values.name,
52
+ nickName: props.values.nickName,
53
+ }}
54
+ title="基本信息"
55
+ >
56
+ <ProFormText
57
+ width="md"
58
+ name="name"
59
+ label="规则名称"
60
+ rules={[{ required: true, message: '请输入规则名称!' }]}
61
+ />
62
+ <ProFormTextArea
63
+ name="desc"
64
+ width="md"
65
+ label="规则描述"
66
+ placeholder="请输入至少五个字符"
67
+ rules={[
68
+ { required: true, message: '请输入至少五个字符的规则描述!', min: 5 },
69
+ ]}
70
+ />
71
+ </StepsForm.StepForm>
72
+ <StepsForm.StepForm
73
+ initialValues={{
74
+ target: '0',
75
+ template: '0',
76
+ }}
77
+ title="配置规则属性"
78
+ >
79
+ <ProFormSelect
80
+ width="md"
81
+ name="target"
82
+ label="监控对象"
83
+ valueEnum={{
84
+ 0: '表一',
85
+ 1: '表二',
86
+ }}
87
+ />
88
+ <ProFormSelect
89
+ width="md"
90
+ name="template"
91
+ label="规则模板"
92
+ valueEnum={{
93
+ 0: '规则模板一',
94
+ 1: '规则模板二',
95
+ }}
96
+ />
97
+ <ProFormRadio.Group
98
+ name="type"
99
+ width="md"
100
+ label="规则类型"
101
+ options={[
102
+ {
103
+ value: '0',
104
+ label: '强',
105
+ },
106
+ {
107
+ value: '1',
108
+ label: '弱',
109
+ },
110
+ ]}
111
+ />
112
+ </StepsForm.StepForm>
113
+ <StepsForm.StepForm
114
+ initialValues={{
115
+ type: '1',
116
+ frequency: 'month',
117
+ }}
118
+ title="设定调度周期"
119
+ >
120
+ <ProFormDateTimePicker
121
+ name="time"
122
+ label="开始时间"
123
+ rules={[{ required: true, message: '请选择开始时间!' }]}
124
+ />
125
+ <ProFormSelect
126
+ name="frequency"
127
+ label="监控对象"
128
+ width="xs"
129
+ valueEnum={{
130
+ month: '月',
131
+ week: '周',
132
+ }}
133
+ />
134
+ </StepsForm.StepForm>
135
+ </StepsForm>
136
+ );
137
+
138
+ export default UpdateForm;
@@ -0,0 +1,270 @@
1
+ import services from '@/services/demo';
2
+ import {
3
+ ActionType,
4
+ FooterToolbar,
5
+ PageContainer,
6
+ ProDescriptions,
7
+ ProDescriptionsItemProps,
8
+ ProTable,
9
+ } from '@ant-design/pro-components';
10
+ import { Button, Divider, Drawer, message } from 'antd';
11
+ import React, { useRef, useState } from 'react';
12
+ import CreateForm from './components/CreateForm';
13
+ import UpdateForm, { FormValueType } from './components/UpdateForm';
14
+
15
+ const { addUser, queryUserList, deleteUser, modifyUser } =
16
+ services.UserController;
17
+
18
+ /**
19
+ * 添加节点
20
+ * @param fields
21
+ */
22
+ const handleAdd = async (fields: API.UserInfo) => {
23
+ const hide = message.loading('正在添加');
24
+ try {
25
+ await addUser({ ...fields });
26
+ hide();
27
+ message.success('添加成功');
28
+ return true;
29
+ } catch (error) {
30
+ hide();
31
+ message.error('添加失败请重试!');
32
+ return false;
33
+ }
34
+ };
35
+
36
+ /**
37
+ * 更新节点
38
+ * @param fields
39
+ */
40
+ const handleUpdate = async (fields: FormValueType) => {
41
+ const hide = message.loading('正在配置');
42
+ try {
43
+ await modifyUser(
44
+ {
45
+ userId: fields.id || '',
46
+ },
47
+ {
48
+ name: fields.name || '',
49
+ nickName: fields.nickName || '',
50
+ email: fields.email || '',
51
+ },
52
+ );
53
+ hide();
54
+
55
+ message.success('配置成功');
56
+ return true;
57
+ } catch (error) {
58
+ hide();
59
+ message.error('配置失败请重试!');
60
+ return false;
61
+ }
62
+ };
63
+
64
+ /**
65
+ * 删除节点
66
+ * @param selectedRows
67
+ */
68
+ const handleRemove = async (selectedRows: API.UserInfo[]) => {
69
+ const hide = message.loading('正在删除');
70
+ if (!selectedRows) return true;
71
+ try {
72
+ await deleteUser({
73
+ userId: selectedRows.find((row) => row.id)?.id || '',
74
+ });
75
+ hide();
76
+ message.success('删除成功,即将刷新');
77
+ return true;
78
+ } catch (error) {
79
+ hide();
80
+ message.error('删除失败,请重试');
81
+ return false;
82
+ }
83
+ };
84
+
85
+ const TableList: React.FC<unknown> = () => {
86
+ const [createModalVisible, handleModalVisible] = useState<boolean>(false);
87
+ const [updateModalVisible, handleUpdateModalVisible] =
88
+ useState<boolean>(false);
89
+ const [stepFormValues, setStepFormValues] = useState({});
90
+ const actionRef = useRef<ActionType>();
91
+ const [row, setRow] = useState<API.UserInfo>();
92
+ const [selectedRowsState, setSelectedRows] = useState<API.UserInfo[]>([]);
93
+ const columns: ProDescriptionsItemProps<API.UserInfo>[] = [
94
+ {
95
+ title: '名称',
96
+ dataIndex: 'name',
97
+ tip: '名称是唯一的 key',
98
+ formItemProps: {
99
+ rules: [
100
+ {
101
+ required: true,
102
+ message: '名称为必填项',
103
+ },
104
+ ],
105
+ },
106
+ },
107
+ {
108
+ title: '昵称',
109
+ dataIndex: 'nickName',
110
+ valueType: 'text',
111
+ },
112
+ {
113
+ title: '性别',
114
+ dataIndex: 'gender',
115
+ hideInForm: true,
116
+ valueEnum: {
117
+ 0: { text: '男', status: 'MALE' },
118
+ 1: { text: '女', status: 'FEMALE' },
119
+ },
120
+ },
121
+ {
122
+ title: '操作',
123
+ dataIndex: 'option',
124
+ valueType: 'option',
125
+ render: (_, record) => (
126
+ <>
127
+ <a
128
+ onClick={() => {
129
+ handleUpdateModalVisible(true);
130
+ setStepFormValues(record);
131
+ }}
132
+ >
133
+ 配置
134
+ </a>
135
+ <Divider type="vertical" />
136
+ <a href="">订阅警报</a>
137
+ </>
138
+ ),
139
+ },
140
+ ];
141
+
142
+ return (
143
+ <PageContainer
144
+ header={{
145
+ title: 'CRUD 示例',
146
+ }}
147
+ >
148
+ <ProTable<API.UserInfo>
149
+ headerTitle="查询表格"
150
+ actionRef={actionRef}
151
+ rowKey="id"
152
+ search={{
153
+ labelWidth: 120,
154
+ }}
155
+ toolBarRender={() => [
156
+ <Button
157
+ key="1"
158
+ type="primary"
159
+ onClick={() => handleModalVisible(true)}
160
+ >
161
+ 新建
162
+ </Button>,
163
+ ]}
164
+ request={async (params, sorter, filter) => {
165
+ const { data, success } = await queryUserList({
166
+ ...params,
167
+ // FIXME: remove @ts-ignore
168
+ // @ts-ignore
169
+ sorter,
170
+ filter,
171
+ });
172
+ return {
173
+ data: data?.list || [],
174
+ success,
175
+ };
176
+ }}
177
+ columns={columns}
178
+ rowSelection={{
179
+ onChange: (_, selectedRows) => setSelectedRows(selectedRows),
180
+ }}
181
+ />
182
+ {selectedRowsState?.length > 0 && (
183
+ <FooterToolbar
184
+ extra={
185
+ <div>
186
+ 已选择{' '}
187
+ <a style={{ fontWeight: 600 }}>{selectedRowsState.length}</a>{' '}
188
+ 项&nbsp;&nbsp;
189
+ </div>
190
+ }
191
+ >
192
+ <Button
193
+ onClick={async () => {
194
+ await handleRemove(selectedRowsState);
195
+ setSelectedRows([]);
196
+ actionRef.current?.reloadAndRest?.();
197
+ }}
198
+ >
199
+ 批量删除
200
+ </Button>
201
+ <Button type="primary">批量审批</Button>
202
+ </FooterToolbar>
203
+ )}
204
+ <CreateForm
205
+ onCancel={() => handleModalVisible(false)}
206
+ modalVisible={createModalVisible}
207
+ >
208
+ <ProTable<API.UserInfo, API.UserInfo>
209
+ onSubmit={async (value) => {
210
+ const success = await handleAdd(value);
211
+ if (success) {
212
+ handleModalVisible(false);
213
+ if (actionRef.current) {
214
+ actionRef.current.reload();
215
+ }
216
+ }
217
+ }}
218
+ rowKey="id"
219
+ type="form"
220
+ columns={columns}
221
+ />
222
+ </CreateForm>
223
+ {stepFormValues && Object.keys(stepFormValues).length ? (
224
+ <UpdateForm
225
+ onSubmit={async (value) => {
226
+ const success = await handleUpdate(value);
227
+ if (success) {
228
+ handleUpdateModalVisible(false);
229
+ setStepFormValues({});
230
+ if (actionRef.current) {
231
+ actionRef.current.reload();
232
+ }
233
+ }
234
+ }}
235
+ onCancel={() => {
236
+ handleUpdateModalVisible(false);
237
+ setStepFormValues({});
238
+ }}
239
+ updateModalVisible={updateModalVisible}
240
+ values={stepFormValues}
241
+ />
242
+ ) : null}
243
+
244
+ <Drawer
245
+ width={600}
246
+ visible={!!row}
247
+ onClose={() => {
248
+ setRow(undefined);
249
+ }}
250
+ closable={false}
251
+ >
252
+ {row?.name && (
253
+ <ProDescriptions<API.UserInfo>
254
+ column={2}
255
+ title={row?.name}
256
+ request={async () => ({
257
+ data: row || {},
258
+ })}
259
+ params={{
260
+ id: row?.name,
261
+ }}
262
+ columns={columns}
263
+ />
264
+ )}
265
+ </Drawer>
266
+ </PageContainer>
267
+ );
268
+ };
269
+
270
+ export default TableList;
@@ -0,0 +1,96 @@
1
+ /* eslint-disable */
2
+ // 该文件由 OneAPI 自动生成,请勿手动修改!
3
+ import { request } from '@umijs/max';
4
+
5
+ /** 此处后端没有提供注释 GET /api/v1/queryUserList */
6
+ export async function queryUserList(
7
+ params: {
8
+ // query
9
+ /** keyword */
10
+ keyword?: string;
11
+ /** current */
12
+ current?: number;
13
+ /** pageSize */
14
+ pageSize?: number;
15
+ },
16
+ options?: { [key: string]: any },
17
+ ) {
18
+ return request<API.Result_PageInfo_UserInfo__>('/api/v1/queryUserList', {
19
+ method: 'GET',
20
+ params: {
21
+ ...params,
22
+ },
23
+ ...(options || {}),
24
+ });
25
+ }
26
+
27
+ /** 此处后端没有提供注释 POST /api/v1/user */
28
+ export async function addUser(
29
+ body?: API.UserInfoVO,
30
+ options?: { [key: string]: any },
31
+ ) {
32
+ return request<API.Result_UserInfo_>('/api/v1/user', {
33
+ method: 'POST',
34
+ headers: {
35
+ 'Content-Type': 'application/json',
36
+ },
37
+ data: body,
38
+ ...(options || {}),
39
+ });
40
+ }
41
+
42
+ /** 此处后端没有提供注释 GET /api/v1/user/${param0} */
43
+ export async function getUserDetail(
44
+ params: {
45
+ // path
46
+ /** userId */
47
+ userId?: string;
48
+ },
49
+ options?: { [key: string]: any },
50
+ ) {
51
+ const { userId: param0 } = params;
52
+ return request<API.Result_UserInfo_>(`/api/v1/user/${param0}`, {
53
+ method: 'GET',
54
+ params: { ...params },
55
+ ...(options || {}),
56
+ });
57
+ }
58
+
59
+ /** 此处后端没有提供注释 PUT /api/v1/user/${param0} */
60
+ export async function modifyUser(
61
+ params: {
62
+ // path
63
+ /** userId */
64
+ userId?: string;
65
+ },
66
+ body?: API.UserInfoVO,
67
+ options?: { [key: string]: any },
68
+ ) {
69
+ const { userId: param0 } = params;
70
+ return request<API.Result_UserInfo_>(`/api/v1/user/${param0}`, {
71
+ method: 'PUT',
72
+ headers: {
73
+ 'Content-Type': 'application/json',
74
+ },
75
+ params: { ...params },
76
+ data: body,
77
+ ...(options || {}),
78
+ });
79
+ }
80
+
81
+ /** 此处后端没有提供注释 DELETE /api/v1/user/${param0} */
82
+ export async function deleteUser(
83
+ params: {
84
+ // path
85
+ /** userId */
86
+ userId?: string;
87
+ },
88
+ options?: { [key: string]: any },
89
+ ) {
90
+ const { userId: param0 } = params;
91
+ return request<API.Result_string_>(`/api/v1/user/${param0}`, {
92
+ method: 'DELETE',
93
+ params: { ...params },
94
+ ...(options || {}),
95
+ });
96
+ }
@@ -0,0 +1,7 @@
1
+ /* eslint-disable */
2
+ // 该文件由 OneAPI 自动生成,请勿手动修改!
3
+
4
+ import * as UserController from './UserController';
5
+ export default {
6
+ UserController,
7
+ };
@@ -0,0 +1,68 @@
1
+ /* eslint-disable */
2
+ // 该文件由 OneAPI 自动生成,请勿手动修改!
3
+
4
+ declare namespace API {
5
+ interface PageInfo {
6
+ /**
7
+ 1 */
8
+ current?: number;
9
+ pageSize?: number;
10
+ total?: number;
11
+ list?: Array<Record<string, any>>;
12
+ }
13
+
14
+ interface PageInfo_UserInfo_ {
15
+ /**
16
+ 1 */
17
+ current?: number;
18
+ pageSize?: number;
19
+ total?: number;
20
+ list?: Array<UserInfo>;
21
+ }
22
+
23
+ interface Result {
24
+ success?: boolean;
25
+ errorMessage?: string;
26
+ data?: Record<string, any>;
27
+ }
28
+
29
+ interface Result_PageInfo_UserInfo__ {
30
+ success?: boolean;
31
+ errorMessage?: string;
32
+ data?: PageInfo_UserInfo_;
33
+ }
34
+
35
+ interface Result_UserInfo_ {
36
+ success?: boolean;
37
+ errorMessage?: string;
38
+ data?: UserInfo;
39
+ }
40
+
41
+ interface Result_string_ {
42
+ success?: boolean;
43
+ errorMessage?: string;
44
+ data?: string;
45
+ }
46
+
47
+ type UserGenderEnum = 'MALE' | 'FEMALE';
48
+
49
+ interface UserInfo {
50
+ id?: string;
51
+ name?: string;
52
+ /** nick */
53
+ nickName?: string;
54
+ /** email */
55
+ email?: string;
56
+ gender?: UserGenderEnum;
57
+ }
58
+
59
+ interface UserInfoVO {
60
+ name?: string;
61
+ /** nick */
62
+ nickName?: string;
63
+ /** email */
64
+ email?: string;
65
+ }
66
+
67
+ type definitions_0 = null;
68
+ }
@@ -0,0 +1,4 @@
1
+ // 示例方法,没有实际意义
2
+ export function trim(str: string) {
3
+ return str.trim();
4
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "extends": "./src/.umi/tsconfig.json"
3
+ }
@@ -0,0 +1 @@
1
+ import '@umijs/max/typings';
@@ -0,0 +1,11 @@
1
+ /node_modules
2
+ /.env.local
3
+ /.umirc.local.ts
4
+ /config/config.local.ts
5
+ /src/.umi
6
+ /src/.umi-production
7
+ /.umi
8
+ /.umi-production
9
+ /.umi-test
10
+ /dist
11
+ /.mfsu
@@ -0,0 +1 @@
1
+ registry={{{ registry }}}
@@ -0,0 +1,4 @@
1
+ export default {
2
+ npmClient: '{{{ npmClient }}}',
3
+ presets: [require.resolve('@umijs/preset-vue')],
4
+ };
@@ -0,0 +1,17 @@
1
+ {
2
+ "private": true,
3
+ "scripts": {
4
+ "dev": "umi dev",
5
+ "build": "umi build",
6
+ "postinstall": "umi setup",
7
+ "start": "npm run dev"
8
+ },
9
+ "dependencies": {
10
+ "vue": "^3.2.36",
11
+ "umi": "{{{ version }}}"
12
+ },
13
+ "devDependencies": {
14
+ "typescript": "^4.1.2",
15
+ "@umijs/preset-vue": "{{{ version }}}"
16
+ }
17
+ }
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <div class="navs">
3
+ <ul>
4
+ <li>
5
+ <router-link to="/">Home</router-link>
6
+ </li>
7
+ <li>
8
+ <router-link to="/docs">Docs</router-link>
9
+ </li>
10
+ <li>
11
+ <a href="https://github.com/umijs/umi">Github</a>
12
+ </li>
13
+ </ul>
14
+ <router-view></router-view>
15
+ </div>
16
+ </template>
17
+ <style lang="less">
18
+ .navs {
19
+ ul {
20
+ padding: 0;
21
+ list-style: none;
22
+ display: flex;
23
+ }
24
+ li {
25
+ margin-right: 1em;
26
+ }
27
+ }
28
+ </style>
@@ -0,0 +1,5 @@
1
+ <template>
2
+ <div>
3
+ <p>This is umi docs.</p>
4
+ </div>
5
+ </template>
@@ -0,0 +1,11 @@
1
+ <template>
2
+ <div>
3
+ <h2>Yay! Welcome to umi ❤️ vue!</h2>
4
+ <p>
5
+ <img src="../assets/yay.jpg" width="388" />
6
+ </p>
7
+ <p>
8
+ To get started, edit <code>pages/index.vue</code> and save to reload.
9
+ </p>
10
+ </div>
11
+ </template>
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "./src/.umi/tsconfig.json",
3
+ "compilerOptions": {
4
+ "jsx": "preserve"
5
+ }
6
+ }
@@ -0,0 +1 @@
1
+ import 'umi/typings';
@@ -1,18 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "esnext",
4
- "module": "esnext",
5
- "moduleResolution": "node",
6
- "importHelpers": true,
7
- "jsx": "react",
8
- "esModuleInterop": true,
9
- "sourceMap": true,
10
- "baseUrl": ".",
11
- "strict": true,
12
- "paths": {
13
- "@/*": ["*"],
14
- "@@/*": [".umi/*"]
15
- },
16
- "allowSyntheticDefaultImports": true
17
- }
18
- }