functions.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*
  2. * @description: 常用函数
  3. * @Author: CP
  4. * @Date: 2020-08-21 11:12:56
  5. * @FilePath: \construction_management\comm\functions.go
  6. */
  7. package comm
  8. import (
  9. "bytes"
  10. "crypto/aes"
  11. "crypto/cipher"
  12. "encoding/base64"
  13. "errors"
  14. "math/rand"
  15. "time"
  16. "unicode"
  17. "crypto/md5"
  18. "encoding/binary"
  19. "fmt"
  20. "strconv"
  21. "strings"
  22. "go.mod/conf"
  23. "go.mod/models"
  24. "go.mod/web/viewmodels"
  25. )
  26. // 账号-构造视图层models
  27. func MakeProjectAccountVM(modelsAccount *models.CmProjectAccount) viewmodels.ProjectAccount {
  28. viewAccountData := viewmodels.ProjectAccount{}
  29. aesId, _ := AesEncrypt(strconv.Itoa(modelsAccount.Id), conf.SignSecret)
  30. aesProjectId, _ := AesEncrypt(strconv.Itoa(modelsAccount.ProjectId), conf.SignSecret)
  31. viewAccountData.Id = aesId
  32. viewAccountData.ProjectId = aesProjectId
  33. viewAccountData.Account = modelsAccount.Account
  34. viewAccountData.Name = modelsAccount.Name
  35. viewAccountData.Company = modelsAccount.Company
  36. viewAccountData.Role = modelsAccount.Role
  37. viewAccountData.Mobile = modelsAccount.Mobile
  38. viewAccountData.Telephone = modelsAccount.Telephone
  39. viewAccountData.IsAdmin = modelsAccount.IsAdmin
  40. return viewAccountData
  41. }
  42. func MakeTreeContract(Data []*viewmodels.TreeContract, node *viewmodels.TreeContract) { //参数为父节点,添加父节点的子节点指针切片
  43. childs, _ := HaveChildContract(Data, node) //判断节点是否有子节点并返回
  44. if childs != nil {
  45. // 子节点总数
  46. Total := len(childs)
  47. node.ChildsTotal = Total
  48. // 标记最后一个元素
  49. end := Total - 1
  50. childs[end].IsEnd = true
  51. // 往父节点添加子节点
  52. node.Children = append(node.Children, childs[0:]...) //添加子节点
  53. for _, v := range childs { //查询子节点的子节点,并添加到子节点
  54. _, has := HaveChildContract(Data, v)
  55. if has {
  56. // 递归添加节点
  57. MakeTreeContract(Data, v)
  58. }
  59. // 目录下是否包含标段
  60. if v.Isfolder == 0 {
  61. node.IsBid = true
  62. } else {
  63. node.HasFolder = true
  64. }
  65. }
  66. }
  67. }
  68. // 是否有子树
  69. func HaveChildContract(Data []*viewmodels.TreeContract, node *viewmodels.TreeContract) (child []*viewmodels.TreeContract, yes bool) {
  70. for _, v := range Data {
  71. if v.ParentId == node.Id {
  72. child = append(child, v)
  73. }
  74. }
  75. if child != nil {
  76. yes = true
  77. }
  78. return
  79. }
  80. // 当前时间的时间戳
  81. func NowUnix() int {
  82. return int(time.Now().In(conf.SysTimeLocation).Unix())
  83. }
  84. // 将unix时间戳格式化为yyyymmdd H:i:s格式字符串
  85. func FormatFromUnixTime(t int64) string {
  86. if t > 0 {
  87. return time.Unix(t, 0).Format(conf.SysTimeform)
  88. } else {
  89. return time.Now().Format(conf.SysTimeform)
  90. }
  91. }
  92. // 将unix时间戳格式化为yyyymmdd格式字符串
  93. func FormatFromUnixTimeShort(t int64) string {
  94. if t > 0 {
  95. return time.Unix(t, 0).Format(conf.SysTimeformShort)
  96. } else {
  97. return time.Now().Format(conf.SysTimeformShort)
  98. }
  99. }
  100. // 将字符串转成时间
  101. func ParseTime(str string) (time.Time, error) {
  102. return time.ParseInLocation(conf.SysTimeform, str, conf.SysTimeLocation)
  103. }
  104. // 得到一个随机数
  105. func Random(max int) int {
  106. r := rand.New(rand.NewSource(time.Now().UnixNano()))
  107. if max < 1 {
  108. return r.Int()
  109. } else {
  110. return r.Intn(max)
  111. }
  112. }
  113. // 加密密码
  114. func CreatePasswordSign(password string, account string) string {
  115. str := string(conf.SignSecret) + password + account
  116. str1 := fmt.Sprintf("%x", md5.Sum([]byte(str)))
  117. sign := fmt.Sprintf("%x", md5.Sum([]byte(str1)))
  118. return sign
  119. }
  120. // 对字符串进行签名
  121. func CreateSign(str string) string {
  122. str = string(conf.SignSecret) + str
  123. str1 := fmt.Sprintf("%x", md5.Sum([]byte(str)))
  124. sign := fmt.Sprintf("%x", md5.Sum([]byte(str1)))
  125. return sign
  126. }
  127. // 对一个字符串进行加密
  128. func Encrypt(key, text []byte) (string, error) {
  129. block, err := aes.NewCipher(key)
  130. if err != nil {
  131. return "", err
  132. }
  133. b := base64.StdEncoding.EncodeToString(text)
  134. ciphertext := make([]byte, aes.BlockSize+len(b))
  135. iv := ciphertext[:aes.BlockSize]
  136. //if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  137. // return nil, err
  138. //}
  139. cfb := cipher.NewCFBEncrypter(block, iv)
  140. cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))
  141. return base64.RawURLEncoding.EncodeToString(ciphertext), nil
  142. }
  143. // 对一个字符串进行解密
  144. func Decrypt(key, text []byte) ([]byte, error) {
  145. block, err := aes.NewCipher(key)
  146. if err != nil {
  147. return nil, err
  148. }
  149. if len(text) < aes.BlockSize {
  150. return nil, errors.New("ciphertext too short")
  151. }
  152. iv := text[:aes.BlockSize]
  153. text = text[aes.BlockSize:]
  154. cfb := cipher.NewCFBDecrypter(block, iv)
  155. cfb.XORKeyStream(text, text)
  156. data, err := base64.StdEncoding.DecodeString(string(text))
  157. if err != nil {
  158. return nil, err
  159. }
  160. return data, nil
  161. }
  162. // 加密
  163. func AesEncrypt(orig string, key string) (string, error) {
  164. // 转成字节数组
  165. origData := []byte(orig)
  166. k := []byte(key)
  167. // 分组秘钥
  168. block, err := aes.NewCipher(k)
  169. if err != nil {
  170. return "", err
  171. }
  172. // 获取秘钥块的长度
  173. blockSize := block.BlockSize()
  174. // 补全码
  175. origData = PKCS7Padding(origData, blockSize)
  176. // 加密模式
  177. blockMode := cipher.NewCBCEncrypter(block, k[:blockSize])
  178. // 创建数组
  179. cryted := make([]byte, len(origData))
  180. // 加密
  181. blockMode.CryptBlocks(cryted, origData)
  182. //使用RawURLEncoding 不要使用StdEncoding
  183. //不要使用StdEncoding 放在url参数中回导致错误
  184. return base64.RawURLEncoding.EncodeToString(cryted), nil
  185. }
  186. // 解密
  187. func AesDecrypt(cryted string, key string) (string, error) {
  188. //使用RawURLEncoding 不要使用StdEncoding
  189. //不要使用StdEncoding 放在url参数中回导致错误
  190. crytedByte, err := base64.RawURLEncoding.DecodeString(cryted)
  191. if err != nil {
  192. return "", err
  193. }
  194. k := []byte(key)
  195. // 分组秘钥
  196. block, err := aes.NewCipher(k)
  197. if err != nil {
  198. return "", err
  199. }
  200. // 获取秘钥块的长度
  201. blockSize := block.BlockSize()
  202. // 加密模式
  203. blockMode := cipher.NewCBCDecrypter(block, k[:blockSize])
  204. // 创建数组
  205. orig := make([]byte, len(crytedByte))
  206. // 解密--传入不正确的字符时会报错-TODO 需捕获
  207. blockMode.CryptBlocks(orig, crytedByte)
  208. // 去补全码
  209. orig = PKCS7UnPadding(orig)
  210. return string(orig), nil
  211. }
  212. //补码
  213. func PKCS7Padding(ciphertext []byte, blocksize int) []byte {
  214. padding := blocksize - len(ciphertext)%blocksize
  215. padtext := bytes.Repeat([]byte{byte(padding)}, padding)
  216. return append(ciphertext, padtext...)
  217. }
  218. //去码
  219. func PKCS7UnPadding(origData []byte) []byte {
  220. length := len(origData)
  221. unpadding := int(origData[length-1])
  222. return origData[:(length - unpadding)]
  223. }
  224. // addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。
  225. // 预定义字符是:
  226. // 单引号(')
  227. // 双引号(")
  228. // 反斜杠(\)
  229. func Addslashes(str string) string {
  230. tmpRune := []rune{}
  231. strRune := []rune(str)
  232. for _, ch := range strRune {
  233. switch ch {
  234. case []rune{'\\'}[0], []rune{'"'}[0], []rune{'\''}[0]:
  235. tmpRune = append(tmpRune, []rune{'\\'}[0])
  236. tmpRune = append(tmpRune, ch)
  237. default:
  238. tmpRune = append(tmpRune, ch)
  239. }
  240. }
  241. return string(tmpRune)
  242. }
  243. // stripslashes() 函数删除由 addslashes() 函数添加的反斜杠。
  244. func Stripslashes(str string) string {
  245. dstRune := []rune{}
  246. strRune := []rune(str)
  247. strLenth := len(strRune)
  248. for i := 0; i < strLenth; i++ {
  249. if strRune[i] == []rune{'\\'}[0] {
  250. i++
  251. }
  252. dstRune = append(dstRune, strRune[i])
  253. }
  254. return string(dstRune)
  255. }
  256. // 将字符串的IP转化为数字
  257. func Ip4toInt(ip string) int64 {
  258. bits := strings.Split(ip, ".")
  259. if len(bits) == 4 {
  260. b0, _ := strconv.Atoi(bits[0])
  261. b1, _ := strconv.Atoi(bits[1])
  262. b2, _ := strconv.Atoi(bits[2])
  263. b3, _ := strconv.Atoi(bits[3])
  264. var sum int64
  265. sum += int64(b0) << 24
  266. sum += int64(b1) << 16
  267. sum += int64(b2) << 8
  268. sum += int64(b3)
  269. return sum
  270. } else {
  271. return 0
  272. }
  273. }
  274. // 得到当前时间到下一天零点的延时
  275. func NextDayDuration() time.Duration {
  276. year, month, day := time.Now().Add(time.Hour * 24).Date()
  277. next := time.Date(year, month, day, 0, 0, 0, 0, conf.SysTimeLocation)
  278. return next.Sub(time.Now())
  279. }
  280. // 从接口类型安全获取到int64
  281. func GetInt64(i interface{}, d int64) int64 {
  282. if i == nil {
  283. return d
  284. }
  285. switch i.(type) {
  286. case string:
  287. num, err := strconv.Atoi(i.(string))
  288. if err != nil {
  289. return d
  290. } else {
  291. return int64(num)
  292. }
  293. case []byte:
  294. bits := i.([]byte)
  295. if len(bits) == 8 {
  296. return int64(binary.LittleEndian.Uint64(bits))
  297. } else if len(bits) <= 4 {
  298. num, err := strconv.Atoi(string(bits))
  299. if err != nil {
  300. return d
  301. } else {
  302. return int64(num)
  303. }
  304. }
  305. case uint:
  306. return int64(i.(uint))
  307. case uint8:
  308. return int64(i.(uint8))
  309. case uint16:
  310. return int64(i.(uint16))
  311. case uint32:
  312. return int64(i.(uint32))
  313. case uint64:
  314. return int64(i.(uint64))
  315. case int:
  316. return int64(i.(int))
  317. case int8:
  318. return int64(i.(int8))
  319. case int16:
  320. return int64(i.(int16))
  321. case int32:
  322. return int64(i.(int32))
  323. case int64:
  324. return i.(int64)
  325. case float32:
  326. return int64(i.(float32))
  327. case float64:
  328. return int64(i.(float64))
  329. }
  330. return d
  331. }
  332. // 从接口类型安全获取到字符串类型
  333. func GetString(str interface{}, d string) string {
  334. if str == nil {
  335. return d
  336. }
  337. switch str.(type) {
  338. case string:
  339. return str.(string)
  340. case []byte:
  341. return string(str.([]byte))
  342. }
  343. return fmt.Sprintf("%s", str)
  344. }
  345. // 从map中得到指定的key
  346. func GetInt64FromMap(dm map[string]interface{}, key string, dft int64) int64 {
  347. data, ok := dm[key]
  348. if !ok {
  349. return dft
  350. }
  351. return GetInt64(data, dft)
  352. }
  353. // 从map中得到指定的key
  354. func GetInt64FromStringMap(dm map[string]string, key string, dft int64) int64 {
  355. data, ok := dm[key]
  356. if !ok {
  357. return dft
  358. }
  359. return GetInt64(data, dft)
  360. }
  361. // 从map中得到指定的key
  362. func GetStringFromMap(dm map[string]interface{}, key string, dft string) string {
  363. data, ok := dm[key]
  364. if !ok {
  365. return dft
  366. }
  367. return GetString(data, dft)
  368. }
  369. // 从map中得到指定的key
  370. func GetStringFromStringMap(dm map[string]string, key string, dft string) string {
  371. data, ok := dm[key]
  372. if !ok {
  373. return dft
  374. }
  375. return data
  376. }
  377. // 首字母大写
  378. func Ucfirst(str string) string {
  379. for i, v := range str {
  380. return string(unicode.ToUpper(v)) + str[i+1:]
  381. }
  382. return ""
  383. }