You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
3.3 KiB
91 lines
3.3 KiB
package user
|
|
|
|
import (
|
|
"os"
|
|
"sort"
|
|
|
|
"yunyan/comm"
|
|
"yunyan/lego/sys/log"
|
|
"yunyan/lego/sys/postgres"
|
|
"yunyan/pb"
|
|
)
|
|
|
|
// 第三方服务下发的解析口径(v2 的 user_getthirdsvcs_v2 与 v3 的 user_getappconfig_v3 共用一份,
|
|
// 两个接口的下发内容必须完全一致,否则客户端换接口就会拿到不一样的配置)。
|
|
//
|
|
// - 作用域:本应用行覆盖全局行(app_name=<app> 优先于 app_name='')。
|
|
// - 区域:按调用方解析出的用户区域合并 svc_region_override(值覆盖 / 区域专属字段 / 停用字段)。
|
|
// - 凭据:encrypted 字段用 ${FIELD_ENCRYPT_KEY} 解密为明文;解不开的服务整条跳过(fail-closed,
|
|
// 密文当明文用会在客户端深处炸成不可理解的错误)。
|
|
// - MCP 服务同在 svc_config 里(categories 含 comm.SvcCatMCP),随本函数一并下发,
|
|
// url/type/tools 就在 fields 中——v3 因此不再单独下发 mcps。
|
|
//
|
|
// 响应整体由网关 AES-CBC 加密(apiV2Comp/apiV3Comp 的 EncryptMsgs),故 fields 内不再逐个加密。
|
|
|
|
// resolveThirdSvcs 解析某应用在指定区域下应下发的第三方服务列表。
|
|
// ids 非空时只取这些服务 id;返回结果按 id 升序,便于客户端 diff。
|
|
func resolveThirdSvcs(app string, region pb.Region, ids []string) ([]*pb.ThirdSvcItem, error) {
|
|
encKey := os.Getenv("FIELD_ENCRYPT_KEY")
|
|
|
|
// 本应用作用域链上的服务行(应用行 + 全局行),可按 ids 过滤。
|
|
svcs := make([]*comm.ThirdSvcConfig, 0)
|
|
query := "(app_name=? OR app_name='')"
|
|
args := []interface{}{app}
|
|
if len(ids) > 0 {
|
|
query += " AND id IN ?"
|
|
args = append(args, ids)
|
|
}
|
|
if err := postgres.Find(comm.TableSvcConfig, &svcs, query, args...); err != nil && err != postgres.ErrNoDocuments {
|
|
return nil, err
|
|
}
|
|
|
|
// 同 id 应用行覆盖全局行;仅启用的(与 echomeet 编排解析同语义:应用行停用则回退全局行)。
|
|
picked := map[string]*comm.ThirdSvcConfig{}
|
|
svcIds := make([]string, 0, len(svcs))
|
|
for _, s := range svcs {
|
|
if !s.Enable {
|
|
continue
|
|
}
|
|
if exist, ok := picked[s.Id]; !ok || (exist.AppName == "" && s.AppName == app && app != "") {
|
|
if _, ok := picked[s.Id]; !ok {
|
|
svcIds = append(svcIds, s.Id)
|
|
}
|
|
picked[s.Id] = s
|
|
}
|
|
}
|
|
|
|
// 区域字段覆盖:按服务行自身的作用域 + 用户区域匹配。
|
|
ovrs := make([]*comm.SvcRegionOverride, 0)
|
|
if len(svcIds) > 0 && region != 0 {
|
|
if err := postgres.Find(comm.TableSvcRegionOverride, &ovrs,
|
|
"(app_name=? OR app_name='') AND svc_id IN ? AND region=?", app, svcIds, int32(region)); err != nil && err != postgres.ErrNoDocuments {
|
|
return nil, err
|
|
}
|
|
}
|
|
ovrOf := func(svc *comm.ThirdSvcConfig) *comm.SvcRegionOverride {
|
|
for _, o := range ovrs {
|
|
if o.SvcId == svc.Id && o.AppName == svc.AppName {
|
|
return o
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
items := make([]*pb.ThirdSvcItem, 0, len(picked))
|
|
for _, svc := range picked {
|
|
fields, err := comm.ResolveSvcPlainFields(svc, ovrOf(svc), encKey)
|
|
if err != nil {
|
|
log.Warnf("第三方服务下发: 服务 %s 字段解析失败已跳过: %v", svc.Id, err)
|
|
continue
|
|
}
|
|
items = append(items, &pb.ThirdSvcItem{
|
|
Id: svc.Id,
|
|
Name: svc.Name,
|
|
Provider: svc.Provider,
|
|
Categories: svc.Categories,
|
|
Fields: fields,
|
|
})
|
|
}
|
|
sort.Slice(items, func(i, j int) bool { return items[i].Id < items[j].Id })
|
|
return items, nil
|
|
}
|
|
|