@@ -0,0 +1,63 @@
|
||||
name: "Bug Report"
|
||||
description: Report a bug to help improve the project.
|
||||
title: "bug: "
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to report this bug!
|
||||
|
||||
_The more information you share, the faster we can identify and fix the bug._
|
||||
|
||||
Prior to opening the issue, please make sure that you:
|
||||
|
||||
- Use English to communicate.
|
||||
- Search the [open issues](https://github.com/APIParkLab/APIPark/issues) and [discussion forum](https://github.com/APIParkLab/APIPark/discussions) to avoid duplicating the issue.
|
||||
|
||||
- type: textarea
|
||||
id: current-behavior
|
||||
attributes:
|
||||
label: Current Behavior
|
||||
description: Describe the issue you are facing.
|
||||
placeholder: |
|
||||
What is the issue with the current behavior?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: expected-behavior
|
||||
attributes:
|
||||
label: Expected Behavior
|
||||
description: Describe what you expected to happen.
|
||||
placeholder: |
|
||||
What did you expect to happen instead?
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: error
|
||||
attributes:
|
||||
label: Error Logs
|
||||
description: Paste the error logs if any.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: steps
|
||||
attributes:
|
||||
label: Steps to Reproduce
|
||||
description: Share the steps you took so that we can reproduce the issue. Reports without proper steps details will likely be closed.
|
||||
placeholder: |
|
||||
1. Run apinto via the Docker image.
|
||||
2. Create a Route with the Admin API.
|
||||
3. Try configuring ...
|
||||
4. ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
description: Share your environment details. Reports without proper environment details will likely be closed.
|
||||
value: |
|
||||
- APINTO Dashboard version (run `apinto dashboard version`):
|
||||
- Operating system (run `uname -a`):
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: APIPark Discussion Forum
|
||||
url: https://github.com/APIParkLab/APIPark/discussions
|
||||
about: Please ask and answer questions here.
|
||||
@@ -0,0 +1,33 @@
|
||||
name: "Documentation Issue"
|
||||
description: Issues related to documentation.
|
||||
title: "docs: "
|
||||
labels: [doc]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
_The more information you share, the faster we can help you._
|
||||
|
||||
Prior to opening the issue, please make sure that you:
|
||||
|
||||
- Use English to communicate.
|
||||
- Search the [open issues](https://github.com/APIParkLab/APIPark/issues) and [discussion forum](https://github.com/APIParkLab/APIPark/discussions) to avoid duplicating the issue.
|
||||
|
||||
- type: textarea
|
||||
id: current-state
|
||||
attributes:
|
||||
label: Current State
|
||||
description: Describe the current state of the documentation.
|
||||
placeholder: |
|
||||
The documentation for the API in this page (url) is missing ...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: desired-state
|
||||
attributes:
|
||||
label: Desired State
|
||||
description: Describe the desired state the documentation should be in.
|
||||
placeholder: |
|
||||
There should be line mentioning how the API behaves when ...
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,23 @@
|
||||
name: "Feature Request"
|
||||
description: Suggest an enhancement to APINTO.
|
||||
title: "feat: As a user, I want to ..., so that ..."
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
_The more information you share, the faster we can help you._
|
||||
|
||||
Prior to opening the issue, please make sure that you:
|
||||
|
||||
- Use English to communicate.
|
||||
- Search the [open issues](https://github.com/APIParkLab/APIPark/issues) and [discussion forum](https://github.com/APIParkLab/APIPark/discussions) to avoid duplicating the issue.
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Describe the feature you would like to see.
|
||||
placeholder: |
|
||||
As a user, I want to ..., so that...
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,31 @@
|
||||
name: "Request Help"
|
||||
description: Stuck? Ask for help!
|
||||
title: "help request: "
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
_The more information you share, the faster we can help you._
|
||||
|
||||
Prior to opening the issue, please make sure that you:
|
||||
|
||||
- Use English to communicate.
|
||||
- Search the [open issues](https://github.com/APIParkLab/APIPark/issues) and [discussion forum](https://github.com/APIParkLab/APIPark/discussions) to avoid duplicating the issue.
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Describe the issue you are facing and what you need help with.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
description: Share your environment details. Reports without proper environment details will likely be closed.
|
||||
value: |
|
||||
- APIPark version (run `apinto dashboard version`):
|
||||
- Operating system (run `uname -a`):
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,86 @@
|
||||
name: release
|
||||
#触发机制,当创建tag时
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
jobs:
|
||||
frontend-builder:
|
||||
name: frontend-builder
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: SetOutput
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/v}" >> $GITHUB_OUTPUT
|
||||
- name: Checkout #Checkout代码
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Node
|
||||
uses: actions/setup-node@v3.0.0
|
||||
with:
|
||||
node-version: '18.12'
|
||||
- name: Pnpm install and build
|
||||
run: |
|
||||
npm install -g pnpm
|
||||
pnpm install --registry https://registry.npmmirror.com --dir ./frontend
|
||||
echo "Build frontend..."
|
||||
cd ./frontend && pnpm run build
|
||||
- name: upload frontend release
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: frontend-package
|
||||
path: frontend/dist
|
||||
release:
|
||||
needs: [frontend-builder]
|
||||
name: release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: SetOutput #处理Tag字符串并存进outputs
|
||||
id: vars
|
||||
run: |
|
||||
echo "tag=${GITHUB_REF#refs/*/v}" >> $GITHUB_OUTPUT
|
||||
- name: Checkout #Checkout代码
|
||||
uses: actions/checkout@v3
|
||||
- name: download frontend release
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: frontend-package
|
||||
path: frontend/dist
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '1.21.1'
|
||||
- name: Go tidy
|
||||
run: |
|
||||
go mod tidy
|
||||
echo "GOVERSION=$(go version)" >> $GITHUB_ENV
|
||||
- name: Create archives on Release #创建各种系统架构下的二进制包并上传至release assets
|
||||
uses: goreleaser/goreleaser-action@v3.1.0
|
||||
with:
|
||||
version: 1.9.2
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
docker-push:
|
||||
needs: [frontend-builder]
|
||||
name: docker-push
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: SetOutput
|
||||
id: vars
|
||||
run: echo "tag=${GITHUB_REF#refs/*/v}" >> $GITHUB_OUTPUT
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: download frontend release
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: frontend-package
|
||||
path: frontend/dist
|
||||
- name: Login Docker #登录docker
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
|
||||
- name: build
|
||||
run: cd scripts && ./docker_publish.sh ${{ secrets.DOCKER_USERNAME }} "backend"
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
*.DS_Store
|
||||
/.idea/
|
||||
/config.yml
|
||||
/build/
|
||||
/apipark
|
||||
|
||||
@@ -16,8 +16,8 @@ type IDynamicModuleController interface {
|
||||
List(ctx *gin.Context, module string, keyword string, cluster string, page string, pageSize string) ([]map[string]interface{}, *dynamic_module_dto.PluginInfo, int64, error)
|
||||
Render(ctx *gin.Context, module string) (*dynamic_module_dto.PluginBasic, map[string]interface{}, error)
|
||||
ModuleDrivers(ctx *gin.Context, group string) ([]*dynamic_module_dto.ModuleDriver, error)
|
||||
Online(ctx *gin.Context, module string, id string, partitionInput *dynamic_module_dto.ClusterInput) error
|
||||
Offline(ctx *gin.Context, module string, id string, partitionInput *dynamic_module_dto.ClusterInput) error
|
||||
Online(ctx *gin.Context, module string, id string) error
|
||||
Offline(ctx *gin.Context, module string, id string) error
|
||||
//PartitionStatuses(ctx *gin.Context, module string, keyword string, page string, pageSize string) (map[string]map[string]string, error)
|
||||
//PartitionStatus(ctx *gin.Context, module string, id string) (*dynamic_module_dto.OnlineInfo, error)
|
||||
}
|
||||
|
||||
@@ -15,12 +15,12 @@ type imlDynamicModuleController struct {
|
||||
module dynamic_module.IDynamicModuleModule `autowired:""`
|
||||
}
|
||||
|
||||
func (i *imlDynamicModuleController) Online(ctx *gin.Context, module string, id string, partitionInput *dynamic_module_dto.ClusterInput) error {
|
||||
return i.module.Online(ctx, module, id, partitionInput)
|
||||
func (i *imlDynamicModuleController) Online(ctx *gin.Context, module string, id string) error {
|
||||
return i.module.Online(ctx, module, id)
|
||||
}
|
||||
|
||||
func (i *imlDynamicModuleController) Offline(ctx *gin.Context, module string, id string, partitionInput *dynamic_module_dto.ClusterInput) error {
|
||||
return i.module.Offline(ctx, module, id, partitionInput)
|
||||
func (i *imlDynamicModuleController) Offline(ctx *gin.Context, module string, id string) error {
|
||||
return i.module.Offline(ctx, module, id)
|
||||
}
|
||||
|
||||
//func (i *imlDynamicModuleController) PartitionStatuses(ctx *gin.Context, module string, keyword string, page string, pageSize string) (map[string]map[string]string, error) {
|
||||
|
||||
@@ -14,6 +14,10 @@ type imlTeamController struct {
|
||||
module my_team.ITeamModule `autowired:""`
|
||||
}
|
||||
|
||||
func (c *imlTeamController) SimpleTeams(ctx *gin.Context, keyword string) ([]*team_dto.SimpleTeam, error) {
|
||||
return c.module.SimpleTeams(ctx, keyword)
|
||||
}
|
||||
|
||||
func (c *imlTeamController) UpdateMemberRole(ctx *gin.Context, id string, input *team_dto.UpdateMemberRole) error {
|
||||
return c.module.UpdateMemberRole(ctx, id, input)
|
||||
}
|
||||
@@ -23,7 +27,7 @@ func (c *imlTeamController) GetTeam(ctx *gin.Context, id string) (*team_dto.Team
|
||||
}
|
||||
|
||||
func (c *imlTeamController) Search(ctx *gin.Context, keyword string) ([]*team_dto.Item, error) {
|
||||
|
||||
|
||||
return c.module.Search(ctx, keyword)
|
||||
}
|
||||
|
||||
@@ -31,8 +35,8 @@ func (c *imlTeamController) EditTeam(ctx *gin.Context, id string, team *team_dto
|
||||
return c.module.Edit(ctx, id, team)
|
||||
}
|
||||
|
||||
func (c *imlTeamController) SimpleTeams(ctx *gin.Context, keyword string) ([]*team_dto.SimpleTeam, error) {
|
||||
return c.module.SimpleTeams(ctx, keyword)
|
||||
func (c *imlTeamController) MySimpleTeams(ctx *gin.Context, keyword string) ([]*team_dto.SimpleTeam, error) {
|
||||
return c.module.MySimpleTeams(ctx, keyword)
|
||||
}
|
||||
|
||||
func (c *imlTeamController) AddMember(ctx *gin.Context, id string, users *team_dto.UserIDs) error {
|
||||
|
||||
@@ -2,7 +2,7 @@ package my_team
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
|
||||
team_dto "github.com/APIParkLab/APIPark/module/my-team/dto"
|
||||
"github.com/eolinker/go-common/autowire"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -13,6 +13,7 @@ type ITeamController interface {
|
||||
GetTeam(ctx *gin.Context, id string) (*team_dto.Team, error)
|
||||
Search(ctx *gin.Context, keyword string) ([]*team_dto.Item, error)
|
||||
EditTeam(ctx *gin.Context, id string, team *team_dto.EditTeam) (*team_dto.Team, error)
|
||||
MySimpleTeams(ctx *gin.Context, keyword string) ([]*team_dto.SimpleTeam, error)
|
||||
SimpleTeams(ctx *gin.Context, keyword string) ([]*team_dto.SimpleTeam, error)
|
||||
AddMember(ctx *gin.Context, id string, users *team_dto.UserIDs) error
|
||||
RemoveMember(ctx *gin.Context, id string, uuid string) error
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
"@vitejs/plugin-react": "^4.2.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"dayjs": "^1.11.10",
|
||||
"dompurify": "^3.1.6",
|
||||
"js-base64": "^3.7.5",
|
||||
"moment": "^2.29.4",
|
||||
"postcss": "^8.4.31",
|
||||
|
||||
@@ -28,6 +28,6 @@
|
||||
"@businessEntry/*": ["./src/*"],
|
||||
},
|
||||
},
|
||||
"include": ["src", "public/iconpark_eolink.js", "public/iconpark_apinto.js", "../common/src/component/aoplatform/EditableTableWithModal.tsx", "../common/src/components/aoplatform/TransferTable.tsx", "../common/src/components/aoplatform/TreeWithMore.tsx", "../common/src/components/aoplatform/DatePicker.tsx", "../common/src/components/aoplatform/TimeRangeSelector.tsx", "../common/src/components/aoplatform/TimePicker.tsx", "../common/src/components/aoplatform/MemberTransfer.tsx", "../common/src/components/aoplatform/Navigation.tsx", "../common/src/components/aoplatform/PageList.tsx", "../common/src/components/aoplatform/GroupTree.tsx", "../common/src/components/aoplatform/ErrorBoundary.tsx", "../common/src/components/aoplatform/ScrollableSection.tsx", "../common/src/utils/postcat.tsx", "../common/src/utils/curl.ts", "../common/src/components/aoplatform/ResetPsw.tsx", "../common/src/components/aoplatform/SubscribeApprovalModalContent.tsx", "../common/src/components/aoplatform/InsidePageForHub.tsx", "src/components/aoplatform/RenderRoutes.tsx", "../common/src/components/aoplatform/PublishApprovalModalContent.tsx", "../common/src/components/aoplatform/InsidePage.tsx", "../common/src/const/type.ts", "../common/src/components/aoplatform/intelligent-plugin", "../common/src/const/domain"],
|
||||
"include": ["src", "public/iconpark_eolink.js", "public/iconpark_apinto.js", "../common/src/component/aoplatform/EditableTableWithModal.tsx", "../common/src/components/aoplatform/TransferTable.tsx", "../common/src/components/aoplatform/TreeWithMore.tsx", "../common/src/components/aoplatform/DatePicker.tsx", "../common/src/components/aoplatform/TimeRangeSelector.tsx", "../common/src/components/aoplatform/TimePicker.tsx", "../common/src/components/aoplatform/MemberTransfer.tsx", "../common/src/components/aoplatform/Navigation.tsx", "../common/src/components/aoplatform/PageList.tsx", "../common/src/components/aoplatform/GroupTree.tsx", "../common/src/components/aoplatform/ErrorBoundary.tsx", "../common/src/components/aoplatform/ScrollableSection.tsx", "../common/src/utils/postcat.tsx", "../common/src/utils/curl.ts", "../common/src/components/aoplatform/ResetPsw.tsx", "../common/src/components/aoplatform/SubscribeApprovalModalContent.tsx", "src/components/aoplatform/RenderRoutes.tsx", "../common/src/components/aoplatform/PublishApprovalModalContent.tsx", "../common/src/components/aoplatform/InsidePage.tsx", "../common/src/const/type.ts", "../common/src/components/aoplatform/intelligent-plugin", "../common/src/const/domain"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<svg width="30" height="30" viewBox="0 0 30 30" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_652_44370)">
|
||||
<path d="M26.9998 0.501787H27.0086L27.0174 0.501479C27.3465 0.489919 27.6745 0.546231 27.981 0.66691C28.2875 0.78759 28.5658 0.970053 28.7987 1.20294C29.0316 1.43583 29.214 1.71417 29.3347 2.02062C29.4554 2.32707 29.5117 2.65508 29.5001 2.98424L29.4998 2.99301V3.00179V27.0018V27.0106L29.5001 27.0193C29.5117 27.3485 29.4554 27.6765 29.3347 27.983C29.214 28.2894 29.0316 28.5677 28.7987 28.8006C28.5658 29.0335 28.2875 29.216 27.981 29.3367C27.6745 29.4573 27.3465 29.5137 27.0174 29.5021L27.0086 29.5018H26.9998H2.99983H2.99106L2.98228 29.5021C2.65313 29.5137 2.32512 29.4573 2.01867 29.3367C1.71221 29.216 1.43388 29.0335 1.20099 28.8006C0.9681 28.5677 0.785636 28.2894 0.664957 27.983C0.544278 27.6765 0.487966 27.3485 0.499526 27.0193L0.499834 27.0106V27.0018V3.00179V2.99301L0.499526 2.98424C0.487966 2.65508 0.544278 2.32707 0.664957 2.02062C0.785636 1.71417 0.9681 1.43583 1.20099 1.20294C1.43388 0.970053 1.71221 0.787589 2.01867 0.66691C2.32512 0.546231 2.65313 0.489919 2.98228 0.501479L2.99106 0.501787H2.99983H26.9998Z" fill="#E8EFFE" stroke="#E8EFFE"/>
|
||||
<rect x="12.2227" y="23.6289" width="5.53122" height="4.14832" fill="#F9D6C2"/>
|
||||
<ellipse cx="22.248" cy="17.0625" rx="1.0371" ry="1.72847" fill="#FFE6D8"/>
|
||||
<ellipse cx="7.72851" cy="17.0625" rx="1.0371" ry="1.72847" fill="#FFE6D8"/>
|
||||
<ellipse cx="14.9882" cy="16.7166" rx="7.60543" ry="8.29663" fill="#FFE6D8"/>
|
||||
<path d="M10 11.5C8.5 11.5 8.30468 13.7205 8.07421 15.3337L7.72851 10.494C7.26757 10.494 6.3457 10.0792 6.3457 8.41985C6.3457 6.76052 7.03711 6.34569 7.38281 6.34569C9.11131 6.23046 13.1214 6 15.3339 6C18.0995 6 19.1366 6 20.1738 7.38277C21.0034 8.48899 20.289 9.91786 19.8281 10.494C16.832 10.494 12.3662 11.5 10 11.5Z" fill="#333333" stroke="#333333" stroke-width="0.691394"/>
|
||||
<path d="M21.9023 9.11089C23.2851 9.94055 22.709 13.144 22.248 14.642L19.1367 9.8028C19.252 9.57234 20.5195 8.28123 21.9023 9.11089Z" fill="#333333" stroke="#333333" stroke-width="0.691394"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.9891 27.7778C16.5165 27.7778 17.7547 26.8492 17.7547 25.7036C17.7547 25.536 17.7282 25.3729 17.6781 25.2168C21.3287 25.7883 23.9774 27.4926 23.9774 29.5063C23.9774 31.9882 19.9533 34.0003 14.9892 34.0003C10.0251 34.0003 6.00098 31.9882 6.00098 29.5063C6.00098 27.4926 8.64969 25.7883 12.3001 25.2168C12.2501 25.373 12.2235 25.536 12.2235 25.7036C12.2235 26.8492 13.4617 27.7778 14.9891 27.7778Z" fill="#1861F2"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_652_44370">
|
||||
<rect width="30" height="30" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 3.9 KiB |
@@ -2,9 +2,10 @@ import {
|
||||
ConfigProvider,
|
||||
Dropdown,
|
||||
MenuProps,
|
||||
App} from 'antd';
|
||||
App,
|
||||
Button} from 'antd';
|
||||
import Logo from '@common/assets/layout-logo.png';
|
||||
import AvatarPic from '@common/assets/avatar_default.svg'
|
||||
import AvatarPic from '@common/assets/default-avatar.png'
|
||||
import { routerKeyMap, TOTAL_MENU_ITEMS } from "./Navigation";
|
||||
import {Outlet, useLocation, useNavigate} from "react-router-dom";
|
||||
import {useEffect, useMemo, useRef, useState} from "react";
|
||||
@@ -19,6 +20,8 @@ import { ResetPsw, ResetPswHandle } from './ResetPsw.tsx';
|
||||
import { BasicResponse, STATUS_CODE } from '@common/const/const.ts';
|
||||
import { UserInfoType, UserProfileHandle } from '@common/const/type.ts';
|
||||
import { useFetch } from '@common/hooks/http.ts';
|
||||
import { QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import { Icon } from '@iconify/react/dist/iconify.js';
|
||||
|
||||
const themeToken = {
|
||||
bgLayout:'#17163E;',
|
||||
@@ -122,13 +125,19 @@ const themeToken = {
|
||||
}
|
||||
|
||||
const items: MenuProps['items'] = [
|
||||
{
|
||||
key: '2',
|
||||
label: (
|
||||
<Button key="changePsw" type="text" className="border-none p-0 flex items-center bg-transparent " onClick={()=>navigator('/userProfile/changepsw')}>
|
||||
账号设置
|
||||
</Button>)
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: (
|
||||
<a className="block px-btnbase leading-[32px]" target="_blank" rel="noopener noreferrer" onClick={logOut}>
|
||||
退出登录
|
||||
</a>
|
||||
),
|
||||
<Button key="logout" type="text" className="border-none p-0 flex items-center bg-transparent " onClick={logOut}>
|
||||
退出登录
|
||||
</Button>)
|
||||
},
|
||||
];
|
||||
|
||||
@@ -210,19 +219,19 @@ const themeToken = {
|
||||
);
|
||||
},
|
||||
}}
|
||||
// actionsRender={(props) => {
|
||||
// if (props.isMobile) return [];
|
||||
// if (typeof window === 'undefined') return [];
|
||||
// return [
|
||||
// <Button className="mr-[20px]">
|
||||
// <span className='flex items-center'><QuestionCircleOutlined className="mr-[4px]" />帮助文档</span>
|
||||
// </Button>
|
||||
// ];
|
||||
// }}
|
||||
actionsRender={(props) => {
|
||||
if (props.isMobile) return [];
|
||||
if (typeof window === 'undefined') return [];
|
||||
return [
|
||||
<Button className=" text-[#ffffffb3] hover:text-[#fff] border-none" type="default" ghost onClick={()=>{window.open('https://docs.apipark.com','_blank')}}>
|
||||
<span className='flex items-center gap-[8px]'> <Icon icon="ic:baseline-help" width="14" height="14"/>文档</span>
|
||||
</Button>
|
||||
];
|
||||
}}
|
||||
headerTitleRender={() => (
|
||||
<div className="w-[192px] flex items-center">
|
||||
<img
|
||||
className="h-[20px] cursor-pointer"
|
||||
className="h-[20px] cursor-pointer "
|
||||
src={Logo}
|
||||
onClick={()=> navigator(mainPage)}
|
||||
/>
|
||||
@@ -259,7 +268,7 @@ const themeToken = {
|
||||
collapsed={false}
|
||||
collapsedButtonRender={false}
|
||||
>
|
||||
<div className={`w-full h-calc-100vh-minus-navbar px-[40px] pt-[30px] ${currentUrl.startsWith('/role/list') ? 'overflow-auto' : 'overflow-hidden' }`}>
|
||||
<div className={`w-full h-calc-100vh-minus-navbar pl-PAGE_INSIDE_X pt-PAGE_INSIDE_T ${currentUrl.startsWith('/role/list') ? 'overflow-auto' : 'overflow-hidden' }`}>
|
||||
<Outlet />
|
||||
</div>
|
||||
</ProLayout>
|
||||
|
||||
@@ -34,8 +34,11 @@ export function DrawerWithFooter(props:DrawerWithFooterProps){
|
||||
width="60%"
|
||||
destroyOnClose={true}
|
||||
maskClosable={false}
|
||||
classNames={
|
||||
{footer:'text-right'}
|
||||
}
|
||||
footer={
|
||||
<Space >
|
||||
<Space className="flex flex-row-reverse" style={{}}>
|
||||
{showOkBtn && <WithPermission access={submitAccess}>
|
||||
<Button onClick={handlerSubmit} type="primary" loading={submitLoading} disabled={submitDisabled}>
|
||||
{okBtnTitle}
|
||||
|
||||
@@ -17,9 +17,14 @@ class InsidePageProps {
|
||||
onBtnClick?:()=>void
|
||||
backUrl?:string = '/'
|
||||
btnAccess?:string
|
||||
showBorder?:boolean = true
|
||||
className?:string = ''
|
||||
contentClassName?:string=''
|
||||
/** 整个页面滚动 */
|
||||
scrollPage?:boolean = true
|
||||
}
|
||||
|
||||
const InsidePage:FC<InsidePageProps> = ({showBanner=true,pageTitle,tagList,showBtn,btnTitle,btnAccess,description,children,onBtnClick,backUrl})=>{
|
||||
const InsidePage:FC<InsidePageProps> = ({showBanner=true,pageTitle,tagList,showBtn,btnTitle,btnAccess,description,children,onBtnClick,backUrl,showBorder=true,className='',contentClassName='',scrollPage=true})=>{
|
||||
const navigate = useNavigate();
|
||||
|
||||
const goBack = () => {
|
||||
@@ -27,27 +32,29 @@ const InsidePage:FC<InsidePageProps> = ({showBanner=true,pageTitle,tagList,showB
|
||||
};
|
||||
return (
|
||||
// <div className="h-full flex flex-col flex-1 overflow-hidden bg-[#f7f8fa]">
|
||||
<div className="h-full flex flex-col flex-1 overflow-hidden ">
|
||||
{ showBanner && <div className=" mx-[4px] border-[0px] border-b-[1px] border-solid border-BORDER">
|
||||
{backUrl &&<div className="text-[18px] leading-[25px] pb-[12px]">
|
||||
<Button type="text" onClick={goBack}><ArrowLeftOutlined className="max-h-[14px]" />返回</Button>
|
||||
</div>}
|
||||
<div className="flex justify-between">
|
||||
<div className="flex items-center">
|
||||
<p className="text-theme text-[26px] pr-[10px]">{pageTitle}</p>
|
||||
{tagList && tagList?.length > 0 && tagList?.map((tag)=>{
|
||||
return ( <Tag className="" key={tag.label as string} bordered={false} >{tag.label}</Tag>)
|
||||
})}
|
||||
<div className={`h-full flex flex-col flex-1 overflow-hidden ${className}`}>
|
||||
{ showBanner && <div className={`border-[0px] mr-PAGE_INSIDE_X ${showBorder ? 'border-b-[1px] border-solid border-BORDER' : ''}`}>
|
||||
<div className="mb-[30px]">
|
||||
{backUrl &&<div className="text-[18px] leading-[25px] mb-[12px]">
|
||||
<Button type="text" onClick={goBack}><ArrowLeftOutlined className="max-h-[14px]" />返回</Button>
|
||||
</div>}
|
||||
<div className="flex justify-between mb-[20px] items-center ">
|
||||
<div className="flex items-center gap-TAG_LEFT ">
|
||||
<p className="text-theme text-[26px] ">{pageTitle}</p>
|
||||
{tagList && tagList?.length > 0 && tagList?.map((tag)=>{
|
||||
return ( <Tag key={tag.label as string} bordered={false} >{tag.label}</Tag>)
|
||||
})}
|
||||
</div>
|
||||
{showBtn && <WithPermission access={btnAccess}><Button type="primary" onClick={()=> {
|
||||
onBtnClick&&onBtnClick()
|
||||
}}>{btnTitle}</Button></WithPermission>}
|
||||
</div>
|
||||
{showBtn && <WithPermission access={btnAccess}><Button type="primary" onClick={()=> {
|
||||
onBtnClick&&onBtnClick()
|
||||
}}>{btnTitle}</Button></WithPermission>}
|
||||
<p >
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
<p className="mb-[30px]">
|
||||
{description}
|
||||
</p>
|
||||
</div>}
|
||||
<div className="h-full overflow-y-hidden">{children}</div>
|
||||
<div className={`h-full ${scrollPage ? 'overflow-hidden' : 'overflow-auto'} ${contentClassName || ''}`}>{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
|
||||
import { Button, Tag } from "antd"
|
||||
import {useNavigate} from "react-router-dom";
|
||||
import WithPermission from "@common/components/aoplatform/WithPermission";
|
||||
import { FC, ReactNode } from "react";
|
||||
import { ArrowLeftOutlined } from "@ant-design/icons";
|
||||
|
||||
|
||||
class InsidePageProps {
|
||||
showBanner?:boolean = true
|
||||
pageTitle:string = ''
|
||||
tagList?:Array<{label:string|ReactNode}> = []
|
||||
children:React.ReactNode
|
||||
showBtn?:boolean = false
|
||||
btnTitle?:string = ''
|
||||
description?:string = ''
|
||||
onBtnClick?:()=>void
|
||||
backUrl:string = '/'
|
||||
btnAccess?:string
|
||||
}
|
||||
|
||||
const InsidePageForHub:FC<InsidePageProps> = ({showBanner=true,pageTitle,tagList,showBtn,btnTitle,btnAccess,description,children,onBtnClick,backUrl})=>{
|
||||
const navigate = useNavigate();
|
||||
|
||||
const goBack = () => {
|
||||
navigate(backUrl);
|
||||
};
|
||||
return (
|
||||
<div className="h-full flex flex-col flex-1 overflow-hidden max-w-[1500px] m-auto">
|
||||
{ showBanner && <div className="p-btnbase mx-[4px]">
|
||||
<div className="text-[18px] leading-[25px] pb-[12px]">
|
||||
<Button type="text" onClick={goBack}><ArrowLeftOutlined className="max-h-[14px]" />返回</Button>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<div className="">
|
||||
<span className="text-[26px] text-theme">{pageTitle}</span>
|
||||
{tagList && tagList?.length > 0 && tagList?.map((tag)=>{
|
||||
return ( <Tag key={tag.label as string} bordered={false}>{tag.label}</Tag>)
|
||||
})}
|
||||
</div>
|
||||
{showBtn && <WithPermission access={btnAccess}><Button type="primary" onClick={()=> {
|
||||
onBtnClick&&onBtnClick()
|
||||
}}>{btnTitle}</Button></WithPermission>}
|
||||
</div>
|
||||
<p className="mb-[30px]">
|
||||
{description}
|
||||
</p>
|
||||
</div>}
|
||||
<div className="h-full overflow-y-hidden">{children}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default InsidePageForHub
|
||||
@@ -4,7 +4,6 @@
|
||||
}
|
||||
|
||||
:global .eo_page_list .ant-pro-table-list-toolbar-container{
|
||||
padding:10px 20px 10px 10px !important;
|
||||
|
||||
.ant-pro-table-list-toolbar-right{
|
||||
justify-content: flex-start;
|
||||
|
||||
@@ -77,8 +77,9 @@ const PageList = <T extends Record<string, unknown>>(props: React.PropsWithChild
|
||||
const handleResize = () => {
|
||||
if (parentRef.current && !noScroll) {
|
||||
const res = parentRef.current.getBoundingClientRect();
|
||||
const height = res.height - ((noTop ? 0 : 52) + 40 + (showPagination && !dragSortKey ? 52 : 0) +( besidesTableHeight ?? 0)); // 减去顶部按钮、底部分页、表头高度
|
||||
setTableWidth(minTableWidth > res.width ? minTableWidth : undefined);
|
||||
const height = res.height - ((noTop ? 0 : 59) + 54 + (showPagination && !dragSortKey ? 52 : 0) +( besidesTableHeight ?? 0) + 1); // 减去顶部按钮、底部分页、表头高度
|
||||
setTableWidth(minTableWidth - 5> res.width ? minTableWidth : undefined);
|
||||
console.log(minTableWidth,res.width )
|
||||
height && setTableHeight(minVirtualHeight === undefined ? height : (height > minVirtualHeight ? height : minVirtualHeight));
|
||||
}
|
||||
};
|
||||
@@ -112,11 +113,11 @@ const PageList = <T extends Record<string, unknown>>(props: React.PropsWithChild
|
||||
const newColumns = useMemo(()=>{
|
||||
let width:number = 0
|
||||
const res = columns?.map(
|
||||
(x)=>{
|
||||
(x, index)=>{
|
||||
width += Number(x.width ?? ((x.filters || x.sorter) ? 120 : 100))
|
||||
x.copyable = x.copyable === false? false: true
|
||||
const sorter = localStorage.getItem(`${id}_sorter`)
|
||||
const filters = localStorage.getItem(`${id}_filters`)
|
||||
x.copyable = x.copyable ?? (index === 0 || x.dataIndex === 'id' || x.dataIndex === 'email')
|
||||
if(sorter && x.sorter){
|
||||
const sorterObj = JSON.parse(sorter)
|
||||
const xName = Array.isArray(x.dataIndex) ? x.dataIndex.join(','):x.dataIndex
|
||||
@@ -137,7 +138,7 @@ const PageList = <T extends Record<string, unknown>>(props: React.PropsWithChild
|
||||
return (
|
||||
<>{
|
||||
tableTitle ? <span className={`text-[30px] leading-[42px] my-mbase pl-[20px] ${tableTitleClass}`}>{tableTitle}</span> : (
|
||||
addNewBtnTitle ? <WithPermission access={addNewBtnAccess} ><Button type="primary" className={`mr-btnbase ${addNewBtnWrapperClass}`} onClick={onAddNewBtnClick}>{addNewBtnTitle}</Button></WithPermission> : undefined
|
||||
addNewBtnTitle ? <WithPermission access={addNewBtnAccess} ><Button type="primary" className={`mr-btnrbase my-btnbase ${addNewBtnWrapperClass}`} onClick={onAddNewBtnClick}>{addNewBtnTitle}</Button></WithPermission> : undefined
|
||||
)
|
||||
|
||||
}
|
||||
@@ -191,7 +192,7 @@ const PageList = <T extends Record<string, unknown>>(props: React.PropsWithChild
|
||||
</Dropdown>):null,
|
||||
]}
|
||||
toolbar={{
|
||||
actions:[...[beforeSearchNode],...[searchPlaceholder?<Input className="" onChange={ onSearchWordChange ? (e) => debounce(onSearchWordChange, 100)(e) : undefined } onPressEnter={()=>manualReloadTable ? manualReloadTable():actionRef.current?.reload?.()} allowClear placeholder={searchPlaceholder} prefix={<SearchOutlined className="cursor-pointer" onClick={()=>{actionRef.current?.reload?.()}}/>}/>:null]],
|
||||
actions:[...[beforeSearchNode],...[searchPlaceholder?<Input className="my-btnbase ml-btnbase" onChange={ onSearchWordChange ? (e) => debounce(onSearchWordChange, 100)(e) : undefined } onPressEnter={()=>manualReloadTable ? manualReloadTable():actionRef.current?.reload?.()} allowClear placeholder={searchPlaceholder} prefix={<SearchOutlined className="cursor-pointer" onClick={()=>{actionRef.current?.reload?.()}}/>}/>:null]],
|
||||
}}
|
||||
options={{
|
||||
reload: false,
|
||||
|
||||
@@ -26,19 +26,16 @@ const apiColumns = [
|
||||
{
|
||||
title:'API 名称',
|
||||
dataIndex:'name',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title:'请求方式',
|
||||
dataIndex:'method',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title:'路径',
|
||||
dataIndex:'path',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -77,7 +74,6 @@ const upstreamColumns = [
|
||||
title:'地址',
|
||||
dataIndex:'addr',
|
||||
render:(text:string[])=>(<>{text.join(',')}</>),
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -265,7 +261,7 @@ export const PublishApprovalModalContent = forwardRef<PublishApprovalModalHandle
|
||||
>
|
||||
<Input.TextArea className="w-INPUT_NORMAL" disabled={type !== 'add' && type !== 'publish'} placeholder="请输入" />
|
||||
</Form.Item>
|
||||
|
||||
{/*
|
||||
{type !== 'add' && type !== 'publish' && <Form.Item
|
||||
label="审批意见"
|
||||
name="opinion"
|
||||
@@ -277,7 +273,7 @@ export const PublishApprovalModalContent = forwardRef<PublishApprovalModalHandle
|
||||
errors: [], // 设置为空数组来移除错误信息
|
||||
},
|
||||
]);}}/>
|
||||
</Form.Item>}
|
||||
</Form.Item>} */}
|
||||
|
||||
{['error','done'].indexOf(data.status) !== -1 && data.clusterPublishStatus &&data.clusterPublishStatus.length > 0 && <> <Row className="text-left h-[32px] mb-8px]" span={3}><span>上线情况:</span></Row>
|
||||
<Row span={24} className="mb-mbase">
|
||||
|
||||
@@ -73,7 +73,7 @@ export const ResetPsw = forwardRef<ResetPswHandle,ResetPswProps>((props,ref)=>{
|
||||
layout='vertical'
|
||||
form={form}
|
||||
scrollToFirstError
|
||||
className="mx-auto mt-mbase "
|
||||
className="mx-auto mt-mbase ml-mbase"
|
||||
name="resetPsw"
|
||||
// labelCol={{ span: 8 }}
|
||||
// wrapperCol={{ span: 10}}
|
||||
|
||||
@@ -70,7 +70,7 @@ const UserAvatar: FC = () => {
|
||||
{
|
||||
key: '3',
|
||||
label: (
|
||||
<a className="block px-btnbase leading-[32px]" target="_blank" rel="noopener noreferrer" onClick={logOut}>
|
||||
<a className="block leading-[32px]" target="_blank" rel="noopener noreferrer" onClick={logOut}>
|
||||
退出登录
|
||||
</a>
|
||||
),
|
||||
|
||||
@@ -9,9 +9,10 @@ type WithPermissionProps = {
|
||||
tooltip?:string
|
||||
children:ReactElement
|
||||
disabled?:boolean
|
||||
showDisabled?:boolean
|
||||
}
|
||||
// 权限控制的高阶组件
|
||||
const WithPermission = ({access, tooltip, children,disabled}:WithPermissionProps) => {
|
||||
const WithPermission = ({access, tooltip, children,disabled, showDisabled = true}:WithPermissionProps) => {
|
||||
|
||||
const [editAccess, setEditAccess] = useState<boolean>(access ? false:true)
|
||||
const {accessData,checkPermission} = useGlobalContext()
|
||||
@@ -24,16 +25,21 @@ const WithPermission = ({access, tooltip, children,disabled}:WithPermissionProps
|
||||
useEffect(()=>{
|
||||
// 先判断权限,无论权限是否为true,如果disabled为true时则必须为ture
|
||||
access && setEditAccess(lastAccess)
|
||||
disabled && setEditAccess(false)
|
||||
console.log('editAccess',editAccess, children,children?.type?.displayName,showDisabled, children?.type?.displayName !== 'Button' && showDisabled)
|
||||
},[lastAccess,disabled])
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{editAccess ? cloneElement(children):
|
||||
<Tooltip title={tooltip ?? "暂无操作权限,请联系管理员分配。"}>
|
||||
{ cloneElement(children, {disabled:true})}
|
||||
</Tooltip>
|
||||
}
|
||||
{editAccess && !disabled && cloneElement(children)}
|
||||
{editAccess && disabled && <Tooltip title={tooltip}>
|
||||
{ cloneElement(children, {disabled:true})}
|
||||
</Tooltip>}
|
||||
{!editAccess && (children?.type?.displayName !== 'Button' && showDisabled ) && <Tooltip title={tooltip ?? "暂无操作权限,请联系管理员分配。"}>
|
||||
{ cloneElement(children, {disabled:true})}
|
||||
</Tooltip>}
|
||||
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ import {createSchemaField, FormProvider, RecursionField, useField, useForm} from
|
||||
import {BasicResponse, STATUS_CODE} from "@common/const/const.ts";
|
||||
import {useFetch} from "@common/hooks/http.ts";
|
||||
import {App} from "antd";
|
||||
import { config } from "process";
|
||||
|
||||
|
||||
|
||||
@@ -218,8 +219,8 @@ export const IntelligentPluginConfig = forwardRef<IntelligentPluginConfigHandle
|
||||
placeholder: '请输入描述',
|
||||
}
|
||||
},
|
||||
container: {
|
||||
type: 'void',
|
||||
config: {
|
||||
type: 'object',
|
||||
'x-component': 'DynamicRender',
|
||||
'x-component-props': {
|
||||
schema: JSON.stringify(renderSchema),
|
||||
|
||||
@@ -130,10 +130,9 @@ export default function IntelligentPluginList(){
|
||||
message.destroy();
|
||||
if(res.code === STATUS_CODE.SUCCESS){
|
||||
getConfig(res.data)
|
||||
setColumns(res.data.basic.fields.map((field:DynamicTableField)=>({
|
||||
setColumns(res.data.basic.fields.map((field:DynamicTableField, index:number)=>({
|
||||
title:field.title,
|
||||
dataIndex:field.name,
|
||||
copyable: true,
|
||||
fixed:field.name === 'title' ? 'left' : undefined,
|
||||
ellipsis:true,
|
||||
width:field.name === 'title' ? 150 : undefined,
|
||||
@@ -227,7 +226,7 @@ export default function IntelligentPluginList(){
|
||||
const openDrawer = async (type:'add'|'edit', entity?:DynamicTableItem)=>{
|
||||
switch (type){
|
||||
case 'add':
|
||||
setCurDetail({driver:driverOptions[0].value || '',config:{'c3ebd745-f7d5-45cd-8d3e-e0e43099d20e':{scopes:[]},'550e2537-8436-48e4-ab84-f9f58faf1b18':{scopes:[]}}})
|
||||
setCurDetail({driver:driverOptions[0].value || '',config:{}})
|
||||
break;
|
||||
case 'edit':{
|
||||
setDrawerLoading(true)
|
||||
@@ -237,9 +236,6 @@ export default function IntelligentPluginList(){
|
||||
const {code, data, msg } = res
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
if(data.info.config){
|
||||
for (const tab in data.info.config) {
|
||||
data.info.config[tab]._apinto_show = true
|
||||
}
|
||||
}
|
||||
setCurDetail(data.info)
|
||||
}else{
|
||||
@@ -276,7 +272,7 @@ export default function IntelligentPluginList(){
|
||||
return;}
|
||||
case 'delete':
|
||||
title='删除'
|
||||
content=<span>确定删除成员<span className="text-status_fail"></span>?此操作无法恢复,确认操作?</span>
|
||||
content=<span>确定删除<span className="text-status_fail"></span>?此操作无法恢复,确认操作?</span>
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,25 +19,21 @@ export const SUBSCRIBE_APPROVAL_TABLE_COLUMN : ProColumns<ApprovalTableListItem>
|
||||
{
|
||||
title: '申请方-应用',
|
||||
dataIndex: ['application','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '申请服务',
|
||||
dataIndex: ['service','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '服务所属系统',
|
||||
dataIndex: ['service','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '服务所属团队',
|
||||
dataIndex: ['team','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -74,7 +70,6 @@ export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
title: '申请时间',
|
||||
dataIndex: 'applyTime',
|
||||
// sorter: true,
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
fixed:'left',
|
||||
@@ -85,7 +80,6 @@ export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
{
|
||||
title: '申请方-应用',
|
||||
dataIndex: ['application','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -101,7 +95,6 @@ export const SUBSCRIBE_APPROVAL_INNER_TODO_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
{
|
||||
title: '申请服务',
|
||||
dataIndex: ['service','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
];
|
||||
@@ -112,7 +105,6 @@ export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
title: '申请时间',
|
||||
dataIndex: 'applyTime',
|
||||
// sorter: true,
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
fixed:'left',
|
||||
@@ -123,7 +115,6 @@ export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
{
|
||||
title: '申请方-应用',
|
||||
dataIndex: ['application','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -139,7 +130,6 @@ export const SUBSCRIBE_APPROVAL_INNER_DONE_TABLE_COLUMN : ProColumns<SubscribeAp
|
||||
{
|
||||
title: '申请服务',
|
||||
dataIndex: ['service','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -235,7 +225,6 @@ export const PUBLISH_APPROVAL_VERSION_INNER_TABLE_COLUMN : ProColumns<PublishTab
|
||||
{
|
||||
title: '发布版本',
|
||||
dataIndex: 'version',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left'
|
||||
@@ -243,7 +232,6 @@ export const PUBLISH_APPROVAL_VERSION_INNER_TABLE_COLUMN : ProColumns<PublishTab
|
||||
{
|
||||
title: '版本说明',
|
||||
dataIndex: 'remark',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -287,7 +275,6 @@ export const PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN : ProColumns<PublishTabl
|
||||
{
|
||||
title: '申请时间',
|
||||
dataIndex: 'applyTime',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
fixed:'left',
|
||||
@@ -295,20 +282,17 @@ export const PUBLISH_APPROVAL_RECORD_INNER_TABLE_COLUMN : ProColumns<PublishTabl
|
||||
{
|
||||
title: '审核时间',
|
||||
dataIndex: 'approveTime',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
},
|
||||
{
|
||||
title: '版本号',
|
||||
dataIndex: 'version',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '版本说明',
|
||||
dataIndex: 'remark',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -357,7 +341,6 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns<ApprovalTableListItem>[]
|
||||
{
|
||||
title: '申请时间',
|
||||
dataIndex: 'applyTime',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:182,
|
||||
fixed:'left',
|
||||
@@ -368,13 +351,11 @@ export const PUBLISH_APPROVAL_TABLE_COLUMN : ProColumns<ApprovalTableListItem>[]
|
||||
{
|
||||
title: '申请系统',
|
||||
dataIndex: ['service','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '所属团队',
|
||||
dataIndex: ['team','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
|
||||
@@ -109,17 +109,22 @@ export const GlobalProvider: FC<{children:ReactNode}> = ({ children }) => {
|
||||
const [pluginAccessDictionary, setPluginAccessDictionary] = useState<{[k:string]:string}>({})
|
||||
const [teamDataFlushed, setTeamDataFlushed] = useState<boolean>(false)
|
||||
const [accessInit, setAccessInit] = useState<boolean>(false)
|
||||
let getGlobalAccessPromise: Promise<BasicResponse<{ access:string[] }>> | null = null
|
||||
|
||||
const getGlobalAccessData = ()=>{
|
||||
fetchData<BasicResponse<{ access:string[]}>>('profile/permission/system',{method:'GET'},).then(response=>{
|
||||
getGlobalAccessPromise = new Promise((resolve, reject) => fetchData<BasicResponse<{ access:string[]}>>('profile/permission/system',{method:'GET'},).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
setAccessInit(true)
|
||||
setAccessData(prevData => new Map(prevData).set('system', data.access))
|
||||
resolve(data.response)
|
||||
}else{
|
||||
message.error(msg || '操作失败')
|
||||
reject(data.msg || '操作失败')
|
||||
}
|
||||
})
|
||||
)
|
||||
return getGlobalAccessData
|
||||
}
|
||||
|
||||
const getTeamAccessData = (teamId:string)=>{
|
||||
@@ -149,7 +154,13 @@ export const GlobalProvider: FC<{children:ReactNode}> = ({ children }) => {
|
||||
setPluginAccessDictionary({})
|
||||
}
|
||||
|
||||
const checkPermission = (access:keyof typeof PERMISSION_DEFINITION[0] | Array<keyof typeof PERMISSION_DEFINITION[0]>)=>{
|
||||
const checkPermission = async (access:keyof typeof PERMISSION_DEFINITION[0] | Array<keyof typeof PERMISSION_DEFINITION[0]>)=>{
|
||||
if( !accessInit && getGlobalAccessPromise){
|
||||
await getGlobalAccessPromise
|
||||
}
|
||||
if( !accessInit && !getGlobalAccessPromise){
|
||||
await getGlobalAccessData()
|
||||
}
|
||||
let revs = false;
|
||||
if (Array.isArray(access)) {
|
||||
revs = access.some(item => checkAccess(item, accessData));
|
||||
|
||||
@@ -75,6 +75,10 @@ module.exports = {
|
||||
DEFAULT_BORDER_RADIUS: 'var(--border-radius)',
|
||||
TREE_TITLE:'var(--small-padding) var(--LAYOUT_PADDING);',
|
||||
'navbar-height': 'var(--layout-header-height)',
|
||||
TAG_LEFT:'10px',
|
||||
PAGE_INSIDE_X:'40px',
|
||||
PAGE_INSIDE_T:'30px',
|
||||
PAGE_INSIDE_B:'20px',
|
||||
},
|
||||
borderColor: {
|
||||
'color-base': 'var(--border-color)'
|
||||
|
||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 6.7 KiB |
@@ -80,7 +80,7 @@
|
||||
.apipark-layout-layout{
|
||||
|
||||
.apipark-layout-layout-bg-list{
|
||||
background:#17163E;
|
||||
background-image: radial-gradient(circle farthest-corner at 450px 350px, #050eb7, #17163e 500px);
|
||||
}
|
||||
.ant-layout-header.apipark-layout-layout-header{
|
||||
backdrop-filter: unset !important;
|
||||
|
||||
@@ -379,6 +379,16 @@ const PUBLIC_ROUTES:RouteConfig[] = [
|
||||
key:uuidv4()
|
||||
}]
|
||||
|
||||
},
|
||||
{
|
||||
path:'userProfile/*',
|
||||
lazy:lazy(() => import(/* webpackChunkName: "[request]" */ '@core/pages/userProfile/UserProfile.tsx')),
|
||||
key:uuidv4(),
|
||||
children:[{
|
||||
path:'changepsw',
|
||||
lazy:lazy(() => import(/* webpackChunkName: "[request]" */ '@core/pages/userProfile/ChangePsw.tsx')),
|
||||
key:uuidv4()
|
||||
}]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -7,7 +7,6 @@ export const MEMBER_TABLE_COLUMNS: ProColumns<MemberTableListItem>[] = [
|
||||
{
|
||||
title: '用户名',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -18,13 +17,11 @@ export const MEMBER_TABLE_COLUMNS: ProColumns<MemberTableListItem>[] = [
|
||||
{
|
||||
title: '邮箱',
|
||||
dataIndex: 'email',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
},
|
||||
{
|
||||
title: '部门',
|
||||
dataIndex: 'department',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
filterMode:'tree',
|
||||
renderText:(_,entity:MemberTableListItem)=>(entity.department?.map(x=>x.name).join(',') || '-'),
|
||||
@@ -36,7 +33,6 @@ export const MEMBER_TABLE_COLUMNS: ProColumns<MemberTableListItem>[] = [
|
||||
{
|
||||
title: '角色',
|
||||
dataIndex: 'roles',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:200
|
||||
},
|
||||
|
||||
@@ -8,7 +8,6 @@ export const PARTITION_CERT_TABLE_COLUMNS: ProColumns<PartitionCertTableListItem
|
||||
{
|
||||
title: '证书',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -22,17 +21,16 @@ export const PARTITION_CERT_TABLE_COLUMNS: ProColumns<PartitionCertTableListItem
|
||||
renderText:(_,entity) =>(
|
||||
entity.domains.join(',')
|
||||
),
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '证书有效期',
|
||||
title: '过期日期',
|
||||
ellipsis: true,
|
||||
dataIndex: 'notAfter',
|
||||
copyable: true,
|
||||
width:320,
|
||||
renderText: (value:string,entity:PartitionCertTableListItem) => {
|
||||
return `${entity.notBefore} - ${entity.notAfter}`
|
||||
width:100,
|
||||
renderText: (value: string) => value ? value.split(' ')?.[0] : '-',
|
||||
sorter: (a,b)=> {
|
||||
return a.notAfter.localeCompare(b.notAfter)
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -60,7 +58,6 @@ export const PARTITION_CLUSTER_TABLE_COLUMNS : ProColumns<PartitionClusterTableL
|
||||
{
|
||||
title: '集群名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -72,7 +69,6 @@ export const PARTITION_CLUSTER_TABLE_COLUMNS : ProColumns<PartitionClusterTableL
|
||||
title: '集群 ID',
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -90,7 +86,6 @@ export const PARTITION_CLUSTER_TABLE_COLUMNS : ProColumns<PartitionClusterTableL
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
}
|
||||
];
|
||||
@@ -100,7 +95,6 @@ export const PARTITION_CLUSTER_NODE_COLUMNS: ProColumns<PartitionClusterNodeTabl
|
||||
{
|
||||
title: '节点名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
fixed:'left',
|
||||
sorter: (a,b)=> {
|
||||
@@ -159,7 +153,6 @@ export const PARTITION_LIST_COLUMNS: ProColumns<PartitionTableListItem>[] = [
|
||||
{
|
||||
title: '环境名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
fixed:'left',
|
||||
sorter: (a,b)=> {
|
||||
@@ -169,7 +162,6 @@ export const PARTITION_LIST_COLUMNS: ProColumns<PartitionTableListItem>[] = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:140,
|
||||
},
|
||||
|
||||
@@ -86,9 +86,15 @@ export type NodeModalFieldType = {
|
||||
|
||||
|
||||
export type NodeModalHandle = {
|
||||
save:()=>Promise<boolean|string>
|
||||
save:()=>void
|
||||
}
|
||||
export type NodeModalPropsType = {
|
||||
changeStatus:(status:ClusterPageShowStatus)=>void
|
||||
getClusterInfo:()=>void
|
||||
status:ClusterPageShowStatus
|
||||
}
|
||||
|
||||
export type ClusterPageShowStatus = 'view'|'preview'|'edit'
|
||||
export type PartitionTableListItem = {
|
||||
id:string;
|
||||
name: string;
|
||||
|
||||
@@ -3,7 +3,6 @@ export const ROLE_TABLE_COLUMNS = [
|
||||
{
|
||||
title: '角色名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
fixed:'left',
|
||||
sorter: (a,b)=> {
|
||||
|
||||
@@ -74,7 +74,6 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
{
|
||||
title: '服务名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -86,13 +85,11 @@ export const SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
title: '服务 ID',
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
},
|
||||
{
|
||||
title: '所属团队',
|
||||
dataIndex: ['team','name'],
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
// filters: true,
|
||||
// onFilter: true,
|
||||
@@ -134,7 +131,6 @@ export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns<SystemSubServiceTableLi
|
||||
{
|
||||
title: '服务名称',
|
||||
dataIndex: ['service','name'],
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -146,7 +142,6 @@ export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns<SystemSubServiceTableLi
|
||||
title: '服务 ID',
|
||||
dataIndex: ['service','name'],
|
||||
width: 140,
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -170,13 +165,11 @@ export const SYSTEM_SUBSERVICE_TABLE_COLUMNS: ProColumns<SystemSubServiceTableLi
|
||||
{
|
||||
title: '所属服务',
|
||||
dataIndex: ['project','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '所属团队',
|
||||
dataIndex: ['team','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -217,7 +210,6 @@ export const SYSTEM_SUBSCRIBER_TABLE_COLUMNS: ProColumns<SystemSubscriberTableLi
|
||||
{
|
||||
title: '服务名称',
|
||||
dataIndex: ['service','name'],
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -229,19 +221,16 @@ export const SYSTEM_SUBSCRIBER_TABLE_COLUMNS: ProColumns<SystemSubscriberTableLi
|
||||
title: '服务 ID',
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '订阅方',
|
||||
dataIndex: ['subscriber','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '所属团队',
|
||||
dataIndex: ['team','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
// {
|
||||
@@ -307,7 +296,6 @@ export const SYSTEM_MEMBER_TABLE_COLUMN: ProColumns<SystemMemberTableListItem>[]
|
||||
{
|
||||
title: '用户名',
|
||||
dataIndex: ['user','name'],
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -318,13 +306,11 @@ export const SYSTEM_MEMBER_TABLE_COLUMN: ProColumns<SystemMemberTableListItem>[]
|
||||
{
|
||||
title: '邮箱',
|
||||
dataIndex: 'email',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '角色',
|
||||
dataIndex: ['roles','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
|
||||
}
|
||||
@@ -374,7 +360,6 @@ export const SYSTEM_API_TABLE_COLUMNS: ProColumns<SystemApiTableListItem>[] = [
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -401,7 +386,6 @@ export const SYSTEM_API_TABLE_COLUMNS: ProColumns<SystemApiTableListItem>[] = [
|
||||
{
|
||||
title: 'URL',
|
||||
dataIndex: 'requestPath',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -429,7 +413,6 @@ export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns<SystemUpstreamTableListIt
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -441,7 +424,6 @@ export const SYSTEM_UPSTREAM_TABLE_COLUMNS: ProColumns<SystemUpstreamTableListIt
|
||||
title: '上游 ID',
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -583,7 +565,6 @@ export const SYSTEM_MYSERVICE_API_TABLE_COLUMNS: ProColumns<ServiceApiTableListI
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
ellipsis:true
|
||||
@@ -596,13 +577,11 @@ export const SYSTEM_MYSERVICE_API_TABLE_COLUMNS: ProColumns<ServiceApiTableListI
|
||||
{
|
||||
title: '请求路径',
|
||||
dataIndex: 'path',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
}
|
||||
];
|
||||
@@ -625,7 +604,6 @@ export const SYSTEM_AUTHORITY_TABLE_COLUMNS: ProColumns<SystemAuthorityTableList
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -702,7 +680,6 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns<MyServiceTableListItem>[
|
||||
{
|
||||
title: '服务名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -714,7 +691,6 @@ export const SYSTEM_MYSERVICE_TABLE_COLUMNS: ProColumns<MyServiceTableListItem>[
|
||||
title: '服务ID',
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -796,7 +772,6 @@ export const SYSTEM_UPSTREAM_GLOBAL_CONFIG_TABLE_COLUMNS: ProColumns<GlobalNodeI
|
||||
},
|
||||
],
|
||||
},
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -928,7 +903,7 @@ const APP_MODE = import.meta.env.VITE_APP_MODE;
|
||||
|
||||
|
||||
export const SYSTEM_PAGE_MENU_ITEMS: MenuProps['items'] = [
|
||||
getItem('内部数据服务', 'assets', null,
|
||||
getItem('服务', 'assets', null,
|
||||
[
|
||||
getItem(<Link to="./api">API</Link>, 'api',undefined,undefined,undefined,'team.service.api.view'),
|
||||
getItem(<Link to="./upstream">上游</Link>, 'upstream',undefined,undefined,undefined,'team.service.upstream.view'),
|
||||
@@ -936,7 +911,7 @@ const APP_MODE = import.meta.env.VITE_APP_MODE;
|
||||
getItem(<Link to="./publish">发布</Link>, 'publish',undefined,undefined,undefined,'team.service.release.view'),
|
||||
],
|
||||
'group'),
|
||||
getItem('提供服务', 'provideSer', null,
|
||||
getItem('订阅管理', 'provideSer', null,
|
||||
[
|
||||
getItem(<Link to="./approval">订阅审批</Link>, 'approval',undefined,undefined,undefined,'team.service.subscription.view'),
|
||||
getItem(<Link to="./subscriber">订阅方管理</Link>, 'subscriber',undefined,undefined,undefined,'team.service.subscription.view'),
|
||||
|
||||
@@ -56,8 +56,7 @@ export type SystemSubscriberTableListItem = {
|
||||
};
|
||||
|
||||
export type SystemSubscriberConfigFieldType = {
|
||||
service:string
|
||||
subscriber:string
|
||||
application:string
|
||||
applier:string
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ export const TEAM_TABLE_COLUMNS: ProColumns<TeamTableListItem>[] = [
|
||||
{
|
||||
title: '名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -24,13 +23,11 @@ export const TEAM_TABLE_COLUMNS: ProColumns<TeamTableListItem>[] = [
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -67,7 +64,6 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
{
|
||||
title: '服务名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -79,13 +75,11 @@ export const TEAM_SYSTEM_TABLE_COLUMNS: ProColumns<SystemTableListItem>[] = [
|
||||
title: '服务 ID',
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '所属团队',
|
||||
dataIndex: ['team','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -128,7 +122,6 @@ export const TEAM_MEMBER_TABLE_COLUMNS: ProColumns<TeamMemberTableListItem>[] =
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: ['user','name'],
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -139,7 +132,6 @@ export const TEAM_MEMBER_TABLE_COLUMNS: ProColumns<TeamMemberTableListItem>[] =
|
||||
{
|
||||
title: '团队角色',
|
||||
dataIndex: 'roles',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -8,7 +8,6 @@ export const USER_LIST_COLUMNS: ProColumns<MemberItem>[]= [
|
||||
{
|
||||
title: '用户名',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -19,7 +18,6 @@ export const USER_LIST_COLUMNS: ProColumns<MemberItem>[]= [
|
||||
{
|
||||
title: '邮箱',
|
||||
dataIndex: 'email',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -727,13 +727,22 @@ p{
|
||||
padding-left:0 !important;
|
||||
padding-top:0 !important;
|
||||
}
|
||||
.pr-PAGE_INSIDE_X{
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ant-drawer-footer{
|
||||
padding:16px 20px !important
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.ant-modal-body .pr-PAGE_INSIDE_X{
|
||||
padding-right: 0 !important;
|
||||
}
|
||||
|
||||
.g6-tooltip {
|
||||
padding: 10px 6px;
|
||||
color: #444;
|
||||
@@ -754,12 +763,22 @@ p{
|
||||
height:10px !important;
|
||||
}
|
||||
|
||||
/* 生产环境无法获取到下列样式,先写在这里 */
|
||||
.eo_page_list .ant-pro-card{
|
||||
margin-top: -1px;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.eo_page_list .ant-pro-card .ant-pro-card-body{
|
||||
padding:0 !important;
|
||||
}
|
||||
.eo_page_list .ant-pro-table-list-toolbar-container{
|
||||
padding:12px 20px 12px 12px !important;
|
||||
/* padding:12px 20px 12px 12px !important; */
|
||||
padding-block:0px !important;
|
||||
flex-direction: row-reverse;
|
||||
|
||||
.ant-pro-table-list-toolbar-left{
|
||||
justify-content: flex-end !important;
|
||||
}
|
||||
|
||||
.ant-pro-table-list-toolbar-right{
|
||||
flex:unset !important;
|
||||
@@ -836,9 +855,10 @@ p{
|
||||
}
|
||||
}
|
||||
|
||||
/* .ant-dropdown .ant-dropdown-menu{
|
||||
border-radius: 10px;
|
||||
padding: 10px;
|
||||
|
||||
.ant-dropdown .ant-dropdown-menu{
|
||||
/* border-radius: 10px;
|
||||
padding: 10px; */
|
||||
li.ant-dropdown-menu-item{
|
||||
padding:0 !important;
|
||||
>button.ant-btn{
|
||||
@@ -848,13 +868,14 @@ p{
|
||||
}
|
||||
>span.ant-dropdown-menu-title-content{
|
||||
padding:0px !important;
|
||||
min-width: 80px;
|
||||
/* padding:0px 12px !important;
|
||||
/* min-width: 80px; */
|
||||
/* padding:0px 12px !important; */
|
||||
height:32px !important;
|
||||
line-height: 32px !important;
|
||||
.ant-btn{
|
||||
width:100%;
|
||||
padding:0px 12px !important;
|
||||
justify-content:flex-start;
|
||||
}
|
||||
.ant-btn-default:not(:disabled):not(.ant-btn-disabled):hover{
|
||||
color:var(--text-color) !important;
|
||||
@@ -862,7 +883,7 @@ p{
|
||||
}
|
||||
}
|
||||
|
||||
} */
|
||||
}
|
||||
.ant-dropdown-button{
|
||||
.ant-btn-link{
|
||||
color:var(--text-color) !important;
|
||||
@@ -1161,11 +1182,6 @@ p{
|
||||
padding-bottom:60px !important;
|
||||
}
|
||||
|
||||
/* .padding-top-20 .virtuoso-grid-list{
|
||||
padding-bottom:60px !important;
|
||||
padding:20px 40px 40px !important;
|
||||
} */
|
||||
|
||||
.ant-form-item-control-input-content{
|
||||
.ant-pro-card-body{
|
||||
padding-bottom: 0px !important;
|
||||
@@ -1198,4 +1214,14 @@ p{
|
||||
/* .eo_page_list.role_table .ant-pro-table-list-toolbar-container{
|
||||
padding-left:0 !important;
|
||||
padding-right:0 !important;
|
||||
} */
|
||||
} */
|
||||
|
||||
|
||||
div.preview-document{
|
||||
p{
|
||||
margin-block-start: 1em;
|
||||
margin-block-end: 1em;}
|
||||
}
|
||||
.ant-table-wrapper .ant-table-thead th.ant-table-column-has-sorters{
|
||||
transition:none !important;
|
||||
}
|
||||
@@ -27,7 +27,6 @@ const AUDIT_LOG_COLUMNS_CONFIG: ProColumns<AuditLogTableListItem, 'multipleSelec
|
||||
dataIndex: 'operateTime',
|
||||
valueType: 'dateTimeRange',
|
||||
order:1,
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
fixed:'left',
|
||||
width:182
|
||||
|
||||
@@ -72,7 +72,7 @@ const LogSettings = ()=>{
|
||||
mode="inline"
|
||||
items={menuItems}
|
||||
/>
|
||||
<div className={`w-full flex flex-1 flex-col h-full overflow-auto bg-MAIN_BG pt-btnbase pl-btnbase`}>
|
||||
<div className={`w-full flex flex-1 flex-col h-full overflow-auto bg-MAIN_BG pt-btnbase pl-btnbase pr-PAGE_INSIDE_X pb-PAGE_INSIDE_B overflow-x-hidden`}>
|
||||
<Outlet context={{accessPrefix:'system.devops.log_configuration'}}/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -232,7 +232,7 @@ const MemberList = ()=>{
|
||||
return !checkAccess(permission, accessData);
|
||||
};
|
||||
|
||||
const openModal = (type:'addMember'|'editMember'|'removeFromDep'|'addToDep'|'blocked'|'activate'|'delete',entity?:MemberTableListItem)=>{
|
||||
const openModal = (type:'addMember'|'editMember'|'addToDep'|'delete',entity?:MemberTableListItem)=>{
|
||||
let title:string = ''
|
||||
let content:string|React.ReactNode = ''
|
||||
switch (type){
|
||||
@@ -244,10 +244,6 @@ const MemberList = ()=>{
|
||||
title='编辑成员信息'
|
||||
content=<MemberDropdownModal topGroupId={topGroupId} ref={EditMemberRef} type={type} entity={entity} />
|
||||
break;
|
||||
case 'removeFromDep':
|
||||
title='移出当前部门'
|
||||
content=<span>确定将成员<span className="text-status_fail"></span>从当前部门中移除?此操作无法恢复,确认操作?</span>
|
||||
break;
|
||||
case 'addToDep':
|
||||
title='加入部门'
|
||||
content=<AddToDepartment ref={AddToDepRef} selectedUserIds={selectedRowKeys as string[]} />
|
||||
@@ -256,14 +252,6 @@ const MemberList = ()=>{
|
||||
title='删除'
|
||||
content=<span>确定删除成员<span className="text-status_fail"></span>?此操作无法恢复,确认操作?</span>
|
||||
break;
|
||||
case 'blocked':
|
||||
title='禁用成员'
|
||||
content=<span>确定禁用成员<span className="text-status_fail"></span>?此操作无法恢复,确认操作?</span>
|
||||
break;
|
||||
case 'activate':
|
||||
title='启用成员'
|
||||
content=<span>确定启用成员<span className="text-status_fail"></span>?此操作无法恢复,确认操作?</span>
|
||||
break;
|
||||
}
|
||||
|
||||
modal.confirm({
|
||||
@@ -274,18 +262,9 @@ const MemberList = ()=>{
|
||||
case 'addMember':
|
||||
return AddMemberRef.current?.save().then((res)=>{if(res === true) {refreshGroup && refreshGroup();manualReloadTable()}})
|
||||
case 'editMember':
|
||||
//console.log('addChild')
|
||||
return EditMemberRef.current?.save().then((res)=>{if(res === true){refreshGroup && refreshGroup();manualReloadTable()}})
|
||||
case 'removeFromDep':
|
||||
//console.log('addChild')
|
||||
return handleMemberAction('removeFromDep').then((res)=>{if(res === true){refreshGroup && refreshGroup();manualReloadTable()}})
|
||||
case 'addToDep':
|
||||
//console.log('addToDep')
|
||||
return AddToDepRef.current?.save().then((res)=>{if(res === true) {refreshGroup && refreshGroup();manualReloadTable()}})
|
||||
case 'activate':
|
||||
return handleMemberAction('activate').then((res)=>{if(res === true){refreshGroup && refreshGroup();manualReloadTable()}})
|
||||
case 'blocked':
|
||||
return handleMemberAction('blocked').then((res)=>{if(res === true){refreshGroup && refreshGroup();manualReloadTable()}})
|
||||
case 'delete':
|
||||
return handleMemberAction('delete').then((res)=>{if(res === true){refreshGroup && refreshGroup();manualReloadTable()}})
|
||||
}
|
||||
@@ -376,7 +355,7 @@ const MemberList = ()=>{
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageList
|
||||
<PageList
|
||||
id="global_member"
|
||||
ref={pageListRef}
|
||||
columns={[...columns, ...operation]}
|
||||
@@ -400,11 +379,11 @@ const MemberList = ()=>{
|
||||
onRowClick={handleRowClick}
|
||||
tableClickAccess="system.organization.member.edit"
|
||||
afterNewBtn={[
|
||||
memberGroupId &&<WithPermission key="removeFromDepPermission" access="system.organization.member.edit"><Button className="mr-btnbase" disabled={selectedRowKeys.length === 0} key="removeFromDep" onClick={()=>openModal('removeFromDep')}>移出当前部门</Button></WithPermission>,
|
||||
memberGroupId &&<WithPermission key="addToDepPermission" access="system.organization.member.edit"><Button className="mr-btnbase" disabled={selectedRowKeys.length === 0} key="addToDep" onClick={()=>openModal('addToDep')}>加入部门</Button></WithPermission>,
|
||||
memberGroupId !== 'disable' &&<WithPermission key="blockedPermission" access="system.organization.member.block"><Button className="mr-btnbase" disabled={selectedRowKeys.length === 0 || memberGroupId === 'unknown'} key="blocked" onClick={()=>openModal('blocked')}>禁用成员</Button></WithPermission>,
|
||||
<WithPermission key="activatePermission" access="system.organization.member.block"><Button className="mr-btnbase" disabled={selectedRowKeys.length === 0} key="activate" onClick={()=>openModal('activate')}>启用成员</Button></WithPermission>,
|
||||
<WithPermission key="deletePermission" access="system.organization.member.delete"><Button className="mr-btnbase" disabled={selectedRowKeys.length === 0} key="delete" onClick={()=>openModal('delete')}>删除成员</Button></WithPermission>,
|
||||
selectedRowKeys.length > 0 && memberGroupId &&<WithPermission key="removeFromDepPermission" access="system.organization.member.edit"><Button className="mr-btnbase" key="removeFromDep" onClick={()=>handleMemberAction('removeFromDep').then((res)=>{if(res === true){refreshGroup && refreshGroup();manualReloadTable()}})}>移出当前部门</Button></WithPermission>,
|
||||
selectedRowKeys.length > 0 && memberGroupId &&<WithPermission key="addToDepPermission" access="system.organization.member.edit"><Button className="mr-btnbase" key="addToDep" onClick={()=>openModal('addToDep')}>加入部门</Button></WithPermission>,
|
||||
selectedRowKeys.length > 0 && memberGroupId !== 'disable' &&<WithPermission key="blockedPermission" access="system.organization.member.block"><Button className="mr-btnbase" key="blocked" onClick={()=>handleMemberAction('blocked').then((res)=>{if(res === true){refreshGroup && refreshGroup();manualReloadTable()}})}>禁用成员</Button></WithPermission>,
|
||||
selectedRowKeys.length > 0 && <WithPermission key="activatePermission" access="system.organization.member.block"><Button className="mr-btnbase" key="activate" onClick={()=>handleMemberAction('activate').then((res)=>{if(res === true){refreshGroup && refreshGroup();manualReloadTable()}})}>启用成员</Button></WithPermission>,
|
||||
selectedRowKeys.length > 0 &&<WithPermission key="deletePermission" access="system.organization.member.delete"><Button className="mr-btnbase" key="delete" onClick={()=>openModal('delete')}>删除成员</Button></WithPermission>,
|
||||
]}
|
||||
onSearchWordChange={(e) => {
|
||||
setSearchWord(e.target.value)
|
||||
|
||||
@@ -17,6 +17,7 @@ import { checkAccess } from "@common/utils/permission.ts";
|
||||
import { RenameDepModal } from "./Modal/RenameDepModal.tsx";
|
||||
import { AddDepModal } from "./Modal/AddDepModal.tsx";
|
||||
import { EditMemberModal } from "./Modal/EditMember.tsx";
|
||||
import InsidePage from "@common/components/aoplatform/InsidePage.tsx";
|
||||
|
||||
const MemberPage = ()=>{
|
||||
const [searchWord, setSearchWord] = useState<string>('')
|
||||
@@ -244,56 +245,41 @@ const MemberPage = ()=>{
|
||||
},[memberGroupId])
|
||||
|
||||
return (
|
||||
|
||||
<div className="flex flex-1 h-full flex-col ">
|
||||
<div className="pb-[30px] border-0 border-b-[1px] border-solid border-BORDER">
|
||||
<p className="text-theme text-[26px] mb-[20px]">成员</p>
|
||||
<p>设置成员和对应的角色,成员只能够看到权限范围内的功能和数据。</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1">
|
||||
<div className="w-[200px] border-0 border-solid border-r-[1px] border-r-BORDER">
|
||||
<div className="px-btnbase pb-[0px]">
|
||||
<Input className=" my-btnybase" onChange={(e) => debounce(onSearchWordChange, 100)(e.target.value)}
|
||||
allowClear placeholder="搜索部门"
|
||||
prefix={<SearchOutlined className="cursor-pointer"/>}/>
|
||||
</div>
|
||||
<div className="h-[calc(100%-52px)] overflow-auto">
|
||||
<div className="h-[calc(100%-30px)] overflow-y-auto pl-[5px] pr-[10px]">
|
||||
<Tree
|
||||
showLine
|
||||
switcherIcon={<DownOutlined />}
|
||||
blockNode={true}
|
||||
treeData={treeData}
|
||||
selectedKeys={[selectedDepartmentId]}
|
||||
expandedKeys={expandedKeys}
|
||||
onExpand={(expandedKeys:Key[])=>{setExpandedKeys(expandedKeys)}}
|
||||
onSelect={(selectedKeys,selectedRow) => {
|
||||
if(selectedKeys.length > 0 ){
|
||||
setSelectedDepartmentIds((selectedRow.node as unknown).departmentIds || [])
|
||||
navigate(`/member/list${selectedKeys[0] === '-1'? '' : `/${selectedKeys[0]}`}`)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
{/* <DirectoryTree
|
||||
icon={<></>}
|
||||
<InsidePage
|
||||
pageTitle='成员'
|
||||
description="设置成员和对应的角色,成员只能够看到权限范围内的功能和数据。"
|
||||
>
|
||||
<div className="flex flex-1 h-full w-full">
|
||||
<div className="w-[200px] border-0 border-solid border-r-[1px] border-r-BORDER">
|
||||
<div className="px-btnbase pb-[0px]">
|
||||
<Input className=" my-btnybase" onChange={(e) => debounce(onSearchWordChange, 100)(e.target.value)}
|
||||
allowClear placeholder="搜索部门"
|
||||
prefix={<SearchOutlined className="cursor-pointer"/>}/>
|
||||
</div>
|
||||
<div className="h-[calc(100%-52px)] overflow-auto">
|
||||
<div className="h-[calc(100%-30px)] overflow-y-auto pl-[5px] pr-[10px]">
|
||||
<Tree
|
||||
showLine
|
||||
switcherIcon={<DownOutlined />}
|
||||
blockNode={true}
|
||||
treeData={treeData}
|
||||
selectedKeys={[selectedDepartmentId]}
|
||||
expandedKeys={expandedKeys}
|
||||
onExpand={(expandedKeys:string[])=>{setExpandedKeys(expandedKeys)}}
|
||||
onExpand={(expandedKeys:Key[])=>{setExpandedKeys(expandedKeys)}}
|
||||
onSelect={(selectedKeys,selectedRow) => {
|
||||
if(selectedKeys.length > 0 ){
|
||||
setSelectedDepartmentIds((selectedRow.node as unknown).departmentIds || [])
|
||||
navigate(`/member/list${selectedKeys[0] === '-1' ? '' : `/${selectedKeys[0]}`}`)
|
||||
navigate(`/member/list${selectedKeys[0] === '-1'? '' : `/${selectedKeys[0]}`}`)
|
||||
}
|
||||
}}
|
||||
/> */}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 p-btnbase pr-PAGE_INSIDE_X overflow-x-hidden">
|
||||
<Outlet context={{refreshMemberCount, selectedDepartmentIds,refreshGroup:()=>getDepartmentList()}}/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-[calc(100%-200px)] pl-btnbase pt-btnbase">
|
||||
<Outlet context={{refreshMemberCount, selectedDepartmentIds,refreshGroup:()=>getDepartmentList()}}/>
|
||||
</div>
|
||||
</div>
|
||||
</div>);
|
||||
</InsidePage>);
|
||||
}
|
||||
export default MemberPage;
|
||||
@@ -16,6 +16,7 @@ import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPe
|
||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
|
||||
import { checkAccess } from "@common/utils/permission.ts";
|
||||
import { PERMISSION_DEFINITION } from "@common/const/permissions.ts";
|
||||
import InsidePage from "@common/components/aoplatform/InsidePage.tsx";
|
||||
|
||||
const CertConfigModal = forwardRef<PartitionCertConfigHandle,PartitionCertConfigProps>((props, ref) => {
|
||||
const { message } = App.useApp()
|
||||
@@ -282,11 +283,12 @@ const PartitionInsideCert:FC = ()=>{
|
||||
},[memberValueEnum])
|
||||
|
||||
return (
|
||||
<div className="flex flex-col flex-1 h-full">
|
||||
<div className="pb-[30px] pt-0">
|
||||
<p className="text-theme text-[26px] mb-[20px]">证书</p>
|
||||
<p>通过为 API 服务配置和管理 SSL 证书,企业可以加密数据传输,防止敏感信息被窃取或篡改。 </p>
|
||||
</div>
|
||||
<InsidePage
|
||||
pageTitle='证书'
|
||||
description="通过为 API 服务配置和管理 SSL 证书,企业可以加密数据传输,防止敏感信息被窃取或篡改。"
|
||||
showBorder={false}
|
||||
contentClassName="pr-PAGE_INSIDE_X pb-PAGE_INSIDE_B"
|
||||
>
|
||||
<PageList
|
||||
id="global_partition_cert"
|
||||
ref={pageListRef}
|
||||
@@ -299,7 +301,7 @@ const PartitionInsideCert:FC = ()=>{
|
||||
onRowClick={(row:PartitionCertTableListItem)=>openModal('edit',row)}
|
||||
tableClickAccess="system.devops.ssl_certificate.edit"
|
||||
/>
|
||||
</div>
|
||||
</InsidePage>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@@ -1,33 +1,30 @@
|
||||
import { FC, useEffect, useRef, useState} from "react";
|
||||
import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx";
|
||||
import {App, Button, Col, Collapse, Empty, Row, Spin, Tag} from "antd";
|
||||
import {App, Button, Card, Col, Row, Spin, Tag} from "antd";
|
||||
import {BasicResponse, STATUS_CODE} from "@common/const/const.ts";
|
||||
import {useFetch} from "@common/hooks/http.ts";
|
||||
import { NodeModalHandle, PartitionClusterNodeTableListItem } from "../../const/partitions/types.ts";
|
||||
import { ClusterPageShowStatus, NodeModalHandle, PartitionClusterNodeTableListItem } from "../../const/partitions/types.ts";
|
||||
import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
|
||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
|
||||
import { ClusterNodeModal } from "./PartitionInsideClusterNode.tsx";
|
||||
import { DownOutlined, LoadingOutlined, UpOutlined } from "@ant-design/icons";
|
||||
import { checkAccess } from "@common/utils/permission.ts";
|
||||
import { LoadingOutlined } from "@ant-design/icons";
|
||||
import InsidePage from "@common/components/aoplatform/InsidePage.tsx";
|
||||
|
||||
const PartitionInsideCluster:FC = ()=> {
|
||||
const {setBreadcrumb} = useBreadcrumb()
|
||||
const {modal, message} = App.useApp()
|
||||
const {fetchData} = useFetch()
|
||||
const [nodesList, setNodesList] = useState<PartitionClusterNodeTableListItem[]>()
|
||||
const [nodeData, setNodeData] = useState<PartitionClusterNodeTableListItem>()
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const {accessData} = useGlobalContext()
|
||||
const [activeKey, setActiveKey] = useState<string[]>([])
|
||||
const editNodeRef = useRef<NodeModalHandle>(null)
|
||||
const [showStatus, setShowStatus] = useState<ClusterPageShowStatus>('view')
|
||||
|
||||
const getPartitionClusterInfo = () => {
|
||||
setNodesList([])
|
||||
setLoading(true)
|
||||
return fetchData<BasicResponse<{ nodes:PartitionClusterNodeTableListItem[] }>>('cluster/nodes', {method: 'GET',eoTransformKeys:['manager_address','service_address','peer_address']}).then(response => {
|
||||
const {code, data, msg} = response
|
||||
if (code === STATUS_CODE.SUCCESS) {
|
||||
setNodesList(data.nodes)
|
||||
setActiveKey(data.nodes.map((x:PartitionClusterNodeTableListItem)=>x.id))
|
||||
data.nodes && data.nodes.length > 0 && setNodeData(data.nodes[0])
|
||||
setShowStatus('view')
|
||||
} else {
|
||||
message.error(msg || '操作失败')
|
||||
}
|
||||
@@ -38,37 +35,6 @@ const PartitionInsideCluster:FC = ()=> {
|
||||
})
|
||||
}
|
||||
|
||||
const openModal = async (type:'editNode')=>{
|
||||
let title:string = ''
|
||||
let content:string|React.ReactNode = ''
|
||||
|
||||
switch(type){
|
||||
case 'editNode': {
|
||||
title = '重置配置'
|
||||
content = <ClusterNodeModal ref={editNodeRef} />
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
modal.confirm({
|
||||
title,
|
||||
content,
|
||||
onOk:()=> {
|
||||
switch (type){
|
||||
case 'editNode':
|
||||
return editNodeRef.current?.save().then((res:boolean)=>{if(res === true) getPartitionClusterInfo(); return false})
|
||||
}
|
||||
},
|
||||
width:type === 'editNode' ? 900 : 600,
|
||||
okText:'确认',
|
||||
okButtonProps:{
|
||||
disabled:!checkAccess('system.devops.cluster.edit', accessData)
|
||||
},
|
||||
cancelText:'取消',
|
||||
closable:true,
|
||||
icon:<></>,
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setBreadcrumb([
|
||||
@@ -77,41 +43,53 @@ const PartitionInsideCluster:FC = ()=> {
|
||||
getPartitionClusterInfo()
|
||||
}, []);
|
||||
|
||||
const setClusterBtn = ()=>{
|
||||
return (<>
|
||||
{showStatus === 'view' && <WithPermission access="system.devops.cluster.edit" key="changeClusterConfig">
|
||||
<Button type="primary" onClick={() => setShowStatus('edit')}>修改配置</Button>
|
||||
</WithPermission> }</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className=" overflow-auto h-full">
|
||||
|
||||
<div className="pb-[30px] pt-0">
|
||||
<p className="text-theme text-[26px] mb-[20px]">集群</p>
|
||||
<p>设置访问 API 的集群,让 API 在分布式环境中稳定运行,并且能够根据业务需求进行灵活扩展和优化。</p>
|
||||
<InsidePage
|
||||
pageTitle='集群'
|
||||
description="设置访问 API 的集群,让 API 在分布式环境中稳定运行,并且能够根据业务需求进行灵活扩展和优化。"
|
||||
showBorder={false}
|
||||
scrollPage={true}
|
||||
>
|
||||
<div className="flex flex-col h-full overflow-auto pb-PAGE_INSIDE_B pr-PAGE_INSIDE_X">
|
||||
<Spin wrapperClassName=" h-full flex-1" indicator={<LoadingOutlined style={{ fontSize: 24 }} spin/>} spinning={loading}>
|
||||
<div className="h-full overflow-auto">
|
||||
<Card
|
||||
classNames={{
|
||||
body: 'overflow-auto',
|
||||
}}
|
||||
className="overflow-hidden w-full max-h-full flex flex-col justify-between"
|
||||
title={<div><span className="text-MAIN_TEXT my-btnybase mr-btnbase" > APIPark Node</span>
|
||||
{!loading && <Tag color={nodeData && nodeData.status === 1 ?'#87d068' : '#f50'}>
|
||||
{ !nodeData && '未配置'}
|
||||
{ nodeData?.status === 1 && '正常' }
|
||||
{ nodeData?.status === 0 && '异常'}
|
||||
</Tag>}</div>}
|
||||
extra={setClusterBtn()}>
|
||||
{showStatus === 'view'&& nodeData && ClusterConfigPreview(nodeData) }
|
||||
{showStatus !== 'view' && <ClusterNodeModal ref={editNodeRef} status={showStatus} changeStatus={setShowStatus} getClusterInfo={getPartitionClusterInfo} />}
|
||||
</Card>
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
|
||||
<div className="pb-btnbase"> <WithPermission access="system.devops.cluster.edit" key="changeClusterConfig"><Button type="primary" onClick={() => openModal('editNode')}>修改集群配置</Button></WithPermission></div>
|
||||
<Spin wrapperClassName=" h-[calc(100%-44px)] flex-1 overflow-auto" indicator={<LoadingOutlined style={{ fontSize: 24 }} spin/>} spinning={loading}>
|
||||
<div className="h-full overflow-auto ">
|
||||
{nodesList && nodesList.length > 0 ?
|
||||
<Collapse className={` p-[0px] mb-btnybase`}
|
||||
expandIcon={({isActive})=>(isActive? <UpOutlined className="w-[23px] text-MAIN_TEXT hover:text-MAIN_HOVER_TEXT"/>:<DownOutlined className="w-[23px] text-MAIN_TEXT hover:text-MAIN_HOVER_TEXT"/> )}
|
||||
items={nodesList?.map(x=>{
|
||||
return {
|
||||
label:<div ><Tag color={x.status === 1 ? '#87d068' : '#f50'}>{x.status === 1 ? '正常' : '异常'}</Tag><span className="text-MAIN_TEXT my-btnybase mr-btnbase" id={`${x.id}`}>{x.managerAddress.join(',')}</span></div>,
|
||||
key:x.id,
|
||||
children:<div className="p-btnbase">
|
||||
<Row className="mb-[4px]"><Col className="font-bold text-right pr-[4px]" span="3">管理地址:</Col><Col>{x.managerAddress.map(m=>(<p className="leading-[22px]">{m}</p>))}</Col></Row>
|
||||
<Row className="mb-[4px]"><Col className="font-bold text-right pr-[4px]" span="3">服务地址:</Col><Col>{x.serviceAddress.map(m=>(<p className="leading-[22px]">{m}</p>))}</Col></Row>
|
||||
<Row className="mb-[4px]"><Col className="font-bold text-right pr-[4px]" span="3">同步地址:</Col><Col><p className="leading-[22px]">{x.peerAddress}</p></Col></Row>
|
||||
</div>
|
||||
}
|
||||
})}
|
||||
activeKey={activeKey}
|
||||
onChange={(val)=>{setActiveKey(val as string[])}}
|
||||
/>:<Empty className="mt-[10%]" image={Empty.PRESENTED_IMAGE_SIMPLE}/>
|
||||
}
|
||||
</div>
|
||||
</Spin>
|
||||
</div>
|
||||
</InsidePage>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export function ClusterConfigPreview (x:PartitionClusterNodeTableListItem){
|
||||
return <div className="flex flex-col gap-[4px] ">
|
||||
<Row className=""><Col className="font-bold text-right pr-[4px]">管理地址:</Col><Col>{x.managerAddress.map(m=>(<p className="leading-[22px]">{m}</p>))}</Col></Row>
|
||||
<Row className=""><Col className="font-bold text-right pr-[4px]">服务地址:</Col><Col>{x.serviceAddress.map(m=>(<p className="leading-[22px]">{m}</p>))}</Col></Row>
|
||||
<Row className=""><Col className="font-bold text-right pr-[4px]">同步地址:</Col><Col><p className="leading-[22px]">{x.peerAddress}</p></Col></Row>
|
||||
</div>}
|
||||
|
||||
export default PartitionInsideCluster
|
||||
@@ -4,45 +4,54 @@ import {App, Button, Form, Input, Table} from "antd";
|
||||
import {useFetch} from "@common/hooks/http.ts";
|
||||
import {BasicResponse, STATUS_CODE} from "@common/const/const.ts";
|
||||
import { NODE_MODAL_COLUMNS } from "../../const/partitions/const.tsx";
|
||||
import { NodeModalHandle, PartitionClusterNodeModalTableListItem, PartitionClusterNodeTableListItem, NodeModalFieldType } from "../../const/partitions/types.ts";
|
||||
import { NodeModalHandle, PartitionClusterNodeModalTableListItem, PartitionClusterNodeTableListItem, NodeModalFieldType, NodeModalPropsType } from "../../const/partitions/types.ts";
|
||||
import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
|
||||
import { ClusterConfigPreview } from "./PartitionInsideCluster.tsx";
|
||||
import { set, values } from "lodash-es";
|
||||
|
||||
export const ClusterNodeModal = forwardRef<NodeModalHandle>((_,ref)=>{
|
||||
export const ClusterNodeModal = forwardRef<NodeModalHandle, NodeModalPropsType>((props,ref)=>{
|
||||
const { message } = App.useApp()
|
||||
const {changeStatus,getClusterInfo, status} = props
|
||||
const [form] = Form.useForm();
|
||||
const [dataSource,setDataSource] = useState<PartitionClusterNodeModalTableListItem[]>([])
|
||||
const {fetchData} = useFetch()
|
||||
const [addressError, setAddressError] = useState<'' | 'error'>('')
|
||||
|
||||
const test = ()=>{
|
||||
setDataSource([])
|
||||
return new Promise((resolve, reject)=>{
|
||||
form.validateFields().then((value)=> {
|
||||
form.validateFields().then((value)=> {
|
||||
if(!value.address) {
|
||||
setAddressError('error')
|
||||
return
|
||||
}
|
||||
fetchData<BasicResponse<{ nodes: PartitionClusterNodeTableListItem[] }>>('cluster/check', {method: 'POST', eoBody: (value),eoTransformKeys:['manager_address','service_address','peer_address']}).then(response => {
|
||||
const {code,data, msg} = response
|
||||
if (code === STATUS_CODE.SUCCESS) {
|
||||
message.success(msg || '操作成功')
|
||||
setDataSource(data.nodes)
|
||||
changeStatus('preview')
|
||||
} else {
|
||||
message.error(msg || '操作失败')
|
||||
message.error(msg || '无法连接集群,请检查集群地址是否正确或防火墙配置')
|
||||
setAddressError('error')
|
||||
|
||||
}
|
||||
}).catch((errorInfo)=> reject(errorInfo))
|
||||
}).catch((errorInfo)=> reject(errorInfo))
|
||||
}).catch((errorInfo)=>{
|
||||
console.warn(errorInfo)
|
||||
})
|
||||
})}
|
||||
|
||||
const save:()=>Promise<boolean | string> = ()=>{
|
||||
return new Promise((resolve, reject)=>{
|
||||
const save = ()=>{
|
||||
form.validateFields().then(()=> {
|
||||
fetchData<BasicResponse<null>>('cluster/reset',{method:'PUT' ,eoBody:({managerAddress:form.getFieldValue('address')}), eoTransformKeys:['managerAddress']}).then(response=>{
|
||||
const {code,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
message.success(msg || '操作成功!')
|
||||
resolve(true)
|
||||
getClusterInfo()
|
||||
}else{
|
||||
message.error(msg || '操作失败')
|
||||
reject(msg || '操作失败')
|
||||
}
|
||||
}).catch((errorInfo)=> reject(errorInfo))
|
||||
}).catch((errorInfo)=> reject(errorInfo))
|
||||
}).catch((errorInfo)=>
|
||||
console.warn(errorInfo))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -61,32 +70,25 @@ export const ClusterNodeModal = forwardRef<NodeModalHandle>((_,ref)=>{
|
||||
className="mx-auto "
|
||||
autoComplete="off"
|
||||
name="partitionInsideClusterNode"
|
||||
|
||||
>
|
||||
<div className="flex items-end justify-between bg-[#fafafa] p-[10px] border-[1px] border-solid border-[#f2f2f2] rounded-[10px] gap-btnbase ">
|
||||
{status === 'edit' ?
|
||||
|
||||
<Form.Item<NodeModalFieldType>
|
||||
label="集群地址"
|
||||
name="address"
|
||||
className="p-0 bg-transparent rounded-none border-none flex-1"
|
||||
rules={[{ required: true, message: '必填项' }]}
|
||||
className="mb-0"
|
||||
validateStatus={addressError}
|
||||
help={addressError ? form.getFieldValue('address')? '无法连接集群,请检查集群地址是否正确或防火墙配置' : '必填项' : ''}
|
||||
>
|
||||
<Input placeholder="请输入" onPressEnter={()=>test()}/>
|
||||
</Form.Item>
|
||||
<div className="">
|
||||
<Button type='primary' className="mb-[10px]" onClick={()=>test()}>测试</Button>
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
dataSource.length > 0 &&
|
||||
<Table
|
||||
className="mt-btnbase"
|
||||
bordered={true}
|
||||
columns={NODE_MODAL_COLUMNS}
|
||||
size="small"
|
||||
rowKey="id"
|
||||
dataSource={dataSource}
|
||||
pagination={false}
|
||||
/>
|
||||
}
|
||||
<Input placeholder="请输入" onPressEnter={()=>test()} onChange={(e)=>setAddressError(e.target?.value ? '' : 'error')}/>
|
||||
</Form.Item> : dataSource && ClusterConfigPreview(dataSource?.[0] as unknown as PartitionClusterNodeTableListItem)}
|
||||
|
||||
<div className="flex gap-btnbase mt-[20px]">
|
||||
{ status === 'edit' && <WithPermission access="system.devops.cluster.edit"><Button type="primary" onClick={test}>下一步</Button></WithPermission>}
|
||||
{ status === 'preview' && <WithPermission access="system.devops.cluster.edit"><Button type="primary" onClick={save}>确定</Button></WithPermission>}
|
||||
<Button type="default" onClick={()=>{changeStatus(status === 'edit' ? 'view' :'edit'); form.resetFields()}}>取消</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</WithPermission>
|
||||
)
|
||||
|
||||
@@ -152,9 +152,7 @@ const RoleConfig = ()=>{
|
||||
const newPermits = generateNewPermit(data.permits)
|
||||
generateDependenciesMap(newPermits)
|
||||
setPermissionTemplate(newPermits)
|
||||
console.log(newPermits)
|
||||
}else{
|
||||
console.log(message)
|
||||
message.error(msg || '获取权限模板失败')
|
||||
}
|
||||
})
|
||||
@@ -196,7 +194,7 @@ const RoleConfig = ()=>{
|
||||
}).catch((errInfo)=>Promise.reject(errInfo))
|
||||
};
|
||||
|
||||
return (<div className="h-full flex flex-col overflow-hidden">
|
||||
return (<div className="h-full flex flex-col overflow-hidden ">
|
||||
<div className="text-[18px] leading-[25px] pb-[12px]">
|
||||
<Button className="flex items-center" type="text" onClick={()=>navigateTo(-1)}><ArrowLeftOutlined className="max-h-[14px]" /><span>返回</span></Button>
|
||||
</div>
|
||||
@@ -214,7 +212,7 @@ const RoleConfig = ()=>{
|
||||
>
|
||||
<div className="flex flex-col h-full">
|
||||
<Form.Item
|
||||
className=" m-btnbase"
|
||||
className=" m-btnbase mr-PAGE_INSIDE_X"
|
||||
name="name"
|
||||
rules={[{ required: true, message: '必填项',whitespace:true }]}
|
||||
>
|
||||
@@ -222,7 +220,7 @@ const RoleConfig = ()=>{
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="permits"
|
||||
className="m-btnbase flex-1 overflow-auto"
|
||||
className="m-btnbase mr-0 flex-1 overflow-auto pr-PAGE_INSIDE_X"
|
||||
>
|
||||
<PermissionCollapse permissionTemplate={permissionTemplate!} dependenciesMap={dependenciesMap} />
|
||||
</Form.Item>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { App, Divider} from "antd";
|
||||
import { App} from "antd";
|
||||
import PageList from "@common/components/aoplatform/PageList.tsx";
|
||||
import { useEffect, useRef,} from "react";
|
||||
import {ActionType, ProColumns} from "@ant-design/pro-components";
|
||||
@@ -12,6 +12,7 @@ import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
|
||||
import { checkAccess } from "@common/utils/permission.ts";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { RoleTableListItem } from "@core/const/role/type.ts";
|
||||
import InsidePage from "@common/components/aoplatform/InsidePage.tsx";
|
||||
|
||||
|
||||
const RoleList = ()=>{
|
||||
@@ -116,46 +117,50 @@ const RoleList = ()=>{
|
||||
}, []);
|
||||
|
||||
return (<>
|
||||
<div className="flex flex-col pb-[20px]">
|
||||
<div className="pb-[30px] ">
|
||||
<p className="text-theme text-[26px] mb-[20px]">角色</p>
|
||||
<p>设置角色的权限范围。</p>
|
||||
</div>
|
||||
<h3 className="p ">系统级别角色</h3>
|
||||
<PageList
|
||||
id="global_role"
|
||||
tableClass="role_table mb-btnrbase"
|
||||
ref={pageListRef}
|
||||
columns={[...ROLE_TABLE_COLUMNS as ProColumns<RoleTableListItem, "text">[], ...operation('system')]}
|
||||
request={()=>getRoleList('system')}
|
||||
addNewBtnTitle="添加角色"
|
||||
showPagination={false}
|
||||
onAddNewBtnClick={() => {
|
||||
navigateTo(`/role/system/config`)
|
||||
}}
|
||||
noScroll={true}
|
||||
addNewBtnAccess="system.organization.role.system.add"
|
||||
onRowClick={(row:RoleTableListItem)=> navigateTo(`/role/system/config/${row.id}`)}
|
||||
tableClickAccess="system.organization.role.system.edit"
|
||||
/>
|
||||
<h3 className=" pt-btnbase ">团队级别角色</h3>
|
||||
<PageList
|
||||
id="global_role"
|
||||
ref={pageListRef}
|
||||
tableClass="role_table "
|
||||
columns={[...ROLE_TABLE_COLUMNS as ProColumns<RoleTableListItem, "text">[], ...operation('team')]}
|
||||
request={()=>getRoleList('team')}
|
||||
showPagination={false}
|
||||
addNewBtnTitle="添加角色"
|
||||
onAddNewBtnClick={() => {
|
||||
navigateTo(`/role/team/config`)
|
||||
}}
|
||||
noScroll={true}
|
||||
addNewBtnAccess="system.organization.role.team.add"
|
||||
onRowClick={(row:RoleTableListItem)=> navigateTo(`/role/team/config/${row.id}`)}
|
||||
tableClickAccess="system.organization.role.team.edit"
|
||||
/>
|
||||
</div>
|
||||
<InsidePage
|
||||
className="pb-PAGE_INSIDE_B overflow-y-auto"
|
||||
pageTitle='角色'
|
||||
description="设置角色的权限范围。"
|
||||
showBorder={false}
|
||||
scrollPage={false}
|
||||
>
|
||||
<div className="pr-PAGE_INSIDE_X">
|
||||
<h3 className="mt-0">系统级别角色</h3>
|
||||
<PageList
|
||||
id="global_role"
|
||||
tableClass="role_table mb-btnrbase"
|
||||
ref={pageListRef}
|
||||
columns={[...ROLE_TABLE_COLUMNS as ProColumns<RoleTableListItem, "text">[], ...operation('system')]}
|
||||
request={()=>getRoleList('system')}
|
||||
addNewBtnTitle="添加角色"
|
||||
showPagination={false}
|
||||
onAddNewBtnClick={() => {
|
||||
navigateTo(`/role/system/config`)
|
||||
}}
|
||||
noScroll={true}
|
||||
addNewBtnAccess="system.organization.role.system.add"
|
||||
onRowClick={(row:RoleTableListItem)=> navigateTo(`/role/system/config/${row.id}`)}
|
||||
tableClickAccess="system.organization.role.system.edit"
|
||||
/>
|
||||
<h3 className=" pt-btnbase ">团队级别角色</h3>
|
||||
<PageList
|
||||
id="global_role"
|
||||
ref={pageListRef}
|
||||
tableClass="role_table "
|
||||
columns={[...ROLE_TABLE_COLUMNS as ProColumns<RoleTableListItem, "text">[], ...operation('team')]}
|
||||
request={()=>getRoleList('team')}
|
||||
showPagination={false}
|
||||
addNewBtnTitle="添加角色"
|
||||
onAddNewBtnClick={() => {
|
||||
navigateTo(`/role/team/config`)
|
||||
}}
|
||||
noScroll={true}
|
||||
addNewBtnAccess="system.organization.role.team.add"
|
||||
onRowClick={(row:RoleTableListItem)=> navigateTo(`/role/team/config/${row.id}`)}
|
||||
tableClickAccess="system.organization.role.team.edit"
|
||||
/>
|
||||
</div>
|
||||
</InsidePage>
|
||||
</>)
|
||||
}
|
||||
export default RoleList;
|
||||
@@ -5,7 +5,7 @@ import { PERMISSION_DEFINITION } from "@common/const/permissions";
|
||||
import { useFetch } from "@common/hooks/http";
|
||||
import { checkAccess } from "@common/utils/permission";
|
||||
import { CategorizesType, ServiceHubCategoryConfigHandle } from "@market/const/serviceHub/type";
|
||||
import { App, Button, Spin, TagType, Tree, TreeDataNode, TreeProps } from "antd";
|
||||
import { App, Button, Spin, Tree, TreeDataNode, TreeProps } from "antd";
|
||||
import { DataNode } from "antd/es/tree";
|
||||
import { Key, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { ServiceHubCategoryConfig } from "./ServiceHubCategoryConfig";
|
||||
@@ -14,6 +14,8 @@ import { useBreadcrumb } from "@common/contexts/BreadcrumbContext";
|
||||
import { LoadingOutlined } from "@ant-design/icons";
|
||||
import { cloneDeep } from "lodash-es";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import InsidePage from "@common/components/aoplatform/InsidePage";
|
||||
import { EntityItem } from "@common/const/type";
|
||||
|
||||
export default function ServiceCategory(){
|
||||
const [gData, setGData] = useState<CategorizesType[]>([]);
|
||||
@@ -227,7 +229,7 @@ export default function ServiceCategory(){
|
||||
|
||||
const getCategoryList = ()=>{
|
||||
setLoading(true)
|
||||
fetchData<BasicResponse<{ catalogues:CategorizesType[],tags:TagType[]}>>('catalogues',{method:'GET'}).then(response=>{
|
||||
fetchData<BasicResponse<{ catalogues:CategorizesType[],tags:EntityItem[]}>>('catalogues',{method:'GET'}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
setGData(data.catalogues)
|
||||
@@ -246,12 +248,14 @@ export default function ServiceCategory(){
|
||||
},[])
|
||||
|
||||
return (
|
||||
<div className=" mx-auto h-full">
|
||||
<div className="pb-[30px] pt-0">
|
||||
<p className="text-theme text-[26px] mb-[20px]">服务分类管理</p>
|
||||
<p>设置服务可选择的分类,方便团队成员快速找到API。</p>
|
||||
</div>
|
||||
<div className="max-h-[calc(100%-75px)] border border-solid border-BORDER p-[20px] rounded-[10px]">
|
||||
<InsidePage
|
||||
pageTitle='服务分类管理'
|
||||
description="设置服务可选择的分类,方便团队成员快速找到API。"
|
||||
showBorder={false}
|
||||
contentClassName="pr-PAGE_INSIDE_X"
|
||||
scrollPage={false}
|
||||
>
|
||||
<div className="border border-solid border-BORDER p-[20px] rounded-[10px] ">
|
||||
<Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />} spinning={loading} className=''>
|
||||
<Tree
|
||||
showIcon
|
||||
@@ -267,6 +271,6 @@ export default function ServiceCategory(){
|
||||
</WithPermission>
|
||||
</Spin>
|
||||
</div>
|
||||
</div>
|
||||
</InsidePage>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import {forwardRef, useEffect, useImperativeHandle, useState} from "react";
|
||||
import {App, Button, Divider, Form, Input, Radio, Row, Select, TagType, TreeSelect, Upload} from "antd";
|
||||
import {App, Button, Form, Input, Radio, Row, Select, TreeSelect, Upload} from "antd";
|
||||
import { Link, useNavigate, useParams} from "react-router-dom";
|
||||
import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx";
|
||||
import {BasicResponse, STATUS_CODE} from "@common/const/const.ts";
|
||||
@@ -20,6 +20,7 @@ import { getImgBase64 } from "@common/utils/dataTransfer.ts";
|
||||
import { CategorizesType } from "@market/const/serviceHub/type.ts";
|
||||
import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
|
||||
|
||||
const MAX_SIZE = 2 * 1024; // 1KB
|
||||
|
||||
@@ -38,6 +39,7 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
|
||||
const [tagOptionList, setTagOptionList] = useState<DefaultOptionType[]>([])
|
||||
const [serviceClassifyOptionList, setServiceClassifyOptionList] = useState<DefaultOptionType[]>()
|
||||
const [uploadLoading, setUploadLoading] = useState<boolean>(false)
|
||||
const {checkPermission} = useGlobalContext()
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
save:onFinish
|
||||
@@ -93,11 +95,11 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
|
||||
const getTagAndServiceClassifyList = ()=>{
|
||||
setTagOptionList([])
|
||||
setServiceClassifyOptionList([])
|
||||
fetchData<BasicResponse<{ catalogues:CategorizesType[],tags:TagType[]}>>('catalogues',{method:'GET'}).then(response=>{
|
||||
fetchData<BasicResponse<{ catalogues:CategorizesType[],tags:EntityItem[]}>>('catalogues',{method:'GET'}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
setTagOptionList(data.tags?.map((x:TagType)=>{return {
|
||||
label:x.name, value:x.name
|
||||
setTagOptionList(data.tags?.map((x:EntityItem)=>{return {
|
||||
label:x.name, value:x.id
|
||||
}})||[])
|
||||
setServiceClassifyOptionList(data.catalogues)
|
||||
|
||||
@@ -127,19 +129,6 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
|
||||
}
|
||||
]
|
||||
})
|
||||
console.log({
|
||||
...data.service,
|
||||
team:data.service.team.id,
|
||||
catalogue:data.service.catalogue?.id,
|
||||
logoFile:[
|
||||
{
|
||||
uid: '-1', // 文件唯一标识
|
||||
name: 'image.png', // 文件名
|
||||
status: 'done', // 状态有:uploading, done, error, removed
|
||||
url: data.service?.logo || '', // 图片 Base64 数据
|
||||
}
|
||||
]
|
||||
})
|
||||
setImageBase64(data.service.logo)
|
||||
setShowClassify(data.service.serviceType === 'public')
|
||||
},0)
|
||||
@@ -170,7 +159,8 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
|
||||
|
||||
const getTeamOptionList = ()=>{
|
||||
setTeamOptionList([])
|
||||
fetchData<BasicResponse<{ teams: SimpleTeamItem[] }>>('simple/teams/mine',{method:'GET',eoTransformKeys:['available_partitions']}).then(response=>{
|
||||
|
||||
fetchData<BasicResponse<{ teams: SimpleTeamItem[] }>>(!checkPermission('system.workspace.team.view_all') ?'simple/teams/mine' :'simple/teams',{method:'GET',eoTransformKeys:[]}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
setTeamOptionList(data.teams?.map((x:MemberItem)=>{return {...x,
|
||||
@@ -202,7 +192,7 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
|
||||
getSystemInfo();
|
||||
setBreadcrumb([
|
||||
{
|
||||
title: <Link to={`/service/list`}>内部数据服务</Link>
|
||||
title: <Link to={`/service/list`}>服务</Link>
|
||||
},
|
||||
{
|
||||
title: '设置'
|
||||
@@ -238,14 +228,13 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`h-full min-w-[570px]`}>
|
||||
<WithPermission access={onEdit ? 'team.service.service.edit' :''}>
|
||||
<Form
|
||||
layout='vertical'
|
||||
labelAlign='left'
|
||||
scrollToFirstError
|
||||
form={form}
|
||||
className="mx-auto pb-[20px] "
|
||||
className="w-full pr-PAGE_INSIDE_X "
|
||||
name="systemConfig"
|
||||
onFinish={onFinish}
|
||||
autoComplete="off"
|
||||
@@ -262,7 +251,6 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
|
||||
<Form.Item<SystemConfigFieldType>
|
||||
label="服务ID"
|
||||
name="id"
|
||||
extra="服务ID(sys_id)可用于检索服务或日志"
|
||||
rules={[{ required: true, message: '必填项' ,whitespace:true }]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" disabled={onEdit} placeholder="请输入服务ID"/>
|
||||
@@ -271,7 +259,7 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
|
||||
<Form.Item<SystemConfigFieldType>
|
||||
label="API 调用前缀"
|
||||
name="prefix"
|
||||
extra="选填,作为服务内所有服务的API的前缀,比如host/{sys_name}/{service_name}/{api_path},一旦保存无法修改"
|
||||
extra="选填,作为服务内所有API的前缀,比如host/{service_name}/{api_path},一旦保存无法修改"
|
||||
rules={[
|
||||
{
|
||||
validator: validateUrlSlash,
|
||||
@@ -376,18 +364,19 @@ const SystemConfig = forwardRef<SystemConfigHandle>((_,ref) => {
|
||||
</Row></>}
|
||||
</div>
|
||||
{onEdit && <>
|
||||
<div className="bg-[rgb(255_120_117_/_5%)] rounded-[10px] mt-[50px] p-btnrbase pb-0">
|
||||
<p className="text-left"><span className="font-bold">删除服务:</span>删除操作不可恢复,请谨慎操作!</p>
|
||||
<div className="text-left">
|
||||
<WithPermission access="team.service.service.delete">
|
||||
<Button className="m-auto mt-[16px] mb-[20px]" type="default" danger={true} onClick={deleteSystemModal}>删除服务</Button>
|
||||
</WithPermission>
|
||||
<WithPermission access="team.service.service.delete" showDisabled={false}>
|
||||
<div className="bg-[rgb(255_120_117_/_5%)] rounded-[10px] mt-[50px] p-btnrbase pb-0">
|
||||
<p className="text-left"><span className="font-bold">删除服务:</span>删除操作不可恢复,请谨慎操作!</p>
|
||||
<div className="text-left">
|
||||
<WithPermission access="team.service.service.delete">
|
||||
<Button className="m-auto mt-[16px] mb-[20px]" type="default" danger={true} onClick={deleteSystemModal}>删除服务</Button>
|
||||
</WithPermission>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WithPermission>
|
||||
</>}
|
||||
</Form>
|
||||
</WithPermission>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
})
|
||||
|
||||
@@ -67,7 +67,7 @@ const ServiceInsideDocument = ()=>{
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-full border-[1px] rounded-[10px] border-BORDER border-solid">
|
||||
<div className="flex flex-col h-full border-[1px] rounded-[10px] border-BORDER border-solid mr-PAGE_INSIDE_X">
|
||||
<Editor
|
||||
tinymceScriptSrc={'/tinymce/tinymce.min.js'}
|
||||
initialValue={initDoc}
|
||||
|
||||
@@ -76,7 +76,6 @@ const SystemInsidePage:FC = ()=> {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log(apiId, serviceId, currentUrl)
|
||||
if(apiId !== undefined){
|
||||
setActiveMenu('api')
|
||||
}else if(serviceId !== currentUrl.split('/')[currentUrl.split('/').length - 1]){
|
||||
@@ -84,7 +83,6 @@ const SystemInsidePage:FC = ()=> {
|
||||
}else{
|
||||
setActiveMenu('api')
|
||||
}
|
||||
console.log(activeMenu)
|
||||
}, [currentUrl]);
|
||||
|
||||
useEffect(()=>{
|
||||
@@ -119,7 +117,7 @@ const SystemInsidePage:FC = ()=> {
|
||||
mode="inline"
|
||||
items={menuData as unknown as ItemType<MenuItemType>[] }
|
||||
/>
|
||||
<div className={` ${['setting', 'upstream'].indexOf(activeMenu!) !== -1 ? 'pr-btnrbase' :''} w-full h-full flex flex-1 flex-col overflow-auto bg-MAIN_BG pt-[20px] pl-[20px] pb-[20px] ` }>
|
||||
<div className={` ${['setting', 'upstream'].indexOf(activeMenu!) !== -1 ? '' :''} w-full h-full flex flex-1 flex-col overflow-auto bg-MAIN_BG pt-[20px] pl-[20px] pb-PAGE_INSIDE_B ` }>
|
||||
<Outlet/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -126,7 +126,7 @@ const SystemInsideSubscriber:FC = ()=>{
|
||||
useEffect(() => {
|
||||
setBreadcrumb([
|
||||
{
|
||||
title:<Link to={`/service/list`}>内部数据服务</Link>
|
||||
title:<Link to={`/service/list`}>服务</Link>
|
||||
},
|
||||
{
|
||||
title:'订阅方管理'
|
||||
@@ -151,6 +151,7 @@ const SystemInsideSubscriber:FC = ()=>{
|
||||
addNewBtnTitle="新增订阅方"
|
||||
onAddNewBtnClick={()=>{openModal('add')}}
|
||||
addNewBtnAccess="team.service.subscription.add"
|
||||
tableClass="pr-PAGE_INSIDE_X"
|
||||
/>
|
||||
)
|
||||
}
|
||||
@@ -164,12 +165,10 @@ export const SystemSubscriberConfig = forwardRef<SystemSubscriberConfigHandle,Sy
|
||||
const [form] = Form.useForm();
|
||||
const {fetchData} = useFetch()
|
||||
const [systemOptionList, setSystemOptionList] = useState<DefaultOptionType[]>()
|
||||
const [memberOptionList, setMemberOptionList] = useState<DefaultOptionType[]>()
|
||||
const [subscriberTeamId, setSubscriberTeamId] = useState<string>()
|
||||
const save:()=>Promise<boolean | string> = ()=>{
|
||||
return new Promise((resolve, reject)=>{
|
||||
form.validateFields().then((value)=>{
|
||||
fetchData<BasicResponse<null>>('service/subscriber',{method:'POST',eoBody:({...value,service:serviceId}), eoParams:{service:serviceId,team:teamId}}).then(response=>{
|
||||
fetchData<BasicResponse<null>>('service/subscriber',{method:'POST',eoBody:({...value}), eoParams:{service:serviceId,team:teamId}}).then(response=>{
|
||||
const {code,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
message.success(msg || '操作成功!')
|
||||
@@ -195,7 +194,6 @@ export const SystemSubscriberConfig = forwardRef<SystemSubscriberConfigHandle,Sy
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
const teamMap = new Map<string, unknown>();
|
||||
|
||||
data.apps
|
||||
.filter((x:SimpleSystemItem)=>x.id !== serviceId)
|
||||
.forEach((item:SimpleSystemItem) => {
|
||||
@@ -225,24 +223,6 @@ export const SystemSubscriberConfig = forwardRef<SystemSubscriberConfigHandle,Sy
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(()=>{
|
||||
subscriberTeamId && getMemberList()
|
||||
form.setFieldValue('applier',null)
|
||||
},[subscriberTeamId])
|
||||
|
||||
const getMemberList = ()=>{
|
||||
setMemberOptionList([])
|
||||
fetchData<BasicResponse<{ members: NewSimpleMemberItem[] }>>('team/members/simple',{method:'GET',eoParams:{team:subscriberTeamId}}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
setMemberOptionList(data.members?.map((x:NewSimpleMemberItem)=>{return {
|
||||
label:x.user.name, value:x.user.id
|
||||
}}))
|
||||
}else{
|
||||
message.error(msg || '操作失败')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getSystemList()
|
||||
@@ -262,7 +242,7 @@ export const SystemSubscriberConfig = forwardRef<SystemSubscriberConfigHandle,Sy
|
||||
>
|
||||
<Form.Item<SystemSubscriberConfigFieldType>
|
||||
label="订阅方"
|
||||
name="subscriber"
|
||||
name="application"
|
||||
rules={[{ required: true, message: '必填项' }]}
|
||||
>
|
||||
<TreeSelect
|
||||
@@ -271,18 +251,9 @@ export const SystemSubscriberConfig = forwardRef<SystemSubscriberConfigHandle,Sy
|
||||
treeData={systemOptionList}
|
||||
placeholder="请选择"
|
||||
treeDefaultExpandAll
|
||||
onSelect={(_:unknown)=>{setSubscriberTeamId(_)}}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label="申请人"
|
||||
name="applier"
|
||||
rules={[{ required: true, message: '必填项' }]}
|
||||
>
|
||||
<Select className="w-INPUT_NORMAL" options={memberOptionList} placeholder="请选择"/>
|
||||
</Form.Item>
|
||||
|
||||
</Form>
|
||||
</WithPermission>)
|
||||
})
|
||||
@@ -11,6 +11,7 @@ import { SystemConfigHandle, SystemTableListItem } from "../../const/system/type
|
||||
import { SYSTEM_TABLE_COLUMNS } from "../../const/system/const.tsx";
|
||||
import { DrawerWithFooter } from "@common/components/aoplatform/DrawerWithFooter.tsx";
|
||||
import SystemConfig from "./SystemConfig.tsx";
|
||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
|
||||
|
||||
const SystemList:FC = ()=>{
|
||||
const navigate = useNavigate();
|
||||
@@ -27,6 +28,7 @@ const SystemList:FC = ()=>{
|
||||
const [memberValueEnum, setMemberValueEnum] = useState<{[k:string]:{text:string}}>({})
|
||||
const [open, setOpen] = useState(false);
|
||||
const drawerFormRef = useRef<SystemConfigHandle>(null)
|
||||
const {checkPermission} = useGlobalContext()
|
||||
|
||||
const getSystemList = ()=>{
|
||||
if(!tableHttpReload){
|
||||
@@ -36,7 +38,7 @@ const SystemList:FC = ()=>{
|
||||
success: true,
|
||||
});
|
||||
}
|
||||
return fetchData<BasicResponse<{services:SystemTableListItem[]}>>('my_services',{method:'GET',eoParams:{keyword:tableSearchWord},eoTransformKeys:['api_num','service_num','create_time']}).then(response=>{
|
||||
return fetchData<BasicResponse<{services:SystemTableListItem[]}>>(!checkPermission('system.workspace.service.view_all') ? 'my_services':'services',{method:'GET',eoParams:{keyword:tableSearchWord},eoTransformKeys:['api_num','service_num','create_time']}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
setTableListDataSource(data.services)
|
||||
@@ -53,7 +55,7 @@ const SystemList:FC = ()=>{
|
||||
}
|
||||
|
||||
const getTeamsList = ()=>{
|
||||
fetchData<BasicResponse<{teams:SimpleTeamItem[]}>>('simple/teams/mine',{method:'GET'}).then(response=>{
|
||||
fetchData<BasicResponse<{ teams: SimpleTeamItem[] }>>(!checkPermission('system.workspace.team.view_all') ?'simple/teams/mine' :'simple/teams',{method:'GET',eoTransformKeys:[]}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
setTeamList(data.teams)
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
@@ -94,7 +96,7 @@ const SystemList:FC = ()=>{
|
||||
getMemberList()
|
||||
setBreadcrumb([
|
||||
{
|
||||
title: '内部数据服务'
|
||||
title: '服务'
|
||||
}])
|
||||
}, []);
|
||||
|
||||
@@ -123,7 +125,7 @@ const SystemList:FC = ()=>{
|
||||
|
||||
return (
|
||||
// <Skeleton className='m-btnbase w-[calc(100%-20px)]' loading={loading} active>
|
||||
<div className="h-full w-full">
|
||||
<div className="h-full w-full pr-PAGE_INSIDE_X pb-PAGE_INSIDE_B">
|
||||
|
||||
<PageList
|
||||
id="global_system"
|
||||
|
||||
@@ -109,7 +109,7 @@ export default function SystemTopology() {
|
||||
getNodeData()
|
||||
setBreadcrumb([
|
||||
{
|
||||
title: <Link to={`/service/list`}>内部数据服务</Link>
|
||||
title: <Link to={`/service/list`}>服务</Link>
|
||||
},
|
||||
{
|
||||
title: '调用拓扑图'
|
||||
|
||||
@@ -176,7 +176,7 @@ const SystemInsideApiList:FC = ()=>{
|
||||
useEffect(() => {
|
||||
setBreadcrumb([
|
||||
{
|
||||
title:<Link to={`/service/list`}>内部数据服务</Link>
|
||||
title:<Link to={`/service/list`}>服务</Link>
|
||||
},
|
||||
{
|
||||
title:'API'
|
||||
@@ -226,6 +226,7 @@ const SystemInsideApiList:FC = ()=>{
|
||||
setTableHttpReload(false)
|
||||
}}
|
||||
onRowClick={(row:SystemApiTableListItem)=>openDrawer('view',row)}
|
||||
tableClass="mr-PAGE_INSIDE_X "
|
||||
/>
|
||||
<DrawerWithFooter
|
||||
title={drawerType === 'add' ? "添加 API":"API 详情"}
|
||||
|
||||
@@ -148,7 +148,7 @@ const SystemInsideApprovalList:FC = ()=>{
|
||||
useEffect(() => {
|
||||
setBreadcrumb([
|
||||
{
|
||||
title:<Link to={`/service/list`}>内部数据服务</Link>
|
||||
title:<Link to={`/service/list`}>服务</Link>
|
||||
},
|
||||
{
|
||||
title:'订阅审批'
|
||||
@@ -182,6 +182,7 @@ const SystemInsideApprovalList:FC = ()=>{
|
||||
}}
|
||||
onRowClick={(row:SubscribeApprovalTableListItem)=>openModal(pageStatus === 0 ? 'approval': 'view',row)}
|
||||
tableClickAccess={pageStatus === 0 ?'team.service.subscription.approval':'team.service.subscription.view'}
|
||||
tableClass="pr-PAGE_INSIDE_X"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -27,7 +27,7 @@ const SystemInsidePublic:FC = ()=>{
|
||||
useEffect(() => {
|
||||
setBreadcrumb([
|
||||
{
|
||||
title:<Link to={`/service/list`}>内部数据服务</Link>
|
||||
title:<Link to={`/service/list`}>服务</Link>
|
||||
},
|
||||
{
|
||||
title:'发布'
|
||||
|
||||
@@ -354,7 +354,7 @@ const SystemInsidePublicList:FC = ()=>{
|
||||
useEffect(() => {
|
||||
setBreadcrumb([
|
||||
{
|
||||
title:<Link to={`/service/list`}>内部数据服务</Link>
|
||||
title:<Link to={`/service/list`}>服务</Link>
|
||||
},
|
||||
{
|
||||
title:'发布'
|
||||
@@ -444,9 +444,9 @@ const SystemInsidePublicList:FC = ()=>{
|
||||
onChange={() => {
|
||||
setTableHttpReload(false)
|
||||
}}
|
||||
besidesTableHeight={58}
|
||||
onRowClick={(row:PublishTableListItem|PublishVersionTableListItem)=>openDrawer('view',row)}
|
||||
tableClickAccess="team.service.release.view"
|
||||
tableClass="pr-PAGE_INSIDE_X"
|
||||
/>
|
||||
<DrawerWithFooter
|
||||
destroyOnClose={true}
|
||||
|
||||
@@ -20,7 +20,7 @@ const DEFAULT_FORM_VALUE = {
|
||||
balance:'round-robin',
|
||||
limitPeerSecond:10000,
|
||||
retry:3,
|
||||
timeout:3,
|
||||
timeout:10000,
|
||||
}
|
||||
|
||||
const SystemInsideUpstreamContent= forwardRef<SystemInsideUpstreamContentHandle>((props,ref) => {
|
||||
@@ -107,7 +107,7 @@ const globalConfigNodesRule: FormItemProps['rules'] = [
|
||||
useEffect(() => {
|
||||
setBreadcrumb([
|
||||
{
|
||||
title: <Link to={`/service/list`}>内部数据服务</Link>
|
||||
title: <Link to={`/service/list`}>服务</Link>
|
||||
},
|
||||
{
|
||||
title: '上游'
|
||||
@@ -118,14 +118,14 @@ const globalConfigNodesRule: FormItemProps['rules'] = [
|
||||
|
||||
return (
|
||||
<Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />} spinning={loading}>
|
||||
<div className={`flex-1 h-full overflow-auto`} >
|
||||
<div className={`flex-1 h-full overflow-auto pr-PAGE_INSIDE_X`} >
|
||||
<WithPermission access={'team.service.upstream.edit'}>
|
||||
<Form
|
||||
layout='vertical'
|
||||
labelAlign='left'
|
||||
name="systemInsideUpstreamContent"
|
||||
scrollToFirstError
|
||||
className="mx-auto mb-[20px] overflow-hidden"
|
||||
className="mx-auto "
|
||||
autoComplete="off"
|
||||
form={form}
|
||||
onFinish={saveUpstream}
|
||||
@@ -224,7 +224,7 @@ const globalConfigNodesRule: FormItemProps['rules'] = [
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
className="border-none bg-transparent pt-btnrbase"
|
||||
className="border-none bg-transparent pt-btnrbase mb-0 pb-0"
|
||||
>
|
||||
<WithPermission access='team.service.upstream.edit'><Button type="primary" htmlType="submit" >
|
||||
保存
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { forwardRef, useEffect, useImperativeHandle, useState} from "react";
|
||||
import {App, Button, Divider, Form, Input, Row, Select} from "antd";
|
||||
import {App, Button, Form, Input, Row, Select} from "antd";
|
||||
import {Link, useLocation, useNavigate, useParams} from "react-router-dom";
|
||||
import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx";
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
@@ -125,13 +125,12 @@ const TeamConfig= forwardRef<TeamConfigHandle,TeamConfigProps>((props,ref) => {
|
||||
setOnEdit(false);
|
||||
form.setFieldsValue({id:uuidv4()}); // 清空 initialValues
|
||||
}
|
||||
// setPageType(currentUrl.split('/')[1] === 'myteam'? 'myteam':'manage')
|
||||
return (form.setFieldsValue({}))
|
||||
}, [teamId]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='overflow-auto h-full w-full'>
|
||||
<div className='overflow-auto h-full w-full pr-PAGE_INSIDE_X'>
|
||||
<WithPermission access={onEdit ?(currentUrl.split('/')[1] === 'myteam'? 'team.team.team.edit':'system.organization.team.edit') : 'system.organization.team.add'}>
|
||||
<Form
|
||||
layout='vertical'
|
||||
@@ -191,16 +190,16 @@ const TeamConfig= forwardRef<TeamConfigHandle,TeamConfigProps>((props,ref) => {
|
||||
</Row>
|
||||
}
|
||||
{onEdit &&
|
||||
<>
|
||||
<WithPermission access="system.organization.team.delete" showDisabled={false}>
|
||||
<div className="bg-[rgb(255_120_117_/_5%)] rounded-[10px] mt-[50px] p-btnrbase pb-0">
|
||||
<p className="text-left"><span className="font-bold">删除团队:</span>删除操作不可恢复,请谨慎操作!</p>
|
||||
<div className="text-left">
|
||||
<WithPermission access="system.organization.team.delete" disabled={!canDelete} tooltip={canDelete ? '':'服务数据清除后,方可删除'}>
|
||||
<Button className="m-auto mt-[16px] mb-[20px]" type="default" danger onClick={()=>deleteTeam(entity!)}>删除</Button></WithPermission>
|
||||
|
||||
<Button className="m-auto mt-[16px] mb-[20px]" type="default" danger onClick={()=>deleteTeam(entity!)}>删除</Button>
|
||||
</WithPermission>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
</WithPermission>
|
||||
}
|
||||
</Form>
|
||||
</WithPermission>
|
||||
|
||||
@@ -58,7 +58,7 @@ const TeamInsideMember:FC = ()=>{
|
||||
{
|
||||
title: '操作',
|
||||
key: 'option',
|
||||
width: 76,
|
||||
width: 88,
|
||||
fixed:'right',
|
||||
valueType: 'option',
|
||||
render: (_: React.ReactNode, entity: TeamMemberTableListItem) => [
|
||||
@@ -288,7 +288,7 @@ const TeamInsideMember:FC = ()=>{
|
||||
request={()=>getMemberList()}
|
||||
primaryKey="user.id"
|
||||
addNewBtnTitle="添加成员"
|
||||
className="ml-[20px] mt-[20px]"
|
||||
className="ml-[20px] mt-[20px] "
|
||||
searchPlaceholder="输入姓名查找"
|
||||
onAddNewBtnClick={()=>{openModal('add')}}
|
||||
addNewBtnAccess="team.team.member.add"
|
||||
|
||||
@@ -94,7 +94,8 @@ const TeamInsidePage:FC = ()=> {
|
||||
tagList={[{label:
|
||||
<Paragraph className="mb-0" copyable={teamId ? { text: teamId } : false}>团队 ID:{teamId || '-'}</Paragraph>
|
||||
}]}
|
||||
backUrl="/team/list">
|
||||
backUrl="/team/list"
|
||||
>
|
||||
<div className="flex h-full">
|
||||
<Menu
|
||||
style={{ width: 220 }}
|
||||
@@ -103,7 +104,7 @@ const TeamInsidePage:FC = ()=> {
|
||||
onClick={onMenuClick}
|
||||
selectedKeys={[activeMenu || '']}
|
||||
/>
|
||||
<div className={`flex flex-1 flex-col h-full overflow-auto bg-MAIN_BG pb-[20px] pt-[20px] pl-[10px] ${activeMenu === 'setting' ? ' pr-btnrbase ':''}`}>
|
||||
<div className={`flex flex-1 flex-col h-full overflow-auto bg-MAIN_BG pb-PAGE_INSIDE_B pt-[20px] pl-[10px] ${activeMenu === 'setting' ? ' ':'pr-PAGE_INSIDE_X'}`}>
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,6 +14,7 @@ import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPe
|
||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
|
||||
import { checkAccess } from "@common/utils/permission.ts";
|
||||
import TeamConfig from "./TeamConfig.tsx";
|
||||
import InsidePage from "@common/components/aoplatform/InsidePage.tsx";
|
||||
|
||||
const TeamList:FC = ()=>{
|
||||
const [searchWord, setSearchWord] = useState<string>('')
|
||||
@@ -32,7 +33,7 @@ const TeamList:FC = ()=>{
|
||||
const [modalType, setModalType] = useState<'add'|'edit'>('add')
|
||||
|
||||
const getTeamList = ()=>{
|
||||
return fetchData<BasicResponse<{teams:TeamTableListItem}>>(!checkPermission('system.organization.team.view') ? 'teams':'manager/teams',{method:'GET',eoParams:{keyword:searchWord},eoTransformKeys:['create_time','service_num','can_delete']}).then(response=>{
|
||||
return fetchData<BasicResponse<{teams:TeamTableListItem}>>(!checkPermission('system.workspace.team.view_all') ? 'teams':'manager/teams',{method:'GET',eoParams:{keyword:searchWord},eoTransformKeys:['create_time','service_num','can_delete']}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
return {data:data.teams, success: true}
|
||||
@@ -158,11 +159,12 @@ const TeamList:FC = ()=>{
|
||||
|
||||
|
||||
return (
|
||||
<div className="flex flex-col flex-1 h-full">
|
||||
<div className="pb-[30px] pt-0">
|
||||
<p className="text-theme text-[26px] mb-[20px]">团队</p>
|
||||
<p>设置团队和成员,然后你可以在团队内创建服务和应用、订阅API,成员只能看到所属团队内的服务和应用。</p>
|
||||
</div>
|
||||
<InsidePage
|
||||
pageTitle='团队'
|
||||
description="设置团队和成员,然后你可以在团队内创建服务和应用、订阅API,成员只能看到所属团队内的服务和应用。"
|
||||
showBorder={false}
|
||||
contentClassName=" pr-PAGE_INSIDE_X pb-PAGE_INSIDE_B"
|
||||
>
|
||||
<PageList
|
||||
id="global_team"
|
||||
className="pl-btnbase"
|
||||
@@ -203,7 +205,7 @@ const TeamList:FC = ()=>{
|
||||
>
|
||||
<TeamConfig ref={teamConfigRef} inModal entity={modalType === 'add' ? undefined : curTeam} />
|
||||
</Modal>
|
||||
</div>
|
||||
</InsidePage>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
|
||||
import { App, Button, Form, Input } from "antd";
|
||||
import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
|
||||
import { BasicResponse, STATUS_CODE } from "@common/const/const.ts";
|
||||
import { useFetch } from "@common/hooks/http.ts";
|
||||
|
||||
const ChangePsw= () => {
|
||||
const { message } = App.useApp()
|
||||
const {fetchData} = useFetch()
|
||||
const [form] = Form.useForm();
|
||||
|
||||
|
||||
const savePsw = ()=>{
|
||||
form.validateFields().then((value)=>{
|
||||
return fetchData<BasicResponse<null>>(
|
||||
'account/password/reset',
|
||||
{
|
||||
method:'PUT',
|
||||
eoBody:({...value}),
|
||||
}).then(response=>{
|
||||
const {code,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
message.success(msg || '操作成功!')
|
||||
}else{
|
||||
message.error(msg || '操作失败')
|
||||
}
|
||||
form.resetFields()
|
||||
}).catch((errorInfo)=> {console.warn(errorInfo)})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className={`flex-1 h-full overflow-auto pr-PAGE_INSIDE_X`} >
|
||||
<WithPermission access={''}>
|
||||
<Form
|
||||
layout='vertical'
|
||||
labelAlign='left'
|
||||
name="changePsw"
|
||||
scrollToFirstError
|
||||
className="mx-auto pl-[10px] "
|
||||
autoComplete="off"
|
||||
form={form}
|
||||
onFinish={savePsw}
|
||||
>
|
||||
|
||||
<Form.Item
|
||||
name="old_password"
|
||||
label="旧密码"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '必填项',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input.Password />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
name="new_password"
|
||||
label="新密码"
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '必填项',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input.Password />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
name="confirm"
|
||||
label="确认密码"
|
||||
dependencies={['new_password']}
|
||||
rules={[
|
||||
{
|
||||
required: true,
|
||||
message: '必填项',
|
||||
},
|
||||
({ getFieldValue }) => ({
|
||||
validator(_, value) {
|
||||
if (!value || getFieldValue('new_password') === value) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return Promise.reject(new Error('两次密码不一致'));
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<Input.Password />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
className="border-none bg-transparent pt-btnrbase mb-0 pb-0 pl-0"
|
||||
>
|
||||
<WithPermission access=''><Button type="primary" htmlType="submit" >
|
||||
修改密码
|
||||
</Button></WithPermission>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</WithPermission>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ChangePsw
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
import {FC, useEffect, useState} from "react";
|
||||
import { Link, Outlet, useLocation, useNavigate, useParams} from "react-router-dom";
|
||||
import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx";
|
||||
import { Menu} from "antd";
|
||||
import InsidePage from "@common/components/aoplatform/InsidePage.tsx";
|
||||
import { getItem } from "@common/utils/navigation.tsx";
|
||||
|
||||
const UserProfile:FC = ()=> {
|
||||
const {teamId} = useParams<RouterParams>();
|
||||
const location = useLocation()
|
||||
const navigateTo = useNavigate()
|
||||
const [activeMenu, setActiveMenu] = useState<string>()
|
||||
|
||||
|
||||
const menuData = [
|
||||
getItem(<Link to="changepsw">修改密码</Link>, 'changepsw')]
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if(location.pathname.split('/')[location.pathname.split('/').length -1] !== teamId){
|
||||
setActiveMenu(location.pathname.split('/')[location.pathname.split('/').length -1].toLowerCase())
|
||||
}
|
||||
}, [location]);
|
||||
|
||||
useEffect(()=>{
|
||||
if( activeMenu && teamId === location.pathname.split('/')[location.pathname.split('/').length - 1]){
|
||||
navigateTo(`/userProfile/${activeMenu}`)
|
||||
}
|
||||
},[activeMenu])
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<InsidePage
|
||||
pageTitle='账号设置'
|
||||
description="管理个人账号"
|
||||
>
|
||||
<div className="flex h-full">
|
||||
<Menu
|
||||
style={{ width: 220 }}
|
||||
mode="inline"
|
||||
items={menuData}
|
||||
selectedKeys={[activeMenu || 'changepsw']}
|
||||
/>
|
||||
<div className={`flex flex-1 flex-col h-full overflow-auto bg-MAIN_BG pb-PAGE_INSIDE_B pt-[20px] pl-[10px] `}>
|
||||
<Outlet />
|
||||
</div>
|
||||
</div>
|
||||
</InsidePage>
|
||||
</>
|
||||
)
|
||||
}
|
||||
export default UserProfile
|
||||
@@ -25,6 +25,6 @@
|
||||
"@market/*": ["../market/src/*"],
|
||||
},
|
||||
},
|
||||
"include": ["src", "public/iconpark_eolink.js", "public/iconpark_apinto.js", "../common/src/component/aoplatform/EditableTableWithModal.tsx", "../common/src/components/aoplatform/TransferTable.tsx", "../common/src/components/aoplatform/TreeWithMore.tsx", "../common/src/components/aoplatform/DatePicker.tsx", "../common/src/components/aoplatform/TimeRangeSelector.tsx", "../common/src/components/aoplatform/TimePicker.tsx", "../common/src/components/aoplatform/MemberTransfer.tsx", "../common/src/components/aoplatform/Navigation.tsx", "../common/src/components/aoplatform/PageList.tsx", "../common/src/components/aoplatform/GroupTree.tsx", "../common/src/components/aoplatform/ErrorBoundary.tsx", "../common/src/components/aoplatform/ScrollableSection.tsx", "../common/src/utils/postcat.tsx", "../common/src/utils/curl.ts", "../common/src/components/aoplatform/ResetPsw.tsx", "../common/src/components/aoplatform/SubscribeApprovalModalContent.tsx", "../common/src/components/aoplatform/InsidePageForHub.tsx", "src/components/aoplatform/RenderRoutes.tsx", "../common/src/components/aoplatform/PublishApprovalModalContent.tsx", "../common/src/components/aoplatform/InsidePage.tsx", "../common/src/const/type.ts", "../common/src/components/aoplatform/intelligent-plugin", "../common/src/const/domain"],
|
||||
"include": ["src", "public/iconpark_eolink.js", "public/iconpark_apinto.js", "../common/src/component/aoplatform/EditableTableWithModal.tsx", "../common/src/components/aoplatform/TransferTable.tsx", "../common/src/components/aoplatform/TreeWithMore.tsx", "../common/src/components/aoplatform/DatePicker.tsx", "../common/src/components/aoplatform/TimeRangeSelector.tsx", "../common/src/components/aoplatform/TimePicker.tsx", "../common/src/components/aoplatform/MemberTransfer.tsx", "../common/src/components/aoplatform/Navigation.tsx", "../common/src/components/aoplatform/PageList.tsx", "../common/src/components/aoplatform/GroupTree.tsx", "../common/src/components/aoplatform/ErrorBoundary.tsx", "../common/src/components/aoplatform/ScrollableSection.tsx", "../common/src/utils/postcat.tsx", "../common/src/utils/curl.ts", "../common/src/components/aoplatform/ResetPsw.tsx", "../common/src/components/aoplatform/SubscribeApprovalModalContent.tsx", "src/components/aoplatform/RenderRoutes.tsx", "../common/src/components/aoplatform/PublishApprovalModalContent.tsx", "../common/src/components/aoplatform/InsidePage.tsx", "../common/src/const/type.ts", "../common/src/components/aoplatform/intelligent-plugin", "../common/src/const/domain"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
dataIndex: 'requestSuccess',
|
||||
width: 106,
|
||||
ellipsis:true,
|
||||
copyable: true,
|
||||
sorter: (a,b)=> {
|
||||
return a.requestSuccess - b.requestSuccess
|
||||
},
|
||||
@@ -33,7 +32,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
eoTitle:'请求成功率',
|
||||
dataIndex: 'requestRate',
|
||||
valueType:'percent',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.requestRate - b.requestRate
|
||||
@@ -45,7 +43,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
eoTitle:'转发总数',
|
||||
width: 96,
|
||||
dataIndex: 'proxyTotal',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.proxyTotal - b.proxyTotal
|
||||
@@ -57,7 +54,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
eoTitle:'转发成功数',
|
||||
width: 106,
|
||||
dataIndex: 'proxySuccess',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.proxySuccess - b.proxySuccess
|
||||
@@ -70,7 +66,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
width: 106,
|
||||
dataIndex: 'proxyRate',
|
||||
valueType:'percent',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.proxyRate - b.proxyRate
|
||||
@@ -82,7 +77,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
eoTitle:'失败状态码数',
|
||||
width: 120,
|
||||
dataIndex: 'statusFail',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.statusFail - b.statusFail
|
||||
@@ -95,7 +89,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
width: 148,
|
||||
dataIndex: 'avgResp',
|
||||
valueType:'digit',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.avgResp - b.avgResp
|
||||
@@ -108,7 +101,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
width: 148,
|
||||
dataIndex: 'maxResp',
|
||||
valueType:'digit',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.maxResp - b.maxResp
|
||||
@@ -121,7 +113,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
width: 148,
|
||||
dataIndex: 'minResp',
|
||||
valueType:'digit',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.minResp - b.minResp
|
||||
@@ -134,7 +125,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
width: 148,
|
||||
dataIndex: 'avgTraffic',
|
||||
valueType:'digit',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.avgTraffic - b.avgTraffic
|
||||
@@ -147,7 +137,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
width: 148,
|
||||
dataIndex: 'maxTraffic',
|
||||
valueType:'digit',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.maxTraffic - b.maxTraffic
|
||||
@@ -160,7 +149,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
width: 148,
|
||||
dataIndex: 'minTraffic',
|
||||
valueType:'digit',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
sorter: (a,b)=> {
|
||||
return a.minTraffic - b.minTraffic
|
||||
@@ -176,7 +164,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
dataIndex: 'name',
|
||||
width:120,
|
||||
ellipsis:true,
|
||||
copyable:true,
|
||||
fixed: 'left',
|
||||
disable:true
|
||||
},
|
||||
@@ -185,7 +172,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
eoTitle:'请求路径',
|
||||
dataIndex: 'path',
|
||||
ellipsis:true,
|
||||
copyable:true,
|
||||
width: 80
|
||||
},
|
||||
{
|
||||
@@ -208,7 +194,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
dataIndex: 'name',
|
||||
width:160,
|
||||
ellipsis:true,
|
||||
copyable:true,
|
||||
fixed: 'left',
|
||||
disable:true
|
||||
},
|
||||
@@ -218,7 +203,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
ellipsis:true,
|
||||
copyable:true,
|
||||
fixed: 'left'
|
||||
},
|
||||
...DASHBOARD_BASE_COLUMNS_CONFIG as (ProColumns<MonitorApiData>&{eoTitle:string})[]
|
||||
@@ -232,7 +216,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
dataIndex: 'name',
|
||||
width:160,
|
||||
ellipsis:true,
|
||||
copyable:true,
|
||||
fixed: 'left',
|
||||
disable:true
|
||||
},
|
||||
@@ -242,7 +225,6 @@ export const DASHBOARD_BASE_COLUMNS_CONFIG:(ProColumns<MonitorData>&{eoTitle:str
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
ellipsis:true,
|
||||
copyable:true,
|
||||
fixed: 'left'
|
||||
},
|
||||
...DASHBOARD_BASE_COLUMNS_CONFIG as (ProColumns<MonitorApiData>&{eoTitle:string})[]
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
"test": "node ./__tests__/market.test.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/dompurify": "^3.0.5",
|
||||
"dompurify": "^3.1.6",
|
||||
"react-virtuoso": "^4.7.11"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ export const SERVICE_HUB_TABLE_COLUMNS: ProColumns<ServiceHubTableListItem>[] =
|
||||
{
|
||||
title: '服务名称',
|
||||
dataIndex: 'name',
|
||||
copyable: true,
|
||||
ellipsis:true,
|
||||
width:160,
|
||||
fixed:'left',
|
||||
@@ -20,7 +19,6 @@ export const SERVICE_HUB_TABLE_COLUMNS: ProColumns<ServiceHubTableListItem>[] =
|
||||
title: '服务ID',
|
||||
dataIndex: 'id',
|
||||
width: 140,
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
@@ -32,19 +30,16 @@ export const SERVICE_HUB_TABLE_COLUMNS: ProColumns<ServiceHubTableListItem>[] =
|
||||
{
|
||||
title: '所属系统',
|
||||
dataIndex: ['app','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '所属团队',
|
||||
dataIndex: ['team','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
},
|
||||
{
|
||||
title: '服务分类',
|
||||
dataIndex: ['catalogue','name'],
|
||||
copyable: true,
|
||||
ellipsis:true
|
||||
}
|
||||
];
|
||||
|
||||
@@ -49,10 +49,6 @@ export type CategorizesType = {
|
||||
children:CategorizesType[]
|
||||
}
|
||||
|
||||
export type TagType = {
|
||||
id:string
|
||||
name:string
|
||||
}
|
||||
|
||||
|
||||
export type ServiceHubTableListItem = {
|
||||
|
||||
@@ -1184,4 +1184,4 @@ p{
|
||||
.ant-form-item-label,
|
||||
.ant-formily-item-label{
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,10 @@ import { EntityItem } from "@common/const/type.ts";
|
||||
import { ApplyServiceModal } from "./ApplyServiceModal.tsx";
|
||||
import ServiceHubApiDocument from "./ServiceHubApiDocument.tsx";
|
||||
import { ApiFilled, ArrowLeftOutlined, LeftOutlined } from "@ant-design/icons";
|
||||
import { Typography } from 'antd';
|
||||
import { SimpleSystemItem } from "@core/const/system/type.ts";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import DOMPurify from 'dompurify';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
const ServiceHubDetail = ()=>{
|
||||
const {serviceId} = useParams<RouterParams>();
|
||||
@@ -42,7 +41,7 @@ const ServiceHubDetail = ()=>{
|
||||
setServiceName(data.service.name)
|
||||
setServiceDesc(data.service.description)
|
||||
setApplied(data.service.applied)
|
||||
setServiceDoc(data.service.document)
|
||||
setServiceDoc(DOMPurify.sanitize(data.service.document))
|
||||
setActiveKey(data.service.apis.map((x)=>x.id))
|
||||
}else{
|
||||
message.error(msg || '操作失败')
|
||||
@@ -106,7 +105,7 @@ const ServiceHubDetail = ()=>{
|
||||
{
|
||||
key: 'introduction',
|
||||
label: '介绍',
|
||||
children: <><pre className="p-btnbase" dangerouslySetInnerHTML={{__html: serviceDoc || ''}}></pre></>,
|
||||
children: <><div className="p-btnbase preview-document" dangerouslySetInnerHTML={{__html: serviceDoc || ''}}></div></>,
|
||||
icon: <Icon icon="ic:baseline-space-dashboard" width="14" height="14"/>,
|
||||
},
|
||||
{
|
||||
@@ -118,7 +117,7 @@ const ServiceHubDetail = ()=>{
|
||||
]
|
||||
|
||||
return (
|
||||
<section className=" grid grid-cols-5 h-full ">
|
||||
<section className=" grid grid-cols-5 h-full mr-PAGE_INSIDE_X">
|
||||
<section className="col-span-4 border-0 border-r-[1px] border-solid border-BORDER flex flex-col overflow-hidden">
|
||||
<section className="flex flex-col gap-btnbase p-btnbase ">
|
||||
|
||||
@@ -128,7 +127,7 @@ const ServiceHubDetail = ()=>{
|
||||
<div className="flex">
|
||||
{/* <Avatar shape="square" size={50} className=" bg-[linear-gradient(135deg,white,#f0f0f0)] text-[#333] rounded-[12px]" > {service?.name?.substring(0,1)}</Avatar> */}
|
||||
<Avatar shape="square" size={50}
|
||||
className={ `rounded-[12px] border-none rounded-[12px] ${ serviceBasicInfo?.logo ? 'bg-[linear-gradient(135deg,white,#f0f0f0)]' : 'bg-[linear-gradient(135deg,#7F83F7,#4E54FF)]'}`}
|
||||
className={ `rounded-[12px] border-none rounded-[12px] ${ serviceBasicInfo?.logo ? 'bg-[linear-gradient(135deg,white,#f0f0f0)]' : 'bg-theme'}`}
|
||||
src={ serviceBasicInfo?.logo ? <img src={serviceBasicInfo?.logo} alt="Logo" style={{ maxWidth: '200px', width:'45px',height:'45px',objectFit:'unset'}}
|
||||
/> : undefined}
|
||||
icon={serviceBasicInfo?.logo ? '' :<iconpark-icon name="auto-generate-api"></iconpark-icon>}> </Avatar>
|
||||
|
||||
@@ -5,8 +5,9 @@ import {useCallback, useEffect, useState} from "react";
|
||||
import Tree, {DataNode} from "antd/es/tree";
|
||||
import {BasicResponse, STATUS_CODE} from "@common/const/const.ts";
|
||||
import {useFetch} from "@common/hooks/http.ts";
|
||||
import { CategorizesType, TagType } from "../../const/serviceHub/type.ts";
|
||||
import { CategorizesType } from "../../const/serviceHub/type.ts";
|
||||
import { filterServiceList, initialServiceHubListState, SERVICE_HUB_LIST_ACTIONS, ServiceHubListActionType } from "./ServiceHubList.tsx";
|
||||
import { EntityItem } from "@common/const/type.ts";
|
||||
|
||||
type ServiceHubGroup = {
|
||||
children:JSX.Element
|
||||
@@ -30,21 +31,21 @@ export const ServiceHubGroup = ({children,filterOption,dispatch}:ServiceHubGroup
|
||||
}
|
||||
|
||||
const getTagAndServiceClassifyList = ()=>{
|
||||
fetchData<BasicResponse<{ catalogues:CategorizesType[],tags:TagType[]}>>('catalogues',{method:'GET'}).then(response=>{
|
||||
fetchData<BasicResponse<{ catalogues:CategorizesType[],tags:EntityItem[]}>>('catalogues',{method:'GET'}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
dispatch({type:SERVICE_HUB_LIST_ACTIONS.GET_CATEGORIES,payload:data.catalogues})
|
||||
dispatch({type:SERVICE_HUB_LIST_ACTIONS.GET_TAGS,payload:[...data.tags,{id:'empty',name:'无标签'}]})
|
||||
dispatch({type:SERVICE_HUB_LIST_ACTIONS.SET_SELECTED_CATE,payload:[...data.catalogues.map((x:CategorizesType)=>x.id)]})
|
||||
dispatch({type:SERVICE_HUB_LIST_ACTIONS.SET_SELECTED_TAG,payload:[...data.tags.map((x:TagType)=>x.id),'empty']})
|
||||
dispatch({type:SERVICE_HUB_LIST_ACTIONS.SET_SELECTED_TAG,payload:[...data.tags.map((x:EntityItem)=>x.id),'empty']})
|
||||
}else{
|
||||
message.error(msg || '操作失败')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const transferToTreeData = useCallback((data:CategorizesType[] | TagType[] ):TreeDataNode[]=>{
|
||||
const loop = (data: CategorizesType[] | TagType[] ): DataNode[] =>
|
||||
const transferToTreeData = useCallback((data:CategorizesType[] | EntityItem[] ):TreeDataNode[]=>{
|
||||
const loop = (data: CategorizesType[] | EntityItem[] ): DataNode[] =>
|
||||
data?.map((item) => {
|
||||
if ((item as CategorizesType).children) {
|
||||
return {
|
||||
|
||||
@@ -6,11 +6,11 @@ import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx";
|
||||
import {BasicResponse, STATUS_CODE} from "@common/const/const.ts";
|
||||
import {useFetch} from "@common/hooks/http.ts";
|
||||
import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx";
|
||||
import { CategorizesType, ServiceHubTableListItem, TagType } from "../../const/serviceHub/type.ts";
|
||||
import { CategorizesType, ServiceHubTableListItem } from "../../const/serviceHub/type.ts";
|
||||
import { VirtuosoGrid } from 'react-virtuoso';
|
||||
import { ApiOutlined,LoadingOutlined } from "@ant-design/icons";
|
||||
import ServiceHubGroup from "./ServiceHubGroup.tsx";
|
||||
import { unset } from "lodash-es";
|
||||
import { EntityItem } from "@common/const/type.ts";
|
||||
|
||||
export enum SERVICE_HUB_LIST_ACTIONS {
|
||||
GET_CATEGORIES = 'GET_CATEGORIES',
|
||||
@@ -19,33 +19,29 @@ export enum SERVICE_HUB_LIST_ACTIONS {
|
||||
SET_SERVICES='SET_SERVICES',
|
||||
SET_SELECTED_CATE = 'SET_SELECTED_CATE',
|
||||
SET_SELECTED_TAG = 'SET_SELECTED_TAG',
|
||||
SET_SELECTED_PARTITION = 'SET_SELECTED_PARTITION',
|
||||
SET_KEYWORD = 'SET_KEYWORD',
|
||||
LIST_LOADING = 'LIST_LOADING'
|
||||
}
|
||||
|
||||
export type ServiceHubListActionType =
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.GET_CATEGORIES, payload: CategorizesType[] }
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.GET_TAGS, payload: TagType[] }
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.GET_TAGS, payload: EntityItem[] }
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.GET_SERVICES, payload: ServiceHubTableListItem[] }
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.SET_SERVICES, payload: ServiceHubTableListItem[] }
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.SET_SELECTED_CATE, payload: string[] }
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.SET_SELECTED_TAG, payload: string[] }
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.SET_SELECTED_PARTITION, payload: string[] }
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.SET_KEYWORD, payload: string }
|
||||
| { type: SERVICE_HUB_LIST_ACTIONS.LIST_LOADING, payload: boolean }
|
||||
|
||||
export const initialServiceHubListState = {
|
||||
categoriesList: [] as CategorizesType[],
|
||||
tagsList: [] as TagType[],
|
||||
tagsList: [] as EntityItem[],
|
||||
servicesList: [] as ServiceHubTableListItem[],
|
||||
showServicesList: [] as ServiceHubTableListItem[],
|
||||
selectedCate: [] as string[],
|
||||
selectedTag: [] as string[],
|
||||
selectedPartition: [] as string[],
|
||||
keyword: '',
|
||||
getCateAndTagData:false,
|
||||
getPartitionData:false,
|
||||
listLoading:false,
|
||||
};
|
||||
|
||||
@@ -63,8 +59,6 @@ export const initialServiceHubListState = {
|
||||
return { ...state, selectedCate: action.payload };
|
||||
case SERVICE_HUB_LIST_ACTIONS.SET_SELECTED_TAG:
|
||||
return { ...state, selectedTag: action.payload };
|
||||
case SERVICE_HUB_LIST_ACTIONS.SET_SELECTED_PARTITION:
|
||||
return { ...state, selectedPartition: action.payload };
|
||||
case SERVICE_HUB_LIST_ACTIONS.SET_KEYWORD:
|
||||
return { ...state, keyword: action.payload };
|
||||
case SERVICE_HUB_LIST_ACTIONS.LIST_LOADING:
|
||||
@@ -75,7 +69,7 @@ export const initialServiceHubListState = {
|
||||
}
|
||||
|
||||
export const filterServiceList = (dataSet: typeof initialServiceHubListState)=>{
|
||||
if(!dataSet.getCateAndTagData || !dataSet.getPartitionData){
|
||||
if(!dataSet.getCateAndTagData ){
|
||||
return dataSet.servicesList
|
||||
}else{
|
||||
return dataSet.servicesList.filter((x)=>{
|
||||
@@ -83,7 +77,6 @@ export const initialServiceHubListState = {
|
||||
if(!dataSet.selectedTag || dataSet.selectedTag.length === 0) return false
|
||||
if((!x.tags || !x.tags.length )&& dataSet.selectedTag.indexOf('empty') === -1) return false
|
||||
if(x.tags && x.tags.length && !x.tags.some(tag => dataSet.selectedTag.includes(tag.id))) return false;
|
||||
if(!dataSet.selectedPartition || dataSet.selectedPartition.length === 0) return false
|
||||
if( dataSet.keyword && !x.name.includes(dataSet.keyword)) return false
|
||||
return true
|
||||
})
|
||||
@@ -143,7 +136,8 @@ const ServiceHubList:FC = ()=>{
|
||||
return (
|
||||
<div className="pt-[20px]">
|
||||
<Card title={CardTitle(item)} className="shadow-[0_5px_10px_0_rgba(0,0,0,0.05)] rounded-[10px] overflow-visible cursor-pointer h-[180px] m-0 transition duration-500 hover:shadow-[0_5px_20px_0_rgba(0,0,0,0.15)] hover:scale-[1.05]" classNames={{header:'border-b-[0px] p-[20px] ', body:"pt-0"}} onClick={()=>showDocumentDetail(item)}>
|
||||
<span className="line-clamp-3 break-all">{item.description || '暂无服务描述'}</span>
|
||||
<span className="line-clamp-3 text-[12px] text-[#666] "
|
||||
style={{'word-break':'auto-phrase'}}>{item.description || '暂无服务描述'}</span>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
@@ -186,7 +180,7 @@ const CardTitle = (service:ServiceHubTableListItem)=>{
|
||||
<div className="pl-[20px] w-[calc(100%-50px)]">
|
||||
<p className="text-[14px] h-[20px] leading-[20px] truncate w-full">{service.name}</p>
|
||||
<div className="mt-[10px] h-[20px] flex items-center font-normal">
|
||||
<Tag color="#7371fc1b" className="text-theme font-normal border-0 mr-[12px] max-w-[70px] truncate" key={service.id} bordered={false} title={service.catalogue?.name || '-'}>{service.catalogue?.name || '-'}</Tag>
|
||||
<Tag color="#7371fc1b" className="text-theme font-normal border-0 mr-[12px] max-w-[150px] truncate" key={service.id} bordered={false} title={service.catalogue?.name || '-'}>{service.catalogue?.name || '-'}</Tag>
|
||||
|
||||
<Tooltip title='API 数量'>
|
||||
<span className="mr-[12px]"><ApiOutlined className="mr-[1px] text-[14px] h-[14px] w-[14px]"/><span className="font-normal text-[14px]">{service.apiNum ?? '-'}</span></span>
|
||||
|
||||
@@ -142,7 +142,6 @@ const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps
|
||||
<Form.Item<ManagementConfigFieldType>
|
||||
label="应用 ID"
|
||||
name="id"
|
||||
extra="应用ID(app_id)可用于检索服务或日志"
|
||||
rules={[{ required: true, message: '必填项' ,whitespace:true }]}
|
||||
>
|
||||
<Input className="w-INPUT_NORMAL" placeholder="请输入" disabled={type === 'edit'}/>
|
||||
@@ -168,14 +167,16 @@ const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps
|
||||
|
||||
{ type === 'edit' && <>
|
||||
|
||||
<div className="bg-[rgb(255_120_117_/_5%)] rounded-[10px] mt-[50px] p-btnrbase pb-0">
|
||||
<p className="text-left"><span className="font-bold">删除应用:</span>删除操作不可恢复,请谨慎操作!</p>
|
||||
<div className="text-left">
|
||||
<WithPermission access="team.application.application.delete">
|
||||
<Button className="m-auto mt-[16px] mb-[20px]" type="default" danger={true} onClick={deleteApplicationModal} loading={delBtnLoading}>删除应用</Button>
|
||||
<WithPermission access="team.application.application.delete" showDisabled={false}>
|
||||
<div className="bg-[rgb(255_120_117_/_5%)] rounded-[10px] mt-[50px] p-btnrbase pb-0">
|
||||
<p className="text-left"><span className="font-bold">删除应用:</span>删除操作不可恢复,请谨慎操作!</p>
|
||||
<div className="text-left">
|
||||
<WithPermission access="team.application.application.delete">
|
||||
<Button className="m-auto mt-[16px] mb-[20px]" type="default" danger={true} onClick={deleteApplicationModal} loading={delBtnLoading}>删除应用</Button>
|
||||
</WithPermission>
|
||||
</div>
|
||||
</div>
|
||||
</WithPermission>
|
||||
</div>
|
||||
</div>
|
||||
</>}
|
||||
</Form>
|
||||
</WithPermission></>
|
||||
|
||||
@@ -25,14 +25,14 @@ export default function ServiceHubManagement() {
|
||||
const [teamList, setTeamList] = useState<MenuItem[]>([])
|
||||
const {setAppName} = useTenantManagementContext()
|
||||
const navigateTo = useNavigate()
|
||||
const {getTeamAccessData,cleanTeamAccessData} = useGlobalContext()
|
||||
const {getTeamAccessData,cleanTeamAccessData,checkPermission} = useGlobalContext()
|
||||
type MenuItem = Required<MenuProps>['items'][number];
|
||||
|
||||
|
||||
const getServiceList = ()=>{
|
||||
//console.log(pagination,sorter,categoryId,tagId)
|
||||
setServiceLoading(true)
|
||||
fetchData<BasicResponse<{apps:ServiceHubAppListItem}>>('my_apps',{method:'GET', eoParams:{ team:teamId,keyword:''},eoTransformKeys:['api_num','subscribe_num','subscribe_verify_num']}).then(response=>{
|
||||
return fetchData<BasicResponse<{apps:ServiceHubAppListItem}>>(!checkPermission('system.workspace.application.view_all') ? 'my_apps':'apps',{method:'GET',eoParams:{ team:teamId,keyword:''},eoTransformKeys:['api_num','subscribe_num','subscribe_verify_num']}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
setServiceList([...data.apps,{type:'addNewItem'}])
|
||||
@@ -51,7 +51,7 @@ const getServiceList = ()=>{
|
||||
|
||||
const getTeamsList = ()=>{
|
||||
setPageLoading(true)
|
||||
fetchData<BasicResponse<{teams:SimpleTeamItem[]}>>('simple/teams/mine',{method:'GET',eoTransformKeys:['app_num','subscribe_num']}).then(response=>{
|
||||
fetchData<BasicResponse<{ teams: SimpleTeamItem[] }>>(!checkPermission('system.workspace.team.view_all') ?'simple/teams/mine' :'simple/teams',{method:'GET',eoTransformKeys:['app_num','subscribe_num']}).then(response=>{
|
||||
const {code,data,msg} = response
|
||||
if(code === STATUS_CODE.SUCCESS){
|
||||
setTeamList(data.teams.map((x:SimpleTeamItem)=>({label:<div className="flex items-center justify-between "><span className="w-[calc(100%-42px)] truncate" title={x.name}>{x.name}</span><span className="bg-[#fff] rounded-[5px] h-[20px] w-[30px] flex items-center justify-center">{x.appNum || 0}</span></div>, key:x.id})))
|
||||
@@ -200,7 +200,7 @@ useEffect(() => {
|
||||
const CardTitle = (service:ServiceHubAppListItem)=>{
|
||||
return(
|
||||
<div className="flex">
|
||||
<Avatar shape="square" size={50} className=" bg-[linear-gradient(135deg,#7F83F7,#4E54FF)] rounded-[12px]" icon={<iconpark-icon className="" name="auto-generate-api"></iconpark-icon>} />
|
||||
<Avatar shape="square" size={50} className=" bg-theme rounded-[12px]" icon={<iconpark-icon className="" name="auto-generate-api"></iconpark-icon>} />
|
||||
<div className="pl-[20px] w-[calc(100%-50px)]">
|
||||
<p className="text-[14px] h-[20px] leading-[20px] truncate">{service.name}</p>
|
||||
<div className="mt-[10px] h-[20px] flex items-center font-normal">
|
||||
|
||||
@@ -19,9 +19,9 @@ export default function SystemRunningInstruction() {
|
||||
</p> */}
|
||||
<div className="flex mt-[28px]">
|
||||
<div className="h-[208px] w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px]">
|
||||
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT">内部数据服务设置</p>
|
||||
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT">服务设置</p>
|
||||
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">支持根据权限,拆分人员对 API 添加 、上游设置、鉴权设置等信息发布及管理;同时支持管理 API 调用服务(包含第三方调用)及订阅;</p>
|
||||
<p><Link to="/service/list">添加内部数据服务信息</Link></p>
|
||||
<p><Link to="/service/list">添加服务信息</Link></p>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
|
||||
@@ -5,9 +5,9 @@ go 1.21
|
||||
//toolchain go1.21.1
|
||||
|
||||
require (
|
||||
github.com/eolinker/ap-account v1.0.6
|
||||
github.com/eolinker/ap-account v1.0.9
|
||||
github.com/eolinker/eosc v0.17.3
|
||||
github.com/eolinker/go-common v1.0.1
|
||||
github.com/eolinker/go-common v1.0.4
|
||||
github.com/gabriel-vasile/mimetype v1.4.4
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/google/uuid v1.6.0
|
||||
@@ -66,4 +66,5 @@ require (
|
||||
gorm.io/driver/mysql v1.5.2 // indirect
|
||||
)
|
||||
|
||||
//replace github.com/eolinker/ap-account v1.0.4 => ../ap-account
|
||||
//replace github.com/eolinker/ap-account => ../../eolinker/ap-account
|
||||
//replace github.com/eolinker/go-common => ../../eolinker/go-common
|
||||
|
||||
@@ -23,12 +23,12 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/eolinker/ap-account v1.0.6 h1:lzkmaItUoIguEKneUbP387qdgsUgjonKjHDnXsu6lTc=
|
||||
github.com/eolinker/ap-account v1.0.6/go.mod h1:MViCOvUaS2QrVift1Be3yGjjMywzICL9317eOxoixSI=
|
||||
github.com/eolinker/ap-account v1.0.9 h1:tW345b1wsn0V8pfMMlZOMfpbjxQhMWBVfgsClFTJGLk=
|
||||
github.com/eolinker/ap-account v1.0.9/go.mod h1:5lsZwkQfnHO5YJ3Cu6X1PZwZ0gbmJBUcix0hxG8aEsY=
|
||||
github.com/eolinker/eosc v0.17.3 h1:sr2yT+v/AsqEdciRaaZZj0zL9pTufR5RvDW6+65hraQ=
|
||||
github.com/eolinker/eosc v0.17.3/go.mod h1:xgq816hpanlMXFtZw7Ztdctb1eEk9UPHchY4NfFO6Cw=
|
||||
github.com/eolinker/go-common v1.0.1 h1:Uan6QmXAlPiX6hc1ptSIHWvaWXNA+VlBjC4gCaDEiz0=
|
||||
github.com/eolinker/go-common v1.0.1/go.mod h1:Kb/jENMN1mApnodvRgV4YwO9FJby1Jkt2EUjrBjvSX4=
|
||||
github.com/eolinker/go-common v1.0.4 h1:F0akjnzJfIFOVmK30fD0SsCLU7DAKPXuY21MeyMmQ7w=
|
||||
github.com/eolinker/go-common v1.0.4/go.mod h1:Kb/jENMN1mApnodvRgV4YwO9FJby1Jkt2EUjrBjvSX4=
|
||||
github.com/gabriel-vasile/mimetype v1.4.4 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
|
||||
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
|
||||
@@ -5,9 +5,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
SystemGroup = "system"
|
||||
TeamGroup = "team"
|
||||
ProjectGroup = "project"
|
||||
SystemGroup = "system"
|
||||
TeamGroup = "team"
|
||||
)
|
||||
|
||||
type IdentityTeamService interface {
|
||||
|
||||
@@ -51,6 +51,7 @@ func (p *PermitMiddleware) Check(method string, path string) (bool, []gin.Handle
|
||||
func(ginCtx *gin.Context) {
|
||||
userId := utils.UserId(ginCtx)
|
||||
if userId == "" {
|
||||
// 未开启游客模式
|
||||
ginCtx.AbortWithStatusJSON(http.StatusForbidden, gin.H{"code": http.StatusForbidden, "msg": "not login", "success": "fail"})
|
||||
ginCtx.Abort()
|
||||
return
|
||||
@@ -67,6 +68,7 @@ func (p *PermitMiddleware) Check(method string, path string) (bool, []gin.Handle
|
||||
// 当前分组没有配置权限
|
||||
continue
|
||||
}
|
||||
|
||||
domainHandler, has := permit.SelectDomain(group)
|
||||
if !has {
|
||||
// 当前分组没有配置身份handler
|
||||
|
||||
@@ -6,6 +6,7 @@ type Item struct {
|
||||
Id string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Children []*Item `json:"children"`
|
||||
Sort int `json:"-"`
|
||||
}
|
||||
|
||||
type ServiceItem struct {
|
||||
|
||||
@@ -347,9 +347,10 @@ func (i *imlCatalogueModule) Services(ctx context.Context, keyword string) ([]*c
|
||||
|
||||
func (i *imlCatalogueModule) recurseUpdateSort(ctx context.Context, parent string, sorts []*catalogue_dto.SortItem) error {
|
||||
for index, item := range sorts {
|
||||
s := index
|
||||
err := i.catalogueService.Save(ctx, item.Id, &catalogue.EditCatalogue{
|
||||
Parent: &parent,
|
||||
Sort: &index,
|
||||
Sort: &s,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -488,8 +489,12 @@ func treeItems(parentId string, parentMap map[string][]*catalogue.Catalogue) []*
|
||||
Id: v.Id,
|
||||
Name: v.Name,
|
||||
Children: childItems,
|
||||
Sort: v.Sort,
|
||||
})
|
||||
}
|
||||
}
|
||||
sort.Slice(items, func(i, j int) bool {
|
||||
return items[i].Sort < items[j].Sort
|
||||
})
|
||||
return items
|
||||
}
|
||||
|
||||
@@ -55,6 +55,7 @@ func NewRoot(list []*catalogue.Catalogue) *Root {
|
||||
Name: i.Name,
|
||||
Depth: 0,
|
||||
children: nil,
|
||||
sort: i.Sort,
|
||||
}
|
||||
l = append(l, g)
|
||||
m[g.Uuid] = g
|
||||
@@ -137,7 +138,7 @@ func (g Groups) Less(i, j int) bool {
|
||||
}
|
||||
return g[i].sort < g[j].sort
|
||||
}
|
||||
return g[i].Parent < g[i].Parent
|
||||
return g[i].Parent < g[j].Parent
|
||||
}
|
||||
return g[i].Depth < g[j].Depth
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ type IDynamicModuleModule interface {
|
||||
Render(ctx context.Context, module string) (map[string]interface{}, error)
|
||||
ModuleDrivers(ctx context.Context, group string) ([]*dynamic_module_dto.ModuleDriver, error)
|
||||
|
||||
Online(ctx context.Context, module string, id string, clusterInput *dynamic_module_dto.ClusterInput) error
|
||||
Offline(ctx context.Context, module string, id string, clusterInput *dynamic_module_dto.ClusterInput) error
|
||||
Online(ctx context.Context, module string, id string) error
|
||||
Offline(ctx context.Context, module string, id string) error
|
||||
//PartitionStatuses(ctx context.Context, module string, keyword string, page int, pageSize int) (map[string]map[string]string, error)
|
||||
//PartitionStatus(ctx context.Context, module string, id string) (*dynamic_module_dto.OnlineInfo, error)
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func (i *imlDynamicModule) initGateway(ctx context.Context, clusterId string, cl
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *imlDynamicModule) Online(ctx context.Context, module string, id string, clusterInput *dynamic_module_dto.ClusterInput) error {
|
||||
func (i *imlDynamicModule) Online(ctx context.Context, module string, id string) error {
|
||||
_, has := driver.Get(module)
|
||||
if !has {
|
||||
return fmt.Errorf("模块【%s】不存在", module)
|
||||
@@ -56,7 +56,7 @@ func (i *imlDynamicModule) Online(ctx context.Context, module string, id string,
|
||||
if err != nil {
|
||||
return fmt.Errorf("上线失败,配置不存在")
|
||||
}
|
||||
clusters, err := i.clusterService.List(ctx, clusterInput.Clusters...)
|
||||
clusters, err := i.clusterService.List(ctx)
|
||||
if err != nil || len(clusters) == 0 {
|
||||
return fmt.Errorf("上线失败,集群不存在")
|
||||
}
|
||||
@@ -102,28 +102,21 @@ func (i *imlDynamicModule) Online(ctx context.Context, module string, id string,
|
||||
})
|
||||
}
|
||||
|
||||
func (i *imlDynamicModule) Offline(ctx context.Context, module string, id string, clusterInput *dynamic_module_dto.ClusterInput) error {
|
||||
func (i *imlDynamicModule) Offline(ctx context.Context, module string, id string) error {
|
||||
_, has := driver.Get(module)
|
||||
if !has {
|
||||
return fmt.Errorf("模块【%s】不存在", module)
|
||||
}
|
||||
//if len(clusterInput.Clusters) == 0 {
|
||||
// return fmt.Errorf("下线分区失败,分区为空")
|
||||
//}
|
||||
|
||||
return i.transaction.Transaction(ctx, func(ctx context.Context) error {
|
||||
id = strings.ToLower(fmt.Sprintf("%s_%s", id, module))
|
||||
if len(clusterInput.Clusters) == 0 {
|
||||
clusters, err := i.clusterService.List(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clusterInput.Clusters = make([]string, 0)
|
||||
for _, c := range clusters {
|
||||
clusterInput.Clusters = append(clusterInput.Clusters, c.Uuid)
|
||||
}
|
||||
clusters, err := i.clusterService.List(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, clusterId := range clusterInput.Clusters {
|
||||
clusterIds := utils.SliceToSlice(clusters, func(s *cluster.Cluster) string {
|
||||
return s.Uuid
|
||||
})
|
||||
for _, clusterId := range clusterIds {
|
||||
err := i.dynamicClient(ctx, clusterId, module, func(dynamicClient gateway.IDynamicClient) error {
|
||||
return dynamicClient.Offline(ctx, &gateway.DynamicRelease{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
|
||||
@@ -64,14 +64,16 @@ type Member struct {
|
||||
User auto.Label `json:"user" aolabel:"user"`
|
||||
Roles []auto.Label `json:"roles" aolabel:"role"`
|
||||
AttachTime auto.TimeLabel `json:"attach_time"`
|
||||
IsDelete bool `json:"is_delete"`
|
||||
}
|
||||
|
||||
func ToMember(model *team_member.Member, roles ...string) *Member {
|
||||
|
||||
func ToMember(model *team_member.Member, userId string, roles ...string) *Member {
|
||||
|
||||
return &Member{
|
||||
User: auto.UUID(model.UID),
|
||||
Roles: auto.List(roles),
|
||||
AttachTime: auto.TimeLabel(model.CreateTime),
|
||||
IsDelete: userId != model.UID,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,21 +4,21 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
|
||||
"github.com/eolinker/ap-account/service/role"
|
||||
|
||||
|
||||
"gorm.io/gorm"
|
||||
|
||||
|
||||
department_member "github.com/eolinker/ap-account/service/department-member"
|
||||
"github.com/eolinker/go-common/auto"
|
||||
|
||||
|
||||
"github.com/eolinker/ap-account/service/user"
|
||||
|
||||
|
||||
"github.com/eolinker/go-common/store"
|
||||
|
||||
|
||||
"github.com/APIParkLab/APIPark/service/service"
|
||||
team_member "github.com/APIParkLab/APIPark/service/team-member"
|
||||
|
||||
|
||||
team_dto "github.com/APIParkLab/APIPark/module/my-team/dto"
|
||||
"github.com/APIParkLab/APIPark/service/team"
|
||||
"github.com/eolinker/go-common/utils"
|
||||
@@ -39,15 +39,54 @@ type imlTeamModule struct {
|
||||
transaction store.ITransaction `autowired:""`
|
||||
}
|
||||
|
||||
func (m *imlTeamModule) SimpleTeams(ctx context.Context, keyword string) ([]*team_dto.SimpleTeam, error) {
|
||||
teams, err := m.teamService.Search(ctx, keyword, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
projects, err := m.serviceService.Search(ctx, "", nil)
|
||||
projectCount := make(map[string]int64)
|
||||
appCount := make(map[string]int64)
|
||||
for _, p := range projects {
|
||||
if p.AsServer {
|
||||
if _, ok := projectCount[p.Team]; !ok {
|
||||
projectCount[p.Team] = 0
|
||||
}
|
||||
projectCount[p.Team]++
|
||||
}
|
||||
if p.AsApp {
|
||||
if _, ok := appCount[p.Team]; !ok {
|
||||
appCount[p.Team] = 0
|
||||
}
|
||||
appCount[p.Team]++
|
||||
}
|
||||
}
|
||||
|
||||
return utils.SliceToSlice(teams, func(s *team.Team) *team_dto.SimpleTeam {
|
||||
return &team_dto.SimpleTeam{
|
||||
Id: s.Id,
|
||||
Name: s.Name,
|
||||
Description: s.Description,
|
||||
ServiceNum: projectCount[s.Id],
|
||||
AppNum: appCount[s.Id],
|
||||
}
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (m *imlTeamModule) UpdateMemberRole(ctx context.Context, id string, input *team_dto.UpdateMemberRole) error {
|
||||
_, err := m.teamService.Get(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
supperRole, err := m.roleService.GetSupperRole(ctx, role.GroupTeam)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.transaction.Transaction(ctx, func(ctx context.Context) error {
|
||||
if len(input.Roles) < 1 {
|
||||
return errors.New("at least one role")
|
||||
}
|
||||
|
||||
err = m.roleMemberService.RemoveUserRole(ctx, role.TeamTarget(id), input.Users...)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -64,6 +103,14 @@ func (m *imlTeamModule) UpdateMemberRole(ctx context.Context, id string, input *
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count, err := m.roleMemberService.CountByRole(ctx, role.TeamTarget(id), supperRole.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count < 1 {
|
||||
return fmt.Errorf("role(%s) must have at least one member", supperRole.Name)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -73,7 +120,7 @@ func (m *imlTeamModule) GetTeam(ctx context.Context, id string) (*team_dto.Team,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
return &team_dto.Team{
|
||||
Id: tv.Id,
|
||||
Name: tv.Name,
|
||||
@@ -109,7 +156,7 @@ func (m *imlTeamModule) Search(ctx context.Context, keyword string) ([]*team_dto
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
outList := make([]*team_dto.Item, 0, len(list))
|
||||
for _, v := range list {
|
||||
outList = append(outList, team_dto.ToItem(v, serviceNumMap[v.Id], appNumMap[v.Id]))
|
||||
@@ -137,14 +184,14 @@ func (m *imlTeamModule) Edit(ctx context.Context, id string, input *team_dto.Edi
|
||||
Description: input.Description,
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return m.GetTeam(ctx, id)
|
||||
}
|
||||
|
||||
func (m *imlTeamModule) SimpleTeams(ctx context.Context, keyword string) ([]*team_dto.SimpleTeam, error) {
|
||||
func (m *imlTeamModule) MySimpleTeams(ctx context.Context, keyword string) ([]*team_dto.SimpleTeam, error) {
|
||||
userID := utils.UserId(ctx)
|
||||
memberMap, err := m.teamMemberService.FilterMembersForUser(ctx, userID)
|
||||
if err != nil {
|
||||
@@ -160,7 +207,7 @@ func (m *imlTeamModule) SimpleTeams(ctx context.Context, keyword string) ([]*tea
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
projects, err := m.serviceService.Search(ctx, "", map[string]interface{}{
|
||||
"team": teamIDs,
|
||||
})
|
||||
@@ -180,7 +227,7 @@ func (m *imlTeamModule) SimpleTeams(ctx context.Context, keyword string) ([]*tea
|
||||
appCount[p.Team]++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
outList := utils.SliceToSlice(list, func(s *team.Team) *team_dto.SimpleTeam {
|
||||
return &team_dto.SimpleTeam{
|
||||
Id: s.Id,
|
||||
@@ -215,7 +262,7 @@ func (m *imlTeamModule) AddMember(ctx context.Context, id string, uuids ...strin
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
func (m *imlTeamModule) RemoveMember(ctx context.Context, id string, uuids ...string) error {
|
||||
@@ -223,7 +270,7 @@ func (m *imlTeamModule) RemoveMember(ctx context.Context, id string, uuids ...st
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
supperRole, err := m.roleService.GetSupperRole(ctx, role.GroupTeam)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -243,12 +290,12 @@ func (m *imlTeamModule) RemoveMember(ctx context.Context, id string, uuids ...st
|
||||
supperRoleCount++
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if supperRoleCount == int(count) {
|
||||
return errors.New("can not delete all team admin")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return m.transaction.Transaction(ctx, func(ctx context.Context) error {
|
||||
err = m.roleMemberService.RemoveUserRole(ctx, role.TeamTarget(id), uuids...)
|
||||
if err != nil {
|
||||
@@ -256,7 +303,7 @@ func (m *imlTeamModule) RemoveMember(ctx context.Context, id string, uuids ...st
|
||||
}
|
||||
return m.teamMemberService.RemoveMemberFrom(ctx, id, uuids...)
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
func (m *imlTeamModule) Members(ctx context.Context, id string, keyword string) ([]*team_dto.Member, error) {
|
||||
@@ -285,12 +332,12 @@ func (m *imlTeamModule) Members(ctx context.Context, id string, keyword string)
|
||||
roleMemberMap := utils.SliceToMapArrayO(roleMembers, func(r *role.Member) (string, string) {
|
||||
return r.User, r.Role
|
||||
})
|
||||
|
||||
uId := utils.UserId(ctx)
|
||||
out := make([]*team_dto.Member, 0, len(members))
|
||||
for _, member := range members {
|
||||
out = append(out, team_dto.ToMember(member, roleMemberMap[member.UID]...))
|
||||
out = append(out, team_dto.ToMember(member, uId, roleMemberMap[member.UID]...))
|
||||
}
|
||||
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -330,20 +377,20 @@ func (m *imlTeamModule) SimpleMembers(ctx context.Context, id string, keyword st
|
||||
}
|
||||
departmentMemberMap[member.UID] = append(departmentMemberMap[member.UID], member.Come)
|
||||
}
|
||||
|
||||
|
||||
out := make([]*team_dto.SimpleMember, 0, len(teamMembers))
|
||||
for _, member := range teamMembers {
|
||||
u, ok := userMap[member.UID]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
out = append(out, &team_dto.SimpleMember{
|
||||
User: auto.UUID(u.UID),
|
||||
Mail: u.Email,
|
||||
Department: auto.List(departmentMemberMap[member.UID]),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
@@ -3,9 +3,9 @@ package my_team
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
|
||||
"github.com/eolinker/go-common/autowire"
|
||||
|
||||
|
||||
team_dto "github.com/APIParkLab/APIPark/module/my-team/dto"
|
||||
)
|
||||
|
||||
@@ -16,6 +16,8 @@ type ITeamModule interface {
|
||||
Search(ctx context.Context, keyword string) ([]*team_dto.Item, error)
|
||||
// Edit 编辑团队
|
||||
Edit(ctx context.Context, id string, input *team_dto.EditTeam) (*team_dto.Team, error)
|
||||
// MySimpleTeams 简易搜索团队
|
||||
MySimpleTeams(ctx context.Context, keyword string) ([]*team_dto.SimpleTeam, error)
|
||||
// SimpleTeams 简易搜索团队
|
||||
SimpleTeams(ctx context.Context, keyword string) ([]*team_dto.SimpleTeam, error)
|
||||
// AddMember 添加团队成员
|
||||
@@ -26,7 +28,7 @@ type ITeamModule interface {
|
||||
Members(ctx context.Context, id string, keyword string) ([]*team_dto.Member, error)
|
||||
// SimpleMembers 获取团队成员简易列表
|
||||
SimpleMembers(ctx context.Context, id string, keyword string) ([]*team_dto.SimpleMember, error)
|
||||
|
||||
|
||||
// UpdateMemberRole 更新成员角色
|
||||
UpdateMemberRole(ctx context.Context, id string, input *team_dto.UpdateMemberRole) error
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/eolinker/go-common/access"
|
||||
"reflect"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -25,10 +25,12 @@ type imlSystemPermitModule struct {
|
||||
}
|
||||
|
||||
func (m *imlSystemPermitModule) accesses(ctx context.Context) ([]string, error) {
|
||||
uid := utils.UserId(ctx)
|
||||
if uid == "" {
|
||||
return nil, errors.New("not login")
|
||||
|
||||
// 判断是否是访客,如果是,直接返回访客权限
|
||||
if utils.GuestAllow() && utils.IsGuest(ctx) {
|
||||
return access.GuestAccess(role.SystemTarget()), nil
|
||||
}
|
||||
uid := utils.UserId(ctx)
|
||||
roleMembers, err := m.roleMemberService.List(ctx, role.SystemTarget(), uid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -2,8 +2,7 @@ package team
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/eolinker/go-common/access"
|
||||
"github.com/eolinker/go-common/permit"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -25,31 +24,32 @@ type imlTeamPermitModule struct {
|
||||
|
||||
func (m *imlTeamPermitModule) Permissions(ctx context.Context, teamId string) ([]string, error) {
|
||||
|
||||
uid := utils.UserId(ctx)
|
||||
roleMembers, err := m.roleMemberService.List(ctx, role.TeamTarget(teamId), uid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
roleIds := utils.SliceToSlice(roleMembers, func(rm *role.Member) string {
|
||||
return rm.Role
|
||||
})
|
||||
if len(roleMembers) == 0 {
|
||||
return []string{}, nil
|
||||
}
|
||||
roles, err := m.roleService.List(ctx, roleIds...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
permits := make(map[string]struct{})
|
||||
for _, r := range roles {
|
||||
for _, p := range r.Permit {
|
||||
permits[p] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
return utils.MapToSlice(permits, func(k string, v struct{}) string {
|
||||
return k
|
||||
}), nil
|
||||
//uid := utils.UserId(ctx)
|
||||
//roleMembers, err := m.roleMemberService.List(ctx, role.TeamTarget(teamId), uid)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//roleIds := utils.SliceToSlice(roleMembers, func(rm *role.Member) string {
|
||||
// return rm.Role
|
||||
//})
|
||||
//if len(roleMembers) == 0 {
|
||||
// return []string{}, nil
|
||||
//}
|
||||
//roles, err := m.roleService.List(ctx, roleIds...)
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
//permits := make(map[string]struct{})
|
||||
//for _, r := range roles {
|
||||
// for _, p := range r.Permit {
|
||||
// permits[p] = struct{}{}
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//return utils.MapToSlice(permits, func(k string, v struct{}) string {
|
||||
// return k
|
||||
//}), nil
|
||||
return m.accesses(ctx, teamId)
|
||||
}
|
||||
|
||||
func (m *imlTeamPermitModule) OnComplete() {
|
||||
@@ -57,10 +57,12 @@ func (m *imlTeamPermitModule) OnComplete() {
|
||||
}
|
||||
|
||||
func (m *imlTeamPermitModule) accesses(ctx context.Context, teamId string) ([]string, error) {
|
||||
uid := utils.UserId(ctx)
|
||||
if uid == "" {
|
||||
return nil, errors.New("not login")
|
||||
|
||||
// 判断是否是访客,如果是,直接返回访客权限
|
||||
if utils.GuestAllow() && utils.IsGuest(ctx) {
|
||||
return access.GuestAccess(role.GroupTeam), nil
|
||||
}
|
||||
uid := utils.UserId(ctx)
|
||||
roleMembers, err := m.roleMemberService.List(ctx, role.TeamTarget(teamId), uid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -2,7 +2,7 @@ package subscribe_dto
|
||||
|
||||
type AddSubscriber struct {
|
||||
Application string `json:"application" aocheck:"service"`
|
||||
Applier string `json:"applier" aocheck:"user"`
|
||||
//Applier string `json:"applier" aocheck:"user"`
|
||||
//Cluster []string `json:"partition" aocheck:"partition"`
|
||||
}
|
||||
|
||||
|
||||