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.
218 lines
6.5 KiB
218 lines
6.5 KiB
package console
|
|
|
|
import (
|
|
"strings"
|
|
"time"
|
|
|
|
"yunyan/comm"
|
|
"yunyan/pb"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// ============================ 会议记录服务配置 (echomeetsvc) ============================
|
|
//
|
|
// admin「会议记录服务配置」页的后端:读写**应用业务库**里的 echomeet_svc_config 表
|
|
// (识别/翻译/总结三类,各自按优先级;识别可配支持语言;总结为具体模型条目)。全局一份、无 app_name。
|
|
//
|
|
// 业务库连接按部署 appId 从 registry 动态取(与 modulecfg 同机制);
|
|
// 密钥字段(是否密钥以 comm.EchoSvcCatalog 为准)AES-GCM 加密落库、返回前端脱敏为 comm.EncMask。
|
|
// 改配置后广播 ConfigKindEchomeetSvc;home 侧 echomeet 改配置需重启生效。
|
|
|
|
// echoSvcCatalog 返回会议记录服务字段目录(前端据此渲染各服务商表单、识别语言选择器)。与选中应用无关。
|
|
func (this *serverComp) echoSvcCatalog(c *gin.Context) {
|
|
writeOK(c, gin.H{
|
|
"catalog": comm.EchoSvcCatalog,
|
|
"categories": []gin.H{
|
|
{"value": comm.EchoSvcCatASR, "label": "识别"},
|
|
{"value": comm.EchoSvcCatMT, "label": "翻译"},
|
|
{"value": comm.EchoSvcCatLLM, "label": "总结"},
|
|
},
|
|
})
|
|
}
|
|
|
|
// echoSvcList 列出某部署业务库里的会议记录服务配置;密钥脱敏。
|
|
func (this *serverComp) echoSvcList(c *gin.Context) {
|
|
var req struct {
|
|
AppId uint32 `json:"app_id"`
|
|
}
|
|
_ = c.ShouldBindJSON(&req)
|
|
if req.AppId == 0 {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "app_id 必填")
|
|
return
|
|
}
|
|
db, err := this.module.registry.getServiceDB(req.AppId)
|
|
if err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, "连接应用业务库失败: "+err.Error())
|
|
return
|
|
}
|
|
if err := comm.EnsureEchoSvcTable(db); err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, err.Error())
|
|
return
|
|
}
|
|
rows, err := comm.LoadEchoSvcConfigs(db)
|
|
if err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, err.Error())
|
|
return
|
|
}
|
|
for _, r := range rows {
|
|
r.Values = comm.MaskEchoValues(r.Category, r.Provider, r.Values)
|
|
}
|
|
writeOK(c, gin.H{"items": rows})
|
|
}
|
|
|
|
// echoSvcSave 保存单条服务配置:新增/更新(按 id)。
|
|
// 是否密钥以目录为准(不信前端);密钥字段回传占位/空则保留原密文,否则加密新明文;目录外的键忽略。
|
|
func (this *serverComp) echoSvcSave(c *gin.Context) {
|
|
var req struct {
|
|
AppId uint32 `json:"app_id"`
|
|
Config comm.EchoSvcConfig `json:"config"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, err.Error())
|
|
return
|
|
}
|
|
cfg := req.Config
|
|
cfg.Id = strings.TrimSpace(cfg.Id)
|
|
cfg.Provider = strings.TrimSpace(cfg.Provider)
|
|
if req.AppId == 0 || cfg.Id == "" {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "app_id 与 id 必填")
|
|
return
|
|
}
|
|
def := comm.FindEchoSvcDef(cfg.Category, cfg.Provider)
|
|
if def == nil {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "未知的服务类别/服务商组合")
|
|
return
|
|
}
|
|
db, err := this.module.registry.getServiceDB(req.AppId)
|
|
if err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, "连接应用业务库失败: "+err.Error())
|
|
return
|
|
}
|
|
if err := comm.EnsureEchoSvcTable(db); err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, err.Error())
|
|
return
|
|
}
|
|
|
|
// 取旧行以保留密钥密文。
|
|
old := &comm.EchoSvcConfig{}
|
|
hasOld := db.FindOne(comm.TableEchomeetSvcConfig, old, "id=?", cfg.Id) == nil && old.Id != ""
|
|
|
|
// 合法字段过滤 + 密钥处理。
|
|
allowed := make(map[string]bool, len(def.Fields))
|
|
for _, f := range def.Fields {
|
|
allowed[f.Key] = true
|
|
}
|
|
encKey := this.options.EncryptKey
|
|
stored := make(map[string]string, len(cfg.Values))
|
|
for k, v := range cfg.Values {
|
|
if !allowed[k] {
|
|
continue
|
|
}
|
|
if comm.EchoSvcFieldIsSecret(cfg.Category, cfg.Provider, k) {
|
|
if v == "" || v == comm.EncMask {
|
|
if hasOld {
|
|
stored[k] = old.Values[k] // 保留原密文
|
|
}
|
|
continue
|
|
}
|
|
ct, ee := comm.Encrypt(encKey, v)
|
|
if ee != nil {
|
|
writeErr(c, pb.ErrorCode_SystemError, "加密失败: "+ee.Error())
|
|
return
|
|
}
|
|
stored[k] = ct
|
|
continue
|
|
}
|
|
stored[k] = v
|
|
}
|
|
cfg.Values = stored
|
|
|
|
now := time.Now().Unix()
|
|
cfg.Updatetime = now
|
|
if hasOld {
|
|
cfg.Createtime = old.Createtime
|
|
if e := db.Save(comm.TableEchomeetSvcConfig, &cfg); e != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, e.Error())
|
|
return
|
|
}
|
|
} else {
|
|
cfg.Createtime = now
|
|
if e := db.Insert(comm.TableEchomeetSvcConfig, &cfg); e != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, e.Error())
|
|
return
|
|
}
|
|
}
|
|
broadcastConfigChanged(comm.ConfigKindEchomeetSvc, "update", 0)
|
|
writeOK(c, gin.H{"id": cfg.Id})
|
|
}
|
|
|
|
// echoSvcDel 删除一条服务配置。
|
|
func (this *serverComp) echoSvcDel(c *gin.Context) {
|
|
var req struct {
|
|
AppId uint32 `json:"app_id"`
|
|
Id string `json:"id"`
|
|
}
|
|
_ = c.ShouldBindJSON(&req)
|
|
req.Id = strings.TrimSpace(req.Id)
|
|
if req.AppId == 0 || req.Id == "" {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "app_id 与 id 必填")
|
|
return
|
|
}
|
|
db, err := this.module.registry.getServiceDB(req.AppId)
|
|
if err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, "连接应用业务库失败: "+err.Error())
|
|
return
|
|
}
|
|
if err := db.Delete(comm.TableEchomeetSvcConfig, "id=?", req.Id); err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, err.Error())
|
|
return
|
|
}
|
|
broadcastConfigChanged(comm.ConfigKindEchomeetSvc, "delete", 0)
|
|
writeOK(c, gin.H{"deleted": req.Id})
|
|
}
|
|
|
|
// echoSvcReorder 批量调整同类内优先级(拖拽排序后提交)。
|
|
func (this *serverComp) echoSvcReorder(c *gin.Context) {
|
|
var req struct {
|
|
AppId uint32 `json:"app_id"`
|
|
Items []struct {
|
|
Id string `json:"id"`
|
|
Priority int32 `json:"priority"`
|
|
} `json:"items"`
|
|
}
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, err.Error())
|
|
return
|
|
}
|
|
if req.AppId == 0 {
|
|
writeErr(c, pb.ErrorCode_ReqParameterError, "app_id 必填")
|
|
return
|
|
}
|
|
db, err := this.module.registry.getServiceDB(req.AppId)
|
|
if err != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, "连接应用业务库失败: "+err.Error())
|
|
return
|
|
}
|
|
now := time.Now().Unix()
|
|
updated := 0
|
|
for _, it := range req.Items {
|
|
id := strings.TrimSpace(it.Id)
|
|
if id == "" {
|
|
continue
|
|
}
|
|
row := &comm.EchoSvcConfig{}
|
|
if e := db.FindOne(comm.TableEchomeetSvcConfig, row, "id=?", id); e != nil || row.Id == "" {
|
|
continue
|
|
}
|
|
row.Priority = it.Priority
|
|
row.Updatetime = now
|
|
if e := db.Save(comm.TableEchomeetSvcConfig, row); e != nil {
|
|
writeErr(c, pb.ErrorCode_DBError, e.Error())
|
|
return
|
|
}
|
|
updated++
|
|
}
|
|
broadcastConfigChanged(comm.ConfigKindEchomeetSvc, "update", 0)
|
|
writeOK(c, gin.H{"updated": updated})
|
|
}
|
|
|