Compare commits

...

2 Commits

8
.idea/.gitignore vendored

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="Go" enabled="true" />
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/awesomeProject.iml" filepath="$PROJECT_DIR$/.idea/awesomeProject.iml" />
</modules>
</component>
</project>

@ -0,0 +1,6 @@
ROOT_DIR = $(shell pwd)
NAMESPACE = "default"
DEPLOY_NAME = "template-single"
DOCKER_NAME = "template-single"
include ./hack/hack.mk

@ -0,0 +1 @@
package main

@ -0,0 +1,17 @@
package main
import (
"github.com/gogf/gf/crypto/gmd5"
"github.com/gogf/gf/util/guid"
)
func GenerateToken(uid interface{}) (string, error) {
// 生成一个随机的 GUID 作为 token
token := guid.S()
// 使用 MD5 加密 token
encryptedToken, err := gmd5.Encrypt(token)
if err != nil {
return "", err
}
return encryptedToken, nil
}

@ -0,0 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package hello
import (
"context"
"awesomeProject/api/hello/v1"
)
type IHelloV1 interface {
Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error)
}

@ -0,0 +1,12 @@
package v1
import (
"github.com/gogf/gf/v2/frame/g"
)
type HelloReq struct {
g.Meta `path:"/hello" tags:"Hello" method:"get" summary:"You first hello api"`
}
type HelloRes struct {
g.Meta `mime:"text/html" example:"string"`
}

@ -0,0 +1,12 @@
package user
import (
"context"
"awesomeProject/api/user/v1"
)
type UserHandler interface {
Login(ctx context.Context, req *v1.LoginReq) (res *v1.LoginRes, err error)
Register(ctx context.Context, req *v1.RegisterReq) (res *v1.RegisterRes, err error)
}

@ -0,0 +1,45 @@
package v1
import (
"github.com/gogf/gf/v2/frame/g"
)
type LoginReq struct {
g.Meta `path:"/login" tags:"Login" method:"post" summary:"user login process"`
Username string `json:"username" v:"required|length:4,30#请输入用户名|用户名长度为:min到:max位"`
Password string `json:"password" v:"required|length:6,30#请输入密码|密码长度为:min到:max位"`
}
type LoginRes struct {
g.Meta `mime:"text/html" example:"{"code":200,"msg":"注册成功"}"`
Reply string `dc:"Reply content"`
Cookie string
}
// RegisterReq 是注册接口的请求参数结构体。
type RegisterReq struct {
g.Meta `path:"/register" tags:"Register" method:"post" summary:"处理用户注册请求"`
Username string `json:"username" v:"required|length:6,30#请输入用户名|用户名长度为:min到:max位"`
Password string `json:"password" v:"required|length:6,30#请输入密码|密码长度为:min到:max位"`
Email string `json:"email" v:"required|email#请输入有效的邮箱地址"`
}
// RegisterRes 是注册接口的响应参数结构体。
type RegisterRes struct {
g.Meta `mime:"application/json" example:"{"code":200,"msg":"注册成功"}"`
Code int `json:"code"`
Msg string `json:"msg"`
}
// RegisterReq 是注册接口的请求参数结构体。
type PushMessageReq struct {
g.Meta `path:"/api/pushmessage" tags:"PushMessage" method:"post" summary:"发送消息"`
body map[string]interface{} `json:"body"`
}
// RegisterRes 是注册接口的响应参数结构体。
type PushMessageRes struct {
g.Meta `mime:"application/json" example:"{"code":200,"msg":"push successed"}"`
Code int `json:"code"`
Msg map[string]interface{} `json:"msg"`
}

Binary file not shown.

@ -0,0 +1,19 @@
database:
default:
link: "mysql:root:12345678@tcp(127.0.0.1:3306)/chanbeyEDU"
logger:
path: "/var/log/gf-app/sql"
level: "all"
stdout: "true"
server:
data:
WeChat:
classPushOfficial:
appId: "wxa4d01973e9df0619"
appSecret: "e57ed40f88fbaf10d60cad2b18a0e54e"

