├── .travis.yml
├── README.md
├── bin
└── conf
│ └── develop
│ ├── app.conf
│ ├── dotlog.conf
│ ├── dottask.conf
│ └── dotweb.conf
├── config
├── config.go
└── model.go
├── const
└── const.go
├── core
├── cmap.go
├── exception
│ └── exception.go
└── timex
│ ├── time.go
│ └── time_test.go
├── document
└── demo.MD
├── global
└── global.go
├── main.go
├── protected
├── model
│ └── DemoInfo.go
├── repository
│ ├── BaseRepository.go
│ └── demo
│ │ └── DemoRepository.go
└── service
│ ├── BaseService.go
│ └── demo
│ └── DemoService.go
├── resources
├── config
│ └── develop
│ │ ├── app.conf
│ │ ├── dotlog.conf
│ │ ├── dottask.conf
│ │ └── dotweb.conf
└── version.yaml
├── server
├── contract
│ └── ResponseInfo.go
├── handlers
│ ├── demo
│ │ └── demo.go
│ └── test
│ │ └── default.go
├── router.go
├── server.go
└── validate
│ └── validate.go
├── task
├── service.go
└── tasks
│ └── demo.go
└── util
├── file
└── files.go
├── http
├── http.go
└── http_test.go
├── json
└── json.go
├── rsa
├── rsa.go
└── rsa_test.go
└── time
└── time.go
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: go
2 | sudo: required
3 |
4 | go:
5 | - 1.8
6 |
7 | env:
8 | - GO15VENDOREXPERIMENT="1"
9 |
10 | before_install:
11 | - Project=devfeel
12 |
13 | script:
14 | - go build -o "$Project"
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DotWeb-Start
2 | 基于dotweb的示范项目结构
3 |
4 | ## 注意事项
5 | * 使用配置文件方式,包含app.conf、dotweb.conf、dotlog.conf
6 | * bin目录为特定目录,建议在开发环境时,将编译生成的文件输出到该目录
7 | * 确保bin目录下conf/develop目录下3个配置文件存在
8 |
9 |
10 | ## 目录说明
11 | * config:全局配置文件定义及使用代码
12 | * const:全局常量
13 | * core:全局核心对象
14 | * document:文档目录
15 | * global:全局访问对象定义及入口
16 | * protected:业务逻辑处理模块,包含数据模型、数据操作等
17 | * resources:开发\测试\生产不同环境资源、配置文件及版本信息
18 | * server:web服务目录,包含常规处理逻辑、路由、静态资源等
19 | * task:task服务目录,主要负责调度器相关
20 | * util:通用方法
21 |
22 | ## 依赖项
23 | * github.com/devfeel/dotweb
24 | * github.com/devfeel/dotlog
25 | * github.com/devfeel/mapper
26 | * github.com/devfeel/middleware
27 | * github.com/devfeel/database
--------------------------------------------------------------------------------
/bin/conf/develop/app.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/bin/conf/develop/dotlog.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/bin/conf/develop/dottask.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/bin/conf/develop/dotweb.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/config/config.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "github.com/devfeel/dotweb-start/const"
5 | "github.com/devfeel/dotweb-start/core"
6 | "github.com/devfeel/dotweb-start/util/file"
7 | "github.com/devfeel/dotweb-start/util/json"
8 | "encoding/xml"
9 | "github.com/devfeel/dotlog"
10 | "io/ioutil"
11 | "strconv"
12 | )
13 |
14 | var (
15 | CurrentConfig *AppConfig
16 | CurrentBaseDir string
17 | innerLogger dotlog.Logger
18 | appSetMap *core.CMap
19 | allowIPMap *core.CMap
20 | redisMap *core.CMap
21 | databaseMap *core.CMap
22 | )
23 |
24 | func SetBaseDir(baseDir string) {
25 | CurrentBaseDir = baseDir
26 | }
27 |
28 | //初始化配置文件
29 | func InitConfig(configFile string) *AppConfig {
30 | innerLogger = dotlog.GetLogger(_const.LoggerName_Inner)
31 | CurrentBaseDir = _file.GetCurrentDirectory()
32 | innerLogger.Info("AppConfig::InitConfig 配置文件[" + configFile + "]开始...")
33 | content, err := ioutil.ReadFile(configFile)
34 | if err != nil {
35 | innerLogger.Warn("AppConfig::InitConfig 配置文件[" + configFile + "]无法解析 - " + err.Error())
36 | panic(err)
37 | }
38 |
39 | var result AppConfig
40 | err = xml.Unmarshal(content, &result)
41 | if err != nil {
42 | innerLogger.Warn("AppConfig::InitConfig 配置文件[" + configFile + "]解析失败 - " + err.Error())
43 | panic(err)
44 | }
45 |
46 | //init config base
47 | CurrentConfig = &result
48 |
49 | //init AppConfig
50 | innerLogger.Info("AppConfig::InitConfig Load AppSet Start")
51 | tmpAppSetMap := core.NewCMap()
52 | for _, v := range result.AppSets {
53 | tmpAppSetMap.Set(v.Key, v.Value)
54 | innerLogger.Info("AppConfig::InitConfig Load AppSet => " + _json.GetJsonString(&v))
55 | }
56 | appSetMap = tmpAppSetMap
57 | innerLogger.Info("AppConfig::InitConfig Load AppSet Finished [" + strconv.Itoa(appSetMap.Len()) + "]")
58 |
59 | //init redisConfig
60 | innerLogger.Info("AppConfig::InitConfig Start Load RedisInfo")
61 | tmpRedisMap := core.NewCMap()
62 | for k, v := range result.Redises {
63 | tmpRedisMap.Set(v.ID, result.Redises[k])
64 | innerLogger.Info("AppConfig::InitConfig Load RedisInfo => " + _json.GetJsonString(v))
65 | }
66 | redisMap = tmpRedisMap
67 | innerLogger.Info("AppConfig::InitConfig Finish Load RedisInfo")
68 |
69 | //init databaseConfig
70 | innerLogger.Info("AppConfig::InitConfig Start Load DataBaseInfo")
71 | temDataBaseMap := core.NewCMap()
72 | for k, v := range result.Databases {
73 | temDataBaseMap.Set(v.ID, result.Databases[k])
74 | innerLogger.Info("AppConfig::InitConfig Load DataBaseInfo => " + _json.GetJsonString(v))
75 | }
76 | databaseMap = temDataBaseMap
77 | innerLogger.Info("AppConfig::InitConfig Finish Load DataBaseInfo")
78 |
79 | innerLogger.Info("AppConfig::InitConfig 配置文件[" + configFile + "]完成")
80 |
81 | CurrentConfig.ConfigPath = GetAppConfig("ConfigPath")
82 |
83 | return CurrentConfig
84 | }
85 |
86 | func GetAppConfig(key string) string {
87 | return appSetMap.GetString(key)
88 | }
89 |
90 | func GetAppSetMap() *core.CMap {
91 | return appSetMap
92 | }
93 |
94 | func GetRedisInfo(redisID string) (*RedisInfo, bool) {
95 | info, exists := redisMap.Get(redisID)
96 | if exists {
97 | return info.(*RedisInfo), exists
98 | } else {
99 | return nil, false
100 | }
101 | }
102 |
103 |
104 | func GetDataBaseInfo(databaseId string) (*DataBaseInfo, bool) {
105 | info, exists := databaseMap.Get(databaseId)
106 | if exists {
107 | return info.(*DataBaseInfo), exists
108 | } else {
109 | return nil, false
110 | }
111 | }
112 |
113 |
114 | //检测IP是否被允许访问
115 | func CheckAllowIP(ip string) bool {
116 | return allowIPMap.Exists(ip)
117 | }
118 |
--------------------------------------------------------------------------------
/config/model.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import (
4 | "encoding/xml"
5 | )
6 |
7 | //配置信息
8 | type AppConfig struct {
9 | XMLName xml.Name `xml:"config"`
10 | AppSets []*AppSet `xml:"appsettings>add"`
11 | Redises []*RedisInfo `xml:"redises>redis"`
12 | Databases []*DataBaseInfo `xml:"databases>database"`
13 | AllowIps []string `xml:"allowips>ip"`
14 | ConfigPath string
15 | }
16 |
17 | //AppSetting配置
18 | type AppSet struct {
19 | Key string `xml:"key,attr"`
20 | Value string `xml:"value,attr"`
21 | }
22 |
23 | //Redis信息
24 | type RedisInfo struct {
25 | ID string `xml:"id,attr"`
26 | ServerUrl string `xml:"serverurl,attr"`
27 | }
28 |
29 | //DataBase信息
30 | type DataBaseInfo struct {
31 | ID string `xml:"id,attr"`
32 | ServerUrl string `xml:"serverurl,attr"`
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/const/const.go:
--------------------------------------------------------------------------------
1 | package _const
2 |
3 | const (
4 | Global_ProjectName = "{project}"
5 | Global_Version = "V1.0 - 20171101"
6 | )
7 |
8 | const (
9 | RedisKey_ProjectPre = "{project}"
10 | )
11 |
12 | const (
13 | LoggerName_Inner = "DefaultLogger"
14 | LoggerName_Mongodb = "MongodbLogger"
15 | LoggerName_Service = "ServiceLogger"
16 | LoggerName_Repository = "RepositoryLogger"
17 | )
18 |
19 | const (
20 | ApiRetCode_Ok = 0
21 | ApiRetCode_Error = -9999
22 | ApiRetCode_BindError = -9100
23 | ApiRetCode_ServiceError = -2001
24 | ApiRetMsg_Ok = ""
25 | )
26 |
--------------------------------------------------------------------------------
/core/cmap.go:
--------------------------------------------------------------------------------
1 | package core
2 |
3 | import (
4 | "fmt"
5 | "sync"
6 | )
7 |
8 | //自带锁,并发安全的Map
9 | type CMap struct {
10 | contextMap map[string]interface{}
11 | *sync.RWMutex
12 | }
13 |
14 | func NewCMap() *CMap {
15 | return &CMap{
16 | contextMap: make(map[string]interface{}),
17 | RWMutex: new(sync.RWMutex),
18 | }
19 | }
20 |
21 | /*
22 | * 以key、value置入AppContext
23 | */
24 | func (ctx *CMap) Set(key string, value interface{}) error {
25 | ctx.Lock()
26 | ctx.contextMap[key] = value
27 | ctx.Unlock()
28 | return nil
29 | }
30 |
31 | /*
32 | * 读取指定key在AppContext中的内容
33 | */
34 | func (ctx *CMap) Get(key string) (value interface{}, exists bool) {
35 | ctx.RLock()
36 | value, exists = ctx.contextMap[key]
37 | ctx.RUnlock()
38 | return value, exists
39 | }
40 |
41 | //remove item by gived key
42 | //if not exists key, do nothing...
43 | func (ctx *CMap) Remove(key string) {
44 | ctx.Lock()
45 | delete(ctx.contextMap, key)
46 | ctx.Unlock()
47 | }
48 |
49 | //get item by gived key, and remove it
50 | //only can be read once, it will be locked
51 | func (ctx *CMap) Once(key string) (value interface{}, exists bool) {
52 | ctx.Lock()
53 | defer ctx.Unlock()
54 | value, exists = ctx.contextMap[key]
55 | if exists {
56 | delete(ctx.contextMap, key)
57 | }
58 | return value, exists
59 | }
60 |
61 | /*
62 | * 读取指定key在AppContext中的内容,以string格式输出
63 | */
64 | func (ctx *CMap) GetString(key string) string {
65 | value, exists := ctx.Get(key)
66 | if !exists {
67 | return ""
68 | }
69 | return fmt.Sprint(value)
70 | }
71 |
72 | /*
73 | * 读取指定key在AppContext中的内容,以int格式输出
74 | */
75 | func (ctx *CMap) GetInt(key string) int {
76 | value, exists := ctx.Get(key)
77 | if !exists {
78 | return 0
79 | }
80 | return value.(int)
81 | }
82 |
83 | //check exists key
84 | func (ctx *CMap) Exists(key string) bool {
85 | _, exists := ctx.contextMap[key]
86 | return exists
87 | }
88 |
89 | //get current map, returns map[string]interface{}
90 | func (ctx *CMap) GetCurrentMap() map[string]interface{} {
91 | return ctx.contextMap
92 | }
93 |
94 | //get context length
95 | func (ctx *CMap) Len() int {
96 | return len(ctx.contextMap)
97 | }
98 |
--------------------------------------------------------------------------------
/core/exception/exception.go:
--------------------------------------------------------------------------------
1 | package exception
2 |
3 | import (
4 | "fmt"
5 | "runtime/debug"
6 | )
7 |
8 | type Exception interface {
9 | GetErrString() string
10 | GetStackString() string
11 | GetDefaultLogString() string
12 | }
13 |
14 | type exception struct {
15 | ErrString string
16 | StackString string
17 | DefaultLogString string
18 | }
19 |
20 | func (e *exception) GetErrString() string {
21 | return e.ErrString
22 | }
23 |
24 | func (e *exception) GetStackString() string {
25 | return e.StackString
26 | }
27 |
28 | func (e *exception) GetDefaultLogString() string {
29 | return e.DefaultLogString
30 | }
31 |
32 | //统一异常处理
33 | func CatchError(title string, err interface{}) Exception {
34 | ex := new(exception)
35 | ex.ErrString = fmt.Sprintln(err)
36 | ex.StackString = string(debug.Stack())
37 | ex.DefaultLogString = title + " CatchError [" + ex.GetErrString() + "] [" + ex.GetStackString() + "]"
38 | return ex
39 | }
40 |
--------------------------------------------------------------------------------
/core/timex/time.go:
--------------------------------------------------------------------------------
1 | package timex
2 |
3 | import "time"
4 |
5 | type Time time.Time
6 |
7 | var (
8 | timeJSONFormat = "2006-01-02 15:04:05"
9 | )
10 |
11 | func SetTimeJJSONFormat(format string){
12 | timeJSONFormat = format
13 | }
14 |
15 | func GetTimeJSONFormat()string{
16 | return timeJSONFormat
17 | }
18 |
19 | func (t *Time) UnmarshalJSON(data []byte) (err error) {
20 | now, err := time.ParseInLocation(`"`+timeJSONFormat+`"`, string(data), time.Local)
21 | *t = Time(now)
22 | return
23 | }
24 |
25 | func (t Time) MarshalJSON() ([]byte, error) {
26 | b := make([]byte, 0, len(timeJSONFormat)+2)
27 | b = append(b, '"')
28 | b = time.Time(t).AppendFormat(b, timeJSONFormat)
29 | b = append(b, '"')
30 | return b, nil
31 | }
32 |
33 | func (t Time) String() string {
34 | return time.Time(t).Format(timeJSONFormat)
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/core/timex/time_test.go:
--------------------------------------------------------------------------------
1 | package timex
2 |
3 | import (
4 | "time"
5 | "testing"
6 | "encoding/json"
7 | )
8 |
9 | type Person struct {
10 | Id int64 `json:"id"`
11 | Name string `json:"name"`
12 | Birthday Time `json:"birthday"`
13 | }
14 |
15 | func TestTimeJson(t *testing.T) {
16 | now := Time(time.Now())
17 | t.Log(now)
18 | src := `{"id":5,"name":"xiaoming","birthday":"2016-06-30 16:09:51"}`
19 | p := new(Person)
20 | err := json.Unmarshal([]byte(src), p)
21 | if err != nil {
22 | t.Fatal(err)
23 | }
24 | t.Log(p)
25 | t.Log(time.Time(p.Birthday))
26 | js, _ := json.Marshal(p)
27 | t.Log(string(js))
28 | }
29 |
30 | func TestTimeJson_NewFormat(t *testing.T) {
31 | now := Time(time.Now())
32 | t.Log(now)
33 | SetTimeJJSONFormat("2006-01-02T15:04:05")
34 | src := `{"id":5,"name":"xiaoming","birthday":"2016-06-30T16:09:51"}`
35 | p := new(Person)
36 | err := json.Unmarshal([]byte(src), p)
37 | if err != nil {
38 | t.Fatal(err)
39 | }
40 | t.Log(p)
41 | t.Log(time.Time(p.Birthday))
42 | js, _ := json.Marshal(p)
43 | t.Log(string(js))
44 | }
45 |
--------------------------------------------------------------------------------
/document/demo.MD:
--------------------------------------------------------------------------------
1 | # demo.MD
2 |
3 | dotweb-start项目demo
4 |
5 | #### 依赖项
6 | * github.com/devfeel/dotweb
7 | * github.com/devfeel/dotlog
8 | * github.com/devfeel/cache
9 | * github.com/devfeel/mapper
10 | * github.com/devfeel/middleware
--------------------------------------------------------------------------------
/global/global.go:
--------------------------------------------------------------------------------
1 | package global
2 |
3 | import (
4 | "github.com/devfeel/dotweb"
5 | "github.com/devfeel/dotlog"
6 | "github.com/devfeel/dotweb-start/const"
7 | "errors"
8 | "github.com/devfeel/dotweb-start/core"
9 | "github.com/devfeel/dottask"
10 | )
11 |
12 | //全局map
13 | var GlobalItemMap *core.CMap
14 | var DotApp *dotweb.DotWeb
15 | var DotTask *task.TaskService
16 | var InnerLogger dotlog.Logger
17 |
18 | func Init(configPath string) error{
19 | GlobalItemMap = core.NewCMap()
20 | err := dotlog.StartLogService(configPath + "/dotlog.conf")
21 | if err != nil {
22 | return errors.New("log service start error => " + err.Error())
23 | }
24 | InnerLogger = dotlog.GetLogger(_const.LoggerName_Inner)
25 | return nil
26 | }
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "flag"
5 | "fmt"
6 | _file "github.com/devfeel/dotweb-start/util/file"
7 | "os"
8 | "os/signal"
9 | "syscall"
10 |
11 | "github.com/devfeel/dotweb-start/config"
12 | "github.com/devfeel/dotweb-start/const"
13 | "github.com/devfeel/dotweb-start/core/exception"
14 | "github.com/devfeel/dotweb-start/global"
15 | "github.com/devfeel/dotweb-start/server"
16 | "github.com/devfeel/dotweb-start/task"
17 | )
18 |
19 | var (
20 | configFile string
21 | configPath string
22 | RunEnv string
23 | )
24 |
25 | const (
26 | RunEnv_Flag = "RunEnv"
27 | RunEnv_Develop = "develop"
28 | RunEnv_Test = "test"
29 | RunEnv_Production = "production"
30 | )
31 |
32 | func main() {
33 | defer func() {
34 | if err := recover(); err != nil {
35 | ex := exception.CatchError(_const.Global_ProjectName+":main", err)
36 | global.InnerLogger.Error(fmt.Errorf("%v", err), ex.GetDefaultLogString())
37 | os.Stdout.Write([]byte(ex.GetDefaultLogString()))
38 | }
39 | }()
40 |
41 | parseFlag()
42 |
43 | //全局初始化
44 | err := global.Init(configPath)
45 | if err != nil {
46 | panic(err)
47 | }
48 |
49 | //加载全局xml配置文件
50 | config.InitConfig(configFile)
51 |
52 | //启动Task Service
53 | task.StartTaskService(configPath)
54 |
55 | //监听系统信号
56 | //go listenSignal()
57 |
58 | //启动监听服务
59 | err = server.StartServer(configPath)
60 | if err != nil {
61 | global.InnerLogger.Error(err, "HttpServer.StartServer失败 "+err.Error())
62 | fmt.Println("HttpServer.StartServer失败 " + err.Error())
63 | }
64 |
65 | }
66 |
67 | func parseFlag() {
68 | RunEnv = os.Getenv(RunEnv_Flag)
69 | if RunEnv == "" {
70 | RunEnv = RunEnv_Develop
71 | }
72 |
73 | configPath = _file.GetCurrentDirectory() + "/conf/" + RunEnv
74 | //load app config
75 | flag.StringVar(&configFile, "config", "", "配置文件路径")
76 | if configFile == "" {
77 | configFile = configPath + "/app.conf"
78 | }
79 |
80 | }
81 |
82 | func listenSignal() {
83 | c := make(chan os.Signal, 1)
84 | //syscall.SIGSTOP
85 | signal.Notify(c, syscall.SIGHUP)
86 | for {
87 | s := <-c
88 | global.InnerLogger.Info("signal::ListenSignal [" + s.String() + "]")
89 | switch s {
90 | case syscall.SIGHUP: //配置重载
91 | global.InnerLogger.Info("signal::ListenSignal reload config begin...")
92 | //重新加载配置文件
93 | config.InitConfig(configFile)
94 | global.InnerLogger.Info("signal::ListenSignal reload config end")
95 | default:
96 | return
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/protected/model/DemoInfo.go:
--------------------------------------------------------------------------------
1 | package model
2 |
3 | type DemoInfo struct {
4 | ID int
5 | DemoID int
6 | DemoName string
7 | }
8 |
--------------------------------------------------------------------------------
/protected/repository/BaseRepository.go:
--------------------------------------------------------------------------------
1 | package repository
2 |
3 | import (
4 | "github.com/devfeel/database/mssql"
5 | "github.com/devfeel/dotlog"
6 | "github.com/devfeel/dotweb-start/const"
7 | )
8 |
9 | type BaseRepository struct {
10 | mssql.MsSqlDBContext
11 | databaseLogger dotlog.Logger
12 | }
13 |
14 | func (base *BaseRepository) InitLogger() {
15 | base.databaseLogger = dotlog.GetLogger(_const.LoggerName_Repository)
16 | base.GetCommand().SetOnTrace(base.Trace)
17 | base.GetCommand().SetOnDebug(base.Debug)
18 | base.GetCommand().SetOnInfo(base.Info)
19 | base.GetCommand().SetOnWarn(base.Warn)
20 | base.GetCommand().SetOnError(base.Error)
21 | }
22 |
23 | func (base *BaseRepository) Trace(content interface{}) {
24 | if base.databaseLogger != nil {
25 | base.databaseLogger.Trace(content)
26 | }
27 | }
28 |
29 | func (base *BaseRepository) Debug(content interface{}) {
30 | if base.databaseLogger != nil {
31 | base.databaseLogger.Debug(content)
32 | }
33 | }
34 |
35 | func (base *BaseRepository) Info(content interface{}) {
36 | if base.databaseLogger != nil {
37 | base.databaseLogger.Info(content)
38 | }
39 | }
40 |
41 | func (base *BaseRepository) Warn(content interface{}) {
42 | if base.databaseLogger != nil {
43 | base.databaseLogger.Warn(content)
44 | }
45 | }
46 |
47 | func (base *BaseRepository) Error(err error, content interface{}) {
48 | if base.databaseLogger != nil {
49 | base.databaseLogger.Error(err, content)
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/protected/repository/demo/DemoRepository.go:
--------------------------------------------------------------------------------
1 | package demo
2 |
3 | import (
4 | "errors"
5 | "github.com/devfeel/dotweb-start/config"
6 | "github.com/devfeel/dotweb-start/protected/model"
7 | "github.com/devfeel/dotweb-start/protected/repository"
8 | "sync"
9 | )
10 |
11 | const defaultDatabaseID = "demodb"
12 |
13 | var defaultDemoRepository *DemoRepository
14 | var demoRepositoryLocker *sync.Mutex
15 |
16 | func init() {
17 | demoRepositoryLocker = new(sync.Mutex)
18 | }
19 |
20 | type DemoRepository struct {
21 | repository.BaseRepository
22 | }
23 |
24 | // GetMessageRepository return MessageRepository which is inited
25 | func GetDemoRepository() *DemoRepository {
26 | //check default repository is init
27 | if defaultDemoRepository == nil {
28 | demoRepositoryLocker.Lock()
29 | defer demoRepositoryLocker.Unlock()
30 | if defaultDemoRepository == nil {
31 | defaultDemoRepository = NewDemoRepository()
32 | }
33 | }
34 | return defaultDemoRepository
35 | }
36 |
37 | // NewMessageRepository return new MessageRepository
38 | func NewDemoRepository() *DemoRepository {
39 | dbInfo, exists := config.GetDataBaseInfo(defaultDatabaseID)
40 | if !exists || dbInfo.ServerUrl == "" {
41 | err := errors.New("no config " + defaultDatabaseID + " database config")
42 | panic(err)
43 | }
44 | repository := new(DemoRepository)
45 | repository.Init(dbInfo.ServerUrl)
46 | repository.InitLogger()
47 | return repository
48 | }
49 |
50 | func (repository *DemoRepository) QueryDemoInfo(dest interface{}, demoId int) error {
51 | sql := "SELECT * FROM [Demo] WITH(NOLOCK) WHERE DemoID = ? "
52 | return repository.FindOne(dest, sql, demoId)
53 | }
54 |
55 | func (repository *DemoRepository) QueryTopDemoList(dest interface{}, rowCount int) error {
56 | sql := "SELECT TOP 10 * FROM [Demo] WITH(NOLOCK)"
57 | return repository.FindList(dest, sql)
58 | }
59 |
60 | func (repository *DemoRepository) InsertDemo(demo *model.DemoInfo) (n int64, err error) {
61 | sql := "INSERT INTO [Demo] ([DemoID], [DemoName]) VALUES(?,?)"
62 | return repository.Insert(sql, demo.DemoID, demo.DemoName)
63 | }
64 |
65 | func (repository *DemoRepository) QueryByPage(dest interface{}, skip, take int) error {
66 | fields := "*"
67 | tableName := "Demo"
68 | where := ""
69 | orderBy := "ID ASC, ID DESC"
70 | return repository.FindListByPage(dest, tableName, fields, where, orderBy, skip, take)
71 | }
72 |
--------------------------------------------------------------------------------
/protected/service/BaseService.go:
--------------------------------------------------------------------------------
1 | package service
2 |
3 | import "github.com/devfeel/cache"
4 |
5 | type BaseService struct {
6 | RedisCache cache.RedisCache
7 | }
8 |
--------------------------------------------------------------------------------
/protected/service/demo/DemoService.go:
--------------------------------------------------------------------------------
1 | package demo
2 |
3 | import (
4 | "database/sql"
5 | "errors"
6 | "github.com/devfeel/cache"
7 | "github.com/devfeel/dotlog"
8 | "github.com/devfeel/dotweb-start/config"
9 | "github.com/devfeel/dotweb-start/const"
10 | "github.com/devfeel/dotweb-start/protected/model"
11 | "github.com/devfeel/dotweb-start/protected/repository/demo"
12 | "github.com/devfeel/dotweb-start/protected/service"
13 | "strconv"
14 | )
15 |
16 | var (
17 | defaultDemoRepository *demo.DemoRepository
18 | defaultLogger dotlog.Logger
19 | )
20 |
21 | const (
22 | defaultRedisID = "DefaultRedis"
23 | RedisKey_DemoInfoID = _const.RedisKey_ProjectPre + "DemoInfoID:"
24 | loggerName_DemoService = "DemoServiceLogger"
25 | )
26 |
27 | type DemoService struct {
28 | service.BaseService
29 | demoRepository *demo.DemoRepository
30 | }
31 |
32 | func init() {
33 | defaultLogger = dotlog.GetLogger(loggerName_DemoService)
34 | }
35 |
36 | // NewDemoService create ConfService use default repository config
37 | func NewDemoService() *DemoService {
38 | service := &DemoService{
39 | demoRepository: demo.GetDemoRepository(),
40 | }
41 |
42 | redisInfo, exists := config.GetRedisInfo(defaultRedisID)
43 | if !exists || redisInfo.ServerUrl == "" {
44 | err := errors.New("no config " + defaultRedisID + " redis config")
45 | panic(err)
46 | }
47 | service.RedisCache = cache.GetRedisCache(redisInfo.ServerUrl)
48 | return service
49 | }
50 |
51 | // QueryDemoInfo 根据指定DemoID查询DemoInfo
52 | func (service *DemoService) QueryDemoInfo(demoId int) (*model.DemoInfo, error) {
53 | if demoId <= 0 {
54 | return nil, errors.New("must set demoId")
55 | }
56 | result := new(model.DemoInfo)
57 | var err error
58 | redisKey := RedisKey_DemoInfoID + strconv.Itoa(demoId)
59 | //get from redis
60 | err = service.RedisCache.GetJsonObj(redisKey, result)
61 | if err == nil {
62 | return result, nil
63 | }
64 |
65 | err = service.demoRepository.QueryDemoInfo(result, demoId)
66 | if err == nil {
67 | service.RedisCache.SetJsonObj(redisKey, result)
68 | } else if err == sql.ErrNoRows {
69 | result = nil
70 | err = errors.New("not exists this demo info")
71 | }
72 | return result, err
73 | }
74 |
75 | // QueryDemoList 根据指定记录数查询记录
76 | func (service *DemoService) QueryDemoList(rowNum int) ([]*model.DemoInfo, error) {
77 | if rowNum <= 0 {
78 | return nil, errors.New("must set rowNum")
79 | }
80 | var results []*model.DemoInfo
81 | var err error
82 | err = service.demoRepository.QueryTopDemoList(&results, rowNum)
83 | if err == nil {
84 | if len(results) <= 0 {
85 | results = nil
86 | err = errors.New("not exists this demo info")
87 | }
88 | }
89 | return results, err
90 | }
91 |
92 | func (service *DemoService) AddDemo(demo *model.DemoInfo) error {
93 | if demo == nil {
94 | return errors.New("must set demoinfo")
95 | }
96 | _, err := service.demoRepository.InsertDemo(demo)
97 | defaultLogger.InfoS("AddDemo", *demo, err)
98 | return err
99 | }
100 |
--------------------------------------------------------------------------------
/resources/config/develop/app.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/resources/config/develop/dotlog.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/resources/config/develop/dottask.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/resources/config/develop/dotweb.conf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/resources/version.yaml:
--------------------------------------------------------------------------------
1 | #version tag
2 | version:1.0
3 |
--------------------------------------------------------------------------------
/server/contract/ResponseInfo.go:
--------------------------------------------------------------------------------
1 | package contract
2 |
3 | type ResponseInfo struct {
4 | RetCode int
5 | RetMsg string
6 | Message interface{}
7 | }
8 |
9 | func NewResonseInfo() *ResponseInfo {
10 | return &ResponseInfo{}
11 | }
12 |
13 | func CreateResponse(retCode int, retMsg string, message interface{}) *ResponseInfo {
14 | return &ResponseInfo{
15 | RetCode: retCode,
16 | RetMsg: retMsg,
17 | Message: message,
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/server/handlers/demo/demo.go:
--------------------------------------------------------------------------------
1 | package demo
2 |
3 | import (
4 | "github.com/devfeel/dotweb"
5 | "github.com/devfeel/dotweb-start/server/contract"
6 | "github.com/devfeel/dotweb-start/const"
7 | "strconv"
8 | "github.com/devfeel/dotweb-start/protected/model"
9 | "github.com/devfeel/dotweb-start/protected/service/demo"
10 | )
11 |
12 | const (
13 | PageSize = 20
14 | )
15 |
16 |
17 | // QueryDemoInfo 查询Demo信息,根据传入demoid
18 | // return code:
19 | // 0 success
20 | // -1001 demoid must set
21 | // -2001 query error & err.Error()
22 | func QueryDemoInfo(ctx dotweb.Context) error {
23 | var err error
24 | response := contract.NewResonseInfo()
25 | demoId := ctx.QueryInt("demoid")
26 | demoId_param := ctx.GetRouterName("demoid")
27 | if demoId_param != ""{
28 | demoId, err = strconv.Atoi(demoId_param)
29 | if err != nil{
30 | demoId = 0
31 | }
32 | }
33 |
34 | if demoId <= 0{
35 | return ctx.WriteJson(contract.CreateResponse(-1001, "demoid must set", nil))
36 | }
37 |
38 | //query data from service
39 | demoService := demo.NewDemoService()
40 | demoInfo, err := demoService.QueryDemoInfo(demoId)
41 | if err != nil {
42 | response.RetCode = _const.ApiRetCode_ServiceError
43 | response.RetMsg = err.Error()
44 | } else {
45 | response.RetCode = _const.ApiRetCode_Ok
46 | response.RetMsg = _const.ApiRetMsg_Ok
47 | response.Message = demoInfo
48 | }
49 | return ctx.WriteJson(response)
50 | }
51 |
52 |
53 | func QueryDemoList(ctx dotweb.Context) error {
54 | var err error
55 | response := contract.NewResonseInfo()
56 | //query data from service
57 | demoService := demo.NewDemoService()
58 | demoInfo, err := demoService.QueryDemoList(10)
59 | if err != nil {
60 | response.RetCode = _const.ApiRetCode_ServiceError
61 | response.RetMsg = err.Error()
62 | } else {
63 | response.RetCode = _const.ApiRetCode_Ok
64 | response.RetMsg = _const.ApiRetMsg_Ok
65 | response.Message = demoInfo
66 | }
67 | return ctx.WriteJson(response)
68 | }
69 |
70 | func AddDemo(ctx dotweb.Context) error {
71 | var err error
72 | response := contract.NewResonseInfo()
73 | demoInfo := &model.DemoInfo{
74 | DemoID:10000,
75 | DemoName : "demoapp",
76 | }
77 |
78 | //query data from service
79 | demoService := demo.NewDemoService()
80 | err = demoService.AddDemo(demoInfo)
81 | if err != nil {
82 | response.RetCode = _const.ApiRetCode_ServiceError
83 | response.RetMsg = err.Error()
84 | } else {
85 | response.RetCode = _const.ApiRetCode_Ok
86 | response.RetMsg = _const.ApiRetMsg_Ok
87 | response.Message = demoInfo
88 | }
89 | return ctx.WriteJson(response)
90 | }
--------------------------------------------------------------------------------
/server/handlers/test/default.go:
--------------------------------------------------------------------------------
1 | package test
2 |
3 | import (
4 | "github.com/devfeel/dotweb-start/const"
5 | "github.com/devfeel/dotweb"
6 | )
7 |
8 | func Index(ctx dotweb.Context) error {
9 | ctx.ViewData().Set("version", _const.Global_Version)
10 | ctx.Response().SetHeader("testh", "testh-v")
11 | return ctx.WriteString("welcome to ", _const.Global_ProjectName)
12 | }
13 |
--------------------------------------------------------------------------------
/server/router.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "github.com/devfeel/dotweb"
5 | "github.com/devfeel/dotweb-start/global"
6 |
7 | "github.com/devfeel/dotweb-start/server/handlers/demo"
8 | "github.com/devfeel/dotweb-start/server/handlers/test"
9 | )
10 |
11 | func InitRoute(server *dotweb.HttpServer) {
12 | g := server.Group("/test")
13 | g.GET("/index", test.Index)
14 |
15 | g = server.Group("/demo")
16 | g.GET("/queryinfo", demo.QueryDemoInfo)
17 | g.GET("/info/:demoid", demo.QueryDemoInfo)
18 | g.GET("/querylist", demo.QueryDemoList)
19 | g.GET("/add", demo.AddDemo)
20 | server.RegisterHandlerFunc(dotweb.RouteMethod_GET, "/task/counter", global.DotTask.CounterOutputHttpHandler)
21 | server.RegisterHandlerFunc(dotweb.RouteMethod_GET, "/task/task", global.DotTask.TaskOutputHttpHandler)
22 | }
23 |
--------------------------------------------------------------------------------
/server/server.go:
--------------------------------------------------------------------------------
1 | package server
2 |
3 | import (
4 | "github.com/devfeel/dotweb-start/global"
5 | _ "fmt"
6 | "github.com/devfeel/dotweb"
7 | "github.com/devfeel/dotweb/config"
8 | "github.com/devfeel/middleware/cors"
9 | "strconv"
10 | )
11 |
12 | func StartServer(configPath string) error {
13 | appConfig := config.MustInitConfig(configPath + "/dotweb.conf")
14 | global.DotApp = dotweb.ClassicWithConf(appConfig)
15 |
16 | global.DotApp.SetDevelopmentMode()
17 | global.DotApp.UseRequestLog()
18 | global.DotApp.Use(cors.Middleware(cors.NewConfig().UseDefault()))
19 |
20 | //设置路由
21 | InitRoute(global.DotApp.HttpServer)
22 |
23 | global.InnerLogger.Debug("dotweb.StartServer => " + strconv.Itoa(appConfig.Server.Port))
24 | err := global.DotApp.Start()
25 | if err != nil {
26 | panic(err)
27 | }
28 | return err
29 | }
30 |
--------------------------------------------------------------------------------
/server/validate/validate.go:
--------------------------------------------------------------------------------
1 | package validate
2 |
3 | import (
4 | "github.com/devfeel/dotweb-start/server/contract"
5 | "github.com/pkg/errors"
6 | )
7 |
8 | func IsNilString(val string, errCode int, errMsg string) (*contract.ResponseInfo, error) {
9 | if val != "" {
10 | return contract.NewResonseInfo(), nil
11 | } else {
12 | return contract.CreateResponse(errCode, errMsg, nil), errors.New("val is nil")
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/task/service.go:
--------------------------------------------------------------------------------
1 | package task
2 |
3 | import (
4 | "github.com/devfeel/dottask"
5 | "github.com/devfeel/dotweb-start/global"
6 | "github.com/devfeel/dotweb-start/task/tasks"
7 | "fmt"
8 | )
9 |
10 | func registerTask(service *task.TaskService) {
11 | //TODO register task to service
12 | service.RegisterHandler("Task_Print", tasks.Task_Print)
13 | }
14 |
15 | func StartTaskService(configPath string) {
16 | global.DotTask = task.StartNewService()
17 |
18 | //register all task handler
19 | registerTask(global.DotTask)
20 |
21 | //load config file
22 | global.DotTask.LoadConfig(configPath + "/dottask.conf")
23 |
24 | //start all task
25 | global.DotTask.StartAllTask()
26 |
27 | global.InnerLogger.Debug(fmt.Sprint("StartTaskService", " ", configPath, " ", global.DotTask.PrintAllCronTask()))
28 | }
29 |
30 | func StopTaskService() {
31 | if global.DotTask != nil {
32 | global.DotTask.StopAllTask()
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/task/tasks/demo.go:
--------------------------------------------------------------------------------
1 | package tasks
2 |
3 | import (
4 | "github.com/devfeel/dottask"
5 | "fmt"
6 | "time"
7 | )
8 |
9 | func Task_Print(context *task.TaskContext) error {
10 | fmt.Println(time.Now(), "Task_Print", context.TaskID)
11 | return nil
12 | }
13 |
--------------------------------------------------------------------------------
/util/file/files.go:
--------------------------------------------------------------------------------
1 | package _file
2 |
3 | import (
4 | "log"
5 | "os"
6 | "path/filepath"
7 | "strings"
8 | )
9 |
10 | func GetCurrentDirectory() string {
11 | dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
12 | if err != nil {
13 | log.Fatalln(err)
14 | os.Exit(1)
15 | }
16 | return strings.Replace(dir, "\\", "/", -1)
17 | }
18 |
19 | //get filename extensions
20 | func GetFileExt(fileName string) string {
21 | if fileName == "" {
22 | return ""
23 | } else {
24 | index := strings.LastIndex(fileName, ".")
25 | if index < 0 {
26 | return ""
27 | } else {
28 | return string(fileName[index:])
29 | }
30 | }
31 | }
32 |
33 | //check filename is exist
34 | func Exist(filename string) bool {
35 | _, err := os.Stat(filename)
36 | return err == nil || os.IsExist(err)
37 | }
38 |
--------------------------------------------------------------------------------
/util/http/http.go:
--------------------------------------------------------------------------------
1 | package _http
2 |
3 | import (
4 | "bytes"
5 | "crypto/tls"
6 | "io/ioutil"
7 | "net"
8 | "net/http"
9 | "net/url"
10 | "time"
11 | )
12 |
13 | const (
14 | MaxIdleConns int = 100
15 | MaxIdleConnsPerHost int = 50
16 | IdleConnTimeout int = 90
17 | InsecureSkipVerify = true
18 | )
19 |
20 | var currClient *http.Client
21 |
22 | func getHttpClient() *http.Client {
23 | return currClient
24 | }
25 |
26 | func init() {
27 | transport := &http.Transport{
28 | Proxy: http.ProxyFromEnvironment,
29 | DialContext: (&net.Dialer{
30 | Timeout: 30 * time.Second,
31 | KeepAlive: 30 * time.Second,
32 | }).DialContext,
33 | MaxIdleConns: MaxIdleConns,
34 | MaxIdleConnsPerHost: MaxIdleConnsPerHost,
35 | IdleConnTimeout: time.Duration(IdleConnTimeout) * time.Second,
36 | TLSClientConfig: &tls.Config{InsecureSkipVerify: InsecureSkipVerify},
37 | }
38 | currClient = &http.Client{Transport: transport}
39 | }
40 |
41 | func HttpGet(url string) (body string, contentType string, intervalTime int64, errReturn error) {
42 | startTime := time.Now()
43 | intervalTime = 0
44 | contentType = ""
45 | body = ""
46 | errReturn = nil
47 |
48 | resp, err := getHttpClient().Get(url)
49 | if err != nil {
50 | intervalTime = int64(time.Now().Sub(startTime) / time.Millisecond)
51 | errReturn = err
52 | return
53 | }
54 | defer resp.Body.Close()
55 |
56 | bytebody, err := ioutil.ReadAll(resp.Body)
57 | intervalTime = int64(time.Now().Sub(startTime) / time.Millisecond)
58 | if err != nil {
59 | intervalTime = int64(time.Now().Sub(startTime) / time.Millisecond)
60 | errReturn = err
61 | return
62 | }
63 | body = string(bytebody)
64 | contentType = resp.Header.Get("Content-Type")
65 | intervalTime = int64(time.Now().Sub(startTime) / time.Millisecond)
66 | return
67 | }
68 |
69 | func HttpPost(url string, postbody string, bodyType string) (body string, contentType string, intervalTime int64, errReturn error) {
70 | startTime := time.Now()
71 | intervalTime = 0
72 | contentType = ""
73 | body = ""
74 | errReturn = nil
75 | postbytes := bytes.NewBuffer([]byte(postbody))
76 | //resp, err := currClient.Post(url, "application/x-www-form-urlencoded", postbytes)
77 | //resp, err := currClient.Post(url, "application/json", postbytes)
78 | if bodyType == "" {
79 | bodyType = "application/x-www-form-urlencoded"
80 | }
81 | resp, err := getHttpClient().Post(url, bodyType, postbytes)
82 | if err != nil {
83 | intervalTime = int64(time.Now().Sub(startTime) / time.Millisecond)
84 | errReturn = err
85 | return
86 | }
87 | defer resp.Body.Close()
88 |
89 | bytebody, err := ioutil.ReadAll(resp.Body)
90 | if err != nil {
91 | intervalTime = int64(time.Now().Sub(startTime) / time.Millisecond)
92 | errReturn = err
93 | return
94 | }
95 | body = string(bytebody)
96 | contentType = resp.Header.Get("Content-Type")
97 | intervalTime = int64(time.Now().Sub(startTime) / time.Millisecond)
98 | return
99 |
100 | }
101 |
102 | //从指定query集合获取指定key的值
103 | func GetQuery(querys url.Values, key string) string {
104 | if len(querys[key]) > 0 {
105 | return querys[key][0]
106 | }
107 | return ""
108 | }
109 |
--------------------------------------------------------------------------------
/util/http/http_test.go:
--------------------------------------------------------------------------------
1 | package _http
2 |
3 | import (
4 | "testing"
5 | )
6 |
7 | func TestHttpGet(t *testing.T) {
8 | url := "http://www.baidu.com"
9 | _, _, _, err := HttpGet(url)
10 | if err != nil {
11 | t.Error(err)
12 | } else {
13 | t.Log("HttpGet success")
14 | }
15 | }
16 |
17 | func TestHttpPost(t *testing.T) {
18 | url := "http://www.baidu.com"
19 | _, _, _, err := HttpPost(url, "", "")
20 | if err != nil {
21 | t.Error(err)
22 | } else {
23 | t.Log("HttpPost success")
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/util/json/json.go:
--------------------------------------------------------------------------------
1 | package _json
2 |
3 | import (
4 | "encoding/json"
5 | )
6 |
7 | //将传入对象转换为json字符串
8 | func GetJsonString(obj interface{}) string {
9 | resByte, err := json.Marshal(obj)
10 | if err != nil {
11 | return ""
12 | }
13 | return string(resByte)
14 | }
15 |
16 | //将传入对象转换为json字符串
17 | func Marshal(v interface{}) (string, error) {
18 | resByte, err := json.Marshal(v)
19 | if err != nil {
20 | return "", err
21 | } else {
22 | return string(resByte), nil
23 | }
24 | }
25 |
26 | //将传入的json字符串转换为对象
27 | func Unmarshal(jsonstring string, v interface{}) error {
28 | return json.Unmarshal([]byte(jsonstring), v)
29 | }
30 |
--------------------------------------------------------------------------------
/util/rsa/rsa.go:
--------------------------------------------------------------------------------
1 | package _rsa
2 |
3 | import (
4 | "crypto/x509"
5 | "crypto/rsa"
6 | "crypto/rand"
7 | "encoding/pem"
8 | "errors"
9 | )
10 |
11 | // RsaEncrypt
12 | func RsaEncrypt(origData []byte, publicKey []byte) ([]byte, error) {
13 | block, _ := pem.Decode(publicKey)
14 | if block == nil {
15 | return nil, errors.New("public key error")
16 | }
17 | pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
18 | if err != nil {
19 | return nil, err
20 | }
21 | pub := pubInterface.(*rsa.PublicKey)
22 | return rsa.EncryptPKCS1v15(rand.Reader, pub, origData)
23 | }
24 |
25 | // RsaDecrypt
26 | // key-len: 1024
27 | // PKCS#1
28 | func RsaDecrypt(ciphertext []byte, privateKey []byte) ([]byte, error) {
29 | block, _ := pem.Decode(privateKey)
30 | if block == nil {
31 | return nil, errors.New("private key error!")
32 | }
33 | priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
34 | if err != nil {
35 | return nil, err
36 | }
37 | return rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext)
38 | }
39 |
40 |
--------------------------------------------------------------------------------
/util/rsa/rsa_test.go:
--------------------------------------------------------------------------------
1 | package _rsa
2 |
3 | import (
4 | "fmt"
5 | "encoding/base64"
6 | "testing"
7 | )
8 |
9 | var publicKey = []byte(`
10 | -----BEGIN PUBLIC KEY-----
11 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGelAapImDcWTfOU3xFQedpRq8
12 | EoLcoPRa0Xu4GsmtaqS34SgmLd+NwA9VfzB0vLdcwLFEV9lsnr2aScyTVr0feac6
13 | xVIWI7SHmQLGlCw4Akb5kYpSdpHxuxfiTLYgWeAfrDw4idwvKopCmq+XQlpbzUVc
14 | +Af0egG/GyV1bQMy3wIDAQAB
15 | -----END PUBLIC KEY-----
16 | `)
17 |
18 |
19 | var privateKey = []byte(`
20 | -----BEGIN RSA PRIVATE KEY-----
21 | MIICXAIBAAKBgQCGelAapImDcWTfOU3xFQedpRq8EoLcoPRa0Xu4GsmtaqS34Sgm
22 | Ld+NwA9VfzB0vLdcwLFEV9lsnr2aScyTVr0feac6xVIWI7SHmQLGlCw4Akb5kYpS
23 | dpHxuxfiTLYgWeAfrDw4idwvKopCmq+XQlpbzUVc+Af0egG/GyV1bQMy3wIDAQAB
24 | AoGAd5OdVQOHr5SOEJvg/YUon3onWqLPMCYDAhqR+3P+bzCLxWH1lHVn+qCUQf71
25 | 9Ge2WEiTl+TR1e8VQ3Np8H3JbjmH9hHaeZN0k3fQ3LfCqB9c/J9LvSlbScWPoqZU
26 | +fTdrVG62s6330D94oeUOJdnkI7vwA5kIddAgtFhOEXP8oECQQCXGv9TcdmtNZby
27 | 8D6Zd6XGqRLNHIRKuS4GjC5Txiy0XGGibUGtS/R5VUEgORsryJJrE3Rq8Li5KCDX
28 | h16di85BAkEA49Rn7cXPhIWdACTvcs6u+vgualGgeslM+Q59Sxd+9hir+z/ZEyN7
29 | RzaHILzVORoVOvSk5zvKZ4SBFQes73j5HwJAdE05O/ai/igDGNVEuUZX+AHmEKzk
30 | Pcct36hBeAVOHzwDgcrqBAI0FrdBuxV5DkgAOh3tOuowo4J5VKpCbqxOgQJBAInQ
31 | I2nN/UBBfn3m2b0NzwTa+WCwra14dQo2vI2e0drVg7rAnXOZQ+oIzuZ7s1MONwdp
32 | kxKYtU+29EofUXmuKKsCQHAbpFRFH8sOB/F3UDFjo/yakRfiEBggikcRFOJ1jY6k
33 | C2aEY5hDv0f6EXWuyg7iw/9320wV7OPhKCW6J9FANvA=
34 | -----END RSA PRIVATE KEY-----
35 | `)
36 |
37 |
38 | func Test_RSA(t *testing.T){
39 | raw := "ea4d35ed8fe19e11b17917ad273021_11_22_x1dd"
40 | encryptBytes, err := RsaEncrypt([]byte(raw), publicKey)
41 | if err!=nil{
42 | t.Error("RsaEncrypt error", err)
43 | return
44 | }
45 | fmt.Println("RsaEncrypt success", base64.StdEncoding.EncodeToString(encryptBytes))
46 | decryptBytes, err:= RsaDecrypt(encryptBytes, privateKey)
47 | if err!=nil{
48 | t.Error("RsaDecrypt error", err)
49 | return
50 | }
51 | if raw == string(decryptBytes){
52 | t.Log("RsaDecrypt success", raw, string(decryptBytes))
53 | }else{
54 | t.Error("RsaDecrypt failed", raw, string(decryptBytes))
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/util/time/time.go:
--------------------------------------------------------------------------------
1 | package _time
2 |
3 | import (
4 | "errors"
5 | "time"
6 | )
7 |
8 | //ParseTime 使用常用的时间格式尝试将字符串转换为time对象
9 | func ParseTime(timeStr string) (time.Time, error) {
10 | timeFormatList := []string{
11 | time.RFC3339,
12 | "2006-01-02 15:04:05",
13 | "2006-01-02 15:04",
14 | "2006-1-2 15:04:05",
15 | "2006-1-2 15:04",
16 | "2006-1-2 15:04 MST",
17 | "2006-1-2 15:04:05 MST",
18 | "2006-01-02 15:04 MST",
19 | "2006-01-02 15:04:05 MST",
20 | "2006-01-02T15:04:05Z",
21 | "2006-1-2T15:04:05Z",
22 | "2006-01-02T15:04:05",
23 | "2006-1-2T15:04:05",
24 | "2006/01/02 15:04:05",
25 | "2006/01/02 15:04",
26 | "2006/1/2 15:04:05",
27 | "2006/1/2 15:04",
28 | "2006/1/2 15:04 MST",
29 | "2006/1/2 15:04:05 MST",
30 | "2006/01/02 15:04 MST",
31 | "2006/01/02 15:04:05 MST",
32 | "2006/01/02T15:04:05Z",
33 | "2006/1/2T15:04:05Z",
34 | "2006-1-2",
35 | "2006-01-02"}
36 | for _, format := range timeFormatList {
37 | time, err := time.ParseInLocation(format, timeStr, time.Local)
38 | if err == nil {
39 | return time, nil
40 | }
41 | }
42 | return time.Time{}, errors.New("未找到匹配的时间格式")
43 |
44 | }
45 |
46 | // ToDay 获取当前日期
47 | //一个对象,设置为当天日期,其时间组成部分设置为 00:00:00。
48 | func ToDay() time.Time {
49 | now := time.Now()
50 | time, _ := time.ParseInLocation("2006-1-2 MST", now.Format("2006-1-2 MST"), time.Local)
51 | return time
52 | }
53 |
54 | // GetMondayAndFriday 获取指定日期所在周的周一和周五
55 | func GetMondayAndFriday(date time.Time) (monday time.Time, friday time.Time) {
56 | weekDay := int(date.Weekday())
57 | if weekDay == 0 {
58 | weekDay = 7
59 | }
60 | monday = date.AddDate(0, 0, -weekDay+1)
61 | friday = date.AddDate(0, 0, 5-weekDay)
62 | return monday, friday
63 | }
64 |
65 | // GetTimestamp 获取时间戳 毫秒级
66 | func GetTimestamp(date time.Time) (timestamp int64) {
67 | timestamp = date.UnixNano() / 1000000
68 | return timestamp
69 | }
70 |
--------------------------------------------------------------------------------