318 lines
8.7 KiB
Go
318 lines
8.7 KiB
Go
|
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")
|
||
|
}
|