@ -0,0 +1,36 @@
module awesomeProject
go 1.18
require (
github.com/gogf/gf v1.16.9
github.com/gogf/gf/v2 v2.5.2
)
require (
github.com/BurntSushi/toml v1.2.0 // indirect
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28 // indirect
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/gomodule/redigo v1.8.5 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/grokify/html-strip-tags-go v0.0.1 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/sdk v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.14.0 // indirect
golang.org/x/net v0.22.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

@ -0,0 +1,92 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28 h1:LdXxtjzvZYhhUaonAaAKArG3pyC67kGL3YY+6hGG8G4=
github.com/clbanning/mxj v1.8.5-0.20200714211355-ff02cfb8ea28/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng=
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/gogf/gf v1.16.9 h1:Q803UmmRo59+Ws08sMVFOcd8oNpkSWL9vS33hlo/Cyk=
github.com/gogf/gf v1.16.9/go.mod h1:8Q/kw05nlVRp+4vv7XASBsMe9L1tsVKiGoeP2AHnlkk=
github.com/gogf/gf/v2 v2.5.2 h1:fACJE7DJH6iTGHGhgiNY1uuZIZtr2IqQkJ52E+wBnt8=
github.com/gogf/gf/v2 v2.5.2/go.mod h1:7yf5qp0BznfsYx7Sw49m3mQvBsHpwAjJk3Q9ZnKoUEc=
github.com/gomodule/redigo v1.8.5 h1:nRAxCa+SVsyjSBrtZmG/cqb6VbTmuRzpg/PoTFlpumc=
github.com/gomodule/redigo v1.8.5/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grokify/html-strip-tags-go v0.0.1 h1:0fThFwLbW7P/kOiTBs03FsJSV9RM2M/Q/MOnCQxKMo0=
github.com/grokify/html-strip-tags-go v0.0.1/go.mod h1:2Su6romC5/1VXOQMaWL2yb618ARB8iVo6/DR99A6d78=
github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

@ -0,0 +1,8 @@
# CLI tool, only in development environment.
# https://goframe.org/pages/viewpage.action?pageId=3673173
gfcli:
docker:
build: "-a amd64 -s linux -p temp -ew"
tagPrefixes:
- my.image.pub/my-app

@ -0,0 +1,19 @@
# Install/Update to the latest CLI tool.
.PHONY: cli
cli:
@set -e; \
wget -O gf https://github.com/gogf/gf/releases/latest/download/gf_$(shell go env GOOS)_$(shell go env GOARCH) && \
chmod +x gf && \
./gf install -y && \
rm ./gf
# Check and install CLI tool.
.PHONY: cli.install
cli.install:
@set -e; \
gf -v > /dev/null 2>&1 || if [[ "$?" -ne "0" ]]; then \
echo "GoFame CLI is not installed, start proceeding auto installation..."; \
make cli; \
fi;

@ -0,0 +1,75 @@
include ./hack/hack-cli.mk
# Update GoFrame and its CLI to latest stable version.
.PHONY: up
up: cli.install
@gf up -a
# Build binary using configuration from hack/config.yaml.
.PHONY: build
build: cli.install
@gf build -ew
# Parse api and generate controller/sdk.
.PHONY: ctrl
ctrl: cli.install
@gf gen ctrl
# Generate Go files for DAO/DO/Entity.
.PHONY: dao
dao: cli.install
@gf gen dao
# Parse current project go files and generate enums go file.
.PHONY: enums
enums: cli.install
@gf gen enums
# Generate Go files for Service.
.PHONY: service
service: cli.install
@gf gen service
# Build docker image.
.PHONY: image
image: cli.install
$(eval _TAG = $(shell git describe --dirty --always --tags --abbrev=8 --match 'v*' | sed 's/-/./2' | sed 's/-/./2'))
ifneq (, $(shell git status --porcelain 2>/dev/null))
$(eval _TAG = $(_TAG).dirty)
endif
$(eval _TAG = $(if ${TAG}, ${TAG}, $(_TAG)))
$(eval _PUSH = $(if ${PUSH}, ${PUSH}, ))
@gf docker ${_PUSH} -tn $(DOCKER_NAME):${_TAG};
# Build docker image and automatically push to docker repo.
.PHONY: image.push
image.push:
@make image PUSH=-p;
# Deploy image and yaml to current kubectl environment.
.PHONY: deploy
deploy:
$(eval _TAG = $(if ${TAG}, ${TAG}, develop))
@set -e; \
mkdir -p $(ROOT_DIR)/temp/kustomize;\
cd $(ROOT_DIR)/manifest/deploy/kustomize/overlays/${_ENV};\
kustomize build > $(ROOT_DIR)/temp/kustomize.yaml;\
kubectl apply -f $(ROOT_DIR)/temp/kustomize.yaml; \
if [ $(DEPLOY_NAME) != "" ]; then \
kubectl patch -n $(NAMESPACE) deployment/$(DEPLOY_NAME) -p "{\"spec\":{\"template\":{\"metadata\":{\"labels\":{\"date\":\"$(shell date +%s)\"}}}}}"; \
fi;
# Parsing protobuf files and generating go files.
.PHONY: pb
pb: cli.install
@gf gen pb
# Generate protobuf files for database tables.
.PHONY: pbentity
pbentity: cli.install
@gf gen pbentity

@ -0,0 +1,37 @@
package cmd
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcmd"
"awesomeProject/internal/controller/hello"
"awesomeProject/internal/controller/user"
)
func MiddlewareHandler(r *ghttp.Request) {
}
var (
Main = gcmd.Command{
Name: "main",
Usage: "main",
Brief: "start http server",
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
s := g.Server()
s.SetPort(80)
s.Group("/", func(group *ghttp.RouterGroup) {
group.Middleware(ghttp.MiddlewareHandlerResponse)
group.Bind(
hello.NewV1(),
user.NewUserController(),
)
})
s.Run()
return nil
},
}
)

@ -0,0 +1 @@
package consts

@ -0,0 +1,5 @@
// =================================================================================
// This is auto-generated by GoFrame CLI tool only once. Fill this file as you wish.
// =================================================================================
package hello

@ -0,0 +1,15 @@
// =================================================================================
// Code generated and maintained by GoFrame CLI tool. DO NOT EDIT.
// =================================================================================
package hello
import (
"awesomeProject/api/hello"
)
type ControllerV1 struct{}
func NewV1() hello.IHelloV1 {
return &ControllerV1{}
}

