@@ -22,4 +22,6 @@ type SubsidyBase struct { | |||
StoreOpen int `json:"store_open" xorm:"default 0 comment('节假日是否结算') INT(1)"` | |||
StoreIntegral string `json:"store_integral" xorm:"default 0.00 comment('消费补贴') DECIMAL(20,2)"` | |||
StoreMoney string `json:"store_money" xorm:"default 0.00 comment('消费补贴') DECIMAL(20,2)"` | |||
PushReward string `json:"push_reward" xorm:"comment('体贴补贴兑换后第X天') VARCHAR(255)"` | |||
ActivityData string `json:"activity_data" xorm:"comment('体贴补贴兑换后第X天') VARCHAR(255)"` | |||
} |
@@ -0,0 +1,14 @@ | |||
package model | |||
import ( | |||
"time" | |||
) | |||
type SubsidyFreezeUser struct { | |||
Id int `json:"id" xorm:"not null pk autoincr INT(11)"` | |||
Uid int `json:"uid" xorm:"default 0 INT(11)"` | |||
Type int `json:"type" xorm:"default 0 comment('0用户 1商家') INT(1)"` | |||
Time time.Time `json:"time" xorm:"DATETIME"` | |||
IsFreeze int `json:"is_freeze" xorm:"default 0 INT(1)"` | |||
LastExchangeTime string `json:"last_exchange_time" xorm:"default '' VARCHAR(255)"` | |||
} |
@@ -13,4 +13,6 @@ type SubsidyWithUserFlow struct { | |||
Date string `json:"date" xorm:"comment('2023-12-01') VARCHAR(255)"` | |||
Day int `json:"day" xorm:"not null default 0 comment('') TINYINT(1)"` | |||
LeaveDay int `json:"leave_day" xorm:"not null default 0 comment('') TINYINT(1)"` | |||
IsStop int `json:"is_stop" xorm:"not null default 0 comment('') TINYINT(1)"` | |||
StopDate string `json:"stop_date" xorm:"comment('2023-12-01') VARCHAR(255)"` | |||
} |
@@ -14,6 +14,7 @@ require ( | |||
github.com/jinzhu/copier v0.4.0 | |||
github.com/shopspring/decimal v1.3.1 | |||
github.com/syyongx/php2go v0.9.8 | |||
github.com/tidwall/gjson v1.14.1 | |||
go.uber.org/zap v1.13.0 | |||
golang.org/x/sync v0.1.0 | |||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 | |||
@@ -1,17 +1,7 @@ | |||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | |||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | |||
code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git v0.0.3 h1:SPp5AswPmkDO2ML6WwGlzhIuls+/1dUfU40iOeH0dh4= | |||
code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git v0.0.3/go.mod h1:TTcCnFn/LhBGapnutpezlW+GXkLRNPMWkziOoCsXQqY= | |||
code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git v0.0.5 h1:dqvWJqlJi0WXCwTxbWPLvSOsKPjP+iEDBVgLcAl9nOE= | |||
code.fnuoos.com/go_rely_warehouse/zyos_go_mq.git v0.0.5/go.mod h1:TTcCnFn/LhBGapnutpezlW+GXkLRNPMWkziOoCsXQqY= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240618104112-42ff22d419df h1:2rSTK/V4sEJWa1Rf+sc0nWixTbRThGsQs60cozAfU/w= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240618104112-42ff22d419df/go.mod h1:ssMD5Wh5IRmd06P4DSIWtKWwlfAIjfLSkK0Xp9ZyE00= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240619111913-4540786aa565 h1:KLbCiwdd/STDY8MTV2Gaqayrzi9Ai43pZe8LfF3UUa8= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240619111913-4540786aa565/go.mod h1:ssMD5Wh5IRmd06P4DSIWtKWwlfAIjfLSkK0Xp9ZyE00= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240620100400-9ebf54e21441 h1:hM0Yq0l3kc+qmdqq147yelawWBTOkR75D85H5O0iyik= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240620100400-9ebf54e21441/go.mod h1:ssMD5Wh5IRmd06P4DSIWtKWwlfAIjfLSkK0Xp9ZyE00= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240701100834-33d58f178d5a h1:BWkXPp6RHYzVy3sT5ZTr3jMYLNpn+dhu9kERwSV8vtc= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240701100834-33d58f178d5a/go.mod h1:nT2x13YFgrS3tS1fDyUR6q/GNIK+hPw7bdzZXz99SM0= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240701102131-0408d7ee8572 h1:HncIr54hrhKSgOpq/KQiOiMdf4895JpxIUk56UyAsMY= | |||
code.fnuoos.com/go_rely_warehouse/zyos_model.git v0.0.4-0.20240701102131-0408d7ee8572/go.mod h1:nT2x13YFgrS3tS1fDyUR6q/GNIK+hPw7bdzZXz99SM0= | |||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= | |||
@@ -232,8 +222,7 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f | |||
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= | |||
github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= | |||
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= | |||
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg= | |||
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= | |||
github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= | |||
github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= | |||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= | |||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= | |||
@@ -411,6 +400,12 @@ github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFd | |||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= | |||
github.com/syyongx/php2go v0.9.8 h1:FNwV1y+RaZxl7KTm/ICh0Zrhca/70d5JRMpwByuQ1FM= | |||
github.com/syyongx/php2go v0.9.8/go.mod h1:meN2eIhhUoxOd2nMxbpe8g6cFPXI5O9/UAAuz7oDdzw= | |||
github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo= | |||
github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= | |||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= | |||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= | |||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= | |||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= | |||
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= | |||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= | |||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= | |||
@@ -12,6 +12,7 @@ import ( | |||
"errors" | |||
"fmt" | |||
"github.com/shopspring/decimal" | |||
"github.com/tidwall/gjson" | |||
"strconv" | |||
"strings" | |||
"time" | |||
@@ -121,15 +122,35 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
_ = session.Rollback() | |||
return err, totalMap, storeTotalMap | |||
} | |||
//读出用户冻结情况 | |||
uids := make([]int, 0) | |||
storeUids := make([]int, 0) | |||
for _, v := range subsidyWithUserForConsumeList { | |||
uids = append(uids, v.Uid) | |||
} | |||
for _, v := range subsidyWithUserForExperienceList { | |||
uids = append(uids, v.Uid) | |||
} | |||
for _, v := range subsidyWithUserForStoreList { | |||
storeUids = append(storeUids, v.Uid) | |||
} | |||
userStatusList := userStatus(session, uids, 0, subsidyBase) | |||
storeStatusList := userStatus(session, storeUids, 1, subsidyBase) | |||
if hasConsumeTotal > 0 { | |||
for _, v := range subsidyWithUserForConsumeList { | |||
if v.LeaveDay > 0 { | |||
if v.LeaveDay > 0 && userStatusList[v.Uid]["status"] != "1" { | |||
consumeTotalMap[v.Uid] = consumeTotalMap[v.Uid].Add(decimal.NewFromFloat(consumeValue)) | |||
totalMap[v.Uid] = totalMap[v.Uid].Add(decimal.NewFromFloat(consumeValue)) | |||
consumeTotalCountMap[v.Uid]++ | |||
totalMap[v.Uid] = totalMap[v.Uid].Add(decimal.NewFromFloat(consumeValue)) | |||
consumeValueTotal = consumeValueTotal.Add(decimal.NewFromFloat(consumeValue)) | |||
} | |||
err1 := DealUserConsumeIntegral(session, &v, consumeValue, mid) | |||
var err1 error | |||
if userStatusList[v.Uid]["status"] != "1" { | |||
err1 = DealUserConsumeIntegral(session, &v, consumeValue, mid) | |||
} else { | |||
err1 = DealUserConsumeIntegralStop(session, &v, consumeValue, mid, storeStatusList[v.Uid]["date"]) | |||
} | |||
if err1 != nil { | |||
_ = session.Rollback() | |||
return err1, totalMap, storeTotalMap | |||
@@ -157,13 +178,18 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
return err, totalMap, storeTotalMap | |||
} | |||
for _, v := range subsidyWithUserForExperienceList { | |||
if v.LeaveDay > 0 { | |||
if v.LeaveDay > 0 && userStatusList[v.Uid]["status"] != "1" { | |||
experienceTotalCountMap[v.Uid]++ | |||
totalMap[v.Uid] = totalMap[v.Uid].Add(decimal.NewFromFloat(experienceValue)) | |||
experienceTotalMap[v.Uid] = experienceTotalMap[v.Uid].Add(decimal.NewFromFloat(experienceValue)) | |||
experienceValueTotal = experienceValueTotal.Add(decimal.NewFromFloat(experienceValue)) | |||
} | |||
err1 := DealUserExperienceIntegral(session, &v, experienceValue, mid) | |||
var err1 error | |||
if userStatusList[v.Uid]["status"] != "1" { | |||
err1 = DealUserExperienceIntegral(session, &v, experienceValue, mid) | |||
} else { | |||
err1 = DealUserExperienceIntegralStop(session, &v, experienceValue, mid, userStatusList[v.Uid]["date"]) | |||
} | |||
if err1 != nil { | |||
_ = session.Rollback() | |||
return err1, totalMap, storeTotalMap | |||
@@ -185,14 +211,18 @@ func DailySettlementBlockConsumeIntegral(engine *xorm.Engine, mid string, isTask | |||
if subsidyBase.StoreOpen == 1 { | |||
var storeTotalCountMap = make(map[int]int) | |||
if hasStoreTotal > 0 && consumeValue > 0 { | |||
for _, v := range subsidyWithUserForStoreList { | |||
num := zhios_order_relate_utils.StrToFloat64(v.IntegralNum) / zhios_order_relate_utils.StrToFloat64(subsidyBase.ConsumptionIntegral) | |||
storeValue := zhios_order_relate_utils.FloatFormat(consumeValue*num, 2) | |||
storeTotalCountMap[v.Uid] += int(num) | |||
storeTotalMap[v.Uid] = storeTotalMap[v.Uid].Add(decimal.NewFromFloat(storeValue)) | |||
storeValueTotal = storeValueTotal.Add(decimal.NewFromFloat(storeValue)) | |||
err1 := DealUserStoreIntegral(session, &v, storeValue, mid) | |||
var err1 error | |||
if storeStatusList[v.Uid]["status"] != "1" { | |||
storeTotalCountMap[v.Uid] += int(num) | |||
storeTotalMap[v.Uid] = storeTotalMap[v.Uid].Add(decimal.NewFromFloat(storeValue)) | |||
storeValueTotal = storeValueTotal.Add(decimal.NewFromFloat(storeValue)) | |||
err1 = DealUserStoreIntegral(session, &v, storeValue, mid) | |||
} else { | |||
err1 = DealUserStoreIntegralStop(session, &v, storeValue, mid, storeStatusList[v.Uid]["date"]) | |||
} | |||
if err1 != nil { | |||
_ = session.Rollback() | |||
return err1, totalMap, storeTotalMap | |||
@@ -596,6 +626,98 @@ func DealUserStoreIntegral(session *xorm.Session, subsidyWithUser *model.Subsidy | |||
} | |||
// DealUserConsumeIntegral 处理给用户发放消费补贴奖励 | |||
func DealUserConsumeIntegralStop(session *xorm.Session, subsidyWithUser *model.SubsidyWithUser, consumeIntegralValue float64, mid, date string) (err error) { | |||
now := time.Now() | |||
//2、新增 subsidy_with_user_flow 记录 | |||
var subsidyWitUserFlow = &model.SubsidyWithUserFlow{ | |||
RecordsId: subsidyWithUser.Id, | |||
Day: 1, | |||
Amount: zhios_order_relate_utils.Float64ToStr(consumeIntegralValue), | |||
LeaveDay: subsidyWithUser.LeaveDay, | |||
CreateAt: now.Format("2006-01-02 15:04:05"), | |||
UpdateAt: now.Format("2006-01-02 15:04:05"), | |||
Date: now.Format("2006-01-02"), | |||
Uid: subsidyWithUser.Uid, | |||
Kind: subsidyWithUser.Kind, | |||
Month: zhios_order_relate_utils.StrToInt(now.Format("200601")), | |||
IsStop: 1, | |||
StopDate: date, | |||
} | |||
insertAffected, err := db.SubsidyWithUserFlowInsert(session, subsidyWitUserFlow) | |||
if err != nil { | |||
return err | |||
} | |||
if insertAffected <= 0 { | |||
return errors.New("新增 subsidy_with_user_flow 记录失败") | |||
} | |||
return nil | |||
} | |||
// DealUserExperienceIntegral 处理给用户发放体验补贴奖励 | |||
func DealUserExperienceIntegralStop(session *xorm.Session, subsidyWithUser *model.SubsidyWithUser, experienceIntegralValue float64, mid, date string) (err error) { | |||
now := time.Now() | |||
isEnd := 0 | |||
if subsidyWithUser.LeaveDay < 0 { | |||
isEnd = 1 | |||
} | |||
if isEnd == 1 { | |||
return nil | |||
} | |||
//2、新增 subsidy_with_user_flow 记录 | |||
var subsidyWitUserFlow = &model.SubsidyWithUserFlow{ | |||
RecordsId: subsidyWithUser.Id, | |||
Uid: subsidyWithUser.Uid, | |||
Kind: subsidyWithUser.Kind, | |||
Amount: zhios_order_relate_utils.Float64ToStr(experienceIntegralValue), | |||
Day: 1, | |||
LeaveDay: subsidyWithUser.LeaveDay, | |||
CreateAt: now.Format("2006-01-02 15:04:05"), | |||
Date: now.Format("2006-01-02"), | |||
Month: zhios_order_relate_utils.StrToInt(now.Format("200601")), | |||
UpdateAt: now.Format("2006-01-02 15:04:05"), | |||
IsStop: 1, | |||
StopDate: date, | |||
} | |||
insertAffected, err := db.SubsidyWithUserFlowInsert(session, subsidyWitUserFlow) | |||
if err != nil { | |||
return err | |||
} | |||
if insertAffected <= 0 { | |||
return errors.New("新增 subsidy_with_user_flow 记录失败") | |||
} | |||
return nil | |||
} | |||
// DealUserExperienceIntegral 处理给用户发放体验补贴奖励 | |||
func DealUserStoreIntegralStop(session *xorm.Session, subsidyWithUser *model.SubsidyWithUser, experienceIntegralValue float64, mid, date string) (err error) { | |||
now := time.Now() | |||
//2、新增 subsidy_with_user_flow 记录 | |||
var subsidyWitUserFlow = &model.SubsidyWithUserFlow{ | |||
RecordsId: subsidyWithUser.Id, | |||
Uid: subsidyWithUser.Uid, | |||
Kind: subsidyWithUser.Kind, | |||
Amount: zhios_order_relate_utils.Float64ToStr(experienceIntegralValue), | |||
BalanceAmount: subsidyWithUser.BalanceAmount, | |||
CreateAt: now.Format("2006-01-02 15:04:05"), | |||
Date: now.Format("2006-01-02"), | |||
Month: zhios_order_relate_utils.StrToInt(now.Format("200601")), | |||
UpdateAt: now.Format("2006-01-02 15:04:05"), | |||
IsStop: 1, | |||
StopDate: date, | |||
} | |||
insertAffected, err := db.SubsidyWithUserFlowInsert(session, subsidyWitUserFlow) | |||
if err != nil { | |||
return err | |||
} | |||
if insertAffected <= 0 { | |||
return errors.New("新增 subsidy_with_user_flow 记录失败") | |||
} | |||
return nil | |||
} | |||
// DealUserConsumeIntegral 处理给用户发放消费补贴奖励 流水 | |||
func DealUserConsumeAmountFlow(session *xorm.Session, uid int, consumeIntegralValue float64, mid, num string) (err error) { | |||
//4、给用户添加余额流水 | |||
@@ -660,3 +782,50 @@ func DealUserStoreAmountFlow(session *xorm.Session, uid int, experienceIntegralV | |||
return nil | |||
} | |||
func userStatus(sess *xorm.Session, uid []int, types int, base *model.SubsidyBase) map[int]map[string]string { | |||
statusList := make(map[int]map[string]string) | |||
if len(uid) == 0 { | |||
return statusList | |||
} | |||
var data []model.SubsidyFreezeUser | |||
sess.Where("type=?", types).In("uid", uid).Find(&data) | |||
for _, v := range data { | |||
_, ok := statusList[v.Uid] | |||
if ok == false { | |||
statusList[v.Uid] = make(map[string]string) | |||
} | |||
status := "1" | |||
date := v.LastExchangeTime | |||
subsidyDay := "0" | |||
dateStr := "" | |||
if date != "" { | |||
t, _ := zhios_order_relate_utils.TimeParse("2006-01-02", date) | |||
today := zhios_order_relate_utils.GetTimeRange("today") | |||
subsidyDay = zhios_order_relate_utils.Int64ToStr((today["start"] - t.Unix()) / 86400) | |||
dateStr = t.Format("2006-01-02 15:04:05") | |||
} | |||
if types == 0 { | |||
if zhios_order_relate_utils.StrToInt(gjson.Get(base.ActivityData, "user_day").String()) > 0 && zhios_order_relate_utils.StrToInt(gjson.Get(base.ActivityData, "user_open").String()) == 1 { | |||
if zhios_order_relate_utils.StrToInt(subsidyDay) > zhios_order_relate_utils.StrToInt(gjson.Get(base.ActivityData, "user_day").String()) { | |||
status = "0" | |||
dateStr = time.Unix(zhios_order_relate_utils.TimeStdParseUnix(dateStr)+zhios_order_relate_utils.StrToInt64(gjson.Get(base.ActivityData, "user_day").String())*86400, 0).Format("2006-01-02") | |||
} | |||
} | |||
} | |||
if types == 1 { | |||
if zhios_order_relate_utils.StrToInt(gjson.Get(base.ActivityData, "store_day").String()) > 0 && zhios_order_relate_utils.StrToInt(gjson.Get(base.ActivityData, "store_open").String()) == 1 { | |||
if zhios_order_relate_utils.StrToInt(subsidyDay) > zhios_order_relate_utils.StrToInt(gjson.Get(base.ActivityData, "store_day").String()) { | |||
status = "0" | |||
dateStr = time.Unix(zhios_order_relate_utils.TimeStdParseUnix(dateStr)+zhios_order_relate_utils.StrToInt64(gjson.Get(base.ActivityData, "store_day").String())*86400, 0).Format("2006-01-02") | |||
} | |||
} | |||
} | |||
if status == "1" { | |||
dateStr = "" | |||
} | |||
statusList[v.Uid]["status"] = status | |||
statusList[v.Uid]["date"] = dateStr | |||
} | |||
return statusList | |||
} |
@@ -0,0 +1,295 @@ | |||
package zhios_order_relate_utils | |||
import ( | |||
"errors" | |||
"fmt" | |||
"strconv" | |||
"strings" | |||
"time" | |||
) | |||
func StrToTime(s string) (int64, error) { | |||
// delete all not int characters | |||
if s == "" { | |||
return time.Now().Unix(), nil | |||
} | |||
r := make([]rune, 14) | |||
l := 0 | |||
// 过滤除数字以外的字符 | |||
for _, v := range s { | |||
if '0' <= v && v <= '9' { | |||
r[l] = v | |||
l++ | |||
if l == 14 { | |||
break | |||
} | |||
} | |||
} | |||
for l < 14 { | |||
r[l] = '0' // 补0 | |||
l++ | |||
} | |||
t, err := time.Parse("20060102150405", string(r)) | |||
if err != nil { | |||
return 0, err | |||
} | |||
return t.Unix(), nil | |||
} | |||
func String2TimeV2(timeStr string) time.Time { | |||
toTime, err := time.ParseInLocation("2006-01-02", timeStr, time.Local) | |||
if err != nil { | |||
return time.Now() | |||
} | |||
return toTime | |||
} | |||
func StringToTime(timeStr string) (time.Time, error) { | |||
toTime, err := time.ParseInLocation("2006-01-02 15:04:05", timeStr, time.Local) | |||
return toTime, err | |||
} | |||
func TimeToStr(unixSecTime interface{}, layout ...string) string { | |||
i := AnyToInt64(unixSecTime) | |||
if i == 0 { | |||
return "" | |||
} | |||
f := "2006-01-02 15:04:05" | |||
if len(layout) > 0 { | |||
f = layout[0] | |||
} | |||
return time.Unix(i, 0).Format(f) | |||
} | |||
func FormatNanoUnix() string { | |||
return strings.Replace(time.Now().Format("20060102150405.0000000"), ".", "", 1) | |||
} | |||
func TimeParse(format, src string) (time.Time, error) { | |||
return time.ParseInLocation(format, src, time.Local) | |||
} | |||
func TimeParseStd(src string) time.Time { | |||
t, _ := TimeParse("2006-01-02 15:04:05", src) | |||
return t | |||
} | |||
func TimeStdParseUnix(src string) int64 { | |||
t, err := TimeParse("2006-01-02 15:04:05", src) | |||
if err != nil { | |||
return 0 | |||
} | |||
return t.Unix() | |||
} | |||
func TimeStdParseUnixDate(src string) int64 { | |||
t, err := TimeParse("2006-01-02", src) | |||
if err != nil { | |||
return 0 | |||
} | |||
return t.Unix() | |||
} | |||
// 获取一个当前时间 时间间隔 时间戳 | |||
func GetTimeInterval(unit string, amount int) (startTime, endTime int64) { | |||
t := time.Now() | |||
nowTime := t.Unix() | |||
tmpTime := int64(0) | |||
switch unit { | |||
case "years": | |||
tmpTime = time.Date(t.Year()+amount, t.Month(), t.Day(), t.Hour(), 0, 0, 0, t.Location()).Unix() | |||
case "months": | |||
tmpTime = time.Date(t.Year(), t.Month()+time.Month(amount), t.Day(), t.Hour(), 0, 0, 0, t.Location()).Unix() | |||
case "days": | |||
tmpTime = time.Date(t.Year(), t.Month(), t.Day()+amount, t.Hour(), 0, 0, 0, t.Location()).Unix() | |||
case "hours": | |||
tmpTime = time.Date(t.Year(), t.Month(), t.Day(), t.Hour()+amount, 0, 0, 0, t.Location()).Unix() | |||
} | |||
if amount > 0 { | |||
startTime = nowTime | |||
endTime = tmpTime | |||
} else { | |||
startTime = tmpTime | |||
endTime = nowTime | |||
} | |||
return | |||
} | |||
// 几天前 | |||
func TimeInterval(newTime int) string { | |||
now := time.Now().Unix() | |||
newTime64 := AnyToInt64(newTime) | |||
if newTime64 >= now { | |||
return "刚刚" | |||
} | |||
interval := now - newTime64 | |||
switch { | |||
case interval < 60: | |||
return AnyToString(interval) + "秒前" | |||
case interval < 60*60: | |||
return AnyToString(interval/60) + "分前" | |||
case interval < 60*60*24: | |||
return AnyToString(interval/60/60) + "小时前" | |||
case interval < 60*60*24*30: | |||
return AnyToString(interval/60/60/24) + "天前" | |||
case interval < 60*60*24*30*12: | |||
return AnyToString(interval/60/60/24/30) + "月前" | |||
default: | |||
return AnyToString(interval/60/60/24/30/12) + "年前" | |||
} | |||
} | |||
// 时分秒字符串转时间戳,传入示例:8:40 or 8:40:10 | |||
func HmsToUnix(str string) (int64, error) { | |||
t := time.Now() | |||
arr := strings.Split(str, ":") | |||
if len(arr) < 3 { | |||
return 0, errors.New("Time format error") | |||
} | |||
h, _ := strconv.Atoi(arr[0]) | |||
m, _ := strconv.Atoi(arr[1]) | |||
s := 0 | |||
if len(arr) == 3 { | |||
s, _ = strconv.Atoi(arr[2]) | |||
} | |||
formatted1 := fmt.Sprintf("%d%02d%02d%02d%02d%02d", t.Year(), t.Month(), t.Day(), h, m, s) | |||
res, err := time.ParseInLocation("20060102150405", formatted1, time.Local) | |||
if err != nil { | |||
return 0, err | |||
} else { | |||
return res.Unix(), nil | |||
} | |||
} | |||
// 获取特定时间范围 | |||
func GetTimeRange(s string) map[string]int64 { | |||
t := time.Now() | |||
var stime, etime time.Time | |||
switch s { | |||
case "today": | |||
stime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "yesterday": | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-1, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
case "within_seven_days": | |||
// 前6天0点 | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-6, 0, 0, 0, 0, t.Location()) | |||
// 明天 0点 | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "current_month": | |||
stime = time.Date(t.Year(), t.Month(), 0, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month()+1, 0, 0, 0, 0, 0, t.Location()) | |||
case "last_month": | |||
stime = time.Date(t.Year(), t.Month()-1, 0, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), 0, 0, 0, 0, 0, t.Location()) | |||
} | |||
return map[string]int64{ | |||
"start": stime.Unix(), | |||
"end": etime.Unix(), | |||
} | |||
} | |||
// 获取特定时间范围 | |||
func GetTimes(s string) map[string]string { | |||
t := time.Now() | |||
var stime, etime time.Time | |||
switch s { | |||
case "today": | |||
stime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "yesterday": | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-1, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location()) | |||
case "within_seven_days": | |||
// 前6天0点 | |||
stime = time.Date(t.Year(), t.Month(), t.Day()-6, 0, 0, 0, 0, t.Location()) | |||
// 明天 0点 | |||
etime = time.Date(t.Year(), t.Month(), t.Day()+1, 0, 0, 0, 0, t.Location()) | |||
case "current_month": | |||
stime = time.Date(t.Year(), t.Month(), 0, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month()+1, 0, 0, 0, 0, 0, t.Location()) | |||
case "last_month": | |||
stime = time.Date(t.Year(), t.Month()-1, 0, 0, 0, 0, 0, t.Location()) | |||
etime = time.Date(t.Year(), t.Month(), 0, 0, 0, 0, 0, t.Location()) | |||
} | |||
return map[string]string{ | |||
"start": stime.Format("2006-01-02 15:04:05"), | |||
"end": etime.Format("2006-01-02 15:04:05"), | |||
} | |||
} | |||
// 获取传入的时间所在月份的第一天,即某月第一天的0点。如传入time.Now(), 返回当前月份的第一天0点时间。 | |||
func GetFirstDateOfMonth(d time.Time) time.Time { | |||
d = d.AddDate(0, 0, -d.Day()+1) | |||
return GetZeroTime(d) | |||
} | |||
// 获取传入的时间所在月份的最后一天,即某月最后一天的0点。如传入time.Now(), 返回当前月份的最后一天0点时间。 | |||
func GetLastDateOfMonth(d time.Time) time.Time { | |||
return GetFirstDateOfMonth(d).AddDate(0, 1, -1) | |||
} | |||
func GetAnyFirstDateOfMonth(d time.Time, monthDiff int) time.Time { | |||
year, month, _ := d.Date() | |||
thisMonth := time.Date(year, month, 1, 0, 0, 0, 0, time.Local) | |||
monthOneDay := thisMonth.AddDate(0, monthDiff, 0) | |||
return monthOneDay | |||
} | |||
// 当天时间戳 | |||
func GetDateTime(date string) (int64, int64) { | |||
//获取当前时区 | |||
loc, _ := time.LoadLocation("Local") | |||
//日期当天0点时间戳(拼接字符串) | |||
startDate := date + "_00:00:00" | |||
startTime, _ := time.ParseInLocation("2006-01-02_15:04:05", startDate, loc) | |||
//日期当天23时59分时间戳 | |||
endDate := date + "_23:59:59" | |||
end, _ := time.ParseInLocation("2006-01-02_15:04:05", endDate, loc) | |||
//返回当天0点和23点59分的时间戳 | |||
return startTime.Unix(), end.Unix() | |||
} | |||
// 获取某一天的0点时间 | |||
func GetZeroTime(d time.Time) time.Time { | |||
return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location()) | |||
} | |||
// getYearMonthToDay 查询指定年份指定月份有多少天 | |||
// @params year int 指定年份 | |||
// @params month int 指定月份 | |||
func GetYearMonthToDay(year int, month int) int { | |||
// 有31天的月份 | |||
day31 := map[int]bool{ | |||
1: true, | |||
3: true, | |||
5: true, | |||
7: true, | |||
8: true, | |||
10: true, | |||
12: true, | |||
} | |||
if day31[month] == true { | |||
return 31 | |||
} | |||
// 有30天的月份 | |||
day30 := map[int]bool{ | |||
4: true, | |||
6: true, | |||
9: true, | |||
11: true, | |||
} | |||
if day30[month] == true { | |||
return 30 | |||
} | |||
// 计算是平年还是闰年 | |||
if (year%4 == 0 && year%100 != 0) || year%400 == 0 { | |||
// 得出2月的天数 | |||
return 29 | |||
} | |||
// 得出2月的天数 | |||
return 28 | |||
} |