mirror of
https://github.com/APIParkLab/APIPark.git
synced 2026-06-14 20:41:15 +08:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3217ad2bba | |||
| 1485b31226 | |||
| 8968e1f961 | |||
| 4b8fa43c36 | |||
| c21d783c52 | |||
| e928cd84d7 | |||
| 412cb75bf0 | |||
| a13b2a8afe | |||
| c0472c8539 | |||
| 5f40d5092c | |||
| b949939816 | |||
| 55f09f7542 | |||
| ef1ccb81a9 |
@@ -156,6 +156,10 @@ curl -sSO https://download.apipark.com/install/quick-start.sh ; bash quick-sta
|
||||
|
||||
<br>
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
# 🚀 Use Cases
|
||||
## Simplify AI Integration Costs
|
||||
- Connect to 100+ major models from all mainstream AI vendors, with standardized API calls requiring no additional adaptation work.
|
||||
@@ -199,11 +203,20 @@ To achieve this goal, we plan to add new features to APIPark, including:
|
||||
# 📕 Documentation
|
||||
Visit [APIPark Documentation](https://docs.apipark.com/docs/deploy) for detailed installation guides, API references, and usage instructions.
|
||||
|
||||
|
||||
# 🧑🤝🧑Friendly Links
|
||||
<a href="https://xroute.ai/">
|
||||
<img width="1248" height="158" alt="新建 PPTX 演示文稿 (2)_03" src="https://github.com/user-attachments/assets/0ebd694c-410a-4e3f-a793-90f1140d15df" />
|
||||
|
||||
</a>
|
||||
<br>
|
||||
|
||||
<br>
|
||||
|
||||
# 🧾 License
|
||||
APIPark uses the Apache 2.0 License. For more details, please refer to the LICENSE file.
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
# 💌 Contact Us
|
||||
@@ -215,3 +228,7 @@ For enterprise-level features and professional technical support, contact our pr
|
||||
<br>
|
||||
|
||||
🙏 A big thanks to everyone who helped shape APIPark. We are thrilled to hear the community’s thoughts! Let’s make the world of APIs and AI stronger and more fun together. 🎉
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ export type MemberTableListItem = {
|
||||
enable:boolean
|
||||
departmentId:string
|
||||
roles:EntityItem[]
|
||||
form: string
|
||||
from: string
|
||||
};
|
||||
|
||||
export type AddToDepartmentProps = {
|
||||
@@ -41,7 +41,7 @@ export type MemberDropdownModalFieldType = {
|
||||
|
||||
export type MemberDropdownModalProps = {
|
||||
type:'addDep'|'addChild'|'addMember'|'editMember'|'rename'
|
||||
entity?:(MemberTableListItem & {departmentIds:string[]}) | ({id?:string, departmentIds?:string[],name?:string,form?:string})
|
||||
entity?:(MemberTableListItem & {departmentIds:string[]}) | ({id?:string, departmentIds?:string[],name?:string,from?:string})
|
||||
selectedMemberGroupId?:string
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@ export const MemberDropdownModal = forwardRef<MemberDropdownModalHandle,MemberDr
|
||||
const {fetchData} = useFetch()
|
||||
const [departmentList, setDepartmentList] = useState<DepartmentListItem[]>([])
|
||||
const { state } = useGlobalContext()
|
||||
const [disableEditMemberData] = useState<boolean>(entity?.form !== 'self-build')
|
||||
|
||||
const [disableEditMemberData] = useState<boolean>(entity?.from === 'feishu')
|
||||
const save:()=>Promise<boolean | string> = ()=>{
|
||||
let url:string
|
||||
let method:string
|
||||
|
||||
@@ -95,14 +95,15 @@ const AddToDepartment = forwardRef<AddToDepartmentHandle, AddToDepartmentProps>(
|
||||
treeData?.map((x: DataNode) => ({
|
||||
...x,
|
||||
name: $t((x as unknown as { name: string }).name),
|
||||
checkable: false,
|
||||
children: x.children?.map(y => ({ ...y, checkable: false }))
|
||||
checkable: false, // 根节点不可选中
|
||||
children: x.children?.map(y => ({ ...y, checkable: true })) // 子节点可以选中
|
||||
})),
|
||||
[state.language, treeData]
|
||||
)
|
||||
|
||||
const onCheck: TreeProps['onCheck'] = (checkedKeys: string[]) => {
|
||||
setSelectedKeys(checkedKeys.checked)
|
||||
const onCheck: TreeProps['onCheck'] = (checkedKeys, info) => {
|
||||
const selectedIds = Array.isArray(checkedKeys) ? checkedKeys : checkedKeys.checked || []
|
||||
setSelectedKeys(selectedIds)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
@@ -153,11 +154,12 @@ const MemberList = () => {
|
||||
const [tableHttpReload, setTableHttpReload] = useState(true)
|
||||
const [tableListDataSource, setTableListDataSource] = useState<MemberTableListItem[]>([])
|
||||
const pageListRef = useRef<ActionType>(null)
|
||||
const { topGroupId, selectedDepartmentIds, refreshGroup } = useOutletContext<{
|
||||
const { topGroupId, selectedDepartmentIds, refreshGroup, refreshTableCount } = useOutletContext<{
|
||||
topGroupId: string
|
||||
departmentList: DepartmentListItem[]
|
||||
selectedDepartmentIds: string[]
|
||||
refreshGroup: () => void
|
||||
refreshTableCount: number
|
||||
}>()
|
||||
const AddMemberRef = useRef<MemberDropdownModalHandle>(null)
|
||||
const EditMemberRef = useRef<MemberDropdownModalHandle>(null)
|
||||
@@ -396,7 +398,7 @@ const MemberList = () => {
|
||||
width: 600,
|
||||
okText: $t('确认'),
|
||||
okButtonProps: {
|
||||
disabled: isActionAllowed(type) || (type === 'editMember' && entity?.form !== 'self-build')
|
||||
disabled: isActionAllowed(type) || (type === 'editMember' && entity?.from === 'feishu')
|
||||
},
|
||||
cancelText: $t('取消'),
|
||||
closable: true,
|
||||
@@ -415,6 +417,13 @@ const MemberList = () => {
|
||||
getDepartmentList()
|
||||
}, [])
|
||||
|
||||
// 监听外部刷新触发器
|
||||
useEffect(() => {
|
||||
if (refreshTableCount > 0) {
|
||||
manualReloadTable()
|
||||
}
|
||||
}, [refreshTableCount])
|
||||
|
||||
const getDepartmentList = async () => {
|
||||
setDepartmentValueEnum([])
|
||||
const { code, data, msg } = await fetchData<BasicResponse<{ department: DepartmentListItem }>>(
|
||||
|
||||
@@ -36,6 +36,11 @@ const MemberPage = ()=>{
|
||||
const [selectedDepartmentId, setSelectedDepartmentId] = useState<string>('-1')
|
||||
const {accessData,state} = useGlobalContext()
|
||||
const [refreshMemberCount, setRefreshMemberCount] = useState<number>(0)
|
||||
const [refreshTableCount, setRefreshTableCount] = useState<number>(0)
|
||||
|
||||
const refreshMemberTable = () => {
|
||||
setRefreshTableCount(prev => prev + 1)
|
||||
}
|
||||
const onSearchWordChange = (e:string)=>{
|
||||
setSearchWord(e || '')
|
||||
}
|
||||
@@ -90,7 +95,7 @@ const MemberPage = ()=>{
|
||||
case 'addChild':
|
||||
return AddChildRef.current?.save().then((res)=>{if(res === true)getDepartmentList()})
|
||||
case 'addMember':
|
||||
return AddMemberRef.current?.save().then((res)=>{if(res === true){getDepartmentList();setRefreshMemberCount(pre=>pre+1)}})
|
||||
return AddMemberRef.current?.save().then((res)=>{if(res === true){getDepartmentList();setRefreshMemberCount(pre=>pre+1);refreshMemberTable()}})
|
||||
case 'rename':
|
||||
return RenameRef.current?.save().then((res)=>{if(res === true)getDepartmentList()})
|
||||
case 'delete':
|
||||
@@ -262,7 +267,7 @@ const MemberPage = ()=>{
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 p-btnbase pr-PAGE_INSIDE_X overflow-x-hidden">
|
||||
<Outlet context={{refreshMemberCount, selectedDepartmentIds,refreshGroup:()=>getDepartmentList()}}/>
|
||||
<Outlet context={{refreshMemberCount, selectedDepartmentIds,refreshGroup:()=>getDepartmentList(), refreshTableCount}}/>
|
||||
</div>
|
||||
</div>
|
||||
</InsidePage>);
|
||||
|
||||
+15
-11
@@ -128,17 +128,19 @@ func (i *imlProviderModelModule) DeleteProviderModel(ctx *gin.Context, provider
|
||||
if err := i.providerModelService.Delete(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
err = i.syncGateway(ctx, cluster.DefaultClusterID, []*gateway.DynamicRelease{
|
||||
{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: fmt.Sprintf("%s#%s", provider, modelInfo.Name),
|
||||
Resource: "ai-model",
|
||||
if p.GetModelConfig().AccessConfigurationStatus {
|
||||
err = i.syncGateway(ctx, cluster.DefaultClusterID, []*gateway.DynamicRelease{
|
||||
{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: fmt.Sprintf("%s$%s", provider, modelInfo.Name),
|
||||
Resource: "ai-model",
|
||||
},
|
||||
Attr: nil,
|
||||
},
|
||||
Attr: nil,
|
||||
},
|
||||
}, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
p.RemoveModel(id)
|
||||
@@ -200,7 +202,9 @@ func (i *imlProviderModelModule) AddProviderModel(ctx *gin.Context, provider str
|
||||
}
|
||||
|
||||
func newModel(provider string, model string, config string) *gateway.DynamicRelease {
|
||||
|
||||
if config == "" {
|
||||
config = "{}"
|
||||
}
|
||||
return &gateway.DynamicRelease{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: fmt.Sprintf("%s$%s", provider, model),
|
||||
|
||||
+38
-26
@@ -185,6 +185,41 @@ func (i *imlPublishModule) getProjectRelease(ctx context.Context, projectID stri
|
||||
Id: projectID,
|
||||
Version: version,
|
||||
}
|
||||
upstreamProxyHeaders := make([]*gateway.ProxyHeader, 0)
|
||||
var upstreamRelease *gateway.UpstreamRelease
|
||||
if len(upstreamCommitIds) > 0 {
|
||||
upstreamCommits, err := i.upstreamService.ListCommit(ctx, upstreamCommitIds...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, c := range upstreamCommits {
|
||||
upstreamRelease = &gateway.UpstreamRelease{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: c.Target,
|
||||
Version: version,
|
||||
MatchLabels: map[string]string{
|
||||
"serviceId": projectID,
|
||||
},
|
||||
},
|
||||
PassHost: c.Data.PassHost,
|
||||
Scheme: c.Data.Scheme,
|
||||
Balance: c.Data.Balance,
|
||||
Timeout: c.Data.Timeout,
|
||||
Nodes: utils.SliceToSlice(c.Data.Nodes, func(n *upstream.NodeConfig) string {
|
||||
return fmt.Sprintf("%s weight=%d", n.Address, n.Weight)
|
||||
}),
|
||||
}
|
||||
|
||||
upstreamProxyHeaders = utils.SliceToSlice(c.Data.ProxyHeaders, func(n *upstream.ProxyHeader) *gateway.ProxyHeader {
|
||||
return &gateway.ProxyHeader{
|
||||
Key: n.Key,
|
||||
Value: n.Value,
|
||||
Opt: n.OptType,
|
||||
}
|
||||
})
|
||||
}
|
||||
r.Upstream = upstreamRelease
|
||||
}
|
||||
apis := make([]*gateway.ApiRelease, 0, len(apiInfos))
|
||||
hasUpstream := len(upstreamCommitIds) > 0
|
||||
for _, a := range apiInfos {
|
||||
@@ -221,38 +256,15 @@ func (i *imlPublishModule) getProjectRelease(ctx context.Context, projectID stri
|
||||
Opt: h.OptType,
|
||||
}
|
||||
})
|
||||
apiInfo.ProxyHeaders = append(apiInfo.ProxyHeaders, upstreamProxyHeaders...)
|
||||
|
||||
apiInfo.Retry = proxy.Retry
|
||||
apiInfo.Timeout = proxy.Timeout
|
||||
}
|
||||
apis = append(apis, apiInfo)
|
||||
}
|
||||
r.Apis = apis
|
||||
var upstreamRelease *gateway.UpstreamRelease
|
||||
if len(upstreamCommitIds) > 0 {
|
||||
upstreamCommits, err := i.upstreamService.ListCommit(ctx, upstreamCommitIds...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, c := range upstreamCommits {
|
||||
upstreamRelease = &gateway.UpstreamRelease{
|
||||
BasicItem: &gateway.BasicItem{
|
||||
ID: c.Target,
|
||||
Version: version,
|
||||
MatchLabels: map[string]string{
|
||||
"serviceId": projectID,
|
||||
},
|
||||
},
|
||||
PassHost: c.Data.PassHost,
|
||||
Scheme: c.Data.Scheme,
|
||||
Balance: c.Data.Balance,
|
||||
Timeout: c.Data.Timeout,
|
||||
Nodes: utils.SliceToSlice(c.Data.Nodes, func(n *upstream.NodeConfig) string {
|
||||
return fmt.Sprintf("%s weight=%d", n.Address, n.Weight)
|
||||
}),
|
||||
}
|
||||
}
|
||||
r.Upstream = upstreamRelease
|
||||
}
|
||||
|
||||
if len(strategyCommitIds) > 0 {
|
||||
strategyCommits, err := i.strategyService.ListStrategyCommit(ctx, strategyCommitIds...)
|
||||
if err != nil {
|
||||
|
||||
@@ -202,6 +202,16 @@ curl -sSO https://download.apipark.com/install/quick-start.sh; bash quick-start.
|
||||
|
||||
# 📕文档
|
||||
访问 [APIPark文档](https://docs.apipark.com/docs/deploy) 获取详细的安装指南、API 参考和使用说明。
|
||||
<br>
|
||||
|
||||
|
||||
|
||||
友情链接
|
||||
<a href="https://xroute.ai/">
|
||||
|
||||
<img width="1248" height="158" alt="新建 PPTX 演示文稿 (2)_02(1)" src="https://github.com/user-attachments/assets/3e1cd0c1-c4c3-4f0c-8649-810d76f3166b" />
|
||||
|
||||
</a>
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ echo "login qiniu..."
|
||||
qshell account ${AccessKey} ${SecretKey} ${QINIU_NAME}
|
||||
|
||||
echo "qshell rput ${QINIU_BUCKET} \"${APP}/images/${Tar}\" ${Tar}"
|
||||
qshell rput ${QINIU_BUCKET} "${APP}/images/${Tar}" ${Tar}
|
||||
qshell rput --overwrite ${QINIU_BUCKET} "${APP}/images/${Tar}" ${Tar}
|
||||
|
||||
rm -f ${Tar}
|
||||
docker rmi -f ${ImageName}:${Version}
|
||||
Reference in New Issue
Block a user