@ -0,0 +1,13 @@
package hello
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"awesomeProject/api/hello/v1"
)
func (c *ControllerV1) Hello(ctx context.Context, req *v1.HelloReq) (res *v1.HelloRes, err error) {
g.RequestFromCtx(ctx).Response.Writeln("Hello World!")
return
}

@ -0,0 +1,58 @@
package user
import (
"context"
en "awesomeProject/internal/model/entity"
"github.com/gogf/gf/crypto/gmd5"
"github.com/gogf/gf/util/guid"
"github.com/gogf/gf/v2/os/glog"
"github.com/gogf/gf/v2/os/gsession"
"github.com/gogf/gf/v2/util/gconv"
v1 "awesomeProject/api/user/v1"
)
// 登录接口处理函数。
func (c *UserController) Login(ctx context.Context, r *v1.LoginReq) (res *v1.LoginRes, err error) {
/*
record, err := g.Model("user").Where("uname=?", r.Username).Where("password=?", r.Password).One()
// 登录成功后返回响应。
if err != nil {
glog.Error(ctx, "user not found")
return &v1.LoginRes{
Code: 500,
Msg: "undefined username or password",
}, err
}
user := record.Map()
*/
user, err := c.userService.Login(ctx, username, password)
if err != nil {
return &v1.LoginRes{
Reply: "test",
Cookie: session + ";" + token,
}
}
res = &v1.LoginRes{
Reply: "test",
Cookie: user.Cookie,
}
return res, nil
}
// 注册接口处理函数。
func (c *UserController) Register(ctx context.Context, r *v1.RegisterReq) (res *v1.RegisterRes, err error) {
// 在这里根据 req 中的用户信息进行注册逻辑处理,省略...
// 注册成功后返回响应。
res = &v1.RegisterRes{
Code: 200,
Msg: "注册成功",
}
return res, nil
}

@ -0,0 +1,14 @@
package user
import (
"awesomeProject/api/user"
"awesomeProject/internal/service"
)
type UserController struct{
userService *service.UserService
}
func NewUserController() user.UserHandler {
return &UserController{}
}

@ -0,0 +1,46 @@
package dao
import (
"awesomeProject/internal/model/do"
"context"
"github.com/gogf/gf/v2/database/gdb"
)
// CourseDAO 定义了课程数据访问对象。
type CourseDAO struct {
DB gdb.DB
}
// NewCourseDAO 创建一个新的课程数据访问对象。
func NewCourseDAO(db gdb.DB) *CourseDAO {
return &CourseDAO{DB: db}
}
// CreateCourse 向数据库中插入新课程。
func (d *CourseDAO) CreateCourse(ctx context.Context, course *do.CourseDO) error {
_, err := d.DB.Model("course").Data(course).Insert()
return err
}
// GetCourseByID 根据课程ID从数据库中查询课程信息。
func (d *CourseDAO) GetCourseByID(ctx context.Context, id int64) (*do.CourseDO, error) {
course := &do.CourseDO{}
err := d.DB.Model("course").Where("id", id).Scan(course)
if err != nil {
return nil, err
}
return course, nil
}
// UpdateCourse 更新数据库中的课程信息。
func (d *CourseDAO) UpdateCourse(ctx context.Context, course *do.CourseDO) error {
_, err := d.DB.Model("course").Data(course).Where("id", course.ID).Update()
return err
}
// DeleteCourse 删除数据库中的课程。
func (d *CourseDAO) DeleteCourse(ctx context.Context, id int64) error {
_, err := d.DB.Model("course").Where("id", id).Delete()
return err
}

@ -0,0 +1,47 @@
package dao
import (
"context"
"awesomeProject/internal/model/do"
"github.com/gogf/gf/v2/database/gdb"
)
// OrderDAO 定义了订单数据访问对象。
type OrderDAO struct {
DB gdb.DB
}
// NewOrderDAO 创建一个新的订单数据访问对象。
func NewOrderDAO(db gdb.DB) *OrderDAO {
return &OrderDAO{DB: db}
}
// CreateOrder 向数据库中插入新订单。
func (d *OrderDAO) CreateOrder(ctx context.Context, order *do.OrderDO) error {
_, err := d.DB.Model("order").Data(order).Insert()
return err
}
// GetOrderByID 根据订单ID从数据库中查询订单信息。
func (d *OrderDAO) GetOrderByID(ctx context.Context, id int64) (*do.OrderDO, error) {
order := &do.OrderDO{}
err := d.DB.Model("order").Where("id", id).Scan(order)
if err != nil {
return nil, err
}
return order, nil
}
// UpdateOrder 更新数据库中的订单信息。
func (d *OrderDAO) UpdateOrder(ctx context.Context, order *do.OrderDO) error {
_, err := d.DB.Model("order").Data(order).Where("id", order.ID).Update()
return err
}
// DeleteOrder 删除数据库中的订单。
func (d *OrderDAO) DeleteOrder(ctx context.Context, id int64) error {
_, err := d.DB.Model("order").Where("id", id).Delete()
return err
}

