refactor: reorganize modules and add Linux build tooling
This commit is contained in:
42
module/base/initial/internal/config/config.go
Normal file
42
module/base/initial/internal/config/config.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/conf"
|
||||
"git.apinb.com/bsm-sdk/core/crypto/encipher"
|
||||
"git.apinb.com/bsm-sdk/core/env"
|
||||
)
|
||||
|
||||
var (
|
||||
Spec SrvConfig
|
||||
)
|
||||
|
||||
type SrvConfig struct {
|
||||
conf.Base `yaml:",inline"`
|
||||
Databases *conf.DBConf `yaml:"Databases"`
|
||||
MicroService *conf.MicroServiceConf `yaml:"MicroService"`
|
||||
Rpc map[string]conf.RpcConf `yaml:"Rpc"`
|
||||
Gateway *conf.GatewayConf `yaml:"Gateway"`
|
||||
Apm *conf.ApmConf `yaml:"APM"`
|
||||
Etcd *conf.EtcdConf `yaml:"Etcd"`
|
||||
}
|
||||
|
||||
func New(srvKey string) {
|
||||
// 初始化配置 创建一个新的配置实例,用于服务配置
|
||||
conf.New(srvKey, &Spec)
|
||||
|
||||
// 配置校验 服务IP,端口; 端口如果不合规,则随机分配端口
|
||||
Spec.Port = conf.CheckPort(Spec.Port)
|
||||
Spec.BindIP = conf.CheckIP(Spec.BindIP)
|
||||
Spec.Addr = net.JoinHostPort(Spec.BindIP, Spec.Port)
|
||||
Spec.Log = conf.InitLoggerConf(Spec.Log)
|
||||
|
||||
// 配置校验 服务名称地址及监听地址不能为空
|
||||
conf.NotNil(Spec.Service, Spec.Cache)
|
||||
|
||||
// 初始化
|
||||
encipher.New(env.Runtime.JwtSecretKey)
|
||||
|
||||
conf.PrintInfo(Spec.Addr)
|
||||
}
|
||||
12
module/base/initial/internal/excode/ex.go
Normal file
12
module/base/initial/internal/excode/ex.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package excode
|
||||
|
||||
import "git.apinb.com/bsm-sdk/core/errcode"
|
||||
|
||||
var (
|
||||
// 参数错误
|
||||
ErrInvalidApp = errcode.ErrNotFound(404, "app")
|
||||
ErrInvalidOS = errcode.ErrNotFound(404, "os")
|
||||
ErrInvalidArch = errcode.ErrNotFound(404, "arch")
|
||||
ErrInvalidVersion = errcode.ErrNotFound(404, "version")
|
||||
ErrInvalidCountry = errcode.ErrNotFound(404, "country")
|
||||
)
|
||||
29
module/base/initial/internal/impl/impl.go
Normal file
29
module/base/initial/internal/impl/impl.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package impl
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/initial/internal/config"
|
||||
"git.apinb.com/bsm-sdk/core/cache/redis"
|
||||
"git.apinb.com/bsm-sdk/core/with"
|
||||
cache "github.com/patrickmn/go-cache"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var (
|
||||
RedisService *redis.RedisClient // Redis 客户端服务
|
||||
EtcdService *clientv3.Client // Etcd 客户端服务
|
||||
DBService *gorm.DB // 数据库服务
|
||||
MemorySerice *cache.Cache // 内存缓存服务
|
||||
)
|
||||
|
||||
// NewImpl 初始化各类服务实例
|
||||
func NewImpl() {
|
||||
// 初始化内存缓存
|
||||
MemorySerice = with.Memory(nil)
|
||||
// 初始化 Redis 缓存
|
||||
RedisService = with.RedisCache(config.Spec.Cache)
|
||||
// 初始化数据库服务
|
||||
DBService = with.Databases(config.Spec.Databases, nil)
|
||||
// 初始化 Etcd 服务
|
||||
EtcdService = with.Etcd(config.Spec.Etcd)
|
||||
}
|
||||
55
module/base/initial/internal/logic/check/config.go
Normal file
55
module/base/initial/internal/logic/check/config.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package check
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"bsm/full/module/base/initial/internal/models"
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 获取应用的相关配置信息
|
||||
func Config(ctx context.Context, in *pb.ConfigRequest) (reply *pb.ConfigReply, err error) {
|
||||
// 输入验证
|
||||
if in == nil || in.App == "" || in.Os == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var (
|
||||
configs []*models.InitialConfig
|
||||
data []*pb.ConfigItem
|
||||
)
|
||||
|
||||
// 查询配置,优先返回特定OS的配置,然后是通用配置
|
||||
configs, err = GetConfigByCache(in.App, in.Os)
|
||||
|
||||
if err != nil {
|
||||
printer.Error("GetConfigByCache", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 去重处理:同一个key只保留优先级最高的配置
|
||||
configMap := make(map[string]*models.InitialConfig)
|
||||
for _, item := range configs {
|
||||
if existing, exists := configMap[item.Key]; !exists || item.Os != "ALL" {
|
||||
configMap[item.Key] = item
|
||||
} else if existing.Os == "ALL" && item.Os != "ALL" {
|
||||
configMap[item.Key] = item
|
||||
}
|
||||
}
|
||||
|
||||
// 转换为响应格式
|
||||
for _, item := range configMap {
|
||||
data = append(data, &pb.ConfigItem{
|
||||
Identity: item.Identity,
|
||||
Key: item.Key,
|
||||
Value: item.Value,
|
||||
Version: item.Version,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.ConfigReply{
|
||||
Data: data,
|
||||
}, nil
|
||||
}
|
||||
29
module/base/initial/internal/logic/check/config_cache.go
Normal file
29
module/base/initial/internal/logic/check/config_cache.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package check
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/initial/internal/impl"
|
||||
"bsm/full/module/base/initial/internal/models"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// GetConfigCache 获取配置缓存
|
||||
func GetConfigByCache(app, os string) ([]*models.InitialConfig, error) {
|
||||
var configs []*models.InitialConfig
|
||||
|
||||
key := impl.RedisService.BuildKey("config", app, os)
|
||||
|
||||
err := impl.RedisService.Get(key, &configs)
|
||||
if err == nil {
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
err = impl.DBService.Where("app = ? AND (os = ? OR os = ?)", app, os, "ALL").
|
||||
Order("CASE WHEN os = '" + os + "' THEN 0 ELSE 1 END, id DESC").
|
||||
Find(&configs).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = impl.RedisService.Set(key, configs, vars.DefaultTTL)
|
||||
return configs, err
|
||||
}
|
||||
32
module/base/initial/internal/logic/check/hello.go
Normal file
32
module/base/initial/internal/logic/check/hello.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package check
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
// HELLO - 健康检查接口
|
||||
func Hello(ctx context.Context, in *pb.Crc) (reply *pb.StatusReply, err error) {
|
||||
// 输入验证
|
||||
if in.Code != "" {
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: vars.OK,
|
||||
Details: "Hello " + in.Code,
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 可以在这里添加更多的健康检查逻辑
|
||||
// 例如检查数据库连接、Redis连接等
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: vars.OK,
|
||||
Details: "",
|
||||
Timeseq: time.Now().Unix(),
|
||||
}, nil
|
||||
}
|
||||
55
module/base/initial/internal/logic/check/updates.go
Normal file
55
module/base/initial/internal/logic/check/updates.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package check
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"bsm/full/module/base/initial/internal/impl"
|
||||
"bsm/full/module/base/initial/internal/models"
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 检查更新
|
||||
func Updates(ctx context.Context, in *pb.CheckForUpdatesRequest) (reply *pb.CheckForUpdatesReply, err error) {
|
||||
// 输入验证
|
||||
if in == nil || in.App == "" || in.Os == "" || in.Arch == "" || in.Version == "" {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
var data models.InitialApps
|
||||
|
||||
// 查询最新版本
|
||||
err = impl.DBService.Where("app = ? AND os = ? AND arch = ?", in.App, in.Os, in.Arch).
|
||||
Order("pubdate DESC, id DESC").
|
||||
First(&data).Error
|
||||
|
||||
if err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
// 没有找到对应的应用版本
|
||||
return &pb.CheckForUpdatesReply{
|
||||
Identity: "0",
|
||||
Version: "0",
|
||||
}, nil
|
||||
}
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 比较版本号
|
||||
if in.Version != data.Version {
|
||||
// 有新版本可用
|
||||
return &pb.CheckForUpdatesReply{
|
||||
Identity: data.Identity,
|
||||
Version: data.Version,
|
||||
Summary: data.Summary,
|
||||
Files: data.Files,
|
||||
Pubdate: data.Pubdate.Format("2006-01-02 15:04:05"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 当前版本是最新的
|
||||
return &pb.CheckForUpdatesReply{
|
||||
Identity: data.Identity,
|
||||
Version: data.Version,
|
||||
}, nil
|
||||
}
|
||||
44
module/base/initial/internal/logic/data/areas.go
Normal file
44
module/base/initial/internal/logic/data/areas.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 区域数据,默认级别:市
|
||||
func Areas(ctx context.Context, in *pb.AreasRequest) (reply *pb.AreasReply, err error) {
|
||||
// 参数检查 - 如果都没有提供,默认使用中国(ID=1)
|
||||
if in.GetCountryCode() == "" && in.GetCountryId() == 0 {
|
||||
in.CountryId = 1 // 默认中国
|
||||
}
|
||||
|
||||
// 查询条件:国家代码优先
|
||||
areas, err := GetAreasByCache(in)
|
||||
if err != nil {
|
||||
printer.Error("GetAreasByCache", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 转换为响应格式
|
||||
var data []*pb.AreasItem
|
||||
for _, area := range areas {
|
||||
data = append(data, &pb.AreasItem{
|
||||
Id: fmt.Sprintf("%d", area.Id),
|
||||
Pid: fmt.Sprintf("%d", area.Pid),
|
||||
Deep: area.Deep,
|
||||
Name: area.Name,
|
||||
PinyinPrefix: area.PinyinPrefix,
|
||||
Pinyin: area.Pinyin,
|
||||
ExtId: area.ExtId,
|
||||
ExtName: area.ExtName,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.AreasReply{
|
||||
Areas: data,
|
||||
}, nil
|
||||
}
|
||||
39
module/base/initial/internal/logic/data/areas_cache.go
Normal file
39
module/base/initial/internal/logic/data/areas_cache.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/initial/internal/impl"
|
||||
"bsm/full/module/base/initial/internal/models"
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
func GetAreasByCache(in *pb.AreasRequest) ([]*models.InitialAreas, error) {
|
||||
var areas []*models.InitialAreas
|
||||
|
||||
var (
|
||||
key string
|
||||
val any
|
||||
)
|
||||
|
||||
if in.GetCountryCode() != "" {
|
||||
key = "country_code = ?"
|
||||
val = in.GetCountryCode()
|
||||
} else if in.GetCountryId() != 0 {
|
||||
key = "country_id = ?"
|
||||
val = in.GetCountryId()
|
||||
}
|
||||
|
||||
cacheKey := impl.RedisService.BuildKey("areas", key, val, in.ShowTown)
|
||||
|
||||
err := impl.RedisService.Get(cacheKey, &areas)
|
||||
if err == nil {
|
||||
return areas, nil
|
||||
}
|
||||
|
||||
err = impl.DBService.Where("enabled = ?", true).Where(key, val).Where("show_town = ?", in.ShowTown).
|
||||
Order("sort_order ASC, name ASC").
|
||||
Find(&areas).Error
|
||||
|
||||
err = impl.RedisService.Set(cacheKey, areas, vars.DefaultTTL)
|
||||
return areas, err
|
||||
}
|
||||
43
module/base/initial/internal/logic/data/country.go
Normal file
43
module/base/initial/internal/logic/data/country.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
func Country(ctx context.Context, in *pb.Empty) (reply *pb.CountryReply, err error) {
|
||||
// 查询启用的国家,按排序字段和名称排序
|
||||
countries, err := GetCountryByCache()
|
||||
if err != nil {
|
||||
printer.Error("GetCountryByCache", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 转换为响应格式
|
||||
var data []*pb.CountryItem
|
||||
for _, country := range countries {
|
||||
data = append(data, &pb.CountryItem{
|
||||
Id: uint32(country.Id),
|
||||
Iso2: country.Iso2,
|
||||
Iso3: country.Iso3,
|
||||
NumCode: country.NumCode,
|
||||
PhoneCode: country.PhoneCode,
|
||||
Currency: country.Currency,
|
||||
CurrencySymbol: country.CurrencySymbol,
|
||||
Region: country.Region,
|
||||
Timezones: country.Timezones,
|
||||
Translations: country.Translations,
|
||||
Name: country.Name,
|
||||
LocalName: country.LocalName,
|
||||
Enabled: country.Enabled,
|
||||
SortOrder: country.SortOrder,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.CountryReply{
|
||||
Countries: data,
|
||||
}, nil
|
||||
}
|
||||
25
module/base/initial/internal/logic/data/country_cache.go
Normal file
25
module/base/initial/internal/logic/data/country_cache.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/initial/internal/impl"
|
||||
"bsm/full/module/base/initial/internal/models"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
func GetCountryByCache() ([]*models.InitialCountry, error) {
|
||||
var country []*models.InitialCountry
|
||||
|
||||
cacheKey := impl.RedisService.BuildKey("country")
|
||||
|
||||
err := impl.RedisService.Get(cacheKey, &country)
|
||||
if err == nil {
|
||||
return country, nil
|
||||
}
|
||||
|
||||
err = impl.DBService.Where("enabled = ?", true).
|
||||
Order("sort_order ASC, name ASC").
|
||||
Find(&country).Error
|
||||
|
||||
err = impl.RedisService.Set(cacheKey, country, vars.DefaultTTL)
|
||||
return country, err
|
||||
}
|
||||
48
module/base/initial/internal/logic/data/datas.go
Normal file
48
module/base/initial/internal/logic/data/datas.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
)
|
||||
|
||||
// 系统标签数据
|
||||
func Datas(ctx context.Context, in *pb.Empty) (reply *pb.DatasReply, err error) {
|
||||
// 查询系统数据,按数据类型和ID排序
|
||||
datas, err := GetDatasByCache()
|
||||
if err != nil {
|
||||
printer.Error("GetDatasByCache", err)
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
// 转换为响应格式
|
||||
var data []*pb.DatasItem
|
||||
|
||||
// 添加默认的"全部"选项
|
||||
data = append(data, &pb.DatasItem{
|
||||
Id: 0,
|
||||
DataType: "default",
|
||||
Key: "all",
|
||||
Title: "全部",
|
||||
Remark: "默认全部选项",
|
||||
Icon: "",
|
||||
})
|
||||
|
||||
// 添加数据库中的数据
|
||||
for _, item := range datas {
|
||||
data = append(data, &pb.DatasItem{
|
||||
Id: int64(item.ID),
|
||||
DataType: item.DataType,
|
||||
Key: item.Key,
|
||||
Title: item.Title,
|
||||
Remark: item.Remark,
|
||||
Icon: item.Icon,
|
||||
})
|
||||
}
|
||||
|
||||
return &pb.DatasReply{
|
||||
Datas: data,
|
||||
}, nil
|
||||
}
|
||||
29
module/base/initial/internal/logic/data/datas_cache.go
Normal file
29
module/base/initial/internal/logic/data/datas_cache.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"bsm/full/module/base/initial/internal/impl"
|
||||
"bsm/full/module/base/initial/internal/models"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
func GetDatasByCache() ([]*models.InitialDatas, error) {
|
||||
var datas []*models.InitialDatas
|
||||
|
||||
cacheKey := impl.RedisService.BuildKey("datas")
|
||||
|
||||
err := impl.RedisService.Get(cacheKey, &datas)
|
||||
if err == nil {
|
||||
return datas, nil
|
||||
}
|
||||
|
||||
err = impl.DBService.Order("data_type ASC, id ASC").Find(&datas).Error
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
err = impl.RedisService.Set(cacheKey, datas, vars.DefaultTTL)
|
||||
return datas, err
|
||||
}
|
||||
28
module/base/initial/internal/models/initial_apps.go
Normal file
28
module/base/initial/internal/models/initial_apps.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
)
|
||||
|
||||
// 应用版本更新表
|
||||
type InitialApps struct {
|
||||
types.Std_IICUDS
|
||||
Version string `gorm:"type:varchar(255);default:'';"` // 版本号
|
||||
App string `gorm:"type:varchar(255);default:'';"` // 应用名称
|
||||
Os string `gorm:"type:varchar(255);default:'';"` // 操作系统
|
||||
Arch string `gorm:"type:varchar(255);default:'';"` // 平台
|
||||
Summary string `gorm:"type:text;default:'';"` // 简介
|
||||
Files string `gorm:"type:text;default:'';"` // 更新文件以及文件hash
|
||||
Pubdate time.Time // 发布时间
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.AppendMigrate(&InitialApps{})
|
||||
}
|
||||
|
||||
func (table *InitialApps) TableName() string {
|
||||
return "initial_apps"
|
||||
}
|
||||
27
module/base/initial/internal/models/initial_areas.go
Normal file
27
module/base/initial/internal/models/initial_areas.go
Normal file
@@ -0,0 +1,27 @@
|
||||
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
|
||||
package models
|
||||
|
||||
import "git.apinb.com/bsm-sdk/core/database"
|
||||
|
||||
// 地区表
|
||||
type InitialAreas struct {
|
||||
Id uint `gorm:"column:id;" json:"id"` //
|
||||
CountryID uint `gorm:"index" json:"country_id"` //
|
||||
CountryCode string `gorm:"column:country_code;index;type:varchar(255);index;" json:"country_code"` // 国家代码
|
||||
Pid uint `gorm:"column:pid;index;" json:"pid"` //
|
||||
Deep int32 `gorm:"column:deep;" json:"deep"` //
|
||||
Name string `gorm:"column:name;type:varchar(255);" json:"name"` //
|
||||
PinyinPrefix string `gorm:"column:pinyin_prefix;type:varchar(255);index;" json:"pinyin_prefix"` //
|
||||
Pinyin string `gorm:"column:pinyin;type:varchar(255);" json:"pinyin"` //
|
||||
ExtId string `gorm:"column:ext_id;type:varchar(255);" json:"ext_id"` //
|
||||
ExtName string `gorm:"column:ext_name;" json:"ext_name"` //
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.AppendMigrate(&InitialAreas{})
|
||||
}
|
||||
|
||||
// TableName .
|
||||
func (table *InitialAreas) TableName() string {
|
||||
return "initial_areas" //对应数据库表名
|
||||
}
|
||||
24
module/base/initial/internal/models/initial_config.go
Normal file
24
module/base/initial/internal/models/initial_config.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
)
|
||||
|
||||
// 系统配置表
|
||||
type InitialConfig struct {
|
||||
types.Std_IICUDS
|
||||
App string `gorm:"type:varchar(255);default:'';"` // 应用名称
|
||||
Os string `gorm:"type:varchar(255);default:'';"` // 操作系统,ALL代表全平台
|
||||
Key string `gorm:"type:text;default:'';"` // 配置主键名称
|
||||
Value string `gorm:"type:text;default:'';"` // 配置参数
|
||||
Version int64 `gorm:"default:0;"` // 版本号
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.AppendMigrate(&InitialConfig{})
|
||||
}
|
||||
|
||||
func (table *InitialConfig) TableName() string {
|
||||
return "initial_config"
|
||||
}
|
||||
30
module/base/initial/internal/models/initial_country.go
Normal file
30
module/base/initial/internal/models/initial_country.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package models
|
||||
|
||||
import "git.apinb.com/bsm-sdk/core/database"
|
||||
|
||||
// 国家表
|
||||
type InitialCountry struct {
|
||||
Id uint `gorm:"column:id;" json:"id"` //
|
||||
Iso2 string `gorm:"type:varchar(255);uniqueIndex" json:"iso2"` // ISO 3166-1 alpha-2
|
||||
Iso3 string `gorm:"type:varchar(255);uniqueIndex" json:"iso3"` // ISO 3166-1 alpha-3
|
||||
NumCode string `gorm:"type:varchar(255)" json:"num_code"` // ISO 3166-1 numeric
|
||||
PhoneCode string `gorm:"type:varchar(255)" json:"phone_code"` // 国际电话区号
|
||||
Currency string `gorm:"type:varchar(24);not null" json:"currency"` // 货币简称
|
||||
CurrencySymbol string `gorm:"type:varchar(24);not null" json:"currency_symbol"` // 货币符号
|
||||
Region string `gorm:"type:varchar(24);not null" json:"region"` // 所属地区
|
||||
Name string `gorm:"type:varchar(255);not null" json:"name"` // 英文名称
|
||||
LocalName string `gorm:"type:varchar(255);not null" json:"local_name"` // 本地语言名称
|
||||
Timezones string // 时区配置
|
||||
Translations string // 翻译
|
||||
Enabled bool `gorm:"default:true" json:"enabled"` // 是否启用
|
||||
SortOrder int32 `gorm:"default:0" json:"sort_order"` // 排序
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.AppendMigrate(&InitialCountry{})
|
||||
}
|
||||
|
||||
// TableName .
|
||||
func (table *InitialCountry) TableName() string {
|
||||
return "initial_country" //对应数据库表名
|
||||
}
|
||||
26
module/base/initial/internal/models/initial_datas.go
Normal file
26
module/base/initial/internal/models/initial_datas.go
Normal file
@@ -0,0 +1,26 @@
|
||||
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
|
||||
package models
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/database"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
)
|
||||
|
||||
// 系统数据表
|
||||
type InitialDatas struct {
|
||||
types.Std_IICUDS
|
||||
DataType string `gorm:"column:data_type;type:varchar(255);index;" json:"data_type"` // 数据类型
|
||||
Key string `gorm:"column:key;type:varchar(255);uniqueIndex;" json:"key"`
|
||||
Title string `gorm:"column:title;type:varchar(255);default:'';" json:"title"`
|
||||
Remark string `gorm:"column:remark;type:varchar(255);default:'';" json:"remark"`
|
||||
Icon string `gorm:"column:icon;default:'';" json:"icon"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
database.AppendMigrate(&InitialDatas{})
|
||||
}
|
||||
|
||||
// TableName .
|
||||
func (table *InitialDatas) TableName() string {
|
||||
return "initial_datas" //对应数据库表名
|
||||
}
|
||||
1
module/base/initial/internal/models/query.go
Normal file
1
module/base/initial/internal/models/query.go
Normal file
@@ -0,0 +1 @@
|
||||
package models
|
||||
31
module/base/initial/internal/server/check_server.go
Normal file
31
module/base/initial/internal/server/check_server.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"bsm/full/module/base/initial/internal/logic/check"
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
)
|
||||
|
||||
type CheckServer struct {
|
||||
pb.UnimplementedCheckServer
|
||||
}
|
||||
|
||||
func NewCheckServer() *CheckServer {
|
||||
return &CheckServer{}
|
||||
}
|
||||
|
||||
// HELLO
|
||||
func (s *CheckServer) Hello(ctx context.Context, in *pb.Crc) (*pb.StatusReply, error) {
|
||||
return check.Hello(ctx, in)
|
||||
}
|
||||
|
||||
// 获取应用的相关配置信息
|
||||
func (s *CheckServer) Config(ctx context.Context, in *pb.ConfigRequest) (*pb.ConfigReply, error) {
|
||||
return check.Config(ctx, in)
|
||||
}
|
||||
|
||||
// 检查更新
|
||||
func (s *CheckServer) Updates(ctx context.Context, in *pb.CheckForUpdatesRequest) (*pb.CheckForUpdatesReply, error) {
|
||||
return check.Updates(ctx, in)
|
||||
}
|
||||
30
module/base/initial/internal/server/data_server.go
Normal file
30
module/base/initial/internal/server/data_server.go
Normal file
@@ -0,0 +1,30 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"bsm/full/module/base/initial/internal/logic/data"
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
)
|
||||
|
||||
type DataServer struct {
|
||||
pb.UnimplementedDataServer
|
||||
}
|
||||
|
||||
func NewDataServer() *DataServer {
|
||||
return &DataServer{}
|
||||
}
|
||||
|
||||
func (s *DataServer) Country(ctx context.Context, in *pb.Empty) (*pb.CountryReply, error) {
|
||||
return data.Country(ctx, in)
|
||||
}
|
||||
|
||||
// 系统区域数据,默认级别:市
|
||||
func (s *DataServer) Areas(ctx context.Context, in *pb.AreasRequest) (*pb.AreasReply, error) {
|
||||
return data.Areas(ctx, in)
|
||||
}
|
||||
|
||||
// 系统数据
|
||||
func (s *DataServer) Datas(ctx context.Context, in *pb.Empty) (*pb.DatasReply, error) {
|
||||
return data.Datas(ctx, in)
|
||||
}
|
||||
96
module/base/initial/internal/server/new.go
Normal file
96
module/base/initial/internal/server/new.go
Normal file
@@ -0,0 +1,96 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
pb "bsm/full/module/base/initial/pb"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
gwRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
"google.golang.org/grpc/reflection"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Grpc *grpc.Server
|
||||
Ctx context.Context
|
||||
Mux *gwRuntime.ServeMux
|
||||
grpcConns map[string]*grpc.ClientConn // 连接池
|
||||
}
|
||||
|
||||
func New(addr string) *Server {
|
||||
srv := &Server{
|
||||
Ctx: context.Background(),
|
||||
Grpc: grpc.NewServer(),
|
||||
Mux: gwRuntime.NewServeMux(gwRuntime.WithForwardResponseRewriter(responseEnvelope)),
|
||||
grpcConns: make(map[string]*grpc.ClientConn),
|
||||
}
|
||||
|
||||
// register service to grpc.Server
|
||||
pb.RegisterCheckServer(srv.Grpc, NewCheckServer())
|
||||
pb.RegisterDataServer(srv.Grpc, NewDataServer())
|
||||
|
||||
reflection.Register(srv.Grpc)
|
||||
|
||||
// 连接池: 只创建一次连接并复用
|
||||
conn, ok := srv.grpcConns[addr]
|
||||
if !ok {
|
||||
var err error
|
||||
conn, err = grpc.NewClient(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
|
||||
if err != nil {
|
||||
panic("failed to dial grpc server: " + err.Error())
|
||||
}
|
||||
srv.grpcConns[addr] = conn
|
||||
}
|
||||
|
||||
// 将服务注册到Gateway
|
||||
|
||||
if err := pb.RegisterCheckHandler(srv.Ctx, srv.Mux, conn); err != nil {
|
||||
panic("Failed to register Check handler: " + err.Error())
|
||||
}
|
||||
|
||||
if err := pb.RegisterDataHandler(srv.Ctx, srv.Mux, conn); err != nil {
|
||||
panic("Failed to register Data handler: " + err.Error())
|
||||
}
|
||||
|
||||
// Register services swagger
|
||||
srv.RegisterSwagger()
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
// RegisterSwagger 注册swagger
|
||||
func (s *Server) RegisterSwagger() {
|
||||
srvKey := strings.ToLower(vars.ServiceKey)
|
||||
s.Mux.HandlePath("GET", "/"+srvKey+".swagger.json", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
bytes, err := os.ReadFile("./swagger/" + srvKey + ".swagger.json")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
w.Write(bytes)
|
||||
return
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// response envelope
|
||||
func responseEnvelope(_ context.Context, response proto.Message) (interface{}, error) {
|
||||
name := string(response.ProtoReflect().Descriptor().Name())
|
||||
if name == "Status" || name == "Error" || name == "StatusReply" {
|
||||
return response, nil
|
||||
}
|
||||
return map[string]any{
|
||||
"code": 0,
|
||||
"message": vars.OK,
|
||||
"details": response,
|
||||
"timeseq": time.Now().Unix(),
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user