add animation

This commit is contained in:
wang_yp 2025-03-16 00:02:24 +08:00
parent af787ba1af
commit 6f37a95953
33 changed files with 387 additions and 516 deletions

View File

@ -122,11 +122,11 @@ module.exports = function (webpackEnv) {
options: cssOptions, options: cssOptions,
}, },
{ {
loader:'less-loader', loader: 'less-loader',
// loader: require.resolve('less-loader') // loader: require.resolve('less-loader')
options: { options: {
lessOptions: { lessOptions: {
javascriptEnabled: true, javascriptEnabled: true,
} }
} }
}, },
@ -143,34 +143,34 @@ module.exports = function (webpackEnv) {
config: false, config: false,
plugins: !useTailwind plugins: !useTailwind
? [ ? [
'postcss-flexbugs-fixes', 'postcss-flexbugs-fixes',
[ [
'postcss-preset-env', 'postcss-preset-env',
{ {
autoprefixer: { autoprefixer: {
flexbox: 'no-2009', flexbox: 'no-2009',
},
stage: 3,
}, },
], stage: 3,
// Adds PostCSS Normalize as the reset css with default options, },
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
'postcss-normalize',
]
: [
'tailwindcss',
'postcss-flexbugs-fixes',
[
'postcss-preset-env',
{
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
},
],
], ],
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
'postcss-normalize',
]
: [
'tailwindcss',
'postcss-flexbugs-fixes',
[
'postcss-preset-env',
{
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
},
],
],
}, },
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment, sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
}, },
@ -233,11 +233,11 @@ module.exports = function (webpackEnv) {
// Point sourcemap entries to original disk location (format as URL on Windows) // Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: isEnvProduction devtoolModuleFilenameTemplate: isEnvProduction
? info => ? info =>
path path
.relative(paths.appSrc, info.absoluteResourcePath) .relative(paths.appSrc, info.absoluteResourcePath)
.replace(/\\/g, '/') .replace(/\\/g, '/')
: isEnvDevelopment && : isEnvDevelopment &&
(info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')), (info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
}, },
cache: { cache: {
type: 'filesystem', type: 'filesystem',
@ -320,7 +320,7 @@ module.exports = function (webpackEnv) {
.map(ext => `.${ext}`) .map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')), .filter(ext => useTypeScript || !ext.includes('ts')),
alias: { alias: {
'@':path.join(__dirname,'../src/'), '@': path.join(__dirname, '../src/'),
// Support React Native Web // Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web', 'react-native': 'react-native-web',
@ -430,11 +430,11 @@ module.exports = function (webpackEnv) {
}, },
], ],
], ],
plugins: [ plugins: [
isEnvDevelopment && isEnvDevelopment &&
shouldUseReactRefresh && shouldUseReactRefresh &&
require.resolve('react-refresh/babel'), require.resolve('react-refresh/babel'),
].filter(Boolean), ].filter(Boolean),
// This is a feature of `babel-loader` for webpack (not Babel itself). // This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/ // It enables caching results in ./node_modules/.cache/babel-loader/
@ -464,7 +464,7 @@ module.exports = function (webpackEnv) {
cacheDirectory: true, cacheDirectory: true,
// See #6846 for context on why cacheCompression is disabled // See #6846 for context on why cacheCompression is disabled
cacheCompression: false, cacheCompression: false,
// Babel sourcemaps are needed for debugging into node_modules // Babel sourcemaps are needed for debugging into node_modules
// code. Without the options below, debuggers like VSCode // code. Without the options below, debuggers like VSCode
// show incorrect code and set breakpoints on the wrong lines. // show incorrect code and set breakpoints on the wrong lines.
@ -605,19 +605,19 @@ module.exports = function (webpackEnv) {
}, },
isEnvProduction isEnvProduction
? { ? {
minify: { minify: {
removeComments: true, removeComments: true,
collapseWhitespace: true, collapseWhitespace: true,
removeRedundantAttributes: true, removeRedundantAttributes: true,
useShortDoctype: true, useShortDoctype: true,
removeEmptyAttributes: true, removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true, removeStyleLinkTypeAttributes: true,
keepClosingSlash: true, keepClosingSlash: true,
minifyJS: true, minifyJS: true,
minifyCSS: true, minifyCSS: true,
minifyURLs: true, minifyURLs: true,
}, },
} }
: undefined : undefined
) )
), ),
@ -625,8 +625,8 @@ module.exports = function (webpackEnv) {
// a network request. // a network request.
// https://github.com/facebook/create-react-app/issues/5358 // https://github.com/facebook/create-react-app/issues/5358
isEnvProduction && isEnvProduction &&
shouldInlineRuntimeChunk && shouldInlineRuntimeChunk &&
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]), new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]),
// Makes some environment variables available in index.html. // Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.: // The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico"> // <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
@ -645,21 +645,21 @@ module.exports = function (webpackEnv) {
// Experimental hot reloading for React . // Experimental hot reloading for React .
// https://github.com/facebook/react/tree/main/packages/react-refresh // https://github.com/facebook/react/tree/main/packages/react-refresh
isEnvDevelopment && isEnvDevelopment &&
shouldUseReactRefresh && shouldUseReactRefresh &&
new ReactRefreshWebpackPlugin({ new ReactRefreshWebpackPlugin({
overlay: false, overlay: false,
}), }),
// Watcher doesn't work well if you mistype casing in a path so we use // Watcher doesn't work well if you mistype casing in a path so we use
// a plugin that prints an error when you attempt to do this. // a plugin that prints an error when you attempt to do this.
// See https://github.com/facebook/create-react-app/issues/240 // See https://github.com/facebook/create-react-app/issues/240
isEnvDevelopment && new CaseSensitivePathsPlugin(), isEnvDevelopment && new CaseSensitivePathsPlugin(),
isEnvProduction && isEnvProduction &&
new MiniCssExtractPlugin({ new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output // Options similar to the same options in webpackOptions.output
// both options are optional // both options are optional
filename: 'static/css/[name].[contenthash:8].css', filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css', chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}), }),
// Generate an asset manifest file with the following content: // Generate an asset manifest file with the following content:
// - "files" key: Mapping of all asset filenames to their corresponding // - "files" key: Mapping of all asset filenames to their corresponding
// output file so that tools can pick it up without having to parse // output file so that tools can pick it up without having to parse
@ -696,92 +696,100 @@ module.exports = function (webpackEnv) {
// Generate a service worker script that will precache, and keep up to date, // Generate a service worker script that will precache, and keep up to date,
// the HTML & assets that are part of the webpack build. // the HTML & assets that are part of the webpack build.
isEnvProduction && isEnvProduction &&
fs.existsSync(swSrc) && fs.existsSync(swSrc) &&
new WorkboxWebpackPlugin.InjectManifest({ new WorkboxWebpackPlugin.InjectManifest({
swSrc, swSrc,
dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./, dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/], exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
// Bump up the default maximum size (2mb) that's precached, // Bump up the default maximum size (2mb) that's precached,
// to make lazy-loading failure scenarios less likely. // to make lazy-loading failure scenarios less likely.
// See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270 // See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
}), }),
// TypeScript type checking // TypeScript type checking
useTypeScript && useTypeScript &&
new ForkTsCheckerWebpackPlugin({ new ForkTsCheckerWebpackPlugin({
async: isEnvDevelopment, async: isEnvDevelopment,
typescript: { typescript: {
typescriptPath: resolve.sync('typescript', { typescriptPath: resolve.sync('typescript', {
basedir: paths.appNodeModules, basedir: paths.appNodeModules,
}), }),
configOverwrite: { configOverwrite: {
compilerOptions: { compilerOptions: {
sourceMap: isEnvProduction sourceMap: isEnvProduction
? shouldUseSourceMap ? shouldUseSourceMap
: isEnvDevelopment, : isEnvDevelopment,
skipLibCheck: true, skipLibCheck: true,
inlineSourceMap: false, inlineSourceMap: false,
declarationMap: false, declarationMap: false,
noEmit: true, noEmit: true,
incremental: true, incremental: true,
tsBuildInfoFile: paths.appTsBuildInfoFile, tsBuildInfoFile: paths.appTsBuildInfoFile,
},
}, },
context: paths.appPath,
diagnosticOptions: {
syntactic: true,
},
mode: 'write-references',
// profile: true,
}, },
issue: { context: paths.appPath,
// This one is specifically to match during CI tests, diagnosticOptions: {
// as micromatch doesn't match syntactic: true,
// '../cra-template-typescript/template/src/App.tsx'
// otherwise.
include: [
{ file: '../**/src/**/*.{ts,tsx}' },
{ file: '**/src/**/*.{ts,tsx}' },
],
exclude: [
{ file: '**/src/**/__tests__/**' },
{ file: '**/src/**/?(*.){spec|test}.*' },
{ file: '**/src/setupProxy.*' },
{ file: '**/src/setupTests.*' },
],
}, },
logger: { mode: 'write-references',
infrastructure: 'silent', // profile: true,
}, },
}), issue: {
// This one is specifically to match during CI tests,
// as micromatch doesn't match
// '../cra-template-typescript/template/src/App.tsx'
// otherwise.
include: [
{ file: '../**/src/**/*.{ts,tsx}' },
{ file: '**/src/**/*.{ts,tsx}' },
],
exclude: [
{ file: '**/src/**/__tests__/**' },
{ file: '**/src/**/?(*.){spec|test}.*' },
{ file: '**/src/setupProxy.*' },
{ file: '**/src/setupTests.*' },
],
},
logger: {
infrastructure: 'silent',
},
}),
!disableESLintPlugin && !disableESLintPlugin &&
new ESLintPlugin({ new ESLintPlugin({
// Plugin options // Plugin options
extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'], extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
formatter: require.resolve('react-dev-utils/eslintFormatter'), formatter: require.resolve('react-dev-utils/eslintFormatter'),
eslintPath: require.resolve('eslint'), eslintPath: require.resolve('eslint'),
failOnError: !(isEnvDevelopment && emitErrorsAsWarnings), failOnError: !(isEnvDevelopment && emitErrorsAsWarnings),
context: paths.appSrc, context: paths.appSrc,
cache: true, cache: true,
cacheLocation: path.resolve( cacheLocation: path.resolve(
paths.appNodeModules, paths.appNodeModules,
'.cache/.eslintcache' '.cache/.eslintcache'
), ),
// ESLint class options // ESLint class options
cwd: paths.appPath, cwd: paths.appPath,
resolvePluginsRelativeTo: __dirname, resolvePluginsRelativeTo: __dirname,
baseConfig: { baseConfig: {
extends: [require.resolve('eslint-config-react-app/base')], extends: [require.resolve('eslint-config-react-app/base')],
rules: { rules: {
...(!hasJsxRuntime && { ...(!hasJsxRuntime && {
'react/react-in-jsx-scope': 'error', 'react/react-in-jsx-scope': 'error',
}), }),
},
}, },
}), },
}),
].filter(Boolean), ].filter(Boolean),
// Turn off performance processing because we utilize // Turn off performance processing because we utilize
// our own hints via the FileSizeReporter // our own hints via the FileSizeReporter
performance: false, performance: false,
devServer: {
proxy: [
{
context: ['/api'],
target: 'http://127.0.0.1:12215',
},
],
}
}; };
}; };