@ -0,0 +1,72 @@
package dao
import (
"context"
"github.com/gogf/gf/os/glog"
do "awesomeProject/internal/model/do"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"awesomeProject/internal/model/entity"
)
// UserDAO 定义了用户数据访问对象。
type UserDAO struct {
DB gdb.DB
}
// NewUserDAO 创建一个新的用户数据访问对象。
func NewUserDAO() *UserDAO {
return &UserDAO{DB: g.DB()}
}
// GetUserByID 根据用户ID从数据库中查询用户信息。
func (d *UserDAO) GetUserByID(ctx context.Context, id int64) (*do.UserDO, error) {
user := &do.UserDO{}
err := d.DB.Model("user").Where("id", id).Scan(user)
if err != nil {
return nil, err
}
return user, nil
}
func newUserByUserDO(user do.UserDO) entity.User {
var userEntity entity.User
gconv.Struct(user, &userEntity)
return userEntity
}
// GetUserByID 根据用户ID从数据库中查询用户信息。
func (d *UserDAO) GetUserByUsernameAndPassword(ctx context.Context, uname string,password string) (entity.User, error) {
user := &do.UserDO{}
err := d.DB.Model("user").Where("uname=? AND password=?", uname,password).Scan(user)
if err != nil {
glog.Error(ctx, "user:" + uname + " not found!")
return nil, err
}
return newUserByUserDO(user), nil
}
// CreateUser 向数据库中插入新用户。
func (d *UserDAO) CreateUser(ctx context.Context, user *do.UserDO) error {
_, err := d.DB.Model("user").Data(user).Insert()
return err
}
// UpdateUser 更新数据库中的用户信息。
func (d *UserDAO) UpdateUser(ctx context.Context, user *do.UserDO) error {
_, err := d.DB.Model("user").Data(user).Where("id", user.UID).Update()
return err
}
// DeleteUser 删除数据库中的用户。
func (d *UserDAO) DeleteUser(ctx context.Context, id int64) error {
_, err := d.DB.Model("user").Where("id", id).Delete()
return err
}

@ -0,0 +1,13 @@
package do
import "time"
// CourseDO 定义了课程数据对象。
type CourseDO struct {
ID int64 `json:"id" gconv:"id,omitempty"`
Name string `json:"name" gconv:"name,omitempty"`
Description string `json:"description" gconv:"description,omitempty"`
Price float64 `json:"price" gconv:"price,omitempty"`
CreateTime time.Time `json:"create_time" gconv:"create_time,omitempty"`
UpdateTime time.Time `json:"update_time" gconv:"update_time,omitempty"`
}

@ -0,0 +1,15 @@
package do
import "time"
// OrderDO 定义了订单数据对象。
type OrderDO struct {
ID int64 `json:"id" gconv:"id,omitempty"`
UserID int64 `json:"user_id" gconv:"user_id,omitempty"`
CourseID int64 `json:"course_id" gconv:"course_id,omitempty"`
OrderNumber string `json:"order_number" gconv:"order_number,omitempty"`
Amount float64 `json:"amount" gconv:"amount,omitempty"`
Status int `json:"status" gconv:"status,omitempty"`
CreateTime time.Time `json:"create_time" gconv:"create_time,omitempty"`
UpdateTime time.Time `json:"update_time" gconv:"update_time,omitempty"`
}

@ -0,0 +1,26 @@
package do
// UserDO 定义了用户的数据对象结构。
type UserDO struct {
UID int64 `json:"uid" db:"uid, primary"`
Username string `json:"uname" db:"uname"`
Password string `json:"password" db:"password"`
Email string `json:"email" db:"email"`
UserType string `json:"userType" db:"userType"`
SexOrType string `json:"sexOrType" db:"sexOrType"`
Department string `json:"department" db:"department"`
Telephone string `json:"telephone" db:"telephone"`
Role string `json:"role" db:"role"`
Cookie string `json:"cookie" db:"cookie"`
}
type StudentDO struct{
}
type UserCourseDO struct {
}

@ -0,0 +1,4 @@
package entity
type Course struct {
}

@ -0,0 +1,108 @@
package entity
import (
"context"
)
// 定义枚举类型
type MessageType int
type ContentType int
const (
PlatformMessage MessageType = iota
WeChatMessage
ShortNoteMessage
)
const (
WeChatTemplateMessage ContentType = iota
)
type Message struct {
MsgType MessageType
ContentType ContentType
Body interface{} `json:"body"`
}
func NewWechatTemplateMessage(fields map[string]interface{}) *Message {
return &Message{
MsgType: WeChatMessage,
ContentType: WeChatTemplateMessage,
Body: fields,
}
}
type Msg interface{
Do(ctx context.Context) error
}
type MsgReq struct{
body Message
sender User
receiver User
}
type PlatformMsgReq struct{
MsgReq
}
func (m *MsgReq) Do(ctx context.Context) error {
// 方法实现
return nil
}
func(this *PlatformMsgReq) Do(ctx context.Context) error{
return nil
}
type WeChatMsgReq struct{
MsgReq
}
func(this *WeChatMsgReq) Do(ctx context.Context) error{
w := NewWeChatOfficial("classPushOfficial")
err := w.PushMessage(ctx,this)
if err != nil {
return err
}
return nil
}
func NewWeChatMsgReq(fields map[string]interface{},msgType ContentType,sender User,receiver User) *WeChatMsgReq{
return &WeChatMsgReq{
MsgReq{
body: Message{
MsgType: WeChatMessage,
ContentType: msgType,
Body: fields,
},
sender: sender,
receiver: receiver,
},
}
}
type ShortNoteMsgReq struct{
MsgReq
}
func(this *ShortNoteMsgReq) Do(ctx context.Context) error{
return nil
}
func NewShortNoteMsgReq(body map[string]interface{},msgType ContentType,sender User,receiver User) *ShortNoteMsgReq{
return nil
}

