提交 2488633e 作者: yueyang.lv

feat:对接费用管理,mui 支持中文支持

上级 f0e00dd8
registry=https://registry.npmmirror.com
......@@ -37,6 +37,7 @@
"chart.js": "^2.9.3",
"codemirror": "^5.52.2",
"history": "^4.10.1",
"js-cookie": "^3.0.1",
"kbar": "^0.1.0-beta.27",
"local-storage-fallback": "^4.1.1",
"lodash": "^4.17.21",
......
......@@ -21,6 +21,7 @@ import { hot } from "react-hot-loader/root";
import ProtectedRoute from "./ProtectedRoutes";
import LoadingComponent from "./common/LoadingComponent";
import AppConsole from "./screens/Console/ConsoleKBar";
import { fullRouters } from "./screens/Console/Saturn/routes";
const Login = React.lazy(() => import("./screens/LoginPage/LoginPage"));
const LoginCallback = React.lazy(
......@@ -49,6 +50,18 @@ const Routes = () => {
</Suspense>
)}
/>
{fullRouters.map((router) => (
<Route
exact
path={router.path}
key={router.path}
children={(routerProps) => (
<Suspense fallback={<LoadingComponent />}>
<router.component />
</Suspense>
)}
/>
))}
<ProtectedRoute Component={AppConsole} />
</Switch>
</Router>
......
......@@ -18,6 +18,7 @@ import request from "superagent";
import get from "lodash/get";
import { clearSession } from "../utils";
import { ErrorResponseHandler } from "../types";
import { toLoginPage } from "../../utils/toLogin";
export class API {
invoke(method: string, url: string, data?: object) {
......@@ -37,7 +38,8 @@ export class API {
clearSession();
// Refresh the whole page to ensure cache is clear
// and we dont end on an infinite loop
window.location.href = "/login";
// window.location.href = "/login";
toLoginPage();
return;
}
return this.onError(err);
......@@ -71,7 +73,7 @@ export class API {
return Promise.reject(throwMessage);
} else {
clearSession();
window.location.href = "/login";
toLoginPage();
}
}
}
......
......@@ -50,7 +50,7 @@ import {
import { hasPermission } from "../../common/SecureComponent";
import { IRouteRule } from "./Menu/types";
import LoadingComponent from "../../common/LoadingComponent";
import { saturnRoutes } from './Saturn';
import { saturnRoutes } from "./Saturn";
const Trace = React.lazy(() => import("./Trace/Trace"));
const Heal = React.lazy(() => import("./Heal/Heal"));
......@@ -107,6 +107,7 @@ const Dashboard = React.lazy(() => import("./Dashboard/Dashboard"));
const Account = React.lazy(() => import("./Account/Account"));
const Users = React.lazy(() => import("./Users/Users"));
const Groups = React.lazy(() => import("./Groups/Groups"));
const SaturnPage = React.lazy(() => import("./SaturnPage"));
const TenantDetails = React.lazy(
() => import("./Tenants/TenantDetails/TenantDetails")
......@@ -607,6 +608,11 @@ const Console = ({
<IconsScreen />
</Suspense>
</Route>
<Route key={"/saturnPage"} path={"/saturn/page"}>
<Suspense fallback={<LoadingComponent />}>
<SaturnPage />
</Suspense>
</Route>
{allowedRoutes.length > 0 ? (
<Redirect to={allowedRoutes[0].path} />
) : null}
......
......@@ -5,6 +5,8 @@ const createPath = (name: string) => {
export const PATH = {
/** 用户基本信息 */
LOGIN: createPath("/login"),
/** 用户基本信息 */
USERINFO: createPath("/userinfo"),
/** 费用管理 */
COST_MANAGE: createPath("/cost"),
......
......@@ -56,7 +56,7 @@ const columns: GridColDef[] = [
const CostHistory: React.FC = () => {
const [searchForm, setSearchForm] = useState<Pagination & Sort>({
page: 1,
pageSize: 2,
pageSize: 10,
total: 0,
sort: SORT.DESC.value,
});
......
import React from "react";
import React, { useEffect, useState } from "react";
import {
Card,
CardContent,
......@@ -13,10 +13,21 @@ import Link from "../../components/Link";
import PageLayout from "../../../Common/Layout/PageLayout";
import PageHeader from "../../../Common/PageHeader/PageHeader";
import Price from "../../components/Price";
import { getAccountMoneyInfo } from "../../services";
import { AccountMoneyInfo } from "../../services/interface";
import styles from "./index.module.css";
const Cost: React.FC = () => {
const [info, setInfo] = useState<Partial<AccountMoneyInfo>>({
balance: 0,
monthly_bill_money: 0,
});
useEffect(() => {
getAccountMoneyInfo().then((res) => {
setInfo(res.data);
});
}, []);
return (
<>
<PageHeader label="费用管理"></PageHeader>
......@@ -42,7 +53,7 @@ const Cost: React.FC = () => {
</div>
<div className={styles.content}>
<div className={styles.price}>
<Price value={50} />
<Price value={info.balance} />
</div>
<Box sx={{ "& button": { m: 1 } }}>
<Link to="/saturn/cost/recharge">
......@@ -70,7 +81,7 @@ const Cost: React.FC = () => {
</div>
<div className={styles.content}>
<div className={styles.price}>
<Price value={50} />
<Price value={info.monthly_bill_money} />
</div>
</div>
</div>
......
import React from 'react';
import React from "react";
import { IRouteRule } from "../Menu/types";
import {PATH} from './constants';
import { PATH } from "./constants";
const routes:IRouteRule[] = [
const routes: IRouteRule[] = [
{
component: React.lazy(() => import('./pages/UserInfo')),
component: React.lazy(() => import("./pages/UserInfo")),
path: PATH.USERINFO,
forceDisplay: true,
},
{
component: React.lazy(() => import('./pages/Cost')),
component: React.lazy(() => import("./pages/Cost")),
path: PATH.COST_MANAGE,
forceDisplay: true,
},
{
component: React.lazy(() => import('./pages/Cost/History')),
component: React.lazy(() => import("./pages/Cost/History")),
path: PATH.CONST_HISTORY,
forceDisplay: true,
},
{
component: React.lazy(() => import('./pages/Cost/Recharge')),
component: React.lazy(() => import("./pages/Cost/Recharge")),
path: PATH.CONST_RECHARGE,
forceDisplay: true,
},
{
component: React.lazy(() => import('./pages/Cost/Withdrawal')),
component: React.lazy(() => import("./pages/Cost/Withdrawal")),
path: PATH.CONST_WITHDRAWAL,
forceDisplay: true,
}
]
},
];
/** 全屏展示 */
export const fullRouters: IRouteRule[] = [
{
component: React.lazy(() => import("./pages/Login")),
path: PATH.LOGIN,
forceDisplay: true,
},
];
export default routes;
\ No newline at end of file
export default routes;
import request from "./request";
import { ResultListPromise, CostItem } from "./interface";
import {
ResultListPromise,
CostItem,
LoginRequestBody,
UserLoginResult,
ResultPromise,
AccountMoneyInfo,
} from "./interface";
import { Pagination, Sort } from "../types";
import { SORT } from "../constants";
/** 登陆 */
export const userLogin = (
data: LoginRequestBody
): ResultPromise<UserLoginResult> => {
return request.post("/api/user/login", data);
};
/** 账单列表 */
export const getCostList = (
options?: Pagination & Sort
......@@ -13,3 +27,8 @@ export const getCostList = (
sort: options?.sort || SORT.DESC.value,
});
};
/** 账户余额与消费合计信息 */
export function getAccountMoneyInfo(): ResultPromise<AccountMoneyInfo> {
return request.post("/api/user/account-money");
}
......@@ -10,8 +10,24 @@ export interface ResultBody<T> {
data: T;
}
export type ResultPromise<T> = Promise<ResultBody<T>>;
export type ResultListPromise<T> = Promise<ResultBody<ListResult<T>>>;
/** 登陆 Body */
export interface LoginRequestBody {
/** 用户名 */
user_name: string;
/** 密码 */
password: string;
}
/** 登录成功结果 */
export interface UserLoginResult {
console_url: string;
token: string;
plus_token: string;
}
/** 账单 */
export interface CostItem {
id: string;
......@@ -21,3 +37,11 @@ export interface CostItem {
transaction_money: number;
account_balance: number;
}
/** 账户余额信息 */
export interface AccountMoneyInfo {
/** 账户余额 */
balance: number;
/** 本月消费合计 */
monthly_bill_money: number;
}
......@@ -31,7 +31,7 @@ class Request {
return this.baseURL + url;
}
requestHandler({ url, methods, data }: RequestHandlerOptions) {
const req = superagent(methods, this.formateUrl(url)).withCredentials();
let req = superagent(methods, this.formateUrl(url)).withCredentials();
const resultSuccessCallback = (res) => {
const body = res.body;
......@@ -43,16 +43,16 @@ class Request {
}
return Promise.reject(res);
}
return body;
return Promise.resolve(body);
};
if (data) {
if (data.params && methods === METHOD.GET) {
return req.query(data.params).then(resultSuccessCallback);
if (methods === METHOD.GET) {
req = req.query(data);
}
return req.send(data).then(resultSuccessCallback);
req = req.send(data);
}
return req;
return req.then(resultSuccessCallback);
}
get(url, data?) {
return this.requestHandler({ url, methods: METHOD.GET, data });
......
import React from "react";
const SaturnPageComponent = () => {
return (
<>
<div>SaturnPageComponent</div>
</>
);
};
export default SaturnPageComponent;
import { createTheme } from "@mui/material";
import { zhCN } from "@mui/material/locale";
const theme = createTheme({
palette: {
primary: {
light: "#073052",
main: "#081C42",
dark: "#05122B",
contrastText: "#fff",
},
secondary: {
light: "#ff7961",
main: "#f44336",
dark: "#ba000d",
contrastText: "#000",
},
grey: {
100: "#f0f0f0",
200: "#e6e6e6",
300: "#cccccc",
400: "#999999",
500: "#8c8c8c",
600: "#737373",
700: "#666666",
800: "#4d4d4d",
900: "#333333",
},
background: {
default: "#fff",
},
success: {
main: "#4ccb92",
},
warning: {
main: "#FFBD62",
},
error: {
light: "#e03a48",
main: "#C83B51",
contrastText: "#fff",
},
},
typography: {
fontFamily: ["Lato", "sans-serif"].join(","),
h1: {
fontWeight: "bold",
color: "#081C42",
},
h2: {
fontWeight: "bold",
color: "#081C42",
},
h3: {
fontWeight: "bold",
color: "#081C42",
},
h4: {
fontWeight: "bold",
color: "#081C42",
},
h5: {
fontWeight: "bold",
color: "#081C42",
const theme = createTheme(
{
palette: {
primary: {
light: "#073052",
main: "#081C42",
dark: "#05122B",
contrastText: "#fff",
},
secondary: {
light: "#ff7961",
main: "#f44336",
dark: "#ba000d",
contrastText: "#000",
},
grey: {
100: "#f0f0f0",
200: "#e6e6e6",
300: "#cccccc",
400: "#999999",
500: "#8c8c8c",
600: "#737373",
700: "#666666",
800: "#4d4d4d",
900: "#333333",
},
background: {
default: "#fff",
},
success: {
main: "#4ccb92",
},
warning: {
main: "#FFBD62",
},
error: {
light: "#e03a48",
main: "#C83B51",
contrastText: "#fff",
},
},
h6: {
fontWeight: "bold",
color: "#000000",
typography: {
fontFamily: ["Lato", "sans-serif"].join(","),
h1: {
fontWeight: "bold",
color: "#081C42",
},
h2: {
fontWeight: "bold",
color: "#081C42",
},
h3: {
fontWeight: "bold",
color: "#081C42",
},
h4: {
fontWeight: "bold",
color: "#081C42",
},
h5: {
fontWeight: "bold",
color: "#081C42",
},
h6: {
fontWeight: "bold",
color: "#000000",
},
},
},
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 3,
height: 40,
padding: "0 20px",
fontSize: 14,
fontWeight: 600,
boxShadow: "none",
"& .min-icon": {
maxHeight: 18,
},
"&.MuiButton-contained.Mui-disabled": {
backgroundColor: "#EAEDEE",
components: {
MuiButton: {
styleOverrides: {
root: {
borderRadius: 3,
height: 40,
padding: "0 20px",
fontSize: 14,
fontWeight: 600,
color: "#767676",
},
"& .MuiButton-iconSizeMedium > *:first-of-type": {
fontSize: 12,
boxShadow: "none",
"& .min-icon": {
maxHeight: 18,
},
"&.MuiButton-contained.Mui-disabled": {
backgroundColor: "#EAEDEE",
fontWeight: 600,
color: "#767676",
},
"& .MuiButton-iconSizeMedium > *:first-of-type": {
fontSize: 12,
},
},
},
},
},
MuiPaper: {
styleOverrides: {
elevation1: {
boxShadow: "none",
border: "#EAEDEE 1px solid",
borderRadius: 3,
MuiPaper: {
styleOverrides: {
elevation1: {
boxShadow: "none",
border: "#EAEDEE 1px solid",
borderRadius: 3,
},
},
},
},
MuiListItem: {
styleOverrides: {
root: {
"&.MuiListItem-root.Mui-selected": {
background: "inherit",
"& .MuiTypography-root": {
fontWeight: "bold",
MuiListItem: {
styleOverrides: {
root: {
"&.MuiListItem-root.Mui-selected": {
background: "inherit",
"& .MuiTypography-root": {
fontWeight: "bold",
},
},
},
},
},
},
colors: {
link: "#2781B0",
},
},
colors: {
link: "#2781B0",
},
});
zhCN
);
declare module "@mui/material/styles" {
interface Theme {
......
import history from "../history";
/** 跳转到登录页 */
export const toLoginPage = (callbackUrl: boolean | string = true): void => {
if (typeof callbackUrl === 'boolean' && callbackUrl) {
if (typeof callbackUrl === "boolean" && callbackUrl) {
// 如果是 true 就是用当前 url 作为登录成功后回调地址
callbackUrl = encodeURIComponent(window.location.href)
callbackUrl = encodeURIComponent(window.location.href);
}
const queryStr = callbackUrl ? `?callbackUrl=${callbackUrl}` : ''
const queryStr = callbackUrl ? `?callbackUrl=${callbackUrl}` : "";
if (process.env.NODE_ENV === 'production') {
if (process.env.NODE_ENV === "production") {
let loginUrl = `https://xxyy.co/#/login${queryStr}`;
// 测试环境
if (window.location.host.endsWith('.kube.ucas')) {
loginUrl = `https://test-www.kube.ucas/login${queryStr}`
if (window.location.host.endsWith(".kube.ucas")) {
loginUrl = `https://test-www.kube.ucas/login${queryStr}`;
}
window.location.href = loginUrl;
} else {
history.push(`/login${queryStr}`);
window.location.href = `/saturn/login${queryStr}`;
}
}
};
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论