mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-14 20:41:15 +08:00
Compare commits
100 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0362f7784f | |||
| 1ab56708a5 | |||
| 42e8030cf7 | |||
| 17b4ede566 | |||
| bbc3fea848 | |||
| 82e46b872b | |||
| 0f6a091c73 | |||
| 4e87adb4b3 | |||
| 320a2b6cf8 | |||
| b216556867 | |||
| 7fbb98a2a9 | |||
| 461a8edbea | |||
| cdef179bed | |||
| a067388d79 | |||
| 2d5e541593 | |||
| be40186ad3 | |||
| c9ae05b22e | |||
| 9da5e5d6c0 | |||
| a6bfce2a5f | |||
| 8cbeabe917 | |||
| 1db354077f | |||
| e31d41a276 | |||
| 21d2abf716 | |||
| 3a86a88870 | |||
| 6117a840e1 | |||
| 0e20987fb8 | |||
| 65e7cab772 | |||
| 935f2ac766 | |||
| 3e12d7eb9c | |||
| d6095269b7 | |||
| 0c415b4e32 | |||
| bc1819b368 | |||
| a9be016c87 | |||
| 11da5e9d26 | |||
| 2c6c194821 | |||
| aedd8b4cc6 | |||
| fa2607e9b8 | |||
| 3783e5ee5d | |||
| fd56b8ffed | |||
| 07e288be16 | |||
| 46143c3fe0 | |||
| 83e3cc85f2 | |||
| a4b50ae60a | |||
| a30d0c37eb | |||
| 64fdf59905 | |||
| 68e8cb72d3 | |||
| a86d3cd65a | |||
| a4b4cbf60f | |||
| 2dcb7ebd74 | |||
| 8fa1985feb | |||
| 451efb8d3e | |||
| d6bf3139ff | |||
| 309b9ea937 | |||
| 554bff38c6 | |||
| d5e6062ec9 | |||
| d588d43aa1 | |||
| f455cecb54 | |||
| b88c0a9305 | |||
| 9030cff8ba | |||
| 98f73f799a | |||
| d2e428ada8 | |||
| 74156ec84c | |||
| f9e6bc92d7 | |||
| 9884586cc9 | |||
| ac717a6efb | |||
| 2b7c1ded15 | |||
| daac27712d | |||
| 1080f33282 | |||
| cc5c0a0a89 | |||
| 85971447e1 | |||
| 256e8ef275 | |||
| c07e54ec03 | |||
| 70f834e1cf | |||
| c320c6f2a2 | |||
| 256eb60df8 | |||
| 5f03973bf2 | |||
| ab2a0d8ae2 | |||
| 7e48402591 | |||
| aa85f6fcd1 | |||
| cd441ccfe7 | |||
| 47f6519006 | |||
| 9679376cb2 | |||
| efa97c3bbc | |||
| 087e598be0 | |||
| 31aa8243ee | |||
| d3d05ef539 | |||
| d6062ea4e7 | |||
| 7949748951 | |||
| 94f7392060 | |||
| 0d737bad57 | |||
| 1225db50c9 | |||
| e5d85bb3df | |||
| 0f09e5c236 | |||
| 0f0204b647 | |||
| 94421d2622 | |||
| 44f0b70461 | |||
| f58768237b | |||
| 588cf839e3 | |||
| aa40b62e0a | |||
| b0b9affbe7 |
+1
-1
@@ -3,4 +3,4 @@
|
|||||||
/config.yml
|
/config.yml
|
||||||
/build/
|
/build/
|
||||||
/apipark
|
/apipark
|
||||||
/aoplatform
|
.gitlab-ci.yml
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
variables:
|
|
||||||
PATH: /opt/go-1.21/go/bin/:/opt/node/node/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
|
|
||||||
GOROOT: /opt/go-1.21/go
|
|
||||||
GOPROXY: https://goproxy.cn
|
|
||||||
VERSION: $CI_COMMIT_SHORT_SHA
|
|
||||||
APP: apipark
|
|
||||||
APP_PRE: ${APP}_${VERSION}
|
|
||||||
BUILD_DIR: ${APP}-build
|
|
||||||
DEPLOY_DESC: "DEV 环境"
|
|
||||||
VIEW_ADDR: http://172.18.166.219:8288
|
|
||||||
SAVE_DIR: /opt/${APP}
|
|
||||||
NODE_OPTIONS: --max_old_space_size=8192
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- notice
|
|
||||||
- prefix
|
|
||||||
- build
|
|
||||||
- deploy
|
|
||||||
- webhook
|
|
||||||
|
|
||||||
feishu-informer: # 飞书回调
|
|
||||||
stage: notice
|
|
||||||
variables:
|
|
||||||
DIFF_URL: "$CI_MERGE_REQUEST_PROJECT_URL/-/merge_requests/$CI_MERGE_REQUEST_IID/diffs"
|
|
||||||
rules:
|
|
||||||
- if: $CI_PIPELINE_SOURCE=="merge_request_event" && $CI_COMMIT_BRANCH =~ "main"
|
|
||||||
script:
|
|
||||||
- echo "merge request"
|
|
||||||
- |
|
|
||||||
curl -X POST -H "Content-Type: application/json" \
|
|
||||||
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"项目:${CI_PROJECT_NAME}\\n提交人:${GITLAB_USER_NAME}\\n提交信息:${CI_MERGE_REQUEST_TITLE}\\n合并分支信息:${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME} -> ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}\\n差异性地址:${DIFF_URL}\\n请及时review代码\"}}" \
|
|
||||||
https://open.feishu.cn/open-apis/bot/v2/hook/1c334752-2874-41a1-8f1b-3060f2d46b6c
|
|
||||||
|
|
||||||
prebuild:
|
|
||||||
stage: prefix
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_BRANCH == "main"
|
|
||||||
script:
|
|
||||||
- echo "prebuild"
|
|
||||||
- chmod +x ./scripts/prefix.sh
|
|
||||||
- ./scripts/prefix.sh
|
|
||||||
|
|
||||||
builder:
|
|
||||||
stage: build
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_BRANCH == "main"
|
|
||||||
script:
|
|
||||||
- set -e
|
|
||||||
- |
|
|
||||||
if [ ! -d "../artifacts" ]; then
|
|
||||||
mkdir -p ../artifacts
|
|
||||||
fi
|
|
||||||
if [ -d "../artifacts/dist" ]; then
|
|
||||||
cp -r ../artifacts/dist frontend/dist
|
|
||||||
fi
|
|
||||||
- |
|
|
||||||
if [ -n "$(git diff --name-status HEAD~1 HEAD -- frontend)" ]; then
|
|
||||||
./scripts/build.sh $BUILD_DIR ${VERSION} all ""
|
|
||||||
else
|
|
||||||
./scripts/build.sh $BUILD_DIR ${VERSION}
|
|
||||||
fi
|
|
||||||
if [ -d "frontend/dist" ]; then
|
|
||||||
echo "copy frontend/dist to artifacts/dist"
|
|
||||||
rm -fr ../artifacts/dist
|
|
||||||
cp -r frontend/dist ../artifacts/dist
|
|
||||||
fi
|
|
||||||
cp $BUILD_DIR/${APP_PRE}_linux_amd64.tar.gz ${SAVE_DIR}
|
|
||||||
|
|
||||||
deployer:
|
|
||||||
stage: deploy
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_BRANCH == "main"
|
|
||||||
variables:
|
|
||||||
APIPARK_GUEST_MODE: allow
|
|
||||||
APIPARK_GUEST_ID: dklejrfbhjqwdh
|
|
||||||
script:
|
|
||||||
- cd ${SAVE_DIR};mkdir -p ${APP_PRE};tar -zxvf ${APP_PRE}_linux_amd64.tar.gz -C ${APP_PRE};cd ${APP_PRE};./install.sh ${SAVE_DIR};./run.sh restart;cd ${SAVE_DIR} && ./clean.sh ${APP_PRE}
|
|
||||||
when: on_success
|
|
||||||
success:
|
|
||||||
stage: webhook
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_BRANCH == "main"
|
|
||||||
script:
|
|
||||||
- |
|
|
||||||
curl -X POST -H "Content-Type: application/json" \
|
|
||||||
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"最近一次提交:${CI_COMMIT_TITLE}\\n提交人:${GITLAB_USER_NAME}\\n项目:${CI_PROJECT_NAME}\\n环境:${DEPLOY_DESC}\\n更新部署完成.\\n访问地址:${VIEW_ADDR}\\n工作流地址:${CI_PIPELINE_URL}\"}}" \
|
|
||||||
https://open.feishu.cn/open-apis/bot/v2/hook/c3672932-4dfa-4989-8023-0128bae59338
|
|
||||||
when: on_success
|
|
||||||
failure:
|
|
||||||
stage: webhook
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_BRANCH == "main"
|
|
||||||
script:
|
|
||||||
- |
|
|
||||||
curl -X POST -H "Content-Type: application/json" \
|
|
||||||
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"最近一次提交:${CI_COMMIT_TITLE}\\n提交人:${GITLAB_USER_NAME}\\n项目:${CI_PROJECT_NAME}\\n环境:${DEPLOY_DESC}\\n更新部署失败,请及时到gitlab上查看\\n工作流地址:${CI_PIPELINE_URL}\"}}" \
|
|
||||||
https://open.feishu.cn/open-apis/bot/v2/hook/c3672932-4dfa-4989-8023-0128bae59338
|
|
||||||
when: on_failure
|
|
||||||
@@ -197,7 +197,7 @@ To achieve this goal, we plan to add new features to APIPark, including:
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
# 📕 Documentation
|
# 📕 Documentation
|
||||||
Visit [APIPark Documentation](https://docs.apipark.com/docs/install) for detailed installation guides, API references, and usage instructions.
|
Visit [APIPark Documentation](https://docs.apipark.com/docs/deploy) for detailed installation guides, API references, and usage instructions.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/eolinker/eosc/log"
|
||||||
|
|
||||||
application_authorization "github.com/APIParkLab/APIPark/module/application-authorization"
|
application_authorization "github.com/APIParkLab/APIPark/module/application-authorization"
|
||||||
application_authorization_dto "github.com/APIParkLab/APIPark/module/application-authorization/dto"
|
application_authorization_dto "github.com/APIParkLab/APIPark/module/application-authorization/dto"
|
||||||
@@ -212,10 +215,7 @@ func (i *imlServiceController) createAIService(ctx *gin.Context, teamID string,
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
//_, err = i.upstreamModule.Save(ctx, info.Id, newAIUpstream(info.Id, *input.Provider, p.URI()))
|
|
||||||
//if err != nil {
|
|
||||||
// return err
|
|
||||||
//}
|
|
||||||
return i.docModule.SaveServiceDoc(ctx, info.Id, &service_dto.SaveServiceDoc{
|
return i.docModule.SaveServiceDoc(ctx, info.Id, &service_dto.SaveServiceDoc{
|
||||||
Doc: "The Translation API allows developers to translate text from one language to another. It supports multiple languages and enables easy integration of high-quality translation features into applications. With simple API requests, you can quickly translate content into different target languages.",
|
Doc: "The Translation API allows developers to translate text from one language to another. It supports multiple languages and enables easy integration of high-quality translation features into applications. With simple API requests, you can quickly translate content into different target languages.",
|
||||||
})
|
})
|
||||||
@@ -237,7 +237,12 @@ func (i *imlServiceController) SearchMyServices(ctx *gin.Context, teamId string,
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
func (i *imlServiceController) Get(ctx *gin.Context, id string) (*service_dto.Service, error) {
|
func (i *imlServiceController) Get(ctx *gin.Context, id string) (*service_dto.Service, error) {
|
||||||
|
now := time.Now()
|
||||||
|
defer func() {
|
||||||
|
log.Infof("get service %s cost %d ms", id, time.Since(now).Milliseconds())
|
||||||
|
}()
|
||||||
return i.module.Get(ctx, id)
|
return i.module.Get(ctx, id)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imlServiceController) Search(ctx *gin.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) {
|
func (i *imlServiceController) Search(ctx *gin.Context, teamID string, keyword string) ([]*service_dto.ServiceItem, error) {
|
||||||
@@ -279,6 +284,10 @@ type imlAppController struct {
|
|||||||
authModule application_authorization.IAuthorizationModule `autowired:""`
|
authModule application_authorization.IAuthorizationModule `autowired:""`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *imlAppController) SearchCanSubscribe(ctx *gin.Context, serviceId string) ([]*service_dto.SimpleAppItem, error) {
|
||||||
|
return i.module.SearchCanSubscribe(ctx, serviceId)
|
||||||
|
}
|
||||||
|
|
||||||
func (i *imlAppController) Search(ctx *gin.Context, teamId string, keyword string) ([]*service_dto.AppItem, error) {
|
func (i *imlAppController) Search(ctx *gin.Context, teamId string, keyword string) ([]*service_dto.AppItem, error) {
|
||||||
return i.module.Search(ctx, teamId, keyword)
|
return i.module.Search(ctx, teamId, keyword)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ type IAppController interface {
|
|||||||
// SimpleApps 获取简易项目列表
|
// SimpleApps 获取简易项目列表
|
||||||
SimpleApps(ctx *gin.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
|
SimpleApps(ctx *gin.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
|
||||||
MySimpleApps(ctx *gin.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
|
MySimpleApps(ctx *gin.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
|
||||||
|
SearchCanSubscribe(ctx *gin.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
|
||||||
GetApp(ctx *gin.Context, appId string) (*service_dto.App, error)
|
GetApp(ctx *gin.Context, appId string) (*service_dto.App, error)
|
||||||
DeleteApp(ctx *gin.Context, appId string) error
|
DeleteApp(ctx *gin.Context, appId string) error
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/frontend/favicon.ico" />
|
<link rel="icon" type="image/svg+xml" href="/frontend/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>APIPark</title>
|
<title>2APIPark</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import {
|
import {
|
||||||
MenuProps,
|
MenuProps,
|
||||||
App,
|
App,
|
||||||
Button,
|
Button,
|
||||||
ConfigProvider,
|
ConfigProvider,
|
||||||
Dropdown} from 'antd';
|
Dropdown
|
||||||
import { Outlet, useLocation, useNavigate} from "react-router-dom";
|
} from 'antd';
|
||||||
|
import { Outlet, useLocation, useNavigate } from "react-router-dom";
|
||||||
import Logo from '@common/assets/layout-logo.png';
|
import Logo from '@common/assets/layout-logo.png';
|
||||||
import AvatarPic from '@common/assets/default-avatar.png'
|
import AvatarPic from '@common/assets/default-avatar.png'
|
||||||
import { useEffect, useMemo, useState} from "react";
|
import { useEffect, useMemo, useState } from "react";
|
||||||
import { useGlobalContext } from '@common/contexts/GlobalStateContext.tsx';
|
import { useGlobalContext } from '@common/contexts/GlobalStateContext.tsx';
|
||||||
import { PERMISSION_DEFINITION } from '@common/const/permissions.ts';
|
import { PERMISSION_DEFINITION } from '@common/const/permissions.ts';
|
||||||
import { BasicResponse, RESPONSE_TIPS, routerKeyMap, STATUS_CODE } from '@common/const/const.tsx';
|
import { BasicResponse, RESPONSE_TIPS, routerKeyMap, STATUS_CODE } from '@common/const/const.tsx';
|
||||||
@@ -24,262 +25,263 @@ const APP_MODE = import.meta.env.VITE_APP_MODE;
|
|||||||
export type MenuItem = Required<MenuProps>['items'][number];
|
export type MenuItem = Required<MenuProps>['items'][number];
|
||||||
|
|
||||||
const themeToken = {
|
const themeToken = {
|
||||||
bgLayout:'#17163E;',
|
bgLayout: '#17163E;',
|
||||||
header: {
|
header: {
|
||||||
heightLayoutHeader:72
|
heightLayoutHeader: 72
|
||||||
},
|
},
|
||||||
pageContainer:{
|
pageContainer: {
|
||||||
paddingBlockPageContainerContent:0,
|
paddingBlockPageContainerContent: 0,
|
||||||
paddingInlinePageContainerContent:0,
|
paddingInlinePageContainerContent: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function BasicLayout({project = 'core'}:{project:string}){
|
|
||||||
const navigator = useNavigate()
|
|
||||||
const location = useLocation()
|
|
||||||
const currentUrl = location.pathname
|
|
||||||
const { state,accessData,checkPermission,accessInit,dispatch,resetAccess,getGlobalAccessData} = useGlobalContext()
|
|
||||||
const [pathname, setPathname] = useState(currentUrl); const mainPage = project === 'core' ?'/service/list':'/serviceHub/list'
|
|
||||||
|
|
||||||
const TOTAL_MENU_ITEMS:MenuProps['items'] = useMemo(() => [
|
function BasicLayout({ project = 'core' }: { project: string }) {
|
||||||
getNavItem($t('工作空间'), 'workspace','/guide/page',<Icon icon="ic:baseline-space-dashboard" width="18" height="18"/>, [
|
const navigator = useNavigate()
|
||||||
getNavItem(<a>{$t('首页')}</a>, 'guide','/guide/page',<Icon icon="ic:baseline-home" width="18" height="18"/>,undefined,undefined,'all'),
|
const location = useLocation()
|
||||||
getNavItem(<a>{$t('服务')}</a>, 'service','/service',<Icon icon="ic:baseline-blinds-closed" width="18" height="18"/>,undefined,undefined,'all'),
|
const currentUrl = location.pathname
|
||||||
getNavItem(<a>{$t('消费者')}</a>, 'consumer','/consumer',<Icon icon="ic:baseline-apps" width="18" height="18"/>,undefined,undefined,'all'),
|
const { state, accessData, checkPermission, accessInit, dispatch, resetAccess, getGlobalAccessData } = useGlobalContext()
|
||||||
getNavItem(<a>{$t('团队')}</a>, 'team','/team',<Icon icon="ic:baseline-people-alt" width="18" height="18"/>,undefined,undefined,'all'),
|
const [pathname, setPathname] = useState(currentUrl); const mainPage = project === 'core' ? '/service/list' : '/serviceHub/list'
|
||||||
|
|
||||||
|
const TOTAL_MENU_ITEMS: MenuProps['items'] = useMemo(() => [
|
||||||
|
getNavItem($t('工作空间'), 'workspace', '/guide/page', <Icon icon="ic:baseline-space-dashboard" width="18" height="18" />, [
|
||||||
|
getNavItem(<a>{$t('首页')}</a>, 'guide', '/guide/page', <Icon icon="ic:baseline-home" width="18" height="18" />, undefined, undefined, 'all'),
|
||||||
|
getNavItem(<a>{$t('服务')}</a>, 'service', '/service', <Icon icon="ic:baseline-blinds-closed" width="18" height="18" />, undefined, undefined, 'all'),
|
||||||
|
getNavItem(<a>{$t('消费者')}</a>, 'consumer', '/consumer', <Icon icon="ic:baseline-apps" width="18" height="18" />, undefined, undefined, 'all'),
|
||||||
|
getNavItem(<a>{$t('团队')}</a>, 'team', '/team', <Icon icon="ic:baseline-people-alt" width="18" height="18" />, undefined, undefined, 'all'),
|
||||||
]),
|
]),
|
||||||
getNavItem($t('API 市场'), 'serviceHub','/serviceHub',<Icon icon="ic:baseline-hub" width="18" height="18"/>,undefined,undefined,'system.api_portal.api_portal.view'),
|
getNavItem($t('API 市场'), 'serviceHub', '/serviceHub', <Icon icon="ic:baseline-hub" width="18" height="18" />, undefined, undefined, 'system.api_portal.api_portal.view'),
|
||||||
|
|
||||||
getNavItem($t('仪表盘'), 'mainPage', APP_MODE === 'pro' ? '/analytics' : '/analytics/total',<Icon icon="ic:baseline-bar-chart" width="18" height="18"/>,[
|
getNavItem($t('仪表盘'), 'mainPage', APP_MODE === 'pro' ? '/analytics' : '/analytics/total', <Icon icon="ic:baseline-bar-chart" width="18" height="18" />, [
|
||||||
getNavItem(<a >{$t('运行视图')}</a>, 'analytics',APP_MODE === 'pro' ? '/analytics' : '/analytics/total' ,<ProjectFilled />,undefined,undefined,'system.analysis.run_view.view'),
|
getNavItem(<a >{$t('运行视图')}</a>, 'analytics', APP_MODE === 'pro' ? '/analytics' : '/analytics/total', <ProjectFilled />, undefined, undefined, 'system.analysis.run_view.view'),
|
||||||
APP_MODE === 'pro' ? getNavItem(<a >{$t('系统拓扑图')}</a>, 'systemrunning','/systemrunning',<ProjectFilled />,undefined,undefined,'system.dashboard.systemrunning.view') : null,
|
APP_MODE === 'pro' ? getNavItem(<a >{$t('系统拓扑图')}</a>, 'systemrunning', '/systemrunning', <ProjectFilled />, undefined, undefined, 'system.dashboard.systemrunning.view') : null,
|
||||||
],undefined,'system.analysis.run_view.view'),
|
], undefined, 'system.analysis.run_view.view'),
|
||||||
|
|
||||||
getNavItem($t('系统设置'), 'operationCenter','/commonsetting',<Icon icon="ic:baseline-settings" width="18" height="18"/>, [
|
getNavItem($t('系统设置'), 'operationCenter', '/commonsetting', <Icon icon="ic:baseline-settings" width="18" height="18" />, [
|
||||||
getNavItem($t('系统'), 'serviceHubSetting','/commonsetting',null,[
|
getNavItem($t('系统'), 'serviceHubSetting', '/commonsetting', null, [
|
||||||
getNavItem(<a>{$t('常规')}</a>, 'commonsetting','/commonsetting',<Icon icon="ic:baseline-hub" width="18" height="18"/>,undefined,undefined,'system.api_market.service_classification.view'),
|
getNavItem(<a>{$t('常规')}</a>, 'commonsetting', '/commonsetting', <Icon icon="ic:baseline-hub" width="18" height="18" />, undefined, undefined, 'system.api_market.service_classification.view'),
|
||||||
getNavItem(<a>{$t('API 网关')}</a>, 'cluster','/cluster',<Icon icon="ic:baseline-device-hub" width="18" height="18"/>,undefined,undefined,'system.settings.api_gateway.view'),
|
getNavItem(<a>{$t('API 网关')}</a>, 'cluster', '/cluster', <Icon icon="ic:baseline-device-hub" width="18" height="18" />, undefined, undefined, 'system.settings.api_gateway.view'),
|
||||||
getNavItem(<a>{$t('AI 模型')}</a>, 'aisetting','/aisetting',<Icon icon="hugeicons:ai-network" width="18" height="18"/>,undefined,undefined,'system.settings.api_gateway.view'),
|
getNavItem(<a>{$t('AI 模型')}</a>, 'aisetting', '/aisetting', <Icon icon="hugeicons:ai-network" width="18" height="18" />, undefined, undefined, 'system.settings.api_gateway.view'),
|
||||||
],undefined,'system.api_market.service_classification.view'),
|
], undefined, 'system.api_market.service_classification.view'),
|
||||||
getNavItem($t('用户'), 'organization','/member',null,[
|
getNavItem($t('用户'), 'organization', '/member', null, [
|
||||||
getNavItem(<a>{$t('账号')}</a>, 'member','/member',<Icon icon="ic:baseline-people-alt" width="18" height="18"/>,undefined,undefined,'system.settings.account.view'),
|
getNavItem(<a>{$t('账号')}</a>, 'member', '/member', <Icon icon="ic:baseline-people-alt" width="18" height="18" />, undefined, undefined, 'system.settings.account.view'),
|
||||||
getNavItem(<a>{$t('角色')}</a>, 'role','/role',<Icon icon="ic:baseline-verified-user" width="18" height="18"/>,undefined,undefined,'system.organization.role.view'),
|
getNavItem(<a>{$t('角色')}</a>, 'role', '/role', <Icon icon="ic:baseline-verified-user" width="18" height="18" />, undefined, undefined, 'system.organization.role.view'),
|
||||||
],undefined,''),
|
], undefined, ''),
|
||||||
getNavItem($t('集成'), 'maintenanceCenter','/datasourcing', null, [
|
getNavItem($t('集成'), 'maintenanceCenter', '/datasourcing', null, [
|
||||||
getNavItem(<a>{$t('数据源')}</a>, 'datasourcing','/datasourcing',<Icon icon="ic:baseline-monitor-heart" width="18" height="18"/>,undefined,undefined,'system.settings.data_source.view'),
|
getNavItem(<a>{$t('数据源')}</a>, 'datasourcing', '/datasourcing', <Icon icon="ic:baseline-monitor-heart" width="18" height="18" />, undefined, undefined, 'system.settings.data_source.view'),
|
||||||
getNavItem(<a>{$t('证书')}</a>, 'cert','/cert',<Icon icon="ic:baseline-security" width="18" height="18"/>,undefined,undefined,'system.settings.ssl_certificate.view'),
|
getNavItem(<a>{$t('全局策略')}</a>, 'globalPolicy', '/globalPolicy', <Icon icon="uil:comment-shield" width="18" height="18" />, undefined, undefined, 'system.settings.data_source.view'),
|
||||||
getNavItem(<a>{$t('日志')}</a>, 'logsettings','/logsettings',<Icon icon="ic:baseline-sticky-note-2" width="18" height="18"/>,undefined,undefined,'system.settings.log_configuration.view'),
|
getNavItem(<a>{$t('证书')}</a>, 'cert', '/cert', <Icon icon="ic:baseline-security" width="18" height="18" />, undefined, undefined, 'system.settings.ssl_certificate.view'),
|
||||||
APP_MODE === 'pro' ? getNavItem(<a>{$t('资源')}</a>, 'resourcesettings','/resourcesettings',null,undefined,undefined,'system.partition.self.view'):null,
|
getNavItem(<a>{$t('日志')}</a>, 'logsettings', '/logsettings', <Icon icon="ic:baseline-sticky-note-2" width="18" height="18" />, undefined, undefined, 'system.settings.log_configuration.view'),
|
||||||
APP_MODE === 'pro' ? getNavItem(<a>{$t('Open API')}</a>, 'openapi','/openapi',null,undefined,undefined,'system.openapi.self.view'):null,
|
APP_MODE === 'pro' ? getNavItem(<a>{$t('资源')}</a>, 'resourcesettings', '/resourcesettings', null, undefined, undefined, 'system.partition.self.view') : null,
|
||||||
|
APP_MODE === 'pro' ? getNavItem(<a>{$t('Open API')}</a>, 'openapi', '/openapi', null, undefined, undefined, 'system.openapi.self.view') : null,
|
||||||
]),
|
]),
|
||||||
]),
|
]),
|
||||||
],[state.language,accessInit])
|
], [state.language, accessInit])
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(currentUrl === '/'){
|
if (currentUrl === '/') {
|
||||||
navigator(mainPage)
|
navigator(mainPage)
|
||||||
}
|
|
||||||
|
|
||||||
}, [currentUrl]);
|
|
||||||
|
|
||||||
const headerMenuData = useMemo(() => {
|
|
||||||
// 判断权限
|
|
||||||
const hasAccess = (access: unknown) => checkPermission(access as keyof typeof PERMISSION_DEFINITION[0]);
|
|
||||||
|
|
||||||
// 过滤菜单项
|
|
||||||
const filterMenu = (menu: Array<{ [k: string]: unknown }>) => {
|
|
||||||
return [...menu]
|
|
||||||
.filter(x => x) // 过滤掉空数据
|
|
||||||
.map((item: any) => {
|
|
||||||
if (item.routes && item.routes.length > 0) {
|
|
||||||
// 递归处理子菜单
|
|
||||||
const filteredRoutes: Array<{ [k: string]: unknown }> = filterMenu(item.routes);
|
|
||||||
|
|
||||||
if(filteredRoutes.length === 0){
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return {...item, routes: filteredRoutes};
|
|
||||||
}
|
|
||||||
// 处理没有 routes 的菜单项
|
|
||||||
if (item.access) {
|
|
||||||
return (item.access === 'all' || hasAccess(item.access)) ? item : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果没有 access 和 routes,则保留
|
|
||||||
return item;
|
|
||||||
})
|
|
||||||
.filter(x => x); // 过滤掉处理后为 null 的项
|
|
||||||
};
|
|
||||||
|
|
||||||
// 初始过滤操作
|
|
||||||
const res = [...TOTAL_MENU_ITEMS]!.filter(x => x).map((x: any) => (x.routes ? { ...x, routes: filterMenu(x.routes) } : x));
|
|
||||||
// 返回处理后的数据
|
|
||||||
return { path: '/', routes: res.map(x=> ({...x, routes: x.routes?.filter(x=> (x.access || x.routes?.length > 0))})).filter(x=> (x.access || x.routes?.length > 0)) };
|
|
||||||
}, [accessData, state.language]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const { message } = App.useApp()
|
|
||||||
const [userInfo,setUserInfo] = useState<UserInfoType>()
|
|
||||||
const {fetchData} = useFetch()
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
const getUserInfo = ()=>{
|
|
||||||
fetchData<BasicResponse<{profile:UserInfoType}>>('account/profile',{method:'GET'})
|
|
||||||
.then(response=>{
|
|
||||||
const {code,data,msg} = response
|
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
|
||||||
setUserInfo(data.profile)
|
|
||||||
dispatch({type:'UPDATE_USERDATA',userData:data.profile})
|
|
||||||
}else{
|
|
||||||
message.error(msg || $t(RESPONSE_TIPS.error))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
}, [currentUrl]);
|
||||||
getUserInfo()
|
|
||||||
getGlobalAccessData()
|
const headerMenuData = useMemo(() => {
|
||||||
}, []);
|
// 判断权限
|
||||||
|
const hasAccess = (access: unknown) => checkPermission(access as keyof typeof PERMISSION_DEFINITION[0]);
|
||||||
const logOut = ()=>{
|
|
||||||
fetchData<BasicResponse<null>>('account/logout',{method:'GET'}).then(response=>{
|
// 过滤菜单项
|
||||||
const {code,msg} = response
|
const filterMenu = (menu: Array<{ [k: string]: unknown }>) => {
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
return [...menu]
|
||||||
dispatch({type:'LOGOUT'})
|
.filter(x => x) // 过滤掉空数据
|
||||||
resetAccess()
|
.map((item: any) => {
|
||||||
// message.success(msg || $t(RESPONSE_TIPS.logoutSuccess))
|
if (item.routes && item.routes.length > 0) {
|
||||||
navigate('/login')
|
// 递归处理子菜单
|
||||||
}else{
|
const filteredRoutes: Array<{ [k: string]: unknown }> = filterMenu(item.routes);
|
||||||
message.error(msg ||$t(RESPONSE_TIPS.error))
|
|
||||||
|
if (filteredRoutes.length === 0) {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
return { ...item, routes: filteredRoutes };
|
||||||
|
}
|
||||||
|
// 处理没有 routes 的菜单项
|
||||||
|
if (item.access) {
|
||||||
|
return (item.access === 'all' || hasAccess(item.access)) ? item : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有 access 和 routes,则保留
|
||||||
|
return item;
|
||||||
})
|
})
|
||||||
}
|
.filter(x => x); // 过滤掉处理后为 null 的项
|
||||||
|
};
|
||||||
|
|
||||||
const items: MenuProps['items'] = useMemo(() => [
|
// 初始过滤操作
|
||||||
userInfo?.type !== 'guest' && {
|
const res = [...TOTAL_MENU_ITEMS]!.filter(x => x).map((x: any) => (x.routes ? { ...x, routes: filterMenu(x.routes) } : x));
|
||||||
key: '2',
|
// 返回处理后的数据
|
||||||
label: (
|
return { path: '/', routes: res.map(x => ({ ...x, routes: x.routes?.filter(x => (x.access || x.routes?.length > 0)) })).filter(x => (x.access || x.routes?.length > 0)) };
|
||||||
<Button key="changePsw" type="text" className="flex items-center p-0 bg-transparent border-none " onClick={()=>navigator('/userProfile/changepsw')}>
|
}, [accessData, state.language]);
|
||||||
{$t('账号设置')}
|
|
||||||
</Button>)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '3',
|
|
||||||
label: (
|
|
||||||
<Button key="logout" type="text" className="flex items-center p-0 bg-transparent border-none " onClick={logOut}>
|
|
||||||
{$t('退出登录')}
|
|
||||||
</Button>)
|
|
||||||
},
|
|
||||||
].filter(Boolean), [userInfo]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return(
|
|
||||||
<div
|
const { message } = App.useApp()
|
||||||
id="test-pro-layout"
|
const [userInfo, setUserInfo] = useState<UserInfoType>()
|
||||||
style={{
|
const { fetchData } = useFetch()
|
||||||
height: '100vh',
|
const navigate = useNavigate();
|
||||||
overflow: 'auto',
|
|
||||||
}}
|
const getUserInfo = () => {
|
||||||
|
fetchData<BasicResponse<{ profile: UserInfoType }>>('account/profile', { method: 'GET' })
|
||||||
|
.then(response => {
|
||||||
|
const { code, data, msg } = response
|
||||||
|
if (code === STATUS_CODE.SUCCESS) {
|
||||||
|
setUserInfo(data.profile)
|
||||||
|
dispatch({ type: 'UPDATE_USERDATA', userData: data.profile })
|
||||||
|
} else {
|
||||||
|
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getUserInfo()
|
||||||
|
getGlobalAccessData()
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const logOut = () => {
|
||||||
|
fetchData<BasicResponse<null>>('account/logout', { method: 'GET' }).then(response => {
|
||||||
|
const { code, msg } = response
|
||||||
|
if (code === STATUS_CODE.SUCCESS) {
|
||||||
|
dispatch({ type: 'LOGOUT' })
|
||||||
|
resetAccess()
|
||||||
|
// message.success(msg || $t(RESPONSE_TIPS.logoutSuccess))
|
||||||
|
navigate('/login')
|
||||||
|
} else {
|
||||||
|
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const items: MenuProps['items'] = useMemo(() => [
|
||||||
|
userInfo?.type !== 'guest' && {
|
||||||
|
key: '2',
|
||||||
|
label: (
|
||||||
|
<Button key="changePsw" type="text" className="flex items-center p-0 bg-transparent border-none " onClick={() => navigator('/userProfile/changepsw')}>
|
||||||
|
{$t('账号设置')}
|
||||||
|
</Button>)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: '3',
|
||||||
|
label: (
|
||||||
|
<Button key="logout" type="text" className="flex items-center p-0 bg-transparent border-none " onClick={logOut}>
|
||||||
|
{$t('退出登录')}
|
||||||
|
</Button>)
|
||||||
|
},
|
||||||
|
].filter(Boolean), [userInfo]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
id="test-pro-layout"
|
||||||
|
style={{
|
||||||
|
height: '100vh',
|
||||||
|
overflow: 'auto',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ProConfigProvider hashed={false}>
|
||||||
|
<ConfigProvider
|
||||||
|
getTargetContainer={() => {
|
||||||
|
return document.getElementById('test-pro-layout') || document.body;
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<ProConfigProvider hashed={false}>
|
<ProLayout
|
||||||
<ConfigProvider
|
prefixCls="apipark-layout"
|
||||||
getTargetContainer={() => {
|
location={{
|
||||||
return document.getElementById('test-pro-layout') || document.body;
|
pathname,
|
||||||
|
}}
|
||||||
|
siderWidth={220}
|
||||||
|
breakpoint={'lg'}
|
||||||
|
route={headerMenuData}
|
||||||
|
token={themeToken}
|
||||||
|
siderMenuType="group"
|
||||||
|
menu={{
|
||||||
|
type: 'group',
|
||||||
|
collapsedShowGroupTitle: true,
|
||||||
|
}}
|
||||||
|
disableMobile={true}
|
||||||
|
avatarProps={{
|
||||||
|
src: AvatarPic || userInfo?.avatar,
|
||||||
|
size: 'small',
|
||||||
|
title: userInfo?.username || 'unknown',
|
||||||
|
render: (props, dom) => {
|
||||||
|
return (
|
||||||
|
<Dropdown
|
||||||
|
menu={{
|
||||||
|
items
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ProLayout
|
<div className='avatar-dom'>{dom}
|
||||||
prefixCls="apipark-layout"
|
|
||||||
location={{
|
|
||||||
pathname,
|
|
||||||
}}
|
|
||||||
siderWidth={220}
|
|
||||||
breakpoint={'lg'}
|
|
||||||
route={headerMenuData}
|
|
||||||
token={themeToken}
|
|
||||||
siderMenuType="group"
|
|
||||||
menu={{
|
|
||||||
type: 'group',
|
|
||||||
collapsedShowGroupTitle: true,
|
|
||||||
}}
|
|
||||||
disableMobile={true}
|
|
||||||
avatarProps={{
|
|
||||||
src: AvatarPic || userInfo?.avatar,
|
|
||||||
size: 'small',
|
|
||||||
title: userInfo?.username||'unknown',
|
|
||||||
render: (props, dom) => {
|
|
||||||
return (
|
|
||||||
<Dropdown
|
|
||||||
menu={{
|
|
||||||
items
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className='avatar-dom'>{dom}
|
|
||||||
</div>
|
|
||||||
</Dropdown>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
actionsRender={(props) => {
|
|
||||||
if (props.isMobile) return [];
|
|
||||||
if (typeof window === 'undefined') return [];
|
|
||||||
return [
|
|
||||||
<LanguageSetting />,
|
|
||||||
<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"/>{$t('文档')}</span>
|
|
||||||
</Button>
|
|
||||||
];
|
|
||||||
}}
|
|
||||||
headerTitleRender={() => (
|
|
||||||
<div className="w-[192px] flex items-center">
|
|
||||||
<img
|
|
||||||
className="h-[20px] cursor-pointer "
|
|
||||||
src={Logo}
|
|
||||||
onClick={()=> navigator(mainPage)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
logo={Logo}
|
|
||||||
pageTitleRender={()=>$t('APIPark - 企业API数据开放平台')}
|
|
||||||
menuFooterRender={(props) => {
|
|
||||||
if (props?.collapsed) return undefined;
|
|
||||||
}}
|
|
||||||
menuItemRender={(item, dom) => (
|
|
||||||
<div
|
|
||||||
onClick={() => {
|
|
||||||
// 同级目录点击无效
|
|
||||||
if(item.key && routerKeyMap.get(item.key) && routerKeyMap.get(item.key).length > 0 && routerKeyMap.get(item.key)?.indexOf(pathname.split('/')[1]) !== -1){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if(item.key === pathname.split('/')[1]){
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if(item.path){
|
|
||||||
navigator(item.path)
|
|
||||||
}
|
|
||||||
setPathname(item.path || '');
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{dom}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
fixSiderbar={true}
|
|
||||||
layout='mix'
|
|
||||||
splitMenus={true}
|
|
||||||
collapsed={false}
|
|
||||||
collapsedButtonRender={false}
|
|
||||||
>
|
|
||||||
<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>
|
</div>
|
||||||
</ProLayout>
|
</Dropdown>
|
||||||
</ConfigProvider>
|
);
|
||||||
</ProConfigProvider>
|
},
|
||||||
</div>
|
}}
|
||||||
)
|
actionsRender={(props) => {
|
||||||
|
if (props.isMobile) return [];
|
||||||
|
if (typeof window === 'undefined') return [];
|
||||||
|
return [
|
||||||
|
<LanguageSetting />,
|
||||||
|
<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" />{$t('文档')}</span>
|
||||||
|
</Button>
|
||||||
|
];
|
||||||
|
}}
|
||||||
|
headerTitleRender={() => (
|
||||||
|
<div className="w-[192px] flex items-center">
|
||||||
|
<img
|
||||||
|
className="h-[20px] cursor-pointer "
|
||||||
|
src={Logo}
|
||||||
|
onClick={() => navigator(mainPage)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
logo={Logo}
|
||||||
|
pageTitleRender={() => $t('APIPark')}
|
||||||
|
menuFooterRender={(props) => {
|
||||||
|
if (props?.collapsed) return undefined;
|
||||||
|
}}
|
||||||
|
menuItemRender={(item, dom) => (
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
// 同级目录点击无效
|
||||||
|
if (item.key && routerKeyMap.get(item.key) && routerKeyMap.get(item.key).length > 0 && routerKeyMap.get(item.key)?.indexOf(pathname.split('/')[1]) !== -1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (item.key === pathname.split('/')[1]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.path) {
|
||||||
|
navigator(item.path)
|
||||||
|
}
|
||||||
|
setPathname(item.path || '');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{dom}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
fixSiderbar={true}
|
||||||
|
layout='mix'
|
||||||
|
splitMenus={true}
|
||||||
|
collapsed={false}
|
||||||
|
collapsedButtonRender={false}
|
||||||
|
>
|
||||||
|
<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>
|
||||||
|
</ConfigProvider>
|
||||||
|
</ProConfigProvider>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
export default BasicLayout
|
export default BasicLayout
|
||||||
@@ -1,27 +1,23 @@
|
|||||||
|
|
||||||
import { GetProp, TransferProps, TreeDataNode, theme, Transfer, Tree, Spin } from "antd";
|
import { TransferProps, TreeDataNode, Tree, Spin, Input, Empty } from "antd";
|
||||||
import { DataNode, TreeProps } from "antd/es/tree";
|
import { DataNode } from "antd/es/tree";
|
||||||
import { Ref, forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
import { Ref, forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
||||||
import { ApartmentOutlined, LoadingOutlined, UserOutlined } from "@ant-design/icons";
|
import { ApartmentOutlined, LoadingOutlined, UserOutlined } from "@ant-design/icons";
|
||||||
import { cloneDeep, debounce } from "lodash-es";
|
|
||||||
import { ColumnsType } from "antd/es/table";
|
import { ColumnsType } from "antd/es/table";
|
||||||
import { $t } from "@common/locales";
|
import { $t } from "@common/locales";
|
||||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
|
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
|
||||||
|
|
||||||
type TransferItem = GetProp<TransferProps, 'dataSource'>[number];
|
|
||||||
|
|
||||||
export type TransferTableProps<T> = {
|
export type TransferTableProps<T> = {
|
||||||
request?:(k?:string)=>Promise<{data:T[],success:boolean}>
|
request?:(k?:string)=>Promise<{data:T[],success:boolean}>
|
||||||
columns: ColumnsType<T>
|
columns: ColumnsType<T>
|
||||||
primaryKey:string
|
primaryKey:string
|
||||||
onSelect:(selectedData:T[])=>void
|
onSelect:(selectedData:string[])=>void
|
||||||
tableType?:'member'|'api'
|
tableType?:'member'|'api'
|
||||||
disabledData:string[]
|
disabledData:string[]
|
||||||
searchPlaceholder?:string
|
searchPlaceholder?:string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TransferTableHandle<T> = {
|
export type TransferTableHandle<T> = {
|
||||||
selectedData: () => T[];
|
|
||||||
selectedRowKeys: () => React.Key[];
|
selectedRowKeys: () => React.Key[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,10 +27,6 @@ interface TreeTransferProps {
|
|||||||
onChange: TransferProps['onChange'];
|
onChange: TransferProps['onChange'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Customize Table Transfer
|
|
||||||
const isChecked = (selectedKeys: React.Key[], eventKey: React.Key) =>
|
|
||||||
selectedKeys.includes(eventKey);
|
|
||||||
|
|
||||||
const generateTree = (
|
const generateTree = (
|
||||||
treeNodes: TreeDataNode[] = [],
|
treeNodes: TreeDataNode[] = [],
|
||||||
checkedKeys: TreeTransferProps['targetKeys'] = [],
|
checkedKeys: TreeTransferProps['targetKeys'] = [],
|
||||||
@@ -73,200 +65,104 @@ const generateTree = (
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
const TransferTree = (props)=>{
|
|
||||||
const { direction, token, tableHeight, dataSource, targetKeys, onItemSelect, onItemSelectAll,checkedKey,selectedKeys, filteredItems ,disabledData} = props;
|
|
||||||
const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
|
|
||||||
|
|
||||||
const getExpandedKeys = (newData:TreeDataNode[], expandedSet:Set<string> = new Set())=>{
|
|
||||||
newData.forEach((item)=>{
|
|
||||||
if(item.children && item.children.length > 0){
|
|
||||||
expandedSet.add(item.key)
|
|
||||||
getExpandedKeys(item.children,expandedSet)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return expandedSet
|
|
||||||
}
|
|
||||||
|
|
||||||
const treeData:TreeDataNode[] = useMemo(()=>{
|
|
||||||
const filteredSet = filteredItems && filteredItems.length > 0 ? new Set(filteredItems.map((x)=>x.id)) : new Set()
|
|
||||||
const res = dataSource && dataSource.length > 0 ? generateTree(dataSource, targetKeys,direction === 'right',disabledData,filteredSet) : []
|
|
||||||
setExpandedKeys(Array.from(getExpandedKeys(res)))
|
|
||||||
return res
|
|
||||||
},[
|
|
||||||
dataSource, targetKeys,direction ,disabledData,filteredItems
|
|
||||||
])
|
|
||||||
|
|
||||||
const onExpand: TreeProps['onExpand'] = (expandedKeysValue) => {
|
|
||||||
setExpandedKeys(expandedKeysValue as string[]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
|
|
||||||
<div style={{ padding: token.paddingXS }}>
|
|
||||||
<Tree
|
|
||||||
className="icon-tree"
|
|
||||||
blockNode
|
|
||||||
checkable
|
|
||||||
showIcon
|
|
||||||
checkedKeys={direction === 'left' ? Array.from(new Set([...checkedKey,...disabledData])) : selectedKeys }
|
|
||||||
defaultExpandAll
|
|
||||||
expandedKeys={expandedKeys}
|
|
||||||
onExpand={onExpand}
|
|
||||||
height={tableHeight}
|
|
||||||
icon={(props)=> { return (props.type === 'member' ? <UserOutlined /> :<ApartmentOutlined /> )} }
|
|
||||||
treeData={treeData}
|
|
||||||
onCheck={(_checkedKeys, e:{checked: boolean, checkedNodes, node, event, halfCheckedKeys}) => {
|
|
||||||
if(e.checked){
|
|
||||||
onItemSelectAll( _checkedKeys, e.checked);
|
|
||||||
}else{
|
|
||||||
const checkedKeyArrFromTree = e.checkedNodes.map(node => node.key)
|
|
||||||
onItemSelectAll((checkedKey as string[]).filter(key => checkedKeyArrFromTree.indexOf(key) === -1),e.checked)
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onSelect={(_, { node: { key } }) => {
|
|
||||||
onItemSelect(key as string, !isChecked(checkedKey, key));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const MemberTransfer= forwardRef<TransferTableHandle<{[k:string]:unknown}>, TransferTableProps<{[k:string]:unknown}>>(
|
const MemberTransfer= forwardRef<TransferTableHandle<{[k:string]:unknown}>, TransferTableProps<{[k:string]:unknown}>>(
|
||||||
<T extends {[k:string]:unknown}>(props: TransferTableProps<T>, ref:Ref<TransferTableHandle<T>>) => {
|
<T extends {[k:string]:unknown}>(props: TransferTableProps<T>, ref:Ref<TransferTableHandle<T>>) => {
|
||||||
const {request,columns,primaryKey,onSelect,tableType,disabledData = [],searchPlaceholder} = props
|
const {request,columns,primaryKey,onSelect,tableType,disabledData = [],searchPlaceholder} = props
|
||||||
const [tableHeight, setTableHeight] = useState(window.innerHeight * 80 / 100 - 64 - 72 - 56 - 16 -3);
|
|
||||||
const [targetKeys, setTargetKeys] = useState<TreeTransferProps['targetKeys']>([]);
|
const [targetKeys, setTargetKeys] = useState<TreeTransferProps['targetKeys']>([]);
|
||||||
const [dataSource, setDataSource] = useState<DataNode[] >([])
|
const [dataSource, setDataSource] = useState<DataNode[] >([])
|
||||||
const parentRef = useRef<HTMLDivElement>(null);
|
const parentRef = useRef<HTMLDivElement>(null);
|
||||||
const [loading, setLoading] = useState<boolean>(false)
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
const {state} = useGlobalContext()
|
const {state} = useGlobalContext()
|
||||||
|
const [expandedKeys, setExpandedKeys] = useState<string[]>([]);
|
||||||
|
const [searchWord, setSearchWord] = useState<string>('')
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
setTargetKeys(disabledData)
|
setTargetKeys(disabledData)
|
||||||
},[disabledData])
|
},[disabledData])
|
||||||
|
|
||||||
useImperativeHandle(ref, () =>({
|
useImperativeHandle(ref, () =>({
|
||||||
selectedData: () => dataSource,
|
|
||||||
selectedRowKeys: () => targetKeys,}))
|
selectedRowKeys: () => targetKeys,}))
|
||||||
|
|
||||||
const onChange: TreeTransferProps['onChange'] = (keys) => {
|
const translatedDataSource = useMemo(()=>{
|
||||||
onSelect?.(new Set(keys))
|
|
||||||
setTargetKeys(Array.from(new Set(keys)));
|
const loop = (data: DataNode[]): DataNode[] =>
|
||||||
};
|
data?.map((item) => {
|
||||||
|
const strTitle:string = item.name === '所有成员' ? $t(item.name) as string : item.name as string;
|
||||||
|
const index = strTitle.indexOf(searchWord);
|
||||||
|
const beforeStr = strTitle.substring(0, index);
|
||||||
|
const afterStr = strTitle.slice(index + searchWord.length);
|
||||||
|
const title =
|
||||||
|
index > -1 ? (
|
||||||
|
<span className='w-[calc(100%-16px)] truncate' title={strTitle}>
|
||||||
|
{beforeStr}
|
||||||
|
<span className="text-theme">{searchWord}</span>
|
||||||
|
{afterStr}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className='w-[calc(100%-16px)] truncate' title={`${strTitle}`}>{strTitle}</span>
|
||||||
|
)
|
||||||
|
if (item.children) {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
title,
|
||||||
|
disableCheckbox:disabledData.indexOf(item.key as string) !== -1,
|
||||||
|
icon:<ApartmentOutlined />,
|
||||||
|
children: loop(item.children as T[]) };
|
||||||
|
}
|
||||||
|
|
||||||
const { token } = theme.useToken();
|
return {
|
||||||
|
...item,
|
||||||
const transferDataSource: TransferItem[] = useMemo(()=>{
|
title,
|
||||||
function flatten(list: TreeDataNode[] = [], res:TransferItem[]) {
|
icon:<UserOutlined />,
|
||||||
list.forEach((item) => {
|
isLeaf:true,
|
||||||
res.push({...item, title:item.title === '所有成员' ? $t((item as unknown as {title:string}).title):item.title }as TransferItem);
|
disableCheckbox:disabledData.indexOf(item.key as string) !== -1
|
||||||
flatten(item.children,res);
|
};
|
||||||
});
|
|
||||||
}
|
|
||||||
const res:TransferItem[] =[]
|
|
||||||
flatten(dataSource,res);
|
|
||||||
return res
|
|
||||||
},[
|
|
||||||
dataSource, state.language
|
|
||||||
])
|
|
||||||
|
|
||||||
|
|
||||||
const translatedDataSource = useMemo(()=>dataSource.map((item)=>({
|
|
||||||
...item,
|
|
||||||
name:item.name === '所有成员' ? $t((item as unknown as {name:string}).name):item.name,
|
|
||||||
})),[dataSource, state.language])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let memo: Record<string, boolean> = {};
|
|
||||||
|
|
||||||
const handlerFilterOption = (inputValue: string, item: any, parentResult: boolean = false, childrenSet: Set<string> = new Set()): boolean => {
|
|
||||||
const cacheKey = `${inputValue}_${item.key}`;
|
|
||||||
if (memo[cacheKey]) {
|
|
||||||
return memo[cacheKey];
|
|
||||||
}
|
|
||||||
|
|
||||||
childrenSet.add(item.key);
|
|
||||||
let result = item.title.includes(inputValue) || parentResult
|
|
||||||
if (item.children) {
|
|
||||||
for (const child of item.children) {
|
|
||||||
if (handlerFilterOption(inputValue, child, result,childrenSet)) {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result) {
|
|
||||||
memo[cacheKey] = result;
|
|
||||||
childrenSet.forEach((key) => {
|
|
||||||
memo[`${inputValue}_${key}`] = result;
|
|
||||||
});
|
});
|
||||||
}
|
return loop(dataSource);
|
||||||
return result;
|
},[dataSource, state.language, searchWord])
|
||||||
};
|
|
||||||
|
|
||||||
|
const getInitExpandKeys = (data:T[], expandKeys:string[] = [])=>{
|
||||||
|
data.forEach((item)=>{
|
||||||
|
if(item.children?.length){
|
||||||
|
expandKeys.push(item.key as string)
|
||||||
|
getInitExpandKeys(item.children,expandKeys)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return expandKeys
|
||||||
|
}
|
||||||
|
|
||||||
const getDataSource = ()=>{
|
const getDataSource = ()=>{
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
request && request().then((res)=>{
|
request && request().then((res)=>{
|
||||||
const {data,success} = res
|
const {data,success} = res
|
||||||
setDataSource(success? data : [])
|
setDataSource(success? data : [])
|
||||||
|
setExpandedKeys(getInitExpandKeys(success? data:[]))
|
||||||
}).finally(()=>{setLoading(false)})
|
}).finally(()=>{setLoading(false)})
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getDataSource()
|
|
||||||
const handleResize = () => {
|
|
||||||
setTableHeight(window.innerHeight * 80 / 100 - 64 - 72 - 56 - 16 -3)
|
|
||||||
};
|
|
||||||
|
|
||||||
const debouncedHandleResize = debounce(handleResize, 200);
|
useEffect(() => {
|
||||||
|
getDataSource()
|
||||||
// 监听窗口大小变化
|
}, []);
|
||||||
window.addEventListener('resize', debouncedHandleResize);
|
|
||||||
handleResize();
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('resize', debouncedHandleResize);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={parentRef}>
|
<div ref={parentRef}>
|
||||||
<Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />} spinning={loading} className=''>
|
<Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />} spinning={loading} className=''>
|
||||||
<Transfer
|
<Input className="mb-[10px]" placeholder={searchPlaceholder} onChange={(e)=>setSearchWord(e.target.value)} value={searchWord} />
|
||||||
showSearch
|
<>{ translatedDataSource && translatedDataSource.length > 0 ? <Tree
|
||||||
onSearch={(dir)=>{
|
checkable
|
||||||
memo = {};
|
expandedKeys={expandedKeys}
|
||||||
}}
|
checkedKeys={targetKeys}
|
||||||
listStyle={{width:'408px'}}
|
selectable={false}
|
||||||
disabledData={disabledData}
|
onCheck={(e)=>{setTargetKeys(e);
|
||||||
filterOption={(inputValue: string, item: any) => handlerFilterOption(inputValue, item)}
|
onSelect(((e as string[])?.filter(x=>disabledData.indexOf(x as string) === -1))||[])}}
|
||||||
targetKeys={targetKeys}
|
onExpand={setExpandedKeys}
|
||||||
dataSource={transferDataSource}
|
treeData={translatedDataSource}
|
||||||
className="tree-transfer"
|
blockNode
|
||||||
render={(item) => item.title!}
|
showIcon
|
||||||
showSelectAll={false}
|
/>
|
||||||
onChange={onChange}
|
: <Empty image={Empty.PRESENTED_IMAGE_SIMPLE}/> }</>
|
||||||
titles={['','']}
|
|
||||||
>
|
|
||||||
{({ direction, onItemSelect, selectedKeys,onItemSelectAll ,filteredItems}) => {
|
|
||||||
const treeProps = {
|
|
||||||
dataSource:translatedDataSource, direction, onItemSelect, selectedKeys,onItemSelectAll ,filteredItems,token,tableHeight,targetKeys,disabledData
|
|
||||||
}
|
|
||||||
if (direction === 'left') {
|
|
||||||
const checkedKey = [...selectedKeys, ...targetKeys as string[]];
|
|
||||||
return (
|
|
||||||
<TransferTree {...treeProps} checkedKey={checkedKey} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if(direction === 'right'){
|
|
||||||
const checkedKey = [...selectedKeys,...targetKeys as string[]];
|
|
||||||
return (
|
|
||||||
<TransferTree {...treeProps} checkedKey={checkedKey} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
</Transfer>
|
|
||||||
</Spin>
|
</Spin>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,64 +8,65 @@ import { Icon } from "@iconify/react/dist/iconify.js"
|
|||||||
import { $t } from "@common/locales"
|
import { $t } from "@common/locales"
|
||||||
|
|
||||||
type TableBtnWithPermissionProps = {
|
type TableBtnWithPermissionProps = {
|
||||||
btnTitle:string
|
btnTitle: string
|
||||||
access?:keyof typeof PERMISSION_DEFINITION[0],
|
access?: keyof typeof PERMISSION_DEFINITION[0],
|
||||||
tooltip?:string,
|
tooltip?: string,
|
||||||
disabled?:boolean,
|
disabled?: boolean,
|
||||||
navigateTo?:string,
|
navigateTo?: string,
|
||||||
onClick?:(args?:unknown)=>void
|
onClick?: (args?: unknown) => void
|
||||||
className?:string
|
className?: string
|
||||||
btnType:string
|
btnType: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const TableIconName={
|
const TableIconName = {
|
||||||
'add':'ic:baseline-add',
|
'add': 'ic:baseline-add',
|
||||||
'edit':'ic:baseline-edit',
|
'edit': 'ic:baseline-edit',
|
||||||
'delete':'ic:baseline-delete',
|
'delete': 'ic:baseline-delete',
|
||||||
'remove':'ic:baseline-minus',
|
'remove': 'ic:baseline-minus',
|
||||||
'copy':'ic:baseline-file-copy',
|
'copy': 'ic:baseline-file-copy',
|
||||||
'view':'ic:baseline-remove-red-eye',
|
'view': 'ic:baseline-remove-red-eye',
|
||||||
'publish':'ic:baseline-publish',
|
'publish': 'ic:baseline-publish',
|
||||||
'approval':'ic:baseline-approval',
|
'approval': 'ic:baseline-approval',
|
||||||
'stop':'ic:baseline-stop-circle',
|
'stop': 'ic:baseline-stop-circle',
|
||||||
'online':'ic:baseline-check-circle',
|
'online': 'ic:baseline-check-circle',
|
||||||
'cancel':'ic:baseline-cancel-schedule-send',
|
'cancel': 'ic:baseline-cancel-schedule-send',
|
||||||
'refresh':'ic:baseline-refresh'
|
'refresh': 'ic:baseline-refresh',
|
||||||
|
'logs': 'hugeicons:google-doc'
|
||||||
}
|
}
|
||||||
// 表格操作栏按钮,受权限控制
|
// 表格操作栏按钮,受权限控制
|
||||||
const TableBtnWithPermission = ({btnTitle, access, tooltip, disabled, navigateTo, onClick,className,btnType}:TableBtnWithPermissionProps) => {
|
const TableBtnWithPermission = ({ btnTitle, access, tooltip, disabled, navigateTo, onClick, className, btnType }: TableBtnWithPermissionProps) => {
|
||||||
|
|
||||||
const [btnAccess, setBtnAccess] = useState<boolean>(false)
|
|
||||||
const {accessData,checkPermission,accessInit} = useGlobalContext()
|
|
||||||
const navigate = useNavigate()
|
|
||||||
const lastAccess = useMemo(()=>{
|
|
||||||
if(!accessInit) return false
|
|
||||||
if(!access) return true
|
|
||||||
return checkPermission(access)
|
|
||||||
},[access, accessData,checkPermission,accessInit])
|
|
||||||
|
|
||||||
useEffect(()=>{
|
const [btnAccess, setBtnAccess] = useState<boolean>(false)
|
||||||
access ? setBtnAccess(lastAccess) : setBtnAccess(true)
|
const { accessData, checkPermission, accessInit } = useGlobalContext()
|
||||||
},[access, lastAccess])
|
const navigate = useNavigate()
|
||||||
|
const lastAccess = useMemo(() => {
|
||||||
|
if (!accessInit) return false
|
||||||
|
if (!access) return true
|
||||||
|
return checkPermission(access)
|
||||||
|
}, [access, accessData, checkPermission, accessInit])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
const handleClick = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {
|
access ? setBtnAccess(lastAccess) : setBtnAccess(true)
|
||||||
e.stopPropagation()
|
}, [access, lastAccess])
|
||||||
navigateTo ? navigate(navigateTo) : onClick?.()
|
|
||||||
}, [navigateTo, navigate, onClick])
|
|
||||||
|
const handleClick = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
return (<>{
|
e.stopPropagation()
|
||||||
!btnAccess || (disabled&&tooltip) ?
|
navigateTo ? navigate(navigateTo) : onClick?.()
|
||||||
<Tooltip placement="top" title={tooltip ?? $t('暂无(0)权限,请联系管理员分配。',[$t(btnTitle).toLowerCase()])}>
|
}, [navigateTo, navigate, onClick])
|
||||||
<Button type="text" disabled={true} className={`h-[22px] border-none p-0 flex items-center bg-transparent ${className}`} key={btnType} icon={<Icon icon={TableIconName[btnType as keyof typeof TableIconName]} width="18" height="18"/>} >{}</Button>
|
|
||||||
</Tooltip>
|
return (<>{
|
||||||
:
|
!btnAccess || (disabled && tooltip) ?
|
||||||
<Tooltip placement="top" title={$t(btnTitle)}>
|
<Tooltip placement="top" title={tooltip ?? $t('暂无(0)权限,请联系管理员分配。', [$t(btnTitle).toLowerCase()])}>
|
||||||
<Button type="text" disabled={disabled} className={`h-[22px] border-none p-0 flex items-center bg-transparent ${className} `} key={btnType} icon={<Icon icon={TableIconName[btnType as keyof typeof TableIconName]} width="18" height="18"/>} onClick={handleClick}>{}</Button>
|
<Button type="text" disabled={true} className={`h-[22px] border-none p-0 flex items-center bg-transparent ${className}`} key={btnType} icon={<Icon icon={TableIconName[btnType as keyof typeof TableIconName]} width="18" height="18" />} >{ }</Button>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
:
|
||||||
|
<Tooltip placement="top" title={$t(btnTitle)}>
|
||||||
|
<Button type="text" disabled={disabled} className={`h-[22px] border-none p-0 flex items-center bg-transparent ${className} `} key={btnType} icon={<Icon icon={TableIconName[btnType as keyof typeof TableIconName]} width="18" height="18" />} onClick={handleClick}>{ }</Button>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
}</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default TableBtnWithPermission
|
export default TableBtnWithPermission
|
||||||
@@ -159,7 +159,10 @@ export const TranslateWord = ()=>{
|
|||||||
{$t('地址')}
|
{$t('地址')}
|
||||||
{$t('新增')}
|
{$t('新增')}
|
||||||
{$t('申请方消费者')}
|
{$t('申请方消费者')}
|
||||||
|
{$t('策略名称')}
|
||||||
|
{$t('优先级')}
|
||||||
|
{$t('筛选条件')}
|
||||||
|
{$t('处理数')}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ const WithPermission = ({access, tooltip, children,disabled, showDisabled = true
|
|||||||
{ cloneElement(children, {disabled:true})}
|
{ cloneElement(children, {disabled:true})}
|
||||||
</Tooltip>}
|
</Tooltip>}
|
||||||
{!editAccess && (children?.type !== Button && children?.type !== Upload && showDisabled) && <Tooltip title={tooltip ?? $t("暂无操作权限,请联系管理员分配。")}>
|
{!editAccess && (children?.type !== Button && children?.type !== Upload && showDisabled) && <Tooltip title={tooltip ?? $t("暂无操作权限,请联系管理员分配。")}>
|
||||||
{ cloneElement(children, {disabled:true,okButtonProps:{disabled:true}})}
|
{ cloneElement(children, {disabled:true, onClick:(e)=>e.preventDefault(),okButtonProps:{disabled:true}})}
|
||||||
</Tooltip>}
|
</Tooltip>}
|
||||||
|
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -276,252 +276,252 @@ export const PERMISSION_DEFINITION = [
|
|||||||
},
|
},
|
||||||
"team.service.api_doc.view": {
|
"team.service.api_doc.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.api_doc.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.api_doc.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.api_doc.add": {
|
"team.service.api_doc.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.api_doc.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api_doc.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.api_doc.edit": {
|
"team.service.api_doc.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.api_doc.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api_doc.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.service_intro.view": {
|
"team.service.service_intro.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.service_intro.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.service_intro.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.service_intro.add": {
|
"team.service.service_intro.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": [" team.service.service_intro.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.service_intro.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.service_intro.edit": {
|
"team.service.service_intro.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": [" team.service.service_intro.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.service_intro.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.api_doc.import": {
|
"team.service.api_doc.import": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.api_doc.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api_doc.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.router.view": {
|
"team.service.router.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.api.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.api.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.router.add": {
|
"team.service.router.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.api.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.router.edit": {
|
"team.service.router.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.api.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.router.delete": {
|
"team.service.router.delete": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.api.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.api.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.upstream.view": {
|
"team.service.upstream.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.upstream.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.upstream.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.upstream.add": {
|
"team.service.upstream.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.upstream.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.upstream.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.upstream.edit": {
|
"team.service.upstream.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.upstream.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.upstream.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.upstream.delete": {
|
"team.service.upstream.delete": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.upstream.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.upstream.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.release.view": {
|
"team.service.release.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.release.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.release.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.release.add": {
|
"team.service.release.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.release.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.release.online": {
|
"team.service.release.online": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.release.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.release.stop": {
|
"team.service.release.stop": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.release.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.release.cancel": {
|
"team.service.release.cancel": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.release.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.release.rollback": {
|
"team.service.release.rollback": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.release.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.release.delete": {
|
"team.service.release.delete": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.release.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.release.approval": {
|
"team.service.release.approval": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.release.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.release.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.subscription.view": {
|
"team.service.subscription.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.subscription.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.view_all","team.service.subscription.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.subscription.approval": {
|
"team.service.subscription.approval": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.subscription.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.subscription.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.subscription.add": {
|
"team.service.subscription.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.subscription.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.subscription.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.subscription.delete": {
|
"team.service.subscription.delete": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.service.subscription.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.service.subscription.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.service.view": {
|
"team.service.service.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.service.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","system.workspace.service.view_all","team.team.service.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.service.add": {
|
"team.service.service.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.service.manager","team.service.service.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.team.service.manager","team.service.service.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.service.edit": {
|
"team.service.service.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.service.manager","team.service.service.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.team.service.manager","team.service.service.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.service.service.delete": {
|
"team.service.service.delete": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.service.manager","team.service.service.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.service.manager_all","team.team.service.manager","team.service.service.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.subscription.view": {
|
"team.application.subscription.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.consumer.subscription.view_subscribed_service"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.view_all","team.consumer.subscription.view_subscribed_service"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.subscription.add": {
|
"team.application.subscription.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.consumer.subscription.subscribe"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.subscription.subscribe"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.subscription.edit": {
|
"team.application.subscription.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.consumer.subscription.manager_subscribed_services"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.subscription.manager_subscribed_services"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.subscription.delete": {
|
"team.application.subscription.delete": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.consumer.subscription.manager_subscribed_services"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.team.consumer.subscription.manager_subscribed_services"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.application.view": {
|
"team.application.application.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.consumer.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.view_all","team.team.consumer.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.application.add": {
|
"team.application.application.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ['team.team.consumer.manager',"team.consumer.application.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al",'team.team.consumer.manager',"team.consumer.application.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.application.edit": {
|
"team.application.application.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ['team.team.consumer.manager',"team.consumer.application.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al",'team.team.consumer.manager',"team.consumer.application.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.application.delete": {
|
"team.application.application.delete": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ['team.team.consumer.manager',"team.consumer.application.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al",'team.team.consumer.manager',"team.consumer.application.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.consumer.authorization.view": {
|
"team.consumer.authorization.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.consumer.authorization.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al","system.workspace.application.view_all","team.consumer.authorization.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.authorization.add": {
|
"team.application.authorization.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.consumer.authorization.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.authorization.edit": {
|
"team.application.authorization.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.consumer.authorization.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.authorization.delete": {
|
"team.application.authorization.delete": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.consumer.authorization.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.authorization.cancelSubApply": {
|
"team.application.authorization.cancelSubApply": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.consumer.authorization.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.application.authorization.cancelSub": {
|
"team.application.authorization.cancelSub": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.consumer.authorization.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.application.manager_al","team.consumer.authorization.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.team.team.view": {
|
"team.team.team.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.team.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.team.view_all","team.team.team.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.team.team.edit": {
|
"team.team.team.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.team.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.team.manager","team.team.team.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.team.member.view": {
|
"team.team.member.view": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.member.view"] }]
|
"anyOf": [{ "backend": ["system.workspace.team.view_all","team.team.member.view"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.team.member.add": {
|
"team.team.member.add": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.member.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.team.manager","team.team.member.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team.team.member.edit": {
|
"team.team.member.edit": {
|
||||||
"granted": {
|
"granted": {
|
||||||
"anyOf": [{ "backend": ["team.team.member.manager"] }]
|
"anyOf": [{ "backend": ["system.workspace.team.manager","team.team.member.manager"] }]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"project.mySystem.topology.view": {
|
"project.mySystem.topology.view": {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
"角色": "Kf644225f",
|
"角色": "Kf644225f",
|
||||||
"集成": "K4057391a",
|
"集成": "K4057391a",
|
||||||
"数据源": "K8fa58214",
|
"数据源": "K8fa58214",
|
||||||
|
"全局策略": "Ke8cbb878",
|
||||||
"证书": "K481e8a05",
|
"证书": "K481e8a05",
|
||||||
"日志": "Kca53edd0",
|
"日志": "Kca53edd0",
|
||||||
"资源": "Kb283e720",
|
"资源": "Kb283e720",
|
||||||
@@ -488,6 +489,14 @@
|
|||||||
"统计图表": "K1358acf",
|
"统计图表": "K1358acf",
|
||||||
"地址(IP:端口)": "K62dabdf6",
|
"地址(IP:端口)": "K62dabdf6",
|
||||||
"组织(Organization)": "K2db12335",
|
"组织(Organization)": "K2db12335",
|
||||||
|
"添加策略": "K34d0d409",
|
||||||
|
"输入名称、筛选条件查找": "Kbb4298ac",
|
||||||
|
"策略名称": "K931615d7",
|
||||||
|
"优先级": "K31faa2a1",
|
||||||
|
"筛选条件": "Kbdec9fa",
|
||||||
|
"处理数": "Kbcbb7391",
|
||||||
|
"数据脱敏": "Kabac9caf",
|
||||||
|
"支持对系统全局进行统一的策略配置,从而简化管理并确保一致性。全局策略的优先级比服务策略略低。": "Kc975cd5a",
|
||||||
"资源配置": "K8e7a0f80",
|
"资源配置": "K8e7a0f80",
|
||||||
"设置角色的权限范围。": "K95c3fd8b",
|
"设置角色的权限范围。": "K95c3fd8b",
|
||||||
"系统级别角色": "K138facd3",
|
"系统级别角色": "K138facd3",
|
||||||
@@ -523,6 +532,7 @@
|
|||||||
"删除服务": "Kde6bae17",
|
"删除服务": "Kde6bae17",
|
||||||
"删除操作不可恢复,请谨慎操作!": "K885ea699",
|
"删除操作不可恢复,请谨慎操作!": "K885ea699",
|
||||||
"上游": "Kda8d5ea1",
|
"上游": "Kda8d5ea1",
|
||||||
|
"服务策略": "K52f72551",
|
||||||
"服务提供了高性能 API 网关,并且可以无缝接入多种大型 AI 模型,并将这些 AI 能力打包成 API 进行调用,从而大幅简化了 AI 模型的使用门槛。同时,我们的平台提供了完善的 API 管理功能,支持 API 的创建、监控、访问控制等,保障开发者可以高效、安全地开发和管理 API 服务。": "K12f58863",
|
"服务提供了高性能 API 网关,并且可以无缝接入多种大型 AI 模型,并将这些 AI 能力打包成 API 进行调用,从而大幅简化了 AI 模型的使用门槛。同时,我们的平台提供了完善的 API 管理功能,支持 API 的创建、监控、访问控制等,保障开发者可以高效、安全地开发和管理 API 服务。": "K12f58863",
|
||||||
"添加服务": "K2d6658ed",
|
"添加服务": "K2d6658ed",
|
||||||
"输入名称、ID、所属团队、负责人查找服务": "K7b8f623f",
|
"输入名称、ID、所属团队、负责人查找服务": "K7b8f623f",
|
||||||
@@ -546,7 +556,7 @@
|
|||||||
"移除成员": "K395acc14",
|
"移除成员": "K395acc14",
|
||||||
"添加成员": "Kec46a57f",
|
"添加成员": "Kec46a57f",
|
||||||
"输入姓名查找": "K48724410",
|
"输入姓名查找": "K48724410",
|
||||||
"搜索用户名、邮箱": "Kb9052305",
|
"输入名称查找用户": "Kf5fd27ed",
|
||||||
"设置团队和成员,然后你可以在团队内创建服务和消费者、订阅API,成员只能看到所属团队内的服务和消费者。": "K4c72fb6f",
|
"设置团队和成员,然后你可以在团队内创建服务和消费者、订阅API,成员只能看到所属团队内的服务和消费者。": "K4c72fb6f",
|
||||||
"添加团队": "K510cdd27",
|
"添加团队": "K510cdd27",
|
||||||
"输入名称、ID、负责人查找团队": "K9244ae14",
|
"输入名称、ID、负责人查找团队": "K9244ae14",
|
||||||
@@ -616,6 +626,19 @@
|
|||||||
"暂无API数据": "K6b75bdbc",
|
"暂无API数据": "K6b75bdbc",
|
||||||
"搜索或选择消费者": "Kb684c806",
|
"搜索或选择消费者": "Kb684c806",
|
||||||
"申请理由": "K4b15d6f5",
|
"申请理由": "K4b15d6f5",
|
||||||
|
"支持把当前服务对接主流的 AI Agent平台,实现在 Agent 平台上快速、安全和合规地使用企业开放的 API 能力。": "K2ec0fa56",
|
||||||
|
"可按以下步骤进行对接:": "K35f23b64",
|
||||||
|
"步骤一:Agent 平台上创建自定义插件": "Kf5cd608b",
|
||||||
|
"不同 Agent 平台的操作细节可查看": "K4c81c7b6",
|
||||||
|
"《 Agent 对接手册》": "K275f7ffa",
|
||||||
|
"步骤二:导入 API 文档数据": "K49b81d06",
|
||||||
|
"可通过以下 URL 或 下载 Json 文件,导入 API 文档数据到 Agent 平台中。": "K4a3b62be",
|
||||||
|
"复制 URL": "K42697e11",
|
||||||
|
"下载 Json 文件": "K27a809c5",
|
||||||
|
"步骤三:配置 API 密钥": "K1e61fdee",
|
||||||
|
"在": "K55912595",
|
||||||
|
"菜单中,选择已通过本 API 服务申请的消费者,": "K33b1bc3",
|
||||||
|
"把 \"访问权限\" 菜单下的密钥填入到 Agent 平台对应的插件密钥配置中。": "K62adc41e",
|
||||||
"消费者管理": "Ke0fbd1c8",
|
"消费者管理": "Ke0fbd1c8",
|
||||||
"鉴权类型": "Kb71b5a13",
|
"鉴权类型": "Kb71b5a13",
|
||||||
"Iss": "K4d1465ee",
|
"Iss": "K4d1465ee",
|
||||||
|
|||||||
@@ -319,7 +319,7 @@
|
|||||||
"Ka46b9b24": "Data Source Type",
|
"Ka46b9b24": "Data Source Type",
|
||||||
"Kbb0cdcd0": "Data Source Address",
|
"Kbb0cdcd0": "Data Source Address",
|
||||||
"Kd9dfb884": "Organization",
|
"Kd9dfb884": "Organization",
|
||||||
"K3e770a75": "Authentication Token",
|
"K3e770a75": "Credentials Token",
|
||||||
"K8ef69ee2": "Key",
|
"K8ef69ee2": "Key",
|
||||||
"Kba3507d6": "Upload Key",
|
"Kba3507d6": "Upload Key",
|
||||||
"K93ac0f23": "Key file suffix is usually .key",
|
"K93ac0f23": "Key file suffix is usually .key",
|
||||||
@@ -365,7 +365,7 @@
|
|||||||
"Kcef64f4d": "Default AI Provider",
|
"Kcef64f4d": "Default AI Provider",
|
||||||
"Kcab588a9": "No AI model provider set,",
|
"Kcab588a9": "No AI model provider set,",
|
||||||
"Kb9b56111": "Set Now",
|
"Kb9b56111": "Set Now",
|
||||||
"Kcf756b7a": "API Call Prefix",
|
"Kcf756b7a": "API Request Prefix",
|
||||||
"K13edc043": "As a prefix for all APIs in the service, e.g., host/{service_name}/{api_path}, cannot be modified once saved.",
|
"K13edc043": "As a prefix for all APIs in the service, e.g., host/{service_name}/{api_path}, cannot be modified once saved.",
|
||||||
"Kf52a584d": "Service Category",
|
"Kf52a584d": "Service Category",
|
||||||
"K72b21be5": "Set the category in which the service will be displayed in the service marketplace",
|
"K72b21be5": "Set the category in which the service will be displayed in the service marketplace",
|
||||||
@@ -391,8 +391,8 @@
|
|||||||
"K813e1c0a": "Team Name",
|
"K813e1c0a": "Team Name",
|
||||||
"K692f5aa6": "Team ID",
|
"K692f5aa6": "Team ID",
|
||||||
"K5de0bc2": "Team ID can be used to retrieve the team, cannot be modified once saved.",
|
"K5de0bc2": "Team ID can be used to retrieve the team, cannot be modified once saved.",
|
||||||
"Ka63dd985": "Team Leader",
|
"Ka63dd985": "Team Administrator",
|
||||||
"Ka6bcd272": "The leader has management authority over the team, services, and members within the team",
|
"Ka6bcd272": "The Administrator has management authority over the team, services, and members within the team",
|
||||||
"Ka2012bdd": "Delete Team",
|
"Ka2012bdd": "Delete Team",
|
||||||
"Kbde1f3d": "Service data must be cleared before deletion",
|
"Kbde1f3d": "Service data must be cleared before deletion",
|
||||||
"K395acc14": "Remove",
|
"K395acc14": "Remove",
|
||||||
@@ -463,7 +463,7 @@
|
|||||||
"Kd59290a2": "Search Category or Tag",
|
"Kd59290a2": "Search Category or Tag",
|
||||||
"K6b75bdbc": "No API Data",
|
"K6b75bdbc": "No API Data",
|
||||||
"K4b15d6f5": "Application Reason",
|
"K4b15d6f5": "Application Reason",
|
||||||
"Kb71b5a13": "Authentication Type",
|
"Kb71b5a13": "Credentials Type",
|
||||||
"K4d1465ee": "ISS",
|
"K4d1465ee": "ISS",
|
||||||
"K5dcd7ed8": "Signature Algorithm",
|
"K5dcd7ed8": "Signature Algorithm",
|
||||||
"K5b0eedd3": "Secret",
|
"K5b0eedd3": "Secret",
|
||||||
@@ -475,10 +475,10 @@
|
|||||||
"K31418470": "SK",
|
"K31418470": "SK",
|
||||||
"Kbfeb5297": "API Key",
|
"Kbfeb5297": "API Key",
|
||||||
"K1a78e6f0": "Expiration Time",
|
"K1a78e6f0": "Expiration Time",
|
||||||
"Ke64e43a": "Hide Authentication Info",
|
"Ke64e43a": "Hide Credentials Info",
|
||||||
"K217cb125": "Authentication Details",
|
"K217cb125": "Credentials Details",
|
||||||
"K2bb63eca": "Add Authentication",
|
"K2bb63eca": "Add Credentials",
|
||||||
"Kd74d69b7": "Edit Authentication",
|
"Kd74d69b7": "Edit Credentials",
|
||||||
"K9cbe1e0": "Modify",
|
"K9cbe1e0": "Modify",
|
||||||
"Kb6e9328f": "Authorization",
|
"Kb6e9328f": "Authorization",
|
||||||
"Kd23d1716": "Add Authorization",
|
"Kd23d1716": "Add Authorization",
|
||||||
@@ -678,5 +678,30 @@
|
|||||||
"K1644b775": "Add",
|
"K1644b775": "Add",
|
||||||
"Kc8ee3e62": "Non-Existence",
|
"Kc8ee3e62": "Non-Existence",
|
||||||
"K1e97dbd8": "Existence",
|
"K1e97dbd8": "Existence",
|
||||||
"Kec91f0db": "Applicant Consumer"
|
"Kec91f0db": "Applicant Consumer",
|
||||||
|
"Kf5fd27ed": "Enter Name to Search User",
|
||||||
|
"K2ec0fa56": "Support integration with mainstream AI Agent platforms to enable the use of enterprise APIs in a fast, secure, and compliant manner on the Agent platform.",
|
||||||
|
"K35f23b64": "Follow these steps for integration:",
|
||||||
|
"Kf5cd608b": "Step 1: Create a custom plugin on the Agent platform",
|
||||||
|
"K4c81c7b6": "For details on the operations of different Agent platforms, refer to",
|
||||||
|
"K275f7ffa": "the 'Agent Integration Manual'",
|
||||||
|
"K49b81d06": "Step 2: Import API documentation data",
|
||||||
|
"K4a3b62be": "You can import API documentation data to the Agent platform via the following URL or by downloading the JSON file.",
|
||||||
|
"K42697e11": "Copy URL",
|
||||||
|
"K27a809c5": "Download JSON file",
|
||||||
|
"K1e61fdee": "Step 3: Configure API keys",
|
||||||
|
"K55912595": "In the",
|
||||||
|
"K33b1bc3": "menu, select the consumer that has applied for the API service,",
|
||||||
|
"K62adc41e": "and fill in the key from the 'Access Permission' menu into the corresponding plugin key configuration on the Agent platform.",
|
||||||
|
"Ke8cbb878": "Global Policy",
|
||||||
|
"K34d0d409": "Add Policy",
|
||||||
|
"Kbb4298ac": "Enter name, filter criteria to search",
|
||||||
|
"Kabac9caf": "Data Masking",
|
||||||
|
"Kc975cd5a": "Supports unified policy configuration for the system globally, simplifying management and ensuring consistency. The priority of global policies is slightly lower than that of service policies.",
|
||||||
|
"K52f72551": "Service Policy",
|
||||||
|
"K931615d7": "Policy Name",
|
||||||
|
"K31faa2a1": "Priority",
|
||||||
|
"Kbdec9fa": "Filter Criteria",
|
||||||
|
"Kbcbb7391": "Processed Count",
|
||||||
|
"Kad207008": "Edit"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -700,5 +700,30 @@
|
|||||||
"K1644b775": "追加",
|
"K1644b775": "追加",
|
||||||
"Kc8ee3e62": "存在しない",
|
"Kc8ee3e62": "存在しない",
|
||||||
"K1e97dbd8": "存在する",
|
"K1e97dbd8": "存在する",
|
||||||
"Kec91f0db": "申請側コンシューマー"
|
"Kec91f0db": "申請側コンシューマー",
|
||||||
|
"Kf5fd27ed": "名前を入力してユーザーを検索",
|
||||||
|
"K2ec0fa56": "主要なAIエージェントプラットフォームと連携し、エージェントプラットフォーム上で企業のAPIを迅速、安全、かつコンプライアンスに準拠して使用できるようサポートします。",
|
||||||
|
"K35f23b64": "以下の手順で統合を行います:",
|
||||||
|
"Kf5cd608b": "ステップ1:エージェントプラットフォームでカスタムプラグインを作成",
|
||||||
|
"K4c81c7b6": "異なるエージェントプラットフォームの操作詳細については、",
|
||||||
|
"K275f7ffa": "「エージェント統合マニュアル」を参照してください。",
|
||||||
|
"K49b81d06": "ステップ2:APIドキュメントデータのインポート",
|
||||||
|
"K4a3b62be": "以下のURLを使用するか、JSONファイルをダウンロードして、APIドキュメントデータをエージェントプラットフォームにインポートできます。",
|
||||||
|
"K42697e11": "URLをコピー",
|
||||||
|
"K27a809c5": "JSONファイルをダウンロード",
|
||||||
|
"K1e61fdee": "ステップ3:APIキーの設定",
|
||||||
|
"K55912595": "「",
|
||||||
|
"K33b1bc3": "メニュー」から、APIサービスを申し込んだ消費者を選択し、",
|
||||||
|
"K62adc41e": "「アクセス権限」メニューのキーをエージェントプラットフォームのプラグインキー設定に入力します。",
|
||||||
|
"Ke8cbb878": "グローバルポリシー",
|
||||||
|
"K34d0d409": "ポリシーを追加",
|
||||||
|
"Kbb4298ac": "名前、フィルタ条件を入力して検索",
|
||||||
|
"Kabac9caf": "データマスキング",
|
||||||
|
"Kc975cd5a": "システム全体で統一されたポリシー設定をサポートし、管理の簡素化と一貫性の確保を実現します。グローバルポリシーの優先度はサービスポリシーより少し低いです。",
|
||||||
|
"K52f72551": "サービスポリシー",
|
||||||
|
"K931615d7": "ポリシー名",
|
||||||
|
"K31faa2a1": "優先度",
|
||||||
|
"Kbdec9fa": "フィルタ条件",
|
||||||
|
"Kbcbb7391": "処理数",
|
||||||
|
"Kad207008": "編集"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
{}
|
{
|
||||||
|
"Kf5fd27ed": "输入名称查找用户"
|
||||||
|
}
|
||||||
@@ -1 +1,3 @@
|
|||||||
{}
|
{
|
||||||
|
"Kf5fd27ed": "输入名称查找用户"
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
"K78b1ca25": "地址",
|
"K78b1ca25": "地址",
|
||||||
"K1644b775": "新增",
|
"K1644b775": "新增",
|
||||||
"Kec91f0db": "申请方消费者",
|
"Kec91f0db": "申请方消费者",
|
||||||
|
"Kf5fd27ed": "输入名称查找用户",
|
||||||
"Kc3b7bfa8": "暂无消费者描述",
|
"Kc3b7bfa8": "暂无消费者描述",
|
||||||
"K3a6f905d": "输入名称、ID 查找消费者"
|
"K3a6f905d": "输入名称、ID 查找消费者"
|
||||||
}
|
}
|
||||||
@@ -1 +1,3 @@
|
|||||||
{}
|
{
|
||||||
|
"Kf5fd27ed": "输入名称查找用户"
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
|
"Kb9052305": "Search Username, Email",
|
||||||
"K40a89bd8": "Enter Name, ID to Search Member"
|
"K40a89bd8": "Enter Name, ID to Search Member"
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
"K9bdd8403": "API を安全に呼び出すためには、アプリケーションとトークンを作成する必要があります。",
|
"K9bdd8403": "API を安全に呼び出すためには、アプリケーションとトークンを作成する必要があります。",
|
||||||
"Kc8239422": "チームにはユーザー、アプリケーション、サービスが含まれ、異なるチームのアプリケーションとサービスのデータは分離されています。企業内の部門/プロジェクトグループ/チームの管理に使用できます。",
|
"Kc8239422": "チームにはユーザー、アプリケーション、サービスが含まれ、異なるチームのアプリケーションとサービスのデータは分離されています。企業内の部門/プロジェクトグループ/チームの管理に使用できます。",
|
||||||
"Ka0a8840a": "他のアプリケーションのサブスクリプション申請をレビューし、承認後に API リクエストが発行できます。",
|
"Ka0a8840a": "他のアプリケーションのサブスクリプション申請をレビューし、承認後に API リクエストが発行できます。",
|
||||||
|
"Kb9052305": "ユーザー名またはメールを検索",
|
||||||
"K5ece3bac": "チームとメンバーを設定してから、チーム内でサービスとアプリケーションを作成し、API をサブスクライブできます。メンバーは所属チーム内のサービスとアプリケーションのみを表示できます。",
|
"K5ece3bac": "チームとメンバーを設定してから、チーム内でサービスとアプリケーションを作成し、API をサブスクライブできます。メンバーは所属チーム内のサービスとアプリケーションのみを表示できます。",
|
||||||
"K1512e983": "アプリケーション呼び出し統計",
|
"K1512e983": "アプリケーション呼び出し統計",
|
||||||
"Kb4d2007f": "Application を選択",
|
"Kb4d2007f": "Application を選択",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"K9bdd8403": "为了安全地调用 API,你需要创建一个消费者以及Token。",
|
"K9bdd8403": "为了安全地调用 API,你需要创建一个消费者以及Token。",
|
||||||
"Kc8239422": "团队中包含了人员、消费者和服务,不同团队之间的消费者和服务数据是隔离的,可用于管理企业内部不同的部门/项目组/团队。",
|
"Kc8239422": "团队中包含了人员、消费者和服务,不同团队之间的消费者和服务数据是隔离的,可用于管理企业内部不同的部门/项目组/团队。",
|
||||||
"Ka0a8840a": "审核其他消费者的订阅申请,审核通过后的才可发起 API 请求。",
|
"Ka0a8840a": "审核其他消费者的订阅申请,审核通过后的才可发起 API 请求。",
|
||||||
|
"Kb9052305": "搜索用户名、邮箱",
|
||||||
"K5ece3bac": "设置团队和成员,然后你可以在团队内创建服务和消费者、订阅API,成员只能看到所属团队内的服务和消费者。",
|
"K5ece3bac": "设置团队和成员,然后你可以在团队内创建服务和消费者、订阅API,成员只能看到所属团队内的服务和消费者。",
|
||||||
"K1512e983": "消费者调用统计",
|
"K1512e983": "消费者调用统计",
|
||||||
"Kb4d2007f": "请选择消费者",
|
"Kb4d2007f": "请选择消费者",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
"K9bdd8403": "為了安全地調用 API,你需要創建一個應用以及Token。",
|
"K9bdd8403": "為了安全地調用 API,你需要創建一個應用以及Token。",
|
||||||
"Kc8239422": "團隊中包含了人員、應用程式和服務,不同團隊之間的應用程式和服務數據是隔離的,可用於管理企業內部不同的部門/項目組/團隊。",
|
"Kc8239422": "團隊中包含了人員、應用程式和服務,不同團隊之間的應用程式和服務數據是隔離的,可用於管理企業內部不同的部門/項目組/團隊。",
|
||||||
"Ka0a8840a": "審核其他應用程式的訂閱申請,審核通過後的才可發起 API 請求。",
|
"Ka0a8840a": "審核其他應用程式的訂閱申請,審核通過後的才可發起 API 請求。",
|
||||||
|
"Kb9052305": "搜索用戶名、電郵",
|
||||||
"K5ece3bac": "設置團隊和成員,然後你可以在團隊內創建服務和應用程式、訂閱API,成員只能看到所屬團隊內的服務和應用程式。",
|
"K5ece3bac": "設置團隊和成員,然後你可以在團隊內創建服務和應用程式、訂閱API,成員只能看到所屬團隊內的服務和應用程式。",
|
||||||
"K1512e983": "應用程式調用統計",
|
"K1512e983": "應用程式調用統計",
|
||||||
"Kb4d2007f": "請選擇應用程式",
|
"Kb4d2007f": "請選擇應用程式",
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -700,5 +700,30 @@
|
|||||||
"K1644b775": "新增",
|
"K1644b775": "新增",
|
||||||
"Kc8ee3e62": "不存在匹配",
|
"Kc8ee3e62": "不存在匹配",
|
||||||
"K1e97dbd8": "存在匹配",
|
"K1e97dbd8": "存在匹配",
|
||||||
"Kec91f0db": "申請方消費者"
|
"Kec91f0db": "申請方消費者",
|
||||||
|
"Kf5fd27ed": "輸入名稱查找使用者",
|
||||||
|
"K2ec0fa56": "支援將當前服務對接主流的 AI Agent 平台,實現在 Agent 平台上快速、安全和合規地使用企業開放的 API 能力。",
|
||||||
|
"K35f23b64": "可按以下步驟進行對接:",
|
||||||
|
"Kf5cd608b": "步驟一:Agent 平台上創建自定義插件",
|
||||||
|
"K4c81c7b6": "不同 Agent 平台的操作細節可查看",
|
||||||
|
"K275f7ffa": "《 Agent 對接手冊》",
|
||||||
|
"K49b81d06": "步驟二:導入 API 文檔數據",
|
||||||
|
"K4a3b62be": "可通過以下 URL 或下載 json 文件,導入 API 文檔數據到 Agent 平台中。",
|
||||||
|
"K42697e11": "複製 URL",
|
||||||
|
"K27a809c5": "下載 Json 文件",
|
||||||
|
"K1e61fdee": "步驟三:配置 API 密鑰",
|
||||||
|
"K55912595": "在",
|
||||||
|
"K33b1bc3": "菜單中,選擇已通過本 API 服務申請的消費者,",
|
||||||
|
"K62adc41e": "把「訪問權限」菜單下的密鑰填入到 Agent 平台對應的插件密鑰配置中。",
|
||||||
|
"Ke8cbb878": "全域策略",
|
||||||
|
"K34d0d409": "新增策略",
|
||||||
|
"Kbb4298ac": "輸入名稱、篩選條件查找",
|
||||||
|
"Kabac9caf": "資料脫敏",
|
||||||
|
"Kc975cd5a": "支援對系統全域進行統一的策略配置,從而簡化管理並確保一致性。全域策略的優先級比服務策略略低。",
|
||||||
|
"K52f72551": "服務策略",
|
||||||
|
"K931615d7": "策略名稱",
|
||||||
|
"K31faa2a1": "優先級",
|
||||||
|
"Kbdec9fa": "篩選條件",
|
||||||
|
"Kbcbb7391": "處理數",
|
||||||
|
"Kad207008": "編輯"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,15 @@ export const checkAccess:(access:AccessDataType, accessData:Map<string,string[]>
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
const neededBackendAccessArr = PERMISSION_DEFINITION[0]?.[access]?.granted?.anyOf[0].backend || []
|
const neededBackendAccessArr = PERMISSION_DEFINITION[0]?.[access]?.granted?.anyOf[0].backend || []
|
||||||
return accessData?.has(accLevel)&& accessData.get(accLevel)!.length > 0 ? hasIntersection(neededBackendAccessArr, accessData.get(accLevel)!) : false
|
let accessSet = new Set(accessData.get('system'))
|
||||||
|
if(accLevel === 'team'){
|
||||||
|
accessSet = new Set(Array.from(accessSet).concat(accessData?.get('team') || []))
|
||||||
|
}
|
||||||
|
return accessSet!.size > 0 ? hasIntersection(neededBackendAccessArr, accessSet) : false
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasIntersection = (arr1:string[], arr2:string[])=> {
|
const hasIntersection = (arr1:string[], set1:Set<string>)=> {
|
||||||
|
const arr2 = Array.from(set1)
|
||||||
const set = new Set(arr1.length > arr2.length ? arr2:arr1)
|
const set = new Set(arr1.length > arr2.length ? arr2:arr1)
|
||||||
const arr = arr1.length > arr2.length ? arr1:arr2
|
const arr = arr1.length > arr2.length ? arr1:arr2
|
||||||
for (const item of arr) {
|
for (const item of arr) {
|
||||||
|
|||||||
@@ -1,16 +1,36 @@
|
|||||||
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head id="head">
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/frontend/favicon.ico" />
|
<link id="favicon" rel="icon" type="image/svg+xml" href="/frontend/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>APIPark</title>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body id="eo-body">
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="/src/main.tsx"></script>
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
<script async src="/frontend/iconpark_eolink.js"></script>
|
<script>
|
||||||
<script async src="/frontend/iconpark_apinto.js"></script>
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const eoBody = document.getElementById('eo-body');
|
||||||
|
const favicon = document.getElementById('favicon');
|
||||||
|
|
||||||
|
const createScript = (id, src) => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.id = id;
|
||||||
|
script.async = true;
|
||||||
|
script.src = src;
|
||||||
|
return script;
|
||||||
|
};
|
||||||
|
|
||||||
|
const iconparkApintoSrc = window.location.hostname === 'localhost' ? '/iconpark_apinto.js' : '/frontend/iconpark_apinto.js';
|
||||||
|
const iconparkEolinkSrc = window.location.hostname === 'localhost' ? '/iconpark_eolink.js' : '/frontend/iconpark_eolink.js';
|
||||||
|
const faviconSrc = window.location.hostname === 'localhost' ? '/favicon.ico' : '/frontend/favicon.ico';
|
||||||
|
|
||||||
|
favicon.href = faviconSrc;
|
||||||
|
|
||||||
|
eoBody.appendChild(createScript('iconpark_apinto', iconparkApintoSrc));
|
||||||
|
eoBody.appendChild(createScript('iconpark_eolink', iconparkEolinkSrc));
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -290,3 +290,13 @@ a{
|
|||||||
transition: background-color 0s 600000s, color 0s 600000s !important;
|
transition: background-color 0s 600000s, color 0s 600000s !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-select-selection-overflow-item:first-child {
|
||||||
|
max-width: calc(100% - 60px);
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a[disabled]:hover {
|
||||||
|
color: #BBB;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -35,6 +35,7 @@ export type MemberDropdownModalFieldType = {
|
|||||||
parent?:string
|
parent?:string
|
||||||
email?:string
|
email?:string
|
||||||
departmentIds?:string[]
|
departmentIds?:string[]
|
||||||
|
password:string
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MemberDropdownModalProps = {
|
export type MemberDropdownModalProps = {
|
||||||
|
|||||||
@@ -1005,6 +1005,19 @@ p{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.global-policy-tabs {
|
||||||
|
.ant-tabs-nav {
|
||||||
|
&::before {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ant-tabs-content {
|
||||||
|
height: 100%;
|
||||||
|
.ant-tabs-tabpane {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.ant-tooltip{
|
.ant-tooltip{
|
||||||
max-width: 280px !important;
|
max-width: 280px !important;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ const AiServiceInsidePage:FC = ()=> {
|
|||||||
|
|
||||||
|
|
||||||
const getApiDefine = ()=>{
|
const getApiDefine = ()=>{
|
||||||
|
console.log('@@@@@@@')
|
||||||
setApiPrefix('')
|
setApiPrefix('')
|
||||||
setPrefixForce(false)
|
setPrefixForce(false)
|
||||||
fetchData<BasicResponse<{ prefix:string, force:boolean }>>('service/router/define',{method:'GET',eoParams:{service:serviceId,team:teamId}}).then(response=>{
|
fetchData<BasicResponse<{ prefix:string, force:boolean }>>('service/router/define',{method:'GET',eoParams:{service:serviceId,team:teamId}}).then(response=>{
|
||||||
@@ -84,19 +85,22 @@ const AiServiceInsidePage:FC = ()=> {
|
|||||||
const filterMenu = (menu:MenuItemGroupType<MenuItemType>[])=>{
|
const filterMenu = (menu:MenuItemGroupType<MenuItemType>[])=>{
|
||||||
const newMenu = cloneDeep(menu)
|
const newMenu = cloneDeep(menu)
|
||||||
return newMenu!.filter((m:MenuItemGroupType )=>{
|
return newMenu!.filter((m:MenuItemGroupType )=>{
|
||||||
if(m.children && m.children.length > 0){
|
if(m&&m.children && m.children.length > 0){
|
||||||
m.children = m.children.filter(
|
m.children = m.children.filter(
|
||||||
(c)=>(c&&(c as MenuItemType&{access:string} ).access ?
|
(c)=>{
|
||||||
|
if(!c) return false
|
||||||
|
return (((c as MenuItemType&{access:string} ).access ?
|
||||||
checkPermission((c as MenuItemType&{access:string} ).access as keyof typeof PERMISSION_DEFINITION[0]):
|
checkPermission((c as MenuItemType&{access:string} ).access as keyof typeof PERMISSION_DEFINITION[0]):
|
||||||
true))
|
true))})
|
||||||
}
|
}
|
||||||
return m.children && m.children.length > 0
|
return m.children && m.children.length > 0
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const filteredMenu = filterMenu(SYSTEM_PAGE_MENU_ITEMS as MenuItemGroupType<MenuItemType>[])
|
const filteredMenu = filterMenu(SYSTEM_PAGE_MENU_ITEMS as MenuItemGroupType<MenuItemType>[])
|
||||||
setActiveMenu((pre)=>{
|
const menu = activeMenu ?? filteredMenu[0]?.children ? filteredMenu[0]?.children?.[0]?.key : filteredMenu[0]?.key
|
||||||
return pre ?? 'route'
|
if(menu && currentUrl.split('/')[-1] !== menu){
|
||||||
})
|
navigateTo(`/service/${teamId}/aiInside/${serviceId}/${menu}`)
|
||||||
|
}
|
||||||
return filteredMenu || []
|
return filteredMenu || []
|
||||||
},[accessData,accessInit, SYSTEM_PAGE_MENU_ITEMS])
|
},[accessData,accessInit, SYSTEM_PAGE_MENU_ITEMS])
|
||||||
|
|
||||||
@@ -116,7 +120,7 @@ const AiServiceInsidePage:FC = ()=> {
|
|||||||
}, [currentUrl]);
|
}, [currentUrl]);
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
if(accessData && accessData.get('team') && accessData.get('team')?.indexOf('team.service.router.view') !== -1){
|
if(accessData && checkPermission('team.service.router.view')){
|
||||||
getApiDefine()
|
getApiDefine()
|
||||||
}
|
}
|
||||||
},[accessData])
|
},[accessData])
|
||||||
|
|||||||
@@ -58,7 +58,6 @@ const AiServiceRouterModelConfig = forwardRef<AiServiceRouterModelConfigHandle,
|
|||||||
const {code,data,msg} = response
|
const {code,data,msg} = response
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
if(code === STATUS_CODE.SUCCESS){
|
||||||
setLlmList(data.llms)
|
setLlmList(data.llms)
|
||||||
console.log(data)
|
|
||||||
form.setFieldsValue({
|
form.setFieldsValue({
|
||||||
id:data.provider.defaultLlm,
|
id:data.provider.defaultLlm,
|
||||||
config:data.llms.find(x=>x.id===data.provider.defaultLlm)?.config})
|
config:data.llms.find(x=>x.id===data.provider.defaultLlm)?.config})
|
||||||
|
|||||||
@@ -21,22 +21,22 @@ export default function Guide(){
|
|||||||
{
|
{
|
||||||
title: $t("配置你的 AI 模型"),
|
title: $t("配置你的 AI 模型"),
|
||||||
description: $t('通过 APIPark 快速接入各种 AI 模型,使用统一的格式来调用API,并且可以随意切换模型。'),
|
description: $t('通过 APIPark 快速接入各种 AI 模型,使用统一的格式来调用API,并且可以随意切换模型。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/pre-work/team'
|
link: 'https://docs.apipark.com/docs/system_setting/ai_model_providers'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: $t("创建 AI 服务和 API"),
|
title: $t("创建 AI 服务和 API"),
|
||||||
description: $t('创建 AI 类型的服务,并且你可以将 Prompt 提示词设置为一个 API,简化使用 AI 的流程。'),
|
description: $t('创建 AI 类型的服务,并且你可以将 Prompt 提示词设置为一个 API,简化使用 AI 的流程。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/provider/service'
|
link: 'https://docs.apipark.com/docs/services/ai_services'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: $t("创建调用 Token"),
|
title: $t("创建调用 Token"),
|
||||||
description: $t('为了安全地调用 API,你需要创建一个消费者以及Token。'),
|
description: $t('为了安全地调用 API,你需要创建一个消费者以及Token。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/suberscriber/application'
|
link: 'https://docs.apipark.com/docs/consumers'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: $t("调用"),
|
title: $t("调用"),
|
||||||
description: $t('现在你可以通过 Token 来调用这些 API。'),
|
description: $t('现在你可以通过 Token 来调用这些 API。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/suberscriber/application'
|
link: 'https://docs.apipark.com/docs/call_api'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -46,17 +46,17 @@ export default function Guide(){
|
|||||||
{
|
{
|
||||||
title: $t("创建 REST 服务和 API"),
|
title: $t("创建 REST 服务和 API"),
|
||||||
description: $t('创建 AI 类型的服务,并且你可以将 Prompt 提示词设置为一个 API,简化使用 AI 的流程。'),
|
description: $t('创建 AI 类型的服务,并且你可以将 Prompt 提示词设置为一个 API,简化使用 AI 的流程。'),
|
||||||
link: 'https://docs.apipark.com/docs/tutorials/api-market/service'
|
link: 'https://docs.apipark.com/docs/services/rest_services'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: $t("创建调用 Token"),
|
title: $t("创建调用 Token"),
|
||||||
description: $t('为了安全地调用 API,你需要创建一个消费者以及Token。'),
|
description: $t('为了安全地调用 API,你需要创建一个消费者以及Token。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/suberscriber/subscribe'
|
link: 'https://docs.apipark.com/docs/consumers'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: $t("调用"),
|
title: $t("调用"),
|
||||||
description: $t('现在你可以通过 Token 来调用这些 API。'),
|
description: $t('现在你可以通过 Token 来调用这些 API。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/provider/approve'
|
link: 'https://docs.apipark.com/docs/call_api'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -66,7 +66,7 @@ export default function Guide(){
|
|||||||
{
|
{
|
||||||
title: $t("统计 API 调用情况"),
|
title: $t("统计 API 调用情况"),
|
||||||
description: $t('仪表盘中提供了多种统计图表,帮助我们了解 API 的运行情况。'),
|
description: $t('仪表盘中提供了多种统计图表,帮助我们了解 API 的运行情况。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/pre-work/monitor'
|
link: 'https://docs.apipark.com/docs/analysis'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -78,17 +78,17 @@ export default function Guide(){
|
|||||||
{
|
{
|
||||||
title: $t("账号与角色"),
|
title: $t("账号与角色"),
|
||||||
description: $t('邀请你的团队成员加入 APIPark,共同管理和调用 API。'),
|
description: $t('邀请你的团队成员加入 APIPark,共同管理和调用 API。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/pre-work/team'
|
link: 'https://docs.apipark.com/docs/system_setting/account_role'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: $t("团队"),
|
title: $t("团队"),
|
||||||
description: $t('团队中包含了人员、消费者和服务,不同团队之间的消费者和服务数据是隔离的,可用于管理企业内部不同的部门/项目组/团队。'),
|
description: $t('团队中包含了人员、消费者和服务,不同团队之间的消费者和服务数据是隔离的,可用于管理企业内部不同的部门/项目组/团队。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/provider/service'
|
link: 'https://docs.apipark.com/docs/teams'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: $t("服务"),
|
title: $t("服务"),
|
||||||
description: $t('服务内包含一组 API,并且可以发布到 API 市场被其他团队使用。'),
|
description: $t('服务内包含一组 API,并且可以发布到 API 市场被其他团队使用。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/suberscriber/application'
|
link: 'https://docs.apipark.com/docs/category/-%E6%9C%8D%E5%8A%A1'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -98,12 +98,12 @@ export default function Guide(){
|
|||||||
{
|
{
|
||||||
title: $t("订阅服务"),
|
title: $t("订阅服务"),
|
||||||
description: $t('如果需要调用某个服务的 API,需要先订阅该服务,并且等待提供服务的团队审核后才可发起 API 请求。'),
|
description: $t('如果需要调用某个服务的 API,需要先订阅该服务,并且等待提供服务的团队审核后才可发起 API 请求。'),
|
||||||
link: 'https://docs.apipark.com/docs/tutorials/api-market/service'
|
link: 'https://docs.apipark.com/docs/developer_portal'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: $t("审核订阅申请"),
|
title: $t("审核订阅申请"),
|
||||||
description: $t('提供服务的团队可以审核来自其他团队的订阅申请,审核通过后的消费者才可发起 API 请求。'),
|
description: $t('提供服务的团队可以审核来自其他团队的订阅申请,审核通过后的消费者才可发起 API 请求。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/suberscriber/subscribe'
|
link: 'https://docs.apipark.com/docs/services/review_consumers'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -113,7 +113,7 @@ export default function Guide(){
|
|||||||
{
|
{
|
||||||
title: $t("日志"),
|
title: $t("日志"),
|
||||||
description: $t('APIPark 提供详尽的 API 调用日志,帮助企业监控、分析和审计 API 的运行状况。'),
|
description: $t('APIPark 提供详尽的 API 调用日志,帮助企业监控、分析和审计 API 的运行状况。'),
|
||||||
link: 'https://docs.apipark.com/docs/quick/pre-work/monitor'
|
link: 'https://docs.apipark.com/docs/system_setting/log/'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
import WithPermission from "@common/components/aoplatform/WithPermission";
|
||||||
import { useBreadcrumb } from "@common/contexts/BreadcrumbContext";
|
import { useBreadcrumb } from "@common/contexts/BreadcrumbContext";
|
||||||
import { $t } from "@common/locales";
|
import { $t } from "@common/locales";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
@@ -24,7 +25,7 @@ export default function LogSettingsInstruction() {
|
|||||||
<div className="h-[208px] w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px]">
|
<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">新增集群的地址、名称、描述和其他相关属性,以确保插件能够正确识别和连接到集群</p>
|
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">新增集群的地址、名称、描述和其他相关属性,以确保插件能够正确识别和连接到集群</p>
|
||||||
<p><Link to="/cluster">添加集群地址</Link></p>
|
<p><WithPermission access="system.settings.api_gateway.view" ><Link to="/cluster">添加集群地址</Link></WithPermission></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div></div>
|
</div></div>
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import {App, Form, Input, TreeSelect} from "antd";
|
import {App, Form, Input, TreeSelect} from "antd";
|
||||||
import {forwardRef, useEffect, useImperativeHandle, useState} from "react";
|
import {forwardRef, useEffect, useImperativeHandle, useMemo, useState} from "react";
|
||||||
import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx";
|
import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx";
|
||||||
import {useFetch} from "@common/hooks/http.ts";
|
import {useFetch} from "@common/hooks/http.ts";
|
||||||
import { MemberDropdownModalHandle, MemberDropdownModalProps, DepartmentListItem, MemberDropdownModalFieldType, MemberTableListItem } from "../../const/member/type.ts";
|
import { MemberDropdownModalHandle, MemberDropdownModalProps, DepartmentListItem, MemberDropdownModalFieldType, MemberTableListItem } from "../../const/member/type.ts";
|
||||||
import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
|
import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
|
||||||
import { $t } from "@common/locales/index.ts";
|
import { $t } from "@common/locales/index.ts";
|
||||||
|
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
|
||||||
|
|
||||||
export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDropdownModalProps>((props,ref)=>{
|
export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDropdownModalProps>((props,ref)=>{
|
||||||
const { message} = App.useApp()
|
const { message} = App.useApp()
|
||||||
@@ -12,6 +13,7 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
|
|||||||
const {type,entity,selectedMemberGroupId} = props
|
const {type,entity,selectedMemberGroupId} = props
|
||||||
const {fetchData} = useFetch()
|
const {fetchData} = useFetch()
|
||||||
const [departmentList, setDepartmentList] = useState<DepartmentListItem[]>([])
|
const [departmentList, setDepartmentList] = useState<DepartmentListItem[]>([])
|
||||||
|
const { state } = useGlobalContext()
|
||||||
|
|
||||||
const save:()=>Promise<boolean | string> = ()=>{
|
const save:()=>Promise<boolean | string> = ()=>{
|
||||||
let url:string
|
let url:string
|
||||||
@@ -78,6 +80,15 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const generateRandomString = () =>{
|
||||||
|
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
let result = '';
|
||||||
|
for (let i = 0; i < 8; i++) {
|
||||||
|
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
switch(type){
|
switch(type){
|
||||||
case 'addChild':
|
case 'addChild':
|
||||||
@@ -87,7 +98,7 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
|
|||||||
form.setFieldsValue({id:entity!.id,name:entity!.name})
|
form.setFieldsValue({id:entity!.id,name:entity!.name})
|
||||||
break
|
break
|
||||||
case 'addMember':
|
case 'addMember':
|
||||||
form.setFieldsValue('-1' === selectedMemberGroupId ? {} : {departmentIds:selectedMemberGroupId})
|
form.setFieldsValue({...('-1' === selectedMemberGroupId ? {} : {departmentIds:selectedMemberGroupId}), password:generateRandomString()})
|
||||||
break
|
break
|
||||||
case 'editMember':
|
case 'editMember':
|
||||||
form.setFieldsValue({...entity,departmentIds:(entity as MemberTableListItem )?.department?.map(x=>x.id)})
|
form.setFieldsValue({...entity,departmentIds:(entity as MemberTableListItem )?.department?.map(x=>x.id)})
|
||||||
@@ -97,6 +108,23 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
|
|||||||
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
const treeData = useMemo(() => {
|
||||||
|
const loop = (data: DepartmentListItem[]): unknown[] =>
|
||||||
|
data?.map((item) => {
|
||||||
|
const title = ['unknown','disable'].indexOf(item.id) === -1 ?item.name : $t(item.name) as string;
|
||||||
|
if (item.children) {
|
||||||
|
return {...item,name:title, children:loop(item.children)}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
name: title
|
||||||
|
};
|
||||||
|
});
|
||||||
|
return loop(departmentList);
|
||||||
|
}, [departmentList,state.language]);
|
||||||
|
|
||||||
|
|
||||||
return (<WithPermission access="">
|
return (<WithPermission access="">
|
||||||
<Form
|
<Form
|
||||||
@@ -163,6 +191,13 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
|
|||||||
>
|
>
|
||||||
<Input className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)}/>
|
<Input className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
<Form.Item<MemberDropdownModalFieldType>
|
||||||
|
label={$t("密码")}
|
||||||
|
name="password"
|
||||||
|
rules={[{required: type === 'addMember',whitespace:true }]}
|
||||||
|
>
|
||||||
|
<Input className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)}/>
|
||||||
|
</Form.Item>
|
||||||
<Form.Item<MemberDropdownModalFieldType>
|
<Form.Item<MemberDropdownModalFieldType>
|
||||||
label={$t("部门")}
|
label={$t("部门")}
|
||||||
name="departmentIds"
|
name="departmentIds"
|
||||||
@@ -175,7 +210,7 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
|
|||||||
placeholder={$t(PLACEHOLDER.select)}
|
placeholder={$t(PLACEHOLDER.select)}
|
||||||
allowClear
|
allowClear
|
||||||
treeDefaultExpandAll
|
treeDefaultExpandAll
|
||||||
treeData={departmentList}
|
treeData={treeData}
|
||||||
multiple
|
multiple
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ const MemberList = ()=>{
|
|||||||
<WithPermission access="system.organization.member.edit">
|
<WithPermission access="system.organization.member.edit">
|
||||||
<Select
|
<Select
|
||||||
className="w-full"
|
className="w-full"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
value={entity.roles?.map((x:EntityItem)=>x.id)}
|
value={entity.roles?.map((x:EntityItem)=>x.id)}
|
||||||
options={roleSelectableList?.map((x:{id:string,name:string})=>({label:(x.name), value:x.id}))}
|
options={roleSelectableList?.map((x:{id:string,name:string})=>({label:(x.name), value:x.id}))}
|
||||||
onChange={(value)=>{
|
onChange={(value)=>{
|
||||||
|
|||||||
@@ -0,0 +1,464 @@
|
|||||||
|
import { ActionType } from "@ant-design/pro-components";
|
||||||
|
import { useMemo, useRef, useState } from "react";
|
||||||
|
import { Button, message, Switch } from 'antd'
|
||||||
|
import PageList, { PageProColumns } from "@common/components/aoplatform/PageList";
|
||||||
|
import { DATA_MASSKING_TABLE_COLUMNS } from './dataMaskingColumn'
|
||||||
|
import { $t } from "@common/locales";
|
||||||
|
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
|
||||||
|
import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const.tsx";
|
||||||
|
import { useFetch } from "@common/hooks/http";
|
||||||
|
import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
|
||||||
|
import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPermission";
|
||||||
|
|
||||||
|
|
||||||
|
const DataMasking = (props: any) => {
|
||||||
|
|
||||||
|
const {
|
||||||
|
// 是否显示发布按钮
|
||||||
|
publishBtn = false,
|
||||||
|
// 行操作
|
||||||
|
rowOperation = []
|
||||||
|
} = props;
|
||||||
|
const { checkPermission, getGlobalAccessData, accessInit, state } = useGlobalContext()
|
||||||
|
/**
|
||||||
|
* 列表ref
|
||||||
|
*/
|
||||||
|
const pageListRef = useRef<ActionType>(null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格数据重新加载
|
||||||
|
*/
|
||||||
|
const [tableHttpReload, setTableHttpReload] = useState(true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格数据
|
||||||
|
*/
|
||||||
|
const [tableListDataSource, setTableListDataSource] = useState<ServiceHubAppListItem[]>([]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求数据
|
||||||
|
*/
|
||||||
|
const { fetchData } = useFetch()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索关键字
|
||||||
|
*/
|
||||||
|
const [searchWord, setSearchWord] = useState<string>('')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取列数据,国际化变化时重新获取
|
||||||
|
*/
|
||||||
|
const columns = useMemo(() => {
|
||||||
|
const res = DATA_MASSKING_TABLE_COLUMNS.map(x => {
|
||||||
|
// 启动列渲染
|
||||||
|
if (x.dataIndex === 'enabled') {
|
||||||
|
x.render = (text: any, record: any) => <Switch checked={record.enabled} onChange={(e) => { changeOpenApiStatus(e, record) }} />
|
||||||
|
}
|
||||||
|
// 处理数列渲染
|
||||||
|
if (x.dataIndex === 'treatmentNumber') {
|
||||||
|
x.render = (text: any, record: any) => <span className="w-full block cursor-pointer [&>.ant-typography]:text-theme" onClick={(e) => { openLogsModal(record) }} >{ text }</span>
|
||||||
|
}
|
||||||
|
// 名称筛选,这里是全量返回时候的,分页的话应该要接口返回对应的筛选数据
|
||||||
|
if (x.dataIndex === 'name') {
|
||||||
|
const nameList = tableListDataSource.map(item => item.name)
|
||||||
|
const valueEnum: any = {}
|
||||||
|
nameList.forEach(item => {
|
||||||
|
valueEnum[item] = { text: item }
|
||||||
|
})
|
||||||
|
x.valueEnum = valueEnum
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
...x,
|
||||||
|
title: typeof x.title === 'string' ? $t(x.title as string) : x.title
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
}, [tableListDataSource, state.language])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作列
|
||||||
|
*/
|
||||||
|
const operation: PageProColumns<any>[] = rowOperation.length ? [
|
||||||
|
{
|
||||||
|
title: '',
|
||||||
|
key: 'option',
|
||||||
|
btnNums: rowOperation.length,
|
||||||
|
fixed: 'right',
|
||||||
|
valueType: 'option',
|
||||||
|
render: (_: React.ReactNode, entity: any) => [
|
||||||
|
...(rowOperation.length && rowOperation.find((item: string) => item === 'edit') ? [<TableBtnWithPermission access="system.organization.member.edit" key="edit" btnType="edit" onClick={() => { openEditModal(entity) }} btnTitle="编辑" />] : []),
|
||||||
|
...(rowOperation.length && rowOperation.find((item: string) => item === 'logs') ? [<TableBtnWithPermission access="system.organization.member.edit" key="logs" btnType="logs" onClick={() => { openLogsModal(entity) }} btnTitle="详情" />] : []),
|
||||||
|
...(rowOperation.length && rowOperation.find((item: string) => item === 'delete') ? [<TableBtnWithPermission access="system.organization.member.edit" key="delete" btnType="delete" onClick={() => { deletePolicy(entity) }} btnTitle="删除" />] : []),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
] : []
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手动刷新表格数据
|
||||||
|
*/
|
||||||
|
const manualReloadTable = () => {
|
||||||
|
setTableHttpReload(true)
|
||||||
|
pageListRef.current?.reload()
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更改启动状态
|
||||||
|
* @param enabled 状态
|
||||||
|
* @param entity 行数据
|
||||||
|
*/
|
||||||
|
const changeOpenApiStatus = (enabled: boolean, entity: any) => {
|
||||||
|
console.log('更改启动状态', enabled, entity);
|
||||||
|
|
||||||
|
manualReloadTable()
|
||||||
|
// 待补充,请求接口更改状态,然后刷新表格
|
||||||
|
// fetchData<BasicResponse<null>>(
|
||||||
|
// `external-app/${enabled ? 'disable' : 'enable'}`,
|
||||||
|
// {
|
||||||
|
// method: 'PUT',
|
||||||
|
// eoParams: {
|
||||||
|
// id: entity.id
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ).then(response => {
|
||||||
|
// const { code, msg } = response
|
||||||
|
// if (code === STATUS_CODE.SUCCESS) {
|
||||||
|
// message.success(msg || $t(RESPONSE_TIPS.success))
|
||||||
|
// manualReloadTable()
|
||||||
|
// } else {
|
||||||
|
// message.error(msg || $t(RESPONSE_TIPS.error))
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取列表数据
|
||||||
|
* @param dataType
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
const getServiceList = () => {
|
||||||
|
if (!accessInit) {
|
||||||
|
getGlobalAccessData()?.then?.(() => { getServiceList() })
|
||||||
|
return Promise.resolve({ data: [], success: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tableHttpReload) {
|
||||||
|
setTableHttpReload(true)
|
||||||
|
return Promise.resolve({
|
||||||
|
data: tableListDataSource,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return fetchData<BasicResponse<any>>(
|
||||||
|
!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) {
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
name: 'test',
|
||||||
|
priority: 1,
|
||||||
|
status: true,
|
||||||
|
enabled: true,
|
||||||
|
condition: 'test',
|
||||||
|
treatmentNumber: 1,
|
||||||
|
updater: 'test',
|
||||||
|
createTime: '2021-10-01'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'test2',
|
||||||
|
priority: 2,
|
||||||
|
status: false,
|
||||||
|
enabled: false,
|
||||||
|
condition: 'test2',
|
||||||
|
treatmentNumber: 2,
|
||||||
|
updater: 'test2',
|
||||||
|
createTime: '2021-10-02'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
// 保存数据
|
||||||
|
setTableListDataSource(data)
|
||||||
|
setTableHttpReload(false)
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
success: true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||||
|
return { data: [], success: false }
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
return { data: [], success: false }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加策略
|
||||||
|
* @param type
|
||||||
|
*/
|
||||||
|
const addPolicy = () => {
|
||||||
|
console.log('添加策略');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布策略
|
||||||
|
*/
|
||||||
|
const publish = () => {
|
||||||
|
console.log('发布策略');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
*/
|
||||||
|
const openEditModal = (entity: any) => {
|
||||||
|
console.log('编辑', entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日志
|
||||||
|
* @param entity
|
||||||
|
*/
|
||||||
|
const openLogsModal = (entity: any) => {
|
||||||
|
console.log('日志', entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除
|
||||||
|
* @param entity
|
||||||
|
*/
|
||||||
|
const deletePolicy = (entity: any) => {
|
||||||
|
console.log('删除', entity);
|
||||||
|
manualReloadTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageList
|
||||||
|
id="data_masking_list"
|
||||||
|
ref={pageListRef}
|
||||||
|
columns={[...columns, ...operation]}
|
||||||
|
request={() => getServiceList()}
|
||||||
|
addNewBtnTitle={$t("添加策略")}
|
||||||
|
onAddNewBtnClick={() => { addPolicy() }}
|
||||||
|
searchPlaceholder={$t("输入名称、筛选条件查找")}
|
||||||
|
afterNewBtn={
|
||||||
|
publishBtn && [<WithPermission key="removeFromDepPermission" access="system.organization.member.edit"><Button className="mr-btnbase" key="removeFromDep" onClick={() => publish()}>{$t('发布')}</Button></WithPermission>]
|
||||||
|
}
|
||||||
|
onSearchWordChange={(e) => {
|
||||||
|
setSearchWord(e.target.value)
|
||||||
|
}}
|
||||||
|
manualReloadTable={manualReloadTable}
|
||||||
|
onChange={() => {
|
||||||
|
setTableHttpReload(false)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DataMasking;
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
import { PageProColumns } from "@common/components/aoplatform/PageList";
|
||||||
|
import { frontendTimeSorter } from "@common/utils/dataTransfer";
|
||||||
|
import { $t } from "@common/locales";
|
||||||
|
|
||||||
|
export const DATA_MASSKING_TABLE_COLUMNS: PageProColumns<any>[] = [
|
||||||
|
{
|
||||||
|
title: ('策略名称'),
|
||||||
|
dataIndex: 'name',
|
||||||
|
ellipsis: true,
|
||||||
|
filters: true,
|
||||||
|
onFilter: true,
|
||||||
|
valueType: 'select',
|
||||||
|
filterSearch: true,
|
||||||
|
width: 160
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: ('优先级'),
|
||||||
|
dataIndex: 'priority',
|
||||||
|
width: 140,
|
||||||
|
ellipsis: true,
|
||||||
|
sorter: (a: any, b: any) => {
|
||||||
|
return (a.priority as number) - (b.priority as number)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: ('发布状态'),
|
||||||
|
dataIndex: 'status',
|
||||||
|
filters: true,
|
||||||
|
onFilter: true,
|
||||||
|
width: 140,
|
||||||
|
valueEnum: new Map([
|
||||||
|
[true, <span className="text-status_success">{$t('已发布')}</span>],
|
||||||
|
[false, <span className="text-status_fail">{$t('未发布')}</span>]
|
||||||
|
])
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: ('启用'),
|
||||||
|
dataIndex: 'enabled',
|
||||||
|
filters: true,
|
||||||
|
onFilter: true,
|
||||||
|
valueEnum: {
|
||||||
|
true: { text: <span className="text-status_success">{$t('启用')}</span> },
|
||||||
|
false: { text: <span className="text-status_fail">{$t('禁用')}</span> }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: ('筛选条件'),
|
||||||
|
dataIndex: 'condition',
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: ('处理数'),
|
||||||
|
dataIndex: 'treatmentNumber',
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: ('更新者'),
|
||||||
|
dataIndex: 'updater',
|
||||||
|
width: 140,
|
||||||
|
ellipsis: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: ('更新时间'),
|
||||||
|
dataIndex: 'createTime',
|
||||||
|
width: 182,
|
||||||
|
ellipsis: true,
|
||||||
|
sorter: (a, b) => frontendTimeSorter(a, b, 'createTime')
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import InsidePage from "@common/components/aoplatform/InsidePage.tsx";
|
||||||
|
import { $t } from "@common/locales/index.ts";
|
||||||
|
import PolicyTabContainer from "./policyTabContainer.tsx";
|
||||||
|
import DataMasking from "./dataMasking.tsx";
|
||||||
|
|
||||||
|
|
||||||
|
const PartitionInsideGlobalPolicy = () => {
|
||||||
|
/**
|
||||||
|
* tab列表
|
||||||
|
*/
|
||||||
|
const tabItems = [
|
||||||
|
{
|
||||||
|
key: 'dataMasking',
|
||||||
|
label: $t('数据脱敏'),
|
||||||
|
children: <div className="pr-[40px] preview-document h-full pb-[40px]"><DataMasking publishBtn rowOperation={['edit', 'logs', 'delete']} /></div>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<InsidePage
|
||||||
|
pageTitle={$t('全局策略')}
|
||||||
|
description={$t("支持对系统全局进行统一的策略配置,从而简化管理并确保一致性。全局策略的优先级比服务策略略低。")}
|
||||||
|
showBorder={false}
|
||||||
|
scrollPage={false}
|
||||||
|
>
|
||||||
|
<PolicyTabContainer tabs={tabItems} />
|
||||||
|
</InsidePage>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PartitionInsideGlobalPolicy
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { Tabs } from "antd";
|
||||||
|
|
||||||
|
const PolicyTabContainer = (props: any) => {
|
||||||
|
/**
|
||||||
|
* 支持的tab
|
||||||
|
*/
|
||||||
|
const { tabs } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Tabs
|
||||||
|
className="overflow-hidden h-full [&>.ant-tabs-content-holder]:overflow-auto global-policy-tabs"
|
||||||
|
items={tabs}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PolicyTabContainer;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { $t } from "@common/locales/index.ts";
|
||||||
|
import DataMasking from "@core/pages/policy/dataMasking";
|
||||||
|
import PolicyTabContainer from "@core/pages/policy/policyTabContainer";
|
||||||
|
|
||||||
|
const servicePolicy = () => {
|
||||||
|
/**
|
||||||
|
* tab列表
|
||||||
|
*/
|
||||||
|
const tabItems = [
|
||||||
|
{
|
||||||
|
key: 'dataMasking',
|
||||||
|
label: $t('数据脱敏'),
|
||||||
|
children: <div className="pr-[40px] h-full preview-document mb-PAGE_INSIDE_B"><DataMasking rowOperation={['edit', 'logs', 'delete']} /></div>
|
||||||
|
}
|
||||||
|
]
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PolicyTabContainer tabs={tabItems} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default servicePolicy;
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import WithPermission from "@common/components/aoplatform/WithPermission";
|
||||||
import { useBreadcrumb } from "@common/contexts/BreadcrumbContext";
|
import { useBreadcrumb } from "@common/contexts/BreadcrumbContext";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
@@ -24,7 +25,7 @@ export default function ResourceSettingsInstruction() {
|
|||||||
<div className="h-[208px] w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px]">
|
<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">新增集群地址、描述和其他相关属性,以确保插件能够正确识别和连接到集群</p>
|
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">新增集群地址、描述和其他相关属性,以确保插件能够正确识别和连接到集群</p>
|
||||||
<p><Link to="/cluster">配置集群地址</Link></p>
|
<p><WithPermission access="system.settings.data_source.view" ><Link to="/cluster">配置集群地址</Link></WithPermission></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div></div>
|
</div></div>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
|
|
||||||
import {FC, useEffect, useMemo, useState} from "react";
|
import { FC, useEffect, useMemo, useState } from "react";
|
||||||
import {Link, Outlet, useLocation, useNavigate, useParams} from "react-router-dom";
|
import { Link, Outlet, useLocation, useNavigate, useParams } from "react-router-dom";
|
||||||
import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx";
|
import { RouterParams } from "@core/components/aoplatform/RenderRoutes.tsx";
|
||||||
import {App, Menu, MenuProps} from "antd";
|
import { App, Menu, MenuProps } from "antd";
|
||||||
import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx";
|
import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const.tsx";
|
||||||
import {useFetch} from "@common/hooks/http.ts";
|
import { useFetch } from "@common/hooks/http.ts";
|
||||||
import { useSystemContext} from "../../contexts/SystemContext.tsx";
|
import { useSystemContext } from "../../contexts/SystemContext.tsx";
|
||||||
import { SystemConfigFieldType } from "../../const/system/type.ts";
|
import { SystemConfigFieldType } from "../../const/system/type.ts";
|
||||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
|
import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx";
|
||||||
import { PERMISSION_DEFINITION } from "@common/const/permissions.ts";
|
import { PERMISSION_DEFINITION } from "@common/const/permissions.ts";
|
||||||
@@ -17,143 +17,147 @@ import { $t } from "@common/locales/index.ts";
|
|||||||
import { getItem } from "@common/utils/navigation.tsx";
|
import { getItem } from "@common/utils/navigation.tsx";
|
||||||
const APP_MODE = import.meta.env.VITE_APP_MODE;
|
const APP_MODE = import.meta.env.VITE_APP_MODE;
|
||||||
|
|
||||||
const SystemInsidePage:FC = ()=> {
|
const SystemInsidePage: FC = () => {
|
||||||
const { message } = App.useApp()
|
const { message } = App.useApp()
|
||||||
const { teamId,serviceId,apiId,routeId} = useParams<RouterParams>();
|
const { teamId, serviceId, apiId, routeId } = useParams<RouterParams>();
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const currentUrl = location.pathname
|
const currentUrl = location.pathname
|
||||||
const {fetchData} = useFetch()
|
const { fetchData } = useFetch()
|
||||||
const { setPrefixForce,setApiPrefix ,systemInfo,setSystemInfo} = useSystemContext()
|
const { setPrefixForce, setApiPrefix, systemInfo, setSystemInfo } = useSystemContext()
|
||||||
const { accessData,checkPermission,accessInit,state} = useGlobalContext()
|
const { accessData, checkPermission, accessInit, state } = useGlobalContext()
|
||||||
const [activeMenu, setActiveMenu] = useState<string>()
|
const [activeMenu, setActiveMenu] = useState<string>()
|
||||||
const navigateTo = useNavigate()
|
const navigateTo = useNavigate()
|
||||||
const [showMenu, setShowMenu] = useState<boolean>(false)
|
const [showMenu, setShowMenu] = useState<boolean>(false)
|
||||||
|
|
||||||
const getSystemInfo = ()=>{
|
const getSystemInfo = () => {
|
||||||
fetchData<BasicResponse<{ service:SystemConfigFieldType }>>('service/info',{method:'GET',eoParams:{team:teamId, service:serviceId}}).then(response=>{
|
fetchData<BasicResponse<{ service: SystemConfigFieldType }>>('service/info', { method: 'GET', eoParams: { team: teamId, service: serviceId } }).then(response => {
|
||||||
const {code,data,msg} = response
|
const { code, data, msg } = response
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
if (code === STATUS_CODE.SUCCESS) {
|
||||||
setSystemInfo(data.service)
|
setSystemInfo(data.service)
|
||||||
}else{
|
} else {
|
||||||
message.error(msg || $t(RESPONSE_TIPS.error))
|
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const getApiDefine = ()=>{
|
const getApiDefine = () => {
|
||||||
setApiPrefix('')
|
setApiPrefix('')
|
||||||
setPrefixForce(false)
|
setPrefixForce(false)
|
||||||
fetchData<BasicResponse<{ prefix:string, force:boolean }>>('service/router/define',{method:'GET',eoParams:{service:serviceId,team:teamId}}).then(response=>{
|
fetchData<BasicResponse<{ prefix: string, force: boolean }>>('service/router/define', { method: 'GET', eoParams: { service: serviceId, team: teamId } }).then(response => {
|
||||||
const {code,data,msg} = response
|
const { code, data, msg } = response
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
if (code === STATUS_CODE.SUCCESS) {
|
||||||
setApiPrefix(data.prefix)
|
setApiPrefix(data.prefix)
|
||||||
setPrefixForce(data.force)
|
setPrefixForce(data.force)
|
||||||
}else{
|
} else {
|
||||||
message.error(msg || $t(RESPONSE_TIPS.error))
|
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const SYSTEM_PAGE_MENU_ITEMS = useMemo(()=>[
|
|
||||||
|
const SYSTEM_PAGE_MENU_ITEMS = useMemo(() => [
|
||||||
getItem($t('服务'), 'assets', null,
|
getItem($t('服务'), 'assets', null,
|
||||||
[
|
[
|
||||||
getItem(<Link to="./route">{$t('API 路由')}</Link>, 'route',undefined,undefined,undefined,'team.service.router.view'),
|
getItem(<Link to="./route">{$t('API 路由')}</Link>, 'route', undefined, undefined, undefined, 'team.service.router.view'),
|
||||||
getItem(<Link to="./api">{$t('API 文档')}</Link>, 'api',undefined,undefined,undefined,'team.service.api_doc.view'),
|
getItem(<Link to="./api">{$t('API 文档')}</Link>, 'api', undefined, undefined, undefined, 'team.service.api_doc.view'),
|
||||||
getItem(<Link to="./upstream">{$t('上游')}</Link>, 'upstream',undefined,undefined,undefined,'team.service.upstream.view'),
|
getItem(<Link to="./upstream">{$t('上游')}</Link>, 'upstream', undefined, undefined, undefined, 'team.service.upstream.view'),
|
||||||
getItem(<Link to="./document">{$t('使用说明')}</Link>, 'document',undefined,undefined,undefined,'team.service.service_intro.view'),
|
getItem(<Link to="./document">{$t('使用说明')}</Link>, 'document', undefined, undefined, undefined, 'team.service.service_intro.view'),
|
||||||
getItem(<Link to="./publish">{$t('发布')}</Link>, 'publish',undefined,undefined,undefined,'team.service.release.view'),
|
getItem(<Link to="./servicePolicy">{$t('服务策略')}</Link>, 'servicePolicy', undefined, undefined, undefined, 'team.service.service_intro.view'),
|
||||||
],
|
getItem(<Link to="./publish">{$t('发布')}</Link>, 'publish', undefined, undefined, undefined, 'team.service.release.view'),
|
||||||
'group'),
|
],
|
||||||
|
'group'),
|
||||||
getItem($t('订阅管理'), 'provideSer', null,
|
getItem($t('订阅管理'), 'provideSer', null,
|
||||||
[
|
[
|
||||||
getItem(<Link to="./approval">{$t('订阅审核')}</Link>, 'approval',undefined,undefined,undefined,'team.service.subscription.view'),
|
getItem(<Link to="./approval">{$t('订阅审核')}</Link>, 'approval', undefined, undefined, undefined, 'team.service.subscription.view'),
|
||||||
getItem(<Link to="./subscriber">{$t('订阅方管理')}</Link>, 'subscriber',undefined,undefined,undefined,'team.service.subscription.view'),
|
getItem(<Link to="./subscriber">{$t('订阅方管理')}</Link>, 'subscriber', undefined, undefined, undefined, 'team.service.subscription.view'),
|
||||||
],
|
],
|
||||||
'group'),
|
'group'),
|
||||||
getItem($t('管理'), 'mng', null,
|
getItem($t('管理'), 'mng', null,
|
||||||
[
|
[
|
||||||
APP_MODE === 'pro' ? getItem(<Link to="./topology">{$t('调用拓扑图')}</Link>, 'topology',undefined,undefined,undefined,'project.mySystem.topology.view'):null,
|
APP_MODE === 'pro' ? getItem(<Link to="./topology">{$t('调用拓扑图')}</Link>, 'topology', undefined, undefined, undefined, 'project.mySystem.topology.view') : null,
|
||||||
getItem(<Link to="./setting">{$t('设置')}</Link>, 'setting',undefined,undefined,undefined,'')],
|
getItem(<Link to="./setting">{$t('设置')}</Link>, 'setting', undefined, undefined, undefined, '')],
|
||||||
'group'),
|
'group'),
|
||||||
],[state.language])
|
], [state.language])
|
||||||
|
|
||||||
|
|
||||||
const menuData = useMemo(()=>{
|
const menuData = useMemo(() => {
|
||||||
const filterMenu = (menu:MenuItemGroupType<MenuItemType>[])=>{
|
const filterMenu = (menu: MenuItemGroupType<MenuItemType>[]) => {
|
||||||
const newMenu = cloneDeep(menu)
|
const newMenu = cloneDeep(menu)
|
||||||
return newMenu!.filter((m:MenuItemGroupType )=>{
|
return newMenu!.filter((m: MenuItemGroupType) => {
|
||||||
if(m.children && m.children.length > 0){
|
if (m && m.children && m.children.length > 0) {
|
||||||
m.children = m.children.filter(
|
m.children = m.children.filter(
|
||||||
(c)=>(c&&(c as MenuItemType&{access:string} ).access ?
|
(c) => {
|
||||||
checkPermission((c as MenuItemType&{access:string} ).access as keyof typeof PERMISSION_DEFINITION[0]):
|
if (!c) return false
|
||||||
true))
|
return (((c as MenuItemType & { access: string }).access ?
|
||||||
}
|
checkPermission((c as MenuItemType & { access: string }).access as keyof typeof PERMISSION_DEFINITION[0]) :
|
||||||
return m.children && m.children.length > 0
|
true))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const filteredMenu = filterMenu(SYSTEM_PAGE_MENU_ITEMS as MenuItemGroupType<MenuItemType>[])
|
return m.children && m.children.length > 0
|
||||||
setActiveMenu((pre)=>{
|
})
|
||||||
return pre ?? 'route'
|
}
|
||||||
})
|
const filteredMenu = filterMenu(SYSTEM_PAGE_MENU_ITEMS as MenuItemGroupType<MenuItemType>[])
|
||||||
return filteredMenu || []
|
const menu = activeMenu ?? filteredMenu[0]?.children ? filteredMenu[0]?.children?.[0]?.key : filteredMenu[0]?.key
|
||||||
},[accessData,accessInit, SYSTEM_PAGE_MENU_ITEMS])
|
if (menu && currentUrl.split('/')[-1] !== menu) navigateTo(`/service/${teamId}/inside/${serviceId}/${menu}`)
|
||||||
|
return filteredMenu || []
|
||||||
const onMenuClick: MenuProps['onClick'] = ({key}) => {
|
}, [accessData, accessInit, SYSTEM_PAGE_MENU_ITEMS])
|
||||||
setActiveMenu(key)
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setShowMenu(!routeId && !currentUrl.includes('route/create'))
|
|
||||||
if(apiId !== undefined){
|
|
||||||
setActiveMenu('api')
|
|
||||||
}else if(serviceId !== currentUrl.split('/')[currentUrl.split('/').length - 1]){
|
|
||||||
setActiveMenu(currentUrl.split('/')[currentUrl.split('/').length - 1])
|
|
||||||
}else{
|
|
||||||
setActiveMenu('route')
|
|
||||||
}
|
|
||||||
}, [currentUrl]);
|
|
||||||
|
|
||||||
useEffect(()=>{
|
const onMenuClick: MenuProps['onClick'] = ({ key }) => {
|
||||||
if(accessData && accessData.get('team') && accessData.get('team')?.indexOf('team.service.router.view') !== -1){
|
setActiveMenu(key)
|
||||||
getApiDefine()
|
};
|
||||||
}
|
|
||||||
},[accessData])
|
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(() => {
|
||||||
if( activeMenu && serviceId === currentUrl.split('/')[currentUrl.split('/').length - 1]){
|
setShowMenu(!routeId && !currentUrl.includes('route/create'))
|
||||||
navigateTo(`/service/${teamId}/inside/${serviceId}/${activeMenu}`)
|
if (apiId !== undefined) {
|
||||||
}
|
setActiveMenu('api')
|
||||||
},[activeMenu])
|
} else if (serviceId !== currentUrl.split('/')[currentUrl.split('/').length - 1]) {
|
||||||
|
setActiveMenu(currentUrl.split('/')[currentUrl.split('/').length - 1])
|
||||||
|
} else {
|
||||||
|
setActiveMenu('route')
|
||||||
|
}
|
||||||
|
}, [currentUrl]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
serviceId && getSystemInfo()
|
if (accessData && checkPermission('team.service.router.view')) {
|
||||||
}, [serviceId]);
|
getApiDefine()
|
||||||
|
}
|
||||||
|
}, [accessData])
|
||||||
|
|
||||||
return (
|
useEffect(() => {
|
||||||
<>{showMenu ?
|
if (activeMenu && serviceId === currentUrl.split('/')[currentUrl.split('/').length - 1]) {
|
||||||
<InsidePage pageTitle={systemInfo?.name || '-'}
|
navigateTo(`/service/${teamId}/inside/${serviceId}/${activeMenu}`)
|
||||||
tagList={[{label:
|
}
|
||||||
<Paragraph className="mb-0" copyable={serviceId ? { text: serviceId } : false}>{$t('服务 ID')}:{serviceId || '-'}</Paragraph>
|
}, [activeMenu])
|
||||||
}]}
|
|
||||||
backUrl="/service/list">
|
|
||||||
<div className="flex flex-1 h-full">
|
|
||||||
<Menu
|
|
||||||
onClick={onMenuClick}
|
|
||||||
className="h-full overflow-y-auto"
|
|
||||||
style={{ width: 220 }}
|
|
||||||
selectedKeys={[activeMenu!]}
|
|
||||||
mode="inline"
|
|
||||||
items={menuData as unknown as ItemType<MenuItemType>[] }
|
|
||||||
/>
|
|
||||||
<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>
|
|
||||||
</InsidePage>: <Outlet/> }
|
|
||||||
|
|
||||||
</>
|
useEffect(() => {
|
||||||
)
|
serviceId && getSystemInfo()
|
||||||
|
}, [serviceId]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>{showMenu ?
|
||||||
|
<InsidePage pageTitle={systemInfo?.name || '-'}
|
||||||
|
tagList={[{
|
||||||
|
label:
|
||||||
|
<Paragraph className="mb-0" copyable={serviceId ? { text: serviceId } : false}>{$t('服务 ID')}:{serviceId || '-'}</Paragraph>
|
||||||
|
}]}
|
||||||
|
backUrl="/service/list">
|
||||||
|
<div className="flex flex-1 h-full">
|
||||||
|
<Menu
|
||||||
|
onClick={onMenuClick}
|
||||||
|
className="h-full overflow-y-auto"
|
||||||
|
style={{ width: 220 }}
|
||||||
|
selectedKeys={[activeMenu!]}
|
||||||
|
mode="inline"
|
||||||
|
items={menuData as unknown as ItemType<MenuItemType>[]}
|
||||||
|
/>
|
||||||
|
<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>
|
||||||
|
</InsidePage> : <Outlet />}
|
||||||
|
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
export default SystemInsidePage
|
export default SystemInsidePage
|
||||||
@@ -34,7 +34,7 @@ const TeamConfig= forwardRef<TeamConfigHandle,TeamConfigProps>((props,ref) => {
|
|||||||
const [managerOption, setManagerOption] = useState<DefaultOptionType[]>([])
|
const [managerOption, setManagerOption] = useState<DefaultOptionType[]>([])
|
||||||
const { setBreadcrumb} = useBreadcrumb()
|
const { setBreadcrumb} = useBreadcrumb()
|
||||||
const { setTeamInfo } =useTeamContext()
|
const { setTeamInfo } =useTeamContext()
|
||||||
const {checkPermission,accessInit} = useGlobalContext()
|
const {checkPermission,accessInit,state} = useGlobalContext()
|
||||||
const pageType= useMemo(()=>{
|
const pageType= useMemo(()=>{
|
||||||
if(!accessInit) return 'myteam'
|
if(!accessInit) return 'myteam'
|
||||||
return checkPermission('system.workspace.team.view_all') ? 'manage' : 'myteam'
|
return checkPermission('system.workspace.team.view_all') ? 'manage' : 'myteam'
|
||||||
@@ -128,7 +128,10 @@ const TeamConfig= forwardRef<TeamConfigHandle,TeamConfigProps>((props,ref) => {
|
|||||||
getTeamInfo();
|
getTeamInfo();
|
||||||
} else {
|
} else {
|
||||||
setOnEdit(false);
|
setOnEdit(false);
|
||||||
form.setFieldsValue({id:uuidv4()}); // 清空 initialValues
|
form.setFieldsValue(
|
||||||
|
{id:uuidv4(),
|
||||||
|
master:state?.userData?.uid
|
||||||
|
}); // 清空 initialValues
|
||||||
}
|
}
|
||||||
return (form.setFieldsValue({}))
|
return (form.setFieldsValue({}))
|
||||||
}, [teamId]);
|
}, [teamId]);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import WithPermission from "@common/components/aoplatform/WithPermission.tsx";
|
|||||||
import { $t } from "@common/locales/index.ts";
|
import { $t } from "@common/locales/index.ts";
|
||||||
|
|
||||||
export const getDepartmentWithMember = (department:(DepartmentListItem & {type?:'department'|'member'})[],departmentMap:Map<string, (MemberItem & {type:'department'|'member'})[]>) : (DepartmentWithMemberItem | undefined)[] =>{
|
export const getDepartmentWithMember = (department:(DepartmentListItem & {type?:'department'|'member'})[],departmentMap:Map<string, (MemberItem & {type:'department'|'member'})[]>) : (DepartmentWithMemberItem | undefined)[] =>{
|
||||||
return department.map((x:DepartmentListItem & {type?:'department'|'member'})=>{
|
return department?.map((x:DepartmentListItem & {type?:'department'|'member'})=>{
|
||||||
const res = ({
|
const res = ({
|
||||||
...x,
|
...x,
|
||||||
key:x.id,
|
key:x.id,
|
||||||
@@ -28,7 +28,7 @@ export const getDepartmentWithMember = (department:(DepartmentListItem & {type?:
|
|||||||
type: x.type || 'department',
|
type: x.type || 'department',
|
||||||
children:((x.type === 'member' || (!x.children||x.children.length === 0 )&& (!departmentMap.get(x.id) || departmentMap.get(x.id)!.length === 0))? undefined : [...(x.children && x.children.length > 0 ? getDepartmentWithMember(x.children,departmentMap) : []),...departmentMap.get(x.id) || []])
|
children:((x.type === 'member' || (!x.children||x.children.length === 0 )&& (!departmentMap.get(x.id) || departmentMap.get(x.id)!.length === 0))? undefined : [...(x.children && x.children.length > 0 ? getDepartmentWithMember(x.children,departmentMap) : []),...departmentMap.get(x.id) || []])
|
||||||
});
|
});
|
||||||
return res}).filter(node=>node.type === 'member' ||( node.children && node.children.length > 0))
|
return res})?.filter(node=>node.type === 'member' ||( node.children && node.children.length > 0)) || []
|
||||||
}
|
}
|
||||||
|
|
||||||
export const addMemberToDepartment = (departmentMap: Map<string, (MemberItem & {type:'department'|'member'})[]>, departmentId: string, member: MemberItem) => {
|
export const addMemberToDepartment = (departmentMap: Map<string, (MemberItem & {type:'department'|'member'})[]>, departmentId: string, member: MemberItem) => {
|
||||||
@@ -84,6 +84,7 @@ const TeamInsideMember:FC = ()=>{
|
|||||||
addMemberToDepartment(departmentMap, '_withoutDepartment', member);
|
addMemberToDepartment(departmentMap, '_withoutDepartment', member);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const finalData = departmentResponse.data.department
|
const finalData = departmentResponse.data.department
|
||||||
? [
|
? [
|
||||||
@@ -93,30 +94,33 @@ const TeamInsideMember:FC = ()=>{
|
|||||||
name: departmentResponse.data.department.name,
|
name: departmentResponse.data.department.name,
|
||||||
title:departmentResponse.data.department.name,
|
title:departmentResponse.data.department.name,
|
||||||
children: [
|
children: [
|
||||||
...getDepartmentWithMember(departmentResponse.data.department.children, departmentMap),
|
...getDepartmentWithMember(departmentResponse.data.department?.children || [], departmentMap),
|
||||||
...departmentMap.get('_withoutDepartment') || []
|
...departmentMap.get('_withoutDepartment') || []
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
: [...departmentMap.get('_withoutDepartment') || []];
|
: [...departmentMap.get('_withoutDepartment') || []];
|
||||||
|
|
||||||
|
let allMemberSelectedFlag:boolean = true
|
||||||
for(const [k,v] of departmentMap){
|
for(const [k,v] of departmentMap){
|
||||||
if(k !== '_withoutDepartment' && allMemberIds.length > 0 ){
|
if(k !== '_withoutDepartment' && allMemberIds.length > 0 ){
|
||||||
// 筛选出部门内没被勾选的用户,如果不存在没勾选用户,需要将部门id放入ids中
|
// 筛选出部门内没被勾选的用户,如果不存在没勾选用户,需要将部门id放入ids中
|
||||||
if(v.filter(m => allMemberIds.indexOf(m.id) === -1).length === 0){
|
if(v.filter(m => allMemberIds.indexOf(m.id) === -1).length === 0){
|
||||||
setAllMemberSelectedDepartIds((pre)=>[...pre, k])
|
setAllMemberSelectedDepartIds((pre)=>[...pre, k])
|
||||||
|
}else if(['unknown','disable'].indexOf(k) === -1){
|
||||||
|
allMemberSelectedFlag = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!finalData[0].children || finalData[0].children.filter(m => allMemberIds.indexOf(m.id) === -1).length === 0){
|
if(departmentMap.get('_withoutDepartment')?.filter(x=>allMemberIds.indexOf(x)!==-1).length === 0 && allMemberSelectedFlag){
|
||||||
setAllMemberSelectedDepartIds((pre)=>[...pre, topDepartmentId])
|
setAllMemberSelectedDepartIds((pre)=>[...pre, topDepartmentId])
|
||||||
}
|
}
|
||||||
|
|
||||||
return {data:finalData, success: true}
|
return {data:finalData, success: true}
|
||||||
}).catch(()=>({data:[], success:false}))
|
}).catch(()=>({data:[], success:false}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const getMemberList = ()=>{
|
const getMemberList = ()=>{
|
||||||
return fetchData<BasicResponse<{members:TeamMemberTableListItem}>>('team/members',{method:'GET',eoParams:{keyword:searchWord, team:teamId},eoTransformKeys:['attach_time','is_delete']}).then(response=>{
|
return fetchData<BasicResponse<{members:TeamMemberTableListItem}>>('team/members',{method:'GET',eoParams:{keyword:searchWord, team:teamId},eoTransformKeys:['attach_time','is_delete']}).then(response=>{
|
||||||
@@ -214,7 +218,6 @@ const TeamInsideMember:FC = ()=>{
|
|||||||
|
|
||||||
|
|
||||||
const changeMemberInfo = (value:string[],entity:TeamMemberTableListItem )=>{
|
const changeMemberInfo = (value:string[],entity:TeamMemberTableListItem )=>{
|
||||||
//console.log(value)
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fetchData<BasicResponse<null>>(`team/member/role`, {method: 'PUT',eoBody:({roles:value, users:[entity.user.id]}), eoParams: {team:teamId}}).then(response => {
|
fetchData<BasicResponse<null>>(`team/member/role`, {method: 'PUT',eoBody:({roles:value, users:[entity.user.id]}), eoParams: {team:teamId}}).then(response => {
|
||||||
const {code, msg} = response
|
const {code, msg} = response
|
||||||
@@ -252,6 +255,7 @@ const TeamInsideMember:FC = ()=>{
|
|||||||
<Select
|
<Select
|
||||||
className="w-full"
|
className="w-full"
|
||||||
mode="multiple"
|
mode="multiple"
|
||||||
|
maxTagCount="responsive"
|
||||||
value={entity.roles?.map((x:EntityItem)=>x.id)}
|
value={entity.roles?.map((x:EntityItem)=>x.id)}
|
||||||
options={roleList?.map((x:{id:string,name:string})=>({label:(x.name), value:x.id}))}
|
options={roleList?.map((x:{id:string,name:string})=>({label:(x.name), value:x.id}))}
|
||||||
onChange={(value)=>{
|
onChange={(value)=>{
|
||||||
@@ -272,7 +276,6 @@ const TeamInsideMember:FC = ()=>{
|
|||||||
},[ state.language,roleList])
|
},[ state.language,roleList])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
getRoleList()
|
|
||||||
setBreadcrumb([
|
setBreadcrumb([
|
||||||
{title:<Link to="/team/list">{$t('团队')}</Link>},
|
{title:<Link to="/team/list">{$t('团队')}</Link>},
|
||||||
{title:$t('成员')}
|
{title:$t('成员')}
|
||||||
@@ -280,6 +283,11 @@ const TeamInsideMember:FC = ()=>{
|
|||||||
manualReloadTable()
|
manualReloadTable()
|
||||||
}, [teamId]);
|
}, [teamId]);
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
getRoleList()
|
||||||
|
},[state.language])
|
||||||
|
|
||||||
const treeDisabledData = useMemo(()=>{ return [...allMemberIds,...allMemberSelectedDepartIds]},[allMemberIds,allMemberSelectedDepartIds])
|
const treeDisabledData = useMemo(()=>{ return [...allMemberIds,...allMemberSelectedDepartIds]},[allMemberIds,allMemberSelectedDepartIds])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -302,7 +310,7 @@ const TeamInsideMember:FC = ()=>{
|
|||||||
title={$t("添加成员")}
|
title={$t("添加成员")}
|
||||||
open={modalVisible}
|
open={modalVisible}
|
||||||
destroyOnClose={true}
|
destroyOnClose={true}
|
||||||
width={900}
|
width={600}
|
||||||
onCancel={() => cleanModalData()}
|
onCancel={() => cleanModalData()}
|
||||||
maskClosable={false}
|
maskClosable={false}
|
||||||
footer={[
|
footer={[
|
||||||
@@ -329,7 +337,7 @@ const TeamInsideMember:FC = ()=>{
|
|||||||
const memberKeyFromModal = Array.from(selectedData)?.filter(x => allMemberIds.indexOf(x) === -1 &&selectableMemberIds.has(x)) || [];
|
const memberKeyFromModal = Array.from(selectedData)?.filter(x => allMemberIds.indexOf(x) === -1 &&selectableMemberIds.has(x)) || [];
|
||||||
setAddMemberBtnDisabled((memberKeyFromModal.length === 0));
|
setAddMemberBtnDisabled((memberKeyFromModal.length === 0));
|
||||||
}}
|
}}
|
||||||
searchPlaceholder={$t("搜索用户名、邮箱")}
|
searchPlaceholder={$t("输入名称查找用户")}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Modal>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
import WithPermission from "@common/components/aoplatform/WithPermission";
|
||||||
import { $t } from "@common/locales";
|
import { $t } from "@common/locales";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
@@ -15,13 +16,13 @@ export default function DashboardInstruction({showClusterIns, showMonitorIns}:{s
|
|||||||
{showClusterIns && <div className="h-[208px] w-[50%] max-w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px] justify-around">
|
{showClusterIns && <div className="h-[208px] w-[50%] max-w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG mr-[24px] justify-around">
|
||||||
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT">{$t('集群配置')}</p>
|
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT">{$t('集群配置')}</p>
|
||||||
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">{$t('配置集群地址,以确保监控系统能够正确识别和连接到集群')}</p>
|
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">{$t('配置集群地址,以确保监控系统能够正确识别和连接到集群')}</p>
|
||||||
<p><a href="/cluster" target="_blank">{$t('配置集群信息')}</a></p>
|
<p><WithPermission access="system.settings.api_gateway.view" ><a href="/cluster" target="_blank">{$t('配置集群信息')}</a></WithPermission></p>
|
||||||
</div>}
|
</div>}
|
||||||
{showMonitorIns &&
|
{showMonitorIns &&
|
||||||
<div className="h-[208px] w-[50%] max-w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG justify-around">
|
<div className="h-[208px] w-[50%] max-w-[384px] flex flex-col items-center py-[32px] px-[24px] gap-[16px] rounded-DEFAULT bg-MENU_BG justify-around">
|
||||||
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT">{$t('监控设置')}</p>
|
<p className="text-[20px] font-medium leading-[32px] text-MAIN_TEXT">{$t('监控设置')}</p>
|
||||||
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">{$t('设置监控报表的数据来源,设置完成之后即可获得详细的API调用统计图表。')}</p>
|
<p className="text-[12px] font-normal leading-[20px] text-DESC_TEXT">{$t('设置监控报表的数据来源,设置完成之后即可获得详细的API调用统计图表。')}</p>
|
||||||
<p><a href="/datasourcing" target="_blank">{$t('配置监控信息')}</a></p>
|
<p><WithPermission access="system.settings.data_source.view" ><a href="/datasourcing" target="_blank">{$t('配置监控信息')}</a></WithPermission></p>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export const SERVICE_HUB_TABLE_COLUMNS: PageProColumns<ServiceHubTableListItem>[
|
|||||||
title:('团队'),
|
title:('团队'),
|
||||||
dataIndex: ['team','name'],
|
dataIndex: ['team','name'],
|
||||||
ellipsis:true,
|
ellipsis:true,
|
||||||
renderText:(_,entity:ServiceHubTableListItem)=>entity.tags?.map(x=>x.name).join(',') || '-'
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title:('订阅服务数量'),
|
title:('订阅服务数量'),
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
import {Link, useNavigate, useParams} from "react-router-dom";
|
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||||
import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx";
|
import { RouterParams } from "@core/components/aoplatform/RenderRoutes.tsx";
|
||||||
import { App, Avatar, Button, Descriptions, Divider, Tabs} from "antd";
|
import { App, Avatar, Button, Descriptions, Divider, Tabs } from "antd";
|
||||||
import { useEffect, useMemo, useRef, useState} from "react";
|
import { useEffect, useMemo, useRef, useState } from "react";
|
||||||
import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx";
|
import { useBreadcrumb } from "@common/contexts/BreadcrumbContext.tsx";
|
||||||
import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx";
|
import { BasicResponse, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const.tsx";
|
||||||
import {useFetch} from "@common/hooks/http.ts";
|
import { useFetch } from "@common/hooks/http.ts";
|
||||||
import {DefaultOptionType} from "antd/es/cascader";
|
import { DefaultOptionType } from "antd/es/cascader";
|
||||||
import { ApplyServiceHandle, ServiceBasicInfoType, ServiceDetailType } from "../../const/serviceHub/type.ts";
|
import { ApplyServiceHandle, ServiceBasicInfoType, ServiceDetailType } from "../../const/serviceHub/type.ts";
|
||||||
import { EntityItem } from "@common/const/type.ts";
|
import { EntityItem } from "@common/const/type.ts";
|
||||||
import { ApplyServiceModal } from "./ApplyServiceModal.tsx";
|
import { ApplyServiceModal } from "./ApplyServiceModal.tsx";
|
||||||
import ServiceHubApiDocument from "./ServiceHubApiDocument.tsx";
|
import ServiceHubApiDocument from "./ServiceHubApiDocument.tsx";
|
||||||
import { ApiFilled, ArrowLeftOutlined } from "@ant-design/icons";
|
import Integrate from "./integrate.tsx";
|
||||||
|
import { ApiFilled, ArrowLeftOutlined, BgColorsOutlined } from "@ant-design/icons";
|
||||||
import { SimpleSystemItem } from "@core/const/system/type.ts";
|
import { SimpleSystemItem } from "@core/const/system/type.ts";
|
||||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
@@ -18,174 +19,182 @@ import { $t } from "@common/locales/index.ts";
|
|||||||
import { approvalTypeTranslate } from "@market/const/serviceHub/const.tsx";
|
import { approvalTypeTranslate } from "@market/const/serviceHub/const.tsx";
|
||||||
|
|
||||||
|
|
||||||
const ServiceHubDetail = ()=>{
|
const ServiceHubDetail = () => {
|
||||||
const {serviceId} = useParams<RouterParams>();
|
const { serviceId } = useParams<RouterParams>();
|
||||||
const {setBreadcrumb} = useBreadcrumb()
|
const { setBreadcrumb } = useBreadcrumb()
|
||||||
const [serviceBasicInfo, setServiceBasicInfo] = useState<ServiceBasicInfoType>()
|
const [serviceBasicInfo, setServiceBasicInfo] = useState<ServiceBasicInfoType>()
|
||||||
const [serviceName, setServiceName] = useState<string>()
|
const [serviceName, setServiceName] = useState<string>()
|
||||||
const [serviceDesc, setServiceDesc] = useState<string>()
|
const [serviceDesc, setServiceDesc] = useState<string>()
|
||||||
const [serviceDoc, setServiceDoc] = useState<string>()
|
const [serviceDoc, setServiceDoc] = useState<string>()
|
||||||
const {fetchData} = useFetch()
|
const { fetchData } = useFetch()
|
||||||
const applyRef = useRef<ApplyServiceHandle>(null)
|
const applyRef = useRef<ApplyServiceHandle>(null)
|
||||||
const { modal,message } = App.useApp()
|
const { modal, message } = App.useApp()
|
||||||
const [mySystemOptionList, setMySystemOptionList] = useState<DefaultOptionType[]>()
|
const [mySystemOptionList, setMySystemOptionList] = useState<DefaultOptionType[]>()
|
||||||
// const [applied,setApplied] = useState<boolean>(false)
|
// const [applied,setApplied] = useState<boolean>(false)
|
||||||
// const [activeKey, setActiveKey] = useState<string[]>([])
|
// const [activeKey, setActiveKey] = useState<string[]>([])
|
||||||
const [service, setService] = useState<ServiceDetailType>()
|
const [service, setService] = useState<ServiceDetailType>()
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const modifyApiDoc = (apiDoc:string, apiPrefix:string)=>{
|
const modifyApiDoc = (apiDoc: string, apiPrefix: string) => {
|
||||||
if(!apiDoc) return ''
|
if (!apiDoc) return ''
|
||||||
if(!apiPrefix) return apiDoc
|
if (!apiPrefix) return apiDoc
|
||||||
try{
|
try {
|
||||||
const openApiSpec = JSON.parse(apiDoc);
|
const openApiSpec = JSON.parse(apiDoc);
|
||||||
// 遍历并修改 paths,给每个路径添加前缀
|
// 遍历并修改 paths,给每个路径添加前缀
|
||||||
const modifiedPaths:Record<string,unknown> = {};
|
const modifiedPaths: Record<string, unknown> = {};
|
||||||
for (const [path, pathItem] of Object.entries(openApiSpec.paths)) {
|
for (const [path, pathItem] of Object.entries(openApiSpec.paths)) {
|
||||||
modifiedPaths[apiPrefix + path] = pathItem;
|
modifiedPaths[apiPrefix + path] = pathItem;
|
||||||
}
|
}
|
||||||
openApiSpec.paths = modifiedPaths;
|
openApiSpec.paths = modifiedPaths;
|
||||||
return JSON.stringify(openApiSpec);
|
return JSON.stringify(openApiSpec);
|
||||||
}catch(err){
|
} catch (err) {
|
||||||
console.warn('拼接api前缀失败',err)
|
console.warn('拼接api前缀失败', err)
|
||||||
}
|
|
||||||
return apiDoc
|
|
||||||
}
|
}
|
||||||
|
return apiDoc
|
||||||
|
}
|
||||||
|
|
||||||
const getServiceBasicInfo = ()=>{
|
const getServiceBasicInfo = () => {
|
||||||
fetchData<BasicResponse<{service:ServiceDetailType}>>('catalogue/service',{method:'GET',eoParams:{service:serviceId}, eoTransformKeys:['app_num','api_num','update_time','api_doc','invoke_address','approval_type','service_kind']}).then(response=>{
|
fetchData<BasicResponse<{ service: ServiceDetailType }>>('catalogue/service', { method: 'GET', eoParams: { service: serviceId }, eoTransformKeys: ['app_num', 'api_num', 'update_time', 'api_doc', 'invoke_address', 'approval_type', 'service_kind'] }).then(response => {
|
||||||
const {code,data,msg} = response
|
const { code, data, msg } = response
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
if (code === STATUS_CODE.SUCCESS) {
|
||||||
setService({...data.service,apiDoc:modifyApiDoc(data.service.apiDoc, data.service.basic?.invokeAddress)})
|
setService({ ...data.service, apiDoc: modifyApiDoc(data.service.apiDoc, data.service.basic?.invokeAddress) })
|
||||||
setServiceBasicInfo(data.service.basic)
|
setServiceBasicInfo(data.service.basic)
|
||||||
setServiceName(data.service.name)
|
setServiceName(data.service.name)
|
||||||
setServiceDesc(data.service.description)
|
setServiceDesc(data.service.description)
|
||||||
setServiceDoc(DOMPurify.sanitize(data.service.document))
|
setServiceDoc(DOMPurify.sanitize(data.service.document))
|
||||||
}else{
|
} else {
|
||||||
message.error(msg || $t(RESPONSE_TIPS.error))
|
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!serviceId) {
|
||||||
|
console.warn('缺少serviceId')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
serviceId && getServiceBasicInfo()
|
||||||
|
}, [serviceId]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if(!serviceId){
|
getMySelectList()
|
||||||
console.warn('缺少serviceId')
|
setBreadcrumb(
|
||||||
return
|
[
|
||||||
}
|
{ title: <Link to={`/serviceHub/list`}>{$t('服务市场')}</Link> },
|
||||||
serviceId && getServiceBasicInfo()
|
{ title: $t('服务详情') }
|
||||||
}, [serviceId]);
|
]
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getMySelectList()
|
|
||||||
setBreadcrumb(
|
|
||||||
[
|
|
||||||
{title:<Link to={`/serviceHub/list`}>{$t('服务市场')}</Link>},
|
|
||||||
{title:$t('服务详情')}
|
|
||||||
]
|
|
||||||
)
|
|
||||||
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
|
|
||||||
const getMySelectList = ()=>{
|
|
||||||
setMySystemOptionList([])
|
|
||||||
fetchData<BasicResponse<{ apps: SimpleSystemItem[] }>>('simple/apps/mine',{method:'GET'}).then(response=>{
|
|
||||||
const {code,data,msg} = response
|
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
|
||||||
setMySystemOptionList(data.apps?.map((x:SimpleSystemItem)=>{return {
|
|
||||||
label:x.name, value:x.id
|
|
||||||
}}))
|
|
||||||
}else{
|
|
||||||
message.error(msg || $t(RESPONSE_TIPS.error))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const openModal = (type:'apply')=>{
|
|
||||||
modal.confirm({
|
|
||||||
title:$t('申请服务'),
|
|
||||||
content:<ApplyServiceModal ref={applyRef} entity={{...serviceBasicInfo!, name:serviceName!, id:serviceId!}} mySystemOptionList={mySystemOptionList!}/>,
|
|
||||||
onOk:()=>{
|
|
||||||
return applyRef.current?.apply().then((res)=>{
|
|
||||||
// if(res === true) setApplied(true)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
okText:$t('确认'),
|
|
||||||
cancelText:$t('取消'),
|
|
||||||
closable:true,
|
|
||||||
icon:<></>,
|
|
||||||
width:600
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const items = [
|
|
||||||
{
|
|
||||||
key: 'introduction',
|
|
||||||
label: $t('介绍'),
|
|
||||||
children: <><div className="p-btnbase preview-document mb-PAGE_INSIDE_B" dangerouslySetInnerHTML={{__html: serviceDoc || ''}}></div></>,
|
|
||||||
icon: <Icon icon="ic:baseline-space-dashboard" width="14" height="14"/>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'api-document',
|
|
||||||
label: $t('API 文档'),
|
|
||||||
children: <div className={`p-btnbase ${serviceBasicInfo?.serviceKind?.toLocaleLowerCase() === 'ai' ? 'ai-service-api-preview' : ''}`}><ServiceHubApiDocument service={service!} /></div>,
|
|
||||||
icon: <ApiFilled />
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
return (
|
|
||||||
<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 ">
|
|
||||||
|
|
||||||
<div className="text-[18px] leading-[25px] pb-[12px]">
|
|
||||||
<Button type="text" onClick={()=>navigate(`/serviceHub/list`)}><ArrowLeftOutlined className="max-h-[14px]" />{$t('返回')}</Button>
|
|
||||||
</div>
|
|
||||||
<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-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>
|
|
||||||
|
|
||||||
<div className="pl-[20px] w-[calc(100%-50px)]">
|
|
||||||
<p className="text-[14px] h-[20px] leading-[20px] truncate font-bold flex items-center gap-[4px]">{serviceName}
|
|
||||||
</p>
|
|
||||||
<div className="mt-[10px] flex flex-col gap-btnrbase font-normal">
|
|
||||||
<p>{serviceDesc || '-'}</p>
|
|
||||||
<p className="flex items-center gap-[4px]"><Icon icon="ic:baseline-link" width="18" height="18" /><span className="font-bold">{$t('Base URL')}</span>: {serviceBasicInfo?.invokeAddress || '-'}</p>
|
|
||||||
<div>
|
|
||||||
<Button type="primary" onClick={()=>openModal('apply')}>{$t('申请')}</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<Tabs
|
|
||||||
className="p-btnbase pr-0 overflow-hidden [&>.ant-tabs-content-holder]:overflow-auto"
|
|
||||||
items={items}
|
|
||||||
|
|
||||||
/>
|
|
||||||
|
|
||||||
</section>
|
|
||||||
<section className="col-span-1 p-btnbase px-btnrbase">
|
|
||||||
<Descriptions title={$t("服务信息")} column={1} size={'small'}>
|
|
||||||
<Descriptions.Item label={$t("接入消费者")}>{serviceBasicInfo?.appNum ?? '-'}</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={$t("供应方")}>{serviceBasicInfo?.team?.name || '-'}</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={$t("审核")}>{serviceBasicInfo?.approvalType ? $t((approvalTypeTranslate[serviceBasicInfo?.approvalType] || '-' )): '-'}</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={$t("分类")}>{serviceBasicInfo?.catalogue?.name || '-'}</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={$t("标签")}>{serviceBasicInfo?.tags?.map(x=>x.name)?.join(',') || '-'}</Descriptions.Item>
|
|
||||||
</Descriptions>
|
|
||||||
<Divider />
|
|
||||||
<Descriptions column={1} >
|
|
||||||
<Descriptions.Item label={$t("版本")}>{ serviceBasicInfo?.version || '-'}</Descriptions.Item>
|
|
||||||
<Descriptions.Item label={$t("更新时间")}><span className="truncate" title={serviceBasicInfo?.updateTime}>{serviceBasicInfo?.updateTime || '-'}</span></Descriptions.Item>
|
|
||||||
</Descriptions>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
|
const getMySelectList = () => {
|
||||||
|
setMySystemOptionList([])
|
||||||
|
fetchData<BasicResponse<{ app: EntityItem[] }>>('apps/can_subscribe', { method: 'GET' }).then(response => {
|
||||||
|
const { code, data, msg } = response
|
||||||
|
if (code === STATUS_CODE.SUCCESS) {
|
||||||
|
setMySystemOptionList(data.app?.map((x: EntityItem) => {
|
||||||
|
return {
|
||||||
|
label: x.name, value: x.id
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const openModal = (type: 'apply') => {
|
||||||
|
modal.confirm({
|
||||||
|
title: $t('申请服务'),
|
||||||
|
content: <ApplyServiceModal ref={applyRef} entity={{ ...serviceBasicInfo!, name: serviceName!, id: serviceId! }} mySystemOptionList={mySystemOptionList!} />,
|
||||||
|
onOk: () => {
|
||||||
|
return applyRef.current?.apply().then((res) => {
|
||||||
|
// if(res === true) setApplied(true)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
okText: $t('确认'),
|
||||||
|
cancelText: $t('取消'),
|
||||||
|
closable: true,
|
||||||
|
icon: <></>,
|
||||||
|
width: 600
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const items = [
|
||||||
|
{
|
||||||
|
key: 'introduction',
|
||||||
|
label: $t('介绍'),
|
||||||
|
children: <><div className="p-btnbase preview-document mb-PAGE_INSIDE_B" dangerouslySetInnerHTML={{ __html: serviceDoc || '' }}></div></>,
|
||||||
|
icon: <Icon icon="ic:baseline-space-dashboard" width="14" height="14" />,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'api-document',
|
||||||
|
label: $t('API 文档'),
|
||||||
|
children: <div className={`p-btnbase ${serviceBasicInfo?.serviceKind?.toLocaleLowerCase() === 'ai' ? 'ai-service-api-preview' : ''}`}><ServiceHubApiDocument service={service!} /></div>,
|
||||||
|
icon: <ApiFilled />
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'api-integrate',
|
||||||
|
label: $t('集成'),
|
||||||
|
children: <div className={`p-btnbase ${serviceBasicInfo?.serviceKind?.toLocaleLowerCase() === 'ai' ? 'ai-service-api-preview' : ''}`}><Integrate service={service!} /></div>,
|
||||||
|
icon: <BgColorsOutlined />
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<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 ">
|
||||||
|
|
||||||
|
<div className="text-[18px] leading-[25px] pb-[12px]">
|
||||||
|
<Button type="text" onClick={() => navigate(`/serviceHub/list`)}><ArrowLeftOutlined className="max-h-[14px]" />{$t('返回')}</Button>
|
||||||
|
</div>
|
||||||
|
<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-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>
|
||||||
|
|
||||||
|
<div className="pl-[20px] w-[calc(100%-50px)]">
|
||||||
|
<p className="text-[14px] h-[20px] leading-[20px] truncate font-bold flex items-center gap-[4px]">{serviceName}
|
||||||
|
</p>
|
||||||
|
<div className="mt-[10px] flex flex-col gap-btnrbase font-normal">
|
||||||
|
<p>{serviceDesc || '-'}</p>
|
||||||
|
<p className="flex items-center gap-[4px]"><Icon icon="ic:baseline-link" width="18" height="18" /><span className="font-bold">{$t('Base URL')}</span>: {serviceBasicInfo?.invokeAddress || '-'}</p>
|
||||||
|
<div>
|
||||||
|
<Button type="primary" onClick={() => openModal('apply')}>{$t('申请')}</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<Tabs
|
||||||
|
className="p-btnbase pr-0 overflow-hidden [&>.ant-tabs-content-holder]:overflow-auto"
|
||||||
|
items={items}
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section className="col-span-1 p-btnbase px-btnrbase">
|
||||||
|
<Descriptions title={$t("服务信息")} column={1} size={'small'}>
|
||||||
|
<Descriptions.Item label={$t("接入消费者")}>{serviceBasicInfo?.appNum ?? '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={$t("供应方")}>{serviceBasicInfo?.team?.name || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={$t("审核")}>{serviceBasicInfo?.approvalType ? $t((approvalTypeTranslate[serviceBasicInfo?.approvalType] || '-')) : '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={$t("分类")}>{serviceBasicInfo?.catalogue?.name || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={$t("标签")}>{serviceBasicInfo?.tags?.map(x => x.name)?.join(',') || '-'}</Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
<Divider />
|
||||||
|
<Descriptions column={1} >
|
||||||
|
<Descriptions.Item label={$t("版本")}>{serviceBasicInfo?.version || '-'}</Descriptions.Item>
|
||||||
|
<Descriptions.Item label={$t("更新时间")}><span className="truncate" title={serviceBasicInfo?.updateTime}>{serviceBasicInfo?.updateTime || '-'}</span></Descriptions.Item>
|
||||||
|
</Descriptions>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ServiceHubDetail
|
export default ServiceHubDetail
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import { ServiceDetailType } from "@market/const/serviceHub/type"
|
||||||
|
import { Input, Button, Space, message } from 'antd'
|
||||||
|
import { $t } from "@common/locales"
|
||||||
|
import { RESPONSE_TIPS } from '@common/const/const'
|
||||||
|
import { downloadFile } from "@common/utils/download.ts"
|
||||||
|
|
||||||
|
|
||||||
|
const Integrate = ({ service }: { service: ServiceDetailType }) => {
|
||||||
|
console.log('service', service);
|
||||||
|
const stepClass = "leading-[20px] truncate font-bold items-center gap-[4px] mt-[15px]";
|
||||||
|
const url = 'https://www.baidu.com';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Agent 平台地址
|
||||||
|
*/
|
||||||
|
const agentAddress = '/cluster';
|
||||||
|
/**
|
||||||
|
* 消费者地址
|
||||||
|
*/
|
||||||
|
const consumerAddress = '/consumer/list';
|
||||||
|
/**
|
||||||
|
* 复制代码
|
||||||
|
*/
|
||||||
|
const copyURL = async (): Promise<void> => {
|
||||||
|
await navigator.clipboard.writeText(url)
|
||||||
|
message.success($t(RESPONSE_TIPS.copySuccess))
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 下载文件
|
||||||
|
*/
|
||||||
|
const onDownload = () => {
|
||||||
|
console.log('downloadFile');
|
||||||
|
downloadFile({
|
||||||
|
body: '',
|
||||||
|
contentType: 'raw',
|
||||||
|
filename: 'test_response',
|
||||||
|
responseType: 'text',
|
||||||
|
uri: ''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div>{$t('支持把当前服务对接主流的 AI Agent平台,实现在 Agent 平台上快速、安全和合规地使用企业开放的 API 能力。')}</div>
|
||||||
|
<div className='my-[10px]'>{$t('可按以下步骤进行对接:')}</div>
|
||||||
|
<p className={stepClass}>{$t('步骤一:Agent 平台上创建自定义插件')}</p>
|
||||||
|
<div className="my-[10px]">{$t('不同 Agent 平台的操作细节可查看')} <a href={agentAddress} target="_blank">{$t('《 Agent 对接手册》')}</a>。</div>
|
||||||
|
<p className={stepClass}>{$t('步骤二:导入 API 文档数据')}</p>
|
||||||
|
<div className='my-[10px]'>{$t('可通过以下 URL 或 下载 Json 文件,导入 API 文档数据到 Agent 平台中。')}</div>
|
||||||
|
<div>
|
||||||
|
<Space.Compact className="w-[500px]">
|
||||||
|
<Input disabled defaultValue={url} />
|
||||||
|
<Button type="primary" onClick={copyURL}>{$t('复制 URL')}</Button>
|
||||||
|
</Space.Compact>
|
||||||
|
<span className="text-[14px] font-bold mx-[30px]">OR</span> <Button onClick={onDownload}>{$t('下载 Json 文件')}</Button>
|
||||||
|
</div>
|
||||||
|
<p className={stepClass}>{$t('步骤三:配置 API 密钥')}</p>
|
||||||
|
<div className='my-[10px]'>{$t('在')}<a href={consumerAddress} target="_blank"> {$t('消费者')} </a>{$t('菜单中,选择已通过本 API 服务申请的消费者,')}</div>
|
||||||
|
<div className='my-[10px]'>{$t('把 "访问权限" 菜单下的密钥填入到 Agent 平台对应的插件密钥配置中。')}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export default Integrate;
|
||||||
@@ -8,6 +8,9 @@ import { useFetch } from "@common/hooks/http";
|
|||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useTenantManagementContext } from "@market/contexts/TenantManagementContext";
|
import { useTenantManagementContext } from "@market/contexts/TenantManagementContext";
|
||||||
import { $t } from "@common/locales";
|
import { $t } from "@common/locales";
|
||||||
|
import Select, { DefaultOptionType } from "antd/es/select";
|
||||||
|
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
|
||||||
|
import { SimpleTeamItem, MemberItem } from "@common/const/type";
|
||||||
|
|
||||||
export type ManagementConfigFieldType = {
|
export type ManagementConfigFieldType = {
|
||||||
name:string
|
name:string
|
||||||
@@ -21,6 +24,7 @@ type ManagementConfigProps = {
|
|||||||
type:'add'|'edit'
|
type:'add'|'edit'
|
||||||
teamId:string
|
teamId:string
|
||||||
appId?:string
|
appId?:string
|
||||||
|
dataShowType?:'block'|'list'
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ManagementConfigHandle = {
|
export type ManagementConfigHandle = {
|
||||||
@@ -30,16 +34,18 @@ export type ManagementConfigHandle = {
|
|||||||
|
|
||||||
const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps>((props, ref) => {
|
const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps>((props, ref) => {
|
||||||
const { message,modal } = App.useApp()
|
const { message,modal } = App.useApp()
|
||||||
const {type,teamId,appId} = props
|
const {type,teamId,appId,dataShowType} = props
|
||||||
const [form] = Form.useForm();
|
const [form] = Form.useForm();
|
||||||
const {fetchData} = useFetch()
|
const {fetchData} = useFetch()
|
||||||
const [delBtnLoading, setDelBtnLoading] = useState<boolean>(false)
|
const [delBtnLoading, setDelBtnLoading] = useState<boolean>(false)
|
||||||
const {setAppName} = type === 'edit' ? useTenantManagementContext():{setAppName:()=>{}}
|
const {setAppName} = type === 'edit' ? useTenantManagementContext():{setAppName:()=>{}}
|
||||||
const navigate = type === 'edit' ? useNavigate() : ()=>{}
|
const navigate = type === 'edit' ? useNavigate() : ()=>{}
|
||||||
|
const [teamOptionList, setTeamOptionList] = useState<DefaultOptionType[]>()
|
||||||
|
const {checkPermission,accessInit, getGlobalAccessData} = useGlobalContext()
|
||||||
const save:()=>Promise<boolean | string> = ()=>{
|
const save:()=>Promise<boolean | string> = ()=>{
|
||||||
return new Promise((resolve, reject)=>{
|
return new Promise((resolve, reject)=>{
|
||||||
form.validateFields().then((value)=>{
|
form.validateFields().then((value)=>{
|
||||||
fetchData<BasicResponse<{apps:ManagementConfigFieldType}>>(type === 'add'? 'team/app' : 'app/info',{method:type === 'add'? 'POST' : 'PUT',eoBody:(value), eoParams:type === 'add' ? {team:teamId}:{app:appId,team:teamId}}).then(response=>{
|
fetchData<BasicResponse<{apps:ManagementConfigFieldType}>>(type === 'add'? 'team/app' : 'app/info',{method:type === 'add'? 'POST' : 'PUT',eoBody:(value), eoParams:type === 'add' ? {team:dataShowType === 'list' ? value.team : teamId}:{app:appId,team:teamId}}).then(response=>{
|
||||||
const {code,data,msg} = response
|
const {code,data,msg} = response
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
if(code === STATUS_CODE.SUCCESS){
|
||||||
message.success(msg || $t(RESPONSE_TIPS.success))
|
message.success(msg || $t(RESPONSE_TIPS.success))
|
||||||
@@ -68,6 +74,24 @@ const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getTeamOptionList = ()=>{
|
||||||
|
setTeamOptionList([])
|
||||||
|
|
||||||
|
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,
|
||||||
|
label:x.name, value:x.id
|
||||||
|
}}))
|
||||||
|
if(form.getFieldValue('team') === undefined&&data.teams?.length){
|
||||||
|
form.setFieldValue('team',data.teams[0].id);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
message.error(msg || $t(RESPONSE_TIPS.error))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const deleteApplicationModal = async ()=>{
|
const deleteApplicationModal = async ()=>{
|
||||||
setDelBtnLoading(true)
|
setDelBtnLoading(true)
|
||||||
modal.confirm({
|
modal.confirm({
|
||||||
@@ -112,7 +136,17 @@ const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps
|
|||||||
if(type === 'edit'){
|
if(type === 'edit'){
|
||||||
appId && getApplicationInfo()
|
appId && getApplicationInfo()
|
||||||
}else{
|
}else{
|
||||||
form.setFieldValue('id',uuidv4())
|
form.setFieldsValue({
|
||||||
|
'id':uuidv4()})
|
||||||
|
}
|
||||||
|
if(type !== 'edit' && dataShowType === 'list'){
|
||||||
|
if(accessInit){
|
||||||
|
getTeamOptionList()
|
||||||
|
}else{
|
||||||
|
getGlobalAccessData()?.then?.(()=>{
|
||||||
|
getTeamOptionList()
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [appId]);
|
}, [appId]);
|
||||||
|
|
||||||
@@ -146,6 +180,16 @@ const ManagementConfig = forwardRef<ManagementConfigHandle,ManagementConfigProps
|
|||||||
<Input className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)} disabled={type === 'edit'}/>
|
<Input className="w-INPUT_NORMAL" placeholder={$t(PLACEHOLDER.input)} disabled={type === 'edit'}/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
|
||||||
|
{dataShowType === 'list' && <Form.Item<ManagementConfigFieldType>
|
||||||
|
label={$t("所属团队")}
|
||||||
|
name="team"
|
||||||
|
rules={[{ required: true }]}
|
||||||
|
>
|
||||||
|
<Select className="w-INPUT_NORMAL" disabled={type === 'edit'} placeholder={$t(PLACEHOLDER.input)} options={teamOptionList} >
|
||||||
|
</Select>
|
||||||
|
</Form.Item>}
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label={$t("描述")}
|
label={$t("描述")}
|
||||||
name="description"
|
name="description"
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import { ManagementConfigFieldType } from "./ManagementConfig";
|
|||||||
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
|
import { useGlobalContext } from "@common/contexts/GlobalStateContext";
|
||||||
import { $t } from "@common/locales";
|
import { $t } from "@common/locales";
|
||||||
import { getItem } from "@common/utils/navigation";
|
import { getItem } from "@common/utils/navigation";
|
||||||
import { MenuItemType } from "antd/es/menu/interface";
|
import { MenuItemGroupType, MenuItemType } from "antd/es/menu/interface";
|
||||||
|
import { PERMISSION_DEFINITION } from "@common/const/permissions";
|
||||||
|
import { cloneDeep } from "lodash-es";
|
||||||
|
|
||||||
export default function ManagementInsidePage(){
|
export default function ManagementInsidePage(){
|
||||||
const { message } = App.useApp()
|
const { message } = App.useApp()
|
||||||
@@ -27,17 +29,29 @@ export default function ManagementInsidePage(){
|
|||||||
const [openKeys, setOpenKeys] = useState<string[]>([])
|
const [openKeys, setOpenKeys] = useState<string[]>([])
|
||||||
const [loading, setLoading] = useState<boolean>(false)
|
const [loading, setLoading] = useState<boolean>(false)
|
||||||
const {appName,setAppName} = useTenantManagementContext()
|
const {appName,setAppName} = useTenantManagementContext()
|
||||||
const {getTeamAccessData,cleanTeamAccessData,state} = useGlobalContext()
|
const {getTeamAccessData,cleanTeamAccessData,state,accessData,checkPermission,accessInit} = useGlobalContext()
|
||||||
|
|
||||||
const TENANT_MANAGEMENT_APP_MENU: MenuProps['items'] = useMemo(()=>[
|
const TENANT_MANAGEMENT_APP_MENU: MenuProps['items'] = useMemo(()=>[
|
||||||
getItem($t('订阅的服务'), 'service'),
|
getItem($t('订阅的服务'), 'service',undefined, undefined, undefined, 'team.application.subscription.view'),
|
||||||
getItem($t('访问授权'), 'authorization'),
|
getItem($t('访问授权'), 'authorization',undefined, undefined, undefined, 'team.consumer.authorization.view'),
|
||||||
getItem($t('消费者管理'), 'setting'),
|
getItem($t('消费者管理'), 'setting',undefined, undefined, undefined, 'team.application.application.view'),
|
||||||
],[state.language])
|
],[state.language])
|
||||||
|
|
||||||
|
|
||||||
const menuData = useMemo(()=>{
|
const menuData = useMemo(()=>{
|
||||||
return TENANT_MANAGEMENT_APP_MENU
|
const filterMenu = (menu:(MenuItemType&{access:string})[])=>{
|
||||||
},[])
|
const newMenu = cloneDeep(menu)
|
||||||
|
return newMenu!.filter((c:MenuItemType&{access:string} )=>{
|
||||||
|
if(!c) return false
|
||||||
|
return (((c as MenuItemType&{access:string} ).access ?
|
||||||
|
checkPermission((c as MenuItemType&{access:string} ).access as keyof typeof PERMISSION_DEFINITION[0]):
|
||||||
|
true))
|
||||||
|
})}
|
||||||
|
const filteredMenu = filterMenu(TENANT_MANAGEMENT_APP_MENU as (MenuItemType&{access:string})[])
|
||||||
|
const menu = activeMenu ?? filteredMenu[0]?.children ? filteredMenu[0]?.children?.[0]?.key : filteredMenu[0]?.key
|
||||||
|
if(menu && currentUrl.split('/')[-1] !== menu) navigateTo(`/consumer/${teamId}/inside/${appId}/${menu}`)
|
||||||
|
return filteredMenu || []
|
||||||
|
},[accessData,accessInit, TENANT_MANAGEMENT_APP_MENU])
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
setActiveMenu(currentUrl.split('/').pop() || 'service')
|
setActiveMenu(currentUrl.split('/').pop() || 'service')
|
||||||
|
|||||||
+110
-45
@@ -1,5 +1,5 @@
|
|||||||
import { MenuProps, Menu, App, Avatar, Card, Tooltip, Empty, Button, Radio } from "antd";
|
import { MenuProps, Menu, App, Avatar, Card, Tooltip, Empty, Button, Radio } from "antd";
|
||||||
import { useState, forwardRef, useEffect, useRef, useMemo, memo } from "react";
|
import { useState, forwardRef, useEffect, useRef, useMemo, memo, Ref, useImperativeHandle } from "react";
|
||||||
import { VirtuosoGrid } from "react-virtuoso";
|
import { VirtuosoGrid } from "react-virtuoso";
|
||||||
import { BasicResponse, DATA_SHOW_TYPE_OPTIONS, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const";
|
import { BasicResponse, DATA_SHOW_TYPE_OPTIONS, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const";
|
||||||
import { ServiceHubAppListItem } from "../../../const/serviceHub/type";
|
import { ServiceHubAppListItem } from "../../../const/serviceHub/type";
|
||||||
@@ -17,6 +17,7 @@ import WithPermission from "@common/components/aoplatform/WithPermission";
|
|||||||
import InsidePage from "@common/components/aoplatform/InsidePage";
|
import InsidePage from "@common/components/aoplatform/InsidePage";
|
||||||
import PageList from "@common/components/aoplatform/PageList";
|
import PageList from "@common/components/aoplatform/PageList";
|
||||||
import { SERVICE_HUB_TABLE_COLUMNS } from "@market/const/serviceHub/const";
|
import { SERVICE_HUB_TABLE_COLUMNS } from "@market/const/serviceHub/const";
|
||||||
|
import { ActionType } from "@ant-design/pro-components";
|
||||||
|
|
||||||
export default function ServiceHubManagement() {
|
export default function ServiceHubManagement() {
|
||||||
const { message ,modal} = App.useApp()
|
const { message ,modal} = App.useApp()
|
||||||
@@ -36,23 +37,25 @@ export default function ServiceHubManagement() {
|
|||||||
const [tableHttpReload, setTableHttpReload] = useState(true);
|
const [tableHttpReload, setTableHttpReload] = useState(true);
|
||||||
const [tableListDataSource, setTableListDataSource] = useState<ServiceHubAppListItem[]>([]);
|
const [tableListDataSource, setTableListDataSource] = useState<ServiceHubAppListItem[]>([]);
|
||||||
const [tableSearchWord, setTableSearchWord] = useState<string>('')
|
const [tableSearchWord, setTableSearchWord] = useState<string>('')
|
||||||
|
const tableRef = useRef<TableAreaHandle>(null)
|
||||||
|
|
||||||
const getServiceList = ()=>{
|
const getServiceList = (dataType?:'block'|'list')=>{
|
||||||
if(!accessInit){
|
dataType = dataType ?? dataShowType
|
||||||
getGlobalAccessData()?.then?.(()=>{getServiceList()})
|
if(!accessInit){
|
||||||
return Promise.resolve({data:[], success:false})
|
getGlobalAccessData()?.then?.(()=>{getServiceList(dataType)})
|
||||||
}
|
return Promise.resolve({data:[], success:false})
|
||||||
|
}
|
||||||
|
|
||||||
|
if(dataType === 'list' && !tableHttpReload){
|
||||||
|
setTableHttpReload(true)
|
||||||
|
return Promise.resolve({
|
||||||
|
data: tableListDataSource,
|
||||||
|
success: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if(dataShowType === 'list' && !tableHttpReload){
|
setServiceLoading(true)
|
||||||
setTableHttpReload(true)
|
return fetchData<BasicResponse<{apps:ServiceHubAppListItem}>>(!checkPermission('system.workspace.application.view_all') ? 'my_apps':'apps',{method:'GET',eoParams:{ team: dataType === 'list' ? undefined : teamId,keyword:tableSearchWord},eoTransformKeys:['api_num','subscribe_num','subscribe_verify_num','auth_num','create_time','can_delete']}).then(response=>{
|
||||||
return Promise.resolve({
|
|
||||||
data: tableListDataSource,
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
setServiceLoading(true)
|
|
||||||
return fetchData<BasicResponse<{apps:ServiceHubAppListItem}>>(!checkPermission('system.workspace.application.view_all') ? 'my_apps':'apps',{method:'GET',eoParams:{ team:teamId,keyword:tableSearchWord},eoTransformKeys:['api_num','subscribe_num','subscribe_verify_num','auth_num']}).then(response=>{
|
|
||||||
const {code,data,msg} = response
|
const {code,data,msg} = response
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
if(code === STATUS_CODE.SUCCESS){
|
||||||
setServiceList([...data.apps,{type:'addNewItem'}])
|
setServiceList([...data.apps,{type:'addNewItem'}])
|
||||||
@@ -75,38 +78,78 @@ const getServiceList = ()=>{
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const getTeamsList = ()=>{
|
const getTeamsList = () => {
|
||||||
if(!accessInit){
|
setPageLoading(true);
|
||||||
setTimeout(()=>{
|
|
||||||
getGlobalAccessData()?.then?.(()=>{getTeamsList()})
|
const fetchTeams = () => {
|
||||||
},200)
|
fetchData<BasicResponse<{ teams: SimpleTeamItem[] }>>(
|
||||||
return
|
!checkPermission('system.workspace.team.view_all')
|
||||||
}
|
? 'simple/teams/mine'
|
||||||
setPageLoading(true)
|
: 'simple/teams',
|
||||||
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
|
method: 'GET',
|
||||||
if(code === STATUS_CODE.SUCCESS){
|
eoTransformKeys: ['app_num', 'subscribe_num'],
|
||||||
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})))
|
|
||||||
if(!teamId && data.teams?.[0]?.id){
|
|
||||||
navigateTo(data.teams[0].id)
|
|
||||||
}
|
}
|
||||||
}else{
|
)
|
||||||
message.error(msg || $t(RESPONSE_TIPS.error))
|
.then(response => {
|
||||||
}
|
const { code, data, msg } = response;
|
||||||
}).finally(()=>{
|
if (code === STATUS_CODE.SUCCESS) {
|
||||||
setPageLoading(false)
|
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,
|
||||||
|
}))
|
||||||
|
);
|
||||||
|
if (!teamId && data.teams?.[0]?.id) {
|
||||||
|
navigateTo(data.teams[0].id);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
message.error(msg || $t(RESPONSE_TIPS.error));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setPageLoading(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!accessInit) {
|
||||||
|
const checkAccessData = () => {
|
||||||
|
const accessInitd = getGlobalAccessData();
|
||||||
|
if (!accessInitd) {
|
||||||
|
setTimeout(checkAccessData, 100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof accessInitd.then === 'function') {
|
||||||
|
accessInitd.then(fetchTeams);
|
||||||
|
} else {
|
||||||
|
fetchTeams();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
checkAccessData();
|
||||||
|
} else {
|
||||||
|
fetchTeams();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const openModal = async (type:'add'|'edit'|'delete')=>{
|
const openModal = async (type:'add'|'edit'|'delete')=>{
|
||||||
|
|
||||||
let title:string = ''
|
let title:string = ''
|
||||||
let content:string|React.ReactNode = ''
|
let content:string|React.ReactNode = ''
|
||||||
switch (type){
|
switch (type){
|
||||||
case 'add':
|
case 'add':
|
||||||
title=$t('添加消费者')
|
title=$t('添加消费者')
|
||||||
content=<ManagementConfig ref={addManagementRef} type={type} teamId={teamId!} />
|
content=<ManagementConfig ref={addManagementRef} dataShowType={dataShowType} type={type} teamId={teamId!} />
|
||||||
break;
|
break;
|
||||||
// case 'edit':{
|
// case 'edit':{
|
||||||
// title='配置 Open Api'
|
// title='配置 Open Api'
|
||||||
@@ -132,7 +175,15 @@ const getServiceList = ()=>{
|
|||||||
onOk:()=> {
|
onOk:()=> {
|
||||||
switch (type){
|
switch (type){
|
||||||
case 'add':
|
case 'add':
|
||||||
return addManagementRef.current?.save().then((res)=>{if(res === true) getTeamsList();getServiceList()})
|
return addManagementRef.current?.save().then((res)=>{if(res === true) {
|
||||||
|
getTeamsList();
|
||||||
|
if(dataShowType === 'list'){
|
||||||
|
setTableHttpReload(true)
|
||||||
|
tableRef.current?.manualReloadTable()
|
||||||
|
}else{
|
||||||
|
getServiceList()
|
||||||
|
}
|
||||||
|
}})
|
||||||
// case 'edit':
|
// case 'edit':
|
||||||
// return editManagementRef.current?.save().then((res)=>{if(res === true) manualReloadTable()})
|
// return editManagementRef.current?.save().then((res)=>{if(res === true) manualReloadTable()})
|
||||||
// case 'delete':
|
// case 'delete':
|
||||||
@@ -169,7 +220,6 @@ useEffect(() => {
|
|||||||
)
|
)
|
||||||
getTeamsList()
|
getTeamsList()
|
||||||
setAppName('')
|
setAppName('')
|
||||||
console.log()
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
@@ -244,13 +294,13 @@ useEffect(() => {
|
|||||||
customBtn={
|
customBtn={
|
||||||
<Radio.Group
|
<Radio.Group
|
||||||
options={dataShowTypeOptions}
|
options={dataShowTypeOptions}
|
||||||
onChange={(e)=>setDataShowType(e.target.value)}
|
onChange={(e)=>{setDataShowType(e.target.value); setTableHttpReload(true); if(e.target.value === 'block'){getServiceList(e.target.value)}}}
|
||||||
value={dataShowType}
|
value={dataShowType}
|
||||||
optionType="button"
|
optionType="button"
|
||||||
buttonStyle="solid"
|
buttonStyle="solid"
|
||||||
/>}
|
/>}
|
||||||
>{
|
>{
|
||||||
dataShowType === 'block' ? <BlockArea /> : <TableArea language={state.language} getServiceList={getServiceList} addNewApp={()=>openModal('add')} setTableHttpReload={setTableHttpReload} setTableSearchWord={setTableSearchWord} editApp={(row:ServiceHubAppListItem)=>{setAppName(row.name);navigateTo(`/consumer/${row.team.id}/inside/${row.id}/service`)}}/>
|
dataShowType === 'block' ? <BlockArea /> : <TableArea language={state.language} getServiceList={()=>getServiceList('list')} ref={tableRef} addNewApp={()=>openModal('add')} setTableHttpReload={setTableHttpReload} setTableSearchWord={setTableSearchWord} editApp={(row:ServiceHubAppListItem)=>{setAppName(row.name);navigateTo(`/consumer/${row.team.id}/inside/${row.id}/service`)}}/>
|
||||||
}
|
}
|
||||||
</InsidePage> :
|
</InsidePage> :
|
||||||
<Empty className="mt-[100px]" image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
<Empty className="mt-[100px]" image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
||||||
@@ -284,16 +334,31 @@ type TableAreaProps = {
|
|||||||
editApp:(item:ServiceHubAppListItem)=>void
|
editApp:(item:ServiceHubAppListItem)=>void
|
||||||
}
|
}
|
||||||
|
|
||||||
const TableArea = memo(({language, getServiceList, addNewApp, setTableHttpReload, setTableSearchWord, editApp}:TableAreaProps)=>{
|
type TableAreaHandle = {
|
||||||
|
manualReloadTable:()=>void
|
||||||
|
}
|
||||||
|
|
||||||
|
const TableArea = memo(forwardRef((props:TableAreaProps, ref:Ref<TableAreaHandle>)=>{
|
||||||
|
const {language, getServiceList, addNewApp, setTableHttpReload, setTableSearchWord, editApp} = props
|
||||||
|
const pageListRef = useRef<ActionType>(null);
|
||||||
const columns = useMemo(()=>{
|
const columns = useMemo(()=>{
|
||||||
const res = SERVICE_HUB_TABLE_COLUMNS.map(x=>{
|
const res = SERVICE_HUB_TABLE_COLUMNS.map(x=>{
|
||||||
return {...x,title:typeof x.title === 'string' ? $t(x.title as string) : x.title}})
|
return {...x,title:typeof x.title === 'string' ? $t(x.title as string) : x.title}})
|
||||||
return res
|
return res
|
||||||
},[language])
|
},[language])
|
||||||
|
|
||||||
|
const manualReloadTable = ()=>{
|
||||||
|
pageListRef.current?.reload()
|
||||||
|
}
|
||||||
|
|
||||||
|
useImperativeHandle(ref, () =>({
|
||||||
|
manualReloadTable}))
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PageList
|
<PageList
|
||||||
id="service_hub_list"
|
id="service_hub_list"
|
||||||
|
ref={pageListRef}
|
||||||
columns={[...columns]}
|
columns={[...columns]}
|
||||||
request={()=>getServiceList()}
|
request={()=>getServiceList()}
|
||||||
addNewBtnTitle={$t("添加消费者")}
|
addNewBtnTitle={$t("添加消费者")}
|
||||||
@@ -307,4 +372,4 @@ const TableArea = memo(({language, getServiceList, addNewApp, setTableHttpReload
|
|||||||
}}
|
}}
|
||||||
onRowClick={(row:ServiceHubAppListItem)=>editApp(row)}
|
onRowClick={(row:ServiceHubAppListItem)=>editApp(row)}
|
||||||
/>
|
/>
|
||||||
)})
|
)}))
|
||||||
@@ -5,9 +5,9 @@ go 1.21
|
|||||||
//toolchain go1.21.1
|
//toolchain go1.21.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/eolinker/ap-account v1.0.14
|
github.com/eolinker/ap-account v1.0.15
|
||||||
github.com/eolinker/eosc v0.17.3
|
github.com/eolinker/eosc v0.17.3
|
||||||
github.com/eolinker/go-common v1.1.0
|
github.com/eolinker/go-common v1.1.1
|
||||||
github.com/gabriel-vasile/mimetype v1.4.4
|
github.com/gabriel-vasile/mimetype v1.4.4
|
||||||
github.com/getkin/kin-openapi v0.127.0
|
github.com/getkin/kin-openapi v0.127.0
|
||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
@@ -75,4 +75,6 @@ require (
|
|||||||
gorm.io/driver/mysql v1.5.2 // indirect
|
gorm.io/driver/mysql v1.5.2 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
//replace github.com/eolinker/ap-account => ../../eolinker/ap-account
|
//replace github.com/eolinker/ap-account => ../aoaccount
|
||||||
|
//
|
||||||
|
//replace github.com/eolinker/go-common => ../go-common
|
||||||
|
|||||||
@@ -28,12 +28,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/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 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/eolinker/ap-account v1.0.14 h1:QE9LWx9F/t/BbTeBcjPX+Alzh3mdlHv+BVvKcBwr5dc=
|
github.com/eolinker/ap-account v1.0.15 h1:n6DJeL6RHZ8eLlZUcY2U3H4d/GPaA5oelAx3R0E6yL8=
|
||||||
github.com/eolinker/ap-account v1.0.14/go.mod h1:qLKg4xervGHTNBWaGckfPkQb+FZT0XfhwPEdNpzvsjE=
|
github.com/eolinker/ap-account v1.0.15/go.mod h1:zm/Ivs6waJ/M/nEszhpPmM6g50y/MKO+5eABFAdeD0g=
|
||||||
github.com/eolinker/eosc v0.17.3 h1:sr2yT+v/AsqEdciRaaZZj0zL9pTufR5RvDW6+65hraQ=
|
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/eosc v0.17.3/go.mod h1:xgq816hpanlMXFtZw7Ztdctb1eEk9UPHchY4NfFO6Cw=
|
||||||
github.com/eolinker/go-common v1.1.0 h1:n/XXK7yVRen3jhNG/SfZGXJA+KNnaYf0XTDfMeviaBw=
|
github.com/eolinker/go-common v1.1.1 h1:3WqqecGqcHDgpa8Ljp156c1uWeZKP1CKScdU+6sOfcc=
|
||||||
github.com/eolinker/go-common v1.1.0/go.mod h1:Kb/jENMN1mApnodvRgV4YwO9FJby1Jkt2EUjrBjvSX4=
|
github.com/eolinker/go-common v1.1.1/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 h1:QjV6pZ7/XZ7ryI2KuyeEDE8wnh7fHP9YnQy+R0LnH8I=
|
||||||
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
|
github.com/gabriel-vasile/mimetype v1.4.4/go.mod h1:JwLei5XPtWdGiMFB5Pjle1oEeoSeEuJfJE+TtfvdB/s=
|
||||||
github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY=
|
github.com/getkin/kin-openapi v0.127.0 h1:Mghqi3Dhryf3F8vR370nN67pAERW+3a95vomb3MAREY=
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
// init module
|
||||||
import (
|
import (
|
||||||
_ "github.com/APIParkLab/APIPark/frontend"
|
_ "github.com/APIParkLab/APIPark/frontend"
|
||||||
_ "github.com/APIParkLab/APIPark/gateway/apinto"
|
_ "github.com/APIParkLab/APIPark/gateway/apinto"
|
||||||
_ "github.com/APIParkLab/APIPark/plugins/core"
|
_ "github.com/APIParkLab/APIPark/plugins/core"
|
||||||
_ "github.com/APIParkLab/APIPark/plugins/permit"
|
_ "github.com/APIParkLab/APIPark/plugins/permit"
|
||||||
_ "github.com/APIParkLab/APIPark/plugins/publish_flow"
|
_ "github.com/APIParkLab/APIPark/plugins/publish_flow"
|
||||||
|
_ "github.com/APIParkLab/APIPark/resources/locale"
|
||||||
_ "github.com/eolinker/ap-account/plugin"
|
_ "github.com/eolinker/ap-account/plugin"
|
||||||
_ "github.com/eolinker/go-common/cache/cache_redis"
|
_ "github.com/eolinker/go-common/cache/cache_redis"
|
||||||
_ "github.com/eolinker/go-common/log-init"
|
_ "github.com/eolinker/go-common/log-init"
|
||||||
|
|||||||
@@ -9,5 +9,4 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func doCheck() {
|
func doCheck() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-14
@@ -6,6 +6,11 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/csv"
|
"encoding/csv"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
_ "github.com/APIParkLab/APIPark/resources/access"
|
_ "github.com/APIParkLab/APIPark/resources/access"
|
||||||
_ "github.com/APIParkLab/APIPark/resources/permit"
|
_ "github.com/APIParkLab/APIPark/resources/permit"
|
||||||
_ "github.com/APIParkLab/APIPark/resources/plugin"
|
_ "github.com/APIParkLab/APIPark/resources/plugin"
|
||||||
@@ -14,19 +19,15 @@ import (
|
|||||||
"github.com/eolinker/go-common/permit"
|
"github.com/eolinker/go-common/permit"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
"github.com/eolinker/go-common/utils"
|
"github.com/eolinker/go-common/utils"
|
||||||
"os"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const unsetValue = "-"
|
const unsetValue = "-"
|
||||||
|
|
||||||
func doCheck() {
|
func doCheck() {
|
||||||
accessConf, unset := loadAccess()
|
accessConf, unset := loadAccess()
|
||||||
|
|
||||||
drivers := pm3.List()
|
drivers := pm3.List()
|
||||||
|
|
||||||
newAccess := 0
|
newAccess := 0
|
||||||
for _, p := range drivers {
|
for _, p := range drivers {
|
||||||
if ac, ok := p.(pm3.AccessConfig); ok {
|
if ac, ok := p.(pm3.AccessConfig); ok {
|
||||||
@@ -39,9 +40,9 @@ func doCheck() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
for asKey := range permit.All() {
|
for asKey := range permit.All() {
|
||||||
key := strings.ToLower(asKey)
|
key := strings.ToLower(asKey)
|
||||||
@@ -53,12 +54,11 @@ func doCheck() {
|
|||||||
if newAccess > 0 || unset > 0 {
|
if newAccess > 0 || unset > 0 {
|
||||||
f := accessFile()
|
f := accessFile()
|
||||||
fmt.Printf("%d access need set, see : %s and %s", newAccess+unset, saveTemplate(accessConf, f), saveCsv(accessConf, f))
|
fmt.Printf("%d access need set, see : %s and %s", newAccess+unset, saveTemplate(accessConf, f), saveCsv(accessConf, f))
|
||||||
|
|
||||||
}
|
}
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
func accessFile() string {
|
func accessFile() string {
|
||||||
|
|
||||||
if version == "" {
|
if version == "" {
|
||||||
return time.Now().Format("20060102-150405")
|
return time.Now().Format("20060102-150405")
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ func saveCsv(as map[string]*Access, key string) string {
|
|||||||
err = os.WriteFile(filePath, buf.Bytes(), 0666)
|
err = os.WriteFile(filePath, buf.Bytes(), 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
||||||
}
|
}
|
||||||
return filePath
|
return filePath
|
||||||
}
|
}
|
||||||
@@ -111,9 +111,9 @@ func (ls AccessListSort) Swap(i, j int) {
|
|||||||
|
|
||||||
func saveTemplate(as map[string]*Access, key string) string {
|
func saveTemplate(as map[string]*Access, key string) string {
|
||||||
out := make(map[string][]access.Access)
|
out := make(map[string][]access.Access)
|
||||||
|
|
||||||
for _, a := range as {
|
for _, a := range as {
|
||||||
|
|
||||||
out[a.Group] = append(out[a.Group], access.Access{
|
out[a.Group] = append(out[a.Group], access.Access{
|
||||||
Name: a.Name,
|
Name: a.Name,
|
||||||
CName: a.Cname,
|
CName: a.Cname,
|
||||||
@@ -130,7 +130,7 @@ func saveTemplate(as map[string]*Access, key string) string {
|
|||||||
err = os.WriteFile(filePath, buf.Bytes(), 0666)
|
err = os.WriteFile(filePath, buf.Bytes(), 0666)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|
||||||
}
|
}
|
||||||
return filePath
|
return filePath
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ package main
|
|||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
"github.com/eolinker/eosc/log"
|
"github.com/eolinker/eosc/log"
|
||||||
"github.com/eolinker/go-common/autowire"
|
"github.com/eolinker/go-common/autowire"
|
||||||
"github.com/eolinker/go-common/cftool"
|
"github.com/eolinker/go-common/cftool"
|
||||||
"github.com/eolinker/go-common/permit"
|
"github.com/eolinker/go-common/permit"
|
||||||
"github.com/eolinker/go-common/server"
|
"github.com/eolinker/go-common/server"
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -54,7 +55,6 @@ func main() {
|
|||||||
for access, paths := range srv.Permits() {
|
for access, paths := range srv.Permits() {
|
||||||
permit.AddPermitRule(access, paths...)
|
permit.AddPermitRule(access, paths...)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = http.Serve(ln, srv)
|
err = http.Serve(ln, srv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package permit_middleware
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
permit_identity "github.com/APIParkLab/APIPark/middleware/permit/identity"
|
permit_identity "github.com/APIParkLab/APIPark/middleware/permit/identity"
|
||||||
"github.com/eolinker/eosc/log"
|
"github.com/eolinker/eosc/log"
|
||||||
"github.com/eolinker/go-common/autowire"
|
"github.com/eolinker/go-common/autowire"
|
||||||
@@ -42,11 +42,11 @@ func (p *PermitMiddleware) Sort() int {
|
|||||||
func (p *PermitMiddleware) Check(method string, path string) (bool, []gin.HandlerFunc) {
|
func (p *PermitMiddleware) Check(method string, path string) (bool, []gin.HandlerFunc) {
|
||||||
// 当前路径是否有配置权限
|
// 当前路径是否有配置权限
|
||||||
accessRules, has := permit.GetPathRule(method, path)
|
accessRules, has := permit.GetPathRule(method, path)
|
||||||
|
|
||||||
if !has || len(accessRules) == 0 {
|
if !has || len(accessRules) == 0 {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return true, []gin.HandlerFunc{
|
return true, []gin.HandlerFunc{
|
||||||
func(ginCtx *gin.Context) {
|
func(ginCtx *gin.Context) {
|
||||||
userId := utils.UserId(ginCtx)
|
userId := utils.UserId(ginCtx)
|
||||||
@@ -56,19 +56,14 @@ func (p *PermitMiddleware) Check(method string, path string) (bool, []gin.Handle
|
|||||||
ginCtx.Abort()
|
ginCtx.Abort()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//if userId == "admin" {
|
|
||||||
// // 超级管理员不校验
|
|
||||||
// return
|
|
||||||
//}
|
|
||||||
|
|
||||||
for _, group := range checkSort {
|
for _, group := range checkSort {
|
||||||
accessList, has := accessRules[group]
|
accessList, has := accessRules[group]
|
||||||
if !has {
|
if !has {
|
||||||
// 当前分组没有配置权限
|
// 当前分组没有配置权限
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
domainHandler, has := permit.SelectDomain(group)
|
domainHandler, has := permit.SelectDomain(group)
|
||||||
if !has {
|
if !has {
|
||||||
// 当前分组没有配置身份handler
|
// 当前分组没有配置身份handler
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ type Kind int
|
|||||||
|
|
||||||
func (k *Kind) UnmarshalJSON(bytes []byte) error {
|
func (k *Kind) UnmarshalJSON(bytes []byte) error {
|
||||||
str := ""
|
str := ""
|
||||||
|
|
||||||
err := json.Unmarshal(bytes, &str)
|
err := json.Unmarshal(bytes, &str)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
+4
-11
@@ -348,20 +348,13 @@ func (i *imlProviderModule) UpdateProviderDefaultLLM(ctx context.Context, id str
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *imlProviderModule) getAiProviders(ctx context.Context, clusterId string) ([]*gateway.DynamicRelease, error) {
|
func (i *imlProviderModule) getAiProviders(ctx context.Context) ([]*gateway.DynamicRelease, error) {
|
||||||
list, err := i.providerService.List(ctx, clusterId)
|
list, err := i.providerService.List(ctx)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
providers := make([]*gateway.DynamicRelease, 0, len(list))
|
providers := make([]*gateway.DynamicRelease, 0, len(list))
|
||||||
for _, p := range list {
|
for _, p := range list {
|
||||||
if !p.Status {
|
|
||||||
// 关闭
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
cfg := make(map[string]interface{})
|
cfg := make(map[string]interface{})
|
||||||
err = json.Unmarshal([]byte(p.Config), &cfg)
|
err = json.Unmarshal([]byte(p.Config), &cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -384,7 +377,7 @@ func (i *imlProviderModule) getAiProviders(ctx context.Context, clusterId string
|
|||||||
return providers, nil
|
return providers, nil
|
||||||
}
|
}
|
||||||
func (i *imlProviderModule) initGateway(ctx context.Context, clusterId string, clientDriver gateway.IClientDriver) error {
|
func (i *imlProviderModule) initGateway(ctx context.Context, clusterId string, clientDriver gateway.IClientDriver) error {
|
||||||
providers, err := i.getAiProviders(ctx, clusterId)
|
providers, err := i.getAiProviders(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -401,7 +394,7 @@ func (i *imlProviderModule) initGateway(ctx context.Context, clusterId string, c
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = client.Online(ctx, providers...)
|
err = client.Online(ctx, p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -320,6 +320,7 @@ func (i *imlCatalogueModule) Services(ctx context.Context, keyword string) ([]*c
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
serviceIds := utils.SliceToSlice(items, func(i *service.Service) string {
|
serviceIds := utils.SliceToSlice(items, func(i *service.Service) string {
|
||||||
return i.Id
|
return i.Id
|
||||||
}, func(s *service.Service) bool {
|
}, func(s *service.Service) bool {
|
||||||
@@ -330,6 +331,7 @@ func (i *imlCatalogueModule) Services(ctx context.Context, keyword string) ([]*c
|
|||||||
if len(serviceIds) < 1 {
|
if len(serviceIds) < 1 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
commits, err := i.releaseService.GetRunningApiDocCommits(ctx, serviceIds...)
|
commits, err := i.releaseService.GetRunningApiDocCommits(ctx, serviceIds...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -75,11 +75,14 @@ type App struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ToService(model *service.Service) *Service {
|
func ToService(model *service.Service) *Service {
|
||||||
|
prefix := "/"
|
||||||
|
if model.Prefix != "" {
|
||||||
|
prefix = model.Prefix
|
||||||
|
}
|
||||||
s := &Service{
|
s := &Service{
|
||||||
Id: model.Id,
|
Id: model.Id,
|
||||||
Name: model.Name,
|
Name: model.Name,
|
||||||
Prefix: model.Prefix,
|
Prefix: prefix,
|
||||||
Description: model.Description,
|
Description: model.Description,
|
||||||
Team: auto.UUID(model.Team),
|
Team: auto.UUID(model.Team),
|
||||||
ServiceType: model.ServiceType.String(),
|
ServiceType: model.ServiceType.String(),
|
||||||
|
|||||||
@@ -6,6 +6,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/eolinker/eosc/log"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
|
|
||||||
|
"github.com/eolinker/ap-account/service/role"
|
||||||
|
|
||||||
application_authorization "github.com/APIParkLab/APIPark/service/application-authorization"
|
application_authorization "github.com/APIParkLab/APIPark/service/application-authorization"
|
||||||
|
|
||||||
@@ -227,6 +234,7 @@ func (i *imlServiceModule) SearchMyServices(ctx context.Context, teamId string,
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
func (i *imlServiceModule) Get(ctx context.Context, id string) (*service_dto.Service, error) {
|
func (i *imlServiceModule) Get(ctx context.Context, id string) (*service_dto.Service, error) {
|
||||||
|
now := time.Now()
|
||||||
serviceInfo, err := i.serviceService.Get(ctx, id)
|
serviceInfo, err := i.serviceService.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -240,6 +248,7 @@ func (i *imlServiceModule) Get(ctx context.Context, id string) (*service_dto.Ser
|
|||||||
s.Tags = auto.List(utils.SliceToSlice(tags, func(p *service_tag.Tag) string {
|
s.Tags = auto.List(utils.SliceToSlice(tags, func(p *service_tag.Tag) string {
|
||||||
return p.Tid
|
return p.Tid
|
||||||
}))
|
}))
|
||||||
|
log.Infof("get service cost %d ms", time.Since(now).Milliseconds())
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,9 +548,72 @@ type imlAppModule struct {
|
|||||||
teamMemberService team_member.ITeamMemberService `autowired:""`
|
teamMemberService team_member.ITeamMemberService `autowired:""`
|
||||||
subscribeService subscribe.ISubscribeService `autowired:""`
|
subscribeService subscribe.ISubscribeService `autowired:""`
|
||||||
authService application_authorization.IAuthorizationService `autowired:""`
|
authService application_authorization.IAuthorizationService `autowired:""`
|
||||||
|
roleService role.IRoleService `autowired:""`
|
||||||
|
roleMemberService role.IRoleMemberService `autowired:""`
|
||||||
transaction store.ITransaction `autowired:""`
|
transaction store.ITransaction `autowired:""`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *imlAppModule) SearchCanSubscribe(ctx context.Context, serviceId string) ([]*service_dto.SimpleAppItem, error) {
|
||||||
|
apps, err := i.searchMyApps(ctx, "", "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
list, err := i.roleService.ListByPermit(ctx, access.SystemWorkspaceApplicationManagerAll)
|
||||||
|
if err == nil && len(list) > 0 {
|
||||||
|
return utils.SliceToSlice(apps, func(p *service.Service) *service_dto.SimpleAppItem {
|
||||||
|
return &service_dto.SimpleAppItem{
|
||||||
|
Id: p.Id,
|
||||||
|
Name: p.Name,
|
||||||
|
Description: p.Description,
|
||||||
|
Team: auto.UUID(p.Team),
|
||||||
|
}
|
||||||
|
}), nil
|
||||||
|
}
|
||||||
|
list, err = i.roleService.ListByPermit(ctx, access.TeamConsumerSubscriptionSubscribe)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
roleIds := utils.SliceToSlice(list, func(p *role.RoleByPermit) string {
|
||||||
|
return p.Id
|
||||||
|
})
|
||||||
|
members, err := i.roleMemberService.ListByRoleIds(ctx, utils.UserId(ctx), roleIds...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(members) == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
subscribes, err := i.subscribeService.ListByServices(ctx, serviceId)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
subscribeMap := utils.SliceToMapO(subscribes, func(p *subscribe.Subscribe) (string, struct{}) {
|
||||||
|
return p.Application, struct{}{}
|
||||||
|
}, func(s *subscribe.Subscribe) bool {
|
||||||
|
return s.ApplyStatus == subscribe.ApplyStatusSubscribe
|
||||||
|
})
|
||||||
|
teamMap := utils.SliceToMapO(members, func(p *role.Member) (string, struct{}) {
|
||||||
|
return role.TrimTeamTarget(p.Target), struct{}{}
|
||||||
|
})
|
||||||
|
result := make([]*service_dto.SimpleAppItem, 0, len(apps))
|
||||||
|
for _, app := range apps {
|
||||||
|
if _, ok := teamMap[app.Team]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := subscribeMap[app.Id]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result = append(result, &service_dto.SimpleAppItem{
|
||||||
|
Id: app.Id,
|
||||||
|
Name: app.Name,
|
||||||
|
Description: app.Description,
|
||||||
|
Team: auto.UUID(app.Team),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (i *imlAppModule) ExportAll(ctx context.Context) ([]*service_dto.ExportApp, error) {
|
func (i *imlAppModule) ExportAll(ctx context.Context) ([]*service_dto.ExportApp, error) {
|
||||||
apps, err := i.serviceService.AppList(ctx)
|
apps, err := i.serviceService.AppList(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ type IAppModule interface {
|
|||||||
UpdateApp(ctx context.Context, appId string, input *service_dto.UpdateApp) (*service_dto.App, error)
|
UpdateApp(ctx context.Context, appId string, input *service_dto.UpdateApp) (*service_dto.App, error)
|
||||||
Search(ctx context.Context, teamId string, keyword string) ([]*service_dto.AppItem, error)
|
Search(ctx context.Context, teamId string, keyword string) ([]*service_dto.AppItem, error)
|
||||||
SearchMyApps(ctx context.Context, teamId string, keyword string) ([]*service_dto.AppItem, error)
|
SearchMyApps(ctx context.Context, teamId string, keyword string) ([]*service_dto.AppItem, error)
|
||||||
|
SearchCanSubscribe(ctx context.Context, serviceId string) ([]*service_dto.SimpleAppItem, error)
|
||||||
// SimpleApps 获取简易项目列表
|
// SimpleApps 获取简易项目列表
|
||||||
SimpleApps(ctx context.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
|
SimpleApps(ctx context.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
|
||||||
MySimpleApps(ctx context.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
|
MySimpleApps(ctx context.Context, keyword string) ([]*service_dto.SimpleAppItem, error)
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
package core
|
|
||||||
+8
-5
@@ -1,19 +1,22 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/eolinker/go-common/pm3"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
|
|
||||||
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) aiAPIs() []pm3.Api {
|
func (p *plugin) aiAPIs() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/providers", []string{"context"}, []string{"providers"}, p.aiProviderController.Providers),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/providers", []string{"context"}, []string{"providers"}, p.aiProviderController.Providers, access.SystemSettingsAiProviderView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/ai/providers", []string{"context"}, []string{"providers"}, p.aiProviderController.SimpleProviders),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/ai/providers", []string{"context"}, []string{"providers"}, p.aiProviderController.SimpleProviders),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/config", []string{"context", "query:provider"}, []string{"provider"}, p.aiProviderController.Provider),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/config", []string{"context", "query:provider"}, []string{"provider"}, p.aiProviderController.Provider, access.SystemSettingsAiProviderView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/llms", []string{"context", "query:provider"}, []string{"llms", "provider"}, p.aiProviderController.LLMs),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai/provider/llms", []string{"context", "query:provider"}, []string{"llms", "provider"}, p.aiProviderController.LLMs),
|
||||||
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/enable", []string{"context", "query:provider"}, nil, p.aiProviderController.Enable),
|
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/enable", []string{"context", "query:provider"}, nil, p.aiProviderController.Enable),
|
||||||
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/disable", []string{"context", "query:provider"}, nil, p.aiProviderController.Disable),
|
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/disable", []string{"context", "query:provider"}, nil, p.aiProviderController.Disable),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/config", []string{"context", "query:provider", "body"}, nil, p.aiProviderController.UpdateProviderConfig),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/config", []string{"context", "query:provider", "body"}, nil, p.aiProviderController.UpdateProviderConfig, access.SystemSettingsAiProviderManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/default-llm", []string{"context", "query:provider", "body"}, nil, p.aiProviderController.UpdateProviderDefaultLLM),
|
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai/provider/default-llm", []string{"context", "query:provider", "body"}, nil, p.aiProviderController.UpdateProviderDefaultLLM),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-13
@@ -3,27 +3,28 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) apiApis() []pm3.Api {
|
func (p *plugin) apiApis() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/routers", []string{"context", "query:keyword", "query:service"}, []string{"routers"}, p.routerController.Search),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/routers", []string{"context", "query:keyword", "query:service"}, []string{"routers"}, p.routerController.Search, access.SystemWorkspaceServiceViewAll, access.TeamServiceApiView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/router/detail", []string{"context", "query:service", "query:router"}, []string{"router"}, p.routerController.Detail),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/router/detail", []string{"context", "query:service", "query:router"}, []string{"router"}, p.routerController.Detail, access.SystemWorkspaceServiceViewAll, access.TeamServiceApiView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/router", []string{"context", "query:service", "body"}, []string{"router"}, p.routerController.Create),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/router", []string{"context", "query:service", "body"}, []string{"router"}, p.routerController.Create, access.SystemWorkspaceServiceManagerAll, access.TeamServiceApiManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/router", []string{"context", "query:service", "query:router", "body"}, []string{"router"}, p.routerController.Edit),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/router", []string{"context", "query:service", "query:router", "body"}, []string{"router"}, p.routerController.Edit, access.SystemWorkspaceServiceManagerAll, access.TeamServiceApiManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/router", []string{"context", "query:service", "query:router"}, nil, p.routerController.Delete),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/router", []string{"context", "query:service", "query:router"}, nil, p.routerController.Delete, access.SystemWorkspaceServiceManagerAll, access.TeamServiceApiManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/router/define", []string{"context", "query:service"}, []string{"prefix", "force"}, p.routerController.Prefix),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/router/define", []string{"context", "query:service"}, []string{"prefix", "force"}, p.routerController.Prefix),
|
||||||
|
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/api_doc", []string{"context", "query:service", "body"}, []string{"doc"}, p.apiDocController.UpdateDoc),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/api_doc", []string{"context", "query:service", "body"}, []string{"doc"}, p.apiDocController.UpdateDoc, access.SystemWorkspaceServiceManagerAll, access.TeamServiceApiDocManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/api_doc", []string{"context", "query:service"}, []string{"doc"}, p.apiDocController.GetDoc),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/api_doc", []string{"context", "query:service"}, []string{"doc"}, p.apiDocController.GetDoc, access.SystemWorkspaceServiceViewAll, access.TeamServiceApiDocView),
|
||||||
|
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/api_doc/upload", []string{"context", "query:service"}, []string{"doc"}, p.apiDocController.UploadDoc),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/api_doc/upload", []string{"context", "query:service"}, []string{"doc"}, p.apiDocController.UploadDoc, access.SystemWorkspaceServiceManagerAll, access.TeamServiceApiDocManager),
|
||||||
|
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/ai-router", []string{"context", "query:service", "query:router"}, []string{"api"}, p.aiAPIController.Get),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/ai-router", []string{"context", "query:service", "query:router"}, []string{"api"}, p.aiAPIController.Get, access.SystemWorkspaceServiceViewAll, access.TeamServiceApiView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/ai-routers", []string{"context", "query:keyword", "query:service"}, []string{"apis"}, p.aiAPIController.List),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/ai-routers", []string{"context", "query:keyword", "query:service"}, []string{"apis"}, p.aiAPIController.List, access.SystemWorkspaceServiceViewAll, access.TeamServiceApiView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/ai-router", []string{"context", "query:service", "query:router", "body"}, []string{"api"}, p.aiAPIController.Edit),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/ai-router", []string{"context", "query:service", "query:router", "body"}, []string{"api"}, p.aiAPIController.Edit, access.SystemWorkspaceServiceManagerAll, access.TeamServiceApiManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/ai-router", []string{"context", "query:service", "body"}, []string{"api"}, p.aiAPIController.Create),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/ai-router", []string{"context", "query:service", "body"}, []string{"api"}, p.aiAPIController.Create, access.SystemWorkspaceServiceManagerAll, access.TeamServiceApiManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/ai-router", []string{"context", "query:service", "query:router"}, nil, p.aiAPIController.Delete),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/ai-router", []string{"context", "query:service", "query:router"}, nil, p.aiAPIController.Delete, access.SystemWorkspaceServiceManagerAll, access.TeamServiceApiManager),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,17 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) projectAuthorizationApis() []pm3.Api {
|
func (p *plugin) appAuthorizationApis() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/app/authorization", []string{"context", "query:app", "body"}, []string{"authorization"}, p.appAuthorizationController.AddAuthorization),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/app/authorization", []string{"context", "query:app", "body"}, []string{"authorization"}, p.appAuthorizationController.AddAuthorization, access.SystemWorkspaceApplicationManagerAll, access.TeamConsumerAuthorizationManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/app/authorization", []string{"context", "query:app", "query:authorization", "body"}, []string{"authorization"}, p.appAuthorizationController.EditAuthorization),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/app/authorization", []string{"context", "query:app", "query:authorization", "body"}, []string{"authorization"}, p.appAuthorizationController.EditAuthorization, access.SystemWorkspaceApplicationManagerAll, access.TeamConsumerAuthorizationManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/app/authorization", []string{"context", "query:app", "query:authorization"}, nil, p.appAuthorizationController.DeleteAuthorization),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/app/authorization", []string{"context", "query:app", "query:authorization"}, nil, p.appAuthorizationController.DeleteAuthorization, access.SystemWorkspaceApplicationManagerAll, access.TeamConsumerAuthorizationManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/app/authorization", []string{"context", "query:app", "query:authorization"}, []string{"authorization"}, p.appAuthorizationController.Info),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/app/authorization", []string{"context", "query:app", "query:authorization"}, []string{"authorization"}, p.appAuthorizationController.Info, access.SystemWorkspaceApplicationViewAll, access.TeamConsumerAuthorizationView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/app/authorizations", []string{"context", "query:app"}, []string{"authorizations"}, p.appAuthorizationController.Authorizations),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/app/authorizations", []string{"context", "query:app"}, []string{"authorizations"}, p.appAuthorizationController.Authorizations, access.SystemWorkspaceApplicationViewAll, access.TeamConsumerAuthorizationView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/app/authorization/details", []string{"context", "query:app", "query:authorization"}, []string{"details"}, p.appAuthorizationController.Detail),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/app/authorization/details", []string{"context", "query:app", "query:authorization"}, []string{"details"}, p.appAuthorizationController.Detail, access.SystemWorkspaceApplicationViewAll, access.TeamConsumerAuthorizationView),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,15 +3,16 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) certificateApi() []pm3.Api {
|
func (p *plugin) certificateApi() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/certificates", []string{"context"}, []string{"certificates"}, p.certificateController.ListForPartition),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/certificates", []string{"context"}, []string{"certificates"}, p.certificateController.ListForPartition, access.SystemSettingsSslCertificateView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/certificate", []string{"context", "query:id"}, []string{"certificate", "cert"}, p.certificateController.Detail),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/certificate", []string{"context", "query:id"}, []string{"certificate", "cert"}, p.certificateController.Detail, access.SystemSettingsSslCertificateView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/certificate", []string{"context", "body"}, nil, p.certificateController.Create),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/certificate", []string{"context", "body"}, nil, p.certificateController.Create, access.SystemSettingsSslCertificateManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/certificate", []string{"context", "query:id", "body"}, nil, p.certificateController.Update),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/certificate", []string{"context", "query:id", "body"}, nil, p.certificateController.Update, access.SystemSettingsSslCertificateManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/certificate", []string{"context", "query:id"}, []string{"id"}, p.certificateController.Delete),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/certificate", []string{"context", "query:id"}, []string{"id"}, p.certificateController.Delete, access.SystemSettingsSslCertificateManager),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) clusterApi() []pm3.Api {
|
func (p *plugin) clusterApi() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/cluster/nodes", []string{"context", "query:partition"}, []string{"nodes"}, p.clusterController.Nodes),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/cluster/nodes", []string{"context", "query:partition"}, []string{"nodes"}, p.clusterController.Nodes, access.SystemSettingsApiGatewayView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/cluster/reset", []string{"context", "query:partition", "body"}, []string{"nodes"}, p.clusterController.ResetCluster),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/cluster/reset", []string{"context", "query:partition", "body"}, []string{"nodes"}, p.clusterController.ResetCluster, access.SystemSettingsApiGatewayManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/cluster/check", []string{"context", "body"}, []string{"nodes"}, p.clusterController.Check),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/cluster/check", []string{"context", "body"}, []string{"nodes"}, p.clusterController.Check, access.SystemSettingsApiGatewayManager),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ func (p *plugin) OnComplete() {
|
|||||||
p.apis = append(p.apis, p.upstreamApis()...)
|
p.apis = append(p.apis, p.upstreamApis()...)
|
||||||
p.apis = append(p.apis, p.apiApis()...)
|
p.apis = append(p.apis, p.apiApis()...)
|
||||||
p.apis = append(p.apis, p.subscribeApis()...)
|
p.apis = append(p.apis, p.subscribeApis()...)
|
||||||
p.apis = append(p.apis, p.projectAuthorizationApis()...)
|
p.apis = append(p.apis, p.appAuthorizationApis()...)
|
||||||
p.apis = append(p.apis, p.releaseApis()...)
|
p.apis = append(p.apis, p.releaseApis()...)
|
||||||
p.apis = append(p.apis, p.DynamicModuleApis()...)
|
p.apis = append(p.apis, p.DynamicModuleApis()...)
|
||||||
p.apis = append(p.apis, p.monitorStatisticApis()...)
|
p.apis = append(p.apis, p.monitorStatisticApis()...)
|
||||||
|
|||||||
@@ -3,18 +3,19 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) monitorStatisticApis() []pm3.Api {
|
func (p *plugin) monitorStatisticApis() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/overview/top10", []string{"context", "body"}, []string{"top10"}, p.monitorStatisticController.Top10),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/overview/top10", []string{"context", "body"}, []string{"top10"}, p.monitorStatisticController.Top10, access.SystemAnalysisRunViewView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/overview/summary", []string{"context", "body"}, []string{"request_summary", "proxy_summary"}, p.monitorStatisticController.Summary),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/overview/summary", []string{"context", "body"}, []string{"request_summary", "proxy_summary"}, p.monitorStatisticController.Summary, access.SystemAnalysisRunViewView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/overview/invoke", []string{"context", "body"}, []string{"date", "request_total", "proxy_total", "status_4xx", "status_5xx", "request_rate", "proxy_rate", "time_interval"}, p.monitorStatisticController.OverviewInvokeTrend),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/overview/invoke", []string{"context", "body"}, []string{"date", "request_total", "proxy_total", "status_4xx", "status_5xx", "request_rate", "proxy_rate", "time_interval"}, p.monitorStatisticController.OverviewInvokeTrend, access.SystemAnalysisRunViewView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/overview/message", []string{"context", "body"}, []string{"date", "request_message", "response_message", "time_interval"}, p.monitorStatisticController.OverviewMessageTrend),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/overview/message", []string{"context", "body"}, []string{"date", "request_message", "response_message", "time_interval"}, p.monitorStatisticController.OverviewMessageTrend, access.SystemAnalysisRunViewView),
|
||||||
|
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/config", []string{"context", "body"}, []string{"info"}, p.monitorConfigController.SaveMonitorConfig),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/monitor/config", []string{"context", "body"}, []string{"info"}, p.monitorConfigController.SaveMonitorConfig, access.SystemSettingsDataSourceManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/monitor/config", []string{"context"}, []string{"info"}, p.monitorConfigController.GetMonitorConfig),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/monitor/config", []string{"context"}, []string{"info"}, p.monitorConfigController.GetMonitorConfig, access.SystemSettingsDataSourceView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/monitor/clusters", []string{"context"}, []string{"clusters"}, p.monitorConfigController.GetMonitorCluster),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/monitor/clusters", []string{"context"}, []string{"clusters"}, p.monitorConfigController.GetMonitorCluster),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-10
@@ -3,27 +3,28 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) MyTeamApi() []pm3.Api {
|
func (p *plugin) MyTeamApi() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/team", []string{"context", "query:team"}, []string{"team"}, p.myTeamController.GetTeam),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/team", []string{"context", "query:team"}, []string{"team"}, p.myTeamController.GetTeam, access.SystemWorkspaceTeamViewAll, access.TeamTeamTeamView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/teams", []string{"context", "query:keyword"}, []string{"teams"}, p.myTeamController.Search),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/teams", []string{"context", "query:keyword"}, []string{"teams"}, p.myTeamController.Search),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/teams/mine", []string{"context", "query:keyword"}, []string{"teams"}, p.myTeamController.MySimpleTeams),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/teams/mine", []string{"context", "query:keyword"}, []string{"teams"}, p.myTeamController.MySimpleTeams),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/teams", []string{"context", "query:keyword"}, []string{"teams"}, p.myTeamController.SimpleTeams),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/teams", []string{"context", "query:keyword"}, []string{"teams"}, p.myTeamController.SimpleTeams),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/team/members/simple", []string{"context", "query:team", "query:keyword"}, []string{"teams"}, p.myTeamController.SimpleMembers),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/team/members/simple", []string{"context", "query:team", "query:keyword"}, []string{"teams"}, p.myTeamController.SimpleMembers),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/team", []string{"context", "query:team", "body"}, []string{"team"}, p.myTeamController.EditTeam),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/team", []string{"context", "query:team", "body"}, []string{"team"}, p.myTeamController.EditTeam, access.SystemWorkspaceTeamManager, access.TeamTeamTeamManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/team/member", []string{"context", "query:team", "body"}, nil, p.myTeamController.AddMember),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/team/member", []string{"context", "query:team", "body"}, nil, p.myTeamController.AddMember, access.SystemWorkspaceTeamManager, access.TeamTeamMemberManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/team/member", []string{"context", "query:team", "query:user"}, nil, p.myTeamController.RemoveMember),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/team/member", []string{"context", "query:team", "query:user"}, nil, p.myTeamController.RemoveMember, access.SystemWorkspaceTeamManager, access.TeamTeamMemberManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/team/members", []string{"context", "query:team", "query:keyword"}, []string{"members"}, p.myTeamController.Members),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/team/members", []string{"context", "query:team", "query:keyword"}, []string{"members"}, p.myTeamController.Members, access.SystemWorkspaceTeamViewAll, access.TeamTeamMemberView),
|
||||||
|
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/team/member/role", []string{"context", "query:team", "body"}, nil, p.myTeamController.UpdateMemberRole),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/team/member/role", []string{"context", "query:team", "body"}, nil, p.myTeamController.UpdateMemberRole, access.SystemWorkspaceTeamManager, access.TeamTeamMemberManager),
|
||||||
|
|
||||||
// 团队项目操作
|
// 团队项目操作
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/team/services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.Search),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/team/services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.Search, access.SystemWorkspaceServiceViewAll, access.TeamTeamServiceView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/team/service", []string{"context", "query:team", "body"}, []string{"service"}, p.serviceController.Create),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/team/service", []string{"context", "query:team", "body"}, []string{"service"}, p.serviceController.Create, access.SystemWorkspaceServiceManagerAll, access.TeamTeamServiceManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/team/app", []string{"context", "query:team", "body"}, []string{"app"}, p.appController.CreateApp),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/team/app", []string{"context", "query:team", "body"}, []string{"app"}, p.appController.CreateApp, access.SystemWorkspaceApplicationManagerAll, access.TeamTeamConsumerManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/team/service", []string{"context", "query:service"}, nil, p.serviceController.Delete),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/team/service", []string{"context", "query:service"}, nil, p.serviceController.Delete, access.SystemWorkspaceServiceManagerAll, access.TeamTeamServiceManager),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,17 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) releaseApis() []pm3.Api {
|
func (p *plugin) releaseApis() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
|
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/release", []string{"context", "query:service", "body"}, []string{}, p.releaseController.Create),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/release", []string{"context", "query:service", "body"}, []string{}, p.releaseController.Create, access.SystemWorkspaceServiceManagerAll, access.TeamServiceReleaseManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/release", []string{"context", "query:service", "query:id"}, []string{}, p.releaseController.Delete),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/release", []string{"context", "query:service", "query:id"}, []string{}, p.releaseController.Delete, access.SystemWorkspaceServiceManagerAll, access.TeamServiceReleaseManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/release", []string{"context", "query:service", "query:id"}, []string{"release"}, p.releaseController.Detail),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/release", []string{"context", "query:service", "query:id"}, []string{"release"}, p.releaseController.Detail, access.SystemWorkspaceServiceViewAll, access.TeamServiceReleaseView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/releases", []string{"context", "query:service"}, []string{"releases"}, p.releaseController.List),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/releases", []string{"context", "query:service"}, []string{"releases"}, p.releaseController.List, access.SystemWorkspaceServiceViewAll, access.TeamServiceReleaseView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/release/preview", []string{"context", "query:service"}, []string{"running", "diff", "complete"}, p.releaseController.Preview),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/release/preview", []string{"context", "query:service"}, []string{"running", "diff", "complete"}, p.releaseController.Preview, access.SystemWorkspaceServiceViewAll, access.TeamServiceReleaseView),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-23
@@ -3,40 +3,29 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) ServiceApis() []pm3.Api {
|
func (p *plugin) ServiceApis() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
// 项目
|
// 项目
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/info", []string{"context", "query:service"}, []string{"service"}, p.serviceController.Get),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/info", []string{"context", "query:service"}, []string{"service"}, p.serviceController.Get, access.SystemWorkspaceServiceViewAll, access.TeamTeamServiceView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/info", []string{"context", "query:service", "body"}, []string{"service"}, p.serviceController.Edit),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/info", []string{"context", "query:service", "body"}, []string{"service"}, p.serviceController.Edit, access.SystemWorkspaceServiceManagerAll, access.TeamTeamServiceManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/info", []string{"context", "query:service"}, nil, p.serviceController.Delete),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/info", []string{"context", "query:service"}, nil, p.serviceController.Delete, access.SystemWorkspaceServiceManagerAll, access.TeamTeamServiceManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/my_services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.SearchMyServices),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/my_services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.SearchMyServices),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.Search),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.Search, access.SystemWorkspaceServiceViewAll, access.TeamTeamServiceView),
|
||||||
|
|
||||||
//pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/services/mine", []string{"context", "query:keyword"}, []string{"services"}, p.serviceController.MySimple),
|
|
||||||
//
|
|
||||||
//pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/services", []string{"context", "query:keyword"}, []string{"services"}, p.serviceController.Simple),
|
|
||||||
|
|
||||||
// AI服务
|
|
||||||
//pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai-services", []string{"context", "query:service", "query:keyword"}, []string{"services"}, p.serviceController.SearchAIServices),
|
|
||||||
//pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/team/ai-service", []string{"context", "query:team", "body"}, []string{"service"}, p.serviceController.CreateAIService),
|
|
||||||
//pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/ai-service/info", []string{"context", "query:service", "body"}, []string{"service"}, p.serviceController.EditAIService),
|
|
||||||
//pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/team/ai-service", []string{"context", "query:service"}, nil, p.serviceController.DeleteAIService),
|
|
||||||
//pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/my_ai_services", []string{"context", "query:team", "query:keyword"}, []string{"services"}, p.serviceController.SearchMyAIServices),
|
|
||||||
//pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/ai-service/info", []string{"context", "query:service"}, []string{"service"}, p.serviceController.Get),
|
|
||||||
|
|
||||||
// 应用相关
|
// 应用相关
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/app/info", []string{"context", "query:app"}, []string{"app"}, p.appController.GetApp),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/app/info", []string{"context", "query:app"}, []string{"app"}, p.appController.GetApp, access.SystemWorkspaceApplicationViewAll, access.TeamTeamConsumerView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/app", []string{"context", "query:app"}, nil, p.appController.DeleteApp),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/app", []string{"context", "query:app"}, nil, p.appController.DeleteApp, access.SystemWorkspaceApplicationManagerAll, access.TeamTeamConsumerManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/apps", []string{"context", "query:keyword"}, []string{"apps"}, p.appController.SimpleApps),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/apps", []string{"context", "query:keyword"}, []string{"apps"}, p.appController.SimpleApps),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/apps/mine", []string{"context", "query:keyword"}, []string{"apps"}, p.appController.MySimpleApps),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/simple/apps/mine", []string{"context", "query:keyword"}, []string{"apps"}, p.appController.MySimpleApps),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/my_apps", []string{"context", "query:team", "query:keyword"}, []string{"apps"}, p.appController.SearchMyApps),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/my_apps", []string{"context", "query:team", "query:keyword"}, []string{"apps"}, p.appController.SearchMyApps),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/apps", []string{"context", "query:team", "query:keyword"}, []string{"apps"}, p.appController.Search),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/apps", []string{"context", "query:team", "query:keyword"}, []string{"apps"}, p.appController.Search, access.SystemWorkspaceApplicationViewAll),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/app/info", []string{"context", "query:app", "body"}, []string{"app"}, p.appController.UpdateApp),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/apps/can_subscribe", []string{"context", "query:service"}, []string{"app"}, p.appController.SearchCanSubscribe),
|
||||||
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/app/info", []string{"context", "query:app", "body"}, []string{"app"}, p.appController.UpdateApp, access.SystemWorkspaceApplicationManagerAll, access.TeamTeamConsumerManager),
|
||||||
|
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/doc", []string{"context", "query:service"}, []string{"doc"}, p.serviceController.ServiceDoc),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/doc", []string{"context", "query:service"}, []string{"doc"}, p.serviceController.ServiceDoc, access.SystemWorkspaceServiceViewAll, access.TeamServiceServiceIntroView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/doc", []string{"context", "query:service", "body"}, nil, p.serviceController.SaveServiceDoc),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/doc", []string{"context", "query:service", "body"}, nil, p.serviceController.SaveServiceDoc, access.SystemWorkspaceServiceManagerAll, access.TeamServiceServiceIntroManager),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,18 +3,19 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) catalogueApi() []pm3.Api {
|
func (p *plugin) catalogueApi() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/catalogues", []string{"context", "query:keyword"}, []string{"catalogues", "tags"}, p.catalogueController.Search),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/catalogues", []string{"context", "query:keyword"}, []string{"catalogues", "tags"}, p.catalogueController.Search, access.SystemSettingsGeneralView, access.SystemApiPortalApiPortalView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/catalogue", []string{"context", "body"}, nil, p.catalogueController.Create),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/catalogue", []string{"context", "body"}, nil, p.catalogueController.Create, access.SystemSettingsGeneralManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/catalogue", []string{"context", "query:catalogue", "body"}, nil, p.catalogueController.Edit),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/catalogue", []string{"context", "query:catalogue", "body"}, nil, p.catalogueController.Edit, access.SystemSettingsGeneralManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/catalogue", []string{"context", "query:catalogue"}, nil, p.catalogueController.Delete),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/catalogue", []string{"context", "query:catalogue"}, nil, p.catalogueController.Delete, access.SystemSettingsGeneralManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/catalogue/sort", []string{"context", "body"}, nil, p.catalogueController.Sort),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/catalogue/sort", []string{"context", "body"}, nil, p.catalogueController.Sort, access.SystemSettingsGeneralManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/catalogue/services", []string{"context", "query:keyword"}, []string{"services"}, p.catalogueController.Services),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/catalogue/services", []string{"context", "query:keyword"}, []string{"services"}, p.catalogueController.Services, access.SystemApiPortalApiPortalView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/catalogue/service", []string{"context", "query:service"}, []string{"service"}, p.catalogueController.ServiceDetail),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/catalogue/service", []string{"context", "query:service"}, []string{"service"}, p.catalogueController.ServiceDetail, access.SystemApiPortalApiPortalView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/catalogue/service/subscribe", []string{"context", "body"}, nil, p.catalogueController.Subscribe),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/catalogue/service/subscribe", []string{"context", "body"}, nil, p.catalogueController.Subscribe),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,23 +3,25 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
|
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) subscribeApis() []pm3.Api {
|
func (p *plugin) subscribeApis() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/subscribers", []string{"context", "query:service", "query:keyword"}, []string{"subscribers"}, p.subscribeController.Search),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/subscribers", []string{"context", "query:service", "query:keyword"}, []string{"subscribers"}, p.subscribeController.Search, access.SystemWorkspaceServiceViewAll, access.TeamServiceSubscriptionView),
|
||||||
|
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/subscriber", []string{"context", "query:service", "body"}, nil, p.subscribeController.AddSubscriber),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/subscriber", []string{"context", "query:service", "body"}, nil, p.subscribeController.AddSubscriber, access.SystemWorkspaceServiceManagerAll, access.TeamServiceSubscriptionManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/subscriber", []string{"context", "query:service", "query:service", "query:application"}, nil, p.subscribeController.DeleteSubscriber),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/service/subscriber", []string{"context", "query:service", "query:service", "query:application"}, nil, p.subscribeController.DeleteSubscriber, access.SystemWorkspaceServiceManagerAll, access.TeamServiceSubscriptionManager),
|
||||||
|
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/application/subscriptions", []string{"context", "query:application", "query:keyword"}, []string{"subscriptions"}, p.subscribeController.SearchSubscriptions),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/application/subscriptions", []string{"context", "query:application", "query:keyword"}, []string{"subscriptions"}, p.subscribeController.SearchSubscriptions, access.SystemWorkspaceApplicationViewAll, access.TeamConsumerSubscriptionViewSubscribed),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/application/subscription/cancel", []string{"context", "query:application", "query:subscription"}, nil, p.subscribeController.RevokeSubscription),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/application/subscription/cancel", []string{"context", "query:application", "query:subscription"}, nil, p.subscribeController.RevokeSubscription, access.SystemWorkspaceApplicationManagerAll, access.TeamConsumerSubscriptionSubscribe, access.TeamConsumerSubscriptionManagerSubscribed),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/application/subscription/cancel_apply", []string{"context", "query:application", "query:subscription"}, nil, p.subscribeController.RevokeApply),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/application/subscription/cancel_apply", []string{"context", "query:application", "query:subscription"}, nil, p.subscribeController.RevokeApply, access.SystemWorkspaceApplicationManagerAll, access.TeamConsumerSubscriptionSubscribe, access.TeamConsumerSubscriptionManagerSubscribed),
|
||||||
|
|
||||||
// 审核相关
|
// 审核相关
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/approval/subscribes", []string{"context", "query:service", "query:status"}, []string{"approvals"}, p.subscribeApprovalController.GetApprovalList),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/approval/subscribes", []string{"context", "query:service", "query:status"}, []string{"approvals"}, p.subscribeApprovalController.GetApprovalList, access.SystemWorkspaceServiceViewAll, access.TeamServiceSubscriptionView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/approval/subscribe", []string{"context", "query:service", "query:apply"}, []string{"approval"}, p.subscribeApprovalController.GetApprovalDetail),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/approval/subscribe", []string{"context", "query:service", "query:apply"}, []string{"approval"}, p.subscribeApprovalController.GetApprovalDetail, access.SystemWorkspaceServiceViewAll, access.TeamServiceSubscriptionView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/approval/subscribe", []string{"context", "query:service", "query:apply", "body"}, nil, p.subscribeApprovalController.Approval),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/service/approval/subscribe", []string{"context", "query:service", "query:apply", "body"}, nil, p.subscribeApprovalController.Approval),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/eolinker/go-common/pm3"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
|
|
||||||
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) TeamManagerApi() []pm3.Api {
|
func (p *plugin) TeamManagerApi() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/manager/team", []string{"context", "query:id"}, []string{"team"}, p.teamManagerController.GetTeam),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/manager/team", []string{"context", "query:id"}, []string{"team"}, p.teamManagerController.GetTeam, access.SystemWorkspaceTeamViewAll, access.TeamTeamTeamView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/manager/teams", []string{"context", "query:keyword"}, []string{"teams"}, p.teamManagerController.Search),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/manager/teams", []string{"context", "query:keyword"}, []string{"teams"}, p.teamManagerController.Search, access.SystemWorkspaceTeamViewAll, access.TeamTeamTeamView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/manager/team", []string{"context", "body"}, []string{"team"}, p.teamManagerController.CreateTeam),
|
pm3.CreateApiWidthDoc(http.MethodPost, "/api/v1/manager/team", []string{"context", "body"}, []string{"team"}, p.teamManagerController.CreateTeam, access.SystemWorkspaceTeamCreate, access.TeamTeamTeamManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/manager/team", []string{"context", "query:id", "body"}, []string{"team"}, p.teamManagerController.EditTeam),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/manager/team", []string{"context", "query:id", "body"}, []string{"team"}, p.teamManagerController.EditTeam, access.SystemWorkspaceTeamManager, access.TeamTeamTeamManager),
|
||||||
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/manager/team", []string{"context", "query:id"}, []string{"id"}, p.teamManagerController.DeleteTeam),
|
pm3.CreateApiWidthDoc(http.MethodDelete, "/api/v1/manager/team", []string{"context", "query:id"}, []string{"id"}, p.teamManagerController.DeleteTeam, access.SystemWorkspaceTeamManager, access.TeamTeamTeamManager),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@ package core
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/APIParkLab/APIPark/resources/access"
|
||||||
"github.com/eolinker/go-common/pm3"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *plugin) upstreamApis() []pm3.Api {
|
func (p *plugin) upstreamApis() []pm3.Api {
|
||||||
return []pm3.Api{
|
return []pm3.Api{
|
||||||
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/upstream", []string{"context", "query:service"}, []string{"upstream"}, p.upstreamController.Get),
|
pm3.CreateApiWidthDoc(http.MethodGet, "/api/v1/service/upstream", []string{"context", "query:service"}, []string{"upstream"}, p.upstreamController.Get, access.SystemWorkspaceServiceViewAll, access.TeamServiceUpstreamView),
|
||||||
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/upstream", []string{"context", "query:service", "body"}, []string{"upstream"}, p.upstreamController.Save),
|
pm3.CreateApiWidthDoc(http.MethodPut, "/api/v1/service/upstream", []string{"context", "query:service", "body"}, []string{"upstream"}, p.upstreamController.Save, access.SystemWorkspaceServiceManagerAll, access.TeamServiceUpstreamManager),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -198,7 +198,7 @@ curl -sSO https://download.apipark.com/install/quick-start.sh; bash quick-start.
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
# 📕ドキュメント
|
# 📕ドキュメント
|
||||||
詳細なインストールガイド、APIリファレンス、使用説明書については、[APIParkドキュメント](https://docs.apipark.com/docs/install) をご覧ください。
|
詳細なインストールガイド、APIリファレンス、使用説明書については、[APIParkドキュメント](https://docs.apipark.com/docs/deploy) をご覧ください。
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ curl -sSO https://download.apipark.com/install/quick-start.sh; bash quick-start.
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
# 📕文档
|
# 📕文档
|
||||||
访问 [APIPark文档](https://docs.apipark.com/docs/install) 获取详细的安装指南、API 参考和使用说明。
|
访问 [APIPark文档](https://docs.apipark.com/docs/deploy) 获取详细的安装指南、API 参考和使用说明。
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ curl -sSO https://download.apipark.com/install/quick-start.sh; bash quick-start.
|
|||||||
<br>
|
<br>
|
||||||
|
|
||||||
# 📕指南
|
# 📕指南
|
||||||
訪問 [APIPark指南](https://docs.apipark.com/docs/install) 以獲取詳細的安裝指南、API 參考與使用說明。
|
訪問 [APIPark指南](https://docs.apipark.com/docs/deploy) 以獲取詳細的安裝指南、API 參考與使用說明。
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
|
|||||||
+59
-19
@@ -3,8 +3,9 @@ package access
|
|||||||
import (
|
import (
|
||||||
_ "embed"
|
_ "embed"
|
||||||
|
|
||||||
|
yaml "gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/eolinker/go-common/access"
|
"github.com/eolinker/go-common/access"
|
||||||
"gopkg.in/yaml.v3"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Access = access.Access
|
type Access = access.Access
|
||||||
@@ -24,22 +25,61 @@ func init() {
|
|||||||
access.Add(group, asl)
|
access.Add(group, asl)
|
||||||
|
|
||||||
}
|
}
|
||||||
//defaultRoles := access.Roles()
|
|
||||||
//for group, rs := range defaultRoles {
|
|
||||||
// p, has := access.GetPermit(group)
|
|
||||||
// if !has {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for _, r := range rs {
|
|
||||||
// for _, pm := range r.Permits {
|
|
||||||
// apis, err := p.GetPermits(pm)
|
|
||||||
// if err != nil {
|
|
||||||
// continue
|
|
||||||
// }
|
|
||||||
// permit.AddPermitRule(pm, apis...)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
SystemAnalysisRunViewView = "system.analysis.run_view.view"
|
||||||
|
SystemApiPortalApiPortalView = "system.api_portal.api_portal.view"
|
||||||
|
SystemSettingsAccountManager = "system.settings.account.manager"
|
||||||
|
SystemSettingsAccountView = "system.settings.account.view"
|
||||||
|
SystemSettingsAiProviderManager = "system.settings.ai_provider.manager"
|
||||||
|
SystemSettingsAiProviderView = "system.settings.ai_provider.view"
|
||||||
|
SystemSettingsApiGatewayManager = "system.settings.api_gateway.manager"
|
||||||
|
SystemSettingsApiGatewayView = "system.settings.api_gateway.view"
|
||||||
|
SystemSettingsDataSourceManager = "system.settings.data_source.manager"
|
||||||
|
SystemSettingsDataSourceView = "system.settings.data_source.view"
|
||||||
|
SystemSettingsGeneralManager = "system.settings.general.manager"
|
||||||
|
SystemSettingsGeneralView = "system.settings.general.view"
|
||||||
|
SystemSettingsLogConfigurationManager = "system.settings.log_configuration.manager"
|
||||||
|
SystemSettingsLogConfigurationView = "system.settings.log_configuration.view"
|
||||||
|
SystemSettingsRoleView = "system.settings.role.view"
|
||||||
|
SystemSettingsSslCertificateManager = "system.settings.ssl_certificate.manager"
|
||||||
|
SystemSettingsSslCertificateView = "system.settings.ssl_certificate.view"
|
||||||
|
SystemWorkspaceApplicationManagerAll = "system.workspace.application.manager_all"
|
||||||
|
SystemWorkspaceApplicationViewAll = "system.workspace.application.view_all"
|
||||||
|
SystemWorkspaceServiceManagerAll = "system.workspace.service.manager_all"
|
||||||
|
SystemWorkspaceServiceViewAll = "system.workspace.service.view_all"
|
||||||
|
SystemWorkspaceTeamCreate = "system.workspace.team.create"
|
||||||
|
SystemWorkspaceTeamManager = "system.workspace.team.manager"
|
||||||
|
SystemWorkspaceTeamViewAll = "system.workspace.team.view_all"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
TeamConsumerApplicationManager = "team.consumer.application.manager"
|
||||||
|
TeamConsumerAuthorizationManager = "team.consumer.authorization.manager"
|
||||||
|
TeamConsumerAuthorizationView = "team.consumer.authorization.view"
|
||||||
|
TeamConsumerSubscriptionManagerSubscribed = "team.consumer.subscription.manager_subscribed_services"
|
||||||
|
TeamConsumerSubscriptionSubscribe = "team.consumer.subscription.subscribe"
|
||||||
|
TeamConsumerSubscriptionViewSubscribed = "team.consumer.subscription.view_subscribed_service"
|
||||||
|
TeamServiceApiManager = "team.service.api.manager"
|
||||||
|
TeamServiceApiView = "team.service.api.view"
|
||||||
|
TeamServiceApiDocManager = "team.service.api_doc.manager"
|
||||||
|
TeamServiceApiDocView = "team.service.api_doc.view"
|
||||||
|
TeamServiceReleaseManager = "team.service.release.manager"
|
||||||
|
TeamServiceReleaseView = "team.service.release.view"
|
||||||
|
TeamServiceServiceManager = "team.service.service.manager"
|
||||||
|
TeamServiceServiceIntroManager = "team.service.service_intro.manager"
|
||||||
|
TeamServiceServiceIntroView = "team.service.service_intro.view"
|
||||||
|
TeamServiceSubscriptionManager = "team.service.subscription.manager"
|
||||||
|
TeamServiceSubscriptionView = "team.service.subscription.view"
|
||||||
|
TeamServiceUpstreamManager = "team.service.upstream.manager"
|
||||||
|
TeamServiceUpstreamView = "team.service.upstream.view"
|
||||||
|
TeamTeamConsumerManager = "team.team.consumer.manager"
|
||||||
|
TeamTeamConsumerView = "team.team.consumer.view"
|
||||||
|
TeamTeamMemberManager = "team.team.member.manager"
|
||||||
|
TeamTeamMemberView = "team.team.member.view"
|
||||||
|
TeamTeamServiceManager = "team.team.service.manager"
|
||||||
|
TeamTeamServiceView = "team.team.service.view"
|
||||||
|
TeamTeamTeamManager = "team.team.team.manager"
|
||||||
|
TeamTeamTeamView = "team.team.team.view"
|
||||||
|
)
|
||||||
|
|||||||
+11
-132
@@ -71,19 +71,6 @@ system:
|
|||||||
guest_allow: true
|
guest_allow: true
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "POST:/api/v1/user/account"
|
|
||||||
- "PUT:/api/v1/user/account"
|
|
||||||
- "DELETE:/api/v1/user/account"
|
|
||||||
- "POST:/api/v1/user/account/enable"
|
|
||||||
- "POST:/api/v1/user/account/disable"
|
|
||||||
- "POST:/api/v1/user/department"
|
|
||||||
- "PUT:/api/v1/user/department"
|
|
||||||
- "DELETE:/api/v1/user/department"
|
|
||||||
- "POST:/api/v1/user/department/member"
|
|
||||||
- "DELETE:/api/v1/user/department/member"
|
|
||||||
- "POST:/api/v1/user/department/member/remove"
|
|
||||||
- "POST:/api/v1/account/role"
|
|
||||||
dependents:
|
dependents:
|
||||||
- system.settings.account.view
|
- system.settings.account.view
|
||||||
- name: role
|
- name: role
|
||||||
@@ -92,11 +79,6 @@ system:
|
|||||||
- name: view
|
- name: view
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
value: 'view'
|
value: 'view'
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/system/roles"
|
|
||||||
- "GET:/api/v1/system/role"
|
|
||||||
- "GET:/api/v1/team/roles"
|
|
||||||
- "GET:/api/v1/team/role"
|
|
||||||
- name: api gateway
|
- name: api gateway
|
||||||
value: 'api_gateway'
|
value: 'api_gateway'
|
||||||
children:
|
children:
|
||||||
@@ -104,27 +86,18 @@ system:
|
|||||||
cname: 查看
|
cname: 查看
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/cluster/nodes"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
dependents:
|
||||||
- "PUT:/api/v1/cluster/reset"
|
- system.settings.api_gateway.view
|
||||||
- "POST:/api/v1/cluster/check"
|
|
||||||
- name: ai provider
|
- name: ai provider
|
||||||
value: 'ai_provider'
|
value: 'ai_provider'
|
||||||
children:
|
children:
|
||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/ai/providers"
|
|
||||||
- "GET:/api/v1/ai/provider/config"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "PUT:/api/v1/ai/provider/config"
|
|
||||||
- "PUT:/api/v1/ai/provider/default-llm"
|
|
||||||
dependents:
|
dependents:
|
||||||
- system.settings.ai_provider.view
|
- system.settings.ai_provider.view
|
||||||
- name: ssl certificate
|
- name: ssl certificate
|
||||||
@@ -134,30 +107,18 @@ system:
|
|||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/certificates"
|
|
||||||
- "GET:/api/v1/certificate"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "POST:/api/v1/certificate"
|
|
||||||
- "PUT:/api/v1/certificate"
|
|
||||||
- "DELETE:/api/v1/certificate"
|
|
||||||
dependents:
|
dependents:
|
||||||
- system.settings.ssl_certificate.view
|
- system.settings.ssl_certificate.view
|
||||||
- name: Data Source
|
- name: data source
|
||||||
value: 'data_source'
|
value: 'data_source'
|
||||||
children:
|
children:
|
||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/monitor/config"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "POST:/api/v1/monitor/config"
|
|
||||||
- "PUT:/api/v1/monitor/config"
|
|
||||||
dependents:
|
dependents:
|
||||||
- system.settings.data_source.view
|
- system.settings.data_source.view
|
||||||
- name: log configuration
|
- name: log configuration
|
||||||
@@ -166,18 +127,8 @@ system:
|
|||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/dynamic/{name}/info"
|
|
||||||
- "GET:/api/v1/dynamic/{name}/list"
|
|
||||||
- "GET:/api/v1/dynamic/{name}/render"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "POST:/api/v1/dynamic/{name}"
|
|
||||||
- "PUT:/api/v1/dynamic/{name}/config"
|
|
||||||
- "DELETE:/api/v1/dynamic/{name}/batch"
|
|
||||||
- "PUT:/api/v1/dynamic/{name}/online"
|
|
||||||
- "PUT:/api/v1/dynamic/{name}/offline"
|
|
||||||
dependents:
|
dependents:
|
||||||
- system.settings.log_configuration.view
|
- system.settings.log_configuration.view
|
||||||
team:
|
team:
|
||||||
@@ -190,17 +141,8 @@ team:
|
|||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/service/routers"
|
|
||||||
- "GET:/api/v1/service/router/detail"
|
|
||||||
- "GET:/api/v1/service/router/detail/simple"
|
|
||||||
- "GET:/api/v1/service/router/define"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "POST:/api/v1/service/router"
|
|
||||||
- "PUT:/api/v1/service/router"
|
|
||||||
- "DELETE:/api/v1/service/router"
|
|
||||||
dependents:
|
dependents:
|
||||||
- team.service.api.view
|
- team.service.api.view
|
||||||
- name: api doc
|
- name: api doc
|
||||||
@@ -210,13 +152,8 @@ team:
|
|||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/service/api_doc"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "PUT:/api/v1/service/api_doc"
|
|
||||||
- "POST:/api/v1/service/api_doc/upload"
|
|
||||||
dependents:
|
dependents:
|
||||||
- team.service.api_doc.view
|
- team.service.api_doc.view
|
||||||
- name: service intro
|
- name: service intro
|
||||||
@@ -236,12 +173,8 @@ team:
|
|||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/service/upstream"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "PUT:/api/v1/service/upstream"
|
|
||||||
dependents:
|
dependents:
|
||||||
- team.service.upstream.view
|
- team.service.upstream.view
|
||||||
- name: release
|
- name: release
|
||||||
@@ -250,94 +183,46 @@ team:
|
|||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/service/releases"
|
|
||||||
- "GET:/api/v1/service/release"
|
|
||||||
- "GET:/api/v1/service/publishs"
|
|
||||||
- "GET:/api/v1/service/publish/check"
|
|
||||||
- "GET:/api/v1/service/release/preview"
|
|
||||||
- "GET:/api/v1/service/publish/status"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "POST:/api/v1/service/publish/release/do"
|
|
||||||
- "DELETE:/api/v1/service/release"
|
|
||||||
dependents:
|
dependents:
|
||||||
- team.service.release.view
|
- team.service.release.view
|
||||||
- name: subscription management
|
- name: subscription review
|
||||||
value: 'subscription'
|
value: 'subscription'
|
||||||
children:
|
children:
|
||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/service/approval/subscribes"
|
|
||||||
- "GET:/api/v1/service/approval/subscribe"
|
|
||||||
- "GET:/api/v1/service/subscribers"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
|
||||||
- "POST:/api/v1/service/approval/subscribe"
|
|
||||||
- "POST:/api/v1/service/subscriber"
|
|
||||||
- "DELETE:/api/v1/service/subscriber"
|
|
||||||
dependents:
|
dependents:
|
||||||
- team.service.subscription.view
|
- team.service.subscription.view
|
||||||
- name: service
|
|
||||||
value: 'service'
|
|
||||||
children:
|
|
||||||
- name: manager
|
|
||||||
value: 'manager'
|
|
||||||
apis:
|
|
||||||
- "PUT:/api/v1/service/info"
|
|
||||||
- "POST:/api/v1/team/service"
|
|
||||||
- "DELETE:/api/v1/team/service"
|
|
||||||
dependents:
|
|
||||||
- team.service.service.manager
|
|
||||||
- name: consumer
|
- name: consumer
|
||||||
value: 'consumer'
|
value: 'consumer'
|
||||||
children:
|
children:
|
||||||
- name: subscription Service
|
- name: subscription service
|
||||||
cname: 订阅服务
|
cname: 订阅服务
|
||||||
value: 'subscription'
|
value: 'subscription'
|
||||||
children:
|
children:
|
||||||
- name: subscribe
|
- name: allow subscribe service
|
||||||
value: 'subscribe'
|
value: 'subscribe'
|
||||||
|
|
||||||
- name: view subscribed services
|
- name: view subscribed services
|
||||||
value: 'view_subscribed_service'
|
value: 'view_subscribed_service'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/application/subscription"
|
|
||||||
- name: manager subscribed services
|
- name: manager subscribed services
|
||||||
value: 'manager_subscribed_services'
|
value: 'manager_subscribed_services'
|
||||||
apis:
|
dependents:
|
||||||
- "POST:/api/v1/catalogue/service/subscribe"
|
- team.consumer.subscription.manager_subscribed_services
|
||||||
- "POST:/api/v1/application/subscription/cancel"
|
|
||||||
- "POST:/api/v1/application/subscription/cancel_apply"
|
|
||||||
- name: authorization
|
- name: authorization
|
||||||
value: 'authorization'
|
value: 'authorization'
|
||||||
children:
|
children:
|
||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/app/authorization"
|
|
||||||
- "GET:/api/v1/app/authorizations"
|
|
||||||
- "GET:/api/v1/app/authorization/details"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
dependents:
|
||||||
- "POST:/api/v1/app/authorization"
|
- team.consumer.authorization.view
|
||||||
- "PUT:/api/v1/app/authorization"
|
|
||||||
- "DELETE:/api/v1/app/authorization"
|
|
||||||
- name: consumer
|
|
||||||
value: 'application'
|
|
||||||
children:
|
|
||||||
- name: manager
|
|
||||||
value: 'manager'
|
|
||||||
apis:
|
|
||||||
- "PUT:/api/v1/app/info"
|
|
||||||
- "POST:/api/v1/team/app"
|
|
||||||
- name: team
|
- name: team
|
||||||
value: 'team'
|
value: 'team'
|
||||||
children:
|
children:
|
||||||
@@ -371,20 +256,14 @@ team:
|
|||||||
value: 'manager'
|
value: 'manager'
|
||||||
dependents:
|
dependents:
|
||||||
- team.team.member.view
|
- team.team.member.view
|
||||||
- name: team
|
- name: team settings
|
||||||
value: 'team'
|
value: 'team'
|
||||||
children:
|
children:
|
||||||
- name: view
|
- name: view
|
||||||
value: 'view'
|
value: 'view'
|
||||||
guest_allow: true
|
guest_allow: true
|
||||||
apis:
|
|
||||||
- "GET:/api/v1/manager/teams"
|
|
||||||
- "GET:/api/v1/manager/team"
|
|
||||||
- name: manager
|
- name: manager
|
||||||
value: 'manager'
|
value: 'manager'
|
||||||
apis:
|
apis:
|
||||||
- "POST:/api/v1/manager/team"
|
|
||||||
- "PUT:/api/v1/manager/team"
|
|
||||||
- "DELETE:/api/v1/manager/team"
|
|
||||||
dependents:
|
dependents:
|
||||||
- team.team.team.view
|
- team.team.team.view
|
||||||
@@ -62,7 +62,6 @@ team:
|
|||||||
- name: team admin
|
- name: team admin
|
||||||
value: team_admin
|
value: team_admin
|
||||||
permits:
|
permits:
|
||||||
- team.consumer.application.manager
|
|
||||||
- team.consumer.authorization.manager
|
- team.consumer.authorization.manager
|
||||||
- team.consumer.authorization.view
|
- team.consumer.authorization.view
|
||||||
- team.consumer.subscription.manager_subscribed_services
|
- team.consumer.subscription.manager_subscribed_services
|
||||||
@@ -74,7 +73,6 @@ team:
|
|||||||
- team.service.api_doc.view
|
- team.service.api_doc.view
|
||||||
- team.service.release.manager
|
- team.service.release.manager
|
||||||
- team.service.release.view
|
- team.service.release.view
|
||||||
- team.service.service.manager
|
|
||||||
- team.service.service_intro.manager
|
- team.service.service_intro.manager
|
||||||
- team.service.service_intro.view
|
- team.service.service_intro.view
|
||||||
- team.service.subscription.manager
|
- team.service.subscription.manager
|
||||||
@@ -99,7 +97,6 @@ team:
|
|||||||
- team.service.api_doc.view
|
- team.service.api_doc.view
|
||||||
- team.service.release.manager
|
- team.service.release.manager
|
||||||
- team.service.release.view
|
- team.service.release.view
|
||||||
- team.service.service.manager
|
|
||||||
- team.service.service_intro.manager
|
- team.service.service_intro.manager
|
||||||
- team.service.service_intro.view
|
- team.service.service_intro.view
|
||||||
- team.service.subscription.manager
|
- team.service.subscription.manager
|
||||||
@@ -134,7 +131,6 @@ team:
|
|||||||
- name: consumer admin
|
- name: consumer admin
|
||||||
value: consumer_admin
|
value: consumer_admin
|
||||||
permits:
|
permits:
|
||||||
- team.consumer.application.manager
|
|
||||||
- team.consumer.authorization.manager
|
- team.consumer.authorization.manager
|
||||||
- team.consumer.authorization.view
|
- team.consumer.authorization.view
|
||||||
- team.consumer.subscription.manager_subscribed_services
|
- team.consumer.subscription.manager_subscribed_services
|
||||||
|
|||||||
@@ -1,44 +1,46 @@
|
|||||||
{
|
{
|
||||||
|
"account": "Account",
|
||||||
"ai provider": "AI Provider",
|
"ai provider": "AI Provider",
|
||||||
"api market": "API Portal",
|
"analysis": "Analysis Report",
|
||||||
|
"api": "API",
|
||||||
"api doc": "API Documentation",
|
"api doc": "API Documentation",
|
||||||
"application": "Application",
|
"api gateway": "API Gateway",
|
||||||
"application admin": "Application Administrator",
|
"api portal": "API Portal",
|
||||||
"application developer": "Application Developer",
|
"authorization": "Access Authorization",
|
||||||
"authorization": "Authorization",
|
"consumer": "Consumer",
|
||||||
"cluster": "Cluster",
|
"consumer admin": "Consumer Admin",
|
||||||
"dashboard": "Dashboard",
|
"consumer developer": "Consumer Developer",
|
||||||
|
"create": "Create",
|
||||||
"data source": "Data Source",
|
"data source": "Data Source",
|
||||||
"devops": "DevOps",
|
"devops admin": "DevOps Admin",
|
||||||
"devops admin": "DevOps Administrator",
|
|
||||||
"general": "General Settings",
|
"general": "General Settings",
|
||||||
"general member": "General Member",
|
"general member": "General Member",
|
||||||
"guest": "Guest",
|
|
||||||
"log configuration": "Log Configuration",
|
"log configuration": "Log Configuration",
|
||||||
"manager": "Manager",
|
"manager": "Manager",
|
||||||
|
"manager all consumer": "Manage All Consumers",
|
||||||
|
"manager subscribed services": "Manage Subscribed Services",
|
||||||
"member": "Member",
|
"member": "Member",
|
||||||
"organization": "Organization Management",
|
|
||||||
"release": "Release",
|
"release": "Release",
|
||||||
"role": "Role",
|
"role": "Role",
|
||||||
"router": "Router",
|
|
||||||
"run view": "Run View",
|
"run view": "Run View",
|
||||||
"service": "Service",
|
"service": "Service",
|
||||||
"service admin": "Service Administrator",
|
"service admin": "Service Admin",
|
||||||
"service classification": "Service Directory",
|
|
||||||
"service developer": "Service Developer",
|
"service developer": "Service Developer",
|
||||||
|
"service intro": "Service Documentation",
|
||||||
"ssl certificate": "SSL Certificate",
|
"ssl certificate": "SSL Certificate",
|
||||||
"subscription management": "Subscription Management",
|
"allow subscribe service": "Allow Subscribe Service",
|
||||||
|
"subscription review": "Subscription Review",
|
||||||
"subscription service": "Subscription Service",
|
"subscription service": "Subscription Service",
|
||||||
"super admin": "Super Administrator",
|
"super admin": "Super Admin",
|
||||||
"system settings": "System Settings",
|
"system settings": "System Settings",
|
||||||
"team": "Team",
|
"team": "Team",
|
||||||
"team admin": "Team Administrator",
|
"team settings": "Team Settings",
|
||||||
|
"team admin": "Team Admin",
|
||||||
"upstream": "Upstream",
|
"upstream": "Upstream",
|
||||||
"view": "View",
|
"view": "View",
|
||||||
"view all application": "View All Applications",
|
"view all consumer": "View All Consumers",
|
||||||
"view all service": "View All Services",
|
"view all service": "View All Services",
|
||||||
"view all team": "View All Teams",
|
"view all team": "View All Teams",
|
||||||
"view system role": "View System Roles",
|
"view subscribed services": "View Subscribed Services",
|
||||||
"view team role": "View Team Roles",
|
|
||||||
"workspace": "Workspace"
|
"workspace": "Workspace"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,46 @@
|
|||||||
{
|
{
|
||||||
|
"account": "アカウント",
|
||||||
"ai provider": "AIプロバイダー",
|
"ai provider": "AIプロバイダー",
|
||||||
"api market": "APIマーケット",
|
"analysis": "分析レポート",
|
||||||
|
"api": "API",
|
||||||
"api doc": "APIドキュメント",
|
"api doc": "APIドキュメント",
|
||||||
"application": "アプリケーション",
|
"api gateway": "APIゲートウェイ",
|
||||||
"application admin": "アプリケーション管理者",
|
"api portal": "APIポータル",
|
||||||
"application developer": "アプリケーション開発者",
|
"authorization": "アクセス許可",
|
||||||
"authorization": "認証",
|
"consumer": "消費者",
|
||||||
"cluster": "クラスター",
|
"consumer admin": "消費者管理者",
|
||||||
"dashboard": "ダッシュボード",
|
"consumer developer": "消費者開発者",
|
||||||
|
"create": "作成",
|
||||||
"data source": "データソース",
|
"data source": "データソース",
|
||||||
"devops": "DevOps",
|
|
||||||
"devops admin": "DevOps管理者",
|
"devops admin": "DevOps管理者",
|
||||||
"general": "一般設定",
|
"general": "一般設定",
|
||||||
"general member": "一般メンバー",
|
"general member": "一般メンバー",
|
||||||
"guest": "ゲスト",
|
|
||||||
"log configuration": "ログ設定",
|
"log configuration": "ログ設定",
|
||||||
"manager": "管理者",
|
"manager": "管理者",
|
||||||
|
"manager all consumer": "すべての消費者を管理",
|
||||||
|
"manager subscribed services": "購読したサービスを管理",
|
||||||
"member": "メンバー",
|
"member": "メンバー",
|
||||||
"organization": "組織管理",
|
|
||||||
"release": "リリース",
|
"release": "リリース",
|
||||||
"role": "役割",
|
"role": "役割",
|
||||||
"router": "ルーター",
|
|
||||||
"run view": "実行ビュー",
|
"run view": "実行ビュー",
|
||||||
"service": "サービス",
|
"service": "サービス",
|
||||||
"service admin": "サービス管理者",
|
"service admin": "サービス管理者",
|
||||||
"service classification": "サービスディレクトリ",
|
|
||||||
"service developer": "サービス開発者",
|
"service developer": "サービス開発者",
|
||||||
|
"service intro": "サービスドキュメント",
|
||||||
"ssl certificate": "SSL証明書",
|
"ssl certificate": "SSL証明書",
|
||||||
"subscription management": "サブスクリプション管理",
|
"allow subscribe service": "サービスの購読を許可",
|
||||||
"subscription service": "サブスクリプションサービス",
|
"subscription review": "購読レビュー",
|
||||||
|
"subscription service": "購読サービス",
|
||||||
"super admin": "スーパ管理者",
|
"super admin": "スーパ管理者",
|
||||||
"system settings": "システム設定",
|
"system settings": "システム設定",
|
||||||
"team": "チーム",
|
"team": "チーム",
|
||||||
|
"team settings": "チーム設定",
|
||||||
"team admin": "チーム管理者",
|
"team admin": "チーム管理者",
|
||||||
"upstream": "アップストリーム",
|
"upstream": "アップストリーム",
|
||||||
"view": "表示",
|
"view": "表示",
|
||||||
"view all application": "すべてのアプリケーションを表示",
|
"view all consumer": "すべての消費者を表示",
|
||||||
"view all service": "すべてのサービスを表示",
|
"view all service": "すべてのサービスを表示",
|
||||||
"view all team": "すべてのチームを表示",
|
"view all team": "すべてのチームを表示",
|
||||||
"view system role": "システム役割を表示",
|
"view subscribed services": "購読したサービスを表示",
|
||||||
"view team role": "チーム役割を表示",
|
|
||||||
"workspace": "ワークスペース"
|
"workspace": "ワークスペース"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,46 @@
|
|||||||
{
|
{
|
||||||
"ai provider": "AI供应商",
|
"account": "账号",
|
||||||
"api market": "API门户",
|
"ai provider": "AI模型供应商",
|
||||||
|
"analysis": "分析报告",
|
||||||
|
"api": "API",
|
||||||
"api doc": "API文档",
|
"api doc": "API文档",
|
||||||
"application": "应用",
|
"api gateway": "API网关",
|
||||||
"application admin": "应用管理员",
|
"api portal": "API门户",
|
||||||
"application developer": "应用开发者",
|
"authorization": "访问授权",
|
||||||
"authorization": "鉴权",
|
"consumer": "消费者",
|
||||||
"cluster": "集群",
|
"consumer admin": "消费者管理员",
|
||||||
"dashboard": "仪表盘",
|
"consumer developer": "消费者开发者",
|
||||||
|
"create": "创建",
|
||||||
"data source": "数据源",
|
"data source": "数据源",
|
||||||
"devops": "运维",
|
|
||||||
"devops admin": "运维管理员",
|
"devops admin": "运维管理员",
|
||||||
"general": "常规设置",
|
"general": "常规设置",
|
||||||
"general member": "普通成员",
|
"general member": "普通成员",
|
||||||
"guest": "访客",
|
|
||||||
"log configuration": "日志配置",
|
"log configuration": "日志配置",
|
||||||
"manager": "管理",
|
"manager": "管理",
|
||||||
|
"manager all consumer": "管理所有消费者",
|
||||||
|
"manager subscribed services": "管理已订阅的服务",
|
||||||
"member": "成员",
|
"member": "成员",
|
||||||
"organization": "组织管理",
|
|
||||||
"release": "发布",
|
"release": "发布",
|
||||||
"role": "角色",
|
"role": "角色",
|
||||||
"router": "路由",
|
|
||||||
"run view": "运行视图",
|
"run view": "运行视图",
|
||||||
"service": "服务",
|
"service": "服务",
|
||||||
"service admin": "服务管理员",
|
"service admin": "服务管理员",
|
||||||
"service classification": "服务目录",
|
|
||||||
"service developer": "服务开发者",
|
"service developer": "服务开发者",
|
||||||
|
"service intro": "服务文档",
|
||||||
"ssl certificate": "SSL证书",
|
"ssl certificate": "SSL证书",
|
||||||
"subscription management": "订阅方管理",
|
"allow subscribe service": "允许订阅服务",
|
||||||
|
"subscription review": "订阅审核",
|
||||||
"subscription service": "订阅服务",
|
"subscription service": "订阅服务",
|
||||||
"super admin": "超级管理员",
|
"super admin": "超级管理员",
|
||||||
"system settings": "系统设置",
|
"system settings": "系统设置",
|
||||||
"team": "团队",
|
"team": "团队",
|
||||||
|
"team settings": "团队设置",
|
||||||
"team admin": "团队管理员",
|
"team admin": "团队管理员",
|
||||||
"upstream": "上游",
|
"upstream": "上游",
|
||||||
"view": "查看",
|
"view": "查看",
|
||||||
"view all application": "查看所有应用",
|
"view all consumer": "查看所有消费者",
|
||||||
"view all service": "查看所有服务",
|
"view all service": "查看所有服务",
|
||||||
"view all team": "查看所有团队",
|
"view all team": "查看所有团队",
|
||||||
"view system role": "查看系统角色",
|
"view subscribed services": "查看已经订阅的服务",
|
||||||
"view team role": "查看团队角色",
|
|
||||||
"workspace": "工作空间"
|
"workspace": "工作空间"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +1,46 @@
|
|||||||
{
|
{
|
||||||
"ai provider": "AI供應商",
|
"account": "帳號",
|
||||||
"api market": "API市場",
|
"ai provider": "AI模型供應商",
|
||||||
|
"analysis": "分析報告",
|
||||||
|
"api": "API",
|
||||||
"api doc": "API文檔",
|
"api doc": "API文檔",
|
||||||
"application": "應用",
|
"api gateway": "API網關",
|
||||||
"application admin": "應用管理員",
|
"api portal": "API門戶",
|
||||||
"application developer": "應用開發者",
|
"authorization": "訪問授權",
|
||||||
"authorization": "授權",
|
"consumer": "消費者",
|
||||||
"cluster": "集群",
|
"consumer admin": "消費者管理員",
|
||||||
"dashboard": "儀表盤",
|
"consumer developer": "消費者開發者",
|
||||||
|
"create": "創建",
|
||||||
"data source": "數據源",
|
"data source": "數據源",
|
||||||
"devops": "運維",
|
|
||||||
"devops admin": "運維管理員",
|
"devops admin": "運維管理員",
|
||||||
"general": "常規設置",
|
"general": "常規設置",
|
||||||
"general member": "普通成員",
|
"general member": "普通成員",
|
||||||
"guest": "訪客",
|
|
||||||
"log configuration": "日誌配置",
|
"log configuration": "日誌配置",
|
||||||
"manager": "管理",
|
"manager": "管理",
|
||||||
|
"manager all consumer": "管理所有消費者",
|
||||||
|
"manager subscribed services": "管理已訂閱的服務",
|
||||||
"member": "成員",
|
"member": "成員",
|
||||||
"organization": "組織管理",
|
|
||||||
"release": "發布",
|
"release": "發布",
|
||||||
"role": "角色",
|
"role": "角色",
|
||||||
"router": "路由",
|
|
||||||
"run view": "運行視圖",
|
"run view": "運行視圖",
|
||||||
"service": "服務",
|
"service": "服務",
|
||||||
"service admin": "服務管理員",
|
"service admin": "服務管理員",
|
||||||
"service classification": "服務目錄",
|
|
||||||
"service developer": "服務開發者",
|
"service developer": "服務開發者",
|
||||||
|
"service intro": "服務文檔",
|
||||||
"ssl certificate": "SSL證書",
|
"ssl certificate": "SSL證書",
|
||||||
"subscription management": "訂閱方管理",
|
"allow subscribe service": "允許訂閱服務",
|
||||||
|
"subscription review": "訂閱審核",
|
||||||
"subscription service": "訂閱服務",
|
"subscription service": "訂閱服務",
|
||||||
"super admin": "超級管理員",
|
"super admin": "超級管理員",
|
||||||
"system settings": "系統設置",
|
"system settings": "系統設置",
|
||||||
"team": "團隊",
|
"team": "團隊",
|
||||||
|
"team settings": "團隊設置",
|
||||||
"team admin": "團隊管理員",
|
"team admin": "團隊管理員",
|
||||||
"upstream": "上游",
|
"upstream": "上游",
|
||||||
"view": "查看",
|
"view": "查看",
|
||||||
"view all application": "查看所有應用",
|
"view all consumer": "查看所有消費者",
|
||||||
"view all service": "查看所有服務",
|
"view all service": "查看所有服務",
|
||||||
"view all team": "查看所有團隊",
|
"view all team": "查看所有團隊",
|
||||||
"view system role": "查看系統角色",
|
"view subscribed services": "查看已訂閱的服務",
|
||||||
"view team role": "查看團隊角色",
|
|
||||||
"workspace": "工作空間"
|
"workspace": "工作空間"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,18 +5,15 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/eolinker/eosc"
|
"github.com/eolinker/go-common/pm3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
//go:embed i18n/*
|
//go:embed i18n/*
|
||||||
i18nDirs embed.FS
|
i18nDirs embed.FS
|
||||||
i18nData eosc.Untyped[string, map[string]string]
|
|
||||||
defaultI18n = "zh-CN"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
i18nData = eosc.BuildUntyped[string, map[string]string]()
|
|
||||||
files, err := i18nDirs.ReadDir("i18n")
|
files, err := i18nDirs.ReadDir("i18n")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -34,19 +31,6 @@ func init() {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
key := strings.TrimSuffix(f.Name(), ".json")
|
key := strings.TrimSuffix(f.Name(), ".json")
|
||||||
i18nData.Set(key, tmp)
|
pm3.I18nRegister(key, tmp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func Get(i18n string) map[string]string {
|
|
||||||
result, has := i18nData.Get(i18n)
|
|
||||||
if has {
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
result, has = i18nData.Get(defaultI18n)
|
|
||||||
if !has {
|
|
||||||
return make(map[string]string)
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
# 名称:apinto通用镜像
|
# 名称:apipark通用镜像
|
||||||
# 创建时间:2022-10-25
|
# 创建时间:2022-10-25
|
||||||
FROM centos:7.9.2009
|
FROM centos:7.9.2009
|
||||||
MAINTAINER liujian
|
MAINTAINER liujian
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
version: '3'
|
||||||
|
services:
|
||||||
|
apipark-mysql:
|
||||||
|
image: mysql:8.0.37
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
container_name: apipark-mysql
|
||||||
|
hostname: apipark-mysql
|
||||||
|
command:
|
||||||
|
- "--character-set-server=utf8mb4"
|
||||||
|
- "--collation-server=utf8mb4_unicode_ci"
|
||||||
|
ports:
|
||||||
|
- "33306:3306"
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=123456
|
||||||
|
- MYSQL_DATABASE=apipark
|
||||||
|
volumes:
|
||||||
|
- /var/lib/apipark/mysql:/var/lib/mysql
|
||||||
|
networks:
|
||||||
|
- apipark
|
||||||
|
apipark:
|
||||||
|
image: apipark/apipark:v1.2.0-beta
|
||||||
|
container_name: apipark
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- apipark
|
||||||
|
ports:
|
||||||
|
- "18288:8288"
|
||||||
|
depends_on:
|
||||||
|
- apipark-mysql
|
||||||
|
environment:
|
||||||
|
- MYSQL_USER_NAME=root
|
||||||
|
- MYSQL_PWD=123456
|
||||||
|
- MYSQL_IP=apipark-mysql
|
||||||
|
- MYSQL_PORT=3306 #mysql端口
|
||||||
|
- MYSQL_DB="apipark"
|
||||||
|
- ERROR_DIR=work/logs # 日志放置目录
|
||||||
|
- ERROR_FILE_NAME=error.log # 错误日志文件名
|
||||||
|
- ERROR_LOG_LEVEL=info # 错误日志等级,可选:panic,fatal,error,warning,info,debug,trace 不填或者非法则为info
|
||||||
|
- ERROR_EXPIRE=7d # 错误日志过期时间,默认单位为天,d|天,h|小时, 不合法配置默认为7d
|
||||||
|
- ERROR_PERIOD=day # 错误日志切割周期,仅支持day、hour
|
||||||
|
- REDIS_ADDR=apipark-redis:6379 #Redis集群地址 多个用,隔开
|
||||||
|
- REDIS_PWD=123456 # Redis密码
|
||||||
|
- ADMIN_PASSWORD=12345678
|
||||||
|
influxdb2:
|
||||||
|
image: influxdb:2.6
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
container_name: influxdb2
|
||||||
|
hostname: influxdb2
|
||||||
|
ports:
|
||||||
|
- "8086:8086"
|
||||||
|
volumes:
|
||||||
|
- /var/lib/apipark/influxdb2:/var/lib/influxdb2
|
||||||
|
networks:
|
||||||
|
- apipark
|
||||||
|
apipark-redis:
|
||||||
|
container_name: apipark-redis
|
||||||
|
image: redis:7.2.4
|
||||||
|
hostname: apipark-redis
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
command:
|
||||||
|
- bash
|
||||||
|
- -c
|
||||||
|
- "redis-server --protected-mode yes --logfile redis.log --appendonly no --port 6379 --requirepass 123456"
|
||||||
|
networks:
|
||||||
|
- apipark
|
||||||
|
apipark-apinto:
|
||||||
|
image: eolinker/apinto-gateway
|
||||||
|
container_name: apipark-apinto
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
command:
|
||||||
|
- ./start.sh
|
||||||
|
ports:
|
||||||
|
- "8099:8099"
|
||||||
|
- "9400:9400"
|
||||||
|
- "9401:9401"
|
||||||
|
volumes:
|
||||||
|
- /var/lib/apipark/apinto/data:/var/lib/apinto
|
||||||
|
- /var/lib/apipark/apinto/log:/var/log/apinto
|
||||||
|
- ${PWD}/config.yml:/etc/apinto/config.yml
|
||||||
|
networks:
|
||||||
|
- apipark
|
||||||
|
networks:
|
||||||
|
apipark:
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
driver: default
|
||||||
|
config:
|
||||||
|
- subnet: 172.100.0.0/24
|
||||||
Executable → Regular
+8
@@ -25,8 +25,16 @@ cd "./eosc" && git pull
|
|||||||
# =========================================================================
|
# =========================================================================
|
||||||
echo "更新 aoaccount"
|
echo "更新 aoaccount"
|
||||||
cd "${BASEPATH}/"
|
cd "${BASEPATH}/"
|
||||||
|
|
||||||
if [ ! -d "./aoaccount" ]; then
|
if [ ! -d "./aoaccount" ]; then
|
||||||
git clone http://gitlab.eolink.com/apinto/aoaccount.git
|
git clone http://gitlab.eolink.com/apinto/aoaccount.git
|
||||||
fi
|
fi
|
||||||
cd "./aoaccount" && git pull
|
cd "./aoaccount" && git pull
|
||||||
|
|
||||||
|
echo "更新go-common"
|
||||||
|
cd "${BASEPATH}/"
|
||||||
|
if [ ! -d "./go-common" ]; then
|
||||||
|
git clone http://gitlab.eolink.com/apinto/go-common.git
|
||||||
|
fi
|
||||||
|
cd "./go-common" && git pull
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ func (i *imlServiceService) ServiceList(ctx context.Context, serviceIds ...strin
|
|||||||
w["uuid"] = serviceIds
|
w["uuid"] = serviceIds
|
||||||
}
|
}
|
||||||
w["as_server"] = true
|
w["as_server"] = true
|
||||||
|
w["is_delete"] = false
|
||||||
list, err := i.store.List(ctx, w)
|
list, err := i.store.List(ctx, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -46,6 +47,7 @@ func (i *imlServiceService) ServiceListByKind(ctx context.Context, kind Kind, se
|
|||||||
}
|
}
|
||||||
w["as_server"] = true
|
w["as_server"] = true
|
||||||
w["kind"] = kind
|
w["kind"] = kind
|
||||||
|
w["is_delete"] = false
|
||||||
list, err := i.store.List(ctx, w)
|
list, err := i.store.List(ctx, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -57,6 +59,7 @@ func (i *imlServiceService) SearchPublicServices(ctx context.Context, keyword st
|
|||||||
w := map[string]interface{}{
|
w := map[string]interface{}{
|
||||||
"as_server": true,
|
"as_server": true,
|
||||||
"service_type": PublicService.Int(),
|
"service_type": PublicService.Int(),
|
||||||
|
"is_delete": false,
|
||||||
}
|
}
|
||||||
list, err := i.store.Search(ctx, keyword, w)
|
list, err := i.store.Search(ctx, keyword, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -93,6 +96,7 @@ func (i *imlServiceService) AppList(ctx context.Context, appIds ...string) ([]*S
|
|||||||
w["uuid"] = appIds
|
w["uuid"] = appIds
|
||||||
}
|
}
|
||||||
w["as_app"] = true
|
w["as_app"] = true
|
||||||
|
w["is_delete"] = false
|
||||||
list, err := i.store.List(ctx, w)
|
list, err := i.store.List(ctx, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
Reference in New Issue
Block a user