@ -0,0 +1,53 @@
package entity
import (
"github.com/gogf/gf/os/glog"
)
var g_runner *scheduleRunner
// 定义一个结构体,用于携带函数和参数
type ScheduleFunc struct {
Fn func(...interface{})
Args []interface{}
}
type scheduleRunner struct {
// max schedule num
maxScheduleCount int `json:"maxScheduleCount"`
reqCh chan ScheduleFunc
}
func ReqChannel() chan ScheduleFunc {
return Runner().reqCh
}
func (this scheduleRunner) SetMaxScheduleCount(count int) {
this.maxScheduleCount = count
}
func (this scheduleRunner) init() {
glog.Debug("scheduleRunner init")
this.SetMaxScheduleCount(128) //default
this.reqCh = make(chan ScheduleFunc)
go func() {
glog.Debug("func is running")
for fun := range this.reqCh {
fun.Fn(fun.Args...)
}
}()
}
func Runner() *scheduleRunner {
if g_runner == nil {
g_runner = &scheduleRunner{}
g_runner.init()
}
return g_runner
}
func (this scheduleRunner) Run(fun ScheduleFunc) {
glog.Debug("add func to run")
this.reqCh <- fun
}

@ -0,0 +1,10 @@
package entity
type Statistics interface{
StatisticsInfo()
}
/*
use as proxy model ,but has some problem ,such as how to call it , whitch role could call it
*/

@ -0,0 +1,265 @@
package entity
import (
"context"
"github.com/gogf/gf/os/glog"
)
type Role int
// 枚举值作为结构体字段
const (
R_Guest Role = iota
R_Student
R_Teacher
R_Manager
R_Customr
R_Admin
)
//
type User interface {
StatisticsInfo()
PushMessage(ctx context.Context,msg Msg)
}
var g_userMgr *UserManager
type UserObject struct {
UID int64 `json:"uid"`
Username string `json:"uname"`
Password string `json:"password"`
Email string `json:"email"`
UserType string `json:"userType"`
SexOrType string `json:"sexOrType"`
Department string `json:"department"`
Telephone string `json:"telephone"`
Cookie string `json:"cookie"`
}
func NewUser() UserObject{
return UserObject{}
}
func NewUserObject() *UserObject {
return &UserObject{}
}
type Student struct {
UserObject
school string `json:"school"`
classGrade string `json:"classGrade"`
studentNum string `json:"studentNum"`
courses []Course `json:"courses"`
department string `json:"department"`
}
type Teacher struct {
UserObject
school string `json:"school"`
courses []Course `json:"courses"`
department string `json:"department"`
}
/*manager as a part*/
type Manager struct {
parts []User
}
type Admin struct {
UserObject
}
type CutomrService struct {
UserObject
}
func (this *Student) StatisticsInfo() {
}
func (this *Student) PushMessage(ctx context.Context,msg Msg) {
UserMgr().PushMessage(ctx,this,msg)
}
func (this *Teacher) PushMessage(ctx context.Context,msg Msg) {
UserMgr().PushMessage(ctx,this,msg)
}
func (this *Teacher) pushByOffcialAccounts(ctx context.Context,args ...interface{}) {
if len(args) != 1 {
glog.Debug("Error: Expected exactly one argument")
return
}
msg, ok := args[0].(Msg)
if !ok {
glog.Error("Error: Expected Message type argument")
}
w := NewWeChatOfficial("default")
err := w.PushMessage(ctx,msg)
if err != nil {
return
}
/*
*/
}
/*@func
*push message to short note
*/
func (this *Teacher) pushByShortNote(args ...interface{}) {
}
func (this *Teacher) pushByPlatform(args ...interface{}) {
}
func (this *Teacher) courseStatistics(course *Course) {
}
func (this *Teacher) StatisticsInfo() {
}
func (this *Teacher) pushEveryOneByOfficial(){
}
func (this *Manager) PushByOfficialAccounts() {
}
func (this *Manager) PushByShortNote() {
}
func (this *Manager) AddCourse() {
}
func (this *Manager) DepartmentStatistics() {
}
func (this *Manager) StatisticsInfo() {
}
func (this *Manager) PushMessage(ctx context.Context,msg Msg) {
UserMgr().PushMessage(ctx ,this,msg)
}
func (this *Admin) SalesStatics() {
}
func (this *Admin) CreateAccount() (UserObject, error) {
return UserObject{}, nil
}
func (this *Admin) GetAccount() {
}
func (this *Admin) ChangeAccount() {
}
func (this *Admin) DeleteAccount() {
}
func (this *Admin) GetAccountsByBelongOf() {
}
func (this *Admin) GetAccountsByCourse() {
}
func (this *Admin) StatisticsInfo() {
}
func (this *Admin) PushMessage(ctx context.Context,msg Msg) {
UserMgr().PushMessage(ctx,this,msg)
}
func (this *CutomrService) StatisticsInfo(){
}
func (this *CutomrService) SalesStatics() {
}
func (this *CutomrService) PushMessage(ctx context.Context,msg Msg) {
UserMgr().PushMessage(ctx,this,msg)
}
func (this *CutomrService) OrderQuery() {
}
type UserManager struct {
userRequestQueue *scheduleRunner
}
func (this *UserManager) PushMessage(ctx context.Context,user User,req Msg) {
glog.Debug("push message")
req.Do(ctx)
}
func (this *UserManager) QueryAccountsByDepartment(dept string) {
}
func (this *UserManager) QueryAccountsById(id string) {
}
/*
delete
*/
func Run(fun func(...interface{}), args ...interface{}) {
sf := ScheduleFunc{
Fn: fun,
Args: args,
}
UserMgr().userRequestQueue.Run(sf)
}
/*
delete
*/
func UserMgr() *UserManager {
if g_userMgr == nil {
g_userMgr = &UserManager{
userRequestQueue: Runner(),
}
}
return g_userMgr
}

