天气服务1.0
parent
b9869bbc6b
commit
f69590b0c6
|
@ -0,0 +1,3 @@
|
|||
log/
|
||||
weather.pp
|
||||
weather
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"marscode.chatLanguage": "cn"
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"cc/util/log"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
var (
|
||||
DB *sqlx.DB
|
||||
// DBPath string = "file:weather.pp?_foreign_keys=1&&_journal_mode=WAL&&mode=rwc"
|
||||
DBPath string = "file:weather.pp?_foreign_keys=1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
DB, err = NewSQLiteDB(DBPath)
|
||||
if err != nil {
|
||||
log.L.Fatalf("数据库连接失败: %v", err)
|
||||
}
|
||||
if !IsDBInitialized(DB) {
|
||||
log.L.Info("数据库未初始化,正在初始化...")
|
||||
createTables()
|
||||
initData()
|
||||
}
|
||||
}
|
||||
|
||||
// 创建表
|
||||
func createTables() {
|
||||
// 创建天气类型表
|
||||
weatherTypeTable := `
|
||||
CREATE TABLE IF NOT EXISTS weather_types (
|
||||
id INTEGER PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT NOT NULL
|
||||
);`
|
||||
|
||||
// 创建天气表
|
||||
weatherTable := `
|
||||
CREATE TABLE IF NOT EXISTS weathers (
|
||||
project_id INTEGER PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
update_at TEXT NOT NULL,
|
||||
FOREIGN KEY(project_id) REFERENCES projects(id)
|
||||
);`
|
||||
|
||||
// 创建位置表
|
||||
localtionTable := `
|
||||
CREATE TABLE IF NOT EXISTS localtions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
code TEXT NOT NULL
|
||||
);`
|
||||
|
||||
// 创建项目表
|
||||
projectTable := `
|
||||
CREATE TABLE IF NOT EXISTS projects (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
code TEXT NOT NULL,
|
||||
user TEXT NOT NULL,
|
||||
description TEXT NOT NULL,
|
||||
localtion_id INTEGER NOT NULL,
|
||||
weather_type_id INTEGER NOT NULL,
|
||||
update_frequency INTEGER NOT NULL,
|
||||
dev BOOLEAN NOT NULL,
|
||||
FOREIGN KEY(localtion_id) REFERENCES localtions(id),
|
||||
FOREIGN KEY(weather_type_id) REFERENCES weather_types(id)
|
||||
);`
|
||||
|
||||
// 创建表
|
||||
tables := []string{weatherTypeTable, weatherTable, localtionTable, projectTable}
|
||||
for _, table := range tables {
|
||||
_, err := DB.Exec(table)
|
||||
if err != nil {
|
||||
log.L.Fatalf("创建表失败: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化数据
|
||||
func initData() {
|
||||
// 初始化天气类型
|
||||
weatherTypes := map[int][]string{
|
||||
1: {"now", "实时天气"},
|
||||
3: {"3d", "3天预报"},
|
||||
7: {"7d", "7天预报"},
|
||||
10: {"10d", "10天预报"},
|
||||
15: {"15d", "15天预报"},
|
||||
30: {"30d", "30天预报"},
|
||||
24: {"24h", "24小时预报"},
|
||||
72: {"72h", "72小时预报"},
|
||||
168: {"168h", "168小时预报"},
|
||||
}
|
||||
for id, v := range weatherTypes {
|
||||
_, err := DB.Exec("INSERT INTO weather_types (id, name, description) VALUES (?,?,?)", id, v[0], v[1])
|
||||
if err != nil {
|
||||
log.L.Errorf("初始化天气类型失败: %v", err)
|
||||
}
|
||||
}
|
||||
// 初始化位置
|
||||
localtions := map[string]string{
|
||||
"西安": "101010100",
|
||||
"上海": "101020100",
|
||||
}
|
||||
for name, code := range localtions {
|
||||
_, err := DB.Exec("INSERT INTO localtions (name, code) VALUES (?,?)", name, code)
|
||||
if err != nil {
|
||||
log.L.Errorf("初始化位置失败: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"cc/db"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Localtion 位置
|
||||
type Localtion struct {
|
||||
ID int `db:"id" json:"id"` // 位置ID
|
||||
Name string `db:"name" json:"name"` // 位置名称
|
||||
Code string `db:"code" json:"code"` // 位置编码
|
||||
}
|
||||
|
||||
// GetAll 获取所有位置
|
||||
func (loc *Localtion) GetAll() (rv []Localtion, rer error) {
|
||||
sql := "SELECT * FROM localtions"
|
||||
rer = db.DB.Select(&rv, sql)
|
||||
return
|
||||
}
|
||||
|
||||
// GetLocaltionByID 根据ID获取位置
|
||||
func (loc *Localtion) GetLocaltionByID() (rer error) {
|
||||
sql := "SELECT * FROM localtions WHERE id =?"
|
||||
return db.DB.Get(loc, sql, loc.ID)
|
||||
}
|
||||
|
||||
// CreateLocaltion 创建位置
|
||||
func (loc *Localtion) CreateLocaltion() (rer error) {
|
||||
// 检查位置名称是否存在
|
||||
var count int
|
||||
sql := "SELECT COUNT(*) FROM localtions WHERE name=?"
|
||||
err := db.DB.Get(&count, sql, loc.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("位置名称已存在")
|
||||
}
|
||||
// 检查位置编码是否存在
|
||||
sql = "SELECT COUNT(*) FROM localtions WHERE code=?"
|
||||
err = db.DB.Get(&count, sql, loc.Code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("位置编码已存在")
|
||||
}
|
||||
// 插入数据
|
||||
sql = "INSERT INTO localtions (name, code) VALUES (?, ?)"
|
||||
_, rer = db.DB.Exec(sql, loc.Name, loc.Code)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateLocaltion 更新位置
|
||||
func (loc *Localtion) UpdateLocaltion() (rer error) {
|
||||
// 检查位置名称是否存在
|
||||
var count int
|
||||
sql := "SELECT COUNT(*) FROM localtions WHERE name=? AND id!=?"
|
||||
err := db.DB.Get(&count, sql, loc.Name, loc.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("位置名称已存在")
|
||||
}
|
||||
// 检查位置编码是否存在
|
||||
sql = "SELECT COUNT(*) FROM localtions WHERE code=? AND id!=?"
|
||||
err = db.DB.Get(&count, sql, loc.Code, loc.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("位置编码已存在")
|
||||
}
|
||||
// 更新数据
|
||||
sql = "UPDATE localtions SET name=?, code=? WHERE id=?"
|
||||
_, rer = db.DB.Exec(sql, loc.Name, loc.Code, loc.ID)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteLocaltion 删除位置
|
||||
func (loc *Localtion) DeleteLocaltion() (rer error) {
|
||||
sql := "DELETE FROM localtions WHERE id=?"
|
||||
_, rer = db.DB.Exec(sql, loc.ID)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"cc/db"
|
||||
"errors"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
// Project 项目
|
||||
type Project struct {
|
||||
ID int `db:"id" json:"id"` // 项目ID
|
||||
Name string `db:"name" json:"name"` // 项目名称
|
||||
Code int `db:"code" json:"code"` // 项目编码
|
||||
User string `db:"user" json:"user"` // 项目用户
|
||||
Description string `db:"description" json:"description"` // 项目描述
|
||||
UpdateFrequency int `db:"update_frequency" json:"update_frequency"` // 更新频率
|
||||
LocaltionID int `db:"localtion_id" json:"localtion_id"` // 项目位置ID
|
||||
WeatherTypeID int `db:"weather_type_id" json:"weather_type_id"` // 天气类型ID
|
||||
Dev bool `db:"dev" json:"dev"` // 是否为开发模式
|
||||
}
|
||||
|
||||
// GetAll 获取所有项目
|
||||
func (pro *Project) GetAll() (rv []Project, rer error) {
|
||||
sql := "SELECT * FROM projects"
|
||||
rer = db.DB.Select(&rv, sql)
|
||||
return
|
||||
}
|
||||
|
||||
// GetProjectByID 通过项目ID获取项目
|
||||
func (pro *Project) GetProjectByID() (rer error) {
|
||||
sql := "SELECT * FROM projects WHERE id =?"
|
||||
return db.DB.Get(pro, sql, pro.ID)
|
||||
}
|
||||
|
||||
// GetProjectByCode 通过项目代码获取项目
|
||||
func (pro *Project) GetProjectByCode() (rer error) {
|
||||
sql := "SELECT * FROM projects WHERE code =?"
|
||||
return db.DB.Get(pro, sql, pro.Code)
|
||||
}
|
||||
|
||||
// CreateProject 创建项目
|
||||
func (pro *Project) CreateProject() (rer error) {
|
||||
// 判断是否存在相同的项目名称和天气类型
|
||||
var count int
|
||||
err := db.DB.Get(&count, "SELECT COUNT(*) FROM projects WHERE name =? AND weather_type_id =?", pro.Name, pro.WeatherTypeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("已存在相同配置")
|
||||
}
|
||||
// 判断项目代码,当前项目代码不为0时,必须是4位数字
|
||||
if pro.Code != 0 {
|
||||
if pro.Code < 1000 || pro.Code > 9999 {
|
||||
return errors.New("项目代码必须是4位数字")
|
||||
}
|
||||
err := db.DB.Get(&count, "SELECT COUNT(*) FROM projects WHERE code =?", pro.Code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
return errors.New("项目代码已存在,请重新输入,或者将项目代码设置为0,系统将随机生成一个4位数字的项目代码")
|
||||
}
|
||||
} else {
|
||||
// 随机生成一个4位数字的项目代码
|
||||
for {
|
||||
pro.Code = rand.Intn(9000) + 1000
|
||||
err := db.DB.Get(&count, "SELECT COUNT(*) FROM projects WHERE code =?", pro.Code)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
// 更新频率为0时,设置为60分钟
|
||||
if pro.UpdateFrequency == 0 {
|
||||
pro.UpdateFrequency = 60
|
||||
}
|
||||
// 插入数据
|
||||
sql := "INSERT INTO projects (name, code, user, description, update_frequency, localtion_id, weather_type_id, dev) VALUES (?,?,?,?,?,?,?,?)"
|
||||
_, rer = db.DB.Exec(sql, pro.Name, pro.Code, pro.User, pro.Description, pro.UpdateFrequency, pro.LocaltionID, pro.WeatherTypeID, pro.Dev)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateProject 更新项目
|
||||
func (pro *Project) UpdateProject() (rer error) {
|
||||
// 更新频率为0时,设置为60分钟
|
||||
if pro.UpdateFrequency == 0 {
|
||||
pro.UpdateFrequency = 60
|
||||
}
|
||||
// 更新数据
|
||||
sql := "UPDATE projects SET name=?, user=?, description=?, update_frequency=?, localtion_id=?, weather_type_id=?, dev=? WHERE id=?"
|
||||
_, rer = db.DB.Exec(sql, pro.Name, pro.User, pro.Description, pro.UpdateFrequency, pro.LocaltionID, pro.WeatherTypeID, pro.Dev, pro.ID)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteProject 删除项目
|
||||
func (pro *Project) DeleteProject() (rer error) {
|
||||
sql := "DELETE FROM projects WHERE id=?"
|
||||
_, rer = db.DB.Exec(sql, pro.ID)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"cc/db"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
// Weather 天气
|
||||
type Weather struct {
|
||||
ProjectID int `db:"project_id" json:"project_id"` // 项目ID
|
||||
UpdateAt string `db:"update_at" json:"update_at"` // 更新时间
|
||||
Value json.RawMessage `db:"value" json:"value"` // 天气信息
|
||||
}
|
||||
|
||||
// GetWeather 获取天气
|
||||
func (w *Weather) GetWeather() (rer error) {
|
||||
sql := "SELECT * FROM weathers WHERE project_id =?"
|
||||
return db.DB.Get(w, sql, w.ProjectID)
|
||||
}
|
||||
|
||||
// UpdateWeather 更新天气
|
||||
func (w *Weather) UpdateWeather() (rer error) {
|
||||
// 如果不存在则创建
|
||||
var count int
|
||||
err := db.DB.Get(&count, "SELECT COUNT(*) FROM weathers WHERE project_id =?", w.ProjectID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if count == 0 {
|
||||
sql := "INSERT INTO weathers (project_id, update_at, value) VALUES (?, ?, ?)"
|
||||
_, rer = db.DB.Exec(sql, w.ProjectID, w.UpdateAt, w.Value)
|
||||
return
|
||||
}
|
||||
// 更新天气
|
||||
sql := "UPDATE weathers SET update_at =?, value =? WHERE project_id =?"
|
||||
_, rer = db.DB.Exec(sql, w.UpdateAt, w.Value, w.ProjectID)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package model
|
||||
|
||||
import "cc/db"
|
||||
|
||||
type WeatherType struct {
|
||||
Id int `db:"id" json:"id"` // 天气类型ID
|
||||
Name string `db:"name" json:"name"` // 天气类型名称
|
||||
Description string `db:"description" json:"description"` // 天气类型描述
|
||||
}
|
||||
|
||||
// GetAll 获取所有天气类型
|
||||
func (w *WeatherType) GetAll() (rv []WeatherType, rer error) {
|
||||
sql := "SELECT * FROM weather_types"
|
||||
rer = db.DB.Select(&rv, sql)
|
||||
return
|
||||
}
|
||||
|
||||
// GetWeatherTypeByID 根据ID获取天气类型
|
||||
func (w *WeatherType) GetWeatherTypeByID() (rer error) {
|
||||
sql := "SELECT * FROM weather_types WHERE id =?"
|
||||
return db.DB.Get(w, sql, w.Id)
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package db
|
||||
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func NewSQLiteDB(Path string) (db *sqlx.DB, rer error) {
|
||||
db, rer = sqlx.Open("sqlite3", Path)
|
||||
if rer != nil {
|
||||
return
|
||||
}
|
||||
rer = db.Ping()
|
||||
return
|
||||
}
|
||||
|
||||
func IsDBInitialized(db *sqlx.DB) bool {
|
||||
var count int
|
||||
err := db.Get(&count, "SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name='localtions';")
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return count > 0
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
module cc
|
||||
|
||||
go 1.23.1
|
||||
|
||||
require (
|
||||
git.shikicc.com/golang/kit v0.0.6
|
||||
github.com/gofiber/contrib/fiberzap/v2 v2.1.4
|
||||
github.com/gofiber/fiber/v2 v2.52.6
|
||||
github.com/jmoiron/sqlx v1.4.0
|
||||
github.com/mattn/go-sqlite3 v1.14.24
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/andybalholm/brotli v1.1.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/tinylib/msgp v1.2.5 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.55.0 // indirect
|
||||
github.com/valyala/tcplisten v1.0.0 // indirect
|
||||
go.uber.org/multierr v1.10.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
)
|
|
@ -0,0 +1,62 @@
|
|||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
git.shikicc.com/golang/kit v0.0.6 h1:4/G3Ajsgw8bET2W2SrMG5hCh94zrh/jZR/Md8QbxG4s=
|
||||
git.shikicc.com/golang/kit v0.0.6/go.mod h1:rDoS4olD/rogB7sKzzFBBR7MF8WsXUcrzaaeDFFQgyQ=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/gofiber/contrib/fiberzap/v2 v2.1.4 h1:GCtCQnT4Cr9az4qab2Ozmqsomkxm4Ei86MfKk/1p5+0=
|
||||
github.com/gofiber/contrib/fiberzap/v2 v2.1.4/go.mod h1:PkdXgUzw+oj4m6ksfKJ0Hs3H7iPhwvhfI4b2LSA9hhA=
|
||||
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
|
||||
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
|
||||
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
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.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||
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 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
|
||||
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8=
|
||||
github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
|
||||
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
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,11 @@
|
|||
[2025-01-01 19:11:28] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 12:35:28] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 12:42:25] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 12:44:26] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 13:57:55] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 14:17:40] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 14:32:17] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 14:33:49] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 14:36:33] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 14:37:47] [INFO] 数据库未初始化,正在初始化...
|
||||
[2025-01-02 14:39:59] [INFO] 数据库未初始化,正在初始化...
|
|
@ -0,0 +1,117 @@
|
|||
[2025-01-01 19:11:56] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/0033", "protocol": "http", "ip": "10.10.10.31", "latency": "861.559µs", "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"}
|
||||
[2025-01-01 19:14:02] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/0033", "protocol": "http", "ip": "10.10.10.31", "latency": "390.925µs", "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"}
|
||||
[2025-01-01 19:14:31] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/0033", "protocol": "http", "ip": "10.10.10.31", "latency": "486.374µs", "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"}
|
||||
[2025-01-01 19:15:21] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/0033", "protocol": "http", "ip": "10.10.10.31", "latency": "184.637µs", "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"}
|
||||
[2025-01-01 19:15:23] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/0033", "protocol": "http", "ip": "10.10.10.31", "latency": "199.286µs", "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"}
|
||||
[2025-01-01 19:17:06] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/0033", "protocol": "http", "ip": "10.10.10.31", "latency": "685.22µs", "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0"}
|
||||
[2025-01-02 12:37:01] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/6143", "protocol": "http", "ip": "10.10.10.31", "latency": "294.391µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:37:35] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "258.253µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:37:54] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "6.59407ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:37:59] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "200.805µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:42:30] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "254.377µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:42:33] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "167.144µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:42:40] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "190.578µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:42:44] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "7.321563ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:42:48] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "215.955µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:42:53] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "7.433112ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:42:55] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "211.919µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:44:33] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "272.261µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:44:36] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "9.664442ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:44:37] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "187.402µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:44:41] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "221.306µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:44:43] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "7.777277ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:44:45] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "217.447µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:45:42] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/localtion/2", "protocol": "http", "ip": "10.10.10.31", "latency": "5.95115ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:45:45] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/localtion/2", "protocol": "http", "ip": "10.10.10.31", "latency": "282.711µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:45:46] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/localtion/2", "protocol": "http", "ip": "10.10.10.31", "latency": "301.948µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:45:47] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/localtion/2", "protocol": "http", "ip": "10.10.10.31", "latency": "259.358µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:45:56] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "201.158µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:45:57] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "149.54µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:46:20] [INFO] Success {"status": 200, "method": "DELETE", "path": "/api/localtion/3", "protocol": "http", "ip": "10.10.10.31", "latency": "6.073141ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:46:27] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "170.13µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:46:34] [INFO] Success {"status": 200, "method": "POST", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "210.967µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:47:11] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "266.07µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:47:37] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project/2977", "protocol": "http", "ip": "10.10.10.31", "latency": "203.612µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:48:00] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "5.957308ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:48:11] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "168.577µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 12:48:13] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "169.73µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 13:58:00] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "271.03µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 13:58:18] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project/2977", "protocol": "http", "ip": "10.10.10.31", "latency": "146.255µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 13:58:20] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project/2977", "protocol": "http", "ip": "10.10.10.31", "latency": "132.428µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 13:58:23] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project/2977", "protocol": "http", "ip": "10.10.10.31", "latency": "180.108µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 13:58:26] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "132.429µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 13:58:45] [INFO] Success {"status": 200, "method": "GET", "path": "/api/localtion", "protocol": "http", "ip": "10.10.10.31", "latency": "165.362µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 13:59:05] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "139.623µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:01:22] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/types", "protocol": "http", "ip": "10.10.10.31", "latency": "100.069µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:01:54] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/types", "protocol": "http", "ip": "10.10.10.31", "latency": "26.189µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:02:18] [INFO] Success {"status": 200, "method": "POST", "path": "/api/weather/types", "protocol": "http", "ip": "10.10.10.31", "latency": "306.087µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:05:20] [INFO] Success {"status": 200, "method": "POST", "path": "/api/weather/types", "protocol": "http", "ip": "10.10.10.31", "latency": "156.755µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:16:37] [INFO] Success {"status": 200, "method": "POST", "path": "/api/weather/types", "protocol": "http", "ip": "10.10.10.31", "latency": "279.27µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:16:38] [INFO] Success {"status": 200, "method": "POST", "path": "/api/weather/types", "protocol": "http", "ip": "10.10.10.31", "latency": "317.023µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:16:52] [INFO] Success {"status": 200, "method": "POST", "path": "/api/weather/types", "protocol": "http", "ip": "10.10.10.31", "latency": "177.116µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:17:42] [INFO] Success {"status": 200, "method": "POST", "path": "/api/weather/types", "protocol": "http", "ip": "10.10.10.31", "latency": "347.31µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:18:02] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "312.112µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:18:12] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "187.847µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:18:45] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "6.345588ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:20:52] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "453.018µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:21:09] [INFO] Success {"status": 200, "method": "DELETE", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "41.258µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:21:20] [INFO] Success {"status": 200, "method": "DELETE", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "33.814µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:24:56] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "269.53µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:25:44] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "135.657µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:26:11] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "332.409µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:26:54] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "261.663µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:28:11] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "319.404µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:28:41] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "312.601µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:32:25] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "7.880342ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:32:30] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "183.968µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:32:34] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "165.132µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:32:45] [INFO] Success {"status": 200, "method": "DELETE", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "88.607µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:33:55] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "13.07987ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:33:58] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "6.922872ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:34:05] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "214.775µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:34:07] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "188.356µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:36:38] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "6.632361ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:36:45] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project/3002", "protocol": "http", "ip": "10.10.10.31", "latency": "223.382µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:36:52] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project/3002", "protocol": "http", "ip": "10.10.10.31", "latency": "182.184µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:37:02] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "157.126µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:37:11] [INFO] Success {"status": 200, "method": "PUT", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "9.599906ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:37:22] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "194.136µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:37:23] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "150.103µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:37:29] [INFO] Success {"status": 200, "method": "DELETE", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "6.156992ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:37:32] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "160.543µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:37:35] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "6.655493ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:37:52] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "9.692681ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:38:01] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/2426", "protocol": "http", "ip": "10.10.10.31", "latency": "165.037576ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:38:05] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/2426", "protocol": "http", "ip": "10.10.10.31", "latency": "39.928172ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:38:06] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/2426", "protocol": "http", "ip": "10.10.10.31", "latency": "41.064915ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:38:07] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/2426", "protocol": "http", "ip": "10.10.10.31", "latency": "42.155822ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:38:08] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/2426", "protocol": "http", "ip": "10.10.10.31", "latency": "40.147544ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:40:12] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "10.894672ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:40:26] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "10.371355ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:40:28] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "6.659095ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:40:29] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "20.576789ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:40:31] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "6.556924ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:40:32] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "6.679473ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:40:37] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "251.754µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:40:50] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "156.228978ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:40:59] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "42.464346ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:41:03] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "39.912975ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:41:52] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "139.313879ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:41:53] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "36.423922ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:43:15] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "151.524839ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:43:17] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "39.584616ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:43:18] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "39.211161ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:43:19] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "38.165661ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:43:20] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "38.649042ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:44:06] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "151.430289ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:44:08] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "40.111296ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:44:09] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "39.638676ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:45:40] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "143.712593ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:45:41] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "207.35µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:45:42] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "245.492µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:45:43] [INFO] Success {"status": 200, "method": "GET", "path": "/api/weather/7127", "protocol": "http", "ip": "10.10.10.31", "latency": "241.755µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:48:26] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "423.669µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:48:28] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "159.64µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:48:34] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "10.289775ms", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:48:35] [INFO] Success {"status": 200, "method": "POST", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "170.822µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 22:48:38] [INFO] Success {"status": 200, "method": "GET", "path": "/api/project", "protocol": "http", "ip": "10.10.10.31", "latency": "252.726µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
|
@ -0,0 +1,2 @@
|
|||
[2025-01-02 12:45:15] [WARN] Client error {"status": 401, "method": "PUT", "path": "/api/localtion/2", "protocol": "http", "ip": "10.10.10.31", "latency": "17.994µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
||||
[2025-01-02 14:20:57] [WARN] Client error {"status": 401, "method": "DELETE", "path": "/api/project/1", "protocol": "http", "ip": "10.10.10.31", "latency": "14.336µs", "ua": "PostmanRuntime-ApipostRuntime/1.1.0"}
|
|
@ -0,0 +1,29 @@
|
|||
package qweather
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// 获取天气
|
||||
func Get(location_id, weather_type_id int, dev bool) (json.RawMessage, error) {
|
||||
// 生成url
|
||||
url, err := makeURL(dev, location_id, weather_type_id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 发送请求, 获取数据
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
// 读取数据
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 返回数据
|
||||
return body, nil
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package qweather
|
||||
|
||||
import (
|
||||
"cc/db/model"
|
||||
)
|
||||
|
||||
var (
|
||||
// 开发者密钥
|
||||
c_DEVKEY = "ecac5888fd314a5d883c0f9126145969"
|
||||
// 生产环境密钥
|
||||
c_PROKEY = "ecac5888fd314a5d883c0f9126145969"
|
||||
// 开发环境url
|
||||
c_DEVURL = "https://devapi.qweather.com/"
|
||||
// 生产环境url
|
||||
c_PROURL = "https://api.qweather.com/"
|
||||
// 版本号
|
||||
c_VERSION = "v7/weather/"
|
||||
)
|
||||
|
||||
// makeURL 生成url
|
||||
func makeURL(dev bool, location_id, weather_type_id int) (rv string, rer error) {
|
||||
// 获取位置信息
|
||||
localtion := model.Localtion{ID: location_id}
|
||||
err := localtion.GetLocaltionByID()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// 获取天气类型
|
||||
weatherType := model.WeatherType{Id: weather_type_id}
|
||||
err = weatherType.GetWeatherTypeByID()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if dev {
|
||||
rv = c_DEVURL
|
||||
} else {
|
||||
rv = c_PROURL
|
||||
}
|
||||
rv += c_VERSION
|
||||
rv += weatherType.Name
|
||||
rv += "?key="
|
||||
if dev {
|
||||
rv += c_DEVKEY
|
||||
} else {
|
||||
rv += c_PROKEY
|
||||
}
|
||||
rv += "&location="
|
||||
rv += localtion.Code
|
||||
return
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"git.shikicc.com/golang/kit/log/zaplog"
|
||||
)
|
||||
|
||||
var L = zaplog.New(zaplog.Config{
|
||||
Mode: zaplog.Debug,
|
||||
DebugLog: zaplog.LogFileConfig{
|
||||
Filename: "log/debug",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
InfoLog: zaplog.LogFileConfig{
|
||||
Filename: "log/info",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
WarnLog: zaplog.LogFileConfig{
|
||||
Filename: "log/warn",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
ErrorLog: zaplog.LogFileConfig{
|
||||
Filename: "log/error",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
FatalLog: zaplog.LogFileConfig{
|
||||
Filename: "log/fatal",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
})
|
||||
|
||||
var W = zaplog.New(zaplog.Config{
|
||||
Mode: zaplog.Debug,
|
||||
DebugLog: zaplog.LogFileConfig{
|
||||
Filename: "log/web_debug",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
InfoLog: zaplog.LogFileConfig{
|
||||
Filename: "log/web_info",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
WarnLog: zaplog.LogFileConfig{
|
||||
Filename: "log/web_warn",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
ErrorLog: zaplog.LogFileConfig{
|
||||
Filename: "log/web_error",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
FatalLog: zaplog.LogFileConfig{
|
||||
Filename: "log/web_fatal",
|
||||
FileSize_MB: 1,
|
||||
FileBackup: 3,
|
||||
},
|
||||
})
|
|
@ -0,0 +1,11 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"cc/db"
|
||||
"cc/web"
|
||||
)
|
||||
|
||||
func main() {
|
||||
defer db.DB.Close()
|
||||
web.Go()
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,82 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"cc/db/model"
|
||||
"cc/web/util/response"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// GetLocaltions 获取所有地点
|
||||
func GetLocaltions(c *fiber.Ctx) error {
|
||||
loc := model.Localtion{}
|
||||
// 获取所有地点
|
||||
localtions, err := loc.GetAll()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "获取地点失败: "+err.Error())
|
||||
}
|
||||
// 返回地点
|
||||
return response.Ok(c, localtions)
|
||||
}
|
||||
|
||||
// CreateLocaltion 创建地点
|
||||
func CreateLocaltion(c *fiber.Ctx) error {
|
||||
loc := model.Localtion{}
|
||||
// 解析参数
|
||||
err := c.BodyParser(&loc)
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 创建地点
|
||||
err = loc.CreateLocaltion()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "创建地点失败: "+err.Error())
|
||||
}
|
||||
// 返回地点
|
||||
return response.Ok(c, loc)
|
||||
}
|
||||
|
||||
// UpdateLocaltion 更新地点
|
||||
func UpdateLocaltion(c *fiber.Ctx) error {
|
||||
// 获取地点id
|
||||
id, err := c.ParamsInt("id")
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 获取地点
|
||||
loc := model.Localtion{
|
||||
ID: id,
|
||||
}
|
||||
// 解析参数
|
||||
err = c.BodyParser(&loc)
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 更新地点
|
||||
err = loc.UpdateLocaltion()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "更新地点失败: "+err.Error())
|
||||
}
|
||||
// 返回地点
|
||||
return response.Ok(c, loc)
|
||||
}
|
||||
|
||||
// DeleteLocaltion 删除地点
|
||||
func DeleteLocaltion(c *fiber.Ctx) error {
|
||||
// 获取地点id
|
||||
id, err := c.ParamsInt("id")
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 获取地点
|
||||
loc := model.Localtion{
|
||||
ID: id,
|
||||
}
|
||||
// 删除地点
|
||||
err = loc.DeleteLocaltion()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "删除地点失败: "+err.Error())
|
||||
}
|
||||
// 返回地点
|
||||
return response.Ok(c, "删除地点成功")
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package localtion
|
||||
|
||||
import (
|
||||
"cc/web/app/localtion/api"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// AddRouter 添加路由
|
||||
func AddRouter(r fiber.Router) {
|
||||
// 获取所有地点
|
||||
r.Get("localtion", api.GetLocaltions)
|
||||
// 创建地点
|
||||
r.Post("localtion", api.CreateLocaltion)
|
||||
// 更新地点
|
||||
r.Put("localtion/:id", api.UpdateLocaltion)
|
||||
// 删除地点
|
||||
r.Delete("localtion/:id", api.DeleteLocaltion)
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"cc/db/model"
|
||||
"cc/web/util/response"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// GetProjects 获取所有项目
|
||||
func GetProjects(c *fiber.Ctx) error {
|
||||
pro := model.Project{}
|
||||
// 获取所有项目
|
||||
projects, err := pro.GetAll()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "获取项目失败: "+err.Error())
|
||||
}
|
||||
// 返回项目
|
||||
return response.Ok(c, projects)
|
||||
}
|
||||
|
||||
// GetProjectByID 通过项目ID获取项目
|
||||
func GetProjectByID(c *fiber.Ctx) error {
|
||||
// 获取项目ID
|
||||
id, err := c.ParamsInt("id")
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 获取项目
|
||||
pro := model.Project{
|
||||
ID: id,
|
||||
}
|
||||
// 通过项目ID获取项目
|
||||
err = pro.GetProjectByID()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "获取项目失败: "+err.Error())
|
||||
}
|
||||
// 返回项目
|
||||
return response.Ok(c, pro)
|
||||
}
|
||||
|
||||
// GetProjectByCode 通过项目代码获取项目
|
||||
func GetProjectByCode(c *fiber.Ctx) error {
|
||||
// 获取项目代码
|
||||
code, err := c.ParamsInt("code")
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 获取项目
|
||||
pro := model.Project{
|
||||
Code: code,
|
||||
}
|
||||
// 通过项目代码获取项目
|
||||
err = pro.GetProjectByCode()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "获取项目失败: "+err.Error())
|
||||
}
|
||||
// 返回项目
|
||||
return response.Ok(c, pro)
|
||||
}
|
||||
|
||||
// CreateProject 创建项目
|
||||
func CreateProject(c *fiber.Ctx) error {
|
||||
pro := model.Project{}
|
||||
// 解析参数
|
||||
err := c.BodyParser(&pro)
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 创建项目
|
||||
err = pro.CreateProject()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "创建项目失败: "+err.Error())
|
||||
}
|
||||
// 返回项目
|
||||
return response.Ok(c, pro)
|
||||
}
|
||||
|
||||
// UpdateProject 更新项目
|
||||
func UpdateProject(c *fiber.Ctx) error {
|
||||
// 获取项目代码
|
||||
id, err := c.ParamsInt("id")
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 获取项目
|
||||
pro := model.Project{
|
||||
ID: id,
|
||||
}
|
||||
// 解析参数
|
||||
err = c.BodyParser(&pro)
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 更新项目
|
||||
err = pro.UpdateProject()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "更新项目失败: "+err.Error())
|
||||
}
|
||||
// 返回项目
|
||||
return response.Ok(c, pro)
|
||||
}
|
||||
|
||||
// DeleteProject 删除项目
|
||||
func DeleteProject(c *fiber.Ctx) error {
|
||||
// 获取项目代码
|
||||
id, err := c.ParamsInt("id")
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 获取项目
|
||||
pro := model.Project{
|
||||
ID: id,
|
||||
}
|
||||
// 删除项目
|
||||
err = pro.DeleteProject()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "删除项目失败: "+err.Error())
|
||||
}
|
||||
// 返回项目
|
||||
return response.Ok(c, "删除成功")
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package project
|
||||
|
||||
import (
|
||||
"cc/web/app/project/api"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// AddRouter 添加路由
|
||||
func AddRouter(r fiber.Router) {
|
||||
// 获取所有项目
|
||||
r.Get("project", api.GetProjects)
|
||||
// 通过项目ID获取项目
|
||||
r.Get("project/:id", api.GetProjectByID)
|
||||
// 通过项目编码获取项目
|
||||
r.Post("project/:code", api.GetProjectByCode)
|
||||
// 创建项目
|
||||
r.Post("project", api.CreateProject)
|
||||
// 更新项目
|
||||
r.Put("project/:id", api.UpdateProject)
|
||||
// 删除项目
|
||||
r.Delete("project/:id", api.DeleteProject)
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"cc/db/model"
|
||||
"cc/qweather"
|
||||
"cc/web/util/response"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func GetWeatherByCode(c *fiber.Ctx) error {
|
||||
// 获取项目代码
|
||||
code, err := c.ParamsInt("code")
|
||||
if err != nil {
|
||||
return response.Error(c, response.BadRequest, "参数错误")
|
||||
}
|
||||
// 获取项目信息
|
||||
project := model.Project{Code: code}
|
||||
err = project.GetProjectByCode()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "获取项目信息失败: "+err.Error())
|
||||
}
|
||||
// 获取天气缓存
|
||||
weather := model.Weather{ProjectID: project.ID}
|
||||
weather.GetWeather()
|
||||
// 判断是否需要更新
|
||||
var flag bool
|
||||
// 检查天气缓存是否为空
|
||||
if weather.Value == nil {
|
||||
flag = true
|
||||
} else {
|
||||
// 检查天气缓存是否过期
|
||||
update, err := time.Parse("2006-01-02 15:04:05", weather.UpdateAt)
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "解析时间失败: "+err.Error())
|
||||
}
|
||||
// 更新时间与当前时间差大于更新频率则更新
|
||||
if time.Since(update) > time.Duration(project.UpdateFrequency)*time.Minute {
|
||||
flag = true
|
||||
}
|
||||
}
|
||||
if flag {
|
||||
// 更新天气
|
||||
// 获取天气
|
||||
weather.UpdateAt = time.Now().Local().Format("2006-01-02 15:04:05")
|
||||
weather.Value, err = qweather.Get(project.LocaltionID, project.WeatherTypeID, project.Dev)
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "获取天气失败: "+err.Error())
|
||||
}
|
||||
// 更新天气缓存
|
||||
err = weather.UpdateWeather()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "更新天气缓存失败: "+err.Error())
|
||||
}
|
||||
}
|
||||
return response.Ok(c, weather)
|
||||
}
|
||||
|
||||
// 获取天气类型
|
||||
func GetWeatherType(c *fiber.Ctx) error {
|
||||
// 获取天气类型
|
||||
weatherType := model.WeatherType{}
|
||||
weatherTypes, err := weatherType.GetAll()
|
||||
if err != nil {
|
||||
return response.Error(c, response.InternalServerError, "获取天气类型失败: "+err.Error())
|
||||
}
|
||||
return response.Ok(c, weatherTypes)
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package weather
|
||||
|
||||
import (
|
||||
"cc/web/app/weather/api"
|
||||
"cc/web/middleware"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
// AddRouter 添加路由
|
||||
func AddRouter(r fiber.Router) {
|
||||
// 通过code获取实时天气
|
||||
r.Use(middleware.Limiter())
|
||||
r.Get("weather/:code", api.GetWeatherByCode)
|
||||
// 获取天气类型
|
||||
r.Post("weather/types", api.GetWeatherType)
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"cc/web/util/response"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/limiter"
|
||||
)
|
||||
|
||||
func Limiter() func(*fiber.Ctx) error {
|
||||
return limiter.New(limiter.Config{
|
||||
Max: 1,
|
||||
Expiration: time.Second,
|
||||
LimitReached: func(c *fiber.Ctx) error {
|
||||
return response.Error(c, response.TooManyRequests, "请求过多")
|
||||
},
|
||||
})
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package middleware
|
||||
|
||||
import (
|
||||
"cc/util/log"
|
||||
|
||||
"github.com/gofiber/contrib/fiberzap/v2"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
)
|
||||
|
||||
func Log() func(*fiber.Ctx) error {
|
||||
return fiberzap.New(fiberzap.Config{
|
||||
Logger: log.W.Desugar(),
|
||||
Fields: []string{
|
||||
"status",
|
||||
"method",
|
||||
"path",
|
||||
"protocol",
|
||||
"ip",
|
||||
"latency",
|
||||
"ua",
|
||||
},
|
||||
Messages: []string{
|
||||
"Server error",
|
||||
"Client error",
|
||||
"Success ",
|
||||
},
|
||||
})
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package request
|
||||
|
||||
// rcud 0123
|
||||
const (
|
||||
|
||||
/***** 用户接口 *****/
|
||||
|
||||
QueryUser ActionNum = 90000 // 用户查询
|
||||
|
||||
CreateUser ActionNum = 90100 // 用户新增
|
||||
|
||||
UpdateUser ActionNum = 90200 // 用户修改
|
||||
UpdateUserPassword ActionNum = 90201 // 用户密码修改
|
||||
|
||||
DeleteUser ActionNum = 90300 // 用户删除
|
||||
|
||||
/***** 登录接口 *****/
|
||||
|
||||
LoginStatus ActionNum = 50000 // 登录状态
|
||||
Logout ActionNum = 50002 // 登出请求
|
||||
|
||||
/***** 系统接口 *****/
|
||||
|
||||
QueryInfo ActionNum = 57000 // 查询信息
|
||||
QueryNet ActionNum = 57001 // 查询网络
|
||||
QueryCom ActionNum = 57002 // 查询串口
|
||||
|
||||
UpdateNet ActionNum = 57201 // 更新网络
|
||||
|
||||
Reboot ActionNum = 57202 // 重启网关
|
||||
|
||||
/***** 模板接口 *****/
|
||||
|
||||
QueryAllTemplates ActionNum = 53000 // 查询模板
|
||||
CreateTemplate ActionNum = 53100 // 新增模板
|
||||
UpdateTemplate ActionNum = 53200 // 更新模板
|
||||
DeleteTemplate ActionNum = 53300 // 删除模板
|
||||
QueryTemplateSupportType ActionNum = 53001 // 查询支持的模板类型
|
||||
|
||||
/***** 模板点位接口 *****/
|
||||
|
||||
QueryTemplatePoint ActionNum = 53010 // 查询模板下的点位
|
||||
CreateTemplatePoint ActionNum = 53110 // 新增模板下的点位
|
||||
UpdateTemplatePoint ActionNum = 53210 // 更新模板下的点位
|
||||
DeleteTemplatePoint ActionNum = 53310 // 删除模板下的点位
|
||||
ExportTemplatePoint ActionNum = 53211 // 导出模板下的点位
|
||||
ImportTemplatePoint ActionNum = 53212 // 导入模板下的点位
|
||||
QueryTemplatePointSupportType ActionNum = 53011 // 查询支持的点位类型
|
||||
QueryDLT645TemplatePointSupportType ActionNum = 53012 // 查询支持的点位类型
|
||||
|
||||
QueryModbusTemplatePoint ActionNum = 53020 // 查询MODBUS模板下的点位
|
||||
CreateModbusTemplatePoint ActionNum = 53120 // 新增MODBUS模板下的点位
|
||||
|
||||
QueryDLT6452007TemplatePoint ActionNum = 53021 // 查询DLT6452007模板下的点位
|
||||
CreateDLT6452007TemplatePoint ActionNum = 53121 // 新增DLT6452007模板下的点位
|
||||
|
||||
/***** 驱动接口 *****/
|
||||
|
||||
QueryDriver ActionNum = 54000 // 查询驱动
|
||||
CreateDriver ActionNum = 54100 // 增加驱动
|
||||
UpdateDriver ActionNum = 54200 // 更新驱动
|
||||
DeleteDriver ActionNum = 54300 // 删除驱动
|
||||
|
||||
StartDriver ActionNum = 54400 // 启动驱动
|
||||
StopDriver ActionNum = 54500 // 停止驱动
|
||||
|
||||
QueryDriverSupportType ActionNum = 54001 // 查询支持的驱动类型
|
||||
QueryDriverSupportTemplateType ActionNum = 54002 // 查询驱动类型支持的模板列表
|
||||
QueryDriverSupportStatus ActionNum = 54003 // 查询支持的驱动状态
|
||||
QueryDriverInfo ActionNum = 54004 // 查询驱动详情
|
||||
QueryDriverConfig ActionNum = 54005 // 查询驱动配置
|
||||
|
||||
ResetDriverInfoCount ActionNum = 54201 // 重置驱动详情的通信统计
|
||||
UpdateDriverConfig ActionNum = 54202 // 更新驱动配置
|
||||
|
||||
/***** 驱动设备接口 *****/
|
||||
|
||||
QueryDriverDevice ActionNum = 54010 // 查询驱动下的设备
|
||||
CreateDriverDevice ActionNum = 54110 // 增加驱动下的设备
|
||||
UpdateDriverDevice ActionNum = 54210 // 更新驱动下的设备
|
||||
DeleteDriverDevice ActionNum = 54310 // 删除驱动下的设备
|
||||
ExportDriverDevice ActionNum = 54211 // 导出驱动下的设备
|
||||
ImportDriverDevice ActionNum = 54212 // 导入驱动下的设备
|
||||
|
||||
/***** 实时数据接口 *****/
|
||||
|
||||
PointGet ActionNum = 56000 // 获取点位
|
||||
PointSet ActionNum = 56001 // 点位写值
|
||||
PointHistoryEnable ActionNum = 56002 // 启用历史记录
|
||||
PointHistoryDisable ActionNum = 56003 // 禁用历史记录
|
||||
PointHistorySetMax ActionNum = 56004 // 设置历史记录最大数量
|
||||
PointHistoryClear ActionNum = 56005 // 清空历史记录
|
||||
PointHistoryExport ActionNum = 56006 // 导出历史记录
|
||||
PointResetHealth ActionNum = 56007 // 重置健康信息
|
||||
|
||||
DeviceGet ActionNum = 56100 // 获取设备
|
||||
DeviceEnable ActionNum = 56101 // 启用设备
|
||||
DeviceDisable ActionNum = 56102 // 禁用设备
|
||||
|
||||
DriverGet ActionNum = 56200 // 获取驱动
|
||||
DriverStart ActionNum = 56201 // 启动驱动
|
||||
DriverStop ActionNum = 56202 // 停止驱动
|
||||
DriverResetHealth ActionNum = 56203 // 重置健康信息
|
||||
)
|
||||
|
||||
type ActionNum uint64
|
|
@ -0,0 +1 @@
|
|||
package request
|
|
@ -0,0 +1,109 @@
|
|||
package response
|
||||
|
||||
const (
|
||||
Success ResponseCode = 0
|
||||
|
||||
NoContent ResponseCode = 204
|
||||
BadRequest ResponseCode = 400
|
||||
Unauthorized ResponseCode = 401
|
||||
TooManyRequests ResponseCode = 429
|
||||
InternalServerError ResponseCode = 500
|
||||
|
||||
InvalidUserName ResponseCode = 40101
|
||||
InvalidUserPassword ResponseCode = 40102
|
||||
|
||||
DBFailure ResponseCode = 50001
|
||||
|
||||
InvalidActionNum ResponseCode = 52000
|
||||
|
||||
InvalidBody ResponseCode = 1002
|
||||
|
||||
DataNotExist ResponseCode = 2002
|
||||
DataIsExist ResponseCode = 2003
|
||||
|
||||
InvalidUserID ResponseCode = 3001
|
||||
|
||||
InvalidUserToken ResponseCode = 3004
|
||||
InvalidUserRole ResponseCode = 3005
|
||||
InvalidUserStatus ResponseCode = 3006
|
||||
|
||||
InvalidTemplateType ResponseCode = 60001
|
||||
TemplateInUse ResponseCode = 60002
|
||||
|
||||
InvalidDriverType ResponseCode = 61001
|
||||
DriverIsRun ResponseCode = 61002
|
||||
|
||||
ErrDataPointWrite ResponseCode = 7001
|
||||
)
|
||||
|
||||
type ResponseCode uint32
|
||||
|
||||
func (r ResponseCode) String() string {
|
||||
switch r {
|
||||
case Success:
|
||||
return "请求成功"
|
||||
|
||||
case NoContent:
|
||||
return "无内容"
|
||||
|
||||
case BadRequest:
|
||||
return "错误请求"
|
||||
|
||||
case Unauthorized:
|
||||
return "未授权"
|
||||
|
||||
case TooManyRequests:
|
||||
return "请求过多"
|
||||
|
||||
case InternalServerError:
|
||||
return "服务器内部错误"
|
||||
case DBFailure:
|
||||
return "数据库操作失败"
|
||||
|
||||
case InvalidUserName:
|
||||
return "无效的用户名"
|
||||
case InvalidUserPassword:
|
||||
return "无效的用户密码"
|
||||
|
||||
case InvalidActionNum:
|
||||
return "无效的请求动作"
|
||||
///////////////////////////////////////
|
||||
|
||||
// 1001-1003
|
||||
case InvalidBody:
|
||||
return "无效的请求体"
|
||||
|
||||
// 2001-2999 数据库相关
|
||||
|
||||
case DataNotExist:
|
||||
return "数据不存在"
|
||||
case DataIsExist:
|
||||
return "数据已存在"
|
||||
|
||||
// 3001-3999 用户相关
|
||||
case InvalidUserID:
|
||||
return "无效的用户ID"
|
||||
|
||||
case InvalidUserToken:
|
||||
return "无效的用户token"
|
||||
case InvalidUserRole:
|
||||
return "无效的用户权限"
|
||||
case InvalidUserStatus:
|
||||
return "无效的用户状态"
|
||||
|
||||
case InvalidTemplateType:
|
||||
return "无效的模板类型"
|
||||
case TemplateInUse:
|
||||
return "模板使用中"
|
||||
|
||||
case InvalidDriverType:
|
||||
return "无效的驱动类型"
|
||||
case DriverIsRun:
|
||||
return "驱动运行中"
|
||||
|
||||
// 96001
|
||||
|
||||
default:
|
||||
return "未知的响应码"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package response
|
||||
|
||||
import "github.com/gofiber/fiber/v2"
|
||||
|
||||
type ResponseData struct {
|
||||
Code ResponseCode `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data interface{} `json:"data"`
|
||||
}
|
||||
|
||||
func Ok(c *fiber.Ctx, data interface{}) error {
|
||||
ret := ResponseData{
|
||||
Code: Success,
|
||||
Message: Success.String(),
|
||||
Data: data,
|
||||
}
|
||||
return c.JSON(ret)
|
||||
}
|
||||
|
||||
func Error(c *fiber.Ctx, errCode ResponseCode, data interface{}) error {
|
||||
ret := ResponseData{
|
||||
Code: errCode,
|
||||
Message: errCode.String(),
|
||||
Data: data,
|
||||
}
|
||||
return c.JSON(ret)
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"cc/web/app/localtion"
|
||||
"cc/web/app/project"
|
||||
"cc/web/app/weather"
|
||||
"cc/web/middleware"
|
||||
"log"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/gofiber/fiber/v2/middleware/basicauth"
|
||||
)
|
||||
|
||||
// Go 启动web服务
|
||||
func Go() {
|
||||
app := fiber.New(fiber.Config{
|
||||
ServerHeader: "weather",
|
||||
AppName: "天气服务",
|
||||
})
|
||||
|
||||
app.Use(middleware.Log())
|
||||
|
||||
r := app.Group("api") // 路由组
|
||||
weather.AddRouter(r) // 天气接口
|
||||
app.Use(basicauth.New(basicauth.Config{
|
||||
Users: map[string]string{
|
||||
"weather": "lweather",
|
||||
},
|
||||
}))
|
||||
project.AddRouter(r) // 项目接口
|
||||
localtion.AddRouter(r) // 地点接口
|
||||
|
||||
if err := app.Listen(":52001"); err != nil {
|
||||
log.Panic("[web]端口监听失败:", err)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue