作者 yangfu

初始化

正在显示 74 个修改的文件 包含 4756 行增加0 行删除

要显示太多修改。

为保证性能只显示 74 of 74+ 个文件。

  1 +.git*
  2 +.idea*
  1 +# Compiled Object codefiles, Static and Dynamic libs (Shared Objects)
  2 +*.o
  3 +*.a
  4 +*.so
  5 +
  6 +# Folders
  7 +_obj
  8 +_test
  9 +
  10 +# Architecture specific extensions/prefixes
  11 +*.[568vq]
  12 +[568vq].out
  13 +
  14 +*.cgo1.go
  15 +*.cgo2.c
  16 +_cgo_defun.c
  17 +_cgo_gotypes.go
  18 +_cgo_export.*
  19 +
  20 +_testmain.go
  21 +
  22 +*.exe
  23 +*.test
  24 +.log
  25 +.idea
  26 +.vscode
  27 +.gitkeep
  28 +
  29 +app.log
  30 +go.sum
  31 +lastupdate.tmp
  32 +*.log
  33 +
  34 +public/
  35 +logs/
  36 +cmd/discuss/api/etc/core.local.yaml
  1 +# Su Enterprise System Module(素天下企业平台系统模块)
  2 +
  3 +## 功能简介
  4 +
  5 +企业平台系统模块包含模块,用户管理、应用管理、组织架构设置、通知公告、系统设置、系统日志
  1 +.PHONY: model
  2 +model:
  3 + goctl model mysql ddl -s .\cmd\ep\chat\deploy\database\table.sql -d cmd/ep/chat
  4 +
  5 +.PHONY: api
  6 +api:
  7 + goctl api go -api .\cmd\ep\chat\dsl\core.api -dir cmd/ep/chat/api -style go_zero
  8 +
  9 +.PHONY: swagger
  10 +swagger:
  11 + goctl api plugin -plugin goctl-swagger="swagger -filename core.json" -api .\cmd\ep\chat\dsl\core.api -dir .\cmd\ep\chat\generate
  12 +
  13 +.PHONY: build
  14 +build:
  15 + docker build -f cmd/ep/chat/deploy/docker/Dockerfile -t sumicro/chat:1.0.0 .
  1 +package main
  2 +
  3 +import (
  4 + "flag"
  5 + "fmt"
  6 + "github.com/zeromicro/go-zero/core/logx"
  7 + "github.com/zeromicro/go-zero/rest/httpx"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/db"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  11 + "net/http"
  12 +
  13 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/config"
  14 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/handler"
  15 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  16 +
  17 + "github.com/zeromicro/go-zero/core/conf"
  18 + "github.com/zeromicro/go-zero/rest"
  19 +)
  20 +
  21 +var configFile = flag.String("f", "etc/core.yaml", "the config file")
  22 +
  23 +func main() {
  24 + flag.Parse()
  25 +
  26 + var c config.Config
  27 + conf.MustLoad(*configFile, &c)
  28 +
  29 + // 系统设置
  30 + systemSetup(c)
  31 +
  32 + // 服务初始化
  33 + opts := make([]rest.RunOption, 0)
  34 + opts = append(opts, rest.WithCustomCors(func(header http.Header) {
  35 + header.Set("Access-Control-Allow-Headers", "*")
  36 + }, func(writer http.ResponseWriter) {
  37 +
  38 + }))
  39 + opts = append(opts, rest.WithUnauthorizedCallback(func(w http.ResponseWriter, r *http.Request, err error) {
  40 + if err != nil {
  41 + logx.Debugf("unauthorized: %s \n", err.Error())
  42 + }
  43 + httpx.WriteJson(w, http.StatusUnauthorized, xerr.Error(xerr.TokenExpireError, err.Error()))
  44 + return
  45 + }))
  46 +
  47 + server := rest.MustNewServer(c.RestConf, opts...)
  48 + defer server.Stop()
  49 +
  50 + ctx := svc.NewServiceContext(c)
  51 + handler.RegisterHandlers(server, ctx)
  52 +
  53 + // 数据迁移
  54 + if c.Migrate {
  55 + db.Migrate(ctx.DB)
  56 + }
  57 +
  58 + fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
  59 + server.Start()
  60 +}
  61 +
  62 +func systemSetup(c config.Config) {
  63 + // 初始化Domain里面的配置
  64 + domain.ProjectName = c.Name
  65 +
  66 + // 系统错误应答包装
  67 + httpx.SetErrorHandlerCtx(xerr.ErrorHandlerCtx)
  68 +
  69 + // 系统成功应答包装
  70 + httpx.SetOkHandler(xerr.OkHandlerCtx)
  71 +}
  1 +Name: sumicro-chat
  2 +Host: 0.0.0.0
  3 +Port: 8080
  4 +
  5 +Verbose: false
  6 +Migrate: true
  7 +Timeout: 30000
  8 +LogRequest: true # 记录详细请求日志
  9 +
  10 +Log:
  11 + #Mode: file
  12 + Encoding: plain
  13 + Level: debug # info
  14 + MaxSize: 1 # 2MB
  15 + TimeFormat: 2006-01-02 15:04:05
  16 + Rotation: size
  17 + MaxContentLength: 10240
  18 +
  19 +SystemAuth:
  20 + AccessSecret: su-platform
  21 + AccessExpire: 360000
  22 +
  23 +Redis:
  24 + Host: 127.0.0.1:6379
  25 + Type: node
  26 + Pass:
  27 +DB:
  28 + DataSource: host=114.55.200.59 user=postgres password=eagle1010 dbname=su_enterprise_platform port=31543 sslmode=disable TimeZone=Asia/Shanghai
  29 +
  1 +package config
  2 +
  3 +import (
  4 + "github.com/zeromicro/go-zero/core/stores/redis"
  5 + "github.com/zeromicro/go-zero/rest"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/config"
  7 +)
  8 +
  9 +type Config struct {
  10 + rest.RestConf
  11 + config.Config
  12 + Redis redis.RedisConf `json:",optional"`
  13 + SystemAuth config.Auth
  14 +}
  1 +package chat
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/logic/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +)
  11 +
  12 +func ChatModelsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.ChatModelsRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := chat.NewChatModelsLogic(r.Context(), svcCtx)
  21 + resp, err := l.ChatModels(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package chat
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/logic/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +)
  11 +
  12 +func ChatSessionConversationHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.ChatSessionConversationRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := chat.NewChatSessionConversationLogic(r.Context(), svcCtx)
  21 + resp, err := l.ChatSessionConversation(w, r, &req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package chat
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/logic/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +)
  11 +
  12 +func ChatSessionConversationWsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.ChatSessionConversationRequestWs
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := chat.NewChatSessionConversationWsLogic(r.Context(), svcCtx)
  21 + resp, err := l.ChatSessionConversationWs(w, r, &req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package chat
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/logic/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +)
  11 +
  12 +func ChatSessionDeleteHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.ChatSessionDeleteRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := chat.NewChatSessionDeleteLogic(r.Context(), svcCtx)
  21 + resp, err := l.ChatSessionDelete(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package chat
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/logic/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +)
  11 +
  12 +func ChatSessionGetHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.ChatSessionGetRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := chat.NewChatSessionGetLogic(r.Context(), svcCtx)
  21 + resp, err := l.ChatSessionGet(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package chat
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/logic/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +)
  11 +
  12 +func ChatSessionRecordsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.ChatSessionRecordsRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := chat.NewChatSessionRecordsLogic(r.Context(), svcCtx)
  21 + resp, err := l.ChatSessionRecords(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package chat
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/logic/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +)
  11 +
  12 +func ChatSessionSaveHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.ChatSessionSaveRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := chat.NewChatSessionSaveLogic(r.Context(), svcCtx)
  21 + resp, err := l.ChatSessionSave(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package chat
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/logic/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +)
  11 +
  12 +func ChatSessionSearchHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.ChatSessionSearchRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := chat.NewChatSessionSearchLogic(r.Context(), svcCtx)
  21 + resp, err := l.ChatSessionSearch(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package chat
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/logic/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +)
  11 +
  12 +func ChatSessionUpdateHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.ChatSessionUpdateRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := chat.NewChatSessionUpdateLogic(r.Context(), svcCtx)
  21 + resp, err := l.ChatSessionUpdate(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +// Code generated by goctl. DO NOT EDIT.
  2 +package handler
  3 +
  4 +import (
  5 + "net/http"
  6 +
  7 + chat "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/handler/chat"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 +
  10 + "github.com/zeromicro/go-zero/rest"
  11 +)
  12 +
  13 +func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
  14 + server.AddRoutes(
  15 + rest.WithMiddlewares(
  16 + []rest.Middleware{serverCtx.LogRequest},
  17 + []rest.Route{
  18 + {
  19 + Method: http.MethodGet,
  20 + Path: "/chat/session/:id",
  21 + Handler: chat.ChatSessionGetHandler(serverCtx),
  22 + },
  23 + {
  24 + Method: http.MethodPost,
  25 + Path: "/chat/session",
  26 + Handler: chat.ChatSessionSaveHandler(serverCtx),
  27 + },
  28 + {
  29 + Method: http.MethodDelete,
  30 + Path: "/chat/session/:id",
  31 + Handler: chat.ChatSessionDeleteHandler(serverCtx),
  32 + },
  33 + {
  34 + Method: http.MethodPut,
  35 + Path: "/chat/session/:id",
  36 + Handler: chat.ChatSessionUpdateHandler(serverCtx),
  37 + },
  38 + {
  39 + Method: http.MethodPost,
  40 + Path: "/chat/session/search",
  41 + Handler: chat.ChatSessionSearchHandler(serverCtx),
  42 + },
  43 + {
  44 + Method: http.MethodPost,
  45 + Path: "/chat/session/conversation",
  46 + Handler: chat.ChatSessionConversationHandler(serverCtx),
  47 + },
  48 + {
  49 + Method: http.MethodGet,
  50 + Path: "/chat/session/conversation",
  51 + Handler: chat.ChatSessionConversationWsHandler(serverCtx),
  52 + },
  53 + {
  54 + Method: http.MethodPost,
  55 + Path: "/chat/session/records",
  56 + Handler: chat.ChatSessionRecordsHandler(serverCtx),
  57 + },
  58 + {
  59 + Method: http.MethodGet,
  60 + Path: "/chat/models",
  61 + Handler: chat.ChatModelsHandler(serverCtx),
  62 + },
  63 + }...,
  64 + ),
  65 + rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret),
  66 + rest.WithPrefix("/v1"),
  67 + )
  68 +}
  1 +package chat
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/samber/lo"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  7 +
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +
  11 + "github.com/zeromicro/go-zero/core/logx"
  12 +)
  13 +
  14 +type ChatModelsLogic struct {
  15 + logx.Logger
  16 + ctx context.Context
  17 + svcCtx *svc.ServiceContext
  18 +}
  19 +
  20 +func NewChatModelsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatModelsLogic {
  21 + return &ChatModelsLogic{
  22 + Logger: logx.WithContext(ctx),
  23 + ctx: ctx,
  24 + svcCtx: svcCtx,
  25 + }
  26 +}
  27 +
  28 +func (l *ChatModelsLogic) ChatModels(req *types.ChatModelsRequest) (resp *types.ChatModelsResponse, err error) {
  29 + var models = make([]types.Model, 0)
  30 + lo.ForEach(domain.DefaultChatModels, func(item *domain.ChatModel, index int) {
  31 + models = append(models, types.Model{
  32 + Id: item.Id,
  33 + Name: item.Name,
  34 + Logo: item.Logo,
  35 + Code: item.Code,
  36 + })
  37 + })
  38 + resp = &types.ChatModelsResponse{
  39 + List: models,
  40 + }
  41 + return
  42 +}
  1 +package chat
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/open"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/ai"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  11 + "net/http"
  12 + "time"
  13 +
  14 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  15 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  16 +
  17 + "github.com/zeromicro/go-zero/core/logx"
  18 +)
  19 +
  20 +type ChatSessionConversationLogic struct {
  21 + logx.Logger
  22 + ctx context.Context
  23 + svcCtx *svc.ServiceContext
  24 +}
  25 +
  26 +func NewChatSessionConversationLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatSessionConversationLogic {
  27 + return &ChatSessionConversationLogic{
  28 + Logger: logx.WithContext(ctx),
  29 + ctx: ctx,
  30 + svcCtx: svcCtx,
  31 + }
  32 +}
  33 +
  34 +func (l *ChatSessionConversationLogic) ChatSessionConversation(w http.ResponseWriter, r *http.Request, req *types.ChatSessionConversationRequest) (resp *types.ChatSessionConversationResponse, err error) {
  35 + var (
  36 + conn = l.svcCtx.DefaultDBConn()
  37 + dm *domain.ChatSessionRecord
  38 + token = contextdata.GetUserTokenFromCtx(l.ctx)
  39 + session *domain.ChatSession
  40 + user open.User
  41 + model *domain.ChatModel
  42 + ok bool
  43 + beginUnix = time.Now().UnixMilli()
  44 + )
  45 + if session, err = l.svcCtx.ChatSessionRepository.FindOne(l.ctx, conn, req.SessionId); err != nil {
  46 + return nil, xerr.NewErrMsgErr("会话不存在", err)
  47 + }
  48 + if user, err = l.svcCtx.SystemOpen.User(l.ctx, conn, token.UserId); err != nil {
  49 + return nil, xerr.NewErrMsgErr("用户不存在", err)
  50 + }
  51 + if user.Id != session.UserId {
  52 + return nil, xerr.NewErrMsgErr("无权限", err)
  53 + }
  54 + if model, ok = domain.DefaultChatModels.Match(req.ModelId); !ok {
  55 + return nil, xerr.NewErrMsgErr("模型不存在", err)
  56 + }
  57 + dm = &domain.ChatSessionRecord{
  58 + CompanyId: token.CompanyId,
  59 + UserId: token.UserId,
  60 + SessionId: req.SessionId,
  61 + ModelId: req.ModelId,
  62 + Author: NewDomainUser(user),
  63 + ContentType: req.ContentType,
  64 + ProblemText: req.Text,
  65 + Metadata: domain.Metadata{},
  66 + Cost: 0,
  67 + Status: domain.Processing,
  68 + }
  69 + var answer string
  70 + var channel = make(chan string, 5)
  71 + // 异步访问AI接口
  72 + go func() {
  73 + // 异步访问AI接口
  74 + answer, err = Conversation(model, req.Text, channel)
  75 + }()
  76 + for {
  77 + if _, ok = <-channel; !ok {
  78 + break
  79 + }
  80 + }
  81 + if err != nil {
  82 + return nil, xerr.NewErrMsgErr("AI模型异常,稍后再试", err)
  83 + }
  84 +
  85 + // 记录
  86 + dm.AnswerText = answer
  87 + dm.Cost = time.Now().UnixMilli() - beginUnix
  88 + dm.Status = domain.FinishedSuccess
  89 + if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  90 + dm, err = l.svcCtx.ChatSessionRecordRepository.Insert(l.ctx, conn, dm)
  91 + return err
  92 + }, true); err != nil {
  93 + return nil, xerr.NewErrMsg("保存失败")
  94 + }
  95 + record := NewTypesChatRecord(dm, user)
  96 + resp = &types.ChatSessionConversationResponse{
  97 + Record: &record,
  98 + Parts: make([]string, 0),
  99 + Finished: true,
  100 + }
  101 + return
  102 +}
  103 +
  104 +func Conversation(m *domain.ChatModel, text string, channel chan string) (answer string, err error) {
  105 +
  106 + switch m.Id {
  107 + // 星火3.5
  108 + case 1, 2, 3:
  109 + answer, err = ai.ChatGPT(m.Code, m.Config.AppKey, text, channel)
  110 + case 4:
  111 + answer, err = ai.Spark(m.Config.AppId, m.Config.AppKey, m.Config.AppSecret, text, channel)
  112 + }
  113 + if err != nil {
  114 + return "", err
  115 + }
  116 + return
  117 +}
  1 +package chat
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/gorilla/websocket"
  6 + "github.com/zeromicro/go-zero/core/fx"
  7 + "github.com/zeromicro/go-zero/rest/httpx"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/open"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  11 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  12 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  13 + "net/http"
  14 + "time"
  15 +
  16 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  17 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  18 +
  19 + "github.com/zeromicro/go-zero/core/logx"
  20 +)
  21 +
  22 +type ChatSessionConversationWsLogic struct {
  23 + logx.Logger
  24 + ctx context.Context
  25 + svcCtx *svc.ServiceContext
  26 +}
  27 +
  28 +func NewChatSessionConversationWsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatSessionConversationWsLogic {
  29 + return &ChatSessionConversationWsLogic{
  30 + Logger: logx.WithContext(ctx),
  31 + ctx: ctx,
  32 + svcCtx: svcCtx,
  33 + }
  34 +}
  35 +
  36 +func (l *ChatSessionConversationWsLogic) ChatSessionConversationWs(w http.ResponseWriter, r *http.Request, req *types.ChatSessionConversationRequestWs) (resp *types.ChatSessionConversationResponse, err error) {
  37 + var (
  38 + conn = l.svcCtx.DefaultDBConn()
  39 + dm *domain.ChatSessionRecord
  40 + token = contextdata.GetUserTokenFromCtx(l.ctx)
  41 + session *domain.ChatSession
  42 + user open.User
  43 + model *domain.ChatModel
  44 + ok bool
  45 + )
  46 + if session, err = l.svcCtx.ChatSessionRepository.FindOne(l.ctx, conn, req.SessionId); err != nil {
  47 + return nil, xerr.NewErrMsgErr("会话不存在", err)
  48 + }
  49 + if user, err = l.svcCtx.SystemOpen.User(l.ctx, conn, token.UserId); err != nil {
  50 + return nil, xerr.NewErrMsgErr("用户不存在", err)
  51 + }
  52 + if user.Id != session.UserId {
  53 + return nil, xerr.NewErrMsgErr("无权限", err)
  54 + }
  55 + if model, ok = domain.DefaultChatModels.Match(req.ModelId); !ok {
  56 + return nil, xerr.NewErrMsgErr("模型不存在", err)
  57 + }
  58 +
  59 + var answer string
  60 +
  61 + var upgrader = websocket.Upgrader{
  62 + ReadBufferSize: 1024,
  63 + WriteBufferSize: 1024,
  64 + CheckOrigin: func(r *http.Request) bool {
  65 + return true
  66 + },
  67 + }
  68 + var wsconn *websocket.Conn
  69 + wsconn, err = upgrader.Upgrade(w, r, nil)
  70 + if err != nil {
  71 + httpx.ErrorCtx(r.Context(), w, err)
  72 + return
  73 + }
  74 + defer func() {
  75 + wsconn.Close()
  76 + }()
  77 + for {
  78 + var text []byte
  79 + _, text, err = wsconn.ReadMessage()
  80 + if err != nil {
  81 + break
  82 + }
  83 + var beginUnix = time.Now().UnixMilli()
  84 + var channel = make(chan string, 5)
  85 + dm = &domain.ChatSessionRecord{
  86 + CompanyId: token.CompanyId,
  87 + UserId: token.UserId,
  88 + SessionId: req.SessionId,
  89 + ModelId: req.ModelId,
  90 + Author: NewDomainUser(user),
  91 + ContentType: req.ContentType,
  92 + ProblemText: string(text),
  93 + Metadata: domain.Metadata{},
  94 + Cost: 0,
  95 + Status: domain.Processing,
  96 + }
  97 + fx.Parallel(func() {
  98 + // 异步访问AI接口
  99 + answer, err = Conversation(model, string(text), channel)
  100 + }, func() {
  101 + for {
  102 + var v string
  103 + if v, ok = <-channel; ok {
  104 + if err = wsconn.WriteJSON(types.ChatSessionConversationResponse{Parts: []string{v}, Finished: false}); err != nil {
  105 + //httpx.ErrorCtx(r.Context(), w, err)
  106 + dm.Status = domain.FinishedFail
  107 + break
  108 + }
  109 + } else {
  110 + dm.Status = domain.FinishedSuccess
  111 + break
  112 + }
  113 + }
  114 + return
  115 + })
  116 +
  117 + // 记录
  118 + dm.AnswerText = answer
  119 + dm.Cost = time.Now().UnixMilli() - beginUnix
  120 + if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  121 + dm, err = l.svcCtx.ChatSessionRecordRepository.Insert(l.ctx, conn, dm)
  122 + return err
  123 + }, true); err != nil {
  124 + return nil, xerr.NewErrMsg("保存失败")
  125 + }
  126 + record := NewTypesChatRecord(dm, user)
  127 + if err = wsconn.WriteJSON(types.ChatSessionConversationResponse{Record: &record, Finished: true}); err != nil {
  128 + return
  129 + }
  130 + }
  131 +
  132 + if err != nil {
  133 + return nil, xerr.NewErrMsgErr("AI模型异常,稍后再试", err)
  134 + }
  135 + return
  136 +}
  1 +package chat
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  9 +
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  11 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  12 +
  13 + "github.com/zeromicro/go-zero/core/logx"
  14 +)
  15 +
  16 +type ChatSessionDeleteLogic struct {
  17 + logx.Logger
  18 + ctx context.Context
  19 + svcCtx *svc.ServiceContext
  20 +}
  21 +
  22 +func NewChatSessionDeleteLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatSessionDeleteLogic {
  23 + return &ChatSessionDeleteLogic{
  24 + Logger: logx.WithContext(ctx),
  25 + ctx: ctx,
  26 + svcCtx: svcCtx,
  27 + }
  28 +}
  29 +
  30 +func (l *ChatSessionDeleteLogic) ChatSessionDelete(req *types.ChatSessionDeleteRequest) (resp *types.ChatSessionDeleteResponse, err error) {
  31 + var (
  32 + conn = l.svcCtx.DefaultDBConn()
  33 + dm *domain.ChatSession
  34 + token = contextdata.GetUserTokenFromCtx(l.ctx)
  35 + )
  36 + if dm, err = l.svcCtx.ChatSessionRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  37 + return nil, xerr.NewErrMsgErr("不存在", err)
  38 + }
  39 + if dm.UserId != token.UserId {
  40 + return nil, xerr.NewErrMsgErr("无权限", err)
  41 + }
  42 + if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  43 + if dm, err = l.svcCtx.ChatSessionRepository.Delete(l.ctx, conn, dm); err != nil {
  44 + return err
  45 + }
  46 + return nil
  47 + }, true); err != nil {
  48 + return nil, xerr.NewErrMsgErr("移除失败", err)
  49 + }
  50 + return
  51 +}
  1 +package chat
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/samber/lo"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/open"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  10 +
  11 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  12 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  13 +
  14 + "github.com/zeromicro/go-zero/core/logx"
  15 +)
  16 +
  17 +type ChatSessionGetLogic struct {
  18 + logx.Logger
  19 + ctx context.Context
  20 + svcCtx *svc.ServiceContext
  21 +}
  22 +
  23 +func NewChatSessionGetLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatSessionGetLogic {
  24 + return &ChatSessionGetLogic{
  25 + Logger: logx.WithContext(ctx),
  26 + ctx: ctx,
  27 + svcCtx: svcCtx,
  28 + }
  29 +}
  30 +
  31 +func (l *ChatSessionGetLogic) ChatSessionGet(req *types.ChatSessionGetRequest) (resp *types.ChatSessionGetResponse, err error) {
  32 + var (
  33 + conn = l.svcCtx.DefaultDBConn()
  34 + dm *domain.ChatSession
  35 + records []*domain.ChatSessionRecord
  36 + token = contextdata.GetUserTokenFromCtx(l.ctx)
  37 + user open.User
  38 + )
  39 + // 货号唯一
  40 + if dm, err = l.svcCtx.ChatSessionRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  41 + return nil, xerr.NewErrMsgErr("不存在", err)
  42 + }
  43 + if user, err = l.svcCtx.SystemOpen.User(l.ctx, conn, dm.UserId); err != nil {
  44 + return nil, xerr.NewErrMsgErr("用户不存在", err)
  45 + }
  46 + if _, records, err = l.svcCtx.ChatSessionRecordRepository.FindByCompanyUser(l.ctx, conn, token.CompanyId, token.UserId, domain.NewQueryOptions().MustWithKV("sessionId", dm.Id)); err != nil {
  47 + return nil, xerr.NewErr(err)
  48 + }
  49 + var typesRecords []types.Record
  50 + lo.ForEach(records, func(item *domain.ChatSessionRecord, index int) {
  51 + typesRecords = append(typesRecords, NewTypesChatRecord(item, user))
  52 + })
  53 +
  54 + resp = &types.ChatSessionGetResponse{
  55 + ChatSession: NewTypesChatSession(dm),
  56 + Records: typesRecords,
  57 + }
  58 + return
  59 +}
  60 +
  61 +func NewTypesChatRecord(item *domain.ChatSessionRecord, user open.User) types.Record {
  62 + model, ok := domain.DefaultChatModels.Match(item.ModelId)
  63 + var typesModel *types.Model
  64 + if !ok {
  65 + typesModel = &types.Model{}
  66 + } else {
  67 + typesModel = &types.Model{
  68 + Name: model.Name,
  69 + Id: model.Id,
  70 + Logo: model.Logo,
  71 + }
  72 + }
  73 + return types.Record{
  74 + Id: item.Id,
  75 + SessionId: item.SessionId,
  76 + GroupId: item.Group,
  77 + Author: NewTypesUser(user),
  78 + Model: typesModel,
  79 + ContentType: item.ContentType,
  80 + ProblemText: item.ProblemText,
  81 + AnswerText: item.AnswerText,
  82 + Status: item.Status,
  83 + CreateAt: item.CreatedAt,
  84 + }
  85 +}
  86 +
  87 +func NewTypesUser(user open.User) *types.User {
  88 + if user.Id == 0 && user.Name == "" {
  89 + return nil
  90 + }
  91 + return &types.User{
  92 + Id: user.Id,
  93 + Name: user.Name,
  94 + }
  95 +}
  96 +
  97 +func NewDomainUser(user open.User) domain.User {
  98 + if user.Id == 0 && user.Name == "" {
  99 + return domain.User{}
  100 + }
  101 + return domain.User{
  102 + Id: user.Id,
  103 + Name: user.Name,
  104 + }
  105 +}
  1 +package chat
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/samber/lo"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/open"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/tool"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  11 +
  12 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  13 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  14 +
  15 + "github.com/zeromicro/go-zero/core/logx"
  16 +)
  17 +
  18 +type ChatSessionRecordsLogic struct {
  19 + logx.Logger
  20 + ctx context.Context
  21 + svcCtx *svc.ServiceContext
  22 +}
  23 +
  24 +func NewChatSessionRecordsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatSessionRecordsLogic {
  25 + return &ChatSessionRecordsLogic{
  26 + Logger: logx.WithContext(ctx),
  27 + ctx: ctx,
  28 + svcCtx: svcCtx,
  29 + }
  30 +}
  31 +
  32 +func (l *ChatSessionRecordsLogic) ChatSessionRecords(req *types.ChatSessionRecordsRequest) (resp *types.ChatSessionRecordsResponse, err error) {
  33 + var (
  34 + conn = l.svcCtx.DefaultDBConn()
  35 + //chatSession *domain.ChatSession
  36 + records []*domain.ChatSessionRecord
  37 + token = contextdata.GetUserTokenFromCtx(l.ctx)
  38 + user open.User
  39 + total int64
  40 + )
  41 + queryOptions := domain.NewQueryOptions().MustWithKV("sessionId", req.SessionId)
  42 + if req.Page > 0 && req.Size > 0 {
  43 + queryOptions.WithOffsetLimit(req.Page, req.Size)
  44 + }
  45 + if total, records, err = l.svcCtx.ChatSessionRecordRepository.FindByCompanyUser(l.ctx, conn, token.CompanyId, token.UserId, queryOptions); err != nil {
  46 + return nil, xerr.NewErr(err)
  47 + }
  48 + var typesRecords []types.Record
  49 + var lazyUser = tool.NewLazyLoadService(l.svcCtx.SystemOpen.User)
  50 + lo.ForEach(records, func(item *domain.ChatSessionRecord, index int) {
  51 + user, _ = lazyUser.Load(l.ctx, conn, item.UserId)
  52 + typesRecords = append(typesRecords, NewTypesChatRecord(item, user))
  53 + })
  54 + resp = &types.ChatSessionRecordsResponse{
  55 + Records: typesRecords,
  56 + Total: total,
  57 + }
  58 + return
  59 +}
  1 +package chat
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  9 +
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  11 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  12 +
  13 + "github.com/zeromicro/go-zero/core/logx"
  14 +)
  15 +
  16 +type ChatSessionSaveLogic struct {
  17 + logx.Logger
  18 + ctx context.Context
  19 + svcCtx *svc.ServiceContext
  20 +}
  21 +
  22 +func NewChatSessionSaveLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatSessionSaveLogic {
  23 + return &ChatSessionSaveLogic{
  24 + Logger: logx.WithContext(ctx),
  25 + ctx: ctx,
  26 + svcCtx: svcCtx,
  27 + }
  28 +}
  29 +
  30 +func (l *ChatSessionSaveLogic) ChatSessionSave(req *types.ChatSessionSaveRequest) (resp *types.ChatSessionSaveResponse, err error) {
  31 + var (
  32 + dm *domain.ChatSession
  33 + token = contextdata.GetUserTokenFromCtx(l.ctx)
  34 + )
  35 + dm = NewDomainChatSession(token, req.ChatSession)
  36 + if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  37 + dm, err = l.svcCtx.ChatSessionRepository.Insert(l.ctx, conn, dm)
  38 + return err
  39 + }, true); err != nil {
  40 + return nil, xerr.NewErrMsg("保存失败")
  41 + }
  42 + resp = &types.ChatSessionSaveResponse{}
  43 + return
  44 +}
  45 +
  46 +func NewDomainChatSession(token contextdata.UserToken, item types.ChatSessionItem) *domain.ChatSession {
  47 + title := item.Title
  48 + if item.Title == "" {
  49 + title = "新对话窗口"
  50 + }
  51 + return &domain.ChatSession{
  52 + CompanyId: token.CompanyId,
  53 + UserId: token.UserId,
  54 + Title: title,
  55 + Abstract: title,
  56 + }
  57 +}
  58 +
  59 +func NewTypesChatSession(item *domain.ChatSession) types.ChatSessionItem {
  60 + return types.ChatSessionItem{
  61 + Id: item.Id,
  62 + Title: item.Title,
  63 + Abstract: item.Abstract,
  64 + CreatedAt: item.CreatedAt,
  65 + }
  66 +}
  1 +package chat
  2 +
  3 +import (
  4 + "context"
  5 + "fmt"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  7 +
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  10 +
  11 + "github.com/zeromicro/go-zero/core/logx"
  12 +)
  13 +
  14 +type ChatSessionSearchLogic struct {
  15 + logx.Logger
  16 + ctx context.Context
  17 + svcCtx *svc.ServiceContext
  18 +}
  19 +
  20 +func NewChatSessionSearchLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatSessionSearchLogic {
  21 + return &ChatSessionSearchLogic{
  22 + Logger: logx.WithContext(ctx),
  23 + ctx: ctx,
  24 + svcCtx: svcCtx,
  25 + }
  26 +}
  27 +
  28 +func (l *ChatSessionSearchLogic) ChatSessionSearch(req *types.ChatSessionSearchRequest) (resp *types.ChatSessionSearchResponse, err error) {
  29 + var (
  30 + conn = l.svcCtx.DefaultDBConn()
  31 + dms []*domain.ChatSession
  32 + total int64
  33 + )
  34 +
  35 + queryOptions := domain.NewQueryOptions().
  36 + WithKV("title", fmt.Sprintf("%%%v%%", req.Title))
  37 +
  38 + if req.Page != 0 && req.Size != 0 {
  39 + queryOptions.WithOffsetLimit(req.Page, req.Size)
  40 + }
  41 +
  42 + total, dms, err = l.svcCtx.ChatSessionRepository.Find(l.ctx, conn, queryOptions)
  43 + list := make([]types.ChatSessionItem, 0)
  44 + for i := range dms {
  45 + list = append(list, NewTypesChatSession(dms[i]))
  46 + }
  47 + resp = &types.ChatSessionSearchResponse{
  48 + List: list,
  49 + Total: total,
  50 + }
  51 + return
  52 +}
  1 +package chat
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  9 +
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/svc"
  11 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/types"
  12 +
  13 + "github.com/zeromicro/go-zero/core/logx"
  14 +)
  15 +
  16 +type ChatSessionUpdateLogic struct {
  17 + logx.Logger
  18 + ctx context.Context
  19 + svcCtx *svc.ServiceContext
  20 +}
  21 +
  22 +func NewChatSessionUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ChatSessionUpdateLogic {
  23 + return &ChatSessionUpdateLogic{
  24 + Logger: logx.WithContext(ctx),
  25 + ctx: ctx,
  26 + svcCtx: svcCtx,
  27 + }
  28 +}
  29 +
  30 +func (l *ChatSessionUpdateLogic) ChatSessionUpdate(req *types.ChatSessionUpdateRequest) (resp *types.ChatSessionUpdateResponse, err error) {
  31 + var (
  32 + conn = l.svcCtx.DefaultDBConn()
  33 + dm *domain.ChatSession
  34 + token = contextdata.GetUserTokenFromCtx(l.ctx)
  35 + )
  36 + if dm, err = l.svcCtx.ChatSessionRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  37 + return nil, xerr.NewErrMsgErr("不存在", err)
  38 + }
  39 + if dm.UserId != token.UserId {
  40 + return nil, xerr.NewErrMsgErr("无权限", err)
  41 + }
  42 + // 赋值
  43 + dm.Title = req.ChatSession.Title
  44 + dm.Abstract = req.ChatSession.Abstract
  45 +
  46 + // 更新
  47 + if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  48 + dm, err = l.svcCtx.ChatSessionRepository.UpdateWithVersion(l.ctx, conn, dm)
  49 + return err
  50 + }, true); err != nil {
  51 + return nil, xerr.NewErrMsg("更新失败")
  52 + }
  53 + resp = &types.ChatSessionUpdateResponse{}
  54 + return
  55 +}
  1 +package svc
  2 +
  3 +import (
  4 + "github.com/zeromicro/go-zero/core/stores/redis"
  5 + "github.com/zeromicro/go-zero/rest"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/api/internal/config"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/db/repository"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/open"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/cache"
  11 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/database"
  12 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/middleware"
  13 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  14 + "gorm.io/gorm"
  15 +)
  16 +
  17 +type ServiceContext struct {
  18 + Config config.Config
  19 + LogRequest rest.Middleware
  20 + Redis *redis.Redis
  21 + DB *gorm.DB
  22 + ChatSessionRepository domain.ChatSessionRepository
  23 + ChatSessionRecordRepository domain.ChatSessionRecordRepository
  24 + SystemOpen open.SystemOpen
  25 +}
  26 +
  27 +func NewServiceContext(c config.Config) *ServiceContext {
  28 + db := database.OpenGormPGDB(c.DB.DataSource, c.Log.Mode)
  29 +
  30 + mlCache := cache.NewMultiLevelCache([]string{c.Redis.Host}, c.Redis.Pass)
  31 + redis, _ := redis.NewRedis(redis.RedisConf{Host: c.Redis.Host, Pass: c.Redis.Pass, Type: "node"})
  32 + return &ServiceContext{
  33 + Config: c,
  34 + DB: db,
  35 + Redis: redis,
  36 + LogRequest: middleware.NewLogRequestMiddleware(c.LogRequest).Handle,
  37 + ChatSessionRepository: repository.NewChatSessionRepository(cache.NewCachedRepository(mlCache)),
  38 + ChatSessionRecordRepository: repository.NewChatSessionRecordRepository(cache.NewCachedRepository(mlCache)),
  39 +
  40 + SystemOpen: open.NewSystemOpen(c.Redis),
  41 + }
  42 +}
  43 +
  44 +func (svc *ServiceContext) DefaultDBConn() transaction.Conn {
  45 + return transaction.NewTransactionContext(svc.DB)
  46 +}
  1 +// Code generated by goctl. DO NOT EDIT.
  2 +package types
  3 +
  4 +type ChatSessionGetRequest struct {
  5 + Id int64 `path:"id"`
  6 +}
  7 +
  8 +type ChatSessionGetResponse struct {
  9 + ChatSession ChatSessionItem `json:"session"`
  10 + Records []Record `json:"records"`
  11 +}
  12 +
  13 +type ChatSessionSaveRequest struct {
  14 + ChatSession ChatSessionItem `json:"session"`
  15 +}
  16 +
  17 +type ChatSessionSaveResponse struct {
  18 +}
  19 +
  20 +type ChatSessionDeleteRequest struct {
  21 + Id int64 `path:"id"`
  22 +}
  23 +
  24 +type ChatSessionDeleteResponse struct {
  25 +}
  26 +
  27 +type ChatSessionUpdateRequest struct {
  28 + Id int64 `path:"id"`
  29 + ChatSession ChatSessionItem `json:"session"`
  30 +}
  31 +
  32 +type ChatSessionUpdateResponse struct {
  33 +}
  34 +
  35 +type ChatSessionSearchRequest struct {
  36 + Page int `json:"page,optional"`
  37 + Size int `json:"size,optional"`
  38 + Title string `json:"title,optional"` // 按标题搜索
  39 +}
  40 +
  41 +type ChatSessionSearchResponse struct {
  42 + List []ChatSessionItem `json:"list"`
  43 + Total int64 `json:"total"`
  44 +}
  45 +
  46 +type ChatSessionItem struct {
  47 + Id int64 `json:"id,optional,omitempty"` // 唯一标识
  48 + Title string `json:"title,optional,omitempty"` // 会话标题
  49 + Abstract string `json:"abstract,optional,omitempty"` // 摘要
  50 + CreatedAt int64 `json:"createdAt,optional,omitempty"` // 创建时间
  51 +}
  52 +
  53 +type ChatModelsRequest struct {
  54 +}
  55 +
  56 +type ChatModelsResponse struct {
  57 + List []Model `json:"list"`
  58 +}
  59 +
  60 +type Model struct {
  61 + Id int64 `json:"id"` // 模型ID
  62 + Name string `json:"name"` // 模型名称
  63 + Code string `json:"code"` // 模型编码
  64 + Logo string `json:"logo"` // 模型LOGO地址
  65 +}
  66 +
  67 +type ChatSessionRecordsRequest struct {
  68 + Page int `json:"page,optional"`
  69 + Size int `json:"size,optional"`
  70 + SessionId int64 `json:"sessionId"`
  71 +}
  72 +
  73 +type ChatSessionRecordsResponse struct {
  74 + Records []Record `json:"list"`
  75 + Total int64 `json:"total"`
  76 +}
  77 +
  78 +type ChatSessionConversationRequest struct {
  79 + SessionId int64 `json:"sessionId"` // 会话ID
  80 + ModelId int64 `json:"modelId"` // 模型ID
  81 + ContentType string `json:"contentType"` // 内容类型 文本:text (图片:image 文档:document)
  82 + Text string `json:"text"` // 内容文本
  83 + FileUrl string `json:"fileUrl,optional"` // 文件地址
  84 +}
  85 +
  86 +type ChatSessionConversationResponse struct {
  87 + Record *Record `json:"record,omitempty"`
  88 + Parts []string `json:"parts"`
  89 + Finished bool `json:"finished"`
  90 +}
  91 +
  92 +type ChatSessionConversationRequestWs struct {
  93 + SessionId int64 `form:"sessionId"` // 会话ID
  94 + ModelId int64 `form:"modelId"` // 模型ID
  95 + ContentType string `form:"contentType"` // 内容类型 文本:text (图片:image 文档:document)
  96 + Text string `form:"text"` // 内容文本
  97 +}
  98 +
  99 +type Record struct {
  100 + Id int64 `json:"id"` // 记录ID
  101 + SessionId int64 `json:"sessionId"` // 会话ID
  102 + GroupId int64 `json:"groupId"` // 分组ID
  103 + ModelId int64 `json:"modelId,omitempty"` // 模型ID
  104 + AuthorId int64 `json:"authorId,omitempty"` // 作者ID
  105 + Author *User `json:"author,omitempty"` // 提问人
  106 + Model *Model `json:"model,omitempty"` // 应答人
  107 + ContentType string `json:"contentType"` // 内容类型 文本:text (图片:image 文档:document)
  108 + ProblemText string `json:"problemText"` // 问题文本
  109 + AnswerText string `json:"answerText"` // 回答文本
  110 + Status string `json:"status"` // 状态 处理中:processing 超时:finished_timeout 结束成功:finished_fail 结束失败:finished_success
  111 + CreateAt int64 `json:"createAt"` // 创建时间
  112 +}
  113 +
  114 +type Content struct {
  115 + ContentType string `json:"contentType"` // 内容类型 文本:text (图片:image 文档:document)
  116 + Parts []string `json:"parts"` // 内容
  117 +}
  118 +
  119 +type User struct {
  120 + Id int64 `json:"id"` // 用ID
  121 + Name string `json:"name"` // 名称
  122 + Avatar string `json:"avatar"` // 头像
  123 +}
  1 +CREATE TABLE `chat_session`
  2 +(
  3 + `id` int(0) NOT NULL COMMENT '唯一标识',
  4 + PRIMARY KEY (`id`) USING BTREE
  5 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  6 +
  7 +CREATE TABLE `chat_session_record`
  8 +(
  9 + `id` int(0) NOT NULL COMMENT '唯一标识',
  10 + PRIMARY KEY (`id`) USING BTREE
  11 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  12 +
  13 +CREATE TABLE `chat_model`
  14 +(
  15 + `id` int(0) NOT NULL COMMENT '唯一标识',
  16 + PRIMARY KEY (`id`) USING BTREE
  17 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  1 +FROM golang:1.19-alpine as builder
  2 +
  3 +# Define the project name | 定义项目名称
  4 +ARG PROJECT=core
  5 +ARG PROJECTCODE=chat
  6 +
  7 +WORKDIR /build
  8 +COPY . .
  9 +
  10 +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
  11 +RUN apk update --no-cache && apk add --no-cache tzdata
  12 +RUN go env -w GO111MODULE=on \
  13 + && go env -w GOPROXY=https://goproxy.cn,direct \
  14 + && go env -w CGO_ENABLED=0 \
  15 + && go env \
  16 + && go mod tidy \
  17 + && cd cmd/ep/${PROJECTCODE}/api \
  18 + && go build -ldflags="-s -w" -o /build/api/${PROJECT} ${PROJECT}.go
  19 +
  20 +FROM alpine:latest
  21 +
  22 +# Define the project name | 定义项目名称
  23 +ARG PROJECT=core
  24 +ARG PROJECTCODE=chat
  25 +# Define the config file name | 定义配置文件名
  26 +ARG CONFIG_FILE=core.yaml
  27 +# Define the author | 定义作者
  28 +ARG AUTHOR=785409885@qq.com
  29 +
  30 +LABEL org.opencontainers.image.authors=${AUTHOR}
  31 +
  32 +WORKDIR /app
  33 +ENV PROJECT=${PROJECT}
  34 +ENV CONFIG_FILE=${CONFIG_FILE}
  35 +ENV TZ Asia/Shanghai
  36 +
  37 +COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
  38 +COPY --from=builder /build/api/${PROJECT} ./
  39 +COPY --from=builder /build/cmd/ep/${PROJECTCODE}/api/etc/${CONFIG_FILE} ./etc/
  40 +
  41 +EXPOSE 8080
  42 +ENTRYPOINT ./${PROJECT} -f etc/${CONFIG_FILE}
  1 +#!/bin/bash
  2 +export PATH=/root/local/bin:$PATH
  3 +kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  4 +if [ "$?" == "1" ];then
  5 + kubectl create -f /tmp/test/sumifcc-discuss/sumifcc-discuss.yaml --record
  6 + kubectl -n mmm-suplus-test get svc | grep -q sumifcc-discuss
  7 + if [ "$?" == "0" ];then
  8 + echo "sumifcc-discuss service install success!"
  9 + else
  10 + echo "sumifcc-discuss service install fail!"
  11 + fi
  12 + kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  13 + if [ "$?" == "0" ];then
  14 + echo "sumifcc-discuss deployment install success!"
  15 + else
  16 + echo "sumifcc-discuss deployment install fail!"
  17 + fi
  18 +else
  19 + kubectl delete -f /tmp/test/sumifcc-discuss/sumifcc-discuss.yaml
  20 + kubectl -n mmm-suplus-test get svc | grep -q sumifcc-discuss
  21 + while [ "$?" == "0" ]
  22 + do
  23 + kubectl -n mmm-suplus-test get svc | grep -q sumifcc-discuss
  24 + done
  25 + kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  26 + while [ "$?" == "0" ]
  27 + do
  28 + kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  29 + done
  30 + kubectl create -f /tmp/test/sumifcc-discuss/sumifcc-discuss.yaml --record
  31 + kubectl -n mmm-suplus-test get svc | grep -q sumifcc-discuss
  32 + if [ "$?" == "0" ];then
  33 + echo "sumifcc-discuss service update success!"
  34 + else
  35 + echo "sumifcc-discuss service update fail!"
  36 + fi
  37 + kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  38 + if [ "$?" == "0" ];then
  39 + echo "sumifcc-discuss deployment update success!"
  40 + else
  41 + echo "sumifcc-discuss deployment update fail!"
  42 + fi
  43 +fi
  1 +apiVersion: v1
  2 +kind: ConfigMap
  3 +metadata:
  4 + name: sumicro-chat-config-dev
  5 +data:
  6 + core.yaml: |
  7 + Name: sumicro-chat-dev
  8 + Host: 0.0.0.0
  9 + Port: 8080
  10 +
  11 + Verbose: false
  12 + Migrate: true
  13 + Timeout: 30000
  14 + LogRequest: true # 记录详细请求日志
  15 +
  16 + Log:
  17 + #Mode: file
  18 + Encoding: plain
  19 + Level: debug # info
  20 + MaxSize: 1 # 2MB
  21 + TimeFormat: 2006-01-02 15:04:05
  22 + Rotation: size
  23 + MaxContentLength: 10240
  24 +
  25 + SystemAuth:
  26 + AccessSecret: su-platform
  27 + AccessExpire: 360000
  28 +
  29 + Redis:
  30 + Host: 192.168.0.243:6379
  31 + Type: node
  32 + Pass:
  33 + DB:
  34 + DataSource: host=114.55.200.59 user=postgres password=eagle1010 dbname=su_enterprise_platform port=31543 sslmode=disable TimeZone=Asia/Shanghai
  35 +
  36 +---
  37 +apiVersion: v1
  38 +kind: Service
  39 +metadata:
  40 + name: sumicro-chat
  41 + namespace: mmm-suplus-test
  42 + labels:
  43 + k8s-app: sumicro-chat
  44 +spec:
  45 + ports:
  46 + - name: "http"
  47 + port: 80
  48 + targetPort: 8080
  49 + - name: "https"
  50 + port: 443
  51 + targetPort: 443
  52 + selector:
  53 + k8s-app: sumicro-chat
  54 +---
  55 +apiVersion: extensions/v1beta1
  56 +kind: Deployment
  57 +metadata:
  58 + name: sumicro-chat
  59 + namespace: mmm-suplus-test
  60 + labels:
  61 + k8s-app: sumicro-chat
  62 +spec:
  63 + replicas: 1
  64 + template:
  65 + metadata:
  66 + labels:
  67 + k8s-app: sumicro-chat
  68 + spec:
  69 + affinity:
  70 + nodeAffinity:
  71 + preferredDuringSchedulingIgnoredDuringExecution:
  72 + - preference: {}
  73 + weight: 100
  74 + requiredDuringSchedulingIgnoredDuringExecution:
  75 + nodeSelectorTerms:
  76 + - matchExpressions:
  77 + - key: kubernetes.io/hostname
  78 + operator: In
  79 + values:
  80 + - cn-hangzhou.i-bp1djh1xn7taumbue1ze
  81 +
  82 + containers:
  83 + - name: sumicro-chat
  84 + image: 192.168.0.243:5000/mmm/sumicro-chat:dev
  85 + imagePullPolicy: Always
  86 + ports:
  87 + - containerPort: 8080
  88 + - containerPort: 443
  89 + volumeMounts:
  90 + - mountPath: /opt/logs
  91 + name: accesslogs
  92 + - mountPath: /app/etc
  93 + name: config-volume
  94 + env:
  95 + - name: LOG_LEVEL
  96 + value: "debug"
  97 + - name: LOG_FILE
  98 + value: "true"
  99 + volumes:
  100 + - name: accesslogs
  101 + emptyDir: {}
  102 + - name: config-volume
  103 + configMap:
  104 + name: sumicro-chat-config-dev
  1 +#!/bin/bash
  2 +export PATH=/root/local/bin:$PATH
  3 +kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  4 +if [ "$?" == "1" ];then
  5 + kubectl create -f /tmp/test/sumifcc-discuss/sumifcc-discuss.yaml --record
  6 + kubectl -n mmm-suplus-test get svc | grep -q sumifcc-discuss
  7 + if [ "$?" == "0" ];then
  8 + echo "sumifcc-discuss service install success!"
  9 + else
  10 + echo "sumifcc-discuss service install fail!"
  11 + fi
  12 + kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  13 + if [ "$?" == "0" ];then
  14 + echo "sumifcc-discuss deployment install success!"
  15 + else
  16 + echo "sumifcc-discuss deployment install fail!"
  17 + fi
  18 +else
  19 + kubectl delete -f /tmp/test/sumifcc-discuss/sumifcc-discuss.yaml
  20 + kubectl -n mmm-suplus-test get svc | grep -q sumifcc-discuss
  21 + while [ "$?" == "0" ]
  22 + do
  23 + kubectl -n mmm-suplus-test get svc | grep -q sumifcc-discuss
  24 + done
  25 + kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  26 + while [ "$?" == "0" ]
  27 + do
  28 + kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  29 + done
  30 + kubectl create -f /tmp/test/sumifcc-discuss/sumifcc-discuss.yaml --record
  31 + kubectl -n mmm-suplus-test get svc | grep -q sumifcc-discuss
  32 + if [ "$?" == "0" ];then
  33 + echo "sumifcc-discuss service update success!"
  34 + else
  35 + echo "sumifcc-discuss service update fail!"
  36 + fi
  37 + kubectl -n mmm-suplus-test get pods | grep -q sumifcc-discuss
  38 + if [ "$?" == "0" ];then
  39 + echo "sumifcc-discuss deployment update success!"
  40 + else
  41 + echo "sumifcc-discuss deployment update fail!"
  42 + fi
  43 +fi
  1 +apiVersion: v1
  2 +kind: ConfigMap
  3 +metadata:
  4 + name: sumicro-chat-config-prd
  5 +data:
  6 + config.yml: |
  7 + Name: sumicro-chat-prd
  8 + Host: 0.0.0.0
  9 + Port: 8080
  10 +
  11 + Verbose: false
  12 + Migrate: true
  13 + Timeout: 30000
  14 + LogRequest: true # 记录详细请求日志
  15 +
  16 + Log:
  17 + #Mode: file
  18 + Encoding: plain
  19 + Level: debug # info
  20 + MaxSize: 1 # 2MB
  21 + TimeFormat: 2006-01-02 15:04:05
  22 + Rotation: size
  23 + MaxContentLength: 10240
  24 +
  25 + SystemAuth:
  26 + AccessSecret: su-platform
  27 + AccessExpire: 360000
  28 +
  29 + Redis:
  30 + Host: 192.168.0.243:6379
  31 + Type: node
  32 + Pass:
  33 + DB:
  34 + DataSource: host=114.55.200.59 user=postgres password=eagle1010 dbname=su_enterprise_platform port=31543 sslmode=disable TimeZone=Asia/Shanghai
  35 +
  36 +---
  37 +apiVersion: v1
  38 +kind: Service
  39 +metadata:
  40 + name: sumicro-chat
  41 + namespace: mmm-suplus-test
  42 + labels:
  43 + k8s-app: sumicro-chat
  44 +spec:
  45 + ports:
  46 + - name: "http"
  47 + port: 80
  48 + targetPort: 8080
  49 + - name: "https"
  50 + port: 443
  51 + targetPort: 443
  52 + selector:
  53 + k8s-app: sumicro-chat
  54 +---
  55 +apiVersion: extensions/v1beta1
  56 +kind: Deployment
  57 +metadata:
  58 + name: sumicro-chat
  59 + namespace: mmm-suplus-test
  60 + labels:
  61 + k8s-app: sumicro-chat
  62 +spec:
  63 + replicas: 1
  64 + template:
  65 + metadata:
  66 + labels:
  67 + k8s-app: sumicro-chat
  68 + spec:
  69 + affinity:
  70 + nodeAffinity:
  71 + preferredDuringSchedulingIgnoredDuringExecution:
  72 + - preference: {}
  73 + weight: 100
  74 + requiredDuringSchedulingIgnoredDuringExecution:
  75 + nodeSelectorTerms:
  76 + - matchExpressions:
  77 + - key: kubernetes.io/hostname
  78 + operator: In
  79 + values:
  80 + - cn-hangzhou.i-bp1djh1xn7taumbue1ze
  81 +
  82 + containers:
  83 + - name: sumicro-chat
  84 + image: 192.168.0.243:5000/mmm/sumicro-chat:dev
  85 + imagePullPolicy: Always
  86 + ports:
  87 + - containerPort: 8080
  88 + - containerPort: 443
  89 + volumeMounts:
  90 + - mountPath: /opt/logs
  91 + name: accesslogs
  92 + - mountPath: /app/etc
  93 + name: config-volume
  94 + env:
  95 + - name: LOG_LEVEL
  96 + value: "debug"
  97 + - name: LOG_FILE
  98 + value: "true"
  99 + volumes:
  100 + - name: accesslogs
  101 + emptyDir: {}
  102 + - name: config-volume
  103 + configMap:
  104 + name: sumicro-chat-config-prd
  1 +## 1、准备工作
  2 +
  3 +在开始之前,我们需要准备一些东西:
  4 +* Docker:这是一个用于容器化应用程序的开源平台。
  5 +
  6 +## 2、准备Nginx配置文件
  7 +完整的配置文件见**nginx.conf**,其核心部分如下:
  8 +```conf
  9 +server {
  10 + listen 80; # 监听80端口,用于HTTP请求
  11 + location / {
  12 + proxy_pass https://api.openai.com/; # 反向代理到https://api.openai.com/这个地址
  13 + proxy_ssl_server_name on; # 开启代理SSL服务器名称验证,确保SSL连接的安全性
  14 + proxy_set_header Host api.openai.com; # 设置代理请求头中的Host字段为api.openai.com
  15 + chunked_transfer_encoding off; # 禁用分块编码传输,避免可能的代理问题
  16 + proxy_buffering off; # 禁用代理缓存,避免数据传输延迟
  17 + proxy_cache off; # 禁用代理缓存,确保实时获取最新的数据
  18 + #proxy_set_header X-Forwarded-For $remote_addr; # 将客户端真实IP添加到代理请求头中的X-Forwarded-For字段中,用于记录客户端真实IP
  19 + }
  20 +}
  21 +```
  22 +
  23 +## 3、启动服务
  24 +
  25 +### 3.1、docker run
  26 +```
  27 +docker run -itd -p 80:80 -v $PWD/nginx.conf:/etc/nginx/nginx.conf --name my-nginx nginx
  28 +```
  29 +
  30 +### 3.2、docker compose up
  31 +```
  32 +docker compose up -d
  33 +```
  34 +
  35 +## 4、应用
  36 +```python
  37 +# Note: you need to be using OpenAI Python v0.27.0 for the code below to work
  38 +import openai
  39 +openai.api_key = api_key
  40 +openai.api_base = "your_proxy_url" # 代理地址,如“http://www.test.com/v1”
  41 +openai.ChatCompletion.create(
  42 + model="gpt-3.5-turbo",
  43 + messages=[
  44 + {"role": "system", "content": "You are a helpful assistant."},
  45 + {"role": "user", "content": "Who won the world series in 2020?"},
  46 + {"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
  47 + {"role": "user", "content": "Where was it played?"}
  48 + ]
  49 +)
  50 +```
  1 +services:
  2 + proxy:
  3 + image: nginx
  4 + volumes:
  5 + - "$PWD/nginx.conf:/etc/nginx/nginx.conf"
  6 + ports:
  7 + - "80:80"
  8 + - "443:443"
  9 + restart: unless-stopped
  1 +user nginx;
  2 +worker_processes auto;
  3 +
  4 +error_log /var/log/nginx/error.log notice;
  5 +pid /var/run/nginx.pid;
  6 +
  7 +
  8 +events {
  9 + worker_connections 1024;
  10 +}
  11 +
  12 +
  13 +http {
  14 + include /etc/nginx/mime.types;
  15 + default_type application/octet-stream;
  16 +
  17 + log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  18 + '$status $body_bytes_sent "$http_referer" '
  19 + '"$http_user_agent" "$http_x_forwarded_for"';
  20 +
  21 + access_log /var/log/nginx/access.log main;
  22 +
  23 + sendfile on;
  24 + #tcp_nopush on;
  25 +
  26 + keepalive_timeout 65;
  27 +
  28 + #gzip on;
  29 +
  30 + # include /etc/nginx/conf.d/*.conf;
  31 +
  32 + server {
  33 + listen 80;
  34 + location / {
  35 + proxy_pass https://api.openai.com/;
  36 + proxy_ssl_server_name on;
  37 + proxy_set_header Host api.openai.com;
  38 + chunked_transfer_encoding off;
  39 + proxy_buffering off;
  40 + proxy_cache off;
  41 + proxy_set_header X-Forwarded-For $remote_addr;
  42 + }
  43 + }
  44 +}
  1 +syntax = "v1"
  2 +
  3 +import "core/session.api"
  1 +syntax = "v1"
  2 +
  3 +// 后台接口
  4 +@server(
  5 + prefix: v1
  6 + group: chat
  7 + middleware: LogRequest
  8 + jwt: SystemAuth
  9 +)
  10 +service Core {
  11 + @doc "聊天会话-详情"
  12 + @handler chatSessionGet
  13 + get /chat/session/:id (ChatSessionGetRequest) returns (ChatSessionGetResponse)
  14 + @doc "聊天会话-保存"
  15 + @handler chatSessionSave
  16 + post /chat/session (ChatSessionSaveRequest) returns (ChatSessionSaveResponse)
  17 + @doc "聊天会话-删除"
  18 + @handler chatSessionDelete
  19 + delete /chat/session/:id (ChatSessionDeleteRequest) returns (ChatSessionDeleteResponse)
  20 + @doc "聊天会话-更新"
  21 + @handler chatSessionUpdate
  22 + put /chat/session/:id (ChatSessionUpdateRequest) returns (ChatSessionUpdateResponse)
  23 + @doc "聊天会话-搜索"
  24 + @handler chatSessionSearch
  25 + post /chat/session/search (ChatSessionSearchRequest) returns (ChatSessionSearchResponse)
  26 + @doc "聊天会话-对话"
  27 + @handler chatSessionConversation
  28 + post /chat/session/conversation (ChatSessionConversationRequest) returns (ChatSessionConversationResponse)
  29 + @doc "聊天会话-对话"
  30 + @handler chatSessionConversationWs
  31 + get /chat/session/conversation (ChatSessionConversationRequestWs) returns (ChatSessionConversationResponse)
  32 +
  33 + @doc "聊天会话-对话记录列表"
  34 + @handler chatSessionRecords
  35 + post /chat/session/records (ChatSessionRecordsRequest) returns (ChatSessionRecordsResponse)
  36 +
  37 + @doc "模型列表"
  38 + @handler chatModels
  39 + get /chat/models (ChatModelsRequest) returns (ChatModelsResponse)
  40 +}
  41 +
  42 +type (
  43 + ChatSessionGetRequest {
  44 + Id int64 `path:"id"`
  45 + }
  46 + ChatSessionGetResponse {
  47 + ChatSession ChatSessionItem `json:"session"`
  48 + Records []Record `json:"records"`
  49 + }
  50 +
  51 + ChatSessionSaveRequest {
  52 + ChatSession ChatSessionItem `json:"session"`
  53 + }
  54 + ChatSessionSaveResponse {}
  55 +
  56 + ChatSessionDeleteRequest {
  57 + Id int64 `path:"id"`
  58 + }
  59 + ChatSessionDeleteResponse {}
  60 +
  61 + ChatSessionUpdateRequest {
  62 + Id int64 `path:"id"`
  63 + ChatSession ChatSessionItem `json:"session"`
  64 + }
  65 + ChatSessionUpdateResponse {}
  66 +
  67 + ChatSessionSearchRequest {
  68 + Page int `json:"page,optional"`
  69 + Size int `json:"size,optional"`
  70 + Title string `json:"title,optional"` // 按标题搜索
  71 + }
  72 + ChatSessionSearchResponse{
  73 + List []ChatSessionItem `json:"list"`
  74 + Total int64 `json:"total"`
  75 + }
  76 + ChatSessionItem {
  77 + Id int64 `json:"id,optional,omitempty"` // 唯一标识
  78 + Title string `json:"title,optional,omitempty"` // 会话标题
  79 + Abstract string `json:"abstract,optional,omitempty"` // 摘要
  80 + CreatedAt int64 `json:"createdAt,optional,omitempty"` // 创建时间
  81 + }
  82 +)
  83 +
  84 +// 模型列表
  85 +type(
  86 + ChatModelsRequest{
  87 +
  88 + }
  89 + ChatModelsResponse{
  90 + List []Model `json:"list"`
  91 + }
  92 + Model{
  93 + Id int64 `json:"id"` // 模型ID
  94 + Name string `json:"name"` // 模型名称
  95 + Code string `json:"code"` // 模型编码
  96 + Logo string `json:"logo"` // 模型LOGO地址
  97 + }
  98 +)
  99 +
  100 +// 聊天会话-记录列表
  101 +type(
  102 + ChatSessionRecordsRequest{
  103 + Page int `json:"page,optional"`
  104 + Size int `json:"size,optional"`
  105 + SessionId int64 `json:"sessionId"`
  106 + }
  107 + ChatSessionRecordsResponse{
  108 + Records []Record `json:"list"`
  109 + Total int64 `json:"total"`
  110 + }
  111 +)
  112 +
  113 +// 聊天会话-对话
  114 +type(
  115 + ChatSessionConversationRequest{
  116 + SessionId int64 `json:"sessionId"` // 会话ID
  117 + ModelId int64 `json:"modelId"` // 模型ID
  118 + ContentType string `json:"contentType"` // 内容类型 文本:text (图片:image 文档:document)
  119 + Text string `json:"text"` // 内容文本
  120 + FileUrl string `json:"fileUrl,optional"` // 文件地址
  121 + }
  122 + ChatSessionConversationResponse{
  123 + Record *Record `json:"record,omitempty"`
  124 + Parts []string `json:"parts"`
  125 + Finished bool `json:"finished"`
  126 + }
  127 + ChatSessionConversationRequestWs{
  128 + SessionId int64 `form:"sessionId"` // 会话ID
  129 + ModelId int64 `form:"modelId"` // 模型ID
  130 + ContentType string `form:"contentType"` // 内容类型 文本:text (图片:image 文档:document)
  131 + Text string `form:"text"` // 内容文本
  132 + }
  133 + Record{
  134 + Id int64 `json:"id"` // 记录ID
  135 + SessionId int64 `json:"sessionId"` // 会话ID
  136 + GroupId int64 `json:"groupId"` // 分组ID
  137 + ModelId int64 `json:"modelId,omitempty"` // 模型ID
  138 + AuthorId int64 `json:"authorId,omitempty"` // 作者ID
  139 + Author *User `json:"author,omitempty"` // 提问人
  140 + Model *Model `json:"model,omitempty"` // 应答人
  141 + ContentType string `json:"contentType"` // 内容类型 文本:text (图片:image 文档:document)
  142 + ProblemText string `json:"problemText"` // 问题文本
  143 + AnswerText string `json:"answerText"` // 回答文本
  144 + Status string `json:"status"` // 状态 处理中:processing 超时:finished_timeout 结束成功:finished_fail 结束失败:finished_success
  145 + CreateAt int64 `json:"createAt"` // 创建时间
  146 + }
  147 + Content{
  148 + ContentType string `json:"contentType"` // 内容类型 文本:text (图片:image 文档:document)
  149 + Parts []string `json:"parts"` // 内容
  150 + }
  151 + User {
  152 + Id int64 `json:"id"` // 用ID
  153 + Name string `json:"name"` // 名称
  154 + Avatar string `json:"avatar"` // 头像
  155 + }
  156 +)
  1 +{
  2 + "swagger": "2.0",
  3 + "info": {
  4 + "title": "",
  5 + "version": ""
  6 + },
  7 + "schemes": [
  8 + "http",
  9 + "https"
  10 + ],
  11 + "consumes": [
  12 + "application/json"
  13 + ],
  14 + "produces": [
  15 + "application/json"
  16 + ],
  17 + "paths": {
  18 + "v1/chat/models": {
  19 + "get": {
  20 + "summary": "模型列表",
  21 + "operationId": "chatModels",
  22 + "responses": {
  23 + "200": {
  24 + "description": "A successful response.",
  25 + "schema": {
  26 + "$ref": "#/definitions/ChatModelsResponse"
  27 + }
  28 + }
  29 + },
  30 + "requestBody": {},
  31 + "tags": [
  32 + "chat"
  33 + ]
  34 + }
  35 + },
  36 + "v1/chat/session": {
  37 + "post": {
  38 + "summary": "聊天会话-保存",
  39 + "operationId": "chatSessionSave",
  40 + "responses": {
  41 + "200": {
  42 + "description": "A successful response.",
  43 + "schema": {
  44 + "$ref": "#/definitions/ChatSessionSaveResponse"
  45 + }
  46 + }
  47 + },
  48 + "parameters": [
  49 + {
  50 + "name": "body",
  51 + "in": "body",
  52 + "required": true,
  53 + "schema": {
  54 + "$ref": "#/definitions/ChatSessionSaveRequest"
  55 + }
  56 + }
  57 + ],
  58 + "requestBody": {},
  59 + "tags": [
  60 + "chat"
  61 + ]
  62 + }
  63 + },
  64 + "v1/chat/session/conversation": {
  65 + "get": {
  66 + "summary": "聊天会话-对话",
  67 + "operationId": "chatSessionConversation",
  68 + "responses": {
  69 + "200": {
  70 + "description": "A successful response.",
  71 + "schema": {
  72 + "$ref": "#/definitions/ChatSessionConversationResponse"
  73 + }
  74 + }
  75 + },
  76 + "parameters": [
  77 + {
  78 + "name": "sessionId",
  79 + "description": " 会话ID",
  80 + "in": "query",
  81 + "required": true,
  82 + "type": "integer",
  83 + "format": "int64"
  84 + },
  85 + {
  86 + "name": "modelId",
  87 + "description": " 模型ID",
  88 + "in": "query",
  89 + "required": true,
  90 + "type": "integer",
  91 + "format": "int64"
  92 + },
  93 + {
  94 + "name": "contentType",
  95 + "description": " 内容类型 文本:text (图片:image 文档:document)",
  96 + "in": "query",
  97 + "required": true,
  98 + "type": "string"
  99 + },
  100 + {
  101 + "name": "text",
  102 + "description": " 内容文本",
  103 + "in": "query",
  104 + "required": true,
  105 + "type": "string"
  106 + },
  107 + {
  108 + "name": "fileUrl",
  109 + "description": " 文件地址",
  110 + "in": "query",
  111 + "required": true,
  112 + "type": "string"
  113 + }
  114 + ],
  115 + "requestBody": {},
  116 + "tags": [
  117 + "chat"
  118 + ]
  119 + }
  120 + },
  121 + "v1/chat/session/records": {
  122 + "get": {
  123 + "summary": "聊天会话-对话记录列表",
  124 + "operationId": "chatSessionRecords",
  125 + "responses": {
  126 + "200": {
  127 + "description": "A successful response.",
  128 + "schema": {
  129 + "$ref": "#/definitions/ChatSessionRecordsResponse"
  130 + }
  131 + }
  132 + },
  133 + "parameters": [
  134 + {
  135 + "name": "page",
  136 + "in": "query",
  137 + "required": false,
  138 + "type": "integer",
  139 + "format": "int32"
  140 + },
  141 + {
  142 + "name": "size",
  143 + "in": "query",
  144 + "required": false,
  145 + "type": "integer",
  146 + "format": "int32"
  147 + },
  148 + {
  149 + "name": "sessionId",
  150 + "in": "query",
  151 + "required": true,
  152 + "type": "integer",
  153 + "format": "int64"
  154 + }
  155 + ],
  156 + "requestBody": {},
  157 + "tags": [
  158 + "chat"
  159 + ]
  160 + }
  161 + },
  162 + "v1/chat/session/search": {
  163 + "post": {
  164 + "summary": "聊天会话-搜索",
  165 + "operationId": "chatSessionSearch",
  166 + "responses": {
  167 + "200": {
  168 + "description": "A successful response.",
  169 + "schema": {
  170 + "$ref": "#/definitions/ChatSessionSearchResponse"
  171 + }
  172 + }
  173 + },
  174 + "parameters": [
  175 + {
  176 + "name": "body",
  177 + "in": "body",
  178 + "required": true,
  179 + "schema": {
  180 + "$ref": "#/definitions/ChatSessionSearchRequest"
  181 + }
  182 + }
  183 + ],
  184 + "requestBody": {},
  185 + "tags": [
  186 + "chat"
  187 + ]
  188 + }
  189 + },
  190 + "v1/chat/session/{id}": {
  191 + "get": {
  192 + "summary": "聊天会话-详情",
  193 + "operationId": "chatSessionGet",
  194 + "responses": {
  195 + "200": {
  196 + "description": "A successful response.",
  197 + "schema": {
  198 + "$ref": "#/definitions/ChatSessionGetResponse"
  199 + }
  200 + }
  201 + },
  202 + "parameters": [
  203 + {
  204 + "name": "id",
  205 + "in": "path",
  206 + "required": true,
  207 + "type": "string"
  208 + }
  209 + ],
  210 + "requestBody": {},
  211 + "tags": [
  212 + "chat"
  213 + ]
  214 + },
  215 + "delete": {
  216 + "summary": "聊天会话-删除",
  217 + "operationId": "chatSessionDelete",
  218 + "responses": {
  219 + "200": {
  220 + "description": "A successful response.",
  221 + "schema": {
  222 + "$ref": "#/definitions/ChatSessionDeleteResponse"
  223 + }
  224 + }
  225 + },
  226 + "parameters": [
  227 + {
  228 + "name": "id",
  229 + "in": "path",
  230 + "required": true,
  231 + "type": "string"
  232 + },
  233 + {
  234 + "name": "body",
  235 + "in": "body",
  236 + "required": true,
  237 + "schema": {
  238 + "$ref": "#/definitions/ChatSessionDeleteRequest"
  239 + }
  240 + }
  241 + ],
  242 + "requestBody": {},
  243 + "tags": [
  244 + "chat"
  245 + ]
  246 + },
  247 + "put": {
  248 + "summary": "聊天会话-更新",
  249 + "operationId": "chatSessionUpdate",
  250 + "responses": {
  251 + "200": {
  252 + "description": "A successful response.",
  253 + "schema": {
  254 + "$ref": "#/definitions/ChatSessionUpdateResponse"
  255 + }
  256 + }
  257 + },
  258 + "parameters": [
  259 + {
  260 + "name": "id",
  261 + "in": "path",
  262 + "required": true,
  263 + "type": "string"
  264 + },
  265 + {
  266 + "name": "body",
  267 + "in": "body",
  268 + "required": true,
  269 + "schema": {
  270 + "$ref": "#/definitions/ChatSessionUpdateRequest"
  271 + }
  272 + }
  273 + ],
  274 + "requestBody": {},
  275 + "tags": [
  276 + "chat"
  277 + ]
  278 + }
  279 + }
  280 + },
  281 + "definitions": {
  282 + "ChatModelsRequest": {
  283 + "type": "object",
  284 + "title": "ChatModelsRequest"
  285 + },
  286 + "ChatModelsResponse": {
  287 + "type": "object",
  288 + "properties": {
  289 + "list": {
  290 + "type": "array",
  291 + "items": {
  292 + "$ref": "#/definitions/Model"
  293 + }
  294 + }
  295 + },
  296 + "title": "ChatModelsResponse",
  297 + "required": [
  298 + "list"
  299 + ]
  300 + },
  301 + "ChatSessionConversationRequest": {
  302 + "type": "object",
  303 + "properties": {
  304 + "sessionId": {
  305 + "type": "integer",
  306 + "format": "int64",
  307 + "description": " 会话ID"
  308 + },
  309 + "modelId": {
  310 + "type": "integer",
  311 + "format": "int64",
  312 + "description": " 模型ID"
  313 + },
  314 + "contentType": {
  315 + "type": "string",
  316 + "description": " 内容类型 文本:text (图片:image 文档:document)"
  317 + },
  318 + "text": {
  319 + "type": "string",
  320 + "description": " 内容文本"
  321 + },
  322 + "fileUrl": {
  323 + "type": "string",
  324 + "description": " 文件地址"
  325 + }
  326 + },
  327 + "title": "ChatSessionConversationRequest",
  328 + "required": [
  329 + "sessionId",
  330 + "modelId",
  331 + "contentType",
  332 + "text",
  333 + "fileUrl"
  334 + ]
  335 + },
  336 + "ChatSessionConversationResponse": {
  337 + "type": "object",
  338 + "title": "ChatSessionConversationResponse"
  339 + },
  340 + "ChatSessionDeleteRequest": {
  341 + "type": "object",
  342 + "properties": {
  343 + "id": {
  344 + "type": "integer",
  345 + "format": "int64"
  346 + }
  347 + },
  348 + "title": "ChatSessionDeleteRequest",
  349 + "required": [
  350 + "id"
  351 + ]
  352 + },
  353 + "ChatSessionDeleteResponse": {
  354 + "type": "object",
  355 + "title": "ChatSessionDeleteResponse"
  356 + },
  357 + "ChatSessionGetRequest": {
  358 + "type": "object",
  359 + "properties": {
  360 + "id": {
  361 + "type": "integer",
  362 + "format": "int64"
  363 + }
  364 + },
  365 + "title": "ChatSessionGetRequest",
  366 + "required": [
  367 + "id"
  368 + ]
  369 + },
  370 + "ChatSessionGetResponse": {
  371 + "type": "object",
  372 + "properties": {
  373 + "session": {
  374 + "$ref": "#/definitions/ChatSessionItem"
  375 + },
  376 + "records": {
  377 + "type": "array",
  378 + "items": {
  379 + "$ref": "#/definitions/Record"
  380 + }
  381 + }
  382 + },
  383 + "title": "ChatSessionGetResponse",
  384 + "required": [
  385 + "session",
  386 + "records"
  387 + ]
  388 + },
  389 + "ChatSessionItem": {
  390 + "type": "object",
  391 + "properties": {
  392 + "id": {
  393 + "type": "integer",
  394 + "format": "int64",
  395 + "description": " 唯一标识"
  396 + },
  397 + "title": {
  398 + "type": "string",
  399 + "description": " 会话标题"
  400 + },
  401 + "abstract": {
  402 + "type": "string",
  403 + "description": " 摘要"
  404 + },
  405 + "createdAt": {
  406 + "type": "integer",
  407 + "format": "int64",
  408 + "description": " 创建时间"
  409 + }
  410 + },
  411 + "title": "ChatSessionItem",
  412 + "required": [
  413 + "id",
  414 + "title",
  415 + "abstract",
  416 + "createdAt"
  417 + ]
  418 + },
  419 + "ChatSessionRecordsRequest": {
  420 + "type": "object",
  421 + "properties": {
  422 + "page": {
  423 + "type": "integer",
  424 + "format": "int32"
  425 + },
  426 + "size": {
  427 + "type": "integer",
  428 + "format": "int32"
  429 + },
  430 + "sessionId": {
  431 + "type": "integer",
  432 + "format": "int64"
  433 + }
  434 + },
  435 + "title": "ChatSessionRecordsRequest",
  436 + "required": [
  437 + "sessionId"
  438 + ]
  439 + },
  440 + "ChatSessionRecordsResponse": {
  441 + "type": "object",
  442 + "properties": {
  443 + "list": {
  444 + "type": "array",
  445 + "items": {
  446 + "$ref": "#/definitions/Record"
  447 + }
  448 + },
  449 + "total": {
  450 + "type": "integer",
  451 + "format": "int64"
  452 + }
  453 + },
  454 + "title": "ChatSessionRecordsResponse",
  455 + "required": [
  456 + "list",
  457 + "total"
  458 + ]
  459 + },
  460 + "ChatSessionSaveRequest": {
  461 + "type": "object",
  462 + "properties": {
  463 + "session": {
  464 + "$ref": "#/definitions/ChatSessionItem"
  465 + }
  466 + },
  467 + "title": "ChatSessionSaveRequest",
  468 + "required": [
  469 + "session"
  470 + ]
  471 + },
  472 + "ChatSessionSaveResponse": {
  473 + "type": "object",
  474 + "title": "ChatSessionSaveResponse"
  475 + },
  476 + "ChatSessionSearchRequest": {
  477 + "type": "object",
  478 + "properties": {
  479 + "page": {
  480 + "type": "integer",
  481 + "format": "int32"
  482 + },
  483 + "size": {
  484 + "type": "integer",
  485 + "format": "int32"
  486 + },
  487 + "title": {
  488 + "type": "string",
  489 + "description": " 按标题搜索"
  490 + }
  491 + },
  492 + "title": "ChatSessionSearchRequest"
  493 + },
  494 + "ChatSessionSearchResponse": {
  495 + "type": "object",
  496 + "properties": {
  497 + "list": {
  498 + "type": "array",
  499 + "items": {
  500 + "$ref": "#/definitions/ChatSessionItem"
  501 + }
  502 + },
  503 + "total": {
  504 + "type": "integer",
  505 + "format": "int64"
  506 + }
  507 + },
  508 + "title": "ChatSessionSearchResponse",
  509 + "required": [
  510 + "list",
  511 + "total"
  512 + ]
  513 + },
  514 + "ChatSessionUpdateRequest": {
  515 + "type": "object",
  516 + "properties": {
  517 + "id": {
  518 + "type": "integer",
  519 + "format": "int64"
  520 + },
  521 + "session": {
  522 + "$ref": "#/definitions/ChatSessionItem"
  523 + }
  524 + },
  525 + "title": "ChatSessionUpdateRequest",
  526 + "required": [
  527 + "id",
  528 + "session"
  529 + ]
  530 + },
  531 + "ChatSessionUpdateResponse": {
  532 + "type": "object",
  533 + "title": "ChatSessionUpdateResponse"
  534 + },
  535 + "Content": {
  536 + "type": "object",
  537 + "properties": {
  538 + "contentType": {
  539 + "type": "string",
  540 + "description": " 内容类型 文本:text (图片:image 文档:document)"
  541 + },
  542 + "parts": {
  543 + "type": "array",
  544 + "items": {
  545 + "type": "string"
  546 + },
  547 + "description": " 内容"
  548 + }
  549 + },
  550 + "title": "Content",
  551 + "required": [
  552 + "contentType",
  553 + "parts"
  554 + ]
  555 + },
  556 + "Model": {
  557 + "type": "object",
  558 + "properties": {
  559 + "id": {
  560 + "type": "integer",
  561 + "format": "int64",
  562 + "description": " 模型ID"
  563 + },
  564 + "name": {
  565 + "type": "string",
  566 + "description": " 模型名称"
  567 + },
  568 + "code": {
  569 + "type": "string",
  570 + "description": " 模型编码"
  571 + },
  572 + "logo": {
  573 + "type": "string",
  574 + "description": " 模型LOGO地址"
  575 + }
  576 + },
  577 + "title": "Model",
  578 + "required": [
  579 + "id",
  580 + "name",
  581 + "code",
  582 + "logo"
  583 + ]
  584 + },
  585 + "Record": {
  586 + "type": "object",
  587 + "properties": {
  588 + "id": {
  589 + "type": "integer",
  590 + "format": "int64",
  591 + "description": " 记录ID"
  592 + },
  593 + "sessionId": {
  594 + "type": "integer",
  595 + "format": "int64",
  596 + "description": " 会话ID"
  597 + },
  598 + "groupId": {
  599 + "type": "integer",
  600 + "format": "int64",
  601 + "description": " 分组ID"
  602 + },
  603 + "modelId": {
  604 + "type": "integer",
  605 + "format": "int64",
  606 + "description": " 模型ID"
  607 + },
  608 + "authorId": {
  609 + "type": "integer",
  610 + "format": "int64",
  611 + "description": " 作者ID"
  612 + },
  613 + "author": {
  614 + "$ref": "#/definitions/User",
  615 + "description": " 提问人"
  616 + },
  617 + "model": {
  618 + "$ref": "#/definitions/Model",
  619 + "description": " 应答人"
  620 + },
  621 + "contentType": {
  622 + "type": "string",
  623 + "description": " 内容类型 文本:text (图片:image 文档:document)"
  624 + },
  625 + "problemText": {
  626 + "type": "string",
  627 + "description": " 问题文本"
  628 + },
  629 + "answerText": {
  630 + "type": "string",
  631 + "description": " 回答文本"
  632 + },
  633 + "status": {
  634 + "type": "string",
  635 + "description": " 状态 处理中:processing 超时:finished_timeout 结束成功:finished_fail 结束失败:finished_success"
  636 + },
  637 + "createAt": {
  638 + "type": "integer",
  639 + "format": "int64",
  640 + "description": " 创建时间"
  641 + }
  642 + },
  643 + "title": "Record",
  644 + "required": [
  645 + "id",
  646 + "sessionId",
  647 + "groupId",
  648 + "modelId",
  649 + "authorId",
  650 + "author",
  651 + "model",
  652 + "contentType",
  653 + "problemText",
  654 + "answerText",
  655 + "status",
  656 + "createAt"
  657 + ]
  658 + },
  659 + "User": {
  660 + "type": "object",
  661 + "properties": {
  662 + "id": {
  663 + "type": "integer",
  664 + "format": "int64",
  665 + "description": " 用ID"
  666 + },
  667 + "name": {
  668 + "type": "string",
  669 + "description": " 名称"
  670 + },
  671 + "avatar": {
  672 + "type": "string",
  673 + "description": " 头像"
  674 + }
  675 + },
  676 + "title": "User",
  677 + "required": [
  678 + "id",
  679 + "name",
  680 + "avatar"
  681 + ]
  682 + }
  683 + },
  684 + "securityDefinitions": {
  685 + "apiKey": {
  686 + "type": "apiKey",
  687 + "description": "Enter JWT Bearer token **_only_**",
  688 + "name": "Authorization",
  689 + "in": "header"
  690 + }
  691 + },
  692 + "security": [
  693 + {
  694 + "apiKey": []
  695 + }
  696 + ]
  697 +}
  1 +
  2 +syntax = "v1"
  3 +
  4 +info(
  5 + title: "xx实例"
  6 + desc: "xx实例"
  7 + author: "author"
  8 + email: "email"
  9 + version: "v1"
  10 +)
  11 +
  12 +@server(
  13 + prefix: v1
  14 + group: chat_model
  15 + jwt: JwtAuth
  16 +)
  17 +service Core {
  18 + @doc "详情"
  19 + @handler chat_modelGet
  20 + get /chat_model/:id (ChatModelGetRequest) returns (ChatModelGetResponse)
  21 + @doc "保存"
  22 + @handler chat_modelSave
  23 + post /chat_model (ChatModelSaveRequest) returns (ChatModelSaveResponse)
  24 + @doc "删除"
  25 + @handler chat_modelDelete
  26 + delete /chat_model/:id (ChatModelDeleteRequest) returns (ChatModelDeleteResponse)
  27 + @doc "更新"
  28 + @handler chat_modelUpdate
  29 + put /chat_model/:id (ChatModelUpdateRequest) returns (ChatModelUpdateResponse)
  30 + @doc "搜索"
  31 + @handler chat_modelSearch
  32 + post /chat_model/search (ChatModelSearchRequest) returns (ChatModelSearchResponse)
  33 +}
  34 +
  35 +type (
  36 + ChatModelGetRequest {
  37 + Id int64 `path:"id"`
  38 + }
  39 + ChatModelGetResponse {
  40 + ChatModel ChatModelItem `json:"chat_model"`
  41 + }
  42 +
  43 + ChatModelSaveRequest {
  44 + ChatModel ChatModelItem `json:"chat_model"`
  45 + }
  46 + ChatModelSaveResponse {}
  47 +
  48 + ChatModelDeleteRequest {
  49 + Id int64 `path:"id"`
  50 + }
  51 + ChatModelDeleteResponse {}
  52 +
  53 + ChatModelUpdateRequest {
  54 + Id int64 `path:"id"`
  55 + ChatModel ChatModelItem `json:"chat_model"`
  56 + }
  57 + ChatModelUpdateResponse {}
  58 +
  59 + ChatModelSearchRequest {
  60 + Page int `json:"page"`
  61 + Size int `json:"size"`
  62 + }
  63 + ChatModelSearchResponse{
  64 + List []ChatModelItem `json:"list"`
  65 + Total int64 `json:"total"`
  66 + }
  67 + ChatModelItem {
  68 +
  69 + }
  70 +)
  71 +
  72 +// logic CRUD
  73 +// Save
  74 + //var (
  75 + // conn = l.svcCtx.DefaultDBConn()
  76 + // dm *domain.ChatModel
  77 + //)
  78 + //// 唯一判断
  79 +
  80 + //dm = NewDomainChatModel(req.ChatModel)
  81 + //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  82 + // dm, err = l.svcCtx.ChatModelRepository.Insert(l.ctx, conn, dm)
  83 + // return err
  84 + //}, true); err != nil {
  85 + // return nil, xerr.NewErrMsg("保存失败")
  86 + //}
  87 + ////resp = &types.ChatModelSaveResponse{}
  88 + //return
  89 +
  90 +//func NewDomainChatModel(item types.ChatModelItem) *domain.ChatModel {
  91 +// return &domain.ChatModel{
  92 +
  93 +// }
  94 +//}
  95 +//
  96 +//func NewTypesChatModel(item *domain.ChatModel) types.ChatModelItem {
  97 +// return types.ChatModelItem{
  98 +// Id: item.Id,
  99 +// }
  100 +//}
  101 +
  102 +// Get
  103 + //var (
  104 + // conn = l.svcCtx.DefaultDBConn()
  105 + // dm *domain.ChatModel
  106 + //)
  107 + //// 货号唯一
  108 + //if dm, err = l.svcCtx.ChatModelRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  109 + // return nil, xerr.NewErrMsgErr("不存在", err)
  110 + //}
  111 + //resp = &types.ChatModelGetResponse{
  112 + // ChatModel: NewTypesChatModel(dm),
  113 + //}
  114 + //return
  115 +
  116 +// Delete
  117 + //var (
  118 + // conn = l.svcCtx.DefaultDBConn()
  119 + // dm *domain.ChatModel
  120 + //)
  121 + //if dm, err = l.svcCtx.ChatModelRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  122 + // return nil, xerr.NewErrMsgErr("不存在", err)
  123 + //}
  124 + //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  125 + // if dm, err = l.svcCtx.ChatModelRepository.Delete(l.ctx, conn, dm); err != nil {
  126 + // return err
  127 + // }
  128 + // return nil
  129 + //}, true); err != nil {
  130 + // return nil, xerr.NewErrMsgErr("移除失败", err)
  131 + //}
  132 + //return
  133 +
  134 +// Search
  135 + //var (
  136 + // conn = l.svcCtx.DefaultDBConn()
  137 + // dms []*domain.ChatModel
  138 + // total int64
  139 + //)
  140 + //
  141 + //queryOptions := domain.NewQueryOptions().WithOffsetLimit(req.Page, req.Size).
  142 + // WithKV("", "")
  143 +
  144 + //total, dms, err = l.svcCtx.ChatModelRepository.Find(l.ctx, conn, queryOptions)
  145 + //list := make([]types.ChatModelItem, 0)
  146 + //for i := range dms {
  147 + // list = append(list, NewTypesChatModel(dms[i]))
  148 + //}
  149 + //resp = &types.ChatModelSearchResponse{
  150 + // List: list,
  151 + // Total: total,
  152 + //}
  153 + //return
  154 +
  155 +// Update
  156 + //var (
  157 + // conn = l.svcCtx.DefaultDBConn()
  158 + // dm *domain.ChatModel
  159 + //)
  160 + //if dm, err = l.svcCtx.ChatModelRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  161 + // return nil, xerr.NewErrMsgErr("不存在", err)
  162 + //}
  163 + //// 不可编辑判断
  164 +
  165 + //// 赋值
  166 +
  167 + //// 更新
  168 + //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  169 + // dm, err = l.svcCtx.ChatModelRepository.UpdateWithVersion(l.ctx, conn, dm)
  170 + // return err
  171 + //}, true); err != nil {
  172 + // return nil, xerr.NewErrMsg("更新失败")
  173 + //}
  174 + //resp = &types.ChatModelUpdateResponse{}
  175 + //return
  1 +
  2 +syntax = "v1"
  3 +
  4 +info(
  5 + title: "xx实例"
  6 + desc: "xx实例"
  7 + author: "author"
  8 + email: "email"
  9 + version: "v1"
  10 +)
  11 +
  12 +@server(
  13 + prefix: v1
  14 + group: chat_session
  15 + jwt: JwtAuth
  16 +)
  17 +service Core {
  18 + @doc "详情"
  19 + @handler chat_sessionGet
  20 + get /chat_session/:id (ChatSessionGetRequest) returns (ChatSessionGetResponse)
  21 + @doc "保存"
  22 + @handler chat_sessionSave
  23 + post /chat_session (ChatSessionSaveRequest) returns (ChatSessionSaveResponse)
  24 + @doc "删除"
  25 + @handler chat_sessionDelete
  26 + delete /chat_session/:id (ChatSessionDeleteRequest) returns (ChatSessionDeleteResponse)
  27 + @doc "更新"
  28 + @handler chat_sessionUpdate
  29 + put /chat_session/:id (ChatSessionUpdateRequest) returns (ChatSessionUpdateResponse)
  30 + @doc "搜索"
  31 + @handler chat_sessionSearch
  32 + post /chat_session/search (ChatSessionSearchRequest) returns (ChatSessionSearchResponse)
  33 +}
  34 +
  35 +type (
  36 + ChatSessionGetRequest {
  37 + Id int64 `path:"id"`
  38 + }
  39 + ChatSessionGetResponse {
  40 + ChatSession ChatSessionItem `json:"chat_session"`
  41 + }
  42 +
  43 + ChatSessionSaveRequest {
  44 + ChatSession ChatSessionItem `json:"chat_session"`
  45 + }
  46 + ChatSessionSaveResponse {}
  47 +
  48 + ChatSessionDeleteRequest {
  49 + Id int64 `path:"id"`
  50 + }
  51 + ChatSessionDeleteResponse {}
  52 +
  53 + ChatSessionUpdateRequest {
  54 + Id int64 `path:"id"`
  55 + ChatSession ChatSessionItem `json:"chat_session"`
  56 + }
  57 + ChatSessionUpdateResponse {}
  58 +
  59 + ChatSessionSearchRequest {
  60 + Page int `json:"page"`
  61 + Size int `json:"size"`
  62 + }
  63 + ChatSessionSearchResponse{
  64 + List []ChatSessionItem `json:"list"`
  65 + Total int64 `json:"total"`
  66 + }
  67 + ChatSessionItem {
  68 +
  69 + }
  70 +)
  71 +
  72 +// logic CRUD
  73 +// Save
  74 + //var (
  75 + // conn = l.svcCtx.DefaultDBConn()
  76 + // dm *domain.ChatSession
  77 + //)
  78 + //// 唯一判断
  79 +
  80 + //dm = NewDomainChatSession(req.ChatSession)
  81 + //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  82 + // dm, err = l.svcCtx.ChatSessionRepository.Insert(l.ctx, conn, dm)
  83 + // return err
  84 + //}, true); err != nil {
  85 + // return nil, xerr.NewErrMsg("保存失败")
  86 + //}
  87 + ////resp = &types.ChatSessionSaveResponse{}
  88 + //return
  89 +
  90 +//func NewDomainChatSession(item types.ChatSessionItem) *domain.ChatSession {
  91 +// return &domain.ChatSession{
  92 +
  93 +// }
  94 +//}
  95 +//
  96 +//func NewTypesChatSession(item *domain.ChatSession) types.ChatSessionItem {
  97 +// return types.ChatSessionItem{
  98 +// Id: item.Id,
  99 +// }
  100 +//}
  101 +
  102 +// Get
  103 + //var (
  104 + // conn = l.svcCtx.DefaultDBConn()
  105 + // dm *domain.ChatSession
  106 + //)
  107 + //// 货号唯一
  108 + //if dm, err = l.svcCtx.ChatSessionRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  109 + // return nil, xerr.NewErrMsgErr("不存在", err)
  110 + //}
  111 + //resp = &types.ChatSessionGetResponse{
  112 + // ChatSession: NewTypesChatSession(dm),
  113 + //}
  114 + //return
  115 +
  116 +// Delete
  117 + //var (
  118 + // conn = l.svcCtx.DefaultDBConn()
  119 + // dm *domain.ChatSession
  120 + //)
  121 + //if dm, err = l.svcCtx.ChatSessionRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  122 + // return nil, xerr.NewErrMsgErr("不存在", err)
  123 + //}
  124 + //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  125 + // if dm, err = l.svcCtx.ChatSessionRepository.Delete(l.ctx, conn, dm); err != nil {
  126 + // return err
  127 + // }
  128 + // return nil
  129 + //}, true); err != nil {
  130 + // return nil, xerr.NewErrMsgErr("移除失败", err)
  131 + //}
  132 + //return
  133 +
  134 +// Search
  135 + //var (
  136 + // conn = l.svcCtx.DefaultDBConn()
  137 + // dms []*domain.ChatSession
  138 + // total int64
  139 + //)
  140 + //
  141 + //queryOptions := domain.NewQueryOptions().WithOffsetLimit(req.Page, req.Size).
  142 + // WithKV("", "")
  143 +
  144 + //total, dms, err = l.svcCtx.ChatSessionRepository.Find(l.ctx, conn, queryOptions)
  145 + //list := make([]types.ChatSessionItem, 0)
  146 + //for i := range dms {
  147 + // list = append(list, NewTypesChatSession(dms[i]))
  148 + //}
  149 + //resp = &types.ChatSessionSearchResponse{
  150 + // List: list,
  151 + // Total: total,
  152 + //}
  153 + //return
  154 +
  155 +// Update
  156 + //var (
  157 + // conn = l.svcCtx.DefaultDBConn()
  158 + // dm *domain.ChatSession
  159 + //)
  160 + //if dm, err = l.svcCtx.ChatSessionRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  161 + // return nil, xerr.NewErrMsgErr("不存在", err)
  162 + //}
  163 + //// 不可编辑判断
  164 +
  165 + //// 赋值
  166 +
  167 + //// 更新
  168 + //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  169 + // dm, err = l.svcCtx.ChatSessionRepository.UpdateWithVersion(l.ctx, conn, dm)
  170 + // return err
  171 + //}, true); err != nil {
  172 + // return nil, xerr.NewErrMsg("更新失败")
  173 + //}
  174 + //resp = &types.ChatSessionUpdateResponse{}
  175 + //return
  1 +
  2 +syntax = "v1"
  3 +
  4 +info(
  5 + title: "xx实例"
  6 + desc: "xx实例"
  7 + author: "author"
  8 + email: "email"
  9 + version: "v1"
  10 +)
  11 +
  12 +@server(
  13 + prefix: v1
  14 + group: chat_session_record
  15 + jwt: JwtAuth
  16 +)
  17 +service Core {
  18 + @doc "详情"
  19 + @handler chat_session_recordGet
  20 + get /chat_session_record/:id (ChatSessionRecordGetRequest) returns (ChatSessionRecordGetResponse)
  21 + @doc "保存"
  22 + @handler chat_session_recordSave
  23 + post /chat_session_record (ChatSessionRecordSaveRequest) returns (ChatSessionRecordSaveResponse)
  24 + @doc "删除"
  25 + @handler chat_session_recordDelete
  26 + delete /chat_session_record/:id (ChatSessionRecordDeleteRequest) returns (ChatSessionRecordDeleteResponse)
  27 + @doc "更新"
  28 + @handler chat_session_recordUpdate
  29 + put /chat_session_record/:id (ChatSessionRecordUpdateRequest) returns (ChatSessionRecordUpdateResponse)
  30 + @doc "搜索"
  31 + @handler chat_session_recordSearch
  32 + post /chat_session_record/search (ChatSessionRecordSearchRequest) returns (ChatSessionRecordSearchResponse)
  33 +}
  34 +
  35 +type (
  36 + ChatSessionRecordGetRequest {
  37 + Id int64 `path:"id"`
  38 + }
  39 + ChatSessionRecordGetResponse {
  40 + ChatSessionRecord ChatSessionRecordItem `json:"chat_session_record"`
  41 + }
  42 +
  43 + ChatSessionRecordSaveRequest {
  44 + ChatSessionRecord ChatSessionRecordItem `json:"chat_session_record"`
  45 + }
  46 + ChatSessionRecordSaveResponse {}
  47 +
  48 + ChatSessionRecordDeleteRequest {
  49 + Id int64 `path:"id"`
  50 + }
  51 + ChatSessionRecordDeleteResponse {}
  52 +
  53 + ChatSessionRecordUpdateRequest {
  54 + Id int64 `path:"id"`
  55 + ChatSessionRecord ChatSessionRecordItem `json:"chat_session_record"`
  56 + }
  57 + ChatSessionRecordUpdateResponse {}
  58 +
  59 + ChatSessionRecordSearchRequest {
  60 + Page int `json:"page"`
  61 + Size int `json:"size"`
  62 + }
  63 + ChatSessionRecordSearchResponse{
  64 + List []ChatSessionRecordItem `json:"list"`
  65 + Total int64 `json:"total"`
  66 + }
  67 + ChatSessionRecordItem {
  68 +
  69 + }
  70 +)
  71 +
  72 +// logic CRUD
  73 +// Save
  74 + //var (
  75 + // conn = l.svcCtx.DefaultDBConn()
  76 + // dm *domain.ChatSessionRecord
  77 + //)
  78 + //// 唯一判断
  79 +
  80 + //dm = NewDomainChatSessionRecord(req.ChatSessionRecord)
  81 + //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  82 + // dm, err = l.svcCtx.ChatSessionRecordRepository.Insert(l.ctx, conn, dm)
  83 + // return err
  84 + //}, true); err != nil {
  85 + // return nil, xerr.NewErrMsg("保存失败")
  86 + //}
  87 + ////resp = &types.ChatSessionRecordSaveResponse{}
  88 + //return
  89 +
  90 +//func NewDomainChatSessionRecord(item types.ChatSessionRecordItem) *domain.ChatSessionRecord {
  91 +// return &domain.ChatSessionRecord{
  92 +
  93 +// }
  94 +//}
  95 +//
  96 +//func NewTypesChatSessionRecord(item *domain.ChatSessionRecord) types.ChatSessionRecordItem {
  97 +// return types.ChatSessionRecordItem{
  98 +// Id: item.Id,
  99 +// }
  100 +//}
  101 +
  102 +// Get
  103 + //var (
  104 + // conn = l.svcCtx.DefaultDBConn()
  105 + // dm *domain.ChatSessionRecord
  106 + //)
  107 + //// 货号唯一
  108 + //if dm, err = l.svcCtx.ChatSessionRecordRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  109 + // return nil, xerr.NewErrMsgErr("不存在", err)
  110 + //}
  111 + //resp = &types.ChatSessionRecordGetResponse{
  112 + // ChatSessionRecord: NewTypesChatSessionRecord(dm),
  113 + //}
  114 + //return
  115 +
  116 +// Delete
  117 + //var (
  118 + // conn = l.svcCtx.DefaultDBConn()
  119 + // dm *domain.ChatSessionRecord
  120 + //)
  121 + //if dm, err = l.svcCtx.ChatSessionRecordRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  122 + // return nil, xerr.NewErrMsgErr("不存在", err)
  123 + //}
  124 + //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  125 + // if dm, err = l.svcCtx.ChatSessionRecordRepository.Delete(l.ctx, conn, dm); err != nil {
  126 + // return err
  127 + // }
  128 + // return nil
  129 + //}, true); err != nil {
  130 + // return nil, xerr.NewErrMsgErr("移除失败", err)
  131 + //}
  132 + //return
  133 +
  134 +// Search
  135 + //var (
  136 + // conn = l.svcCtx.DefaultDBConn()
  137 + // dms []*domain.ChatSessionRecord
  138 + // total int64
  139 + //)
  140 + //
  141 + //queryOptions := domain.NewQueryOptions().WithOffsetLimit(req.Page, req.Size).
  142 + // WithKV("", "")
  143 +
  144 + //total, dms, err = l.svcCtx.ChatSessionRecordRepository.Find(l.ctx, conn, queryOptions)
  145 + //list := make([]types.ChatSessionRecordItem, 0)
  146 + //for i := range dms {
  147 + // list = append(list, NewTypesChatSessionRecord(dms[i]))
  148 + //}
  149 + //resp = &types.ChatSessionRecordSearchResponse{
  150 + // List: list,
  151 + // Total: total,
  152 + //}
  153 + //return
  154 +
  155 +// Update
  156 + //var (
  157 + // conn = l.svcCtx.DefaultDBConn()
  158 + // dm *domain.ChatSessionRecord
  159 + //)
  160 + //if dm, err = l.svcCtx.ChatSessionRecordRepository.FindOne(l.ctx, conn, req.Id); err != nil {
  161 + // return nil, xerr.NewErrMsgErr("不存在", err)
  162 + //}
  163 + //// 不可编辑判断
  164 +
  165 + //// 赋值
  166 +
  167 + //// 更新
  168 + //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
  169 + // dm, err = l.svcCtx.ChatSessionRecordRepository.UpdateWithVersion(l.ctx, conn, dm)
  170 + // return err
  171 + //}, true); err != nil {
  172 + // return nil, xerr.NewErrMsg("更新失败")
  173 + //}
  174 + //resp = &types.ChatSessionRecordUpdateResponse{}
  175 + //return
  1 +
  2 +syntax = "proto3";
  3 +
  4 +option go_package ="./pb";
  5 +
  6 +package pb;
  7 +
  8 +message ChatModelGetReq {
  9 + int64 Id = 1;
  10 +}
  11 +message ChatModelGetResp{
  12 + ChatModelItem ChatModel = 1;
  13 +}
  14 +
  15 +message ChatModelSaveReq {
  16 +
  17 +}
  18 +message ChatModelSaveResp{
  19 +
  20 +}
  21 +
  22 +message ChatModelDeleteReq {
  23 + int64 Id = 1;
  24 +}
  25 +message ChatModelDeleteResp{
  26 +
  27 +}
  28 +
  29 +message ChatModelUpdateReq {
  30 + int64 Id = 1;
  31 +}
  32 +message ChatModelUpdateResp{
  33 +
  34 +}
  35 +
  36 +message ChatModelSearchReq {
  37 + int64 PageNumber = 1;
  38 + int64 PageSize = 2;
  39 +}
  40 +message ChatModelSearchResp{
  41 + repeated ChatModelItem List =1;
  42 + int64 Total =2;
  43 +}
  44 +message ChatModelItem {
  45 +
  46 +}
  47 +
  48 +service ChatModelService {
  49 + rpc ChatModelGet(ChatModelGetReq) returns(ChatModelGetResp);
  50 + rpc ChatModelSave(ChatModelSaveReq) returns(ChatModelSaveResp);
  51 + rpc ChatModelDelete(ChatModelDeleteReq) returns(ChatModelDeleteResp);
  52 + rpc ChatModelUpdate(ChatModelUpdateReq) returns(ChatModelUpdateResp);
  53 + rpc ChatModelSearch(ChatModelSearchReq) returns(ChatModelSearchResp);
  54 +}
  1 +
  2 +syntax = "proto3";
  3 +
  4 +option go_package ="./pb";
  5 +
  6 +package pb;
  7 +
  8 +message ChatSessionGetReq {
  9 + int64 Id = 1;
  10 +}
  11 +message ChatSessionGetResp{
  12 + ChatSessionItem ChatSession = 1;
  13 +}
  14 +
  15 +message ChatSessionSaveReq {
  16 +
  17 +}
  18 +message ChatSessionSaveResp{
  19 +
  20 +}
  21 +
  22 +message ChatSessionDeleteReq {
  23 + int64 Id = 1;
  24 +}
  25 +message ChatSessionDeleteResp{
  26 +
  27 +}
  28 +
  29 +message ChatSessionUpdateReq {
  30 + int64 Id = 1;
  31 +}
  32 +message ChatSessionUpdateResp{
  33 +
  34 +}
  35 +
  36 +message ChatSessionSearchReq {
  37 + int64 PageNumber = 1;
  38 + int64 PageSize = 2;
  39 +}
  40 +message ChatSessionSearchResp{
  41 + repeated ChatSessionItem List =1;
  42 + int64 Total =2;
  43 +}
  44 +message ChatSessionItem {
  45 +
  46 +}
  47 +
  48 +service ChatSessionService {
  49 + rpc ChatSessionGet(ChatSessionGetReq) returns(ChatSessionGetResp);
  50 + rpc ChatSessionSave(ChatSessionSaveReq) returns(ChatSessionSaveResp);
  51 + rpc ChatSessionDelete(ChatSessionDeleteReq) returns(ChatSessionDeleteResp);
  52 + rpc ChatSessionUpdate(ChatSessionUpdateReq) returns(ChatSessionUpdateResp);
  53 + rpc ChatSessionSearch(ChatSessionSearchReq) returns(ChatSessionSearchResp);
  54 +}
  1 +
  2 +syntax = "proto3";
  3 +
  4 +option go_package ="./pb";
  5 +
  6 +package pb;
  7 +
  8 +message ChatSessionRecordGetReq {
  9 + int64 Id = 1;
  10 +}
  11 +message ChatSessionRecordGetResp{
  12 + ChatSessionRecordItem ChatSessionRecord = 1;
  13 +}
  14 +
  15 +message ChatSessionRecordSaveReq {
  16 +
  17 +}
  18 +message ChatSessionRecordSaveResp{
  19 +
  20 +}
  21 +
  22 +message ChatSessionRecordDeleteReq {
  23 + int64 Id = 1;
  24 +}
  25 +message ChatSessionRecordDeleteResp{
  26 +
  27 +}
  28 +
  29 +message ChatSessionRecordUpdateReq {
  30 + int64 Id = 1;
  31 +}
  32 +message ChatSessionRecordUpdateResp{
  33 +
  34 +}
  35 +
  36 +message ChatSessionRecordSearchReq {
  37 + int64 PageNumber = 1;
  38 + int64 PageSize = 2;
  39 +}
  40 +message ChatSessionRecordSearchResp{
  41 + repeated ChatSessionRecordItem List =1;
  42 + int64 Total =2;
  43 +}
  44 +message ChatSessionRecordItem {
  45 +
  46 +}
  47 +
  48 +service ChatSessionRecordService {
  49 + rpc ChatSessionRecordGet(ChatSessionRecordGetReq) returns(ChatSessionRecordGetResp);
  50 + rpc ChatSessionRecordSave(ChatSessionRecordSaveReq) returns(ChatSessionRecordSaveResp);
  51 + rpc ChatSessionRecordDelete(ChatSessionRecordDeleteReq) returns(ChatSessionRecordDeleteResp);
  52 + rpc ChatSessionRecordUpdate(ChatSessionRecordUpdateReq) returns(ChatSessionRecordUpdateResp);
  53 + rpc ChatSessionRecordSearch(ChatSessionRecordSearchReq) returns(ChatSessionRecordSearchResp);
  54 +}
  1 +package db
  2 +
  3 +import (
  4 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/db/models"
  5 + "gorm.io/gorm"
  6 +)
  7 +
  8 +func Migrate(db *gorm.DB) {
  9 + db.AutoMigrate(
  10 + &models.ChatSession{},
  11 + &models.ChatSessionRecord{},
  12 + )
  13 +}
  1 +package models
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  6 + "gorm.io/gorm"
  7 + "gorm.io/plugin/soft_delete"
  8 +)
  9 +
  10 +type ChatModel struct {
  11 + Id int64 // 唯一标识
  12 + CreatedAt int64
  13 + UpdatedAt int64
  14 + DeletedAt int64
  15 + Version int
  16 + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"`
  17 +}
  18 +
  19 +func (m *ChatModel) TableName() string {
  20 + return "chat.model"
  21 +}
  22 +
  23 +func (m *ChatModel) BeforeCreate(tx *gorm.DB) (err error) {
  24 + // m.CreatedAt = time.Now().Unix()
  25 + // m.UpdatedAt = time.Now().Unix()
  26 + return
  27 +}
  28 +
  29 +func (m *ChatModel) BeforeUpdate(tx *gorm.DB) (err error) {
  30 + // m.UpdatedAt = time.Now().Unix()
  31 + return
  32 +}
  33 +
  34 +func (m *ChatModel) CacheKeyFunc() string {
  35 + if m.Id == 0 {
  36 + return ""
  37 + }
  38 + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
  39 +}
  40 +
  41 +func (m *ChatModel) CacheKeyFuncByObject(obj interface{}) string {
  42 + if v, ok := obj.(*ChatModel); ok {
  43 + return v.CacheKeyFunc()
  44 + }
  45 + return ""
  46 +}
  47 +
  48 +func (m *ChatModel) CachePrimaryKeyFunc() string {
  49 + if len("") == 0 {
  50 + return ""
  51 + }
  52 + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
  53 +}
  1 +package models
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  6 + "gorm.io/gorm"
  7 + "gorm.io/plugin/soft_delete"
  8 +)
  9 +
  10 +type ChatSession struct {
  11 + Id int64 // 唯一标识
  12 + CompanyId int64 // 公司ID
  13 + UserId int64 // 用户ID
  14 + Title string // 会话标题
  15 + Abstract string // 摘要
  16 + CreatedAt int64
  17 + UpdatedAt int64
  18 + DeletedAt int64
  19 + Version int
  20 + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"`
  21 +}
  22 +
  23 +func (m *ChatSession) TableName() string {
  24 + return "chat.session"
  25 +}
  26 +
  27 +func (m *ChatSession) BeforeCreate(tx *gorm.DB) (err error) {
  28 + // m.CreatedAt = time.Now().Unix()
  29 + // m.UpdatedAt = time.Now().Unix()
  30 + return
  31 +}
  32 +
  33 +func (m *ChatSession) BeforeUpdate(tx *gorm.DB) (err error) {
  34 + // m.UpdatedAt = time.Now().Unix()
  35 + return
  36 +}
  37 +
  38 +func (m *ChatSession) CacheKeyFunc() string {
  39 + if m.Id == 0 {
  40 + return ""
  41 + }
  42 + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
  43 +}
  44 +
  45 +func (m *ChatSession) CacheKeyFuncByObject(obj interface{}) string {
  46 + if v, ok := obj.(*ChatSession); ok {
  47 + return v.CacheKeyFunc()
  48 + }
  49 + return ""
  50 +}
  51 +
  52 +func (m *ChatSession) CachePrimaryKeyFunc() string {
  53 + if len("") == 0 {
  54 + return ""
  55 + }
  56 + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
  57 +}
  1 +package models
  2 +
  3 +import (
  4 + "fmt"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  6 + "gorm.io/gorm"
  7 + "gorm.io/plugin/soft_delete"
  8 +)
  9 +
  10 +type ChatSessionRecord struct {
  11 + Id int64 // 唯一标识
  12 + Group int64 // 分组(一个问题多次重复提问)
  13 + CompanyId int64 // 公司ID
  14 + UserId int64 // 用户ID
  15 + SessionId int64 // 会话ID
  16 + ModelId int64 // 选择模型ID
  17 + Author domain.User `gorm:"type:jsonb;serializer:json"` // 作者
  18 + ContentType string // 内容类型 文本:text (图片:image 文档:document)
  19 + ProblemText string // 问题文本
  20 + AnswerText string // 回答文本
  21 + Metadata domain.Metadata `gorm:"type:jsonb;serializer:json"` // 记录元数据
  22 + Cost int64 // 花费时间 单位毫秒
  23 + Status string // 状态 处理中:processing 超时:finished_timeout 结束成功:finished_fail 结束失败:finished_success
  24 + CreatedAt int64
  25 + UpdatedAt int64
  26 + DeletedAt int64
  27 + Version int
  28 + IsDel soft_delete.DeletedAt `gorm:"softDelete:flag,DeletedAtField:DeletedAt"`
  29 +}
  30 +
  31 +func (m *ChatSessionRecord) TableName() string {
  32 + return "chat.session_record"
  33 +}
  34 +
  35 +func (m *ChatSessionRecord) BeforeCreate(tx *gorm.DB) (err error) {
  36 + // m.CreatedAt = time.Now().Unix()
  37 + // m.UpdatedAt = time.Now().Unix()
  38 + return
  39 +}
  40 +
  41 +func (m *ChatSessionRecord) BeforeUpdate(tx *gorm.DB) (err error) {
  42 + // m.UpdatedAt = time.Now().Unix()
  43 + return
  44 +}
  45 +
  46 +func (m *ChatSessionRecord) CacheKeyFunc() string {
  47 + if m.Id == 0 {
  48 + return ""
  49 + }
  50 + return fmt.Sprintf("%v:cache:%v:id:%v", domain.ProjectName, m.TableName(), m.Id)
  51 +}
  52 +
  53 +func (m *ChatSessionRecord) CacheKeyFuncByObject(obj interface{}) string {
  54 + if v, ok := obj.(*ChatSessionRecord); ok {
  55 + return v.CacheKeyFunc()
  56 + }
  57 + return ""
  58 +}
  59 +
  60 +func (m *ChatSessionRecord) CachePrimaryKeyFunc() string {
  61 + if len("") == 0 {
  62 + return ""
  63 + }
  64 + return fmt.Sprintf("%v:cache:%v:primarykey:%v", domain.ProjectName, m.TableName(), "key")
  65 +}
  1 +package repository
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/jinzhu/copier"
  6 + "github.com/pkg/errors"
  7 + "github.com/tiptok/gocomm/pkg/cache"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/db/models"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  11 + "gorm.io/gorm"
  12 +)
  13 +
  14 +type ChatModelRepository struct {
  15 + *cache.CachedRepository
  16 +}
  17 +
  18 +func (repository *ChatModelRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.ChatModel) (*domain.ChatModel, error) {
  19 + var (
  20 + err error
  21 + m = &models.ChatModel{}
  22 + tx = conn.DB()
  23 + )
  24 + if m, err = repository.DomainModelToModel(dm); err != nil {
  25 + return nil, err
  26 + }
  27 + if tx = tx.Model(m).Save(m); tx.Error != nil {
  28 + return nil, tx.Error
  29 + }
  30 + dm.Id = m.Id
  31 + return repository.ModelToDomainModel(m)
  32 +
  33 +}
  34 +
  35 +func (repository *ChatModelRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.ChatModel) (*domain.ChatModel, error) {
  36 + var (
  37 + err error
  38 + m *models.ChatModel
  39 + tx = conn.DB()
  40 + )
  41 + if m, err = repository.DomainModelToModel(dm); err != nil {
  42 + return nil, err
  43 + }
  44 + queryFunc := func() (interface{}, error) {
  45 + tx = tx.Model(m).Updates(m)
  46 + return nil, tx.Error
  47 + }
  48 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  49 + return nil, err
  50 + }
  51 + return repository.ModelToDomainModel(m)
  52 +}
  53 +
  54 +func (repository *ChatModelRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.ChatModel) (*domain.ChatModel, error) {
  55 + var (
  56 + err error
  57 + m *models.ChatModel
  58 + tx = transaction.DB()
  59 + )
  60 + if m, err = repository.DomainModelToModel(dm); err != nil {
  61 + return nil, err
  62 + }
  63 + oldVersion := dm.Version
  64 + m.Version += 1
  65 + queryFunc := func() (interface{}, error) {
  66 + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
  67 + if tx.RowsAffected == 0 {
  68 + return nil, domain.ErrUpdateFail
  69 + }
  70 + return nil, tx.Error
  71 + }
  72 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  73 + return nil, err
  74 + }
  75 + return repository.ModelToDomainModel(m)
  76 +}
  77 +
  78 +func (repository *ChatModelRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.ChatModel) (*domain.ChatModel, error) {
  79 + var (
  80 + tx = conn.DB()
  81 + m = &models.ChatModel{Id: dm.Id}
  82 + )
  83 + queryFunc := func() (interface{}, error) {
  84 + tx = tx.Where("id = ?", m.Id).Delete(m)
  85 + return m, tx.Error
  86 + }
  87 + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  88 + return dm, err
  89 + }
  90 + return repository.ModelToDomainModel(m)
  91 +}
  92 +
  93 +func (repository *ChatModelRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.ChatModel, error) {
  94 + var (
  95 + err error
  96 + tx = conn.DB()
  97 + m = new(models.ChatModel)
  98 + )
  99 + queryFunc := func() (interface{}, error) {
  100 + tx = tx.Model(m).Where("id = ?", id).First(m)
  101 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  102 + return nil, domain.ErrNotFound
  103 + }
  104 + return m, tx.Error
  105 + }
  106 + cacheModel := new(models.ChatModel)
  107 + cacheModel.Id = id
  108 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  109 + return nil, err
  110 + }
  111 + return repository.ModelToDomainModel(m)
  112 +}
  113 +
  114 +func (repository *ChatModelRepository) FindOneUnscoped(ctx context.Context, conn transaction.Conn, id int64) (*domain.ChatModel, error) {
  115 + var (
  116 + err error
  117 + tx = conn.DB()
  118 + m = new(models.ChatModel)
  119 + )
  120 + queryFunc := func() (interface{}, error) {
  121 + tx = tx.Model(m).Unscoped().Where("id = ?", id).First(m)
  122 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  123 + return nil, domain.ErrNotFound
  124 + }
  125 + return m, tx.Error
  126 + }
  127 + cacheModel := new(models.ChatModel)
  128 + cacheModel.Id = id
  129 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  130 + return nil, err
  131 + }
  132 + return repository.ModelToDomainModel(m)
  133 +}
  134 +
  135 +func (repository *ChatModelRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.ChatModel, error) {
  136 + var (
  137 + tx = conn.DB()
  138 + ms []*models.ChatModel
  139 + dms = make([]*domain.ChatModel, 0)
  140 + total int64
  141 + )
  142 + queryFunc := func() (interface{}, error) {
  143 + tx = tx.Model(&ms).Order("id desc")
  144 + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
  145 + return dms, tx.Error
  146 + }
  147 + return dms, nil
  148 + }
  149 +
  150 + if _, err := repository.Query(queryFunc); err != nil {
  151 + return 0, nil, err
  152 + }
  153 +
  154 + for _, item := range ms {
  155 + if dm, err := repository.ModelToDomainModel(item); err != nil {
  156 + return 0, dms, err
  157 + } else {
  158 + dms = append(dms, dm)
  159 + }
  160 + }
  161 + return total, dms, nil
  162 +}
  163 +
  164 +func (repository *ChatModelRepository) ModelToDomainModel(from *models.ChatModel) (*domain.ChatModel, error) {
  165 + to := &domain.ChatModel{}
  166 + err := copier.Copy(to, from)
  167 + return to, err
  168 +}
  169 +
  170 +func (repository *ChatModelRepository) DomainModelToModel(from *domain.ChatModel) (*models.ChatModel, error) {
  171 + to := &models.ChatModel{}
  172 + err := copier.Copy(to, from)
  173 + return to, err
  174 +}
  175 +
  176 +func NewChatModelRepository(cache *cache.CachedRepository) domain.ChatModelRepository {
  177 + return &ChatModelRepository{CachedRepository: cache}
  178 +}
  1 +package repository
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/jinzhu/copier"
  6 + "github.com/pkg/errors"
  7 + "github.com/tiptok/gocomm/pkg/cache"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/db/models"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  11 + "gorm.io/gorm"
  12 +)
  13 +
  14 +type ChatSessionRecordRepository struct {
  15 + *cache.CachedRepository
  16 +}
  17 +
  18 +func (repository *ChatSessionRecordRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.ChatSessionRecord) (*domain.ChatSessionRecord, error) {
  19 + var (
  20 + err error
  21 + m = &models.ChatSessionRecord{}
  22 + tx = conn.DB()
  23 + )
  24 + if m, err = repository.DomainModelToModel(dm); err != nil {
  25 + return nil, err
  26 + }
  27 + if tx = tx.Model(m).Save(m); tx.Error != nil {
  28 + return nil, tx.Error
  29 + }
  30 + dm.Id = m.Id
  31 + return repository.ModelToDomainModel(m)
  32 +
  33 +}
  34 +
  35 +func (repository *ChatSessionRecordRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.ChatSessionRecord) (*domain.ChatSessionRecord, error) {
  36 + var (
  37 + err error
  38 + m *models.ChatSessionRecord
  39 + tx = conn.DB()
  40 + )
  41 + if m, err = repository.DomainModelToModel(dm); err != nil {
  42 + return nil, err
  43 + }
  44 + queryFunc := func() (interface{}, error) {
  45 + tx = tx.Model(m).Updates(m)
  46 + return nil, tx.Error
  47 + }
  48 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  49 + return nil, err
  50 + }
  51 + return repository.ModelToDomainModel(m)
  52 +}
  53 +
  54 +func (repository *ChatSessionRecordRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.ChatSessionRecord) (*domain.ChatSessionRecord, error) {
  55 + var (
  56 + err error
  57 + m *models.ChatSessionRecord
  58 + tx = transaction.DB()
  59 + )
  60 + if m, err = repository.DomainModelToModel(dm); err != nil {
  61 + return nil, err
  62 + }
  63 + oldVersion := dm.Version
  64 + m.Version += 1
  65 + queryFunc := func() (interface{}, error) {
  66 + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
  67 + if tx.RowsAffected == 0 {
  68 + return nil, domain.ErrUpdateFail
  69 + }
  70 + return nil, tx.Error
  71 + }
  72 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  73 + return nil, err
  74 + }
  75 + return repository.ModelToDomainModel(m)
  76 +}
  77 +
  78 +func (repository *ChatSessionRecordRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.ChatSessionRecord) (*domain.ChatSessionRecord, error) {
  79 + var (
  80 + tx = conn.DB()
  81 + m = &models.ChatSessionRecord{Id: dm.Id}
  82 + )
  83 + queryFunc := func() (interface{}, error) {
  84 + tx = tx.Where("id = ?", m.Id).Delete(m)
  85 + return m, tx.Error
  86 + }
  87 + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  88 + return dm, err
  89 + }
  90 + return repository.ModelToDomainModel(m)
  91 +}
  92 +
  93 +func (repository *ChatSessionRecordRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.ChatSessionRecord, error) {
  94 + var (
  95 + err error
  96 + tx = conn.DB()
  97 + m = new(models.ChatSessionRecord)
  98 + )
  99 + queryFunc := func() (interface{}, error) {
  100 + tx = tx.Model(m).Where("id = ?", id).First(m)
  101 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  102 + return nil, domain.ErrNotFound
  103 + }
  104 + return m, tx.Error
  105 + }
  106 + cacheModel := new(models.ChatSessionRecord)
  107 + cacheModel.Id = id
  108 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  109 + return nil, err
  110 + }
  111 + return repository.ModelToDomainModel(m)
  112 +}
  113 +
  114 +func (repository *ChatSessionRecordRepository) FindOneUnscoped(ctx context.Context, conn transaction.Conn, id int64) (*domain.ChatSessionRecord, error) {
  115 + var (
  116 + err error
  117 + tx = conn.DB()
  118 + m = new(models.ChatSessionRecord)
  119 + )
  120 + queryFunc := func() (interface{}, error) {
  121 + tx = tx.Model(m).Unscoped().Where("id = ?", id).First(m)
  122 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  123 + return nil, domain.ErrNotFound
  124 + }
  125 + return m, tx.Error
  126 + }
  127 + cacheModel := new(models.ChatSessionRecord)
  128 + cacheModel.Id = id
  129 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  130 + return nil, err
  131 + }
  132 + return repository.ModelToDomainModel(m)
  133 +}
  134 +
  135 +func (repository *ChatSessionRecordRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.ChatSessionRecord, error) {
  136 + var (
  137 + tx = conn.DB()
  138 + ms []*models.ChatSessionRecord
  139 + dms = make([]*domain.ChatSessionRecord, 0)
  140 + total int64
  141 + )
  142 + queryFunc := func() (interface{}, error) {
  143 + tx = tx.Model(&ms).Order("id asc")
  144 + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
  145 + return dms, tx.Error
  146 + }
  147 + return dms, nil
  148 + }
  149 +
  150 + if _, err := repository.Query(queryFunc); err != nil {
  151 + return 0, nil, err
  152 + }
  153 +
  154 + for _, item := range ms {
  155 + if dm, err := repository.ModelToDomainModel(item); err != nil {
  156 + return 0, dms, err
  157 + } else {
  158 + dms = append(dms, dm)
  159 + }
  160 + }
  161 + return total, dms, nil
  162 +}
  163 +
  164 +func (repository *ChatSessionRecordRepository) FindByCompanyUser(ctx context.Context, conn transaction.Conn, companyId, userId int64, queryOptions map[string]interface{}) (int64, []*domain.ChatSessionRecord, error) {
  165 + var (
  166 + tx = conn.DB()
  167 + ms []*models.ChatSessionRecord
  168 + dms = make([]*domain.ChatSessionRecord, 0)
  169 + total int64
  170 + )
  171 + queryFunc := func() (interface{}, error) {
  172 + tx = tx.Model(&ms).Order("id asc")
  173 + tx.Where("company_id = ?", companyId).Where("user_id = ?", userId)
  174 + if v, ok := queryOptions["sessionId"]; ok {
  175 + tx.Where("session_id =?", v)
  176 + }
  177 + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
  178 + return dms, tx.Error
  179 + }
  180 + return dms, nil
  181 + }
  182 +
  183 + if _, err := repository.Query(queryFunc); err != nil {
  184 + return 0, nil, err
  185 + }
  186 +
  187 + for _, item := range ms {
  188 + if dm, err := repository.ModelToDomainModel(item); err != nil {
  189 + return 0, dms, err
  190 + } else {
  191 + dms = append(dms, dm)
  192 + }
  193 + }
  194 + return total, dms, nil
  195 +}
  196 +
  197 +func (repository *ChatSessionRecordRepository) ModelToDomainModel(from *models.ChatSessionRecord) (*domain.ChatSessionRecord, error) {
  198 + to := &domain.ChatSessionRecord{}
  199 + err := copier.Copy(to, from)
  200 + return to, err
  201 +}
  202 +
  203 +func (repository *ChatSessionRecordRepository) DomainModelToModel(from *domain.ChatSessionRecord) (*models.ChatSessionRecord, error) {
  204 + to := &models.ChatSessionRecord{}
  205 + err := copier.Copy(to, from)
  206 + return to, err
  207 +}
  208 +
  209 +func NewChatSessionRecordRepository(cache *cache.CachedRepository) domain.ChatSessionRecordRepository {
  210 + return &ChatSessionRecordRepository{CachedRepository: cache}
  211 +}
  1 +package repository
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/jinzhu/copier"
  6 + "github.com/pkg/errors"
  7 + "github.com/tiptok/gocomm/pkg/cache"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/db/models"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  11 + "gorm.io/gorm"
  12 +)
  13 +
  14 +type ChatSessionRepository struct {
  15 + *cache.CachedRepository
  16 +}
  17 +
  18 +func (repository *ChatSessionRepository) Insert(ctx context.Context, conn transaction.Conn, dm *domain.ChatSession) (*domain.ChatSession, error) {
  19 + var (
  20 + err error
  21 + m = &models.ChatSession{}
  22 + tx = conn.DB()
  23 + )
  24 + if m, err = repository.DomainModelToModel(dm); err != nil {
  25 + return nil, err
  26 + }
  27 + if tx = tx.Model(m).Save(m); tx.Error != nil {
  28 + return nil, tx.Error
  29 + }
  30 + dm.Id = m.Id
  31 + return repository.ModelToDomainModel(m)
  32 +
  33 +}
  34 +
  35 +func (repository *ChatSessionRepository) Update(ctx context.Context, conn transaction.Conn, dm *domain.ChatSession) (*domain.ChatSession, error) {
  36 + var (
  37 + err error
  38 + m *models.ChatSession
  39 + tx = conn.DB()
  40 + )
  41 + if m, err = repository.DomainModelToModel(dm); err != nil {
  42 + return nil, err
  43 + }
  44 + queryFunc := func() (interface{}, error) {
  45 + tx = tx.Model(m).Updates(m)
  46 + return nil, tx.Error
  47 + }
  48 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  49 + return nil, err
  50 + }
  51 + return repository.ModelToDomainModel(m)
  52 +}
  53 +
  54 +func (repository *ChatSessionRepository) UpdateWithVersion(ctx context.Context, transaction transaction.Conn, dm *domain.ChatSession) (*domain.ChatSession, error) {
  55 + var (
  56 + err error
  57 + m *models.ChatSession
  58 + tx = transaction.DB()
  59 + )
  60 + if m, err = repository.DomainModelToModel(dm); err != nil {
  61 + return nil, err
  62 + }
  63 + oldVersion := dm.Version
  64 + m.Version += 1
  65 + queryFunc := func() (interface{}, error) {
  66 + tx = tx.Model(m).Select("*").Where("id = ?", m.Id).Where("version = ?", oldVersion).Updates(m)
  67 + if tx.RowsAffected == 0 {
  68 + return nil, domain.ErrUpdateFail
  69 + }
  70 + return nil, tx.Error
  71 + }
  72 + if _, err = repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  73 + return nil, err
  74 + }
  75 + return repository.ModelToDomainModel(m)
  76 +}
  77 +
  78 +func (repository *ChatSessionRepository) Delete(ctx context.Context, conn transaction.Conn, dm *domain.ChatSession) (*domain.ChatSession, error) {
  79 + var (
  80 + tx = conn.DB()
  81 + m = &models.ChatSession{Id: dm.Id}
  82 + )
  83 + queryFunc := func() (interface{}, error) {
  84 + tx = tx.Where("id = ?", m.Id).Delete(m)
  85 + return m, tx.Error
  86 + }
  87 + if _, err := repository.Query(queryFunc, m.CacheKeyFunc()); err != nil {
  88 + return dm, err
  89 + }
  90 + return repository.ModelToDomainModel(m)
  91 +}
  92 +
  93 +func (repository *ChatSessionRepository) FindOne(ctx context.Context, conn transaction.Conn, id int64) (*domain.ChatSession, error) {
  94 + var (
  95 + err error
  96 + tx = conn.DB()
  97 + m = new(models.ChatSession)
  98 + )
  99 + queryFunc := func() (interface{}, error) {
  100 + tx = tx.Model(m).Where("id = ?", id).First(m)
  101 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  102 + return nil, domain.ErrNotFound
  103 + }
  104 + return m, tx.Error
  105 + }
  106 + cacheModel := new(models.ChatSession)
  107 + cacheModel.Id = id
  108 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  109 + return nil, err
  110 + }
  111 + return repository.ModelToDomainModel(m)
  112 +}
  113 +
  114 +func (repository *ChatSessionRepository) FindOneUnscoped(ctx context.Context, conn transaction.Conn, id int64) (*domain.ChatSession, error) {
  115 + var (
  116 + err error
  117 + tx = conn.DB()
  118 + m = new(models.ChatSession)
  119 + )
  120 + queryFunc := func() (interface{}, error) {
  121 + tx = tx.Model(m).Unscoped().Where("id = ?", id).First(m)
  122 + if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
  123 + return nil, domain.ErrNotFound
  124 + }
  125 + return m, tx.Error
  126 + }
  127 + cacheModel := new(models.ChatSession)
  128 + cacheModel.Id = id
  129 + if err = repository.QueryCache(cacheModel.CacheKeyFunc, m, queryFunc); err != nil {
  130 + return nil, err
  131 + }
  132 + return repository.ModelToDomainModel(m)
  133 +}
  134 +
  135 +func (repository *ChatSessionRepository) Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*domain.ChatSession, error) {
  136 + var (
  137 + tx = conn.DB()
  138 + ms []*models.ChatSession
  139 + dms = make([]*domain.ChatSession, 0)
  140 + total int64
  141 + )
  142 + queryFunc := func() (interface{}, error) {
  143 + tx = tx.Model(&ms).Order("id desc")
  144 + if v, ok := queryOptions["title"]; ok {
  145 + tx.Where("title like ?", v)
  146 + }
  147 + if total, tx = transaction.PaginationAndCount(ctx, tx, queryOptions, &ms); tx.Error != nil {
  148 + return dms, tx.Error
  149 + }
  150 + return dms, nil
  151 + }
  152 +
  153 + if _, err := repository.Query(queryFunc); err != nil {
  154 + return 0, nil, err
  155 + }
  156 +
  157 + for _, item := range ms {
  158 + if dm, err := repository.ModelToDomainModel(item); err != nil {
  159 + return 0, dms, err
  160 + } else {
  161 + dms = append(dms, dm)
  162 + }
  163 + }
  164 + return total, dms, nil
  165 +}
  166 +
  167 +func (repository *ChatSessionRepository) ModelToDomainModel(from *models.ChatSession) (*domain.ChatSession, error) {
  168 + to := &domain.ChatSession{}
  169 + err := copier.Copy(to, from)
  170 + return to, err
  171 +}
  172 +
  173 +func (repository *ChatSessionRepository) DomainModelToModel(from *domain.ChatSession) (*models.ChatSession, error) {
  174 + to := &models.ChatSession{}
  175 + err := copier.Copy(to, from)
  176 + return to, err
  177 +}
  178 +
  179 +func NewChatSessionRepository(cache *cache.CachedRepository) domain.ChatSessionRepository {
  180 + return &ChatSessionRepository{CachedRepository: cache}
  181 +}
  1 +package domain
  2 +
  3 +import (
  4 + "context"
  5 + "github.com/samber/lo"
  6 + "github.com/sashabaranov/go-openai"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  8 +)
  9 +
  10 +type ChatModel struct {
  11 + Id int64 `json:",omitempty"` // 唯一标识
  12 + Name string `json:",omitempty"`
  13 + Code string `json:",omitempty"`
  14 + Logo string `json:",omitempty"`
  15 + Config ModelConfig `json:",omitempty"`
  16 + CreatedAt int64 `json:",omitempty"`
  17 + UpdatedAt int64 `json:",omitempty"`
  18 + DeletedAt int64 `json:",omitempty"`
  19 + Version int `json:",omitempty"`
  20 +}
  21 +
  22 +type ChatModelRepository interface {
  23 + Insert(ctx context.Context, conn transaction.Conn, dm *ChatModel) (*ChatModel, error)
  24 + Update(ctx context.Context, conn transaction.Conn, dm *ChatModel) (*ChatModel, error)
  25 + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *ChatModel) (*ChatModel, error)
  26 + Delete(ctx context.Context, conn transaction.Conn, dm *ChatModel) (*ChatModel, error)
  27 + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ChatModel, error)
  28 + FindOneUnscoped(ctx context.Context, conn transaction.Conn, id int64) (*ChatModel, error)
  29 + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ChatModel, error)
  30 +}
  31 +
  32 +type ChatModels []*ChatModel
  33 +
  34 +func (list ChatModels) Match(id int64) (*ChatModel, bool) {
  35 + return lo.Find(list, func(item *ChatModel) bool {
  36 + if item.Id == id {
  37 + return true
  38 + }
  39 + return false
  40 + })
  41 +}
  42 +
  43 +var DefaultChatModels ChatModels = []*ChatModel{
  44 + NewChatModels(1, "ChatGPT 4o", openai.GPT4o, "", NewModelConfig("", "sk-proj-0odTHgsYqzGpjPMWYuw2T3BlbkFJpaIsQ9I6j8kYc8P7l60H", "")),
  45 + NewChatModels(2, "ChatGPT 4-turbo", openai.GPT4Turbo, "", NewModelConfig("", "sk-proj-0odTHgsYqzGpjPMWYuw2T3BlbkFJpaIsQ9I6j8kYc8P7l60H", "")),
  46 + NewChatModels(3, "ChatGPT 3.5", openai.GPT3Dot5Turbo, "", NewModelConfig("", "sk-proj-0odTHgsYqzGpjPMWYuw2T3BlbkFJpaIsQ9I6j8kYc8P7l60H", "")),
  47 + NewChatModels(4, "星火大模型V3.5", "spark3.5", "", NewModelConfig("4fd8694e", "4a4081a20e9ba0fb1b9686ed93221989", "NTVkM2FjNzk2NzQ5MzBkNWMwYTUwNjAz")),
  48 +}
  49 +
  50 +type ModelConfig struct {
  51 + AppId string
  52 + AppKey string
  53 + AppSecret string
  54 +}
  55 +
  56 +func NewModelConfig(appid, appKey, appSecret string) ModelConfig {
  57 + return ModelConfig{
  58 + AppId: appid,
  59 + AppKey: appKey,
  60 + AppSecret: appSecret,
  61 + }
  62 +}
  63 +
  64 +func NewChatModels(id int64, name, code string, logo string, config ModelConfig) *ChatModel {
  65 + return &ChatModel{
  66 + Id: id,
  67 + Name: name,
  68 + Code: code,
  69 + Logo: logo,
  70 + Config: config,
  71 + }
  72 +}
  1 +package domain
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  6 +)
  7 +
  8 +type ChatSession struct {
  9 + Id int64 `json:",omitempty"` // 唯一标识
  10 + CompanyId int64 `json:",omitempty"` // 公司ID
  11 + UserId int64 `json:",omitempty"` // 用户ID
  12 + Title string `json:",omitempty"` // 会话标题
  13 + Abstract string `json:",omitempty"` // 摘要
  14 + CreatedAt int64 `json:",omitempty"`
  15 + UpdatedAt int64 `json:",omitempty"`
  16 + DeletedAt int64 `json:",omitempty"`
  17 + Version int `json:",omitempty"`
  18 +}
  19 +
  20 +type ChatSessionRepository interface {
  21 + Insert(ctx context.Context, conn transaction.Conn, dm *ChatSession) (*ChatSession, error)
  22 + Update(ctx context.Context, conn transaction.Conn, dm *ChatSession) (*ChatSession, error)
  23 + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *ChatSession) (*ChatSession, error)
  24 + Delete(ctx context.Context, conn transaction.Conn, dm *ChatSession) (*ChatSession, error)
  25 + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ChatSession, error)
  26 + FindOneUnscoped(ctx context.Context, conn transaction.Conn, id int64) (*ChatSession, error)
  27 + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ChatSession, error)
  28 +}
  1 +package domain
  2 +
  3 +import (
  4 + "context"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  6 +)
  7 +
  8 +type ChatSessionRecord struct {
  9 + Id int64 // 唯一标识
  10 + Group int64 // 分组(一个问题多次重复提问)
  11 + CompanyId int64 // 公司ID
  12 + UserId int64 // 用户ID
  13 + SessionId int64 // 会话ID
  14 + ModelId int64 // 选择模型ID
  15 + Author User // 作者
  16 + ContentType string // 内容类型 文本:text (图片:image 文档:document)
  17 + ProblemText string // 问题文本
  18 + AnswerText string // 回答文本
  19 + Metadata Metadata // 记录元数据
  20 + Cost int64 // 花费时间 单位毫秒
  21 + Status string // 状态 处理中:processing 超时:finished_timeout 结束成功:finished_fail 结束失败:finished_success
  22 + CreatedAt int64 `json:",omitempty"`
  23 + UpdatedAt int64 `json:",omitempty"`
  24 + DeletedAt int64 `json:",omitempty"`
  25 + Version int `json:",omitempty"`
  26 +}
  27 +
  28 +const (
  29 + Processing = "processing"
  30 + FinishedTimeout = "finished_timeout"
  31 + FinishedFail = "finished_fail"
  32 + FinishedSuccess = "finished_success"
  33 +)
  34 +
  35 +type User struct {
  36 + Id int64
  37 + Name string
  38 + Avatar string
  39 + Role string // 角色类型 用户:user 模型:model
  40 +}
  41 +
  42 +type Metadata struct {
  43 + FailReason string // 失败原因
  44 +}
  45 +
  46 +type ChatSessionRecordRepository interface {
  47 + Insert(ctx context.Context, conn transaction.Conn, dm *ChatSessionRecord) (*ChatSessionRecord, error)
  48 + Update(ctx context.Context, conn transaction.Conn, dm *ChatSessionRecord) (*ChatSessionRecord, error)
  49 + UpdateWithVersion(ctx context.Context, conn transaction.Conn, dm *ChatSessionRecord) (*ChatSessionRecord, error)
  50 + Delete(ctx context.Context, conn transaction.Conn, dm *ChatSessionRecord) (*ChatSessionRecord, error)
  51 + FindOne(ctx context.Context, conn transaction.Conn, id int64) (*ChatSessionRecord, error)
  52 + FindOneUnscoped(ctx context.Context, conn transaction.Conn, id int64) (*ChatSessionRecord, error)
  53 + Find(ctx context.Context, conn transaction.Conn, queryOptions map[string]interface{}) (int64, []*ChatSessionRecord, error)
  54 + FindByCompanyUser(ctx context.Context, conn transaction.Conn, companyId, userId int64, queryOptions map[string]interface{}) (int64, []*ChatSessionRecord, error)
  55 +}
  1 +package domain
  2 +
  3 +import (
  4 + "context"
  5 + "fmt"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
  7 + "reflect"
  8 +)
  9 +
  10 +func OffsetLimit(page, size int) (offset int, limit int) {
  11 + if page == 0 {
  12 + page = 1
  13 + }
  14 + if size == 0 {
  15 + size = 20
  16 + }
  17 + offset = (page - 1) * size
  18 + limit = size
  19 + return
  20 +}
  21 +
  22 +type QueryOptions map[string]interface{}
  23 +
  24 +func NewQueryOptions() QueryOptions {
  25 + options := make(map[string]interface{})
  26 + return options
  27 +}
  28 +func (options QueryOptions) WithOffsetLimit(page, size int) QueryOptions {
  29 + offset, limit := OffsetLimit(page, size)
  30 + options["offset"] = offset
  31 + options["limit"] = limit
  32 + return options
  33 +}
  34 +
  35 +func (options QueryOptions) WithKV(key string, value interface{}) QueryOptions {
  36 + if isEmptyOrZeroValue(value) {
  37 + return options
  38 + }
  39 + options[key] = value
  40 + return options
  41 +}
  42 +
  43 +func isEmptyOrZeroValue(i interface{}) bool {
  44 + if i == nil {
  45 + return true // 如果接口为空,返回true
  46 + }
  47 + // 使用反射判断接口的值是否为零值
  48 + v := reflect.ValueOf(i)
  49 + switch v.Kind() {
  50 + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice, reflect.String:
  51 + return v.Len() == 0
  52 + case reflect.Bool:
  53 + return !v.Bool()
  54 + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  55 + return v.Int() == 0
  56 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  57 + return v.Uint() == 0
  58 + case reflect.Float32, reflect.Float64:
  59 + return v.Float() == 0
  60 + case reflect.Interface, reflect.Ptr:
  61 + return v.IsNil()
  62 + default:
  63 + return false // 其他类型默认不为空
  64 + }
  65 +}
  66 +
  67 +func (options QueryOptions) MustWithKV(key string, value interface{}) QueryOptions {
  68 + options[key] = value
  69 + return options
  70 +}
  71 +
  72 +func (options QueryOptions) Copy() QueryOptions {
  73 + newOptions := NewQueryOptions()
  74 + for k, v := range options {
  75 + newOptions[k] = v
  76 + }
  77 + return newOptions
  78 +}
  79 +
  80 +type IndexQueryOptionFunc func() QueryOptions
  81 +
  82 +// 自定义的一些查询条件
  83 +
  84 +func (options QueryOptions) WithCountOnly() QueryOptions {
  85 + options["countOnly"] = true
  86 + return options
  87 +}
  88 +func (options QueryOptions) WithFindOnly() QueryOptions {
  89 + options["findOnly"] = true
  90 + return options
  91 +}
  92 +
  93 +func LazyLoad[K comparable, T any](source map[K]T, ctx context.Context, conn transaction.Conn, k K, load func(context.Context, transaction.Conn, K) (T, error)) (T, error) {
  94 + if isEmptyOrZeroValue(k) {
  95 + var t T
  96 + return t, fmt.Errorf("empty key ‘%v’", k)
  97 + }
  98 + if v, ok := source[k]; ok {
  99 + return v, nil
  100 + }
  101 + if v, err := load(ctx, conn, k); err != nil {
  102 + return v, err
  103 + } else {
  104 + source[k] = v
  105 + return v, nil
  106 + }
  107 +}
  108 +
  109 +func Values[T any, V any](list []T, each func(item T) V) []V {
  110 + var result []V
  111 + for _, item := range list {
  112 + value := each(item)
  113 + result = append(result, value)
  114 + }
  115 + return result
  116 +}
  1 +package domain
  2 +
  3 +import (
  4 + "errors"
  5 + "github.com/zeromicro/go-zero/core/stores/sqlx"
  6 +)
  7 +
  8 +var (
  9 + ErrNotFound = sqlx.ErrNotFound
  10 + ErrUpdateFail = errors.New("sql: no rows affected")
  11 +)
  12 +
  13 +var ProjectName = "project"
  1 +.PHONY: model
  2 +model:
  3 + goctl model mysql ddl -s .\cmd\ep\system\deploy\database\table.sql -d cmd/ep/system
  4 +
  5 +.PHONY: api
  6 +api:
  7 + goctl api go -api .\cmd\ep\system\dsl\core.api -dir cmd/ep/system/api -style go_zero
  8 +
  9 +.PHONY: swagger
  10 +swagger:
  11 + goctl api plugin -plugin goctl-swagger="swagger -filename core.json" -api .\cmd\ep\system\dsl\core.api -dir .\cmd\ep\system\generate
  12 +
  13 +.PHONY: build
  14 +build:
  15 + docker build -f cmd/ep/system/deploy/docker/Dockerfile -t sumicro/system:1.0.0 .
  1 +package main
  2 +
  3 +import (
  4 + "flag"
  5 + "fmt"
  6 + "github.com/zeromicro/go-zero/core/logx"
  7 + "github.com/zeromicro/go-zero/rest/httpx"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/config"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/handler"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  11 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/internal/pkg/db"
  12 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/internal/pkg/domain"
  13 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/gateway/smslib"
  14 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  15 + "net/http"
  16 +
  17 + "github.com/zeromicro/go-zero/core/conf"
  18 + "github.com/zeromicro/go-zero/rest"
  19 +)
  20 +
  21 +var configFile = flag.String("f", "etc/core.yaml", "the config file")
  22 +
  23 +func main() {
  24 + flag.Parse()
  25 +
  26 + var c config.Config
  27 + conf.MustLoad(*configFile, &c)
  28 +
  29 + // 系统设置
  30 + systemSetup(c)
  31 +
  32 + // 服务初始化
  33 + opts := make([]rest.RunOption, 0)
  34 + opts = append(opts, rest.WithCustomCors(func(header http.Header) {
  35 + header.Set("Access-Control-Allow-Headers", "*")
  36 + }, func(writer http.ResponseWriter) {
  37 +
  38 + }))
  39 + opts = append(opts, rest.WithUnauthorizedCallback(func(w http.ResponseWriter, r *http.Request, err error) {
  40 + if err != nil {
  41 + logx.Debugf("unauthorized: %s \n", err.Error())
  42 + }
  43 + httpx.WriteJson(w, http.StatusUnauthorized, xerr.Error(xerr.TokenExpireError, err.Error()))
  44 + return
  45 + }))
  46 +
  47 + server := rest.MustNewServer(c.RestConf, opts...)
  48 + defer server.Stop()
  49 +
  50 + ctx := svc.NewServiceContext(c)
  51 + handler.RegisterHandlers(server, ctx)
  52 + server.AddRoutes(RoutersOpenapi(ctx))
  53 +
  54 + // 数据迁移
  55 + if c.Migrate {
  56 + db.Migrate(ctx.DB)
  57 + }
  58 +
  59 + fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
  60 + server.Start()
  61 +}
  62 +
  63 +func systemSetup(c config.Config) {
  64 + // 初始化Domain里面的配置
  65 + domain.ProjectName = c.Name
  66 +
  67 + // 系统错误应答包装
  68 + httpx.SetErrorHandlerCtx(xerr.ErrorHandlerCtx)
  69 +
  70 + // 系统成功应答包装
  71 + httpx.SetOkHandler(xerr.OkHandlerCtx)
  72 +}
  73 +
  74 +func RoutersOpenapi(svc *svc.ServiceContext) []rest.Route {
  75 + return []rest.Route{
  76 + {
  77 + Method: http.MethodPost,
  78 + Path: "/openapi/sms/send-sms-code",
  79 + Handler: smslib.SendSmsCodeHandler(svc.SmsService),
  80 + },
  81 + }
  82 +}
  1 +Name: sumicro-system
  2 +Host: 0.0.0.0
  3 +Port: 8080
  4 +
  5 +Verbose: false
  6 +Migrate: true
  7 +Timeout: 30000
  8 +LogRequest: true # 记录详细请求日志
  9 +
  10 +Log:
  11 + #Mode: file
  12 + Encoding: plain
  13 + Level: debug # info
  14 + MaxSize: 1 # 2MB
  15 + TimeFormat: 2006-01-02 15:04:05
  16 + Rotation: size
  17 + MaxContentLength: 10240
  18 +
  19 +SystemAuth:
  20 + AccessSecret: su-platform
  21 + AccessExpire: 360000
  22 +
  23 +Redis:
  24 + Host: 127.0.0.1:6379
  25 + Type: node
  26 + Pass:
  27 +DB:
  28 + DataSource: host=114.55.200.59 user=postgres password=eagle1010 dbname=su_enterprise_platform port=31543 sslmode=disable TimeZone=Asia/Shanghai
  1 +package config
  2 +
  3 +import (
  4 + "github.com/zeromicro/go-zero/core/stores/redis"
  5 + "github.com/zeromicro/go-zero/rest"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/config"
  7 +)
  8 +
  9 +type Config struct {
  10 + rest.RestConf
  11 + config.Config
  12 + Redis redis.RedisConf `json:",optional"`
  13 + SystemAuth config.Auth
  14 + DebugSmsCode string `json:",optional,default=999512"`
  15 +}
  1 +package auth
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/logic/auth"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  10 +)
  11 +
  12 +func SystemAuthLoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.AuthLoginRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := auth.NewSystemAuthLoginLogic(r.Context(), svcCtx)
  21 + resp, err := l.SystemAuthLogin(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package auth
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/logic/auth"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  10 +)
  11 +
  12 +func SystemAuthRegisterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.CompanyRegisterRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := auth.NewSystemAuthRegisterLogic(r.Context(), svcCtx)
  21 + resp, err := l.SystemAuthRegister(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package auth
  2 +
  3 +import (
  4 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  5 + "net/http"
  6 +
  7 + "github.com/zeromicro/go-zero/rest/httpx"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/logic/auth"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  10 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  11 +)
  12 +
  13 +func SystemAuthUserInfoHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  14 + return func(w http.ResponseWriter, r *http.Request) {
  15 + var req types.UserInfoRequest
  16 + if err := httpx.Parse(r, &req); err != nil {
  17 + httpx.ErrorCtx(r.Context(), w, err)
  18 + return
  19 + }
  20 +
  21 + token := contextdata.GetUserTokenFromCtx(r.Context())
  22 + req.UserId = token.UserId
  23 + req.CompanyId = token.CompanyId
  24 + req.EmployeeId = token.EmployeeId
  25 + l := auth.NewSystemAuthUserInfoLogic(r.Context(), svcCtx)
  26 + resp, err := l.SystemAuthUserInfo(&req)
  27 + if err != nil {
  28 + httpx.ErrorCtx(r.Context(), w, err)
  29 + } else {
  30 + httpx.OkJsonCtx(r.Context(), w, resp)
  31 + }
  32 + }
  33 +}
  1 +package department
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/logic/department"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  10 +)
  11 +
  12 +func SystemDepartmentBatchDeleteHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.DepartmentBatchDeleteRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := department.NewSystemDepartmentBatchDeleteLogic(r.Context(), svcCtx)
  21 + resp, err := l.SystemDepartmentBatchDelete(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package department
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/logic/department"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  10 +)
  11 +
  12 +func SystemDepartmentDeleteHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.DepartmentDeleteRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := department.NewSystemDepartmentDeleteLogic(r.Context(), svcCtx)
  21 + resp, err := l.SystemDepartmentDelete(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package department
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/logic/department"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  10 +)
  11 +
  12 +func SystemDepartmentExportHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.DepartmentSearchRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := department.NewSystemDepartmentExportLogic(r.Context(), svcCtx)
  21 + resp, err := l.SystemDepartmentExport(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package department
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/logic/department"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  10 +)
  11 +
  12 +func SystemDepartmentGetHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.DepartmentGetRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := department.NewSystemDepartmentGetLogic(r.Context(), svcCtx)
  21 + resp, err := l.SystemDepartmentGet(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
  1 +package department
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/logic/department"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  10 +)
  11 +
  12 +func SystemDepartmentImportHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.DepartmentImportRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := department.NewSystemDepartmentImportLogic(r.Context(), svcCtx)
  21 + resp, err := l.SystemDepartmentImport(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}