@ -0,0 +1,264 @@
package entity
import (
"context"
"encoding/json"
"io"
"net/http"
"time"
"github.com/gogf/gf/frame/g"
"github.com/gogf/gf/net/ghttp"
"github.com/gogf/gf/os/glog"
"github.com/gogf/gf/os/gtime"
)
type WeChatOfficial struct {
name string
url string `json:"url"`
accessToken string `json:"access_Token"`
expiresIn int64 `json:"expires_In"`
appId string
appSecret string
client *ghttp.Client
}
func NewWeChatOfficial(name string) *WeChatOfficial {
we := WeChatOfficial{
url: "https://api.weixin.qq.com",
name: name,
}
err := we.UpdateAccessToken()
we.client = g.Client()
if err != nil {
glog.Debug("get access token error")
}
return &we
}
func (this *WeChatOfficial) UpdateAccessToken() error {
// 构造请求 URL
config := g.Cfg()
url := this.url + "/cgi-bin/token?grant_type=client_credential&appid=" + config.GetString("WeChat.pushOfficial.appId") + "&secret=" + config.GetString("WeChat.pushOfficial.appSecret")
glog.Debug(config.GetString("WeChat.pushOfficial.appId"))
glog.Debug(url)
// 创建 HTTP 客户端
client := http.Client{
Timeout: 10 * time.Second, // 设置超时时间为 10 秒
}
// 发送 GET 请求
resp, err := client.Get(url)
if err != nil {
return err
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
glog.Debug(err.Error())
}
}(resp.Body)
// 解析响应的 JSON 数据
var result struct {
AccessToken string `json:"access_token"`
ExpiresIn int64 `json:"expires_in"`
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return err
}
// 更新 AccessToken 和 ExpiresIn 字段
this.accessToken = result.AccessToken
glog.Debug(this.accessToken)
this.expiresIn = time.Now().Unix() + result.ExpiresIn // 计算过期时间
return nil
}
func (this *WeChatOfficial) PushMessage(ctx context.Context,msg Msg) error {
currentTime := gtime.Now()
timestamp := currentTime.Timestamp()
if timestamp > this.expiresIn {
err := this.UpdateAccessToken()
if err != nil {
glog.Error("update token failed")
return err
}
}
// 判断接口类型是否为子类
if cmsg, ok := msg.(*WeChatMsgReq); ok {
glog.Debug(cmsg.body.Body)
switch cmsg.body.ContentType {
case WeChatTemplateMessage:
err := this.pushTemplateMsg(cmsg.body)
if err != nil {
return err
}
break
}
//fmt.Printf("Name: %s, Width: %.2f, Height: %.2f\n", child.Name, child.Width, child.Height)
} else {
glog.Error("unexceptd param msg not is type WeChatMsgReq")
}
return nil
}
/*
* @brief
* @details
*/
func (this *WeChatOfficial) setIndustry(msg Message) error {
// 构造请求 URL
url := this.url + "/cgi-bin/template/api_set_industry?access_token=" + this.accessToken
body, err := json.Marshal(msg)
if err != nil {
glog.Debug("JSON marshal error:", err)
}
// 发送 GET 请求
resp, err := this.client.Post(url, body)
if err != nil {
return err
}
defer func(Body io.ReadCloser) {
err := Body.Close()
if err != nil {
glog.Debug(err.Error())
}
}(resp.Body)
// 解析响应数据
result := resp.ReadAllString()
glog.Debug("Response:", result)
return nil
}
/*
* @brief
*/
func (this *WeChatOfficial) getIndustry() error {
// 构造请求 URL
url := this.url + "/cgi-bin/template/get_industry?access_token=" + this.accessToken
// 发送 POST 请求
response, err := this.client.Get(url)
if err != nil {//
//2 获取设置的行业信息
//
//3 获得模板ID
//
//4 获取模板列表
//
//5 删除模板
//
//6 发送模板消息
//
//7 事件推送
glog.Debug(err)
return err
}
defer response.Close()
// 解析响应数据
result := response.ReadAllString()
glog.Debug("Response:", result)
return nil
}
/*
* @brief ID
*/
func (this *WeChatOfficial) getTemplateId(msg Message) error {
// 构造请求 URL
url := this.url + "/cgi-bin/template/api_add_template?access_token=" + this.accessToken
body, err := json.Marshal(msg)
if err != nil {
glog.Debug("JSON marshal error:", err)
}
// 发送 POST 请求
response, err := this.client.Post(url, body)
if err != nil {
glog.Debug(err)
return err
}
defer response.Close()
// 解析响应数据
result := response.ReadAllString()
glog.Debug("Response:", result)
return nil
}
/*
* @brief
* @param msg.body : template_id
*/
func (this *WeChatOfficial) deleteTemplate(msg Message) error {
// 构造请求 URL
url := this.url + "/cgi-bin/template/del_private_template?access_token=" + this.accessToken
// 发送 POST 请求
body, err := json.Marshal(msg)
if err != nil {
glog.Debug("JSON marshal error:", err)
}
response, err := this.client.Post(url, body)
if err != nil {
glog.Debug(err)
return err
}
defer response.Close()
// 解析响应数据
result := response.ReadAllString()
glog.Debug("Response:", result)
return nil
}
/*
- @brief
- @param msg.body :
{
"touser":openid
"template_id":ID
"url":
"miniprogram":
"appid":appidappid
"pagepath":,index?foo=bar
"client_msg_id":idopenid + client_msg_id, ,10,10
"data":
}
}
*/
func (this *WeChatOfficial) pushTemplateMsg(msg Message) error {
// 构造请求 URL
url := this.url + "/cgi-bin/template/send?access_token=" + this.accessToken
// 发送 POST 请求
body, err := json.Marshal(msg)
glog.Debug("POST", url)
if err != nil {
glog.Debug("JSON marshal error:", err)
}
response, err := this.client.Post(url, body)
if err != nil {
glog.Debug(err)
return err
}
defer response.Close()
// 解析响应数据
result := response.ReadAllString()
glog.Debug("Response:", result)
return nil
}

@ -0,0 +1 @@
package packed

@ -0,0 +1,115 @@
package service
import (
"context"
"awesomeProject/internal/dao"
"awesomeProject/internal/model/entity"
"github.com/gogf/gf/crypto/gmd5"
"github.com/gogf/gf/util/guid"
"github.com/gogf/gf/v2/os/gsession"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/os/glog"
)
type UserService struct {
userDAO *dao.UserDAO
}
func NewUserService() *UserService {
return &UserService{}
}
func GenerateToken(data interface{}) (string, error) {
// 生成一个随机的 GUID 作为 token
token := guid.S(gconv.Bytes(data))
// 使用 MD5 加密 token
encryptedToken, err := gmd5.Encrypt(token)
if err != nil {
return "", err
}
return encryptedToken, nil
}
func (s *UserService) Login(ctx context.Context, username string, password string) (*entity.User, error) {
// 调用 Dao 层的方法查询用户信息
user, err := s.userDAO.GetUserByUsernameAndPassword(ctx, username, password)
if err != nil {
return nil, err
}
// 生成 token
token, _ := GenerateToken(password)
token = "token=" + token
session := gsession.NewSessionId()
glog.Info(ctx, token)
user.Cookie = token + ";" + session;
return user, nil
}
// RegisterUser 注册用户
func (s *UserService) RegisterUser(ctx context.Context, user *entity.User) error {
// 执行注册逻辑,例如验证用户信息、生成密码哈希等
// 调用 DAO 层保存用户信息到数据库
err := userDao.SaveUser(ctx, user)
if err != nil {
return err
}
return nil
}
// GetUserByID 根据用户ID获取用户信息
func (s *UserService) GetUserByID(ctx context.Context, userID int64) (*entity.User, error) {
// 调用 DAO 层获取用户信息
user, err := userDao.GetUserByID(ctx, userID)
if err != nil {
return nil, err
}
return user, nil
}
func (s *UserService) PushMessage(ctx context.Context, req Msg){
glog.Debug("push message")
go func(){
err := req.Do(ctx)
if err != nil{
glog.Error(ctx,"push message error:" ,err)
}
}()
}
func (s *UserService) StatisticsInfo(ctx context.Context,user entity.User){
glog.Debug("Statistics Info")
go func(){
err := user.StatisticsInfo(ctx)
if err != nil{
glog.Error(ctx,"Statistics Info error:" ,err)
}
}()
}
type StudentServer struct {
}
type TeacherServer struct {
}
type ManagerServer struct {
}
type AdminServer struct {
}
type CutomrServiceServer struct {
}

BIN
main

Binary file not shown.

@ -0,0 +1,31 @@
package main
import (
"fmt"
"awesomeProject/internal/cmd"
_ "awesomeProject/internal/packed"
"github.com/gogf/gf/v2/os/gctx"
"github.com/gogf/gf/frame/g"
)
func init() {
users, err := g.DB().Model("user").All()
if err != nil {
// 处理错误
fmt.Println(err.Error())
} else {
// 处理查询结果
fmt.Println(users)
}
}
func main() {
cmd.Main.Run(gctx.GetInitCtx())
}

@ -0,0 +1,11 @@
server:
address: ":8000"
openapiPath: "/api.json"
swaggerPath: "/swagger"
logger:
level : "all"
stdout: true

@ -0,0 +1,21 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: template-single
labels:
app: template-single
spec:
replicas: 1
selector:
matchLabels:
app: template-single
template:
metadata:
labels:
app: template-single
spec:
containers:
- name : main
image: template-single
imagePullPolicy: Always

@ -0,0 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml

@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: template-single
spec:
ports:
- port: 80
protocol: TCP
targetPort: 8000
selector:
app: template-single

@ -0,0 +1,14 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: template-single-configmap
data:
config.yaml: |
server:
address: ":8000"
openapiPath: "/api.json"
swaggerPath: "/swagger"
logger:
level : "all"
stdout: true

@ -0,0 +1,10 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: template-single
spec:
template:
spec:
containers:
- name : main
image: template-single:develop

@ -0,0 +1,14 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
- configmap.yaml
patchesStrategicMerge:
- deployment.yaml
namespace: default

@ -0,0 +1,16 @@
FROM loads/alpine:3.8
###############################################################################
# INSTALLATION
###############################################################################
ENV WORKDIR /app
ADD resource $WORKDIR/
ADD ./temp/linux_amd64/main $WORKDIR/main
RUN chmod +x $WORKDIR/main
###############################################################################
# START
###############################################################################
WORKDIR $WORKDIR
CMD ./main

@ -0,0 +1,8 @@
#!/bin/bash
# This shell is executed before docker build.

@ -0,0 +1,40 @@
/* Navigation 样式 */
.navbar {
background-color: #007bff;
padding: 10px 0; /* 添加上下内边距 */
overflow: hidden; /* 触发 BFC块级格式化上下文以防止浮动元素影响布局 */
}
.navbar ul {
list-style-type: none; /* 移除列表默认样式 */
margin: 0;
padding: 0;
overflow: hidden; /* 清除浮动 */
}
.navbar li {
float: left; /* 将列表项水平排列 */
}
.navbar li a {
display: block; /* 将链接显示为块级元素,使其充满父元素的宽度 */
color: #fff;
text-align: center;
padding: 14px 16px; /* 添加上下内边距,左右内边距 */
text-decoration: none;
}
.navbar li a:hover {
background-color: #0056b3; /* 鼠标悬停时的背景颜色 */
}
/* Footer 样式 */
.footer {
background-color: #ddd; /* 设置背景颜色为灰色 */
color: #333; /* 设置文字颜色 */
padding: 20px;
text-align: center;
position: fixed; /* 将 footer 固定在底部 */
width: 100%; /* 设置宽度为100% */
bottom: 0; /* 将 footer 置底 */
}

@ -0,0 +1,16 @@
<div class="container">
<div class="row">
<div class="col-md-4">
<h2>Column 1</h2>
<p>This is the content of column 1.</p>
</div>
<div class="col-md-4">
<h2>Column 2</h2>
<p>This is the content of column 2.</p>
</div>
<div class="col-md-4">
<h2>Column 3</h2>
<p>This is the content of column 3.</p>
</div>
</div>
</div>

@ -0,0 +1,7 @@
<!-- 底部栏 -->
<footer class="footer">
<div class="footer-content">
<p>&copy; 2024 AwesomeProject. All Rights Reserved.</p>
<p>联系我们contact@example.com</p>
</div>
</footer>

@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Layout Example</title>
</head>
<body>
<!-- Include the navigation -->
{{ include "nav.html" .}}
<!-- Main content container -->
{{ include .mainTpl .}}
<!-- Include the footer -->
{{ include "footer.html" .}}
</body>
</html>

@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Layout Example</title>
<link rel="stylesheet" href="../resource/public/resource/css/style.css">
<style>
/* Navigation 样式 */
.navbar {
background-color: #007bff;
padding: 10px 0; /* 添加上下内边距 */
overflow: hidden; /* 触发 BFC块级格式化上下文以防止浮动元素影响布局 */
}
.navbar ul {
list-style-type: none; /* 移除列表默认样式 */
margin: 0;
padding: 0;
overflow: hidden; /* 清除浮动 */
}
.navbar li {
float: left; /* 将列表项水平排列 */
}
.navbar li a {
display: block; /* 将链接显示为块级元素,使其充满父元素的宽度 */
color: #fff;
text-align: center;
padding: 14px 16px; /* 添加上下内边距,左右内边距 */
text-decoration: none;
}
.navbar li a:hover {
background-color: #0056b3; /* 鼠标悬停时的背景颜色 */
}
/* Footer 样式 */
.footer {
background-color: #ddd; /* 设置背景颜色为灰色 */
color: #333; /* 设置文字颜色 */
padding: 20px;
text-align: center;
position: fixed; /* 将 footer 固定在底部 */
width: 100%; /* 设置宽度为100% */
bottom: 0; /* 将 footer 置底 */
}
</style>
</head>
<body>
<!-- Include the navigation -->
{{ include "nav.html" .}}
<!-- Main content container -->
{{ include .mainTpl .}}
<!-- Include the footer -->
{{ include "footer.html" .}}
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
</body>
</html>

@ -0,0 +1,15 @@
<!-- 导航栏 -->
<nav class="navbar">
<div class="logo">
<a href="/">AwesomeProject</a>
</div>
<ul class="nav-links">
<li><a href="/">首页</a></li>
<li><a href="/courses">课程</a></li>
<li><a href="/teachers">教师</a></li>
<li><a href="/community">社区</a></li>
</ul>
<div class="user">
<a href="/login">登录</a> / <a href="/register">注册</a>
</div>
</nav>
Loading…
Cancel
Save