Merge branch 'develop' of https://github.com/opengoofy/hippo4j into develop

pull/1470/head
MZR 2 years ago
commit adcca1aacf

@ -1,35 +1,41 @@
{
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[jsonc]": {
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"typescript.tsdk":"./node_modules/typescript/lib"
}
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"[javascriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"[less]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnPaste": true,
"editor.formatOnSave": true
},
"typescript.tsdk": "./node_modules/typescript/lib"
}

@ -46,7 +46,8 @@ const config = {
sidebarPath: require.resolve("./sidebars.js"),
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
sidebarCollapsed: false,
// Do not automatically expand the menu
sidebarCollapsed: true,
/*editUrl: 'https://github.com/longtai-cn',*/
},
blog: {
@ -92,10 +93,11 @@ const config = {
autoCollapseCategories: true,
announcementBar: {
id: "announcementBar-1", // Increment on change
// content: `⭐️ If you like hippo4j, give it a star on <a target="_blank" rel="noopener noreferrer" href="https://gitee.com/mabaiwancn/hippo4j">Gitee</a>, thanks.`,
// content: `⭐️ 如果您喜欢 hippo4j请在 <a target="_blank" rel="noopener noreferrer" href="https://gitee.com/mabaiwancn/hippo4j">Gitee</a> 和 <a target="_blank" rel="noopener noreferrer" href="https://github.com/opengoofy/hippo4j">GitHub</a> 上给它一个 star谢谢`,
content: `⭐️ 开源不易,如果 Hippo4j 对您有帮助,请在 <a target="_blank" rel="noopener noreferrer" href="https://github.com/opengoofy/hippo4j">GitHub</a> 上给它一个 Star 🌟`,
// content: `<a target="_blank" rel="noopener noreferrer" href="https://xiaomage.info/knowledge-planet/">👉 《小马哥的代码实战课》官方知识星球来啦!!!</a>`,
content:
'⭐️ If you like hippo4j, give it a star on <a target="_blank" rel="noopener noreferrer" href="https://github.com/opengoofy/hippo4j">GitHub</a> ⭐️',
backgroundColor: "#fafbfc",
textColor: "#091E42",
isCloseable: false,
},
navbar: {
title: "",

@ -36,7 +36,7 @@
"description": "The label of footer link with label=公司登记 linking to https://github.com/opengoofy/hippo4j/issues/13"
},
"copyright": {
"message": "Copyright © 2021-2022 小马哥版权所有 <a href=\"https://beian.miit.gov.cn\">京ICP备2021038095号-2\n</a>",
"message": "Copyright © 2021-2023 马丁@版权所有 <a href=\"https://beian.miit.gov.cn\">京ICP备2021038095号-2\n</a>",
"description": "The footer copyright"
},
"link.title.Links": {

@ -9,30 +9,19 @@ const Hero = () => {
const bgUrl = useBaseUrl("/img/bg.jpg");
return (
<div className=" h-[100vh] lg:h-[65vh] relative text-black dark:text-white">
<div
// style={{ backgroundImage: `url(${bgUrl})` }}
className="bg-svg absolute inset-0 overflow-hidden bg-repeat"
>
<div className="absolute inset-0 bg-gray-400 opacity-5 dark:opacity-0"></div>
<div className=" h-[100vh] lg:h-[58vh] relative text-black dark:text-white">
<div className=" absolute inset-0 overflow-hidden bg-repeat">
{/* <div className="absolute inset-0 bg-gray-400 opacity-5 dark:opacity-0"></div> */}
<div className=" container px-20 py-12 lg:py-16 md:py-8 lg:px-20 md:px-10 mx-auto flex flex-wrap flex-col lg:flex-row items-center">
<div className=" container px-20 py-12 lg:py-8 md:py-8 lg:px-20 md:px-10 mx-auto flex flex-wrap flex-col lg:flex-row items-center">
{/* <!--Left Col--> */}
<div className="flex flex-col w-full lg:w-1/2 md:w-2/3 justify-center items-start text-center md:text-left">
{/* title and desc */}
<div>
<h1 className="my-4 font-jakarta lg:my-4 md:my-4 text-5xl font-bold leading-tight ">
<h1 className="my-4 font-jakarta lg:my-8 md:my-4 text-5xl font-bold leading-tight ">
Hippo4j Thread Pool
</h1>
{/* <p className="leading-normal dark:text-white font-bold text-gray-800 hero-image-url text-3xl md:text-3xl">
<Translate
id="homepage.titleDescription1"
description="The homepage title description"
>
Thread Pool Framework For Java
</Translate>
</p> */}
<p className="leading-normal hero-image-url text-gray-600 dark:text-gray-100 text-xl mb-0">
<Translate
id="homepage.titleDescription2"
@ -46,65 +35,12 @@ const Hero = () => {
{/* button group */}
<div className="flex my-4 lg:my-8 md:my-6 w-full justify-center md:justify-start">
{/* <Link to="/docs/user_docs/intro" className="">
<button className="mr-2 lg:mr-4 text-base lg:text-lg w-32 lg:w-40 hover:bg-blue-500 bg-blue-400 font-medium py-2 px-4 rounded-md focus:outline-none shadow-none border-none cursor-pointer transition-all duration-300 ease-in-out">
<Translate
className="cursor-pointer"
id="homepage.startButton"
description="The homepage start button text"
>
Quick Start
</Translate>
</button>
</Link>
<a href="https://github.com/opengoofy/hippo4j">
<button className="ml-2 lg:mx-0 w-32 lg:w-40 border-1 border-solid dark:border-gray-500 border-gray-400 bg-transparent hover:bg-gray-400 hover:bg-opacity-50 font-medium py-2 px-4 rounded-md focus:outline-none shadow-none cursor-pointer transition-all duration-300 ease-in-out">
<div className="flex cursor-pointer items-center justify-center">
<Icon
className="w-6 h-6 mr-2 rounded-full flex-shrink-0 dark:bg-white"
icon="devicon:github"
/>
<span className="text-base lg:text-lg">GitHub</span>
</div>
</button>
</a> */}
<Link
to="/docs/user_docs/intro"
class="relative mr-4 w-32 text-center lg:w-48 hover:no-underline inline-flex items-center justify-start py-3 overflow-hidden font-semibold text-white transition-all duration-150 ease-in-out rounded bg-blue-500 group"
>
<span class="absolute bottom-0 left-0 w-full h-1 transition-all duration-150 ease-in-out bg-blue-600 group-hover:h-full"></span>
{/* <span class="absolute right-0 pr-4 duration-200 ease-out group-hover:translate-x-12">
<svg
class="w-5 h-5 text-white"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M14 5l7 7m0 0l-7 7m7-7H3"
></path>
</svg>
</span> */}
{/* <span class="absolute left-0 pl-2.5 -translate-x-12 group-hover:translate-x-0 ease-out duration-200">
<svg
class="w-5 h-5 text-gray-200"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M14 5l7 7m0 0l-7 7m7-7H3"
></path>
</svg>
</span> */}
<span class="relative w-full text-center transition-colors duration-200 ease-in-out group-hover:text-white">
Start Learning
</span>
@ -125,13 +61,6 @@ const Hero = () => {
/>
Github
</span>
{/* <div className="flex cursor-pointer items-center justify-center">
<Icon
className="w-6 h-6 mr-2 rounded-full flex-shrink-0 dark:bg-white"
icon="devicon:github"
/>
<span className="text-base lg:text-lg">GitHub</span>
</div> */}
</span>
<span
class="absolute bottom-0 right-0 w-full h-12 -mb-1 -mr-1 transition-all duration-200 ease-linear bg-gray-900 rounded-lg group-hover:mb-0 group-hover:mr-0"

@ -3,19 +3,19 @@ import useBaseUrl from "@docusaurus/useBaseUrl";
import Translate from "@docusaurus/Translate";
const Introduction = () => {
return (
<section className=" border-b mb-28 dark:text-white">
<div className=" ">
<div className="title-container w-full bg-gray-50 p-4 mb-4 flex flex-wrap dark:bg-[#242526]">
<section className="mb-28 dark:text-white">
<div className="introduction-container ">
<div className="title-container w-full bg-[#EFEFEF] p-4 mb-12 flex flex-wrap dark:bg-[#242526]">
<div className="left-image-container px-24 w-full md:w-1/2 sm:w-1/3">
<img
className="w-full -mt-8 h-64 object-cover lg:h-80 md:h-96 dark:rounded-lg "
className="w-full -mt-8 h-64 object-contain lg:h-64 md:h-96 dark:rounded-lg "
alt="Hippo4j System"
src={useBaseUrl("/img/introduction/t2.svg")}
/>
{/* <div className="introduction-title-image h-64 w-full img-div"></div> */}
</div>
<div className="right-title-container py-4 px-16 md:px-4 md:pt-8 w-full md:w-1/2 sm:w-2/3 sm:px-8">
<h2 className="w-full my-2 text-3xl font-medium leading-tight text-gray-800 dark:text-white ">
<h2 className="w-full my-2 text-3xl font-medium leading-tight dark:text-white ">
<Translate
id="homepage.secondTitle"
description="The title for the introduction part"
@ -23,15 +23,8 @@ const Introduction = () => {
What can Hippo4j do?
</Translate>
</h2>
<p className=" my-4 leading-relaxed dark:text-white text-xl font-medium text-gray-800 md:pr-20 ">
<Translate
id="homepage.secondTitleDesc1"
description="The p1 for the secondTitle part"
>
Hippo4j is a Java thread pool framework.
</Translate>
</p>
<p className="leading-normal max-w-xl md:pr-10 text-gray-600 dark:text-gray-100 mb-2">
<p className="leading-normal mt-8 max-w-xl md:pr-10 dark:text-white mb-2">
<Translate
id="homepage.secondTitleDesc2"
description="The p2 for the secondTitle part"
@ -44,10 +37,17 @@ const Introduction = () => {
</div>
</div>
<div class="container px-20 lg:px-36 md:px-10 three-part-container">
<div class="container px-20 lg:px-20 md:px-10 three-part-container">
<div class="flex flex-wrap pt-6">
<div class="w-full pr-4 sm:w-2/3 md:w-1/2 ">
<h3 class="text-2xl md:pb-6 text-gray-800 dark:text-white font-medium leading-none mb-3">
<div class="w-full sm:w-1/3 md:w-1/4 ">
<img
className="w-full -mt-4 h-auto sm:h-64 object-contain lg:h-52 md:h-72 dark:rounded-lg "
src={useBaseUrl("/img/introduction/p11.svg")}
alt="Hippo4j System"
/>
</div>
<div class="w-full pr-4 sm:w-2/3 md:w-1/2 flex-grow ">
<h3 class="text-2xl dark:text-white font-normal leading-none ">
<Translate
id="homepage.introduction.fristPartTitle"
description="the title for the first introduction part"
@ -55,10 +55,10 @@ const Introduction = () => {
Dynamic Change
</Translate>
</h3>
<div class="dark:text-white text-gray-600 mb-8">
<div class="dark:text-white mb-8 ">
<p>
<Translate
className="cursor-pointer"
className="cursor-pointer "
id="homepage.introduction.fristPartDesc1"
description="The first desc for fristPart "
>
@ -66,48 +66,13 @@ const Introduction = () => {
parameters.
</Translate>{" "}
</p>
<p>
<Translate
className="cursor-pointer"
id="homepage.introduction.fristPartDesc2"
description="The second desc for fristPart "
>
Including but not limited to core size, maximum threads,
blocking queue size, and rejection policy.
</Translate>
</p>
<p>
<Translate
className="cursor-pointer"
id="homepage.introduction.fristPartDesc3"
description="The third desc for fristPart "
>
It supports differentiated thread pool configurations for
different nodes in the application cluster.
</Translate>
</p>
</div>
</div>
<div class="w-full sm:w-1/3 md:w-1/2 ">
{/* <img class="mx-auto w-4/5 z-50" src="f1.png" /> */}
<img
className="w-full -mt-4 h-auto sm:h-64 object-contain lg:h-80 md:h-72 dark:rounded-lg "
src={useBaseUrl("/img/introduction/p11.svg")}
alt="Hippo4j System"
/>
</div>
</div>
<div class="flex flex-wrap pt-6 flex-col-reverse sm:flex-row">
<div class="w-full pr-16 sm:w-1/3 md:w-1/2 mt-6">
<img
className="w-full h-auto sm:h-64 object-contain lg:h-80 md:h-96 dark:rounded-lg "
src={useBaseUrl("/img/introduction/p22.svg")}
alt="Hippo4j System"
/>
</div>
<div class="w-full sm:w-2/3 md:w-1/2 md:pl-16 sm:pl-8 mt-6 lg:pt-8">
<div class="align-middle">
<h3 class="text-2xl md:pb-6 text-gray-800 dark:text-white font-medium leading-none mb-3">
<div class="flex flex-wrap md:-mt16 flex-col-reverse sm:flex-row">
<div class="w-full flex-grow sm:w-2/3 md:w-2/3 md:pl-[28rem] sm:pl-8 mt-6 lg:pt-8">
<div class="align-middle ">
<h3 class="text-2xl dark:text-white font-normal leading-none mb-3">
<Translate
id="homepage.introduction.secondPartTitle"
description="the title for the second introduction part"
@ -115,7 +80,7 @@ const Introduction = () => {
Custom Alarm
</Translate>
</h3>
<div class="dark:text-white text-gray-600 mb-8">
<div class="dark:text-white mb-8">
<p>
<Translate
className="cursor-pointer"
@ -126,33 +91,28 @@ const Introduction = () => {
alarm dimensions.
</Translate>
</p>
<p>
<Translate
className="cursor-pointer"
id="homepage.introduction.secondPartDesc2"
description="The second desc for secondPart "
>
Thread pool overload, blocking queue capacity, running for
too long, and rejection strategy alarm.
</Translate>{" "}
</p>
<p>
<Translate
className="cursor-pointer"
id="homepage.introduction.secondPartDesc3"
description="The third desc for secondPart "
>
It also supports non-repetitive alarms within a custom
time period.
</Translate>
</p>
</div>
</div>
</div>
<div class="w-full sm:w-1/3 md:w-1/4 mt-6">
<img
className="w-full h-auto sm:h-64 object-contain lg:h-52 md:h-96 dark:rounded-lg "
src={useBaseUrl("/img/introduction/p22.svg")}
alt="Hippo4j System"
/>
</div>
</div>
<div class="flex flex-wrap pt-6">
<div class="w-5/6 sm:w-2/3 md:w-1/2 sm:pr-8 md:pr-4">
<h3 class="text-2xl md:py-6 text-gray-800 dark:text-white font-medium leading-none mb-3">
<div class="flex mt-2 flex-wrap">
<div class="w-full sm:w-1/3 md:w-1/4 ">
<img
className="w-full -mt-4 h-auto sm:h-64 object-contain lg:h-60 md:h-72 dark:rounded-lg "
src={useBaseUrl("/img/introduction/p33.svg")}
alt="Hippo4j System"
/>
</div>
<div class="w-full pr-4 sm:w-2/3 md:w-1/2 md:mt-8 flex-grow ">
<h3 class="text-2xl dark:text-white font-normal leading-none ">
<Translate
id="homepage.introduction.thirdPartTitle"
description="the title for the third introduction part"
@ -160,8 +120,8 @@ const Introduction = () => {
Operation Monitoring
</Translate>
</h3>
<div class="dark:text-white text-gray-600 mb-8 md:pr-6">
<p>
<div class="dark:text-white mb-8">
<p className="m-0">
<Translate
className="cursor-pointer"
id="homepage.introduction.thirdPartDesc1"
@ -171,36 +131,8 @@ const Introduction = () => {
storage.
</Translate>
</p>
<p>
<Translate
className="cursor-pointer"
id="homepage.introduction.thirdPartDesc2"
description="The second desc for thirdPart "
>
while also supporting Prometheus, InfluxDB, and other
monitoring systems.
</Translate>
</p>
<p>
<Translate
className="cursor-pointer"
id="homepage.introduction.thirdPartDesc3"
description="The third desc for thirdPart "
>
Provides visualized dashboard monitoring metrics through
Grafana or built-in monitoring pages.
</Translate>
</p>
</div>
</div>
<div class="w-full sm:w-1/3 md:w-1/2 ">
{/* <img class="mx-auto w-4/5 z-50" src="f3_r.png" /> */}
<img
className="w-full -mt-16 -ml-16 h-auto sm:h-64 object-contain lg:h-80 md:h-96 dark:rounded-lg "
src={useBaseUrl("/img/introduction/p33.svg")}
alt="Hippo4j System"
/>
</div>
</div>
</div>
</div>

@ -1,4 +1,5 @@
import React from "react";
import { useEffect } from "react";
import Hero from "./Hero";
import Introduction from "./Introduction";
function LandingLayout(props) {

@ -26,6 +26,10 @@
--site-color-checkbox-checked-bg: hsl(167deg 56% 73% / 25%);
--site-color-feedback-background: #fff;
--ifm-font-family-base: "Poppins";
/* custom */
--docs-color-primary-tint: #2160fd29;
--ifm-breadcrumb-item-background-active: #0000000d;
--ifm-breadcrumb-color-active: #2160fd;
}
html[data-theme="dark"] {
@ -35,7 +39,7 @@ html[data-theme="dark"] {
}
[data-theme="light"] {
--ifm-color-primary: hsl(var(--site-primary-hue-saturation) 30%);
--ifm-color-primary: #2160fd;
--ifm-color-primary-dark: hsl(var(--site-primary-hue-saturation) 26%);
--ifm-color-primary-darker: hsl(var(--site-primary-hue-saturation) 23%);
--ifm-color-primary-darkest: hsl(var(--site-primary-hue-saturation) 17%);
@ -47,13 +51,10 @@ html[data-theme="dark"] {
--ifm-color-primary-lightest: hsl(
var(--site-primary-hue-saturation-light) 58%
);
--ifm-breadcrumb-item-background-active: #0000000d;
--ifm-breadcrumb-color-active: #2160fd;
}
[data-theme="dark"] {
--ifm-color-primary: hsl(var(--site-primary-hue-saturation) 45%);
--ifm-color-primary: #1a90ff;
--ifm-color-primary-dark: hsl(var(--site-primary-hue-saturation) 41%);
--ifm-color-primary-darker: hsl(var(--site-primary-hue-saturation) 38%);
--ifm-color-primary-darkest: hsl(var(--site-primary-hue-saturation) 32%);
@ -65,9 +66,8 @@ html[data-theme="dark"] {
--ifm-color-primary-lightest: hsl(
var(--site-primary-hue-saturation-light) 73%
);
/* --ifm-breadcrumb-item-background-active: #333333; */
--ifm-breadcrumb-color-active: #ffffff;
--ifm-breadcrumb-item-background-active: #222222;
--ifm-breadcrumb-color-active: #1a90ff;
}
.docusaurus-highlight-code-line {
@ -124,8 +124,6 @@ html[data-theme="dark"] {
}
[data-theme="light"] .DocSearch {
/* --docsearch-primary-color: var(--ifm-color-primary); */
/* --docsearch-text-color: var(--ifm-font-color-base); */
--docsearch-muted-color: var(--ifm-color-emphasis-700);
--docsearch-container-background: rgb(94 100 112 / 70%);
/* Modal */
@ -233,8 +231,8 @@ div[class^="announcementBar_"] {
:root[data-theme="light"] {
--hero-image-url: url("../../static/img/hero/hero-removebg.png");
--bg-background-color: #f9fafb;
--bg-background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48' viewBox='0 0 48 48'%3E%3Cg fill='%23bfbfbf' fill-opacity='0.4'%3E%3Cpath fill-rule='evenodd' d='M5 3.59L1.46.05.05 1.46 3.59 5 .05 8.54l1.41 1.41L5 6.41l3.54 3.54 1.41-1.41L6.41 5l3.54-3.54L8.54.05 5 3.59zM17 2h24v2H17V2zm0 4h24v2H17V6zM2 17h2v24H2V17zm4 0h2v24H6V17z'/%3E%3C/g%3E%3C/svg%3E");
--bg-background-color: #ffffff;
--bg-background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='199' viewBox='0 0 100 199'%3E%3Cg fill='%23dddddd' fill-opacity='0.4'%3E%3Cpath d='M0 199V0h1v1.99L100 199h-1.12L1 4.22V199H0zM100 2h-.12l-1-2H100v2z'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
}
:root[data-theme="dark"] {
@ -259,3 +257,47 @@ div[class^="announcementBar_"] {
.font-jakarta {
font-family: "Plus Jakarta Sans", sans-serif;
}
/* sidebar style */
ul.menu__list > li > a.menu__link--active {
border-right: 1px solid var(--ifm-color-primary);
}
nav.menu {
padding-right: 0px;
scrollbar-gutter: auto;
}
.menu__link {
border-radius: 4px 0 0 4px;
--ifm-menu-color-background-active: var(--docs-color-primary-tint);
}
/* other style */
::selection {
--tw-text-opacity: 1;
background-color: rgb(var(--docs-color-primary-200, 33 96 253) / 0.8);
color: rgb(255 255 255 / var(--tw-text-opacity));
}
div[class^="announcementBar_"] {
font-size: 14px;
background: none;
background-color: #fafbfc;
padding: 8px 0;
display: flex;
justify-content: center;
font-weight: inherit;
}
div[class^="announcementBar_"] a {
text-decoration: underline;
color: #091e42;
}
.introduction-container {
color: #1c1e21;
}
.three-part-container p {
margin: 0;
line-height: 2;
}

@ -1,4 +1,5 @@
import React from "react";
import { useEffect } from "react";
import clsx from "clsx";
import Link from "@docusaurus/Link";
// import Translate from "@docusaurus/Translate";
@ -43,6 +44,7 @@ function HomepageHeader() {
export default function Home() {
const { siteConfig } = useDocusaurusContext();
return (
<Layout
title={`${siteConfig.title}`}

@ -5,7 +5,7 @@ import useBaseUrl from "@docusaurus/useBaseUrl";
import Translate from "@docusaurus/Translate";
function CompanyCards({ companies }) {
return (
<div className="grid sm:grid-cols-2 grid-cols-1 md:px-16 md:grid-cols-3 lg:grid-cols-5 gap-4 mb-16 lg:px-2 px-10">
<div className="grid sm:grid-cols-2 grid-cols-1 md:px-16 md:grid-cols-3 lg:grid-cols-6 gap-4 mb-16 lg:px-2 px-10">
{/* Filter out those without a logo. */}
{companies
.filter((comapny) => comapny.logo.length > 0)
@ -19,13 +19,13 @@ function CompanyCards({ companies }) {
>
<div className="flex dark:text-black items-center justify-center h-28">
<div
className="h-24 w-24 object-contain"
className="h-22 w-24 object-contain"
style={{ position: "relative" }}
>
<img
src={useBaseUrl(company.logo)}
alt={`${company.name}`}
className="h-24 w-24 object-contain"
className="h-22 w-24 object-contain"
/>
</div>
</div>
@ -39,9 +39,9 @@ export default function OurUsers() {
<Layout title="OurUsers" description="companies using our product">
<div className="max-w-screen-lg mx-auto dark:text-white">
{/* text description*/}
<div className="max-w-screen-sm sm:mx-auto mx-10 text-center my-8 ">
<div className="max-w-screen-sm sm:mx-auto mx-10 text-center my-8 mt-16 ">
<div className="text-center mt-8">
<h2 className="text-3xl font-bold mb-4">
<h2 className="text-3xl font-bold my-4">
<Translate
id="companyPage.title"
description="the title for the company page"
@ -50,12 +50,12 @@ export default function OurUsers() {
</Translate>
</h2>
<div
className="mx-auto h-1 bg-gradient-to-r from-green-400 to-blue-500 mb-4"
className="mx-auto h-1 bg-gradient-to-r from-green-400 to-blue-500 my-6"
style={{ width: "30%" }}
></div>
</div>
<div className="flex flex-col items-center mx-auto">
<p className="text-lg mb-2 max-w-1/2" style={{ lineHeight: "1.5" }}>
<p className="text-lg leading-loose mb-2 max-w-1/2">
<Translate
id="companyPage.descriptionText"
description="the description for the company page"
@ -64,7 +64,7 @@ export default function OurUsers() {
This is our greatest motivation to move forward.
</Translate>{" "}
</p>
<p className="text-lg mb-4 max-w-1/2" style={{ lineHeight: "1.5" }}>
<p className="text-lg mb-4 max-w-1/2 leading-loose">
<Translate
id="companyPage.questionText"
description="the text for the company question"

@ -24,6 +24,8 @@ import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.junit.Assert;
import org.junit.Test;
import org.json.JSONException;
import org.skyscreamer.jsonassert.JSONAssert;
import java.util.Arrays;
import java.util.Collections;
@ -42,7 +44,11 @@ public class JSONUtilTest {
@Test
public void assertToJSONString() {
Assert.assertNull(JSONUtil.toJSONString(null));
Assert.assertEquals(EXPECTED_FOO_JSON, JSONUtil.toJSONString(EXPECTED_FOO));
try {
JSONAssert.assertEquals(EXPECTED_FOO_JSON, JSONUtil.toJSONString(EXPECTED_FOO), false);
} catch (JSONException jse) {
throw new RuntimeException(jse);
}
}
@Test

@ -19,12 +19,16 @@ package cn.hippo4j.common.toolkit;
import cn.hippo4j.common.model.ThreadPoolParameterInfo;
import org.junit.Test;
import org.mockito.MockedStatic;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.mockStatic;
public class Md5UtilTest {
@Test
@ -50,12 +54,15 @@ public class Md5UtilTest {
@Test
public void assetGetTpContentMd5() {
String md5Result = "ef5ea7cb47377fb9fb85a7125e76715d";
ThreadPoolParameterInfo threadPoolParameterInfo = ThreadPoolParameterInfo.builder().tenantId("prescription")
.itemId("dynamic-threadpool-example").tpId("message-consume").content("描述信息").corePoolSize(1)
.maximumPoolSize(2).queueType(1).capacity(4).keepAliveTime(513L).executeTimeOut(null).rejectedType(4)
.isAlarm(1).capacityAlarm(80).livenessAlarm(80).allowCoreThreadTimeOut(1).build();
Assert.isTrue(md5Result.equals(Md5Util.getTpContentMd5(threadPoolParameterInfo)));
final ThreadPoolParameterInfo threadPoolParameterInfo = new ThreadPoolParameterInfo();
final String mockContent = "mockContent";
final String mockContentMd5 = "34cf17bc632ece6e4c81a4ce8aa97d5e";
try (final MockedStatic<ContentUtil> mockedContentUtil = mockStatic(ContentUtil.class)) {
mockedContentUtil.when(() -> ContentUtil.getPoolContent(threadPoolParameterInfo)).thenReturn(mockContent);
final String result = Md5Util.getTpContentMd5(threadPoolParameterInfo);
Assert.isTrue(result.equals(mockContentMd5));
mockedContentUtil.verify(() -> ContentUtil.getPoolContent(threadPoolParameterInfo), times(1));
}
}
@Test

@ -66,7 +66,7 @@ public class WeChatSendMessageHandler extends AbstractRobotSendMessageHandler {
weChatReq.setMarkdown(markdown);
String responseBody = HttpUtil.post(serverUrl, weChatReq);
WeChatRobotResponse response = JSONUtil.parseObject(responseBody, WeChatRobotResponse.class);
Assert.isTrue(response != null, "Response is null.");
Assert.notNull(response, "Response is null.");
if (response.getErrcode() != 0) {
log.error("WeChat failed to send message, reason : {}", response.errmsg);
}

@ -12,6 +12,7 @@
"@testing-library/user-event": "^13.5.0",
"ahooks": "^3.7.8",
"antd": "^5.4.7",
"buffer": "^6.0.3",
"classnames": "^2.3.2",
"dayjs": "^1.11.9",
"echarts": "^5.4.3",
@ -32,7 +33,8 @@
"build": "craco build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"lint": "eslint -c .eslintrc.js src --ext .ts,.tsx,.js,.jsx --fix"
"lint": "eslint -c .eslintrc.js src --ext .ts,.tsx,.js,.jsx --fix",
"format": "prettier --write src/"
},
"eslintConfig": {
"extends": [

@ -1,14 +1,14 @@
.header-wrapper {
display: flex;
width: 100%;
justify-content: space-between;
.logo {
display: flex;
width: 100%;
justify-content: space-between;
.logo {
display: flex;
flex-direction: column;
width: 50px;
img {
flex: 1;
object-fit: contain;
}
flex-direction: column;
width: 50px;
img {
flex: 1;
object-fit: contain;
}
}
}

@ -1,3 +0,0 @@
// .custom-icon {
// color: red !important;
// }

@ -1,6 +1,5 @@
import { createFromIconfontCN } from '@ant-design/icons';
import React from 'react';
import style from './index.module.less';
const MyIcon = createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/c/font_4254722_vw34zn7su2.js', // 在 iconfont.cn 上生成
@ -9,7 +8,7 @@ const MyIcon = createFromIconfontCN({
type MyComponentProps = React.HTMLProps<HTMLDivElement> & { type: string };
const IconFont: React.FC<MyComponentProps> = props => {
return <MyIcon className={style['custom-icon']} {...props}></MyIcon>;
return <MyIcon {...props}></MyIcon>;
};
export default IconFont;

@ -52,7 +52,7 @@ const LayoutCom = (props: ILayoutCom) => {
style={{
backgroundColor: myThemes.backgroundColor.bg1,
height: `calc(100vh - ${isHeader ? '64px' : '0px'})`,
margin: isHeader ? '10px 10px 0px' : '0px',
margin: isHeader ? '10px 10px 0px 0px' : '0px',
}}
>
{isSider && (

@ -1,5 +1,5 @@
.tenant_wrapper {
.opreate_btn {
padding: 0px;
padding: 0px;
}
}

@ -1,5 +1,5 @@
.tenant_wrapper {
.opreate_btn {
padding: 0px;
padding: 0px;
}
}

@ -1,37 +1,37 @@
.login-wrapper {
display: grid;
grid-template-columns: 1fr 550px;
grid-template-rows: 1fr;
height: 100%;
.login-bgi {
background: url('https://gw.alipayobjects.com/zos/rmsportal/FfdJeJRQWjEeGTpqgBKj.png') no-repeat fixed center center;
background-size: contain;
display: grid;
grid-template-columns: 1fr 550px;
grid-template-rows: 1fr;
height: 100%;
.login-bgi {
background: url('https://gw.alipayobjects.com/zos/rmsportal/FfdJeJRQWjEeGTpqgBKj.png') no-repeat fixed center center;
background-size: contain;
}
.login-form-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.img-wrapper {
width: 50px;
display: flex;
flex-direction: column;
img {
flex: 1;
object-fit: contain;
}
}
.login-form-wrapper {
.tip {
margin-block-start: 12px;
margin-block-end: 36px;
}
.form-content {
width: 330px;
.login-edit {
display: flex;
flex-direction: column;
justify-content: center;
justify-content: space-between;
align-items: center;
.img-wrapper {
width: 50px;
display: flex;
flex-direction: column;
img {
flex: 1;
object-fit: contain;
}
}
.tip {
margin-block-start: 12px;
margin-block-end: 36px;
}
.form-content {
width: 330px;
.login-edit {
display: flex;
justify-content: space-between;
align-items: center;
}
}
}
}
}
}

@ -4,7 +4,7 @@ import service from './service';
import { LockOutlined, UserOutlined } from '@ant-design/icons';
import style from './index.module.less';
import { useRequest } from 'ahooks';
import { setToken } from '@/utils';
import { encrypt, genKey, setToken } from '@/utils';
import { useNavigate } from 'react-router-dom';
import { STR_MAP } from '@/config/i18n/locales/constants';
import { useTranslation } from 'react-i18next';
@ -20,7 +20,7 @@ const Login = () => {
const [form] = Form.useForm();
const navigate = useNavigate();
const { validateFields } = form;
const [remenberMe, setRemenberMe] = useState(0);
const [rememberMe, setRememberMe] = useState(1);
const { t } = useTranslation();
const { run, loading } = useRequest(service.fetchLogin, {
@ -36,17 +36,20 @@ const Login = () => {
const handleLogin = useCallback(() => {
validateFields()
.then(values => {
console.log('value:::', values, remenberMe);
.then(async values => {
const { password, username } = values;
let key = genKey();
let encodePassword = await encrypt(password, key);
key = key.split('').reverse().join('');
run({
password: '1BsL68bUgS52alKirqFprU1QfWJyPFlb3dA2AzEMc6kMTpTHN1doEN4=',
rememberMe: 1,
tag: 'lw4xNmj6QuamOFsy',
username: 'baoxinyi_user',
password: encodePassword,
tag: key,
username,
rememberMe,
});
})
.catch(err => console.log('err:::', err));
}, [remenberMe, validateFields, run]);
}, [validateFields, run, rememberMe]);
const formNode = useMemo(
() => (
@ -88,10 +91,9 @@ const Login = () => {
<Form.Item name="rememberMe">
<div className={style['login-edit']}>
<Checkbox
value={1}
checked
checked={Boolean(rememberMe)}
onChange={e => {
setRemenberMe(e.target.checked ? 1 : 0);
setRememberMe(Number(e.target.checked));
}}
>
{t(STR_MAP.REMERBER_PASSWORD)}
@ -113,7 +115,7 @@ const Login = () => {
</Form.Item>
</Form>
),
[form, loading, handleLogin, t]
[form, loading, rememberMe, handleLogin, t]
);
const items: TabsProps['items'] = [

@ -1,5 +1,5 @@
.tenant_wrapper {
.opreate_btn {
padding: 0px;
padding: 0px;
}
}

@ -1,5 +1,5 @@
.tenant_wrapper {
.opreate_btn {
padding: 0px;
padding: 0px;
}
}

@ -1,3 +1,3 @@
/// <reference types="react-scripts" />
declare module '*.less';
declare module 'crypto-browserify' {}
declare module 'crypto-js';

@ -1,40 +1,5 @@
import Cookie from 'js-cookie';
// import { Buffer } from 'buffer';
// import crypto from 'crypto-browserify';
// /**
// * generate key
// * @returns {string} key(length 16)
// */
// export function genKey() {
// let chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// let result = '';
// for (let i = 16; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
// return result;
// }
// /**
// * encode message
// * @param msg message
// * @param key key
// * @returns {string} encoded message
// */
// export function encrypt(msg: string, key: string) {
// try {
// let pwd = Buffer.from(key);
// let iv = (crypto as any).randomBytes(12);
// let cipher = (crypto as any).createCipheriv('aes-128-gcm', pwd, iv);
// let enc = cipher.update(msg, 'utf8', 'base64');
// enc += cipher.final('base64');
// let tags = cipher.getAuthTag();
// enc = Buffer.from(enc, 'base64') as any;
// let totalLength = iv.length + enc.length + tags.length;
// let bufferMsg = Buffer.concat([iv, enc as any, tags], totalLength);
// return bufferMsg.toString('base64');
// } catch (e) {
// console.log('Encrypt is error', e);
// return null;
// }
// }
import { Buffer } from 'buffer';
import _ from 'lodash';
// is plain object
@ -89,4 +54,36 @@ const isEmpty = (value: any) => {
return typeof value === 'object' ? _.isEmpty(value) : isNilValue(value);
};
export { isPlainObject, isEmpty, filterEmptyField, setToken, removeToken, getToken };
function genKey() {
let chars = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let result = '';
for (let i = 16; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
return result;
}
async function encrypt(msg: string, key: any) {
try {
let pwd = Buffer.from(key);
const cryptoKey = await window.crypto.subtle.importKey('raw', pwd, { name: 'AES-GCM' }, false, ['encrypt']);
const iv = window.crypto.getRandomValues(new Uint8Array(12));
const encodedMsg = new TextEncoder().encode(msg);
const encryptedData = await window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv: iv,
},
cryptoKey,
encodedMsg
);
const encryptedArray = new Uint8Array(encryptedData);
const totalLength = iv.length + encryptedArray.length;
const combinedArray = new Uint8Array(totalLength);
combinedArray.set(iv);
combinedArray.set(encryptedArray, iv.length);
return btoa(String.fromCharCode(...combinedArray));
} catch (e) {
return null;
}
}
export { isPlainObject, isEmpty, filterEmptyField, setToken, removeToken, getToken, genKey, encrypt };

@ -124,7 +124,6 @@ function request<T>(url: string, config: RequestOptions): Promise<Response<T>> {
return fetch(url, config as any).then(function onfulfilled(response) {
let { status, statusText } = response;
console.log('status:::', status, response);
if (status >= 200 && status < 400) {
let result;
switch (responseType) {
@ -141,10 +140,11 @@ function request<T>(url: string, config: RequestOptions): Promise<Response<T>> {
result = response.arrayBuffer();
break;
}
// business code
result?.then(res => {
if (res?.code === 200) {
// console.log(':::');
if (!res?.success) {
notification.error({
message: res.message,
});
}
});
return result;

@ -1,11 +1,8 @@
{
"compilerOptions": {
"target": "es5",
"target": "es2015",
"lib": ["dom", "dom.iterable", "esnext"],
"typeRoots": [
"node_modules/@types",
"src/typings"
],
"typeRoots": ["node_modules/@types", "src/typings"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
@ -22,8 +19,8 @@
"baseUrl": "./",
"paths": {
// baseUrl
"@/*": ["src/*"],
},
"@/*": ["src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx"]
}

File diff suppressed because it is too large Load Diff

@ -5,7 +5,38 @@
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
import * as user from '@/api/hippo4j-user';
export default {
name: 'App',
computed: {
...mapGetters(['tenantInfo'])
},
mounted() {
const userName = this.$cookie.get('userName');
user
.getCurrentUser(userName)
.then((response) => {
const { resources } = response;
resources.map((item) => ({
...item,
tenantId: item.resource
}))
if (response.role == 'ROLE_ADMIN') {
resources.unshift({
action: "rw",
resource: this.$t('common.allTenant'),
username: userName,
tenantId: this.$t('common.allTenant'),
})
}
this.$store.dispatch('tenant/setTenantList', resources)
if (!this.tenantInfo.resource) {
this.$store.dispatch('tenant/setTenantInfo', resources[0])
console.log("ssss", this.tenantInfo)
}
})
.catch(() => {});
}
};
</script>

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1695992735183" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1815" id="mx_n_1695992735184" width="400" height="400" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M855.8 868.3H167.1l-7.5-9.5c-29.3-37.4-52.2-78.9-67.9-123.3-16.2-46-24.4-94.3-24.4-143.5 0-59.2 11.8-116.6 35.2-170.7 22.4-52.1 54.6-98.9 95.5-138.9 40.8-40 88.2-71.3 141.1-93.3 54.6-22.6 112.6-34.2 172.4-34.2 59.7 0 117.7 11.5 172.4 34.2 52.9 22 100.3 53.2 141.1 93.3 40.9 40.1 73 86.8 95.5 138.9 23.3 54 35.2 111.5 35.2 170.7 0 49.2-8.2 97.5-24.5 143.5-15.7 44.4-38.6 85.9-67.9 123.3l-7.5 9.5z m-665-51.9h641.1c48.4-65.7 73.8-143 73.8-224.4 0-212.3-176.9-385.1-394.4-385.1-217.4 0.1-394.4 172.8-394.4 385.1 0.1 81.4 25.7 158.8 73.9 224.4z m0 0" p-id="1816" fill="#435f81"></path><path d="M421 650.7c0 49.9 40.5 90.4 90.4 90.4 49.9 0 90.4-40.5 90.4-90.4s-40.5-90.4-90.4-90.4c-49.9 0-90.4 40.5-90.4 90.4z m0 0" p-id="1817" fill="#435f81"></path><path d="M518.2 643.3c-10.8 8.3-26.5 6.3-34.9-4.6L382.9 508.3c-8.3-10.8-6.3-26.5 4.6-34.9 10.8-8.3 26.5-6.3 34.9 4.6l100.5 130.5c8.2 10.7 6.1 26.4-4.7 34.8z m0 0" p-id="1818" fill="#435f81"></path><path d="M806.9 602.1c-13.7 0-24.8-11.6-24.8-25.9 0-141-121.4-255.6-270.6-255.6-149.2 0-270.6 114.6-270.6 255.6 0 14.3-11.1 25.9-24.8 25.9-13.7 0-24.8-11.6-24.8-25.9 0-41.8 8.5-82.4 25.5-120.5 16.3-36.7 39.5-69.5 69.2-97.8 60.4-57.5 140.5-89.2 225.6-89.2s165.2 31.7 225.6 89.2c29.6 28.2 52.9 61.1 69.1 97.8 16.9 38.2 25.5 78.7 25.5 120.5-0.1 14.2-11.2 25.9-24.9 25.9z m0 0" p-id="1819" fill="#435f81"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -18,6 +18,14 @@
<!-- </el-tooltip>-->
</template>
<el-select class="select-tenant" v-model="tenant.resource" filterable @change="changeTenant">
<el-option
v-for="(item, index) in tenantList"
:key="index"
:label="item.resource"
:value="index">
</el-option>
</el-select>
<langChange />
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
<div class="avatar-wrapper">
@ -41,13 +49,25 @@
</template>
<script>
import { mapGetters } from 'vuex'
import * as jobProjectApi from '@/api/hippo4j-tenant';
import * as user from '@/api/hippo4j-user';
import { mapGetters, mapState } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger'
import ErrorLog from '@/components/ErrorLog'
import langChange from '@/locale/langChange'
import { i18nConfig } from '@/locale/config'
export default {
data() {
return {
tenant: {
action: '',
resource: '',
username: ''
}
}
},
components: {
Breadcrumb,
Hamburger,
@ -58,9 +78,18 @@
...mapGetters([
'sidebar',
'avatar',
'device'
'device',
'tenantList',
'tenantInfo'
])
},
watch: {
tenantInfo(newVal) {
this.tenant.tenantId = newVal.tenantId
this.tenant.resource = newVal.resource
console.log("ischangLang", newVal)
}
},
methods: {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
@ -69,8 +98,54 @@
this.$cookie.delete('userName')
await this.$store.dispatch('user/logout')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
},
async getTenantList() {
const userName = this.$cookie.get('userName')
await user
.getCurrentUser(userName)
.then((response) => {
const { resources } = response;
resources.map((item) => ({
...item,
tenantId: item.resource
}))
if (response.role == 'ROLE_ADMIN') {
resources.unshift({
action: "rw",
resource: this.$t('common.allTenant'),
username: userName,
tenantId: this.$t('common.allTenant'),
})
}
this.$store.dispatch('tenant/setTenantList', resources)
this.$store.dispatch('tenant/setTenantInfo', this.tenantInfo || resources[0])
this.tenant = this.tenantInfo || resources[0]
console.log("isResour", resources[0], this.tenant)
})
.catch(() => {});
},
async changeTenant(index) {
console.log("isTenList", this.tenantList)
let tenant = {
tenantId: this.tenantList[index].resource,
resource: this.tenantList[index].resource,
current: 1,
desc: true,
size: 10,
}
this.$store.dispatch('tenant/setTenantInfo', tenant)
let isAllTenant = tenant.tenantId == i18nConfig.messages.zh.common.allTenant || tenant.tenantId == i18nConfig.messages.en.common.allTenant
tenant.tenantId = isAllTenant ? '' : tenant.tenantId
await jobProjectApi.list(tenant).then((response) => {
console.log("isRes", response)
// this.$store.dispatch('tenant/setTenantList', resources)
});
}
}
},
async mounted() {
this.getTenantList()
},
}
</script>
@ -113,6 +188,17 @@
outline: none;
}
::v-deep .el-input__inner {
border: none;
box-shadow: none;
}
.select-tenant {
margin-right: 20px;
border: 0;
width: 150px;
}
.right-menu-item {
display: inline-block;
padding: 0 8px;

@ -51,6 +51,7 @@ export default {
audit: 'Audit',
yes: 'Yes',
no: 'No',
allTenant: 'ALL TENANT'
},
// 运行报表

@ -49,6 +49,7 @@ export default {
audit: '审核',
yes: '是',
no: '否',
allTenant: '所有租户'
},
// 运行报表

@ -18,7 +18,9 @@
</div>
</template>
<script>
import { langSelectList } from './config'
import { langSelectList, i18nConfig } from './config'
import * as user from '@/api/hippo4j-user';
import { mapGetters } from 'vuex';
export default {
data() {
return {
@ -31,6 +33,7 @@ export default {
this.currentLang = lang || null
},
computed: {
...mapGetters(['tenantInfo', 'tenantList']),
currentLangName() {
const langItem = this.langSelectList.find(item => item.lang === this.currentLang)
return langItem?.name || '选择语言'
@ -42,6 +45,42 @@ export default {
this.currentLang = value
this.$i18n.locale = value
localStorage.setItem('locale_lang', value)
this.changeTenant()
},
changeTenant() {
const userName = this.$cookie.get('userName');
user.getCurrentUser(userName)
.then((response) => {
const { resources } = response;
resources.map((item) => ({
...item,
tenantId: item.resource
}))
//change lang = change global tenantInfo
if (response.role == 'ROLE_ADMIN') {
//tenantInfo
let tenantId = this.tenantInfo.resource
let isAllTenant = tenantId == i18nConfig.messages.zh.common.allTenant || tenantId == i18nConfig.messages.en.common.allTenant
let alreadyHasAll = resources[0] == i18nConfig.messages.zh.common.allTenant || resources[0] == i18nConfig.messages.en.common.allTenant
if (alreadyHasAll) {
this.$set(resources[0], 'resource', this.$t('common.allTenant'))
this.$store.dispatch('tenant/setTenantList', resources)
} else {
resources.unshift({
action: "rw",
resource: this.$t('common.allTenant'),
username: userName,
tenantId: this.$t('common.allTenant'),
})
this.$store.dispatch('tenant/setTenantList', resources)
}
if (isAllTenant) {
this.$store.dispatch('tenant/setTenantInfo', resources[0])
}
}
})
}
}
}

@ -10,6 +10,8 @@ const getters = {
introduction: state => state.user.introduction,
roles: state => state.user.roles,
permission_routes: state => state.permission.routes,
errorLogs: state => state.errorLog.logs
errorLogs: state => state.errorLog.logs,
tenantList: state => state.tenant.tenantList,
tenantInfo: state => state.tenant.tenantInfo,
}
export default getters

@ -0,0 +1,53 @@
import * as user from '@/api/hippo4j-user';
const state = {
tenantList: [],
tenantInfo: {}
}
const mutations = {
SET_TENANT_LIST: (state, log) => {
state.tenantList = log;
console.log("sssssss", state.tenantList)
},
SET_GLOBAL_TENANT: (state, log) => {
state.tenantInfo = log;
}
}
const actions = {
async getTenantList({commit}) {
debugger
const userName = this.$cookie.get('userName');
user
.getCurrentUser(userName)
.then((response) => {
const { resources } = response;
if (response.role == 'ROLE_ADMIN') {
resources.unshift({
action: "rw",
resource: "所有租户",
username: userName
})
}
commit('SET_TENANT_LIST', resources)
if (!state.tenantInfo) {
commit('SET_GLOBAL_TENANT', resources[0])
}
})
.catch(() => {});
},
setTenantList({commit}, log) {
commit('SET_TENANT_LIST', log)
},
setTenantInfo({commit}, log) {
commit('SET_GLOBAL_TENANT', log)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -443,6 +428,8 @@ import * as instanceApi from '@/api/hippo4j-instance';
import waves from '@/directive/waves';
import Pagination from '@/components/Pagination';
import axios from 'axios';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
components: { Pagination },
@ -567,6 +554,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
tenantId: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -585,6 +575,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
// this.fetchData()
//
@ -595,6 +591,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.tenantId) {
this.$message.warning(this.$t('message.emptyWarning', { name: this.$t('tenantManage.tenant') }));
return;

@ -163,6 +163,8 @@ import * as jobProjectApi from '@/api/hippo4j-item';
import * as tenantApi from '@/api/hippo4j-tenant';
import waves from '@/directive/waves';
import Pagination from '@/components/Pagination';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -218,6 +220,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
tenantId: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -228,6 +233,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
this.fetchData();
//
@ -238,6 +249,9 @@ export default {
},
methods: {
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
this.listLoading = true;
jobProjectApi.list(this.listQuery).then((response) => {
const { records } = response;

@ -142,6 +142,8 @@
import * as logApi from '@/api/hippo4j-log';
import waves from '@/directive/waves';
import Pagination from '@/components/Pagination';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -198,6 +200,9 @@ export default {
},
methods: {
fetchData() {
// this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
// let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
// this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
this.listLoading = true;
logApi.list(this.listQuery).then((response) => {
const { records } = response;

@ -32,6 +32,14 @@ export default {
type: Array,
required: true,
},
title: {
type: String,
default: '标题'
},
cusFormatter: {
type: Boolean,
default: false
}
},
data() {
return {
@ -67,11 +75,19 @@ export default {
},
setOptions() {
const series = this.chartData.map((item) => {
const other = !item.show ? {
symbolSize: 0,
showSymbol: false,
lineStyle: {
width: 0,
color: 'rgba(0, 0, 0, 0)'
}
} : {}
return {
name: item.name,
type: 'line',
stack: 'Total',
areaStyle: {},
// stack: 'Total',
// areaStyle: {},
label: {
position: 'top',
},
@ -82,40 +98,82 @@ export default {
smooth: true,
data: item.data,
showSymbol: false,
...other
};
});
let numbers = this.chartData && this.chartData[0]?.data;
let maxNumber = Math.max(...numbers);
const cusFormatterObj = this.cusFormatter ? {
formatter: (params) => {
const taskAll = params.find(item => item.seriesName === '任务总数')
const taskCom = params.find(item => item.seriesName === '区间任务完成数')
const taskReject = params.find(item => item.seriesName === '拒绝总数')
return `<div>
<div style="padding: 6px 0;font-weight: bolder;">${taskCom?.seriesName}${taskCom?.value}</div>
<div style="width: 100%,height: 0px;border-bottom: 1px dashed #ddd;padding: 6px 0;"></div>
<div style="padding: 6px 0;">${taskAll?.seriesName}${taskAll?.value}</div>
<div style="padding: 6px 0;">${taskReject?.seriesName}${taskReject?.value}</div>
</div>`
}
} : {};
this.chart.setOption({
title: {
text: this.title,
textStyle: {
fontSize: '16px'
},
left: 0,
right: 0,
top: 0,
bottom: 0,
padding: 0,
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985',
},
},
...cusFormatterObj
},
legend: {
show:false,
data: this.chartData,
icon: 'circle',
top: 0,
},
toolbox: {
feature: {},
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
left: 0,
right: 0,
top: '18%',
bottom: '0',
containLabel: true,
},
xAxis: [
{
type: 'category',
boundaryGap: false,
data: this.times,
xAxis: {
type: 'category',
boundaryGap: false,
data: this.times,
nameTextStyle: {
width: '20px'
},
],
axisLabel: {
color: '#333'
},
axisLine: {
lineStyle: {
color: '#ddd'
}
},
axisTick: {
show: true,
lineStyle: {
color: '#ddd'
}
},
},
yAxis: [
{
type: 'value',
max: maxNumber,
},
],
series: series,

@ -1,28 +1,28 @@
import { debounce } from '@/utils'
import { debounce } from '@/utils';
export default {
data() {
return {
$_sidebarElm: null
}
$_sidebarElm: null,
};
},
mounted() {
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
this.$_initResizeEvent();
this.$_initSidebarResizeEvent();
},
beforeDestroy() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
this.$_destroyResizeEvent();
this.$_destroySidebarResizeEvent();
},
// to fixed bug when cached by keep-alive
// https://github.com/PanJiaChen/vue-element-admin/issues/2116
activated() {
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
this.$_initResizeEvent();
this.$_initSidebarResizeEvent();
},
deactivated() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
this.$_destroyResizeEvent();
this.$_destroySidebarResizeEvent();
},
methods: {
// use $_ for mixins properties
@ -30,27 +30,29 @@ export default {
$_resizeHandler() {
return debounce(() => {
if (this.chart) {
this.chart.resize()
this.chart.resize();
}
}, 100)()
}, 100)();
},
$_initResizeEvent() {
window.addEventListener('resize', this.$_resizeHandler)
window.addEventListener('resize', this.$_resizeHandler);
},
$_destroyResizeEvent() {
window.removeEventListener('resize', this.$_resizeHandler)
window.removeEventListener('resize', this.$_resizeHandler);
},
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
this.$_resizeHandler();
}
},
$_initSidebarResizeEvent() {
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0];
this.$_sidebarElm &&
this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler);
},
$_destroySidebarResizeEvent() {
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
}
}
}
this.$_sidebarElm &&
this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler);
},
},
};

@ -1,410 +1,475 @@
<template>
<div class="dashboard-editor-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="itemSelectList()"
>
<el-option
v-for="item in itemOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.tpId"
:placeholder="$t('threadPool.threadPoolRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="threadPoolSelectList()"
>
<el-option
v-for="item in threadPoolOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.identify"
:placeholder="$t('threadPoolMonitor.ipPortRequired')"
style="width: 220px"
filterable
class="filter-item"
>
<el-option
v-for="item in identifyOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-button
v-waves
class="filter-item"
type="primary"
style="margin-left: 10px"
icon="el-icon-search"
@click="fetchData"
>
{{ $t('common.query') }}
</el-button>
<el-button
v-waves
class="filter-item"
type="primary"
style="margin-left: 10px"
icon="el-icon-refresh"
@click="refreshData"
>
{{ $t('common.reset') }}
</el-button>
<div class="monitor-wrapper">
<div class="info-wrapper">
<div class="top-card">
<svg-icon id="top-icon" icon-class="monitor" />
<div class="top-info">
<div class="label">操作者</div>
<span class="user">{{userName}}</span>
</div>
</div>
<div class="query-monitoring">
<div class="title">查询监控</div>
<el-cascader
class="el-cascader"
learable
v-model="selectMonitorValue"
:options="selectMonitor"
:props="{ expandTrigger: 'hover' }"
@change="handleChangeMonitorSelect"></el-cascader>
</div>
<div class="info-card">
<div class="info-card-title">{{ selectMonitor[0].label }}数量</div>
<div class="data-num">
<span class="num">
{{ selectMonitor[0].children.length || "_" }}
</span>
</div>
</div>
<div class="tp-card">
<div class="tp-item" v-for="(item, index) in tableData" :key="index">
<div>{{ item.name }}</div>
<div class="tp-label">{{ item.label }}</div>
</div>
</div>
</div>
<div class="search-wrapper">
<div class="demonstration">时间筛选</div>
<el-date-picker
type="datetimerange"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd HH:mm:ss"
v-model="timeValue"
@input="changeMonitorData">
</el-date-picker>
</div>
<div class="center-chart-wrapper">
<line-chart title="任务数" :chart-data="lineChartData" :times="times" height="100%" :cus-formatter="true" />
</div>
<div class="bottom-chart-wraper">
<div class="inner-chart">
<line-chart title="活跃线程数" :chart-data="activeSizeList" :times="times" height="100%" />
</div>
<div class="inner-chart">
<line-chart title="线程数" :chart-data="poolSizeList" :times="times" height="100%" />
</div>
<div class="inner-chart">
<line-chart title="队列元素数" :chart-data="queueSizeList" :times="times" height="100%" />
</div>
<div class="inner-chart">
<line-chart title="拒绝数" :chart-data="rangeRejectCountList" :times="times" height="100%" />
</div>
</div>
<el-empty v-if="!temp.coreSize" :description="$t('threadPoolMonitor.noResultsYet')" />
<section v-else>
<!-- <el-card shadow="hover">
<el-descriptions :column="3" border>
<el-descriptions-item label="实例 ID">{{ listQuery.identify }}</el-descriptions-item>
<el-descriptions-item label="核心线程">{{ temp.coreSize }}</el-descriptions-item>
<el-descriptions-item label="最大线程">{{ temp.maxSize }}</el-descriptions-item>
<el-descriptions-item label="队列类型">
{{ temp.queueType | queueFilter }}
</el-descriptions-item>
<el-descriptions-item label="队列容量">{{ temp.capacity }}</el-descriptions-item>
<el-descriptions-item label="已完成任务数">{{ lastTaskCount }}</el-descriptions-item>
<el-descriptions-item label="拒绝策略">
{{ temp.rejectedType | rejectedFilter }}
</el-descriptions-item>
<el-descriptions-item label="是否报警">
{{ temp.isAlarm | alarmFilter }}
</el-descriptions-item>
<el-descriptions-item label="任务拒绝次数">
{{ rejectCount }}
</el-descriptions-item>
</el-descriptions>
</el-card> -->
<el-row :gutter="10" style="margin-top: 16px">
<el-col :span="12">
<el-card shadow="hover">
<line-chart :chart-data="lineChartData1" :times="times" />
</el-card>
</el-col>
<!-- <el-col :span="8">
<el-card shadow="hover">
<line-chart :chart-data="lineChartData2" :times="times" />
</el-card>
</el-col> -->
<el-col :span="12">
<el-card shadow="hover">
<line-chart :chart-data="lineChartData3" :times="times" />
</el-card>
</el-col>
</el-row>
<el-row :gutter="10" style="margin-top: 16px">
<el-col :span="12">
<el-card shadow="hover">
<line-chart :chart-data="lineChartData5" :times="times" />
</el-card>
</el-col>
<!-- <el-col :span="8">
<el-card shadow="hover">
<line-chart :chart-data="lineChartData4" :times="times" />
</el-card>
</el-col> -->
<el-col :span="12">
<el-card shadow="hover">
<line-chart :chart-data="lineChartData6" :times="times" />
</el-card>
</el-col>
</el-row>
</section>
</div>
</template>
<script>
import LineChart from './components/LineChart.vue';
import waves from '@/directive/waves';
import * as itemApi from '@/api/hippo4j-item';
import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as instanceApi from '@/api/hippo4j-instance';
import * as monitorApi from '@/api/hippo4j-monitor';
import * as instanceApi from '@/api/hippo4j-instance';
import * as itemApi from '@/api/hippo4j-item';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
import LineChart from './components/LineChart.vue';
export default {
name: 'Monitor',
components: {
LineChart,
},
directives: { waves },
filters: {
queueFilter(type) {
const typeList = {
1: 'ArrayBlockingQueue',
2: 'LinkedBlockingQueue',
3: 'LinkedBlockingDeque',
4: 'SynchronousQueue',
5: 'LinkedTransferQueue',
6: 'PriorityBlockingQueue',
9: 'ResizableLinkedBlockingQueue',
};
return typeList[type];
},
rejectedFilter(type) {
const typeList = {
1: 'CallerRunsPolicy',
2: 'AbortPolicy',
3: 'DiscardPolicy',
4: 'DiscardOldestPolicy',
5: 'RunsOldestTaskPolicy',
6: 'SyncPutQueuePolicy',
};
return type && typeList[type] ? typeList[type] : type ? `CustomRejectedPolicy-${type}` : '';
},
alarmFilter(type) {
return type === '1' ? '报警' : '忽略';
},
allowCoreThreadTimeOutFilter(type) {
return type === '1' ? '超时' : '不超时';
},
},
data() {
return {
lineChartData1: [
{
name: 'activeSizeList',
data: [],
color: '#709775',
},
],
lineChartData2: [
{
name: 'poolSizeList',
data: [],
color: '#e9c46a',
},
],
lineChartData3: [
{
name: 'queueSizeList',
data: [],
color: '#003049',
},
],
lineChartData4: [
{
name: 'queueRemainingCapacityList',
data: [],
color: '#f4a261',
},
],
lineChartData5: [
{
name: 'completedTaskCountList',
data: [],
color: '#023e8a',
},
],
lineChartData6: [
{
name: 'rejectCountList',
data: [],
color: '#dd1c1a',
},
],
lineChartData: [],
times: [],
size: 500,
tenantOptions: [],
threadPoolOptions: [],
itemOptions: [],
identifyOptions: [],
listQuery: {
current: 1,
size: 10,
itemId: '',
tpId: '',
tenantId: '',
identify: '',
instanceId: '',
timeValue: new Date(),
selectMonitorValue: {
default: [0]
},
temp: {},
rejectCount: null,
lastTaskCount: null,
};
selectMonitor: [{
value: 0,
label: '项目',
children: []
}, {
value: 1,
label: '线程池',
children: [],
}, {
value: 2,
label: '实例',
children: [],
}],
activeSizeList: [],
poolSizeList: [],
queueSizeList: [],
rangeRejectCountList: [],
chooseData: {},
pickerOptions: {
shortcuts: [{
text: '今天',
onClick(picker) {
picker.$emit('pick', new Date());
}
}, {
text: '昨天',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
picker.$emit('pick', date);
}
}, {
text: '一周前',
onClick(picker) {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit('pick', date);
}
}]
},
selectMonitor: [],
tableData: [{
date: '2016-05-02',
name: '王小虎',
}, {
date: '2016-05-04',
name: '王小虎',
}, {
date: '2016-05-01',
name: '王小虎',
}, {
date: '2016-05-03',
name: '王小虎',
}],
listQuery : {
"current": 1,
"size": 10,
"itemId": "dynamic-threadpool-example",
"tpId": "message-produce",
"tenantId": "prescription",
"identify": "127.0.0.1:8088_93bfe5307a844e07ada13cbfc3f16662",
"instanceId": "127.0.0.1:8088_93bfe5307a844e07ada13cbfc3f16662"
}
}
},
computed: {
...mapGetters([
'tenantInfo'
]),
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
async created() {
this.initSelect();
created() {
this.fetchData()
this.fetchChartData()
this.getSelectMonitor()
},
methods: {
fetchData() {
if (!this.listQuery.tenantId) {
this.$message.warning(this.$t('message.emptyWarning', { name: this.$t('tenantManage.tenant') }));
return;
}
if (!this.listQuery.itemId) {
this.$message.warning(this.$t('message.emptyWarning', { name: this.$t('projectManage.item') }));
return;
}
if (!this.listQuery.tpId) {
this.$message.warning(this.$t('message.emptyWarning', { name: this.$t('threadPool.threadPool') }));
return;
}
if (!this.listQuery.identify) {
this.$message.warning(this.$t('message.emptyWarning', { name: this.$t('threadPoolMonitor.ipPort') }));
return;
}
this.listQuery.instanceId = this.listQuery.identify;
threadPoolApi.info(this.listQuery).then((res) => {
this.userName = this.$cookie.get('userName')
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
threadPoolApi.info( this.listQuery).then((res) => {
this.temp = res;
});
// monitorApi.lastTaskCountFun(this.listQuery).then((res) => {
// this.rejectCount = res.rejectCount;
// this.lastTaskCount = res.completedTaskCount;
// });
this.initChart();
},
refreshData() {
this.listQuery.tenantId = null;
this.listQuery.itemId = null;
this.listQuery.tpId = null;
this.listQuery.identify = null;
this.itemOptions = [];
this.threadPoolOptions = [];
this.identifyOptions = [];
},
initSelect() {
tenantApi.list({ size: this.size }).then((res) => {
getSelectMonitor() {
this.selectMonitor = [{
value: 0,
label: '项目',
children: []
}, {
value: 1,
label: '线程池',
children: [],
}, {
value: 2,
label: '实例',
children: [],
}]
// itenId
itemApi.list(this.listQuery).then((res) => {
const { records } = res || {};
this.tenantOptions =
records &&
records.map((item) => {
return {
key: item.tenantId,
display_name: item.tenantId + ' ' + item.tenantName,
};
});
records && records.map((item) => {
item.value = item.tenantId
item.label = item.tenantId
});
this.selectMonitor[0].children = records
//tenantId
this.selectMonitorValue = [0, records[0].tenantId ]
this.listQuery.tenantId = records[0].tenantId
this.listQuery.itemId = records[0].itemId
this.listQuery.current = records[0].current
});
},
tenantSelectList() {
this.listQuery.itemId = null;
this.listQuery.tpId = null;
this.listQuery.identify = null;
this.itemOptions = [];
this.threadPoolOptions = [];
this.identifyOptions = [];
const params = { tenantId: this.listQuery.tenantId, size: this.size };
itemApi.list(params).then((res) => {
//线tpId,itemId,tenantId
threadPoolApi.list( this.listQuery).then((res) => {
const { records } = res || {};
this.itemOptions =
records &&
records.map((item) => {
return {
key: item.itemId,
display_name: item.itemId + ' ' + item.itemName,
};
});
records && records.map((item) => {
item.value = item.tenantId
item.label = item.tenantId
});
this.selectMonitor[1].children = records
this.listQuery.tenantId = records[0].tenantId
this.listQuery.itemId = records[0].itemId
this.listQuery.current = records[0].current
this.listQuery.tpId = records[0].tpId
});
let param = [
this.listQuery.itemId,
this.listQuery.tpId,
]
//
instanceApi.list(param).then((res) => {
res.map((item) => {
item.value = item.tenantId
item.label = item.tenantId
});
this.selectMonitor[2].children = res
this.listQuery.tenantId = res[0].tenantId
this.listQuery.itemId = res[0].itemId
this.listQuery.current = res[0].current
this.listQuery.tpId = res[0].tpId,
this.listQuery.identify = res[0].identify
});
},
itemSelectList() {
this.listQuery.tpId = null;
this.listQuery.identify = null;
this.threadPoolOptions = [];
this.identifyOptions = [];
const params = { itemId: this.listQuery.itemId, size: this.size };
threadPoolApi.list(params).then((res) => {
const { records } = res || {};
this.threadPoolOptions =
records &&
records.map((item) => {
return {
key: item.tpId,
display_name: item.tpId,
};
});
//线
threadPoolApi.info(this.listQuery).then((res) => {
this.temp = res;
this.tableData = [{
name: '租户',
label: res.tenantId
}, {
name: '线程池',
label: res.tpId
}, {
name: '核心线程池',
label: res.coreSize
}, {
// name: '',
// label: res.itemId
// }, {
name: '拒绝次数',
label: res.rejectedType
}]
});
},
threadPoolSelectList() {
this.listQuery.identify = null;
this.identifyOptions = [];
const listArray = [this.listQuery.itemId, this.listQuery.tpId];
instanceApi.list(listArray).then((res) => {
this.identifyOptions =
res &&
res.map((item) => {
return {
key: item.identify,
display_name: item.clientAddress,
};
});
});
fetchChartData() {
monitorApi.active( this.listQuery).then(res => {
this.monitor = res
this.lineChartData = [
{
name: '区间任务完成数',
data: res?.rangeCompletedTaskCountList,
show: true
}, {
name: '拒绝总数',
data: res?.rejectCountList,
show: false,
itemStyle: {
opacity: 0,
},
textStyle: {
opacity: 0,
}
}, {
name: '任务总数',
data: res?.completedTaskCountList,
show: false,
itemStyle: {
opacity: 0,
},
textStyle: {
opacity: 0,
}
},]
this.times = res?.times.map(item => {
const list = item.split(':')
list.pop()
return list.join(':')
})
console.log
this.activeSizeList = [{
name: '活跃线程数',
data: res?.activeSizeList,
show: true,
num: res?.activeSizeList[res.activeSizeList.length - 1]
}]
this.poolSizeList = [{
name: '线程数',
data: res?.poolSizeList,
show: true
}]
this.queueSizeList = [{
name: '队列元素数',
data: res?.queueSizeList,
show: true
}]
this.rangeRejectCountList = [{
name: '拒绝数',
data: res?.rangeRejectCountList,
show: true
}]
})
},
initChart() {
monitorApi.active(this.listQuery).then((res) => {
const {
poolSizeList,
activeSizeList,
queueSizeList,
queueRemainingCapacityList,
completedTaskCountList,
rejectCountList,
times,
} = res || {};
this.times = times;
this.lineChartData1[0].data = activeSizeList;
this.lineChartData2[0].data = poolSizeList;
this.lineChartData3[0].data = queueSizeList;
this.lineChartData4[0].data = queueRemainingCapacityList;
this.lineChartData5[0].data = completedTaskCountList;
this.lineChartData6[0].data = rejectCountList;
});
changeMonitorData(value, row) {
console.log("time", value)
this.listQuery.startTime = value[0]
this.listQuery.endTime = value[1]
this.fetchChartData()
},
},
};
handleChangeMonitorSelect(value) {
console.log("asaksasa", value)
this.selectMonitor[value[0]].map((item) => {
if (item.children.label == value[1]) {
this.listQuery.identify = item.identify || this.listQuery.identify
this.listQuery.tenantId = item.tenantId || this.listQuery.tenantId
this.listQuery.itemId = item.itemId || this.listQuery.itemId
this.listQuery.instanceId = item.current || this.listQuery.instanceId
this.listQuery.tpId = item.tpId || this.listQuery.tpId
}
})
}
}
}
</script>
<style lang="scss" scoped>
.dashboard-editor-container {
padding: 32px;
background-color: rgb(240, 242, 245);
/* background-color: #2f4256; */
position: relative;
min-height: 100vh;
.monitor-wrapper {
width: 100%;
height: calc(100vh - 50px);
display: grid;
grid-template-rows: 60px 1fr 2fr;
grid-template-columns: 240px 2fr 1fr;
background-color: #ebebf3;
gap: 10px;
padding: 10px;
box-sizing: border-box;
>div {
border-radius: 8px;
background-color: #fff;
padding: 12px;
}
.chart-title {
font-size: 16px;
font-weight: bolder;
margin: 0;
}
.info-wrapper::-webkit-scrollbar {
display: none; /*隐藏滚动条*/
}
.info-wrapper {
grid-row: 1 / 4;
grid-column: 1 / 2;
padding: 20rpx;
overflow-y: scroll;
.top-card {
display: flex;
justify-content: space-around;
padding: 20px 0;
align-items: center;
color: rgba($color: #435f81, $alpha: 0.9);
font-weight: 600;
.svg-icon {
width: 60px;
height: 60px;
left: 0;
}
.top-icon {
width: 40px;
}
}
.query-monitoring {
margin-bottom: 30px;
.title {
padding: 0 0 10px 5px;
font-weight: 600;
color: rgba($color: #435f81, $alpha: 0.9);
}
.el-cascader {
width: 100%;
}
}
.info-card {
// background: #435f81;
background-color: rgba($color: #435f81, $alpha: 0.9);
border-radius: 8px;
padding: 20px;
margin-bottom: 20px;
color: #fefefe;
font-family: HelveticaNeue-Medium,Helvetica Medium,PingFangSC-Medium,STHeitiSC-Medium,Microsoft YaHei Bold,Arial,sans-serif;
.info-card-title, .data-num {
font-size: 14px;
font-weight: 500;
padding-bottom: 10px;
}
.num {
font-family: DIDIFD-Regular;
font-size: 40px;
}
.operation-list {
color: darkgray;
}
}
.tp-card {
// background: rgb(237, 237, 237);
border: 1px solid #dfe6ec;
padding: 20px 10px 30px 10px;
border-radius: 8px;
background-color: rgba($color: #435f81, $alpha: 0.9);
color: white;
.tp-item {
border-bottom: 1px solid #e3e3e3;
line-height: 40px;
display: flex;
justify-content: space-between;
font-size: 14px;
flex-wrap: nowrap;
overflow: hidden;
.tp-label {
width: 600;
}
}
}
}
.search-wrapper {
grid-row: 1 / 2;
grid-column: 2 / 4;
display: flex;
align-items: center;
.demonstration {
margin: 0 10px;
font-weight: 600;
color: #3a3b3c;
}
}
.center-chart-wrapper {
grid-row: 2 / 3;
grid-column: 2 / 4;
}
.bottom-chart-wraper {
grid-row: 3 / 4;
grid-column: 2 / 4;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 24px;
.inner-chart {
grid-column: span 1;
grid-row: span 1;
}
}
}
</style>

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenant')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.item')"
@ -307,6 +292,8 @@ import * as notifyApi from '@/api/hippo4j-notify';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import waves from '@/directive/waves';
import Pagination from '@/components/Pagination';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -392,6 +379,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
tenantId: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -407,6 +397,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
this.fetchData();
//
@ -414,6 +410,9 @@ export default {
},
methods: {
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? undefined : this.listQuery.tenantId
this.listLoading = true;
notifyApi.list(this.listQuery).then((response) => {
const { records } = response;
@ -421,6 +420,8 @@ export default {
this.total = total;
this.list = records;
this.listLoading = false;
}).catch((err) => {
console.log("isAError", err)
});
},
initSelect() {

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -187,6 +172,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as threadPoolAdapterApi from '@/api/hippo4j-adapterThreadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -276,6 +263,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -283,6 +273,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -292,6 +288,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.mark) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('frameworkThreadPool.threadPoolType') }),

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -187,6 +172,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as threadPoolAdapterApi from '@/api/hippo4j-adapterThreadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -276,6 +263,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -283,6 +273,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -292,6 +288,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.mark) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('frameworkThreadPool.threadPoolType') }),

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -187,6 +172,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as threadPoolAdapterApi from '@/api/hippo4j-adapterThreadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -276,6 +263,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -283,6 +273,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -292,6 +288,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.mark) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('frameworkThreadPool.threadPoolType') }),

@ -194,6 +194,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as threadPoolAdapterApi from '@/api/hippo4j-adapterThreadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -295,6 +297,11 @@ export default {
visible: true,
};
},
computed: {
...mapGetters([
'tenantInfo'
]),
},
created() {
//
this.initSelect();
@ -304,6 +311,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.mark) {
this.$message.warning('线程池类型不允许为空');
return;
@ -331,6 +341,17 @@ export default {
},
},
},
computed: {
...mapGetters([
'tenantInfo'
]),
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -340,6 +361,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.mark) {
this.$message.warning('线程池类型不允许为空');
return;

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -186,6 +171,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as threadPoolAdapterApi from '@/api/hippo4j-adapterThreadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -275,6 +262,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -282,6 +272,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -291,6 +287,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.mark) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('frameworkThreadPool.threadPoolType') }),

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -187,6 +172,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as threadPoolAdapterApi from '@/api/hippo4j-adapterThreadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -276,6 +263,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -283,6 +273,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -292,6 +288,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.mark) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('frameworkThreadPool.threadPoolType') }),

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -186,6 +171,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as threadPoolAdapterApi from '@/api/hippo4j-adapterThreadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -275,6 +262,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -282,6 +272,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -291,6 +287,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.mark) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('frameworkThreadPool.threadPoolType') }),

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -187,6 +172,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as threadPoolAdapterApi from '@/api/hippo4j-adapterThreadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -276,6 +263,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -283,6 +273,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -292,6 +288,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.mark) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('frameworkThreadPool.threadPoolType') }),

@ -270,6 +270,8 @@ import * as itemApi from '@/api/hippo4j-item';
import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -366,6 +368,17 @@ export default {
visible: true,
};
},
computed: {
...mapGetters([
'tenantInfo'
]),
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -378,6 +391,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.tenantId) {
this.$message.warning('租户不允许为空');
return;

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -280,6 +265,8 @@ import * as itemApi from '@/api/hippo4j-item';
import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -364,6 +351,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -371,6 +361,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -383,6 +379,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.tenantId) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('tenantManage.tenant') }),

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -290,6 +275,8 @@ import * as itemApi from '@/api/hippo4j-item';
import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -374,6 +361,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -381,6 +371,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -393,6 +389,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.tenantId) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('tenantManage.tenant') }),

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenantRequired')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.itemRequired')"
@ -290,6 +275,8 @@ import * as itemApi from '@/api/hippo4j-item';
import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import waves from '@/directive/waves';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -374,6 +361,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
coreSize: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -381,6 +371,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
//
this.initSelect();
@ -393,6 +389,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
if (!this.listQuery.tenantId) {
this.$message.warning(
this.$t('message.emptyWarning', { name: this.$t('tenantManage.tenant') }),

@ -31,6 +31,7 @@
<el-table
v-loading="listLoading"
:data="list"
:key="tableIsChange"
border
highlight-current-row
element-loading-text="Loading"
@ -134,6 +135,8 @@
import * as jobProjectApi from '@/api/hippo4j-tenant';
import waves from '@/directive/waves';
import Pagination from '@/components/Pagination';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -167,6 +170,7 @@ export default {
tenantId: '',
desc: true,
},
tableIsChange: false,
pluginTypeOptions: ['reader', 'writer'],
dialogPluginVisible: false,
pluginData: [],
@ -187,7 +191,16 @@ export default {
visible: true,
};
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
tenantId: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -209,6 +222,9 @@ export default {
},
methods: {
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
this.listLoading = true;
jobProjectApi.list(this.listQuery).then((response) => {
const { records } = response;

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenant')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.item')"
@ -384,6 +369,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import waves from '@/directive/waves';
import Pagination from '@/components/Pagination';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
export default {
name: 'JobProject',
@ -507,6 +494,9 @@ export default {
};
},
computed:{
...mapGetters([
'tenantInfo'
]),
rules(){
return{
tenantId: [{ required: true, message: this.$t('message.requiredError'), trigger: 'blur' }],
@ -538,6 +528,12 @@ export default {
}
},
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
this.fetchData();
//
@ -553,6 +549,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
this.listLoading = true;
threadPoolApi.list(this.listQuery).then((response) => {
const { records } = response;

@ -128,6 +128,7 @@ import * as user from '@/api/hippo4j-user';
import waves from '@/directive/waves';
import Pagination from '@/components/Pagination';
import * as tenantApi from '@/api/hippo4j-tenant';
export default {
name: 'User',
components: { Pagination },

@ -1,21 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<el-select
v-model="listQuery.tenantId"
:placeholder="$t('tenantManage.tenant')"
style="width: 220px"
filterable
class="filter-item"
@change="tenantSelectList()"
>
<el-option
v-for="item in tenantOptions"
:key="item.key"
:label="item.display_name"
:value="item.key"
/>
</el-select>
<el-select
v-model="listQuery.itemId"
:placeholder="$t('projectManage.item')"
@ -314,6 +299,8 @@ import * as tenantApi from '@/api/hippo4j-tenant';
import * as verifyApi from '@/api/verify';
import waves from '@/directive/waves';
import Pagination from '@/components/Pagination';
import { mapGetters } from 'vuex';
import { i18nConfig } from '@/locale/config'
import * as threadPoolApi from '@/api/hippo4j-threadPool';
import * as threadPoolAdapterApi from '@/api/hippo4j-adapterThreadPool';
@ -489,6 +476,17 @@ export default {
that: this,
};
},
computed: {
...mapGetters([
'tenantInfo'
]),
},
watch: {
tenantInfo(newVal, oldVal) {
this.listQuery.tenantId = newVal.tenantId;
this.fetchData()
}
},
created() {
this.fetchData();
this.initSelect();
@ -501,6 +499,9 @@ export default {
this.$forceUpdate();
},
fetchData() {
this.listQuery.tenantId = this?.tenantInfo?.tenantId || this.listQuery.tenantId
let isAllTenant = this.listQuery.tenantId == i18nConfig.messages.zh.common.allTenant || this.listQuery.tenantId == i18nConfig.messages.en.common.allTenant
this.listQuery.tenantId = isAllTenant ? '' : this.listQuery.tenantId
this.listLoading = true;
verifyApi.list(this.listQuery).then((response) => {
const { records } = response;

@ -35,7 +35,7 @@ module.exports = {
},
proxy: {
'/hippo4j/v1/cs': {
target: `http://console.hippo4j.cn:6691/hippo4j/v1/cs`,
target: `http://127.0.0.1:6691/hippo4j/v1/cs`,
changOrigin: true,
secure: false,
pathRewrite: {

@ -18,6 +18,7 @@
package cn.hippo4j.config.model.biz.monitor;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -27,6 +28,7 @@ import java.util.List;
* Monitor active resp dto.
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MonitorActiveRespDTO {
@ -51,11 +53,21 @@ public class MonitorActiveRespDTO {
*/
private List<Long> queueSizeList;
/**
* Range completed task count list
*/
private List<Long> rangeCompletedTaskCountList;
/**
* Completed task count list
*/
private List<Long> completedTaskCountList;
/**
* Range reject count list
*/
private List<Long> rangeRejectCountList;
/**
* Reject count list
*/
@ -66,11 +78,6 @@ public class MonitorActiveRespDTO {
*/
private List<Long> queueRemainingCapacityList;
/**
* Current load list
*/
private List<Long> currentLoadList;
/**
* Queue capacity list
*/

@ -44,4 +44,14 @@ public class MonitorQueryReqDTO {
* Instance id
*/
private String instanceId;
/**
* Start time
*/
private Long startTime;
/**
* End time
*/
private Long endTime;
}

@ -17,13 +17,14 @@
package cn.hippo4j.config.service.biz.impl;
import cn.hippo4j.common.model.Result;
import cn.hippo4j.common.monitor.Message;
import cn.hippo4j.common.monitor.MessageWrapper;
import cn.hippo4j.common.monitor.RuntimeMessage;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.common.toolkit.DateUtil;
import cn.hippo4j.common.toolkit.GroupKey;
import cn.hippo4j.common.toolkit.MessageConvert;
import cn.hippo4j.common.model.Result;
import cn.hippo4j.config.config.ServerBootstrapProperties;
import cn.hippo4j.config.mapper.HisRunDataMapper;
import cn.hippo4j.config.model.HisRunDataInfo;
@ -33,7 +34,6 @@ import cn.hippo4j.config.model.biz.monitor.MonitorRespDTO;
import cn.hippo4j.config.monitor.QueryMonitorExecuteChoose;
import cn.hippo4j.config.service.ConfigCacheService;
import cn.hippo4j.config.service.biz.HisRunDataService;
import cn.hippo4j.common.toolkit.BeanUtil;
import cn.hippo4j.server.common.base.Results;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
@ -45,7 +45,6 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import static cn.hippo4j.common.constant.MagicNumberConstants.INDEX_0;
import static cn.hippo4j.common.constant.MagicNumberConstants.INDEX_1;
@ -84,15 +83,20 @@ public class HisRunDataServiceImpl extends ServiceImpl<HisRunDataMapper, HisRunD
@Override
public MonitorActiveRespDTO queryInfoThreadPoolMonitor(MonitorQueryReqDTO reqDTO) {
LocalDateTime currentDate = LocalDateTime.now();
LocalDateTime dateTime = currentDate.plusMinutes(-properties.getCleanHistoryDataPeriod());
long startTime = DateUtil.getTime(dateTime);
Long startTime = reqDTO.getStartTime();
Long endTime = reqDTO.getEndTime();
if (startTime == null || endTime == null) {
LocalDateTime currentDate = LocalDateTime.now();
LocalDateTime dateTime = currentDate.plusMinutes(-properties.getCleanHistoryDataPeriod());
startTime = DateUtil.getTime(dateTime);
endTime = DateUtil.getTime(currentDate);
}
List<HisRunDataInfo> hisRunDataInfos = this.lambdaQuery()
.eq(HisRunDataInfo::getTenantId, reqDTO.getTenantId())
.eq(HisRunDataInfo::getItemId, reqDTO.getItemId())
.eq(HisRunDataInfo::getTpId, reqDTO.getTpId())
.eq(HisRunDataInfo::getInstanceId, reqDTO.getInstanceId())
.between(HisRunDataInfo::getTimestamp, startTime, DateUtil.getTime(currentDate))
.between(HisRunDataInfo::getTimestamp, startTime, endTime)
.orderByAsc(HisRunDataInfo::getTimestamp)
.list();
List<String> times = new ArrayList<>();
@ -100,34 +104,48 @@ public class HisRunDataServiceImpl extends ServiceImpl<HisRunDataMapper, HisRunD
List<Long> activeSizeList = new ArrayList<>();
List<Long> queueCapacityList = new ArrayList<>();
List<Long> queueSizeList = new ArrayList<>();
List<Long> rangeCompletedTaskCountList = new ArrayList<>();
List<Long> completedTaskCountList = new ArrayList<>();
List<Long> rangeRejectCountList = new ArrayList<>();
List<Long> rejectCountList = new ArrayList<>();
List<Long> queueRemainingCapacityList = new ArrayList<>();
List<Long> currentLoadList = new ArrayList<>();
long countTemp = 0L;
AtomicBoolean firstFlag = new AtomicBoolean(Boolean.TRUE);
long completedTaskCountTemp = 0L;
long rejectCountTemp = 0L;
boolean firstFlag = true;
for (HisRunDataInfo each : hisRunDataInfos) {
String time = DateUtil.format(new Date(each.getTimestamp()), NORM_TIME_PATTERN);
times.add(time);
poolSizeList.add(each.getPoolSize());
activeSizeList.add(each.getActiveSize());
queueSizeList.add(each.getQueueSize());
rejectCountList.add(each.getRejectCount());
queueRemainingCapacityList.add(each.getQueueRemainingCapacity());
currentLoadList.add(each.getCurrentLoad());
queueCapacityList.add(each.getQueueCapacity());
if (firstFlag.get()) {
if (firstFlag) {
firstFlag = false;
completedTaskCountList.add(0L);
firstFlag.set(Boolean.FALSE);
countTemp = each.getCompletedTaskCount();
completedTaskCountTemp = each.getCompletedTaskCount();
rejectCountTemp = each.getRejectCount();
continue;
}
long completedTaskCount = each.getCompletedTaskCount();
long countTask = completedTaskCount - countTemp;
completedTaskCountList.add(countTask);
countTemp = each.getCompletedTaskCount();
rangeCompletedTaskCountList.add(each.getCompletedTaskCount() - completedTaskCountTemp);
completedTaskCountList.add(each.getCompletedTaskCount());
rangeRejectCountList.add(each.getRejectCount() - rejectCountTemp);
rejectCountList.add(each.getRejectCount());
completedTaskCountTemp = each.getCompletedTaskCount();
rejectCountTemp = each.getRejectCount();
}
return new MonitorActiveRespDTO(times, poolSizeList, activeSizeList, queueSizeList, completedTaskCountList, rejectCountList, queueRemainingCapacityList, currentLoadList, queueCapacityList);
return MonitorActiveRespDTO.builder()
.times(times)
.poolSizeList(poolSizeList)
.activeSizeList(activeSizeList)
.queueSizeList(queueSizeList)
.queueCapacityList(queueCapacityList)
.rangeRejectCountList(rangeRejectCountList)
.rejectCountList(rejectCountList)
.completedTaskCountList(completedTaskCountList)
.rangeCompletedTaskCountList(rangeCompletedTaskCountList)
.queueRemainingCapacityList(queueRemainingCapacityList)
.build();
}
@Override

Loading…
Cancel
Save