mirror of http://gitlab.batiao8.com/yic/film.git
init
This commit is contained in:
commit
6888a8a813
|
@ -0,0 +1,12 @@
|
|||
*.iml
|
||||
.idea/
|
||||
output/
|
||||
dockerfiles/
|
||||
log
|
||||
.DS_Store
|
||||
web/node_modules
|
||||
ad-api.exe
|
||||
doc
|
||||
cmd/test
|
||||
go.sum
|
||||
pkg
|
|
@ -0,0 +1,20 @@
|
|||
FROM registry.cn-shanghai.aliyuncs.com/devcon/godev:v1.0.14
|
||||
ADD . /app/src
|
||||
WORKDIR /app/src
|
||||
|
||||
RUN mkdir -p /app/bin /app/log
|
||||
|
||||
RUN export GOROOT=/usr/local/go1.18.2 && \
|
||||
export GOPROXY=https://goproxy.cn && \
|
||||
export PATH=$PATH:$GOROOT/bin && \
|
||||
go mod tidy && \
|
||||
go build cmd/film.go && \
|
||||
mv film /app/bin && \
|
||||
cp -r conf /app && \
|
||||
cp start.sh /app && \
|
||||
chmod +x /app/start.sh
|
||||
|
||||
WORKDIR /app
|
||||
EXPOSE 9263
|
||||
|
||||
CMD ["/app/start.sh"]
|
|
@ -0,0 +1,62 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"film/config"
|
||||
"film/model"
|
||||
"film/worker"
|
||||
"fmt"
|
||||
rotatelogs "github.com/lestrrat-go/file-rotatelogs"
|
||||
"github.com/rifflock/lfshook"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/smbrave/goutil"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func initLog() {
|
||||
cfg := config.GetConfig()
|
||||
logfile := "log/server.log"
|
||||
writer, err := rotatelogs.New(
|
||||
logfile+".%Y%m%d",
|
||||
rotatelogs.WithLinkName(logfile),
|
||||
rotatelogs.WithMaxAge(time.Duration(86400*7)*time.Second),
|
||||
rotatelogs.WithRotationTime(time.Duration(86400)*time.Second),
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pathMap := lfshook.WriterMap{
|
||||
log.TraceLevel: writer,
|
||||
log.DebugLevel: writer,
|
||||
log.InfoLevel: writer,
|
||||
log.WarnLevel: writer,
|
||||
log.ErrorLevel: writer,
|
||||
log.FatalLevel: writer,
|
||||
log.PanicLevel: writer,
|
||||
}
|
||||
|
||||
log.AddHook(lfshook.NewHook(pathMap, new(goutil.LogFile)))
|
||||
|
||||
log.SetOutput(os.Stdout)
|
||||
log.SetReportCaller(true)
|
||||
log.SetFormatter(new(goutil.LogFile))
|
||||
log.SetLevel(log.Level(cfg.Server.LogLevel))
|
||||
}
|
||||
func main() {
|
||||
config.LoadServerConfig()
|
||||
initLog()
|
||||
cfg := config.GetConfig()
|
||||
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", cfg.Mysql.User,
|
||||
cfg.Mysql.Pass, cfg.Mysql.Host, cfg.Mysql.Port, cfg.Mysql.Db)
|
||||
_, err := model.Init(dsn)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
w := &worker.Worker{
|
||||
Token: config.GetConfig().Film.Token,
|
||||
}
|
||||
w.Init()
|
||||
select {}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
[server]
|
||||
address = "0.0.0.0:9263"
|
||||
#0:PAINC 1:FATAL 2:ERROR 3:WARNING 4:INFO 5:DEBUG 6:TRACE
|
||||
log_level = 6
|
||||
|
||||
|
||||
[mysql]
|
||||
host = "100.118.29.74"
|
||||
port = 3307
|
||||
user = "film"
|
||||
pass = "7VCfJx7H8MymUm"
|
||||
db = "film"
|
||||
|
||||
|
||||
[film]
|
||||
token = "cc5f1d4c36f7e9544d641a174b298f94"
|
|
@ -0,0 +1,12 @@
|
|||
[server]
|
||||
address = "0.0.0.0:9263"
|
||||
#0:PAINC 1:FATAL 2:ERROR 3:WARNING 4:INFO 5:DEBUG 6:TRACE
|
||||
log_level = 6
|
||||
|
||||
|
||||
[mysql]
|
||||
host = "192.168.13.213"
|
||||
port = 3306
|
||||
user = "film"
|
||||
pass = "7VCfJx7H8MymUm"
|
||||
db = "film"
|
|
@ -0,0 +1,93 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"github.com/mitchellh/mapstructure"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/smbrave/goutil"
|
||||
"github.com/spf13/viper"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
config *Config
|
||||
configEnv string
|
||||
BuildTime string
|
||||
CommitId string
|
||||
)
|
||||
|
||||
type Mysql struct {
|
||||
Host string `toml:"host"`
|
||||
Port int `toml:"port"`
|
||||
User string `toml:"user"`
|
||||
Pass string `toml:"pass"`
|
||||
Db string `toml:"db"`
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
Address string `toml:"address"`
|
||||
LogLevel int `toml:"log_level"`
|
||||
EnableDoc bool `toml:"enable_doc"`
|
||||
}
|
||||
|
||||
type Redis struct {
|
||||
Addr string `toml:"addr"`
|
||||
Db int `toml:"db"`
|
||||
Password string `toml:"password"`
|
||||
}
|
||||
type Film struct {
|
||||
Token string `toml:"token"`
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Server *Server `toml:"server"`
|
||||
Mysql *Mysql `toml:"mysql"`
|
||||
Redis *Redis `toml:"redis"`
|
||||
Film *Film `toml:"film"`
|
||||
}
|
||||
|
||||
func GetEnv() string {
|
||||
return configEnv
|
||||
}
|
||||
|
||||
func IsProdEnv() bool {
|
||||
return configEnv == "prod"
|
||||
}
|
||||
|
||||
func IsDevEnv() bool {
|
||||
return configEnv == "dev"
|
||||
}
|
||||
|
||||
func IsTestEnv() bool {
|
||||
return configEnv == "test"
|
||||
}
|
||||
|
||||
func GetConfig() *Config {
|
||||
return config
|
||||
}
|
||||
|
||||
func LoadServerConfig() {
|
||||
configEnv = os.Getenv("CONFIG_ENV")
|
||||
if configEnv == "" {
|
||||
configEnv = "dev"
|
||||
}
|
||||
|
||||
var envConfig Config
|
||||
|
||||
viper.SetConfigFile("conf/server.conf." + configEnv)
|
||||
viper.SetConfigType("toml")
|
||||
viper.AutomaticEnv()
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
viper.SetEnvPrefix("conf")
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := viper.Unmarshal(&envConfig, func(decoderConfig *mapstructure.DecoderConfig) {
|
||||
decoderConfig.TagName = "toml"
|
||||
}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
config = &envConfig
|
||||
log.Infof("load real config[%s] ", goutil.EncodeJSONIndent(config))
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
module film
|
||||
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
github.com/go-co-op/gocron v1.19.0
|
||||
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/smbrave/goutil v0.0.0-20230208141215-e3360c3bfd1b
|
||||
github.com/spf13/cast v1.5.0
|
||||
github.com/spf13/viper v1.15.0
|
||||
gorm.io/driver/mysql v1.4.7
|
||||
gorm.io/gorm v1.24.6
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.6.0 // indirect
|
||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/jonboulle/clockwork v0.4.0 // indirect
|
||||
github.com/lestrrat-go/strftime v1.0.6 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
github.com/spf13/afero v1.9.3 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.4.2 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.3.0 // indirect
|
||||
golang.org/x/text v0.5.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
|
@ -0,0 +1,81 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
db *gorm.DB = nil
|
||||
)
|
||||
|
||||
func SetDb(b *gorm.DB) {
|
||||
db = b
|
||||
}
|
||||
|
||||
func GetOrm() *gorm.DB {
|
||||
return db
|
||||
}
|
||||
|
||||
type DBLogger struct {
|
||||
level logger.LogLevel
|
||||
}
|
||||
|
||||
func (d *DBLogger) LogMode(level logger.LogLevel) logger.Interface {
|
||||
d.level = level
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *DBLogger) Info(context.Context, string, ...interface{}) {
|
||||
|
||||
}
|
||||
|
||||
func (d *DBLogger) Warn(context.Context, string, ...interface{}) {
|
||||
|
||||
}
|
||||
|
||||
func (d *DBLogger) Error(context.Context, string, ...interface{}) {
|
||||
|
||||
}
|
||||
|
||||
func (d *DBLogger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
|
||||
sql, affects := fc()
|
||||
|
||||
if err != nil && err != gorm.ErrRecordNotFound {
|
||||
log.Errorf("[SQL]sql=%s affect=%d cost=%dms error=%v", sql, affects, time.Since(begin).Milliseconds(), err)
|
||||
} else {
|
||||
if time.Since(begin).Milliseconds() > 200 {
|
||||
log.Errorf("[SQL]sql=%s affect=%d cost=%dms", sql, affects, time.Since(begin).Milliseconds())
|
||||
} else {
|
||||
log.Debugf("[SQL]sql=%s affect=%d cost=%dms", sql, affects, time.Since(begin).Milliseconds())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Init(dsn string) (*gorm.DB, error) {
|
||||
var err error
|
||||
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
|
||||
if err != nil {
|
||||
log.Errorf("open dsn[%s] error[%s]", dsn, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db.Logger = &DBLogger{}
|
||||
return db, err
|
||||
}
|
||||
|
||||
func Ping() error {
|
||||
d, err := db.DB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d.Ping(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
tableNameOrder = "orders"
|
||||
)
|
||||
|
||||
type Order struct {
|
||||
Id int64
|
||||
OrderId string
|
||||
StartTime string
|
||||
StartDate string
|
||||
TotalPrice int64
|
||||
PayPrice int64
|
||||
MaoyanPrice int64
|
||||
SeatNum int
|
||||
Seats string
|
||||
ShowTime int64
|
||||
PayTime int64
|
||||
CityName string
|
||||
ProvinceName string
|
||||
Ting string
|
||||
CinemaName string
|
||||
MovieName string
|
||||
Address string
|
||||
CreateTime int64
|
||||
UpdateTime int64
|
||||
}
|
||||
|
||||
func AddOrder(o *Order) (int64, error) {
|
||||
o.CreateTime = time.Now().Unix()
|
||||
res := db.Table(tableNameOrder).Create(o)
|
||||
return o.Id, res.Error
|
||||
}
|
||||
|
||||
func GetOrder(id int64) (*Order, error) {
|
||||
var u Order
|
||||
tx := db.Table(tableNameOrder)
|
||||
tx = tx.Where("id = ?", id)
|
||||
res := tx.First(&u)
|
||||
if res.Error == gorm.ErrRecordNotFound {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if res.Error != nil {
|
||||
return nil, res.Error
|
||||
}
|
||||
return &u, nil
|
||||
}
|
||||
|
||||
func UpdateOrder(o *Order) error {
|
||||
o.UpdateTime = time.Now().Unix()
|
||||
tx := db.Table(tableNameOrder)
|
||||
res := tx.Save(o)
|
||||
return res.Error
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash
|
||||
set -x
|
||||
ROOT=$(cd `dirname $0`; pwd)
|
||||
cd $ROOT
|
||||
|
||||
if [ "$BINARY" = "" ];then
|
||||
BINARY="film"
|
||||
fi
|
||||
|
||||
while [ true ];do
|
||||
$ROOT/bin/$BINARY $@ >> log/run.log 2>&1
|
||||
/usr/local/bin/sendproxy weixin jiangyong "$CONFIG_ENV $BINARY 服务崩溃[`date +"%Y-%m-%d %H:%M:%S"`]"
|
||||
sleep 60
|
||||
done
|
||||
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
package worker
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"film/model"
|
||||
"fmt"
|
||||
"github.com/go-co-op/gocron"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cast"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Worker struct {
|
||||
Token string
|
||||
}
|
||||
|
||||
func (w *Worker) Init() error {
|
||||
timezone, _ := time.LoadLocation("Asia/Shanghai")
|
||||
cron := gocron.NewScheduler(timezone)
|
||||
|
||||
cron.Every(30).Seconds().Do(func() {
|
||||
w.syncOrder()
|
||||
})
|
||||
|
||||
cron.StartAsync()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *Worker) httpPost(requestUrl string) ([]byte, error) {
|
||||
client := &http.Client{Timeout: 20 * time.Second}
|
||||
//忽略https的证书
|
||||
client.Transport = &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}
|
||||
p := url.Values{}
|
||||
u, _ := url.Parse(requestUrl)
|
||||
|
||||
u.RawQuery = p.Encode()
|
||||
req, err := http.NewRequest("POST", u.String(), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("token", w.Token)
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
return io.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
func (w *Worker) syncOrder() {
|
||||
orderUrl := "https://hahapiao.cn/api/Synchro/toList"
|
||||
body, err := w.httpPost(orderUrl)
|
||||
if err != nil {
|
||||
log.Errorf("syncOrder error : %s", err.Error())
|
||||
return
|
||||
}
|
||||
result := make(map[string]interface{})
|
||||
if err := json.Unmarshal(body, &result); err != nil {
|
||||
log.Errorf("json.unmarshal [%s] error : %s", string(body), err.Error())
|
||||
return
|
||||
}
|
||||
if cast.ToInt(result["status"]) != 200 || cast.ToInt(result["code"]) != 200 {
|
||||
log.Errorf("status[%d] code[%d] message[%s]", cast.ToInt(result["status"]), cast.ToInt(result["code"]), cast.ToString(result["msg"]))
|
||||
return
|
||||
}
|
||||
|
||||
datas := cast.ToSlice(result["data"])
|
||||
|
||||
for _, d := range datas {
|
||||
data := cast.ToStringMap(d)
|
||||
id := cast.ToInt64(data["id"])
|
||||
order, err := model.GetOrder(id)
|
||||
if err != nil {
|
||||
log.Errorf("get order id : %d error :%s", id, err.Error())
|
||||
}
|
||||
isAdd := false
|
||||
|
||||
if order == nil {
|
||||
order = new(model.Order)
|
||||
order.Id = id
|
||||
isAdd = true
|
||||
}
|
||||
order.OrderId = cast.ToString(data["order_id"])
|
||||
order.PayPrice = int64(cast.ToFloat64(data["payPrice"]) * 100)
|
||||
order.TotalPrice = int64(cast.ToFloat64(data["total_price"]) * 100)
|
||||
order.MaoyanPrice = int64(cast.ToFloat64(data["maoyan_price"]) * 100)
|
||||
order.StartTime = cast.ToString(data["startTime"])
|
||||
order.StartDate = cast.ToString(data["invalidateDate"])
|
||||
order.SeatNum = cast.ToInt(data["seat_num"])
|
||||
order.Seats = cast.ToString(data["seats"])
|
||||
order.ShowTime = cast.ToInt64(data["show_time"])
|
||||
order.PayTime = cast.ToInt64(data["pay_time"])
|
||||
order.CityName = cast.ToString(data["cityName"])
|
||||
order.ProvinceName = cast.ToString(data["provinceName"])
|
||||
order.MovieName = cast.ToString(data["movieName"])
|
||||
order.Address = cast.ToString(data["address"])
|
||||
order.Ting = cast.ToString(data["ting"])
|
||||
|
||||
if isAdd {
|
||||
model.AddOrder(order)
|
||||
} else {
|
||||
model.UpdateOrder(order)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue