This commit is contained in:
asp_ly 2024-12-26 20:44:12 +08:00
parent 83b2ebc31b
commit a5d85f8555
9 changed files with 281 additions and 314 deletions

View File

@ -24,10 +24,6 @@
"@logicflow/core": "^2.0.9", "@logicflow/core": "^2.0.9",
"@logicflow/extension": "^2.0.13", "@logicflow/extension": "^2.0.13",
"@reduxjs/toolkit": "^2.0.1", "@reduxjs/toolkit": "^2.0.1",
"@rjsf/antd": "^5.23.2",
"@rjsf/core": "^5.23.2",
"@rjsf/utils": "^5.23.2",
"@rjsf/validator-ajv8": "^5.23.2",
"@types/recharts": "^1.8.29", "@types/recharts": "^1.8.29",
"ajv": "^8.17.1", "ajv": "^8.17.1",
"ajv-formats": "^3.0.1", "ajv-formats": "^3.0.1",
@ -1952,163 +1948,6 @@
"node": ">=14.0.0" "node": ">=14.0.0"
} }
}, },
"node_modules/@rjsf/antd": {
"version": "5.23.2",
"resolved": "https://registry.npmmirror.com/@rjsf/antd/-/antd-5.23.2.tgz",
"integrity": "sha512-XZG0sIiJTjxdNXAIFyM88nP7MmCLUxugm3wyJ34jQlwGThZqmsgbHqyhrTum9ZcOvMAknDeNK3MSwI0CugswtQ==",
"license": "Apache-2.0",
"dependencies": {
"classnames": "^2.5.1",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"rc-picker": "2.7.6"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"@ant-design/icons": "^4.0.0 || ^5.0.0",
"@rjsf/core": "^5.23.x",
"@rjsf/utils": "^5.23.x",
"antd": "^4.24.0 || ^5.8.5",
"dayjs": "^1.8.0",
"react": "^16.14.0 || >=17"
}
},
"node_modules/@rjsf/antd/node_modules/rc-picker": {
"version": "2.7.6",
"resolved": "https://registry.npmmirror.com/rc-picker/-/rc-picker-2.7.6.tgz",
"integrity": "sha512-H9if/BUJUZBOhPfWcPeT15JUI3/ntrG9muzERrXDkSoWmDj4yzmBvumozpxYrHwjcKnjyDGAke68d+whWwvhHA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.10.1",
"classnames": "^2.2.1",
"date-fns": "2.x",
"dayjs": "1.x",
"moment": "^2.24.0",
"rc-trigger": "^5.0.4",
"rc-util": "^5.37.0",
"shallowequal": "^1.1.0"
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/@rjsf/antd/node_modules/rc-picker/node_modules/rc-trigger": {
"version": "5.3.4",
"resolved": "https://registry.npmmirror.com/rc-trigger/-/rc-trigger-5.3.4.tgz",
"integrity": "sha512-mQv+vas0TwKcjAO2izNPkqR4j86OemLRmvL2nOzdP9OWNWA1ivoTt5hzFqYNW9zACwmTezRiN8bttrC7cZzYSw==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.18.3",
"classnames": "^2.2.6",
"rc-align": "^4.0.0",
"rc-motion": "^2.0.0",
"rc-util": "^5.19.2"
},
"engines": {
"node": ">=8.x"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/@rjsf/antd/node_modules/rc-picker/node_modules/rc-trigger/node_modules/rc-align": {
"version": "4.0.15",
"resolved": "https://registry.npmmirror.com/rc-align/-/rc-align-4.0.15.tgz",
"integrity": "sha512-wqJtVH60pka/nOX7/IspElA8gjPNQKIx/ZqJ6heATCkXpe1Zg4cPVrMD2vC96wjsFFL8WsmhPbx9tdMo1qqlIA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.10.1",
"classnames": "2.x",
"dom-align": "^1.7.0",
"rc-util": "^5.26.0",
"resize-observer-polyfill": "^1.5.1"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
}
},
"node_modules/@rjsf/core": {
"version": "5.23.2",
"resolved": "https://registry.npmmirror.com/@rjsf/core/-/core-5.23.2.tgz",
"integrity": "sha512-jSz3X8SOZ1xL3wMPhBt01j/cA4FszhdGTLBhHfncM9nme4SpbQ6GRAiePOBakEVhT89GAM11ML1DA888YTZfmg==",
"license": "Apache-2.0",
"dependencies": {
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"markdown-to-jsx": "^7.4.1",
"nanoid": "^3.3.7",
"prop-types": "^15.8.1"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"@rjsf/utils": "^5.23.x",
"react": "^16.14.0 || >=17"
}
},
"node_modules/@rjsf/utils": {
"version": "5.23.2",
"resolved": "https://registry.npmmirror.com/@rjsf/utils/-/utils-5.23.2.tgz",
"integrity": "sha512-CDpZTroRE1O2lkZBNYsWCRj7moF3fqnwIo/Vf3flhoS7rGwb8kWlIHakOOBZxlqorKZB1UPzhQZn+FcwhzNldw==",
"license": "Apache-2.0",
"dependencies": {
"json-schema-merge-allof": "^0.8.1",
"jsonpointer": "^5.0.1",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"react-is": "^18.2.0"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"react": "^16.14.0 || >=17"
}
},
"node_modules/@rjsf/validator-ajv8": {
"version": "5.23.2",
"resolved": "https://registry.npmmirror.com/@rjsf/validator-ajv8/-/validator-ajv8-5.23.2.tgz",
"integrity": "sha512-EHOTZ/YxTcFHpCj2p42PD3daxJyozZ5gkIVCfbtIXgTtubt/pOMFvM2OxNcQ6OBQ+ulo96OmnDxYGsNPpZZVaw==",
"license": "Apache-2.0",
"dependencies": {
"ajv": "^8.12.0",
"ajv-formats": "^2.1.1",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"@rjsf/utils": "^5.23.x"
}
},
"node_modules/@rjsf/validator-ajv8/node_modules/ajv-formats": {
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz",
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
"license": "MIT",
"dependencies": {
"ajv": "^8.0.0"
},
"peerDependencies": {
"ajv": "^8.0.0"
},
"peerDependenciesMeta": {
"ajv": {
"optional": true
}
}
},
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.27.4", "version": "4.27.4",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz", "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.27.4.tgz",
@ -3385,27 +3224,6 @@
"resolved": "https://registry.npmmirror.com/component-indexof/-/component-indexof-0.0.3.tgz", "resolved": "https://registry.npmmirror.com/component-indexof/-/component-indexof-0.0.3.tgz",
"integrity": "sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw==" "integrity": "sha512-puDQKvx/64HZXb4hBwIcvQLaLgux8o1CbWl39s41hrIIZDl1lJiD5jc22gj3RBeGK0ovxALDYpIbyjqDUUl0rw=="
}, },
"node_modules/compute-gcd": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/compute-gcd/-/compute-gcd-1.2.1.tgz",
"integrity": "sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==",
"dependencies": {
"validate.io-array": "^1.0.3",
"validate.io-function": "^1.0.2",
"validate.io-integer-array": "^1.0.0"
}
},
"node_modules/compute-lcm": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/compute-lcm/-/compute-lcm-1.1.2.tgz",
"integrity": "sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==",
"dependencies": {
"compute-gcd": "^1.2.1",
"validate.io-array": "^1.0.3",
"validate.io-function": "^1.0.2",
"validate.io-integer-array": "^1.0.0"
}
},
"node_modules/compute-scroll-into-view": { "node_modules/compute-scroll-into-view": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz", "resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz",
@ -3682,6 +3500,8 @@
"resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-2.30.0.tgz", "resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-2.30.0.tgz",
"integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"dependencies": { "dependencies": {
"@babel/runtime": "^7.21.0" "@babel/runtime": "^7.21.0"
}, },
@ -4806,29 +4626,6 @@
"resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
}, },
"node_modules/json-schema-compare": {
"version": "0.2.2",
"resolved": "https://registry.npmmirror.com/json-schema-compare/-/json-schema-compare-0.2.2.tgz",
"integrity": "sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==",
"license": "MIT",
"dependencies": {
"lodash": "^4.17.4"
}
},
"node_modules/json-schema-merge-allof": {
"version": "0.8.1",
"resolved": "https://registry.npmmirror.com/json-schema-merge-allof/-/json-schema-merge-allof-0.8.1.tgz",
"integrity": "sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==",
"license": "MIT",
"dependencies": {
"compute-lcm": "^1.1.2",
"json-schema-compare": "^0.2.2",
"lodash": "^4.17.20"
},
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/json-schema-traverse": { "node_modules/json-schema-traverse": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
@ -4859,15 +4656,6 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/jsonpointer": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/jsonpointer/-/jsonpointer-5.0.1.tgz",
"integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/keyv": { "node_modules/keyv": {
"version": "4.5.4", "version": "4.5.4",
"resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz", "resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz",
@ -5020,18 +4808,6 @@
"semver": "bin/semver" "semver": "bin/semver"
} }
}, },
"node_modules/markdown-to-jsx": {
"version": "7.7.2",
"resolved": "https://registry.npmmirror.com/markdown-to-jsx/-/markdown-to-jsx-7.7.2.tgz",
"integrity": "sha512-N3AKfYRvxNscvcIH6HDnDKILp4S8UWbebp+s92Y8SwIq0CuSbLW4Jgmrbjku3CWKjTQO0OyIMS6AhzqrwjEa3g==",
"license": "MIT",
"engines": {
"node": ">= 10"
},
"peerDependencies": {
"react": ">= 0.14.0"
}
},
"node_modules/medium-editor": { "node_modules/medium-editor": {
"version": "5.23.3", "version": "5.23.3",
"resolved": "https://registry.npmmirror.com/medium-editor/-/medium-editor-5.23.3.tgz", "resolved": "https://registry.npmmirror.com/medium-editor/-/medium-editor-5.23.3.tgz",
@ -5187,6 +4963,8 @@
"resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz", "resolved": "https://registry.npmmirror.com/moment/-/moment-2.30.1.tgz",
"integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==",
"license": "MIT", "license": "MIT",
"optional": true,
"peer": true,
"engines": { "engines": {
"node": "*" "node": "*"
} }
@ -5205,6 +4983,7 @@
"version": "3.3.7", "version": "3.3.7",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz", "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -7067,39 +6846,6 @@
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
}, },
"node_modules/validate.io-array": {
"version": "1.0.6",
"resolved": "https://registry.npmmirror.com/validate.io-array/-/validate.io-array-1.0.6.tgz",
"integrity": "sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==",
"license": "MIT"
},
"node_modules/validate.io-function": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/validate.io-function/-/validate.io-function-1.0.2.tgz",
"integrity": "sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ=="
},
"node_modules/validate.io-integer": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/validate.io-integer/-/validate.io-integer-1.0.5.tgz",
"integrity": "sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==",
"dependencies": {
"validate.io-number": "^1.0.3"
}
},
"node_modules/validate.io-integer-array": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/validate.io-integer-array/-/validate.io-integer-array-1.0.0.tgz",
"integrity": "sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==",
"dependencies": {
"validate.io-array": "^1.0.3",
"validate.io-integer": "^1.0.4"
}
},
"node_modules/validate.io-number": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/validate.io-number/-/validate.io-number-1.0.3.tgz",
"integrity": "sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg=="
},
"node_modules/vanilla-picker": { "node_modules/vanilla-picker": {
"version": "2.12.3", "version": "2.12.3",
"resolved": "https://registry.npmmirror.com/vanilla-picker/-/vanilla-picker-2.12.3.tgz", "resolved": "https://registry.npmmirror.com/vanilla-picker/-/vanilla-picker-2.12.3.tgz",

View File

@ -26,10 +26,6 @@
"@logicflow/core": "^2.0.9", "@logicflow/core": "^2.0.9",
"@logicflow/extension": "^2.0.13", "@logicflow/extension": "^2.0.13",
"@reduxjs/toolkit": "^2.0.1", "@reduxjs/toolkit": "^2.0.1",
"@rjsf/antd": "^5.23.2",
"@rjsf/core": "^5.23.2",
"@rjsf/utils": "^5.23.2",
"@rjsf/validator-ajv8": "^5.23.2",
"@types/recharts": "^1.8.29", "@types/recharts": "^1.8.29",
"ajv": "^8.17.1", "ajv": "^8.17.1",
"ajv-formats": "^3.0.1", "ajv-formats": "^3.0.1",

View File

@ -10,7 +10,6 @@ import {
ClockCircleOutlined, ClockCircleOutlined,
CloudOutlined CloudOutlined
} from '@ant-design/icons'; } from '@ant-design/icons';
import * as AntdIcons from '@ant-design/icons';
import {logout, setMenus} from '../store/userSlice'; import {logout, setMenus} from '../store/userSlice';
import type {MenuProps} from 'antd'; import type {MenuProps} from 'antd';
import {getCurrentUserMenus} from '@/pages/System/Menu/service'; import {getCurrentUserMenus} from '@/pages/System/Menu/service';

View File

@ -1,15 +1,12 @@
import React, {useEffect, useState} from 'react'; import React, {useEffect, useState} from 'react';
import {Modal, Form, Select, Switch, InputNumber, message} from 'antd'; import {Modal, Form, Select, message, Switch, InputNumber} from 'antd';
import type {DeploymentConfig, DeployConfigTemplate} from '../types'; import type {DeploymentConfig, DeployConfigTemplate} from '../types';
import {createDeploymentConfig, updateDeploymentConfig, getDeployConfigTemplates} from '../service'; import {createDeploymentConfig, updateDeploymentConfig, getDeployConfigTemplates} from '../service';
import {getApplicationList} from '../../../Application/List/service'; import {getApplicationList} from '../../../Application/List/service';
import type {Application} from '../../../Application/List/types'; import type {Application} from '../../../Application/List/types';
import {withTheme} from '@rjsf/core'; import {BetaSchemaForm} from '@ant-design/pro-form';
import {Theme as AntdTheme} from '@rjsf/antd'; import {convertJsonSchemaToColumns} from '@/utils/jsonSchemaUtils';
import validator from '@rjsf/validator-ajv8'; import './styles.less';
import type {IChangeEvent} from '@rjsf/utils';
const JsonForm = withTheme(AntdTheme);
interface DeploymentConfigModalProps { interface DeploymentConfigModalProps {
visible: boolean; visible: boolean;
@ -55,7 +52,7 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
} }
}; };
// 在模态框显示时获取数据 // <EFBFBD><EFBFBD>在模态框显示时获取数据
useEffect(() => { useEffect(() => {
if (visible) { if (visible) {
fetchApplications(); fetchApplications();
@ -90,8 +87,11 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
const app = applications.find(a => a.id === appId); const app = applications.find(a => a.id === appId);
if (app) { if (app) {
const template = templates.find(t => t.languageType === app.language); const template = templates.find(t => t.languageType === app.language);
if (template) {
setSelectedTemplate(template); setSelectedTemplate(template);
setBuildVariables({}); setBuildVariables({});
form.setFieldValue('templateCode', template.code);
}
} }
}; };
@ -100,7 +100,6 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
const values = await form.validateFields(); const values = await form.validateFields();
const submitData = { const submitData = {
...values, ...values,
templateCode: selectedTemplate?.code,
buildVariables, buildVariables,
}; };
@ -120,12 +119,6 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
} }
}; };
const handleJsonFormChange = (e: IChangeEvent) => {
if (e.formData) {
setBuildVariables(e.formData);
}
};
return ( return (
<Modal <Modal
title={`${isEdit ? '编辑' : '新建'}部署配置`} title={`${isEdit ? '编辑' : '新建'}部署配置`}
@ -136,6 +129,8 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
}} }}
onOk={handleSubmit} onOk={handleSubmit}
width={800} width={800}
className="deployment-config-modal"
maskClosable={false}
> >
<Form <Form
form={form} form={form}
@ -145,15 +140,19 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
sort: 0, sort: 0,
}} }}
> >
{/* 应用选<E794A8><E98089><EFBFBD> */}
<Form.Item <Form.Item
name="appId" name="appId"
label="应用" label="应用"
rules={[{required: true, message: '请选择应用'}]} required
tooltip="选择要部署的应用"
> >
<Select <Select
placeholder="请选择应用" placeholder="请选择应用"
onChange={handleAppChange} onChange={handleAppChange}
disabled={isEdit} disabled={isEdit}
showSearch
optionFilterProp="children"
> >
{applications.map((app) => ( {applications.map((app) => (
<Option key={app.id} value={app.id}> <Option key={app.id} value={app.id}>
@ -163,25 +162,17 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
</Select> </Select>
</Form.Item> </Form.Item>
{/* 动态构建配置 */}
{selectedTemplate && ( {selectedTemplate && (
<Form.Item <BetaSchemaForm
label={selectedTemplate.name} layoutType="Embed"
required columns={convertJsonSchemaToColumns(selectedTemplate.buildVariablesSchema)}
> initialValues={buildVariables}
<JsonForm onValuesChange={(_, values) => setBuildVariables(values)}
schema={selectedTemplate.buildVariablesSchema}
validator={validator}
formData={buildVariables}
onChange={handleJsonFormChange}
uiSchema={{
"ui:submitButtonOptions": {
"norender": true,
},
}}
/> />
</Form.Item>
)} )}
{/* 状态和排序 */}
<Form.Item <Form.Item
name="enabled" name="enabled"
label="状态" label="状态"
@ -193,9 +184,15 @@ const DeploymentConfigModal: React.FC<DeploymentConfigModalProps> = ({
<Form.Item <Form.Item
name="sort" name="sort"
label="排序" label="排序"
rules={[{required: true, message: '请输入排序号'}]} required
tooltip="数字越小越靠前"
> >
<InputNumber min={0} max={999} style={{width: '100%'}}/> <InputNumber
min={0}
max={999}
style={{ width: '100%' }}
placeholder="请输入排序号"
/>
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>

View File

@ -0,0 +1,98 @@
.deployment-config-modal {
.ant-modal-body {
padding: 24px;
max-height: calc(100vh - 200px);
overflow-y: auto;
}
.config-section {
background: #fafafa;
border-radius: 8px;
margin-bottom: 24px;
&:last-child {
margin-bottom: 0;
}
.ant-card-body {
padding: 20px;
}
.section-header {
margin-bottom: 16px;
padding-bottom: 16px;
border-bottom: 1px solid #f0f0f0;
.section-icon {
font-size: 18px;
color: #1890ff;
}
.section-title {
font-size: 16px;
font-weight: 500;
color: #262626;
}
}
.section-content {
.ant-form-item {
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
.ant-form-item-label {
padding-bottom: 8px;
label {
color: #262626;
font-weight: 500;
}
}
.ant-input,
.ant-select-selector,
.ant-input-number {
border-radius: 4px;
&:hover,
&:focus {
border-color: #1890ff;
}
}
.ant-switch {
background: rgba(0, 0, 0, 0.25);
&-checked {
background: #1890ff;
}
}
}
}
}
// Schema表单样式优化
.ant-form-item-extra {
font-size: 12px;
color: #666;
margin-top: 4px;
}
.ant-form-item-with-help {
margin-bottom: 24px;
}
// 必填项标记样式
.ant-form-item-required::before {
display: inline-block;
margin-right: 4px;
color: #ff4d4f;
font-size: 14px;
font-family: SimSun, sans-serif;
line-height: 1;
content: '*';
}
}

View File

@ -120,13 +120,6 @@ const DeploymentConfigList: React.FC = () => {
width: 100, width: 100,
align: 'center', align: 'center',
}, },
{
title: '资源配置',
dataIndex: ['deployConfig', 'resources'],
width: 200,
ellipsis: true,
render: (_, record) => renderResourceInfo(record.deployConfig?.resources),
},
], ],
}, },
{ {

View File

@ -1,7 +1,7 @@
import request from '@/utils/request'; import request from '@/utils/request';
import type { Page } from '@/types/base/page';
import type { MenuResponse, MenuRequest } from './types'; import type { MenuResponse, MenuRequest } from './types';
import { MenuTypeEnum } from './types'; import { MenuTypeEnum } from './types';
import {Page} from "@/types/base";
const BASE_URL = '/api/v1/menu'; const BASE_URL = '/api/v1/menu';

View File

@ -1,6 +1,4 @@
import {BaseRequest} from "@/types/base/request.ts"; import {BaseQuery, BaseRequest, BaseResponse} from "@/types/base";
import {BaseResponse} from "@/types/base/response.ts";
import {BaseQuery} from "@/types/base";
export enum MenuTypeEnum { export enum MenuTypeEnum {
DIRECTORY = 1, // 目录 DIRECTORY = 1, // 目录

View File

@ -0,0 +1,140 @@
import type {ProFormColumnsType} from '@ant-design/pro-form';
interface JsonSchemaProperty {
type: string;
title?: string;
description?: string;
default?: any;
enum?: any[];
enumNames?: string[];
items?: {
type: string;
enum?: any[];
enumNames?: string[];
};
minimum?: number;
maximum?: number;
minLength?: number;
maxLength?: number;
pattern?: string;
}
interface JsonSchema {
type: string;
properties: Record<string, JsonSchemaProperty>;
required?: string[];
}
/**
* JSON Schema转换为ProForm的columns配置
* @param schema JSON Schema对象
* @returns ProForm的columns配置
*/
export const convertJsonSchemaToColumns = (schema: JsonSchema): ProFormColumnsType[] => {
if (!schema?.properties) return [];
return Object.entries(schema.properties).map(([key, value]: [string, JsonSchemaProperty]) => {
const baseConfig = {
title: value.title || key,
dataIndex: key,
formItemProps: {
required: schema.required?.includes(key),
help: value.description,
},
};
// 根据类型处理不同的表单项
switch (value.type) {
case 'string':
// 如果有枚举值,使用选择器
if (value.enum) {
return {
...baseConfig,
valueType: 'select',
fieldProps: {
options: value.enum.map((item, index) => ({
label: value.enumNames?.[index] || item,
value: item,
})),
placeholder: `请选择${value.title || key}`,
},
};
}
// 否则使用文本输入框
return {
...baseConfig,
valueType: 'text',
fieldProps: {
placeholder: `请输入${value.title || key}`,
},
};
case 'number':
case 'integer':
return {
...baseConfig,
valueType: 'digit',
fieldProps: {
min: value.minimum,
max: value.maximum,
placeholder: `请输入${value.title || key}`,
style: { width: '100%' }
},
};
case 'boolean':
return {
...baseConfig,
valueType: 'switch',
};
case 'array':
// 处理数组类型的枚举值,支持两种方式:
// 1. enum 定义在 items 中
// 2. enum 直接定义在属性上
if (value.items?.enum || value.enum) {
const enumValues = value.items?.enum || value.enum || [];
const enumNames = value.items?.enumNames || value.enumNames;
return {
...baseConfig,
valueType: 'select',
fieldProps: {
mode: 'multiple',
options: enumValues.map((item, index) => ({
label: enumNames?.[index] || item,
value: item,
})),
placeholder: `请选择${value.title || key}`,
},
};
}
// 否则使用标签输入
return {
...baseConfig,
valueType: 'select',
fieldProps: {
mode: 'tags',
placeholder: `请输入${value.title || key}`,
},
};
case 'object':
return {
...baseConfig,
valueType: 'jsonCode',
fieldProps: {
placeholder: `请输入${value.title || key}`,
},
};
default:
return {
...baseConfig,
valueType: 'text',
fieldProps: {
placeholder: `请输入${value.title || key}`,
},
};
}
});
};