fonchain-fiee/pkg/utils/holiday/holiday.go

318 lines
8.7 KiB
Go
Raw Normal View History

2025-02-19 06:24:15 +00:00
package holiday
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/fonchain_enterprise/fonchain-main/pkg/cache"
"github.com/fonchain_enterprise/fonchain-main/pkg/config"
"github.com/fonchain_enterprise/fonchain-main/pkg/e"
"go.uber.org/zap"
"io"
"net/http"
"strconv"
"strings"
"time"
)
type HolidayDate struct {
Date string `json:"date"`
WeekDay int8 `json:"weekDay"`
YearTips string `json:"yearTips"`
Type int8 `json:"type"`
TypeDes string `json:"typeDes"`
ChineseZodiac string `json:"chineseZodiac"`
SolarTerms string `json:"solarTerms"`
Avoid string `json:"avoid"`
LunarCalendar string `json:"lunarCalendar"`
Suit string `json:"suit"`
DayOfYear int16 `json:"dayOfYear"`
WeekOfYear int16 `json:"weekOfYear"`
Constellation string `json:"constellation"`
IndexWorkDayOfMonth int8 `json:"indexWorkDayOfMonth"`
}
type HolidayInfoReq struct {
BeginDate string `json:"beginDate"`
EndDate string `json:"endDate"`
}
type SingleHolidayResp struct {
Code int8 `json:"code"`
Msg string `json:"msg"`
Data HolidayDate `json:"data"`
}
type MultiHolidayResp struct {
Code int8 `json:"code"`
Msg string `json:"msg"`
Data []HolidayDate `json:"data"`
}
type RespData struct {
IsToday bool `json:"isToday,default:false"` // 是否是今天
IsOtherMonthDay bool `json:"isOtherMonthDay,default:true"` // 是否是其他月份的日期
Day int8 `json:"day"`
Month int8 `json:"month"`
Type int8 `json:"type"` // 0 工作日 1 假日 2 节假日
WeekDay int8 `json:"weekDay"`
RenderMonth int8 `json:"renderMonth"`
RenderYear int32 `json:"renderYear"`
Year int32 `json:"year"`
TypeDes string `json:"typeDes"`
Lunar string `json:"lunar"` // 农历
}
var (
IsStartFromZERO = true
)
// 万年历
func GetSingleData(date string, ignoreHoliday bool) (*RespData, error) {
if v, err := GetCacheHolidayInfo([]string{date}); err == nil && len(v) > 0 {
fmt.Println("go to cache ")
return v[len(v)-len(v)], nil
}
resp, err := http.Get(fmt.Sprintf(config.HolidaySingleUrl, date, ignoreHoliday, config.HolidayID, config.HolidaySecret))
if err != nil {
return nil, err
}
defer resp.Body.Close()
bt := make([]byte, 0)
buf := bytes.NewBuffer(bt)
io.Copy(buf, resp.Body)
holidayResp := SingleHolidayResp{}
err = json.Unmarshal(buf.Bytes(), &holidayResp)
if err != nil {
return nil, err
}
data := dataHandle([]HolidayDate{holidayResp.Data}, []string{date})
if len(data) == 1 {
return data[0], nil
} else {
return nil, errors.New("操作失败")
}
}
func GetMultiData(beginDate, endDate string, ignoreHoliday bool) ([]*RespData, error) {
dates := SplitDates(beginDate, endDate, "20060102")
//fmt.Println(dates)
if v, err := GetCacheHolidayInfo(dates); err == nil && len(v) > 0 {
fmt.Println("go to cache ")
return v, nil
}
fmt.Println(fmt.Sprintf(config.HolidayMultiUrl, strings.Join(dates, ","), ignoreHoliday, config.HolidayID, config.HolidaySecret))
//time.Sleep(100 * time.Nanosecond)
resp, err := http.Get(fmt.Sprintf(config.HolidayMultiUrl, strings.Join(dates, ","), ignoreHoliday, config.HolidayID, config.HolidaySecret))
if err != nil {
return nil, err
}
defer resp.Body.Close()
bt := make([]byte, 0)
buf := bytes.NewBuffer(bt)
io.Copy(buf, resp.Body)
holidayResp := new(MultiHolidayResp)
holidayResp.Data = make([]HolidayDate, 0)
err = json.Unmarshal(buf.Bytes(), &holidayResp)
if err != nil {
return nil, err
}
fmt.Println(holidayResp.Data)
holidayMap := make(map[string]interface{}, 0)
for i := 0; i < len(holidayResp.Data); i++ {
bt, _ := json.Marshal(holidayResp.Data[i])
holidayMap[ConvertTime(holidayResp.Data[i].Date)] = bt
}
// 缓存 日历信息
cache.HMSet(cache.HolidayMap, holidayMap)
data := dataHandle(holidayResp.Data, dates)
fmt.Println(data)
if len(data) > 0 {
return data, nil
} else {
return nil, errors.New("操作失败")
}
}
func dataHandle(holidayDate []HolidayDate, dates []string) []*RespData {
respDatas := make([]*RespData, 0)
for i := 0; i < len(holidayDate); i++ {
respData := &RespData{}
if holidayDate[i].Date == time.Now().Format("2006-01-02") {
respData.IsToday = true
}
for j := 0; j < len(dates); j++ {
if strings.Replace(holidayDate[i].Date, "-", "", -1) == dates[j] {
dateArray := strings.Split(dates[j], "")
year, _ := strconv.Atoi(strings.Join(dateArray[0:4], ""))
respData.Year = int32(year)
month, _ := strconv.Atoi(strings.Join(dateArray[4:6], ""))
respData.Month = int8(month)
day, _ := strconv.Atoi(strings.Join(dateArray[6:8], ""))
respData.Day = int8(day)
}
}
respData.RenderYear = int32(time.Now().Year())
respData.RenderMonth = int8(time.Now().Month())
if respData.RenderYear != respData.Year || respData.RenderMonth != respData.Month {
respData.IsOtherMonthDay = true
}
respData.Lunar = holidayDate[i].LunarCalendar
respData.WeekDay = holidayDate[i].WeekDay
respData.Type = holidayDate[i].Type
//if respData.Type >= 1 { //
// respData.Type = 1
//}
respData.TypeDes = holidayDate[i].TypeDes
respDatas = append(respDatas, respData)
}
return respDatas
}
func SplitDates(beginDate, endDate, format string) []string {
bDate, _ := time.ParseInLocation(format, beginDate, time.Local)
eDate, _ := time.ParseInLocation(format, endDate, time.Local)
if bDate == eDate {
return []string{bDate.Format(format)}
}
day := int(eDate.Sub(bDate).Hours() / 24)
dlist := make([]string, 0)
dlist = append(dlist, beginDate)
for i := 1; i < day; i++ {
result := bDate.AddDate(0, 0, i)
dlist = append(dlist, result.Format(format))
}
dlist = append(dlist, endDate)
return dlist
}
// 格式 2023-01-01
func SplitMonth(month string, format string) []string {
bDate, _ := time.ParseInLocation(format, month, time.Local)
bDate = bDate.AddDate(0, 1, 0)
eDate := bDate.AddDate(0, 0, -1)
return SplitDates(month, eDate.Format(format), format)
}
func GetCommonWorkDays(days []*RespData, m map[int]int) []*RespData {
workDays := make([]*RespData, 0)
for i := 0; i < len(days); i++ {
_, ok := m[int(days[i].WeekDay)]
if ok { // m 不为 nil 则使用 m 的规则
//workDays = append(workDays, days[i])
if days[i].Type == 0 {
workDays = append(workDays, days[i])
}
} else if days[i].Type == 0 { // m 为 nil 则使用 正常工作日 的规则
workDays = append(workDays, days[i])
}
}
return workDays
}
func ConvertTime(t string) string {
ts := strings.Split(t, "-")
for i := 1; i < len(ts); i++ {
if s, err := strconv.Atoi(ts[i]); err == nil {
if s < 10 {
//fmt.Println(s)
ts[i] = "0" + strconv.Itoa(s)
//fmt.Println(ts[i])
}
}
}
return strings.Join(ts, "")
}
func GetCacheHolidayInfo(date []string) (value []*RespData, err error) {
v, err := cache.HMGet(cache.HolidayMap, date...)
if err != nil {
return nil, err
}
zap.L().Info("GetCacheHolidayInfo", zap.Any("redis client ", cache.RedisClient.String()))
fmt.Printf("redis client %+v\n", cache.RedisClient.String())
if len(v) == 0 {
return nil, errors.New(e.ErrHolidayMiss)
}
holidayDates := make([]HolidayDate, 0)
for i := 0; i < len(v); i++ {
holidayDate := HolidayDate{}
if v[i] == nil {
return nil, errors.New(e.ErrHolidayMiss)
}
json.Unmarshal([]byte(v[i].(string)), &holidayDate)
holidayDates = append(holidayDates, holidayDate)
zap.L().Info("holiday list ", zap.Any("holiday list ", fmt.Sprintf(" v: %+v", holidayDate)))
fmt.Printf("holiday list %+v\n", holidayDate)
}
return dataHandle(holidayDates, date), nil
}
func CurrentWeek(t time.Time) (string, string) {
if t.Weekday() == time.Monday {
return t.Format("2006-01-02"), t.AddDate(0, 0, 6).Format("2006-01-02")
} else if t.Weekday() == time.Sunday {
return t.AddDate(0, 0, -6).Format("2006-01-02"), t.Format("2006-01-02")
} else {
return t.AddDate(0, 0, -int(t.Weekday())+1).Format("2006-01-02"),
t.AddDate(0, 0, -int(t.Weekday())+1).AddDate(0, 0, 6).Format("2006-01-02")
}
}
// 格式 2023-01-26 ~ 2023-02-25
func SplitMonthV1(month string, format string) []string {
bDate, _ := time.ParseInLocation(format, month, time.Local)
bDate = bDate.AddDate(0, -1, 0)
sDate := bDate.AddDate(0, 0, 1)
return SplitDates(sDate.Format(format), month, format)
}
func CurrentMonth() string {
t := time.Now()
var month string
// 25号之后属于下个月
if t.Day() > 25 {
tt, _ := time.ParseInLocation("2006-01", t.Format("2006-01"), time.Local)
month = tt.AddDate(0, 1, 0).Format("2006-01")
} else if t.Day() <= 25 {
month = t.Format("2006-01")
}
return month
}
func NextDate() string {
return time.Now().AddDate(0, 0, 1).Format("2006-01-02")
}