From 67deef3c4f032a5e4a28660c97fbbed187d8a780 Mon Sep 17 00:00:00 2001 From: maggieyyy <61950669+maggieyyy@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:05:47 +0800 Subject: [PATCH] fix: delete files & width of pic in editor & timing bug --- .../src/contexts/GlobalStateContext.tsx | 2 +- frontend/packages/common/src/locales/index.ts | 12 + .../src/pages/aiService/AiServiceConfig.tsx | 416 ------------------ .../aiService/AiServiceInsideDocument.tsx | 2 +- .../src/pages/aiService/AiServiceList.tsx | 159 ------- .../src/pages/common/ApiRequestSetting.tsx | 2 +- .../pages/serviceCategory/ServiceCategory.tsx | 277 ------------ .../ServiceHubCategoryConfig.tsx | 122 ----- .../core/src/pages/system/SystemConfig.tsx | 2 +- .../src/pages/system/SystemInsideDocument.tsx | 2 +- .../core/src/pages/system/SystemList.tsx | 4 +- .../system/api/SystemInsideApiCreate.tsx | 156 ------- .../system/api/SystemInsideApiDetail.tsx | 99 ----- .../pages/system/api/SystemInsideApiList.tsx | 251 ----------- .../packages/core/src/pages/team/TeamList.tsx | 2 +- .../market/src/const/serviceHub/type.ts | 1 + .../src/pages/serviceHub/ServiceHubDetail.tsx | 4 +- .../src/pages/serviceHub/ServiceHubList.tsx | 2 +- .../management/ServiceHubManagement.tsx | 4 +- 19 files changed, 26 insertions(+), 1493 deletions(-) delete mode 100644 frontend/packages/core/src/pages/aiService/AiServiceConfig.tsx delete mode 100644 frontend/packages/core/src/pages/aiService/AiServiceList.tsx delete mode 100644 frontend/packages/core/src/pages/serviceCategory/ServiceCategory.tsx delete mode 100644 frontend/packages/core/src/pages/serviceCategory/ServiceHubCategoryConfig.tsx delete mode 100644 frontend/packages/core/src/pages/system/api/SystemInsideApiCreate.tsx delete mode 100644 frontend/packages/core/src/pages/system/api/SystemInsideApiDetail.tsx delete mode 100644 frontend/packages/core/src/pages/system/api/SystemInsideApiList.tsx diff --git a/frontend/packages/common/src/contexts/GlobalStateContext.tsx b/frontend/packages/common/src/contexts/GlobalStateContext.tsx index 6cf49469..b338b76a 100644 --- a/frontend/packages/common/src/contexts/GlobalStateContext.tsx +++ b/frontend/packages/common/src/contexts/GlobalStateContext.tsx @@ -110,7 +110,7 @@ export const GlobalProvider: FC<{children:ReactNode}> = ({ children }) => { updateDate: '2024-07-01', powered:'Powered by https://apipark.com', mainPage:'/guide/page', - language:'en' + language:'en-US' }); const [accessData,setAccessData] = useState>(new Map()) const [pluginAccessDictionary, setPluginAccessDictionary] = useState<{[k:string]:string}>({}) diff --git a/frontend/packages/common/src/locales/index.ts b/frontend/packages/common/src/locales/index.ts index f83c77e2..00cb3708 100644 --- a/frontend/packages/common/src/locales/index.ts +++ b/frontend/packages/common/src/locales/index.ts @@ -6,8 +6,12 @@ import crc32 from 'crc/crc32'; // 引入需要实现国际化的简体、繁体、英文三种数据的json文件 import zhCN from 'antd/locale/zh_CN'; import enUS from 'antd/locale/en_US'; +import jaJP from 'antd/locale/ja_JP'; +import zhTW from 'antd/locale/zh_TW'; import localZh_CN from './scan/zh-CN.json'; // 本地翻译中文文件 import localEn_US from './scan/en-US.json'; // 本地翻译英文文件 +import localZh_TW from './scan/zh-TW.json'; // 本地翻译英文文件 +import localJa_JP from './scan/ja-JP.json'; // 本地翻译英文文件 // import config from '../../../../i18next-scanner.config.js'; const resources = { @@ -18,6 +22,14 @@ const resources = { 'en-US': { translation: localEn_US, ...enUS + }, + 'zh-TW': { + translation: localZh_TW, + ...zhTW + }, + 'ja-JP': { + translation: localJa_JP, + ...jaJP } }; diff --git a/frontend/packages/core/src/pages/aiService/AiServiceConfig.tsx b/frontend/packages/core/src/pages/aiService/AiServiceConfig.tsx deleted file mode 100644 index 802a0085..00000000 --- a/frontend/packages/core/src/pages/aiService/AiServiceConfig.tsx +++ /dev/null @@ -1,416 +0,0 @@ - -import { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from "react"; -import { App, Button, Form, Input, Radio, Row, Select, TreeSelect, Upload } from "antd"; -import { Link, useNavigate, useParams } from "react-router-dom"; -import { RouterParams } from "@core/components/aoplatform/RenderRoutes.tsx"; -import { BasicResponse, DELETE_TIPS, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const.tsx"; -import { useFetch} from "@common/hooks/http.ts"; -import { DefaultOptionType } from "antd/es/cascader"; -import { EntityItem, MemberItem, SimpleTeamItem } from "@common/const/type.ts"; -import { v4 as uuidv4 } from 'uuid' -import { validateUrlSlash } from "@common/utils/validate.ts"; -import { normFile } from "@common/utils/uploadPic.ts"; -import { useBreadcrumb } from "@common/contexts/BreadcrumbContext.tsx"; -import { SERVICE_VISUALIZATION_OPTIONS } from "@core/const/system/const.tsx"; -import { RcFile, UploadChangeParam, UploadFile, UploadProps } from "antd/es/upload/interface"; -import { LoadingOutlined } from "@ant-design/icons"; -import { getImgBase64 } from "@common/utils/dataTransfer.ts"; -import { CategorizesType } from "@market/const/serviceHub/type.ts"; -import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; -import { Icon } from "@iconify/react/dist/iconify.js"; -import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; -import { $t } from "@common/locales/index.ts"; -import { AiServiceConfigHandle, AiServiceConfigFieldType } from "@core/const/ai-service/type"; -import { useAiServiceContext } from "@core/contexts/AiServiceContext"; - -type SimpleAiProviderItem = EntityItem & { - configured:boolean - logo:string -} - -const AiServiceConfig = forwardRef((_,ref) => { - const { message,modal } = App.useApp() - const { teamId, serviceId } = useParams(); - const [onEdit, setOnEdit] = useState(!!teamId) - const [form] = Form.useForm(); - const {fetchData} = useFetch() - const [teamOptionList, setTeamOptionList] = useState() - const [providerOptionList, setProviderOptionList] = useState() - const navigate = useNavigate(); - const {setBreadcrumb} = useBreadcrumb() - const { setAiServiceInfo} = useAiServiceContext() - const [showClassify, setShowClassify] = useState() - const [imageBase64, setImageBase64] = useState(null); - const [tagOptionList, setTagOptionList] = useState([]) - const [serviceClassifyOptionList, setServiceClassifyOptionList] = useState() - const [uploadLoading, setUploadLoading] = useState(false) - const {checkPermission,accessInit, getGlobalAccessData,state, aiConfigFlushed, setAiConfigFlushed} = useGlobalContext() - - useImperativeHandle(ref, () => ({ - save:onFinish - })); - - const beforeUpload = async (file: RcFile) => { - if (!['image/png', 'image/jpeg', 'image/svg+xml'].includes(file.type)) { - alert($t('只允许上传PNG、JPG或SVG格式的图片')); - return false; - } - const reader = new FileReader(); - reader.onload = (e: ProgressEvent) => { - setImageBase64(e.target?.result as string); - form.setFieldValue('logo', e.target?.result); - }; - reader.readAsDataURL(file); - // } - return false; - }; - - - const handleChange: UploadProps['onChange'] = (info: UploadChangeParam) => { - if (info.file.status === 'uploading') { - setUploadLoading(true); - return; - } - if (info.file.status === 'done') { - getImgBase64(info.file.originFileObj as RcFile, () => { - setUploadLoading(false); - }); - } - if (info.fileList.length === 0) { - form.setFieldValue( "logo", null ); - } - }; - - const uploadButton = ( -
- {uploadLoading ? : } -
- ); - - const getTagAndServiceClassifyList = ()=>{ - setTagOptionList([]) - setServiceClassifyOptionList([]) - fetchData>('catalogues',{method:'GET'}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setTagOptionList(data.tags?.map((x:EntityItem)=>{return { - label:x.name, value:x.name - }})||[]) - setServiceClassifyOptionList(data.catalogues) - - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - }) - } - - - // 获取表单默认值 - const getAiServiceInfo = () => { - fetchData>('ai-service/info',{method:'GET',eoParams:{team:teamId, service:serviceId},eoTransformKeys:['team_id','service_type']}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setTimeout(()=>{ - form.setFieldsValue({ - ...data.service, - team:data.service.team.id, - catalogue:data.service.catalogue?.id, - tags:data.service.tags?.map((x:EntityItem)=>x.name), - provider:data.service.provider.id, - logoFile:[ - { - uid: '-1', // 文件唯一标识 - name: 'image.png', // 文件名 - status: 'done', // 状态有:uploading, done, error, removed - url: data.service?.logo || '', // 图片 Base64 数据 - } - ] - }) - setImageBase64(data.service.logo) - setShowClassify(data.service.serviceType === 'public') - },0) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - }) - }; - - const onFinish:()=>Promise = () => { - return form.validateFields().then((value)=>{ - return fetchData>(serviceId === undefined? 'team/ai-service':'ai-service/info',{method:serviceId === undefined? 'POST' : 'PUT',eoParams: {...(serviceId === undefined ? {team:value.team} :{service:serviceId,team:teamId})},eoBody:({...value,prefix:value.prefix?.trim()}), eoTransformKeys:['serviceType']},).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || $t(RESPONSE_TIPS.success)) - setAiServiceInfo(data.service) - return Promise.resolve(true) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - return Promise.reject(msg || $t(RESPONSE_TIPS.error)) - } - }).catch((errorInfo)=>{ - return Promise.reject(errorInfo) - }) - }) - }; - - const getProviderOptionList = ()=>{ - setProviderOptionList([]) - fetchData>('simple/ai/providers',{method:'GET',eoTransformKeys:[]}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setProviderOptionList(data.providers?.filter(x=>x.configured)?.map((x:SimpleAiProviderItem)=>{return {...x, - label:
, value:x.id - }})) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - }) - } - - const getTeamOptionList = ()=>{ - setTeamOptionList([]) - - fetchData>(!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 - }})) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - }) - } - - const deleteAiService = ()=>{ - fetchData>('team/ai-service',{method:'DELETE',eoParams:{team:teamId,service:serviceId}}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || $t(RESPONSE_TIPS.success)) - navigate(`/aiservice/list`) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - }) - } - - useEffect(()=>{ - aiConfigFlushed && getProviderOptionList() - },[aiConfigFlushed]) - - useEffect(() => { - getProviderOptionList() - getTagAndServiceClassifyList() - if(accessInit){ - getTeamOptionList() - }else{ - getGlobalAccessData()?.then(()=>{ - getTeamOptionList() - }) - } - if (serviceId !== undefined) { - setOnEdit(true); - getAiServiceInfo(); - setBreadcrumb([ - { - title: {$t('服务')} - }, - { - title: $t('设置') - }]) - - } else { - setOnEdit(false); - form.setFieldValue('id',uuidv4()); - form.setFieldValue('team',teamId); - form.setFieldValue('serviceType','inner'); - } - return (form.setFieldsValue({})) - }, [serviceId]); - - - const deleteAiServiceModal = async ()=>{ - modal.confirm({ - title:$t('删除'), - content:$t(DELETE_TIPS.default), - onOk:()=> { - return deleteAiService() - }, - width:600, - okText:$t('确认'), - okButtonProps:{ - danger:true - }, - cancelText:$t('取消'), - closable:true, - icon:<> - }) - } - - const visualizationOptions = useMemo(()=>SERVICE_VISUALIZATION_OPTIONS.map((x)=>({...x, label:$t(x.label)})),[state.language]) - - return ( - <> - -
-
- - label={$t("服务名称")} - name="name" - rules={[{ required: true ,whitespace:true }]} - > - - - - - label={$t("服务ID")} - name="id" - rules={[{ required: true ,whitespace:true }]} - > - - - - - label={$t("AI 模型供应商")} - name="provider" - rules={[{ required: true }]} - >{ - (providerOptionList && providerOptionList.length >0 ) ? :

未配置任何 AI 模型供应商,setAiConfigFlushed(false)}>立即配置

- } - - - - label={$t("API 调用前缀")} - name="prefix" - extra={$t("选填,作为服务内所有API的前缀,比如host/{service_name}/{api_path},一旦保存无法修改")} - rules={[ - { - validator: validateUrlSlash, - }]} - > - - - - - label={$t("图标")} - name="logoFile" - extra={$t("仅支持 .png .jpg .jpeg .svg 格式的图片文件, 大于 1KB 的文件将被压缩")} - valuePropName="fileList" getValueFromEvent={normFile} - > - -
- {imageBase64 ? Logo : uploadButton} -
-
- - - - - label={$t("描述")} - name="description" - > - - - - - label={$t("Logo")} - name="logo" - hidden - > - - - {!onEdit && - label={$t("所属团队")} - name="team" - rules={[{ required: true }]} - > - - } - - - - label={$t("标签")} - name="tags" - > - - - - - label={$t("服务类型")} - name="serviceType" - rules={[{required: true}]} - > - {setShowClassify(e.target.value === 'public')}} /> - - - {showClassify && - - label={$t("所属服务分类")} - name="catalogue" - extra={$t("设置服务展示在服务市场中的哪个分类下")} - rules={[{required: true}]} - > - - - } - {onEdit && <> - - - - - } -
- {onEdit && <> - -
-

{$t('删除服务')}:{$t('删除操作不可恢复,请谨慎操作!')}

-
- - - -
-
-
- } -
-
- - ) -}) -export default AiServiceConfig \ No newline at end of file diff --git a/frontend/packages/core/src/pages/aiService/AiServiceInsideDocument.tsx b/frontend/packages/core/src/pages/aiService/AiServiceInsideDocument.tsx index 411f367d..3dd2ef2b 100644 --- a/frontend/packages/core/src/pages/aiService/AiServiceInsideDocument.tsx +++ b/frontend/packages/core/src/pages/aiService/AiServiceInsideDocument.tsx @@ -80,7 +80,7 @@ const ServiceInsideDocument = ()=>{ ], toolbar: 'undo redo | styles | bold italic | alignleft aligncenter alignright alignjustify | codesample |table|' + 'bullist numlist outdent indent | link image | print preview media fullscreen | ' + 'forecolor backcolor emoticons | help', - content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }', + content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px; } img { max-width: 100%; }', setup: setupEditor, codesample_languages:[ { diff --git a/frontend/packages/core/src/pages/aiService/AiServiceList.tsx b/frontend/packages/core/src/pages/aiService/AiServiceList.tsx deleted file mode 100644 index dbb3ec7b..00000000 --- a/frontend/packages/core/src/pages/aiService/AiServiceList.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import PageList from "@common/components/aoplatform/PageList.tsx" -import {ActionType} from "@ant-design/pro-components"; -import {FC, useEffect, useMemo, useRef, useState} from "react"; -import {useNavigate} from "react-router-dom"; -import { App} from "antd"; -import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; -import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; -import {useFetch} from "@common/hooks/http.ts"; -import { SimpleTeamItem ,SimpleMemberItem} from "@common/const/type.ts"; -import { DrawerWithFooter } from "@common/components/aoplatform/DrawerWithFooter.tsx"; -import AiServiceConfig from "./AiServiceConfig.tsx"; -import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; -import { $t } from "@common/locales/index.ts"; -import { AiServiceTableListItem, AiServiceConfigHandle } from "@core/const/ai-service/type.ts"; -import { AI_SERVICE_TABLE_COLUMNS } from "@core/const/ai-service/const.tsx"; - -const AiServiceList:FC = ()=>{ - const navigate = useNavigate(); - const [tableSearchWord, setTableSearchWord] = useState('') - const { setBreadcrumb } = useBreadcrumb() - const [teamList, setTeamList] = useState<{ [k: string]: { text: string; }; }>() - const {fetchData} = useFetch() - const [tableListDataSource, setTableListDataSource] = useState([]); - const [tableHttpReload, setTableHttpReload] = useState(true); - const { message } = App.useApp() - const pageListRef = useRef(null); - const [memberValueEnum, setMemberValueEnum] = useState<{[k:string]:{text:string}}>({}) - const [open, setOpen] = useState(false); - const drawerFormRef = useRef(null) - const {checkPermission,accessInit, getGlobalAccessData,state} = useGlobalContext() - - const getAiServiceList = ()=>{ - if(!accessInit){ - getGlobalAccessData()?.then(()=>{ - getAiServiceList() - }) - return - } - if(!tableHttpReload){ - setTableHttpReload(true) - return Promise.resolve({ - data: tableListDataSource, - success: true, - }); - } - return fetchData>(!checkPermission('system.workspace.service.view_all') ? 'my_ai_services':'ai-services',{method:'GET',eoParams:{keyword:tableSearchWord},eoTransformKeys:['api_num','can_delete','create_time']}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setTableListDataSource(data.services) - setTableHttpReload(false) - return {data:data.services, success: true} - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - return {data:[], success:false} - } - }).catch(() => { - return {data:[], success:false} - }) - } - - const getTeamsList = ()=>{ - if(!accessInit){ - getGlobalAccessData()?.then(()=>{ - getTeamsList() - }) - return - } - fetchData>(!checkPermission('system.workspace.team.view_all') ?'simple/teams/mine' :'simple/teams',{method:'GET',eoTransformKeys:[]}).then(response=>{ - const {code,data,msg} = response - setTeamList(data.teams) - if(code === STATUS_CODE.SUCCESS){ - const tmpValueEnum:{[k:string]:{text:string}} = {} - data.teams?.forEach((x:SimpleMemberItem)=>{ - tmpValueEnum[x.name] = {text:x.name} - }) - setTeamList(tmpValueEnum) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - return {data:[], success:false} - } - }) - } - - const manualReloadTable = () => { - setTableHttpReload(true); // 表格数据需要从后端接口获取 - pageListRef.current?.reload() - }; - - const getMemberList = async ()=>{ - setMemberValueEnum({}) - const {code,data,msg} = await fetchData>('simple/member',{method:'GET'}) - if(code === STATUS_CODE.SUCCESS){ - const tmpValueEnum:{[k:string]:{text:string}} = {} - data.members?.forEach((x:SimpleMemberItem)=>{ - tmpValueEnum[x.name] = {text:x.name} - }) - setMemberValueEnum(tmpValueEnum) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - } - - useEffect(() => { - getTeamsList(); - getMemberList() - setBreadcrumb([ - { - title: $t('服务') - }]) - }, []); - - const onClose = () => { - setOpen(false); - }; - - const columns = useMemo(()=>{ - const res = AI_SERVICE_TABLE_COLUMNS.map(x=>{ - if(x.filters &&((x.dataIndex as string[])?.indexOf('master') !== -1 ) ){ - x.valueEnum = memberValueEnum - } - if(x.filters &&((x.dataIndex as string[])?.indexOf('team') !== -1 ) ){ - x.valueEnum = teamList - } - - return {...x,title:typeof x.title === 'string' ? $t(x.title as string) : x.title}}) - return res - },[memberValueEnum,teamList,state.language]); - - return ( -
- {/* */} - getAiServiceList()} - addNewBtnTitle={$t("添加服务")} - addNewBtnWrapperClass={'my-first-step'} - searchPlaceholder={$t("输入名称、ID、所属团队、负责人查找服务")} - onAddNewBtnClick={() => { - setOpen(true) - }} - manualReloadTable={manualReloadTable} - onChange={() => { - setTableHttpReload(false) - }} - onSearchWordChange={(e) => { - setTableSearchWord(e.target.value) - }} - onRowClick={(row:AiServiceTableListItem)=>navigate(`/aiservice/${row.team.id}/inside/${row.id}`)} - /> - drawerFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res})} > - - -
- ) - -} -export default AiServiceList \ No newline at end of file diff --git a/frontend/packages/core/src/pages/common/ApiRequestSetting.tsx b/frontend/packages/core/src/pages/common/ApiRequestSetting.tsx index 8e756927..9fd9a810 100644 --- a/frontend/packages/core/src/pages/common/ApiRequestSetting.tsx +++ b/frontend/packages/core/src/pages/common/ApiRequestSetting.tsx @@ -67,7 +67,7 @@ export default function ApiRequestSetting(){ > label={$t("API 调用地址")} - name="name" + name="invokeAddress" rules={[{ required: true,whitespace:true }]} extra={$t("API base URL 一般设置为API 网关的外部网络访问地址,或者是API网关绑定的域名。")} > diff --git a/frontend/packages/core/src/pages/serviceCategory/ServiceCategory.tsx b/frontend/packages/core/src/pages/serviceCategory/ServiceCategory.tsx deleted file mode 100644 index 80579bc4..00000000 --- a/frontend/packages/core/src/pages/serviceCategory/ServiceCategory.tsx +++ /dev/null @@ -1,277 +0,0 @@ -import TreeWithMore from "@common/components/aoplatform/TreeWithMore"; -import WithPermission from "@common/components/aoplatform/WithPermission"; -import { BasicResponse, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE } from "@common/const/const"; -import { PERMISSION_DEFINITION } from "@common/const/permissions"; -import { useFetch } from "@common/hooks/http"; -import { checkAccess } from "@common/utils/permission"; -import { CategorizesType, ServiceHubCategoryConfigHandle } from "@market/const/serviceHub/type"; -import { App, Button, Spin, Tree, TreeDataNode, TreeProps } from "antd"; -import { DataNode } from "antd/es/tree"; -import { Key, useEffect, useMemo, useRef, useState } from "react"; -import { ServiceHubCategoryConfig } from "./ServiceHubCategoryConfig"; -import { useGlobalContext } from "@common/contexts/GlobalStateContext"; -import { useBreadcrumb } from "@common/contexts/BreadcrumbContext"; -import { LoadingOutlined } from "@ant-design/icons"; -import { cloneDeep } from "lodash-es"; -import { Icon } from "@iconify/react/dist/iconify.js"; -import InsidePage from "@common/components/aoplatform/InsidePage"; -import { EntityItem } from "@common/const/type"; -import { $t } from "@common/locales"; - -export default function ServiceCategory(){ - const [gData, setGData] = useState([]); - const [cateData, setCateData] = useState([]); - const [expandedKeys, setExpandedKeys] = useState([]); - const {message,modal} = App.useApp() - const {fetchData} = useFetch() - const addRef = useRef(null) - const addChildRef = useRef(null) - const renameRef = useRef(null) - const {accessData} = useGlobalContext() - const { setBreadcrumb } = useBreadcrumb() - const [loading, setLoading] = useState(false) - - const onDrop: TreeProps['onDrop'] = (info) => { - const dropKey = info.node.key; - const dragKey = info.dragNode.key; - const dropPos = info.node.pos.split('-'); - const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]); // the drop position relative to the drop node, inside 0, top -1, bottom 1 - - const loop = ( - data: TreeDataNode[], - key: React.Key, - callback: (node: TreeDataNode, i: number, data: TreeDataNode[]) => void, - ) => { - for (let i = 0; i < data.length; i++) { - if (data[i].id === key) { - return callback(data[i], i, data); - } - if (data[i].children) { - loop(data[i].children!, key, callback); - } - } - }; - const data = cloneDeep(gData); - - // Find dragObject - let dragObj: TreeDataNode; - loop(data, dragKey, (item, index, arr) => { - arr.splice(index, 1); - dragObj = item; - }); - - if (!info.dropToGap) { - // Drop on the content - loop(data, dropKey, (item) => { - item.children = item.children || []; - // where to insert. New item was inserted to the start of the array in this example, but can be anywhere - item.children.unshift(dragObj); - }); - } else { - let ar: TreeDataNode[] = []; - let i: number; - loop(data, dropKey, (_item, index, arr) => { - ar = arr; - i = index; - }); - if (dropPosition === -1) { - // Drop on the top of the drop node - ar.splice(i!, 0, dragObj!); - } else { - // Drop on the bottom of the drop node - ar.splice(i! + 1, 0, dragObj!); - } - } - - setGData(data); - sortCategories(data) - }; - - - const dropdownMenu = (entity:CategorizesType) => [ - { - key: 'addChildCate', - label: ( - - ), - }, - { - key: 'renameCate', - label: ( - - ), - }, - { - key: 'delete', - label: ( - - ), - }, - ]; - - const treeData = useMemo(() => { - setExpandedKeys([]) - const loop = (data: CategorizesType[]): DataNode[] => - data?.map((item) => { - if (item.children) { - setExpandedKeys(prev=>[...prev,item.id]) - return { - title: {item.name} , - key: item.id, children: loop(item.children) - }; - } - - return { - title: {item.name}, - key: item.id, - }; - }); - return loop(gData ?? []) - }, [gData]); - - const isActionAllowed = (type:'addCate'|'addChildCate'|'renameCate'|'delete') => { - const actionToPermissionMap = { - 'addCate': 'add', - 'addChildCate': 'add', - 'renameCate': 'edit', - 'delete': 'delete' - }; - - const action = actionToPermissionMap[type]; - const permission :keyof typeof PERMISSION_DEFINITION[0]= `system.api_market.service_classification.${action}`; - - return !checkAccess(permission, accessData); - }; - - const openModal = (type:'addCate'|'addChildCate'|'renameCate'|'delete',entity?:CategorizesType)=>{ - let title:string = '' - let content:string|React.ReactNode = '' - switch (type){ - case 'addCate': - title=$t('添加分类') - content= - break; - case 'addChildCate': - title=$t('添加子分类') - content= - break; - case 'renameCate': - title=$t('重命名分类') - content= - break; - case 'delete': - title=$t('删除') - content=$t(DELETE_TIPS.default) - break; - } - modal.confirm({ - title, - content, - onOk:()=>{ - switch (type){ - case 'addCate': - return addRef.current?.save().then((res)=>{if(res === true) getCategoryList()}) - case 'addChildCate': - return addChildRef.current?.save().then((res)=>{if(res === true) getCategoryList()}) - case 'renameCate': - return renameRef.current?.save().then((res)=>{if(res === true) getCategoryList()}) - case 'delete': - return deleteCate(entity!).then((res)=>{if(res === true) getCategoryList()}) - } - }, - width:600, - okText:$t('确认'), - okButtonProps:{ - disabled : isActionAllowed(type) - }, - cancelText:$t('取消'), - closable:true, - icon:<>, - }) - } - - const deleteCate = (entity:CategorizesType)=>{ - return new Promise((resolve, reject)=>{ - fetchData>('catalogue',{method:'DELETE',eoParams:{catalogue:entity.id},}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || $t(RESPONSE_TIPS.success)) - resolve(true) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - reject(msg || $t(RESPONSE_TIPS.error)) - } - }).catch((errorInfo)=> reject(errorInfo)) - }) - } - - const sortCategories = (newData:CategorizesType[])=>{ - setLoading(true) - fetchData>('catalogue/sort',{method:'PUT',eoBody:newData}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - getCategoryList() - }else{ - setGData(cateData) - message.error(msg || $t(RESPONSE_TIPS.error)) - } - }).catch(()=>{setGData(cateData)}).finally(()=>{setLoading(false)}) - } - - const getCategoryList = ()=>{ - setLoading(true) - fetchData>('catalogues',{method:'GET'}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setGData(data.catalogues) - setCateData(data.catalogues) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - }).finally(()=>{setLoading(false)}) - } - - useEffect(()=>{ - setBreadcrumb([ - { - title: $t('服务分类管理')}]) - getCategoryList() - },[]) - - return ( - -
- } spinning={loading} className=''> - {setExpandedKeys(expandedKeys as string[])}} - onDrop={onDrop} - treeData={treeData} - /> - - - - -
-
- ) -} \ No newline at end of file diff --git a/frontend/packages/core/src/pages/serviceCategory/ServiceHubCategoryConfig.tsx b/frontend/packages/core/src/pages/serviceCategory/ServiceHubCategoryConfig.tsx deleted file mode 100644 index 7add0f3c..00000000 --- a/frontend/packages/core/src/pages/serviceCategory/ServiceHubCategoryConfig.tsx +++ /dev/null @@ -1,122 +0,0 @@ -import {App, Form, Input} from "antd"; -import {forwardRef, useEffect, useImperativeHandle} from "react"; -import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; -import {useFetch} from "@common/hooks/http.ts"; -import { ServiceHubCategoryConfigHandle, ServiceHubCategoryConfigFieldType, ServiceHubCategoryConfigProps } from "@market/const/serviceHub/type.ts" -import WithPermission from "@common/components/aoplatform/WithPermission"; -import { $t } from "@common/locales"; - -export const ServiceHubCategoryConfig = forwardRef((props,ref)=>{ - const { message } = App.useApp() - const [form] = Form.useForm(); - const {type,entity} = props - const {fetchData} = useFetch() - - const save:()=>Promise = ()=>{ - const url:string = 'catalogue' - let method:string - switch (type){ - case 'addCate': - case 'addChildCate': - method = 'POST' - break; - case 'renameCate': - method = 'PUT' - break - } - return new Promise((resolve, reject)=>{ - if(!url || !method){ - reject($t(RESPONSE_TIPS.error)) - return - } - form.validateFields().then((value)=>{ - fetchData>(url,{method,eoBody:(value), eoParams:{ ...(type === 'renameCate' ? {catalogue:value.id} :undefined)}}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || $t(RESPONSE_TIPS.success)) - resolve(true) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - reject(msg || $t(RESPONSE_TIPS.error)) - } - }).catch((errorInfo)=> reject(errorInfo)) - }).catch((errorInfo)=> reject(errorInfo)) - }) - } - - useImperativeHandle(ref, ()=>({ - save - }) - ) - - useEffect(() => { - - switch(type){ - case 'addCate': - form.setFieldsValue({}) - break - case 'addChildCate': - form.setFieldsValue({parent:entity!.id}) - break - case 'renameCate': - form.setFieldsValue(entity) - break - } - - }, []); - - - return ( - -
- - {type === 'renameCate' && - - label={$t("ID")} - name="id" - hidden - rules={[{ required: true,whitespace:true }]} - > - - - } - {(type === 'addCate' || type === 'renameCate') && - - label={$t("分类名称")} - name="name" - rules={[{ required: true ,whitespace:true }]} - > - - } - - {type === 'addChildCate' &&<> - - label={$t("父分类 ID")} - name="parent" - hidden - rules={[{ required: true,whitespace:true }]} - > - - - - - label={$t("子分类名称")} - name="name" - rules={[{ required: true ,whitespace:true }]} - > - - - - } - -
-) -}) \ No newline at end of file diff --git a/frontend/packages/core/src/pages/system/SystemConfig.tsx b/frontend/packages/core/src/pages/system/SystemConfig.tsx index 1280e598..4c90e5c2 100644 --- a/frontend/packages/core/src/pages/system/SystemConfig.tsx +++ b/frontend/packages/core/src/pages/system/SystemConfig.tsx @@ -237,7 +237,7 @@ const SystemConfig = forwardRef((_,ref) => { if(accessInit){ getTeamOptionList() }else{ - getGlobalAccessData()?.then(()=>{ + getGlobalAccessData()?.then?.(()=>{ getTeamOptionList() }) } diff --git a/frontend/packages/core/src/pages/system/SystemInsideDocument.tsx b/frontend/packages/core/src/pages/system/SystemInsideDocument.tsx index 411f367d..5755ffa9 100644 --- a/frontend/packages/core/src/pages/system/SystemInsideDocument.tsx +++ b/frontend/packages/core/src/pages/system/SystemInsideDocument.tsx @@ -80,7 +80,7 @@ const ServiceInsideDocument = ()=>{ ], toolbar: 'undo redo | styles | bold italic | alignleft aligncenter alignright alignjustify | codesample |table|' + 'bullist numlist outdent indent | link image | print preview media fullscreen | ' + 'forecolor backcolor emoticons | help', - content_style: 'body { font-family:Helvetica,Arial,sans-serif; font-size:14px }', + content_style: 'body{ font-family:Helvetica,Arial,sans-serif; font-size:14px } img{ max-width: 100%; }', setup: setupEditor, codesample_languages:[ { diff --git a/frontend/packages/core/src/pages/system/SystemList.tsx b/frontend/packages/core/src/pages/system/SystemList.tsx index fe817614..5a4776ef 100644 --- a/frontend/packages/core/src/pages/system/SystemList.tsx +++ b/frontend/packages/core/src/pages/system/SystemList.tsx @@ -34,7 +34,7 @@ const SystemList:FC = ()=>{ const getSystemList = ()=>{ if(!accessInit){ - getGlobalAccessData()?.then(()=>{ + getGlobalAccessData()?.then?.(()=>{ getSystemList() }) return @@ -63,7 +63,7 @@ const SystemList:FC = ()=>{ const getTeamsList = ()=>{ if(!accessInit){ - getGlobalAccessData()?.then(()=>{ + getGlobalAccessData()?.then?.(()=>{ getTeamsList() }) return diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideApiCreate.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideApiCreate.tsx deleted file mode 100644 index f154021a..00000000 --- a/frontend/packages/core/src/pages/system/api/SystemInsideApiCreate.tsx +++ /dev/null @@ -1,156 +0,0 @@ -import {App, Col, Form, Input, Row, Select} from "antd"; -import {forwardRef, useEffect, useImperativeHandle, useRef} from "react"; -import EditableTableWithModal from "@common/components/aoplatform/EditableTableWithModal.tsx"; -import styles from "./SystemInsideApi.module.css" -import {BasicResponse, PLACEHOLDER, RESPONSE_TIPS, STATUS_CODE, VALIDATE_MESSAGE} from "@common/const/const.tsx"; -import {useFetch} from "@common/hooks/http.ts"; -import { HTTP_METHOD, MATCH_CONFIG } from "../../../const/system/const.tsx"; -import { SystemInsideApiCreateHandle, SystemInsideApiCreateProps, SystemApiProxyFieldType, SystemInsideApiProxyHandle } from "../../../const/system/type.ts"; -import { MatchItem } from "@common/const/type.ts"; -import { validateUrlSlash } from "@common/utils/validate.ts"; -import { $t } from "@common/locales/index.ts"; -import SystemInsideApiProxy from "@core/pages/system/api/SystemInsideApiProxy"; - -const SystemInsideApiCreate = forwardRef((props, ref) => { - const { message } = App.useApp() - const {type, entity, serviceId,teamId, modalApiPrefix:apiPrefix, modalPrefixForce:prefixForce} = props - const [form] = Form.useForm(); - const {fetchData} = useFetch() - const proxyRef = useRef(null) - - const onFinish = ()=>{ - return Promise.all([proxyRef.current?.validate?.(), form.validateFields()]).then(([,formValue])=>{ - const body = {...formValue,path:formValue.path.trim(),proxy:{...formValue.proxy,path:formValue.proxy.path ? (formValue.proxy.path.startsWith('/')? formValue.proxy.path: '/'+ formValue.proxy.path) : undefined}} - return fetchData>('service/api',{method:'POST',eoBody:(body), eoParams: {service:serviceId,team:teamId},eoTransformKeys:['matchType']}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || $t(RESPONSE_TIPS.success)) - return Promise.resolve(true) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - return Promise.reject(msg || $t(RESPONSE_TIPS.error)) - } - }).catch(errInfo=>Promise.reject(errInfo)) - }) - } - - const copy: ()=>Promise = ()=>{ - return new Promise((resolve, reject)=>{ - return form.validateFields().then((value)=>{ - fetchData>('service/api/copy',{method:'POST',eoParams:{service:serviceId,team:teamId, api:entity!.id},eoBody:({...value,path:value.path.trim()})}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || $t(RESPONSE_TIPS.success)) - return resolve(data.api.id) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - return reject(msg || $t(RESPONSE_TIPS.error)) - } - }).catch((errorInfo)=> reject(errorInfo)) - }).catch((errorInfo)=> reject(errorInfo)) - }) - } - - useImperativeHandle(ref, ()=>({ - copy, - save:onFinish - }) - ) - - useEffect(() => { - if(type === 'copy'){ - form.setFieldsValue({ - ...entity, - name:`${$t('副本')}-${entity!.name}`, - ...(prefixForce? - {prefix:apiPrefix,path: entity!.path.substring(apiPrefix?.length|| 0)}: - {}), - proxy:{timeout:10000, retry:0, ...entity?.proxy} - }); - } - else{ - form.setFieldValue('prefix',apiPrefix) - form.setFieldValue(['proxy','timeout'],10000) - form.setFieldValue(['proxy','retry'],0) - } - return (form.setFieldsValue({})) - }, []); - - return (
-
-
- {$t('API 基础信息')} - - label={$t("API 名称")} - name="name" - rules={[{ required: true ,whitespace:true }]} - > - - - - - label={$t("描述")} - name="description" - > - - - - - label={$t("请求方式")} - name="method" - rules={[{ required: true }]} - > - - - - - label={$t("请求路径")} - name="path" - rules={[{ required: true,whitespace:true }, - { - validator: validateUrlSlash, - }]} - className={styles['form-input-group']} - > - - - - - label={$t("高级匹配")} - name="match" - > - - configFields={MATCH_CONFIG} - /> - - {/* } */} - - { type !== 'copy' &&<> - - {$t('转发规则设置')} - - className="mb-0 bg-transparent border-none p-0" - name="proxy" - > - - - } -
-
-
- ) -}) -export default SystemInsideApiCreate \ No newline at end of file diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideApiDetail.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideApiDetail.tsx deleted file mode 100644 index 37b2af84..00000000 --- a/frontend/packages/core/src/pages/system/api/SystemInsideApiDetail.tsx +++ /dev/null @@ -1,99 +0,0 @@ - -import {useEffect, useRef, useState} from "react"; -import {BasicResponse, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; -import {useFetch} from "@common/hooks/http.ts"; -import {App, Button, Spin} from "antd"; -import ApiBasicInfoDisplay from "@common/components/postcat/api/ApiPreview/components/ApiBasicInfoDisplay"; -import ApiPreview from "@common/components/postcat/ApiPreview.tsx"; -import ApiMatch from "@common/components/postcat/api/ApiPreview/components/ApiMatch"; -import {v4 as uuidv4} from 'uuid' -import ApiProxy from "@common/components/postcat/api/ApiPreview/components/ApiProxy"; -import { ProxyHeaderItem, SystemApiDetail, SystemInsideApiDetailProps, SystemInsideApiDocumentHandle } from "../../../const/system/type.ts"; -import { MatchItem } from "@common/const/type.ts"; -import { DrawerWithFooter } from "@common/components/aoplatform/DrawerWithFooter.tsx"; -import SystemInsideApiDocument from "./SystemInsideApiDocument.tsx"; -import ScrollableSection from "@common/components/aoplatform/ScrollableSection.tsx"; -import WithPermission from "@common/components/aoplatform/WithPermission.tsx"; -import { LoadingOutlined } from "@ant-design/icons"; -import { $t } from "@common/locales/index.ts"; - -const SystemInsideApiDetail = (props:SystemInsideApiDetailProps)=>{ - const { message } = App.useApp() - const {serviceId, teamId, apiId} = props - const {fetchData} = useFetch() - const [apiDetail, setApiDetail] = useState() - const [open, setOpen] = useState(false); - const drawerFormRef = useRef(null) - const [loading, setLoading] = useState(false) - - const getApiDetail = ()=>{ - setLoading(true) - fetchData>('service/api/detail',{method:'GET',eoParams:{service:serviceId,team:teamId, api:apiId},eoTransformKeys:['create_time','update_time','match_type','upstream_id','opt_type']}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - const newApiDetail = { - ...data.api, - match:data.api.match?.map((x:MatchItem)=>{x.id = x.id ?? uuidv4();return x}) || [], - ...data.api.proxy && {proxy:{...data.api.proxy, - headers:data.api.proxy?.headers?.map((x:ProxyHeaderItem)=>{x.id = x.id?? uuidv4();return x || [] - })} - } - } - setApiDetail(newApiDetail) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - }).finally(()=>{setLoading(false)}) - } - - const onClose = ()=>{ - setOpen(false) - } - - useEffect(() => { - getApiDetail() - }, []); - - return ( - } spinning={loading} className="h-full 1" rootClassName="h-full 2" wrapperClassName="h-full 3" > -
- -
- { - apiDetail !== undefined && <> -
- - -
-

- {$t('创建者')}:{apiDetail?.creator.name || '-'} - {$t('最后编辑人')}:{apiDetail?.updater.name || '-'}{$t('更新时间')}:{apiDetail?.updateTime || '-'}

- } -
-
- { - apiDetail?.match && apiDetail.match?.length > 0 && - - } - - { - apiDetail?.proxy && Object.keys(apiDetail?.proxy).length > 0 && - - } - - {apiDetail && } -
-
- drawerFormRef.current?.save()?.then((res)=>{res&& getApiDetail();return res})} - showLastStep={true} - > - - -
-
) -} -export default SystemInsideApiDetail \ No newline at end of file diff --git a/frontend/packages/core/src/pages/system/api/SystemInsideApiList.tsx b/frontend/packages/core/src/pages/system/api/SystemInsideApiList.tsx deleted file mode 100644 index 7fe9dadb..00000000 --- a/frontend/packages/core/src/pages/system/api/SystemInsideApiList.tsx +++ /dev/null @@ -1,251 +0,0 @@ -import PageList, { PageProColumns } from "@common/components/aoplatform/PageList.tsx" -import {ActionType} from "@ant-design/pro-components"; -import {FC, useEffect, useMemo, useRef, useState} from "react"; -import {Link, useParams} from "react-router-dom"; -import {useBreadcrumb} from "@common/contexts/BreadcrumbContext.tsx"; -import {App, Divider} from "antd"; -import {BasicResponse, COLUMNS_TITLE, DELETE_TIPS, RESPONSE_TIPS, STATUS_CODE} from "@common/const/const.tsx"; -import { SimpleMemberItem} from '@common/const/type.ts' -import {useFetch} from "@common/hooks/http.ts"; -import {RouterParams} from "@core/components/aoplatform/RenderRoutes.tsx"; -import SystemInsideApiCreate from "./SystemInsideApiCreate.tsx"; -import {useSystemContext} from "../../../contexts/SystemContext.tsx"; -import { SYSTEM_API_TABLE_COLUMNS } from "../../../const/system/const.tsx"; -import { SystemApiSimpleFieldType, SystemApiTableListItem, SystemInsideApiCreateHandle, SystemInsideApiDocumentHandle } from "../../../const/system/type.ts"; -import TableBtnWithPermission from "@common/components/aoplatform/TableBtnWithPermission.tsx"; -import { useGlobalContext } from "@common/contexts/GlobalStateContext.tsx"; -import { checkAccess } from "@common/utils/permission.ts"; -import { DrawerWithFooter } from "@common/components/aoplatform/DrawerWithFooter.tsx"; -import SystemInsideApiDetail from "./SystemInsideApiDetail.tsx"; -import SystemInsideApiDocument from "./SystemInsideApiDocument.tsx"; -import { $t } from "@common/locales/index.ts"; - -const SystemInsideApiList:FC = ()=>{ - const [searchWord, setSearchWord] = useState('') - const { setBreadcrumb } = useBreadcrumb() - const { modal,message } = App.useApp() - // const [confirmLoading, setConfirmLoading] = useState(false); - const [init, setInit] = useState(true) - const [tableListDataSource, setTableListDataSource] = useState([]); - const [tableHttpReload, setTableHttpReload] = useState(true); - const {fetchData} = useFetch() - const pageListRef = useRef(null); - const copyRef = useRef(null) - const {apiPrefix, prefixForce} = useSystemContext() - const [memberValueEnum, setMemberValueEnum] = useState([]) - const {accessData,state} = useGlobalContext() - const [drawerType,setDrawerType]= useState<'add'|'edit'|'view'|'upstream'|undefined>() - const [open, setOpen] = useState(false); - const drawerEditFormRef = useRef(null) - const drawerAddFormRef = useRef(null) - const {serviceId, teamId} = useParams() - - const [curApi, setCurApi] = useState() - - const getApiList = (): Promise<{ data: SystemApiTableListItem[], success: boolean }>=> { - //console.log(sorter, filter) - if(!tableHttpReload){ - setTableHttpReload(true) - return Promise.resolve({ - data: tableListDataSource, - success: true, - }); - } - - return fetchData>('service/apis',{method:'GET',eoParams:{service:serviceId,team:teamId, keyword:searchWord},eoTransformKeys:['request_path','create_time','update_time','can_delete']}).then(response=>{ - const {code,data,msg} = response - if(code === STATUS_CODE.SUCCESS){ - setTableListDataSource(data.apis) - setInit((prev)=>prev ? false : prev) - setTableHttpReload(false) - return {data:data.apis, success: true} - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - return {data:[], success:false} - } - }).catch(() => { - return {data:[], success:false} - }) - } - - const deleteApi = (entity:SystemApiTableListItem)=>{ - return new Promise((resolve, reject)=>{ - fetchData>('service/api',{method:'DELETE',eoParams:{service:serviceId,team:teamId, api:entity!.id}}).then(response=>{ - const {code,msg} = response - if(code === STATUS_CODE.SUCCESS){ - message.success(msg || $t(RESPONSE_TIPS.success)) - resolve(true) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - reject(msg || $t(RESPONSE_TIPS.error)) - } - }).catch((errorInfo)=> reject(errorInfo)) - }) - } - - const openModal = async (type:'copy' | 'delete',entity:SystemApiTableListItem) =>{ - let title:string = '' - let content:string|React.ReactNode = '' - switch (type){ - case 'copy':{ - title=$t('复制 API') - message.loading($t(RESPONSE_TIPS.loading)) - const {code,data,msg} = await fetchData>('service/api/detail/simple',{method:'GET',eoParams:{service:serviceId,team:teamId, api:entity!.id}}) - message.destroy() - if(code === STATUS_CODE.SUCCESS){ - content= - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - return - } - break;} - case 'delete': - title=$t('删除') - content=$t(DELETE_TIPS.default) - break; - } - - modal.confirm({ - title, - content, - onOk:()=> { - switch (type){ - case 'copy': - return copyRef.current?.copy().then(()=> { - manualReloadTable() - }) - case 'delete': - return deleteApi(entity).then((res)=>{if(res === true) manualReloadTable()}) - } - }, - width:type==='copy'? 900: 600, - okText:$t('确认'), - okButtonProps:{ - disabled : !checkAccess( `team.service.api.${type}`, accessData ) - }, - cancelText:$t('取消'), - closable:true, - icon:<>, - }) - } - - const operation:PageProColumns[] =[ - { - title: COLUMNS_TITLE.operate, - key: 'option', - btnNums:4, - fixed:'right', - valueType: 'option', - render: (_: React.ReactNode, entity: SystemApiTableListItem) => [ - {openDrawer('view',entity)}} btnTitle="详情"/>, - , - {openModal('copy',entity)}} btnTitle="复制"/>, - , - {openDrawer('edit',entity)}} btnTitle="编辑"/>, - entity.canDelete && , - entity.canDelete && {openModal('delete',entity)}} btnTitle="删除"/>, - ], - } - ] - - const manualReloadTable = () => { - setTableHttpReload(true); // 表格数据需要从后端接口获取 - pageListRef.current?.reload() - }; - - const getMemberList = async ()=>{ - setMemberValueEnum([]) - const {code,data,msg} = await fetchData>('simple/member',{method:'GET'}) - if(code === STATUS_CODE.SUCCESS){ - setMemberValueEnum(data.members) - }else{ - message.error(msg || $t(RESPONSE_TIPS.error)) - } - } - - const openDrawer = (type:'add'|'edit'|'view',entity?:SystemApiTableListItem)=>{ - setCurApi(entity) - setDrawerType(type) - } - - useEffect(()=>{drawerType !== undefined ? setOpen(true):setOpen(false)},[drawerType]) - - useEffect(() => { - setBreadcrumb([ - { - title:{$t('服务')} - }, - { - title:$t('API') - } - ]) - getMemberList() - manualReloadTable() - }, [serviceId]); - - const onClose = () => { - setDrawerType(undefined); - setCurApi(undefined) - }; - - const columns = useMemo(()=>{ - return [...SYSTEM_API_TABLE_COLUMNS].map(x=>{ - if(x.filters &&((x.dataIndex as string[])?.indexOf('creator') !== -1) ){ - const tmpValueEnum:{[k:string]:{text:string}} = {} - memberValueEnum?.forEach((x:SimpleMemberItem)=>{ - tmpValueEnum[x.name] = {text:x.name} - }) - x.valueEnum = tmpValueEnum - } - return {...x,title:typeof x.title === 'string' ? $t(x.title as string) : x.title}}) - },[memberValueEnum,state.language]) - - const handlerSubmit:() => Promise|undefined= ()=>{ - switch(drawerType){ - case 'add':{ - return drawerAddFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res}) - } - case 'edit':{ - return drawerEditFormRef.current?.save()?.then((res)=>{res && manualReloadTable();return res}) - } - default:return undefined - } - } - - return ( - <> - getApiList()} - dataSource={tableListDataSource} - addNewBtnTitle={$t('添加 API')} - searchPlaceholder={$t('输入名称、URL 查找 API')} - onAddNewBtnClick={()=>{openDrawer('add')}} - addNewBtnAccess="team.service.api.add" - tableClickAccess="team.service.api.view" - manualReloadTable={manualReloadTable} - onSearchWordChange={(e)=>{setSearchWord(e.target.value)}} - onChange={() => { - setTableHttpReload(false) - }} - onRowClick={(row:SystemApiTableListItem)=>openDrawer('view',row)} - tableClass="mr-PAGE_INSIDE_X " - /> - handlerSubmit()} - showOkBtn={drawerType !== 'view'} - > - {drawerType === 'add' && } - {drawerType === 'edit' && } - {drawerType === 'view' && } - - - ) - -} -export default SystemInsideApiList \ No newline at end of file diff --git a/frontend/packages/core/src/pages/team/TeamList.tsx b/frontend/packages/core/src/pages/team/TeamList.tsx index dc1fab9e..1fba9241 100644 --- a/frontend/packages/core/src/pages/team/TeamList.tsx +++ b/frontend/packages/core/src/pages/team/TeamList.tsx @@ -35,7 +35,7 @@ const TeamList:FC = ()=>{ const getTeamList = ()=>{ if(!accessInit){ - getGlobalAccessData()?.then(()=>{getTeamList()}) + getGlobalAccessData()?.then?.(()=>{getTeamList()}) return } return fetchData>(!checkPermission('system.workspace.team.view_all') ? 'teams':'manager/teams',{method:'GET',eoParams:{keyword:searchWord},eoTransformKeys:['create_time','service_num','can_delete']}).then(response=>{ diff --git a/frontend/packages/market/src/const/serviceHub/type.ts b/frontend/packages/market/src/const/serviceHub/type.ts index 7ebbdab8..970c7fe8 100644 --- a/frontend/packages/market/src/const/serviceHub/type.ts +++ b/frontend/packages/market/src/const/serviceHub/type.ts @@ -17,6 +17,7 @@ export type ServiceBasicInfoType = { logo?:string invokeAddress:string approvalType:'auto'|'manual' + serviceType:'ai'|'rest' } export type ServiceDetailType = { diff --git a/frontend/packages/market/src/pages/serviceHub/ServiceHubDetail.tsx b/frontend/packages/market/src/pages/serviceHub/ServiceHubDetail.tsx index 99b8a000..9308a836 100644 --- a/frontend/packages/market/src/pages/serviceHub/ServiceHubDetail.tsx +++ b/frontend/packages/market/src/pages/serviceHub/ServiceHubDetail.tsx @@ -35,7 +35,7 @@ const ServiceHubDetail = ()=>{ const navigate = useNavigate(); const getServiceBasicInfo = ()=>{ - fetchData>('catalogue/service',{method:'GET',eoParams:{service:serviceId}, eoTransformKeys:['app_num','api_num','update_time','api_doc','invoke_address','approval_type']}).then(response=>{ + fetchData>('catalogue/service',{method:'GET',eoParams:{service:serviceId}, eoTransformKeys:['app_num','api_num','update_time','api_doc','invoke_address','approval_type','service_type']}).then(response=>{ const {code,data,msg} = response if(code === STATUS_CODE.SUCCESS){ setService(data.service) @@ -113,7 +113,7 @@ const ServiceHubDetail = ()=>{ { key: 'api-document', label: $t('API 文档'), - children:
, + children:
, icon: } ] diff --git a/frontend/packages/market/src/pages/serviceHub/ServiceHubList.tsx b/frontend/packages/market/src/pages/serviceHub/ServiceHubList.tsx index fc3c449b..1d5e3384 100644 --- a/frontend/packages/market/src/pages/serviceHub/ServiceHubList.tsx +++ b/frontend/packages/market/src/pages/serviceHub/ServiceHubList.tsx @@ -78,7 +78,7 @@ export const initialServiceHubListState = { if(!dataSet.selectedTag || dataSet.selectedTag.length === 0) return false if((!x.tags || !x.tags.length )&& dataSet.selectedTag.indexOf('empty') === -1) return false if(x.tags && x.tags.length && !x.tags.some(tag => dataSet.selectedTag.includes(tag.id))) return false; - if( dataSet.keyword && !x.name.includes(dataSet.keyword)) return false + if( dataSet.keyword && !x.name.toLocaleLowerCase().includes(dataSet.keyword.toLocaleLowerCase())) return false return true }) } diff --git a/frontend/packages/market/src/pages/serviceHub/management/ServiceHubManagement.tsx b/frontend/packages/market/src/pages/serviceHub/management/ServiceHubManagement.tsx index 10684e97..52e27669 100644 --- a/frontend/packages/market/src/pages/serviceHub/management/ServiceHubManagement.tsx +++ b/frontend/packages/market/src/pages/serviceHub/management/ServiceHubManagement.tsx @@ -33,7 +33,7 @@ export default function ServiceHubManagement() { const getServiceList = ()=>{ if(!accessInit){ - getGlobalAccessData()?.then(()=>{getServiceList()}) + getGlobalAccessData()?.then?.(()=>{getServiceList()}) return } setServiceLoading(true) @@ -56,7 +56,7 @@ const getServiceList = ()=>{ const getTeamsList = ()=>{ if(!accessInit){ - getGlobalAccessData()?.then(()=>{getTeamsList()}) + getGlobalAccessData()?.then?.(()=>{getTeamsList()}) return } setPageLoading(true)