修改app config格式

This commit is contained in:
xiabin 2025-02-24 17:27:51 +08:00
parent e92287bb62
commit 0f88992db9
9 changed files with 135 additions and 80 deletions

View File

@ -20,6 +20,9 @@ jobs:
- service: auth
dockerfile: app/auth_service/Dockerfile
image: auth
- service: admin
dockerfile: app/admin_service/Dockerfile
image: admin
steps:
- uses: https://gitea.youtukeji.com.cn/actions/checkout@v4
@ -45,3 +48,7 @@ jobs:
docker-compose up -d --build
env:
COMPOSE_PROJECT_NAME: youtu_grpc
steps:
- name: clean up
run: |
docker rmi $(docker images -f "dangling=true" -q)

View File

@ -0,0 +1,33 @@
FROM golang:alpine AS builder
LABEL stage=gobuilder
ENV CGO_ENABLED=0
ENV GOPROXY=https://goproxy.cn,direct
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk update --no-cache && apk add --no-cache tzdata
RUN apk add --no-cache git
WORKDIR /build
ADD go.mod .
ADD go.sum .
RUN go env -w GOPRIVATE=gitea.youtukeji.com.cn
RUN go mod download
COPY . .
RUN go build -ldflags="-s -w" -o /app/admin ./app/admin_service/admin_service.go
FROM alpine
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ=Asia/Shanghai
WORKDIR /app
COPY --from=builder /app/admin /app/admin
EXPOSE 8888
CMD ["/app/admin"]

View File

