357 lines
7.2 KiB
Go
357 lines
7.2 KiB
Go
package utils
|
||
|
||
import (
|
||
"crypto/sha1"
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"servicebase/pkg/constant"
|
||
"strconv"
|
||
"strings"
|
||
"time"
|
||
|
||
"github.com/anxpp/common-utils/str"
|
||
"github.com/gin-gonic/gin"
|
||
)
|
||
|
||
func FullPhotoUrl(path string) string {
|
||
if len(path) == 0 {
|
||
return ""
|
||
}
|
||
if strings.Index(path, "http") >= 0 {
|
||
return path
|
||
}
|
||
return fmt.Sprintf("%s%s", constant.PhotoDomainUrl, path)
|
||
}
|
||
|
||
// 从gin Context获取AppUserId
|
||
func AppUserIdByHeader(c *gin.Context) (staffId string) {
|
||
|
||
inputToken := c.Request.Header.Get("X-Token")
|
||
if len(inputToken) == 0 {
|
||
return
|
||
}
|
||
|
||
//从缓存获取
|
||
// redisClient := cache.GetCommonRedisInstance().RedisClient
|
||
// accessTokenKey := cache.ACCESSTOKEN_KEY_PREV + inputToken
|
||
// staffId = redisClient.Get(cache.Ctx(), accessTokenKey).Val()
|
||
return
|
||
}
|
||
|
||
// 获取客户端真实IP
|
||
func GetClientRealIp(c *gin.Context) (ip string) {
|
||
ip = c.ClientIP()
|
||
xForwardedFor := c.Request.Header.Get("X-Forwarded-For")
|
||
if xForwardedFor != "" {
|
||
ip = xForwardedFor
|
||
// 可能有多个IP,第一个是客户端的真实IP
|
||
if i := strings.Index(xForwardedFor, ","); i >= 0 {
|
||
ip = xForwardedFor[:i]
|
||
}
|
||
}
|
||
return
|
||
}
|
||
|
||
// 移出int数组重复项
|
||
func RemoveDuplicatesInt(nums []int) []int {
|
||
result := make([]int, 0, len(nums))
|
||
temp := make(map[int]int, len(nums))
|
||
for _, item := range nums {
|
||
if _, ok := temp[item]; !ok {
|
||
temp[item] = item
|
||
result = append(result, item)
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
// 移出string数组重复项
|
||
func RemoveDuplicatesString(nums []string) []string {
|
||
result := make([]string, 0, len(nums))
|
||
temp := make(map[string]string, len(nums))
|
||
for _, item := range nums {
|
||
if _, ok := temp[item]; !ok {
|
||
temp[item] = item
|
||
result = append(result, item)
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
// 判断数组是否包含某个数
|
||
func IsInIntList(v int, list []int) bool {
|
||
if len(list) == 0 {
|
||
return false
|
||
}
|
||
isIn := false
|
||
for _, item := range list {
|
||
if v == item {
|
||
isIn = true
|
||
break
|
||
}
|
||
}
|
||
|
||
return isIn
|
||
|
||
}
|
||
|
||
// 判断数组是否包含某个字符串
|
||
func IsInStringList(v string, list []string) bool {
|
||
if len(list) == 0 {
|
||
return false
|
||
}
|
||
isIn := false
|
||
for _, item := range list {
|
||
if v == item {
|
||
isIn = true
|
||
break
|
||
}
|
||
}
|
||
|
||
return isIn
|
||
}
|
||
|
||
// 根据生日获得年龄
|
||
func AgeByBirthday(birthday string) (age string) {
|
||
age = ""
|
||
if len(birthday) < 10 {
|
||
return
|
||
}
|
||
|
||
t, err := time.Parse(str.DateLayout, birthday)
|
||
|
||
if err != nil {
|
||
return
|
||
}
|
||
birthdayYear := t.Year()
|
||
nowYear := time.Now().Year()
|
||
|
||
ageInt := nowYear - birthdayYear
|
||
|
||
if ageInt < 0 {
|
||
ageInt = 0
|
||
}
|
||
|
||
age = strconv.Itoa(ageInt)
|
||
return
|
||
}
|
||
|
||
// 根据年龄获取生日
|
||
func BirthdayByAge(age int) (birthday string) {
|
||
birthday = ""
|
||
if age < 0 || age > 100 {
|
||
return
|
||
}
|
||
nowYear := time.Now().Year()
|
||
birthYear := nowYear - age
|
||
|
||
birthday = strconv.Itoa(birthYear) + "-01-01"
|
||
return
|
||
}
|
||
|
||
// 获取日期是周几
|
||
func GetWeekDayByDate(d string) string {
|
||
|
||
dayTime, err := time.Parse(str.DateLayout, d)
|
||
|
||
if err != nil {
|
||
return ""
|
||
}
|
||
week := int(dayTime.Weekday())
|
||
return strconv.Itoa(week)
|
||
}
|
||
|
||
// stringList转intList
|
||
func StringListToIntList(stringList []string) (intList []int) {
|
||
|
||
if len(stringList) == 0 {
|
||
return
|
||
}
|
||
|
||
for _, item := range stringList {
|
||
intList = append(intList, str.StringToInt(item))
|
||
}
|
||
|
||
return
|
||
}
|
||
|
||
// float32转string
|
||
func Float32ToString(f float32, prec int) string {
|
||
return strconv.FormatFloat(float64(f), 'f', prec, 32)
|
||
}
|
||
|
||
// float64转string
|
||
func Float64ToString(f float64, prec int) string {
|
||
return strconv.FormatFloat(f, 'f', prec, 64)
|
||
}
|
||
|
||
func Decimal(num float64) float64 {
|
||
num, _ = strconv.ParseFloat(fmt.Sprintf("%.2f", num), 64)
|
||
return num
|
||
}
|
||
|
||
// 获取周几的名字
|
||
func GetWeekNameByIndex(weekIndex int) (weekName string) {
|
||
if weekIndex < 0 || weekIndex > 6 {
|
||
return
|
||
}
|
||
names := []string{"周日", "周一", "周二", "周三", "周四", "周五", "周六"}
|
||
return names[weekIndex]
|
||
}
|
||
|
||
// 获取周几的名字
|
||
func GetWeekNameListByIndexList(weekIndexList string) (weekName string) {
|
||
if len(weekIndexList) == 0 {
|
||
return
|
||
}
|
||
var indexList []string
|
||
_ = json.Unmarshal([]byte(weekIndexList), &indexList)
|
||
|
||
if len(indexList) == 0 {
|
||
return
|
||
}
|
||
var nameList []string
|
||
for _, item := range indexList {
|
||
name := GetWeekNameByIndex(str.StringToInt(item))
|
||
nameList = append(nameList, name)
|
||
}
|
||
weekName = strings.Join(nameList, ",")
|
||
|
||
return
|
||
|
||
}
|
||
|
||
// 获取某时间的当月第一天
|
||
func GetFirstDateOfMonth(d time.Time) time.Time {
|
||
d = d.AddDate(0, 0, -d.Day()+1)
|
||
return GetZeroTime(d)
|
||
}
|
||
|
||
// 获取某时间的当月最后一天
|
||
func GetLastDateOfMonth(d time.Time) time.Time {
|
||
return GetFirstDateOfMonth(d).AddDate(0, 1, -1)
|
||
}
|
||
|
||
// 获取某一天的0点时间
|
||
func GetZeroTime(d time.Time) time.Time {
|
||
return time.Date(d.Year(), d.Month(), d.Day(), 0, 0, 0, 0, d.Location())
|
||
}
|
||
|
||
/*
|
||
*
|
||
获取本周周一的日期
|
||
*/
|
||
func GetCurrentWeekFirstDate() (weekMonday string) {
|
||
now := time.Now()
|
||
|
||
offset := int(time.Monday - now.Weekday())
|
||
if offset > 0 {
|
||
offset = -6
|
||
}
|
||
|
||
weekStartDate := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
|
||
weekMonday = weekStartDate.Format("2006-01-02")
|
||
return
|
||
}
|
||
|
||
/*
|
||
*
|
||
日期加天数
|
||
*/
|
||
func DateAddDays(dateStr string, days int) (resultDate string) {
|
||
dateTime, _ := time.Parse(str.DateLayout, dateStr)
|
||
weekStartDate := dateTime.AddDate(0, 0, days)
|
||
resultDate = str.DateToString(weekStartDate)
|
||
return
|
||
}
|
||
|
||
/*
|
||
获取上周的周一日期
|
||
*/
|
||
func GetLastWeekFirstDate() (resultDate string) {
|
||
thisWeekMonday := GetCurrentWeekFirstDate()
|
||
TimeMonday, _ := time.Parse(str.DateLayout, thisWeekMonday)
|
||
lastWeekMonday := TimeMonday.AddDate(0, 0, -7)
|
||
resultDate = lastWeekMonday.Format("2006-01-02")
|
||
return
|
||
}
|
||
|
||
// SHA1 加密
|
||
func Sha1Str(str string) (result string) {
|
||
t := sha1.New()
|
||
io.WriteString(t, str)
|
||
|
||
result = fmt.Sprintf("%x", t.Sum(nil))
|
||
return
|
||
}
|
||
|
||
func GetAgeFromIDCard(idCard string) (int, error) {
|
||
// 验证身份证号码长度
|
||
if len(idCard) != 18 {
|
||
return 0, fmt.Errorf("身份证号码必须是18位")
|
||
}
|
||
|
||
// 提取出生日期部分 (第7-14位)
|
||
birthStr := idCard[6:14]
|
||
|
||
// 解析出生日期
|
||
birthDate, err := time.Parse("20060102", birthStr)
|
||
if err != nil {
|
||
return 0, fmt.Errorf("解析出生日期失败: %v", err)
|
||
}
|
||
|
||
// 获取当前日期
|
||
now := time.Now()
|
||
|
||
// 计算年龄
|
||
age := now.Year() - birthDate.Year()
|
||
|
||
// 考虑月份和日期,如果还没过生日则减1岁
|
||
birthDay := time.Date(now.Year(), birthDate.Month(), birthDate.Day(), 0, 0, 0, 0, now.Location())
|
||
if now.Before(birthDay) {
|
||
age--
|
||
}
|
||
|
||
return age, nil
|
||
}
|
||
|
||
// IDCardInfo 存储从身份证提取的信息
|
||
type IDCardInfo struct {
|
||
BirthYear int // 出生年份
|
||
BirthMonth int // 出生月份
|
||
BirthDay int // 出生日
|
||
Gender string // 性别:"男" 或 "女"
|
||
}
|
||
|
||
// ParseIDCard 从身份证号码提取出生日期和性别
|
||
func ParseIDCard(idCard string) (birthday, gender string) {
|
||
// 验证身份证号码长度
|
||
if len(idCard) != 18 {
|
||
return "", ""
|
||
}
|
||
|
||
// 提取出生日期部分 (第7-14位)
|
||
birthStr := idCard[6:14]
|
||
birthDate, err := time.Parse("20060102", birthStr)
|
||
if err != nil {
|
||
return "", ""
|
||
}
|
||
|
||
birthday = str.DateToString(birthDate)
|
||
|
||
// 提取性别标识 (第17位)
|
||
genderChar := idCard[16:17]
|
||
genderNum, err := strconv.Atoi(genderChar)
|
||
if err != nil {
|
||
return "", ""
|
||
}
|
||
|
||
gender = "0"
|
||
if genderNum%2 == 1 {
|
||
gender = "1"
|
||
}
|
||
return
|
||
|
||
}
|