Skip to content

Commit

Permalink
.
Browse files Browse the repository at this point in the history
  • Loading branch information
jinyaoMa committed Sep 30, 2022
1 parent cbb336e commit 2870d72
Show file tree
Hide file tree
Showing 33 changed files with 903 additions and 108 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# My App (my-app)
# My Application (my-app)

My App is a continuously updated personal service collection.
My Application is a continuously updated personal service collection.

## Technologies

Expand All @@ -11,7 +11,7 @@ My App is a continuously updated personal service collection.
| Sass/Scss | Frontend CSS extension language | https://sass-lang.com/dart-sass |
| Vite | Next Generation Frontend Tooling | https://vitejs.dev/ |
| Vue 3 | Progressive JavaScript Framework | https://vuejs.org/ |
| Wails | Build cross-platform desktop applications using Go | https://wails.io/ |
| Wails v2 | Build cross-platform desktop applications using Go | https://wails.io/ |
| UPX | Ultimate packer for executables | https://upx.github.io/ |
| Systray | A cross platfrom system tray using Go | https://github.com/getlantern/systray |
| Gin | A HTTP web framework using Go | https://gin-gonic.com/ |
Expand Down Expand Up @@ -106,7 +106,7 @@ $ pnpm <[install|preinstall]:[task]> # install/preinstall scripts trigger during
├── frontend # sources related to frontend code, workplace managed by PNPM
│ ├── packages # frontend components, icons, etc.
│ ├── src # wails frontend sources
│ │ ├── vite-env.d.ts # put go struct associated types into namespace app
│ │ ├── vite-env.d.ts # put go struct associated types into it
│ │ └── # ...
│ └── # ...
├── main.go # wails main application, presentations & services layer
Expand Down
120 changes: 120 additions & 0 deletions README.zh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# 我的应用程序 (my-app)

“我的应用程序” 是一个不断更新的个人服务集合。

## 技术

| 技术 | 作用 | 来源 |
| :---------- | :---------------------------------------------------- | :-------------------------------------- |
| Go | Backend programming language | https://pkg.go.dev/std |
| TypeScript | Frontend programming language | https://typescriptlang.org/ |
| Sass/Scss | Frontend CSS extension language | https://sass-lang.com/dart-sass |
| Vite | Next Generation Frontend Tooling | https://vitejs.dev/ |
| Vue 3 | Progressive JavaScript Framework | https://vuejs.org/ |
| Wails v2 | Build cross-platform desktop applications using Go | https://wails.io/ |
| UPX | Ultimate packer for executables | https://upx.github.io/ |
| Systray | A cross platfrom system tray using Go | https://github.com/getlantern/systray |
| Gin | A HTTP web framework using Go | https://gin-gonic.com/ |
| Gin Swagger | Gin middleware for API documentation with Swagger 2.0 | https://github.com/swaggo/gin-swagger |
| Swaggo | Converts Go annotations to Swagger Documentation 2.0 | https://github.com/swaggo/swag |
| Air | Live reload and test for API service | https://github.com/cosmtrek/air |
| GORM | ORM library for Go | https://gorm.io/ |
| SQLite | GORM sqlite driver | https://github.com/go-gorm/sqlite |
| SVG To Font | Generator of fonts from SVG icons | https://github.com/jaywcjlove/svgtofont |

## 安装

安装并准备好在 windows 10/11 中的开发环境

- Git v2.37+, https://git-scm.com/
- Go v1.19+, https://go.dev/
- Node.js v16+, https://nodejs.org/
- PNPM v7+, https://pnpm.io/
- VS Code v1.71+ with GCC, https://code.visualstudio.com/docs/cpp/config-mingw
- WebView2 v104+, https://developer.microsoft.com/en-us/microsoft-edge/webview2/

> 安装 VS Code 推荐插件,在插件搜索栏中输入 `@recommended` 查看推荐插件。
> _CGO_ 包做准备,执行命令 `go env -w CGO_ENABLED=1`
> 安装项目依赖,在项目根目录中,执行命令 `pnpm install`
## NPM 脚本

```shell
$ pnpm wails:dev # run wails in development mode
$ pnpm wails:build # build wails application
$ pnpm upx:compress # compress the generated executable by `wails:build` script
$ pnpm air:dev # test web service individually
$ pnpm swag:docs # generate/update swagger docs
$ pnpm docs:dev # test vitepress docs individually
$ pnpm docs:build # generate/update vitepress docs
$ pnpm icons:build # build frontend/packages/icons
$ pnpm design:build # build frontend/packages/design
$ pnpm <[install|preinstall]:[task]> # install/preinstall scripts trigger during project setup
```

## 目录结构

```yaml
.
├── .tools # auto-generated, development tools/CLIs
├── .vscode # extensions for VS Code
├── air # sources related to air hot reload tool
│ ├── bin # auto-generated, try script `air:dev`
│ ├── .air.toml # air config
│ └── main.go # run web service individually w/o wails and tray
├── backend # sources related to backend code
│ ├── app # app module, business layer
│ │ ├── app.go # contain global state and resources
│ │ ├── config.go # load application options from database
│ │ ├── env.go # load os environment variable
│ │ ├── logger.go # setup loggers
│ ├── model # model module, data layer
│ │ ├── model.go # database setup
│ │ └── my_option.go # define application options for app config storage
│ ├── pkg # pkg module, cross cutting
│ │ ├── i18n # manage locale/translation strings for backend
│ │ ├── log # define loggers for backend
│ │ └── utils # helper functions
│ ├── service # service module, business layer
│ │ ├── service.go # initialize provided services
│ │ └── settings.go # functions about configure application
│ ├── tray # tray module, presentations & services layer
│ │ ├── icons # tray icons
│ │ ├── menus # tray menus
│ │ ├── listeners.go # listen to tray menu-item click events
│ │ └── tray.go # system tray
│ └── web # web module, presentations & services layer
│ ├── api # API services
│ ├── auth # Auth services
│ ├── middleware # custom gin middlewares
│ ├── static # static websites and sources
│ │ ├── certs # auto-generated for localhost TLS, try script `install:certs`
│ │ ├── docs # auto-generated, try script `docs:build`
│ │ ├── swagger # auto-generated, try script `swag:docs`
│ │ ├── static.go # manage static sources
│ │ └── # ...
│ ├── air.go # special function for air to run web service individually
│ ├── router.go # entry point of swaggo docs generator, manage routes for API
│ └── web.go # web service
├── build # sources to use during wails build process
│ ├── bin # auto-generated, try script `wails:dev` or `wails:build`
│ └── # ...
├── diagrams # diagrams about 4+1 view model
├── docs # vitepress documentation
├── frontend # sources related to frontend code, workplace managed by PNPM
│ ├── packages # frontend components, icons, etc.
│ ├── src # wails frontend sources
│ │ ├── vite-env.d.ts # put go struct associated types into it
│ │ └── # ...
│ └── # ...
├── main.go # wails main application, presentations & services layer
├── wails_life_cycle.go # wails life cycle
├── wails.json # wails CLI config
└── # ...
```

## 开发视图

![Package Diagram](./diagrams/package.png)
21 changes: 18 additions & 3 deletions backend/app/app.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package app

import (
"context"
"my-app/backend/model"
"my-app/backend/pkg/log"
"os"
Expand All @@ -15,9 +16,10 @@ var (
)

type app struct {
logger *Logger
env *Env
config *Config
wailsContext context.Context
logger *Logger
env *Env
config *Config
}

func init() {
Expand Down Expand Up @@ -48,6 +50,15 @@ func App() *app {
return instance
}

func (a *app) SetWailsContext(ctx context.Context) *app {
a.wailsContext = ctx
return a
}

func (a *app) WailsContext() context.Context {
return a.wailsContext
}

func (a *app) Config() *Config {
return a.config
}
Expand Down Expand Up @@ -75,3 +86,7 @@ func (a *app) TrayLog() *log.Logger {
func (a *app) WailsLog() logger.Logger {
return a.logger.Wails
}

func (a *app) ServiceLog() *log.Logger {
return a.logger.Service
}
12 changes: 11 additions & 1 deletion backend/app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import (
)

const (
CfgTotalNumberOfOptions = 6
CfgTotalNumberOfOptions = 7
CfgDisplayLanguage = "Config.DisplayLanguage"
CfgColorTheme = "Config.ColorTheme"
CfgLogPath = "Config.LogPath"
CfgWebAutoStart = "Config.Web.AutoStart"
CfgWebPortHttp = "Config.Web.PortHttp"
CfgWebPortHttps = "Config.Web.PortHttps"
CfgWebDirCerts = "Config.Web.DirCerts"
Expand All @@ -30,6 +31,7 @@ type Config struct {
}

type WebConfig struct {
AutoStart string
PortHttp string
PortHttps string
DirCerts string
Expand All @@ -41,6 +43,7 @@ func DefaultConfig() *Config {
ColorTheme: ColorThemeSystem,
LogPath: utils.GetExecutablePath("MyApp.log"),
Web: &WebConfig{
AutoStart: "true",
PortHttp: ":10080",
PortHttps: ":10443",
DirCerts: "",
Expand Down Expand Up @@ -73,6 +76,7 @@ func (c *Config) updateOptions(options model.MyOptions) {
{CfgDisplayLanguage, c.DisplayLanguage},
{CfgColorTheme, c.ColorTheme},
{CfgLogPath, c.LogPath},
{CfgWebAutoStart, c.Web.AutoStart},
{CfgWebPortHttp, c.Web.PortHttp},
{CfgWebPortHttps, c.Web.PortHttps},
{CfgWebDirCerts, c.Web.DirCerts},
Expand Down Expand Up @@ -119,6 +123,10 @@ func (c *Config) saveOptions(options model.MyOptions) {
Name: CfgLogPath,
Value: c.LogPath,
})
options = append(options, model.MyOption{
Name: CfgWebAutoStart,
Value: c.Web.AutoStart,
})
options = append(options, model.MyOption{
Name: CfgWebPortHttp,
Value: c.Web.PortHttp,
Expand Down Expand Up @@ -147,6 +155,8 @@ func (c *Config) loadOptions(options model.MyOptions) {
c.ColorTheme = option.Value
case CfgLogPath:
c.LogPath = option.Value
case CfgWebAutoStart:
c.Web.AutoStart = option.Value
case CfgWebPortHttp:
c.Web.PortHttp = option.Value
case CfgWebPortHttps:
Expand Down
40 changes: 22 additions & 18 deletions backend/app/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ import (
)

const (
LogPrefixModel = "MDL"
LogPrefixWails = "WLS"
LogPrefixApp = "APP"
LogPrefixTray = "TRY"
LogPrefixWeb = "WEB"
LogPrefixModel = "MDL"
LogPrefixWails = "WLS"
LogPrefixApp = "APP"
LogPrefixTray = "TRY"
LogPrefixWeb = "WEB"
LogPrefixService = "SEV"
)

type Logger struct {
Model logger.Interface
Wails wailsLogger.Logger
App *log.Logger
Tray *log.Logger
Web *log.Logger
Model logger.Interface
Wails wailsLogger.Logger
App *log.Logger
Tray *log.Logger
Web *log.Logger
Service *log.Logger
}

func LoadConsoleLogger() *Logger {
Expand All @@ -36,10 +38,11 @@ func LoadConsoleLogger() *Logger {
Colorful: true,
},
),
Wails: log.NewWailsConsoleLogger(LogPrefixWails),
App: log.ConsoleLogger(LogPrefixApp),
Tray: log.ConsoleLogger(LogPrefixTray),
Web: log.ConsoleLogger(LogPrefixWeb),
Wails: log.NewWailsConsoleLogger(LogPrefixWails),
App: log.ConsoleLogger(LogPrefixApp),
Tray: log.ConsoleLogger(LogPrefixTray),
Web: log.ConsoleLogger(LogPrefixWeb),
Service: log.ConsoleLogger(LogPrefixService),
}
}

Expand All @@ -54,9 +57,10 @@ func LoadFileLogger(file *os.File) *Logger {
Colorful: false,
},
),
Wails: log.NewWailsFileLogger(LogPrefixWails, file),
App: log.FileLogger(LogPrefixApp, file),
Tray: log.FileLogger(LogPrefixTray, file),
Web: log.FileLogger(LogPrefixWeb, file),
Wails: log.NewWailsFileLogger(LogPrefixWails, file),
App: log.FileLogger(LogPrefixApp, file),
Tray: log.FileLogger(LogPrefixTray, file),
Web: log.FileLogger(LogPrefixWeb, file),
Service: log.FileLogger(LogPrefixService, file),
}
}
19 changes: 19 additions & 0 deletions backend/pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,22 @@ func init() {
func GetExecutablePath(elem ...string) string {
return filepath.Join(append([]string{executablePath}, elem...)...)
}

func IsDir(path string) bool {
s, err := os.Stat(path)
if err != nil {
return false
}
return s.IsDir()
}

func GetDialogDirectoryPath(path string) string {
if IsDir(path) {
return path
}
next := filepath.Dir(path)
if next == path {
return path
}
return GetDialogDirectoryPath(path)
}
32 changes: 32 additions & 0 deletions backend/service/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package service
import (
"my-app/backend/app"
"my-app/backend/model"
"path/filepath"

"github.com/wailsapp/wails/v2/pkg/runtime"
)

type settings struct{}
Expand All @@ -20,6 +23,8 @@ func (s *settings) SaveOption(name string, value string) error {
app.App().Config().ColorTheme = value
case app.CfgLogPath:
app.App().Config().LogPath = value
case app.CfgWebAutoStart:
app.App().Config().Web.AutoStart = value
case app.CfgWebPortHttp:
app.App().Config().Web.PortHttp = value
case app.CfgWebPortHttps:
Expand All @@ -39,6 +44,8 @@ func (s *settings) GetOption(name string) string {
return app.App().Config().ColorTheme
case app.CfgLogPath:
return app.App().Config().LogPath
case app.CfgWebAutoStart:
return app.App().Config().Web.AutoStart
case app.CfgWebPortHttp:
return app.App().Config().Web.PortHttp
case app.CfgWebPortHttps:
Expand All @@ -52,3 +59,28 @@ func (s *settings) GetOption(name string) string {
func (s *settings) GetOptions() *app.Config {
return app.App().Config()
}

func (s *settings) ChooseLogPath(path string, title string) string {
chosenPath, err := runtime.OpenFileDialog(app.App().WailsContext(), runtime.OpenDialogOptions{
DefaultDirectory: filepath.Dir(path),
DefaultFilename: filepath.Base(path),
Title: title,
ShowHiddenFiles: true,
CanCreateDirectories: true,
ResolvesAliases: false,
TreatPackagesAsDirectories: false,
})
if err != nil {
app.App().ServiceLog().Fatalf("fail to open directory dialog: %+v\n", err)
return ""
}

if chosenPath != "" {
err = s.SaveOption(app.CfgLogPath, chosenPath)
if err != nil {
app.App().ServiceLog().Fatalf("fail to update log path: %+v\n", err)
return ""
}
}
return chosenPath
}
Loading

0 comments on commit 2870d72

Please sign in to comment.