107 lines
3.3 KiB
Go
107 lines
3.3 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"git.118im.com/im_team/olons_server/internal/accounts"
|
|
"git.118im.com/im_team/olons_server/internal/attachments"
|
|
"git.118im.com/im_team/olons_server/internal/auth"
|
|
"git.118im.com/im_team/olons_server/internal/config"
|
|
"git.118im.com/im_team/olons_server/internal/finance"
|
|
"git.118im.com/im_team/olons_server/internal/httpapi"
|
|
"git.118im.com/im_team/olons_server/internal/imclient"
|
|
"git.118im.com/im_team/olons_server/internal/mall"
|
|
"git.118im.com/im_team/olons_server/internal/portal"
|
|
"git.118im.com/im_team/olons_server/internal/store"
|
|
"git.118im.com/im_team/olons_server/internal/support"
|
|
"git.118im.com/im_team/olons_server/internal/tasks"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
type App struct {
|
|
store *store.Store
|
|
redis *redis.Client
|
|
api *httpapi.API
|
|
frontendPath string
|
|
upload config.UploadConfig
|
|
}
|
|
|
|
func New(cfg *config.Config) (*App, error) {
|
|
st, err := store.Open(cfg.MySQL)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
redisClient := redis.NewClient(&redis.Options{
|
|
Addr: cfg.Redis.Addr, Username: cfg.Redis.Username, Password: cfg.Redis.Password, DB: cfg.Redis.DB,
|
|
})
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
if err := redisClient.Ping(ctx).Err(); err != nil {
|
|
_ = redisClient.Close()
|
|
_ = st.Close()
|
|
return nil, err
|
|
}
|
|
authenticator := auth.New(cfg.Auth, redisClient)
|
|
accountService := accounts.New(st, redisClient, cfg.Auth)
|
|
portalService := portal.New(st)
|
|
taskService := tasks.New(st)
|
|
mallService := mall.New(st)
|
|
financeService := finance.New(st, redisClient, cfg.Auth)
|
|
attachmentService := attachments.New(st, cfg.Upload)
|
|
supportService := support.New(st, imclient.New(cfg.IM), cfg.Auth)
|
|
return &App{store: st, redis: redisClient, api: httpapi.New(authenticator, accountService, portalService, taskService, mallService, financeService, attachmentService, supportService), frontendPath: cfg.FrontendDir, upload: cfg.Upload}, nil
|
|
}
|
|
|
|
func (a *App) Handler() http.Handler {
|
|
mux := http.NewServeMux()
|
|
mux.Handle(strings.TrimRight(a.upload.PublicPath, "/")+"/", http.StripPrefix(strings.TrimRight(a.upload.PublicPath, "/"), http.FileServer(http.Dir(a.upload.Dir))))
|
|
if a.frontendDir() != "" {
|
|
mux.Handle("/", frontendHandler(a.frontendDir()))
|
|
}
|
|
mux.HandleFunc("/healthz", a.api.Healthz)
|
|
mux.Handle("/metrics", promhttp.Handler())
|
|
a.api.Register(mux)
|
|
return mux
|
|
}
|
|
|
|
func (a *App) frontendDir() string {
|
|
if dir := strings.TrimSpace(os.Getenv("OLONS_SERVER_FRONTEND_DIR")); dir != "" {
|
|
return dir
|
|
}
|
|
return strings.TrimSpace(a.frontendPath)
|
|
}
|
|
|
|
func frontendHandler(dir string) http.Handler {
|
|
files := http.FileServer(http.Dir(dir))
|
|
index := filepath.Join(dir, "index.html")
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
path := r.URL.Path
|
|
if path == "" {
|
|
path = "/"
|
|
}
|
|
candidate := filepath.Join(dir, filepath.Clean(path))
|
|
if info, err := os.Stat(candidate); err == nil && !info.IsDir() {
|
|
r2 := r.Clone(r.Context())
|
|
r2.URL.Path = path
|
|
files.ServeHTTP(w, r2)
|
|
return
|
|
}
|
|
http.ServeFile(w, r, index)
|
|
})
|
|
}
|
|
|
|
func (a *App) Close() {
|
|
if a.redis != nil {
|
|
_ = a.redis.Close()
|
|
}
|
|
if a.store != nil {
|
|
_ = a.store.Close()
|
|
}
|
|
}
|