16
package-lock.json generated
View File

@ -1,11 +1,11 @@
{ {
"name": "ball_admin", "name": "store",
"version": "0.1.0", "version": "0.1.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ball_admin", "name": "store",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1", "@amap/amap-jsapi-loader": "^1.0.1",
@ -7637,9 +7637,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001660", "version": "1.0.30001704",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz", "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001704.tgz",
"integrity": "sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==", "integrity": "sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@ -39394,9 +39394,9 @@
} }
}, },
"caniuse-lite": { "caniuse-lite": {
"version": "1.0.30001660", "version": "1.0.30001704",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001660.tgz", "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001704.tgz",
"integrity": "sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==" "integrity": "sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew=="
}, },
"canvg": { "canvg": {
"version": "3.0.10", "version": "3.0.10",

View File

@ -94,6 +94,7 @@
"build": "node scripts/build.js", "build": "node scripts/build.js",
"test": "node scripts/test.js" "test": "node scripts/test.js"
}, },
"proxy": "http://127.0.0.1:12215/",
"eslintConfig": { "eslintConfig": {
"extends": [ "extends": [
"react-app", "react-app",

View File

@ -1,59 +0,0 @@
.modal {
width: 100%;
height: 100%;
position: fixed;
left: 0;
top: 0;
text-align: center;
z-index: 9999;
background: rgba(0, 0, 0, .45);
display: flex;
align-items: center;
justify-content: center;
animation-name: mode_animation;
animation-duration: .2s;
.modal-content {
min-width: 600px;
min-height: 300px;
background-color: white;
border-radius: 10px;
padding: 10px;
display: flex;
flex-direction: column;
.modal-header {
display: flex;
align-items: flex-end;
justify-content: flex-end;
.close-btn{
font-size: 20px;
font-weight: 800;
}
}
.model-cont{
flex-grow: 1;
}
.modal-footer{
display: flex;
border-top: 1px solid #ccc;
justify-content: space-around;
}
}
}
@keyframes mode_animation {
0% {
background: rgba(0, 0, 0, 0);
}
25% {
background: rgba(0, 0, 0, 0.1);
}
50% {
background: rgba(0, 0, 0, 0.25);
}
75% {
background: rgba(0, 0, 0, 0.35);
}
100% {
background: rgba(0, 0, 0, 0.45);
}
}

View File

@ -1,64 +0,0 @@
import React, { ReactNode, useEffect, useState } from "react";
// 使用ReactDOM.createPortal 动态创建弹窗
// 可以插入到dom任意节点不限于父节点
import { CloseOutlined } from "@ant-design/icons";
import ReactDOM from "react-dom";
import "./dilog.less";
interface DilogModel {
show: boolean;
close: Function;
children: ReactNode;
maskClosable: boolean;
title?: string;
okText?: string;
}
const Dilog = (props: DilogModel) => {
const [isShow, showState] = useState(false);
useEffect(() => {
showState(props.show);
const onClick = (ev:MouseEvent) => {
if (ev.target === document.getElementsByClassName("modal")[0]) {
showState(false);
props.close();
}
};
const handleKeyword = (e:KeyboardEvent) => {
if (e.eventPhase === 27) {
showState(false);
props.close();
}
};
document.documentElement.addEventListener("click", onClick);
document.documentElement.addEventListener("keydown", handleKeyword);
return () => {
document.documentElement.removeEventListener("click", onClick);
document.documentElement.removeEventListener("keydown", handleKeyword);
};
}, [props.show]);
const handleClose = () => {
showState(false);
props.close();
};
const childrens = (
<div className="modal">
<div className="modal-content">
<div className="modal-header">
<CloseOutlined className="close-btn" onClick={handleClose} />
</div>
<div className="model-cont">{props.children}</div>
<div className="modal-footer">
<button>{props.okText ?? "确认"}</button>
<button></button>
</div>
</div>
</div>
);
return isShow
? ReactDOM.createPortal(
childrens,
document.getElementById("root") as Element
)
: null;
};
export default Dilog;

View File

@ -45,9 +45,9 @@ const LayOut = (props: Store) => {
<Layout> <Layout>
<Header style={headStyle}> <Header style={headStyle}>
<div style={logoStyle}>logo</div> <div style={logoStyle}>logo</div>
<Dropdown menu={{ items }}> {/* <Dropdown menu={{ items }}> */}
<Avatar icon={<UserOutlined />} /> <Avatar icon={<UserOutlined />} />
</Dropdown> {/* </Dropdown> */}
</Header> </Header>
<Layout> <Layout>
<Sider <Sider
@ -65,7 +65,6 @@ const LayOut = (props: Store) => {
style={{ height: "100%", borderRight: 0 }} style={{ height: "100%", borderRight: 0 }}
items={items} items={items}
onClick={(e) => { onClick={(e) => {
console.log(e);
nav(e.key); nav(e.key);
}} }}
/> />

View File

@ -1,4 +1,7 @@
export const items = [ import { ItemType, MenuItemType } from 'antd/es/menu/interface';
export const items:ItemType<MenuItemType>[] = [
{ {
key: "/", key: "/",
label: `首页看板`, label: `首页看板`,
@ -11,25 +14,49 @@ export const items = [
], ],
}, },
{ {
key: "/source", key: "/sku",
label: `数据管理`, label: `商品管理`,
children: [ children: [
{ label: "数据管理", key: "/source/list" }, { key: "/sku/list", label: `商品列表` },
{ key: "/sku/cat", label: `商品分类` },
{ key: "/sku/spec", label: `商品规格` },
{ key: "/sku/brand", label: `商品品牌` },
], ],
}, },
{ {
key: "/permission", key: "/order",
label: `订单管理`,
children: [
{ key: "/order/list", label: `订单列表` },
],
},
{
key: "/rbac",
label: `权限管理`, label: `权限管理`,
children: [ children: [
{ label: `角色管理`, key: "/permission/role" }, { label: `角色管理`, key: "/rbac/role" },
{ label: `菜单管理`, key: "/permission/menu" }, { label: `菜单管理`, key: "/rbac/menu" },
{ label: `部门管理`, key: "/rbac/dep" },
{ label: `机构管理`, key: "/rbac/org" },
{ label: `员工管理`, key: "/rbac/org1" },
],
},
{
key: "/city",
label: `区域管理`,
children: [
{ label: `区域列表`, key: "/city/list" },
], ],
}, },
{ {
key: "/sys", key: "/sys",
label: `系统管理`, label: `系统管理`,
children: [ children: [
{ label: `部门管理`, key: "/dep" }, { label: `部门管理`, key: "/sys/dep" },
{ label: `数据字典`, key: "/sys/keywod" },
{ label: `版本管理`, key: "/sys/version" },
{ label: `捐赠管理`, key: "/sys/don" },
{ label: `通告管理`, key: "/sys/notic" },
], ],
}, },
]; ];

View File

@ -1,4 +1,4 @@
import { Button, Space } from "antd"; import { Space } from "antd";
import { inject, observer } from "mobx-react"; import { inject, observer } from "mobx-react";
import { Store } from "antd/lib/form/interface"; import { Store } from "antd/lib/form/interface";
import React from "react"; import React from "react";
@ -7,11 +7,11 @@ import "./index.less";
const Dashbord = (props: Store) => { const Dashbord = (props: Store) => {
return ( return (
<div className="contentBox"> <div className="contentBox">
<Space direction="vertical" size="middle" style={{ display: "flex" }}> <Space
<Button type="primary" onClick={() => props.usrStore.getUserList()}> direction="vertical"
size="middle"
</Button> style={{ display: "flex" }}
</Space> ></Space>
</div> </div>
); );
}; };

View File

@ -1,74 +1,75 @@
.login_model { .login_model {
width: 100%;
height: 100%;
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
.login_box {
text-align: right;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-repeat: no-repeat;
background-size: 100% 100%;
display: flex;
align-items: center;
justify-content: center;
.login_box {
text-align: right;
width: 100%;
height: 100%;
#login_basic { #login_basic {
width: 100%; width: 100%;
}
.container {
height: 100%;
}
.login-wrapper {
background-color: #fff;
width: 35%;
height: 400px;
border-radius: 15px;
padding: 0 50px;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 180px;
}
.input-item {
display: block;
width: 100%;
margin-bottom: 20px;
border: 0;
padding: 10px;
font-size: 15px;
outline: none;
}
.input-item:placeholder {
text-transform: uppercase;
}
.btn {
text-align: center;
cursor: pointer;
background-color: red;
color: #fff;
padding: 10px;
border-radius: 10px;
width: 100%;
margin-top: 40px;
}
.msg {
text-align: center;
line-height: 88px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
} }
} .container {
height: 100%;
}
.login-wrapper {
background-color: #ececec;
width: 40%;
border-radius: 15px;
padding: 50px;
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
}
.header {
font-size: 38px;
font-weight: bold;
text-align: center;
line-height: 180px;
}
.input-item {
display: block;
width: 100%;
margin-bottom: 20px;
border: 0;
padding: 10px;
font-size: 15px;
outline: none;
}
.input-item:placeholder {
text-transform: uppercase;
}
.btn {
text-align: center;
cursor: pointer;
background-color: blue;
color: #fff;
padding: 10px;
border-radius: 10px;
width: 300px;
margin-top: 40px;
}
.msg {
text-align: center;
line-height: 88px;
}
a {
text-decoration-line: none;
color: #abc1ee;
}
}
}

View File

@ -9,13 +9,15 @@ const Login = (props) => {
const formRef = React.useRef<FormInstance>(null); const formRef = React.useRef<FormInstance>(null);
const navigate = useNavigate(); const navigate = useNavigate();
const onFinish = async (values: any) => { const onFinish = async (values: any) => {
navigate("/", { replace: true });
return;
let status = await usrStore.login({ let status = await usrStore.login({
userName: values.account, userName: values.account,
passWord: values.password, passWord: values.password,
}); });
if (status) { if (status) {
usrStore.closeLoginDilog(); usrStore.closeLoginDilog();
navigate("/user/list", { replace: true }); navigate("/", { replace: true });
} }
}; };
const onFinishFailed = () => {}; const onFinishFailed = () => {};

11
src/pages/rbac/index.tsx Normal file
View File

@ -0,0 +1,11 @@
import { Outlet } from "react-router";
const Rbac = () => {
return (
<div>
<Outlet />
</div>
);
};
export default Rbac;

View File

@ -0,0 +1,9 @@
const Brand = () => {
return (
<div>
cat
</div>
);
};
export default Brand;

View File

@ -0,0 +1,9 @@
const Cat = () => {
return (
<div>
cat
</div>
);
};
export default Cat;

11
src/pages/sku/index.tsx Normal file
View File

@ -0,0 +1,11 @@
import { Outlet } from "react-router";
const Sku = () => {
return (
<div>
<Outlet />
</div>
);
};
export default Sku;

View File

@ -0,0 +1,9 @@
const Spec = () => {
return (
<div>
cat
</div>
);
};
export default Spec;

View File

@ -1,8 +0,0 @@
.contentBox{
overflow-y: auto;
height: 100%;
.tableName{
height: 100%;
overflow-y: auto;
}
}

View File

@ -1,50 +0,0 @@
import React, { useEffect, useState } from "react";
import { Space } from "antd";
import { Store } from "antd/lib/form/interface";
import { inject, observer } from "mobx-react";
import BTable from "@/components/b_table";
import "./source.less";
const Source = (props: Store) => {
const { sourceStore } = props;
const [coloums,setColumns] = useState([])
const [content,setContent] = useState([])
// 获取列表数据
useEffect(() => {
sourceStore.getHead().then((res)=>{
res.forEach(element => {
element.dataIndex = "dbs_"+element.identity.toLowerCase()
element.title = element.data_name
});
setColumns(res)
});
sourceStore.geContent().then((res)=>{
res.forEach(element => {
element.key = "dbs_"+element.identity
});
setContent(res)
});
}, [sourceStore]);
return (
<div className="contentBox">
<Space direction="vertical" size="middle" style={{ display: "flex" }}>
<BTable
store={sourceStore}
scroll={{ x: "max-content" }}
columns={coloums}
dataSource={content}
deleteCallback={(id) => {
sourceStore.deleteItem(id);
}}
actionCloumn={(e)=>{
}}
editCallback={(record) => {
}}
/>
</Space>
</div>
);
};
export default inject("sourceStore")(observer(Source));

View File

@ -1,22 +0,0 @@
import { FormType } from "@/components/form/interface";
import { UserDataType } from "@/model/userModel";
import { ColumnsType } from "antd/lib/table";
import dayjs from "dayjs";
export const defaultConfig = [
{
type: FormType.input,
label: "数据集名称",
name: "resource_name",
value: "",
rules: [{ required: true, message: "请输入用户名称!" }],
},
];
export const columns: ColumnsType<UserDataType> = [
{
title: "数据集名称",
dataIndex: "resource_name",
width: 200,
},
];

View File

@ -3,9 +3,8 @@ import LayOut from "@/components/layout/layout";
import Login from "@/pages/login/login"; import Login from "@/pages/login/login";
import User from "@/pages/user/user"; import User from "@/pages/user/user";
import Dashbord from "@/pages/dashbord"; import Dashbord from "@/pages/dashbord";
import Source from "@/pages/source/source"; import { rbac } from "./routers/rbac_router";
import Menu from "@/pages/menu/menu"; import { sku } from "./routers/sku_router";
import Role from "@/pages/role/role";
const routers = createHashRouter([ const routers = createHashRouter([
{ {
@ -22,21 +21,8 @@ const routers = createHashRouter([
index: true, index: true,
element: <User />, element: <User />,
}, },
{ ...rbac,
path: "/source/list", ...sku
index: true,
element: <Source />,
},
{
path: "/permission/menu",
index: true,
element: <Menu />,
},
{
path: "/permission/role",
index: true,
element: <Role />,
},
], ],
}, },
{ {

View File

@ -0,0 +1,21 @@
import Rbac from "@/pages/rbac";
import Menu from "@/pages/rbac/menu";
import Role from "@/pages/rbac/role";
export const rbac = [
{
path: "/rbac",
element: <Rbac />,
children: [
{
path: "/rbac/menu",
index: true,
element: <Menu />,
},
{
path: "/rbac/role",
index: true,
element: <Role />,
},
],
},
];

View File

@ -0,0 +1,33 @@
import Menu from "@/pages/rbac/menu";
import Sku from "@/pages/sku";
import Brand from "@/pages/sku/brand";
import Cat from "@/pages/sku/cat";
import Spec from "@/pages/sku/spec";
export const sku = [
{
path: "/sku",
element: <Sku />,
children: [
{
path: "/sku/list",
index: true,
element: <Menu />,
},
{
path: "/sku/cat",
index: true,
element: <Cat />,
},
{
path: "/sku/spec",
index: true,
element: <Spec />,
},
{
path: "/sku/brand",
index: true,
element: <Brand />,
},
],
},
];

View File

@ -1,7 +1,6 @@
import store from "@/store"; import store from "@/store";
import Config from "@/util/config"; import Config from "@/util/config";
import axios, { AxiosResponse } from "axios"; import axios, { AxiosResponse } from "axios";
// import { baseHttp } from '@/service/base';
// 添加请求拦截器 // 添加请求拦截器
axios.defaults.headers.common["Content-Type"] = "application/json; charset=utf8"; axios.defaults.headers.common["Content-Type"] = "application/json; charset=utf8";
axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest"; axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
@ -19,16 +18,16 @@ axios.interceptors.request.use((config) => {
// 添加响应拦截器 // 添加响应拦截器
axios.interceptors.response.use((res: AxiosResponse) => { axios.interceptors.response.use((res: AxiosResponse) => {
if (res.data?.status === 401) { if (res.data?.status === 401) {
store.usrStore.openLoginDilog() // store.usrStore.openLoginDilog()
store.usrStore.logOut() // store.usrStore.logOut()
window.location.href = '#/login' // window.location.href = '#/login'
} }
return res; return res;
}, (err) => { }, (err) => {
if (err.status === 401) { if (err.status === 401) {
store.usrStore.openLoginDilog() // store.usrStore.openLoginDilog()
store.usrStore.logOut() // store.usrStore.logOut()
window.location.href = '#/login' // window.location.href = '#/login'
} }
return Promise.reject(err); return Promise.reject(err);
}); });

View File

@ -1,10 +0,0 @@
class SourceConfig {
static ADD: string = "/desc";
static EDIT: string = "/desc";
static LIST: string = "/desc/content";
static DELETE: string = "/desc";
static Headers: string = "/desc/header";
static Content: string = "/desc/content";
}
export default SourceConfig;

View File

@ -1,5 +1,5 @@
class UserConfig { class UserConfig {
static LOGINURI: string = "/anth/login/pc" static LOGINURI: string = "/anth/login"
static ADD: string = "/user"; static ADD: string = "/user";
static EDIT: string = "/user"; static EDIT: string = "/user";
static LIST: string = "/user/list"; static LIST: string = "/user/list";

View File

@ -1,9 +1,7 @@
import usrStore from '@/store/user' import usrStore from '@/store/user'
import sourceStore from '@/store/source';
const store = { const store = {
usrStore, usrStore,
sourceStore
}; };
export default store; export default store;

View File

@ -1,41 +0,0 @@
import { action, makeObservable, observable } from "mobx";
import BaseStore from "./baseStore";
import { UserDataType } from "@/model/userModel";
import SourceConfig from "@/service/source_config";
import { base } from "@/service/base";
import { message } from "antd";
class SourceStore extends BaseStore<UserDataType> {
headlist =[]
contentList =[]
constructor() {
super(SourceConfig)
makeObservable(this, {
getHead:action,
headlist:observable,
contentList:observable
})
}
async getHead(){
let res = await base.get(SourceConfig.Headers, {})
if (res.code !== 200) {
message.error(res.msg)
return false
}
this.headlist = res.data.record;
return res.data.record;
}
async geContent(){
let res = await base.get(SourceConfig.Content, {})
if (res.code !== 0) {
message.error(res.msg)
return false
}
this.contentList = res.data;
return res.data;
}
}
const sourceStore = new SourceStore();
export default sourceStore;

View File

@ -1,4 +1,5 @@
class Config { class Config {
static baseUrl = "http://127.0.0.1:12214/v1"; static baseUrl = "/v1";
// static baseUrl = "http://127.0.0.1:12215/v1";
} }
export default Config; export default Config;