Initial commit
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"stat/common/log"
|
||||
"stat/tool/dspSync/model"
|
||||
"stat/tool/dspSync/service"
|
||||
"time"
|
||||
)
|
||||
|
||||
func initMongoDB() error {
|
||||
|
||||
if err := model.InitMongoDB(); err != nil {
|
||||
log.Error("InitMongoDB err", log.E(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
initMongoDB()
|
||||
time.Local, _ = time.LoadLocation("Asia/Shanghai")
|
||||
_ = service.UserStatInfo() //用户同步完成可执行
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
// DistrictInfo 渠道原始信息
|
||||
type DistrictInfo struct {
|
||||
Code string `bson:"code"` //商区码
|
||||
Name string `bson:"name"` //账号
|
||||
Mobile string `bson:"mobile"` //手机号
|
||||
Parent string `bson:"parent"` //parent
|
||||
Password string `bson:"password"` //密码
|
||||
DiscType int `bson:"discType"` //商区类型/结算类型
|
||||
DividendRatio float64 `bson:"dividendRatio"` //分红比例 参与结算
|
||||
DisSettlement bool `bson:"disSettlement"` //禁止结算
|
||||
UserUnitCent float64 `bson:"userUnitCent"` //用户单价 单位:分
|
||||
NUDeductionRatio float64 `bson:"nuDeductionRatio"` //新增用户扣量比例
|
||||
NUDedLowerOutset int64 `bson:"nuDedLowerOutset"` //新增用户扣量起点
|
||||
NUDedAt time.Time `bson:"nuDedAt"` //新增用户扣量时间
|
||||
RechgDeductionRatio float64 `bson:"rechgDeductionRatio"` //充值扣量比例
|
||||
RechgDedLowerOutset int64 `bson:"rechgDedLowerOutset"` //充值扣量起点
|
||||
RechgDedAt time.Time `bson:"rechgDedAt"` //充值扣量时间
|
||||
ChildMax int `bson:"childMax"` //最大孩子数
|
||||
Disable bool `bson:"disable"` //禁用
|
||||
Lock bool `bson:"lock"` //禁止登陆
|
||||
DisTrans bool `bson:"disTrans"` //禁止交易
|
||||
DisAd bool `bson:"disAd"` //禁止广告
|
||||
DisMulDivi bool `bson:"disMulDivi"` //禁止多级分成(目前针对CPS)
|
||||
PayPassword string `bson:"payPassword"` //支付密码
|
||||
BalanceCent float64 `bson:"balance"` //余额 单位:分
|
||||
Remark string `bson:"remark"` //备注
|
||||
CreatedAt time.Time `bson:"createdAt"` //文档创建时间
|
||||
UpdatedAt time.Time `bson:"updatedAt"` //文档更新时间
|
||||
}
|
||||
|
||||
// DspDistrictCodeInfo 渠道码信息
|
||||
type DspDistrictCodeInfo struct {
|
||||
DiscCode string `bson:"discCode"` //商圈码
|
||||
PromSeq string `bson:"promSeq"` //推广序列
|
||||
Remark string `bson:"remark"` //备注
|
||||
CreatedAt time.Time `bson:"createdAt"`
|
||||
DeletedAt time.Time `bson:"deletedAt,omitempty"` //删除时间
|
||||
}
|
||||
|
||||
type BillLog struct {
|
||||
SumDate time.Time `bson:"sumDate"` //日期
|
||||
DiscType string `bson:"discType"` //商区类型
|
||||
DistrictCode string `bson:"districtCode"` //商圈码
|
||||
Name string `bson:"name"` //账号
|
||||
Cent float64 `bson:"cent"` //人民币分
|
||||
Desc string `bson:"desc"` //记录描述
|
||||
CreatedAt time.Time `bson:"createdAt"` //创建时间
|
||||
}
|
||||
|
||||
const CollDistrict = "district"
|
||||
const CollDistrictCode = "prom_seqe"
|
||||
|
||||
var dbDistrict *mongos.MongoTool
|
||||
var dbDistrictcode *mongos.MongoTool
|
||||
var dbDistrictLog *mongos.MongoTool
|
||||
|
||||
func DistrictInit() {
|
||||
dbDistrict = mongos.New(ManagerDsp, CollDistrict)
|
||||
dbDistrictcode = mongos.New(ManagerDsp, CollDistrictCode)
|
||||
}
|
||||
|
||||
// FindDspDistrictInfo 查询所有渠道
|
||||
func FindDspDistrictInfo(ctx context.Context) ([]DistrictInfo, error) {
|
||||
list := make([]DistrictInfo, 0)
|
||||
query := bson.M{}
|
||||
|
||||
if err := dbDistrict.Find(ctx, &list, query); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindDspDistrictInfo Find error", CollDistrict), log.E(err))
|
||||
return list, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// FindDspDistrictCodeInfo 查询渠道的渠道码
|
||||
func FindDspDistrictCodeInfo(ctx context.Context, discCode string) ([]DspDistrictCodeInfo, error) {
|
||||
list := make([]DspDistrictCodeInfo, 0)
|
||||
query := bson.M{"discCode": discCode}
|
||||
|
||||
if err := dbDistrictcode.Find(ctx, &list, query); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindDspDistrictInfo Find error", CollDistrict), log.E(err))
|
||||
return list, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"stat/models"
|
||||
)
|
||||
|
||||
var (
|
||||
ManagerDsp *mongos.Manager
|
||||
ManagerStat *mongos.Manager
|
||||
)
|
||||
|
||||
// InitMongoDB 初始化同步数据库
|
||||
func InitMongoDB() error {
|
||||
// DspDB := mongos.NewManager("mongodb://yinse:7P1pwdsMLds6QOB092Xq@172.104.42.200:47018/video?direct=game&maxPoolSize=200&connectTimeout=30&authSource=video")
|
||||
// if err := DspDB.Connect(); err != nil {
|
||||
// log.Error("mgoDB connect err", log.E(err))
|
||||
// return err
|
||||
// }
|
||||
// ManagerDsp = DspDB
|
||||
|
||||
// // 初始化表链接
|
||||
// UserInit()
|
||||
// RechargeInit()
|
||||
// WithdrawInit()
|
||||
|
||||
statDB := mongos.NewManager("mongodb://stat:ebCJuLfJQAGKVDecdFH0@172.104.42.200:47017,139.162.18.46:47017,139.162.35.214:47017/statcentre?maxPoolSize=200&connectTimeout=30&authSource=statcentre")
|
||||
if err := statDB.Connect(); err != nil {
|
||||
log.Error("mgoDB connect err", log.E(err))
|
||||
return err
|
||||
}
|
||||
mongos.MgoManager = statDB
|
||||
|
||||
// 初始化数据库索引
|
||||
models.InitIndex()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"stat/common/utils"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type DspRecharge struct {
|
||||
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` //流水id
|
||||
UID uint64 `json:"uid" bson:"uid"` //用户id
|
||||
DevType string `json:"devType" bson:"devType"` //设备系统类型 ios pc android
|
||||
Channel string `json:"channel" bson:"channel"` //渠道类型 鲨鱼 金鱼
|
||||
OID string `json:"oid" bson:"oid"` //支付平台订单号
|
||||
WithdrawType string `json:"WithdrawType" bson:"WithdrawType"` //充值类型
|
||||
Money int64 `json:"money" bson:"money"` //充值金额 订单金额 李秋山确认
|
||||
PayMoney int64 `json:"payMoney" bson:"payMoney"` //实际到账金额 用户实际支付金额 李秋山确认
|
||||
Status int `json:"status" bson:"status"` //1进行中 2付款失败 3付款成功 4已经退款
|
||||
SuccessAt time.Time `json:"successAt" bson:"successAt"` //回调成功时间
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //创建时间
|
||||
IsDirect bool `json:"isDirect" bson:"isDirect"` //true:是直推用户
|
||||
DistrictCode string `json:"districtCode" bson:"districtCode"` //商区码
|
||||
}
|
||||
|
||||
const CollRecharge = "recharge_order"
|
||||
|
||||
var dbRecharge *mongos.MongoTool
|
||||
|
||||
func RechargeInit() {
|
||||
dbRecharge = mongos.New(ManagerDsp, CollRecharge)
|
||||
}
|
||||
|
||||
// FindDspRecharge 查询用户
|
||||
func FindDspRecharge(ctx context.Context, skip int64, limit int64) ([]DspRecharge, error) {
|
||||
list := make([]DspRecharge, 0)
|
||||
|
||||
beginTimeStr := "2020-07-01T00:00:00-08:00"
|
||||
|
||||
beginTime := utils.StrTimeToTime(beginTimeStr)
|
||||
query := bson.M{"successAt": bson.M{"$gt": beginTime}}
|
||||
|
||||
sort := bson.D{{Key: "successAt", Value: 1}}
|
||||
opts := options.Find().SetSkip(skip).SetLimit(limit).SetSort(sort)
|
||||
|
||||
if err := dbRecharge.Find(ctx, &list, query, opts); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindDspRecharge Find error", CollDistrict), log.E(err))
|
||||
return list, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func FindDspRechargeCount(ctx context.Context) (count int64, err error) {
|
||||
|
||||
beginTimeStr := "2020-07-01T00:00:00-08:00"
|
||||
|
||||
beginTime := utils.StrTimeToTime(beginTimeStr)
|
||||
query := bson.M{"successAt": bson.M{"$gt": beginTime}}
|
||||
|
||||
count, err = dbRecharge.Count(ctx, query)
|
||||
if err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindDspRecharge Find error", CollDistrict), log.E(err))
|
||||
return count, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// FindDspDistrictRecharge
|
||||
func FindDspDistrictRecharge(ctx context.Context, district string) ([]DspRecharge, error) {
|
||||
list := make([]DspRecharge, 0)
|
||||
|
||||
beginTimeStr := "2020-10-01T00:00:00-08:00"
|
||||
|
||||
beginTime := utils.StrTimeToTime(beginTimeStr)
|
||||
query := bson.M{"successAt": bson.M{"$gt": beginTime}, "districtCode": district}
|
||||
|
||||
if err := dbRecharge.Find(ctx, &list, query); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindDspDistrictRecharge Find error", CollDistrict), log.E(err))
|
||||
return list, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
//
|
||||
@@ -0,0 +1,69 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type DspUser struct {
|
||||
UID uint64 `json:"uid" bson:"uid"` //用户id
|
||||
SysType string `json:"sysType" bson:"sysType"` //系统类型
|
||||
DevType string `json:"devType" bson:"devType"` //设备类型
|
||||
Mobile string `json:"mobile" bson:"mobile"` //手机号
|
||||
Name string `json:"name" bson:"name"` //名字
|
||||
DistrictCode string `json:"districtCode" bson:"districtCode"` //商区码
|
||||
PromCode string `json:"promotionCode" bson:"promotionCode"` //推广码
|
||||
IsDirect bool `json:"isDirect" bson:"isDirect"` //true:是直推用户
|
||||
CreatedAt time.Time `bson:"createdAt"` //文档创建时间
|
||||
}
|
||||
|
||||
const CollUser = "user"
|
||||
|
||||
var dbUser *mongos.MongoTool
|
||||
|
||||
func UserInit() {
|
||||
dbUser = mongos.New(ManagerDsp, CollUser)
|
||||
}
|
||||
|
||||
// FindDspUserInfo 查询用户
|
||||
func FindDspUserInfo(ctx context.Context, skip int64, limit int64) ([]DspUser, error) {
|
||||
list := make([]DspUser, 0)
|
||||
query := bson.M{}
|
||||
sort := bson.D{{Key: "_id", Value: 1}}
|
||||
opts := options.Find().SetSkip(skip).SetLimit(limit).SetSort(sort)
|
||||
|
||||
if err := dbUser.Find(ctx, &list, query, opts); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindDspUserInfo Find error", CollDistrict), log.E(err))
|
||||
return list, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func FindOneUserInfo(ctx context.Context, uid uint64) (user DspUser, err error) {
|
||||
query := bson.M{"uid": uid}
|
||||
|
||||
if err := dbUser.FindOne(ctx, &user, query); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindDspUserInfo Find error", CollDistrict), log.E(err))
|
||||
return user, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func FindManyUserInfo(ctx context.Context, uid []uint64) (user []DspUser, err error) {
|
||||
query := bson.M{"uid": bson.M{"$in": uid}}
|
||||
|
||||
if err := dbUser.Find(ctx, &user, query); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindDspUserInfo Find error", CollDistrict), log.E(err))
|
||||
return user, err
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"stat/common/utils"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type DspWithdraw struct {
|
||||
ID primitive.ObjectID `json:"id" bson:"_id,omitempty"` //流水id
|
||||
AppId int32 `json:"appId" bson:"appId"` // appID
|
||||
UID uint64 `json:"uid" bson:"uid"` //用户id
|
||||
Name string `json:"name" bson:"name"` //用户名
|
||||
Amount int64 `json:"amount" bson:"amount"` //蝴蝶币数量
|
||||
OID string `json:"oid" bson:"oid"` //第三方支付平台id
|
||||
Money int64 `json:"money" bson:"money" binding:"required"` //提现金额
|
||||
PayMoney int64 `json:"payMoney" bson:"payMoney"` //实际到账
|
||||
PayType string `json:"payType" bson:"payType" binding:"required"` //提现方式,alipay,bankcard
|
||||
ActName string `json:"actName" bson:"actName"` //交易账户持有人
|
||||
Act string `json:"act" bson:"act"` //交易账户
|
||||
UserIP string `json:"userIp" bson:"userIp"` //用户ip
|
||||
DeviceType string `json:"deviceType" bson:"deviceType"` //设备类型
|
||||
DevID string `json:"devID" bson:"devID"` //设备id
|
||||
Status int `json:"status" bson:"status"` //1未审核 2审核通过,转账中 3已拒绝 4未知错误 5提现成功 6提现失败
|
||||
StatusDesc string `json:"statusDesc" bson:"statusDesc"` //状态说明
|
||||
CheckedAt time.Time `json:"checkedAt" bson:"checkedAt"` //审核时间
|
||||
ProgressAt time.Time `json:"progressAt" bson:"progressAt"` //第三方下单成功时间
|
||||
SuccessAt time.Time `json:"successAt" bson:"successAt"` //回调成功时间
|
||||
UpdatedAt time.Time `json:"updatedAt" bson:"updatedAt"` //刷新时间
|
||||
CreatedAt time.Time `json:"createdAt" bson:"createdAt"` //提现申请时间
|
||||
ReceivedAt time.Time `json:"receivedAt" bson:"receivedAt"` //到账时间 李秋山确认 三方出款时间
|
||||
BlocDeduction bool `json:"blocDeduction" bson:"blocDeduction"` //集团扣量(特定渠道扣量)
|
||||
IsDirect bool `json:"isDirect" bson:"isDirect"` //true:是直推用户
|
||||
DistrictCode string `json:"districtCode" bson:"districtCode"` //渠道码
|
||||
PromCode string `json:"promCode,omitempty" bson:"promCode"` //用户推广序列
|
||||
}
|
||||
|
||||
const CollWithdraw = "withdraw_order"
|
||||
|
||||
var dbWithdraw *mongos.MongoTool
|
||||
|
||||
func WithdrawInit() {
|
||||
dbWithdraw = mongos.New(ManagerDsp, CollWithdraw)
|
||||
}
|
||||
|
||||
// FindDspWithdraw 查询用户
|
||||
func FindDspWithdraw(ctx context.Context, skip int64, limit int64) ([]DspWithdraw, error) {
|
||||
list := make([]DspWithdraw, 0)
|
||||
|
||||
beginTimeStr := "2020-07-01T00:00:00-08:00"
|
||||
|
||||
beginTime := utils.StrTimeToTime(beginTimeStr)
|
||||
query := bson.M{"successAt": bson.M{"$gt": beginTime}, "withdrawType": 1}
|
||||
|
||||
sort := bson.D{{Key: "successAt", Value: 1}}
|
||||
opts := options.Find().SetSkip(skip).SetLimit(limit).SetSort(sort)
|
||||
|
||||
if err := dbWithdraw.Find(ctx, &list, query, opts); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindDspWithdraw Find error", CollDistrict), log.E(err))
|
||||
return list, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"stat/models/advertiseMod"
|
||||
)
|
||||
|
||||
type InviteInfo struct {
|
||||
Count int64
|
||||
}
|
||||
|
||||
func UserStatInfo() error {
|
||||
ctx := context.Background()
|
||||
adsList, err := advertiseMod.FindAds(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//fmt.Println(len(adsList))
|
||||
for _, v := range adsList {
|
||||
links := make([]advertiseMod.LinkInfo, 0)
|
||||
links = append(links, advertiseMod.LinkInfo{
|
||||
Link: v.Link,
|
||||
Weight: 100,
|
||||
Foreign: false,
|
||||
})
|
||||
doc := advertiseMod.UpdateAds{
|
||||
Links: &links,
|
||||
}
|
||||
|
||||
err = advertiseMod.UpdateAdvertise(ctx, v.Id, doc)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// func UserStatInfo() error {
|
||||
// ctx := context.Background()
|
||||
// userList, err := registermod.TimeUsersStatInfoByTime(ctx, 1)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
// fmt.Println(len(userList))
|
||||
// userIds := make([]uint64, 0)
|
||||
// for _, v := range userList {
|
||||
// if v.AppId == 1 {
|
||||
// userIds = append(userIds, v.UserId)
|
||||
// }
|
||||
// }
|
||||
// dspuserList, _ := model.FindManyUserInfo(ctx, userIds)
|
||||
|
||||
// writeModels := make([]mongo.WriteModel, 0)
|
||||
// for _, v := range dspuserList {
|
||||
// model := mongo.NewUpdateOneModel()
|
||||
// filter := bson.M{"userId": v.UID, "appId": 1}
|
||||
// update := bson.M{"$set": bson.M{"promCode": v.PromCode}}
|
||||
// model.SetFilter(filter).SetUpdate(update)
|
||||
|
||||
// writeModels = append(writeModels, model)
|
||||
// fmt.Println(filter, update)
|
||||
// }
|
||||
// fmt.Println("update.............")
|
||||
// err = registermod.UpdateRegisterInfo(ctx, writeModels)
|
||||
// if err != nil {
|
||||
// log.Error("SyncUserInfo UpdateRegisterInfo", log.E(err))
|
||||
// return err
|
||||
// }
|
||||
|
||||
// return nil
|
||||
// }
|
||||
@@ -0,0 +1,791 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var sbr, ser, mbr, mer *regexp.Regexp
|
||||
var out *bufio.Writer
|
||||
var model string
|
||||
var log *zap.SugaredLogger
|
||||
|
||||
type table struct {
|
||||
tableName string
|
||||
// <字段名、bson名>
|
||||
filedInfo map[string]interface{}
|
||||
}
|
||||
|
||||
var rootPath string
|
||||
var dealPath string
|
||||
var tmpPath string
|
||||
|
||||
func init() {
|
||||
zl, _ := zap.NewDevelopment(zap.IncreaseLevel(zapcore.WarnLevel))
|
||||
log = zl.Sugar()
|
||||
|
||||
// rootPath = "/Volumes/work/prj" // 项目根目录
|
||||
currDir, _ := os.Getwd() // 获取当前目录
|
||||
rootPath = func() string {
|
||||
v := LookupProjectRootByGomod()
|
||||
if v != "" {
|
||||
return v
|
||||
}
|
||||
// 获取上四级目录
|
||||
// rootPath = strCurrDir+"/../../../../"
|
||||
return getParentDir(getParentDir(currDir))
|
||||
}()
|
||||
dealPath = "/pub/models" // 处理目录
|
||||
tmpPath = "/temp" // 临时目录
|
||||
}
|
||||
|
||||
func LookupProjectRootByGomod() string {
|
||||
currDir, _ := os.Getwd()
|
||||
var dir = currDir
|
||||
for {
|
||||
found, err := isProjectRoot(dir)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
if found {
|
||||
break
|
||||
}
|
||||
dir = filepath.Dir(dir)
|
||||
if dir == "/" {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
func isProjectRoot(dir string) (bool, error) {
|
||||
modFileName := filepath.Join(dir, "go.mod")
|
||||
_, err := os.Stat(modFileName)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
// 验证go.mod文件
|
||||
f, err := os.Open(modFileName)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(io.LimitReader(f, 20))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if bytes.Contains(data, []byte("module stat")) {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func getCurDir() string {
|
||||
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
|
||||
if err != nil {
|
||||
// log.Fatal(err)
|
||||
fmt.Sprint(err)
|
||||
}
|
||||
return strings.Replace(dir, "\\", "/", -1)
|
||||
}
|
||||
|
||||
func substr(s string, pos, length int) string {
|
||||
runes := []rune(s)
|
||||
l := pos + length
|
||||
if l > len(runes) {
|
||||
l = len(runes)
|
||||
}
|
||||
return string(runes[pos:l])
|
||||
}
|
||||
|
||||
func getParentDir(dir string) string {
|
||||
return substr(dir, 0, strings.LastIndex(dir, "/"))
|
||||
}
|
||||
|
||||
func shellCmd(cmdStr string) (string, error) {
|
||||
cmd := exec.Command("/bin/bash", "-c", cmdStr)
|
||||
var outb bytes.Buffer
|
||||
var errb bytes.Buffer
|
||||
cmd.Stdout = &outb
|
||||
cmd.Stderr = &errb
|
||||
ec := cmd.Run()
|
||||
log.Infof("command: %s", cmdStr)
|
||||
if outb.Len() > 0 {
|
||||
log.Debug("stdout: %s", outb.String())
|
||||
}
|
||||
if errb.Len() > 0 {
|
||||
log.Errorf("stderr: %s", errb.String())
|
||||
}
|
||||
|
||||
return outb.String(), ec
|
||||
}
|
||||
|
||||
func parseStruct(tbName string, br *bufio.Reader) map[string]interface{} {
|
||||
subStructName := regexp.MustCompile("(\\w+)\\s+struct\\s{$")
|
||||
// endFlag := regexp.MustCompile(`}`)
|
||||
endFlag := regexp.MustCompile(`}`)
|
||||
// <字段名、tag名>
|
||||
filedInfo := make(map[string]interface{})
|
||||
|
||||
for {
|
||||
line, _, ec := br.ReadLine()
|
||||
if nil != ec {
|
||||
return filedInfo
|
||||
}
|
||||
|
||||
if strings.HasPrefix(strings.TrimSpace(string(line)), "//") {
|
||||
continue
|
||||
}
|
||||
|
||||
if "" == string(line) {
|
||||
continue
|
||||
}
|
||||
|
||||
end := endFlag.FindStringSubmatch(string(line))
|
||||
if len(end) > 0 {
|
||||
log.Info("end ...")
|
||||
|
||||
return filedInfo
|
||||
}
|
||||
log.Infof(string(line))
|
||||
if subStruct := subStructName.FindStringSubmatch(string(line)); len(subStruct) > 0 {
|
||||
subFiledInfo := parseStruct(subStruct[1], br)
|
||||
filedInfo[subStruct[1]] = &table{
|
||||
tableName: subStruct[1],
|
||||
filedInfo: subFiledInfo,
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
flags := strings.Split(string(line), "bson")
|
||||
|
||||
if len(flags) > 1 {
|
||||
tag := regexp.MustCompile(":\"(\\w+)\"")
|
||||
dst := tag.FindStringSubmatch(flags[1])
|
||||
dstName := ""
|
||||
if len(dst) < 1 {
|
||||
// 带有omit的
|
||||
tagomt := regexp.MustCompile(":\"(\\w+),omitempty\"")
|
||||
dst = tagomt.FindStringSubmatch(flags[1])
|
||||
dstName = dst[1]
|
||||
} else {
|
||||
dstName = dst[1]
|
||||
}
|
||||
filedName := strings.Split(strings.TrimSpace(string(line)), " ")
|
||||
|
||||
log.Info("aaaaa, ", filedName[0], " -> ", dstName)
|
||||
|
||||
// structBuf += fmt.Sprintf("const T%s%s = \"%s\"\n", tbName, filedName[0], dstName)
|
||||
filedInfo[filedName[0]] = dstName
|
||||
|
||||
} else if strings.Contains(string(line), "\"inline\"") {
|
||||
// 内联结构体
|
||||
continue
|
||||
} else {
|
||||
log.Error("parse bson is failed, code = ", string(line))
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeStr(tab table, parentTab string) (string, string) {
|
||||
structsBuf := fmt.Sprintf("//%s\n", tab.tableName)
|
||||
if "" != parentTab {
|
||||
structsBuf += fmt.Sprintf("%s struct {\n", tab.tableName)
|
||||
} else {
|
||||
structsBuf += fmt.Sprintf("type Tag%s struct {\n", tab.tableName)
|
||||
}
|
||||
|
||||
initsBuf := fmt.Sprintf("\n")
|
||||
|
||||
var sortedNames []string
|
||||
for name, _ := range tab.filedInfo {
|
||||
sortedNames = append(sortedNames, name)
|
||||
}
|
||||
sort.Strings(sortedNames)
|
||||
|
||||
for _, filedName := range sortedNames {
|
||||
field := tab.filedInfo[filedName]
|
||||
switch field.(type) {
|
||||
case string:
|
||||
structsBuf += fmt.Sprintf("%s string\n", filedName)
|
||||
if "" != parentTab {
|
||||
initsBuf += fmt.Sprintf("Fn%s.%s.%s = \"%v\"\n", parentTab, tab.tableName, filedName, field)
|
||||
} else {
|
||||
initsBuf += fmt.Sprintf("Fn%s.%s = \"%v\"\n", tab.tableName, filedName, field)
|
||||
}
|
||||
case *table:
|
||||
subTab := field.(*table)
|
||||
var buf1, buf2 string
|
||||
if "" != parentTab {
|
||||
buf1, buf2 = makeStr(*subTab, parentTab+"."+tab.tableName)
|
||||
} else {
|
||||
buf1, buf2 = makeStr(*subTab, tab.tableName)
|
||||
}
|
||||
|
||||
structsBuf += buf1
|
||||
initsBuf += buf2
|
||||
}
|
||||
}
|
||||
structsBuf += fmt.Sprintf("}\n\n\n")
|
||||
initsBuf += fmt.Sprintf("\n")
|
||||
|
||||
return structsBuf, initsBuf
|
||||
}
|
||||
|
||||
func getAllModel(fileName string) []string {
|
||||
cmd := fmt.Sprintf(`cat %s | grep "^type " | grep "struct {$" | awk '{print $2}' | tr "\n" " "`, fileName)
|
||||
output, err := shellCmd(cmd)
|
||||
if nil != err {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
models := strings.Split(output, " ")
|
||||
return models[:len(models)-1]
|
||||
}
|
||||
|
||||
func parseOrm(fileName string) (resultFileBuf string) {
|
||||
models := getAllModel(fileName)
|
||||
log.Info(fileName, models)
|
||||
// 构建临时文件
|
||||
|
||||
return ""
|
||||
packageName, _ := shellCmd(fmt.Sprintf(`cat %s | grep ^package | awk '{print $2}'`, fileName))
|
||||
packageName = strings.TrimSpace(packageName)
|
||||
if "" == packageName {
|
||||
log.Errorf("can not parse package name, stop it")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var tables []table
|
||||
|
||||
defer func() {
|
||||
if len(tables) > 0 {
|
||||
resultFileBuf = fmt.Sprintf("package %s\n", packageName)
|
||||
structsBuf := ""
|
||||
initsBuf := "func init() {"
|
||||
|
||||
for _, v := range tables {
|
||||
buf1, buf2 := makeStr(v, "")
|
||||
structsBuf += buf1
|
||||
initsBuf += buf2
|
||||
}
|
||||
initsBuf += fmt.Sprintf("\n}\n")
|
||||
|
||||
resultFileBuf += structsBuf
|
||||
resultFileBuf += fmt.Sprintf("\n\n\n\n\n")
|
||||
|
||||
for _, v := range tables {
|
||||
resultFileBuf += fmt.Sprintf("var Fn%s Tag%s\n", v.tableName, v.tableName)
|
||||
}
|
||||
|
||||
resultFileBuf += initsBuf
|
||||
resultFileBuf += fmt.Sprintf("\n")
|
||||
}
|
||||
}()
|
||||
|
||||
// structsBuf := "package " + packageName + "\n"
|
||||
// fnsBuf := "func init() {\n"
|
||||
// initBuf := ""
|
||||
|
||||
tableName := regexp.MustCompile("^type\\s+(\\w+)\\s+struct\\s{$")
|
||||
// endFlag := regexp.MustCompile(`}`)
|
||||
file, _ := os.Open(fileName)
|
||||
br := bufio.NewReader(file)
|
||||
|
||||
// inStruct := false
|
||||
// tbName := ""
|
||||
for {
|
||||
line, _, ec := br.ReadLine()
|
||||
if nil != ec {
|
||||
return
|
||||
}
|
||||
|
||||
names := tableName.FindStringSubmatch(string(line))
|
||||
if len(names) > 1 {
|
||||
log.Info("begin -> ", names[1])
|
||||
// tbName = names[1]
|
||||
// structBuf := ("//" + names[1] + "\n")
|
||||
// structBuf += fmt.Sprintf("type Tag%s struct {\n", tbName)
|
||||
|
||||
// inStruct = true
|
||||
|
||||
filedInfo := parseStruct(names[1], br)
|
||||
|
||||
tables = append(tables, table{
|
||||
tableName: names[1],
|
||||
filedInfo: filedInfo,
|
||||
})
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func writeGoFile(packageName string, packgePath string, tableMetas []TableMeta, dstFile string) {
|
||||
// orms := `[]interface{}{orm.UserEx{}, orm.User{}}`
|
||||
// shellCmd(fmt.Sprintf("rm -f %s/src/%s/tag.go", os.Getenv("GOPATH"), packgePath))
|
||||
// orms := `[]interface{}`
|
||||
// for k, _ := range tableNames {
|
||||
// tableNames[k] = "orm." + tableNames[k] + "{}"
|
||||
// }
|
||||
var tbOrms []string
|
||||
var cmdParams []string
|
||||
for _, meta := range tableMetas {
|
||||
tbOrms = append(tbOrms, "orm."+meta.StructName+"{}")
|
||||
cmdParams = append(cmdParams, fmt.Sprintf("%v--%v", meta.StructName, meta.DbName))
|
||||
}
|
||||
// strCmdParam := strings.Join(cmdParams, "---")
|
||||
strCmdParam := func() string {
|
||||
data, _ := json.Marshal(tableMetas)
|
||||
return base64.StdEncoding.EncodeToString([]byte(data))
|
||||
}()
|
||||
|
||||
orms := "[]interface{}{" + strings.Join(tbOrms, ",") + "}"
|
||||
|
||||
buf := []byte(`package main
|
||||
|
||||
import (
|
||||
// orm "PACKAGE-PATH"
|
||||
orm "stat/temp/orm"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sort"
|
||||
"encoding/json"
|
||||
"encoding/base64"
|
||||
)
|
||||
|
||||
func getBson(ormName string, tag string) string {
|
||||
if tag == "" {
|
||||
panic(ormName + "miss bson tag")
|
||||
}
|
||||
|
||||
array := strings.Split(tag, ",")
|
||||
if len(array) <= 1 {
|
||||
return tag
|
||||
}
|
||||
|
||||
return strings.TrimSpace(array[0])
|
||||
}
|
||||
|
||||
type fieldStruct struct {
|
||||
parentTag string
|
||||
parentName string
|
||||
subFieldInfo map[string]string
|
||||
}
|
||||
|
||||
func parse(param interface{}, tab int) map[string]interface{} {
|
||||
fieldData := make(map[string]interface{})
|
||||
|
||||
t := reflect.TypeOf(param)
|
||||
v := reflect.ValueOf(param)
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
if v.Field(i).CanInterface() {
|
||||
|
||||
if v.Field(i).Type().Kind() == reflect.Struct {
|
||||
if "time.Time" == fmt.Sprintf("%v", t.Field(i).Type) {
|
||||
|
||||
fieldData[t.Field(i).Name] = getBson(t.Field(i).Name, t.Field(i).Tag.Get("bson"))
|
||||
continue
|
||||
}
|
||||
structField := v.Field(i).Type()
|
||||
//fmt.Printf("%v %v\n", t.Field(i).Name, t.Field(i).Tag)
|
||||
subFields := &fieldStruct{
|
||||
parentTag: getBson(t.Field(i).Name, t.Field(i).Tag.Get("bson")),
|
||||
parentName: t.Field(i).Name,
|
||||
subFieldInfo: make(map[string]string),
|
||||
}
|
||||
for j := 0; j < structField.NumField(); j++ {
|
||||
// fmt.Printf(" %s %s \n",
|
||||
// structField.Field(j).Name,
|
||||
// structField.Field(j).Tag)
|
||||
subFields.subFieldInfo[structField.Field(j).Name] = getBson(structField.Field(j).Name, structField.Field(j).Tag.Get("bson"))
|
||||
}
|
||||
fieldData[t.Field(i).Name] = subFields
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// fmt.Printf("%s %s \n",
|
||||
// t.Field(i).Name,
|
||||
// t.Field(i).Tag)
|
||||
|
||||
fieldData[t.Field(i).Name] = getBson(t.Field(i).Name, t.Field(i).Tag.Get("bson"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return fieldData
|
||||
}
|
||||
|
||||
type TableMeta struct {
|
||||
StructName string
|
||||
DbName string
|
||||
}
|
||||
|
||||
func main() {
|
||||
param := PARAM
|
||||
packageName := "PACKAGE-NAME"
|
||||
structsBuf := fmt.Sprintf("package %s \n", packageName)
|
||||
initsBuf := "func init() {\n"
|
||||
tabsBuf := "var FN struct {\n"
|
||||
|
||||
decodeMetas := func(arg string) []TableMeta {
|
||||
v, _ := base64.StdEncoding.DecodeString(strings.TrimSpace(arg))
|
||||
var tableMetas []TableMeta
|
||||
if err := json.Unmarshal([]byte(v), &tableMetas); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return tableMetas
|
||||
}
|
||||
|
||||
tableMetas := decodeMetas(os.Args[1])
|
||||
|
||||
for _, v := range param {
|
||||
fieldInfo := parse(v, 0)
|
||||
if len(fieldInfo) > 0 {
|
||||
keys := make([]string, 0, len(fieldInfo))
|
||||
hasID := false
|
||||
for fieldname, fieldTag := range fieldInfo {
|
||||
keys = append(keys,fieldname)
|
||||
switch fieldTag.(type) {
|
||||
case string:
|
||||
tempStr := fieldTag.(string)
|
||||
if tempStr == "_id" {
|
||||
hasID = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !hasID {
|
||||
panic("table miss _id")
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
temp := reflect.TypeOf(v)
|
||||
tabNames := strings.Split(fmt.Sprintf("%v", temp), ".")
|
||||
tabName := "Tag" + tabNames[1]
|
||||
tabsBuf += fmt.Sprintf("%s %s\n", tabNames[1], tabName)
|
||||
structsBuf += fmt.Sprintf("type %s struct {\n", tabName)
|
||||
for _, fieldname := range keys {
|
||||
fieldTag := fieldInfo[fieldname]
|
||||
switch fieldTag.(type) {
|
||||
case *fieldStruct:
|
||||
subStruct := fieldTag.(*fieldStruct)
|
||||
|
||||
// 嵌套字段也排序
|
||||
var sortedFieldNames []string
|
||||
for subFieldName := range subStruct.subFieldInfo {
|
||||
sortedFieldNames = append(sortedFieldNames, subFieldName)
|
||||
}
|
||||
sort.Strings(sortedFieldNames)
|
||||
|
||||
structsBuf += fmt.Sprintf("%s struct {\n", subStruct.parentName)
|
||||
for _, subFieldName := range sortedFieldNames {
|
||||
subFieldTag := subStruct.subFieldInfo[subFieldName]
|
||||
structsBuf += fmt.Sprintf("%s string\n", subFieldName)
|
||||
initsBuf += fmt.Sprintf("FN.%s.%s.%s = \"%s.%s\"\n", tabNames[1], subStruct.parentName, subFieldName, subStruct.parentTag, subFieldTag)
|
||||
}
|
||||
structsBuf += "}\n"
|
||||
|
||||
default:
|
||||
structsBuf += fmt.Sprintf("%s string\n", fieldname)
|
||||
initsBuf += fmt.Sprintf("FN.%s.%s = \"%s\"\n", tabNames[1], fieldname, fieldTag)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
structsBuf += "}\n"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//initsBuf += "}\n"
|
||||
tabsBuf += "}\n\n\n"
|
||||
//tabsBuf += "var FN XXX\n\n"
|
||||
|
||||
tabsBuf += "var TN struct {\n"
|
||||
//tabsBuf += "var FN XXX\n\n"
|
||||
|
||||
for _, meta := range tableMetas {
|
||||
tabsBuf += fmt.Sprintf("%s string\n", meta.StructName)
|
||||
initsBuf += fmt.Sprintf("TN.%v = \"%v\"\n", meta.StructName, meta.DbName)
|
||||
}
|
||||
|
||||
tabsBuf += "}\n"
|
||||
initsBuf += "}\n"
|
||||
|
||||
totalBuf := structsBuf + tabsBuf + initsBuf
|
||||
|
||||
fmt.Println(totalBuf)
|
||||
|
||||
err3 := ioutil.WriteFile(fmt.Sprintf("%s/%s/tag.go", "PACKAGE-ROOTPATH", "PACKAGE-PATH"), []byte(totalBuf), 0777)
|
||||
// err3 := ioutil.WriteFile(fmt.Sprintf("%s/%s/tag_1.go", "PACKAGE-ROOTPATH", "PACKAGE-PATH"), []byte(totalBuf), 0777)
|
||||
// err3 := ioutil.WriteFile(fmt.Sprintf("%s/src/%s/tag.go", os.Getenv("GOPATH"), "PACKAGE-PATH"), []byte(totalBuf), 0777)
|
||||
|
||||
fmt.Println("write file, err = ", err3)
|
||||
}`)
|
||||
|
||||
ioutil.WriteFile(dstFile, buf, 0777)
|
||||
// shellCmd(fmt.Sprintf(`echo "%s" > %s`, string(buf), dstFile))
|
||||
cmd := fmt.Sprintf(`sed -i '' 's#PACKAGE-PATH#%s#g' %s`, packgePath, dstFile)
|
||||
shellCmd(cmd)
|
||||
|
||||
// fmt.Println(cmd)
|
||||
// output, err := shellCmd(cmd)
|
||||
// fmt.Println(err, output)
|
||||
|
||||
cmd = fmt.Sprintf(`sed -i '' 's#PACKAGE-ROOTPATH#%s#g' %s`, rootPath, dstFile)
|
||||
shellCmd(cmd)
|
||||
|
||||
cmd = fmt.Sprintf(`sed -i '' 's/PACKAGE-NAME/%s/g' %s`, packageName, dstFile)
|
||||
shellCmd(cmd)
|
||||
|
||||
cmd = fmt.Sprintf(`sed -i '' 's/PARAM/%s/g' %s`, orms, dstFile)
|
||||
shellCmd(cmd)
|
||||
|
||||
cmd = "go run " + dstFile + " " + strCmdParam
|
||||
shellCmd(cmd)
|
||||
|
||||
cmd = fmt.Sprintf(`go fmt %s`, rootPath+"/"+packgePath+"/tag.go")
|
||||
shellCmd(cmd)
|
||||
|
||||
}
|
||||
|
||||
type TableMeta struct {
|
||||
StructName string
|
||||
DbName string
|
||||
}
|
||||
|
||||
// 返回值:<结构体名、表名>
|
||||
func getOrmName(servicePath string) []TableMeta {
|
||||
tableMetas := make([]TableMeta, 0)
|
||||
tableName := regexp.MustCompile("^type\\s+(\\w+)\\s+struct\\s{$")
|
||||
files, _, _ := GetFilesAndDirs(servicePath)
|
||||
for _, file := range files {
|
||||
if "tag.go" != file {
|
||||
fileBuf, _ := os.Open(file)
|
||||
br := bufio.NewReader(fileBuf)
|
||||
|
||||
// inStruct := false
|
||||
tbName := ""
|
||||
// hasFlag := false
|
||||
for {
|
||||
line, _, ec := br.ReadLine()
|
||||
if nil != ec {
|
||||
break
|
||||
}
|
||||
|
||||
if strings.HasPrefix(string(line), "// @table:") {
|
||||
temp := strings.Split(string(line), ":")
|
||||
tbName = strings.TrimSpace(temp[1])
|
||||
if "" == tbName {
|
||||
panic("tb name is empty, error table description")
|
||||
}
|
||||
|
||||
// hasFlag = true
|
||||
continue
|
||||
}
|
||||
|
||||
if "" != tbName {
|
||||
if names := tableName.FindStringSubmatch(string(line)); len(names) > 0 {
|
||||
log.Infof("有效表结构: (%v -> %v)\n", names[1], tbName)
|
||||
// tabs = append(tabs, names[1])
|
||||
// tabs[names[1]] = tbName
|
||||
tableMetas = append(tableMetas, TableMeta{
|
||||
StructName: names[1],
|
||||
DbName: tbName,
|
||||
})
|
||||
}
|
||||
}
|
||||
// hasFlag = false
|
||||
tbName = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tableMetas
|
||||
}
|
||||
|
||||
func genTagImpl(servicePath string) {
|
||||
// path := servicePath
|
||||
// files, err := ioutil.ReadDir(path)
|
||||
// if err != nil {
|
||||
// fmt.Println("read dir faild:", err.Error())
|
||||
// return
|
||||
// }
|
||||
|
||||
// fileBuf := "\n\n\n"
|
||||
// for _, file := range files {
|
||||
// if "tag.go" != file.Name() && strings.HasSuffix(file.Name(), ".go") {
|
||||
// fileBuf += parseOrm(path + "/" + file.Name())
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// if len(fileBuf) > 100 {
|
||||
// shellCmd(fmt.Sprintf(`echo '%s' > %s`, fileBuf, path+"/tag.go"))
|
||||
// shellCmd("go fmt " + path + "/tag.go")
|
||||
// }
|
||||
|
||||
cmd := fmt.Sprintf(`ls -l %s | grep type.go | grep -v "^d"| grep -v "tag.go" | tail -n 1 | awk '{print $NF}'`, servicePath)
|
||||
output, err := shellCmd(cmd)
|
||||
if err != nil {
|
||||
panic("has error, " + cmd)
|
||||
}
|
||||
|
||||
output = strings.TrimSpace(output)
|
||||
cmd = fmt.Sprintf(`cat %s/%s | grep "^package " | awk '{print $2}'`, servicePath, output)
|
||||
packageName, err2 := shellCmd(cmd)
|
||||
if err2 != nil {
|
||||
panic("has error, " + cmd)
|
||||
}
|
||||
packageName = strings.TrimSpace(packageName)
|
||||
|
||||
// gopath := os.Getenv("GOPATH")
|
||||
// packagePath := strings.TrimLeft(servicePath, gopath+"/")
|
||||
packagePath := strings.TrimPrefix(servicePath, rootPath+"/")
|
||||
|
||||
log.Infof("处理%v包...", packageName)
|
||||
tableMetas := getOrmName(rootPath + "/" + packagePath)
|
||||
if len(tableMetas) <= 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// shellCmd("mkdir -p $GOPATH/src/plus/server/temp")
|
||||
// shellCmd("rm -rf $GOPATH/src/plus/server/temp")
|
||||
shellCmd(fmt.Sprintf("rm -rf %s%s", rootPath, tmpPath))
|
||||
|
||||
// shellCmd("mkdir -p $GOPATH/src/plus/server/temp/orm")
|
||||
// strTest := fmt.Sprintf("------------- mkdir -p %s%s/orm", rootPath, tmpPath)
|
||||
// fmt.Println(strTest)
|
||||
shellCmd(fmt.Sprintf("mkdir -p %s%s/orm", rootPath, tmpPath))
|
||||
// shellCmd("mkdir -p "+rootPath+tmpPath+"/orm")
|
||||
// shellCmd("cp $GOPATH/src/" + packagePath + "/*_define.go $GOPATH/src/plus/server/temp/orm/")
|
||||
shellCmd("cp " + rootPath + "/" + packagePath + "/type.go " + rootPath + tmpPath + "/orm/")
|
||||
|
||||
// writeGoFile(packageName, packagePath, tabs, os.Getenv("GOPATH")+"/src/plus/server/temp/main.go")
|
||||
writeGoFile(packageName, packagePath, tableMetas, fmt.Sprintf("%s%s/main.go", rootPath, tmpPath))
|
||||
// output, err = shellCmd(``)
|
||||
|
||||
// _, err = shellCmd(`cat `)
|
||||
// writeGoFile(packageName, packagePath)
|
||||
}
|
||||
|
||||
// 获取指定目录下的所有文件和目录
|
||||
func GetFilesAndDirs(dirPth string) (files []string, dirs []string, err error) {
|
||||
dir, err := ioutil.ReadDir(dirPth)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
PthSep := string(os.PathSeparator)
|
||||
// suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写
|
||||
dirs = append(dirs, dirPth)
|
||||
for _, fi := range dir {
|
||||
if fi.IsDir() { // 目录, 递归遍历
|
||||
dirs = append(dirs, dirPth+PthSep+fi.Name())
|
||||
GetFilesAndDirs(dirPth + PthSep + fi.Name())
|
||||
} else {
|
||||
// 过滤指定格式
|
||||
ok := strings.HasSuffix(fi.Name(), ".go")
|
||||
if ok {
|
||||
files = append(files, dirPth+PthSep+fi.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return files, dirs, nil
|
||||
}
|
||||
|
||||
// 获取指定目录下的所有文件,包含子目录下的文件
|
||||
func GetAllFiles(dirPth string) (files []string, err error) {
|
||||
var dirs []string
|
||||
dir, err := ioutil.ReadDir(dirPth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
PthSep := string(os.PathSeparator)
|
||||
// suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写
|
||||
|
||||
for _, fi := range dir {
|
||||
if fi.IsDir() { // 目录, 递归遍历
|
||||
dirs = append(dirs, dirPth+PthSep+fi.Name())
|
||||
GetAllFiles(dirPth + PthSep + fi.Name())
|
||||
} else {
|
||||
// 过滤指定格式
|
||||
ok := strings.HasSuffix(fi.Name(), ".go")
|
||||
if ok {
|
||||
files = append(files, dirPth+PthSep+fi.Name())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 读取子目录下文件
|
||||
for _, table := range dirs {
|
||||
temp, _ := GetAllFiles(table)
|
||||
for _, temp1 := range temp {
|
||||
files = append(files, temp1)
|
||||
}
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func genTag(path string) {
|
||||
|
||||
_, dirs, _ := GetFilesAndDirs(path)
|
||||
for _, dir := range dirs {
|
||||
subFiles, _, _ := GetFilesAndDirs(dir)
|
||||
if len(subFiles) > 0 {
|
||||
genTagImpl(dir)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// func genTag1(path string) {
|
||||
// genTagImpl(path)
|
||||
// }
|
||||
|
||||
func main() {
|
||||
path := ""
|
||||
if "" == path {
|
||||
path = rootPath + dealPath
|
||||
}
|
||||
|
||||
flag.StringVar(&model, "m", "", "指定要生成的model,不指定则生成所有model")
|
||||
flag.Parse()
|
||||
|
||||
if model != "" {
|
||||
path = filepath.Join(path, model)
|
||||
}
|
||||
|
||||
genTagImpl("/Users/mac/code/stat_center/models/channelmod")
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package pubtest
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"stat/common/config"
|
||||
"stat/common/genId"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"stat/common/redis"
|
||||
"stat/models"
|
||||
"stat/service/cacheSer"
|
||||
"stat/statg"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestInit(workPath string) error {
|
||||
// 设置时区
|
||||
time.Local, _ = time.LoadLocation("Asia/Shanghai")
|
||||
|
||||
// 更换工作目录
|
||||
pwd, _ := os.Getwd()
|
||||
fmt.Println("开始工作目录", pwd)
|
||||
if err := os.Chdir(workPath); err != nil {
|
||||
return err
|
||||
}
|
||||
// 初始化配置文件
|
||||
if err := initConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
// 恢复工作目录
|
||||
if err := os.Chdir(pwd); err != nil {
|
||||
return err
|
||||
}
|
||||
// 初始化数据库
|
||||
if err := initMongoDB(); err != nil {
|
||||
return err
|
||||
}
|
||||
// 初始化redis
|
||||
if err := initRedis(); err != nil {
|
||||
return err
|
||||
}
|
||||
// 初始化缓存
|
||||
cacheSer.Init()
|
||||
// 自增id
|
||||
genId.Start()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func initConfig() error {
|
||||
err := config.LoadJSON("conf/server.json", &statg.Conf)
|
||||
if err != nil {
|
||||
log.Fatal("加载本地配置失败", log.E(err))
|
||||
return err
|
||||
}
|
||||
// set default value
|
||||
if statg.Conf.Limit.Ip.Capacity <= 0 {
|
||||
statg.Conf.Limit.Ip.Capacity = 300
|
||||
}
|
||||
if statg.Conf.Limit.Ip.Rate <= 0 {
|
||||
statg.Conf.Limit.Ip.Rate = 5
|
||||
}
|
||||
statg.Tgbotsend = statg.Conf.TgbotSend
|
||||
return nil
|
||||
}
|
||||
|
||||
func initMongoDB() error {
|
||||
mgoDB := mongos.NewManager(statg.Conf.Mongo.Url)
|
||||
if err := mgoDB.Connect(); err != nil {
|
||||
log.Error("mgoDB connect err", log.E(err))
|
||||
return err
|
||||
}
|
||||
|
||||
mongos.MgoManager = mgoDB
|
||||
|
||||
// 初始化数据库索引
|
||||
models.InitIndex()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func initRedis() error {
|
||||
rds, err := redis.NewManagerWithUrl(statg.Conf.Redis.Url, nil)
|
||||
if err != nil {
|
||||
log.Error("rds init err", log.E(err))
|
||||
return err
|
||||
}
|
||||
|
||||
redis.StatRds = rds
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"stat/common/log"
|
||||
"stat/tool/sqSync/model"
|
||||
|
||||
"stat/tool/sqSync/service"
|
||||
)
|
||||
|
||||
func initMongoDB() error {
|
||||
|
||||
if err := model.InitMongoDB(); err != nil {
|
||||
log.Error("InitMongoDB err", log.E(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
initMongoDB()
|
||||
// _ = service.SyncDistrictInfo()
|
||||
_ = service.SyncUserInfo()
|
||||
// _ = service.SyncAdsInfo()
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"time"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
// DistrictInfo 渠道原始信息
|
||||
type DistrictInfo struct {
|
||||
Code string `bson:"code"` //商区码
|
||||
Name string `bson:"name"` //账号
|
||||
Mobile string `bson:"mobile"` //手机号
|
||||
Parent string `bson:"parent"` //parent
|
||||
Password string `bson:"password"` //密码
|
||||
DiscType int `bson:"discType"` //商区类型/结算类型
|
||||
DividendRatio float64 `bson:"dividendRatio"` //分红比例 参与结算
|
||||
DisSettlement bool `bson:"disSettlement"` //禁止结算
|
||||
UserUnitCent float64 `bson:"userUnitCent"` //用户单价 单位:分
|
||||
NUDeductionRatio float64 `bson:"nuDeductionRatio"` //新增用户扣量比例
|
||||
NUDedLowerOutset int64 `bson:"nuDedLowerOutset"` //新增用户扣量起点
|
||||
NUDedAt time.Time `bson:"nuDedAt"` //新增用户扣量时间
|
||||
RechgDeductionRatio float64 `bson:"rechgDeductionRatio"` //充值扣量比例
|
||||
RechgDedLowerOutset int64 `bson:"rechgDedLowerOutset"` //充值扣量起点
|
||||
RechgDedAt time.Time `bson:"rechgDedAt"` //充值扣量时间
|
||||
ChildMax int `bson:"childMax"` //最大孩子数
|
||||
Disable bool `bson:"disable"` //禁用
|
||||
Lock bool `bson:"lock"` //禁止登陆
|
||||
DisTrans bool `bson:"disTrans"` //禁止交易
|
||||
DisAd bool `bson:"disAd"` //禁止广告
|
||||
DisMulDivi bool `bson:"disMulDivi"` //禁止多级分成(目前针对CPS)
|
||||
PayPassword string `bson:"payPassword"` //支付密码
|
||||
BalanceCent decimal.Decimal `bson:"balance"` //余额 单位:分
|
||||
Remark string `bson:"remark"` //备注
|
||||
CreatedAt time.Time `bson:"createdAt"` //文档创建时间
|
||||
UpdatedAt time.Time `bson:"updatedAt"` //文档更新时间
|
||||
}
|
||||
|
||||
// YhDistrictCodeInfo 渠道码信息
|
||||
type YhDistrictCodeInfo struct {
|
||||
DiscCode string `bson:"discCode"` //商圈码
|
||||
PromSeq string `bson:"promSeq"` //推广序列
|
||||
Remark string `bson:"remark"` //备注
|
||||
PromCode string `bson:"promCode"` //备注
|
||||
CreatedAt time.Time `bson:"createdAt"`
|
||||
DeletedAt time.Time `bson:"deletedAt,omitempty"` //删除时间
|
||||
}
|
||||
|
||||
const CollDistrict = "district"
|
||||
const CollDistrictCode = "disc_prom_seqe"
|
||||
|
||||
var dbDistrict *mongos.MongoTool
|
||||
var dbDistrictcode *mongos.MongoTool
|
||||
|
||||
func DistrictInit() {
|
||||
dbDistrict = mongos.New(ManagerYh, CollDistrict)
|
||||
dbDistrictcode = mongos.New(ManagerYh, CollDistrictCode)
|
||||
}
|
||||
|
||||
// FindYhDistrictInfo 查询所有渠道
|
||||
func FindSQDistrictInfo(ctx context.Context) ([]DistrictInfo, error) {
|
||||
list := make([]DistrictInfo, 0)
|
||||
query := bson.M{}
|
||||
|
||||
if err := dbDistrict.Find(ctx, &list, query); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindYhDistrictInfo Find error", CollDistrict), log.E(err))
|
||||
return list, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
|
||||
// FindSQDistrictCodeInfo 查询渠道的渠道码
|
||||
func FindSQDistrictCodeInfo(ctx context.Context, discCode string) ([]YhDistrictCodeInfo, error) {
|
||||
list := make([]YhDistrictCodeInfo, 0)
|
||||
query := bson.M{"discCode": discCode}
|
||||
|
||||
if err := dbDistrictcode.Find(ctx, &list, query); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindYhDistrictInfo Find error", CollDistrict), log.E(err))
|
||||
return list, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"stat/models"
|
||||
)
|
||||
|
||||
var (
|
||||
ManagerYh *mongos.Manager
|
||||
ManagerStat *mongos.Manager
|
||||
)
|
||||
|
||||
// InitMongoDB 初始化同步数据库
|
||||
func InitMongoDB() error {
|
||||
yhDB := mongos.NewManager("mongodb://read:6zwcDUpPy7dMkLTeWwHX@172.104.42.200:47017,139.162.18.46:47017,139.162.35.214:47017/sz?direct=game&maxPoolSize=200&connectTimeout=30&authSource=admin")
|
||||
if err := yhDB.Connect(); err != nil {
|
||||
log.Error("mgoDB connect err", log.E(err))
|
||||
return err
|
||||
}
|
||||
ManagerYh = yhDB
|
||||
|
||||
// 初始化表链接
|
||||
DistrictInit()
|
||||
UserInit()
|
||||
|
||||
statDB := mongos.NewManager("mongodb://bill:E4OSVEd6zuWibxJo@118.107.44.79:47017/statcentre?direct=game&maxPoolSize=200&connectTimeout=30&authSource=statcentre")
|
||||
if err := statDB.Connect(); err != nil {
|
||||
log.Error("mgoDB connect err", log.E(err))
|
||||
return err
|
||||
}
|
||||
mongos.MgoManager = statDB
|
||||
fmt.Println(statDB)
|
||||
// 初始化数据库索引
|
||||
models.InitIndex()
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type YhUser struct {
|
||||
UID uint64 `json:"id" bson:"id"` //用户id
|
||||
SysType string `json:"sysType" bson:"sysType"` //系统类型
|
||||
DevType string `json:"deviceType" bson:"deviceType"` //设备类型
|
||||
Mobile string `json:"mobile" bson:"mobile"` //手机号
|
||||
Name string `json:"nickName" bson:"nickName"` //名字
|
||||
DistrictCode string `json:"agentInviteCode" bson:"agentInviteCode"` //商区码
|
||||
PromSeqe string `json:"promSeqe" bson:"promSeqe"` //推广序列
|
||||
PromCode string `json:"inviteCode" bson:"inviteCode"` //邀请码
|
||||
IsDirect bool `json:"isDirect" bson:"isDirect"` //true:是直推用户
|
||||
CreatedAt time.Time `bson:"createdAt"` //文档创建时间
|
||||
}
|
||||
|
||||
const CollUser = "server_user"
|
||||
|
||||
var dbUser *mongos.MongoTool
|
||||
|
||||
func UserInit() {
|
||||
dbUser = mongos.New(ManagerYh, CollUser)
|
||||
}
|
||||
|
||||
// FindSQUserInfo 查询用户
|
||||
func FindSQUserInfo(ctx context.Context, skip int64, limit int64) ([]YhUser, error) {
|
||||
list := make([]YhUser, 0)
|
||||
query := bson.M{}
|
||||
sort := bson.D{{Key: "_id", Value: 1}}
|
||||
opts := options.Find().SetSkip(skip).SetLimit(limit).SetSort(sort).SetProjection(bson.M{"id": 1, "sysType": 1, "deviceType": 1, "mobile": 1, "nickName": 1, "agentInviteCode": 1, "inviteCode": 1, "isDirect": 1, "createdAt": 1})
|
||||
|
||||
if err := dbUser.Find(ctx, &list, query, opts); err != nil {
|
||||
log.Error(fmt.Sprintf("model %s FindYhUserInfo Find error", CollDistrict), log.E(err))
|
||||
return list, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"stat/common/log"
|
||||
"stat/models/registermod"
|
||||
"stat/tool/sqSync/model"
|
||||
)
|
||||
|
||||
func SyncUserInfo() error {
|
||||
skip := int64(0)
|
||||
limit := int64(10000)
|
||||
ctx := context.Background()
|
||||
//fmt.Println("before delete:", skip)
|
||||
for {
|
||||
//fmt.Println(skip)
|
||||
userlist, err := model.FindSQUserInfo(ctx, skip, limit)
|
||||
if err != nil {
|
||||
log.Error("SyncUserInfo FindSQUserInfo", log.E(err))
|
||||
return err
|
||||
}
|
||||
// 转换
|
||||
//fmt.Println(len(userlist))
|
||||
|
||||
docs := make([]*registermod.RegisterMod, 0)
|
||||
for _, userInfo := range userlist {
|
||||
doc := registermod.RegisterMod{
|
||||
UserId: userInfo.UID,
|
||||
AppId: 2,
|
||||
SysType: userInfo.SysType,
|
||||
DevType: userInfo.DevType,
|
||||
Mobile: userInfo.Mobile,
|
||||
Name: userInfo.Name,
|
||||
IsDirect: userInfo.IsDirect,
|
||||
DistrictCode: userInfo.DistrictCode,
|
||||
RegisterTime: userInfo.CreatedAt,
|
||||
IsDeduction: false,
|
||||
PromCode: userInfo.PromCode,
|
||||
}
|
||||
docs = append(docs, &doc)
|
||||
}
|
||||
|
||||
if err = registermod.AddManyRegisterCode(ctx, &docs); err != nil {
|
||||
log.Error("SyncUserInfo AddManyRegisterCode", log.E(err))
|
||||
return err
|
||||
}
|
||||
|
||||
// 插入数据库
|
||||
skip = skip + int64(len(userlist))
|
||||
//fmt.Println(skip)
|
||||
if int64(len(userlist)) < limit {
|
||||
log.Info("SyncUserInfo total:", log.Any("total", skip))
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
滑动窗口告诉发送端 接收端还有多少缓冲去可以接受数据, 于是发送端可以根据这个接收端的处理能力来发送数据,而不会导致接收端处理不过来
|
||||
以此控制发送数据的速率,从而达到流量控制,窗口大小是一个16bit字段,大小65536 socket的接收缓冲区大小
|
||||
|
||||
CLose sync =1 seq=x
|
||||
syc-send sync=1 ACK=1 seq=y ack=x=1 listen
|
||||
EStablisend ACK=1 seq=x+1 ack=y+1 SYNC-Recv
|
||||
|
||||
|
||||
Fin——wait FIN =1 seq
|
||||
fin_wait2 ACk=1 seq=v ack=u+1
|
||||
FIN=1,acl
|
||||
|
||||
半关闭状态, 客户端没有数据发送来 closewait 半关闭状态
|
||||
|
||||
Timewait 和closewait的区别:
|
||||
timewait 指主动发起关闭连接方 在收到对端 fin +ack后进入等待关闭,施放
|
||||
确保客户端发送的最后一个ACK报文能够到达服务器,因为ACK可能丢失, 服务器可能认为没收到,启动超时从传机制,导致服务器处理close_wait状态,新的连接不会出现旧连接报文
|
||||
|
||||
closewait 被动关闭的机器接收到对方请求关闭的fin豹纹,在第一次ACK应答后,进入close——wait状态, 同志应用层发送剩余数据,关闭相关资源
|
||||
我们一般在/etc/sysctl.conf文件中来修改默认值
|
||||
|
||||
滑动窗口
|
||||
动态改变窗口大小来调节两台主机间数据传输,tcp/IP支持全双工的数据传输,因此TCP有两个滑动串口, 一个用于接收, 一个用于发送
|
||||
|
||||
TCP的确认机制,滑动串口是TCP使用的一种流量控制方法,该协议允许发送在同志并等待确认前可以连续发送多个分组,犹豫发送方不必每发送一个分组就停止袭来等待确认,因此该协议
|
||||
可以加速数据船
|
||||
流量控制,端到端,接收端额应用层处理速度决定
|
||||
|
||||
|
||||
分布式一致性
|
||||
对于一个分布式系统而言,分区容错性是一个最基本的要求,因此既然是一个分布式系统,那么分布式系统中的组件必然需要被部署到不同的节点
|
||||
分区容错性也就成为一个分布式系统必然需要面对和解决的问题,因此系统架构师往往把精力花在如何根据业务特点在C一致性和A可用性之前寻求平衡
|
||||
base理论
|
||||
基本可用 出现不可预知状态时,允许
|
||||
软状态,允许数据存在中间状态,并认为该状态不会影响系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步的过程存在延时。
|
||||
最终一致性
|
||||
最终一致性 强调的是所有的数据副本,在经过一段时间的同步之后,最终都能够达到一个一直的状态,因此最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的
|
||||
强一致性。
|
||||
大型高可用可扩展的分布式系统和传统ACID特性相反, 牺牲强一致性来活动可用性,
|
||||
A 原子性 一致性 隔离性能 持久性
|
||||
|
||||
etcd就是使用raft算法来保持数据一致性的 与raft类似的还有POXOS算法和 ZAB协议等
|
||||
|
||||
etcd和console
|
||||
|
||||
leader 和 follower
|
||||
选举超时时间 一定周期/时间 150ms-300ms 之间的随机数 心跳<选举周期
|
||||
|
||||
|
||||
选举周期
|
||||
周期数
|
||||
|
||||
|
||||
面对对象编程:
|
||||
|
||||
|
||||
封装
|
||||
public、pretected、private
|
||||
|
||||
|
||||
继承
|
||||
|
||||
|
||||
|
||||
|
||||
多态
|
||||
|
||||
nginx 是以even处理模型为基础摩卡,它为了支持跨平台,抽象出了event模块,一部IO,主要是epoll
|
||||
event模块的主要功能就是监听,监听accept后建立的连接,对读写事件进行添加删除,事件处理模型和nginx的非阻塞IO模型结合在一起使用,当IO可读可写的时候,相应的事件就会被唤醒
|
||||
此时就会处理事件的回掉函数
|
||||
|
||||
|
||||
|
||||
面试:
|
||||
拓扑:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,25 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"stat/common/log"
|
||||
"stat/tool/yc/model"
|
||||
"stat/tool/yc/service"
|
||||
"time"
|
||||
)
|
||||
|
||||
func initMongoDB() error {
|
||||
|
||||
if err := model.InitMongoDB(); err != nil {
|
||||
log.Error("InitMongoDB err", log.E(err))
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
initMongoDB()
|
||||
time.Local, _ = time.LoadLocation("Asia/Shanghai")
|
||||
_ = service.SyncUserInfo()
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"stat/common/log"
|
||||
"stat/common/mongos"
|
||||
"stat/models"
|
||||
)
|
||||
|
||||
// InitMongoDB 初始化同步数据库
|
||||
func InitMongoDB() error {
|
||||
|
||||
statDB := mongos.NewManager("mongodb://stat:7u9CUAEE1Nv2tSvz@192.53.118.36:47017,192.53.173.209:47017,139.162.65.62:47017,172.105.237.106:47017,172.105.189.212:47017/stat?replicaSet=MDstat&maxPoolSize=200&connectTimeout=30&authSource=stat")
|
||||
if err := statDB.Connect(); err != nil {
|
||||
log.Error("mgoDB connect err", log.E(err))
|
||||
return err
|
||||
}
|
||||
mongos.MgoManager = statDB
|
||||
|
||||
// 初始化数据库索引
|
||||
models.InitIndex()
|
||||
fmt.Println("init")
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"stat/common/log"
|
||||
"stat/common/utils"
|
||||
"stat/models/syncvip"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
func SyncUserInfo() error {
|
||||
ctx := context.Background()
|
||||
|
||||
end := utils.BeginOfToday()
|
||||
start := end.AddDate(0, 0, -1)
|
||||
|
||||
registerMap := make(map[time.Time]int64)
|
||||
|
||||
filter := bson.M{
|
||||
syncvip.FN.SyncVip.AppId: 888,
|
||||
syncvip.FN.SyncVip.SuccessAt: bson.M{"$gte": start, "$lt": end},
|
||||
}
|
||||
|
||||
VipList, err := syncvip.FindManySyncVip(ctx, filter)
|
||||
if err != nil {
|
||||
log.Error("ChannelChannelStatMethod FindManyVisitInfo ", log.E(err))
|
||||
return err
|
||||
}
|
||||
//fmt.Println(len(VipList))
|
||||
|
||||
for _, orderinfo := range VipList {
|
||||
registerTime := utils.BeginWithTime(orderinfo.RegisterTime)
|
||||
if registerTime.Before(start.AddDate(0, 0, -20)) {
|
||||
continue
|
||||
}
|
||||
if money, ok := registerMap[registerTime]; ok {
|
||||
registerMap[registerTime] = money + orderinfo.Money
|
||||
} else {
|
||||
registerMap[registerTime] = orderinfo.Money
|
||||
}
|
||||
}
|
||||
|
||||
//for key, value := range registerMap {
|
||||
// fmt.Println(key, "充值金额:", fmt.Sprintf("%02f", float64(value)/100))
|
||||
//}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// func SyncUserInfo() error {
|
||||
// ctx := context.Background()
|
||||
|
||||
// end := utils.BeginOfToday().AddDate(0, 0, -15)
|
||||
// start := end.AddDate(0, 0, -1)
|
||||
|
||||
// registerMap := make(map[time.Time]int64)
|
||||
// // 获取充值金额
|
||||
// rechargeList, err := rechargemod.TotalDistricRechargeAmountV1(ctx, 888, start, end)
|
||||
// if err != nil {
|
||||
// log.Error("DirectAmountMethod DirectRechargeAmount ", log.E(err))
|
||||
// return err
|
||||
// }
|
||||
|
||||
// for _, orderinfo := range rechargeList {
|
||||
// registerTime := utils.BeginWithTime(orderinfo.RegisterTime)
|
||||
// if registerTime.Before(start.AddDate(0, 0, -20)) {
|
||||
// continue
|
||||
// }
|
||||
// if money, ok := registerMap[registerTime]; ok {
|
||||
// registerMap[registerTime] = money + orderinfo.Money
|
||||
// } else {
|
||||
// registerMap[registerTime] = orderinfo.Money
|
||||
// }
|
||||
// }
|
||||
|
||||
// for key, value := range registerMap {
|
||||
// fmt.Println(key, "充值金额:", fmt.Sprintf("%02f", float64(value)/100))
|
||||
// }
|
||||
|
||||
// return nil
|
||||
// }
|
||||
Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user