@ -22,7 +22,7 @@ message GetAppListResponse {
message AppInfo {
int32 id = 1;
int32 type = 2;
string type = 2;
string app_id = 3;
string secret = 4;
string remark = 5;

View File

@ -192,7 +192,7 @@ func (x *GetAppListResponse) GetAppList() []*AppInfo {
type AppInfo struct {
state protoimpl.MessageState `protogen:"open.v1"`
Id int32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
Type int32 `protobuf:"varint,2,opt,name=type,proto3" json:"type,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
AppId string `protobuf:"bytes,3,opt,name=app_id,json=appId,proto3" json:"app_id,omitempty"`
Secret string `protobuf:"bytes,4,opt,name=secret,proto3" json:"secret,omitempty"`
Remark string `protobuf:"bytes,5,opt,name=remark,proto3" json:"remark,omitempty"`
@ -239,11 +239,11 @@ func (x *AppInfo) GetId() int32 {
return 0
}
func (x *AppInfo) GetType() int32 {
func (x *AppInfo) GetType() string {
if x != nil {
return x.Type
}
return 0
return ""
}
func (x *AppInfo) GetAppId() string {
@ -298,7 +298,7 @@ var file_admin_service_proto_rawDesc = string([]byte{
0x2e, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x07, 0x61, 0x70, 0x70, 0x4c, 0x69, 0x73,
0x74, 0x22, 0x9a, 0x01, 0x0a, 0x07, 0x41, 0x70, 0x70, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a,
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a,
0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x79, 0x70,
0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70,
0x65, 0x12, 0x15, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
0x09, 0x52, 0x05, 0x61, 0x70, 0x70, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72,
0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74,

View File

@ -4,11 +4,12 @@ import (
"context"
"encoding/json"
"fmt"
"strconv"
"gitea.youtukeji.com.cn/youtu/youtu_grpc/app/admin_service/admin_service"
"slices"
"strings"
"gitea.youtukeji.com.cn/youtu/youtu_grpc/app/admin_service/internal/svc"
clientv3 "go.etcd.io/etcd/client/v3"
"github.com/zeromicro/go-zero/core/logx"
)
@ -27,53 +28,62 @@ func NewGetAppListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetApp
}
}
// 定义数据结构
// EcpmConfig 定义数据结构
type EcpmConfig struct {
AppID string `json:"appId"`
ECPM int `json:"eCPM"`
IPU int `json:"IPU"`
ECPM float32 `json:"eCPM"`
IPU uint32 `json:"IPU"`
}
type AppData struct {
AppID string `json:"appId"`
AppSecret string `json:"appSecret"`
Type string `json:"type"`
Remark string `json:"remark"`
}
type MergedAppInfo struct {
AppID string `json:"appId"`
ECPM int `json:"eCPM,omitempty"`
IPU int `json:"IPU,omitempty"`
ECPM float32 `json:"eCPM,omitempty"`
IPU uint32 `json:"IPU,omitempty"`
AppSecret string `json:"appSecret,omitempty"`
Type string `json:"type,omitempty"`
Remark string `json:"remark,omitempty"`
}
// GetAppList 获取app列表
func (l *GetAppListLogic) GetAppList(_ *admin_service.GetAppListRequest) (res *admin_service.GetAppListResponse, err error) {
// 从ETCD获取ecpm配置
ecpmResp, err := l.svcCtx.EtcdClient.Get(l.ctx, "/youtu/ecpm/config")
ecpmResp, err := l.svcCtx.EtcdClient.Get(l.ctx, "/youtu/app/ecpm/config", clientv3.WithPrefix())
if err != nil {
return nil, fmt.Errorf("获取ecpm配置失败: %v", err)
}
var ecpmConfigs []EcpmConfig
if len(ecpmResp.Kvs) > 0 {
if err := json.Unmarshal(ecpmResp.Kvs[0].Value, &ecpmConfigs); err != nil {
// 解析ecpm配置
ecpmConfigs := make([]EcpmConfig, 0, len(ecpmResp.Kvs))
for _, kv := range ecpmResp.Kvs {
cfg := EcpmConfig{}
if err := json.Unmarshal(kv.Value, &cfg); err != nil {
return nil, fmt.Errorf("解析ecpm配置失败: %v", err)
}
cfg.AppID = strings.TrimPrefix(string(kv.Key), "/youtu/app/ecpm/config/")
ecpmConfigs = append(ecpmConfigs, cfg)
}
// 从ETCD获取app数据
appDataResp, err := l.svcCtx.EtcdClient.Get(l.ctx, "/youtu/appData")
appDataResp, err := l.svcCtx.EtcdClient.Get(l.ctx, "/youtu/app/account", clientv3.WithPrefix())
if err != nil {
return nil, fmt.Errorf("获取app数据失败: %v", err)
}
var appDatas []AppData
if len(appDataResp.Kvs) > 0 {
if err := json.Unmarshal(appDataResp.Kvs[0].Value, &appDatas); err != nil {
appDatas := make([]AppData, 0, len(appDataResp.Kvs))
for _, kv := range appDataResp.Kvs {
appData := AppData{}
if err := json.Unmarshal(kv.Value, &appData); err != nil {
return nil, fmt.Errorf("解析app数据失败: %v", err)
}
appData.AppID = strings.TrimPrefix(string(kv.Key), "/youtu/app/account/")
appDatas = append(appDatas, appData)
}
// 创建合并映射
@ -93,11 +103,13 @@ func (l *GetAppListLogic) GetAppList(_ *admin_service.GetAppListRequest) (res *a
if info, exists := merged[app.AppID]; exists {
info.AppSecret = app.AppSecret
info.Type = app.Type
info.Remark = app.Remark
} else {
merged[app.AppID] = &MergedAppInfo{
AppID: app.AppID,
AppSecret: app.AppSecret,
Type: app.Type,
Remark: app.Remark,
}
}
}
@ -112,17 +124,25 @@ func (l *GetAppListLogic) GetAppList(_ *admin_service.GetAppListRequest) (res *a
appInfo := &admin_service.AppInfo{
AppId: info.AppID,
Secret: info.AppSecret,
Ecpm: float32(info.ECPM),
Ipu: uint32(info.IPU),
}
// 转换type为int32
if typeInt, err := strconv.Atoi(info.Type); err == nil {
appInfo.Type = int32(typeInt)
Ecpm: info.ECPM,
Ipu: info.IPU,
Type: info.Type,
Remark: info.Remark,
}
res.AppList = append(res.AppList, appInfo)
}
slices.SortFunc(res.AppList, func(i, j *admin_service.AppInfo) int {
if i.AppId < j.AppId {
return -1
}
return 1
})
for i, info := range res.AppList {
info.Id = int32(i + 1)
}
return res, nil
}

View File

@ -14,12 +14,12 @@ import (
"github.com/spf13/viper"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/core/discov"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/zrpc"
clientv3 "go.etcd.io/etcd/client/v3"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"strings"
)
type ServiceContext struct {
@ -73,7 +73,7 @@ type AppData struct {
type AppDataList []AppData
const AppDataWatchKey = "/youtu/appData"
const AppDataWatchKey = "/youtu/app/account/"
func (svc *ServiceContext) InitClient() {
@ -85,26 +85,27 @@ func (svc *ServiceContext) InitClient() {
}
go func() {
ch := make(chan []byte)
ch := make(chan config.WatchKV)
go config.EtcdGetOneAndWatch(context.TODO(), cli, AppDataWatchKey, ch)
//从通道中尝试取值(监视的信息)
for res := range ch {
var appDataArr AppDataList
err = json.Unmarshal(res, &appDataArr)
appData := AppData{}
err = json.Unmarshal(res.Value, &appData)
if err != nil {
logx.Errorf("etcd watch %s json.Unmarshal: %v", AppDataWatchKey, err)
continue
}
svc.SaveDW(appDataArr, svc.dwCache)
appData.AppId = strings.TrimPrefix(res.Key, AppDataWatchKey)
svc.SaveDW(appData, svc.dwCache)
}
}()
}
func (svc *ServiceContext) SaveDW(arr []AppData, dwCache cache.Cache) {
svc.Cli.Clear()
func (svc *ServiceContext) SaveDW(v AppData, dwCache cache.Cache) {
//配置小程序cli抖音&微信)
for _, v := range arr {
var c cli2.DWClient
switch v.Type {
case cli2.DouyinClientType:
@ -112,11 +113,10 @@ func (svc *ServiceContext) SaveDW(arr []AppData, dwCache cache.Cache) {
case cli2.WechatClientType:
c = cli2.NewWechatApi(v.AppId, v.AppSecret, dwCache)
default:
continue
return
}
svc.Cli.Set(v.AppId, c)
}
}
func (svc *ServiceContext) DeleteDWCache(appId string) (err error) {
err = svc.dwCache.Delete(appId)

View File

@ -41,13 +41,17 @@ func (c *EcpmConfigCli) SetAll(list []Ecpm) {
}
}
func (c *EcpmConfigCli) SetAllByJson(data []byte) {
var list []Ecpm
func (c *EcpmConfigCli) SetEcpm(list Ecpm) {
c.Map.Store(list.AppId, &list)
}
func (c *EcpmConfigCli) SetAllByJson(appId string, data []byte) {
var list Ecpm
err := json.Unmarshal(data, &list)
if err != nil {
return
}
list.AppId = appId
slog.Info("set ecpm config", slog.AnyValue(list))
c.SetAll(list)
c.SetEcpm(list)
}

View File

@ -9,6 +9,7 @@ import (
"github.com/zeromicro/go-zero/core/discov"
"github.com/zeromicro/go-zero/zrpc"
clientv3 "go.etcd.io/etcd/client/v3"
"strings"
)
type ServiceContext struct {
@ -32,7 +33,7 @@ func NewServiceContext(c config.Config) *ServiceContext {
return svc
}
const EcpmConfigWatchKey = "/youtu/ecpm/config"
const EcpmConfigWatchKey = "/youtu/app/ecpm/config/"
func (svc *ServiceContext) initEtcd() {
@ -44,27 +45,12 @@ func (svc *ServiceContext) initEtcd() {
panic(err)
}
//获取ecpm配置
res, err := cli.Get(context.Background(), EcpmConfigWatchKey)
if err != nil {
panic(err)
}
ch := make(chan config.WatchKV)
go config.EtcdGetOneAndWatch(context.Background(), cli, EcpmConfigWatchKey, ch)
//设置ecpm配置
for _, kv := range res.Kvs {
svc.EcpmConfig.SetAllByJson(kv.Value)
}
//监听etcd
go func() {
ch := cli.Watch(context.Background(), EcpmConfigWatchKey)
//从通道中尝试取值(监视的信息)
for res := range ch {
for _, evt := range res.Events {
svc.EcpmConfig.SetAllByJson(evt.Kv.Value)
svc.EcpmConfig.SetAllByJson(strings.TrimPrefix(res.Key, EcpmConfigWatchKey), res.Value)
}
}
}()
svc.etcdCli = cli
}

View File

@ -77,21 +77,26 @@ func SetConfig(b, serverName string) (err error) {
return
}
type WatchKV struct {
Key string
Value []byte
}
// EtcdGetOneAndWatch 获取etcd配置并监听对应的key
func EtcdGetOneAndWatch(ctx context.Context, cli *clientv3.Client, key string, ch chan []byte) {
func EtcdGetOneAndWatch(ctx context.Context, cli *clientv3.Client, key string, ch chan WatchKV) {
defer close(ch)
b, err := cli.Get(ctx, key)
b, err := cli.Get(ctx, key, clientv3.WithPrefix())
if err != nil {
return
}
for _, kv := range b.Kvs {
ch <- kv.Value
ch <- WatchKV{Key: string(kv.Key), Value: kv.Value}
}
resCh := cli.Watch(ctx, key)
resCh := cli.Watch(ctx, key, clientv3.WithPrefix())
for res := range resCh {
for _, event := range res.Events {
ch <- event.Kv.Value
ch <- WatchKV{Key: string(event.Kv.Key), Value: event.Kv.Value}
}
}